From owner-p4-projects@FreeBSD.ORG Fri Oct 20 11:12:31 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 0D77816A54B; Fri, 20 Oct 2006 11:12:31 +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 C2FC216A546 for ; Fri, 20 Oct 2006 11:12:30 +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 7CD7F43D6A for ; Fri, 20 Oct 2006 11:12:21 +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 k9KBCL0f013701 for ; Fri, 20 Oct 2006 11:12:21 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9KBCKVl013698 for perforce@freebsd.org; Fri, 20 Oct 2006 11:12:20 GMT (envelope-from bushman@freebsd.org) Date: Fri, 20 Oct 2006 11:12:20 GMT Message-Id: <200610201112.k9KBCKVl013698@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 108172 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: Fri, 20 Oct 2006 11:12:31 -0000 http://perforce.freebsd.org/chv.cgi?CH=108172 Change 108172 by bushman@bushman_nss_ldap_cached on 2006/10/20 11:11:40 + Support for Range option for groups members parsing added. Needs debugging. + Issue with proper return of (NS_RETURN) and setting errno to ERANGE fixed. + Lot of debugging printfs - will be deleted when everything works as expected. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#11 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#10 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#12 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_serv.c#9 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#14 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#13 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#12 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#12 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#11 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.c#9 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#13 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#13 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#14 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#11 (text+ko) ==== @@ -34,6 +34,7 @@ #include #include #include +#include #include "ldapconn.h" #include "ldapschema.h" #include "ldapsearch.h" @@ -64,6 +65,40 @@ assert(pctx != NULL); +/* 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); + + 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); + + printf("3\n"); + res = __nss_ldap_parse_range("member;range=-*", &start, &end); + printf("res: %d, start: %d, end: %d\n", res, start, end); + + printf("4\n"); + res = __nss_ldap_parse_range("member;range=1-", &start, &end); + printf("res: %d, start: %d, end: %d\n", res, start, end); + + printf("5\n"); + res = __nss_ldap_parse_range("member;range=*-*", &start, &end); + printf("res: %d, start: %d, end: %d\n", res, start, end); + + 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("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); + + 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);*/ + sctx = pctx->sctx; grp = (struct group *)pctx->mdata; buf = pctx->buffer; @@ -92,8 +127,9 @@ goto errfin; buflen -= len; buf += len; - - rv = __nss_ldap_assign_attr_multi_str(sctx, + + //rv = __nss_ldap_assign_attr_multi_str(sctx, + rv = __nss_ldap_assign_attr_multi_str_paged(sctx, _ATM(schema, GROUP, memberUid), &grp->gr_mem, &memlen, &len, buf, buflen); if (rv != NSS_LDAP_SUCCESS) @@ -102,6 +138,7 @@ buf += len; errfin: + //printf("__ %s %d %d\n", __FILE__, __LINE__, rv); return (rv); } ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#10 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#12 (text+ko) ==== @@ -33,6 +33,8 @@ #include #include #include +#include + #include "ldapconn.h" #include "ldapschema.h" #include "ldapsearch.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_serv.c#9 (text+ko) ==== @@ -33,6 +33,7 @@ #include #include #include +#include #include "ldapconn.h" #include "ldapschema.h" #include "ldapsearch.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#14 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include #include +#include #include "ldapschema.h" #include "ldapconn.h" #include "ldapsearch.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#13 (text+ko) ==== @@ -37,6 +37,7 @@ #include #include #include +#include #include "ldapschema.h" #include "ldapsearch.h" #include "ldaptls.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#12 (text+ko) ==== @@ -33,6 +33,7 @@ #include #include #include +#include #include "ldapschema.h" #include "ldapsearch.h" #include "nss_ldap.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#12 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include #include +#include #include "ldapschema.h" #include "ldapconn.h" #include "ldapsearch.h" @@ -42,10 +43,18 @@ #include "ldapconf.h" #include "nss_ldap.h" +#define DO_ASSIGN_ATTR_MULTI_STR_END_WITH_PTRS (1) +#define DO_ASSIGN_ATTR_MULTI_STR_NO_END_NULL (1 << 1) + static int copy_request(struct nss_ldap_search_request *, struct nss_ldap_search_request const *); static void destroy_request(struct nss_ldap_search_request *); +static int do_assign_attr_multi_str(struct nss_ldap_search_context *, + char const *, char ***, size_t *, size_t *, char *, size_t, int); +static int do_assign_attr_multi_str_paged(struct nss_ldap_search_context *, + char const *, char const *, char ***, size_t *, size_t *, char *, + size_t); static int do_ldap_search_ext(struct nss_ldap_connection *, struct nss_ldap_configuration *, struct nss_ldap_search_request *, struct nss_ldap_search_context *, int *); @@ -60,6 +69,7 @@ copy_request(struct nss_ldap_search_request *dest, struct nss_ldap_search_request const *src) { + char **cp, *s; assert(dest != NULL); assert(src != NULL); @@ -74,6 +84,21 @@ if (dest->filter == NULL) return (NSS_LDAP_MEMORY_ERROR); + if (src->attributes != NULL) { + dest->attributes = sl_init(); + if (dest->attributes == NULL) + return (NSS_LDAP_MEMORY_ERROR); + + for (cp = dest->attributes->sl_str; *cp; ++cp) { + s = strdup(*cp); + if (s == NULL) + return (NSS_LDAP_MEMORY_ERROR); + if (sl_add(dest->attributes,s) != 0) + return (NSS_LDAP_MEMORY_ERROR); + } + } else + dest->attributes = NULL; + return (NSS_LDAP_SUCCESS); } @@ -85,8 +110,216 @@ free(request->search_base); free(request->filter); + if (request->attributes != NULL) + sl_free(request->attributes, 1); +} + +static int +do_assign_attr_multi_str(struct nss_ldap_search_context *ctx, + char const *attr, char ***str_array, size_t *str_array_size, + size_t *len, char *buf, size_t bufsize, int flags) +{ + char **values, **viter, **siter, **siter_end; + size_t size, valsize; + int rv; + + 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 & DO_ASSIGN_ATTR_MULTI_STR_NO_END_NULL)) + ++*str_array_size; + *len = sizeof(char *) * (*str_array_size); + + //printf("__ %s %d %d\n", __FILE__, __LINE__, valsize); + if (flags & DO_ASSIGN_ATTR_MULTI_STR_END_WITH_PTRS) { + siter_end = (char **)ALIGN(buf + bufsize); + while ((char *)siter_end > buf + bufsize - sizeof(char *)) + --siter_end; + + siter = siter_end - valsize; + //printf("__ %s %d %p %p\n", __FILE__, __LINE__, (void *)buf, (void *)siter); + if ((char *)siter <= buf) { + //printf("__ %s %d %d\n", __FILE__, __LINE__, valsize); + ldap_value_free(values); + __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, + "do_assign_attr_multi_str: " + "buffer size exceeded"); + //printf("__ %s %d\n", __FILE__, __LINE__); + return (NSS_LDAP_BUFFER_ERROR); + } + } else { + siter = (char **)ALIGN(buf); + if ((char *)siter + *len > buf + bufsize) { + ldap_value_free(values); + __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, + "do_assign_attr_multi_str: " + "buffer size exceeded"); + //printf("__ %s %d\n", __FILE__, __LINE__); + return (NSS_LDAP_BUFFER_ERROR); + } + } + + *str_array = siter; + + if (!(flags & DO_ASSIGN_ATTR_MULTI_STR_END_WITH_PTRS)) + buf = (char *)siter + *len; + bufsize -= *len; + + if (values != NULL) { + for (viter = values; *viter; ++viter, ++siter) { + rv = __nss_ldap_assign_str(*viter, siter, &size, + buf, bufsize); + //printf("__ %s %d %d\n", __FILE__, __LINE__, bufsize); + if (rv != NSS_LDAP_SUCCESS) { + ldap_value_free(values); + //printf("__ %s %d %d\n", __FILE__, __LINE__, valsize); + goto fin; + } + + buf += size; + *len += size; + bufsize -= size; + } + + ldap_value_free(values); + } + + if (!(flags & DO_ASSIGN_ATTR_MULTI_STR_NO_END_NULL)) + *siter = NULL; + rv = NSS_LDAP_SUCCESS; + //printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size); + +fin: + //printf("__ %s %d\n", __FILE__, __LINE__); + return (rv); } +static int +do_assign_attr_multi_str_paged(struct nss_ldap_search_context *ctx, + char const *attr_model, char const *attr, char ***str_array, + size_t *str_array_size, size_t *len, char *buf, size_t bufsize) +{ + char range_buffer[128]; + struct nss_ldap_search_request sreq; + struct nss_ldap_search_context *newctx; + BerElement *cookie; + char **res_arr, **new_res_arr; + size_t res_arr_size, res_buf_size, res_buf_offset, res_arr_offset; + int range_start, range_end, rv, sf; + + rv = __nss_ldap_parse_range(attr, &range_start, &range_end); + if (rv != NSS_LDAP_SUCCESS) + return (rv); + + res_arr_size = 0; + res_buf_size = 0; + sf = 0; + do { +st: + rv = do_assign_attr_multi_str(ctx, attr, + &res_arr, &res_arr_offset, &res_buf_offset, buf, + bufsize, sf == 0 ? + DO_ASSIGN_ATTR_MULTI_STR_END_WITH_PTRS : + DO_ASSIGN_ATTR_MULTI_STR_END_WITH_PTRS | + DO_ASSIGN_ATTR_MULTI_STR_NO_END_NULL); + if (rv != NSS_LDAP_SUCCESS) + goto fin; + + res_arr_size += res_arr_offset; + res_buf_size += res_buf_offset; + + 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); + if (sreq.search_base == NULL) { + rv = NSS_LDAP_CONNECTION_ERROR; + break; + } + + sreq.attributes = sl_init(); + rv = __nss_ldap_form_range(range_buffer, sizeof(range_buffer), + range_end + 1, -1); + if (rv == -1) { + rv = NSS_LDAP_GENERIC_ERROR; + break; + } + rv = sl_add(sreq.attributes, range_buffer); + if (rv == -1) { + rv = NSS_LDAP_MEMORY_ERROR; + break; + } + rv = sl_add(sreq.attributes, NULL); + if (rv == -1) { + rv = NSS_LDAP_MEMORY_ERROR; + break; + } + + newctx = __nss_ldap_start_search(&__nss_ldap_conf->search_method, + ctx->conn, ctx->conf, &sreq); + sl_free(sreq.attributes, 1); + ldap_memfree(sreq.search_base); + if (newctx == NULL) { + rv = NSS_LDAP_CONNECTION_ERROR; + break; + } + + if (sf != 0) { + __nss_ldap_end_search(&__nss_ldap_conf->search_method, + ctx); + + attr = NULL; + sf = 1; + } + ctx = newctx; + + rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, + ctx); + if (rv != NSS_LDAP_SUCCESS) + break; + + attr = ldap_first_attribute(ctx->conn->ld, ctx->msg, &cookie); + ber_free(cookie, 0); + + if (attr == NULL) + break; + + rv = __nss_ldap_parse_range(attr, &range_start, &range_end); + if (rv != NSS_LDAP_SUCCESS) + break; + goto st; + } while (range_end != -1); + + if (sf != 0) { + if (ctx != NULL) + __nss_ldap_end_search(&__nss_ldap_conf->search_method, + ctx); + if (attr != NULL) + ldap_memfree((char *)attr); + } + + + new_res_arr = (char **)ALIGN(buf + res_buf_size - sizeof(char *) * + res_arr_size); + if (new_res_arr != res_arr) + memmove(new_res_arr, res_arr, sizeof(char *) * res_arr_size); + *str_array = res_arr; + *str_array_size = res_arr_size; + *len = res_buf_size; + rv = NSS_LDAP_SUCCESS; + +fin: + if (rv != NSS_LDAP_SUCCESS) + __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, + "do_assign_attr_multi_str_paged failed: attr='%s', rv=%d", + attr, rv); + + return (rv); +} + static int do_ldap_search_ext(struct nss_ldap_connection *conn, struct nss_ldap_configuration *conf, @@ -110,7 +343,8 @@ } rv = ldap_search_ext( conn->ld, request->search_base, request->scope, - request->filter, NULL, 0, + request->filter, request->attributes == NULL ? NULL : + request->attributes->sl_str, 0, rv == LDAP_SUCCESS ? server_controls : NULL, NULL, NULL, LDAP_NO_LIMIT, msgid ); @@ -439,7 +673,7 @@ if (values != NULL) { type_len = strlen(type); for (viter = values; *viter; ++viter) - if ((strncmp(*viter, type, type_len) == 0) && + if ((strncasecmp(*viter, type, type_len) == 0) && (*(*viter + type_len) != '\0')) { res = *viter + type_len + 1; rv = __nss_ldap_assign_str(res, str, len, buf, @@ -515,8 +749,6 @@ char const *attr, char ***str_array, size_t *str_array_size, size_t *len, char *buf, size_t bufsize) { - char **values, **viter, **siter; - size_t size, valsize; int rv; assert(ctx != NULL); @@ -525,51 +757,92 @@ assert(str_array_size != NULL); assert(len != NULL); assert(buf != NULL); + + rv = do_assign_attr_multi_str(ctx, attr, str_array, str_array_size, + len, buf, bufsize, 0); + if (rv != NSS_LDAP_SUCCESS) + __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, + "__nss_ldap_assign_attr_multi_str failed: attr='%s', rv=%d", + attr, rv); + + return (rv); +} + +int +__nss_ldap_assign_attr_multi_str_paged(struct nss_ldap_search_context *ctx, + char const *attr, char ***str_array, size_t *str_array_size, + size_t *len, char *buf, size_t bufsize) +{ + BerElement *cookie; + char *aname; + size_t attr_len; + int rv; - values = (char **)ldap_get_values(ctx->conn->ld, ctx->msg, attr); - valsize = values == NULL ? 0 : ldap_count_values(values); + assert(ctx != NULL); + assert(attr != NULL); + assert(str_array != NULL); + assert(str_array_size != NULL); + assert(len != NULL); + assert(buf != NULL); - siter = (char **)ALIGN(buf); - - *str_array = siter; - *str_array_size = valsize + 1; - *len = sizeof(char *) * (*str_array_size); - - if ((char *)siter + *len > buf + bufsize) { - ldap_value_free(values); - __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, - "__nss_ldap_assign_attr_multi_str: " - "buffer size exceeded"); - return (NSS_LDAP_BUFFER_ERROR); - } + attr_len = strlen(attr); - buf = (char *)siter + *len; - bufsize -= *len; - - if (values != NULL) { - for (viter = values; *viter; ++viter, ++siter) { - rv = __nss_ldap_assign_str(*viter, siter, &size, - buf, bufsize); - if (rv != NSS_LDAP_SUCCESS) { - ldap_value_free(values); - goto fin; + aname = ldap_first_attribute(ctx->conn->ld, ctx->msg, &cookie); + if (aname != NULL) { + do { + if (strncasecmp(aname, attr, attr_len) == 0) { + /* + * Falling back to standard routine if there + * is no Range option in the + * AttributeDescription + */ + if (strlen(aname) == attr_len) { +// printf("__ %s %d %s\n", +// __FILE__, +// __LINE__, +// aname); + rv = do_assign_attr_multi_str( + ctx, attr, str_array, + str_array_size, len, buf, + bufsize, 0); + } else { +// printf("__ %s %d %s\n", +// __FILE__, +// __LINE__, +// aname); + rv = do_assign_attr_multi_str_paged( + ctx, attr, aname, str_array, + str_array_size, len, buf, + bufsize); + } + +// printf("__ %s %d\n", __FILE__, __LINE__); + if ((rv != NSS_LDAP_SUCCESS) || + ((rv == NSS_LDAP_SUCCESS) && + (*str_array_size != 1))) { + ldap_memfree(aname); + ber_free(cookie, 0); +// printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size); + goto fin; + } +// printf("__ %s %d\n", __FILE__, __LINE__); } - - buf += size; - *len += size; - bufsize -= size; - } - - ldap_value_free(values); + + ldap_memfree(aname); + aname = ldap_next_attribute(ctx->conn->ld, ctx->msg, + cookie); + } while (aname != NULL); + ber_free(cookie, 0); } - - *siter = NULL; - rv = NSS_LDAP_SUCCESS; + + rv = NSS_LDAP_PARSE_ERROR; fin: - if (rv == NSS_LDAP_PARSE_ERROR) + if (rv != NSS_LDAP_SUCCESS) __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, - "__nss_ldap_assign_attr_multi_str failed: attr='%s'", attr); - + "__nss_ldap_assign_attr_multi_str_paged failed: attr='%s', " + "rv=%d", attr, rv); + +// printf("__ %s %d %d\n", __FILE__, __LINE__, rv); return (rv); } @@ -747,9 +1020,9 @@ if (values != NULL) { /* NOTE: actually, we can insert a hook in the configuration file - * parser to avoid using strcmp() every time. But the approach + * parser to avoid using strcasecmp() every time. But the approach * below seems to be a bit cleaner */ - if (strcmp(attr, "userPassword") == 0) { + if (strcasecmp(attr, "userPassword") == 0) { for (viter = values; *viter; ++viter) { if (strncmp(*viter, "{CRYPT}", sizeof("{CRYPT}") - 1) == 0) { @@ -757,7 +1030,7 @@ break; } } - } else if (strcmp(attr, "authPassword") == 0) { + } else if (strcasecmp(attr, "authPassword") == 0) { for (viter = values; *viter; ++viter) { if (strncmp(*viter, "CRYPT$", sizeof("CRYPT$") - 1) == 0) { ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#11 (text+ko) ==== @@ -32,7 +32,9 @@ struct nss_ldap_search_request { char *search_base; int scope; - char *filter; + char *filter; + + StringList *attributes; }; struct nss_ldap_search_context { @@ -105,6 +107,9 @@ char const *, char **, size_t *, char *, size_t); extern int __nss_ldap_assign_attr_multi_str(struct nss_ldap_search_context *, char const *, char ***, size_t *, size_t *, char *, size_t); +extern int __nss_ldap_assign_attr_multi_str_paged( + struct nss_ldap_search_context *, char const *, char ***, size_t *, + size_t *, char *, size_t); extern int __nss_ldap_assign_attr_indexed_str(struct nss_ldap_search_context *, char const *, ssize_t, size_t *, char **, size_t *, char *, size_t); extern int __nss_ldap_assign_attr_uid(struct nss_ldap_search_context *, ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.c#9 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include #include +#include #include "ldapconn.h" #include "ldapsearch.h" #include "ldapschema.h" ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#13 (text+ko) ==== @@ -34,6 +34,7 @@ #include #include #include +#include #include "ldaputil.h" #include "ldapschema.h" /* for NSS_LDAP_FILTER_MAX_SIZE */ #include "ldapsearch.h" @@ -121,17 +122,17 @@ if (slash_mod == 1 ) { cmp_buf[0] = *sp; cmp_buf[1] = *(sp + 1); - if (strncasecmp(cmp_buf, "2a", 2) == 0) { + if (strncasecmp(cmp_buf, "2a", 2) == 0) *bp = '*'; - } else if (strncasecmp(cmp_buf, "2b", 2) == 0) { + else if (strncasecmp(cmp_buf, "2b", 2) == 0) *bp = '+'; - } else if (strncasecmp(cmp_buf, "28", 2) == 0) { + else if (strncasecmp(cmp_buf, "28", 2) == 0) *bp = '('; - } else if (strncasecmp(cmp_buf, "29", 2) == 0) { + else if (strncasecmp(cmp_buf, "29", 2) == 0) *bp = ')'; - } else if (strncasecmp(cmp_buf, "5c", 2) == 0) { + else if (strncasecmp(cmp_buf, "5c", 2) == 0) *bp = '\\'; - } else + else return (NSS_LDAP_PARSE_ERROR); ++bp; @@ -326,3 +327,114 @@ */ return (LDAP_SUCCESS); } + +/* TODO: review again for border-cases */ +int +__nss_ldap_parse_range(char const *str, int *range_start, int *range_end) +{ + char numeric_buf[16]; + char *p, *p2, *ends; + size_t slen, str_len; + + assert(str != NULL); + assert(range_start != NULL); + assert(range_end != NULL); + + //printf("-- %s %d %s\n", __FILE__, __LINE__, str); + str_len = strlen(str); + p = strchr(str, ';'); + if ((p == NULL) || (*(++p) == '\0')) + return (NSS_LDAP_GENERIC_ERROR); + + //printf("-- %s %d\n", __FILE__, __LINE__); + do { + p2 = strchr(p, ';'); + if (p2 != NULL) + slen = p2 - p; + else + slen = str_len - (p - str); + + //printf("-- %s %d %s %d\n", __FILE__, __LINE__, p, slen); + if (strncasecmp("range=", p, sizeof("range") - 1) == 0) { + p += sizeof("range=") - 1; + slen -= sizeof("range=") - 1; + + //printf("-- %s %d\n", __FILE__, __LINE__); + p2 = memchr(p, '-', slen); + if ((p2 == NULL) || (p2 == p)) + return (NSS_LDAP_PARSE_ERROR); + + if (p2 - p > sizeof(numeric_buf) - 1) + return (NSS_LDAP_BUFFER_ERROR); + + //printf("-- %s %d\n", __FILE__, __LINE__); + memcpy(numeric_buf, p, p2 - p); + numeric_buf[p2 - p] = '\0'; + + //printf("-- %s %d\n", __FILE__, __LINE__); + *range_start = strtol(numeric_buf, &ends, 10); + if (*ends != '\0') + return (NSS_LDAP_PARSE_ERROR); + + //printf("-- %s %d\n", __FILE__, __LINE__); + slen -= p2 + 1 - p; + p = p2 + 1; + if (slen == 0) + return (NSS_LDAP_PARSE_ERROR); + + //printf("-- %s %d %s %d\n", __FILE__, __LINE__, p, slen); + if (*p == '*') + *range_end = -1; + else { + //printf("-- %s %d\n", __FILE__, __LINE__); + if (slen > sizeof(numeric_buf) - 1) + return (NSS_LDAP_BUFFER_ERROR); + + memcpy(numeric_buf, p, slen); + numeric_buf[slen] = '\0'; + *range_end = strtol(numeric_buf, &ends, 10); + if (*ends != '\0') + return (NSS_LDAP_PARSE_ERROR); + } + + //printf("-- %s %d\n", __FILE__, __LINE__); + return (NSS_LDAP_SUCCESS); + } + + //printf("-- %s %d\n", __FILE__, __LINE__); + p = p2 + 1; + } while (p2 != NULL); + + //printf("-- %s %d\n", __FILE__, __LINE__); + *range_start = 0; + *range_end = -1; + return (NSS_LDAP_SUCCESS); +} + +int +__nss_ldap_form_range(char *buf, size_t bufsize, int range_start, + int range_end) +{ + size_t rv; + + assert(buf != NULL); + assert(range_start >= 0); + assert((range_end >= 0) || (range_end == -1)); + + if (range_end == -1) + rv = snprintf(buf, bufsize, "%d-*", range_start); + else + rv = snprintf(buf, bufsize, "%d-%d", range_start, range_end); + + if (rv >= bufsize) + return (NSS_LDAP_BUFFER_ERROR); + + return (NSS_LDAP_SUCCESS); +} + +int +__nss_ldap_check_control_suppot(LDAP *ld, char const *option) +{ + /* TODO: implement */ + return (LDAP_SUCCESS); +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#13 (text+ko) ==== @@ -47,4 +47,9 @@ extern int __nss_ldap_parse_page_control(LDAP *, LDAPControl **, unsigned long *, struct berval **); +extern int __nss_ldap_parse_range(char const *, int *, int *); +extern int __nss_ldap_form_range(char *, size_t, int, int); + +extern int __nss_ldap_check_option_suppot(LDAP *, char const *); + #endif /* _LDAPUTILS_H_ */ ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#14 (text+ko) ==== @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "ldapschema.h" #include "ldapconn.h" @@ -662,6 +663,7 @@ conn_flag = 0; memset(&conn_error, 0, sizeof(struct nss_ldap_connection_error)); while (conn_flag < 2) { +// printf("__ %s %d\n", __FILE__, __LINE__); rv = nss_ldap_connection_init(connection_method, tls_method, &conn, &conn_error); if (rv != NS_SUCCESS) { @@ -683,6 +685,7 @@ parse_tls != 0 ? tls_method : NULL, map_id, filter, &pctx, conn, &pctx_model); if (rv != NS_SUCCESS) { +// printf("__ %s %d\n", __FILE__, __LINE__); __nss_ldap_log(NSS_LDAP_LL_DEBUG, "nss_ldap_get_common: parse context was not " "initialized: rv=%d, map_id=%d, filter='%s'", @@ -690,12 +693,16 @@ goto fin; } +// printf("__ %s %d\n", __FILE__, __LINE__); rv = NSS_LDAP_PARSE_ERROR; while ((rv == NSS_LDAP_PARSE_ERROR) || (rv == NSS_LDAP_SUCCESS)) { rv = __nss_ldap_parse_next(pctx); +// printf("__ %s %d %d\n", __FILE__, __LINE__, rv); if (rv == NSS_LDAP_PARSE_ERROR) { +// printf("__ %s %d %d\n", __FILE__, __LINE__, rv); rv = __nss_ldap_search_next(search_method, pctx->sctx); if (pctx->sctx->msg == NULL) { +// printf("__ %s %d %d\n", __FILE__, __LINE__, rv); rv = NSS_LDAP_GENERIC_ERROR; break; } @@ -703,24 +710,29 @@ break; } +// printf("__ %s %d %d\n", __FILE__, __LINE__, rv); switch (rv) { case NSS_LDAP_SUCCESS: +// printf("__ %s %d\n", __FILE__, __LINE__); rv = NS_SUCCESS; break; case NSS_LDAP_BUFFER_ERROR: rv = NS_RETURN; errno = ERANGE; +// printf("__ %s %d\n", __FILE__, __LINE__); __nss_ldap_log(NSS_LDAP_LL_DEBUG, "nss_ldap_get_common: supplied buffer was too " "small: map_id=%d, filter='%s'", map_id, filter); break; case NSS_LDAP_CONNECTION_ERROR: rv = NS_UNAVAIL; +// printf("__ %s %d\n", __FILE__, __LINE__); __nss_ldap_log(NSS_LDAP_LL_ERR, "nss_ldap_get_common: connection_error " "small: map_id=%d, filter='%s'", map_id, filter); break; default: +// printf("__ %s %d\n", __FILE__, __LINE__); __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, "nss_ldap_get_common: not found: " "map_id=%d, filter='%s'", map_id, filter); @@ -756,6 +768,7 @@ // else // nss_ldap_connection_reset(tls_method, conn); +// printf("__ %s %d\n", __FILE__, __LINE__); return (rv); } @@ -772,6 +785,7 @@ int rv, isthreaded; rv = nss_ldap_configure(); +// printf("__ %s %d\n", __FILE__, __LINE__); if (rv != NSS_LDAP_SUCCESS) return (NS_UNAVAIL); @@ -785,12 +799,14 @@ } } +// printf("__ %s %d\n", __FILE__, __LINE__); rv = nss_ldap_get_common(map_id, filter, mdata, buffer, bufsize, parse_next_fn, NULL, 0); if (isthreaded) pthread_rwlock_unlock(&nss_ldap_lock); +// printf("__ %s %d %d %d\n", __FILE__, __LINE__, rv, NS_SUCCESS); return (rv); } @@ -818,6 +834,8 @@ rv = nss_ldap_get_common(map_id, filter, mdata, buffer, bufsize, parse_next_fn, parse_destroy_fn, 1); +// printf("__ %s %d %d\n", __FILE__, __LINE__, bufsize); +// printf("__ %s %d %d %d %d %d %d\n", __FILE__, __LINE__, rv, NS_RETURN, NS_NOTFOUND, errno, ERANGE); if (isthreaded) pthread_rwlock_unlock(&nss_ldap_lock);