From owner-p4-projects@FreeBSD.ORG Tue Oct 17 17:44:24 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 1B16416A415; Tue, 17 Oct 2006 17:44:24 +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 A641416A407 for ; Tue, 17 Oct 2006 17:44:23 +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 F222343D78 for ; Tue, 17 Oct 2006 17:44:15 +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 k9HHiFJF047287 for ; Tue, 17 Oct 2006 17:44:15 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9HHiF5A047284 for perforce@freebsd.org; Tue, 17 Oct 2006 17:44:15 GMT (envelope-from bushman@freebsd.org) Date: Tue, 17 Oct 2006 17:44:15 GMT Message-Id: <200610171744.k9HHiF5A047284@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 108032 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: Tue, 17 Oct 2006 17:44:24 -0000 http://perforce.freebsd.org/chv.cgi?CH=108032 Change 108032 by bushman@bushman_nss_ldap_cached on 2006/10/17 17:43:38 Draft implementation of paged results search was made + minor bug fix in schema mappings. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#11 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#13 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#13 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#11 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#11 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#10 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#12 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#12 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#13 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#11 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#13 (text+ko) ==== @@ -167,6 +167,7 @@ conf->connect_policy = NSS_LDAP_CONNECT_POLICY_PERSIST_PERTHREAD; conf->restart = 0; conf->debug = 0; + conf->search_page_size = NSS_LDAP_DEFAULT_SEARCH_PAGE_SIZE; conf->tls_checkpeer = NSS_LDAP_OPTION_DEFAULT; ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#13 (text+ko) ==== @@ -63,6 +63,8 @@ #define NSS_LDAP_MAX_ERR_DESC_SIZE 256 +#define NSS_LDAP_DEFAULT_SEARCH_PAGE_SIZE 1024 + struct nss_ldap_configuration { /* schema and methods part @@ -99,6 +101,7 @@ int connect_policy; int restart; int debug; + int search_page_size; char *sasl_authid; char *root_sasl_authid; ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#11 (text+ko) ==== @@ -96,7 +96,7 @@ { assert(schema != NULL); - + switch (rules_id) { case NSS_LDAP_SCHEMA_MAP_ATTRIBUTE_RULES: return (&schema->map_attribute_rules); @@ -190,7 +190,6 @@ assert(right_arg != NULL); memset(rule, 0, sizeof(struct nss_ldap_schema_rule)); - rule->left_arg = strdup(left_arg); if (rule->left_arg == NULL) return (NSS_LDAP_MEMORY_ERROR); @@ -305,7 +304,10 @@ assert(rule != NULL); if (rules->rules_size == rules->rules_eff_size) { - rules->rules_eff_size <<= 1; + if (rules->rules_eff_size == 0) + rules->rules_eff_size = 1; + else + rules->rules_eff_size <<= 1; new_coll = (struct nss_ldap_schema_rule *)malloc( sizeof(struct nss_ldap_schema_rule) * rules->rules_eff_size); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#11 (text+ko) ==== @@ -46,6 +46,10 @@ struct nss_ldap_search_request const *); static void destroy_request(struct nss_ldap_search_request *); +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 *); + static struct nss_ldap_search_context *start_search_def( struct nss_ldap_connection *, struct nss_ldap_configuration *, struct nss_ldap_search_request *); @@ -83,23 +87,52 @@ free(request->filter); } +static int +do_ldap_search_ext(struct nss_ldap_connection *conn, + struct nss_ldap_configuration *conf, + struct nss_ldap_search_request *request, + struct nss_ldap_search_context *sctx, + int *msgid) +{ + LDAPControl *server_controls[2]; + int rv; + + assert(conn != NULL); + assert(conf != NULL); + assert(request != NULL); + assert(msgid != NULL); + + server_controls[1] = NULL; + rv = __nss_ldap_create_page_control(conn->ld, conf->search_page_size, + sctx == NULL ? NULL : sctx->cookie, 0, &server_controls[0]); + if (rv != LDAP_SUCCESS) { + /* TODO: warn the logs */ + } + + rv = ldap_search_ext( conn->ld, request->search_base, request->scope, + request->filter, NULL, 0, + rv == LDAP_SUCCESS ? server_controls : NULL, NULL, NULL, + LDAP_NO_LIMIT, msgid ); + + return (rv); +} + + static struct nss_ldap_search_context * start_search_def(struct nss_ldap_connection *conn, struct nss_ldap_configuration *conf, struct nss_ldap_search_request *request) { - struct nss_ldap_search_context *ctx; + struct nss_ldap_search_context *ctx; int msgid, rv; assert(conn != NULL); assert(request != NULL); - - rv = ldap_search_ext( conn->ld, request->search_base, request->scope, - request->filter, NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, - &msgid ); - if ( rv != LDAP_SUCCESS ) { + + rv = do_ldap_search_ext(conn, conf, request, NULL, &msgid); + if ((rv != LDAP_SUCCESS ) && (rv != LDAP_PARTIAL_RESULTS)){ __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT, "start_search_def: " - "ldap_search_ext failed: search_base='%s', scope='%d', " + "do_ldap_search_ext failed: search_base='%s', scope='%d', " "filter='%s', rv=%d", request->search_base, request->scope, request->filter); return (NULL); @@ -126,27 +159,18 @@ static int search_next_def(struct nss_ldap_search_context *ctx) { - struct timeval zerotime; - int finished, rv; + LDAPControl **server_controls; + char *matcheddn, *errmsg, **referrals; + int errcode, finished, rv; + unsigned long abs_rescount; assert(ctx != NULL); - if (ctx->msgid == -1) { - ldap_msgfree(ctx->msg); - ctx->msg = NULL; - return (NSS_LDAP_SUCCESS); - } - - finished = 0; - memset(&zerotime, 0, sizeof(struct timeval)); - while (!finished) { - if (ctx->msg != NULL) { - ldap_msgfree(ctx->msg); - ctx->msg = NULL; - } - rv = ldap_result( ctx->conn->ld, ctx->msgid, LDAP_MSG_ONE, - &zerotime, &ctx->msg); - +st: + if (ctx->msg_first == NULL) { + rv = ldap_result( ctx->conn->ld, ctx->msgid, LDAP_MSG_ALL, + NULL, &ctx->msg_first); + switch (rv) { case -1: __nss_ldap_log(NSS_LDAP_LL_ERR_INT, "search_next_def: " @@ -156,9 +180,13 @@ ctx->search_request.scope, ctx->search_request.filter); return (NSS_LDAP_CONNECTION_ERROR); - case 0: - break; + case 0: + goto st; + case LDAP_RES_SEARCH_RESULT: case LDAP_RES_SEARCH_ENTRY: + ctx->msg = ldap_first_message(ctx->conn->ld, + ctx->msg_first); + return (NSS_LDAP_SUCCESS); case LDAP_RES_SEARCH_REFERENCE: /* NOT IMPLEMENTED */ @@ -169,14 +197,70 @@ ctx->search_request.scope, ctx->search_request.filter); return (NSS_LDAP_GENERIC_ERROR); - case LDAP_RES_SEARCH_RESULT: - ctx->msgid = -1; - return (NSS_LDAP_SUCCESS); default: /* NOTE: SHOULD NOT BE REACHABLE */ - finished = 1; - break; - }; + __nss_ldap_log(NSS_LDAP_LL_ERR_INT, "search_next_def: " + "ldap_result returned %d" + ": search_base='%s', scope='%d', filter='%s', " + "rv=%d", rv, ctx->search_request.search_base, + ctx->search_request.scope, + ctx->search_request.filter); + return (NSS_LDAP_GENERIC_ERROR); + } + } else { + ctx->msg = ldap_next_message(ctx->conn->ld, ctx->msg); + if (ctx->msg != NULL) + return (NSS_LDAP_SUCCESS); + else { + rv = ldap_parse_result(ctx->conn->ld, + ctx->msg_first, &errcode, &matcheddn, + &errmsg, &referrals, &server_controls, + 0); + + ldap_msgfree(ctx->msg_first); + ctx->msg_first = NULL; + + if (rv == LDAP_SUCCESS) { + if (server_controls != NULL) { + if (ctx->cookie != NULL) { + ber_bvfree(ctx->cookie); + ctx->cookie = NULL; + } + + rv = __nss_ldap_parse_page_control( + ctx->conn->ld, server_controls, + &abs_rescount, &ctx->cookie); + + if (rv != LDAP_SUCCESS) { + // TODO: write to logs smth scary + } + + ldap_controls_free(server_controls); + } + + if (errmsg != NULL) + ldap_memfree(errmsg); + if (matcheddn != NULL) + ldap_memfree(matcheddn); + if (referrals != NULL) + ldap_value_free(referrals); + } else { + // TODO: signal to logs + } + + if (ctx->cookie && ctx->cookie->bv_val != NULL && + (strlen(ctx->cookie->bv_val) > 0)) { + rv = do_ldap_search_ext(ctx->conn, ctx->conf, + &ctx->search_request, ctx, &ctx->msgid); + if (rv != LDAP_SUCCESS) { + /* TODO: check this place */ + return (NSS_LDAP_SUCCESS); + } + + goto st; + } else + return (NSS_LDAP_SUCCESS); + } } return (NSS_LDAP_GENERIC_ERROR); @@ -188,9 +272,10 @@ assert(ctx != NULL); - if (ctx->msg != NULL) { - ldap_msgfree(ctx->msg); - ctx->msg = NULL; + if (ctx->msg_first != NULL) { + ldap_msgfree(ctx->msg_first); + ctx->msg_first = NULL; + ctx->msg = NULL; } destroy_request(&ctx->search_request); free(ctx); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#10 (text+ko) ==== @@ -40,13 +40,15 @@ struct nss_ldap_connection *conn; struct nss_ldap_configuration *conf; - LDAPMessage *msg; + LDAPMessage *msg_first; + LDAPMessage *msg; int msgid; int type; int retry_count; struct berval *cookie; + int controls_processed; }; struct nss_ldap_parse_context; ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#12 (text+ko) ==== @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -251,3 +252,77 @@ return (rv); } + +int +__nss_ldap_create_page_control(LDAP *ld, unsigned long page_size, + struct berval *cookie, int is_critical, LDAPControl **control) +{ + BerElement *berelem; + int rv; + + assert(ld != NULL); + assert(control != NULL); + + berelem = ber_alloc_t(LBER_USE_DER); + if (berelem == NULL) { + /* TODO: error handling here */ + return (LDAP_NO_MEMORY); + } + + if (cookie == NULL) + rv = ber_printf(berelem, "{ion}", page_size, "", 0); + else + rv = ber_printf(berelem, "{iOn}", page_size, cookie); + + if (rv == LBER_ERROR) { + ber_free(berelem, 1); + /* TODO: error handling here */ + return (LDAP_ENCODING_ERROR); + } + + rv = ldap_create_control(LDAP_CONTROL_PAGEDRESULTS, + berelem, is_critical, control); + + ber_free(berelem, 1); + return (rv); +} + +int +__nss_ldap_parse_page_control(LDAP *ld, LDAPControl **server_controls, + unsigned long *total_count, struct berval **cookie) +{ + LDAPControl *page_control; + BerElement *berelem; + int rv; + + assert(ld != NULL); + assert(server_controls != NULL); + assert(total_count != NULL); + assert(cookie != NULL); + + page_control = ldap_find_control(LDAP_CONTROL_PAGEDRESULTS, + server_controls); + if (page_control == NULL) { + /* TODO: error handling here */ + return (LDAP_CONTROL_NOT_FOUND); + } + + berelem = ber_init(&page_control->ldctl_value); + if (berelem == NULL) { + /* TODO: check errors */ + return (LDAP_NO_MEMORY); + } + rv = ber_scanf(berelem, "{iO", &total_count, cookie); + if (rv == LBER_ERROR) { + /* TODO: write error log */ + ber_free(berelem, 1); + return (LDAP_DECODING_ERROR); + } + + ber_free(berelem, 1); + /* + * TODO: seems to be unneeded + ldap_control_free(page_control); + */ + return (LDAP_SUCCESS); +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#12 (text+ko) ==== @@ -42,4 +42,9 @@ extern int __nss_ldap_unescape_string(char const *, char *, size_t); extern int __nss_ldap_format_filter(char const *, int, char *, size_t, ...); +extern int __nss_ldap_create_page_control(LDAP *, unsigned long, + struct berval *, int, LDAPControl **); +extern int __nss_ldap_parse_page_control(LDAP *, LDAPControl **, + unsigned long *, struct berval **); + #endif /* _LDAPUTILS_H_ */ ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#13 (text+ko) ====