PERFORCE change 108032 for review
Michael Bushkov
bushman at FreeBSD.org
Tue Oct 17 10:44:24 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=108032
Change 108032 by bushman at 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) ====
More information about the p4-projects
mailing list