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 #ifndef _POSIX_PTHREAD_SEMANTICS
40 #define _POSIX_PTHREAD_SEMANTICS
43 #define NSS_WRAPPER_NOT_REPLACE
44 #include "../replace/replace.h"
45 #include "system/passwd.h"
46 #include "system/filesys.h"
47 #include "../nsswitch/nsstest.h"
49 #else /* _SAMBA_BUILD_ */
51 #error nss_wrapper_only_supported_in_samba_yet
59 /* not all systems have _r functions... */
60 #ifndef HAVE_GETPWNAM_R
61 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
63 #ifndef HAVE_GETPWUID_R
64 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
66 #ifndef HAVE_GETPWENT_R
67 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
69 #ifndef HAVE_GETGRNAM_R
70 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
72 #ifndef HAVE_GETGRGID_R
73 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
75 #ifndef HAVE_GETGRENT_R
76 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
79 /* not all systems have getgrouplist */
80 #ifndef HAVE_GETGROUPLIST
81 #define getgrouplist(user, group, groups, ngroups) 0
84 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
90 #define real_getpwnam getpwnam
91 #define real_getpwnam_r getpwnam_r
92 #define real_getpwuid getpwuid
93 #define real_getpwuid_r getpwuid_r
95 #define real_setpwent setpwent
96 #define real_getpwent getpwent
97 #define real_getpwent_r getpwent_r
98 #define real_endpwent endpwent
101 #define real_getgrlst getgrlst
102 #define real_getgrlst_r getgrlst_r
103 #define real_initgroups_dyn initgroups_dyn
105 #define real_initgroups initgroups
106 #define real_getgrouplist getgrouplist
108 #define real_getgrnam getgrnam
109 #define real_getgrnam_r getgrnam_r
110 #define real_getgrgid getgrgid
111 #define real_getgrgid_r getgrgid_r
113 #define real_setgrent setgrent
114 #define real_getgrent getgrent
115 #define real_getgrent_r getgrent_r
116 #define real_endgrent endgrent
122 # define NWRAP_ERROR(args) DEBUG(0, args)
124 # define NWRAP_ERROR(args) printf args
127 #define NWRAP_ERROR(args)
132 # define NWRAP_DEBUG(args) DEBUG(0, args)
134 # define NWRAP_DEBUG(args) printf args
137 #define NWRAP_DEBUG(args)
142 # define NWRAP_VERBOSE(args) DEBUG(0, args)
144 # define NWRAP_VERBOSE(args) printf args
147 #define NWRAP_VERBOSE(args)
150 struct nwrap_module_nss_fns
{
151 NSS_STATUS (*_nss_getpwnam_r
)(const char *name
, struct passwd
*result
, char *buffer
,
152 size_t buflen
, int *errnop
);
153 NSS_STATUS (*_nss_getpwuid_r
)(uid_t uid
, struct passwd
*result
, char *buffer
,
154 size_t buflen
, int *errnop
);
155 NSS_STATUS (*_nss_setpwent
)(void);
156 NSS_STATUS (*_nss_getpwent_r
)(struct passwd
*result
, char *buffer
,
157 size_t buflen
, int *errnop
);
158 NSS_STATUS (*_nss_endpwent
)(void);
159 NSS_STATUS (*_nss_initgroups
)(const char *user
, gid_t group
, long int *start
,
160 long int *size
, gid_t
**groups
, long int limit
, int *errnop
);
161 NSS_STATUS (*_nss_getgrnam_r
)(const char *name
, struct group
*result
, char *buffer
,
162 size_t buflen
, int *errnop
);
163 NSS_STATUS (*_nss_getgrgid_r
)(gid_t gid
, struct group
*result
, char *buffer
,
164 size_t buflen
, int *errnop
);
165 NSS_STATUS (*_nss_setgrent
)(void);
166 NSS_STATUS (*_nss_getgrent_r
)(struct group
*result
, char *buffer
,
167 size_t buflen
, int *errnop
);
168 NSS_STATUS (*_nss_endgrent
)(void);
171 struct nwrap_backend
{
175 struct nwrap_ops
*ops
;
176 struct nwrap_module_nss_fns
*fns
;
180 struct passwd
* (*nw_getpwnam
)(struct nwrap_backend
*b
,
182 int (*nw_getpwnam_r
)(struct nwrap_backend
*b
,
183 const char *name
, struct passwd
*pwdst
,
184 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
185 struct passwd
* (*nw_getpwuid
)(struct nwrap_backend
*b
,
187 int (*nw_getpwuid_r
)(struct nwrap_backend
*b
,
188 uid_t uid
, struct passwd
*pwdst
,
189 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
190 void (*nw_setpwent
)(struct nwrap_backend
*b
);
191 struct passwd
* (*nw_getpwent
)(struct nwrap_backend
*b
);
192 int (*nw_getpwent_r
)(struct nwrap_backend
*b
,
193 struct passwd
*pwdst
, char *buf
,
194 size_t buflen
, struct passwd
**pwdstp
);
195 void (*nw_endpwent
)(struct nwrap_backend
*b
);
196 int (*nw_initgroups
)(struct nwrap_backend
*b
,
197 const char *user
, gid_t group
);
198 struct group
* (*nw_getgrnam
)(struct nwrap_backend
*b
,
200 int (*nw_getgrnam_r
)(struct nwrap_backend
*b
,
201 const char *name
, struct group
*grdst
,
202 char *buf
, size_t buflen
, struct group
**grdstp
);
203 struct group
* (*nw_getgrgid
)(struct nwrap_backend
*b
,
205 int (*nw_getgrgid_r
)(struct nwrap_backend
*b
,
206 gid_t gid
, struct group
*grdst
,
207 char *buf
, size_t buflen
, struct group
**grdstp
);
208 void (*nw_setgrent
)(struct nwrap_backend
*b
);
209 struct group
* (*nw_getgrent
)(struct nwrap_backend
*b
);
210 int (*nw_getgrent_r
)(struct nwrap_backend
*b
,
211 struct group
*grdst
, char *buf
,
212 size_t buflen
, struct group
**grdstp
);
213 void (*nw_endgrent
)(struct nwrap_backend
*b
);
216 /* prototypes for files backend */
219 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
221 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
222 const char *name
, struct passwd
*pwdst
,
223 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
224 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
226 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
227 uid_t uid
, struct passwd
*pwdst
,
228 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
229 static void nwrap_files_setpwent(struct nwrap_backend
*b
);
230 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
);
231 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
232 struct passwd
*pwdst
, char *buf
,
233 size_t buflen
, struct passwd
**pwdstp
);
234 static void nwrap_files_endpwent(struct nwrap_backend
*b
);
235 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
236 const char *user
, gid_t group
);
237 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
239 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
240 const char *name
, struct group
*grdst
,
241 char *buf
, size_t buflen
, struct group
**grdstp
);
242 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
244 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
245 gid_t gid
, struct group
*grdst
,
246 char *buf
, size_t buflen
, struct group
**grdstp
);
247 static void nwrap_files_setgrent(struct nwrap_backend
*b
);
248 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
);
249 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
250 struct group
*grdst
, char *buf
,
251 size_t buflen
, struct group
**grdstp
);
252 static void nwrap_files_endgrent(struct nwrap_backend
*b
);
254 /* prototypes for module backend */
256 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
);
257 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
258 struct passwd
*pwdst
, char *buf
,
259 size_t buflen
, struct passwd
**pwdstp
);
260 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
262 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
263 const char *name
, struct passwd
*pwdst
,
264 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
265 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
267 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
268 uid_t uid
, struct passwd
*pwdst
,
269 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
270 static void nwrap_module_setpwent(struct nwrap_backend
*b
);
271 static void nwrap_module_endpwent(struct nwrap_backend
*b
);
272 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
);
273 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
274 struct group
*grdst
, char *buf
,
275 size_t buflen
, struct group
**grdstp
);
276 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
278 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
279 const char *name
, struct group
*grdst
,
280 char *buf
, size_t buflen
, struct group
**grdstp
);
281 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
283 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
284 gid_t gid
, struct group
*grdst
,
285 char *buf
, size_t buflen
, struct group
**grdstp
);
286 static void nwrap_module_setgrent(struct nwrap_backend
*b
);
287 static void nwrap_module_endgrent(struct nwrap_backend
*b
);
288 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
289 const char *user
, gid_t group
);
291 struct nwrap_ops nwrap_files_ops
= {
292 .nw_getpwnam
= nwrap_files_getpwnam
,
293 .nw_getpwnam_r
= nwrap_files_getpwnam_r
,
294 .nw_getpwuid
= nwrap_files_getpwuid
,
295 .nw_getpwuid_r
= nwrap_files_getpwuid_r
,
296 .nw_setpwent
= nwrap_files_setpwent
,
297 .nw_getpwent
= nwrap_files_getpwent
,
298 .nw_getpwent_r
= nwrap_files_getpwent_r
,
299 .nw_endpwent
= nwrap_files_endpwent
,
300 .nw_initgroups
= nwrap_files_initgroups
,
301 .nw_getgrnam
= nwrap_files_getgrnam
,
302 .nw_getgrnam_r
= nwrap_files_getgrnam_r
,
303 .nw_getgrgid
= nwrap_files_getgrgid
,
304 .nw_getgrgid_r
= nwrap_files_getgrgid_r
,
305 .nw_setgrent
= nwrap_files_setgrent
,
306 .nw_getgrent
= nwrap_files_getgrent
,
307 .nw_getgrent_r
= nwrap_files_getgrent_r
,
308 .nw_endgrent
= nwrap_files_endgrent
,
311 struct nwrap_ops nwrap_module_ops
= {
312 .nw_getpwnam
= nwrap_module_getpwnam
,
313 .nw_getpwnam_r
= nwrap_module_getpwnam_r
,
314 .nw_getpwuid
= nwrap_module_getpwuid
,
315 .nw_getpwuid_r
= nwrap_module_getpwuid_r
,
316 .nw_setpwent
= nwrap_module_setpwent
,
317 .nw_getpwent
= nwrap_module_getpwent
,
318 .nw_getpwent_r
= nwrap_module_getpwent_r
,
319 .nw_endpwent
= nwrap_module_endpwent
,
320 .nw_initgroups
= nwrap_module_initgroups
,
321 .nw_getgrnam
= nwrap_module_getgrnam
,
322 .nw_getgrnam_r
= nwrap_module_getgrnam_r
,
323 .nw_getgrgid
= nwrap_module_getgrgid
,
324 .nw_getgrgid_r
= nwrap_module_getgrgid_r
,
325 .nw_setgrent
= nwrap_module_setgrent
,
326 .nw_getgrent
= nwrap_module_getgrent
,
327 .nw_getgrent_r
= nwrap_module_getgrent_r
,
328 .nw_endgrent
= nwrap_module_endgrent
,
332 const char *nwrap_switch
;
334 struct nwrap_backend
*backends
;
337 struct nwrap_main
*nwrap_main_global
;
338 struct nwrap_main __nwrap_main_global
;
346 bool (*parse_line
)(struct nwrap_cache
*, char *line
);
347 void (*unload
)(struct nwrap_cache
*);
351 struct nwrap_cache
*cache
;
358 struct nwrap_cache __nwrap_cache_pw
;
359 struct nwrap_pw nwrap_pw_global
;
361 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
);
362 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
);
365 struct nwrap_cache
*cache
;
372 struct nwrap_cache __nwrap_cache_gr
;
373 struct nwrap_gr nwrap_gr_global
;
375 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
);
376 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
);
378 static void *nwrap_load_module_fn(struct nwrap_backend
*b
,
385 NWRAP_ERROR(("%s: no handle\n",
390 if (asprintf(&s
, "_nss_%s_%s", b
->name
, fn_name
) == -1) {
391 NWRAP_ERROR(("%s: out of memory\n",
396 res
= dlsym(b
->so_handle
, s
);
398 NWRAP_ERROR(("%s: cannot find function %s in %s\n",
399 __location__
, s
, b
->so_path
));
406 static struct nwrap_module_nss_fns
*nwrap_load_module_fns(struct nwrap_backend
*b
)
408 struct nwrap_module_nss_fns
*fns
;
414 fns
= (struct nwrap_module_nss_fns
*)malloc(sizeof(struct nwrap_module_nss_fns
));
419 fns
->_nss_getpwnam_r
= (NSS_STATUS (*)(const char *, struct passwd
*, char *, size_t, int *))
420 nwrap_load_module_fn(b
, "getpwnam_r");
421 fns
->_nss_getpwuid_r
= (NSS_STATUS (*)(uid_t
, struct passwd
*, char *, size_t, int *))
422 nwrap_load_module_fn(b
, "getpwuid_r");
423 fns
->_nss_setpwent
= (NSS_STATUS(*)(void))
424 nwrap_load_module_fn(b
, "setpwent");
425 fns
->_nss_getpwent_r
= (NSS_STATUS (*)(struct passwd
*, char *, size_t, int *))
426 nwrap_load_module_fn(b
, "getpwent_r");
427 fns
->_nss_endpwent
= (NSS_STATUS(*)(void))
428 nwrap_load_module_fn(b
, "endpwent");
429 fns
->_nss_initgroups
= (NSS_STATUS (*)(const char *, gid_t
, long int *, long int *, gid_t
**, long int, int *))
430 nwrap_load_module_fn(b
, "initgroups_dyn");
431 fns
->_nss_getgrnam_r
= (NSS_STATUS (*)(const char *, struct group
*, char *, size_t, int *))
432 nwrap_load_module_fn(b
, "getgrnam_r");
433 fns
->_nss_getgrgid_r
= (NSS_STATUS (*)(gid_t
, struct group
*, char *, size_t, int *))
434 nwrap_load_module_fn(b
, "getgrgid_r");
435 fns
->_nss_setgrent
= (NSS_STATUS(*)(void))
436 nwrap_load_module_fn(b
, "setgrent");
437 fns
->_nss_getgrent_r
= (NSS_STATUS (*)(struct group
*, char *, size_t, int *))
438 nwrap_load_module_fn(b
, "getgrent_r");
439 fns
->_nss_endgrent
= (NSS_STATUS(*)(void))
440 nwrap_load_module_fn(b
, "endgrent");
445 static void *nwrap_load_module(const char *so_path
)
449 if (!so_path
|| !strlen(so_path
)) {
453 h
= dlopen(so_path
, RTLD_LAZY
);
455 NWRAP_ERROR(("%s: cannot open shared library %s\n",
456 __location__
, so_path
));
463 static bool nwrap_module_init(const char *name
,
464 struct nwrap_ops
*ops
,
467 struct nwrap_backend
**backends
)
469 struct nwrap_backend
*b
;
471 *backends
= (struct nwrap_backend
*)realloc(*backends
,
472 sizeof(struct nwrap_backend
) * ((*num_backends
) + 1));
474 NWRAP_ERROR(("%s: out of memory\n",
479 b
= &((*backends
)[*num_backends
]);
483 b
->so_path
= so_path
;
485 if (so_path
!= NULL
) {
486 b
->so_handle
= nwrap_load_module(so_path
);
487 b
->fns
= nwrap_load_module_fns(b
);
488 if (b
->fns
== NULL
) {
501 static void nwrap_backend_init(struct nwrap_main
*r
)
503 const char *winbind_so_path
= getenv("NSS_WRAPPER_WINBIND_SO_PATH");
508 if (!nwrap_module_init("files", &nwrap_files_ops
, NULL
,
511 NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
516 if (winbind_so_path
&& strlen(winbind_so_path
)) {
517 if (!nwrap_module_init("winbind", &nwrap_module_ops
, winbind_so_path
,
520 NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n",
527 static void nwrap_init(void)
529 static bool initialized
;
531 if (initialized
) return;
534 nwrap_main_global
= &__nwrap_main_global
;
536 nwrap_backend_init(nwrap_main_global
);
538 nwrap_pw_global
.cache
= &__nwrap_cache_pw
;
540 nwrap_pw_global
.cache
->path
= getenv("NSS_WRAPPER_PASSWD");
541 nwrap_pw_global
.cache
->fd
= -1;
542 nwrap_pw_global
.cache
->private_data
= &nwrap_pw_global
;
543 nwrap_pw_global
.cache
->parse_line
= nwrap_pw_parse_line
;
544 nwrap_pw_global
.cache
->unload
= nwrap_pw_unload
;
546 nwrap_gr_global
.cache
= &__nwrap_cache_gr
;
548 nwrap_gr_global
.cache
->path
= getenv("NSS_WRAPPER_GROUP");
549 nwrap_gr_global
.cache
->fd
= -1;
550 nwrap_gr_global
.cache
->private_data
= &nwrap_gr_global
;
551 nwrap_gr_global
.cache
->parse_line
= nwrap_gr_parse_line
;
552 nwrap_gr_global
.cache
->unload
= nwrap_gr_unload
;
555 static bool nwrap_enabled(void)
559 if (!nwrap_pw_global
.cache
->path
) {
562 if (nwrap_pw_global
.cache
->path
[0] == '\0') {
565 if (!nwrap_gr_global
.cache
->path
) {
568 if (nwrap_gr_global
.cache
->path
[0] == '\0') {
575 static bool nwrap_parse_file(struct nwrap_cache
*nwrap
)
581 if (nwrap
->st
.st_size
== 0) {
582 NWRAP_DEBUG(("%s: size == 0\n",
587 if (nwrap
->st
.st_size
> INT32_MAX
) {
588 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
589 __location__
, (unsigned)nwrap
->st
.st_size
));
593 ret
= lseek(nwrap
->fd
, 0, SEEK_SET
);
595 NWRAP_ERROR(("%s: lseek - %d\n",__location__
,ret
));
599 buf
= (uint8_t *)malloc(nwrap
->st
.st_size
+ 1);
601 NWRAP_ERROR(("%s: malloc failed\n",__location__
));
605 ret
= read(nwrap
->fd
, buf
, nwrap
->st
.st_size
);
606 if (ret
!= nwrap
->st
.st_size
) {
607 NWRAP_ERROR(("%s: read(%u) gave %d\n",
608 __location__
, (unsigned)nwrap
->st
.st_size
, ret
));
612 buf
[nwrap
->st
.st_size
] = '\0';
615 while (nline
&& nline
[0]) {
623 e
= strchr(line
, '\n');
634 NWRAP_VERBOSE(("%s:'%s'\n",__location__
, line
));
636 if (strlen(line
) == 0) {
640 ok
= nwrap
->parse_line(nwrap
, line
);
655 static void nwrap_files_cache_unload(struct nwrap_cache
*nwrap
)
657 nwrap
->unload(nwrap
);
659 if (nwrap
->buf
) free(nwrap
->buf
);
664 static void nwrap_files_cache_reload(struct nwrap_cache
*nwrap
)
669 bool retried
= false;
673 nwrap
->fd
= open(nwrap
->path
, O_RDONLY
);
675 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
677 nwrap
->path
, nwrap
->fd
,
681 NWRAP_VERBOSE(("%s: open '%s'\n", __location__
, nwrap
->path
));
684 ret
= fstat(nwrap
->fd
, &st
);
686 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
689 ret
, strerror(errno
)));
693 if (retried
== false && st
.st_nlink
== 0) {
694 /* maybe someone has replaced the file... */
695 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
696 __location__
, nwrap
->path
));
698 memset(&nwrap
->st
, 0, sizeof(nwrap
->st
));
704 if (st
.st_mtime
== nwrap
->st
.st_mtime
) {
705 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
706 __location__
, (unsigned)st
.st_mtime
));
709 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
710 __location__
, (unsigned)st
.st_mtime
,
711 (unsigned)nwrap
->st
.st_mtime
));
715 nwrap_files_cache_unload(nwrap
);
717 ok
= nwrap_parse_file(nwrap
);
719 NWRAP_ERROR(("%s: failed to reload %s\n",
720 __location__
, nwrap
->path
));
721 nwrap_files_cache_unload(nwrap
);
723 NWRAP_DEBUG(("%s: reloaded %s\n",
724 __location__
, nwrap
->path
));
728 * the caller has to call nwrap_unload() on failure
730 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
)
732 struct nwrap_pw
*nwrap_pw
;
739 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
741 list_size
= sizeof(*nwrap_pw
->list
) * (nwrap_pw
->num
+1);
742 pw
= (struct passwd
*)realloc(nwrap_pw
->list
, list_size
);
744 NWRAP_ERROR(("%s:realloc(%u) failed\n",
745 __location__
, list_size
));
750 pw
= &nwrap_pw
->list
[nwrap_pw
->num
];
757 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
758 __location__
, line
, c
));
766 NWRAP_VERBOSE(("name[%s]\n", pw
->pw_name
));
771 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
772 __location__
, line
, c
));
780 NWRAP_VERBOSE(("password[%s]\n", pw
->pw_passwd
));
785 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
786 __location__
, line
, c
));
792 pw
->pw_uid
= (uid_t
)strtoul(c
, &e
, 10);
794 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
795 __location__
, line
, c
, strerror(errno
)));
799 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
800 __location__
, line
, c
, strerror(errno
)));
804 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
805 __location__
, line
, c
, strerror(errno
)));
810 NWRAP_VERBOSE(("uid[%u]\n", pw
->pw_uid
));
815 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
816 __location__
, line
, c
));
822 pw
->pw_gid
= (gid_t
)strtoul(c
, &e
, 10);
824 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
825 __location__
, line
, c
, strerror(errno
)));
829 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
830 __location__
, line
, c
, strerror(errno
)));
834 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
835 __location__
, line
, c
, strerror(errno
)));
840 NWRAP_VERBOSE(("gid[%u]\n", pw
->pw_gid
));
845 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
846 __location__
, line
, c
));
854 NWRAP_VERBOSE(("gecos[%s]\n", pw
->pw_gecos
));
859 NWRAP_ERROR(("%s:'%s'\n",__location__
,c
));
867 NWRAP_VERBOSE(("dir[%s]\n", pw
->pw_dir
));
871 NWRAP_VERBOSE(("shell[%s]\n", pw
->pw_shell
));
873 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
874 pw
->pw_name
, pw
->pw_passwd
,
875 pw
->pw_uid
, pw
->pw_gid
,
876 pw
->pw_gecos
, pw
->pw_dir
, pw
->pw_shell
));
882 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
)
884 struct nwrap_pw
*nwrap_pw
;
885 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
887 if (nwrap_pw
->list
) free(nwrap_pw
->list
);
889 nwrap_pw
->list
= NULL
;
894 static int nwrap_pw_copy_r(const struct passwd
*src
, struct passwd
*dst
,
895 char *buf
, size_t buflen
, struct passwd
**dstp
)
901 first
= src
->pw_name
;
903 last
= src
->pw_shell
;
904 while (*last
) last
++;
906 ofs
= PTR_DIFF(last
+ 1, first
);
912 memcpy(buf
, first
, ofs
);
914 ofs
= PTR_DIFF(src
->pw_name
, first
);
915 dst
->pw_name
= buf
+ ofs
;
916 ofs
= PTR_DIFF(src
->pw_passwd
, first
);
917 dst
->pw_passwd
= buf
+ ofs
;
918 dst
->pw_uid
= src
->pw_uid
;
919 dst
->pw_gid
= src
->pw_gid
;
920 ofs
= PTR_DIFF(src
->pw_gecos
, first
);
921 dst
->pw_gecos
= buf
+ ofs
;
922 ofs
= PTR_DIFF(src
->pw_dir
, first
);
923 dst
->pw_dir
= buf
+ ofs
;
924 ofs
= PTR_DIFF(src
->pw_shell
, first
);
925 dst
->pw_shell
= buf
+ ofs
;
935 * the caller has to call nwrap_unload() on failure
937 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
)
939 struct nwrap_gr
*nwrap_gr
;
947 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
949 list_size
= sizeof(*nwrap_gr
->list
) * (nwrap_gr
->num
+1);
950 gr
= (struct group
*)realloc(nwrap_gr
->list
, list_size
);
952 NWRAP_ERROR(("%s:realloc failed\n",__location__
));
957 gr
= &nwrap_gr
->list
[nwrap_gr
->num
];
964 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
965 __location__
, line
, c
));
973 NWRAP_VERBOSE(("name[%s]\n", gr
->gr_name
));
978 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
979 __location__
, line
, c
));
987 NWRAP_VERBOSE(("password[%s]\n", gr
->gr_passwd
));
992 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
993 __location__
, line
, c
));
999 gr
->gr_gid
= (gid_t
)strtoul(c
, &e
, 10);
1001 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1002 __location__
, line
, c
, strerror(errno
)));
1006 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1007 __location__
, line
, c
, strerror(errno
)));
1011 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
1012 __location__
, line
, c
, strerror(errno
)));
1017 NWRAP_VERBOSE(("gid[%u]\n", gr
->gr_gid
));
1020 gr
->gr_mem
= (char **)malloc(sizeof(char *));
1022 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
1025 gr
->gr_mem
[0] = NULL
;
1027 for(nummem
=0; p
; nummem
++) {
1037 if (strlen(c
) == 0) {
1041 m_size
= sizeof(char *) * (nummem
+2);
1042 m
= (char **)realloc(gr
->gr_mem
, m_size
);
1044 NWRAP_ERROR(("%s:realloc(%u) failed\n",
1045 __location__
, m_size
));
1049 gr
->gr_mem
[nummem
] = c
;
1050 gr
->gr_mem
[nummem
+1] = NULL
;
1052 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem
, gr
->gr_mem
[nummem
]));
1055 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
1056 gr
->gr_name
, gr
->gr_passwd
, gr
->gr_gid
, nummem
));
1062 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
)
1065 struct nwrap_gr
*nwrap_gr
;
1066 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
1068 if (nwrap_gr
->list
) {
1069 for (i
=0; i
< nwrap_gr
->num
; i
++) {
1070 if (nwrap_gr
->list
[i
].gr_mem
) {
1071 free(nwrap_gr
->list
[i
].gr_mem
);
1074 free(nwrap_gr
->list
);
1077 nwrap_gr
->list
= NULL
;
1082 static int nwrap_gr_copy_r(const struct group
*src
, struct group
*dst
,
1083 char *buf
, size_t buflen
, struct group
**dstp
)
1093 first
= src
->gr_name
;
1095 lastm
= src
->gr_mem
;
1102 last
= src
->gr_passwd
;
1104 while (*last
) last
++;
1106 ofsb
= PTR_DIFF(last
+ 1, first
);
1107 ofsm
= PTR_DIFF(lastm
+ 1, src
->gr_mem
);
1109 if ((ofsb
+ ofsm
) > buflen
) {
1113 memcpy(buf
, first
, ofsb
);
1114 memcpy(buf
+ ofsb
, src
->gr_mem
, ofsm
);
1116 ofs
= PTR_DIFF(src
->gr_name
, first
);
1117 dst
->gr_name
= buf
+ ofs
;
1118 ofs
= PTR_DIFF(src
->gr_passwd
, first
);
1119 dst
->gr_passwd
= buf
+ ofs
;
1120 dst
->gr_gid
= src
->gr_gid
;
1122 dst
->gr_mem
= (char **)(buf
+ ofsb
);
1123 for (i
=0; src
->gr_mem
[i
]; i
++) {
1124 ofs
= PTR_DIFF(src
->gr_mem
[i
], first
);
1125 dst
->gr_mem
[i
] = buf
+ ofs
;
1135 /* user functions */
1136 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
1141 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1143 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1144 if (strcmp(nwrap_pw_global
.list
[i
].pw_name
, name
) == 0) {
1145 NWRAP_DEBUG(("%s: user[%s] found\n",
1146 __location__
, name
));
1147 return &nwrap_pw_global
.list
[i
];
1149 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
1151 nwrap_pw_global
.list
[i
].pw_name
));
1154 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__
, name
));
1160 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
1161 const char *name
, struct passwd
*pwdst
,
1162 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1166 pw
= nwrap_files_getpwnam(b
, name
);
1174 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1177 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
1182 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1184 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1185 if (nwrap_pw_global
.list
[i
].pw_uid
== uid
) {
1186 NWRAP_DEBUG(("%s: uid[%u] found\n",
1187 __location__
, uid
));
1188 return &nwrap_pw_global
.list
[i
];
1190 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
1192 nwrap_pw_global
.list
[i
].pw_uid
));
1195 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__
, uid
));
1201 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
1202 uid_t uid
, struct passwd
*pwdst
,
1203 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1207 pw
= nwrap_files_getpwuid(b
, uid
);
1215 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1218 /* user enum functions */
1219 static void nwrap_files_setpwent(struct nwrap_backend
*b
)
1221 nwrap_pw_global
.idx
= 0;
1224 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
)
1228 if (nwrap_pw_global
.idx
== 0) {
1229 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1232 if (nwrap_pw_global
.idx
>= nwrap_pw_global
.num
) {
1237 pw
= &nwrap_pw_global
.list
[nwrap_pw_global
.idx
++];
1239 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
1240 __location__
, pw
->pw_name
, pw
->pw_uid
));
1245 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
1246 struct passwd
*pwdst
, char *buf
,
1247 size_t buflen
, struct passwd
**pwdstp
)
1251 pw
= nwrap_files_getpwent(b
);
1259 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1262 static void nwrap_files_endpwent(struct nwrap_backend
*b
)
1264 nwrap_pw_global
.idx
= 0;
1267 /* misc functions */
1268 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
1269 const char *user
, gid_t group
)
1271 /* TODO: maybe we should also fake this... */
1275 /* group functions */
1276 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
1281 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1283 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1284 if (strcmp(nwrap_gr_global
.list
[i
].gr_name
, name
) == 0) {
1285 NWRAP_DEBUG(("%s: group[%s] found\n",
1286 __location__
, name
));
1287 return &nwrap_gr_global
.list
[i
];
1289 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1291 nwrap_gr_global
.list
[i
].gr_name
));
1294 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__
, name
));
1300 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
1301 const char *name
, struct group
*grdst
,
1302 char *buf
, size_t buflen
, struct group
**grdstp
)
1306 gr
= nwrap_files_getgrnam(b
, name
);
1314 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1317 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
1322 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1324 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1325 if (nwrap_gr_global
.list
[i
].gr_gid
== gid
) {
1326 NWRAP_DEBUG(("%s: gid[%u] found\n",
1327 __location__
, gid
));
1328 return &nwrap_gr_global
.list
[i
];
1330 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1332 nwrap_gr_global
.list
[i
].gr_gid
));
1335 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__
, gid
));
1341 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
1342 gid_t gid
, struct group
*grdst
,
1343 char *buf
, size_t buflen
, struct group
**grdstp
)
1347 gr
= nwrap_files_getgrgid(b
, gid
);
1355 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1358 /* group enum functions */
1359 static void nwrap_files_setgrent(struct nwrap_backend
*b
)
1361 nwrap_gr_global
.idx
= 0;
1364 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
)
1368 if (nwrap_gr_global
.idx
== 0) {
1369 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1372 if (nwrap_gr_global
.idx
>= nwrap_gr_global
.num
) {
1377 gr
= &nwrap_gr_global
.list
[nwrap_gr_global
.idx
++];
1379 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1380 __location__
, gr
->gr_name
, gr
->gr_gid
));
1385 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
1386 struct group
*grdst
, char *buf
,
1387 size_t buflen
, struct group
**grdstp
)
1391 gr
= nwrap_files_getgrent(b
);
1399 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1402 static void nwrap_files_endgrent(struct nwrap_backend
*b
)
1404 nwrap_gr_global
.idx
= 0;
1412 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
1415 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
1418 static struct passwd pwd
;
1419 static char buf
[1000];
1422 if (!b
->fns
->_nss_getpwnam_r
) {
1426 status
= b
->fns
->_nss_getpwnam_r(name
, &pwd
, buf
, sizeof(buf
), &errno
);
1427 if (status
== NSS_STATUS_NOTFOUND
) {
1430 if (status
!= NSS_STATUS_SUCCESS
) {
1436 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
1437 const char *name
, struct passwd
*pwdst
,
1438 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1442 if (!b
->fns
->_nss_getpwnam_r
) {
1443 return NSS_STATUS_NOTFOUND
;
1446 ret
= b
->fns
->_nss_getpwnam_r(name
, pwdst
, buf
, buflen
, &errno
);
1448 case NSS_STATUS_SUCCESS
:
1450 case NSS_STATUS_NOTFOUND
:
1455 case NSS_STATUS_TRYAGAIN
:
1468 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
1471 static struct passwd pwd
;
1472 static char buf
[1000];
1475 if (!b
->fns
->_nss_getpwuid_r
) {
1479 status
= b
->fns
->_nss_getpwuid_r(uid
, &pwd
, buf
, sizeof(buf
), &errno
);
1480 if (status
== NSS_STATUS_NOTFOUND
) {
1483 if (status
!= NSS_STATUS_SUCCESS
) {
1489 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
1490 uid_t uid
, struct passwd
*pwdst
,
1491 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1495 if (!b
->fns
->_nss_getpwuid_r
) {
1499 ret
= b
->fns
->_nss_getpwuid_r(uid
, pwdst
, buf
, buflen
, &errno
);
1501 case NSS_STATUS_SUCCESS
:
1503 case NSS_STATUS_NOTFOUND
:
1508 case NSS_STATUS_TRYAGAIN
:
1521 static void nwrap_module_setpwent(struct nwrap_backend
*b
)
1523 if (!b
->fns
->_nss_setpwent
) {
1527 b
->fns
->_nss_setpwent();
1530 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
)
1532 static struct passwd pwd
;
1533 static char buf
[1000];
1536 if (!b
->fns
->_nss_getpwent_r
) {
1540 status
= b
->fns
->_nss_getpwent_r(&pwd
, buf
, sizeof(buf
), &errno
);
1541 if (status
== NSS_STATUS_NOTFOUND
) {
1544 if (status
!= NSS_STATUS_SUCCESS
) {
1550 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
1551 struct passwd
*pwdst
, char *buf
,
1552 size_t buflen
, struct passwd
**pwdstp
)
1556 if (!b
->fns
->_nss_getpwent_r
) {
1560 ret
= b
->fns
->_nss_getpwent_r(pwdst
, buf
, buflen
, &errno
);
1562 case NSS_STATUS_SUCCESS
:
1564 case NSS_STATUS_NOTFOUND
:
1569 case NSS_STATUS_TRYAGAIN
:
1582 static void nwrap_module_endpwent(struct nwrap_backend
*b
)
1584 if (!b
->fns
->_nss_endpwent
) {
1588 b
->fns
->_nss_endpwent();
1591 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
1592 const char *user
, gid_t group
)
1598 if (!b
->fns
->_nss_initgroups
) {
1599 return NSS_STATUS_UNAVAIL
;
1602 return b
->fns
->_nss_initgroups(user
, group
, &start
, &size
, &groups
, 0, &errno
);
1605 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
1608 static struct group grp
;
1610 static int buflen
= 1000;
1613 if (!b
->fns
->_nss_getgrnam_r
) {
1618 buf
= (char *)malloc(buflen
);
1621 status
= b
->fns
->_nss_getgrnam_r(name
, &grp
, buf
, buflen
, &errno
);
1622 if (status
== NSS_STATUS_TRYAGAIN
) {
1624 buf
= (char *)realloc(buf
, buflen
);
1630 if (status
== NSS_STATUS_NOTFOUND
) {
1634 if (status
!= NSS_STATUS_SUCCESS
) {
1641 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
1642 const char *name
, struct group
*grdst
,
1643 char *buf
, size_t buflen
, struct group
**grdstp
)
1647 if (!b
->fns
->_nss_getgrnam_r
) {
1651 ret
= b
->fns
->_nss_getgrnam_r(name
, grdst
, buf
, buflen
, &errno
);
1653 case NSS_STATUS_SUCCESS
:
1655 case NSS_STATUS_NOTFOUND
:
1660 case NSS_STATUS_TRYAGAIN
:
1673 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
1676 static struct group grp
;
1678 static int buflen
= 1000;
1681 if (!b
->fns
->_nss_getgrgid_r
) {
1686 buf
= (char *)malloc(buflen
);
1690 status
= b
->fns
->_nss_getgrgid_r(gid
, &grp
, buf
, buflen
, &errno
);
1691 if (status
== NSS_STATUS_TRYAGAIN
) {
1693 buf
= (char *)realloc(buf
, buflen
);
1699 if (status
== NSS_STATUS_NOTFOUND
) {
1703 if (status
!= NSS_STATUS_SUCCESS
) {
1710 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
1711 gid_t gid
, struct group
*grdst
,
1712 char *buf
, size_t buflen
, struct group
**grdstp
)
1716 if (!b
->fns
->_nss_getgrgid_r
) {
1720 ret
= b
->fns
->_nss_getgrgid_r(gid
, grdst
, buf
, buflen
, &errno
);
1722 case NSS_STATUS_SUCCESS
:
1724 case NSS_STATUS_NOTFOUND
:
1729 case NSS_STATUS_TRYAGAIN
:
1742 static void nwrap_module_setgrent(struct nwrap_backend
*b
)
1744 if (!b
->fns
->_nss_setgrent
) {
1748 b
->fns
->_nss_setgrent();
1751 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
)
1753 static struct group grp
;
1755 static int buflen
= 1024;
1758 if (!b
->fns
->_nss_getgrent_r
) {
1763 buf
= (char *)malloc(buflen
);
1767 status
= b
->fns
->_nss_getgrent_r(&grp
, buf
, buflen
, &errno
);
1768 if (status
== NSS_STATUS_TRYAGAIN
) {
1770 buf
= (char *)realloc(buf
, buflen
);
1776 if (status
== NSS_STATUS_NOTFOUND
) {
1780 if (status
!= NSS_STATUS_SUCCESS
) {
1787 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
1788 struct group
*grdst
, char *buf
,
1789 size_t buflen
, struct group
**grdstp
)
1793 if (!b
->fns
->_nss_getgrent_r
) {
1797 ret
= b
->fns
->_nss_getgrent_r(grdst
, buf
, buflen
, &errno
);
1799 case NSS_STATUS_SUCCESS
:
1801 case NSS_STATUS_NOTFOUND
:
1806 case NSS_STATUS_TRYAGAIN
:
1819 static void nwrap_module_endgrent(struct nwrap_backend
*b
)
1821 if (!b
->fns
->_nss_endgrent
) {
1825 b
->fns
->_nss_endgrent();
1832 _PUBLIC_
struct passwd
*nwrap_getpwnam(const char *name
)
1837 if (!nwrap_enabled()) {
1838 return real_getpwnam(name
);
1841 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1842 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1843 pwd
= b
->ops
->nw_getpwnam(b
, name
);
1852 _PUBLIC_
int nwrap_getpwnam_r(const char *name
, struct passwd
*pwdst
,
1853 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1857 if (!nwrap_enabled()) {
1858 return real_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
1861 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1862 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1863 ret
= b
->ops
->nw_getpwnam_r(b
, name
, pwdst
, buf
, buflen
, pwdstp
);
1864 if (ret
== ENOENT
) {
1873 _PUBLIC_
struct passwd
*nwrap_getpwuid(uid_t uid
)
1878 if (!nwrap_enabled()) {
1879 return real_getpwuid(uid
);
1882 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1883 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1884 pwd
= b
->ops
->nw_getpwuid(b
, uid
);
1893 _PUBLIC_
int nwrap_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
1894 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1898 if (!nwrap_enabled()) {
1899 return real_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
1902 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1903 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1904 ret
= b
->ops
->nw_getpwuid_r(b
, uid
, pwdst
, buf
, buflen
, pwdstp
);
1905 if (ret
== ENOENT
) {
1914 _PUBLIC_
void nwrap_setpwent(void)
1918 if (!nwrap_enabled()) {
1923 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1924 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1925 b
->ops
->nw_setpwent(b
);
1929 _PUBLIC_
struct passwd
*nwrap_getpwent(void)
1934 if (!nwrap_enabled()) {
1935 return real_getpwent();
1938 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1939 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1940 pwd
= b
->ops
->nw_getpwent(b
);
1949 _PUBLIC_
int nwrap_getpwent_r(struct passwd
*pwdst
, char *buf
,
1950 size_t buflen
, struct passwd
**pwdstp
)
1954 if (!nwrap_enabled()) {
1955 #ifdef SOLARIS_GETPWENT_R
1957 pw
= real_getpwent_r(pwdst
, buf
, buflen
);
1969 return real_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
1973 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1974 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1975 ret
= b
->ops
->nw_getpwent_r(b
, pwdst
, buf
, buflen
, pwdstp
);
1976 if (ret
== ENOENT
) {
1985 _PUBLIC_
void nwrap_endpwent(void)
1989 if (!nwrap_enabled()) {
1994 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1995 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1996 b
->ops
->nw_endpwent(b
);
2000 _PUBLIC_
int nwrap_initgroups(const char *user
, gid_t group
)
2004 if (!nwrap_enabled()) {
2005 return real_initgroups(user
, group
);
2008 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2009 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2010 return b
->ops
->nw_initgroups(b
, user
, group
);
2017 _PUBLIC_
struct group
*nwrap_getgrnam(const char *name
)
2022 if (!nwrap_enabled()) {
2023 return real_getgrnam(name
);
2026 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2027 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2028 grp
= b
->ops
->nw_getgrnam(b
, name
);
2037 _PUBLIC_
int nwrap_getgrnam_r(const char *name
, struct group
*grdst
,
2038 char *buf
, size_t buflen
, struct group
**grdstp
)
2042 if (!nwrap_enabled()) {
2043 return real_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
2046 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2047 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2048 ret
= b
->ops
->nw_getgrnam_r(b
, name
, grdst
, buf
, buflen
, grdstp
);
2049 if (ret
== ENOENT
) {
2058 _PUBLIC_
struct group
*nwrap_getgrgid(gid_t gid
)
2063 if (!nwrap_enabled()) {
2064 return real_getgrgid(gid
);
2067 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2068 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2069 grp
= b
->ops
->nw_getgrgid(b
, gid
);
2078 _PUBLIC_
int nwrap_getgrgid_r(gid_t gid
, struct group
*grdst
,
2079 char *buf
, size_t buflen
, struct group
**grdstp
)
2083 if (!nwrap_enabled()) {
2084 return real_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
2087 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2088 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2089 ret
= b
->ops
->nw_getgrgid_r(b
, gid
, grdst
, buf
, buflen
, grdstp
);
2090 if (ret
== ENOENT
) {
2099 _PUBLIC_
void nwrap_setgrent(void)
2103 if (!nwrap_enabled()) {
2108 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2109 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2110 b
->ops
->nw_setgrent(b
);
2114 _PUBLIC_
struct group
*nwrap_getgrent(void)
2119 if (!nwrap_enabled()) {
2120 return real_getgrent();
2123 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2124 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2125 grp
= b
->ops
->nw_getgrent(b
);
2134 _PUBLIC_
int nwrap_getgrent_r(struct group
*grdst
, char *buf
,
2135 size_t buflen
, struct group
**grdstp
)
2139 if (!nwrap_enabled()) {
2140 #ifdef SOLARIS_GETGRENT_R
2142 gr
= real_getgrent_r(grdst
, buf
, buflen
);
2154 return real_getgrent_r(grdst
, buf
, buflen
, grdstp
);
2158 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2159 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2160 ret
= b
->ops
->nw_getgrent_r(b
, grdst
, buf
, buflen
, grdstp
);
2161 if (ret
== ENOENT
) {
2170 _PUBLIC_
void nwrap_endgrent(void)
2174 if (!nwrap_enabled()) {
2179 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2180 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2181 b
->ops
->nw_endgrent(b
);
2185 _PUBLIC_
int nwrap_getgrouplist(const char *user
, gid_t group
, gid_t
*groups
, int *ngroups
)
2190 const char *name_of_group
= "";
2192 if (!nwrap_enabled()) {
2193 return real_getgrouplist(user
, group
, groups
, ngroups
);
2196 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__
, user
));
2198 groups_tmp
= (gid_t
*)malloc(count
* sizeof(gid_t
));
2200 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2205 memcpy(groups_tmp
, &group
, sizeof(gid_t
));
2207 grp
= nwrap_getgrgid(group
);
2209 name_of_group
= grp
->gr_name
;
2213 while ((grp
= nwrap_getgrent()) != NULL
) {
2216 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
2217 __location__
, grp
->gr_name
));
2219 for (i
=0; grp
->gr_mem
&& grp
->gr_mem
[i
] != NULL
; i
++) {
2221 if ((strcmp(user
, grp
->gr_mem
[i
]) == 0) &&
2222 (strcmp(name_of_group
, grp
->gr_name
) != 0)) {
2224 NWRAP_DEBUG(("%s: %s is member of %s\n",
2225 __location__
, user
, grp
->gr_name
));
2227 groups_tmp
= (gid_t
*)realloc(groups_tmp
, (count
+ 1) * sizeof(gid_t
));
2229 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2234 memcpy(&groups_tmp
[count
], &grp
->gr_gid
, sizeof(gid_t
));
2242 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
2243 __location__
, user
, *ngroups
));
2245 if (*ngroups
< count
) {
2252 memcpy(groups
, groups_tmp
, count
* sizeof(gid_t
));