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_GETGRGID_R
65 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS
67 #ifndef HAVE_GETGRENT_R
68 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
71 /* not all systems have getgrouplist */
72 #ifndef HAVE_GETGROUPLIST
73 #define getgrouplist(user, group, groups, ngroups) 0
76 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
82 #define real_getpwnam getpwnam
83 #define real_getpwnam_r getpwnam_r
84 #define real_getpwuid getpwuid
85 #define real_getpwuid_r getpwuid_r
87 #define real_setpwent setpwent
88 #define real_getpwent getpwent
89 #define real_getpwent_r getpwent_r
90 #define real_endpwent endpwent
93 #define real_getgrlst getgrlst
94 #define real_getgrlst_r getgrlst_r
95 #define real_initgroups_dyn initgroups_dyn
97 #define real_initgroups initgroups
98 #define real_getgrouplist getgrouplist
100 #define real_getgrnam getgrnam
101 #define real_getgrnam_r getgrnam_r
102 #define real_getgrgid getgrgid
103 #define real_getgrgid_r getgrgid_r
105 #define real_setgrent setgrent
106 #define real_getgrent getgrent
107 #define real_getgrent_r getgrent_r
108 #define real_endgrent endgrent
114 # define NWRAP_ERROR(args) DEBUG(0, args)
116 # define NWRAP_ERROR(args) printf args
119 #define NWRAP_ERROR(args)
124 # define NWRAP_DEBUG(args) DEBUG(0, args)
126 # define NWRAP_DEBUG(args) printf args
129 #define NWRAP_DEBUG(args)
134 # define NWRAP_VERBOSE(args) DEBUG(0, args)
136 # define NWRAP_VERBOSE(args) printf args
139 #define NWRAP_VERBOSE(args)
144 struct passwd * (*nw_getpwnam)(const char *name);
145 int (*nw_getpwnam_r)(const char *name, struct passwd *pwdst,
146 char *buf, size_t buflen, struct passwd **pwdstp);
147 struct passwd * (*nw_getpwuid)(uid_t uid);
148 int (*nw_getpwuid_r)(uid_t uid, struct passwd *pwdst,
149 char *buf, size_t buflen, struct passwd **pwdstp);
150 void (*nw_setpwent)(void);
151 struct passwd * (*nw_getpwent)(void);
152 int (*nw_getpwent_r)(struct passwd *pwdst, char *buf,
153 size_t buflen, struct passwd **pwdstp);
154 void (*nw_endpwent)(void);
155 int (*nw_initgroups)(const char *user, gid_t group);
156 struct group * (*nw_getgrnam)(const char *name);
157 int (*nw_getgrnam_r)(const char *name, struct group *grdst,
158 char *buf, size_t buflen, struct group **grdstp);
159 struct group * (*nw_getgrgid)(gid_t gid);
160 int (*nw_getgrgid_r)(gid_t gid, struct group *grdst,
161 char *buf, size_t buflen, struct group **grdstp);
162 void (*nw_setgrent)(void);
163 struct group * (*nw_getgrent)(void);
164 int (*nw_getgrent_r)(struct group *grdst, char *buf,
165 size_t buflen, struct group **grdstp);
166 void (*nw_endgrent)(void);
169 static struct passwd *nwrap_files_getpwnam(const char *name);
170 static int nwrap_files_getpwnam_r(const char *name, struct passwd *pwdst,
171 char *buf, size_t buflen, struct passwd **pwdstp);
172 static struct passwd *nwrap_files_getpwuid(uid_t uid);
173 static int nwrap_files_getpwuid_r(uid_t uid, struct passwd *pwdst,
174 char *buf, size_t buflen, struct passwd **pwdstp);
175 static void nwrap_files_setpwent(void);
176 static struct passwd *nwrap_files_getpwent(void);
177 static int nwrap_files_getpwent_r(struct passwd *pwdst, char *buf,
178 size_t buflen, struct passwd **pwdstp);
179 static void nwrap_files_endpwent(void);
180 static int nwrap_files_initgroups(const char *user, gid_t group);
181 static struct group *nwrap_files_getgrnam(const char *name);
182 static int nwrap_files_getgrnam_r(const char *name, struct group *grdst,
183 char *buf, size_t buflen, struct group **grdstp);
184 static struct group *nwrap_files_getgrgid(gid_t gid);
185 static int nwrap_files_getgrgid_r(gid_t gid, struct group *grdst,
186 char *buf, size_t buflen, struct group **grdstp);
187 static void nwrap_files_setgrent(void);
188 static struct group *nwrap_files_getgrent(void);
189 static int nwrap_files_getgrent_r(struct group *grdst, char *buf,
190 size_t buflen, struct group **grdstp);
191 static void nwrap_files_endgrent(void);
193 struct nwrap_ops nwrap_files_ops = {
195 .nw_getpwnam = nwrap_files_getpwnam,
196 .nw_getpwnam_r = nwrap_files_getpwnam_r,
197 .nw_getpwuid = nwrap_files_getpwuid,
198 .nw_getpwuid_r = nwrap_files_getpwuid_r,
199 .nw_setpwent = nwrap_files_setpwent,
200 .nw_getpwent = nwrap_files_getpwent,
201 .nw_getpwent_r = nwrap_files_getpwent_r,
202 .nw_endpwent = nwrap_files_endpwent,
203 .nw_initgroups = nwrap_files_initgroups,
204 .nw_getgrnam = nwrap_files_getgrnam,
205 .nw_getgrnam_r = nwrap_files_getgrnam_r,
206 .nw_getgrgid = nwrap_files_getgrgid,
207 .nw_getgrgid_r = nwrap_files_getgrgid_r,
208 .nw_setgrent = nwrap_files_setgrent,
209 .nw_getgrent = nwrap_files_getgrent,
210 .nw_getgrent_r = nwrap_files_getgrent_r,
211 .nw_endgrent = nwrap_files_endgrent,
215 struct nwrap_ops *ops;
218 struct nwrap_main *nwrap_main_global;
219 struct nwrap_main __nwrap_main_global;
227 bool (*parse_line)(struct nwrap_cache *, char *line);
228 void (*unload)(struct nwrap_cache *);
232 struct nwrap_cache *cache;
239 struct nwrap_cache __nwrap_cache_pw;
240 struct nwrap_pw nwrap_pw_global;
242 static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line);
243 static void nwrap_pw_unload(struct nwrap_cache *nwrap);
246 struct nwrap_cache *cache;
253 struct nwrap_cache __nwrap_cache_gr;
254 struct nwrap_gr nwrap_gr_global;
256 static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line);
257 static void nwrap_gr_unload(struct nwrap_cache *nwrap);
259 static void nwrap_init(void)
261 static bool initialized;
263 if (initialized) return;
266 nwrap_main_global = &__nwrap_main_global;
268 nwrap_main_global->ops = &nwrap_files_ops;
270 nwrap_pw_global.cache = &__nwrap_cache_pw;
272 nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD");
273 nwrap_pw_global.cache->fd = -1;
274 nwrap_pw_global.cache->private_data = &nwrap_pw_global;
275 nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line;
276 nwrap_pw_global.cache->unload = nwrap_pw_unload;
278 nwrap_gr_global.cache = &__nwrap_cache_gr;
280 nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP");
281 nwrap_gr_global.cache->fd = -1;
282 nwrap_gr_global.cache->private_data = &nwrap_gr_global;
283 nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line;
284 nwrap_gr_global.cache->unload = nwrap_gr_unload;
287 static bool nwrap_enabled(void)
291 if (!nwrap_pw_global.cache->path) {
294 if (nwrap_pw_global.cache->path[0] == '\0') {
297 if (!nwrap_gr_global.cache->path) {
300 if (nwrap_gr_global.cache->path[0] == '\0') {
307 static bool nwrap_parse_file(struct nwrap_cache *nwrap)
313 if (nwrap->st.st_size == 0) {
314 NWRAP_DEBUG(("%s: size == 0\n",
319 if (nwrap->st.st_size > INT32_MAX) {
320 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",
321 __location__, (unsigned)nwrap->st.st_size));
325 ret = lseek(nwrap->fd, 0, SEEK_SET);
327 NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret));
331 buf = (uint8_t *)malloc(nwrap->st.st_size + 1);
333 NWRAP_ERROR(("%s: malloc failed\n",__location__));
337 ret = read(nwrap->fd, buf, nwrap->st.st_size);
338 if (ret != nwrap->st.st_size) {
339 NWRAP_ERROR(("%s: read(%u) gave %d\n",
340 __location__, (unsigned)nwrap->st.st_size, ret));
344 buf[nwrap->st.st_size] = '\0';
347 while (nline && nline[0]) {
355 e = strchr(line, '\n');
366 NWRAP_VERBOSE(("%s:'%s'\n",__location__, line));
368 if (strlen(line) == 0) {
372 ok = nwrap->parse_line(nwrap, line);
387 static void nwrap_cache_unload(struct nwrap_cache *nwrap)
389 nwrap->unload(nwrap);
391 if (nwrap->buf) free(nwrap->buf);
396 static void nwrap_cache_reload(struct nwrap_cache *nwrap)
401 bool retried = false;
405 nwrap->fd = open(nwrap->path, O_RDONLY);
407 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",
409 nwrap->path, nwrap->fd,
413 NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path));
416 ret = fstat(nwrap->fd, &st);
418 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",
421 ret, strerror(errno)));
425 if (retried == false && st.st_nlink == 0) {
426 /* maybe someone has replaced the file... */
427 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",
428 __location__, nwrap->path));
430 memset(&nwrap->st, 0, sizeof(nwrap->st));
436 if (st.st_mtime == nwrap->st.st_mtime) {
437 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",
438 __location__, (unsigned)st.st_mtime));
441 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",
442 __location__, (unsigned)st.st_mtime,
443 (unsigned)nwrap->st.st_mtime));
447 nwrap_cache_unload(nwrap);
449 ok = nwrap_parse_file(nwrap);
451 NWRAP_ERROR(("%s: failed to reload %s\n",
452 __location__, nwrap->path));
453 nwrap_cache_unload(nwrap);
455 NWRAP_DEBUG(("%s: reloaded %s\n",
456 __location__, nwrap->path));
460 * the caller has to call nwrap_unload() on failure
462 static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line)
464 struct nwrap_pw *nwrap_pw;
471 nwrap_pw = (struct nwrap_pw *)nwrap->private_data;
473 list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1);
474 pw = (struct passwd *)realloc(nwrap_pw->list, list_size);
476 NWRAP_ERROR(("%s:realloc(%u) failed\n",
477 __location__, list_size));
482 pw = &nwrap_pw->list[nwrap_pw->num];
489 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
490 __location__, line, c));
498 NWRAP_VERBOSE(("name[%s]\n", pw->pw_name));
503 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
504 __location__, line, c));
512 NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd));
517 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
518 __location__, line, c));
524 pw->pw_uid = (uid_t)strtoul(c, &e, 10);
526 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
527 __location__, line, c, strerror(errno)));
531 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
532 __location__, line, c, strerror(errno)));
536 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
537 __location__, line, c, strerror(errno)));
542 NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid));
547 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
548 __location__, line, c));
554 pw->pw_gid = (gid_t)strtoul(c, &e, 10);
556 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
557 __location__, line, c, strerror(errno)));
561 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
562 __location__, line, c, strerror(errno)));
566 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
567 __location__, line, c, strerror(errno)));
572 NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid));
577 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
578 __location__, line, c));
586 NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos));
591 NWRAP_ERROR(("%s:'%s'\n",__location__,c));
599 NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir));
603 NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell));
605 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",
606 pw->pw_name, pw->pw_passwd,
607 pw->pw_uid, pw->pw_gid,
608 pw->pw_gecos, pw->pw_dir, pw->pw_shell));
614 static void nwrap_pw_unload(struct nwrap_cache *nwrap)
616 struct nwrap_pw *nwrap_pw;
617 nwrap_pw = (struct nwrap_pw *)nwrap->private_data;
619 if (nwrap_pw->list) free(nwrap_pw->list);
621 nwrap_pw->list = NULL;
626 static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst,
627 char *buf, size_t buflen, struct passwd **dstp)
633 first = src->pw_name;
635 last = src->pw_shell;
636 while (*last) last++;
638 ofs = PTR_DIFF(last + 1, first);
644 memcpy(buf, first, ofs);
646 ofs = PTR_DIFF(src->pw_name, first);
647 dst->pw_name = buf + ofs;
648 ofs = PTR_DIFF(src->pw_passwd, first);
649 dst->pw_passwd = buf + ofs;
650 dst->pw_uid = src->pw_uid;
651 dst->pw_gid = src->pw_gid;
652 ofs = PTR_DIFF(src->pw_gecos, first);
653 dst->pw_gecos = buf + ofs;
654 ofs = PTR_DIFF(src->pw_dir, first);
655 dst->pw_dir = buf + ofs;
656 ofs = PTR_DIFF(src->pw_shell, first);
657 dst->pw_shell = buf + ofs;
667 * the caller has to call nwrap_unload() on failure
669 static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line)
671 struct nwrap_gr *nwrap_gr;
679 nwrap_gr = (struct nwrap_gr *)nwrap->private_data;
681 list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1);
682 gr = (struct group *)realloc(nwrap_gr->list, list_size);
684 NWRAP_ERROR(("%s:realloc failed\n",__location__));
689 gr = &nwrap_gr->list[nwrap_gr->num];
696 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
697 __location__, line, c));
705 NWRAP_VERBOSE(("name[%s]\n", gr->gr_name));
710 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
711 __location__, line, c));
719 NWRAP_VERBOSE(("password[%s]\n", gr->gr_passwd));
724 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",
725 __location__, line, c));
731 gr->gr_gid = (gid_t)strtoul(c, &e, 10);
733 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
734 __location__, line, c, strerror(errno)));
738 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
739 __location__, line, c, strerror(errno)));
743 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",
744 __location__, line, c, strerror(errno)));
749 NWRAP_VERBOSE(("gid[%u]\n", gr->gr_gid));
752 gr->gr_mem = (char **)malloc(sizeof(char *));
754 NWRAP_ERROR(("%s:calloc failed\n",__location__));
757 gr->gr_mem[0] = NULL;
759 for(nummem=0; p; nummem++) {
769 if (strlen(c) == 0) {
773 m_size = sizeof(char *) * (nummem+2);
774 m = (char **)realloc(gr->gr_mem, m_size);
776 NWRAP_ERROR(("%s:realloc(%u) failed\n",
777 __location__, m_size));
781 gr->gr_mem[nummem] = c;
782 gr->gr_mem[nummem+1] = NULL;
784 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem]));
787 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n",
788 gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem));
794 static void nwrap_gr_unload(struct nwrap_cache *nwrap)
797 struct nwrap_gr *nwrap_gr;
798 nwrap_gr = (struct nwrap_gr *)nwrap->private_data;
800 if (nwrap_gr->list) {
801 for (i=0; i < nwrap_gr->num; i++) {
802 if (nwrap_gr->list[i].gr_mem) {
803 free(nwrap_gr->list[i].gr_mem);
806 free(nwrap_gr->list);
809 nwrap_gr->list = NULL;
814 static int nwrap_gr_copy_r(const struct group *src, struct group *dst,
815 char *buf, size_t buflen, struct group **dstp)
825 first = src->gr_name;
828 while (*lastm) lastm++;
831 while (*last) last++;
833 ofsb = PTR_DIFF(last + 1, first);
834 ofsm = PTR_DIFF(lastm + 1, src->gr_mem);
836 if ((ofsb + ofsm) > buflen) {
840 memcpy(buf, first, ofsb);
841 memcpy(buf + ofsb, src->gr_mem, ofsm);
843 ofs = PTR_DIFF(src->gr_name, first);
844 dst->gr_name = buf + ofs;
845 ofs = PTR_DIFF(src->gr_passwd, first);
846 dst->gr_passwd = buf + ofs;
847 dst->gr_gid = src->gr_gid;
849 dst->gr_mem = (char **)(buf + ofsb);
850 for (i=0; src->gr_mem[i]; i++) {
851 ofs = PTR_DIFF(src->gr_mem[i], first);
852 dst->gr_mem[i] = buf + ofs;
864 static struct passwd *nwrap_files_getpwnam(const char *name)
868 nwrap_cache_reload(nwrap_pw_global.cache);
870 for (i=0; i<nwrap_pw_global.num; i++) {
871 if (strcmp(nwrap_pw_global.list[i].pw_name, name) == 0) {
872 NWRAP_DEBUG(("%s: user[%s] found\n",
873 __location__, name));
874 return &nwrap_pw_global.list[i];
876 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n",
878 nwrap_pw_global.list[i].pw_name));
881 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__, name));
887 static int nwrap_files_getpwnam_r(const char *name, struct passwd *pwdst,
888 char *buf, size_t buflen, struct passwd **pwdstp)
892 pw = nwrap_files_getpwnam(name);
900 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
903 static struct passwd *nwrap_files_getpwuid(uid_t uid)
907 nwrap_cache_reload(nwrap_pw_global.cache);
909 for (i=0; i<nwrap_pw_global.num; i++) {
910 if (nwrap_pw_global.list[i].pw_uid == uid) {
911 NWRAP_DEBUG(("%s: uid[%u] found\n",
913 return &nwrap_pw_global.list[i];
915 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n",
917 nwrap_pw_global.list[i].pw_uid));
920 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__, uid));
926 static int nwrap_files_getpwuid_r(uid_t uid, struct passwd *pwdst,
927 char *buf, size_t buflen, struct passwd **pwdstp)
931 pw = nwrap_files_getpwuid(uid);
939 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
942 /* user enum functions */
943 static void nwrap_files_setpwent(void)
945 nwrap_pw_global.idx = 0;
948 static struct passwd *nwrap_files_getpwent(void)
952 if (nwrap_pw_global.idx == 0) {
953 nwrap_cache_reload(nwrap_pw_global.cache);
956 if (nwrap_pw_global.idx >= nwrap_pw_global.num) {
961 pw = &nwrap_pw_global.list[nwrap_pw_global.idx++];
963 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n",
964 __location__, pw->pw_name, pw->pw_uid));
969 static int nwrap_files_getpwent_r(struct passwd *pwdst, char *buf,
970 size_t buflen, struct passwd **pwdstp)
974 pw = nwrap_files_getpwent();
982 return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp);
985 static void nwrap_files_endpwent(void)
987 nwrap_pw_global.idx = 0;
991 static int nwrap_files_initgroups(const char *user, gid_t group)
993 /* TODO: maybe we should also fake this... */
997 /* group functions */
998 static struct group *nwrap_files_getgrnam(const char *name)
1002 nwrap_cache_reload(nwrap_gr_global.cache);
1004 for (i=0; i<nwrap_gr_global.num; i++) {
1005 if (strcmp(nwrap_gr_global.list[i].gr_name, name) == 0) {
1006 NWRAP_DEBUG(("%s: group[%s] found\n",
1007 __location__, name));
1008 return &nwrap_gr_global.list[i];
1010 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n",
1012 nwrap_gr_global.list[i].gr_name));
1015 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__, name));
1021 static int nwrap_files_getgrnam_r(const char *name, struct group *grdst,
1022 char *buf, size_t buflen, struct group **grdstp)
1026 gr = nwrap_files_getgrnam(name);
1034 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1037 static struct group *nwrap_files_getgrgid(gid_t gid)
1041 nwrap_cache_reload(nwrap_gr_global.cache);
1043 for (i=0; i<nwrap_gr_global.num; i++) {
1044 if (nwrap_gr_global.list[i].gr_gid == gid) {
1045 NWRAP_DEBUG(("%s: gid[%u] found\n",
1046 __location__, gid));
1047 return &nwrap_gr_global.list[i];
1049 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n",
1051 nwrap_gr_global.list[i].gr_gid));
1054 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__, gid));
1060 static int nwrap_files_getgrgid_r(gid_t gid, struct group *grdst,
1061 char *buf, size_t buflen, struct group **grdstp)
1065 gr = nwrap_files_getgrgid(gid);
1073 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1076 /* group enum functions */
1077 static void nwrap_files_setgrent(void)
1079 nwrap_gr_global.idx = 0;
1082 static struct group *nwrap_files_getgrent(void)
1086 if (nwrap_gr_global.idx == 0) {
1087 nwrap_cache_reload(nwrap_gr_global.cache);
1090 if (nwrap_gr_global.idx >= nwrap_gr_global.num) {
1095 gr = &nwrap_gr_global.list[nwrap_gr_global.idx++];
1097 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n",
1098 __location__, gr->gr_name, gr->gr_gid));
1103 static int nwrap_files_getgrent_r(struct group *grdst, char *buf,
1104 size_t buflen, struct group **grdstp)
1108 gr = nwrap_files_getgrent();
1116 return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp);
1119 static void nwrap_files_endgrent(void)
1121 nwrap_gr_global.idx = 0;
1128 _PUBLIC_ struct passwd *nwrap_getpwnam(const char *name)
1130 if (!nwrap_enabled()) {
1131 return real_getpwnam(name);
1134 return nwrap_main_global->ops->nw_getpwnam(name);
1137 _PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst,
1138 char *buf, size_t buflen, struct passwd **pwdstp)
1140 if (!nwrap_enabled()) {
1141 return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
1144 return nwrap_main_global->ops->nw_getpwnam_r(name, pwdst, buf, buflen, pwdstp);
1147 _PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid)
1149 if (!nwrap_enabled()) {
1150 return real_getpwuid(uid);
1153 return nwrap_main_global->ops->nw_getpwuid(uid);
1156 _PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst,
1157 char *buf, size_t buflen, struct passwd **pwdstp)
1159 if (!nwrap_enabled()) {
1160 return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
1163 return nwrap_main_global->ops->nw_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);
1166 _PUBLIC_ void nwrap_setpwent(void)
1168 if (!nwrap_enabled()) {
1173 nwrap_main_global->ops->nw_setpwent();
1176 _PUBLIC_ struct passwd *nwrap_getpwent(void)
1178 if (!nwrap_enabled()) {
1179 return real_getpwent();
1182 return nwrap_main_global->ops->nw_getpwent();
1185 _PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf,
1186 size_t buflen, struct passwd **pwdstp)
1188 if (!nwrap_enabled()) {
1189 #ifdef SOLARIS_GETPWENT_R
1191 pw = real_getpwent_r(pwdst, buf, buflen);
1203 return real_getpwent_r(pwdst, buf, buflen, pwdstp);
1207 return nwrap_main_global->ops->nw_getpwent_r(pwdst, buf, buflen, pwdstp);
1210 _PUBLIC_ void nwrap_endpwent(void)
1212 if (!nwrap_enabled()) {
1217 nwrap_main_global->ops->nw_endpwent();
1220 _PUBLIC_ int nwrap_initgroups(const char *user, gid_t group)
1222 if (!nwrap_enabled()) {
1223 return real_initgroups(user, group);
1226 return nwrap_main_global->ops->nw_initgroups(user, group);
1229 _PUBLIC_ struct group *nwrap_getgrnam(const char *name)
1231 if (!nwrap_enabled()) {
1232 return real_getgrnam(name);
1235 return nwrap_main_global->ops->nw_getgrnam(name);
1238 _PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst,
1239 char *buf, size_t buflen, struct group **grdstp)
1241 if (!nwrap_enabled()) {
1242 return real_getgrnam_r(name, grdst, buf, buflen, grdstp);
1245 return nwrap_main_global->ops->nw_getgrnam_r(name, grdst, buf, buflen, grdstp);
1248 _PUBLIC_ struct group *nwrap_getgrgid(gid_t gid)
1250 if (!nwrap_enabled()) {
1251 return real_getgrgid(gid);
1254 return nwrap_main_global->ops->nw_getgrgid(gid);
1257 _PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst,
1258 char *buf, size_t buflen, struct group **grdstp)
1260 if (!nwrap_enabled()) {
1261 return real_getgrgid_r(gid, grdst, buf, buflen, grdstp);
1264 return nwrap_main_global->ops->nw_getgrgid_r(gid, grdst, buf, buflen, grdstp);
1267 _PUBLIC_ void nwrap_setgrent(void)
1269 if (!nwrap_enabled()) {
1274 nwrap_main_global->ops->nw_setgrent();
1277 _PUBLIC_ struct group *nwrap_getgrent(void)
1279 if (!nwrap_enabled()) {
1280 return real_getgrent();
1283 return nwrap_main_global->ops->nw_getgrent();
1286 _PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf,
1287 size_t buflen, struct group **grdstp)
1289 if (!nwrap_enabled()) {
1290 #ifdef SOLARIS_GETGRENT_R
1292 gr = real_getgrent_r(grdst, buf, buflen);
1304 return real_getgrent_r(grdst, buf, buflen, grdstp);
1308 return nwrap_main_global->ops->nw_getgrent_r(grdst, buf, buflen, grdstp);
1311 _PUBLIC_ void nwrap_endgrent(void)
1313 if (!nwrap_enabled()) {
1318 nwrap_main_global->ops->nw_endgrent();
1321 _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
1326 const char *name_of_group = NULL;
1328 if (!nwrap_enabled()) {
1329 return real_getgrouplist(user, group, groups, ngroups);
1332 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user));
1334 groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
1336 NWRAP_ERROR(("%s:calloc failed\n",__location__));
1341 memcpy(groups_tmp, &group, sizeof(gid_t));
1343 grp = nwrap_getgrgid(group);
1345 name_of_group = grp->gr_name;
1349 while ((grp = nwrap_getgrent()) != NULL) {
1352 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
1353 __location__, grp->gr_name));
1355 for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
1357 if ((strcmp(user, grp->gr_mem[i]) == 0) &&
1358 (strcmp(name_of_group, grp->gr_name) != 0)) {
1360 NWRAP_DEBUG(("%s: %s is member of %s\n",
1361 __location__, user, grp->gr_name));
1363 groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t));
1365 NWRAP_ERROR(("%s:calloc failed\n",__location__));
1370 memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t));
1377 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
1378 __location__, user, *ngroups));
1380 if (*ngroups < count) {
1387 memcpy(groups, groups_tmp, count * sizeof(gid_t));