| |
| |
| @@ -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; |
| +} |
| |
| |
| @@ -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 |
| |
| |
| @@ -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 " |
| ); |
| } |