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 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