2 * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #define NSS_WRAPPER_NOT_REPLACE
37 #include "../replace/replace.h"
38 #include "system/passwd.h"
39 #include "system/filesys.h"
40 #include "../nsswitch/nsstest.h"
42 #else /* _SAMBA_BUILD_ */
44 #error nss_wrapper_only_supported_in_samba_yet
52 /* not all systems have _r functions... */
53 #ifndef HAVE_GETPWNAM_R
54 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
56 #ifndef HAVE_GETPWUID_R
57 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
59 #ifndef HAVE_GETPWENT_R
60 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
62 #ifndef HAVE_GETGRNAM_R
63 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
65 #ifndef HAVE_GETGRGID_R
66 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
68 #ifndef HAVE_GETGRENT_R
69 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
72 /* not all systems have getgrouplist */
73 #ifndef HAVE_GETGROUPLIST
74 #define getgrouplist(user, group, groups, ngroups) 0
77 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
83 #define real_getpwnam getpwnam
84 #define real_getpwnam_r getpwnam_r
85 #define real_getpwuid getpwuid
86 #define real_getpwuid_r getpwuid_r
88 #define real_setpwent setpwent
89 #define real_getpwent getpwent
90 #define real_getpwent_r getpwent_r
91 #define real_endpwent endpwent
94 #define real_getgrlst getgrlst
95 #define real_getgrlst_r getgrlst_r
96 #define real_initgroups_dyn initgroups_dyn
98 #define real_initgroups initgroups
99 #define real_getgrouplist getgrouplist
101 #define real_getgrnam getgrnam
102 #define real_getgrnam_r getgrnam_r
103 #define real_getgrgid getgrgid
104 #define real_getgrgid_r getgrgid_r
106 #define real_setgrent setgrent
107 #define real_getgrent getgrent
108 #define real_getgrent_r getgrent_r
109 #define real_endgrent endgrent
115 # define NWRAP_ERROR(args) DEBUG(0, args)
117 # define NWRAP_ERROR(args) printf args
120 #define NWRAP_ERROR(args)
125 # define NWRAP_DEBUG(args) DEBUG(0, args)
127 # define NWRAP_DEBUG(args) printf args
130 #define NWRAP_DEBUG(args)
135 # define NWRAP_VERBOSE(args) DEBUG(0, args)
137 # define NWRAP_VERBOSE(args) printf args
140 #define NWRAP_VERBOSE(args)
143 struct nwrap_module_nss_fns
{
144 NSS_STATUS (*_nss_getpwnam_r
)(const char *name
, struct passwd
*result
, char *buffer
,
145 size_t buflen
, int *errnop
);
146 NSS_STATUS (*_nss_getpwuid_r
)(uid_t uid
, struct passwd
*result
, char *buffer
,
147 size_t buflen
, int *errnop
);
148 NSS_STATUS (*_nss_setpwent
)(void);
149 NSS_STATUS (*_nss_getpwent_r
)(struct passwd
*result
, char *buffer
,
150 size_t buflen
, int *errnop
);
151 NSS_STATUS (*_nss_endpwent
)(void);
152 NSS_STATUS (*_nss_initgroups
)(const char *user
, gid_t group
, long int *start
,
153 long int *size
, gid_t
**groups
, long int limit
, int *errnop
);
154 NSS_STATUS (*_nss_getgrnam_r
)(const char *name
, struct group
*result
, char *buffer
,
155 size_t buflen
, int *errnop
);
156 NSS_STATUS (*_nss_getgrgid_r
)(gid_t gid
, struct group
*result
, char *buffer
,
157 size_t buflen
, int *errnop
);
158 NSS_STATUS (*_nss_setgrent
)(void);
159 NSS_STATUS (*_nss_getgrent_r
)(struct group
*result
, char *buffer
,
160 size_t buflen
, int *errnop
);
161 NSS_STATUS (*_nss_endgrent
)(void);
164 struct nwrap_backend
{
168 struct nwrap_ops
*ops
;
169 struct nwrap_module_nss_fns
*fns
;
173 struct passwd
* (*nw_getpwnam
)(struct nwrap_backend
*b
,
175 int (*nw_getpwnam_r
)(struct nwrap_backend
*b
,
176 const char *name
, struct passwd
*pwdst
,
177 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
178 struct passwd
* (*nw_getpwuid
)(struct nwrap_backend
*b
,
180 int (*nw_getpwuid_r
)(struct nwrap_backend
*b
,
181 uid_t uid
, struct passwd
*pwdst
,
182 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
183 void (*nw_setpwent
)(struct nwrap_backend
*b
);
184 struct passwd
* (*nw_getpwent
)(struct nwrap_backend
*b
);
185 int (*nw_getpwent_r
)(struct nwrap_backend
*b
,
186 struct passwd
*pwdst
, char *buf
,
187 size_t buflen
, struct passwd
**pwdstp
);
188 void (*nw_endpwent
)(struct nwrap_backend
*b
);
189 int (*nw_initgroups
)(struct nwrap_backend
*b
,
190 const char *user
, gid_t group
);
191 struct group
* (*nw_getgrnam
)(struct nwrap_backend
*b
,
193 int (*nw_getgrnam_r
)(struct nwrap_backend
*b
,
194 const char *name
, struct group
*grdst
,
195 char *buf
, size_t buflen
, struct group
**grdstp
);
196 struct group
* (*nw_getgrgid
)(struct nwrap_backend
*b
,
198 int (*nw_getgrgid_r
)(struct nwrap_backend
*b
,
199 gid_t gid
, struct group
*grdst
,
200 char *buf
, size_t buflen
, struct group
**grdstp
);
201 void (*nw_setgrent
)(struct nwrap_backend
*b
);
202 struct group
* (*nw_getgrent
)(struct nwrap_backend
*b
);
203 int (*nw_getgrent_r
)(struct nwrap_backend
*b
,
204 struct group
*grdst
, char *buf
,
205 size_t buflen
, struct group
**grdstp
);
206 void (*nw_endgrent
)(struct nwrap_backend
*b
);
209 /* protoypes for files backend */
212 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
214 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
215 const char *name
, struct passwd
*pwdst
,
216 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
217 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
219 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
220 uid_t uid
, struct passwd
*pwdst
,
221 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
222 static void nwrap_files_setpwent(struct nwrap_backend
*b
);
223 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
);
224 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
225 struct passwd
*pwdst
, char *buf
,
226 size_t buflen
, struct passwd
**pwdstp
);
227 static void nwrap_files_endpwent(struct nwrap_backend
*b
);
228 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
229 const char *user
, gid_t group
);
230 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
232 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
233 const char *name
, struct group
*grdst
,
234 char *buf
, size_t buflen
, struct group
**grdstp
);
235 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
237 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
238 gid_t gid
, struct group
*grdst
,
239 char *buf
, size_t buflen
, struct group
**grdstp
);
240 static void nwrap_files_setgrent(struct nwrap_backend
*b
);
241 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
);
242 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
243 struct group
*grdst
, char *buf
,
244 size_t buflen
, struct group
**grdstp
);
245 static void nwrap_files_endgrent(struct nwrap_backend
*b
);
247 /* protoypes for module backend */
249 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
);
250 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
251 struct passwd
*pwdst
, char *buf
,
252 size_t buflen
, struct passwd
**pwdstp
);
253 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
255 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
256 const char *name
, struct passwd
*pwdst
,
257 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
258 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
260 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
261 uid_t uid
, struct passwd
*pwdst
,
262 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
263 static void nwrap_module_setpwent(struct nwrap_backend
*b
);
264 static void nwrap_module_endpwent(struct nwrap_backend
*b
);
265 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
);
266 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
267 struct group
*grdst
, char *buf
,
268 size_t buflen
, struct group
**grdstp
);
269 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
271 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
272 const char *name
, struct group
*grdst
,
273 char *buf
, size_t buflen
, struct group
**grdstp
);
274 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
276 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
277 gid_t gid
, struct group
*grdst
,
278 char *buf
, size_t buflen
, struct group
**grdstp
);
279 static void nwrap_module_setgrent(struct nwrap_backend
*b
);
280 static void nwrap_module_endgrent(struct nwrap_backend
*b
);
281 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
282 const char *user
, gid_t group
);
284 struct nwrap_ops nwrap_files_ops
= {
285 .nw_getpwnam
= nwrap_files_getpwnam
,
286 .nw_getpwnam_r
= nwrap_files_getpwnam_r
,
287 .nw_getpwuid
= nwrap_files_getpwuid
,
288 .nw_getpwuid_r
= nwrap_files_getpwuid_r
,
289 .nw_setpwent
= nwrap_files_setpwent
,
290 .nw_getpwent
= nwrap_files_getpwent
,
291 .nw_getpwent_r
= nwrap_files_getpwent_r
,
292 .nw_endpwent
= nwrap_files_endpwent
,
293 .nw_initgroups
= nwrap_files_initgroups
,
294 .nw_getgrnam
= nwrap_files_getgrnam
,
295 .nw_getgrnam_r
= nwrap_files_getgrnam_r
,
296 .nw_getgrgid
= nwrap_files_getgrgid
,
297 .nw_getgrgid_r
= nwrap_files_getgrgid_r
,
298 .nw_setgrent
= nwrap_files_setgrent
,
299 .nw_getgrent
= nwrap_files_getgrent
,
300 .nw_getgrent_r
= nwrap_files_getgrent_r
,
301 .nw_endgrent
= nwrap_files_endgrent
,
304 struct nwrap_ops nwrap_module_ops
= {
305 .nw_getpwnam
= nwrap_module_getpwnam
,
306 .nw_getpwnam_r
= nwrap_module_getpwnam_r
,
307 .nw_getpwuid
= nwrap_module_getpwuid
,
308 .nw_getpwuid_r
= nwrap_module_getpwuid_r
,
309 .nw_setpwent
= nwrap_module_setpwent
,
310 .nw_getpwent
= nwrap_module_getpwent
,
311 .nw_getpwent_r
= nwrap_module_getpwent_r
,
312 .nw_endpwent
= nwrap_module_endpwent
,
313 .nw_initgroups
= nwrap_module_initgroups
,
314 .nw_getgrnam
= nwrap_module_getgrnam
,
315 .nw_getgrnam_r
= nwrap_module_getgrnam_r
,
316 .nw_getgrgid
= nwrap_module_getgrgid
,
317 .nw_getgrgid_r
= nwrap_module_getgrgid_r
,
318 .nw_setgrent
= nwrap_module_setgrent
,
319 .nw_getgrent
= nwrap_module_getgrent
,
320 .nw_getgrent_r
= nwrap_module_getgrent_r
,
321 .nw_endgrent
= nwrap_module_endgrent
,
325 const char *nwrap_switch
;
327 struct nwrap_backend
*backends
;
330 struct nwrap_main
*nwrap_main_global
;
331 struct nwrap_main __nwrap_main_global
;
339 bool (*parse_line
)(struct nwrap_cache
*, char *line
);
340 void (*unload
)(struct nwrap_cache
*);
344 struct nwrap_cache
*cache
;
351 struct nwrap_cache __nwrap_cache_pw
;
352 struct nwrap_pw nwrap_pw_global
;
354 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
);
355 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
);
358 struct nwrap_cache
*cache
;
365 struct nwrap_cache __nwrap_cache_gr
;
366 struct nwrap_gr nwrap_gr_global
;
368 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
);
369 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
);
371 static void *nwrap_load_module_fn(struct nwrap_backend
*b
,
378 NWRAP_ERROR(("%s: no handle\n",
383 if (asprintf(&s
, "_nss_%s_%s", b
->name
, fn_name
) == -1) {
384 NWRAP_ERROR(("%s: out of memory\n",
389 res
= dlsym(b
->so_handle
, s
);
391 NWRAP_ERROR(("%s: cannot find function %s in %s\n",
392 __location__
, s
, b
->so_path
));
399 static struct nwrap_module_nss_fns
*nwrap_load_module_fns(struct nwrap_backend
*b
)
401 struct nwrap_module_nss_fns
*fns
;
407 fns
= (struct nwrap_module_nss_fns
*)malloc(sizeof(struct nwrap_module_nss_fns
));
412 fns
->_nss_getpwnam_r
= (NSS_STATUS (*)(const char *, struct passwd
*, char *, size_t, int *))
413 nwrap_load_module_fn(b
, "getpwnam_r");
414 fns
->_nss_getpwuid_r
= (NSS_STATUS (*)(uid_t
, struct passwd
*, char *, size_t, int *))
415 nwrap_load_module_fn(b
, "getpwuid_r");
416 fns
->_nss_setpwent
= (NSS_STATUS(*)(void))
417 nwrap_load_module_fn(b
, "setpwent");
418 fns
->_nss_getpwent_r
= (NSS_STATUS (*)(struct passwd
*, char *, size_t, int *))
419 nwrap_load_module_fn(b
, "getpwent_r");
420 fns
->_nss_endpwent
= (NSS_STATUS(*)(void))
421 nwrap_load_module_fn(b
, "endpwent");
422 fns
->_nss_initgroups
= (NSS_STATUS (*)(const char *, gid_t
, long int *, long int *, gid_t
**, long int, int *))
423 nwrap_load_module_fn(b
, "initgroups_dyn");
424 fns
->_nss_getgrnam_r
= (NSS_STATUS (*)(const char *, struct group
*, char *, size_t, int *))
425 nwrap_load_module_fn(b
, "getgrnam_r");
426 fns
->_nss_getgrgid_r
= (NSS_STATUS (*)(gid_t
, struct group
*, char *, size_t, int *))
427 nwrap_load_module_fn(b
, "getgrgid_r");
428 fns
->_nss_setgrent
= (NSS_STATUS(*)(void))
429 nwrap_load_module_fn(b
, "setgrent");
430 fns
->_nss_getgrent_r
= (NSS_STATUS (*)(struct group
*, char *, size_t, int *))
431 nwrap_load_module_fn(b
, "getgrent_r");
432 fns
->_nss_endgrent
= (NSS_STATUS(*)(void))
433 nwrap_load_module_fn(b
, "endgrent");
438 static void *nwrap_load_module(const char *so_path
)
442 if (!so_path
|| !strlen(so_path
)) {
446 h
= dlopen(so_path
, RTLD_LAZY
);
448 NWRAP_ERROR(("%s: cannot open shared library %s\n",
449 __location__
, so_path
));
456 static bool nwrap_module_init(const char *name
,
457 struct nwrap_ops
*ops
,
460 struct nwrap_backend
**backends
)
462 *backends
= (struct nwrap_backend
*)realloc(*backends
,
463 sizeof(struct nwrap_backend
) * ((*num_backends
) + 1));
465 NWRAP_ERROR(("%s: out of memory\n",
470 (*backends
)[*num_backends
].name
= name
;
471 (*backends
)[*num_backends
].ops
= ops
;
472 (*backends
)[*num_backends
].so_path
= so_path
;
473 (*backends
)[*num_backends
].so_handle
= nwrap_load_module(so_path
);
474 (*backends
)[*num_backends
].fns
= nwrap_load_module_fns(&((*backends
)[*num_backends
]));
481 static void nwrap_backend_init(struct nwrap_main
*r
)
486 if (!nwrap_module_init("files", &nwrap_files_ops
, NULL
,
489 NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
495 static void nwrap_init(void)
497 static bool initialized
;
499 if (initialized
) return;
502 nwrap_main_global
= &__nwrap_main_global
;
504 nwrap_backend_init(nwrap_main_global
);
506 nwrap_pw_global
.cache
= &__nwrap_cache_pw
;
508 nwrap_pw_global
.cache
->path
= getenv("NSS_WRAPPER_PASSWD");
509 nwrap_pw_global
.cache
->fd
= -1;
510 nwrap_pw_global
.cache
->private_data
= &nwrap_pw_global
;
511 nwrap_pw_global
.cache
->parse_line
= nwrap_pw_parse_line
;
512 nwrap_pw_global
.cache
->unload
= nwrap_pw_unload
;
514 nwrap_gr_global
.cache
= &__nwrap_cache_gr
;
516 nwrap_gr_global
.cache
->path
= getenv("NSS_WRAPPER_GROUP");
517 nwrap_gr_global
.cache
->fd
= -1;
518 nwrap_gr_global
.cache
->private_data
= &nwrap_gr_global
;
519 nwrap_gr_global
.cache
->parse_line
= nwrap_gr_parse_line
;
520 nwrap_gr_global
.cache
->unload
= nwrap_gr_unload
;
523 static bool nwrap_enabled(void)
527 if (!nwrap_pw_global
.cache
->path
) {
530 if (nwrap_pw_global
.cache
->path
[0] == '\0') {
533 if (!nwrap_gr_global
.cache
->path
) {
536 if (nwrap_gr_global
.cache
->path
[0] == '\0') {
543 static bool nwrap_parse_file(struct nwrap_cache
*nwrap
)
549 if (nwrap
->st
.st_size
== 0) {
550 NWRAP_DEBUG(("%s: size == 0\n",
555 if (nwrap
->st
.st_size
> INT32_MAX
) {
556 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
557 __location__
, (unsigned)nwrap
->st
.st_size
));
561 ret
= lseek(nwrap
->fd
, 0, SEEK_SET
);
563 NWRAP_ERROR(("%s: lseek - %d\n",__location__
,ret
));
567 buf
= (uint8_t *)malloc(nwrap
->st
.st_size
+ 1);
569 NWRAP_ERROR(("%s: malloc failed\n",__location__
));
573 ret
= read(nwrap
->fd
, buf
, nwrap
->st
.st_size
);
574 if (ret
!= nwrap
->st
.st_size
) {
575 NWRAP_ERROR(("%s: read(%u) gave %d\n",
576 __location__
, (unsigned)nwrap
->st
.st_size
, ret
));
580 buf
[nwrap
->st
.st_size
] = '\0';
583 while (nline
&& nline
[0]) {
591 e
= strchr(line
, '\n');
602 NWRAP_VERBOSE(("%s:'%s'\n",__location__
, line
));
604 if (strlen(line
) == 0) {
608 ok
= nwrap
->parse_line(nwrap
, line
);
623 static void nwrap_cache_unload(struct nwrap_cache
*nwrap
)
625 nwrap
->unload(nwrap
);
627 if (nwrap
->buf
) free(nwrap
->buf
);
632 static void nwrap_cache_reload(struct nwrap_cache
*nwrap
)
637 bool retried
= false;
641 nwrap
->fd
= open(nwrap
->path
, O_RDONLY
);
643 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
645 nwrap
->path
, nwrap
->fd
,
649 NWRAP_VERBOSE(("%s: open '%s'\n", __location__
, nwrap
->path
));
652 ret
= fstat(nwrap
->fd
, &st
);
654 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
657 ret
, strerror(errno
)));
661 if (retried
== false && st
.st_nlink
== 0) {
662 /* maybe someone has replaced the file... */
663 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
664 __location__
, nwrap
->path
));
666 memset(&nwrap
->st
, 0, sizeof(nwrap
->st
));
672 if (st
.st_mtime
== nwrap
->st
.st_mtime
) {
673 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
674 __location__
, (unsigned)st
.st_mtime
));
677 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
678 __location__
, (unsigned)st
.st_mtime
,
679 (unsigned)nwrap
->st
.st_mtime
));
683 nwrap_cache_unload(nwrap
);
685 ok
= nwrap_parse_file(nwrap
);
687 NWRAP_ERROR(("%s: failed to reload %s\n",
688 __location__
, nwrap
->path
));
689 nwrap_cache_unload(nwrap
);
691 NWRAP_DEBUG(("%s: reloaded %s\n",
692 __location__
, nwrap
->path
));
696 * the caller has to call nwrap_unload() on failure
698 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
)
700 struct nwrap_pw
*nwrap_pw
;
707 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
709 list_size
= sizeof(*nwrap_pw
->list
) * (nwrap_pw
->num
+1);
710 pw
= (struct passwd
*)realloc(nwrap_pw
->list
, list_size
);
712 NWRAP_ERROR(("%s:realloc(%u) failed\n",
713 __location__
, list_size
));
718 pw
= &nwrap_pw
->list
[nwrap_pw
->num
];
725 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
726 __location__
, line
, c
));
734 NWRAP_VERBOSE(("name[%s]\n", pw
->pw_name
));
739 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
740 __location__
, line
, c
));
748 NWRAP_VERBOSE(("password[%s]\n", pw
->pw_passwd
));
753 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
754 __location__
, line
, c
));
760 pw
->pw_uid
= (uid_t
)strtoul(c
, &e
, 10);
762 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
763 __location__
, line
, c
, strerror(errno
)));
767 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
768 __location__
, line
, c
, strerror(errno
)));
772 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
773 __location__
, line
, c
, strerror(errno
)));
778 NWRAP_VERBOSE(("uid[%u]\n", pw
->pw_uid
));
783 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
784 __location__
, line
, c
));
790 pw
->pw_gid
= (gid_t
)strtoul(c
, &e
, 10);
792 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
793 __location__
, line
, c
, strerror(errno
)));
797 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
798 __location__
, line
, c
, strerror(errno
)));
802 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
803 __location__
, line
, c
, strerror(errno
)));
808 NWRAP_VERBOSE(("gid[%u]\n", pw
->pw_gid
));
813 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
814 __location__
, line
, c
));
822 NWRAP_VERBOSE(("gecos[%s]\n", pw
->pw_gecos
));
827 NWRAP_ERROR(("%s:'%s'\n",__location__
,c
));
835 NWRAP_VERBOSE(("dir[%s]\n", pw
->pw_dir
));
839 NWRAP_VERBOSE(("shell[%s]\n", pw
->pw_shell
));
841 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
842 pw
->pw_name
, pw
->pw_passwd
,
843 pw
->pw_uid
, pw
->pw_gid
,
844 pw
->pw_gecos
, pw
->pw_dir
, pw
->pw_shell
));
850 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
)
852 struct nwrap_pw
*nwrap_pw
;
853 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
855 if (nwrap_pw
->list
) free(nwrap_pw
->list
);
857 nwrap_pw
->list
= NULL
;
862 static int nwrap_pw_copy_r(const struct passwd
*src
, struct passwd
*dst
,
863 char *buf
, size_t buflen
, struct passwd
**dstp
)
869 first
= src
->pw_name
;
871 last
= src
->pw_shell
;
872 while (*last
) last
++;
874 ofs
= PTR_DIFF(last
+ 1, first
);
880 memcpy(buf
, first
, ofs
);
882 ofs
= PTR_DIFF(src
->pw_name
, first
);
883 dst
->pw_name
= buf
+ ofs
;
884 ofs
= PTR_DIFF(src
->pw_passwd
, first
);
885 dst
->pw_passwd
= buf
+ ofs
;
886 dst
->pw_uid
= src
->pw_uid
;
887 dst
->pw_gid
= src
->pw_gid
;
888 ofs
= PTR_DIFF(src
->pw_gecos
, first
);
889 dst
->pw_gecos
= buf
+ ofs
;
890 ofs
= PTR_DIFF(src
->pw_dir
, first
);
891 dst
->pw_dir
= buf
+ ofs
;
892 ofs
= PTR_DIFF(src
->pw_shell
, first
);
893 dst
->pw_shell
= buf
+ ofs
;
903 * the caller has to call nwrap_unload() on failure
905 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
)
907 struct nwrap_gr
*nwrap_gr
;
915 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
917 list_size
= sizeof(*nwrap_gr
->list
) * (nwrap_gr
->num
+1);
918 gr
= (struct group
*)realloc(nwrap_gr
->list
, list_size
);
920 NWRAP_ERROR(("%s:realloc failed\n",__location__
));
925 gr
= &nwrap_gr
->list
[nwrap_gr
->num
];
932 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
933 __location__
, line
, c
));
941 NWRAP_VERBOSE(("name[%s]\n", gr
->gr_name
));
946 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
947 __location__
, line
, c
));
955 NWRAP_VERBOSE(("password[%s]\n", gr
->gr_passwd
));
960 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
961 __location__
, line
, c
));
967 gr
->gr_gid
= (gid_t
)strtoul(c
, &e
, 10);
969 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
970 __location__
, line
, c
, strerror(errno
)));
974 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
975 __location__
, line
, c
, strerror(errno
)));
979 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
980 __location__
, line
, c
, strerror(errno
)));
985 NWRAP_VERBOSE(("gid[%u]\n", gr
->gr_gid
));
988 gr
->gr_mem
= (char **)malloc(sizeof(char *));
990 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
993 gr
->gr_mem
[0] = NULL
;
995 for(nummem
=0; p
; nummem
++) {
1005 if (strlen(c
) == 0) {
1009 m_size
= sizeof(char *) * (nummem
+2);
1010 m
= (char **)realloc(gr
->gr_mem
, m_size
);
1012 NWRAP_ERROR(("%s:realloc(%u) failed\n",
1013 __location__
, m_size
));
1017 gr
->gr_mem
[nummem
] = c
;
1018 gr
->gr_mem
[nummem
+1] = NULL
;
1020 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem
, gr
->gr_mem
[nummem
]));
1023 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
1024 gr
->gr_name
, gr
->gr_passwd
, gr
->gr_gid
, nummem
));
1030 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
)
1033 struct nwrap_gr
*nwrap_gr
;
1034 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
1036 if (nwrap_gr
->list
) {
1037 for (i
=0; i
< nwrap_gr
->num
; i
++) {
1038 if (nwrap_gr
->list
[i
].gr_mem
) {
1039 free(nwrap_gr
->list
[i
].gr_mem
);
1042 free(nwrap_gr
->list
);
1045 nwrap_gr
->list
= NULL
;
1050 static int nwrap_gr_copy_r(const struct group
*src
, struct group
*dst
,
1051 char *buf
, size_t buflen
, struct group
**dstp
)
1061 first
= src
->gr_name
;
1063 lastm
= src
->gr_mem
;
1070 last
= src
->gr_passwd
;
1072 while (*last
) last
++;
1074 ofsb
= PTR_DIFF(last
+ 1, first
);
1075 ofsm
= PTR_DIFF(lastm
+ 1, src
->gr_mem
);
1077 if ((ofsb
+ ofsm
) > buflen
) {
1081 memcpy(buf
, first
, ofsb
);
1082 memcpy(buf
+ ofsb
, src
->gr_mem
, ofsm
);
1084 ofs
= PTR_DIFF(src
->gr_name
, first
);
1085 dst
->gr_name
= buf
+ ofs
;
1086 ofs
= PTR_DIFF(src
->gr_passwd
, first
);
1087 dst
->gr_passwd
= buf
+ ofs
;
1088 dst
->gr_gid
= src
->gr_gid
;
1090 dst
->gr_mem
= (char **)(buf
+ ofsb
);
1091 for (i
=0; src
->gr_mem
[i
]; i
++) {
1092 ofs
= PTR_DIFF(src
->gr_mem
[i
], first
);
1093 dst
->gr_mem
[i
] = buf
+ ofs
;
1103 /* user functions */
1104 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
1109 nwrap_cache_reload(nwrap_pw_global
.cache
);
1111 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1112 if (strcmp(nwrap_pw_global
.list
[i
].pw_name
, name
) == 0) {
1113 NWRAP_DEBUG(("%s: user[%s] found\n",
1114 __location__
, name
));
1115 return &nwrap_pw_global
.list
[i
];
1117 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
1119 nwrap_pw_global
.list
[i
].pw_name
));
1122 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__
, name
));
1128 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
1129 const char *name
, struct passwd
*pwdst
,
1130 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1134 pw
= nwrap_files_getpwnam(b
, name
);
1142 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1145 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
1150 nwrap_cache_reload(nwrap_pw_global
.cache
);
1152 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1153 if (nwrap_pw_global
.list
[i
].pw_uid
== uid
) {
1154 NWRAP_DEBUG(("%s: uid[%u] found\n",
1155 __location__
, uid
));
1156 return &nwrap_pw_global
.list
[i
];
1158 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
1160 nwrap_pw_global
.list
[i
].pw_uid
));
1163 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__
, uid
));
1169 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
1170 uid_t uid
, struct passwd
*pwdst
,
1171 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1175 pw
= nwrap_files_getpwuid(b
, uid
);
1183 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1186 /* user enum functions */
1187 static void nwrap_files_setpwent(struct nwrap_backend
*b
)
1189 nwrap_pw_global
.idx
= 0;
1192 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
)
1196 if (nwrap_pw_global
.idx
== 0) {
1197 nwrap_cache_reload(nwrap_pw_global
.cache
);
1200 if (nwrap_pw_global
.idx
>= nwrap_pw_global
.num
) {
1205 pw
= &nwrap_pw_global
.list
[nwrap_pw_global
.idx
++];
1207 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
1208 __location__
, pw
->pw_name
, pw
->pw_uid
));
1213 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
1214 struct passwd
*pwdst
, char *buf
,
1215 size_t buflen
, struct passwd
**pwdstp
)
1219 pw
= nwrap_files_getpwent(b
);
1227 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1230 static void nwrap_files_endpwent(struct nwrap_backend
*b
)
1232 nwrap_pw_global
.idx
= 0;
1235 /* misc functions */
1236 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
1237 const char *user
, gid_t group
)
1239 /* TODO: maybe we should also fake this... */
1243 /* group functions */
1244 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
1249 nwrap_cache_reload(nwrap_gr_global
.cache
);
1251 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1252 if (strcmp(nwrap_gr_global
.list
[i
].gr_name
, name
) == 0) {
1253 NWRAP_DEBUG(("%s: group[%s] found\n",
1254 __location__
, name
));
1255 return &nwrap_gr_global
.list
[i
];
1257 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1259 nwrap_gr_global
.list
[i
].gr_name
));
1262 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__
, name
));
1268 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
1269 const char *name
, struct group
*grdst
,
1270 char *buf
, size_t buflen
, struct group
**grdstp
)
1274 gr
= nwrap_files_getgrnam(b
, name
);
1282 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1285 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
1290 nwrap_cache_reload(nwrap_gr_global
.cache
);
1292 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1293 if (nwrap_gr_global
.list
[i
].gr_gid
== gid
) {
1294 NWRAP_DEBUG(("%s: gid[%u] found\n",
1295 __location__
, gid
));
1296 return &nwrap_gr_global
.list
[i
];
1298 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1300 nwrap_gr_global
.list
[i
].gr_gid
));
1303 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__
, gid
));
1309 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
1310 gid_t gid
, struct group
*grdst
,
1311 char *buf
, size_t buflen
, struct group
**grdstp
)
1315 gr
= nwrap_files_getgrgid(b
, gid
);
1323 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1326 /* group enum functions */
1327 static void nwrap_files_setgrent(struct nwrap_backend
*b
)
1329 nwrap_gr_global
.idx
= 0;
1332 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
)
1336 if (nwrap_gr_global
.idx
== 0) {
1337 nwrap_cache_reload(nwrap_gr_global
.cache
);
1340 if (nwrap_gr_global
.idx
>= nwrap_gr_global
.num
) {
1345 gr
= &nwrap_gr_global
.list
[nwrap_gr_global
.idx
++];
1347 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1348 __location__
, gr
->gr_name
, gr
->gr_gid
));
1353 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
1354 struct group
*grdst
, char *buf
,
1355 size_t buflen
, struct group
**grdstp
)
1359 gr
= nwrap_files_getgrent(b
);
1367 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1370 static void nwrap_files_endgrent(struct nwrap_backend
*b
)
1372 nwrap_gr_global
.idx
= 0;
1379 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
1385 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
1386 const char *name
, struct passwd
*pwdst
,
1387 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1392 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
1398 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
1399 uid_t uid
, struct passwd
*pwdst
,
1400 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1405 static void nwrap_module_setpwent(struct nwrap_backend
*b
)
1409 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
)
1414 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
1415 struct passwd
*pwdst
, char *buf
,
1416 size_t buflen
, struct passwd
**pwdstp
)
1421 static void nwrap_module_endpwent(struct nwrap_backend
*b
)
1425 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
1426 const char *user
, gid_t group
)
1431 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
1437 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
1438 const char *name
, struct group
*grdst
,
1439 char *buf
, size_t buflen
, struct group
**grdstp
)
1444 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
1450 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
1451 gid_t gid
, struct group
*grdst
,
1452 char *buf
, size_t buflen
, struct group
**grdstp
)
1457 static void nwrap_module_setgrent(struct nwrap_backend
*b
)
1461 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
)
1466 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
1467 struct group
*grdst
, char *buf
,
1468 size_t buflen
, struct group
**grdstp
)
1473 static void nwrap_module_endgrent(struct nwrap_backend
*b
)
1481 _PUBLIC_
struct passwd
*nwrap_getpwnam(const char *name
)
1486 if (!nwrap_enabled()) {
1487 return real_getpwnam(name
);
1490 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1491 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1492 pwd
= b
->ops
->nw_getpwnam(b
, name
);
1501 _PUBLIC_
int nwrap_getpwnam_r(const char *name
, struct passwd
*pwdst
,
1502 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1506 if (!nwrap_enabled()) {
1507 return real_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
1510 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1511 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1512 ret
= b
->ops
->nw_getpwnam_r(b
, name
, pwdst
, buf
, buflen
, pwdstp
);
1513 if (ret
== ENOENT
) {
1522 _PUBLIC_
struct passwd
*nwrap_getpwuid(uid_t uid
)
1527 if (!nwrap_enabled()) {
1528 return real_getpwuid(uid
);
1531 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1532 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1533 pwd
= b
->ops
->nw_getpwuid(b
, uid
);
1542 _PUBLIC_
int nwrap_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
1543 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1547 if (!nwrap_enabled()) {
1548 return real_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
1551 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1552 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1553 ret
= b
->ops
->nw_getpwuid_r(b
, uid
, pwdst
, buf
, buflen
, pwdstp
);
1554 if (ret
== ENOENT
) {
1563 _PUBLIC_
void nwrap_setpwent(void)
1567 if (!nwrap_enabled()) {
1572 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1573 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1574 b
->ops
->nw_setpwent(b
);
1578 _PUBLIC_
struct passwd
*nwrap_getpwent(void)
1583 if (!nwrap_enabled()) {
1584 return real_getpwent();
1587 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1588 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1589 pwd
= b
->ops
->nw_getpwent(b
);
1598 _PUBLIC_
int nwrap_getpwent_r(struct passwd
*pwdst
, char *buf
,
1599 size_t buflen
, struct passwd
**pwdstp
)
1603 if (!nwrap_enabled()) {
1604 #ifdef SOLARIS_GETPWENT_R
1606 pw
= real_getpwent_r(pwdst
, buf
, buflen
);
1618 return real_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
1622 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1623 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1624 ret
= b
->ops
->nw_getpwent_r(b
, pwdst
, buf
, buflen
, pwdstp
);
1625 if (ret
== ENOENT
) {
1634 _PUBLIC_
void nwrap_endpwent(void)
1638 if (!nwrap_enabled()) {
1643 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1644 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1645 b
->ops
->nw_endpwent(b
);
1649 _PUBLIC_
int nwrap_initgroups(const char *user
, gid_t group
)
1653 if (!nwrap_enabled()) {
1654 return real_initgroups(user
, group
);
1657 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1658 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1659 return b
->ops
->nw_initgroups(b
, user
, group
);
1666 _PUBLIC_
struct group
*nwrap_getgrnam(const char *name
)
1671 if (!nwrap_enabled()) {
1672 return real_getgrnam(name
);
1675 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1676 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1677 grp
= b
->ops
->nw_getgrnam(b
, name
);
1686 _PUBLIC_
int nwrap_getgrnam_r(const char *name
, struct group
*grdst
,
1687 char *buf
, size_t buflen
, struct group
**grdstp
)
1691 if (!nwrap_enabled()) {
1692 return real_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
1695 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1696 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1697 ret
= b
->ops
->nw_getgrnam_r(b
, name
, grdst
, buf
, buflen
, grdstp
);
1698 if (ret
== ENOENT
) {
1707 _PUBLIC_
struct group
*nwrap_getgrgid(gid_t gid
)
1712 if (!nwrap_enabled()) {
1713 return real_getgrgid(gid
);
1716 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1717 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1718 grp
= b
->ops
->nw_getgrgid(b
, gid
);
1727 _PUBLIC_
int nwrap_getgrgid_r(gid_t gid
, struct group
*grdst
,
1728 char *buf
, size_t buflen
, struct group
**grdstp
)
1732 if (!nwrap_enabled()) {
1733 return real_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
1736 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1737 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1738 ret
= b
->ops
->nw_getgrgid_r(b
, gid
, grdst
, buf
, buflen
, grdstp
);
1739 if (ret
== ENOENT
) {
1748 _PUBLIC_
void nwrap_setgrent(void)
1752 if (!nwrap_enabled()) {
1757 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1758 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1759 b
->ops
->nw_setgrent(b
);
1763 _PUBLIC_
struct group
*nwrap_getgrent(void)
1768 if (!nwrap_enabled()) {
1769 return real_getgrent();
1772 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1773 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1774 grp
= b
->ops
->nw_getgrent(b
);
1783 _PUBLIC_
int nwrap_getgrent_r(struct group
*grdst
, char *buf
,
1784 size_t buflen
, struct group
**grdstp
)
1788 if (!nwrap_enabled()) {
1789 #ifdef SOLARIS_GETGRENT_R
1791 gr
= real_getgrent_r(grdst
, buf
, buflen
);
1803 return real_getgrent_r(grdst
, buf
, buflen
, grdstp
);
1807 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1808 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1809 ret
= b
->ops
->nw_getgrent_r(b
, grdst
, buf
, buflen
, grdstp
);
1810 if (ret
== ENOENT
) {
1819 _PUBLIC_
void nwrap_endgrent(void)
1823 if (!nwrap_enabled()) {
1828 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1829 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1830 b
->ops
->nw_endgrent(b
);
1834 _PUBLIC_
int nwrap_getgrouplist(const char *user
, gid_t group
, gid_t
*groups
, int *ngroups
)
1839 const char *name_of_group
= NULL
;
1841 if (!nwrap_enabled()) {
1842 return real_getgrouplist(user
, group
, groups
, ngroups
);
1845 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__
, user
));
1847 groups_tmp
= (gid_t
*)malloc(count
* sizeof(gid_t
));
1849 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
1854 memcpy(groups_tmp
, &group
, sizeof(gid_t
));
1856 grp
= nwrap_getgrgid(group
);
1858 name_of_group
= grp
->gr_name
;
1862 while ((grp
= nwrap_getgrent()) != NULL
) {
1865 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
1866 __location__
, grp
->gr_name
));
1868 for (i
=0; grp
->gr_mem
&& grp
->gr_mem
[i
] != NULL
; i
++) {
1870 if ((strcmp(user
, grp
->gr_mem
[i
]) == 0) &&
1871 (strcmp(name_of_group
, grp
->gr_name
) != 0)) {
1873 NWRAP_DEBUG(("%s: %s is member of %s\n",
1874 __location__
, user
, grp
->gr_name
));
1876 groups_tmp
= (gid_t
*)realloc(groups_tmp
, (count
+ 1) * sizeof(gid_t
));
1878 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
1883 memcpy(&groups_tmp
[count
], &grp
->gr_gid
, sizeof(gid_t
));
1891 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
1892 __location__
, user
, *ngroups
));
1894 if (*ngroups
< count
) {
1901 memcpy(groups
, groups_tmp
, count
* sizeof(gid_t
));