
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.

