mirror of
				https://github.com/bklang/ldap2dns.git
				synced 2025-11-04 08:53:12 -05:00 
			
		
		
		
	
		
			
	
	
		
			973 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
		
		
			
		
	
	
			973 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/Makefile djbdns-1.05/Makefile
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/Makefile	Sun Feb 11 22:11:45 2001
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/Makefile	Tue Aug 13 14:28:52 2002
							 | 
						||
| 
								 | 
							
								@@ -1,9 +1,6 @@
							 | 
						||
| 
								 | 
							
								-# Don't edit Makefile! Use conf-* for configuration.
							 | 
						||
| 
								 | 
							
								-
							 | 
						||
| 
								 | 
							
								-SHELL=/bin/sh
							 | 
						||
| 
								 | 
							
								-
							 | 
						||
| 
								 | 
							
								 default: it
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								 alloc.a: \
							 | 
						||
| 
								 | 
							
								 makelib alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o \
							 | 
						||
| 
								 | 
							
								 stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o \
							 | 
						||
| 
								 | 
							
								@@ -55,8 +52,8 @@
							 | 
						||
| 
								 | 
							
								 prot.o timeoutread.o timeoutwrite.o dns.a libtai.a alloc.a env.a \
							 | 
						||
| 
								 | 
							
								 cdb.a buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								 	./load axfrdns iopause.o droproot.o tdlookup.o response.o \
							 | 
						||
| 
								 | 
							
								-	qlog.o prot.o timeoutread.o timeoutwrite.o dns.a libtai.a \
							 | 
						||
| 
								 | 
							
								-	alloc.a env.a cdb.a buffer.a unix.a byte.a 
							 | 
						||
| 
								 | 
							
								+	qlog.o prot.o timeoutread.o timeoutwrite.o askldap.o dns.a libtai.a \
							 | 
						||
| 
								 | 
							
								+	alloc.a env.a cdb.a buffer.a unix.a byte.a `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 axfrdns-conf: \
							 | 
						||
| 
								 | 
							
								 load axfrdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								@@ -626,11 +623,11 @@
							 | 
						||
| 
								 | 
							
								 	./compile parsetype.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 pickdns: \
							 | 
						||
| 
								 | 
							
								-load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \
							 | 
						||
| 
								 | 
							
								+load pickdns.o server.o response.o droproot.o qlog.o prot.o askldap.o dns.a \
							 | 
						||
| 
								 | 
							
								 env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
							 | 
						||
| 
								 | 
							
								 	./load pickdns server.o response.o droproot.o qlog.o \
							 | 
						||
| 
								 | 
							
								-	prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								-	byte.a  `cat socket.lib`
							 | 
						||
| 
								 | 
							
								+	prot.o askldap.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								+	byte.a  `cat socket.lib` `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 pickdns-conf: \
							 | 
						||
| 
								 | 
							
								 load pickdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								@@ -704,11 +701,11 @@
							 | 
						||
| 
								 | 
							
								 	./compile random-ip.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 rbldns: \
							 | 
						||
| 
								 | 
							
								-load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \
							 | 
						||
| 
								 | 
							
								+load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o askldap.o dns.a \
							 | 
						||
| 
								 | 
							
								 env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
							 | 
						||
| 
								 | 
							
								 	./load rbldns server.o response.o dd.o droproot.o qlog.o \
							 | 
						||
| 
								 | 
							
								-	prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								-	byte.a  `cat socket.lib`
							 | 
						||
| 
								 | 
							
								+	prot.o askldap.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								+	byte.a  `cat socket.lib` `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 rbldns-conf: \
							 | 
						||
| 
								 | 
							
								 load rbldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								@@ -792,6 +789,9 @@
							 | 
						||
| 
								 | 
							
								 	&& echo -lsocket -lnsl || exit 0 ) > socket.lib
							 | 
						||
| 
								 | 
							
								 	rm -f trylsock.o trylsock
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								+ldap.lib:
							 | 
						||
| 
								 | 
							
								+	echo -lldap -llber > ldap.lib
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								 socket_accept.o: \
							 | 
						||
| 
								 | 
							
								 compile socket_accept.c byte.h socket.h uint16.h
							 | 
						||
| 
								 | 
							
								 	./compile socket_accept.c
							 | 
						||
| 
								 | 
							
								@@ -978,13 +978,17 @@
							 | 
						||
| 
								 | 
							
								 timeoutwrite.h
							 | 
						||
| 
								 | 
							
								 	./compile timeoutwrite.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								+askldap.o: \
							 | 
						||
| 
								 | 
							
								+compile askldap.c askldap.h
							 | 
						||
| 
								 | 
							
								+	./compile askldap.c
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								 tinydns: \
							 | 
						||
| 
								 | 
							
								 load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \
							 | 
						||
| 
								 | 
							
								-prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \
							 | 
						||
| 
								 | 
							
								-socket.lib
							 | 
						||
| 
								 | 
							
								+prot.o askldap.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \
							 | 
						||
| 
								 | 
							
								+socket.lib ldap.lib
							 | 
						||
| 
								 | 
							
								 	./load tinydns server.o droproot.o tdlookup.o response.o \
							 | 
						||
| 
								 | 
							
								-	qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \
							 | 
						||
| 
								 | 
							
								-	unix.a byte.a  `cat socket.lib`
							 | 
						||
| 
								 | 
							
								+	qlog.o prot.o askldap.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \
							 | 
						||
| 
								 | 
							
								+	unix.a byte.a  `cat socket.lib` `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 tinydns-conf: \
							 | 
						||
| 
								 | 
							
								 load tinydns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								@@ -1015,26 +1019,26 @@
							 | 
						||
| 
								 | 
							
								 tinydns-edit.o: \
							 | 
						||
| 
								 | 
							
								 compile tinydns-edit.c stralloc.h gen_alloc.h buffer.h exit.h open.h \
							 | 
						||
| 
								 | 
							
								 getln.h buffer.h stralloc.h strerr.h scan.h byte.h str.h fmt.h ip4.h \
							 | 
						||
| 
								 | 
							
								-dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h
							 | 
						||
| 
								 | 
							
								+dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h askldap.h
							 | 
						||
| 
								 | 
							
								 	./compile tinydns-edit.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 tinydns-get: \
							 | 
						||
| 
								 | 
							
								 load tinydns-get.o tdlookup.o response.o printpacket.o printrecord.o \
							 | 
						||
| 
								 | 
							
								 parsetype.o dns.a libtai.a cdb.a buffer.a alloc.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								 	./load tinydns-get tdlookup.o response.o printpacket.o \
							 | 
						||
| 
								 | 
							
								-	printrecord.o parsetype.o dns.a libtai.a cdb.a buffer.a \
							 | 
						||
| 
								 | 
							
								-	alloc.a unix.a byte.a 
							 | 
						||
| 
								 | 
							
								+	printrecord.o parsetype.o askldap.o dns.a libtai.a cdb.a buffer.a \
							 | 
						||
| 
								 | 
							
								+	alloc.a unix.a byte.a `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 tinydns-get.o: \
							 | 
						||
| 
								 | 
							
								 compile tinydns-get.c str.h byte.h scan.h exit.h stralloc.h \
							 | 
						||
| 
								 | 
							
								 gen_alloc.h buffer.h strerr.h uint16.h response.h uint32.h case.h \
							 | 
						||
| 
								 | 
							
								 printpacket.h stralloc.h parsetype.h ip4.h dns.h stralloc.h iopause.h \
							 | 
						||
| 
								 | 
							
								-taia.h tai.h uint64.h taia.h
							 | 
						||
| 
								 | 
							
								+taia.h tai.h uint64.h taia.h  askldap.h
							 | 
						||
| 
								 | 
							
								 	./compile tinydns-get.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 tinydns.o: \
							 | 
						||
| 
								 | 
							
								 compile tinydns.c dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \
							 | 
						||
| 
								 | 
							
								-uint64.h taia.h
							 | 
						||
| 
								 | 
							
								+uint64.h taia.h  askldap.h
							 | 
						||
| 
								 | 
							
								 	./compile tinydns.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 uint16_pack.o: \
							 | 
						||
| 
								 | 
							
								@@ -1084,11 +1088,11 @@
							 | 
						||
| 
								 | 
							
								 	./compile utime.c
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 walldns: \
							 | 
						||
| 
								 | 
							
								-load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \
							 | 
						||
| 
								 | 
							
								+load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o askldap.o \
							 | 
						||
| 
								 | 
							
								 dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib
							 | 
						||
| 
								 | 
							
								 	./load walldns server.o response.o droproot.o qlog.o \
							 | 
						||
| 
								 | 
							
								-	prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								-	byte.a  `cat socket.lib`
							 | 
						||
| 
								 | 
							
								+	prot.o dd.o askldap.o dns.a env.a cdb.a alloc.a buffer.a unix.a \
							 | 
						||
| 
								 | 
							
								+	byte.a  `cat socket.lib` `cat ldap.lib`
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 walldns-conf: \
							 | 
						||
| 
								 | 
							
								 load walldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a
							 | 
						||
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/askldap.c djbdns-1.05/askldap.c
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/askldap.c	Thu Jan  1 01:00:00 1970
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/askldap.c	Tue Aug 13 14:30:18 2002
							 | 
						||
| 
								 | 
							
								@@ -0,0 +1,750 @@
							 | 
						||
| 
								 | 
							
								+/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup.
							 | 
						||
| 
								 | 
							
								+ * $Id$
							 | 
						||
| 
								 | 
							
								+ * Copyright 2002 <jacob.rief@tiscover.com> 
							 | 
						||
| 
								 | 
							
								+ */ 
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+#include <lber.h>
							 | 
						||
| 
								 | 
							
								+#include <ldap.h>
							 | 
						||
| 
								 | 
							
								+#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								+#include <stdio.h>
							 | 
						||
| 
								 | 
							
								+#include <ctype.h>
							 | 
						||
| 
								 | 
							
								+#include <string.h>
							 | 
						||
| 
								 | 
							
								+#include <assert.h>
							 | 
						||
| 
								 | 
							
								+#include <unistd.h>
							 | 
						||
| 
								 | 
							
								+#include <time.h>
							 | 
						||
| 
								 | 
							
								+#include <sys/time.h>
							 | 
						||
| 
								 | 
							
								+#include <setjmp.h>
							 | 
						||
| 
								 | 
							
								+#include "alloc.h"
							 | 
						||
| 
								 | 
							
								+#include "byte.h"
							 | 
						||
| 
								 | 
							
								+#include "response.h"
							 | 
						||
| 
								 | 
							
								+#include "askldap.h"
							 | 
						||
| 
								 | 
							
								+#include "dns.h"
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static LDAP* ldap_con;
							 | 
						||
| 
								 | 
							
								+static sigjmp_buf stack_context;
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static struct {
							 | 
						||
| 
								 | 
							
								+	char ldaphosts[256];
							 | 
						||
| 
								 | 
							
								+	const char* basedn;
							 | 
						||
| 
								 | 
							
								+	char binddn[256];
							 | 
						||
| 
								 | 
							
								+	char bindpwd[16];
							 | 
						||
| 
								 | 
							
								+	struct timeval timeout;	
							 | 
						||
| 
								 | 
							
								+	int verbose;
							 | 
						||
| 
								 | 
							
								+	int initialized;
							 | 
						||
| 
								 | 
							
								+} options;
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+struct zonerecord {
							 | 
						||
| 
								 | 
							
								+	char zonedn[256];
							 | 
						||
| 
								 | 
							
								+	char zonename[64];
							 | 
						||
| 
								 | 
							
								+	char class[16];
							 | 
						||
| 
								 | 
							
								+	char type[16];
							 | 
						||
| 
								 | 
							
								+	char adminmailbox[64];
							 | 
						||
| 
								 | 
							
								+	char zonemaster[64];
							 | 
						||
| 
								 | 
							
								+	unsigned long serial, refresh, retry, expire, minimum;
							 | 
						||
| 
								 | 
							
								+	int ttl;
							 | 
						||
| 
								 | 
							
								+	int timestamp;
							 | 
						||
| 
								 | 
							
								+};
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+struct resourcerecord {
							 | 
						||
| 
								 | 
							
								+	char qualifieddomainname[256];
							 | 
						||
| 
								 | 
							
								+	char class[16];
							 | 
						||
| 
								 | 
							
								+	char type[16];
							 | 
						||
| 
								 | 
							
								+	char ipaddr[8][4];
							 | 
						||
| 
								 | 
							
								+	int numipaddrs;
							 | 
						||
| 
								 | 
							
								+	char cname[256];
							 | 
						||
| 
								 | 
							
								+	unsigned int preference;
							 | 
						||
| 
								 | 
							
								+	int ttl;
							 | 
						||
| 
								 | 
							
								+	int timestamp;
							 | 
						||
| 
								 | 
							
								+	int additionalinfo;
							 | 
						||
| 
								 | 
							
								+	struct resourcerecord* next;
							 | 
						||
| 
								 | 
							
								+};
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+enum { ASKLDAP_RETRY = 1, ASKLDAP_RETURN = 2, ASKLDAP_RECONNECT = 3 };
							 | 
						||
| 
								 | 
							
								+	
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void assert_ldap(int err)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	static int retries;
							 | 
						||
| 
								 | 
							
								+	switch (err) {
							 | 
						||
| 
								 | 
							
								+	    case LDAP_SUCCESS:
							 | 
						||
| 
								 | 
							
								+		return;
							 | 
						||
| 
								 | 
							
								+	    case LDAP_TIMELIMIT_EXCEEDED:
							 | 
						||
| 
								 | 
							
								+		fprintf(stderr, "Warning: %s\n", ldap_err2string(err));
							 | 
						||
| 
								 | 
							
								+		retries++;
							 | 
						||
| 
								 | 
							
								+		if (retries<3)
							 | 
						||
| 
								 | 
							
								+			siglongjmp(stack_context, ASKLDAP_RETRY);
							 | 
						||
| 
								 | 
							
								+		retries = 0;
							 | 
						||
| 
								 | 
							
								+		siglongjmp(stack_context, ASKLDAP_RETURN);
							 | 
						||
| 
								 | 
							
								+	    case LDAP_TIMEOUT:
							 | 
						||
| 
								 | 
							
								+	    case LDAP_NO_SUCH_OBJECT:
							 | 
						||
| 
								 | 
							
								+		fprintf(stderr, "Warning: %s\n", ldap_err2string(err));
							 | 
						||
| 
								 | 
							
								+		siglongjmp(stack_context, ASKLDAP_RETURN);
							 | 
						||
| 
								 | 
							
								+	    case LDAP_BUSY:
							 | 
						||
| 
								 | 
							
								+	    case LDAP_UNAVAILABLE:
							 | 
						||
| 
								 | 
							
								+	    case LDAP_UNWILLING_TO_PERFORM:
							 | 
						||
| 
								 | 
							
								+	    case LDAP_SERVER_DOWN:
							 | 
						||
| 
								 | 
							
								+		fprintf(stderr, "Warning: %s\n", ldap_err2string(err));
							 | 
						||
| 
								 | 
							
								+		siglongjmp(stack_context, ASKLDAP_RECONNECT);
							 | 
						||
| 
								 | 
							
								+	    default:
							 | 
						||
| 
								 | 
							
								+		fprintf(stderr, "Fatal error: %s\n", ldap_err2string(err));
							 | 
						||
| 
								 | 
							
								+#ifdef _DEBUG
							 | 
						||
| 
								 | 
							
								+		abort();
							 | 
						||
| 
								 | 
							
								+#else
							 | 
						||
| 
								 | 
							
								+		exit(1);
							 | 
						||
| 
								 | 
							
								+#endif
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+void free_domainrecords(struct resourcerecord* anchor)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	struct resourcerecord* ptr;
							 | 
						||
| 
								 | 
							
								+	for (ptr = anchor; ptr; ptr = anchor) {
							 | 
						||
| 
								 | 
							
								+		anchor = anchor->next;
							 | 
						||
| 
								 | 
							
								+		alloc_free(ptr);
							 | 
						||
| 
								 | 
							
								+	}	
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void fill_resourcerecord(struct resourcerecord* rr, LDAPMessage* m, const char* zonename)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	BerElement* ber = NULL;
							 | 
						||
| 
								 | 
							
								+	char* attr;
							 | 
						||
| 
								 | 
							
								+		
							 | 
						||
| 
								 | 
							
								+	byte_zero(rr, sizeof(struct resourcerecord));
							 | 
						||
| 
								 | 
							
								+	strcpy(rr->class, "IN");
							 | 
						||
| 
								 | 
							
								+	for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) {
							 | 
						||
| 
								 | 
							
								+		struct berval** bvals = ldap_get_values_len(ldap_con, m, attr);
							 | 
						||
| 
								 | 
							
								+		if (bvals && bvals[0] && bvals[0]->bv_len>0) {
							 | 
						||
| 
								 | 
							
								+			if (strcasecmp(attr, "dnsdomainname")==0) {
							 | 
						||
| 
								 | 
							
								+				char tmp[64];
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%64s", tmp)==1) {
							 | 
						||
| 
								 | 
							
								+					if (zonename[0]!='\0') 
							 | 
						||
| 
								 | 
							
								+						snprintf(rr->qualifieddomainname, 256, "%s.%s", tmp, zonename);
							 | 
						||
| 
								 | 
							
								+					else
							 | 
						||
| 
								 | 
							
								+						strncpy(rr->qualifieddomainname, tmp, 256);
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnstype")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%16s", rr->type)!=1) {
							 | 
						||
| 
								 | 
							
								+					rr->type[0] = '\0';
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsipaddr")==0) {
							 | 
						||
| 
								 | 
							
								+				int k, ip[4];
							 | 
						||
| 
								 | 
							
								+				for (k = 0; bvals[k] && k < 8-rr->numipaddrs; k++) {
							 | 
						||
| 
								 | 
							
								+					if (sscanf(bvals[k]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) {
							 | 
						||
| 
								 | 
							
								+						rr->ipaddr[rr->numipaddrs][0] = (char)ip[0];
							 | 
						||
| 
								 | 
							
								+						rr->ipaddr[rr->numipaddrs][1] = (char)ip[1];
							 | 
						||
| 
								 | 
							
								+						rr->ipaddr[rr->numipaddrs][2] = (char)ip[2];
							 | 
						||
| 
								 | 
							
								+						rr->ipaddr[rr->numipaddrs][3] = (char)ip[3];
							 | 
						||
| 
								 | 
							
								+						rr->numipaddrs++;
							 | 
						||
| 
								 | 
							
								+					}
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else if (rr->numipaddrs<8 && strcasecmp(attr, "dnscipaddr")==0) {
							 | 
						||
| 
								 | 
							
								+				int ip[4];
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) {
							 | 
						||
| 
								 | 
							
								+					rr->ipaddr[rr->numipaddrs][0] = (char)ip[0];
							 | 
						||
| 
								 | 
							
								+					rr->ipaddr[rr->numipaddrs][1] = (char)ip[1];
							 | 
						||
| 
								 | 
							
								+					rr->ipaddr[rr->numipaddrs][2] = (char)ip[2];
							 | 
						||
| 
								 | 
							
								+					rr->ipaddr[rr->numipaddrs][3] = (char)ip[3];
							 | 
						||
| 
								 | 
							
								+					rr->numipaddrs++;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnscname")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%256s", rr->cname)==1) {
							 | 
						||
| 
								 | 
							
								+					int len = strlen(rr->cname);
							 | 
						||
| 
								 | 
							
								+					if (rr->cname[len-1]!='.' && zonename[0]!='\0') {
							 | 
						||
| 
								 | 
							
								+						strcat(rr->cname, ".");
							 | 
						||
| 
								 | 
							
								+						strncat(rr->cname, zonename, 252-len);
							 | 
						||
| 
								 | 
							
								+						strcat(rr->cname, ".");
							 | 
						||
| 
								 | 
							
								+					}
							 | 
						||
| 
								 | 
							
								+				} else {
							 | 
						||
| 
								 | 
							
								+					rr->cname[0] = '\0';
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsttl")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%d", &rr->ttl)!=1)
							 | 
						||
| 
								 | 
							
								+					rr->ttl = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnstimestamp")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%d", &rr->timestamp)!=1)
							 | 
						||
| 
								 | 
							
								+					rr->timestamp = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnspreference")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%u", &rr->preference)!=1)
							 | 
						||
| 
								 | 
							
								+					rr->preference = 1;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		ldap_value_free_len(bvals);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void fill_zonerecord(struct zonerecord* zone, LDAPMessage* m)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	BerElement* ber = NULL;
							 | 
						||
| 
								 | 
							
								+	char* attr;
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+	byte_zero(zone, sizeof(struct zonerecord));
							 | 
						||
| 
								 | 
							
								+	strcpy(zone->class, "IN");
							 | 
						||
| 
								 | 
							
								+	for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) {
							 | 
						||
| 
								 | 
							
								+		struct berval** bvals = ldap_get_values_len(ldap_con, m, attr);
							 | 
						||
| 
								 | 
							
								+		if (bvals && bvals[0] && bvals[0]->bv_len>0) {
							 | 
						||
| 
								 | 
							
								+			if (strcasecmp(attr, "dnstype")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%16s", zone->type)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->type[0] = '\0';
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsserial")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%lu", &zone->serial)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->serial = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsrefresh")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%lu", &zone->refresh)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->refresh = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsretry")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%lu", &zone->retry)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->retry = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsexpire")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%lu", &zone->expire)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->expire = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsminimum")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%lu", &zone->minimum)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->minimum = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsadminmailbox")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%64s", zone->adminmailbox)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->adminmailbox[0] = '\0';
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnszonemaster")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%64s", zone->zonemaster)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->zonemaster[0] = '\0';
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnsttl")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%d", &zone->ttl)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->ttl = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnstimestamp")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%d", &zone->timestamp)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->timestamp = 0;
							 | 
						||
| 
								 | 
							
								+			} else if (strcasecmp(attr, "dnszonename")==0) {
							 | 
						||
| 
								 | 
							
								+				if (sscanf(bvals[0]->bv_val, "%s", zone->zonename)!=1)
							 | 
						||
| 
								 | 
							
								+					zone->zonename[0] = '\0';
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		ldap_value_free_len(bvals);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+int find_ipaddr(const char* queryname, char ip[4])
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	static char *rrattrs[] = { "dnsipaddr", "dnscipaddr", 0 };
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* res = NULL;
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* m;
							 | 
						||
| 
								 | 
							
								+	int ret = 0;
							 | 
						||
| 
								 | 
							
								+	char filter[256], domainname[64];
							 | 
						||
| 
								 | 
							
								+	const char *zonename = queryname;
							 | 
						||
| 
								 | 
							
								+	domainname[0] = '\0';
							 | 
						||
| 
								 | 
							
								+	while (*zonename) {
							 | 
						||
| 
								 | 
							
								+		int len = snprintf(filter, 256, "(&(dnszonename=%s", zonename);
							 | 
						||
| 
								 | 
							
								+		if (filter[len-1]=='.')
							 | 
						||
| 
								 | 
							
								+			filter[len-1] = '\0';
							 | 
						||
| 
								 | 
							
								+	        strncat(filter, ")(objectclass=dnszone)(dnsclass=IN))", 256-len);
							 | 
						||
| 
								 | 
							
								+		assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+		if (m = ldap_first_entry(ldap_con, res)) {
							 | 
						||
| 
								 | 
							
								+			char* zonedn = ldap_get_dn(ldap_con, m);
							 | 
						||
| 
								 | 
							
								+			if (ldap_next_entry(ldap_con, m))
							 | 
						||
| 
								 | 
							
								+				printf("Warning: ambigous zonename for %s in %s\n", zonename, zonedn);
							 | 
						||
| 
								 | 
							
								+			if (domainname[0]!='\0') {
							 | 
						||
| 
								 | 
							
								+				len = strlen(domainname);
							 | 
						||
| 
								 | 
							
								+				if (domainname[len-1]=='.')
							 | 
						||
| 
								 | 
							
								+					domainname[len-1] = '\0';
							 | 
						||
| 
								 | 
							
								+				snprintf(filter, 256, "(&(|(dnsdomainname=%s)(dnscname=%s))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", domainname, domainname);
							 | 
						||
| 
								 | 
							
								+			} else {
							 | 
						||
| 
								 | 
							
								+				strcpy(filter, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))");
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+			assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+			if (m = ldap_first_entry(ldap_con, res)) {
							 | 
						||
| 
								 | 
							
								+				struct resourcerecord rr;
							 | 
						||
| 
								 | 
							
								+				fill_resourcerecord(&rr, m, "");
							 | 
						||
| 
								 | 
							
								+				if (rr.numipaddrs>0) {
							 | 
						||
| 
								 | 
							
								+					rr.numipaddrs = rand()%rr.numipaddrs;
							 | 
						||
| 
								 | 
							
								+					ip[0] = rr.ipaddr[rr.numipaddrs][0];
							 | 
						||
| 
								 | 
							
								+					ip[1] = rr.ipaddr[rr.numipaddrs][1];
							 | 
						||
| 
								 | 
							
								+					ip[2] = rr.ipaddr[rr.numipaddrs][2];
							 | 
						||
| 
								 | 
							
								+					ip[3] = rr.ipaddr[rr.numipaddrs][3];
							 | 
						||
| 
								 | 
							
								+					ret = 1;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			ldap_memfree(zonedn);
							 | 
						||
| 
								 | 
							
								+			ldap_msgfree(res); res = NULL;
							 | 
						||
| 
								 | 
							
								+			if (ret)
							 | 
						||
| 
								 | 
							
								+				return 1;
							 | 
						||
| 
								 | 
							
								+			break;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		while (*zonename && *zonename!='.') {
							 | 
						||
| 
								 | 
							
								+			domainname[zonename-queryname] = *zonename;
							 | 
						||
| 
								 | 
							
								+			zonename++;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		domainname[zonename-queryname] = *zonename;
							 | 
						||
| 
								 | 
							
								+		if (*zonename=='.') {
							 | 
						||
| 
								 | 
							
								+			zonename++;
							 | 
						||
| 
								 | 
							
								+			domainname[zonename-queryname] = '\0';
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	/* sometimes the queryname resolves directly as cname in some other records */
							 | 
						||
| 
								 | 
							
								+	snprintf(filter, 256, "(&(dnscname=%s)(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", queryname);
							 | 
						||
| 
								 | 
							
								+	assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+	if (m = ldap_first_entry(ldap_con, res)) {
							 | 
						||
| 
								 | 
							
								+		struct resourcerecord rr;
							 | 
						||
| 
								 | 
							
								+		fill_resourcerecord(&rr, m, "");
							 | 
						||
| 
								 | 
							
								+		if (rr.numipaddrs>0) {
							 | 
						||
| 
								 | 
							
								+			rr.numipaddrs = rand()%rr.numipaddrs;
							 | 
						||
| 
								 | 
							
								+			ip[0] = rr.ipaddr[rr.numipaddrs][0];
							 | 
						||
| 
								 | 
							
								+			ip[1] = rr.ipaddr[rr.numipaddrs][1];
							 | 
						||
| 
								 | 
							
								+			ip[2] = rr.ipaddr[rr.numipaddrs][2];
							 | 
						||
| 
								 | 
							
								+			ip[3] = rr.ipaddr[rr.numipaddrs][3];
							 | 
						||
| 
								 | 
							
								+			ret = 1;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+	return ret;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+struct resourcerecord* find_reverserecord(const char* queryname, int ip[4])
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	static char *rrattrs[] = { "dnstype", "dnsdomainname", "dnscname", "dnsttl", 0 };
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* res = NULL;
							 | 
						||
| 
								 | 
							
								+	struct resourcerecord* rr = NULL;
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* m;
							 | 
						||
| 
								 | 
							
								+	char filter[256];
							 | 
						||
| 
								 | 
							
								+	snprintf(filter, 256, "(&(dnscipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]);
							 | 
						||
| 
								 | 
							
								+	assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+	if (m = ldap_first_entry(ldap_con, res)) {
							 | 
						||
| 
								 | 
							
								+		char* rrsetdn = ldap_get_dn(ldap_con, m);
							 | 
						||
| 
								 | 
							
								+		char** explodedn = NULL;
							 | 
						||
| 
								 | 
							
								+		
							 | 
						||
| 
								 | 
							
								+		rr = (void*)alloc(sizeof(struct resourcerecord));
							 | 
						||
| 
								 | 
							
								+		fill_resourcerecord(rr, m, "");
							 | 
						||
| 
								 | 
							
								+		if (ldap_next_entry(ldap_con, m))
							 | 
						||
| 
								 | 
							
								+			printf("Warning: ambigous IP-address for %u.%u.%u.%u in dn: %s\n", ip[0], ip[1], ip[2], ip[3], rrsetdn);
							 | 
						||
| 
								 | 
							
								+		explodedn = ldap_explode_dn(rrsetdn, 0);
							 | 
						||
| 
								 | 
							
								+		if (explodedn[0]) {
							 | 
						||
| 
								 | 
							
								+			static char *zoneattrs[] = { "dnszonename", 0 };
							 | 
						||
| 
								 | 
							
								+			char zonedn[256];
							 | 
						||
| 
								 | 
							
								+			int i, len = 0;
							 | 
						||
| 
								 | 
							
								+			struct zonerecord zone;
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+			zonedn[0] = '\0';
							 | 
						||
| 
								 | 
							
								+			for (i = 1; explodedn[i]; i++)
							 | 
						||
| 
								 | 
							
								+				len += snprintf(zonedn+len, 256-len, "%s,", explodedn[i]);
							 | 
						||
| 
								 | 
							
								+			zonedn[len-1] = '\0';
							 | 
						||
| 
								 | 
							
								+			ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+			assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, "(objectclass=dnszone)", zoneattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+			m = ldap_first_entry(ldap_con, res);
							 | 
						||
| 
								 | 
							
								+			if (m==NULL)
							 | 
						||
| 
								 | 
							
								+				printf("Error: parent dn: %s not found for %s\n", zonedn, rrsetdn);
							 | 
						||
| 
								 | 
							
								+			fill_zonerecord(&zone, m);
							 | 
						||
| 
								 | 
							
								+			len = strlen(rr->qualifieddomainname);
							 | 
						||
| 
								 | 
							
								+			if (len==0) {
							 | 
						||
| 
								 | 
							
								+				len = strlen(rr->cname);
							 | 
						||
| 
								 | 
							
								+				if (rr->cname[len-1]!='.') {
							 | 
						||
| 
								 | 
							
								+					strcat(rr->cname, ".");
							 | 
						||
| 
								 | 
							
								+					strncat(rr->cname, zone.zonename, 252-len);
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			} else {
							 | 
						||
| 
								 | 
							
								+				/* in those situations where a dnsrrset
							 | 
						||
| 
								 | 
							
								+				 * defines something like MX or NS for a zone
							 | 
						||
| 
								 | 
							
								+				 * and also sets a canonical name for the
							 | 
						||
| 
								 | 
							
								+				 * service. */
							 | 
						||
| 
								 | 
							
								+				snprintf(rr->cname, 256, "%s.%s", rr->qualifieddomainname, zone.zonename);
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			strcpy(rr->type, "PTR");
							 | 
						||
| 
								 | 
							
								+			strncpy(rr->qualifieddomainname, queryname, 256);
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		ldap_memfree(rrsetdn);
							 | 
						||
| 
								 | 
							
								+		ldap_value_free(explodedn);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+	return rr;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+struct resourcerecord* read_domainrecords(const char* zonedn, const char* domainname, const char* zonename)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	static char *rrattrs[] = { "dnsdomainname", "dnstype", "dnsttl", "dnscname", "dnsipaddr", "dnscipaddr", "dnstimestamp", "dnspreference", 0 };
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* res = NULL;
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* m;
							 | 
						||
| 
								 | 
							
								+	char filter[256];
							 | 
						||
| 
								 | 
							
								+	struct resourcerecord *prev, *anchor = NULL;
							 | 
						||
| 
								 | 
							
								+	
							 | 
						||
| 
								 | 
							
								+	if (domainname[0]) {
							 | 
						||
| 
								 | 
							
								+		if (strstr(zonename, "in-addr.arpa")) {
							 | 
						||
| 
								 | 
							
								+			unsigned int ip[4];
							 | 
						||
| 
								 | 
							
								+			char queryname[256];
							 | 
						||
| 
								 | 
							
								+			snprintf(queryname, 256, "%s.%s", domainname, zonename);
							 | 
						||
| 
								 | 
							
								+			if (sscanf(queryname, "%3u.%3u.%3u.%3u", &ip[3], &ip[2], &ip[1], &ip[0])!=4)
							 | 
						||
| 
								 | 
							
								+				return NULL;
							 | 
						||
| 
								 | 
							
								+			snprintf(filter, 256, "(&(dnsipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]);
							 | 
						||
| 
								 | 
							
								+			assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+			if (m = ldap_first_entry(ldap_con, res)) {
							 | 
						||
| 
								 | 
							
								+				struct resourcerecord* rr;
							 | 
						||
| 
								 | 
							
								+				rr = (void*)alloc(sizeof(struct resourcerecord));
							 | 
						||
| 
								 | 
							
								+				fill_resourcerecord(rr, m, zonename);
							 | 
						||
| 
								 | 
							
								+				strncpy(rr->qualifieddomainname, queryname, 256);
							 | 
						||
| 
								 | 
							
								+				ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+				return rr;
							 | 
						||
| 
								 | 
							
								+			} else {
							 | 
						||
| 
								 | 
							
								+				/* ipaddr not in our baliwick, search the whole tree for canonical ipaddr */
							 | 
						||
| 
								 | 
							
								+				ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+				return find_reverserecord(queryname, ip);
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		} else {
							 | 
						||
| 
								 | 
							
								+			int i;
							 | 
						||
| 
								 | 
							
								+			for (i = 0; domainname[i]; i++) {
							 | 
						||
| 
								 | 
							
								+				snprintf(filter, 256, (i==0 ? "(&(dnsdomainname=%s)(objectclass=dnsrrset)(dnsclass=IN))" :
							 | 
						||
| 
								 | 
							
								+				    "(&(dnsdomainname=\\*.%s)(objectclass=dnsrrset)(dnsclass=IN))"), &domainname[i]);
							 | 
						||
| 
								 | 
							
								+				assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+				if (ldap_count_entries(ldap_con, res)>0)
							 | 
						||
| 
								 | 
							
								+					break;
							 | 
						||
| 
								 | 
							
								+				while (domainname[i] && domainname[i]!='.')
							 | 
						||
| 
								 | 
							
								+				       i++;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	} else {
							 | 
						||
| 
								 | 
							
								+		snprintf(filter, 256, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN))");
							 | 
						||
| 
								 | 
							
								+		assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) {
							 | 
						||
| 
								 | 
							
								+		struct resourcerecord* rr;
							 | 
						||
| 
								 | 
							
								+		rr = (void*)alloc(sizeof(struct resourcerecord));
							 | 
						||
| 
								 | 
							
								+		fill_resourcerecord(rr, m, zonename);
							 | 
						||
| 
								 | 
							
								+		snprintf(rr->qualifieddomainname, 256, "%s%s%s", domainname, domainname[0] ? "." : "", zonename);
							 | 
						||
| 
								 | 
							
								+		if (anchor==NULL) {
							 | 
						||
| 
								 | 
							
								+			prev = anchor = rr;
							 | 
						||
| 
								 | 
							
								+		} else {
							 | 
						||
| 
								 | 
							
								+			prev->next = rr;
							 | 
						||
| 
								 | 
							
								+			prev = rr;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		if (options.verbose&1)
							 | 
						||
| 
								 | 
							
								+			printf("\trr: %s %s\n", domainname, rr->type);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+	return anchor;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+int read_dnszone(struct zonerecord* zone, const char* zonename)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	static char *zoneattrs[] = { "dnszonename", "dnstype", "dnsserial", "dnsrefresh", "dnsretry", "dnsexpire", "dnsminimum", "dnszonemaster", "dnsadminmailbox", "dnsttl", "dnstimestamp", 0 };
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* res = NULL;
							 | 
						||
| 
								 | 
							
								+	LDAPMessage* m;
							 | 
						||
| 
								 | 
							
								+	char* dn;
							 | 
						||
| 
								 | 
							
								+	char filter[256];
							 | 
						||
| 
								 | 
							
								+	
							 | 
						||
| 
								 | 
							
								+	snprintf(filter, 256, "(&(dnszonename=%s)(objectclass=dnszone)(dnsclass=IN))", zonename);
							 | 
						||
| 
								 | 
							
								+	assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, zoneattrs, 0, &options.timeout, &res));
							 | 
						||
| 
								 | 
							
								+	m = ldap_first_entry(ldap_con, res);
							 | 
						||
| 
								 | 
							
								+	if (m==NULL) {
							 | 
						||
| 
								 | 
							
								+		ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+		return 0;
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	dn = ldap_get_dn(ldap_con, m);
							 | 
						||
| 
								 | 
							
								+	fill_zonerecord(zone, m);
							 | 
						||
| 
								 | 
							
								+	m = ldap_next_entry(ldap_con, m);
							 | 
						||
| 
								 | 
							
								+	if (m) {
							 | 
						||
| 
								 | 
							
								+		char* otherdn = ldap_get_dn(ldap_con, m);
							 | 
						||
| 
								 | 
							
								+		printf("Warning: ambigous zonename found in dn: %s and dn: %s\n", dn, otherdn);
							 | 
						||
| 
								 | 
							
								+		ldap_memfree(otherdn);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	strncpy(zone->zonedn, dn, 256);
							 | 
						||
| 
								 | 
							
								+	ldap_memfree(dn);
							 | 
						||
| 
								 | 
							
								+	ldap_msgfree(res);
							 | 
						||
| 
								 | 
							
								+	return 1;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void djb_name(const char* dotname, char* djbname)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	const char* c = dotname;
							 | 
						||
| 
								 | 
							
								+	int i, k;
							 | 
						||
| 
								 | 
							
								+	for (i = 0; *c; c++) {
							 | 
						||
| 
								 | 
							
								+		k = i;
							 | 
						||
| 
								 | 
							
								+		while (*c!='.') {
							 | 
						||
| 
								 | 
							
								+			k++;
							 | 
						||
| 
								 | 
							
								+			djbname[k] = *c;
							 | 
						||
| 
								 | 
							
								+			if (*c=='\0') {
							 | 
						||
| 
								 | 
							
								+				djbname[i] = k-i-1;
							 | 
						||
| 
								 | 
							
								+				return;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			c++;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		djbname[i] = k-i;
							 | 
						||
| 
								 | 
							
								+		i = k+1;
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	djbname[i] = '\0';
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void djb_type(const char* dottype, char djbtype[2])
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	djbtype[0] = '\0';
							 | 
						||
| 
								 | 
							
								+	if (strcasecmp(dottype, "A")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 001;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "NS")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 002;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "CNAME")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 005;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "SOA")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 006;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "PTR")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 014;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "MX")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 017;
							 | 
						||
| 
								 | 
							
								+	else if (strcasecmp(dottype, "TXT")==0)
							 | 
						||
| 
								 | 
							
								+		djbtype[1] = 020;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void split_djbstyle(const char* djbname, char* domainname, char* zonename, int offset)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	int i, k, m = 0, n = 0;
							 | 
						||
| 
								 | 
							
								+	for (i = *djbname; i; i = *++djbname) {
							 | 
						||
| 
								 | 
							
								+		if (offset>0) {
							 | 
						||
| 
								 | 
							
								+			offset--;
							 | 
						||
| 
								 | 
							
								+			for (k = m; k<m+i; k++) {
							 | 
						||
| 
								 | 
							
								+				domainname[k] = *++djbname;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			domainname[k] = '.';
							 | 
						||
| 
								 | 
							
								+			m = k+1;
							 | 
						||
| 
								 | 
							
								+		} else {
							 | 
						||
| 
								 | 
							
								+			for (k = n; k<n+i; k++) {
							 | 
						||
| 
								 | 
							
								+				zonename[k] = *++djbname;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			zonename[k] = '.';
							 | 
						||
| 
								 | 
							
								+			n = k+1;
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	domainname[m>0 ? m-1 : 0] = '\0';
							 | 
						||
| 
								 | 
							
								+	zonename[n>0 ? n-1 : 0] = '\0';
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void build_response_section(struct resourcerecord *rr, char qtype[2], int section)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	char djbname[256], djbtype[2];
							 | 
						||
| 
								 | 
							
								+	djb_name(rr->qualifieddomainname, djbname);
							 | 
						||
| 
								 | 
							
								+	djb_type(rr->type, djbtype);
							 | 
						||
| 
								 | 
							
								+	if (byte_equal(djbtype, 2, DNS_T_A)) {
							 | 
						||
| 
								 | 
							
								+		if (byte_equal(qtype, 2, DNS_T_A) || byte_equal(qtype, 2, DNS_T_ANY)) {
							 | 
						||
| 
								 | 
							
								+			response_rstart(djbname, djbtype, rr->ttl);
							 | 
						||
| 
								 | 
							
								+			response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4);
							 | 
						||
| 
								 | 
							
								+			response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	} else if (byte_equal(djbtype, 2, DNS_T_CNAME)) {
							 | 
						||
| 
								 | 
							
								+		response_rstart(djbname, djbtype, rr->ttl);
							 | 
						||
| 
								 | 
							
								+		djb_name(rr->cname, djbname);
							 | 
						||
| 
								 | 
							
								+		response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+		response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+	} else if (byte_equal(djbtype, 2, DNS_T_NS)) {
							 | 
						||
| 
								 | 
							
								+		if (byte_equal(qtype, 2, DNS_T_NS) || byte_equal(qtype, 2, DNS_T_ANY)) {
							 | 
						||
| 
								 | 
							
								+			response_rstart(djbname, djbtype, rr->ttl);
							 | 
						||
| 
								 | 
							
								+			if (rr->cname[0]) {
							 | 
						||
| 
								 | 
							
								+				djb_name(rr->cname, djbname);
							 | 
						||
| 
								 | 
							
								+				response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+				rr->additionalinfo = 1;
							 | 
						||
| 
								 | 
							
								+			} else {
							 | 
						||
| 
								 | 
							
								+				response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4);
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	} else if (byte_equal(djbtype, 2, DNS_T_PTR)) {
							 | 
						||
| 
								 | 
							
								+		response_rstart(djbname, djbtype, rr->ttl);
							 | 
						||
| 
								 | 
							
								+		djb_name(rr->cname, djbname);
							 | 
						||
| 
								 | 
							
								+		response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+		response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+	} else if (byte_equal(djbtype, 2, DNS_T_MX)) {
							 | 
						||
| 
								 | 
							
								+		if (byte_equal(qtype, 2, DNS_T_MX) || byte_equal(qtype, 2, DNS_T_ANY)) {
							 | 
						||
| 
								 | 
							
								+			char tmp[2];
							 | 
						||
| 
								 | 
							
								+			response_rstart(djbname, djbtype, rr->ttl);
							 | 
						||
| 
								 | 
							
								+			tmp[0] = rr->preference/0x100;
							 | 
						||
| 
								 | 
							
								+			tmp[1] = rr->preference%0x100;
							 | 
						||
| 
								 | 
							
								+			response_addbytes(tmp, 2);
							 | 
						||
| 
								 | 
							
								+			if (rr->cname[0]) {
							 | 
						||
| 
								 | 
							
								+				djb_name(rr->cname, djbname);
							 | 
						||
| 
								 | 
							
								+				response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+				rr->additionalinfo = 1;
							 | 
						||
| 
								 | 
							
								+			} else {
							 | 
						||
| 
								 | 
							
								+				response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4);
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void build_soa_section(struct zonerecord *zone, int section)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	time_t now;
							 | 
						||
| 
								 | 
							
								+	char defaultsoa[20];
							 | 
						||
| 
								 | 
							
								+	char djbname[256];
							 | 
						||
| 
								 | 
							
								+	char zonesoa[20];
							 | 
						||
| 
								 | 
							
								+	unsigned long tmp;
							 | 
						||
| 
								 | 
							
								+	time(&now);
							 | 
						||
| 
								 | 
							
								+	djb_name(zone->zonename, djbname);
							 | 
						||
| 
								 | 
							
								+	response_rstart(djbname, DNS_T_SOA, zone->ttl);
							 | 
						||
| 
								 | 
							
								+	djb_name(zone->zonemaster, djbname);
							 | 
						||
| 
								 | 
							
								+	response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+	djb_name(zone->adminmailbox, djbname);
							 | 
						||
| 
								 | 
							
								+	response_addname(djbname);
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(defaultsoa, now);
							 | 
						||
| 
								 | 
							
								+	if (byte_equal(defaultsoa,4,"\0\0\0\0"))
							 | 
						||
| 
								 | 
							
								+	defaultsoa[3] = 1;
							 | 
						||
| 
								 | 
							
								+	byte_copy(defaultsoa + 4, 16, "\0\0\100\000\0\0\010\000\0\020\000\000\0\0\012\000");
							 | 
						||
| 
								 | 
							
								+	if (zone->serial==0)
							 | 
						||
| 
								 | 
							
								+		uint32_unpack_big(defaultsoa, &tmp);
							 | 
						||
| 
								 | 
							
								+	else
							 | 
						||
| 
								 | 
							
								+		tmp = zone->serial;
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(zonesoa, tmp);
							 | 
						||
| 
								 | 
							
								+	if (zone->refresh==0)
							 | 
						||
| 
								 | 
							
								+		uint32_unpack_big(defaultsoa+4, &tmp);
							 | 
						||
| 
								 | 
							
								+	else
							 | 
						||
| 
								 | 
							
								+		tmp = zone->refresh;
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(zonesoa+4, tmp);
							 | 
						||
| 
								 | 
							
								+	if (zone->retry==0)
							 | 
						||
| 
								 | 
							
								+		uint32_unpack_big(defaultsoa+8, &tmp);
							 | 
						||
| 
								 | 
							
								+	else
							 | 
						||
| 
								 | 
							
								+		tmp = zone->retry;
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(zonesoa+8, tmp);
							 | 
						||
| 
								 | 
							
								+	if (zone->expire==0)
							 | 
						||
| 
								 | 
							
								+		uint32_unpack_big(defaultsoa+12, &tmp);
							 | 
						||
| 
								 | 
							
								+	else
							 | 
						||
| 
								 | 
							
								+		tmp = zone->expire;
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(zonesoa+12, tmp);
							 | 
						||
| 
								 | 
							
								+	if (zone->minimum==0)
							 | 
						||
| 
								 | 
							
								+		uint32_unpack_big(defaultsoa+16, &tmp);
							 | 
						||
| 
								 | 
							
								+	else
							 | 
						||
| 
								 | 
							
								+		tmp = zone->minimum;
							 | 
						||
| 
								 | 
							
								+	uint32_pack_big(zonesoa+16, tmp);
							 | 
						||
| 
								 | 
							
								+	response_addbytes(zonesoa, 20);
							 | 
						||
| 
								 | 
							
								+	response_rfinish(section);
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+void build_additional_section(struct resourcerecord *rr)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	char djbname[256], ip[4];
							 | 
						||
| 
								 | 
							
								+	if (rr->additionalinfo && find_ipaddr(rr->cname, ip)) {
							 | 
						||
| 
								 | 
							
								+		djb_name(rr->cname, djbname);
							 | 
						||
| 
								 | 
							
								+		response_rstart(djbname, DNS_T_A, rr->ttl);
							 | 
						||
| 
								 | 
							
								+		response_addbytes(ip, 4);
							 | 
						||
| 
								 | 
							
								+		response_rfinish(RESPONSE_ADDITIONAL);
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+static
							 | 
						||
| 
								 | 
							
								+int connect_and_bind()
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	ldap_con = ldap_init(options.ldaphosts, LDAP_PORT);
							 | 
						||
| 
								 | 
							
								+	if (ldap_simple_bind_s(ldap_con, options.binddn, options.bindpwd)==LDAP_SUCCESS) {
							 | 
						||
| 
								 | 
							
								+		printf("Connected to %s as \"%s\"\n", options.ldaphosts, options.binddn);
							 | 
						||
| 
								 | 
							
								+		return 1;
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	ldap_con = NULL;
							 | 
						||
| 
								 | 
							
								+	return 0;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+int askldap_query(const char* djbdomainname, char qtype[2])
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	int offset;
							 | 
						||
| 
								 | 
							
								+	char domainname[64], zonename[64];
							 | 
						||
| 
								 | 
							
								+	struct zonerecord zoneinfo;
							 | 
						||
| 
								 | 
							
								+	int answer_ok = 0, flagsoa = 0, flagns = 0;
							 | 
						||
| 
								 | 
							
								+	if (!options.initialized)
							 | 
						||
| 
								 | 
							
								+		return 0;
							 | 
						||
| 
								 | 
							
								+	switch (sigsetjmp(stack_context, 1)) {
							 | 
						||
| 
								 | 
							
								+	    default:
							 | 
						||
| 
								 | 
							
								+		    if (ldap_con==NULL && !connect_and_bind())
							 | 
						||
| 
								 | 
							
								+		    	return answer_ok;
							 | 
						||
| 
								 | 
							
								+		    break;
							 | 
						||
| 
								 | 
							
								+	    case ASKLDAP_RECONNECT:
							 | 
						||
| 
								 | 
							
								+		    if (connect_and_bind())
							 | 
						||
| 
								 | 
							
								+			    break;
							 | 
						||
| 
								 | 
							
								+		    return answer_ok;
							 | 
						||
| 
								 | 
							
								+	    case ASKLDAP_RETURN:
							 | 
						||
| 
								 | 
							
								+		    return answer_ok;
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	for (offset = 0; offset<32; offset++) {
							 | 
						||
| 
								 | 
							
								+		struct resourcerecord *rransw, *rrauth, *rr;
							 | 
						||
| 
								 | 
							
								+		
							 | 
						||
| 
								 | 
							
								+		split_djbstyle(djbdomainname, domainname, zonename, offset);
							 | 
						||
| 
								 | 
							
								+		if (zonename[0]=='\0') return 0;
							 | 
						||
| 
								 | 
							
								+		if (!read_dnszone(&zoneinfo, zonename))
							 | 
						||
| 
								 | 
							
								+			continue;
							 | 
						||
| 
								 | 
							
								+		rransw = read_domainrecords(zoneinfo.zonedn, domainname, zonename);
							 | 
						||
| 
								 | 
							
								+		rrauth = NULL;
							 | 
						||
| 
								 | 
							
								+		if (offset==0) {
							 | 
						||
| 
								 | 
							
								+			/* query is in our bailiwick */
							 | 
						||
| 
								 | 
							
								+			if (byte_equal(qtype, 2, DNS_T_ANY) || byte_equal(qtype, 2, DNS_T_SOA)) {
							 | 
						||
| 
								 | 
							
								+				build_soa_section(&zoneinfo, RESPONSE_ANSWER);
							 | 
						||
| 
								 | 
							
								+				flagsoa = 1;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			for (rr = rransw; rr; rr = rr->next) {
							 | 
						||
| 
								 | 
							
								+				build_response_section(rr, qtype, RESPONSE_ANSWER);
							 | 
						||
| 
								 | 
							
								+				answer_ok = 1;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			if (!flagsoa) {
							 | 
						||
| 
								 | 
							
								+				build_soa_section(&zoneinfo, RESPONSE_AUTHORITY);
							 | 
						||
| 
								 | 
							
								+				flagsoa = 1;
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			if (!byte_equal(qtype, 2, DNS_T_ANY) && !byte_equal(qtype, 2, DNS_T_NS)) {
							 | 
						||
| 
								 | 
							
								+				for (rr = rransw; rr; rr = rr->next)
							 | 
						||
| 
								 | 
							
								+					if (strcmp(rr->type, "NS")==0) {
							 | 
						||
| 
								 | 
							
								+						build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY);
							 | 
						||
| 
								 | 
							
								+						flagns = 1;
							 | 
						||
| 
								 | 
							
								+					}
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		} else {
							 | 
						||
| 
								 | 
							
								+			for (rr = rransw; rr; rr = rr->next) {
							 | 
						||
| 
								 | 
							
								+				if (strcmp(rr->type, "NS")==0) {
							 | 
						||
| 
								 | 
							
								+					build_response_section(rr, qtype, RESPONSE_AUTHORITY);
							 | 
						||
| 
								 | 
							
								+					flagns = 1;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			if (!flagns) {
							 | 
						||
| 
								 | 
							
								+				for (rr = rransw; rr; rr = rr->next) {
							 | 
						||
| 
								 | 
							
								+					build_response_section(rr, qtype, RESPONSE_ANSWER);
							 | 
						||
| 
								 | 
							
								+					answer_ok = 1;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+				if (answer_ok) {
							 | 
						||
| 
								 | 
							
								+					rrauth = read_domainrecords(zoneinfo.zonedn, "", zonename);
							 | 
						||
| 
								 | 
							
								+				} else {
							 | 
						||
| 
								 | 
							
								+					build_soa_section(&zoneinfo, RESPONSE_AUTHORITY);
							 | 
						||
| 
								 | 
							
								+					flagsoa = 1;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+			for (rr = rrauth; rr; rr = rr->next) {
							 | 
						||
| 
								 | 
							
								+				if (strcmp(rr->type, "NS")==0) {
							 | 
						||
| 
								 | 
							
								+					build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY);
							 | 
						||
| 
								 | 
							
								+					flagns = 1;
							 | 
						||
| 
								 | 
							
								+				}
							 | 
						||
| 
								 | 
							
								+			}
							 | 
						||
| 
								 | 
							
								+		}
							 | 
						||
| 
								 | 
							
								+		for (rr = rransw; rr; rr = rr->next)
							 | 
						||
| 
								 | 
							
								+			build_additional_section(rr);
							 | 
						||
| 
								 | 
							
								+		for (rr = rrauth; rr; rr = rr->next)
							 | 
						||
| 
								 | 
							
								+			build_additional_section(rr);
							 | 
						||
| 
								 | 
							
								+		free_domainrecords(rransw);
							 | 
						||
| 
								 | 
							
								+		free_domainrecords(rrauth);
							 | 
						||
| 
								 | 
							
								+		break;
							 | 
						||
| 
								 | 
							
								+	}
							 | 
						||
| 
								 | 
							
								+	return answer_ok || flagsoa || flagns;
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd)
							 | 
						||
| 
								 | 
							
								+{
							 | 
						||
| 
								 | 
							
								+	strncpy(options.ldaphosts, ldaphost, 256);
							 | 
						||
| 
								 | 
							
								+	options.basedn = basedn;
							 | 
						||
| 
								 | 
							
								+	if (binddn) strncpy(options.binddn, binddn, 256);
							 | 
						||
| 
								 | 
							
								+	if (passwd) strncpy(options.bindpwd, passwd, 16);
							 | 
						||
| 
								 | 
							
								+	/* LDAP timeout is hardcoded to 2/10 second.
							 | 
						||
| 
								 | 
							
								+	 * This must be enough because bindoperations usually
							 | 
						||
| 
								 | 
							
								+	 * timeout after one second and here we usually have to
							 | 
						||
| 
								 | 
							
								+	 * send five queries to the LDAP-server */
							 | 
						||
| 
								 | 
							
								+	options.timeout.tv_sec = 1;
							 | 
						||
| 
								 | 
							
								+	options.timeout.tv_usec = 200000;
							 | 
						||
| 
								 | 
							
								+	options.verbose = 0;
							 | 
						||
| 
								 | 
							
								+	options.initialized = 1;
							 | 
						||
| 
								 | 
							
								+	connect_and_bind();
							 | 
						||
| 
								 | 
							
								+}
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/askldap.h djbdns-1.05/askldap.h
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/askldap.h	Thu Jan  1 01:00:00 1970
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/askldap.h	Tue Aug 13 14:30:22 2002
							 | 
						||
| 
								 | 
							
								@@ -0,0 +1,10 @@
							 | 
						||
| 
								 | 
							
								+/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup.
							 | 
						||
| 
								 | 
							
								+ * $Id$
							 | 
						||
| 
								 | 
							
								+ * Copyright 2002 <jacob.rief@tiscover.com> 
							 | 
						||
| 
								 | 
							
								+ */ 
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								+extern
							 | 
						||
| 
								 | 
							
								+int askldap_query(const char* djbdomainname, char qtype[2]);
							 | 
						||
| 
								 | 
							
								+	
							 | 
						||
| 
								 | 
							
								+extern
							 | 
						||
| 
								 | 
							
								+void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd);
							 | 
						||
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/ldap.lib djbdns-1.05/ldap.lib
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/ldap.lib	Thu Jan  1 01:00:00 1970
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/ldap.lib	Tue Aug 13 14:29:53 2002
							 | 
						||
| 
								 | 
							
								@@ -0,0 +1 @@
							 | 
						||
| 
								 | 
							
								+-lldap -llber
							 | 
						||
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/server.c djbdns-1.05/server.c
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/server.c	Sun Feb 11 22:11:45 2001
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/server.c	Tue Aug 13 14:29:15 2002
							 | 
						||
| 
								 | 
							
								@@ -11,6 +11,7 @@
							 | 
						||
| 
								 | 
							
								 #include "qlog.h"
							 | 
						||
| 
								 | 
							
								 #include "response.h"
							 | 
						||
| 
								 | 
							
								 #include "dns.h"
							 | 
						||
| 
								 | 
							
								+#include "askldap.h"
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 extern char *fatal;
							 | 
						||
| 
								 | 
							
								 extern char *starting;
							 | 
						||
| 
								 | 
							
								@@ -79,6 +80,7 @@
							 | 
						||
| 
								 | 
							
								   return 0;
							 | 
						||
| 
								 | 
							
								 }
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								+
							 | 
						||
| 
								 | 
							
								 int main()
							 | 
						||
| 
								 | 
							
								 {
							 | 
						||
| 
								 | 
							
								   char *x;
							 | 
						||
| 
								 | 
							
								@@ -90,6 +92,19 @@
							 | 
						||
| 
								 | 
							
								   if (!ip4_scan(x,ip))
							 | 
						||
| 
								 | 
							
								     strerr_die3x(111,fatal,"unable to parse IP address ",x);
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								+  x = env_get("LDAPHOSTS");
							 | 
						||
| 
								 | 
							
								+  if (x) {
							 | 
						||
| 
								 | 
							
								+    char *basedn = env_get("LDAPBASEDN");
							 | 
						||
| 
								 | 
							
								+    char *binddn = env_get("LDAPBINDDN");
							 | 
						||
| 
								 | 
							
								+    char *bindpwd = env_get("LDAPPASSWD");
							 | 
						||
| 
								 | 
							
								+    if (basedn)
							 | 
						||
| 
								 | 
							
								+      askldap_init(x, basedn, binddn, bindpwd);
							 | 
						||
| 
								 | 
							
								+    if (bindpwd) {
							 | 
						||
| 
								 | 
							
								+      int len = str_len(bindpwd);
							 | 
						||
| 
								 | 
							
								+      while (len) bindpwd[--len] = 'x';
							 | 
						||
| 
								 | 
							
								+    }
							 | 
						||
| 
								 | 
							
								+  }
							 | 
						||
| 
								 | 
							
								+  
							 | 
						||
| 
								 | 
							
								   udp53 = socket_udp();
							 | 
						||
| 
								 | 
							
								   if (udp53 == -1)
							 | 
						||
| 
								 | 
							
								     strerr_die2sys(111,fatal,"unable to create UDP socket: ");
							 | 
						||
| 
								 | 
							
								diff -Naur djbdns-1.05.orig/tdlookup.c djbdns-1.05/tdlookup.c
							 | 
						||
| 
								 | 
							
								--- djbdns-1.05.orig/tdlookup.c	Sun Feb 11 22:11:45 2001
							 | 
						||
| 
								 | 
							
								+++ djbdns-1.05/tdlookup.c	Tue Aug 13 14:29:29 2002
							 | 
						||
| 
								 | 
							
								@@ -8,6 +8,7 @@
							 | 
						||
| 
								 | 
							
								 #include "dns.h"
							 | 
						||
| 
								 | 
							
								 #include "seek.h"
							 | 
						||
| 
								 | 
							
								 #include "response.h"
							 | 
						||
| 
								 | 
							
								+#include "askldap.h"
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								 static int want(const char *owner,const char type[2])
							 | 
						||
| 
								 | 
							
								 {
							 | 
						||
| 
								 | 
							
								@@ -285,10 +286,13 @@
							 | 
						||
| 
								 | 
							
								   char key[6];
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								   tai_now(&now);
							 | 
						||
| 
								 | 
							
								+  if (askldap_query(q, qtype))
							 | 
						||
| 
								 | 
							
								+    return 1;
							 | 
						||
| 
								 | 
							
								+  
							 | 
						||
| 
								 | 
							
								   fd = open_read("data.cdb");
							 | 
						||
| 
								 | 
							
								   if (fd == -1) return 0;
							 | 
						||
| 
								 | 
							
								   cdb_init(&c,fd);
							 | 
						||
| 
								 | 
							
								-
							 | 
						||
| 
								 | 
							
								+  
							 | 
						||
| 
								 | 
							
								   byte_zero(clientloc,2);
							 | 
						||
| 
								 | 
							
								   key[0] = 0;
							 | 
						||
| 
								 | 
							
								   key[1] = '%';
							 |