From owner-p4-projects@FreeBSD.ORG Wed Jun 21 16:32:38 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 D8F5E16A47D; Wed, 21 Jun 2006 16:32:37 +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 9E07616A474 for ; Wed, 21 Jun 2006 16:32:37 +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 5191A43D46 for ; Wed, 21 Jun 2006 16:32:37 +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 k5LGWb52003128 for ; Wed, 21 Jun 2006 16:32:37 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k5LGWanG003125 for perforce@freebsd.org; Wed, 21 Jun 2006 16:32:36 GMT (envelope-from bushman@freebsd.org) Date: Wed, 21 Jun 2006 16:32:36 GMT Message-Id: <200606211632.k5LGWanG003125@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 99763 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: Wed, 21 Jun 2006 16:32:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=99763 Change 99763 by bushman@bushman_nss_ldap_cached on 2006/06/21 16:32:08 Agents system of the caching daemon reworked in order to support new nsdispatch behavior (when all nss-modules are external). Hosts agent finally implemented. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/Makefile#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agent.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agent.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/Makefile.inc#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/group.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/group.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/hosts.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/hosts.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/net.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/net.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/passwd.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/passwd.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/proto.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/proto.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/rpc.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/rpc.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/services.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/services.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/cached.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/debug.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/mp_rs_query.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#2 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/Makefile#2 (text) ==== @@ -8,7 +8,7 @@ SRCS= agent.c cached.c cachedcli.c cachelib.c cacheplcs.c debug.c log.c \ config.c query.c mp_ws_query.c mp_rs_query.c singletons.c protocol.c \ parser.c -CFLAGS+= -DCONFIG_PATH="\"${PREFIX}/etc/cached.conf\"" +CFLAGS+= -g -DCONFIG_PATH="\"${PREFIX}/etc/cached.conf\"" DPADD+=${LIBM} ${LIBPTHREAD} ${LIBUTIL} LDADD+=${LIBM} ${LIBPTHREAD} ${LIBUTIL} LDFLAGS+= -Xlinker --export-dynamic ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agent.c#2 (text) ==== @@ -34,6 +34,11 @@ #include "agent.h" #include "debug.h" +const ns_dtab emptydtab[] = { + { NULL, NULL, NULL } +}; + + static int agent_cmp_func(const void *a1, const void *a2) { @@ -54,6 +59,47 @@ return (res); } +int +agent_marshal_results(char **buffer, size_t *bufsize, + agent_marshal_func marshal_func, void *cache_mdata, void *retval, ...) +{ + va_list ap; + size_t size; + int rv; + + va_start(ap, retval); + if (*buffer == NULL) { + *buffer = malloc(AGENT_BUFFER_STORAGE_INITIAL); + if (*buffer == NULL) + return (NS_UNAVAIL); + *bufsize = AGENT_BUFFER_STORAGE_INITIAL; + } + + size = *bufsize; + rv = marshal_func(*buffer, &size, retval, ap, cache_mdata); + if (rv == NS_RETURN) { + *bufsize = size; + if (*bufsize <= AGENT_BUFFER_STORAGE_MAX) { + *buffer = (char *)realloc(*buffer, *bufsize); + if (*buffer == NULL) + return (NS_UNAVAIL); + + size = *bufsize; + rv = marshal_func(*buffer, &size, retval, ap, + cache_mdata); + } + } + + if (rv != NS_SUCCESS) { + free(*buffer); + *buffer = NULL; + *bufsize = 0; + } + + va_end(ap); + return (rv); +} + struct agent_table * init_agent_table() { ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agent.h#2 (text) ==== @@ -29,6 +29,92 @@ #ifndef __CACHED_AGENT_H__ #define __CACHED_AGENT_H__ +#include +#include + +extern int __isthreaded; + +/* TLS handling routine obtained from libc/include/nss_tls.h */ +#define AGENT_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 + + +#define AGENT_DECLARE_BUFFER_TLS_HANDLING(name) \ +struct name##_state { \ + char *buffer; \ + size_t bufsize; \ +}; \ + \ +static void \ +name##_endstate(void *p) \ +{ \ + free(p); \ +} \ + \ +AGENT_TLS_HANDLING(name); + +enum agent_buffer_constants +{ + AGENT_BUFFER_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ + AGENT_BUFFER_STORAGE_MAX = 1 << 20, /* 1 MByte */ +}; + +#define AGENT_BUFFER_TLS_HANDLING_INIT(st) \ + { \ + if (st->buffer == NULL) { \ + st->buffer = malloc(AGENT_BUFFER_STORAGE_INITIAL);\ + st->bufsize = AGENT_BUFFER_STORAGE_INITIAL; \ + } \ + } + +#define AGENT_BUFFER_TLS_HANDLING_CHECK(st) (st->buffer == NULL) + +#define AGENT_BUFFER_TLS_HANDLING_RESIZE(st) \ + free(st->buffer); \ + st->bufsize <<= 1; \ + if (st->bufsize < AGENT_BUFFER_STORAGE_MAX) \ + st->buffer = malloc(st->bufsize); \ + else \ + st->buffer = NULL + /* * Agents are used to perform the actual lookups from the caching daemon. * There are two types of daemons: for common requests and for multipart @@ -41,21 +127,28 @@ MULTIPART_AGENT = 1 }; +typedef int (*agent_marshal_func)(char *, size_t *, void *, va_list, void *); +typedef int (*agent_lookup_func)(const char *, size_t, char **, size_t *); +typedef void *(*agent_mp_init_func)(); +typedef int (*agent_mp_lookup_func)(char **, size_t *, void *); +typedef void (*agent_mp_destroy_func)(void *); + struct agent { - char *name; + char *name; enum agent_type type; }; struct common_agent { struct agent parent; - int (*lookup_func)(const char *, size_t, char **, size_t *); + agent_lookup_func lookup_func; }; struct multipart_agent { struct agent parent; - void *(*mp_init_func)(); - int (*mp_lookup_func)(char **, size_t *, void *); - void (*mp_destroy_func)(void *); + + agent_mp_init_func mp_init_func; + agent_mp_lookup_func mp_lookup_func; + agent_mp_destroy_func mp_destroy_func; }; struct agent_table { @@ -63,6 +156,10 @@ size_t agents_num; }; +extern const ns_dtab emptydtab[]; + +extern int agent_marshal_results(char **, size_t *, agent_marshal_func, + void *, void *, ...); extern struct agent_table *init_agent_table(); extern void register_agent(struct agent_table *, struct agent *); extern struct agent *find_agent(struct agent_table *, const char *, ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/Makefile.inc#2 (text) ==== @@ -1,3 +1,3 @@ # $FreeBSD: src/usr.sbin/cached/agents/Makefile.inc,v 1.1 2006/04/28 12:03:38 ume Exp $ -SRCS += passwd.c group.c services.c +SRCS += passwd.c group.c services.c hosts.c ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/group.c#2 (text) ==== @@ -31,28 +31,73 @@ #include #include #include +#include +#include #include +#include +#include #include #include #include +#include #include "../debug.h" -#include "passwd.h" +#include "group.h" + +static const ns_src defaultsrc[] = { + { NSSRC_COMPAT, NS_SUCCESS }, + { NULL, 0 } +}; + -static int group_marshal_func(struct group *, char *, size_t *); +static int group_marshal_func(char *, size_t *, void *, va_list, void *); static int group_lookup_func(const char *, size_t, char **, size_t *); static void *group_mp_init_func(); -static int group_mp_lookup_func(char **, size_t *, void *); -static void group_mp_destroy_func(void *); +static int group_mp_lookup_func(char **out_buffer, size_t *out_size, void *mdata); +static void group_mp_destroy_func(void *mdata); + +AGENT_DECLARE_BUFFER_TLS_HANDLING(group); + +#ifndef _ALIGNBYTES +#define _ALIGNBYTES ALIGNBYTES +#endif + +#ifndef _ALIGN +#define _ALIGN(x) ALIGN(x) +#endif static int -group_marshal_func(struct group *grp, char *buffer, size_t *buffer_size) +group_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, + void *cache_mdata) { + char *name; + gid_t gid; + struct group *grp; + char *orig_buf; + size_t orig_buf_size; + struct group new_grp; size_t desired_size, size, mem_size; char *p, **mem; - TRACE_IN(group_marshal_func); - desired_size = ALIGNBYTES + sizeof(struct group) + sizeof(char *); + switch ((enum nss_lookup_type)cache_mdata) { + case nss_lt_name: + name = va_arg(ap, char *); + break; + case nss_lt_id: + gid = va_arg(ap, gid_t); + break; + case nss_lt_all: + break; + default: + /* should be unreachable */ + return (NS_UNAVAIL); + } + + grp = va_arg(ap, struct group *); + orig_buf = va_arg(ap, char *); + orig_buf_size = va_arg(ap, size_t); + + desired_size = _ALIGNBYTES + sizeof(struct group) + sizeof(char *); if (grp->gr_name != NULL) desired_size += strlen(grp->gr_name) + 1; @@ -66,12 +111,12 @@ ++mem_size; } - desired_size += ALIGNBYTES + (mem_size + 1) * sizeof(char *); + desired_size += _ALIGNBYTES + (mem_size + 1) * sizeof(char *); } - if ((desired_size > *buffer_size) || (buffer == NULL)) { + if (desired_size > *buffer_size) { + /* this assignment is here for future use */ *buffer_size = desired_size; - TRACE_OUT(group_marshal_func); return (NS_RETURN); } @@ -81,7 +126,7 @@ *buffer_size = desired_size; p = buffer + sizeof(struct group) + sizeof(char *); memcpy(buffer + sizeof(struct group), &p, sizeof(char *)); - p = (char *)ALIGN(p); + p = (char *)_ALIGN(p); if (new_grp.gr_name != NULL) { size = strlen(new_grp.gr_name); @@ -98,7 +143,7 @@ } if (new_grp.gr_mem != NULL) { - p = (char *)ALIGN(p); + p = (char *)_ALIGN(p); memcpy(p, new_grp.gr_mem, sizeof(char *) * mem_size); new_grp.gr_mem = (char **)p; p += sizeof(char *) * (mem_size + 1); @@ -112,24 +157,24 @@ } memcpy(buffer, &new_grp, sizeof(struct group)); - TRACE_OUT(group_marshal_func); return (NS_SUCCESS); } static int -group_lookup_func(const char *key, size_t key_size, char **buffer, - size_t *buffer_size) +group_lookup_func(const char *key, size_t key_size, char **out_buffer, + size_t *out_size) { + struct group_state *st; + struct group grp, *retval; enum nss_lookup_type lookup_type; - char *name; + char *name; + gid_t gid; + int error, result; size_t size; - gid_t gid; - - struct group *result; TRACE_IN(group_lookup_func); - assert(buffer != NULL); - assert(buffer_size != NULL); + assert(out_buffer != NULL); + assert(out_size != NULL); if (key_size < sizeof(enum nss_lookup_type)) { TRACE_OUT(group_lookup_func); @@ -137,18 +182,19 @@ } memcpy(&lookup_type, key, sizeof(enum nss_lookup_type)); + name = NULL; switch (lookup_type) { case nss_lt_name: - size = key_size - sizeof(enum nss_lookup_type) + 1; + size = key_size - sizeof(enum nss_lookup_type) + 1; name = (char *)malloc(size); assert(name != NULL); memset(name, 0, size); memcpy(name, key + sizeof(enum nss_lookup_type), size - 1); - break; + break; case nss_lt_id: if (key_size < sizeof(enum nss_lookup_type) + sizeof(gid_t)) { - TRACE_OUT(passwd_lookup_func); + TRACE_OUT(group_lookup_func); return (NS_UNAVAIL); } @@ -159,29 +205,67 @@ return (NS_UNAVAIL); } + result = group_getstate(&st); + AGENT_BUFFER_TLS_HANDLING_INIT(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + free(name); + TRACE_OUT(group_lookup_func); + return (NS_UNAVAIL); + } + switch (lookup_type) { case nss_lt_name: - TRACE_STR(name); - result = getgrnam(name); - free(name); + do { + result = nsdispatch(&retval, emptydtab, NSDB_GROUP, + "getgrnam_r", defaultsrc, name, + &grp, st->buffer, st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + free(name); + TRACE_OUT(group_lookup_func); + return (NS_UNAVAIL); + } + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) + result = agent_marshal_results(out_buffer, out_size, + group_marshal_func, (void *)nss_lt_name, + retval, name, &grp, + st->buffer, st->bufsize, &error); + break; case nss_lt_id: - result = getgrgid(gid); + do { + result = nsdispatch(&retval, emptydtab, NSDB_GROUP, + "getgrgid_r", defaultsrc, gid, + &grp, st->buffer, st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + TRACE_OUT(group_lookup_func); + return (NS_UNAVAIL); + } + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) + result = agent_marshal_results(out_buffer, out_size, + group_marshal_func, + (void *)nss_lt_id, retval, gid, + &grp, st->buffer, st->bufsize, &error); break; default: /* SHOULD NOT BE REACHED */ break; - } + } - if (result != NULL) { - group_marshal_func(result, NULL, buffer_size); - *buffer = (char *)malloc(*buffer_size); - assert(*buffer != NULL); - group_marshal_func(result, *buffer, buffer_size); - } - + free(name); TRACE_OUT(group_lookup_func); - return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); + return (result); } static void * @@ -195,21 +279,40 @@ } static int -group_mp_lookup_func(char **buffer, size_t *buffer_size, void *mdata) +group_mp_lookup_func(char **out_buffer, size_t *out_size, void *mdata) { - struct group *result; + struct group_state *st; + struct group grp, *retval; + int result, error; TRACE_IN(group_mp_lookup_func); - result = getgrent(); - if (result != NULL) { - group_marshal_func(result, NULL, buffer_size); - *buffer = (char *)malloc(*buffer_size); - assert(*buffer != NULL); - group_marshal_func(result, *buffer, buffer_size); + + result = group_getstate(&st); + AGENT_BUFFER_TLS_HANDLING_INIT(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) + return (NS_UNAVAIL); + + do { + result = nsdispatch(&retval, emptydtab, NSDB_GROUP, + "getgrent_r", defaultsrc, &grp, st->buffer, + st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) + return (NS_UNAVAIL); + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) { + result = agent_marshal_results(out_buffer, + out_size, group_marshal_func, + (void *)nss_lt_all, retval, &grp, + st->buffer, st->bufsize, &error); } TRACE_OUT(group_mp_lookup_func); - return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); + return (result); } static void ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/group.h#2 (text) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/passwd.c#2 (text) ==== @@ -30,29 +30,65 @@ #include #include +#include +#include #include +#include +#include #include #include #include #include "../debug.h" #include "passwd.h" -static int passwd_marshal_func(struct passwd *, char *, size_t *); +static const ns_src defaultsrc[] = { + { NSSRC_COMPAT, NS_SUCCESS }, + { NULL, 0 } +}; + + +static int passwd_marshal_func(char *, size_t *, void *, va_list, void *); static int passwd_lookup_func(const char *, size_t, char **, size_t *); static void *passwd_mp_init_func(); -static int passwd_mp_lookup_func(char **, size_t *, void *); +static int passwd_mp_lookup_func(char **out_buffer, size_t *out_size, void *mdata); static void passwd_mp_destroy_func(void *mdata); +AGENT_DECLARE_BUFFER_TLS_HANDLING(passwd); + static int -passwd_marshal_func(struct passwd *pwd, char *buffer, size_t *buffer_size) +passwd_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, + void *cache_mdata) { - char *p; - struct passwd new_pwd; - size_t desired_size, size; + char *name; + uid_t uid; + struct passwd *pwd; + char *orig_buf; + size_t orig_buf_size; + + struct passwd new_pwd; + size_t desired_size, size; + char *p; + + switch ((enum nss_lookup_type)cache_mdata) { + case nss_lt_name: + name = va_arg(ap, char *); + break; + case nss_lt_id: + uid = va_arg(ap, uid_t); + break; + case nss_lt_all: + break; + default: + /* should be unreachable */ + return (NS_UNAVAIL); + } + + pwd = va_arg(ap, struct passwd *); + orig_buf = va_arg(ap, char *); + orig_buf_size = va_arg(ap, size_t); - TRACE_IN(passwd_marshal_func); desired_size = sizeof(struct passwd) + sizeof(char *) + - strlen(pwd->pw_name) + 1; + strlen(pwd->pw_name) + 1; if (pwd->pw_passwd != NULL) desired_size += strlen(pwd->pw_passwd) + 1; if (pwd->pw_class != NULL) @@ -64,9 +100,9 @@ if (pwd->pw_shell != NULL) desired_size += strlen(pwd->pw_shell) + 1; - if ((*buffer_size < desired_size) || (buffer == NULL)) { + if (*buffer_size < desired_size) { + /* this assignment is here for future use */ *buffer_size = desired_size; - TRACE_OUT(passwd_marshal_func); return (NS_RETURN); } @@ -120,34 +156,35 @@ } memcpy(buffer, &new_pwd, sizeof(struct passwd)); - TRACE_OUT(passwd_marshal_func); return (NS_SUCCESS); } static int -passwd_lookup_func(const char *key, size_t key_size, char **buffer, - size_t *buffer_size) +passwd_lookup_func(const char *key, size_t key_size, char **out_buffer, + size_t *out_size) { + struct passwd_state *st; + struct passwd pwd, *retval; enum nss_lookup_type lookup_type; - char *login; + char *login; + uid_t uid; + int error, result; size_t size; - uid_t uid; - struct passwd *result; - TRACE_IN(passwd_lookup_func); - assert(buffer != NULL); - assert(buffer_size != NULL); + assert(out_buffer != NULL); + assert(out_size != NULL); - if (key_size < sizeof(enum nss_lookup_type)) { + if (key_size < sizeof(enum nss_lookup_type) + 1) { TRACE_OUT(passwd_lookup_func); return (NS_UNAVAIL); } memcpy(&lookup_type, key, sizeof(enum nss_lookup_type)); + login = NULL; switch (lookup_type) { case nss_lt_name: - size = key_size - sizeof(enum nss_lookup_type) + 1; + size = key_size - sizeof(enum nss_lookup_type) + 1; login = (char *)malloc(size); assert(login != NULL); memset(login, 0, size); @@ -167,28 +204,67 @@ return (NS_UNAVAIL); } + result = passwd_getstate(&st); + AGENT_BUFFER_TLS_HANDLING_INIT(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + free(login); + TRACE_OUT(passwd_lookup_func); + return (NS_UNAVAIL); + } + switch (lookup_type) { case nss_lt_name: - result = getpwnam(login); - free(login); + do { + result = nsdispatch(&retval, emptydtab, NSDB_PASSWD, + "getpwnam_r", defaultsrc, login, + &pwd, st->buffer, st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + free(login); + TRACE_OUT(passwd_lookup_func); + return (NS_UNAVAIL); + } + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) + result = agent_marshal_results(out_buffer, out_size, + passwd_marshal_func, (void *)nss_lt_name, + retval, login, &pwd, + st->buffer, st->bufsize, &error); + break; case nss_lt_id: - result = getpwuid(uid); + do { + result = nsdispatch(&retval, emptydtab, NSDB_SERVICES, + "getpwuid_r", defaultsrc, uid, + &pwd, st->buffer, st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) { + TRACE_OUT(passwd_lookup_func); + return (NS_UNAVAIL); + } + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) + result = agent_marshal_results(out_buffer, out_size, + passwd_marshal_func, + (void *)nss_lt_id, retval, uid, + &pwd, st->buffer, st->bufsize, &error); break; default: /* SHOULD NOT BE REACHED */ break; - } + } - if (result != NULL) { - passwd_marshal_func(result, NULL, buffer_size); - *buffer = (char *)malloc(*buffer_size); - assert(*buffer != NULL); - passwd_marshal_func(result, *buffer, buffer_size); - } - + free(login); TRACE_OUT(passwd_lookup_func); - return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); + return (result); } static void * @@ -202,21 +278,40 @@ } static int -passwd_mp_lookup_func(char **buffer, size_t *buffer_size, void *mdata) +passwd_mp_lookup_func(char **out_buffer, size_t *out_size, void *mdata) { - struct passwd *result; + struct passwd_state *st; + struct passwd pwd, *retval; + int result, error; TRACE_IN(passwd_mp_lookup_func); - result = getpwent(); - if (result != NULL) { - passwd_marshal_func(result, NULL, buffer_size); - *buffer = (char *)malloc(*buffer_size); - assert(*buffer != NULL); - passwd_marshal_func(result, *buffer, buffer_size); + + result = passwd_getstate(&st); + AGENT_BUFFER_TLS_HANDLING_INIT(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) + return (NS_UNAVAIL); + + do { + result = nsdispatch(&retval, emptydtab, NSDB_PASSWD, + "getpwent_r", defaultsrc, &pwd, st->buffer, + st->bufsize, &error); + + if ((result == NS_RETURN) && (error == ERANGE)) { + AGENT_BUFFER_TLS_HANDLING_RESIZE(st); + if (AGENT_BUFFER_TLS_HANDLING_CHECK(st) != 0) + return (NS_UNAVAIL); + } + } while ((result == NS_RETURN) && (error == ERANGE)); + + if (result == NS_SUCCESS) { + result = agent_marshal_results(out_buffer, + out_size, passwd_marshal_func, + (void *)nss_lt_all, retval, &pwd, + st->buffer, st->bufsize, &error); } TRACE_OUT(passwd_mp_lookup_func); - return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); + return (result); } static void ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/passwd.h#2 (text) ==== ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/agents/services.c#2 (text) ==== @@ -31,31 +31,70 @@ #include #include #include +#include #include #include +#include +#include #include #include +#include #include "../debug.h" #include "services.h" -static int services_marshal_func(struct servent *, char *, size_t *); +static const ns_src defaultsrc[] = { + { NSSRC_COMPAT, NS_SUCCESS }, + { NULL, 0 } +}; + + +static int services_marshal_func(char *, size_t *, void *, va_list, void *); static int services_lookup_func(const char *, size_t, char **, size_t *); static void *services_mp_init_func(); -static int services_mp_lookup_func(char **, size_t *, void *); -static void services_mp_destroy_func(void *); +static int services_mp_lookup_func(char **out_buffer, size_t *out_size, void *mdata); +static void services_mp_destroy_func(void *mdata); + +AGENT_DECLARE_BUFFER_TLS_HANDLING(servent); static int -services_marshal_func(struct servent *serv, char *buffer, size_t *buffer_size) +services_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, + void *cache_mdata) { - struct servent new_serv; - size_t desired_size; - char **alias; - char *p; - size_t size; - size_t aliases_size; + char *name; + char *proto; + int port; + struct servent *serv; + char *orig_buf; + size_t orig_buf_size; + + struct servent new_serv; + size_t desired_size; + char **alias; + char *p; + size_t size; + size_t aliases_size; + + switch ((enum nss_lookup_type)cache_mdata) { + case nss_lt_name: + name = va_arg(ap, char *); + proto = va_arg(ap, char *); + break; + case nss_lt_id: + port = va_arg(ap, int); + proto = va_arg(ap, char *); + break; + case nss_lt_all: + break; + default: + /* should be unreachable */ + return (NS_UNAVAIL); + } + + serv = va_arg(ap, struct servent *); + orig_buf = va_arg(ap, char *); + orig_buf_size = va_arg(ap, size_t); - TRACE_IN(services_marshal_func); - desired_size = ALIGNBYTES + sizeof(struct servent) + sizeof(char *); + desired_size = _ALIGNBYTES + sizeof(struct servent) + sizeof(char *); if (serv->s_name != NULL) desired_size += strlen(serv->s_name) + 1; if (serv->s_proto != NULL) @@ -68,13 +107,13 @@ ++aliases_size; } - desired_size += ALIGNBYTES + sizeof(char *) * - (aliases_size + 1); + desired_size += _ALIGNBYTES + + sizeof(char *) * (aliases_size + 1); } - if ((*buffer_size < desired_size) || (buffer == NULL)) { + if (*buffer_size < desired_size) { + /* this assignment is here for future use */ *buffer_size = desired_size; - TRACE_OUT(services_marshal_func); return (NS_RETURN); } @@ -84,7 +123,7 @@ *buffer_size = desired_size; p = buffer + sizeof(struct servent) + sizeof(char *); memcpy(buffer + sizeof(struct servent), &p, sizeof(char *)); - p = (char *)ALIGN(p); + p = (char *)_ALIGN(p); if (new_serv.s_name != NULL) { size = strlen(new_serv.s_name); @@ -101,7 +140,7 @@ } if (new_serv.s_aliases != NULL) { - p = (char *)ALIGN(p); + p = (char *)_ALIGN(p); memcpy(p, new_serv.s_aliases, sizeof(char *) * aliases_size); new_serv.s_aliases = (char **)p; p += sizeof(char *) * (aliases_size + 1); @@ -115,26 +154,24 @@ } memcpy(buffer, &new_serv, sizeof(struct servent)); - TRACE_OUT(services_marshal_func); return (NS_SUCCESS); } static int -services_lookup_func(const char *key, size_t key_size, char **buffer, - size_t *buffer_size) +services_lookup_func(const char *key, size_t key_size, char **out_buffer, + size_t *out_size) { + struct servent_state *st; + struct servent serv, *retval; + char *name; + char *proto; + size_t size, size2; enum nss_lookup_type lookup_type; - char *name = NULL; - char *proto = NULL; - size_t size, size2; - int port; + int port, error, result; - struct servent *result; - TRACE_IN(services_lookup_func); - - assert(buffer != NULL); - assert(buffer_size != NULL); + assert(out_buffer != NULL); + assert(out_size != NULL); if (key_size < sizeof(enum nss_lookup_type)) { TRACE_OUT(passwd_lookup_func); @@ -142,8 +179,9 @@ } memcpy(&lookup_type, key, sizeof(enum nss_lookup_type)); + name = NULL; + proto = NULL; switch (lookup_type) { - case nss_lt_name: size = key_size - sizeof(enum nss_lookup_type); >>> TRUNCATED FOR MAIL (1000 lines) <<<