PERFORCE change 109617 for review

Michael Bushkov bushman at FreeBSD.org
Thu Nov 9 14:14:47 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=109617

Change 109617 by bushman at bushman_nss_ldap_cached on 2006/11/09 14:14:23

	+ bug in nss_ldap.c fixed - buffer and mdata pointers should be updated during several getent calls with small buffers (i.e. when we return NSS_LDAP_BUFFER_ERROR)
	+ user names caching in ldap_group.c - optimizes getent() calls when groups with huge amount of members should be returned (and uniqueMember field is used)
	+ small changes in _ATM _OCM _AT and _OC behavior to respect the map argument
	+ some fixes in paged results parsing code. Several potential errors (hopefully errors) fixed (hopefully).
	+ some minor fixes in style
	- some more debugging printf's added - they will be eliminated soon

Affected files ...

.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_serv.c#11 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#13 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#11 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#17 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#16 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#16 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#17 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#13 edit

Differences ...

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

@@ -45,29 +45,63 @@
 #include "ldapconf.h"
 #include "nss_ldap.h"
 
+#define NSS_LDAP_MAP_USER_HASH_ENTRY_INITIAL_SIZE (8)
+#define NSS_LDAP_MAP_USER_HASH_SIZE (127)
+
 #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 {
+/*
+ * Hashtable-and-friends definitions for caching mapped user names
+ */
+struct mapped_user {
+	char *dn;
+	char *mapped_name;
+};
+
+struct __mu_he {
+	HASHTABLE_ENTRY_HEAD(__mu_he_item, struct mapped_user) data;
+};
+
+HASHTABLE_HEAD(__mu_ht, __mu_he);
+
+struct group_mdata_ext {
+	struct __mu_ht *users;
+	struct __pg_ht *groups;
+};
+
+/*
+ * Hashtable-and-friends definitions for nested groups processing
+ */
+struct processed_group {
 	char *dn;
 };
 
-struct __mg_he {
-	HASHTABLE_ENTRY_HEAD(__mg_he_item, struct mapped_group) data;
+struct __pg_he {
+	HASHTABLE_ENTRY_HEAD(__pg_he_item, struct processed_group) data;
 };
 
+HASHTABLE_HEAD(__pg_ht, __pg_he);
+
 struct map_group_dn_request {
 	StringList *next_requests;
-	HASHTABLE_HEAD(__mg_ht, __mg_he) groups;
+	struct __mu_ht *users;
+	struct __pg_ht *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 __mu_ht_item_cmp_func(const void *, const void *);
+static hashtable_index_t __mu_ht_item_hash_func(const void *, size_t);
+HASHTABLE_PROTOTYPE(__mu_ht, __mu_he, struct mapped_user);
+
+static int __pg_ht_item_cmp_func(const void *, const void *);
+static hashtable_index_t __pg_ht_item_hash_func(const void *, size_t);
+HASHTABLE_PROTOTYPE(__pg_ht, __pg_he, struct processed_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 *,
@@ -75,10 +109,9 @@
 	size_t *, char *, size_t);
 
 static int nss_ldap_parse_group(struct nss_ldap_parse_context *);
+static void nss_ldap_destroy_group_ctx(struct nss_ldap_parse_context *);
 	
-//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,
+static 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 **);
@@ -86,51 +119,85 @@
 static void ldap_setgrent();
 
 static int
-__mg_ht_item_cmp_func(const void *p1, const void *p2)
+__mu_ht_item_cmp_func(const void *p1, const void *p2)
+{
+	
+	return (strcmp(
+		((struct mapped_user *)p1)->dn,
+		((struct mapped_user *)p2)->dn));
+				
+}
+
+static hashtable_index_t
+__mu_ht_item_hash_func(const void *p, size_t cache_entries_size)
+{
+	struct mapped_user const *mu;
+        size_t i, len;
+        hashtable_index_t retval;
+
+        mu = p;
+        assert(mu->dn != NULL);
+
+	len = strlen(mu->dn);
+        retval = 0;
+        for (i = 0; i < len; ++i)
+            retval = (127 * retval + (unsigned char)mu->dn[i]) %
+                cache_entries_size;
+
+        return (retval);
+}
+
+static int
+__pg_ht_item_cmp_func(const void *p1, const void *p2)
 {
 	
 	return (strcmp(
-		((struct mapped_group *)p1)->dn,
-		((struct mapped_group *)p2)->dn));
+		((struct processed_group *)p1)->dn,
+		((struct processed_group *)p2)->dn));
 				
 }
 
 static hashtable_index_t
-__mg_ht_item_hash_func(const void *p, size_t cache_entries_size)
+__pg_ht_item_hash_func(const void *p, size_t cache_entries_size)
 {
-	struct mapped_group const *mg;
+	struct processed_group const *pg;
         size_t i, len;
         hashtable_index_t retval;
 
-        mg = p;
-        assert(mg->dn != NULL);
+        pg = p;
+        assert(pg->dn != NULL);
 
-	len = strlen(mg->dn);
+	len = strlen(pg->dn);
         retval = 0;
         for (i = 0; i < len; ++i)
-            retval = (127 * retval + (unsigned char)mg->dn[i]) %
+            retval = (127 * retval + (unsigned char)pg->dn[i]) %
                 cache_entries_size;
 
-        return retval;	
+        return (retval);
 }
 
-HASHTABLE_GENERATE(__mg_ht, __mg_he, struct mapped_group, data,
-	__mg_ht_item_hash_func, __mg_ht_item_cmp_func);
+HASHTABLE_GENERATE(__mu_ht, __mu_he, struct mapped_user, data,
+	__mu_ht_item_hash_func, __mu_ht_item_cmp_func);
+HASHTABLE_GENERATE(__pg_ht, __pg_he, struct processed_group, data,
+	__pg_ht_item_hash_func, __pg_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_search_request sreq;
-	struct mapped_group new_mg;
+	struct processed_group new_pg;
+	struct mapped_user new_mu;
 	struct nss_ldap_search_context *newctx;
 	struct map_group_dn_request *req;
 	char **cp;
 	char const *uid_attr, *gid_attr;
-	struct mapped_group *hash_entry_data;
-	struct __mg_he *hash_entry;
-	hashtable_index_t hash;
-	int rv;
+	struct processed_group *group_hash_entry_data;
+	struct __pg_he *group_hash_entry;
+	struct mapped_user *user_hash_entry_data;
+	struct __mu_he *user_hash_entry;
+	hashtable_index_t group_hash, user_hash;
+	int rv, rv2;
 	
 	assert(ctx != NULL);
 	assert(dn != NULL);
@@ -139,34 +206,64 @@
 	assert(buf != NULL);
 	assert(mdata != NULL);
 	
-	//printf("__ %s %d %s\n", __FILE__, __LINE__, dn);
-	
 	req = mdata;
 	newctx = NULL;
+	
+	if (req->users == NULL) {
+		req->users = malloc(sizeof(struct __mu_ht));
+		if (req->users == NULL) {
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto fin;
+		}
 
+		HASHTABLE_INIT(req->users, struct mapped_user, data, 
+			NSS_LDAP_MAP_USER_HASH_SIZE, 
+			NSS_LDAP_MAP_USER_HASH_ENTRY_INITIAL_SIZE);
+		if (!HASHTABLE_OK(req->users)) {
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto fin;
+		}
+	}
 
-	memset(&new_mg, 0, sizeof(new_mg));
-	new_mg.dn = (char *)dn;
+	memset(&sreq, 0, sizeof(sreq));	
+	memset(&new_pg, 0, sizeof(new_pg));
+	memset(&new_mu, 0, sizeof(new_mu));
+	new_pg.dn = new_mu.dn = (char *)dn;
+	
+	group_hash = HASHTABLE_CALCULATE_HASH(__pg_ht, req->groups, &new_pg);
+	assert(group_hash > 0);
+	assert(group_hash < HASHTABLE_ENTRIES_COUNT(req->groups));
 		
-	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) {
+	group_hash_entry = HASHTABLE_GET_ENTRY(req->groups, group_hash);
+	group_hash_entry_data = HASHTABLE_ENTRY_FIND(__pg_ht, group_hash_entry, 
+		&new_pg);
+//		printf("__ %s %d\n", __FILE__, __LINE__);
+	if (group_hash_entry_data != NULL) {
 		rv = NSS_LDAP_SUCCESS;
 		*res_size = 0;
-		//printf("__ %s %d\n", __FILE__, __LINE__);
+//		printf("__ %s %d\n", __FILE__, __LINE__);
+		goto fin;
+	}
+	
+	user_hash = HASHTABLE_CALCULATE_HASH(__mu_ht, req->users, &new_mu);
+	assert(user_hash > 0);
+	assert(user_hash < HASHTABLE_ENTRIES_COUNT(req->users));
+	
+	user_hash_entry = HASHTABLE_GET_ENTRY(req->users, user_hash);
+	user_hash_entry_data = HASHTABLE_ENTRY_FIND(__mu_ht, user_hash_entry,
+		&new_mu);
+	if (user_hash_entry_data != NULL) {
+		rv = __nss_ldap_assign_str(user_hash_entry_data->mapped_name, 
+			res, res_size, buf, bufsize);
 		goto fin;
 	}
 
-	memset(&sreq, 0, sizeof(sreq));	
 	sreq.scope = LDAP_SCOPE_BASE;
 	sreq.filter = "(objectClass=*)";
 	sreq.search_base = (char *)dn;
+	sreq.map = NSS_LDAP_MAP_GROUP;
 
+//	printf("__ %s %d\n", __FILE__, __LINE__);
 	uid_attr = _ATM(&ctx->conf->schema, PASSWD, uid);
 	gid_attr = _ATM(&ctx->conf->schema, GROUP, gidNumber);
 	sreq.attributes = sl_init();
@@ -176,12 +273,14 @@
 		goto fin;
 	}
 
+//	printf("__ %s %d\n", __FILE__, __LINE__);
 	rv = sl_add(sreq.attributes, (char *)gid_attr);
 	if (rv == -1) {
 		rv = NSS_LDAP_MEMORY_ERROR;
 		goto fin;
 	}		
 
+//	printf("__ %s %d\n", __FILE__, __LINE__);
 	rv = sl_add(sreq.attributes, "objectClass");
 	if (rv == -1) {
 		rv = NSS_LDAP_MEMORY_ERROR;
@@ -207,6 +306,7 @@
 		goto fin2;
 	}
 	
+//	printf("__ %s %d\n", __FILE__, __LINE__);
 	rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, 
 		newctx);
 	if (rv != NSS_LDAP_SUCCESS) {
@@ -215,18 +315,19 @@
 		goto fin2;
 	}
 
-	new_mg.dn = strdup(dn);
-	if (new_mg.dn == NULL) {
+	new_pg.dn = strdup(dn);
+	if (new_pg.dn == NULL) {
 		rv = NSS_LDAP_MEMORY_ERROR;
 		goto fin2;
 	}		
 
+//	printf("__ %s %d\n", __FILE__, __LINE__);
 	if (__nss_ldap_check_oc(newctx, _OC(&ctx->conf->schema, posixGroup)) == 
 		NSS_LDAP_SUCCESS) {
 		
-		rv = sl_add(req->next_requests, new_mg.dn);
+		rv = sl_add(req->next_requests, new_pg.dn);
 		if (rv == -1) {
-			free(new_mg.dn);
+			free(new_pg.dn);
 			rv = NSS_LDAP_MEMORY_ERROR;
 			goto fin2;
 		}
@@ -237,12 +338,35 @@
 		rv = __nss_ldap_assign_attr_str(newctx, uid_attr, res, 
 			res_size, buf, bufsize);
 
-		rv = HASHTABLE_ENTRY_STORE(__mg_ht, hash_entry, &new_mg);
-		if (rv == -1) {
-			free(new_mg.dn);
-			rv = NSS_LDAP_MEMORY_ERROR;	
-		} else
-			rv = NSS_LDAP_SUCCESS;
+		rv2 = HASHTABLE_ENTRY_STORE(__pg_ht, group_hash_entry, &new_pg);
+		if (rv2 == -1) {
+			free(new_pg.dn);
+			if (rv == NSS_LDAP_SUCCESS)
+				rv = NSS_LDAP_MEMORY_ERROR;	
+			goto fin2;
+		}
+
+		if (rv == NSS_LDAP_SUCCESS) {		
+			new_mu.dn = strdup(dn);
+			if (new_mu.dn == NULL) {
+				rv = NSS_LDAP_MEMORY_ERROR;
+				goto fin2;
+			}
+			new_mu.mapped_name = strdup(*res);
+			if (new_mu.mapped_name == NULL) {
+				free(new_mu.dn);
+				rv = NSS_LDAP_MEMORY_ERROR;
+				goto fin2;
+			}
+			rv2 = HASHTABLE_ENTRY_STORE(__mu_ht, user_hash_entry, 
+				&new_mu);
+			if (rv2 == -1) {
+				free(new_mu.dn);
+				free(new_mu.mapped_name);
+				rv = NSS_LDAP_MEMORY_ERROR;	
+				goto fin2;
+			}
+		}
 	}
 	
 fin:
@@ -250,9 +374,11 @@
 		sl_free(sreq.attributes, 0);
 		
 fin2:
+//	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);
 }
 
@@ -270,6 +396,7 @@
 	sreq.scope = LDAP_SCOPE_BASE;
 	sreq.filter = "(objectClass=*)";
 	sreq.search_base = (char *)dn;
+	sreq.map = NSS_LDAP_MAP_GROUP;
 	
 	//printf("__ %s %d\n", __FILE__, __LINE__);
 	newctx = __nss_ldap_start_search(&__nss_ldap_conf->search_method,
@@ -285,7 +412,6 @@
 		goto fin;
 	}
 
-	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,
@@ -295,7 +421,6 @@
 		nss_ldap_map_group_dn, (void *)dnreq);
 	
 fin:
-	printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 	if (newctx != NULL)
 		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
 
@@ -307,23 +432,25 @@
 static int
 nss_ldap_parse_group(struct nss_ldap_parse_context *pctx)
 {
+	struct group_mdata_ext *gmdata;
 	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;
+	struct __pg_he *group_hash_entry;
+	struct processed_group *group_hash_data;
 	size_t len, memlen, res_memlen, nr_offset;
 	int rv;
 	
 	assert(pctx != NULL);
 	
 	sctx = pctx->sctx;
-	grp = (struct group *)pctx->mdata;
+	grp = pctx->mdata;
 	buf = pctx->buffer;
-	rbuf = buf + pctx->bufsize;
+	rbuf = buf + pctx->bufsize;	
+	gmdata = pctx->mdata_ext;
 	
 	schema = &sctx->conf->schema;
 //	printf("__ %s %d\n", __FILE__, __LINE__);
@@ -340,7 +467,7 @@
 		&grp->gr_name, &len, buf, rbuf - buf);
 	if (rv != NSS_LDAP_SUCCESS)
 		goto errfin;
-	//printf("__ %s %d\n", __FILE__, __LINE__);
+//	printf("__ %s %d %s\n", __FILE__, __LINE__, grp->gr_name);
 	buf += len;
 	
 	rv = __nss_ldap_assign_attr_password(sctx,
@@ -359,37 +486,54 @@
 		&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) {
-//				printf("__ %s %d %p\n", __FILE__, __LINE__, (void *)*cp);
-//				printf("__ %s %d %s\n", __FILE__, __LINE__, *cp);
-//			}
-
 		rbuf = (char *)res;
 		buf += len;
 		
 		grp->gr_mem = res;
 	}
 
+	if (gmdata == NULL) {
+		gmdata = malloc(sizeof(struct group_mdata_ext));
+		if (gmdata == NULL) {
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto errfin;
+		}
+		memset(gmdata, 0, sizeof(struct group_mdata_ext));
+		pctx->mdata_ext = gmdata;
+		
+		gmdata->groups = malloc(sizeof(struct __pg_ht));
+		if (gmdata->groups == NULL) {
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto errfin;
+		}
+
+		HASHTABLE_INIT(gmdata->groups, struct processed_group, data, 
+			NSS_LDAP_MAP_GROUP_HASH_SIZE, 
+			NSS_LDAP_MAP_GROUP_HASH_ENTRY_INITIAL_SIZE);
+		if (!HASHTABLE_OK(gmdata->groups)) {
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto errfin;
+		}
+	} else
+		HASHTABLE_FOREACH(gmdata->groups, group_hash_entry) {
+			HASHTABLE_ENTRY_FOREACH(group_hash_entry, data,
+				group_hash_data)
+				free(group_hash_data->dn);
+		
+			HASHTABLE_ENTRY_CLEAR(group_hash_entry, data);
+		}
+	
 	nr_offset = 0;
 	memset(&dnreq, 0, sizeof(struct nss_ldap_dn2attr_request));
 	dnreq.flags = NSS_LDAP_MAP_GROUP_DN_PROCESS_NESTED_FLAG;
+	dnreq.groups = gmdata->groups;
+	dnreq.users = gmdata->users;	
 	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;
@@ -401,25 +545,18 @@
 			(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) {
 			res_memlen += memlen;
 			grp->gr_mem = res;
 			rbuf = (char *)res;
 			buf += len;
-//			char **cp;
-//			for (cp = res; *cp; ++cp) {
-//				printf("__ %s %d %p\n", __FILE__, __LINE__, (void *)*cp);
-//				printf("==__ %s %d %s\n", __FILE__, __LINE__, *cp);
-//			}
 
 			//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,
@@ -456,6 +593,12 @@
 //				printf("__ %s %d %s\n", __FILE__, __LINE__, *cp);
 		}
 
+//		char **cp;
+//		for (cp = grp->gr_mem; *cp; ++cp) {
+//			printf("__ %s %d %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) && (rv != NSS_LDAP_BUFFER_ERROR)) {
 			new_res = (char **)ALIGN(rbuf);
 			if (new_res != grp->gr_mem) {
@@ -465,25 +608,71 @@
 			}
 			rv = NSS_LDAP_SUCCESS;
 		}
+		
+		/*
+		 * Users hash table could be allocated by
+		 * nss_ldap_map_group_dn
+		 */
+		gmdata->users = dnreq.users;
 	}
 
-	HASHTABLE_FOREACH(&dnreq.groups, hash_entry) {
-		HASHTABLE_ENTRY_FOREACH(hash_entry, data, hash_data)
-			free(hash_data->dn);
+	sl_free(dnreq.next_requests, 0);
+errfin:
+//	printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
+	return (rv);
+}
 
-		HASHTABLE_ENTRY_CLEAR(hash_entry, data);
-	}
+static void
+nss_ldap_destroy_group_ctx(struct nss_ldap_parse_context *pctx)
+{
+	struct group_mdata_ext *gmdata;
+	
+	struct __mu_he *user_hash_entry;
+	struct mapped_user *user_hash_data;
+		
+	struct __pg_he *group_hash_entry;
+	struct processed_group *group_hash_data;
 	
+	assert(pctx != NULL);
+	printf("%s %d\n", __FILE__, __LINE__);
+	if (pctx->mdata_ext != NULL) {
+		gmdata = pctx->mdata_ext;
 	
-	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);
+		printf("%s %d\n", __FILE__, __LINE__);		
+		if (gmdata->users != NULL) {
+			HASHTABLE_FOREACH(gmdata->users, user_hash_entry) {
+				HASHTABLE_ENTRY_FOREACH(user_hash_entry, data, 
+					user_hash_data) {
+					free(user_hash_data->dn);
+					free(user_hash_data->mapped_name);
+				}
+
+				HASHTABLE_ENTRY_CLEAR(user_hash_entry, data);
+			}		
+			HASHTABLE_DESTROY(gmdata->users, data);
+			free(gmdata->users);
+			printf("%s %d\n", __FILE__, __LINE__);
+		}
+		
+		printf("%s %d\n", __FILE__, __LINE__);
+		if (gmdata->groups != NULL) {
+			HASHTABLE_FOREACH(gmdata->groups, group_hash_entry) {
+				HASHTABLE_ENTRY_FOREACH(group_hash_entry, data,
+					group_hash_data)
+					free(group_hash_data->dn);
+			
+				HASHTABLE_ENTRY_CLEAR(group_hash_entry, data);
+			}
+			HASHTABLE_DESTROY(gmdata->groups, data);
+			free(gmdata->groups);
+			printf("%s %d\n", __FILE__, __LINE__);
+		}
+		
+		free(gmdata);
+	}
 }
 
-//static int 
-int
+static int 
 ldap_getgrnam_r(const char *name, struct group *grp, 
 	char *buffer, size_t bufsize, struct group **result)
 {
@@ -500,7 +689,8 @@
 		sizeof(filter), name);
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_GROUP, filter, (void *)grp, 
-		buffer, bufsize, nss_ldap_parse_group);
+		buffer, bufsize, nss_ldap_parse_group,
+		nss_ldap_destroy_group_ctx);
 	
 	if (rv == NS_SUCCESS)
 		*result = grp;
@@ -525,7 +715,8 @@
 		sizeof(filter), gid);
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_GROUP, filter, (void *)grp, 
-		buffer, bufsize, nss_ldap_parse_group);
+		buffer, bufsize, nss_ldap_parse_group,
+		nss_ldap_destroy_group_ctx);
 	
 	if (rv == NS_SUCCESS)
 		*result = grp;
@@ -546,7 +737,8 @@
 		return (NS_UNAVAIL);
 	
 	rv = __nss_ldap_getent(NSS_LDAP_MAP_GROUP, filter, (void *)grp, 
-		buffer, bufsize, nss_ldap_parse_group, NULL);
+		buffer, bufsize, nss_ldap_parse_group,
+		nss_ldap_destroy_group_ctx);
 	
 	if (rv == NS_SUCCESS)
 		*result = grp;

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

@@ -200,7 +200,7 @@
 		sizeof(filter), name);
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_PASSWD, filter, (void *)pwd, 
-		buffer, bufsize, nss_ldap_parse_passwd);
+		buffer, bufsize, nss_ldap_parse_passwd, NULL);
 	
 	if (rv == NS_SUCCESS)
 		*result = pwd;
@@ -225,7 +225,7 @@
 		sizeof(filter), uid);
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_PASSWD, filter, (void *)pwd, 
-		buffer, bufsize, nss_ldap_parse_passwd);
+		buffer, bufsize, nss_ldap_parse_passwd, NULL);
 	
 	if (rv == NS_SUCCESS)
 		*result = pwd;

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

@@ -59,7 +59,7 @@
 };
 
 static int nss_ldap_parse_servent(struct nss_ldap_parse_context *);
-static void nss_ldap_destroy_servent(struct nss_ldap_parse_context *);
+static void nss_ldap_destroy_servent_ctx(struct nss_ldap_parse_context *);
 	
 static int ldap_getservbyname_r(const char *, const char *, struct servent *, 
 	char *, size_t, struct servent **);
@@ -147,9 +147,9 @@
 			if (++serv_mdata_ext->offset >= serv_mdata_ext->count) {
 				serv_mdata_ext->offset = -1;
 				serv_mdata_ext->count = 0;
-				pctx->need_no_more = 0;
+				pctx->need_no_more = NSS_LDAP_NEED_NO_MORE_OFF;
 			} else
-				pctx->need_no_more = 1;
+				pctx->need_no_more = NSS_LDAP_NEED_NO_MORE_ON;
 			
 			buflen -= len;
 			buf += len;			
@@ -190,7 +190,7 @@
 }
 
 static void
-nss_ldap_destroy_servent(struct nss_ldap_parse_context *pctx)
+nss_ldap_destroy_servent_ctx(struct nss_ldap_parse_context *pctx)
 {
 	
 	assert(pctx != NULL);
@@ -225,7 +225,7 @@
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_SERVICES, filter,
 		(void *)&mdata, buffer, bufsize, 
-		nss_ldap_parse_servent);
+		nss_ldap_parse_servent, NULL);
 	
 	if (rv == NS_SUCCESS)
 		*result = serv;
@@ -261,7 +261,7 @@
 	
 	rv = __nss_ldap_getby(NSS_LDAP_MAP_SERVICES, filter, 
 		(void *)&mdata, buffer, bufsize,
-		nss_ldap_parse_servent);
+		nss_ldap_parse_servent, NULL);
 	
 	printf("== %d\n", rv);
 	if (rv == NS_SUCCESS)
@@ -289,7 +289,7 @@
 
 	rv = __nss_ldap_getent(NSS_LDAP_MAP_SERVICES, filter, (void *)&mdata, 
 		buffer, bufsize, nss_ldap_parse_servent,
-		nss_ldap_destroy_servent);
+		nss_ldap_destroy_servent_ctx);
 		
 	if (rv == NS_SUCCESS)
 		*result = serv;

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

@@ -353,18 +353,28 @@
 
 struct nss_ldap_schema_rule *
 __nss_ldap_find_rule(struct nss_ldap_rules_collection *rules,
-	char const *left_arg)
+	char const *left_arg, int map)
 {
+	struct nss_ldap_schema_rule *first_chance;
 	size_t i;
 	
 	assert(rules != NULL);
 	assert(left_arg != NULL);
 	
+	/* 
+	 * Concrete rules mappings (with .map != NSS_LDAP_MAP_NONE) take
+	 * precedence of global mappings (with .map == NSS_LDAP_MAP_NONE).
+	 */	
+	first_chance = NULL;
 	for (i = 0; i < rules->rules_size; ++i)
-		if (strcmp(rules->rules[i].left_arg, left_arg) == 0)
-			return (&rules->rules[i]);
+		if (strcmp(rules->rules[i].left_arg, left_arg) == 0) {
+			if (rules->rules[i].map == map)
+				return (&rules->rules[i]);
+			else if (rules->rules[i].map == NSS_LDAP_MAP_NONE)
+				first_chance = &rules->rules[i];
+		}
 	
-	return (NULL);
+	return (first_chance);
 }
 	
 void 
@@ -394,7 +404,7 @@
 	result = __nss_ldap_find_rule(
 		__nss_ldap_get_schema_rules(schema,
 		    NSS_LDAP_SCHEMA_MAP_ATTRIBUTE_RULES),
-		key);
+		key, map);
 	
 	return (result == NULL ? key : result->right_arg);
 }
@@ -413,7 +423,7 @@
 	result = __nss_ldap_find_rule(
 		__nss_ldap_get_schema_rules(schema,
 		    NSS_LDAP_SCHEMA_MAP_OBJECTCLASS_RULES),
-		key);
+		key, NSS_LDAP_MAP_NONE);
 	
 	return (result == NULL ? key : result->right_arg);
 }

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

@@ -67,6 +67,7 @@
 {
 	char *left_arg;
 	char *right_arg;
+	int map;
 };
 
 struct nss_ldap_rules_collection
@@ -116,7 +117,7 @@
 	size_t );
 struct nss_ldap_schema_rule *__nss_ldap_find_rule(
 	struct nss_ldap_rules_collection *,
-	char const *);
+	char const *, int);
 extern void __nss_ldap_destroy_rules_collection(
 	struct nss_ldap_rules_collection *);
 	

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

@@ -77,6 +77,7 @@
 		return (NSS_LDAP_MEMORY_ERROR);
 	
 	dest->scope = src->scope;
+	dest->map = src->map;
 	
 	dest->filter = strdup(src->filter);
 	if (dest->filter == NULL)
@@ -91,9 +92,13 @@
 			s = strdup(*cp);
 			if (s == NULL)
 				return (NSS_LDAP_MEMORY_ERROR);
-			if (sl_add(dest->attributes,s) != 0)
+			if (sl_add(dest->attributes, s) != 0) {
+				free(s);
 				return (NSS_LDAP_MEMORY_ERROR);
+			}
 		}
+		if (sl_add(dest->attributes, NULL) != 0)
+				return (NSS_LDAP_MEMORY_ERROR);
 	} else
 		dest->attributes = NULL;
 	
@@ -154,7 +159,10 @@
 		}
 		if (!(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG))
 			*(siter + 1) = NULL;
+
+		//printf("%s %d\n", __FILE__, __LINE__);
 		rbuf = (char *)siter;
+		*str_array = siter + 1;
 	} else  {
 		siter = (char **)ALIGN(buf);
 		if ((char *)siter +  size >= rbuf) {
@@ -167,12 +175,16 @@
 		}
 		
 		buf = (char *)siter + size;
+		*str_array = siter;
 	}
 
-	*str_array = siter;
-		
+	//printf("%s %d\n", __FILE__, __LINE__);	
+
 	if (values != NULL) {
+		//printf("%s %d\n", __FILE__, __LINE__);
 		for (viter = values; *viter; ++viter) {
+			//printf("%s %d %p %p\n", __FILE__, __LINE__, (void *)*siter, (void *)**str_array);
+			//printf("%s %d %p %p\n", __FILE__, __LINE__, (void *)siter, (void *)*str_array);			
 			if (sp_fn == NULL)
 				rv = __nss_ldap_assign_str(*viter, siter, &size,
 					buf, rbuf - buf);
@@ -181,17 +193,16 @@
 					rbuf - buf, mdata);
 			
 			if (rv != NSS_LDAP_SUCCESS) {
-				//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
               			ldap_value_free(values);
               			goto fin;                       
               		}
 								
 			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) {
+				NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {				
+				--*str_array;
 				--siter;
 				if ((char *)siter <= buf) {
 					rv = NSS_LDAP_BUFFER_ERROR;
@@ -206,13 +217,21 @@
 		
 		ldap_value_free(values);
 	}
-
+	
 	if (!(flags & (NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG | 
 		NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG)))
 		*siter = NULL;
 		
+//	if (rv == NSS_LDAP_SUCCESS) {
+//		char **cp;
+//		for (cp = *str_array; *cp; ++cp) {
+//			printf("_____ %s %d %p %d\n", __FILE__, __LINE__, (void *)*cp, flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG);
+//			printf("_____ %s %d %s\n", __FILE__, __LINE__, *cp);
+//		}
+//	}
+
 	if (flags & NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {
-		*str_array = siter + 1;
+//		*str_array = siter + 1;
 		if (!(flags & NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG)) {
 			new_res_arr = (char **)ALIGN(buf);
 		
@@ -220,18 +239,15 @@
 				memmove(new_res_arr, *str_array, 
 					sizeof(char *) * (*str_array_size));
 				*str_array = new_res_arr;
-			}
-			
+			}			
 		}
 	}
 	
 	*len = buf - sbuf;
 	//printf("%s %d %d %d %p %p %d %d\n", __FILE__, __LINE__, *len, *str_array_size, (void *)(sbuf + bufsize), (void *)*str_array, (size_t)(sbuf + bufsize - (char *)(*str_array)), (size_t)(sbuf + bufsize - (char *)(*str_array))/ sizeof( char *));
 	rv = NSS_LDAP_SUCCESS;
-	//printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size);
 
 fin:
-	//printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 	return (rv);
 }
 
@@ -250,12 +266,10 @@
 	size_t res_arr_size, res_buf_size, res_buf_offset, res_arr_offset;
 	int range_start, range_end, rv, sf;
 	
-	//printf("__ %s %d %s %s\n", __FILE__, __LINE__, attr, attr_model);
 	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;
@@ -267,11 +281,11 @@
 		rv = do_assign_attr_multi_str(ctx, attr,
 			&res_arr, &res_arr_offset, &res_buf_offset, 
 			buf, rbuf - buf,
-			(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG) |
+			(flags & ~NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG) |
 			(sf == 0 ? NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG :
 			    NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG |
 			    NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG) | 
-			NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG,
+			    NSS_LDAP_ATTR_MULTI_STR_DONT_PACK_PTRS_FLAG,
 			sp_fn, mdata);
 		if (rv != NSS_LDAP_SUCCESS)
 			break;
@@ -285,6 +299,7 @@
 				
 		sreq.scope = LDAP_SCOPE_BASE;
 		sreq.filter = "(objectClass=*)";
+		sreq.map = ctx->search_request.map;
 		sreq.search_base = ldap_get_dn(ctx->conn->ld, ctx->msg);
 		if (sreq.search_base == NULL) {
 			rv = NSS_LDAP_CONNECTION_ERROR;
@@ -354,7 +369,6 @@
 		if (attr == NULL)
 			break;
 					
-//		printf("__ %s %d\n", __FILE__, __LINE__);
 		rv = __nss_ldap_parse_range(attr, &range_start, &range_end);
 		if (rv != NSS_LDAP_SUCCESS)
 			break;

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list