Annotation of src/usr.bin/sudo/getspwuid.c, Revision 1.9
1.1 millert 1: /*
1.9 ! millert 2: * Copyright (c) 1996, 1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 millert 3: *
1.8 millert 4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
1.1 millert 7: *
1.8 millert 8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.7 millert 15: *
16: * Sponsored in part by the Defense Advanced Research Projects
17: * Agency (DARPA) and Air Force Research Laboratory, Air Force
18: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
1.1 millert 19: */
20:
1.9 ! millert 21: #include <config.h>
1.1 millert 22:
1.5 millert 23: #include <sys/types.h>
24: #include <sys/stat.h>
25: #include <sys/param.h>
1.1 millert 26: #include <stdio.h>
27: #ifdef STDC_HEADERS
28: # include <stdlib.h>
1.5 millert 29: # include <stddef.h>
30: #else
31: # ifdef HAVE_STDLIB_H
32: # include <stdlib.h>
33: # endif
1.1 millert 34: #endif /* STDC_HEADERS */
35: #ifdef HAVE_STRING_H
1.5 millert 36: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
37: # include <memory.h>
38: # endif
1.1 millert 39: # include <string.h>
1.5 millert 40: #else
41: # ifdef HAVE_STRINGS_H
42: # include <strings.h>
43: # endif
1.1 millert 44: #endif /* HAVE_STRING_H */
45: #ifdef HAVE_UNISTD_H
46: # include <unistd.h>
47: #endif /* HAVE_UNISTD_H */
48: #include <pwd.h>
49: #ifdef HAVE_GETSPNAM
50: # include <shadow.h>
51: #endif /* HAVE_GETSPNAM */
52: #ifdef HAVE_GETPRPWNAM
53: # ifdef __hpux
54: # undef MAXINT
55: # include <hpsecurity.h>
56: # else
57: # include <sys/security.h>
58: # endif /* __hpux */
59: # include <prot.h>
60: #endif /* HAVE_GETPRPWNAM */
61: #ifdef HAVE_GETPWANAM
62: # include <sys/label.h>
63: # include <sys/audit.h>
64: # include <pwdadj.h>
65: #endif /* HAVE_GETPWANAM */
66: #ifdef HAVE_GETAUTHUID
67: # include <auth.h>
68: #endif /* HAVE_GETAUTHUID */
69:
70: #include "sudo.h"
71:
72: #ifndef lint
1.9 ! millert 73: __unused static const char rcsid[] = "$Sudo: getspwuid.c,v 1.65.2.2 2007/06/12 01:28:41 millert Exp $";
1.1 millert 74: #endif /* lint */
75:
76: /*
77: * Global variables (yuck)
78: */
79: #if defined(HAVE_GETPRPWNAM) && defined(__alpha)
80: int crypt_type = INT_MAX;
81: #endif /* HAVE_GETPRPWNAM && __alpha */
82:
83:
84: /*
1.5 millert 85: * Return a copy of the encrypted password for the user described by pw.
86: * If shadow passwords are in use, look in the shadow file.
1.1 millert 87: */
1.2 millert 88: char *
1.1 millert 89: sudo_getepw(pw)
1.8 millert 90: const struct passwd *pw;
1.1 millert 91: {
1.5 millert 92: char *epw;
1.1 millert 93:
94: /* If there is a function to check for shadow enabled, use it... */
95: #ifdef HAVE_ISCOMSEC
96: if (!iscomsec())
1.5 millert 97: return(estrdup(pw->pw_passwd));
1.1 millert 98: #endif /* HAVE_ISCOMSEC */
99: #ifdef HAVE_ISSECURE
100: if (!issecure())
1.5 millert 101: return(estrdup(pw->pw_passwd));
1.1 millert 102: #endif /* HAVE_ISSECURE */
103:
1.5 millert 104: epw = NULL;
1.1 millert 105: #ifdef HAVE_GETPRPWNAM
106: {
107: struct pr_passwd *spw;
108:
1.5 millert 109: setprpwent();
110: if ((spw = getprpwnam(pw->pw_name)) && spw->ufld.fd_encrypt) {
1.1 millert 111: # ifdef __alpha
112: crypt_type = spw->ufld.fd_oldcrypt;
113: # endif /* __alpha */
1.5 millert 114: epw = estrdup(spw->ufld.fd_encrypt);
1.1 millert 115: }
1.5 millert 116: endprpwent();
117: if (epw)
118: return(epw);
1.1 millert 119: }
120: #endif /* HAVE_GETPRPWNAM */
121: #ifdef HAVE_GETSPNAM
122: {
123: struct spwd *spw;
124:
1.5 millert 125: setspent();
1.1 millert 126: if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp)
1.5 millert 127: epw = estrdup(spw->sp_pwdp);
128: endspent();
129: if (epw)
130: return(epw);
1.1 millert 131: }
132: #endif /* HAVE_GETSPNAM */
133: #ifdef HAVE_GETSPWUID
134: {
135: struct s_passwd *spw;
136:
1.5 millert 137: setspwent();
1.1 millert 138: if ((spw = getspwuid(pw->pw_uid)) && spw->pw_passwd)
1.5 millert 139: epw = estrdup(spw->pw_passwd);
140: endspwent();
141: if (epw)
142: return(epw);
1.1 millert 143: }
144: #endif /* HAVE_GETSPWUID */
145: #ifdef HAVE_GETPWANAM
146: {
147: struct passwd_adjunct *spw;
148:
1.5 millert 149: setpwaent();
1.1 millert 150: if ((spw = getpwanam(pw->pw_name)) && spw->pwa_passwd)
1.5 millert 151: epw = estrdup(spw->pwa_passwd);
152: endpwaent();
153: if (epw)
154: return(epw);
1.1 millert 155: }
156: #endif /* HAVE_GETPWANAM */
157: #ifdef HAVE_GETAUTHUID
158: {
159: AUTHORIZATION *spw;
160:
1.5 millert 161: setauthent();
1.1 millert 162: if ((spw = getauthuid(pw->pw_uid)) && spw->a_password)
1.5 millert 163: epw = estrdup(spw->a_password);
164: endauthent();
165: if (epw)
166: return(epw);
1.1 millert 167: }
168: #endif /* HAVE_GETAUTHUID */
169:
170: /* Fall back on normal password. */
1.5 millert 171: return(estrdup(pw->pw_passwd));
1.1 millert 172: }
173:
174: /*
175: * Dynamically allocate space for a struct password and the constituent parts
176: * that we care about. Fills in pw_passwd from shadow file if necessary.
177: */
1.8 millert 178: struct passwd *
1.3 millert 179: sudo_pwdup(pw)
1.8 millert 180: const struct passwd *pw;
1.1 millert 181: {
1.8 millert 182: char *cp;
183: const char *pw_passwd, *pw_shell;
184: size_t nsize, psize, csize, gsize, dsize, ssize, total;
185: struct passwd *newpw;
186:
187: /* Get shadow password if available. */
188: pw_passwd = sudo_getepw(pw);
189:
190: /* If shell field is empty, expand to _PATH_BSHELL. */
191: pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
192: ? _PATH_BSHELL : pw->pw_shell;
1.1 millert 193:
1.8 millert 194: /* Allocate in one big chunk for easy freeing. */
195: nsize = psize = csize = gsize = dsize = ssize = 0;
196: total = sizeof(struct passwd);
197: if (pw->pw_name) {
198: nsize = strlen(pw->pw_name) + 1;
199: total += nsize;
200: }
201: if (pw_passwd) {
202: psize = strlen(pw_passwd) + 1;
203: total += psize;
204: }
205: #ifdef HAVE_LOGIN_CAP_H
206: if (pw->pw_class) {
207: csize = strlen(pw->pw_class) + 1;
208: total += csize;
209: }
210: #endif
211: if (pw->pw_gecos) {
212: gsize = strlen(pw->pw_gecos) + 1;
213: total += gsize;
214: }
215: if (pw->pw_dir) {
216: dsize = strlen(pw->pw_dir) + 1;
217: total += dsize;
218: }
219: if (pw_shell) {
220: ssize = strlen(pw_shell) + 1;
221: total += ssize;
222: }
223: if ((cp = malloc(total)) == NULL)
224: return (NULL);
225: newpw = (struct passwd *)cp;
1.1 millert 226:
227: /*
1.8 millert 228: * Copy in passwd contents and make strings relative to space
229: * at the end of the buffer.
1.1 millert 230: */
1.8 millert 231: (void)memcpy(newpw, pw, sizeof(struct passwd));
232: cp += sizeof(struct passwd);
233: if (nsize) {
234: (void)memcpy(cp, pw->pw_name, nsize);
235: newpw->pw_name = cp;
236: cp += nsize;
237: }
238: if (psize) {
239: (void)memcpy(cp, pw_passwd, psize);
240: newpw->pw_passwd = cp;
241: cp += psize;
242: }
1.4 millert 243: #ifdef HAVE_LOGIN_CAP_H
1.8 millert 244: if (csize) {
245: (void)memcpy(cp, pw->pw_class, csize);
246: newpw->pw_class = cp;
247: cp += csize;
248: }
1.4 millert 249: #endif
1.8 millert 250: if (gsize) {
251: (void)memcpy(cp, pw->pw_gecos, gsize);
252: newpw->pw_gecos = cp;
253: cp += gsize;
254: }
255: if (dsize) {
256: (void)memcpy(cp, pw->pw_dir, dsize);
257: newpw->pw_dir = cp;
258: cp += dsize;
259: }
260: if (ssize) {
261: (void)memcpy(cp, pw_shell, ssize);
262: newpw->pw_shell = cp;
263: cp += ssize;
264: }
1.1 millert 265:
1.8 millert 266: return (newpw);
1.3 millert 267: }
268:
269: /*
270: * Get a password entry by uid and allocate space for it.
271: * Fills in pw_passwd from shadow file if necessary.
272: */
273: struct passwd *
274: sudo_getpwuid(uid)
275: uid_t uid;
276: {
277: struct passwd *pw;
278:
279: if ((pw = getpwuid(uid)) == NULL)
280: return(NULL);
281: else
282: return(sudo_pwdup(pw));
283: }
284:
285: /*
286: * Get a password entry by name and allocate space for it.
287: * Fills in pw_passwd from shadow file if necessary.
288: */
289: struct passwd *
290: sudo_getpwnam(name)
291: const char *name;
292: {
293: struct passwd *pw;
294:
295: if ((pw = getpwnam(name)) == NULL)
296: return(NULL);
297: else
298: return(sudo_pwdup(pw));
1.1 millert 299: }