Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Oct 2006 17:44:15 GMT
From:      Michael Bushkov <bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108032 for review
Message-ID:  <200610171744.k9HHiF5A047284@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/types.h>
 #include <assert.h>
+#include <lber.h>
 #include <ldap.h>
 #include <stdarg.h>
 #include <string.h>
@@ -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) ====




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610171744.k9HHiF5A047284>