Imported Upstream version 1.6.6
[debian/sudo] / getspwuid.c
1 /*
2  * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * 4. Products derived from this software may not be called "Sudo" nor
20  *    may "Sudo" appear in their names without specific prior written
21  *    permission from the author.
22  *
23  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
26  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include "config.h"
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/param.h>
40 #include <stdio.h>
41 #ifdef STDC_HEADERS
42 # include <stdlib.h>
43 # include <stddef.h>
44 #else
45 # ifdef HAVE_STDLIB_H
46 #  include <stdlib.h>
47 # endif
48 #endif /* STDC_HEADERS */
49 #ifdef HAVE_STRING_H
50 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
51 #  include <memory.h>
52 # endif
53 # include <string.h>
54 #else
55 # ifdef HAVE_STRINGS_H
56 #  include <strings.h>
57 # endif
58 #endif /* HAVE_STRING_H */
59 #ifdef HAVE_UNISTD_H
60 # include <unistd.h>
61 #endif /* HAVE_UNISTD_H */
62 #include <pwd.h>
63 #ifdef HAVE_GETSPNAM
64 # include <shadow.h>
65 #endif /* HAVE_GETSPNAM */
66 #ifdef HAVE_GETPRPWNAM
67 # ifdef __hpux
68 #  undef MAXINT
69 #  include <hpsecurity.h>
70 # else
71 #  include <sys/security.h>
72 # endif /* __hpux */
73 # include <prot.h>
74 #endif /* HAVE_GETPRPWNAM */
75 #ifdef HAVE_GETPWANAM
76 # include <sys/label.h>
77 # include <sys/audit.h>
78 # include <pwdadj.h>
79 #endif /* HAVE_GETPWANAM */
80 #ifdef HAVE_GETAUTHUID
81 # include <auth.h>
82 #endif /* HAVE_GETAUTHUID */
83
84 #include "sudo.h"
85
86 #ifndef lint
87 static const char rcsid[] = "$Sudo: getspwuid.c,v 1.62 2002/01/15 23:43:59 millert Exp $";
88 #endif /* lint */
89
90 /*
91  * Global variables (yuck)
92  */
93 #if defined(HAVE_GETPRPWNAM) && defined(__alpha)
94 int crypt_type = INT_MAX;
95 #endif /* HAVE_GETPRPWNAM && __alpha */
96
97
98 /*
99  * Local functions not visible outside getspwuid.c
100  */
101 static struct passwd *sudo_pwdup        __P((struct passwd *));
102
103
104 /*
105  * Return a copy of the encrypted password for the user described by pw.
106  * If shadow passwords are in use, look in the shadow file.
107  */
108 char *
109 sudo_getepw(pw)
110     struct passwd *pw;
111 {
112     char *epw;
113
114     /* If there is a function to check for shadow enabled, use it... */
115 #ifdef HAVE_ISCOMSEC
116     if (!iscomsec())
117         return(estrdup(pw->pw_passwd));
118 #endif /* HAVE_ISCOMSEC */
119 #ifdef HAVE_ISSECURE
120     if (!issecure())
121         return(estrdup(pw->pw_passwd));
122 #endif /* HAVE_ISSECURE */
123
124     epw = NULL;
125 #ifdef HAVE_GETPRPWNAM
126     {
127         struct pr_passwd *spw;
128
129         setprpwent();
130         if ((spw = getprpwnam(pw->pw_name)) && spw->ufld.fd_encrypt) {
131 # ifdef __alpha
132             crypt_type = spw->ufld.fd_oldcrypt;
133 # endif /* __alpha */
134             epw = estrdup(spw->ufld.fd_encrypt);
135         }
136         endprpwent();
137         if (epw)
138             return(epw);
139     }
140 #endif /* HAVE_GETPRPWNAM */
141 #ifdef HAVE_GETSPNAM
142     {
143         struct spwd *spw;
144
145         setspent();
146         if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp)
147             epw = estrdup(spw->sp_pwdp);
148         endspent();
149         if (epw)
150             return(epw);
151     }
152 #endif /* HAVE_GETSPNAM */
153 #ifdef HAVE_GETSPWUID
154     {
155         struct s_passwd *spw;
156
157         setspwent();
158         if ((spw = getspwuid(pw->pw_uid)) && spw->pw_passwd)
159             epw = estrdup(spw->pw_passwd);
160         endspwent();
161         if (epw)
162             return(epw);
163     }
164 #endif /* HAVE_GETSPWUID */
165 #ifdef HAVE_GETPWANAM
166     {
167         struct passwd_adjunct *spw;
168
169         setpwaent();
170         if ((spw = getpwanam(pw->pw_name)) && spw->pwa_passwd)
171             epw = estrdup(spw->pwa_passwd);
172         endpwaent();
173         if (epw)
174             return(epw);
175     }
176 #endif /* HAVE_GETPWANAM */
177 #ifdef HAVE_GETAUTHUID
178     {
179         AUTHORIZATION *spw;
180
181         setauthent();
182         if ((spw = getauthuid(pw->pw_uid)) && spw->a_password)
183             epw = estrdup(spw->a_password);
184         endauthent();
185         if (epw)
186             return(epw);
187     }
188 #endif /* HAVE_GETAUTHUID */
189
190     /* Fall back on normal password. */
191     return(estrdup(pw->pw_passwd));
192 }
193
194 /*
195  * Dynamically allocate space for a struct password and the constituent parts
196  * that we care about.  Fills in pw_passwd from shadow file if necessary.
197  */
198 static struct passwd *
199 sudo_pwdup(pw)
200     struct passwd *pw;
201 {
202     struct passwd *local_pw;
203
204     /* Allocate space for a local copy of pw. */
205     local_pw = (struct passwd *) emalloc(sizeof(struct passwd));
206
207     /*
208      * Copy the struct passwd and the interesting strings...
209      */
210     (void) memcpy(local_pw, pw, sizeof(struct passwd));
211     local_pw->pw_name = estrdup(pw->pw_name);
212     local_pw->pw_dir = estrdup(pw->pw_dir);
213     local_pw->pw_gecos = estrdup(pw->pw_gecos);
214 #ifdef HAVE_LOGIN_CAP_H
215     local_pw->pw_class = estrdup(pw->pw_class);
216 #endif
217
218     /* If shell field is empty, expand to _PATH_BSHELL. */
219     if (local_pw->pw_shell[0] == '\0')
220         local_pw->pw_shell = _PATH_BSHELL;
221     else
222         local_pw->pw_shell = estrdup(pw->pw_shell);
223
224     /* pw_passwd gets a shadow password if applicable */
225     local_pw->pw_passwd = sudo_getepw(pw);
226
227     return(local_pw);
228 }
229
230 /*
231  * Get a password entry by uid and allocate space for it.
232  * Fills in pw_passwd from shadow file if necessary.
233  */
234 struct passwd *
235 sudo_getpwuid(uid)
236     uid_t uid;
237 {
238     struct passwd *pw;
239
240     if ((pw = getpwuid(uid)) == NULL)
241         return(NULL);
242     else
243         return(sudo_pwdup(pw));
244 }
245
246 /*
247  * Get a password entry by name and allocate space for it.
248  * Fills in pw_passwd from shadow file if necessary.
249  */
250 struct passwd *
251 sudo_getpwnam(name)
252     const char *name;
253 {
254     struct passwd *pw;
255
256     if ((pw = getpwnam(name)) == NULL)
257         return(NULL);
258     else
259         return(sudo_pwdup(pw));
260 }