--- /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 + * $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 +#include + +#include + +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 #include #include +#include #include #include @@ -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 " ); }