2 * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #define NSS_WRAPPER_NOT_REPLACE
37 #include "../replace/replace.h"
38 #include "system/passwd.h"
39 #include "system/filesys.h"
41 #else /* _SAMBA_BUILD_ */
43 #error nss_wrapper_only_supported_in_samba_yet
51 /* not all systems have _r functions... */
52 #ifndef HAVE_GETPWNAM_R
53 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS
55 #ifndef HAVE_GETPWUID_R
56 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS
58 #ifndef HAVE_GETPWENT_R
59 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS
61 #ifndef HAVE_GETGRNAM_R
62 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS
64 #ifndef HAVE_GETGRUID_R
65 #define getgrgid_r(uid, grdst, buf, buflen, grdstp) ENOSYS
67 #ifndef HAVE_GETGRENT_R
68 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
71 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
77 #define real_getpwnam getpwnam
78 #define real_getpwnam_r getpwnam_r
79 #define real_getpwuid getpwuid
80 #define real_getpwuid_r getpwuid_r
82 #define real_setpwent setpwent
83 #define real_getpwent getpwent
84 #define real_getpwent_r getpwent_r
85 #define real_endpwent endpwent
88 #define real_getgrlst getgrlst
89 #define real_getgrlst_r getgrlst_r
90 #define real_initgroups_dyn initgroups_dyn
92 #define real_initgroups initgroups
94 #define real_getgrnam getgrnam
95 #define real_getgrnam_r getgrnam_r
96 #define real_getgrgid getgrgid
97 #define real_getgrgid_r getgrgid_r
99 #define real_setgrent setgrent
100 #define real_getgrent getgrent
101 #define real_getgrent_r getgrent_r
102 #define real_endgrent endgrent
108 # define NWRAP_ERROR(args) DEBUG(0, args)
110 # define NWRAP_ERROR(args) printf args
113 #define NWRAP_ERROR(args)
118 # define NWRAP_DEBUG(args) DEBUG(0, args)
120 # define NWRAP_DEBUG(args) printf args
123 #define NWRAP_DEBUG(args)
128 # define NWRAP_VERBOSE(args) DEBUG(0, args)
130 # define NWRAP_VERBOSE(args) printf args
133 #define NWRAP_VERBOSE(args)
142 bool (*parse_line
)(struct nwrap_cache
*, char *line
);
143 void (*unload
)(struct nwrap_cache
*);
147 struct nwrap_cache
*cache
;
154 struct nwrap_cache __nwrap_cache_pw
;
155 struct nwrap_pw nwrap_pw_global
;
157 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
);
158 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
);
161 struct nwrap_cache
*cache
;
168 struct nwrap_cache __nwrap_cache_gr
;
169 struct nwrap_gr nwrap_gr_global
;
171 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
);
172 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
);
174 static void nwrap_init(void)
176 static bool initialized
;
178 if (initialized
) return;
181 nwrap_pw_global
.cache
= &__nwrap_cache_pw
;
183 nwrap_pw_global
.cache
->path
= getenv("NSS_WRAPPER_PASSWD");
184 nwrap_pw_global
.cache
->fd
= -1;
185 nwrap_pw_global
.cache
->private_data
= &nwrap_pw_global
;
186 nwrap_pw_global
.cache
->parse_line
= nwrap_pw_parse_line
;
187 nwrap_pw_global
.cache
->unload
= nwrap_pw_unload
;
189 nwrap_gr_global
.cache
= &__nwrap_cache_gr
;
191 nwrap_gr_global
.cache
->path
= getenv("NSS_WRAPPER_GROUP");
192 nwrap_gr_global
.cache
->fd
= -1;
193 nwrap_gr_global
.cache
->private_data
= &nwrap_gr_global
;
194 nwrap_gr_global
.cache
->parse_line
= nwrap_gr_parse_line
;
195 nwrap_gr_global
.cache
->unload
= nwrap_gr_unload
;
198 static bool nwrap_enabled(void)
202 if (!nwrap_pw_global
.cache
->path
) {
205 if (nwrap_pw_global
.cache
->path
[0] == '\0') {
208 if (!nwrap_gr_global
.cache
->path
) {
211 if (nwrap_gr_global
.cache
->path
[0] == '\0') {
218 static bool nwrap_parse_file(struct nwrap_cache
*nwrap
)
224 if (nwrap
->st
.st_size
== 0) {
225 NWRAP_DEBUG(("%s: size == 0\n",
230 if (nwrap
->st
.st_size
> INT32_MAX
) {
231 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
232 __location__
, (unsigned)nwrap
->st
.st_size
));
236 ret
= lseek(nwrap
->fd
, 0, SEEK_SET
);
238 NWRAP_ERROR(("%s: lseek - %d\n",__location__
,ret
));
242 buf
= (uint8_t *)malloc(nwrap
->st
.st_size
+ 1);
244 NWRAP_ERROR(("%s: malloc failed\n",__location__
));
248 ret
= read(nwrap
->fd
, buf
, nwrap
->st
.st_size
);
249 if (ret
!= nwrap
->st
.st_size
) {
250 NWRAP_ERROR(("%s: read(%u) gave %d\n",
251 __location__
, (unsigned)nwrap
->st
.st_size
, ret
));
255 buf
[nwrap
->st
.st_size
] = '\0';
258 while (nline
&& nline
[0]) {
266 e
= strchr(line
, '\n');
277 NWRAP_VERBOSE(("%s:'%s'\n",__location__
, line
));
279 if (strlen(line
) == 0) {
283 ok
= nwrap
->parse_line(nwrap
, line
);
298 static void nwrap_cache_unload(struct nwrap_cache
*nwrap
)
300 nwrap
->unload(nwrap
);
302 if (nwrap
->buf
) free(nwrap
->buf
);
307 static void nwrap_cache_reload(struct nwrap_cache
*nwrap
)
312 bool retried
= false;
316 nwrap
->fd
= open(nwrap
->path
, O_RDONLY
);
318 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
320 nwrap
->path
, nwrap
->fd
,
324 NWRAP_VERBOSE(("%s: open '%s'\n", __location__
, nwrap
->path
));
327 ret
= fstat(nwrap
->fd
, &st
);
329 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
332 ret
, strerror(errno
)));
336 if (retried
== false && st
.st_nlink
== 0) {
337 /* maybe someone has replaced the file... */
338 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
339 __location__
, nwrap
->path
));
341 memset(&nwrap
->st
, 0, sizeof(nwrap
->st
));
347 if (st
.st_mtime
== nwrap
->st
.st_mtime
) {
348 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
349 __location__
, (unsigned)st
.st_mtime
));
352 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
353 __location__
, (unsigned)st
.st_mtime
,
354 (unsigned)nwrap
->st
.st_mtime
));
358 nwrap_cache_unload(nwrap
);
360 ok
= nwrap_parse_file(nwrap
);
362 NWRAP_ERROR(("%s: failed to reload %s\n",
363 __location__
, nwrap
->path
));
364 nwrap_cache_unload(nwrap
);
366 NWRAP_DEBUG(("%s: reloaded %s\n",
367 __location__
, nwrap
->path
));
371 * the caller has to call nwrap_unload() on failure
373 static bool nwrap_pw_parse_line(struct nwrap_cache
*nwrap
, char *line
)
375 struct nwrap_pw
*nwrap_pw
;
382 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
384 list_size
= sizeof(*nwrap_pw
->list
) * (nwrap_pw
->num
+1);
385 pw
= (struct passwd
*)realloc(nwrap_pw
->list
, list_size
);
387 NWRAP_ERROR(("%s:realloc(%u) failed\n",
388 __location__
, list_size
));
393 pw
= &nwrap_pw
->list
[nwrap_pw
->num
];
400 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
401 __location__
, line
, c
));
409 NWRAP_VERBOSE(("name[%s]\n", pw
->pw_name
));
414 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
415 __location__
, line
, c
));
423 NWRAP_VERBOSE(("password[%s]\n", pw
->pw_passwd
));
428 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
429 __location__
, line
, c
));
435 pw
->pw_uid
= (uid_t
)strtoul(c
, &e
, 10);
437 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
438 __location__
, line
, c
, strerror(errno
)));
442 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
443 __location__
, line
, c
, strerror(errno
)));
447 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
448 __location__
, line
, c
, strerror(errno
)));
453 NWRAP_VERBOSE(("uid[%u]\n", pw
->pw_uid
));
458 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
459 __location__
, line
, c
));
465 pw
->pw_gid
= (gid_t
)strtoul(c
, &e
, 10);
467 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
468 __location__
, line
, c
, strerror(errno
)));
472 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
473 __location__
, line
, c
, strerror(errno
)));
477 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
478 __location__
, line
, c
, strerror(errno
)));
483 NWRAP_VERBOSE(("gid[%u]\n", pw
->pw_gid
));
488 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
489 __location__
, line
, c
));
497 NWRAP_VERBOSE(("gecos[%s]\n", pw
->pw_gecos
));
502 NWRAP_ERROR(("%s:'%s'\n",__location__
,c
));
510 NWRAP_VERBOSE(("dir[%s]\n", pw
->pw_dir
));
514 NWRAP_VERBOSE(("shell[%s]\n", pw
->pw_shell
));
516 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
517 pw
->pw_name
, pw
->pw_passwd
,
518 pw
->pw_uid
, pw
->pw_gid
,
519 pw
->pw_gecos
, pw
->pw_dir
, pw
->pw_shell
));
525 static void nwrap_pw_unload(struct nwrap_cache
*nwrap
)
527 struct nwrap_pw
*nwrap_pw
;
528 nwrap_pw
= (struct nwrap_pw
*)nwrap
->private_data
;
530 if (nwrap_pw
->list
) free(nwrap_pw
->list
);
532 nwrap_pw
->list
= NULL
;
537 static int nwrap_pw_copy_r(const struct passwd
*src
, struct passwd
*dst
,
538 char *buf
, size_t buflen
, struct passwd
**dstp
)
544 first
= src
->pw_name
;
546 last
= src
->pw_shell
;
547 while (*last
) last
++;
549 ofs
= PTR_DIFF(last
+ 1, first
);
555 memcpy(buf
, first
, ofs
);
557 ofs
= PTR_DIFF(src
->pw_name
, first
);
558 dst
->pw_name
= buf
+ ofs
;
559 ofs
= PTR_DIFF(src
->pw_passwd
, first
);
560 dst
->pw_passwd
= buf
+ ofs
;
561 dst
->pw_uid
= src
->pw_uid
;
562 dst
->pw_gid
= src
->pw_gid
;
563 ofs
= PTR_DIFF(src
->pw_gecos
, first
);
564 dst
->pw_gecos
= buf
+ ofs
;
565 ofs
= PTR_DIFF(src
->pw_dir
, first
);
566 dst
->pw_dir
= buf
+ ofs
;
567 ofs
= PTR_DIFF(src
->pw_shell
, first
);
568 dst
->pw_shell
= buf
+ ofs
;
578 * the caller has to call nwrap_unload() on failure
580 static bool nwrap_gr_parse_line(struct nwrap_cache
*nwrap
, char *line
)
582 struct nwrap_gr
*nwrap_gr
;
590 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
592 list_size
= sizeof(*nwrap_gr
->list
) * (nwrap_gr
->num
+1);
593 gr
= (struct group
*)realloc(nwrap_gr
->list
, list_size
);
595 NWRAP_ERROR(("%s:realloc failed\n",__location__
));
600 gr
= &nwrap_gr
->list
[nwrap_gr
->num
];
607 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
608 __location__
, line
, c
));
616 NWRAP_VERBOSE(("name[%s]\n", gr
->gr_name
));
621 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
622 __location__
, line
, c
));
630 NWRAP_VERBOSE(("password[%s]\n", gr
->gr_passwd
));
635 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
636 __location__
, line
, c
));
642 gr
->gr_gid
= (gid_t
)strtoul(c
, &e
, 10);
644 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
645 __location__
, line
, c
, strerror(errno
)));
649 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
650 __location__
, line
, c
, strerror(errno
)));
654 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
655 __location__
, line
, c
, strerror(errno
)));
660 NWRAP_VERBOSE(("gid[%u]\n", gr
->gr_gid
));
663 gr
->gr_mem
= (char **)malloc(sizeof(char *));
665 NWRAP_ERROR(("%s:calloc failed\n",__location__
));
668 gr
->gr_mem
[0] = NULL
;
670 for(nummem
=0; p
; nummem
++) {
680 if (strlen(c
) == 0) {
684 m_size
= sizeof(char *) * (nummem
+2);
685 m
= (char **)realloc(gr
->gr_mem
, m_size
);
687 NWRAP_ERROR(("%s:realloc(%u) failed\n",
688 __location__
, m_size
));
692 gr
->gr_mem
[nummem
] = c
;
693 gr
->gr_mem
[nummem
+1] = NULL
;
695 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem
, gr
->gr_mem
[nummem
]));
698 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
699 gr
->gr_name
, gr
->gr_passwd
, gr
->gr_gid
, nummem
));
705 static void nwrap_gr_unload(struct nwrap_cache
*nwrap
)
708 struct nwrap_gr
*nwrap_gr
;
709 nwrap_gr
= (struct nwrap_gr
*)nwrap
->private_data
;
711 if (nwrap_gr
->list
) {
712 for (i
=0; i
< nwrap_gr
->num
; i
++) {
713 if (nwrap_gr
->list
[i
].gr_mem
) {
714 free(nwrap_gr
->list
[i
].gr_mem
);
717 free(nwrap_gr
->list
);
720 nwrap_gr
->list
= NULL
;
725 static int nwrap_gr_copy_r(const struct group
*src
, struct group
*dst
,
726 char *buf
, size_t buflen
, struct group
**dstp
)
736 first
= src
->gr_name
;
739 while (*lastm
) lastm
++;
742 while (*last
) last
++;
744 ofsb
= PTR_DIFF(last
+ 1, first
);
745 ofsm
= PTR_DIFF(lastm
+ 1, src
->gr_mem
);
747 if ((ofsb
+ ofsm
) > buflen
) {
751 memcpy(buf
, first
, ofsb
);
752 memcpy(buf
+ ofsb
, src
->gr_mem
, ofsm
);
754 ofs
= PTR_DIFF(src
->gr_name
, first
);
755 dst
->gr_name
= buf
+ ofs
;
756 ofs
= PTR_DIFF(src
->gr_passwd
, first
);
757 dst
->gr_passwd
= buf
+ ofs
;
758 dst
->gr_gid
= src
->gr_gid
;
760 dst
->gr_mem
= (char **)(buf
+ ofsb
);
761 for (i
=0; src
->gr_mem
[i
]; i
++) {
762 ofs
= PTR_DIFF(src
->gr_mem
[i
], first
);
763 dst
->gr_mem
[i
] = buf
+ ofs
;
775 static struct passwd
*nwrap_files_getpwnam(const char *name
)
779 nwrap_cache_reload(nwrap_pw_global
.cache
);
781 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
782 if (strcmp(nwrap_pw_global
.list
[i
].pw_name
, name
) == 0) {
783 NWRAP_DEBUG(("%s: user[%s] found\n",
784 __location__
, name
));
785 return &nwrap_pw_global
.list
[i
];
787 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
789 nwrap_pw_global
.list
[i
].pw_name
));
792 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__
, name
));
798 _PUBLIC_
struct passwd
*nwrap_getpwnam(const char *name
)
800 if (!nwrap_enabled()) {
801 return real_getpwnam(name
);
804 return nwrap_files_getpwnam(name
);
807 static int nwrap_files_getpwnam_r(const char *name
, struct passwd
*pwdst
,
808 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
812 pw
= nwrap_getpwnam(name
);
820 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
823 _PUBLIC_
int nwrap_getpwnam_r(const char *name
, struct passwd
*pwdst
,
824 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
826 if (!nwrap_enabled()) {
827 return real_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
830 return nwrap_files_getpwnam_r(name
, pwdst
, buf
, buflen
, pwdstp
);
833 static struct passwd
*nwrap_files_getpwuid(uid_t uid
)
837 nwrap_cache_reload(nwrap_pw_global
.cache
);
839 for (i
=0; i
<nwrap_pw_global
.num
; i
++) {
840 if (nwrap_pw_global
.list
[i
].pw_uid
== uid
) {
841 NWRAP_DEBUG(("%s: uid[%u] found\n",
843 return &nwrap_pw_global
.list
[i
];
845 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
847 nwrap_pw_global
.list
[i
].pw_uid
));
850 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__
, uid
));
856 _PUBLIC_
struct passwd
*nwrap_getpwuid(uid_t uid
)
860 if (!nwrap_enabled()) {
861 return real_getpwuid(uid
);
864 return nwrap_files_getpwuid(uid
);
867 static int nwrap_files_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
868 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
872 pw
= nwrap_getpwuid(uid
);
880 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
883 _PUBLIC_
int nwrap_getpwuid_r(uid_t uid
, struct passwd
*pwdst
,
884 char *buf
, size_t buflen
, struct passwd
**pwdstp
)
886 if (!nwrap_enabled()) {
887 return real_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
890 return nwrap_files_getpwuid_r(uid
, pwdst
, buf
, buflen
, pwdstp
);
893 /* user enum functions */
894 static void nwrap_files_setpwent(void)
896 nwrap_pw_global
.idx
= 0;
899 _PUBLIC_
void nwrap_setpwent(void)
901 if (!nwrap_enabled()) {
905 nwrap_files_setpwent();
908 static struct passwd
*nwrap_files_getpwent(void)
912 if (nwrap_pw_global
.idx
== 0) {
913 nwrap_cache_reload(nwrap_pw_global
.cache
);
916 if (nwrap_pw_global
.idx
>= nwrap_pw_global
.num
) {
921 pw
= &nwrap_pw_global
.list
[nwrap_pw_global
.idx
++];
923 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
924 __location__
, pw
->pw_name
, pw
->pw_uid
));
929 _PUBLIC_
struct passwd
*nwrap_getpwent(void)
931 if (!nwrap_enabled()) {
932 return real_getpwent();
935 return nwrap_files_getpwent();
938 static int nwrap_files_getpwent_r(struct passwd
*pwdst
, char *buf
,
939 size_t buflen
, struct passwd
**pwdstp
)
943 pw
= nwrap_getpwent();
951 return nwrap_pw_copy_r(pw
, pwdst
, buf
, buflen
, pwdstp
);
954 _PUBLIC_
int nwrap_getpwent_r(struct passwd
*pwdst
, char *buf
,
955 size_t buflen
, struct passwd
**pwdstp
)
957 if (!nwrap_enabled()) {
958 #ifdef SOLARIS_GETPWENT_R
959 pw
= real_getpwent_r(pwdst
, buf
, buflen
);
971 return real_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
975 return nwrap_files_getpwent_r(pwdst
, buf
, buflen
, pwdstp
);
978 static void nwrap_files_endpwent(void)
980 nwrap_pw_global
.idx
= 0;
983 _PUBLIC_
void nwrap_endpwent(void)
985 if (!nwrap_enabled()) {
989 nwrap_files_endpwent();
993 static int nwrap_files_initgroups(const char *user
, gid_t group
)
995 /* TODO: maybe we should also fake this... */
999 _PUBLIC_
int nwrap_initgroups(const char *user
, gid_t group
)
1001 if (!nwrap_enabled()) {
1002 return real_initgroups(user
, group
);
1005 return nwrap_files_initgroups(user
, group
);
1008 /* group functions */
1009 static struct group
*nwrap_files_getgrnam(const char *name
)
1013 nwrap_cache_reload(nwrap_gr_global
.cache
);
1015 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1016 if (strcmp(nwrap_gr_global
.list
[i
].gr_name
, name
) == 0) {
1017 NWRAP_DEBUG(("%s: group[%s] found\n",
1018 __location__
, name
));
1019 return &nwrap_gr_global
.list
[i
];
1021 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1023 nwrap_gr_global
.list
[i
].gr_name
));
1026 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__
, name
));
1032 _PUBLIC_
struct group
*nwrap_getgrnam(const char *name
)
1034 if (!nwrap_enabled()) {
1035 return real_getgrnam(name
);
1038 return nwrap_files_getgrnam(name
);
1041 static int nwrap_files_getgrnam_r(const char *name
, struct group
*grdst
,
1042 char *buf
, size_t buflen
, struct group
**grdstp
)
1046 gr
= nwrap_getgrnam(name
);
1054 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1057 _PUBLIC_
int nwrap_getgrnam_r(const char *name
, struct group
*grdst
,
1058 char *buf
, size_t buflen
, struct group
**grdstp
)
1062 if (!nwrap_enabled()) {
1063 return real_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
1066 return nwrap_files_getgrnam_r(name
, grdst
, buf
, buflen
, grdstp
);
1069 static struct group
*nwrap_files_getgrgid(gid_t gid
)
1073 nwrap_cache_reload(nwrap_gr_global
.cache
);
1075 for (i
=0; i
<nwrap_gr_global
.num
; i
++) {
1076 if (nwrap_gr_global
.list
[i
].gr_gid
== gid
) {
1077 NWRAP_DEBUG(("%s: gid[%u] found\n",
1078 __location__
, gid
));
1079 return &nwrap_gr_global
.list
[i
];
1081 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1083 nwrap_gr_global
.list
[i
].gr_gid
));
1086 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__
, gid
));
1092 _PUBLIC_
struct group
*nwrap_getgrgid(gid_t gid
)
1096 if (!nwrap_enabled()) {
1097 return real_getgrgid(gid
);
1100 return nwrap_files_getgrgid(gid
);
1103 static int nwrap_files_getgrgid_r(gid_t gid
, struct group
*grdst
,
1104 char *buf
, size_t buflen
, struct group
**grdstp
)
1108 gr
= nwrap_getgrgid(gid
);
1116 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1121 _PUBLIC_
int nwrap_getgrgid_r(gid_t gid
, struct group
*grdst
,
1122 char *buf
, size_t buflen
, struct group
**grdstp
)
1124 if (!nwrap_enabled()) {
1125 return real_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
1128 return nwrap_files_getgrgid_r(gid
, grdst
, buf
, buflen
, grdstp
);
1131 /* group enum functions */
1132 static void nwrap_files_setgrent(void)
1134 nwrap_gr_global
.idx
= 0;
1137 _PUBLIC_
void nwrap_setgrent(void)
1139 if (!nwrap_enabled()) {
1143 nwrap_files_setgrent();
1146 static struct group
*nwrap_files_getgrent(void)
1150 if (nwrap_gr_global
.idx
== 0) {
1151 nwrap_cache_reload(nwrap_gr_global
.cache
);
1154 if (nwrap_gr_global
.idx
>= nwrap_gr_global
.num
) {
1159 gr
= &nwrap_gr_global
.list
[nwrap_gr_global
.idx
++];
1161 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1162 __location__
, gr
->gr_name
, gr
->gr_gid
));
1167 _PUBLIC_
struct group
*nwrap_getgrent(void)
1169 if (!nwrap_enabled()) {
1170 return real_getgrent();
1173 return nwrap_files_getgrent();
1176 static int nwrap_files_getgrent_r(struct group
*grdst
, char *buf
,
1177 size_t buflen
, struct group
**grdstp
)
1181 gr
= nwrap_getgrent();
1189 return nwrap_gr_copy_r(gr
, grdst
, buf
, buflen
, grdstp
);
1192 _PUBLIC_
int nwrap_getgrent_r(struct group
*grdst
, char *buf
,
1193 size_t buflen
, struct group
**grdstp
)
1195 if (!nwrap_enabled()) {
1196 #ifdef SOLARIS_GETGRENT_R
1197 gr
= real_getgrent_r(grdst
, buf
, buflen
);
1209 return real_getgrent_r(grdst
, buf
, buflen
, grdstp
);
1213 return nwrap_files_getgrent_r(grdst
, buf
, buflen
, grdstp
);
1216 static void nwrap_files_endgrent(void)
1218 nwrap_gr_global
.idx
= 0;
1221 _PUBLIC_
void nwrap_endgrent(void)
1223 if (!nwrap_enabled()) {
1227 nwrap_files_endgrent();