xref: /netbsd-src/external/bsd/libbind/dist/irs/getpwent_r.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1 /*	$NetBSD: getpwent_r.c,v 1.1.1.2 2012/09/09 16:07:55 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (c) 1998-1999 by Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: getpwent_r.c,v 1.8 2005/04/27 04:56:26 sra Exp ";
22 #endif /* LIBC_SCCS and not lint */
23 
24 #include <port_before.h>
25 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
26 	static int getpwent_r_not_required = 0;
27 #else
28 #include <errno.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <sys/types.h>
32 #if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R))
33 #if defined(_POSIX_PTHREAD_SEMANTICS)
34 	/* turn off solaris remapping in <grp.h> */
35 #undef _POSIX_PTHREAD_SEMANTICS
36 #include <pwd.h>
37 #define _POSIX_PTHREAD_SEMANTICS 1
38 #else
39 #define _UNIX95 1
40 #include <pwd.h>
41 #endif
42 #else
43 #include <pwd.h>
44 #endif
45 #include <port_after.h>
46 
47 #ifdef PASS_R_RETURN
48 
49 static int
50 copy_passwd(struct passwd *, struct passwd *, char *buf, int buflen);
51 
52 /* POSIX 1003.1c */
53 #ifdef POSIX_GETPWNAM_R
54 int
__posix_getpwnam_r(const char * login,struct passwd * pwptr,char * buf,size_t buflen,struct passwd ** result)55 __posix_getpwnam_r(const char *login,  struct passwd *pwptr,
56 		char *buf, size_t buflen, struct passwd **result) {
57 #else
58 int
59 getpwnam_r(const char *login,  struct passwd *pwptr,
60 		char *buf, size_t buflen, struct passwd **result) {
61 #endif
62 	struct passwd *pw = getpwnam(login);
63 	int res;
64 
65 	if (pw == NULL) {
66 		*result = NULL;
67 		return (0);
68 	}
69 
70 	res = copy_passwd(pw, pwptr, buf, buflen);
71 	*result = res ? NULL : pwptr;
72 	return (res);
73 }
74 
75 #ifdef POSIX_GETPWNAM_R
76 struct passwd *
77 getpwnam_r(const char *login,  struct passwd *pwptr, char *buf, int buflen) {
78 	struct passwd *pw = getpwnam(login);
79 	int res;
80 
81 	if (pw == NULL)
82 		return (NULL);
83 
84 	res = copy_passwd(pw, pwptr, buf, buflen);
85 	return (res ? NULL : pwptr);
86 }
87 #endif
88 
89 /* POSIX 1003.1c */
90 #ifdef POSIX_GETPWUID_R
91 int
92 __posix_getpwuid_r(uid_t uid, struct passwd *pwptr,
93 		char *buf, int buflen, struct passwd **result) {
94 #else
95 int
96 getpwuid_r(uid_t uid, struct passwd *pwptr,
97 		char *buf, size_t buflen, struct passwd **result) {
98 #endif
99 	struct passwd *pw = getpwuid(uid);
100 	int res;
101 
102 	if (pw == NULL) {
103 		*result = NULL;
104 		return (0);
105 	}
106 
107 	res = copy_passwd(pw, pwptr, buf, buflen);
108 	*result = res ? NULL : pwptr;
109 	return (res);
110 }
111 
112 #ifdef POSIX_GETPWUID_R
113 struct passwd *
114 getpwuid_r(uid_t uid,  struct passwd *pwptr, char *buf, int buflen) {
115 	struct passwd *pw = getpwuid(uid);
116 	int res;
117 
118 	if (pw == NULL)
119 		return (NULL);
120 
121 	res = copy_passwd(pw, pwptr, buf, buflen);
122 	return (res ? NULL : pwptr);
123 }
124 #endif
125 
126 /*%
127  *	These assume a single context is in operation per thread.
128  *	If this is not the case we will need to call irs directly
129  *	rather than through the base functions.
130  */
131 
132 PASS_R_RETURN
133 getpwent_r(struct passwd *pwptr, PASS_R_ARGS) {
134 	struct passwd *pw = getpwent();
135 	int res = 0;
136 
137 	if (pw == NULL)
138 		return (PASS_R_BAD);
139 
140 	res = copy_passwd(pw, pwptr, buf, buflen);
141 	return (res ? PASS_R_BAD : PASS_R_OK);
142 }
143 
144 PASS_R_SET_RETURN
145 #ifdef PASS_R_ENT_ARGS
146 setpassent_r(int stayopen, PASS_R_ENT_ARGS)
147 #else
148 setpassent_r(int stayopen)
149 #endif
150 {
151 
152 	setpassent(stayopen);
153 #ifdef PASS_R_SET_RESULT
154 	return (PASS_R_SET_RESULT);
155 #endif
156 }
157 
158 PASS_R_SET_RETURN
159 #ifdef PASS_R_ENT_ARGS
160 setpwent_r(PASS_R_ENT_ARGS)
161 #else
162 setpwent_r(void)
163 #endif
164 {
165 
166 	setpwent();
167 #ifdef PASS_R_SET_RESULT
168 	return (PASS_R_SET_RESULT);
169 #endif
170 }
171 
172 PASS_R_END_RETURN
173 #ifdef PASS_R_ENT_ARGS
174 endpwent_r(PASS_R_ENT_ARGS)
175 #else
176 endpwent_r(void)
177 #endif
178 {
179 
180 	endpwent();
181 	PASS_R_END_RESULT(PASS_R_OK);
182 }
183 
184 
185 #ifdef HAS_FGETPWENT
186 PASS_R_RETURN
187 fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) {
188 	struct passwd *pw = fgetpwent(f);
189 	int res = 0;
190 
191 	if (pw == NULL)
192 		return (PASS_R_BAD);
193 
194 	res = copy_passwd(pw, pwptr, PASS_R_COPY);
195 	return (res ? PASS_R_BAD : PASS_R_OK );
196 }
197 #endif
198 
199 /* Private */
200 
201 static int
202 copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
203 	char *cp;
204 	int n;
205 	int len;
206 
207 	/* Find out the amount of space required to store the answer. */
208 	len = strlen(pw->pw_name) + 1;
209 	len += strlen(pw->pw_passwd) + 1;
210 #ifdef HAVE_PW_CLASS
211 	len += strlen(pw->pw_class) + 1;
212 #endif
213 	len += strlen(pw->pw_gecos) + 1;
214 	len += strlen(pw->pw_dir) + 1;
215 	len += strlen(pw->pw_shell) + 1;
216 
217 	if (len > buflen) {
218 		errno = ERANGE;
219 		return (ERANGE);
220 	}
221 
222 	/* copy fixed atomic values*/
223 	pwptr->pw_uid = pw->pw_uid;
224 	pwptr->pw_gid = pw->pw_gid;
225 #ifdef HAVE_PW_CHANGE
226 	pwptr->pw_change = pw->pw_change;
227 #endif
228 #ifdef HAVE_PW_EXPIRE
229 	pwptr->pw_expire = pw->pw_expire;
230 #endif
231 
232 	cp = buf;
233 
234 	/* copy official name */
235 	n = strlen(pw->pw_name) + 1;
236 	strcpy(cp, pw->pw_name);
237 	pwptr->pw_name = cp;
238 	cp += n;
239 
240 	/* copy password */
241 	n = strlen(pw->pw_passwd) + 1;
242 	strcpy(cp, pw->pw_passwd);
243 	pwptr->pw_passwd = cp;
244 	cp += n;
245 
246 #ifdef HAVE_PW_CLASS
247 	/* copy class */
248 	n = strlen(pw->pw_class) + 1;
249 	strcpy(cp, pw->pw_class);
250 	pwptr->pw_class = cp;
251 	cp += n;
252 #endif
253 
254 	/* copy gecos */
255 	n = strlen(pw->pw_gecos) + 1;
256 	strcpy(cp, pw->pw_gecos);
257 	pwptr->pw_gecos = cp;
258 	cp += n;
259 
260 	/* copy directory */
261 	n = strlen(pw->pw_dir) + 1;
262 	strcpy(cp, pw->pw_dir);
263 	pwptr->pw_dir = cp;
264 	cp += n;
265 
266 	/* copy login shell */
267 	n = strlen(pw->pw_shell) + 1;
268 	strcpy(cp, pw->pw_shell);
269 	pwptr->pw_shell = cp;
270 	cp += n;
271 
272 	return (0);
273 }
274 #else /* PASS_R_RETURN */
275 	static int getpwent_r_unknown_system = 0;
276 #endif /* PASS_R_RETURN */
277 #endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
278 /*! \file */
279