Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Oct 2006 12:26:39 GMT
From:      Michael Bushkov <bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108568 for review
Message-ID:  <200610271226.k9RCQda4007514@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108568

Change 108568 by bushman@bushman_nss_ldap_cached on 2006/10/27 12:26:22

	+ getgr*** functionality finished - now resolving nested groups
	+ several memory leaks eliminated
	+ tons of debugging output in the code - will be cleaned up soon

Affected files ...

.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#13 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#13 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#11 edit

Differences ...

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#13 (text+ko) ====

@@ -28,13 +28,15 @@
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
- 
+
+#include <sys/param.h>
 #include <assert.h>
 #include <errno.h>
 #include <nsswitch.h>
 #include <ldap.h>
 #include <grp.h>
 #include <stringlist.h>
+#include "hashtable.h"
 #include "ldapconn.h"
 #include "ldapschema.h"
 #include "ldapsearch.h"
@@ -43,9 +45,40 @@
 #include "ldapconf.h"
 #include "nss_ldap.h"
 
+#define NSS_LDAP_MAP_GROUP_HASH_ENTRY_INITIAL_SIZE (8)
+#define NSS_LDAP_MAP_GROUP_HASH_SIZE (127)
+#define NSS_LDAP_MAP_GROUP_DN_PROCESS_NESTED_FLAG (1)
+#define NSS_LDAP_MAP_GROUP_DN_USE_CACHE_FLAG (1 << 1)
+#define NSS_LDAP_MAP_GROUP_DN_USE_RDN_FLAG (1 << 2)
+
+struct mapped_group {
+	char *dn;
+};
+
+struct __mg_he {
+	HASHTABLE_ENTRY_HEAD(__mg_he_item, struct mapped_group) data;
+};
+
+struct map_group_dn_request {
+	StringList *next_requests;
+	HASHTABLE_HEAD(__mg_ht, __mg_he) groups;
+	int flags;
+};
+
+static int __mg_ht_item_cmp_func(const void *, const void *);
+static hashtable_index_t __mg_ht_item_hash_func(const void *, size_t);
+HASHTABLE_PROTOTYPE(__mg_ht, __mg_he, struct mapped_group);
+static int nss_ldap_map_group_dn(struct nss_ldap_search_context *, 
+	char const *, char **, size_t *, char *, size_t, void *);
+static int nss_ldap_parse_nested_group(struct nss_ldap_search_context *,
+	char const *, struct map_group_dn_request *, char ***, size_t *,
+	size_t *, char *, size_t);
+
 static int nss_ldap_parse_group(struct nss_ldap_parse_context *);
 	
-static int ldap_getgrnam_r(const char *, struct group *, char *, size_t,
+//static int ldap_getgrnam_r(const char *, struct group *, char *, size_t,
+//	struct group **);
+int ldap_getgrnam_r(const char *, struct group *, char *, size_t,
 	struct group **);
 static int ldap_getgrgid_r(gid_t, struct group *, char *, size_t,
 	struct group **);
@@ -53,59 +86,252 @@
 static void ldap_setgrent();
 
 static int
-nss_ldap_parse_group(struct nss_ldap_parse_context *pctx)
+__mg_ht_item_cmp_func(const void *p1, const void *p2)
+{
+	
+	return (strcmp(
+		((struct mapped_group *)p1)->dn,
+		((struct mapped_group *)p2)->dn));
+				
+}
+
+static hashtable_index_t
+__mg_ht_item_hash_func(const void *p, size_t cache_entries_size)
+{
+	struct mapped_group const *mg;
+        size_t i, len;
+        hashtable_index_t retval;
+
+        mg = p;
+        assert(mg->dn != NULL);
+
+	len = strlen(mg->dn);
+        retval = 0;
+        for (i = 0; i < len; ++i)
+            retval = (127 * retval + (unsigned char)mg->dn[i]) %
+                cache_entries_size;
+
+        return retval;	
+}
+
+HASHTABLE_GENERATE(__mg_ht, __mg_he, struct mapped_group, data,
+	__mg_ht_item_hash_func, __mg_ht_item_cmp_func);
+
+static int 
+nss_ldap_map_group_dn(struct nss_ldap_search_context *ctx, char const *dn,
+	char **res, size_t *res_size, char *buf, size_t bufsize, void *mdata)
 {
-	struct nss_ldap_dn2attr_request dnreq;
-	char *valid_oc_arr[3];
-	struct nss_ldap_schema *schema;
-	struct nss_ldap_search_context *sctx;
-	struct group *grp;
-	char *buf;
-	char **res;
-	size_t buflen;
-	size_t len, memlen, res_memlen;
+	struct nss_ldap_search_request sreq;
+	struct mapped_group new_mg;
+	struct nss_ldap_search_context *newctx;
+	struct map_group_dn_request *req;
+	char **cp, *str;
+	char const *uid_attr, *gid_attr;
+	struct mapped_group *hash_entry_data;
+	struct __mg_he *hash_entry;
+	hashtable_index_t hash;
 	int rv;
 	
-	assert(pctx != NULL);
+	assert(ctx != NULL);
+	assert(dn != NULL);
+	assert(res != NULL);
+	assert(res_size != NULL);
+	assert(buf != NULL);
+	assert(mdata != NULL);
+	
+	//printf("__ %s %d %s\n", __FILE__, __LINE__, dn);
+	
+	req = mdata;
+	newctx = NULL;
+
+
+	memset(&new_mg, 0, sizeof(new_mg));
+	new_mg.dn = (char *)dn;
+		
+	hash = HASHTABLE_CALCULATE_HASH(__mg_ht, &req->groups, &new_mg);
+	assert(hash > 0);
+	assert(hash < HASHTABLE_ENTRIES_COUNT(&req->groups));
+		
+	hash_entry = HASHTABLE_GET_ENTRY(&req->groups, hash);
+	hash_entry_data = HASHTABLE_ENTRY_FIND(__mg_ht, hash_entry, 
+		&new_mg);
+	if (hash_entry_data != NULL) {
+		rv = NSS_LDAP_SUCCESS;
+		*res_size = 0;
+		//printf("__ %s %d\n", __FILE__, __LINE__);
+		goto fin;
+	}
+
+	memset(&sreq, 0, sizeof(sreq));	
+	sreq.scope = LDAP_SCOPE_BASE;
+	sreq.filter = "(objectClass=*)";
+	sreq.search_base = (char *)dn;
+
+	uid_attr = _ATM(&ctx->conf->schema, PASSWD, uid);
+	gid_attr = _ATM(&ctx->conf->schema, GROUP, gidNumber);
+	sreq.attributes = sl_init();
+	rv = sl_add(sreq.attributes, (char *)uid_attr);
+	if (rv == -1) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto fin;
+	}
+
+	rv = sl_add(sreq.attributes, (char *)gid_attr);
+	if (rv == -1) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto fin;
+	}		
+
+	rv = sl_add(sreq.attributes, "objectClass");
+	if (rv == -1) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto fin;
+	}
+
+	rv = sl_add(sreq.attributes, NULL);
+	if (rv == -1) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto fin;
+	}
+	
+//		printf("__ %s %d\n", __FILE__, __LINE__);
+	newctx = __nss_ldap_start_search(&__nss_ldap_conf->search_method,
+		ctx->conn, ctx->conf, &sreq);
+//		printf("__ %s %d\n", __FILE__, __LINE__);
+	sl_free(sreq.attributes, 0);
+	sreq.attributes = NULL; /* just in case */
 	
-/*	int start, end;
-	int res;
-	printf("1\n");
-	res = __nss_ldap_parse_range("member;range=1-*", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+	if (newctx == NULL) {
+		rv = NSS_LDAP_SUCCESS;
+		*res_size = 0;
+		goto fin2;
+	}
 	
-	printf("2\n");
-	res = __nss_ldap_parse_range("member;range=134-100", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+	rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, 
+		newctx);
+	if (rv != NSS_LDAP_SUCCESS) {
+		rv = NSS_LDAP_SUCCESS;
+		*res_size = 0;		
+		goto fin2;
+	}
+
+	new_mg.dn = strdup(dn);
+	if (new_mg.dn == NULL) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto fin2;
+	}		
 
-	printf("3\n");
-	res = __nss_ldap_parse_range("member;range=-*", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+	if (__nss_ldap_check_oc(newctx, _OC(&ctx->conf->schema, posixGroup)) == 
+		NSS_LDAP_SUCCESS) {
+		
+			//printf("__ %s %d %s\n", __FILE__, __LINE__, str);
+			rv = sl_add(req->next_requests, new_mg.dn);
+			if (rv == -1) {
+				free(new_mg.dn);
+				rv = NSS_LDAP_MEMORY_ERROR;
+				goto fin2;
+			}
+			rv = NSS_LDAP_SUCCESS;
+			
+			//printf("__ %s %d %s\n", __FILE__, __LINE__, str);			
+		*res_size = 0;
+		goto fin2;
+	} else {
+		rv = __nss_ldap_assign_attr_str(newctx, uid_attr, res, 
+			res_size, buf, bufsize);
+		if (rv != NSS_LDAP_SUCCESS)
+			goto fin2;
+	}
 
-	printf("4\n");
-	res = __nss_ldap_parse_range("member;range=1-", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+	rv = HASHTABLE_ENTRY_STORE(__mg_ht, hash_entry, &new_mg);
+	if (rv == -1) {
+		if (new_mg.dn != 
+			req->next_requests->sl_str[req->next_requests->sl_cur])
+			free(new_mg.dn);
+		rv = NSS_LDAP_MEMORY_ERROR;	
+	} else
+		rv = NSS_LDAP_SUCCESS;
+	
+fin:
+	if (sreq.attributes != NULL)
+		sl_free(sreq.attributes, 0);
+		
+fin2:
+	if (newctx != NULL)
+		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
+	
+	//printf("__%s %d %d\n", __FILE__, __LINE__, rv);
+	return (rv);
+}
 
-	printf("5\n");
-	res = __nss_ldap_parse_range("member;range=*-*", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+static int 
+nss_ldap_parse_nested_group(struct nss_ldap_search_context *ctx,
+	char const *dn, struct map_group_dn_request *dnreq, char ***res, 
+	size_t *res_size, size_t *len, char *buf, size_t bufsize)
+{
+	struct nss_ldap_search_request sreq;
+	struct nss_ldap_search_context *newctx;
+	int rv;
+	
+	//printf("__ %s %d %s\n", __FILE__, __LINE__, dn);
+	memset(&sreq, 0, sizeof(sreq));	
+	sreq.scope = LDAP_SCOPE_BASE;
+	sreq.filter = "(objectClass=*)";
+	sreq.search_base = (char *)dn;
+	
+	//printf("__ %s %d\n", __FILE__, __LINE__);
+	newctx = __nss_ldap_start_search(&__nss_ldap_conf->search_method,
+		ctx->conn, ctx->conf, &sreq);
+	if (newctx == NULL)
+		return (NSS_LDAP_CONNECTION_ERROR);
+	
+	//printf("__ %s %d\n", __FILE__, __LINE__);
+	rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, 
+		newctx);
+	if (rv != NSS_LDAP_SUCCESS) {
+		rv = NSS_LDAP_CONNECTION_ERROR;
+		goto fin;
+	}
 
-	printf("6\n");
-	res = __nss_ldap_parse_range("member;range=1-*;binary", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+	//printf("__ %s %d\n", __FILE__, __LINE__);
+	rv = __nss_ldap_assign_attr_multi_str_paged_ext(newctx,
+		_ATM(&ctx->conf->schema, GROUP, uniqueMember),
+		res, res_size, len, buf, bufsize,
+		NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG | 
+		NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG |
+		NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG, 
+		nss_ldap_map_group_dn, (void *)dnreq);
 	
-	printf("7\n");
-	res = __nss_ldap_parse_range("member;binary;range=1-*;binary", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);
+fin:
+	//printf("__ %s %d\n", __FILE__, __LINE__);
+	if (newctx != NULL)
+		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
+
+	//printf("__ %s %d\n", __FILE__, __LINE__);
+	return (rv);
+}
 
-	printf("8\n");
-	res = __nss_ldap_parse_range("member;binary;range=1-*;", &start, &end);
-	printf("res: %d, start: %d, end: %d\n", res, start, end);*/
 
+static int
+nss_ldap_parse_group(struct nss_ldap_parse_context *pctx)
+{
+	struct map_group_dn_request dnreq;
+	struct nss_ldap_schema *schema;
+	struct nss_ldap_search_context *sctx;
+	struct group *grp;
+	char *buf, *rbuf;
+	char **res, **new_res;
+	struct __mg_he *hash_entry;
+	struct mapped_group *hash_data;
+	size_t len, memlen, res_memlen, nr_offset;
+	int rv;
+	
+	assert(pctx != NULL);
+	
 	sctx = pctx->sctx;
 	grp = (struct group *)pctx->mdata;
 	buf = pctx->buffer;
-	buflen = pctx->bufsize;
+	rbuf = buf + pctx->bufsize;
 	
 	schema = &sctx->conf->schema;
 //	printf("__ %s %d\n", __FILE__, __LINE__);
@@ -119,19 +345,17 @@
 	
 	rv = __nss_ldap_assign_rdn_str(sctx, 
 		_ATM(schema, GROUP, cn),
-		&grp->gr_name, &len, buf, buflen);
+		&grp->gr_name, &len, buf, rbuf - buf);
 	if (rv != NSS_LDAP_SUCCESS)
 		goto errfin;
 //	printf("__ %s %d\n", __FILE__, __LINE__);
-	buflen -= len;
 	buf += len;
 	
 	rv = __nss_ldap_assign_attr_password(sctx,
 		_ATM(schema, GROUP, userPassword),
-		&grp->gr_passwd, &len, buf, buflen);
+		&grp->gr_passwd, &len, buf, rbuf - buf);
 	if (rv != NSS_LDAP_SUCCESS)
 		goto errfin;
-	buflen -= len;
 	buf += len;
 		
 	grp->gr_mem = NULL;
@@ -140,9 +364,10 @@
 	//rv = __nss_ldap_assign_attr_multi_str(sctx,
 	rv = __nss_ldap_assign_attr_multi_str_paged_ext(sctx,
 		_ATM(schema, GROUP, memberUid),
-		&res, &memlen, &len, buf, buflen,
+		&res, &memlen, &len, buf, rbuf - buf,
 		NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG | 
 		NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG, NULL, NULL);
+	//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 	if (rv == NSS_LDAP_SUCCESS) {
 //			char **cp;
 //			for (cp = res; *cp; ++cp) {
@@ -150,35 +375,78 @@
 //				printf("__ %s %d %s\n", __FILE__, __LINE__, *cp);
 //			}
 
-			buflen -= len + (buf + buflen - (char *)res);
+		rbuf = (char *)res;
 		buf += len;
 		
 		grp->gr_mem = res;
 	}
 
+	nr_offset = 0;
 	memset(&dnreq, 0, sizeof(struct nss_ldap_dn2attr_request));
-	dnreq.attr = (char *)_ATM(schema, PASSWD, uid);
-	valid_oc_arr[0] = (char *)_OC(schema, posixAccount);
-	valid_oc_arr[1] = (char *)_OC(schema, shadowAccount);
-	valid_oc_arr[2] = NULL;
-	dnreq.oc = valid_oc_arr;
+	dnreq.flags = NSS_LDAP_MAP_GROUP_DN_PROCESS_NESTED_FLAG;
+	dnreq.next_requests = sl_init();
+	if (dnreq.next_requests == NULL) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		goto errfin;
+	}
+	HASHTABLE_INIT(&dnreq.groups, struct mapped_group, data, 
+		NSS_LDAP_MAP_GROUP_HASH_SIZE, 
+		NSS_LDAP_MAP_GROUP_HASH_ENTRY_INITIAL_SIZE);
+	if (!HASHTABLE_OK(&dnreq.groups)) {
+		rv = NSS_LDAP_MEMORY_ERROR;
+		sl_free(dnreq.next_requests, 0);
+		goto errfin;
+	}		
 //	printf("__ %s %d %d %p %s\n", __FILE__, __LINE__, rv, (void *)grp->gr_mem, grp->gr_name);
 
 	if (rv != NSS_LDAP_BUFFER_ERROR) {
 		res_memlen = memlen;
+		//printf("__ %s %d\n", __FILE__, __LINE__);
 		rv = __nss_ldap_assign_attr_multi_str_paged_ext(sctx,
 			_ATM(schema, GROUP, uniqueMember),
-			&res, &memlen, &len, buf, buflen,
-			0, __nss_ldap_map_dn2attr_fn, (void *)&dnreq);
+			&res, &memlen, &len, buf, rbuf - buf,
+			NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG | 
+			NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG |
+			(grp->gr_mem == NULL ? 0 :
+				NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG), 
+			nss_ldap_map_group_dn, (void *)&dnreq);
+		//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 		if (rv == NSS_LDAP_SUCCESS) {
-//			printf("__ %s %d %d %d %d\n", __FILE__, __LINE__, memlen, len, buflen);
+			res_memlen += memlen;
+			grp->gr_mem = res;
+			rbuf = (char *)res;
+			buf += len;
+
+			//printf("__ %s %d %d %d %d\n", __FILE__, __LINE__,
+			//	nr_offset,
+	//			dnreq.next_requests->sl_cur,
+	//			dnreq.next_requests->sl_max);
+			while (nr_offset < dnreq.next_requests->sl_cur) {
+
+				//printf("__ %s %d\n", __FILE__, __LINE__);
+				rv = nss_ldap_parse_nested_group(sctx, 
+					dnreq.next_requests->sl_str[nr_offset],
+					&dnreq, &res, &memlen, &len, buf,
+					rbuf - buf);
+				if (rv == NSS_LDAP_BUFFER_ERROR)
+					break;
+					
+				if (rv == NSS_LDAP_SUCCESS) {
+					res_memlen += memlen;
+					grp->gr_mem = res;
+					rbuf = (char *)res;
+					buf += len;
+				}
+				
+				++nr_offset;
+			}
+//			printf("__ %s %d %d %d\n", __FILE__, __LINE__, memlen, len);
 //			char **cp;
-//			for (cp = res; *cp; ++cp)
+//			for (cp = res; *cp; ++cp) {
+//				printf("__ %p %p %p\n", __FILE__, __LINE__, (void *)cp, (void *)*cp, (void *)buf);
 //				printf("__ %s %d %s\n", __FILE__, __LINE__, *cp);
+//			}
 
-			if (grp->gr_mem != NULL)
-				memmove(res + memlen - 1, grp->gr_mem, res_memlen * sizeof(char *));
-			grp->gr_mem = res;
 //			else if (memlen > 1) {
 //				printf("__ %s %d %p %s\n", __FILE__, __LINE__, (void *)(*(res - 1)), *(res + memlen - 2));
 //				printf("__ %s %d %s %s\n", __FILE__, __LINE__, *(res - 1), *(res + memlen - 2));
@@ -192,15 +460,34 @@
 //				printf("__ %s %d %s\n", __FILE__, __LINE__, *cp);
 		}
 
-		if ((grp->gr_mem != NULL) && (rv != NSS_LDAP_BUFFER_ERROR))
+		if ((grp->gr_mem != NULL) && (rv != NSS_LDAP_BUFFER_ERROR)) {
+			new_res = (char **)ALIGN(rbuf);
+			if (new_res != grp->gr_mem) {
+				memmove(new_res, grp->gr_mem, 
+					res_memlen * sizeof(char *));
+				grp->gr_mem = new_res;
+			}
 			rv = NSS_LDAP_SUCCESS;
+		}
 	}
+
+	HASHTABLE_FOREACH(&dnreq.groups, hash_entry) {
+		HASHTABLE_ENTRY_FOREACH(hash_entry, data, hash_data)
+			free(hash_data->dn);
+
+		HASHTABLE_ENTRY_CLEAR(hash_entry, data);
+	}
+	
+	
+	sl_free(dnreq.next_requests, 0);
+	HASHTABLE_DESTROY(&dnreq.groups, data);
 errfin:
 //	printf("__ %s %d %d %p %s\n", __FILE__, __LINE__, rv, (void *)grp->gr_mem, grp->gr_name);
 	return (rv);
 }
 
-static int 
+//static int 
+int
 ldap_getgrnam_r(const char *name, struct group *grp, 
 	char *buffer, size_t bufsize, struct group **result)
 {

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#14 (text+ko) ====


==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#14 (text+ko) ====

@@ -507,10 +507,8 @@
 	struct nss_ldap_connection_error *err)
 {	
 	LDAPMessage     *res;
-	int             msgid = 0, rc = 0, parse_rc = 0, finished = 0;
-	char            *matched_msg = NULL, *error_msg = NULL;
-	char            **referrals;
-	LDAPControl     **serverctrls;
+	int             msgid, rc, parse_rc, finished;
+	char            *matched_msg, *error_msg;
 	char		*err_str;
 	struct timeval  zerotime;	
 	
@@ -521,6 +519,9 @@
 	assert(conf != NULL);
 	assert(err != NULL);
 	
+	msgid = rc = parse_rc = finished = 0;
+	matched_msg = error_msg = NULL;
+	
 	if (geteuid() != 0)
 		bind_dn = conf->bind_dn;
 	else
@@ -545,6 +546,8 @@
 			"ldap_simple_bind() error: %s; %s\n", 
 			ldap_err2string(err->err_num),
 			err_str == NULL ? "" : err_str);
+		if (err_str != NULL)
+			ldap_memfree(err_str);
 		__nss_ldap_log(NSS_LDAP_LL_ERR_INT,
 		    "__nss_ldap_simple_auth failed on ldap_simple_bind");		
   		return (NSS_LDAP_CONNECTION_ERROR);
@@ -587,8 +590,8 @@
       			which indicates that the LDAPMessage structure res should be 
       			freed when done.  (No need to call ldap_msgfree().) */
     			parse_rc = ldap_parse_result( conn->ld, res, &rc,
-				&matched_msg, &error_msg, &referrals, 
-				&serverctrls, 1 );
+				&matched_msg, &error_msg, NULL, 
+				NULL, 1 );
 			/* TODO: probably don't need this, check */
     			if ( parse_rc != LDAP_SUCCESS ) {
 				err->err_num = parse_rc;
@@ -600,6 +603,11 @@
 				    "__nss_ldap_simple_auth failed on "
 				    "ldap_parse_result");
 
+				if (error_msg != NULL)
+					ldap_memfree(error_msg);
+				if (matched_msg != NULL)
+					ldap_memfree(matched_msg);
+
       				return (NSS_LDAP_CONNECTION_ERROR);
     			}
     
@@ -622,13 +630,24 @@
 				    (matched_msg != NULL && *matched_msg != '\0') ?
 					matched_msg : "[unknown]"
 				    );
-
+				
+				if (error_msg != NULL)
+					ldap_memfree(error_msg);
+				if (matched_msg != NULL)
+					ldap_memfree(matched_msg);
+				
 				__nss_ldap_log(NSS_LDAP_LL_ERR_INT,
 				    "__nss_ldap_simple_auth failed on "
 				    "ldap_parse_result");
       				return (NSS_LDAP_CONNECTION_ERROR);
-    			} else
+    			} else {
+				if (error_msg != NULL)
+					ldap_memfree(error_msg);
+				if (matched_msg != NULL)
+					ldap_memfree(matched_msg);
+				
 				return (NSS_LDAP_SUCCESS);
+			}
     		break;
   		}
 	}

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#14 (text+ko) ====

@@ -125,10 +125,12 @@
 	
 	values = (char **)ldap_get_values(ctx->conn->ld, ctx->msg, attr);
 	valsize = values == NULL ? 0 : ldap_count_values(values);
-	*str_array_size = valsize;
-	if (!(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG))
+	*str_array_size = 0;
+	if (!(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG)) {
+		++valsize;
 		++*str_array_size;
-	size = *str_array_size * sizeof(char *);
+	}
+	size = valsize * sizeof(char *);
 
 	sbuf = buf;
 	rbuf = buf + bufsize;
@@ -138,8 +140,8 @@
 		siter_end = (char **)ALIGN(rbuf);
 		while ((char *)siter_end > rbuf)
 			--siter_end;
-		
-		siter = siter_end - *str_array_size;		
+		siter = siter_end - 
+		    (flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG ? 1 : 2);
 		//printf("__ %s %d %p %p\n", __FILE__, __LINE__, (void *)buf, (void *)siter);
 		if ((char *)siter <= buf) {
 			//printf("__ %s %d %d\n", __FILE__, __LINE__, valsize);
@@ -150,7 +152,8 @@
 			//printf("__ %s %d\n", __FILE__, __LINE__);
 			return (NSS_LDAP_BUFFER_ERROR);
 		}
-		
+		if (!(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG))
+			*(siter + 1) = NULL;
 		rbuf = (char *)siter;
 	} else  {
 		siter = (char **)ALIGN(buf);
@@ -169,7 +172,7 @@
 	*str_array = siter;
 		
 	if (values != NULL) {
-		for (viter = values; *viter; ++viter, ++siter) {
+		for (viter = values; *viter; ++viter) {
 			if (sp_fn == NULL)
 				rv = __nss_ldap_assign_str(*viter, siter, &size,
 					buf, rbuf - buf);
@@ -178,21 +181,38 @@
 					rbuf - buf, mdata);
 			
 			if (rv != NSS_LDAP_SUCCESS) {
-//				printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
+				//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
               			ldap_value_free(values);
               			goto fin;                       
               		}
-		
-			buf += size;
+								
+			if (size > 0) {
+			    //printf("__%s %d %s\n", __FILE__, __LINE__, *siter);
+			    ++*str_array_size;
+			    buf += size;
+			    if (flags & 
+				NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {
+				--siter;
+				if ((char *)siter <= buf) {
+					rv = NSS_LDAP_BUFFER_ERROR;
+					ldap_value_free(values);
+					goto fin;
+				}
+				rbuf = (char *)siter;
+			    } else
+				++siter;
+			}
 		}
 		
 		ldap_value_free(values);
 	}
 
-	if (!(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG))
+	if (!(flags & (NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG | 
+		NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG)))
 		*siter = NULL;
-	
-	if (flags && NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {
+		
+	if (flags & NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {
+		*str_array = siter + 1;
 		if (!(flags & NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG)) {
 			new_res_arr = (char **)ALIGN(buf);
 		
@@ -211,7 +231,7 @@
 	//printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size);
 
 fin:
-	//printf("__ %s %d\n", __FILE__, __LINE__);
+	//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 	return (rv);
 }
 
@@ -230,16 +250,20 @@
 	size_t res_arr_size, res_buf_size, res_buf_offset, res_arr_offset;
 	int range_start, range_end, rv, sf;
 	
+	//printf("__ %s %d\n", __FILE__, __LINE__);
 	rv = __nss_ldap_parse_range(attr, &range_start, &range_end);
 	if (rv != NSS_LDAP_SUCCESS)
 		return (rv);
 		
+	//printf("__ %s %d\n", __FILE__, __LINE__);
 	sbuf = buf;
 	rbuf = buf + bufsize;
 	res_arr_size = 0;
 	sf = 0;
 	do {
 st:
+		memset(&sreq, 0, sizeof(sreq));
+
 		rv = do_assign_attr_multi_str(ctx, attr,
 			&res_arr, &res_arr_offset, &res_buf_offset, 
 			buf, rbuf - buf,
@@ -249,7 +273,7 @@
 			NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG,
 			sp_fn, mdata);
 		if (rv != NSS_LDAP_SUCCESS)
-			goto fin;
+			break;
 		
 		res_arr_size += res_arr_offset;
 		buf += res_buf_offset;
@@ -258,7 +282,6 @@
 		if (range_end == -1)
 			break;
 				
-		memset(&sreq, 0, sizeof(sreq));
 		sreq.scope = LDAP_SCOPE_BASE;
 		sreq.filter = "(objectClass=*)";
 		sreq.search_base = ldap_get_dn(ctx->conn->ld, ctx->msg);
@@ -300,7 +323,7 @@
 		sl_free(sreq.attributes, 0);
 		ldap_memfree(sreq.search_base);
 		if (newctx == NULL) {
-			rv = NSS_LDAP_CONNECTION_ERROR;
+			rv = NSS_LDAP_SUCCESS;
 			break;
 		}
 		
@@ -317,8 +340,10 @@
 //		printf("__ %s %d\n", __FILE__, __LINE__);
 		rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, 
 			ctx);
-		if (rv != NSS_LDAP_SUCCESS)
+		if (rv != NSS_LDAP_SUCCESS) {
+			rv = NSS_LDAP_SUCCESS;
 			break;		
+		}
 		
 //		printf("__ %s %d\n", __FILE__, __LINE__);
 		attr = ldap_first_attribute(ctx->conn->ld, ctx->msg, &cookie);
@@ -341,8 +366,11 @@
 				ctx);
 		if (attr != NULL)
 			ldap_memfree((char *)attr);
+		
+		if (sreq.attributes != NULL)
+			sl_free(sreq.attributes, 0);
 	}
-
+	
 //	printf("__ %s %d %d %d %d\n", __FILE__, __LINE__, res_buf_size,
 //		res_arr_size, (buf + bufsize - (char *)res_arr) / sizeof(char *) );
 
@@ -353,6 +381,7 @@
 //	}
 //	printf("__ %s %d %p %p\n", __FILE__, __LINE__, (void *)new_res_arr, 
 //		res_arr);
+	
 	if (!(flags & NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG)) {
 		new_res_arr = (char **)ALIGN(buf);
 		if (new_res_arr != res_arr) {
@@ -365,7 +394,7 @@
 	*str_array = res_arr;
 	*str_array_size = res_arr_size;
 	
-	rv = NSS_LDAP_SUCCESS;
+//	rv = NSS_LDAP_SUCCESS;
 	
 fin:
 	if (rv != NSS_LDAP_SUCCESS)
@@ -403,6 +432,7 @@
 		request->attributes->sl_str, 0,
 		rv == LDAP_SUCCESS ? server_controls : NULL, NULL, NULL,
 		LDAP_NO_LIMIT, msgid );
+	ldap_control_free(server_controls[0]);
 
 	return (rv);
 }
@@ -526,9 +556,9 @@
 					}
 					
 //				printf("== %s %d\n", __FILE__, __LINE__);
-				rv = __nss_ldap_parse_page_control(
-					ctx->conn->ld, server_controls,
-					&abs_rescount, &ctx->cookie);	
+					rv = __nss_ldap_parse_page_control(
+						ctx->conn->ld, server_controls,
+						&abs_rescount, &ctx->cookie);	
 				
 					if (rv != LDAP_SUCCESS) {
 //						printf("== %s %d\n", __FILE__, __LINE__);
@@ -736,7 +766,8 @@
 	if ((rdn == NULL) || (rdn[0] == '\0')) {
 		__nss_ldap_log(NSS_LDAP_LL_DEBUG_INT,
 			"__nss_ldap_assign_rdn_str failed: type='%s'", type);
-		return (NSS_LDAP_PARSE_ERROR);
+		rv = NSS_LDAP_PARSE_ERROR;
+		goto fin;
 	}
 
 	rv = NSS_LDAP_PARSE_ERROR;
@@ -758,7 +789,9 @@
 	if (rv == NSS_LDAP_PARSE_ERROR)	
 		__nss_ldap_log(NSS_LDAP_LL_DEBUG_INT,
 			"__nss_ldap_assign_rdn_str failed: type='%s'", type);
-		
+
+fin:	
+	ldap_memfree(rdn);
 	return (rv);
 }
 
@@ -848,6 +881,7 @@
 		"__nss_ldap_assign_attr_multi_str_ext failed: attr='%s', "
 		"rv=%d", attr, rv);
 			
+	printf("__ %s %d %d\n", __FILE__, __LINE__);
 	return (rv);
 }
 
@@ -901,7 +935,7 @@
 						ctx, attr, str_array, 
 						str_array_size, len, buf, 
 						bufsize, flags, sp_fn, mdata);
-//					printf("__ %s %d\n", __FILE__, __LINE__);
+//					printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 				} else {
 //					printf("__ %s %d %s\n",
 //						__FILE__,
@@ -918,7 +952,8 @@
 //				printf("__ %s %d\n", __FILE__, __LINE__);
 				if ((rv != NSS_LDAP_SUCCESS) ||
 					((rv == NSS_LDAP_SUCCESS) && 
-					(*str_array_size != 1))) {
+					(*str_array_size != (flags & 
+					NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG ? 0 : 1)))) {						
 					ldap_memfree(aname);
 					ber_free(cookie, 0);
 //					printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size);
@@ -944,7 +979,7 @@
 		"__nss_ldap_assign_attr_multi_str_paged failed: attr='%s', "
 		"rv=%d", attr, rv);
 
-//	printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
+	//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 //	printf("__ %s %d\n", __FILE__, __LINE__);
 	return (rv);
 }

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#13 (text+ko) ====


==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#15 (text+ko) ====


==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#15 (text+ko) ====


==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#15 (text+ko) ====

@@ -82,7 +82,7 @@
         {NSDB_GROUP_COMPAT, "endgrent", __ldap_setgrent, (void *)nss_end_ent},
         {NSDB_GROUP_COMPAT, "setgrent", __ldap_setgrent, (void *)nss_set_ent},
 	
-	{NSDB_SERVICES, "getservbyname_r", __ldap_servent, (void *)nss_lt_name},
+/*	{NSDB_SERVICES, "getservbyname_r", __ldap_servent, (void *)nss_lt_name},
 	{NSDB_SERVICES, "getservbyport_r", __ldap_servent, (void *)nss_lt_id},
 	{NSDB_SERVICES, "getservent_r", __ldap_servent, (void *)nss_lt_all},
 	{NSDB_SERVICES, "endservent", __ldap_setservent, (void *)nss_end_ent},
@@ -97,7 +97,7 @@
 	{NSDB_SERVICES_COMPAT, "endservent", __ldap_setservent, 
 		(void *)nss_end_ent},
 	{NSDB_SERVICES_COMPAT, "setservent", __ldap_setservent, 
-		(void *)nss_set_ent}
+		(void *)nss_set_ent}*/
 };
 
 static pthread_rwlock_t nss_ldap_lock = PTHREAD_RWLOCK_INITIALIZER;

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#11 (text+ko) ====




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610271226.k9RCQda4007514>