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 #define NSS_WRAPPER_NOT_REPLACE
38 #include "../replace/replace.h"
39 #include "system/passwd.h"
40 #include "system/filesys.h"
41 #include "../nsswitch/nsstest.h"
43 #else /* _SAMBA_BUILD_ */
45 #error nss_wrapper_only_supported_in_samba_yet
53 /* not all systems have _r functions... */
54 #ifndef HAVE_GETPWNAM_R
55 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
57 #ifndef HAVE_GETPWUID_R
58 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
60 #ifndef HAVE_GETPWENT_R
61 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
63 #ifndef HAVE_GETGRNAM_R
64 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
66 #ifndef HAVE_GETGRGID_R
67 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
69 #ifndef HAVE_GETGRENT_R
70 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
73 /* not all systems have getgrouplist */
74 #ifndef HAVE_GETGROUPLIST
75 #define getgrouplist(user, group, groups, ngroups) 0
78 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
84 #define real_getpwnam getpwnam
85 #define real_getpwnam_r getpwnam_r
86 #define real_getpwuid getpwuid
87 #define real_getpwuid_r getpwuid_r
89 #define real_setpwent setpwent
90 #define real_getpwent getpwent
91 #define real_getpwent_r getpwent_r
92 #define real_endpwent endpwent
95 #define real_getgrlst getgrlst
96 #define real_getgrlst_r getgrlst_r
97 #define real_initgroups_dyn initgroups_dyn
99 #define real_initgroups initgroups
100 #define real_getgrouplist getgrouplist
102 #define real_getgrnam getgrnam
103 #define real_getgrnam_r getgrnam_r
104 #define real_getgrgid getgrgid
105 #define real_getgrgid_r getgrgid_r
107 #define real_setgrent setgrent
108 #define real_getgrent getgrent
109 #define real_getgrent_r getgrent_r
110 #define real_endgrent endgrent
116 # define NWRAP_ERROR(args) DEBUG(0, args)
118 # define NWRAP_ERROR(args) printf args
121 #define NWRAP_ERROR(args)
126 # define NWRAP_DEBUG(args) DEBUG(0, args)
128 # define NWRAP_DEBUG(args) printf args
131 #define NWRAP_DEBUG(args)
136 # define NWRAP_VERBOSE(args) DEBUG(0, args)
138 # define NWRAP_VERBOSE(args) printf args
141 #define NWRAP_VERBOSE(args)
144 struct nwrap_module_nss_fns
{
145 NSS_STATUS (*_nss_getpwnam_r
)(const char *name
, struct passwd
*result
, char *buffer
,
146 size_t buflen
, int *errnop
);
147 NSS_STATUS (*_nss_getpwuid_r
)(uid_t uid
, struct passwd
*result
, char *buffer
,
148 size_t buflen
, int *errnop
);
149 NSS_STATUS (*_nss_setpwent
)(void);
150 NSS_STATUS (*_nss_getpwent_r
)(struct passwd
*result
, char *buffer
,
151 size_t buflen
, int *errnop
);
152 NSS_STATUS (*_nss_endpwent
)(void);
153 NSS_STATUS (*_nss_initgroups
)(const char *user
, gid_t group
, long int *start
,
154 long int *size
, gid_t
**groups
, long int limit
, int *errnop
);
155 NSS_STATUS (*_nss_getgrnam_r
)(const char *name
, struct group
*result
, char *buffer
,
156 size_t buflen
, int *errnop
);
157 NSS_STATUS (*_nss_getgrgid_r
)(gid_t gid
, struct group
*result
, char *buffer
,
158 size_t buflen
, int *errnop
);
159 NSS_STATUS (*_nss_setgrent
)(void);
160 NSS_STATUS (*_nss_getgrent_r
)(struct group
*result
, char *buffer
,
161 size_t buflen
, int *errnop
);
162 NSS_STATUS (*_nss_endgrent
)(void);
165 struct nwrap_backend
{
169 struct nwrap_ops
*ops
;
170 struct nwrap_module_nss_fns
*fns
;
174 struct passwd
* (*nw_getpwnam
)(struct nwrap_backend
*b
,
176 int (*nw_getpwnam_r
)(struct nwrap_backend
*b
,
177 const char *name
, struct passwd
*pwdst
,
178 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
179 struct passwd
* (*nw_getpwuid
)(struct nwrap_backend
*b
,
181 int (*nw_getpwuid_r
)(struct nwrap_backend
*b
,
182 uid_t uid
, struct passwd
*pwdst
,
183 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
184 void (*nw_setpwent
)(struct nwrap_backend
*b
);
185 struct passwd
* (*nw_getpwent
)(struct nwrap_backend
*b
);
186 int (*nw_getpwent_r
)(struct nwrap_backend
*b
,
187 struct passwd
*pwdst
, char *buf
,
188 size_t buflen
, struct passwd
**pwdstp
);
189 void (*nw_endpwent
)(struct nwrap_backend
*b
);
190 int (*nw_initgroups
)(struct nwrap_backend
*b
,
191 const char *user
, gid_t group
);
192 struct group
* (*nw_getgrnam
)(struct nwrap_backend
*b
,
194 int (*nw_getgrnam_r
)(struct nwrap_backend
*b
,
195 const char *name
, struct group
*grdst
,
196 char *buf
, size_t buflen
, struct group
**grdstp
);
197 struct group
* (*nw_getgrgid
)(struct nwrap_backend
*b
,
199 int (*nw_getgrgid_r
)(struct nwrap_backend
*b
,
200 gid_t gid
, struct group
*grdst
,
201 char *buf
, size_t buflen
, struct group
**grdstp
);
202 void (*nw_setgrent
)(struct nwrap_backend
*b
);
203 struct group
* (*nw_getgrent
)(struct nwrap_backend
*b
);
204 int (*nw_getgrent_r
)(struct nwrap_backend
*b
,
205 struct group
*grdst
, char *buf
,
206 size_t buflen
, struct group
**grdstp
);
207 void (*nw_endgrent
)(struct nwrap_backend
*b
);
210 /* protoypes for files backend */
213 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
215 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
216 const char *name
, struct passwd
*pwdst
,
217 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
218 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
220 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
221 uid_t uid
, struct passwd
*pwdst
,
222 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
223 static void nwrap_files_setpwent(struct nwrap_backend
*b
);
224 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
);
225 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
226 struct passwd
*pwdst
, char *buf
,
227 size_t buflen
, struct passwd
**pwdstp
);
228 static void nwrap_files_endpwent(struct nwrap_backend
*b
);
229 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
230 const char *user
, gid_t group
);
231 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
233 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
234 const char *name
, struct group
*grdst
,
235 char *buf
, size_t buflen
, struct group
**grdstp
);
236 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
238 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
239 gid_t gid
, struct group
*grdst
,
240 char *buf
, size_t buflen
, struct group
**grdstp
);
241 static void nwrap_files_setgrent(struct nwrap_backend
*b
);
242 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
);
243 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
244 struct group
*grdst
, char *buf
,
245 size_t buflen
, struct group
**grdstp
);
246 static void nwrap_files_endgrent(struct nwrap_backend
*b
);
248 /* protoypes for module backend */
250 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
);
251 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
252 struct passwd
*pwdst
, char *buf
,
253 size_t buflen
, struct passwd
**pwdstp
);
254 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
256 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
257 const char *name
, struct passwd
*pwdst
,
258 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
259 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
261 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
262 uid_t uid
, struct passwd
*pwdst
,
263 char *buf
, size_t buflen
, struct passwd
**pwdstp
);
264 static void nwrap_module_setpwent(struct nwrap_backend
*b
);
265 static void nwrap_module_endpwent(struct nwrap_backend
*b
);
266 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
);
267 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
268 struct group
*grdst
, char *buf
,
269 size_t buflen
, struct group
**grdstp
);
270 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
272 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
273 const char *name
, struct group
*grdst
,
274 char *buf
, size_t buflen
, struct group
**grdstp
);
275 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
277 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
278 gid_t gid
, struct group
*grdst
,
279 char *buf
, size_t buflen
, struct group
**grdstp
);
280 static void nwrap_module_setgrent(struct nwrap_backend
*b
);
281 static void nwrap_module_endgrent(struct nwrap_backend
*b
);
282 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
283 const char *user
, gid_t group
);
285 struct nwrap_ops nwrap_files_ops
= {
286 .nw_getpwnam
= nwrap_files_getpwnam
,
287 .nw_getpwnam_r
= nwrap_files_getpwnam_r
,
288 .nw_getpwuid
= nwrap_files_getpwuid
,
289 .nw_getpwuid_r
= nwrap_files_getpwuid_r
,
290 .nw_setpwent
= nwrap_files_setpwent
,
291 .nw_getpwent
= nwrap_files_getpwent
,
292 .nw_getpwent_r
= nwrap_files_getpwent_r
,
293 .nw_endpwent
= nwrap_files_endpwent
,
294 .nw_initgroups
= nwrap_files_initgroups
,
295 .nw_getgrnam
= nwrap_files_getgrnam
,
296 .nw_getgrnam_r
= nwrap_files_getgrnam_r
,
297 .nw_getgrgid
= nwrap_files_getgrgid
,
298 .nw_getgrgid_r
= nwrap_files_getgrgid_r
,
299 .nw_setgrent
= nwrap_files_setgrent
,
300 .nw_getgrent
= nwrap_files_getgrent
,
301 .nw_getgrent_r
= nwrap_files_getgrent_r
,
302 .nw_endgrent
= nwrap_files_endgrent
,
305 struct nwrap_ops nwrap_module_ops
= {
306 .nw_getpwnam
= nwrap_module_getpwnam
,
307 .nw_getpwnam_r
= nwrap_module_getpwnam_r
,
308 .nw_getpwuid
= nwrap_module_getpwuid
,
309 .nw_getpwuid_r
= nwrap_module_getpwuid_r
,
310 .nw_setpwent
= nwrap_module_setpwent
,
311 .nw_getpwent
= nwrap_module_getpwent
,
312 .nw_getpwent_r
= nwrap_module_getpwent_r
,
313 .nw_endpwent
= nwrap_module_endpwent
,
314 .nw_initgroups
= nwrap_module_initgroups
,
315 .nw_getgrnam
= nwrap_module_getgrnam
,
316 .nw_getgrnam_r
= nwrap_module_getgrnam_r
,
317 .nw_getgrgid
= nwrap_module_getgrgid
,
318 .nw_getgrgid_r
= nwrap_module_getgrgid_r
,
319 .nw_setgrent
= nwrap_module_setgrent
,
320 .nw_getgrent
= nwrap_module_getgrent
,
321 .nw_getgrent_r
= nwrap_module_getgrent_r
,
322 .nw_endgrent
= nwrap_module_endgrent
,
326 const char *nwrap_switch
;
328 struct nwrap_backend
*backends
;
331 struct nwrap_main
*nwrap_main_global
;
332 struct nwrap_main __nwrap_main_global
;
340 bool (*parse_line
)(struct nwrap_cache
*, char *line
);
341 void (*unload
)(struct nwrap_cache
*);
345 struct nwrap_cache
*cache
;
352 struct nwrap_cache __nwrap_cache_pw
;
353 struct nwrap_pw nwrap_pw_global
;
355 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
);
356 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
);
359 struct nwrap_cache
*cache
;
366 struct nwrap_cache __nwrap_cache_gr
;
367 struct nwrap_gr nwrap_gr_global
;
369 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
);
370 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
);
372 static void *nwrap_load_module_fn(struct nwrap_backend
*b
,
379 NWRAP_ERROR(("%s: no handle\n",
384 if (asprintf(&s
, "_nss_%s_%s", b
->name
, fn_name
) == -1) {
385 NWRAP_ERROR(("%s: out of memory\n",
390 res
= dlsym(b
->so_handle
, s
);
392 NWRAP_ERROR(("%s: cannot find function %s in %s\n",
393 __location__
, s
, b
->so_path
));
400 static struct nwrap_module_nss_fns
*nwrap_load_module_fns(struct nwrap_backend
*b
)
402 struct nwrap_module_nss_fns
*fns
;
408 fns
= (struct nwrap_module_nss_fns
*)malloc(sizeof(struct nwrap_module_nss_fns
));
413 fns
->_nss_getpwnam_r
= (NSS_STATUS (*)(const char *, struct passwd
*, char *, size_t, int *))
414 nwrap_load_module_fn(b
, "getpwnam_r");
415 fns
->_nss_getpwuid_r
= (NSS_STATUS (*)(uid_t
, struct passwd
*, char *, size_t, int *))
416 nwrap_load_module_fn(b
, "getpwuid_r");
417 fns
->_nss_setpwent
= (NSS_STATUS(*)(void))
418 nwrap_load_module_fn(b
, "setpwent");
419 fns
->_nss_getpwent_r
= (NSS_STATUS (*)(struct passwd
*, char *, size_t, int *))
420 nwrap_load_module_fn(b
, "getpwent_r");
421 fns
->_nss_endpwent
= (NSS_STATUS(*)(void))
422 nwrap_load_module_fn(b
, "endpwent");
423 fns
->_nss_initgroups
= (NSS_STATUS (*)(const char *, gid_t
, long int *, long int *, gid_t
**, long int, int *))
424 nwrap_load_module_fn(b
, "initgroups_dyn");
425 fns
->_nss_getgrnam_r
= (NSS_STATUS (*)(const char *, struct group
*, char *, size_t, int *))
426 nwrap_load_module_fn(b
, "getgrnam_r");
427 fns
->_nss_getgrgid_r
= (NSS_STATUS (*)(gid_t
, struct group
*, char *, size_t, int *))
428 nwrap_load_module_fn(b
, "getgrgid_r");
429 fns
->_nss_setgrent
= (NSS_STATUS(*)(void))
430 nwrap_load_module_fn(b
, "setgrent");
431 fns
->_nss_getgrent_r
= (NSS_STATUS (*)(struct group
*, char *, size_t, int *))
432 nwrap_load_module_fn(b
, "getgrent_r");
433 fns
->_nss_endgrent
= (NSS_STATUS(*)(void))
434 nwrap_load_module_fn(b
, "endgrent");
439 static void *nwrap_load_module(const char *so_path
)
443 if (!so_path
|| !strlen(so_path
)) {
447 h
= dlopen(so_path
, RTLD_LAZY
);
449 NWRAP_ERROR(("%s: cannot open shared library %s\n",
450 __location__
, so_path
));
457 static bool nwrap_module_init(const char *name
,
458 struct nwrap_ops
*ops
,
461 struct nwrap_backend
**backends
)
463 *backends
= (struct nwrap_backend
*)realloc(*backends
,
464 sizeof(struct nwrap_backend
) * ((*num_backends
) + 1));
466 NWRAP_ERROR(("%s: out of memory\n",
471 (*backends
)[*num_backends
].name
= name
;
472 (*backends
)[*num_backends
].ops
= ops
;
473 (*backends
)[*num_backends
].so_path
= so_path
;
474 (*backends
)[*num_backends
].so_handle
= nwrap_load_module(so_path
);
475 (*backends
)[*num_backends
].fns
= nwrap_load_module_fns(&((*backends
)[*num_backends
]));
482 static void nwrap_backend_init(struct nwrap_main
*r
)
484 const char *winbind_so_path
= getenv("NSS_WRAPPER_WINBIND_SO_PATH");
489 if (!nwrap_module_init("files", &nwrap_files_ops
, NULL
,
492 NWRAP_ERROR(("%s: failed to initialize 'files' backend\n",
497 if (winbind_so_path
&& strlen(winbind_so_path
)) {
498 if (!nwrap_module_init("winbind", &nwrap_module_ops
, winbind_so_path
,
501 NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n",
508 static void nwrap_init(void)
510 static bool initialized
;
512 if (initialized
) return;
515 nwrap_main_global
= &__nwrap_main_global
;
517 nwrap_backend_init(nwrap_main_global
);
519 nwrap_pw_global
.cache
= &__nwrap_cache_pw
;
521 nwrap_pw_global
.cache
->path
= getenv("NSS_WRAPPER_PASSWD");
522 nwrap_pw_global
.cache
->fd
= -1;
523 nwrap_pw_global
.cache
->private_data
= &nwrap_pw_global
;
524 nwrap_pw_global
.cache
->parse_line
= nwrap_pw_parse_line
;
525 nwrap_pw_global
.cache
->unload
= nwrap_pw_unload
;
527 nwrap_gr_global
.cache
= &__nwrap_cache_gr
;
529 nwrap_gr_global
.cache
->path
= getenv("NSS_WRAPPER_GROUP");
530 nwrap_gr_global
.cache
->fd
= -1;
531 nwrap_gr_global
.cache
->private_data
= &nwrap_gr_global
;
532 nwrap_gr_global
.cache
->parse_line
= nwrap_gr_parse_line
;
533 nwrap_gr_global
.cache
->unload
= nwrap_gr_unload
;
536 static bool nwrap_enabled(void)
540 if (!nwrap_pw_global
.cache
->path
) {
543 if (nwrap_pw_global
.cache
->path
[0] == '\0') {
546 if (!nwrap_gr_global
.cache
->path
) {
549 if (nwrap_gr_global
.cache
->path
[0] == '\0') {
556 static bool nwrap_parse_file(struct nwrap_cache
*nwrap
)
562 if (nwrap
->st
.st_size
== 0) {
563 NWRAP_DEBUG(("%s: size == 0\n",
568 if (nwrap
->st
.st_size
> INT32_MAX
) {
569 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
570 __location__
, (unsigned)nwrap
->st
.st_size
));
574 ret
= lseek(nwrap
->fd
, 0, SEEK_SET
);
576 NWRAP_ERROR(("%s: lseek - %d\n",__location__
,ret
));
580 buf
= (uint8_t *)malloc(nwrap
->st
.st_size
+ 1);
582 NWRAP_ERROR(("%s: malloc failed\n",__location__
));
586 ret
= read(nwrap
->fd
, buf
, nwrap
->st
.st_size
);
587 if (ret
!= nwrap
->st
.st_size
) {
588 NWRAP_ERROR(("%s: read(%u) gave %d\n",
589 __location__
, (unsigned)nwrap
->st
.st_size
, ret
));
593 buf
[nwrap
->st
.st_size
] = '\0';
596 while (nline
&& nline
[0]) {
604 e
= strchr(line
, '\n');
615 NWRAP_VERBOSE(("%s:'%s'\n",__location__
, line
));
617 if (strlen(line
) == 0) {
621 ok
= nwrap
->parse_line(nwrap
, line
);
636 static void nwrap_files_cache_unload(struct nwrap_cache
*nwrap
)
638 nwrap
->unload(nwrap
);
640 if (nwrap
->buf
) free(nwrap
->buf
);
645 static void nwrap_files_cache_reload(struct nwrap_cache
*nwrap
)
650 bool retried
= false;
654 nwrap
->fd
= open(nwrap
->path
, O_RDONLY
);
656 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
658 nwrap
->path
, nwrap
->fd
,
662 NWRAP_VERBOSE(("%s: open '%s'\n", __location__
, nwrap
->path
));
665 ret
= fstat(nwrap
->fd
, &st
);
667 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
670 ret
, strerror(errno
)));
674 if (retried
== false && st
.st_nlink
== 0) {
675 /* maybe someone has replaced the file... */
676 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
677 __location__
, nwrap
->path
));
679 memset(&nwrap
->st
, 0, sizeof(nwrap
->st
));
685 if (st
.st_mtime
== nwrap
->st
.st_mtime
) {
686 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
687 __location__
, (unsigned)st
.st_mtime
));
690 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
691 __location__
, (unsigned)st
.st_mtime
,
692 (unsigned)nwrap
->st
.st_mtime
));
696 nwrap_files_cache_unload(nwrap
);
698 ok
= nwrap_parse_file(nwrap
);
700 NWRAP_ERROR(("%s: failed to reload %s\n",
701 __location__
, nwrap
->path
));
702 nwrap_files_cache_unload(nwrap
);
704 NWRAP_DEBUG(("%s: reloaded %s\n",
705 __location__
, nwrap
->path
));
709 * the caller has to call nwrap_unload() on failure
711 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
)
713 struct nwrap_pw
*nwrap_pw
;
720 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
722 list_size
= sizeof(*nwrap_pw
->list
) * (nwrap_pw
->num
+1);
723 pw
= (struct passwd
*)realloc(nwrap_pw
->list
, list_size
);
725 NWRAP_ERROR(("%s:realloc(%u) failed\n",
726 __location__
, list_size
));
731 pw
= &nwrap_pw
->list
[nwrap_pw
->num
];
738 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
739 __location__
, line
, c
));
747 NWRAP_VERBOSE(("name[%s]\n", pw
->pw_name
));
752 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
753 __location__
, line
, c
));
761 NWRAP_VERBOSE(("password[%s]\n", pw
->pw_passwd
));
766 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
767 __location__
, line
, c
));
773 pw
->pw_uid
= (uid_t
)strtoul(c
, &e
, 10);
775 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
776 __location__
, line
, c
, strerror(errno
)));
780 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
781 __location__
, line
, c
, strerror(errno
)));
785 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
786 __location__
, line
, c
, strerror(errno
)));
791 NWRAP_VERBOSE(("uid[%u]\n", pw
->pw_uid
));
796 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
797 __location__
, line
, c
));
803 pw
->pw_gid
= (gid_t
)strtoul(c
, &e
, 10);
805 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
806 __location__
, line
, c
, strerror(errno
)));
810 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
811 __location__
, line
, c
, strerror(errno
)));
815 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
816 __location__
, line
, c
, strerror(errno
)));
821 NWRAP_VERBOSE(("gid[%u]\n", pw
->pw_gid
));
826 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
827 __location__
, line
, c
));
835 NWRAP_VERBOSE(("gecos[%s]\n", pw
->pw_gecos
));
840 NWRAP_ERROR(("%s:'%s'\n",__location__
,c
));
848 NWRAP_VERBOSE(("dir[%s]\n", pw
->pw_dir
));
852 NWRAP_VERBOSE(("shell[%s]\n", pw
->pw_shell
));
854 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
855 pw
->pw_name
, pw
->pw_passwd
,
856 pw
->pw_uid
, pw
->pw_gid
,
857 pw
->pw_gecos
, pw
->pw_dir
, pw
->pw_shell
));
863 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
)
865 struct nwrap_pw
*nwrap_pw
;
866 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
868 if (nwrap_pw
->list
) free(nwrap_pw
->list
);
870 nwrap_pw
->list
= NULL
;
875 static int nwrap_pw_copy_r(const struct passwd
*src
, struct passwd
*dst
,
876 char *buf
, size_t buflen
, struct passwd
**dstp
)
882 first
= src
->pw_name
;
884 last
= src
->pw_shell
;
885 while (*last
) last
++;
887 ofs
= PTR_DIFF(last
+ 1, first
);
893 memcpy(buf
, first
, ofs
);
895 ofs
= PTR_DIFF(src
->pw_name
, first
);
896 dst
->pw_name
= buf
+ ofs
;
897 ofs
= PTR_DIFF(src
->pw_passwd
, first
);
898 dst
->pw_passwd
= buf
+ ofs
;
899 dst
->pw_uid
= src
->pw_uid
;
900 dst
->pw_gid
= src
->pw_gid
;
901 ofs
= PTR_DIFF(src
->pw_gecos
, first
);
902 dst
->pw_gecos
= buf
+ ofs
;
903 ofs
= PTR_DIFF(src
->pw_dir
, first
);
904 dst
->pw_dir
= buf
+ ofs
;
905 ofs
= PTR_DIFF(src
->pw_shell
, first
);
906 dst
->pw_shell
= buf
+ ofs
;
916 * the caller has to call nwrap_unload() on failure
918 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
)
920 struct nwrap_gr
*nwrap_gr
;
928 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
930 list_size
= sizeof(*nwrap_gr
->list
) * (nwrap_gr
->num
+1);
931 gr
= (struct group
*)realloc(nwrap_gr
->list
, list_size
);
933 NWRAP_ERROR(("%s:realloc failed\n",__location__
));
938 gr
= &nwrap_gr
->list
[nwrap_gr
->num
];
945 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
946 __location__
, line
, c
));
954 NWRAP_VERBOSE(("name[%s]\n", gr
->gr_name
));
959 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
960 __location__
, line
, c
));
968 NWRAP_VERBOSE(("password[%s]\n", gr
->gr_passwd
));
973 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
974 __location__
, line
, c
));
980 gr
->gr_gid
= (gid_t
)strtoul(c
, &e
, 10);
982 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
983 __location__
, line
, c
, strerror(errno
)));
987 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
988 __location__
, line
, c
, strerror(errno
)));
992 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
993 __location__
, line
, c
, strerror(errno
)));
998 NWRAP_VERBOSE(("gid[%u]\n", gr
->gr_gid
));
1001 gr
->gr_mem
= (char **)malloc(sizeof(char *));
1003 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
1006 gr
->gr_mem
[0] = NULL
;
1008 for(nummem
=0; p
; nummem
++) {
1018 if (strlen(c
) == 0) {
1022 m_size
= sizeof(char *) * (nummem
+2);
1023 m
= (char **)realloc(gr
->gr_mem
, m_size
);
1025 NWRAP_ERROR(("%s:realloc(%u) failed\n",
1026 __location__
, m_size
));
1030 gr
->gr_mem
[nummem
] = c
;
1031 gr
->gr_mem
[nummem
+1] = NULL
;
1033 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem
, gr
->gr_mem
[nummem
]));
1036 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
1037 gr
->gr_name
, gr
->gr_passwd
, gr
->gr_gid
, nummem
));
1043 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
)
1046 struct nwrap_gr
*nwrap_gr
;
1047 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
1049 if (nwrap_gr
->list
) {
1050 for (i
=0; i
< nwrap_gr
->num
; i
++) {
1051 if (nwrap_gr
->list
[i
].gr_mem
) {
1052 free(nwrap_gr
->list
[i
].gr_mem
);
1055 free(nwrap_gr
->list
);
1058 nwrap_gr
->list
= NULL
;
1063 static int nwrap_gr_copy_r(const struct group
*src
, struct group
*dst
,
1064 char *buf
, size_t buflen
, struct group
**dstp
)
1074 first
= src
->gr_name
;
1076 lastm
= src
->gr_mem
;
1083 last
= src
->gr_passwd
;
1085 while (*last
) last
++;
1087 ofsb
= PTR_DIFF(last
+ 1, first
);
1088 ofsm
= PTR_DIFF(lastm
+ 1, src
->gr_mem
);
1090 if ((ofsb
+ ofsm
) > buflen
) {
1094 memcpy(buf
, first
, ofsb
);
1095 memcpy(buf
+ ofsb
, src
->gr_mem
, ofsm
);
1097 ofs
= PTR_DIFF(src
->gr_name
, first
);
1098 dst
->gr_name
= buf
+ ofs
;
1099 ofs
= PTR_DIFF(src
->gr_passwd
, first
);
1100 dst
->gr_passwd
= buf
+ ofs
;
1101 dst
->gr_gid
= src
->gr_gid
;
1103 dst
->gr_mem
= (char **)(buf
+ ofsb
);
1104 for (i
=0; src
->gr_mem
[i
]; i
++) {
1105 ofs
= PTR_DIFF(src
->gr_mem
[i
], first
);
1106 dst
->gr_mem
[i
] = buf
+ ofs
;
1116 /* user functions */
1117 static struct passwd
*nwrap_files_getpwnam(struct nwrap_backend
*b
,
1122 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1124 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1125 if (strcmp(nwrap_pw_global
.list
[i
].pw_name
, name
) == 0) {
1126 NWRAP_DEBUG(("%s: user[%s] found\n",
1127 __location__
, name
));
1128 return &nwrap_pw_global
.list
[i
];
1130 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
1132 nwrap_pw_global
.list
[i
].pw_name
));
1135 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__
, name
));
1141 static int nwrap_files_getpwnam_r(struct nwrap_backend
*b
,
1142 const char *name
, struct passwd
*pwdst
,
1143 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1147 pw
= nwrap_files_getpwnam(b
, name
);
1155 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1158 static struct passwd
*nwrap_files_getpwuid(struct nwrap_backend
*b
,
1163 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1165 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
1166 if (nwrap_pw_global
.list
[i
].pw_uid
== uid
) {
1167 NWRAP_DEBUG(("%s: uid[%u] found\n",
1168 __location__
, uid
));
1169 return &nwrap_pw_global
.list
[i
];
1171 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
1173 nwrap_pw_global
.list
[i
].pw_uid
));
1176 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__
, uid
));
1182 static int nwrap_files_getpwuid_r(struct nwrap_backend
*b
,
1183 uid_t uid
, struct passwd
*pwdst
,
1184 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1188 pw
= nwrap_files_getpwuid(b
, uid
);
1196 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1199 /* user enum functions */
1200 static void nwrap_files_setpwent(struct nwrap_backend
*b
)
1202 nwrap_pw_global
.idx
= 0;
1205 static struct passwd
*nwrap_files_getpwent(struct nwrap_backend
*b
)
1209 if (nwrap_pw_global
.idx
== 0) {
1210 nwrap_files_cache_reload(nwrap_pw_global
.cache
);
1213 if (nwrap_pw_global
.idx
>= nwrap_pw_global
.num
) {
1218 pw
= &nwrap_pw_global
.list
[nwrap_pw_global
.idx
++];
1220 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
1221 __location__
, pw
->pw_name
, pw
->pw_uid
));
1226 static int nwrap_files_getpwent_r(struct nwrap_backend
*b
,
1227 struct passwd
*pwdst
, char *buf
,
1228 size_t buflen
, struct passwd
**pwdstp
)
1232 pw
= nwrap_files_getpwent(b
);
1240 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
1243 static void nwrap_files_endpwent(struct nwrap_backend
*b
)
1245 nwrap_pw_global
.idx
= 0;
1248 /* misc functions */
1249 static int nwrap_files_initgroups(struct nwrap_backend
*b
,
1250 const char *user
, gid_t group
)
1252 /* TODO: maybe we should also fake this... */
1256 /* group functions */
1257 static struct group
*nwrap_files_getgrnam(struct nwrap_backend
*b
,
1262 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1264 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1265 if (strcmp(nwrap_gr_global
.list
[i
].gr_name
, name
) == 0) {
1266 NWRAP_DEBUG(("%s: group[%s] found\n",
1267 __location__
, name
));
1268 return &nwrap_gr_global
.list
[i
];
1270 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1272 nwrap_gr_global
.list
[i
].gr_name
));
1275 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__
, name
));
1281 static int nwrap_files_getgrnam_r(struct nwrap_backend
*b
,
1282 const char *name
, struct group
*grdst
,
1283 char *buf
, size_t buflen
, struct group
**grdstp
)
1287 gr
= nwrap_files_getgrnam(b
, name
);
1295 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1298 static struct group
*nwrap_files_getgrgid(struct nwrap_backend
*b
,
1303 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1305 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1306 if (nwrap_gr_global
.list
[i
].gr_gid
== gid
) {
1307 NWRAP_DEBUG(("%s: gid[%u] found\n",
1308 __location__
, gid
));
1309 return &nwrap_gr_global
.list
[i
];
1311 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1313 nwrap_gr_global
.list
[i
].gr_gid
));
1316 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__
, gid
));
1322 static int nwrap_files_getgrgid_r(struct nwrap_backend
*b
,
1323 gid_t gid
, struct group
*grdst
,
1324 char *buf
, size_t buflen
, struct group
**grdstp
)
1328 gr
= nwrap_files_getgrgid(b
, gid
);
1336 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1339 /* group enum functions */
1340 static void nwrap_files_setgrent(struct nwrap_backend
*b
)
1342 nwrap_gr_global
.idx
= 0;
1345 static struct group
*nwrap_files_getgrent(struct nwrap_backend
*b
)
1349 if (nwrap_gr_global
.idx
== 0) {
1350 nwrap_files_cache_reload(nwrap_gr_global
.cache
);
1353 if (nwrap_gr_global
.idx
>= nwrap_gr_global
.num
) {
1358 gr
= &nwrap_gr_global
.list
[nwrap_gr_global
.idx
++];
1360 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1361 __location__
, gr
->gr_name
, gr
->gr_gid
));
1366 static int nwrap_files_getgrent_r(struct nwrap_backend
*b
,
1367 struct group
*grdst
, char *buf
,
1368 size_t buflen
, struct group
**grdstp
)
1372 gr
= nwrap_files_getgrent(b
);
1380 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1383 static void nwrap_files_endgrent(struct nwrap_backend
*b
)
1385 nwrap_gr_global
.idx
= 0;
1393 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
1396 static struct passwd
*nwrap_module_getpwnam(struct nwrap_backend
*b
,
1399 static struct passwd pwd
;
1400 static char buf
[1000];
1403 if (!b
->fns
->_nss_getpwnam_r
) {
1407 status
= b
->fns
->_nss_getpwnam_r(name
, &pwd
, buf
, sizeof(buf
), &errno
);
1408 if (status
== NSS_STATUS_NOTFOUND
) {
1411 if (status
!= NSS_STATUS_SUCCESS
) {
1417 static int nwrap_module_getpwnam_r(struct nwrap_backend
*b
,
1418 const char *name
, struct passwd
*pwdst
,
1419 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1423 if (!b
->fns
->_nss_getpwnam_r
) {
1424 return NSS_STATUS_NOTFOUND
;
1427 ret
= b
->fns
->_nss_getpwnam_r(name
, pwdst
, buf
, buflen
, &errno
);
1429 case NSS_STATUS_SUCCESS
:
1431 case NSS_STATUS_NOTFOUND
:
1436 case NSS_STATUS_TRYAGAIN
:
1449 static struct passwd
*nwrap_module_getpwuid(struct nwrap_backend
*b
,
1452 static struct passwd pwd
;
1453 static char buf
[1000];
1456 if (!b
->fns
->_nss_getpwuid_r
) {
1460 status
= b
->fns
->_nss_getpwuid_r(uid
, &pwd
, buf
, sizeof(buf
), &errno
);
1461 if (status
== NSS_STATUS_NOTFOUND
) {
1464 if (status
!= NSS_STATUS_SUCCESS
) {
1470 static int nwrap_module_getpwuid_r(struct nwrap_backend
*b
,
1471 uid_t uid
, struct passwd
*pwdst
,
1472 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1476 if (!b
->fns
->_nss_getpwuid_r
) {
1480 ret
= b
->fns
->_nss_getpwuid_r(uid
, pwdst
, buf
, buflen
, &errno
);
1482 case NSS_STATUS_SUCCESS
:
1484 case NSS_STATUS_NOTFOUND
:
1489 case NSS_STATUS_TRYAGAIN
:
1502 static void nwrap_module_setpwent(struct nwrap_backend
*b
)
1504 if (!b
->fns
->_nss_setpwent
) {
1508 b
->fns
->_nss_setpwent();
1511 static struct passwd
*nwrap_module_getpwent(struct nwrap_backend
*b
)
1513 static struct passwd pwd
;
1514 static char buf
[1000];
1517 if (!b
->fns
->_nss_getpwent_r
) {
1521 status
= b
->fns
->_nss_getpwent_r(&pwd
, buf
, sizeof(buf
), &errno
);
1522 if (status
== NSS_STATUS_NOTFOUND
) {
1525 if (status
!= NSS_STATUS_SUCCESS
) {
1531 static int nwrap_module_getpwent_r(struct nwrap_backend
*b
,
1532 struct passwd
*pwdst
, char *buf
,
1533 size_t buflen
, struct passwd
**pwdstp
)
1537 if (!b
->fns
->_nss_getpwent_r
) {
1541 ret
= b
->fns
->_nss_getpwent_r(pwdst
, buf
, buflen
, &errno
);
1543 case NSS_STATUS_SUCCESS
:
1545 case NSS_STATUS_NOTFOUND
:
1550 case NSS_STATUS_TRYAGAIN
:
1563 static void nwrap_module_endpwent(struct nwrap_backend
*b
)
1565 if (!b
->fns
->_nss_endpwent
) {
1569 b
->fns
->_nss_endpwent();
1572 static int nwrap_module_initgroups(struct nwrap_backend
*b
,
1573 const char *user
, gid_t group
)
1579 if (!b
->fns
->_nss_initgroups
) {
1580 return NSS_STATUS_UNAVAIL
;
1583 return b
->fns
->_nss_initgroups(user
, group
, &start
, &size
, &groups
, 0, &errno
);
1586 static struct group
*nwrap_module_getgrnam(struct nwrap_backend
*b
,
1589 static struct group grp
;
1591 static int buflen
= 1000;
1594 if (!b
->fns
->_nss_getgrnam_r
) {
1599 buf
= (char *)malloc(buflen
);
1602 status
= b
->fns
->_nss_getgrnam_r(name
, &grp
, buf
, buflen
, &errno
);
1603 if (status
== NSS_STATUS_TRYAGAIN
) {
1605 buf
= (char *)realloc(buf
, buflen
);
1611 if (status
== NSS_STATUS_NOTFOUND
) {
1615 if (status
!= NSS_STATUS_SUCCESS
) {
1622 static int nwrap_module_getgrnam_r(struct nwrap_backend
*b
,
1623 const char *name
, struct group
*grdst
,
1624 char *buf
, size_t buflen
, struct group
**grdstp
)
1628 if (!b
->fns
->_nss_getgrnam_r
) {
1632 ret
= b
->fns
->_nss_getgrnam_r(name
, grdst
, buf
, buflen
, &errno
);
1634 case NSS_STATUS_SUCCESS
:
1636 case NSS_STATUS_NOTFOUND
:
1641 case NSS_STATUS_TRYAGAIN
:
1654 static struct group
*nwrap_module_getgrgid(struct nwrap_backend
*b
,
1657 static struct group grp
;
1659 static int buflen
= 1000;
1662 if (!b
->fns
->_nss_getgrgid_r
) {
1667 buf
= (char *)malloc(buflen
);
1671 status
= b
->fns
->_nss_getgrgid_r(gid
, &grp
, buf
, buflen
, &errno
);
1672 if (status
== NSS_STATUS_TRYAGAIN
) {
1674 buf
= (char *)realloc(buf
, buflen
);
1680 if (status
== NSS_STATUS_NOTFOUND
) {
1684 if (status
!= NSS_STATUS_SUCCESS
) {
1691 static int nwrap_module_getgrgid_r(struct nwrap_backend
*b
,
1692 gid_t gid
, struct group
*grdst
,
1693 char *buf
, size_t buflen
, struct group
**grdstp
)
1697 if (!b
->fns
->_nss_getgrgid_r
) {
1701 ret
= b
->fns
->_nss_getgrgid_r(gid
, grdst
, buf
, buflen
, &errno
);
1703 case NSS_STATUS_SUCCESS
:
1705 case NSS_STATUS_NOTFOUND
:
1710 case NSS_STATUS_TRYAGAIN
:
1723 static void nwrap_module_setgrent(struct nwrap_backend
*b
)
1725 if (!b
->fns
->_nss_setgrent
) {
1729 b
->fns
->_nss_setgrent();
1732 static struct group
*nwrap_module_getgrent(struct nwrap_backend
*b
)
1734 static struct group grp
;
1736 static int buflen
= 1024;
1739 if (!b
->fns
->_nss_getgrent_r
) {
1744 buf
= (char *)malloc(buflen
);
1748 status
= b
->fns
->_nss_getgrent_r(&grp
, buf
, buflen
, &errno
);
1749 if (status
== NSS_STATUS_TRYAGAIN
) {
1751 buf
= (char *)realloc(buf
, buflen
);
1757 if (status
== NSS_STATUS_NOTFOUND
) {
1761 if (status
!= NSS_STATUS_SUCCESS
) {
1768 static int nwrap_module_getgrent_r(struct nwrap_backend
*b
,
1769 struct group
*grdst
, char *buf
,
1770 size_t buflen
, struct group
**grdstp
)
1774 if (!b
->fns
->_nss_getgrent_r
) {
1778 ret
= b
->fns
->_nss_getgrent_r(grdst
, buf
, buflen
, &errno
);
1780 case NSS_STATUS_SUCCESS
:
1782 case NSS_STATUS_NOTFOUND
:
1787 case NSS_STATUS_TRYAGAIN
:
1800 static void nwrap_module_endgrent(struct nwrap_backend
*b
)
1802 if (!b
->fns
->_nss_endgrent
) {
1806 b
->fns
->_nss_endgrent();
1813 _PUBLIC_
struct passwd
*nwrap_getpwnam(const char *name
)
1818 if (!nwrap_enabled()) {
1819 return real_getpwnam(name
);
1822 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1823 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1824 pwd
= b
->ops
->nw_getpwnam(b
, name
);
1833 _PUBLIC_
int nwrap_getpwnam_r(const char *name
, struct passwd
*pwdst
,
1834 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1838 if (!nwrap_enabled()) {
1839 return real_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
1842 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1843 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1844 ret
= b
->ops
->nw_getpwnam_r(b
, name
, pwdst
, buf
, buflen
, pwdstp
);
1845 if (ret
== ENOENT
) {
1854 _PUBLIC_
struct passwd
*nwrap_getpwuid(uid_t uid
)
1859 if (!nwrap_enabled()) {
1860 return real_getpwuid(uid
);
1863 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1864 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1865 pwd
= b
->ops
->nw_getpwuid(b
, uid
);
1874 _PUBLIC_
int nwrap_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
1875 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
1879 if (!nwrap_enabled()) {
1880 return real_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
1883 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1884 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1885 ret
= b
->ops
->nw_getpwuid_r(b
, uid
, pwdst
, buf
, buflen
, pwdstp
);
1886 if (ret
== ENOENT
) {
1895 _PUBLIC_
void nwrap_setpwent(void)
1899 if (!nwrap_enabled()) {
1904 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1905 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1906 b
->ops
->nw_setpwent(b
);
1910 _PUBLIC_
struct passwd
*nwrap_getpwent(void)
1915 if (!nwrap_enabled()) {
1916 return real_getpwent();
1919 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1920 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1921 pwd
= b
->ops
->nw_getpwent(b
);
1930 _PUBLIC_
int nwrap_getpwent_r(struct passwd
*pwdst
, char *buf
,
1931 size_t buflen
, struct passwd
**pwdstp
)
1935 if (!nwrap_enabled()) {
1936 #ifdef SOLARIS_GETPWENT_R
1938 pw
= real_getpwent_r(pwdst
, buf
, buflen
);
1950 return real_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
1954 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1955 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1956 ret
= b
->ops
->nw_getpwent_r(b
, pwdst
, buf
, buflen
, pwdstp
);
1957 if (ret
== ENOENT
) {
1966 _PUBLIC_
void nwrap_endpwent(void)
1970 if (!nwrap_enabled()) {
1975 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1976 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1977 b
->ops
->nw_endpwent(b
);
1981 _PUBLIC_
int nwrap_initgroups(const char *user
, gid_t group
)
1985 if (!nwrap_enabled()) {
1986 return real_initgroups(user
, group
);
1989 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
1990 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
1991 return b
->ops
->nw_initgroups(b
, user
, group
);
1998 _PUBLIC_
struct group
*nwrap_getgrnam(const char *name
)
2003 if (!nwrap_enabled()) {
2004 return real_getgrnam(name
);
2007 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2008 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2009 grp
= b
->ops
->nw_getgrnam(b
, name
);
2018 _PUBLIC_
int nwrap_getgrnam_r(const char *name
, struct group
*grdst
,
2019 char *buf
, size_t buflen
, struct group
**grdstp
)
2023 if (!nwrap_enabled()) {
2024 return real_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
2027 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2028 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2029 ret
= b
->ops
->nw_getgrnam_r(b
, name
, grdst
, buf
, buflen
, grdstp
);
2030 if (ret
== ENOENT
) {
2039 _PUBLIC_
struct group
*nwrap_getgrgid(gid_t gid
)
2044 if (!nwrap_enabled()) {
2045 return real_getgrgid(gid
);
2048 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2049 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2050 grp
= b
->ops
->nw_getgrgid(b
, gid
);
2059 _PUBLIC_
int nwrap_getgrgid_r(gid_t gid
, struct group
*grdst
,
2060 char *buf
, size_t buflen
, struct group
**grdstp
)
2064 if (!nwrap_enabled()) {
2065 return real_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
2068 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2069 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2070 ret
= b
->ops
->nw_getgrgid_r(b
, gid
, grdst
, buf
, buflen
, grdstp
);
2071 if (ret
== ENOENT
) {
2080 _PUBLIC_
void nwrap_setgrent(void)
2084 if (!nwrap_enabled()) {
2089 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2090 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2091 b
->ops
->nw_setgrent(b
);
2095 _PUBLIC_
struct group
*nwrap_getgrent(void)
2100 if (!nwrap_enabled()) {
2101 return real_getgrent();
2104 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2105 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2106 grp
= b
->ops
->nw_getgrent(b
);
2115 _PUBLIC_
int nwrap_getgrent_r(struct group
*grdst
, char *buf
,
2116 size_t buflen
, struct group
**grdstp
)
2120 if (!nwrap_enabled()) {
2121 #ifdef SOLARIS_GETGRENT_R
2123 gr
= real_getgrent_r(grdst
, buf
, buflen
);
2135 return real_getgrent_r(grdst
, buf
, buflen
, grdstp
);
2139 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2140 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2141 ret
= b
->ops
->nw_getgrent_r(b
, grdst
, buf
, buflen
, grdstp
);
2142 if (ret
== ENOENT
) {
2151 _PUBLIC_
void nwrap_endgrent(void)
2155 if (!nwrap_enabled()) {
2160 for (i
=0; i
< nwrap_main_global
->num_backends
; i
++) {
2161 struct nwrap_backend
*b
= &nwrap_main_global
->backends
[i
];
2162 b
->ops
->nw_endgrent(b
);
2166 _PUBLIC_
int nwrap_getgrouplist(const char *user
, gid_t group
, gid_t
*groups
, int *ngroups
)
2171 const char *name_of_group
= NULL
;
2173 if (!nwrap_enabled()) {
2174 return real_getgrouplist(user
, group
, groups
, ngroups
);
2177 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__
, user
));
2179 groups_tmp
= (gid_t
*)malloc(count
* sizeof(gid_t
));
2181 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2186 memcpy(groups_tmp
, &group
, sizeof(gid_t
));
2188 grp
= nwrap_getgrgid(group
);
2190 name_of_group
= grp
->gr_name
;
2194 while ((grp
= nwrap_getgrent()) != NULL
) {
2197 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
2198 __location__
, grp
->gr_name
));
2200 for (i
=0; grp
->gr_mem
&& grp
->gr_mem
[i
] != NULL
; i
++) {
2202 if ((strcmp(user
, grp
->gr_mem
[i
]) == 0) &&
2203 (strcmp(name_of_group
, grp
->gr_name
) != 0)) {
2205 NWRAP_DEBUG(("%s: %s is member of %s\n",
2206 __location__
, user
, grp
->gr_name
));
2208 groups_tmp
= (gid_t
*)realloc(groups_tmp
, (count
+ 1) * sizeof(gid_t
));
2210 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
2215 memcpy(&groups_tmp
[count
], &grp
->gr_gid
, sizeof(gid_t
));
2223 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
2224 __location__
, user
, *ngroups
));
2226 if (*ngroups
< count
) {
2233 memcpy(groups
, groups_tmp
, count
* sizeof(gid_t
));