From owner-p4-projects@FreeBSD.ORG Thu Jul 20 19:00:41 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 425F316A4EA; Thu, 20 Jul 2006 19:00:41 +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 DA29B16A4DD for ; Thu, 20 Jul 2006 19:00:40 +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 A412743D62 for ; Thu, 20 Jul 2006 19:00:36 +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 k6KJ0atw036900 for ; Thu, 20 Jul 2006 19:00:36 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k6KJ0aIV036897 for perforce@freebsd.org; Thu, 20 Jul 2006 19:00:36 GMT (envelope-from bushman@freebsd.org) Date: Thu, 20 Jul 2006 19:00:36 GMT Message-Id: <200607201900.k6KJ0aIV036897@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 102017 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: Thu, 20 Jul 2006 19:00:41 -0000 http://perforce.freebsd.org/chv.cgi?CH=102017 Change 102017 by bushman@bushman_nss_ldap_cached on 2006/07/20 18:59:44 Further nss_ldap development. Passwd database support is almost implemented. Some general routines have to be implemented to allow current code to be plugged in into the nss. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaptls.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#3 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#3 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#3 (text+ko) ==== @@ -9,9 +9,10 @@ #SHLIBDIR?= /lib SRCS= nss_ldap.c ldap_passwd.c ldapconn.c ldapconf.c ldapschema.c \ - ldapsearch.c ldaputil.c + ldapsearch.c ldaptls.c ldaputil.c CFLAGS+=-I${.CURDIR}/../libnssutil -I/usr/local/include CFLAGS+=-DINET6 +CFLAGS+=-g LDADD+= -lnssutil -lldap LDFLAGS+= -L${.OBJDIR}/../libnssutil -L/usr/local/lib ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#2 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#2 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#3 (text+ko) ==== @@ -43,11 +43,35 @@ // 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) +{ +} + +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_search_context *sctx) +__nss_ldap_parse_passwd(struct nss_ldap_parse_context *pctx) { struct nss_ldap_schema *schema; + struct nss_ldap_search_context *sctx; struct passwd *pwd; char *buf; size_t buflen; @@ -55,10 +79,18 @@ int rv; assert(pctx != NULL); - assert(sctx != NULL); + + sctx = pctx->sctx; +/* >>>for debug only */ + pwd = (struct passwd *)malloc(sizeof(struct passwd)); + memset(pwd, 0, sizeof(struct passwd)); + buf = malloc(1024); + memset(buf, 0, 1024); +/* <<conf->schema; + printf("==> %d %s\n", __LINE__, __FILE__); rv = __nss_ldap_assign_attr_str(sctx, _ATM(schema, PASSWD, uid), &pwd->pw_name, &len, buf, buflen); @@ -66,21 +98,31 @@ goto errfin; buflen -= len; buf += len; - + + printf("==> %d %s\n", __LINE__, __FILE__); rv = __nss_ldap_assign_attr_uid(sctx, _AT(schema, uidNumber), &pwd->pw_uid); if (rv != 0) goto errfin; + printf("==> %d %s\n", __LINE__, __FILE__); rv = __nss_ldap_assign_attr_str(sctx, _AT(schema, gecos), &pwd->pw_gecos, &len, buf, buflen); + if (rv != 0) { + pwd->pw_gecos = NULL; + rv = __nss_ldap_assign_attr_str(sctx, + _ATM(schema, PASSWD, cn), + &pwd->pw_gecos, &len, buf, buflen); + } + if (rv != 0) goto errfin; buflen -= len; buf += len; + printf("==> %d %s\n", __LINE__, __FILE__); rv = __nss_ldap_assign_attr_str(sctx, _AT(schema, homeDirectory), &pwd->pw_dir, &len, buf, buflen); @@ -92,7 +134,7 @@ buflen -= len; buf += len; - + printf("==> %d %s\n", __LINE__, __FILE__); rv = __nss_ldap_assign_attr_str(sctx, _AT(schema, loginShell), &pwd->pw_shell, &len, buf, buflen); ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#3 (text+ko) ==== @@ -29,8 +29,7 @@ #ifndef _LDAP_PASSWD_H_ #define _LDAP_PASSWD_H_ -extern int __nss_ldap_parse_passwd(struct nss_ldap_parse_context *, - struct nss_ldap_search_context *); +extern int __nss_ldap_parse_passwd(struct nss_ldap_parse_context *); 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#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#3 (text+ko) ==== @@ -63,7 +63,7 @@ char *bind_dn; char *bind_pw; - struct nss_ldap_schema schema; + struct nss_ldap_schema schema; }; struct nss_ldap_config_file_error ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#3 (text+ko) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#2 (text+ko) ==== @@ -28,6 +28,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -125,6 +126,7 @@ return (0); } + finished = 0; memset(&zerotime, 0, sizeof(struct timeval)); while (!finished) { rv = ldap_result( ctx->conn->ld, ctx->msgid, LDAP_MSG_ONE, @@ -180,6 +182,7 @@ memset(pctx, 0, sizeof(struct nss_ldap_parse_context)); pctx->parse_next_fn = parse_next_fn; + pctx->sctx = sctx; return (pctx); } @@ -243,15 +246,13 @@ int __nss_ldap_parse_next(struct nss_ldap_search_method *method, - struct nss_ldap_parse_context *pctx, - struct nss_ldap_search_context *sctx) + struct nss_ldap_parse_context *pctx) { assert(method != NULL); assert(pctx != NULL); - assert(sctx != NULL); - return (pctx->parse_next_fn(pctx, sctx)); + return (pctx->parse_next_fn(pctx)); } void @@ -315,7 +316,6 @@ assert(str != NULL); assert(len != NULL); assert(buf != NULL); - assert(bufsize != 0); /* check for the overriding rule */ schema = &ctx->conf->schema; @@ -346,7 +346,59 @@ return (rv); } + +int +__nss_ldap_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) +{ + char **values, **viter; + size_t size, valsize; + int rv; + + assert(ctx != NULL); + assert(attr != NULL); + assert(str_array != NULL); + assert(str_array_size != NULL); + assert(len != NULL); + assert(buf != NULL); + + values = (char **)ldap_get_values(ctx->conn->ld, ctx->msg, attr); + if (values == NULL) { + /* TODO: proper error handling */ + return (-1); + } + + valsize = ldap_count_values(values); + + *str_array = (char **)ALIGN(buf); + *len = sizeof(char *) * valsize; + if ((char *)(*str_array) + *len > buf + bufsize) { + /* TODO: proper error handling */ + ldap_value_free(values); + return (-1); + } + + buf = (char *)(*str_array) + (*len); + bufsize -= (*len); + + for (viter = values; *viter; ++viter, ++(*str_array)) { + rv = __nss_ldap_assign_str(*viter, *str_array, &size, + buf, bufsize); + if (rv == -1) { + /* TODO: proper error handling */ + ldap_value_free(values); + return (-1); + } + + buf += size; + bufsize -= size; + } + ldap_value_free(values); + return (0); +} + int __nss_ldap_assign_attr_uid(struct nss_ldap_search_context *ctx, char const *attr, uid_t *uid) @@ -375,6 +427,33 @@ } int +__nss_ldap_assign_attr_gid(struct nss_ldap_search_context *ctx, + char const *attr, gid_t *gid) +{ + char temp_buf[16]; + size_t temp_bufsize; + char *temp_ptr; + int rv; + + assert(ctx != NULL); + assert(attr != NULL); + assert(gid != NULL); + + /* TODO: do we need this memset? */ + memset(temp_buf, 0, sizeof(temp_buf)); + + rv = __nss_ldap_assign_attr_str(ctx, attr, &temp_ptr, &temp_bufsize, + temp_buf, sizeof(temp_buf)); + + if (rv != 0) + return (rv); + + *gid = (gid_t)strtol(temp_buf, (char **)NULL, 10); + /* TODO: check that the string is actually a number */ + return (0); +} + +int __nss_ldap_assign_attr_int(struct nss_ldap_search_context *ctx, char const *attr, int *num) { @@ -400,3 +479,69 @@ /* TODO: check that the string is actually a number */ return (0); } + +int +__nss_ldap_assign_attr_password(struct nss_ldap_search_context *ctx, + char const *attr, char **str, size_t *len, char *buf, size_t bufsize) +{ + char **values, **viter; + char *pass; + int rv; + + values = (char **)ldap_get_values(ctx->conn->ld, ctx->msg, attr); + if (values == NULL) + return (-1); + + pass = NULL; + + /* NOTE: actually, we can insert a hook in the configuration file + * parser to avoid using strcmp() every time. But the approach + * below seems to be a bit cleaner */ + if (strcmp(attr, "userPassword") == 0) { + for (viter = values; *viter; ++viter) { + if (strncmp(*viter, "{CRYPT}", sizeof("{CRYPT}") - 1) == 0) { + pass = *viter + sizeof("{CRYPT}") - 1; + break; + } + } + } else if (strcmp(attr, "authPassword") == 0) { + for (viter = values; *viter; ++viter) { + if (strncmp(*viter, "CRYPT$", sizeof("CRYPT$") - 1) == 0) { + pass = *viter + sizeof("CRYPT$") - 1; + break; + } + } + } else + pass = *values; + + if (pass == NULL) + rv = -1; + else + rv = __nss_ldap_assign_str(pass, str, len, buf, bufsize); + + ldap_value_free(*values); + return (rv); +} + +int +__nss_ldap_check_oc(struct nss_ldap_search_context *ctx, + char const *oc) +{ + char **values, **viter; + int rv; + + rv = -1; + values = (char **)ldap_get_values(ctx->conn->ld, ctx->msg, + "objectClass"); + if (values == NULL) + return (rv); + + for (viter = values; *viter; ++viter) + if (strcasecmp(*viter, oc) == 0) { + rv = 0; + break; + } + + ldap_value_free(values); + return (rv); +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#2 (text+ko) ==== @@ -47,12 +47,15 @@ }; struct nss_ldap_parse_context; -typedef int (*nss_ldap_parse_next_fn)(struct nss_ldap_parse_context *, - struct nss_ldap_search_context *); +typedef int (*nss_ldap_parse_next_fn)(struct nss_ldap_parse_context *); struct nss_ldap_parse_context { + struct nss_ldap_search_context *sctx; nss_ldap_parse_next_fn parse_next_fn; + void *mdata; + char *buffer; + size_t bufsize; int type; int retry_count; @@ -95,8 +98,7 @@ struct nss_ldap_search_context *, nss_ldap_parse_next_fn); extern int __nss_ldap_parse_next(struct nss_ldap_search_method *, - struct nss_ldap_parse_context *, - struct nss_ldap_search_context *); + struct nss_ldap_parse_context *); extern void __nss_ldap_end_parsing(struct nss_ldap_search_method *, struct nss_ldap_parse_context *); @@ -107,10 +109,17 @@ size_t); extern int __nss_ldap_assign_attr_str(struct nss_ldap_search_context *, 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_uid(struct nss_ldap_search_context *, char const *, uid_t *); +extern int __nss_ldap_assign_attr_gid(struct nss_ldap_search_context *, + char const *, gid_t *); extern int __nss_ldap_assign_attr_int(struct nss_ldap_search_context *, char const *, int *); +extern int __nss_ldap_assign_attr_password(struct nss_ldap_search_context *, + char const *, char **, size_t *, char *, size_t); - +extern int __nss_ldap_check_oc(struct nss_ldap_search_context *, + char const *); #endif ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#3 (text+ko) ==== @@ -32,3 +32,55 @@ #include #include #include "ldaputil.h" + +int +__nss_ldap_escape_string(char const *str, char *buffer, size_t bufsize) +{ + char *p, *l, *np; + char const *s; + + p = buffer; + l = p + bufsize; + + for (s = str; *s; ++s) { + switch (*s) { + case '*': + np = p + 3; + if (np >= l) + return (-1); + + memcpy(p, "\\2a", 3); + p = np; + break; + case '(': + np = p + 3; + if (np >= l) + return (-1); + memcpy(p, "\\28", 3); + p = np; + break; + case ')': + np = p + 3; + if (np >= l) + return (-1); + memcpy(p, "\\29", 3); + p = np; + break; + case '\\': + np = p + 3; + if (np >= l) + return (-1); + memcpy(p, "\\5c", 3); + p = np; + break; + default: + *p = *s; + if (++p == l) + return (-1); + break; + } + } + + *p = '\0'; + return (0); +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#3 (text+ko) ==== @@ -29,6 +29,8 @@ #ifndef _LDAPUTIL_H_ #define _LDAPUTIL_H_ +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 ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#3 (text+ko) ==== @@ -150,6 +150,8 @@ int main(int argc, char **argv) { + char buf[14]; + struct nss_ldap_connection_method method; struct nss_ldap_connection *conn; struct nss_ldap_connection_error conn_error; @@ -160,7 +162,13 @@ struct nss_ldap_search_request request; int rv; - printf("testing nss_ldap\n"); + rv = __nss_ldap_escape_string("() ui = 3", buf, sizeof(buf)); + if (rv == 0) + printf("escaped: %s\n", buf); + else + printf("can't escape\n"); + + printf("testing nss_ldap %d\n", sizeof ("CRYPT$")); printf("configuring\n"); rv = nss_ldap_configure(); @@ -196,6 +204,12 @@ return (rv); } + memset(&request, 0, sizeof(request)); + request.search_base = nss_ldap_conf.schema.filter_bases[NSS_LDAP_MAP_PASSWD]; + asprintf(&request.filter, nss_ldap_conf.schema.filters[NSS_LDAP_FILTER_GETPWNAM], "bushman"); + request.scope = LDAP_SCOPE_SUBTREE; + + printf("%s %s %d\n", request.search_base, request.filter, request.scope); printf("creating search context\n"); search_context = __nss_ldap_start_search(&search_method, conn, &nss_ldap_conf, &request); @@ -212,14 +226,15 @@ } printf("initializing parse context\n"); - parse_context = __nss_ldap_start_parsing(&search_method, search_context, __nss_ldap_parse_passwd); + parse_context = __nss_ldap_start_parsing(&search_method, + search_context, __nss_ldap_parse_passwd); if (parse_context == NULL) { printf("failed\n"); return (-1); } printf("parsing\n"); - rv = __nss_ldap_parse_next(&search_method, parse_context, search_context); + rv = __nss_ldap_parse_next(&search_method, parse_context); if (rv != 0) { printf("failed\n"); } ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#3 (text+ko) ==== @@ -34,4 +34,9 @@ nss_end_ent = 2 }; +extern int __nss_ldap_getby(struct nss_ldap_connection *, + char const *, void *, char *, size_t, nss_ldap_parse_next_fn); +extern int __nss_ldap_getent(struct nss_ldap_connection *, char const *, void *, char *, size_t, + nss_ldap_parse_next_fn); + #endif