summaryrefslogtreecommitdiffstats
path: root/bind-9.3.2b1-fix_sdb_ldap.patch
diff options
context:
space:
mode:
authorjvdias <jvdias@fedoraproject.org>2005-12-03 00:10:48 +0000
committerjvdias <jvdias@fedoraproject.org>2005-12-03 00:10:48 +0000
commit207484f5d447b8b291e04a7304b16a997e71d10b (patch)
tree2bb48a2298a167f8c6b8f71ff377153a6a111a69 /bind-9.3.2b1-fix_sdb_ldap.patch
parent4330327e1c004d36d1579066590ba21364239a04 (diff)
downloadbind-207484f5d447b8b291e04a7304b16a997e71d10b.tar.gz
bind-207484f5d447b8b291e04a7304b16a997e71d10b.tar.xz
bind-207484f5d447b8b291e04a7304b16a997e71d10b.zip
Upgrade to 9.3.2rc1
Diffstat (limited to 'bind-9.3.2b1-fix_sdb_ldap.patch')
-rw-r--r--bind-9.3.2b1-fix_sdb_ldap.patch922
1 files changed, 922 insertions, 0 deletions
diff --git a/bind-9.3.2b1-fix_sdb_ldap.patch b/bind-9.3.2b1-fix_sdb_ldap.patch
new file mode 100644
index 0000000..6768b30
--- /dev/null
+++ b/bind-9.3.2b1-fix_sdb_ldap.patch
@@ -0,0 +1,922 @@
+--- /dev/null 2005-10-06 11:34:58.093275500 -0400
++++ bind-9.3.2b1/bin/sdb_tools/ldap2zone.c 2005-10-06 18:57:32.000000000 -0400
+@@ -0,0 +1,397 @@
++/*
++ * Copyright (C) 2004, 2005 Stig Venaas <venaas@uninett.no>
++ * $Id: ldap2zone.c,v 0.1 2005/04/23 21:30:12 venaas Exp $
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ */
++
++#include <sys/types.h>
++#include <stdio.h>
++
++#include <ldap.h>
++
++struct string {
++ void *data;
++ size_t len;
++};
++
++struct assstack_entry {
++ struct string key;
++ struct string val;
++ struct assstack_entry *next;
++};
++
++struct assstack_entry *assstack_find(struct assstack_entry *stack, struct string *key) {
++ for (; stack; stack = stack->next)
++ if (stack->key.len == key->len && !memcmp(stack->key.data, key->data, key->len))
++ return stack;
++ return NULL;
++}
++
++void assstack_push(struct assstack_entry **stack, struct assstack_entry *item) {
++ item->next = *stack;
++ *stack = item;
++}
++
++void assstack_insertbottom(struct assstack_entry **stack, struct assstack_entry *item) {
++ struct assstack_entry *p;
++
++ item->next = NULL;
++ if (!*stack) {
++ *stack = item;
++ return;
++ }
++ /* find end, should keep track of end somewhere */
++ /* really a queue, not a stack */
++ p = *stack;
++ while (p->next)
++ p = p->next;
++ p->next = item;
++}
++
++void printsoa(struct string *soa) {
++ char *s;
++ int i;
++
++ s = (char *)soa->data;
++ i = 0;
++ while (i < soa->len) {
++ putchar(s[i]);
++ if (s[i++] == ' ')
++ break;
++ }
++ while (i < soa->len) {
++ putchar(s[i]);
++ if (s[i++] == ' ')
++ break;
++ }
++ printf("(\n\t\t\t\t");
++ while (i < soa->len) {
++ putchar(s[i]);
++ if (s[i++] == ' ')
++ break;
++ }
++ printf("; Serialnumber\n\t\t\t\t");
++ while (i < soa->len) {
++ if (s[i] == ' ')
++ break;
++ putchar(s[i++]);
++ }
++ i++;
++ printf("\t; Refresh\n\t\t\t\t");
++ while (i < soa->len) {
++ if (s[i] == ' ')
++ break;
++ putchar(s[i++]);
++ }
++ i++;
++ printf("\t; Retry\n\t\t\t\t");
++ while (i < soa->len) {
++ if (s[i] == ' ')
++ break;
++ putchar(s[i++]);
++ }
++ i++;
++ printf("\t; Expire\n\t\t\t\t");
++ while (i < soa->len) {
++ putchar(s[i++]);
++ }
++ printf(" )\t; Minimum TTL\n");
++}
++
++void printrrs(char *defaultttl, struct assstack_entry *item) {
++ struct assstack_entry *stack;
++ char *s;
++ int first;
++ int i;
++ char *ttl, *type;
++ int top;
++
++ s = (char *)item->key.data;
++
++ if (item->key.len == 1 && *s == '@') {
++ top = 1;
++ printf("@\t");
++ } else {
++ top = 0;
++ for (i = 0; i < item->key.len; i++)
++ putchar(s[i]);
++ if (item->key.len < 8)
++ putchar('\t');
++ putchar('\t');
++ }
++
++ first = 1;
++ for (stack = (struct assstack_entry *) item->val.data; stack; stack = stack->next) {
++ ttl = (char *)stack->key.data;
++ s = strchr(ttl, ' ');
++ *s++ = '\0';
++ type = s;
++
++ if (first)
++ first = 0;
++ else
++ printf("\t\t");
++
++ if (strcmp(defaultttl, ttl))
++ printf("%s", ttl);
++ putchar('\t');
++
++ if (top) {
++ top = 0;
++ printf("IN\t%s\t", type);
++ /* Should always be SOA here */
++ if (!strcmp(type, "SOA")) {
++ printsoa(&stack->val);
++ continue;
++ }
++ } else
++ printf("%s\t", type);
++
++ s = (char *)stack->val.data;
++ for (i = 0; i < stack->val.len; i++)
++ putchar(s[i]);
++ putchar('\n');
++ }
++}
++
++void print_zone(char *defaultttl, struct assstack_entry *stack) {
++ printf("$TTL %s\n", defaultttl);
++ for (; stack; stack = stack->next)
++ printrrs(defaultttl, stack);
++};
++
++void usage(char *name) {
++ fprintf(stderr, "Usage:%s zone-name LDAP-URL default-ttl [serial]\n", name);
++ exit(1);
++};
++
++void err(char *name, char *msg) {
++ fprintf(stderr, "%s: %s\n", name, msg);
++ exit(1);
++};
++
++int putrr(struct assstack_entry **stack, struct berval *name, char *type, char *ttl, struct berval *val) {
++ struct string key;
++ struct assstack_entry *rr, *rrdata;
++
++ /* Do nothing if name or value have 0 length */
++ if (!name->bv_len || !val->bv_len)
++ return 0;
++
++ /* see if already have an entry for this name */
++ key.len = name->bv_len;
++ key.data = name->bv_val;
++
++ rr = assstack_find(*stack, &key);
++ if (!rr) {
++ /* Not found, create and push new entry */
++ rr = (struct assstack_entry *) malloc(sizeof(struct assstack_entry));
++ if (!rr)
++ return -1;
++ rr->key.len = name->bv_len;
++ rr->key.data = (void *) malloc(rr->key.len);
++ if (!rr->key.data) {
++ free(rr);
++ return -1;
++ }
++ memcpy(rr->key.data, name->bv_val, name->bv_len);
++ rr->val.len = sizeof(void *);
++ rr->val.data = NULL;
++ if (name->bv_len == 1 && *(char *)name->bv_val == '@')
++ assstack_push(stack, rr);
++ else
++ assstack_insertbottom(stack, rr);
++ }
++
++ rrdata = (struct assstack_entry *) malloc(sizeof(struct assstack_entry));
++ if (!rrdata) {
++ free(rr->key.data);
++ free(rr);
++ return -1;
++ }
++ rrdata->key.len = strlen(type) + strlen(ttl) + 1;
++ rrdata->key.data = (void *) malloc(rrdata->key.len);
++ if (!rrdata->key.data) {
++ free(rrdata);
++ free(rr->key.data);
++ free(rr);
++ return -1;
++ }
++ sprintf((char *)rrdata->key.data, "%s %s", ttl, type);
++
++ rrdata->val.len = val->bv_len;
++ rrdata->val.data = (void *) malloc(val->bv_len);
++ if (!rrdata->val.data) {
++ free(rrdata->key.data);
++ free(rrdata);
++ free(rr->key.data);
++ free(rr);
++ return -1;
++ }
++ memcpy(rrdata->val.data, val->bv_val, val->bv_len);
++
++ if (!strcmp(type, "SOA"))
++ assstack_push((struct assstack_entry **) &(rr->val.data), rrdata);
++ else
++ assstack_insertbottom((struct assstack_entry **) &(rr->val.data), rrdata);
++ return 0;
++}
++
++int main(int argc, char **argv) {
++ char *s, *hostporturl, *base = NULL;
++ char *ttl, *defaultttl;
++ LDAP *ld;
++ char *fltr = NULL;
++ LDAPMessage *res, *e;
++ char *a, **ttlvals, **soavals, *serial;
++ struct berval **vals, **names;
++ char type[64];
++ BerElement *ptr;
++ int i, j, rc, msgid;
++ struct assstack_entry *zone = NULL;
++
++ if (argc < 4 || argc > 5)
++ usage(argv[0]);
++
++ hostporturl = argv[2];
++
++ if (hostporturl != strstr( hostporturl, "ldap"))
++ err(argv[0], "Not an LDAP URL");
++
++ s = strchr(hostporturl, ':');
++
++ if (!s || strlen(s) < 3 || s[1] != '/' || s[2] != '/')
++ err(argv[0], "Not an LDAP URL");
++
++ s = strchr(s+3, '/');
++ if (s) {
++ *s++ = '\0';
++ base = s;
++ s = strchr(base, '?');
++ if (s)
++ err(argv[0], "LDAP URL can only contain host, port and base");
++ }
++
++ defaultttl = argv[3];
++
++ rc = ldap_initialize(&ld, hostporturl);
++ if (rc != LDAP_SUCCESS)
++ err(argv[0], "ldap_initialize() failed");
++
++ if (argc == 5) {
++ /* serial number specified, check if different from one in SOA */
++ fltr = (char *)malloc(strlen(argv[1]) + strlen("(&(relativeDomainName=@)(zoneName=))") + 1);
++ sprintf(fltr, "(&(relativeDomainName=@)(zoneName=%s))", argv[1]);
++ msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
++ if (msgid == -1)
++ err(argv[0], "ldap_search() failed");
++
++ while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) {
++ /* not supporting continuation references at present */
++ if (rc != LDAP_RES_SEARCH_ENTRY)
++ err(argv[0], "ldap_result() returned cont.ref? Exiting");
++
++ /* only one entry per result message */
++ e = ldap_first_entry(ld, res);
++ if (e == NULL) {
++ ldap_msgfree(res);
++ err(argv[0], "ldap_first_entry() failed");
++ }
++
++ soavals = ldap_get_values(ld, e, "SOARecord");
++ if (soavals)
++ break;
++ }
++
++ ldap_msgfree(res);
++ if (!soavals) {
++ err(argv[0], "No SOA Record found");
++ }
++
++ /* We have a SOA, compare serial numbers */
++ /* Only checkinf first value, should be only one */
++ s = strchr(soavals[0], ' ');
++ s++;
++ s = strchr(s, ' ');
++ s++;
++ serial = s;
++ s = strchr(s, ' ');
++ *s = '\0';
++ if (!strcmp(serial, argv[4])) {
++ ldap_value_free(soavals);
++ err(argv[0], "serial numbers match");
++ }
++ ldap_value_free(soavals);
++ }
++
++ if (!fltr)
++ fltr = (char *)malloc(strlen(argv[1]) + strlen("(zoneName=)") + 1);
++ if (!fltr)
++ err(argv[0], "Malloc failed");
++ sprintf(fltr, "(zoneName=%s)", argv[1]);
++
++ msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
++ if (msgid == -1)
++ err(argv[0], "ldap_search() failed");
++
++ while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) {
++ /* not supporting continuation references at present */
++ if (rc != LDAP_RES_SEARCH_ENTRY)
++ err(argv[0], "ldap_result() returned cont.ref? Exiting");
++
++ /* only one entry per result message */
++ e = ldap_first_entry(ld, res);
++ if (e == NULL) {
++ ldap_msgfree(res);
++ err(argv[0], "ldap_first_entry() failed");
++ }
++
++ names = ldap_get_values_len(ld, e, "relativeDomainName");
++ if (!names)
++ continue;
++
++ ttlvals = ldap_get_values(ld, e, "dNSTTL");
++ ttl = ttlvals ? ttlvals[0] : defaultttl;
++
++ for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) {
++ char *s;
++
++ for (s = a; *s; s++)
++ *s = toupper(*s);
++ s = strstr(a, "RECORD");
++ if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) {
++ ldap_memfree(a);
++ continue;
++ }
++
++ strncpy(type, a, s - a);
++ type[s - a] = '\0';
++ vals = ldap_get_values_len(ld, e, a);
++ if (vals) {
++ for (i = 0; vals[i]; i++)
++ for (j = 0; names[j]; j++)
++ if (putrr(&zone, names[j], type, ttl, vals[i]))
++ err(argv[0], "malloc failed");
++ ldap_value_free_len(vals);
++ }
++ ldap_memfree(a);
++ }
++
++ if (ptr)
++ ber_free(ptr, 0);
++ if (ttlvals)
++ ldap_value_free(ttlvals);
++ ldap_value_free_len(names);
++ /* free this result */
++ ldap_msgfree(res);
++ }
++
++ /* free final result */
++ ldap_msgfree(res);
++
++ print_zone(defaultttl, zone);
++ return 0;
++}
+--- bind-9.3.2b1/bin/sdb_tools/Makefile.in.fix_sdb_ldap 2005-02-17 01:43:28.000000000 -0500
++++ bind-9.3.2b1/bin/sdb_tools/Makefile.in 2005-10-06 18:57:32.000000000 -0400
+@@ -30,11 +30,11 @@
+ LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \
+ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} ${DBDRIVER_LIBS} @LIBS@
+
+-TARGETS = zone2ldap@EXEEXT@ zonetodb@EXEEXT@
++TARGETS = zone2ldap@EXEEXT@ ldap2zone@EXEEXT@ zonetodb@EXEEXT@
+
+-OBJS = zone2ldap.o zonetodb.o
++OBJS = zone2ldap.o ldap2zone.o zonetodb.o
+
+-SRCS = zone2ldap.c zonetodb.c
++SRCS = zone2ldap.c ldap2zone.c zonetodb.c
+
+ MANPAGES = zone2ldap.1
+
+@@ -54,6 +54,9 @@
+ zonetodb: zonetodb.o ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ zonetodb.o -lpq ${LIBS}
+
++ldap2zone: ldap2zone.o ${DEPLIBS}
++ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ldap2zone.o -lldap -llber ${LIBS}
++
+ clean distclean manclean maintainer-clean::
+ rm -f ${TARGETS} ${OBJS}
+
+@@ -63,5 +66,6 @@
+
+ install:: ${TARGETS} installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} zone2ldap ${DESTDIR}${sbindir}
++ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} ldap2zone ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} zonetodb ${DESTDIR}${sbindir}
+ ${INSTALL_DATA} ${srcdir}/zone2ldap.1 ${DESTDIR}${mandir}/man1/zone2ldap.1
+--- bind-9.3.2b1/bin/sdb_tools/zone2ldap.c.fix_sdb_ldap 2005-10-06 18:57:32.000000000 -0400
++++ bind-9.3.2b1/bin/sdb_tools/zone2ldap.c 2005-10-06 18:57:32.000000000 -0400
+@@ -24,6 +24,7 @@
+ #include <isc/hash.h>
+ #include <isc/mem.h>
+ #include <isc/print.h>
++#include <isc/hash.h>
+ #include <isc/result.h>
+
+ #include <dns/db.h>
+@@ -61,6 +62,9 @@
+ /* usage Info */
+ void usage (void);
+
++/* Check for existence of (and possibly add) containing dNSZone objects */
++int lookup_dns_zones( ldap_info *ldinfo);
++
+ /* Add to the ldap dit */
+ void add_ldap_values (ldap_info * ldinfo);
+
+@@ -77,7 +81,7 @@
+ int get_attr_list_size (char **tmp);
+
+ /* Get a DN */
+-char *build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag);
++char *build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag, char *zone);
+
+ /* Add to RR list */
+ void add_to_rr_list (char *dn, char *name, char *type, char *data,
+@@ -99,11 +103,27 @@
+ init_ldap_conn ();
+ void usage();
+
+-char *argzone, *ldapbase, *binddn, *bindpw = NULL;
+-const char *ldapsystem = "localhost";
+-static const char *objectClasses[] =
+- { "top", "dNSZone", NULL };
+-static const char *topObjectClasses[] = { "top", NULL };
++static char *argzone, *ldapbase, *binddn, *bindpw = NULL;
++
++/* these are needed to placate gcc4's const-ness const-ernations : */
++static char localhost[] = "localhost";
++static char *ldapsystem=&(localhost[0]);
++/* dnszone schema class names: */
++static char topClass [] ="top";
++static char dNSZoneClass[] ="dNSZone";
++static char objectClass [] ="objectClass";
++static char dcObjectClass[]="dcObject";
++/* dnszone schema attribute names: */
++static char relativeDomainName[]="relativeDomainName";
++static char dNSTTL []="dNSTTL";
++static char zoneName []="zoneName";
++static char dc []="dc";
++static char sameZone []="@";
++/* LDAPMod mod_values: */
++static char *objectClasses []= { &(topClass[0]), &(dNSZoneClass[0]), NULL };
++static char *topObjectClasses []= { &(topClass[0]), &(dcObjectClass[0]), &(dNSZoneClass[0]), NULL };
++static char *dn_buffer [64]={NULL};
++
+ LDAP *conn;
+ unsigned int debug = 0;
+
+@@ -119,12 +139,12 @@
+ isc_result_t result;
+ char *basedn;
+ ldap_info *tmp;
+- LDAPMod *base_attrs[2];
+- LDAPMod base;
++ LDAPMod *base_attrs[5];
++ LDAPMod base, dcBase, znBase, rdnBase;
+ isc_buffer_t buff;
+ char *zonefile=0L;
+ char fullbasedn[1024];
+- char *ctmp;
++ char *ctmp, *zn, *dcp[2], *znp[2], *rdn[2];
+ dns_fixedname_t fixedzone, fixedname;
+ dns_rdataset_t rdataset;
+ char **dc_list;
+@@ -137,7 +157,7 @@
+ extern char *optarg;
+ extern int optind, opterr, optopt;
+ int create_base = 0;
+- int topt;
++ int topt, dcn, zdn, znlen;
+
+ if ((int) argc < 2)
+ {
+@@ -145,7 +165,7 @@
+ exit (-1);
+ }
+
+- while ((topt = getopt ((int) argc, argv, "D:w:b:z:f:h:?dcv")) != -1)
++ while ((topt = getopt ((int) argc, argv, "D:Ww:b:z:f:h:?dcv")) != -1)
+ {
+ switch (topt)
+ {
+@@ -164,8 +184,11 @@
+ case 'w':
+ bindpw = strdup (optarg);
+ break;
++ case 'W':
++ bindpw = getpass("Enter LDAP Password: ");
++ break;
+ case 'b':
+- ldapbase = strdup (optarg);
++ ldapbase = strdup (optarg);
+ break;
+ case 'z':
+ argzone = strdup (optarg);
+@@ -277,27 +300,62 @@
+ {
+ if (debug)
+ printf ("Creating base zone DN %s\n", argzone);
+-
++
+ dc_list = hostname_to_dn_list (argzone, argzone, DNS_TOP);
+- basedn = build_dn_from_dc_list (dc_list, 0, NO_SPEC);
+
+- for (ctmp = &basedn[strlen (basedn)]; ctmp >= &basedn[0]; ctmp--)
++ basedn = build_dn_from_dc_list (dc_list, 0, NO_SPEC, argzone);
++ if (debug)
++ printf ("base DN %s\n", basedn);
++
++ for (ctmp = &basedn[strlen (basedn)], dcn=0; ctmp >= &basedn[0]; ctmp--)
+ {
+- if ((*ctmp == ',') || (ctmp == &basedn[0]))
++ if ((*ctmp == ',') || (ctmp == &basedn[0]))
+ {
++
+ base.mod_op = LDAP_MOD_ADD;
+- base.mod_type = (char*)"objectClass";
+- base.mod_values = (char**)topObjectClasses;
++ base.mod_type = objectClass;
++ base.mod_values = topObjectClasses;
+ base_attrs[0] = (void*)&base;
+- base_attrs[1] = NULL;
+-
++
++ dcBase.mod_op = LDAP_MOD_ADD;
++ dcBase.mod_type = dc;
++ dcp[0]=dc_list[dcn];
++ dcp[1]=0L;
++ dcBase.mod_values=dcp;
++ base_attrs[1] = (void*)&dcBase;
++
++ znBase.mod_op = LDAP_MOD_ADD;
++ znBase.mod_type = zoneName;
++ for( zdn = dcn, znlen = 0; zdn >= 0; zdn-- )
++ znlen += strlen(dc_list[zdn])+1;
++ znp[0] = (char*)malloc(znlen+1);
++ znp[1] = 0L;
++ for( zdn = dcn, zn=znp[0]; zdn >= 0; zdn-- )
++ zn+=sprintf(zn,"%s%s",dc_list[zdn],
++ ((zdn > 0) && (*(dc_list[zdn-1])!='.')) ? "." : ""
++ );
++
++ znBase.mod_values = znp;
++ base_attrs[2] = (void*)&znBase;
++
++ rdnBase.mod_op = LDAP_MOD_ADD;
++ rdnBase.mod_type = relativeDomainName;
++ rdn[0] = strdup(sameZone);
++ rdn[1] = 0L;
++ rdnBase.mod_values = rdn;
++ base_attrs[3] = (void*)&rdnBase;
++
++ dcn++;
++
++ base.mod_values = topObjectClasses;
++ base_attrs[4] = NULL;
++
+ if (ldapbase)
+ {
+ if (ctmp != &basedn[0])
+ sprintf (fullbasedn, "%s,%s", ctmp + 1, ldapbase);
+ else
+- sprintf (fullbasedn, "%s,%s", ctmp, ldapbase);
+-
++ sprintf (fullbasedn, "%s,%s", ctmp, ldapbase);
+ }
+ else
+ {
+@@ -306,8 +364,13 @@
+ else
+ sprintf (fullbasedn, "%s", ctmp);
+ }
++
++ if( debug )
++ printf("Full base dn: %s\n", fullbasedn);
++
+ result = ldap_add_s (conn, fullbasedn, base_attrs);
+ ldap_result_check ("intial ldap_add_s", fullbasedn, result);
++
+ }
+
+ }
+@@ -383,14 +446,14 @@
+ isc_result_check (result, "dns_rdata_totext");
+ data[isc_buffer_usedlength (&buff)] = 0;
+
+- dc_list = hostname_to_dn_list (name, argzone, DNS_OBJECT);
++ dc_list = hostname_to_dn_list ((char*)name, argzone, DNS_OBJECT);
+ len = (get_attr_list_size (dc_list) - 2);
+- dn = build_dn_from_dc_list (dc_list, ttl, WI_SPEC);
++ dn = build_dn_from_dc_list (dc_list, ttl, WI_SPEC, argzone);
+
+ if (debug)
+ printf ("Adding %s (%s %s) to run queue list.\n", dn, type, data);
+
+- add_to_rr_list (dn, dc_list[len], type, data, ttl, DNS_OBJECT);
++ add_to_rr_list (dn, dc_list[len], (char*)type, (char*)data, ttl, DNS_OBJECT);
+ }
+
+
+@@ -430,7 +493,8 @@
+ int attrlist;
+ char ldap_type_buffer[128];
+ char charttl[64];
+-
++ char *zn;
++ int znlen;
+
+ if ((tmp = locate_by_dn (dn)) == NULL)
+ {
+@@ -465,13 +529,13 @@
+ }
+ }
+ tmp->attrs[0]->mod_op = LDAP_MOD_ADD;
+- tmp->attrs[0]->mod_type = (char*)"objectClass";
++ tmp->attrs[0]->mod_type = objectClass;
+
+ if (flags == DNS_OBJECT)
+- tmp->attrs[0]->mod_values = (char**)objectClasses;
++ tmp->attrs[0]->mod_values = objectClasses;
+ else
+ {
+- tmp->attrs[0]->mod_values = (char**)topObjectClasses;
++ tmp->attrs[0]->mod_values =topObjectClasses;
+ tmp->attrs[1] = NULL;
+ tmp->attrcnt = 2;
+ tmp->next = ldap_info_base;
+@@ -480,7 +544,7 @@
+ }
+
+ tmp->attrs[1]->mod_op = LDAP_MOD_ADD;
+- tmp->attrs[1]->mod_type = (char*)"relativeDomainName";
++ tmp->attrs[1]->mod_type = relativeDomainName;
+ tmp->attrs[1]->mod_values = (char **) calloc (sizeof (char *), 2);
+
+ if (tmp->attrs[1]->mod_values == (char **)NULL)
+@@ -502,7 +566,7 @@
+ tmp->attrs[2]->mod_values[1] = NULL;
+
+ tmp->attrs[3]->mod_op = LDAP_MOD_ADD;
+- tmp->attrs[3]->mod_type = (char*)"dNSTTL";
++ tmp->attrs[3]->mod_type = dNSTTL;
+ tmp->attrs[3]->mod_values = (char **) calloc (sizeof (char *), 2);
+
+ if (tmp->attrs[3]->mod_values == (char **)NULL)
+@@ -512,10 +576,21 @@
+ tmp->attrs[3]->mod_values[0] = strdup (charttl);
+ tmp->attrs[3]->mod_values[1] = NULL;
+
++ znlen=strlen(gbl_zone);
++ if ( *(gbl_zone + (znlen-1)) == '.' )
++ { /* ldapdb MUST search by relative zone name */
++ zn = (char*)malloc(znlen);
++ strncpy(zn,gbl_zone,znlen-1);
++ *(zn + (znlen-1))='\0';
++ }else
++ {
++ zn = gbl_zone;
++ }
++
+ tmp->attrs[4]->mod_op = LDAP_MOD_ADD;
+- tmp->attrs[4]->mod_type = (char*)"zoneName";
++ tmp->attrs[4]->mod_type = zoneName;
+ tmp->attrs[4]->mod_values = (char **)calloc(sizeof(char *), 2);
+- tmp->attrs[4]->mod_values[0] = gbl_zone;
++ tmp->attrs[4]->mod_values[0] = zn;
+ tmp->attrs[4]->mod_values[1] = NULL;
+
+ tmp->attrs[5] = NULL;
+@@ -526,7 +601,7 @@
+ else
+ {
+
+- for (i = 0; tmp->attrs[i] != NULL; i++)
++ for (i = 0; tmp->attrs[i] != NULL; i++)
+ {
+ sprintf (ldap_type_buffer, "%sRecord", type);
+ if (!strncmp
+@@ -595,69 +670,105 @@
+ hostname_to_dn_list (char *hostname, char *zone, unsigned int flags)
+ {
+ char *tmp;
+- static char *dn_buffer[64];
+ int i = 0;
+- char *zname;
+- char *hnamebuff;
+-
+- zname = strdup (hostname);
+-
+- if (flags == DNS_OBJECT)
+- {
++ char *hname=0L, *last=0L;
++ int hlen=strlen(hostname), zlen=(strlen(zone));
+
+- if (strlen (zname) != strlen (zone))
+- {
+- tmp = &zname[strlen (zname) - strlen (zone)];
+- *--tmp = '\0';
+- hnamebuff = strdup (zname);
+- zname = ++tmp;
+- }
+- else
+- hnamebuff = (char*)"@";
+- }
+- else
+- {
+- zname = zone;
+- hnamebuff = NULL;
+- }
+-
+- for (tmp = strrchr (zname, '.'); tmp != (char *) 0;
+- tmp = strrchr (zname, '.'))
+- {
+- *tmp++ = '\0';
+- dn_buffer[i++] = tmp;
+- }
+- dn_buffer[i++] = zname;
+- dn_buffer[i++] = hnamebuff;
++/* printf("hostname: %s zone: %s\n",hostname, zone); */
++ hname=0L;
++ if(flags == DNS_OBJECT)
++ {
++ if( (zone[ zlen - 1 ] == '.') && (hostname[hlen - 1] != '.') )
++ {
++ hname=(char*)malloc(hlen + 1);
++ hlen += 1;
++ sprintf(hname, "%s.", hostname);
++ hostname = hname;
++ }
++ if(strcmp(hostname, zone) == 0)
++ {
++ if( hname == 0 )
++ hname=strdup(hostname);
++ last = strdup(sameZone);
++ }else
++ {
++ if( (hlen < zlen)
++ ||( strcmp( hostname + (hlen - zlen), zone ) != 0)
++ )
++ {
++ if( hname != 0 )
++ free(hname);
++ hname=(char*)malloc( hlen + zlen + 1);
++ if( *zone == '.' )
++ sprintf(hname, "%s%s", hostname, zone);
++ else
++ sprintf(hname,"%s",zone);
++ }else
++ {
++ if( hname == 0 )
++ hname = strdup(hostname);
++ }
++ last = hname;
++ }
++ }else
++ { /* flags == DNS_TOP */
++ hname = strdup(zone);
++ last = hname;
++ }
++
++ for (tmp = strrchr (hname, '.'); tmp != (char *) 0;
++ tmp = strrchr (hname, '.'))
++ {
++ if( *( tmp + 1 ) != '\0' )
++ {
++ *tmp = '\0';
++ dn_buffer[i++] = ++tmp;
++ }else
++ { /* trailing '.' ! */
++ dn_buffer[i++] = strdup(".");
++ *tmp = '\0';
++ if( tmp == hname )
++ break;
++ }
++ }
++ if( ( last != hname ) && (tmp != hname) )
++ dn_buffer[i++] = hname;
++ dn_buffer[i++] = last;
+ dn_buffer[i] = NULL;
+-
+ return dn_buffer;
+ }
+
+-
+ /* build an sdb compatible LDAP DN from a "dc_list" (char **).
+ * will append dNSTTL information to each RR Record, with the
+ * exception of "@"/SOA. */
+
+ char *
+-build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag)
++build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag, char *zone)
+ {
+ int size;
+- int x;
++ int x, znlen;
+ static char dn[1024];
+ char tmp[128];
++ char zn[DNS_NAME_MAXTEXT+1];
+
+ bzero (tmp, sizeof (tmp));
+ bzero (dn, sizeof (dn));
+ size = get_attr_list_size (dc_list);
++ znlen = strlen(zone);
++ if ( *(zone + (znlen-1)) == '.' )
++ { /* ldapdb MUST search by relative zone name */
++ memcpy(&(zn[0]),zone,znlen-1);
++ *(zn + (znlen-1))='\0';
++ zone = zn;
++ }
+ for (x = size - 2; x > 0; x--)
+ {
+ if (flag == WI_SPEC)
+ {
+ if (x == (size - 2) && (strncmp (dc_list[x], "@", 1) == 0) && (ttl))
+- sprintf (tmp, "relativeDomainName=%s + dNSTTL=%d,", dc_list[x], ttl);
++ sprintf (tmp, "zoneName=%s + relativeDomainName=%s,", zone, dc_list[x]);
+ else if (x == (size - 2))
+- sprintf(tmp, "relativeDomainName=%s,",dc_list[x]);
++ sprintf(tmp, "zoneName=%s + relativeDomainName=%s,", zone, dc_list[x]);
+ else
+ sprintf(tmp,"dc=%s,", dc_list[x]);
+ }
+@@ -683,6 +794,7 @@
+ init_ldap_conn ()
+ {
+ int result;
++ char ldb_tag[]="LDAP Bind";
+ conn = ldap_open (ldapsystem, LDAP_PORT);
+ if (conn == NULL)
+ {
+@@ -692,7 +804,7 @@
+ }
+
+ result = ldap_simple_bind_s (conn, binddn, bindpw);
+- ldap_result_check ("ldap_simple_bind_s", (char*)"LDAP Bind", result);
++ ldap_result_check ("ldap_simple_bind_s", ldb_tag , result);
+ }
+
+ /* Like isc_result_check, only for LDAP */
+@@ -709,8 +821,6 @@
+ }
+ }
+
+-
+-
+ /* For running the ldap_info run queue. */
+ void
+ add_ldap_values (ldap_info * ldinfo)
+@@ -718,14 +828,14 @@
+ int result;
+ char dnbuffer[1024];
+
+-
+ if (ldapbase != NULL)
+ sprintf (dnbuffer, "%s,%s", ldinfo->dn, ldapbase);
+ else
+ sprintf (dnbuffer, "%s", ldinfo->dn);
+
+ result = ldap_add_s (conn, dnbuffer, ldinfo->attrs);
+- ldap_result_check ("ldap_add_s", dnbuffer, result);
++ ldap_result_check ("ldap_add_s", dnbuffer, result);
++
+ }
+
+
+@@ -736,7 +846,7 @@
+ usage ()
+ {
+ fprintf (stderr,
+- "zone2ldap -D [BIND DN] -w [BIND PASSWORD] -b [BASE DN] -z [ZONE] -f [ZONE FILE] -h [LDAP HOST]\n"
++ "zone2ldap -D [BIND DN] [-w BIND PASSWORD | -W:prompt] -b [BASE DN] -z [ZONE] -f [ZONE FILE] -h [LDAP HOST]\n"
+ "\t[-c Create LDAP Base structure][-d Debug Output (lots !)]\n "
+ );
+ }