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>