Date: Fri, 21 Jul 2006 19:09:16 GMT From: Michael Bushkov <bushman@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102070 for review Message-ID: <200607211909.k6LJ9GDT097431@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102070 Change 102070 by bushman@bushman_nss_ldap_cached on 2006/07/21 19:08:28 "passwd" source basically works! Still has to be decorated with nsdispatch(3)-friendly interface. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#4 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#4 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#4 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#4 (text+ko) ==== @@ -35,41 +35,17 @@ #include <pwd.h> #include "ldapconn.h" #include "ldapschema.h" -#include "ldapconf.h" #include "ldapsearch.h" +#include "ldaptls.h" #include "ldaputil.h" +#include "ldapconf.h" +#include "nss_ldap.h" //static int nss_ldap_parse_passwd(struct nss_ldap_parse_context *, // struct nss_ldap_search_context *); - - static int -ldap_getpwnam_r(const char *name, struct passwd *pwd, - char *buffer, size_t bufsize, struct passwd **result) -{ - -} - -static int -ldap_getpwuid_r(uid_t uid, struct passwd *pwd, - char *buffer, size_t bufsize, struct passwd **result) +nss_ldap_parse_passwd(struct nss_ldap_parse_context *pctx) { -} - -static int -ldap_getpwent_r(struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ -} - -static int -ldap_setpwent() -{ -} - -int -__nss_ldap_parse_passwd(struct nss_ldap_parse_context *pctx) -{ struct nss_ldap_schema *schema; struct nss_ldap_search_context *sctx; struct passwd *pwd; @@ -81,11 +57,14 @@ assert(pctx != NULL); sctx = pctx->sctx; + pwd = (struct passwd *)pctx->mdata; + buf = pctx->buffer; + buflen = pctx->bufsize; /* >>>for debug only */ - pwd = (struct passwd *)malloc(sizeof(struct passwd)); - memset(pwd, 0, sizeof(struct passwd)); - buf = malloc(1024); - memset(buf, 0, 1024); +// pwd = (struct passwd *)malloc(sizeof(struct passwd)); +// memset(pwd, 0, sizeof(struct passwd)); +// buf = malloc(1024); +// memset(buf, 0, 1024); /* <<<for debug only */ schema = &sctx->conf->schema; @@ -154,6 +133,85 @@ } int +ldap_getpwnam_r(const char *name, struct passwd *pwd, + char *buffer, size_t bufsize, struct passwd **result) +{ + char filter[NSS_LDAP_FILTER_MAX_SIZE]; + char const *fmt; + int rv; + + fmt = __nss_ldap_get_schema_filter(&__nss_ldap_conf->schema, + NSS_LDAP_FILTER_GETPWNAM); + if (fmt == NULL) + return (NS_UNAVAIL); + + __nss_ldap_format_filter(fmt, NSS_LDAP_FILTER_ARGS_STR, filter, + sizeof(filter), name); + + rv = __nss_ldap_getby(NSS_LDAP_MAP_PASSWD, filter, (void *)pwd, + buffer, bufsize, nss_ldap_parse_passwd); + + if (rv == NS_SUCCESS) + *result = pwd; + + return (rv); +} + +int +ldap_getpwuid_r(uid_t uid, struct passwd *pwd, + char *buffer, size_t bufsize, struct passwd **result) +{ + char filter[NSS_LDAP_FILTER_MAX_SIZE]; + char const *fmt; + int rv; + + fmt = __nss_ldap_get_schema_filter(&__nss_ldap_conf->schema, + NSS_LDAP_FILTER_GETPWUID); + if (fmt == NULL) + return (NS_UNAVAIL); + + __nss_ldap_format_filter(fmt, NSS_LDAP_FILTER_ARGS_UID, filter, + sizeof(filter), uid); + + rv = __nss_ldap_getby(NSS_LDAP_MAP_PASSWD, filter, (void *)pwd, + buffer, bufsize, nss_ldap_parse_passwd); + + if (rv == NS_SUCCESS) + *result = pwd; + + return (rv); +} + +int +ldap_getpwent_r(struct passwd *pwd, char *buffer, size_t bufsize, + struct passwd **result) +{ + char const *filter; + int rv; + + filter = __nss_ldap_get_schema_filter(&__nss_ldap_conf->schema, + NSS_LDAP_FILTER_GETPWENT); + if (filter == NULL) + return (NS_UNAVAIL); + + rv = __nss_ldap_getent(NSS_LDAP_MAP_PASSWD, filter, (void *)pwd, + buffer, bufsize, nss_ldap_parse_passwd); + + if (rv == NS_SUCCESS) + *result = pwd; + + return (rv); +} + +void +ldap_setpwent() +{ + + __nss_ldap_setent(NSS_LDAP_MAP_PASSWD); +} + + +int __ldap_setpwent(void *retval, void *mdata, va_list ap) { return (NS_UNAVAIL); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#4 (text+ko) ==== @@ -29,8 +29,18 @@ #ifndef _LDAP_PASSWD_H_ #define _LDAP_PASSWD_H_ -extern int __nss_ldap_parse_passwd(struct nss_ldap_parse_context *); - +int +ldap_getpwnam_r(const char *name, struct passwd *pwd, + char *buffer, size_t bufsize, struct passwd **result); +int +ldap_getpwuid_r(uid_t uid, struct passwd *pwd, + char *buffer, size_t bufsize, struct passwd **result); +int +ldap_getpwent_r(struct passwd *pwd, char *buffer, size_t bufsize, + struct passwd **result); +void +ldap_setpwent(); + extern int __ldap_setpwent(void *, void *, va_list); extern int __ldap_passwd(void *, void *, va_list); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#4 (text+ko) ==== @@ -28,12 +28,16 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/types.h> #include <assert.h> #include <ldap.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "ldapschema.h" +#include "ldapconn.h" +#include "ldapsearch.h" +#include "ldaptls.h" #include "ldapconf.h" #define NSS_BASE_PREFIX ("nss_base_") @@ -146,9 +150,9 @@ conf->bind_pw = strdup("[passwd]"); assert(conf->bind_pw != NULL); -// conf->base_passwd = strdup( -// "ou=Users,ou=R61.NET,ou=Domains,dc=r61,dc=net"); -// assert(conf->base_passwd != NULL); + __nss_ldap_init_start_tls_simple_auth_method(&conf->connection_method); + __nss_ldap_init_default_search_method(&conf->search_method); + __nss_ldap_init_default_tls_method(&conf->tls_method); } int ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#4 (text+ko) ==== @@ -49,7 +49,7 @@ #define NSS_LDAP_PROTO_VERSION_3 3 #define NSS_LDAP_MAX_ERR_DESC_SIZE 256 - + struct nss_ldap_configuration { char *host; @@ -64,6 +64,10 @@ char *bind_pw; struct nss_ldap_schema schema; + + struct nss_ldap_connection_method connection_method; + struct nss_ldap_search_method search_method; + struct nss_ldap_tls_method tls_method; }; struct nss_ldap_config_file_error ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#4 (text+ko) ==== @@ -34,9 +34,11 @@ #include <stdlib.h> #include <string.h> #include "ldapschema.h" -#include "ldapconf.h" +#include "ldapsearch.h" +#include "ldaptls.h" #include "ldaputil.h" #include "ldapconn.h" +#include "ldapconf.h" struct nss_ldap_connection * __nss_ldap_connect(struct nss_ldap_connection_method *method, ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#4 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#4 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#4 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#3 (text+ko) ==== @@ -35,9 +35,10 @@ #include <stdlib.h> #include <string.h> #include "ldapschema.h" -#include "ldapconf.h" #include "ldapconn.h" #include "ldapsearch.h" +#include "ldaptls.h" +#include "ldapconf.h" static void copy_request(struct nss_ldap_search_request *, struct nss_ldap_search_request const *); @@ -49,8 +50,9 @@ static int search_next_def(struct nss_ldap_search_context *); static void end_search_def(struct nss_ldap_search_context *); -static struct nss_ldap_parse_context *start_parsing_def( - struct nss_ldap_search_context *, nss_ldap_parse_next_fn); +static struct nss_ldap_parse_context *start_parsing_def( + struct nss_ldap_search_context *, + void *, char *, size_t, nss_ldap_parse_next_fn); static void end_parsing_def(struct nss_ldap_parse_context *); @@ -169,6 +171,7 @@ static struct nss_ldap_parse_context * start_parsing_def(struct nss_ldap_search_context *sctx, + void *mdata, char *buffer, size_t bufsize, nss_ldap_parse_next_fn parse_next_fn) { struct nss_ldap_parse_context *pctx; @@ -183,6 +186,9 @@ pctx->parse_next_fn = parse_next_fn; pctx->sctx = sctx; + pctx->mdata = mdata; + pctx->buffer = buffer; + pctx->bufsize = bufsize; return (pctx); } @@ -235,13 +241,15 @@ struct nss_ldap_parse_context * __nss_ldap_start_parsing(struct nss_ldap_search_method *method, struct nss_ldap_search_context *ctx, + void *mdata, char *buffer, size_t bufsize, nss_ldap_parse_next_fn parse_next_fn) { assert(method != NULL); assert(ctx != NULL); - return (method->start_parsing_fn(ctx, parse_next_fn)); + return (method->start_parsing_fn(ctx, mdata, buffer, bufsize, + parse_next_fn)); } int ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#3 (text+ko) ==== @@ -43,6 +43,14 @@ LDAPMessage *msg; int msgid; + int type; + int retry_count; + + union { + char const *key; + int offset; + }; + struct berval *cookie; }; @@ -55,15 +63,7 @@ void *mdata; char *buffer; - size_t bufsize; - - int type; - int retry_count; - - union { - char const *key; - int offset; - }; + size_t bufsize; }; typedef struct nss_ldap_search_context *(*nss_ldap_start_search_fn)( @@ -73,7 +73,8 @@ typedef void (*nss_ldap_end_search_fn)(struct nss_ldap_search_context *); typedef struct nss_ldap_parse_context *(*nss_ldap_start_parsing_fn)( - struct nss_ldap_search_context *, nss_ldap_parse_next_fn); + struct nss_ldap_search_context *, void *, char *, size_t, + nss_ldap_parse_next_fn); typedef void (*nss_ldap_end_parsing_fn)(struct nss_ldap_parse_context *); struct nss_ldap_search_method { @@ -96,6 +97,7 @@ extern struct nss_ldap_parse_context *__nss_ldap_start_parsing( struct nss_ldap_search_method *, struct nss_ldap_search_context *, + void *, char *, size_t, nss_ldap_parse_next_fn); extern int __nss_ldap_parse_next(struct nss_ldap_search_method *, struct nss_ldap_parse_context *); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.c#2 (text+ko) ==== @@ -27,3 +27,249 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <assert.h> +#include <errno.h> +#include <ldap.h> +#include <pthread.h> +#include <pthread_np.h> +#include <stdlib.h> +#include "ldapconn.h" +#include "ldapsearch.h" +#include "ldapschema.h" +#include "ldaptls.h" + +/* the default is to have connections and search contexts one per thread */ +#define NSS_LDAP_TLS_DEF(x, name) \ +struct name##_state { \ + struct x *instance; \ + void (*destroy_fn)(struct x *); \ +}; \ + \ +static void \ +name##_endstate(void *p) \ +{ \ + \ + if (p == NULL) \ + return; \ + \ + if (((struct name##_state *)p)->instance != NULL) \ + ((struct name##_state *)p)->destroy_fn( \ + ((struct name##_state *)p)->instance); \ + free(p); \ +} + +NSS_LDAP_TLS_DEF(nss_ldap_connection, nss_ldap_connection) +NSS_LDAP_TLS_DEF(nss_ldap_search_context, nss_ldap_passwd_search_context) +NSS_LDAP_TLS_DEF(nss_ldap_search_context, nss_ldap_group_search_context) + +NSS_LDAP_TLS_HANDLING(nss_ldap_connection); +NSS_LDAP_TLS_HANDLING(nss_ldap_passwd_search_context); +NSS_LDAP_TLS_HANDLING(nss_ldap_group_search_context); + +static int tls_get_connection_def(struct nss_ldap_connection **); +static int tls_set_connection_def(struct nss_ldap_connection *, + void (*)(struct nss_ldap_connection *)); +static void tls_return_connection_def(struct nss_ldap_connection *); + +static int tls_get_search_context_def(int, struct nss_ldap_search_context **); +static int tls_set_search_context_def(int, struct nss_ldap_search_context *, + void (*)(struct nss_ldap_search_context *)); +static void tls_return_search_context_def(int, + struct nss_ldap_search_context *); + +int +tls_get_connection_def(struct nss_ldap_connection **res) +{ + struct nss_ldap_connection_state *st; + int rv; + + assert(res != NULL); + + rv = nss_ldap_connection_getstate(&st); + if (rv != 0) + return (rv); + + *res = st->instance; + return (0); +} + +int +tls_set_connection_def(struct nss_ldap_connection *conn, + void (*destroy_fn)(struct nss_ldap_connection *)) +{ + struct nss_ldap_connection_state *st; + int rv; + + rv = nss_ldap_connection_getstate(&st); + if (rv != 0) + return (rv); + + st->instance = conn; + st->destroy_fn = destroy_fn; + return (0); +} + +void +tls_return_connection_def(struct nss_ldap_connection *conn) +{ + /* DO NOTHING */ +} + +int +tls_get_search_context_def(int id, struct nss_ldap_search_context **res) +{ + union { + struct nss_ldap_passwd_search_context_state *pwd; + struct nss_ldap_group_search_context_state *grp; + } st; + int rv; + + assert(id < NSS_LDAP_MAP_MAX); + assert(res != NULL); + + switch (id) { + case NSS_LDAP_MAP_PASSWD: + rv = nss_ldap_passwd_search_context_getstate(&st.pwd); + if (rv != 0) + return (rv); + + *res = st.pwd->instance; + return (0); + case NSS_LDAP_MAP_GROUP: + rv = nss_ldap_group_search_context_getstate(&st.grp); + if (rv != 0) + return (rv); + + *res = st.grp->instance; + return (0); + default: + return (-1); + } +} + +int +tls_set_search_context_def(int id, struct nss_ldap_search_context *sctx, + void (*destroy_fn)(struct nss_ldap_search_context *)) +{ + union { + struct nss_ldap_passwd_search_context_state *pwd; + struct nss_ldap_group_search_context_state *grp; + } st; + int rv; + + assert(id < NSS_LDAP_MAP_MAX); + + switch (id) { + case NSS_LDAP_MAP_PASSWD: + rv = nss_ldap_passwd_search_context_getstate(&st.pwd); + if (rv != 0) + return (rv); + + st.pwd->instance = sctx; + st.pwd->destroy_fn = destroy_fn; + return (0); + case NSS_LDAP_MAP_GROUP: + rv = nss_ldap_group_search_context_getstate(&st.grp); + if (rv != 0) + return (rv); + + st.grp->instance = sctx; + st.grp->destroy_fn = destroy_fn; + return (0); + default: + return (-1); + } +} + +void +tls_return_search_context_def(int id, + struct nss_ldap_search_context *sctx) +{ + + assert(id < NSS_LDAP_MAP_MAX); + + /* DO NOTHING */ +} + +int +__nss_ldap_tls_get_connection(struct nss_ldap_tls_method *method, + struct nss_ldap_connection **res) +{ + + assert(method != NULL); + + return (method->get_connection_fn(res)); +} + +int +__nss_ldap_tls_set_connection(struct nss_ldap_tls_method *method, + struct nss_ldap_connection *conn, + void (*destroy_fn)(struct nss_ldap_connection *)) +{ + + assert(method != NULL); + + return (method->set_connection_fn(conn, destroy_fn)); +} + +void +__nss_ldap_tls_return_connection(struct nss_ldap_tls_method *method, + struct nss_ldap_connection *conn) +{ + + assert(method != NULL); + + return (method->return_connection_fn(conn)); +} + +int +__nss_ldap_tls_get_search_context(struct nss_ldap_tls_method *method, int id, + struct nss_ldap_search_context **res) +{ + + assert(id < NSS_LDAP_MAP_MAX); + assert(method != NULL); + assert(res != NULL); + + return (method->get_search_context_fn(id, res)); +} + +int +__nss_ldap_tls_set_search_context(struct nss_ldap_tls_method *method, int id, + struct nss_ldap_search_context *sctx, + void (*destroy_fn)(struct nss_ldap_search_context *)) +{ + + assert(method != NULL); + assert(id < NSS_LDAP_MAP_MAX); + + return (method->set_search_context_fn(id, sctx, destroy_fn)); +} + +void +__nss_ldap_tls_return_search_context(struct nss_ldap_tls_method *method, + int id, struct nss_ldap_search_context *sctx) +{ + + assert(method != NULL); + assert(id < NSS_LDAP_MAP_MAX); + + return (method->return_search_context_fn(id, sctx)); +} + +void +__nss_ldap_init_default_tls_method(struct nss_ldap_tls_method *method) +{ + + assert(method != NULL); + + method->get_connection_fn = tls_get_connection_def; + method->set_connection_fn = tls_set_connection_def; + method->return_connection_fn = tls_return_connection_def; + + method->get_search_context_fn = tls_get_search_context_def; + method->set_search_context_fn = tls_set_search_context_def; + method->return_search_context_fn = tls_return_search_context_def; +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.h#2 (text+ko) ==== @@ -29,14 +29,64 @@ #ifndef _LDAPTLS_H_ #define _LDAPTLS_H_ -typedef struct nss_ldap_connection *(*nss_ldap_tls_get_connection_fn)(); -typedef int (*nss_ldap_tls_set_connection_fn)(struct nss_ldap_connection *); +/* NOTE: is this ok? */ +extern int __isthreaded; + +/* NOTE: implementation from libc/include/nss_tls.h is used. Slightly + * modified to use original names of pthread-functions (without the starting + * underscore. If nss_ldap is included into the libc, NSS_LDAP_TLS_HANDLING + * should be probably redefined through original NSS_TLS_HANDLING. */ +#define NSS_LDAP_TLS_HANDLING(name) \ +static pthread_key_t name##_state_key; \ +static void name##_keyinit(void); \ +static int name##_getstate(struct name##_state **); \ +\ +static void \ +name##_keyinit(void) \ +{ \ + (void)_pthread_key_create(&name##_state_key, name##_endstate); \ +} \ +\ +static int \ +name##_getstate(struct name##_state **p) \ +{ \ + static struct name##_state st; \ + static pthread_once_t keyinit = PTHREAD_ONCE_INIT; \ + int rv; \ + \ + if (!__isthreaded || _pthread_main_np() != 0) { \ + *p = &st; \ + return (0); \ + } \ + rv = _pthread_once(&keyinit, name##_keyinit); \ + if (rv != 0) \ + return (rv); \ + *p = (struct name##_state *)_pthread_getspecific(name##_state_key);\ + if (*p != NULL) \ + return (0); \ + *p = calloc(1, sizeof(**p)); \ + if (*p == NULL) \ + return (ENOMEM); \ + rv = _pthread_setspecific(name##_state_key, *p); \ + if (rv != 0) { \ + free(*p); \ + *p = NULL; \ + } \ + return (rv); \ +} \ +/* allow the macro invocation to end with a semicolon */ \ +struct _clashproof_bmVjdGFy + +typedef int (*nss_ldap_tls_get_connection_fn)(struct nss_ldap_connection **); +typedef int (*nss_ldap_tls_set_connection_fn)(struct nss_ldap_connection *, + void (*)(struct nss_ldap_connection *)); typedef void (*nss_ldap_tls_return_connection_fn)(struct nss_ldap_connection *); -typedef struct nss_ldap_search_context *(*nss_ldap_tls_get_search_context_fn)( - int); +typedef int (*nss_ldap_tls_get_search_context_fn)( + int, struct nss_ldap_search_context **); typedef int (*nss_ldap_tls_set_search_context_fn)(int, - struct nss_ldap_search_context *); + struct nss_ldap_search_context *, + void (*)(struct nss_ldap_search_context *)); typedef void (*nss_ldap_tls_return_search_context_fn)(int, struct nss_ldap_search_context *); @@ -51,4 +101,21 @@ nss_ldap_tls_return_search_context_fn return_search_context_fn; }; +extern int __nss_ldap_tls_get_connection( + struct nss_ldap_tls_method *, struct nss_ldap_connection **); +extern int __nss_ldap_tls_set_connection(struct nss_ldap_tls_method *, + struct nss_ldap_connection *, void (*)(struct nss_ldap_connection *)); +extern void __nss_ldap_tls_return_connection(struct nss_ldap_tls_method *, + struct nss_ldap_connection *); + +extern int __nss_ldap_tls_get_search_context(struct nss_ldap_tls_method *, + int, struct nss_ldap_search_context **); +extern int __nss_ldap_tls_set_search_context(struct nss_ldap_tls_method *, + int, struct nss_ldap_search_context *, + void (*)(struct nss_ldap_search_context *)); +extern void __nss_ldap_tls_return_search_context(struct nss_ldap_tls_method *, + int, struct nss_ldap_search_context *); + +extern void __nss_ldap_init_default_tls_method(struct nss_ldap_tls_method *); + #endif ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#4 (text+ko) ==== @@ -28,10 +28,13 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/types.h> #include <assert.h> #include <ldap.h> +#include <stdarg.h> #include <string.h> #include "ldaputil.h" +#include "ldapschema.h" /* for NSS_LDAP_FILTER_MAX_SIZE */ int __nss_ldap_escape_string(char const *str, char *buffer, size_t bufsize) @@ -84,3 +87,55 @@ *p = '\0'; return (0); } + +int +__nss_ldap_format_filter(char const *fmt, int type, char *buffer, + size_t bufsize, ...) +{ + char str[NSS_LDAP_FILTER_MAX_SIZE]; + char str2[NSS_LDAP_FILTER_MAX_SIZE]; + char *s; + va_list ap; + int num, rv; + uid_t uid; + gid_t gid; + + rv = -1; + va_start(ap, bufsize); + + switch (type) { + case NSS_LDAP_FILTER_ARGS_STR: + s = va_arg(ap, char *); + rv = __nss_ldap_escape_string(s, str, sizeof(str)); + if (rv == 0) { + rv = snprintf(buffer, bufsize, fmt, str); + rv = (rv >= bufsize) ? -1 : 0; + } + break; + case NSS_LDAP_FILTER_ARGS_INT: + num = va_arg(ap, int); + rv = snprintf(buffer, bufsize, fmt, num); + rv = (rv >= bufsize) ? -1 : 0; + break; + case NSS_LDAP_FILTER_ARGS_UID: + uid = va_arg(ap, uid_t); + rv = snprintf(buffer, bufsize, fmt, uid); + rv = (rv >= bufsize) ? -1 : 0; + break; + case NSS_LDAP_FILTER_ARGS_GID: + gid = va_arg(ap, gid_t); + rv = snprintf(buffer, bufsize, fmt, gid); + rv = (rv >= bufsize) ? -1 : 0; + break; + case NSS_LDAP_FILTER_ARGS_STR_INT: + break; + case NSS_LDAP_FILTER_ARGS_STR_STR: + break; + default: + break; + }; + +fin: + va_end(ap); + return (rv); +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#4 (text+ko) ==== @@ -28,52 +28,15 @@ #ifndef _LDAPUTIL_H_ #define _LDAPUTIL_H_ - + +#define NSS_LDAP_FILTER_ARGS_STR 0 +#define NSS_LDAP_FILTER_ARGS_INT 1 +#define NSS_LDAP_FILTER_ARGS_UID 2 +#define NSS_LDAP_FILTER_ARGS_GID 3 +#define NSS_LDAP_FILTER_ARGS_STR_INT 4 +#define NSS_LDAP_FILTER_ARGS_STR_STR 5 + extern int __nss_ldap_escape_string(char const *, char *, size_t); - -/* NOTE: implementation from libc/include/nss_tls.h is used. Slightly - * modified to use original names of pthread-functions (without the starting - * underscore. If nss_ldap is included into the libc, NSS_LDAP_TLS_HANDLING - * should be probably redefined through original NSS_TLS_HANDLING. */ -#define NSS_LDAP_TLS_HANDLING(name) \ -static pthread_key_t name##_state_key; \ -static void name##_keyinit(void); \ -static int name##_getstate(struct name##_state **); \ -\ -static void \ -name##_keyinit(void) \ -{ \ - (void)_pthread_key_create(&name##_state_key, name##_endstate); \ -} \ -\ -static int \ -name##_getstate(struct name##_state **p) \ -{ \ - static struct name##_state st; \ - static pthread_once_t keyinit = PTHREAD_ONCE_INIT; \ - int rv; \ - \ - if (!__isthreaded || _pthread_main_np() != 0) { \ - *p = &st; \ - return (0); \ - } \ - rv = _pthread_once(&keyinit, name##_keyinit); \ - if (rv != 0) \ - return (rv); \ - *p = (struct name##_state *)_pthread_getspecific(name##_state_key);\ - if (*p != NULL) \ - return (0); \ - *p = calloc(1, sizeof(**p)); \ - if (*p == NULL) \ - return (ENOMEM); \ - rv = _pthread_setspecific(name##_state_key, *p); \ - if (rv != 0) { \ - free(*p); \ - *p = NULL; \ - } \ - return (rv); \ -} \ -/* allow the macro invocation to end with a semicolon */ \ -struct _clashproof_bmVjdGFy +extern int __nss_ldap_format_filter(char const *, int, char *, size_t, ...); #endif /* _LDAPUTILS_H_ */ ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#4 (text+ko) ==== @@ -30,6 +30,7 @@ #include <sys/types.h> #include <sys/stat.h> +#include <assert.h> #include <nsswitch.h> #include <ldap.h> #include <pthread.h> @@ -37,10 +38,11 @@ #include <stdio.h> #include <stdlib.h> #include "ldapschema.h" -#include "ldapconf.h" #include "ldapconn.h" #include "ldaputil.h" #include "ldapsearch.h" +#include "ldaptls.h" +#include "ldapconf.h" #include "nss_ldap.h" #include "ldap_passwd.h" @@ -63,6 +65,7 @@ static pthread_rwlock_t nss_ldap_lock = PTHREAD_RWLOCK_INITIALIZER; static struct nss_ldap_configuration nss_ldap_conf; +struct nss_ldap_configuration *__nss_ldap_conf = NULL; static int nss_ldap_configure(); static void nss_ldap_atexit(); @@ -102,7 +105,14 @@ __nss_ldap_init_default_config(&nss_ldap_conf); result = __nss_ldap_load_config_from_file(&nss_ldap_conf, path, &config_file_error); + if (result == 0) + __nss_ldap_conf = &nss_ldap_conf; + else { + /* TODO: proper error handling */ + } + __nss_ldap_build_schema_filters(&nss_ldap_conf.schema); + fin: if (isthreaded) (void)pthread_rwlock_unlock(&nss_ldap_lock); @@ -135,6 +145,325 @@ } } +static void +connection_destroy_func(struct nss_ldap_connection *conn) +{ + struct nss_ldap_connection_error conn_error; + int rv; + + memset(&conn_error, 0, sizeof(conn_error)); + rv = __nss_ldap_disconnect(&__nss_ldap_conf->connection_method, + conn, __nss_ldap_conf, &conn_error); + + if (rv != 0) { + /* TODO: proper error handling */ + } +} + +static void +search_context_destroy_func(struct nss_ldap_search_context *sctx) +{ + __nss_ldap_end_search(&nss_ldap_conf.search_method, sctx); +} + +int +__nss_ldap_getby(int map_id, char const *filter, void *mdata, char *buffer, + size_t bufsize, nss_ldap_parse_next_fn parse_next_fn) +{ + struct nss_ldap_connection_method *connection_method; + struct nss_ldap_search_method *search_method; + struct nss_ldap_tls_method *tls_method; + + struct nss_ldap_connection_error conn_error; + struct nss_ldap_search_request search_request; + struct nss_ldap_connection *conn; + struct nss_ldap_search_context *sctx; + struct nss_ldap_parse_context *pctx; + int rv; + + assert(map_id < NSS_LDAP_MAP_MAX); + assert(filter != NULL); + assert(mdata != NULL); + assert(buffer != NULL); + assert(parse_next_fn != NULL); + + connection_method = &__nss_ldap_conf->connection_method; + search_method = &__nss_ldap_conf->search_method; + tls_method = &__nss_ldap_conf->tls_method; + + conn = NULL; + pctx = NULL; + sctx = NULL; + rv = __nss_ldap_tls_get_connection(tls_method, &conn); + if (rv != 0) { + /* TODO: proper error handling */ + rv = NS_UNAVAIL; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607211909.k6LJ9GDT097431>