2014-04-30:
	Most of the Q&A in this FAQ is dated around 2004. Most of the
	content is still quite valid. With the exception(s) regarding *BSD,
	and possibly Openldap. As things have changed, and version(s) are
	newer. This is especially true where *BSD is concerned, as they
	were all pure conjecture, anyway. :)

note: this really is a FAQ. people asked me these questions at one point
or another. i have found that most people could find the answer easily
enough if they simply knew what question to ask.

however, for convenience's sake (and my gigantic maildir) you may also
find answers that i have given.

------------------------------------------------------------------------------
------------------------------------------------------------------------------

preinstallation:

Q:  these version numbers are confusing! what do they mean?
A:  they shouldn't be anymore. To ease package maintainers jobs' I've
	switched to a more conventional scheme. I had to change my
	build-scripts to handle these changes, but that wasn't such a big
	deal.

	2.01 means simply that we're using LDAPDNS2, serial number 1.

	if you're new to ldapdns, we've actually had 37 releases between
	2.00 and 2.01.


Q:  what does ldapdns require?
A:  two pieces of software: pthreads library, and the openldap library.
	build/install these first before using ldapdns. you'll probably want
	a decent ldap browser like GQ (search freshmeat for it).

	to run the admin scripts, you'll need perl, the Net::LDAP module,
	and probably Net::LDAPS and Crypt::SSLeay.

	beyond software? a good understanding of dns ldap schemas is nice,
	but not completely required. a decent understanding of ldap is also
	good, but (apparently) not completely required.

Q:  what platforms will ldapdns run on?
A:  ldapdns will run on any system with a semi-decent C library, and
	even less-than-decent POSIX threads (pthreads) support. finally,
	(and mostly obvious), ldapdns requires LDAP client library, and an
	LDAP server.

	version 2 has a very small test-base. let me know what platforms it
	works on and i'll add them here.

Q:  how do I build it?
A:  read INSTALL. it contains all the build instructions you will need.

Q:  i'm getting a bunch of undefined references! what gives!
A:  you probably don't have openldap installed. install it (rpm is fine)
A2:make sure you're using openldap 2. openldap 1 doesn't have
	server-side schema support, and it's API is somewhat deficient.

Q:  it just won't compile! i have openldap installed.
A:  let me see the error. i may know what's going on and just not have
	written it down into this faq...

Q:  what's this merge/ directory for?
A:  you unpacked ldapdns 2 into your ldapdns 1 source folder. dumbass.
	delete the old tree and/or unpack elsewhere.

Q:  i'm getting a lot of undefined symbols for `_pthread_.*'
A:  make sure you set -I/-L properly in your Makefile
A2:OpenBSD will find pthreads in -lc_r NOT -lpthread
A3:Actually. You can solve this for lots of programs in the future with:
	ln -s /usr/lib/libc_r.a /usr/lib/libpthread.a
A4:The configure script should detect this for you. Please send the
mailing list details about your system so that future versions of
ldapdns will know about you.

Q:  i'm getting warnings when i compile, what does that mean?
A:  it means there's a bug. there shouldn't be _ANY_ warnings. if there
	are, i'm not doing my job right...

Q:  is ldapdns secure?
A:  signs point to yes.
A2:ldapdns has a very good security history. the biggest failure has
	been a potential crash due to misconfiguration. i'm fairly sure
	there simply aren't any places where a remote user can trigger a
	buffer overflow, or a stack smash.

	ldapdns doesn't run very long as root, and doesn't answer any
	queries while it is root, so remote users can't gain root.

	ldapdns chroots itself so even if a problem is discovered, remote
	users can't manipulate any files.

	the biggest risk to using ldapdns is ldap. you've got an ldap server
	and a machine that can query it, or at least parts of it. don't give
	ldapdns any more access than it absolutely needs to query your
	directory, and you'll probably be fine.

------------------------------------------------------------------------------
------------------------------------------------------------------------------

postinstallation:

Q:  how do i use it?
A:  similarly to tinydns. quickstart (using daemontools):
	ldapdns-conf named nobody /var/ldapdns 172.16.0.2 192.168.0.15 \
	'cn=root,o=myorg' 'dc=dns,o=myorg'
		[ assumes this will be a nameserver listening to 172.16.0.2
		and talking to an ldap server on 192.168.0.15 ]

	then put your password into /var/ldapdns/root/password
	and finally:
	ln -s /var/ldapdns /service/ldapdns

	and svscan should notice the new directory and start it. check the
	log to see if anything went wrong (it probably won't)
A2:take a look at INSTALL

Q:  can i use kerberos with ldapdns?
A:  yes! you probably want to know how.
	after initially configuring it (see previous question), do the
	following:

	rm -f $ROOT/env/LDAP_BINDDN
	rm -f $ROOT/env/ROOT
	rm -f $ROOT/root/password

	then create:

	echo 'xxx' > $ROOT/env/LDAP_SASL

	replacing xxx with whatever your kerberos identity is.
	ldapdns will try LDAP_AUTH_KRBV42 first (authentication against
	DSA), then LDAP_AUTH_KRB41 (authentication directly against the ldap
	server)

Q:  none of the admin scripts seem to work!
A:  you'll need perl to run them. you'll also need Net::LDAP , and
	probably also Net::LDAPS + Crypt::SSLeay

Q:  i think ldapdns has a memory leak! it keeps growing!
A:  the openldap client libraries seem to "cache" attributes, and on a
	heavy nameserver it may seem to grow for a while. make sure
	softlimit is correct, and that you have a backup nameserver. one
	day, i may write a more low-memory ldap client lib to fix this...
	[ or i may find a bug in my code... or YOU might. it's possible;
	especially since i refuse to look at code before 2am... ]

	if it's a real bug. let me know, and i'll try to track it down. if
	you can code, more power! let's squash it together!

Q:  how do i make ldapdns resolve domains not in the directory?
A:  you don't. and you shouldn't either. DNS is "supposed" to be a
	unified space; however, if you're using a proper dns cache (like
	djb's dnscache), you CAN load the "root" nameservers into ldapdns.
	use:
	$ROOT/transfer_zone dns.vrx.net .
	then tell dnscache to use ldapdns as the only "root" server (in the
	@ file).
	[note: you will have to set up the admin tools first; see
	README.admin]

	there aren't a lot of good reasons to do this. if you come up with
	one, let me know...

Q:  how do I get "generic" records to work?
A:  use the "photo" objectClass, and write your data directly into it.
	note that you'll (probably) need to write a program to do this.
A2:use the administrative tools: $ROOT/add_generic_record and
	$ROOT/set_generic_record -- they both take a format string. see
	README.generic-rr for details.

Q:  how do I create LOC records?
A:  you have to use "generic" records for now... if there's enough
	demand, i'll add a parser for it. even if there isn't enough demand,
	YOU can add it. just send patches.

Q:  how do I delagate PTR records?
A:  short answer: you can't.
A2:long answer, if you point cNAMERecord inside the in-addr.arpa space
	from inside the in-addr.arpa space you'll get a real CNAME. note
	that this only works ONCE (RFC2317) so it probably won't do
	everything you want. some clients will (erroniously) work better if
	you use an nSRecord in there.
A3:you can create users and allow ldap users to modify that part of your
	directory.
A4:seeAlso is encoded as a DN (as that's what the schema for seeAlso
	requires) this attribute emits real PTR.
A5:use regular ldap referrals. ldapdns understand them, and works fine
	with them. this is best because you can get other people to use
	ldapdns too :)

Q:  how do I listen for NOTIFY requests?
A:  set $HELPER_NOTIFY to your notify-helper program :)
A2:I haven't written one yet... you could theoretically use
	transfer_zone, although you might want to make sure the zone exists,
	and that your source (the machine sending the notify request) is
	allowed. The remote address is put in the environment variable
	$REMOTE_ADDR. i don't think using transfer_zone would be safe.

Q:  i like to set the hostmaster address depending on the zone as I do a
	lot of delagation. how can I do this with ldapdns?
A:  i would prefer that you setup seperate instances of ldapdns, but
	that's not always possible. use the "mail" attribute in your
	directory on an object that also has an nSRecord. It's simply an
	email address; the last one listed will be used as the hostmaster
	address.
A2:when I said it was an email address, i mean you put:
	hostmaster@nimh.org. not that stupid bind thing of
	hostmaster.nimh.org.

Q:  sometimes ldapdns crashes after serving queries, what's going on?
A:  this appears to be a bug in the openldap libraries. it seems to be
	getting better; all data comming into ldapdns is checked, so
	whatever openldap is doing, it's doing it on it's own. normal
	ldapdns operation should keep it running (by restarting it). I don't
	know how other openldap clients work around this.

Q:  sometimes ldapdns hangs after serving queries, what's going on?
A:  again, i need to attribute this to openldap; all loops in ldapdns
	are finite, so ldapdns should never hang. it might hang due to bugs
	in the C library, or blocking errors, but at this point i'm betting
	my chips on openldap. the only calls that openldap should block on
	are:

	ldap_result

	using timeval, so max block time should be ~500usec

	ldap_simple_bind_s

	nameserver hasn't started yet normally, unless openldap hung up on
	ldapdns - in which case a connection isn't possible yet. the log
	will contain: ``handler XX was hung up on, restarting'' if this
	happens.
A2:there is a legitimate bug in many operating systems. if the operating
	system is not reentrant, you will have better luck using 1:1 mode
	(HANDLERS=1) if you are using an SMP system, your operating system
	isn't using it any. trade it in on a nice 486 :)

	openbsd and freebsd _both_ have problems using the fast threading
	system. solaris does not, and oddly enough, LINUX does not- despite
	all the hype about linux having such poor support for threads,
	etc...

Q:  what does the following error mean?
ldapdns: getattr.c:99: ldap_next_attribute: Assertion `entry != ((void *)0)' failed.
Q:  what does the following error mean?
ldapdns: error.c:221: ldap_parse_result: Assertion `r != ((void *)0)' failed.
A:  it means there's a bug in openlap (imagine that)! try upgrading to a
	newer version

------------------------------------------------------------------------------
------------------------------------------------------------------------------

tweaking/tuning:


Q:  i have lots of A records and I want to load balance with them.
A:  well, DNS is the poorest place to put that, IMHO, but if you define
	multiple aRecords, and:

	echo random > env/SCHEDULE_ARECORD

	you'll be set.

Q:  ldapdns appears to parse the ldap data each time the query occurs.
	is there a way to speed this up?
A:  i've been using ldapdns for quite a while, and i haven't noticed any
	speed problems. adding caching to this would probably slow things
	down some, (because we have to expire the cache), and definately add
	so much complexity that bugs would crop up.
A2:enable the feature ACCELERATE_CACHE
	but do so at your own risk: OpenLDAP presently has bugs in this
	code.

	this enables the OpenLDAP client-side cache into ldapdns thus
	increasing speed. this can help GREATLY if your ldap server is
	blocking. (buying faster hardware is probably better)

	this value is measured in seconds, the default (60*5) is five
	minutes.

	under NO CIRCUMSTANCES should you set this above DEFAULT_RETRY (900,
	or 15 minutes). you will force ldapdns to violate the DNS protocol
	by doing this...

	echo 900 > $ROOT/env/ACCELERATE_CACHE

Q:  how can i provide access control for ldapdns?
A:  you don't. use a dnscache in a method described by the previous
	answer.

Q:  how do I provide a distributed directory to make sure things stay
	running?
A:  here's the way I did it:

	LDAPM (192.168.1.20)	- master openldap server
	LDAP1 (192.168.1.25)	- slave openldap server
	LDAP2 (192.168.1.26)	- slave openldap server
	DNS1 (192.168.1.40)	- ldapdns
	DNS2 (192.168.1.41)	- ldapdns

	then after ldapdns installation is complete, you go into
	/service/ldapdns/env and delete the file: LDAP_HOST and create a new
	file called LDAP_HOSTS which

	has:
	192.168.1.25,192.168.1.26,192.168.1.20
	in it. this will cause ldapdns to try each one.

	since ldapdns will die if an ldap query fails, daemontools will
	restart ldapdns to try another host.

	try to set a different order on each machine (if possible) as it
	will speed recovery somewhat.

Q:  BIND has an option that XXX... how do I do this in ldapdns?
A:  chances are, you don't. however, in conjunction with other tools
	(including tools distributed with djbdns), it SHOULD be possible to
	do everything BIND does except crash [eratically].

Q:  i'm used to using relative names and origins. how can I do this with
	ldapdns?
A:  well, ordinarily you can't. fortunately another programmer saw this
	to be necessary for him (<jordan@mjh.teddy-net.com>) and added
	support for it. if you type:

	echo 1 > $ROOT/env/RELATIVE_NAMES

	the feature is now enabled. restart ldapdns. please remember that if
	you're going to use some admin scripts the rely on this, make sure
	to keep the environment variable RELATIVE_NAMES actually IN the
	environment.

	I do not recommend that you use this feature, as it makes your
	directory confusing. It may be useful if you are handling the
	directory by hand.

Q:  are there any general purpose speed improvements you can recommend?
A:  use dnscache as a front-line resolver. this is not appropriate for
	all users of ldapdns, but should be suitable for a small number of
	zones.
A2:put slapd in replication mode on the same machine as ldapdns. this
	will speed requests.
A3:balance your requests by setting up multiple ldapdns's. use pickdns
	to help load balance further.
A4:enable the feature ACCELERATE_CACHE
	this builds the OpenLDAP client-side cache into ldapdns thus
	increasing speed. this can help GREATLY if your ldap server is
	blocking. (OpenLDAP blocks horribly) this is measured in seconds,
	the default (60*5) is five minutes. this is a recommended value for
	most cases.

	under NO CIRCUMSTANCES should you set this above DEFAULT_RETRY (900,
	or 15 minutes). you will force ldapdns to violate the DNS spec by
	doing this...

	echo 900 > $ROOT/env/CACHE

	just so you know. thie OpenLDAP client-side cache is broken at the
	time of this writing. don't use it.

Q:  what's an optimal value for $HANDLERS ?
A:  the default :)
A2:you want the value to be just a little bit greater than your AVERAGE
	DNS REQUESTS PER UNIQUE LDAP CYCLE. this means that if you can yank
	100 ldap records per second, and are receiving around 500 dns
	requests per second, you'll want: 500/100 or 5 handlers. 8 should be
	fine. however, if your ldap server is heavily loaded, you may only
	be able to fit 50 records per second. 500/50 or 10 handlers. 12
	should be fine.
A3:i've found the above formula to also be a crock of shit when dealing
	with OpenLDAP. Whatever number you get, multiply by ten, because
	OpenLDAP likes to block at strange moments.
A4:this number is SHARED, so if you say 128, then you really only have
	128, not 1024 (with 8 threads).
A5:HANDLERS=1 is good for broken threading libraries with non-reentrant
	kernels. it does NOT seem to be necessary with LINUX or SOLARIS. if
	you set HANDLERS=1, then ldapdns uses your THREADS count to set up
	1:1: mode.

Q:  what's an optimal value for $THREADS ?
A:  usually, DOUBLE the number of cpu's is good.
A2:this is extremely dependent on the schedular that your operating
	system uses.
A3:you can tune this: $LDAP_THREADS and $DNS_THREADS are seperate entities.
A4:if using $HANDLERS=1 then set this number high. 100-200 seem good.

------------------------------------------------------------------------------
------------------------------------------------------------------------------

migration:

Q:  how do i convert from using BIND/DJBDNS/Win2K/etc?
A:  at the moment? perform a zone transfer. see README.admin for details
	of how to use the admin scripts. note see below for
	behavior-modifying options to ldapdns.

Q:  How do I use ldapdns as a drop-in replacement for BIND+LDAP?
A:  very carefully. There are several BIND+LDAP patches; one set follows
	RFC1279 which should work if:

	echo 1 > $ROOT/env/RFC1279

Q:  How do I use ldapdns with Active Directory?
A:  very carefully. First you must enable MSDNS mode. this is presently
	done by simply setting the LDAP suffix to:

	CN=MicrosoftDNS,CN=System,DC=windowsdomain,DC=...

[e.g. mydomain.local is: CN=MicrosoftDNS,CN=System,DC=mydomain,DC=local]

	ldapdns will now attempt to search for dnsRecords that are encoded
	in the manner that Active Directory uses.

	[note that ldapdns will NOT SEARCH PROPERLY unless you're setting
	your ldap_suffix properly. you CAN force it to use AD encoded
	entries if you've mirrored your trees elsewhere by:

	echo msdns > $ROOT/env/DNSRECORD

	but please avoid doing this as Microsoft DNS records search slowly.]

	ldapdns does not understand all RR's that MSDNS does. It should be
	sufficient for gatewaying certain Win2K services (like IIS) to the
	outside world, yet still provide the ease/management that Active
	Directory can provide.

	All my understanding of Active Directory was obtained through
	reverse-engineering of the directory by examining the LDAP tree
	directly. I can guarantee I am not supporting all features. I can
	not guarantee that I am supporting _any_ of the features. Send
	patches for additional queries that you find I'm performing
	incorrectly.

	big warning here: until I can handle SRV requests properly, you
	cannot use ldapdns as a stand-in for Microsoft DNS. this is because
	Microsoft REQUIRES the use of SRV records to locate the directory,
	locate the keyservers, and to locate that big hole you have in your
	head.

	however, if you are MIGRATING from a MS-DNS platform, this option
	MAY be of some use to you. on the other hand, if you are migrating,
	zone transfers may be a better option... you have been warned.

Q:  i use bind. i provide name-services for my customers so that they
	can have a NS1.EXAMPLE.COM and a NS2.EXAMPLE.COM of their own in the
	whois records. how do i do this with ldapdns?
A:  set up multiple ldapdns instances- each on a seperate IP.
A2:set up multiple ldapdns servers. just like bind :)

Q:  how do I setup ldapdns to be a secondary for a BIND-based machine?
A:  this is one of the most common ldapdns questions. i highly recommend
	that you don't do this (nor the other way around). running two dns
	databases is a bad idea, but transfer_zone and ldapaxfr can help you
	do this...
A2:the admin tool secondary_zone was built for this purpose. run it as:
	secondary_zone ns zone ... periodically to keep the directory up to
	date with your bind files.
	- <jordan@mjh.teddy-net.com>

Q:  i used djbdns, and i really like the ability to send information
	based on what address the client is comming from. how do i do this
	in ldapdns?
A:  you couldn't until very recently: first you need to create a:
	$ROOT/root/switch
	the format is simple:
	nym=subnet
	nym=subnet
	then, in your directory, set up multiple aRecords that end with
	%nym;
	to perform djb's example you'll have:
	in=192.168.0.0/16
	ex=0/0
	and then records:
	dc=juniper, dc=heaven, dc=af, dc=mil
	aRecord=192.168.1.2%in
	aRecord=1.2.3.4%ex
	this feature is experimental. i have no use for it, but other people
	seem to like it. so if you used this feature, you too might like it.
A2:You can also create aRecords like this:
	192.168.0.0/16=192.168.1.2
	0/0=1.2.3.4
	but note that this method depends on the order in which things come
	back from the LDAP directory. Unless you have control of this,
	you'll probably want to use the former method.

------------------------------------------------------------------------------
------------------------------------------------------------------------------

bugs and problems:

Q:  i keep getting ber_dump: related things in my log.
A:  you enabled ACCELERATE_CACHE thinking it would be a good idea to use
	overly complicated and experimental code on a production nameserver,
	didn't you? :)

	don't do that. ACCELERATE_CACHE is presently BROKEN in OpenLDAP
	(2.0.11) this could change at any time. post the bug to the OpenLDAP
	mailing lists; it isn't my fault.

Q:  there's a long delay before "starting ldapdns" is displayed. how do
	i fix this?
A:  don't use names in defining your LDAP servers. ldapdns chroots into
	it's directory so it cannot access your resolver files or your
	static host map.
A2:freebsd appears to have some weird resolver problems:
	mkdir $ROOT/root/etc
	cp /etc/hosts /etc/resolv.conf $ROOT/root/etc/.
	echo hosts > $ROOT/root/etc/host.conf
	yet another braindead thing freebsd does...
	(should not probe 127.0.0.1 if no resolver is found)
	(thanks to mg@bindone.de for helping me work this out)
A3:ldapdns 2 should solve this issue (by bringing up ldap connections in a
   different order).

Q:  it built fine on solaris, but it doesn't run!
A2:solaris requires some device nodes. you need to:
	mkdir $ROOT/root/dev
	cp -p /devices/pseudo/clone@0:ip $ROOT/root/dev/ip
	cp -p /devices/pseudo/clone@0:tcp $ROOT/root/dev/tcp

Q:  what does this mean?
	ldapdns fatal: handler 91 has waited too long
A:  it means there's a bug in openlap (imagine that)! try upgrading to a
	newer version
A2:you can try and increase the number of threads/handlers so that it
	won't affect DNS operation.
A3:try disabling the client side cache if you have it enabled. I've
	noticed some potentially infinite loops there...

------------------------------------------------------------------------------
------------------------------------------------------------------------------

other questions:

Q:  how much of ldapdns is dependant on djbdns?
A:  none. not any more. djbdns is very quick so long as the
	blocking-factor is the udp network. however with ldapdns, the
	blocking factor is LDAP.

Q:  ldap2dns allows djbdns to use ldap. why do we need another gateway?
A:  because ldap2dns (despite the propaganda) is not an ldap to dns
	gateway. it's a perl script that downloads records out of an ldap
	directory and into a normal tinydns data file. i wanted something
	that could speak directly.

Q:  why don't you support the ldap2dns schema format?
A:  because it's extremely slow, and doesn't appear to be well thought
	out. it's fairly easy to reconstruct valid entries from the LDAP
	tree that ldap2dns uses, but it is not easy to contort a valid DNS
	query into one of these messages. storing the record type as part of
	the DN is a bad idea.

Q:  bind can already read from an ldap directory? why not use that?
A:  honestly. do you really think i would be caught dead running ISC
	software?
A2:bind is slow, by-design bug prone, and it's methods in the directory
	are quite silly.
A3:some BIND people find this humerous. I will digress: BIND has got to
	be the worst nameserver implementation ever. It is certainly the
	first, and most certainly the most rhobust (all around), and for
	that I am fortunate, for I have learned from many of the mistakes
	BIND has (is, does) made.
A4:BIND leaks memory even worse than the OpenLDAP client libs.
A5:Okay, this one is for real: BIND's LDAP support is still very buggy,
	and crashed on me several times when first trying it out. Perhaps
	it's better now. Probably not. The BIND core isn't well suited for
	anything except pulling records from memory. This is because BIND
	uses the same blocks for caching DNS records as it uses for storing
	the real authoritative records. This is probably the reason DNS
	poisoning worked so well. Anyway, BIND isn't multithreaded, so no
	matter which hacks you're using, BIND will either block when a query
	is received, or it will suck up memory like mad. Your choice.

Q:  windows 2000 with active directory and three-dee-action stores DNS
	records in active directory (ldap server), why not just use that?
A:  because nameservers should never be rebooted!
A2:win2k requires lots of licensing. ldapdns is free (cost-wise).
A3:win2k requires lots of licensing. ldapdns is free (freedom-wise).
A4:win2k has many security-related problems. try a good *nix and
	ldapdns.

Q:  will active directory/BIND+LDAP support improve over time?
A:  possibly. only you can answer that question by using it. tell me
	what you need, write patches, run probes, and etc. I don't use
	Microsoft anything, nor do I use BIND, so I can't help you a whole
	lot.

	the only reason I was able to do ANY active directory code is that a
	client used MSDNS and I decided to take some snaps of parts of the
	directory for perusal.

Q:  what do i do if my question isn't answered here?
A:  ask me! see http://www.nimh.org/ for directions on reaching my
	contact page.
