Adam Tkac 66a96f
--- bind-9.4.1/contrib/sdb/ldap/ldapdb.c.new-api	2004-08-27 02:10:25.000000000 +0200
Adam Tkac 66a96f
+++ bind-9.4.1/contrib/sdb/ldap/ldapdb.c	2007-05-21 15:22:10.000000000 +0200
Adam Tkac 66a96f
@@ -58,9 +58,13 @@
Adam Tkac 66a96f
 static dns_sdbimplementation_t *ldapdb = NULL;
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 struct ldapdb_data {
Adam Tkac 66a96f
+#if LDAP_API_VERSION >= 3001
Adam Tkac 66a96f
+	LDAPURLDesc *lud;
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
 	char *hostport;
Adam Tkac 66a96f
 	char *hostname;
Adam Tkac 66a96f
 	int portno;
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	char *base;
Adam Tkac 66a96f
 	int defaultttl;
Adam Tkac 66a96f
 	char *filterall;
Adam Tkac 66a96f
@@ -135,7 +139,11 @@ ldapdb_getconn(struct ldapdb_data *data)
Adam Tkac 66a96f
 				conndata = threaddata->data;
Adam Tkac 66a96f
 				free(conndata->index);
Adam Tkac 66a96f
 				if (conndata->data != NULL)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 					ldap_unbind((LDAP *)conndata->data);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+					ldap_unbind_ext((LDAP *)conndata->data, NULL, NULL);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 				threaddata->data = conndata->next;
Adam Tkac 66a96f
 				free(conndata);
Adam Tkac 66a96f
 			}
Adam Tkac 66a96f
@@ -172,14 +180,14 @@ ldapdb_getconn(struct ldapdb_data *data)
Adam Tkac 66a96f
 	/* threaddata points at the connection list for current thread */
Adam Tkac 66a96f
 	/* look for existing connection to our server */
Adam Tkac 66a96f
 	conndata = ldapdb_find((struct ldapdb_entry *)threaddata->data,
Adam Tkac 66a96f
-			       data->hostport, strlen(data->hostport));
Adam Tkac 66a96f
+			       data->lud->lud_host, strlen(data->lud->lud_host));
Adam Tkac 66a96f
 	if (conndata == NULL) {
Adam Tkac 66a96f
 		/* no connection data structure for this server, create one */
Adam Tkac 66a96f
 		conndata = malloc(sizeof(*conndata));
Adam Tkac 66a96f
 		if (conndata == NULL)
Adam Tkac 66a96f
 			return (NULL);
Adam Tkac 66a96f
-		conndata->index = data->hostport;
Adam Tkac 66a96f
-		conndata->size = strlen(data->hostport);
Adam Tkac 66a96f
+		conndata->index = data->lud->lud_host;
Adam Tkac 66a96f
+		conndata->size = strlen(data->lud->lud_host);
Adam Tkac 66a96f
 		conndata->data = NULL;
Adam Tkac 66a96f
 		ldapdb_insert((struct ldapdb_entry **)&threaddata->data,
Adam Tkac 66a96f
 			      conndata);
Adam Tkac 66a96f
@@ -196,9 +204,15 @@ ldapdb_bind(struct ldapdb_data *data, LD
Adam Tkac 66a96f
 #endif
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	if (*ldp != NULL)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 		ldap_unbind(*ldp);
Adam Tkac 66a96f
 	*ldp = ldap_open(data->hostname, data->portno);
Adam Tkac 66a96f
 	if (*ldp == NULL)
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+		ldap_unbind_ext (*ldp, NULL, NULL);
Adam Tkac 66a96f
+	int res = ldap_initialize(ldp, ldap_url_desc2str(data->lud));
Adam Tkac 66a96f
+	if (res != LDAP_SUCCESS)
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 		return;
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 #ifndef LDAPDB_RFC1823API
Adam Tkac 66a96f
@@ -211,8 +225,17 @@ ldapdb_bind(struct ldapdb_data *data, LD
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 #endif
Adam Tkac 66a96f
 
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 	if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) {
Adam Tkac 66a96f
 		ldap_unbind(*ldp);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+	struct berval ber;
Adam Tkac 66a96f
+	ber.bv_val = data->bindpw;
Adam Tkac 66a96f
+	ber.bv_len = (data->bindpw == NULL) ? 0 : strlen(data->bindpw);
Adam Tkac 66a96f
+
Adam Tkac 66a96f
+	if (ldap_sasl_bind_s(*ldp, data->base, LDAP_SASL_SIMPLE, &ber, NULL, NULL, NULL) != LDAP_SUCCESS) {
Adam Tkac 66a96f
+		ldap_unbind_ext(*ldp, NULL, NULL);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 		*ldp = NULL;
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 }
Adam Tkac 66a96f
@@ -224,14 +247,19 @@ ldapdb_search(const char *zone, const ch
Adam Tkac 66a96f
 	isc_result_t result = ISC_R_NOTFOUND;
Adam Tkac 66a96f
 	LDAP **ldp;
Adam Tkac 66a96f
 	LDAPMessage *res, *e;
Adam Tkac 66a96f
-	char *fltr, *a, **vals = NULL, **names = NULL;
Adam Tkac 66a96f
+	char *fltr, *a;
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
+	char **names, **vals;
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+	struct berval **names, **vals;
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	char type[64];
Adam Tkac 66a96f
 #ifdef LDAPDB_RFC1823API
Adam Tkac 66a96f
 	void *ptr;
Adam Tkac 66a96f
 #else
Adam Tkac 66a96f
 	BerElement *ptr;
Adam Tkac 66a96f
 #endif
Adam Tkac 66a96f
-	int i, j, errno, msgid;
Adam Tkac 66a96f
+	int i, j, errno, msgid, ldap_res;
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	ldp = ldapdb_getconn(data);
Adam Tkac 66a96f
 	if (ldp == NULL)
Adam Tkac 66a96f
@@ -256,12 +284,21 @@ ldapdb_search(const char *zone, const ch
Adam Tkac 66a96f
 		sprintf(data->filtername, "%s))", name);
Adam Tkac 66a96f
 		fltr = data->filterone;
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
-
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 	msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+	ldap_res = ldap_search_ext(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0,
Adam Tkac 66a96f
+				 NULL, NULL, NULL, 65535, &msgid);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	if (msgid == -1) {
Adam Tkac 66a96f
 		ldapdb_bind(data, ldp);
Adam Tkac 66a96f
 		if (*ldp != NULL)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 			msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+			ldap_res = ldap_search_ext(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0,
Adam Tkac 66a96f
+                                 NULL, NULL, NULL, 65535, &msgid);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	if (*ldp == NULL || msgid == -1) {
Adam Tkac 66a96f
@@ -293,15 +330,27 @@ ldapdb_search(const char *zone, const ch
Adam Tkac 66a96f
                 }
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 		if (name == NULL) {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 			names = ldap_get_values(ld, e, "relativeDomainName");
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+			names = ldap_get_values_len(ld, e, "relativeDomainName");
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 			if (names == NULL)
Adam Tkac 66a96f
 				continue;
Adam Tkac 66a96f
 		}
Adam Tkac 66a96f
-
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 		vals = ldap_get_values(ld, e, "dNSTTL");
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+		vals = ldap_get_values_len(ld, e, "dNSTTL");
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 		if (vals != NULL) {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 			ttl = atoi(vals[0]);
Adam Tkac 66a96f
 			ldap_value_free(vals);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+			ttl = atoi(vals[0]->bv_val);
Adam Tkac 66a96f
+			ldap_value_free_len(vals);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 		}
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 		for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) {
Adam Tkac 66a96f
@@ -319,34 +368,60 @@ ldapdb_search(const char *zone, const ch
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 			strncpy(type, a, s - a);
Adam Tkac 66a96f
 			type[s - a] = '\0';
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 			vals = ldap_get_values(ld, e, a);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+			vals = ldap_get_values_len(ld, e, a);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 			if (vals != NULL) {
Adam Tkac 66a96f
 				for (i = 0; vals[i] != NULL; i++) {
Adam Tkac 66a96f
 					if (name != NULL) {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 						result = dns_sdb_putrr(retdata, type, ttl, vals[i]);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+						result = dns_sdb_putrr(retdata, type, ttl, vals[i]->bv_val);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 					} else {
Adam Tkac 66a96f
 						for (j = 0; names[j] != NULL; j++) {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 							result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+							result = dns_sdb_putnamedrr(retdata, names[j]->bv_val, type, ttl, vals[i]->bv_val);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 							if (result != ISC_R_SUCCESS)
Adam Tkac 66a96f
 								break;
Adam Tkac 66a96f
 						}
Adam Tkac 66a96f
 					}
Adam Tkac 66a96f
-;					if (result != ISC_R_SUCCESS) {
Adam Tkac 66a96f
+					if (result != ISC_R_SUCCESS) {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 						isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,	
Adam Tkac 66a96f
 							      "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]);
Adam Tkac 66a96f
 						ldap_value_free(vals);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+						isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,	
Adam Tkac 66a96f
+							      "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]->bv_val);
Adam Tkac 66a96f
+						ldap_value_free_len(vals);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 #ifndef LDAPDB_RFC1823API
Adam Tkac 66a96f
 						ldap_memfree(a);
Adam Tkac 66a96f
 						if (ptr != NULL)
Adam Tkac 66a96f
 							ber_free(ptr, 0);
Adam Tkac 66a96f
 #endif
Adam Tkac 66a96f
 						if (name == NULL)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 							ldap_value_free(names);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+							ldap_value_free_len(names);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 						ldap_msgfree(res);
Adam Tkac 66a96f
 						return (ISC_R_FAILURE);
Adam Tkac 66a96f
 					}
Adam Tkac 66a96f
 				}
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 				ldap_value_free(vals);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+				ldap_value_free_len(vals);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 			}
Adam Tkac 66a96f
 #ifndef LDAPDB_RFC1823API
Adam Tkac 66a96f
 			ldap_memfree(a);
Adam Tkac 66a96f
@@ -357,7 +432,11 @@ ldapdb_search(const char *zone, const ch
Adam Tkac 66a96f
 			ber_free(ptr, 0);
Adam Tkac 66a96f
 #endif
Adam Tkac 66a96f
 		if (name == NULL)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 			ldap_value_free(names);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+			ldap_value_free_len(names);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 		/* free this result */
Adam Tkac 66a96f
 		ldap_msgfree(res);
Adam Tkac 66a96f
@@ -460,10 +539,15 @@ parseextensions(char *extensions, struct
Adam Tkac 66a96f
 static void
Adam Tkac 66a96f
 free_data(struct ldapdb_data *data)
Adam Tkac 66a96f
 {
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 	if (data->hostport != NULL)
Adam Tkac 66a96f
 		isc_mem_free(ns_g_mctx, data->hostport);
Adam Tkac 66a96f
 	if (data->hostname != NULL)
Adam Tkac 66a96f
 		isc_mem_free(ns_g_mctx, data->hostname);
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+	if (data->lud != NULL)
Adam Tkac 66a96f
+		ldap_free_urldesc(data->lud);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	if (data->filterall != NULL)
Adam Tkac 66a96f
 		isc_mem_put(ns_g_mctx, data->filterall, data->filteralllen);
Adam Tkac 66a96f
 	if (data->filterone != NULL)
Adam Tkac 66a96f
@@ -478,7 +562,7 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 {
Adam Tkac 66a96f
 	struct ldapdb_data *data;
Adam Tkac 66a96f
 	char *s, *filter = NULL, *extensions = NULL;
Adam Tkac 66a96f
-	int defaultttl;
Adam Tkac 66a96f
+	int defaultttl, i;
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	UNUSED(driverdata);
Adam Tkac 66a96f
 
Adam Tkac 66a96f
@@ -486,7 +570,10 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 	/* want to do this only once for all instances */
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	if ((argc < 2)
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
+	/* Could be ldap[is]:// */
Adam Tkac 66a96f
 	    || (argv[0] != strstr( argv[0], "ldap://"))
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 	    || ((defaultttl = atoi(argv[1])) < 1))
Adam Tkac 66a96f
                 return (ISC_R_FAILURE);
Adam Tkac 66a96f
         data = isc_mem_get(ns_g_mctx, sizeof(struct ldapdb_data));
Adam Tkac 66a96f
@@ -494,14 +581,15 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
                 return (ISC_R_NOMEMORY);
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	memset(data, 0, sizeof(struct ldapdb_data));
Adam Tkac 66a96f
+
Adam Tkac 66a96f
+	data->defaultttl = defaultttl;
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 	data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://"));
Adam Tkac 66a96f
 	if (data->hostport == NULL) {
Adam Tkac 66a96f
 		free_data(data);
Adam Tkac 66a96f
 		return (ISC_R_NOMEMORY);
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 
Adam Tkac 66a96f
-	data->defaultttl = defaultttl;
Adam Tkac 66a96f
-
Adam Tkac 66a96f
 	s = strchr(data->hostport, '/');
Adam Tkac 66a96f
 	if (s != NULL) {
Adam Tkac 66a96f
 		*s++ = '\0';
Adam Tkac 66a96f
@@ -544,11 +632,26 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 		}
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
+	if (ldap_url_parse (argv[0], &data->lud) != LDAP_URL_SUCCESS) {
Adam Tkac 66a96f
+		free_data (data);
Adam Tkac 66a96f
+		return (ISC_R_FAILURE);
Adam Tkac 66a96f
+	}
Adam Tkac 66a96f
+
Adam Tkac 66a96f
+	data->base = data->lud->lud_dn;
Adam Tkac 66a96f
+
Adam Tkac 66a96f
+	for (i = 0; data->lud->lud_exts[i] != NULL; i++) {
Adam Tkac 66a96f
+		extensions = strdup (data->lud->lud_exts[i]);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
+
Adam Tkac 66a96f
 	/* parse extensions */
Adam Tkac 66a96f
 	if (extensions != NULL) {
Adam Tkac 66a96f
 		int err;
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 		err = parseextensions(extensions, data);
Adam Tkac 66a96f
+#if LDAP_API_VERSION >= 3001
Adam Tkac 66a96f
+		free (extensions);
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 		if (err < 0) {
Adam Tkac 66a96f
 			/* err should be -1 or -2 */
Adam Tkac 66a96f
 			free_data(data);
Adam Tkac 66a96f
@@ -562,6 +665,14 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 			return (ISC_R_FAILURE);
Adam Tkac 66a96f
 		}
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
+#if LDAP_API_VERSION >= 3001
Adam Tkac 66a96f
+	else {
Adam Tkac 66a96f
+		free_data (data);
Adam Tkac 66a96f
+		return (ISC_R_NOMEMORY);
Adam Tkac 66a96f
+	}
Adam Tkac 66a96f
+	}
Adam Tkac 66a96f
+	filter = data->lud->lud_filter;
Adam Tkac 66a96f
+#else
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	if ((data->base != NULL && unhex(data->base) == NULL) ||
Adam Tkac 66a96f
 	    (filter != NULL && unhex(filter) == NULL) ||
Adam Tkac 66a96f
@@ -572,6 +683,7 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 			      "LDAP sdb zone '%s': URL: bad hex values", zone);
Adam Tkac 66a96f
 		return (ISC_R_FAILURE);
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	/* compute filterall and filterone once and for all */
Adam Tkac 66a96f
 	if (filter == NULL) {
Adam Tkac 66a96f
@@ -602,6 +714,7 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 	}
Adam Tkac 66a96f
 	data->filtername = data->filterone + strlen(data->filterone);
Adam Tkac 66a96f
 
Adam Tkac 66a96f
+#if LDAP_API_VERSION < 3001
Adam Tkac 66a96f
 	/* support URLs with literal IPv6 addresses */
Adam Tkac 66a96f
 	data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport + (*data->hostport == '[' ? 1 : 0));
Adam Tkac 66a96f
 	if (data->hostname == NULL) {
Adam Tkac 66a96f
@@ -620,8 +733,10 @@ ldapdb_create(const char *zone, int argc
Adam Tkac 66a96f
 		data->portno = atoi(s);
Adam Tkac 66a96f
 	} else
Adam Tkac 66a96f
 		data->portno = LDAP_PORT;
Adam Tkac 66a96f
+#endif
Adam Tkac 66a96f
 
Adam Tkac 66a96f
 	*dbdata = data;
Adam Tkac 66a96f
+
Adam Tkac 66a96f
 	return (ISC_R_SUCCESS);
Adam Tkac 66a96f
 }
Adam Tkac 66a96f