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
;
483 if (so_path
!= NULL
) {
484 b
->so_handle
= nwrap_load_module(so_path
);
485 b
->fns
= nwrap_load_module_fns(b
);
486 if (b
->fns
== NULL
) {
499 static void nwrap_backend_init(struct nwrap_main
*r
)
501 const char *winbind_so_path
= getenv("NSS_WRAPPER_WINBIND_SO_PATH");
506 if (!nwrap_module_init("files", &nwrap_files_ops
, NULL
,
509 NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
514 if (winbind_so_path
&& strlen(winbind_so_path
)) {
515 if (!nwrap_module_init("winbind", &nwrap_module_ops
, winbind_so_path
,
518 NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n",
525 static void nwrap_init(void)
527 static bool initialized
;
529 if (initialized
) return;
532 nwrap_main_global
= &__nwrap_main_global
;
534 nwrap_backend_init(nwrap_main_global
);
536 nwrap_pw_global
.cache
= &__nwrap_cache_pw
;
538 nwrap_pw_global
.cache
->path
= getenv("NSS_WRAPPER_PASSWD");
539 nwrap_pw_global
.cache
->fd
= -1;
540 nwrap_pw_global
.cache
->private_data
= &nwrap_pw_global
;
541 nwrap_pw_global
.cache
->parse_line
= nwrap_pw_parse_line
;
542 nwrap_pw_global
.cache
->unload
= nwrap_pw_unload
;
544 nwrap_gr_global
.cache
= &__nwrap_cache_gr
;
546 nwrap_gr_global
.cache
->path
= getenv("NSS_WRAPPER_GROUP");
547 nwrap_gr_global
.cache
->fd
= -1;
548 nwrap_gr_global
.cache
->private_data
= &nwrap_gr_global
;
549 nwrap_gr_global
.cache
->parse_line
= nwrap_gr_parse_line
;
550 nwrap_gr_global
.cache
->unload
= nwrap_gr_unload
;
553 static bool nwrap_enabled(void)
557 if (!nwrap_pw_global
.cache
->path
) {
560 if (nwrap_pw_global
.cache
->path
[0] == '\0') {
563 if (!nwrap_gr_global
.cache
->path
) {
566 if (nwrap_gr_global
.cache
->path
[0] == '\0') {
573 static bool nwrap_parse_file(struct nwrap_cache
*nwrap
)
579 if (nwrap
->st
.st_size
== 0) {
580 NWRAP_DEBUG(("%s: size == 0\n",
585 if (nwrap
->st
.st_size
> INT32_MAX
) {
586 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
587 __location__
, (unsigned)nwrap
->st
.st_size
));
591 ret
= lseek(nwrap
->fd
, 0, SEEK_SET
);
593 NWRAP_ERROR(("%s: lseek - %d\n",__location__
,ret
));
597 buf
= (uint8_t *)malloc(nwrap
->st
.st_size
+ 1);
599 NWRAP_ERROR(("%s: malloc failed\n",__location__
));
603 ret
= read(nwrap
->fd
, buf
, nwrap
->st
.st_size
);
604 if (ret
!= nwrap
->st
.st_size
) {
605 NWRAP_ERROR(("%s: read(%u) gave %d\n",
606 __location__
, (unsigned)nwrap
->st
.st_size
, ret
));
610 buf
[nwrap
->st
.st_size
] = '\0';
613 while (nline
&& nline
[0]) {
621 e
= strchr(line
, '\n');
632 NWRAP_VERBOSE(("%s:'%s'\n",__location__
, line
));
634 if (strlen(line
) == 0) {
638 ok
= nwrap
->parse_line(nwrap
, line
);
653 static void nwrap_files_cache_unload(struct nwrap_cache
*nwrap
)
655 nwrap
->unload(nwrap
);
657 if (nwrap
->buf
) free(nwrap
->buf
);
662 static void nwrap_files_cache_reload(struct nwrap_cache
*nwrap
)
667 bool retried
= false;
671 nwrap
->fd
= open(nwrap
->path
, O_RDONLY
);
673 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
675 nwrap
->path
, nwrap
->fd
,
679 NWRAP_VERBOSE(("%s: open '%s'\n", __location__
, nwrap
->path
));
682 ret
= fstat(nwrap
->fd
, &st
);
684 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
687 ret
, strerror(errno
)));
691 if (retried
== false && st
.st_nlink
== 0) {
692 /* maybe someone has replaced the file... */
693 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
694 __location__
, nwrap
->path
));
696 memset(&nwrap
->st
, 0, sizeof(nwrap
->st
));
702 if (st
.st_mtime
== nwrap
->st
.st_mtime
) {
703 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
704 __location__
, (unsigned)st
.st_mtime
));
707 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
708 __location__
, (unsigned)st
.st_mtime
,
709 (unsigned)nwrap
->st
.st_mtime
));
713 nwrap_files_cache_unload(nwrap
);
715 ok
= nwrap_parse_file(nwrap
);
717 NWRAP_ERROR(("%s: failed to reload %s\n",
718 __location__
, nwrap
->path
));
719 nwrap_files_cache_unload(nwrap
);
721 NWRAP_DEBUG(("%s: reloaded %s\n",
722 __location__
, nwrap
->path
));
726 * the caller has to call nwrap_unload() on failure
728 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
)
730 struct nwrap_pw
*nwrap_pw
;
737 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
739 list_size
= sizeof(*nwrap_pw
->list
) * (nwrap_pw
->num
+1);
740 pw
= (struct passwd
*)realloc(nwrap_pw
->list
, list_size
);
742 NWRAP_ERROR(("%s:realloc(%u) failed\n",
743 __location__
, list_size
));
748 pw
= &nwrap_pw
->list
[nwrap_pw
->num
];
755 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
756 __location__
, line
, c
));
764 NWRAP_VERBOSE(("name[%s]\n", pw
->pw_name
));
769 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
770 __location__
, line
, c
));
778 NWRAP_VERBOSE(("password[%s]\n", pw
->pw_passwd
));
783 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
784 __location__
, line
, c
));
790 pw
->pw_uid
= (uid_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(("uid[%u]\n", pw
->pw_uid
));
813 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
814 __location__
, line
, c
));
820 pw
->pw_gid
= (gid_t
)strtoul(c
, &e
, 10);
822 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
823 __location__
, line
, c
, strerror(errno
)));
827 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
828 __location__
, line
, c
, strerror(errno
)));
832 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
833 __location__
, line
, c
, strerror(errno
)));
838 NWRAP_VERBOSE(("gid[%u]\n", pw
->pw_gid
));
843 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
844 __location__
, line
, c
));
852 NWRAP_VERBOSE(("gecos[%s]\n", pw
->pw_gecos
));
857 NWRAP_ERROR(("%s:'%s'\n",__location__
,c
));
865 NWRAP_VERBOSE(("dir[%s]\n", pw
->pw_dir
));
869 NWRAP_VERBOSE(("shell[%s]\n", pw
->pw_shell
));
871 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
872 pw
->pw_name
, pw
->pw_passwd
,
873 pw
->pw_uid
, pw
->pw_gid
,
874 pw
->pw_gecos
, pw
->pw_dir
, pw
->pw_shell
));
880 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
)
882 struct nwrap_pw
*nwrap_pw
;
883 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
885 if (nwrap_pw
->list
) free(nwrap_pw
->list
);
887 nwrap_pw
->list
= NULL
;
892 static int nwrap_pw_copy_r(const struct passwd
*src
, struct passwd
*dst
,
893 char *buf
, size_t buflen
, struct passwd
**dstp
)
899 first
= src
->pw_name
;
901 last
= src
->pw_shell
;
902 while (*last
) last
++;
904 ofs
= PTR_DIFF(last
+ 1, first
);
910 memcpy(buf
, first
, ofs
);
912 ofs
= PTR_DIFF(src
->pw_name
, first
);
913 dst
->pw_name
= buf
+ ofs
;
914 ofs
= PTR_DIFF(src
->pw_passwd
, first
);
915 dst
->pw_passwd
= buf
+ ofs
;
916 dst
->pw_uid
= src
->pw_uid
;
917 dst
->pw_gid
= src
->pw_gid
;
918 ofs
= PTR_DIFF(src
->pw_gecos
, first
);
919 dst
->pw_gecos
= buf
+ ofs
;
920 ofs
= PTR_DIFF(src
->pw_dir
, first
);
921 dst
->pw_dir
= buf
+ ofs
;
922 ofs
= PTR_DIFF(src
->pw_shell
, first
);
923 dst
->pw_shell
= buf
+ ofs
;
933 * the caller has to call nwrap_unload() on failure
935 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
)
937 struct nwrap_gr
*nwrap_gr
;
945 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
947 list_size
= sizeof(*nwrap_gr
->list
) * (nwrap_gr
->num
+1);
948 gr
= (struct group
*)realloc(nwrap_gr
->list
, list_size
);
950 NWRAP_ERROR(("%s:realloc failed\n",__location__
));
955 gr
= &nwrap_gr
->list
[nwrap_gr
->num
];
962 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
963 __location__
, line
, c
));
971 NWRAP_VERBOSE(("name[%s]\n", gr
->gr_name
));
976 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
977 __location__
, line
, c
));
985 NWRAP_VERBOSE(("password[%s]\n", gr
->gr_passwd
));
990 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
991 __location__
, line
, c
));
997 gr
->gr_gid
= (gid_t
)strtoul(c
, &e
, 10);
999 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1000 __location__
, line
, c
, strerror(errno
)));
1004 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1005 __location__
, line
, c
, strerror(errno
)));
1009 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1010 __location__
, line
, c
, strerror(errno
)));
1015 NWRAP_VERBOSE(("gid[%u]\n", gr
->gr_gid
));
1018 gr
->gr_mem
= (char **)malloc(sizeof(char *));
1020 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
1023 gr
->gr_mem
[0] = NULL
;
1025 for(nummem
=0; p
; nummem
++) {
1035 if (strlen(c
) == 0) {
1039 m_size
= sizeof(char *) * (nummem
+2);
1040 m
= (char **)realloc(gr
->gr_mem
, m_size
);
1042 NWRAP_ERROR(("%s:realloc(%u) failed\n",
1043 __location__
, m_size
));
1047 gr
->gr_mem
[nummem
] = c
;
1048 gr
->gr_mem
[nummem
+1] = NULL
;
1050 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem
, gr
->gr_mem
[nummem
]));
1053 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
1054 gr
->gr_name
, gr
->gr_passwd
, gr
->gr_gid
, nummem
));
1060 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
)
1063 struct nwrap_gr
*nwrap_gr
;
1064 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
1066 if (nwrap_gr
->list
) {
1067 for (i
=0; i
< nwrap_gr
->num
; i
++) {
1068 if (nwrap_gr
->list
[i
].gr_mem
) {
1069 free(nwrap_gr
->list
[i
].gr_mem
);
1072 free(nwrap_gr
->list
);
1075 nwrap_gr
->list
= NULL
;
1080 static int nwrap_gr_copy_r(const struct group
*src
, struct group
*dst
,
1081 char *buf
, size_t buflen
, struct group
**dstp
)
1091 first
= src
->gr_name
;
1093 lastm
= src
->gr_mem
;
1100 last
= src
->gr_passwd
;
1102 while (*last
) last
++;
1104 ofsb
= PTR_DIFF(last
+ 1, first
);
1105 ofsm
= PTR_DIFF(lastm
+ 1, src
->gr_mem
);
1107 if ((ofsb
+ ofsm
) > buflen
) {
1111 memcpy(buf
, first
, ofsb
);
1112 memcpy(buf
+ ofsb
, src
->gr_mem
, ofsm
);
1114 ofs
= PTR_DIFF(src
->gr_name
, first
);
1115 dst
->gr_name
= buf
+ ofs
;
1116 ofs
= PTR_DIFF(src
->gr_passwd
, first
);
1117 dst
->gr_passwd
= buf
+ ofs
;
1118 dst
->gr_gid
= src
->gr_gid
;
1120 dst
->gr_mem
= (char **)(buf
+ ofsb
);
1121 for (i
=0; src
->gr_mem
[i
]; i
++) {
1122 ofs
= PTR_DIFF(src
->gr_mem
[i
], first
);
1123 dst
->gr_mem
[i
] = buf
+ ofs
;
1133 /* user functions */
1134 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
1139 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1141 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1142 if (strcmp(nwrap_pw_global
.list
[i
].pw_name
, name
) == 0) {
1143 NWRAP_DEBUG(("%s: user[%s] found\n",
1144 __location__
, name
));
1145 return &nwrap_pw_global
.list
[i
];
1147 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
1149 nwrap_pw_global
.list
[i
].pw_name
));
1152 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__
, name
));
1158 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
1159 const char *name
, struct passwd
*pwdst
,
1160 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1164 pw
= nwrap_files_getpwnam(b
, name
);
1172 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1175 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
1180 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1182 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1183 if (nwrap_pw_global
.list
[i
].pw_uid
== uid
) {
1184 NWRAP_DEBUG(("%s: uid[%u] found\n",
1185 __location__
, uid
));
1186 return &nwrap_pw_global
.list
[i
];
1188 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
1190 nwrap_pw_global
.list
[i
].pw_uid
));
1193 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__
, uid
));
1199 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
1200 uid_t uid
, struct passwd
*pwdst
,
1201 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1205 pw
= nwrap_files_getpwuid(b
, uid
);
1213 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1216 /* user enum functions */
1217 static void nwrap_files_setpwent(struct nwrap_backend
*b
)
1219 nwrap_pw_global
.idx
= 0;
1222 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
)
1226 if (nwrap_pw_global
.idx
== 0) {
1227 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1230 if (nwrap_pw_global
.idx
>= nwrap_pw_global
.num
) {
1235 pw
= &nwrap_pw_global
.list
[nwrap_pw_global
.idx
++];
1237 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
1238 __location__
, pw
->pw_name
, pw
->pw_uid
));
1243 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
1244 struct passwd
*pwdst
, char *buf
,
1245 size_t buflen
, struct passwd
**pwdstp
)
1249 pw
= nwrap_files_getpwent(b
);
1257 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1260 static void nwrap_files_endpwent(struct nwrap_backend
*b
)
1262 nwrap_pw_global
.idx
= 0;
1265 /* misc functions */
1266 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
1267 const char *user
, gid_t group
)
1269 /* TODO: maybe we should also fake this... */
1273 /* group functions */
1274 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
1279 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1281 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1282 if (strcmp(nwrap_gr_global
.list
[i
].gr_name
, name
) == 0) {
1283 NWRAP_DEBUG(("%s: group[%s] found\n",
1284 __location__
, name
));
1285 return &nwrap_gr_global
.list
[i
];
1287 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1289 nwrap_gr_global
.list
[i
].gr_name
));
1292 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__
, name
));
1298 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
1299 const char *name
, struct group
*grdst
,
1300 char *buf
, size_t buflen
, struct group
**grdstp
)
1304 gr
= nwrap_files_getgrnam(b
, name
);
1312 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1315 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
1320 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1322 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1323 if (nwrap_gr_global
.list
[i
].gr_gid
== gid
) {
1324 NWRAP_DEBUG(("%s: gid[%u] found\n",
1325 __location__
, gid
));
1326 return &nwrap_gr_global
.list
[i
];
1328 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1330 nwrap_gr_global
.list
[i
].gr_gid
));
1333 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__
, gid
));
1339 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
1340 gid_t gid
, struct group
*grdst
,
1341 char *buf
, size_t buflen
, struct group
**grdstp
)
1345 gr
= nwrap_files_getgrgid(b
, gid
);
1353 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1356 /* group enum functions */
1357 static void nwrap_files_setgrent(struct nwrap_backend
*b
)
1359 nwrap_gr_global
.idx
= 0;
1362 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
)
1366 if (nwrap_gr_global
.idx
== 0) {
1367 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1370 if (nwrap_gr_global
.idx
>= nwrap_gr_global
.num
) {
1375 gr
= &nwrap_gr_global
.list
[nwrap_gr_global
.idx
++];
1377 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1378 __location__
, gr
->gr_name
, gr
->gr_gid
));
1383 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
1384 struct group
*grdst
, char *buf
,
1385 size_t buflen
, struct group
**grdstp
)
1389 gr
= nwrap_files_getgrent(b
);
1397 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1400 static void nwrap_files_endgrent(struct nwrap_backend
*b
)
1402 nwrap_gr_global
.idx
= 0;
1410 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
1413 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
1416 static struct passwd pwd
;
1417 static char buf
[1000];
1420 if (!b
->fns
->_nss_getpwnam_r
) {
1424 status
= b
->fns
->_nss_getpwnam_r(name
, &pwd
, buf
, sizeof(buf
), &errno
);
1425 if (status
== NSS_STATUS_NOTFOUND
) {
1428 if (status
!= NSS_STATUS_SUCCESS
) {
1434 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
1435 const char *name
, struct passwd
*pwdst
,
1436 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1440 if (!b
->fns
->_nss_getpwnam_r
) {
1441 return NSS_STATUS_NOTFOUND
;
1444 ret
= b
->fns
->_nss_getpwnam_r(name
, pwdst
, buf
, buflen
, &errno
);
1446 case NSS_STATUS_SUCCESS
:
1448 case NSS_STATUS_NOTFOUND
:
1453 case NSS_STATUS_TRYAGAIN
:
1466 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
1469 static struct passwd pwd
;
1470 static char buf
[1000];
1473 if (!b
->fns
->_nss_getpwuid_r
) {
1477 status
= b
->fns
->_nss_getpwuid_r(uid
, &pwd
, buf
, sizeof(buf
), &errno
);
1478 if (status
== NSS_STATUS_NOTFOUND
) {
1481 if (status
!= NSS_STATUS_SUCCESS
) {
1487 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
1488 uid_t uid
, struct passwd
*pwdst
,
1489 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1493 if (!b
->fns
->_nss_getpwuid_r
) {
1497 ret
= b
->fns
->_nss_getpwuid_r(uid
, pwdst
, buf
, buflen
, &errno
);
1499 case NSS_STATUS_SUCCESS
:
1501 case NSS_STATUS_NOTFOUND
:
1506 case NSS_STATUS_TRYAGAIN
:
1519 static void nwrap_module_setpwent(struct nwrap_backend
*b
)
1521 if (!b
->fns
->_nss_setpwent
) {
1525 b
->fns
->_nss_setpwent();
1528 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
)
1530 static struct passwd pwd
;
1531 static char buf
[1000];
1534 if (!b
->fns
->_nss_getpwent_r
) {
1538 status
= b
->fns
->_nss_getpwent_r(&pwd
, buf
, sizeof(buf
), &errno
);
1539 if (status
== NSS_STATUS_NOTFOUND
) {
1542 if (status
!= NSS_STATUS_SUCCESS
) {
1548 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
1549 struct passwd
*pwdst
, char *buf
,
1550 size_t buflen
, struct passwd
**pwdstp
)
1554 if (!b
->fns
->_nss_getpwent_r
) {
1558 ret
= b
->fns
->_nss_getpwent_r(pwdst
, buf
, buflen
, &errno
);
1560 case NSS_STATUS_SUCCESS
:
1562 case NSS_STATUS_NOTFOUND
:
1567 case NSS_STATUS_TRYAGAIN
:
1580 static void nwrap_module_endpwent(struct nwrap_backend
*b
)
1582 if (!b
->fns
->_nss_endpwent
) {
1586 b
->fns
->_nss_endpwent();
1589 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
1590 const char *user
, gid_t group
)
1596 if (!b
->fns
->_nss_initgroups
) {
1597 return NSS_STATUS_UNAVAIL
;
1600 return b
->fns
->_nss_initgroups(user
, group
, &start
, &size
, &groups
, 0, &errno
);
1603 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
1606 static struct group grp
;
1608 static int buflen
= 1000;
1611 if (!b
->fns
->_nss_getgrnam_r
) {
1616 buf
= (char *)malloc(buflen
);
1619 status
= b
->fns
->_nss_getgrnam_r(name
, &grp
, buf
, buflen
, &errno
);
1620 if (status
== NSS_STATUS_TRYAGAIN
) {
1622 buf
= (char *)realloc(buf
, buflen
);
1628 if (status
== NSS_STATUS_NOTFOUND
) {
1632 if (status
!= NSS_STATUS_SUCCESS
) {
1639 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
1640 const char *name
, struct group
*grdst
,
1641 char *buf
, size_t buflen
, struct group
**grdstp
)
1645 if (!b
->fns
->_nss_getgrnam_r
) {
1649 ret
= b
->fns
->_nss_getgrnam_r(name
, grdst
, buf
, buflen
, &errno
);
1651 case NSS_STATUS_SUCCESS
:
1653 case NSS_STATUS_NOTFOUND
:
1658 case NSS_STATUS_TRYAGAIN
:
1671 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
1674 static struct group grp
;
1676 static int buflen
= 1000;
1679 if (!b
->fns
->_nss_getgrgid_r
) {
1684 buf
= (char *)malloc(buflen
);
1688 status
= b
->fns
->_nss_getgrgid_r(gid
, &grp
, buf
, buflen
, &errno
);
1689 if (status
== NSS_STATUS_TRYAGAIN
) {
1691 buf
= (char *)realloc(buf
, buflen
);
1697 if (status
== NSS_STATUS_NOTFOUND
) {
1701 if (status
!= NSS_STATUS_SUCCESS
) {
1708 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
1709 gid_t gid
, struct group
*grdst
,
1710 char *buf
, size_t buflen
, struct group
**grdstp
)
1714 if (!b
->fns
->_nss_getgrgid_r
) {
1718 ret
= b
->fns
->_nss_getgrgid_r(gid
, grdst
, buf
, buflen
, &errno
);
1720 case NSS_STATUS_SUCCESS
:
1722 case NSS_STATUS_NOTFOUND
:
1727 case NSS_STATUS_TRYAGAIN
:
1740 static void nwrap_module_setgrent(struct nwrap_backend
*b
)
1742 if (!b
->fns
->_nss_setgrent
) {
1746 b
->fns
->_nss_setgrent();
1749 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
)
1751 static struct group grp
;
1753 static int buflen
= 1024;
1756 if (!b
->fns
->_nss_getgrent_r
) {
1761 buf
= (char *)malloc(buflen
);
1765 status
= b
->fns
->_nss_getgrent_r(&grp
, buf
, buflen
, &errno
);
1766 if (status
== NSS_STATUS_TRYAGAIN
) {
1768 buf
= (char *)realloc(buf
, buflen
);
1774 if (status
== NSS_STATUS_NOTFOUND
) {
1778 if (status
!= NSS_STATUS_SUCCESS
) {
1785 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
1786 struct group
*grdst
, char *buf
,
1787 size_t buflen
, struct group
**grdstp
)
1791 if (!b
->fns
->_nss_getgrent_r
) {
1795 ret
= b
->fns
->_nss_getgrent_r(grdst
, buf
, buflen
, &errno
);
1797 case NSS_STATUS_SUCCESS
:
1799 case NSS_STATUS_NOTFOUND
:
1804 case NSS_STATUS_TRYAGAIN
:
1817 static void nwrap_module_endgrent(struct nwrap_backend
*b
)
1819 if (!b
->fns
->_nss_endgrent
) {
1823 b
->fns
->_nss_endgrent();
1830 _PUBLIC_
struct passwd
*nwrap_getpwnam(const char *name
)
1835 if (!nwrap_enabled()) {
1836 return real_getpwnam(name
);
1839 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1840 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1841 pwd
= b
->ops
->nw_getpwnam(b
, name
);
1850 _PUBLIC_
int nwrap_getpwnam_r(const char *name
, struct passwd
*pwdst
,
1851 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1855 if (!nwrap_enabled()) {
1856 return real_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
1859 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1860 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1861 ret
= b
->ops
->nw_getpwnam_r(b
, name
, pwdst
, buf
, buflen
, pwdstp
);
1862 if (ret
== ENOENT
) {
1871 _PUBLIC_
struct passwd
*nwrap_getpwuid(uid_t uid
)
1876 if (!nwrap_enabled()) {
1877 return real_getpwuid(uid
);
1880 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1881 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1882 pwd
= b
->ops
->nw_getpwuid(b
, uid
);
1891 _PUBLIC_
int nwrap_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
1892 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1896 if (!nwrap_enabled()) {
1897 return real_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
1900 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1901 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1902 ret
= b
->ops
->nw_getpwuid_r(b
, uid
, pwdst
, buf
, buflen
, pwdstp
);
1903 if (ret
== ENOENT
) {
1912 _PUBLIC_
void nwrap_setpwent(void)
1916 if (!nwrap_enabled()) {
1921 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1922 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1923 b
->ops
->nw_setpwent(b
);
1927 _PUBLIC_
struct passwd
*nwrap_getpwent(void)
1932 if (!nwrap_enabled()) {
1933 return real_getpwent();
1936 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1937 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1938 pwd
= b
->ops
->nw_getpwent(b
);
1947 _PUBLIC_
int nwrap_getpwent_r(struct passwd
*pwdst
, char *buf
,
1948 size_t buflen
, struct passwd
**pwdstp
)
1952 if (!nwrap_enabled()) {
1953 #ifdef SOLARIS_GETPWENT_R
1955 pw
= real_getpwent_r(pwdst
, buf
, buflen
);
1967 return real_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
1971 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1972 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1973 ret
= b
->ops
->nw_getpwent_r(b
, pwdst
, buf
, buflen
, pwdstp
);
1974 if (ret
== ENOENT
) {
1983 _PUBLIC_
void nwrap_endpwent(void)
1987 if (!nwrap_enabled()) {
1992 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1993 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1994 b
->ops
->nw_endpwent(b
);
1998 _PUBLIC_
int nwrap_initgroups(const char *user
, gid_t group
)
2002 if (!nwrap_enabled()) {
2003 return real_initgroups(user
, group
);
2006 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2007 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2008 return b
->ops
->nw_initgroups(b
, user
, group
);
2015 _PUBLIC_
struct group
*nwrap_getgrnam(const char *name
)
2020 if (!nwrap_enabled()) {
2021 return real_getgrnam(name
);
2024 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2025 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2026 grp
= b
->ops
->nw_getgrnam(b
, name
);
2035 _PUBLIC_
int nwrap_getgrnam_r(const char *name
, struct group
*grdst
,
2036 char *buf
, size_t buflen
, struct group
**grdstp
)
2040 if (!nwrap_enabled()) {
2041 return real_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
2044 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2045 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2046 ret
= b
->ops
->nw_getgrnam_r(b
, name
, grdst
, buf
, buflen
, grdstp
);
2047 if (ret
== ENOENT
) {
2056 _PUBLIC_
struct group
*nwrap_getgrgid(gid_t gid
)
2061 if (!nwrap_enabled()) {
2062 return real_getgrgid(gid
);
2065 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2066 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2067 grp
= b
->ops
->nw_getgrgid(b
, gid
);
2076 _PUBLIC_
int nwrap_getgrgid_r(gid_t gid
, struct group
*grdst
,
2077 char *buf
, size_t buflen
, struct group
**grdstp
)
2081 if (!nwrap_enabled()) {
2082 return real_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
2085 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2086 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2087 ret
= b
->ops
->nw_getgrgid_r(b
, gid
, grdst
, buf
, buflen
, grdstp
);
2088 if (ret
== ENOENT
) {
2097 _PUBLIC_
void nwrap_setgrent(void)
2101 if (!nwrap_enabled()) {
2106 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2107 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2108 b
->ops
->nw_setgrent(b
);
2112 _PUBLIC_
struct group
*nwrap_getgrent(void)
2117 if (!nwrap_enabled()) {
2118 return real_getgrent();
2121 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2122 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2123 grp
= b
->ops
->nw_getgrent(b
);
2132 _PUBLIC_
int nwrap_getgrent_r(struct group
*grdst
, char *buf
,
2133 size_t buflen
, struct group
**grdstp
)
2137 if (!nwrap_enabled()) {
2138 #ifdef SOLARIS_GETGRENT_R
2140 gr
= real_getgrent_r(grdst
, buf
, buflen
);
2152 return real_getgrent_r(grdst
, buf
, buflen
, grdstp
);
2156 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2157 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2158 ret
= b
->ops
->nw_getgrent_r(b
, grdst
, buf
, buflen
, grdstp
);
2159 if (ret
== ENOENT
) {
2168 _PUBLIC_
void nwrap_endgrent(void)
2172 if (!nwrap_enabled()) {
2177 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2178 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2179 b
->ops
->nw_endgrent(b
);
2183 _PUBLIC_
int nwrap_getgrouplist(const char *user
, gid_t group
, gid_t
*groups
, int *ngroups
)
2188 const char *name_of_group
= "";
2190 if (!nwrap_enabled()) {
2191 return real_getgrouplist(user
, group
, groups
, ngroups
);
2194 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__
, user
));
2196 groups_tmp
= (gid_t
*)malloc(count
* sizeof(gid_t
));
2198 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2203 memcpy(groups_tmp
, &group
, sizeof(gid_t
));
2205 grp
= nwrap_getgrgid(group
);
2207 name_of_group
= grp
->gr_name
;
2211 while ((grp
= nwrap_getgrent()) != NULL
) {
2214 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
2215 __location__
, grp
->gr_name
));
2217 for (i
=0; grp
->gr_mem
&& grp
->gr_mem
[i
] != NULL
; i
++) {
2219 if ((strcmp(user
, grp
->gr_mem
[i
]) == 0) &&
2220 (strcmp(name_of_group
, grp
->gr_name
) != 0)) {
2222 NWRAP_DEBUG(("%s: %s is member of %s\n",
2223 __location__
, user
, grp
->gr_name
));
2225 groups_tmp
= (gid_t
*)realloc(groups_tmp
, (count
+ 1) * sizeof(gid_t
));
2227 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2232 memcpy(&groups_tmp
[count
], &grp
->gr_gid
, sizeof(gid_t
));
2240 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
2241 __location__
, user
, *ngroups
));
2243 if (*ngroups
< count
) {
2250 memcpy(groups
, groups_tmp
, count
* sizeof(gid_t
));