PERFORCE change 102017 for review
Michael Bushkov
bushman at FreeBSD.org
Thu Jul 20 19:00:41 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=102017
Change 102017 by bushman at 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);
+/* <<<for debug only */
schema = &sctx->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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
#include <sys/time.h>
#include <assert.h>
#include <ldap.h>
@@ -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 <ldap.h>
#include <string.h>
#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
More information about the p4-projects
mailing list