From owner-p4-projects@FreeBSD.ORG Thu Nov 9 14:14:47 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A01D816A4C9; Thu, 9 Nov 2006 14:14:47 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 76E6316A49E for ; Thu, 9 Nov 2006 14:14:47 +0000 (UTC) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4019E43D77 for ; Thu, 9 Nov 2006 14:14:47 +0000 (GMT) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kA9EElYe017239 for ; Thu, 9 Nov 2006 14:14:47 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kA9EEkCZ017236 for perforce@freebsd.org; Thu, 9 Nov 2006 14:14:46 GMT (envelope-from bushman@freebsd.org) Date: Thu, 9 Nov 2006 14:14:46 GMT Message-Id: <200611091414.kA9EEkCZ017236@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bushman@freebsd.org using -f From: Michael Bushkov To: Perforce Change Reviews Cc: Subject: PERFORCE change 109617 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Nov 2006 14:14:47 -0000 http://perforce.freebsd.org/chv.cgi?CH=109617 Change 109617 by bushman@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) <<<