2 * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org>
3 * Copyright (C) Guenther Deschner 2009 <gd@samba.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the author nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 /* defining this gives us the posix getpwnam_r() calls on solaris
38 Thanks to heimdal for this */
39 #define _POSIX_PTHREAD_SEMANTICS
41 #define NSS_WRAPPER_NOT_REPLACE
42 #include "../replace/replace.h"
43 #include "system/passwd.h"
44 #include "system/filesys.h"
45 #include "../nsswitch/nsstest.h"
47 #else /* _SAMBA_BUILD_ */
49 #error nss_wrapper_only_supported_in_samba_yet
57 /* not all systems have _r functions... */
58 #ifndef HAVE_GETPWNAM_R
59 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
61 #ifndef HAVE_GETPWUID_R
62 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
64 #ifndef HAVE_GETPWENT_R
65 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
67 #ifndef HAVE_GETGRNAM_R
68 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
70 #ifndef HAVE_GETGRGID_R
71 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
73 #ifndef HAVE_GETGRENT_R
74 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
77 /* not all systems have getgrouplist */
78 #ifndef HAVE_GETGROUPLIST
79 #define getgrouplist(user, group, groups, ngroups) 0
82 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
88 #define real_getpwnam getpwnam
89 #define real_getpwnam_r getpwnam_r
90 #define real_getpwuid getpwuid
91 #define real_getpwuid_r getpwuid_r
93 #define real_setpwent setpwent
94 #define real_getpwent getpwent
95 #define real_getpwent_r getpwent_r
96 #define real_endpwent endpwent
99 #define real_getgrlst getgrlst
100 #define real_getgrlst_r getgrlst_r
101 #define real_initgroups_dyn initgroups_dyn
103 #define real_initgroups initgroups
104 #define real_getgrouplist getgrouplist
106 #define real_getgrnam getgrnam
107 #define real_getgrnam_r getgrnam_r
108 #define real_getgrgid getgrgid
109 #define real_getgrgid_r getgrgid_r
111 #define real_setgrent setgrent
112 #define real_getgrent getgrent
113 #define real_getgrent_r getgrent_r
114 #define real_endgrent endgrent
120 # define NWRAP_ERROR(args) DEBUG(0, args)
122 # define NWRAP_ERROR(args) printf args
125 #define NWRAP_ERROR(args)
130 # define NWRAP_DEBUG(args) DEBUG(0, args)
132 # define NWRAP_DEBUG(args) printf args
135 #define NWRAP_DEBUG(args)
140 # define NWRAP_VERBOSE(args) DEBUG(0, args)
142 # define NWRAP_VERBOSE(args) printf args
145 #define NWRAP_VERBOSE(args)
148 struct nwrap_module_nss_fns {
149 NSS_STATUS (*_nss_getpwnam_r)(const char *name, struct passwd *result, char *buffer,
150 size_t buflen, int *errnop);
151 NSS_STATUS (*_nss_getpwuid_r)(uid_t uid, struct passwd *result, char *buffer,
152 size_t buflen, int *errnop);
153 NSS_STATUS (*_nss_setpwent)(void);
154 NSS_STATUS (*_nss_getpwent_r)(struct passwd *result, char *buffer,
155 size_t buflen, int *errnop);
156 NSS_STATUS (*_nss_endpwent)(void);
157 NSS_STATUS (*_nss_initgroups)(const char *user, gid_t group, long int *start,
158 long int *size, gid_t **groups, long int limit, int *errnop);
159 NSS_STATUS (*_nss_getgrnam_r)(const char *name, struct group *result, char *buffer,
160 size_t buflen, int *errnop);
161 NSS_STATUS (*_nss_getgrgid_r)(gid_t gid, struct group *result, char *buffer,
162 size_t buflen, int *errnop);
163 NSS_STATUS (*_nss_setgrent)(void);
164 NSS_STATUS (*_nss_getgrent_r)(struct group *result, char *buffer,
165 size_t buflen, int *errnop);
166 NSS_STATUS (*_nss_endgrent)(void);
169 struct nwrap_backend {
173 struct nwrap_ops *ops;
174 struct nwrap_module_nss_fns *fns;
178 struct passwd * (*nw_getpwnam)(struct nwrap_backend *b,
180 int (*nw_getpwnam_r)(struct nwrap_backend *b,
181 const char *name, struct passwd *pwdst,
182 char *buf, size_t buflen, struct passwd **pwdstp);
183 struct passwd * (*nw_getpwuid)(struct nwrap_backend *b,
185 int (*nw_getpwuid_r)(struct nwrap_backend *b,
186 uid_t uid, struct passwd *pwdst,
187 char *buf, size_t buflen, struct passwd **pwdstp);
188 void (*nw_setpwent)(struct nwrap_backend *b);
189 struct passwd * (*nw_getpwent)(struct nwrap_backend *b);
190 int (*nw_getpwent_r)(struct nwrap_backend *b,
191 struct passwd *pwdst, char *buf,
192 size_t buflen, struct passwd **pwdstp);
193 void (*nw_endpwent)(struct nwrap_backend *b);
194 int (*nw_initgroups)(struct nwrap_backend *b,
195 const char *user, gid_t group);
196 struct group * (*nw_getgrnam)(struct nwrap_backend *b,
198 int (*nw_getgrnam_r)(struct nwrap_backend *b,
199 const char *name, struct group *grdst,
200 char *buf, size_t buflen, struct group **grdstp);
201 struct group * (*nw_getgrgid)(struct nwrap_backend *b,
203 int (*nw_getgrgid_r)(struct nwrap_backend *b,
204 gid_t gid, struct group *grdst,
205 char *buf, size_t buflen, struct group **grdstp);
206 void (*nw_setgrent)(struct nwrap_backend *b);
207 struct group * (*nw_getgrent)(struct nwrap_backend *b);
208 int (*nw_getgrent_r)(struct nwrap_backend *b,
209 struct group *grdst, char *buf,
210 size_t buflen, struct group **grdstp);
211 void (*nw_endgrent)(struct nwrap_backend *b);
214 /* prototypes for files backend */
217 static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b,
219 static int nwrap_files_getpwnam_r(struct nwrap_backend *b,
220 const char *name, struct passwd *pwdst,
221 char *buf, size_t buflen, struct passwd **pwdstp);
222 static struct passwd *nwrap_files_getpwuid(struct nwrap_backend *b,
224 static int nwrap_files_getpwuid_r(struct nwrap_backend *b,
225 uid_t uid, struct passwd *pwdst,
226 char *buf, size_t buflen, struct passwd **pwdstp);
227 static void nwrap_files_setpwent(struct nwrap_backend *b);
228 static struct passwd *nwrap_files_getpwent(struct nwrap_backend *b);
229 static int nwrap_files_getpwent_r(struct nwrap_backend *b,
230 struct passwd *pwdst, char *buf,
231 size_t buflen, struct passwd **pwdstp);
232 static void nwrap_files_endpwent(struct nwrap_backend *b);
233 static int nwrap_files_initgroups(struct nwrap_backend *b,
234 const char *user, gid_t group);
235 static struct group *nwrap_files_getgrnam(struct nwrap_backend *b,
237 static int nwrap_files_getgrnam_r(struct nwrap_backend *b,
238 const char *name, struct group *grdst,
239 char *buf, size_t buflen, struct group **grdstp);
240 static struct group *nwrap_files_getgrgid(struct nwrap_backend *b,
242 static int nwrap_files_getgrgid_r(struct nwrap_backend *b,
243 gid_t gid, struct group *grdst,
244 char *buf, size_t buflen, struct group **grdstp);
245 static void nwrap_files_setgrent(struct nwrap_backend *b);
246 static struct group *nwrap_files_getgrent(struct nwrap_backend *b);
247 static int nwrap_files_getgrent_r(struct nwrap_backend *b,
248 struct group *grdst, char *buf,
249 size_t buflen, struct group **grdstp);
250 static void nwrap_files_endgrent(struct nwrap_backend *b);
252 /* prototypes for module backend */
254 static struct passwd *nwrap_module_getpwent(struct nwrap_backend *b);
255 static int nwrap_module_getpwent_r(struct nwrap_backend *b,
256 struct passwd *pwdst, char *buf,
257 size_t buflen, struct passwd **pwdstp);
258 static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b,
260 static int nwrap_module_getpwnam_r(struct nwrap_backend *b,
261 const char *name, struct passwd *pwdst,
262 char *buf, size_t buflen, struct passwd **pwdstp);
263 static struct passwd *nwrap_module_getpwuid(struct nwrap_backend *b,
265 static int nwrap_module_getpwuid_r(struct nwrap_backend *b,
266 uid_t uid, struct passwd *pwdst,
267 char *buf, size_t buflen, struct passwd **pwdstp);
268 static void nwrap_module_setpwent(struct nwrap_backend *b);
269 static void nwrap_module_endpwent(struct nwrap_backend *b);
270 static struct group *nwrap_module_getgrent(struct nwrap_backend *b);
271 static int nwrap_module_getgrent_r(struct nwrap_backend *b,
272 struct group *grdst, char *buf,
273 size_t buflen, struct group **grdstp);
274 static struct group *nwrap_module_getgrnam(struct nwrap_backend *b,
276 static int nwrap_module_getgrnam_r(struct nwrap_backend *b,
277 const char *name, struct group *grdst,
278 char *buf, size_t buflen, struct group **grdstp);
279 static struct group *nwrap_module_getgrgid(struct nwrap_backend *b,
281 static int nwrap_module_getgrgid_r(struct nwrap_backend *b,
282 gid_t gid, struct group *grdst,
283 char *buf, size_t buflen, struct group **grdstp);
284 static void nwrap_module_setgrent(struct nwrap_backend *b);
285 static void nwrap_module_endgrent(struct nwrap_backend *b);
286 static int nwrap_module_initgroups(struct nwrap_backend *b,
287 const char *user, gid_t group);
289 struct nwrap_ops nwrap_files_ops = {
290 .nw_getpwnam = nwrap_files_getpwnam,
291 .nw_getpwnam_r = nwrap_files_getpwnam_r,
292 .nw_getpwuid = nwrap_files_getpwuid,
293 .nw_getpwuid_r = nwrap_files_getpwuid_r,
294 .nw_setpwent = nwrap_files_setpwent,
295 .nw_getpwent = nwrap_files_getpwent,
296 .nw_getpwent_r = nwrap_files_getpwent_r,
297 .nw_endpwent = nwrap_files_endpwent,
298 .nw_initgroups = nwrap_files_initgroups,
299 .nw_getgrnam = nwrap_files_getgrnam,
300 .nw_getgrnam_r = nwrap_files_getgrnam_r,
301 .nw_getgrgid = nwrap_files_getgrgid,
302 .nw_getgrgid_r = nwrap_files_getgrgid_r,
303 .nw_setgrent = nwrap_files_setgrent,
304 .nw_getgrent = nwrap_files_getgrent,
305 .nw_getgrent_r = nwrap_files_getgrent_r,
306 .nw_endgrent = nwrap_files_endgrent,
309 struct nwrap_ops nwrap_module_ops = {
310 .nw_getpwnam = nwrap_module_getpwnam,
311 .nw_getpwnam_r = nwrap_module_getpwnam_r,
312 .nw_getpwuid = nwrap_module_getpwuid,
313 .nw_getpwuid_r = nwrap_module_getpwuid_r,
314 .nw_setpwent = nwrap_module_setpwent,
315 .nw_getpwent = nwrap_module_getpwent,
316 .nw_getpwent_r = nwrap_module_getpwent_r,
317 .nw_endpwent = nwrap_module_endpwent,
318 .nw_initgroups = nwrap_module_initgroups,
319 .nw_getgrnam = nwrap_module_getgrnam,
320 .nw_getgrnam_r = nwrap_module_getgrnam_r,
321 .nw_getgrgid = nwrap_module_getgrgid,
322 .nw_getgrgid_r = nwrap_module_getgrgid_r,
323 .nw_setgrent = nwrap_module_setgrent,
324 .nw_getgrent = nwrap_module_getgrent,
325 .nw_getgrent_r = nwrap_module_getgrent_r,
326 .nw_endgrent = nwrap_module_endgrent,
330 const char *nwrap_switch;
332 struct nwrap_backend *backends;
335 struct nwrap_main *nwrap_main_global;
336 struct nwrap_main __nwrap_main_global;
344 bool (*parse_line)(struct nwrap_cache *, char *line);
345 void (*unload)(struct nwrap_cache *);
349 struct nwrap_cache *cache;
356 struct nwrap_cache __nwrap_cache_pw;
357 struct nwrap_pw nwrap_pw_global;
359 static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line);
360 static void nwrap_pw_unload(struct nwrap_cache *nwrap);
363 struct nwrap_cache *cache;
370 struct nwrap_cache __nwrap_cache_gr;
371 struct nwrap_gr nwrap_gr_global;
373 static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line);
374 static void nwrap_gr_unload(struct nwrap_cache *nwrap);
376 static void *nwrap_load_module_fn(struct nwrap_backend *b,
383 NWRAP_ERROR(("%s: no handle\n",
388 if (asprintf(&s, "_nss_%s_%s", b->name, fn_name) == -1) {
389 NWRAP_ERROR(("%s: out of memory\n",
394 res = dlsym(b->so_handle, s);
396 NWRAP_ERROR(("%s: cannot find function %s in %s\n",
397 __location__, s, b->so_path));
404 static struct nwrap_module_nss_fns *nwrap_load_module_fns(struct nwrap_backend *b)
406 struct nwrap_module_nss_fns *fns;
412 fns = (struct nwrap_module_nss_fns *)malloc(sizeof(struct nwrap_module_nss_fns));
417 fns->_nss_getpwnam_r = (NSS_STATUS (*)(const char *, struct passwd *, char *, size_t, int *))
418 nwrap_load_module_fn(b, "getpwnam_r");
419 fns->_nss_getpwuid_r = (NSS_STATUS (*)(uid_t, struct passwd *, char *, size_t, int *))
420 nwrap_load_module_fn(b, "getpwuid_r");
421 fns->_nss_setpwent = (NSS_STATUS(*)(void))
422 nwrap_load_module_fn(b, "setpwent");
423 fns->_nss_getpwent_r = (NSS_STATUS (*)(struct passwd *, char *, size_t, int *))
424 nwrap_load_module_fn(b, "getpwent_r");
425 fns->_nss_endpwent = (NSS_STATUS(*)(void))
426 nwrap_load_module_fn(b, "endpwent");
427 fns->_nss_initgroups = (NSS_STATUS (*)(const char *, gid_t, long int *, long int *, gid_t **, long int, int *))
428 nwrap_load_module_fn(b, "initgroups_dyn");
429 fns->_nss_getgrnam_r = (NSS_STATUS (*)(const char *, struct group *, char *, size_t, int *))
430 nwrap_load_module_fn(b, "getgrnam_r");
431 fns->_nss_getgrgid_r = (NSS_STATUS (*)(gid_t, struct group *, char *, size_t, int *))
432 nwrap_load_module_fn(b, "getgrgid_r");
433 fns->_nss_setgrent = (NSS_STATUS(*)(void))
434 nwrap_load_module_fn(b, "setgrent");
435 fns->_nss_getgrent_r = (NSS_STATUS (*)(struct group *, char *, size_t, int *))
436 nwrap_load_module_fn(b, "getgrent_r");
437 fns->_nss_endgrent = (NSS_STATUS(*)(void))
438 nwrap_load_module_fn(b, "endgrent");
443 static void *nwrap_load_module(const char *so_path)
447 if (!so_path || !strlen(so_path)) {
451 h = dlopen(so_path, RTLD_LAZY);
453 NWRAP_ERROR(("%s: cannot open shared library %s\n",
454 __location__, so_path));
461 static bool nwrap_module_init(const char *name,
462 struct nwrap_ops *ops,
465 struct nwrap_backend **backends)
467 struct nwrap_backend *b;
469 *backends = (struct nwrap_backend *)realloc(*backends,
470 sizeof(struct nwrap_backend) * ((*num_backends) + 1));
472 NWRAP_ERROR(("%s: out of memory\n",
477 b = &((*backends)[*num_backends]);
481 b->so_path = so_path;
482 b->so_handle = nwrap_load_module(so_path);
483 b->fns = nwrap_load_module_fns(b);
490 static void nwrap_backend_init(struct nwrap_main *r)
492 const char *winbind_so_path = getenv("NSS_WRAPPER_WINBIND_SO_PATH");
497 if (!nwrap_module_init("files", &nwrap_files_ops, NULL,
500 NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
505 if (winbind_so_path && strlen(winbind_so_path)) {
506 if (!nwrap_module_init("winbind", &nwrap_module_ops, winbind_so_path,
509 NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n",
516 static void nwrap_init(void)
518 static bool initialized;
520 if (initialized) return;
523 nwrap_main_global = &__nwrap_main_global;
525 nwrap_backend_init(nwrap_main_global);
527 nwrap_pw_global.cache = &__nwrap_cache_pw;
529 nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD");
530 nwrap_pw_global.cache->fd = -1;
531 nwrap_pw_global.cache->private_data = &nwrap_pw_global;
532 nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line;
533 nwrap_pw_global.cache->unload = nwrap_pw_unload;
535 nwrap_gr_global.cache = &__nwrap_cache_gr;
537 nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP");
538 nwrap_gr_global.cache->fd = -1;
539 nwrap_gr_global.cache->private_data = &nwrap_gr_global;
540 nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line;
541 nwrap_gr_global.cache->unload = nwrap_gr_unload;
544 static bool nwrap_enabled(void)
548 if (!nwrap_pw_global.cache->path) {
551 if (nwrap_pw_global.cache->path[0] == '\0') {
554 if (!nwrap_gr_global.cache->path) {
557 if (nwrap_gr_global.cache->path[0] == '\0') {
564 static bool nwrap_parse_file(struct nwrap_cache *nwrap)
570 if (nwrap->st.st_size == 0) {
571 NWRAP_DEBUG(("%s: size == 0\n",
576 if (nwrap->st.st_size > INT32_MAX) {
577 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
578 __location__, (unsigned)nwrap->st.st_size));
582 ret = lseek(nwrap->fd, 0, SEEK_SET);
584 NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret));
588 buf = (uint8_t *)malloc(nwrap->st.st_size + 1);
590 NWRAP_ERROR(("%s: malloc failed\n",__location__));
594 ret = read(nwrap->fd, buf, nwrap->st.st_size);
595 if (ret != nwrap->st.st_size) {
596 NWRAP_ERROR(("%s: read(%u) gave %d\n",
597 __location__, (unsigned)nwrap->st.st_size, ret));
601 buf[nwrap->st.st_size] = '\0';
604 while (nline && nline[0]) {
612 e = strchr(line, '\n');
623 NWRAP_VERBOSE(("%s:'%s'\n",__location__, line));
625 if (strlen(line) == 0) {
629 ok = nwrap->parse_line(nwrap, line);
644 static void nwrap_files_cache_unload(struct nwrap_cache *nwrap)
646 nwrap->unload(nwrap);
648 if (nwrap->buf) free(nwrap->buf);
653 static void nwrap_files_cache_reload(struct nwrap_cache *nwrap)
658 bool retried = false;
662 nwrap->fd = open(nwrap->path, O_RDONLY);
664 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
666 nwrap->path, nwrap->fd,
670 NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path));
673 ret = fstat(nwrap->fd, &st);
675 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
678 ret, strerror(errno)));
682 if (retried == false && st.st_nlink == 0) {
683 /* maybe someone has replaced the file... */
684 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
685 __location__, nwrap->path));
687 memset(&nwrap->st, 0, sizeof(nwrap->st));
693 if (st.st_mtime == nwrap->st.st_mtime) {
694 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
695 __location__, (unsigned)st.st_mtime));
698 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
699 __location__, (unsigned)st.st_mtime,
700 (unsigned)nwrap->st.st_mtime));
704 nwrap_files_cache_unload(nwrap);
706 ok = nwrap_parse_file(nwrap);
708 NWRAP_ERROR(("%s: failed to reload %s\n",
709 __location__, nwrap->path));
710 nwrap_files_cache_unload(nwrap);
712 NWRAP_DEBUG(("%s: reloaded %s\n",
713 __location__, nwrap->path));
717 * the caller has to call nwrap_unload() on failure
719 static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
721 struct nwrap_pw *nwrap_pw;
728 nwrap_pw = (struct nwrap_pw *)nwrap->private_data;
730 list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1);
731 pw = (struct passwd *)realloc(nwrap_pw->list, list_size);
733 NWRAP_ERROR(("%s:realloc(%u) failed\n",
734 __location__, list_size));
739 pw = &nwrap_pw->list[nwrap_pw->num];
746 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
747 __location__, line, c));
755 NWRAP_VERBOSE(("name[%s]\n", pw->pw_name));
760 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
761 __location__, line, c));
769 NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd));
774 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
775 __location__, line, c));
781 pw->pw_uid = (uid_t)strtoul(c, &e, 10);
783 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
784 __location__, line, c, strerror(errno)));
788 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
789 __location__, line, c, strerror(errno)));
793 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
794 __location__, line, c, strerror(errno)));
799 NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid));
804 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
805 __location__, line, c));
811 pw->pw_gid = (gid_t)strtoul(c, &e, 10);
813 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
814 __location__, line, c, strerror(errno)));
818 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
819 __location__, line, c, strerror(errno)));
823 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
824 __location__, line, c, strerror(errno)));
829 NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid));
834 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
835 __location__, line, c));
843 NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos));
848 NWRAP_ERROR(("%s:'%s'\n",__location__,c));
856 NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir));
860 NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell));
862 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
863 pw->pw_name, pw->pw_passwd,
864 pw->pw_uid, pw->pw_gid,
865 pw->pw_gecos, pw->pw_dir, pw->pw_shell));
871 static void nwrap_pw_unload(struct nwrap_cache *nwrap)
873 struct nwrap_pw *nwrap_pw;
874 nwrap_pw = (struct nwrap_pw *)nwrap->private_data;
876 if (nwrap_pw->list) free(nwrap_pw->list);
878 nwrap_pw->list = NULL;
883 static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst,
884 char *buf, size_t buflen, struct passwd **dstp)
890 first = src->pw_name;
892 last = src->pw_shell;
893 while (*last) last++;
895 ofs = PTR_DIFF(last + 1, first);
901 memcpy(buf, first, ofs);
903 ofs = PTR_DIFF(src->pw_name, first);
904 dst->pw_name = buf + ofs;
905 ofs = PTR_DIFF(src->pw_passwd, first);
906 dst->pw_passwd = buf + ofs;
907 dst->pw_uid = src->pw_uid;
908 dst->pw_gid = src->pw_gid;
909 ofs = PTR_DIFF(src->pw_gecos, first);
910 dst->pw_gecos = buf + ofs;
911 ofs = PTR_DIFF(src->pw_dir, first);
912 dst->pw_dir = buf + ofs;
913 ofs = PTR_DIFF(src->pw_shell, first);
914 dst->pw_shell = buf + ofs;
924 * the caller has to call nwrap_unload() on failure
926 static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
928 struct nwrap_gr *nwrap_gr;
936 nwrap_gr = (struct nwrap_gr *)nwrap->private_data;
938 list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1);
939 gr = (struct group *)realloc(nwrap_gr->list, list_size);
941 NWRAP_ERROR(("%s:realloc failed\n",__location__));
946 gr = &nwrap_gr->list[nwrap_gr->num];
953 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
954 __location__, line, c));
962 NWRAP_VERBOSE(("name[%s]\n", gr->gr_name));
967 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
968 __location__, line, c));
976 NWRAP_VERBOSE(("password[%s]\n", gr->gr_passwd));
981 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
982 __location__, line, c));
988 gr->gr_gid = (gid_t)strtoul(c, &e, 10);
990 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
991 __location__, line, c, strerror(errno)));
995 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
996 __location__, line, c, strerror(errno)));
1000 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1001 __location__, line, c, strerror(errno)));
1006 NWRAP_VERBOSE(("gid[%u]\n", gr->gr_gid));
1009 gr->gr_mem = (char **)malloc(sizeof(char *));
1011 NWRAP_ERROR(("%s:calloc failed\n",__location__));
1014 gr->gr_mem[0] = NULL;
1016 for(nummem=0; p; nummem++) {
1026 if (strlen(c) == 0) {
1030 m_size = sizeof(char *) * (nummem+2);
1031 m = (char **)realloc(gr->gr_mem, m_size);
1033 NWRAP_ERROR(("%s:realloc(%u) failed\n",
1034 __location__, m_size));
1038 gr->gr_mem[nummem] = c;
1039 gr->gr_mem[nummem+1] = NULL;
1041 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem]));
1044 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
1045 gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem));
1051 static void nwrap_gr_unload(struct nwrap_cache *nwrap)
1054 struct nwrap_gr *nwrap_gr;
1055 nwrap_gr = (struct nwrap_gr *)nwrap->private_data;
1057 if (nwrap_gr->list) {
1058 for (i=0; i < nwrap_gr->num; i++) {
1059 if (nwrap_gr->list[i].gr_mem) {
1060 free(nwrap_gr->list[i].gr_mem);
1063 free(nwrap_gr->list);
1066 nwrap_gr->list = NULL;
1071 static int nwrap_gr_copy_r(const struct group *src, struct group *dst,
1072 char *buf, size_t buflen, struct group **dstp)
1082 first = src->gr_name;
1084 lastm = src->gr_mem;
1091 last = src->gr_passwd;
1093 while (*last) last++;
1095 ofsb = PTR_DIFF(last + 1, first);
1096 ofsm = PTR_DIFF(lastm + 1, src->gr_mem);
1098 if ((ofsb + ofsm) > buflen) {
1102 memcpy(buf, first, ofsb);
1103 memcpy(buf + ofsb, src->gr_mem, ofsm);
1105 ofs = PTR_DIFF(src->gr_name, first);
1106 dst->gr_name = buf + ofs;
1107 ofs = PTR_DIFF(src->gr_passwd, first);
1108 dst->gr_passwd = buf + ofs;
1109 dst->gr_gid = src->gr_gid;
1111 dst->gr_mem = (char **)(buf + ofsb);
1112 for (i=0; src->gr_mem[i]; i++) {
1113 ofs = PTR_DIFF(src->gr_mem[i], first);
1114 dst->gr_mem[i] = buf + ofs;
1124 /* user functions */
1125 static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b,
1130 nwrap_files_cache_reload(nwrap_pw_global.cache);
1132 for (i=0; i<nwrap_pw_global.num; i++) {
1133 if (strcmp(nwrap_pw_global.list[i].pw_name, name) == 0) {
1134 NWRAP_DEBUG(("%s: user[%s] found\n",
1135 __location__, name));
1136 return &nwrap_pw_global.list[i];
1138 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
1140 nwrap_pw_global.list[i].pw_name));
1143 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__, name));
1149 static int nwrap_files_getpwnam_r(struct nwrap_backend *b,
1150 const char *name, struct passwd *pwdst,
1151 char *buf, size_t buflen, struct passwd **pwdstp)
1155 pw = nwrap_files_getpwnam(b, name);
1163 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
1166 static struct passwd *nwrap_files_getpwuid(struct nwrap_backend *b,
1171 nwrap_files_cache_reload(nwrap_pw_global.cache);
1173 for (i=0; i<nwrap_pw_global.num; i++) {
1174 if (nwrap_pw_global.list[i].pw_uid == uid) {
1175 NWRAP_DEBUG(("%s: uid[%u] found\n",
1176 __location__, uid));
1177 return &nwrap_pw_global.list[i];
1179 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
1181 nwrap_pw_global.list[i].pw_uid));
1184 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__, uid));
1190 static int nwrap_files_getpwuid_r(struct nwrap_backend *b,
1191 uid_t uid, struct passwd *pwdst,
1192 char *buf, size_t buflen, struct passwd **pwdstp)
1196 pw = nwrap_files_getpwuid(b, uid);
1204 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
1207 /* user enum functions */
1208 static void nwrap_files_setpwent(struct nwrap_backend *b)
1210 nwrap_pw_global.idx = 0;
1213 static struct passwd *nwrap_files_getpwent(struct nwrap_backend *b)
1217 if (nwrap_pw_global.idx == 0) {
1218 nwrap_files_cache_reload(nwrap_pw_global.cache);
1221 if (nwrap_pw_global.idx >= nwrap_pw_global.num) {
1226 pw = &nwrap_pw_global.list[nwrap_pw_global.idx++];
1228 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
1229 __location__, pw->pw_name, pw->pw_uid));
1234 static int nwrap_files_getpwent_r(struct nwrap_backend *b,
1235 struct passwd *pwdst, char *buf,
1236 size_t buflen, struct passwd **pwdstp)
1240 pw = nwrap_files_getpwent(b);
1248 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
1251 static void nwrap_files_endpwent(struct nwrap_backend *b)
1253 nwrap_pw_global.idx = 0;
1256 /* misc functions */
1257 static int nwrap_files_initgroups(struct nwrap_backend *b,
1258 const char *user, gid_t group)
1260 /* TODO: maybe we should also fake this... */
1264 /* group functions */
1265 static struct group *nwrap_files_getgrnam(struct nwrap_backend *b,
1270 nwrap_files_cache_reload(nwrap_gr_global.cache);
1272 for (i=0; i<nwrap_gr_global.num; i++) {
1273 if (strcmp(nwrap_gr_global.list[i].gr_name, name) == 0) {
1274 NWRAP_DEBUG(("%s: group[%s] found\n",
1275 __location__, name));
1276 return &nwrap_gr_global.list[i];
1278 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1280 nwrap_gr_global.list[i].gr_name));
1283 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__, name));
1289 static int nwrap_files_getgrnam_r(struct nwrap_backend *b,
1290 const char *name, struct group *grdst,
1291 char *buf, size_t buflen, struct group **grdstp)
1295 gr = nwrap_files_getgrnam(b, name);
1303 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1306 static struct group *nwrap_files_getgrgid(struct nwrap_backend *b,
1311 nwrap_files_cache_reload(nwrap_gr_global.cache);
1313 for (i=0; i<nwrap_gr_global.num; i++) {
1314 if (nwrap_gr_global.list[i].gr_gid == gid) {
1315 NWRAP_DEBUG(("%s: gid[%u] found\n",
1316 __location__, gid));
1317 return &nwrap_gr_global.list[i];
1319 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1321 nwrap_gr_global.list[i].gr_gid));
1324 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__, gid));
1330 static int nwrap_files_getgrgid_r(struct nwrap_backend *b,
1331 gid_t gid, struct group *grdst,
1332 char *buf, size_t buflen, struct group **grdstp)
1336 gr = nwrap_files_getgrgid(b, gid);
1344 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1347 /* group enum functions */
1348 static void nwrap_files_setgrent(struct nwrap_backend *b)
1350 nwrap_gr_global.idx = 0;
1353 static struct group *nwrap_files_getgrent(struct nwrap_backend *b)
1357 if (nwrap_gr_global.idx == 0) {
1358 nwrap_files_cache_reload(nwrap_gr_global.cache);
1361 if (nwrap_gr_global.idx >= nwrap_gr_global.num) {
1366 gr = &nwrap_gr_global.list[nwrap_gr_global.idx++];
1368 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1369 __location__, gr->gr_name, gr->gr_gid));
1374 static int nwrap_files_getgrent_r(struct nwrap_backend *b,
1375 struct group *grdst, char *buf,
1376 size_t buflen, struct group **grdstp)
1380 gr = nwrap_files_getgrent(b);
1388 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1391 static void nwrap_files_endgrent(struct nwrap_backend *b)
1393 nwrap_gr_global.idx = 0;
1401 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
1404 static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b,
1407 static struct passwd pwd;
1408 static char buf[1000];
1411 if (!b->fns->_nss_getpwnam_r) {
1415 status = b->fns->_nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &errno);
1416 if (status == NSS_STATUS_NOTFOUND) {
1419 if (status != NSS_STATUS_SUCCESS) {
1425 static int nwrap_module_getpwnam_r(struct nwrap_backend *b,
1426 const char *name, struct passwd *pwdst,
1427 char *buf, size_t buflen, struct passwd **pwdstp)
1431 if (!b->fns->_nss_getpwnam_r) {
1432 return NSS_STATUS_NOTFOUND;
1435 ret = b->fns->_nss_getpwnam_r(name, pwdst, buf, buflen, &errno);
1437 case NSS_STATUS_SUCCESS:
1439 case NSS_STATUS_NOTFOUND:
1444 case NSS_STATUS_TRYAGAIN:
1457 static struct passwd *nwrap_module_getpwuid(struct nwrap_backend *b,
1460 static struct passwd pwd;
1461 static char buf[1000];
1464 if (!b->fns->_nss_getpwuid_r) {
1468 status = b->fns->_nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &errno);
1469 if (status == NSS_STATUS_NOTFOUND) {
1472 if (status != NSS_STATUS_SUCCESS) {
1478 static int nwrap_module_getpwuid_r(struct nwrap_backend *b,
1479 uid_t uid, struct passwd *pwdst,
1480 char *buf, size_t buflen, struct passwd **pwdstp)
1484 if (!b->fns->_nss_getpwuid_r) {
1488 ret = b->fns->_nss_getpwuid_r(uid, pwdst, buf, buflen, &errno);
1490 case NSS_STATUS_SUCCESS:
1492 case NSS_STATUS_NOTFOUND:
1497 case NSS_STATUS_TRYAGAIN:
1510 static void nwrap_module_setpwent(struct nwrap_backend *b)
1512 if (!b->fns->_nss_setpwent) {
1516 b->fns->_nss_setpwent();
1519 static struct passwd *nwrap_module_getpwent(struct nwrap_backend *b)
1521 static struct passwd pwd;
1522 static char buf[1000];
1525 if (!b->fns->_nss_getpwent_r) {
1529 status = b->fns->_nss_getpwent_r(&pwd, buf, sizeof(buf), &errno);
1530 if (status == NSS_STATUS_NOTFOUND) {
1533 if (status != NSS_STATUS_SUCCESS) {
1539 static int nwrap_module_getpwent_r(struct nwrap_backend *b,
1540 struct passwd *pwdst, char *buf,
1541 size_t buflen, struct passwd **pwdstp)
1545 if (!b->fns->_nss_getpwent_r) {
1549 ret = b->fns->_nss_getpwent_r(pwdst, buf, buflen, &errno);
1551 case NSS_STATUS_SUCCESS:
1553 case NSS_STATUS_NOTFOUND:
1558 case NSS_STATUS_TRYAGAIN:
1571 static void nwrap_module_endpwent(struct nwrap_backend *b)
1573 if (!b->fns->_nss_endpwent) {
1577 b->fns->_nss_endpwent();
1580 static int nwrap_module_initgroups(struct nwrap_backend *b,
1581 const char *user, gid_t group)
1587 if (!b->fns->_nss_initgroups) {
1588 return NSS_STATUS_UNAVAIL;
1591 return b->fns->_nss_initgroups(user, group, &start, &size, &groups, 0, &errno);
1594 static struct group *nwrap_module_getgrnam(struct nwrap_backend *b,
1597 static struct group grp;
1599 static int buflen = 1000;
1602 if (!b->fns->_nss_getgrnam_r) {
1607 buf = (char *)malloc(buflen);
1610 status = b->fns->_nss_getgrnam_r(name, &grp, buf, buflen, &errno);
1611 if (status == NSS_STATUS_TRYAGAIN) {
1613 buf = (char *)realloc(buf, buflen);
1619 if (status == NSS_STATUS_NOTFOUND) {
1623 if (status != NSS_STATUS_SUCCESS) {
1630 static int nwrap_module_getgrnam_r(struct nwrap_backend *b,
1631 const char *name, struct group *grdst,
1632 char *buf, size_t buflen, struct group **grdstp)
1636 if (!b->fns->_nss_getgrnam_r) {
1640 ret = b->fns->_nss_getgrnam_r(name, grdst, buf, buflen, &errno);
1642 case NSS_STATUS_SUCCESS:
1644 case NSS_STATUS_NOTFOUND:
1649 case NSS_STATUS_TRYAGAIN:
1662 static struct group *nwrap_module_getgrgid(struct nwrap_backend *b,
1665 static struct group grp;
1667 static int buflen = 1000;
1670 if (!b->fns->_nss_getgrgid_r) {
1675 buf = (char *)malloc(buflen);
1679 status = b->fns->_nss_getgrgid_r(gid, &grp, buf, buflen, &errno);
1680 if (status == NSS_STATUS_TRYAGAIN) {
1682 buf = (char *)realloc(buf, buflen);
1688 if (status == NSS_STATUS_NOTFOUND) {
1692 if (status != NSS_STATUS_SUCCESS) {
1699 static int nwrap_module_getgrgid_r(struct nwrap_backend *b,
1700 gid_t gid, struct group *grdst,
1701 char *buf, size_t buflen, struct group **grdstp)
1705 if (!b->fns->_nss_getgrgid_r) {
1709 ret = b->fns->_nss_getgrgid_r(gid, grdst, buf, buflen, &errno);
1711 case NSS_STATUS_SUCCESS:
1713 case NSS_STATUS_NOTFOUND:
1718 case NSS_STATUS_TRYAGAIN:
1731 static void nwrap_module_setgrent(struct nwrap_backend *b)
1733 if (!b->fns->_nss_setgrent) {
1737 b->fns->_nss_setgrent();
1740 static struct group *nwrap_module_getgrent(struct nwrap_backend *b)
1742 static struct group grp;
1744 static int buflen = 1024;
1747 if (!b->fns->_nss_getgrent_r) {
1752 buf = (char *)malloc(buflen);
1756 status = b->fns->_nss_getgrent_r(&grp, buf, buflen, &errno);
1757 if (status == NSS_STATUS_TRYAGAIN) {
1759 buf = (char *)realloc(buf, buflen);
1765 if (status == NSS_STATUS_NOTFOUND) {
1769 if (status != NSS_STATUS_SUCCESS) {
1776 static int nwrap_module_getgrent_r(struct nwrap_backend *b,
1777 struct group *grdst, char *buf,
1778 size_t buflen, struct group **grdstp)
1782 if (!b->fns->_nss_getgrent_r) {
1786 ret = b->fns->_nss_getgrent_r(grdst, buf, buflen, &errno);
1788 case NSS_STATUS_SUCCESS:
1790 case NSS_STATUS_NOTFOUND:
1795 case NSS_STATUS_TRYAGAIN:
1808 static void nwrap_module_endgrent(struct nwrap_backend *b)
1810 if (!b->fns->_nss_endgrent) {
1814 b->fns->_nss_endgrent();
1821 _PUBLIC_ struct passwd *nwrap_getpwnam(const char *name)
1826 if (!nwrap_enabled()) {
1827 return real_getpwnam(name);
1830 for (i=0; i < nwrap_main_global->num_backends; i++) {
1831 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1832 pwd = b->ops->nw_getpwnam(b, name);
1841 _PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst,
1842 char *buf, size_t buflen, struct passwd **pwdstp)
1846 if (!nwrap_enabled()) {
1847 return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
1850 for (i=0; i < nwrap_main_global->num_backends; i++) {
1851 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1852 ret = b->ops->nw_getpwnam_r(b, name, pwdst, buf, buflen, pwdstp);
1853 if (ret == ENOENT) {
1862 _PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid)
1867 if (!nwrap_enabled()) {
1868 return real_getpwuid(uid);
1871 for (i=0; i < nwrap_main_global->num_backends; i++) {
1872 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1873 pwd = b->ops->nw_getpwuid(b, uid);
1882 _PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst,
1883 char *buf, size_t buflen, struct passwd **pwdstp)
1887 if (!nwrap_enabled()) {
1888 return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
1891 for (i=0; i < nwrap_main_global->num_backends; i++) {
1892 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1893 ret = b->ops->nw_getpwuid_r(b, uid, pwdst, buf, buflen, pwdstp);
1894 if (ret == ENOENT) {
1903 _PUBLIC_ void nwrap_setpwent(void)
1907 if (!nwrap_enabled()) {
1912 for (i=0; i < nwrap_main_global->num_backends; i++) {
1913 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1914 b->ops->nw_setpwent(b);
1918 _PUBLIC_ struct passwd *nwrap_getpwent(void)
1923 if (!nwrap_enabled()) {
1924 return real_getpwent();
1927 for (i=0; i < nwrap_main_global->num_backends; i++) {
1928 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1929 pwd = b->ops->nw_getpwent(b);
1938 _PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf,
1939 size_t buflen, struct passwd **pwdstp)
1943 if (!nwrap_enabled()) {
1944 #ifdef SOLARIS_GETPWENT_R
1946 pw = real_getpwent_r(pwdst, buf, buflen);
1958 return real_getpwent_r(pwdst, buf, buflen, pwdstp);
1962 for (i=0; i < nwrap_main_global->num_backends; i++) {
1963 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1964 ret = b->ops->nw_getpwent_r(b, pwdst, buf, buflen, pwdstp);
1965 if (ret == ENOENT) {
1974 _PUBLIC_ void nwrap_endpwent(void)
1978 if (!nwrap_enabled()) {
1983 for (i=0; i < nwrap_main_global->num_backends; i++) {
1984 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1985 b->ops->nw_endpwent(b);
1989 _PUBLIC_ int nwrap_initgroups(const char *user, gid_t group)
1993 if (!nwrap_enabled()) {
1994 return real_initgroups(user, group);
1997 for (i=0; i < nwrap_main_global->num_backends; i++) {
1998 struct nwrap_backend *b = &nwrap_main_global->backends[i];
1999 return b->ops->nw_initgroups(b, user, group);
2006 _PUBLIC_ struct group *nwrap_getgrnam(const char *name)
2011 if (!nwrap_enabled()) {
2012 return real_getgrnam(name);
2015 for (i=0; i < nwrap_main_global->num_backends; i++) {
2016 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2017 grp = b->ops->nw_getgrnam(b, name);
2026 _PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst,
2027 char *buf, size_t buflen, struct group **grdstp)
2031 if (!nwrap_enabled()) {
2032 return real_getgrnam_r(name, grdst, buf, buflen, grdstp);
2035 for (i=0; i < nwrap_main_global->num_backends; i++) {
2036 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2037 ret = b->ops->nw_getgrnam_r(b, name, grdst, buf, buflen, grdstp);
2038 if (ret == ENOENT) {
2047 _PUBLIC_ struct group *nwrap_getgrgid(gid_t gid)
2052 if (!nwrap_enabled()) {
2053 return real_getgrgid(gid);
2056 for (i=0; i < nwrap_main_global->num_backends; i++) {
2057 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2058 grp = b->ops->nw_getgrgid(b, gid);
2067 _PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst,
2068 char *buf, size_t buflen, struct group **grdstp)
2072 if (!nwrap_enabled()) {
2073 return real_getgrgid_r(gid, grdst, buf, buflen, grdstp);
2076 for (i=0; i < nwrap_main_global->num_backends; i++) {
2077 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2078 ret = b->ops->nw_getgrgid_r(b, gid, grdst, buf, buflen, grdstp);
2079 if (ret == ENOENT) {
2088 _PUBLIC_ void nwrap_setgrent(void)
2092 if (!nwrap_enabled()) {
2097 for (i=0; i < nwrap_main_global->num_backends; i++) {
2098 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2099 b->ops->nw_setgrent(b);
2103 _PUBLIC_ struct group *nwrap_getgrent(void)
2108 if (!nwrap_enabled()) {
2109 return real_getgrent();
2112 for (i=0; i < nwrap_main_global->num_backends; i++) {
2113 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2114 grp = b->ops->nw_getgrent(b);
2123 _PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf,
2124 size_t buflen, struct group **grdstp)
2128 if (!nwrap_enabled()) {
2129 #ifdef SOLARIS_GETGRENT_R
2131 gr = real_getgrent_r(grdst, buf, buflen);
2143 return real_getgrent_r(grdst, buf, buflen, grdstp);
2147 for (i=0; i < nwrap_main_global->num_backends; i++) {
2148 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2149 ret = b->ops->nw_getgrent_r(b, grdst, buf, buflen, grdstp);
2150 if (ret == ENOENT) {
2159 _PUBLIC_ void nwrap_endgrent(void)
2163 if (!nwrap_enabled()) {
2168 for (i=0; i < nwrap_main_global->num_backends; i++) {
2169 struct nwrap_backend *b = &nwrap_main_global->backends[i];
2170 b->ops->nw_endgrent(b);
2174 _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
2179 const char *name_of_group = "";
2181 if (!nwrap_enabled()) {
2182 return real_getgrouplist(user, group, groups, ngroups);
2185 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user));
2187 groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
2189 NWRAP_ERROR(("%s:calloc failed\n",__location__));
2194 memcpy(groups_tmp, &group, sizeof(gid_t));
2196 grp = nwrap_getgrgid(group);
2198 name_of_group = grp->gr_name;
2202 while ((grp = nwrap_getgrent()) != NULL) {
2205 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
2206 __location__, grp->gr_name));
2208 for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
2210 if ((strcmp(user, grp->gr_mem[i]) == 0) &&
2211 (strcmp(name_of_group, grp->gr_name) != 0)) {
2213 NWRAP_DEBUG(("%s: %s is member of %s\n",
2214 __location__, user, grp->gr_name));
2216 groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t));
2218 NWRAP_ERROR(("%s:calloc failed\n",__location__));
2223 memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t));
2231 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
2232 __location__, user, *ngroups));
2234 if (*ngroups < count) {
2241 memcpy(groups, groups_tmp, count * sizeof(gid_t));