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