1 /* passwd.c --- verifying typed passwords with the OS.
2 * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
17 #ifndef NO_LOCKING /* whole file */
30 #include <sys/types.h>
40 # include <sys/param.h>
41 # if _BSDI_VERSION >= 199608
47 #if defined(HAVE_SHADOW_PASSWD) /* passwds live in /etc/shadow */
50 # define PWTYPE struct spwd *
51 # define PWPSLOT sp_pwdp
52 # define GETPW getspnam
54 #elif defined(HAVE_ENHANCED_PASSWD) /* passwds live in /tcb/files/auth/ */
55 /* M.Matsumoto <matsu@yao.sharp.co.jp> */
56 # include <sys/security.h>
59 # define PWTYPE struct pr_passwd *
60 # define PWPSLOT ufld.fd_encrypt
61 # define GETPW getprpwnam
63 #elif defined(HAVE_ADJUNCT_PASSWD)
65 # include <sys/label.h>
66 # include <sys/audit.h>
69 # define PWTYPE struct passwd_adjunct *
70 # define PWPSLOT pwa_passwd
71 # define GETPW getpwanam
73 #elif defined(HAVE_HPUX_PASSWD)
75 # include <hpsecurity.h>
78 # define PWTYPE struct s_passwd *
79 # define PWPSLOT pw_passwd
80 # define GETPW getspwnam
81 # define crypt bigcrypt
95 extern const char *blurb(void);
97 static char *encrypted_root_passwd = 0;
98 static char *encrypted_user_passwd = 0;
101 # define ROOT "SYSTEM"
113 /* I think that just checking $USER here is not the best idea. */
117 /* It has been reported that getlogin() returns the wrong user id on some
118 very old SGI systems... And I've seen it return the string "rlogin"
119 sometimes! Screw it, using getpwuid() should be enough...
121 /* u = (char *) getlogin ();
124 /* getlogin() fails if not attached to a terminal; in that case, use
125 getpwuid(). (Note that in this case, we're not doing shadow stuff, since
126 all we're interested in is the name, not the password. So that should
127 still work. Right?) */
130 struct passwd *p = getpwuid (getuid ());
131 u = (p ? p->pw_name : 0);
134 return (u ? strdup(u) : 0);
142 char *u = getenv("USER");
143 return (u ? strdup(u) : 0);
150 passwd_known_p (const char *pw)
153 pw[0] != '*' && /* This would be sensible... */
154 strlen(pw) > 4); /* ...but this is what Solaris does. */
159 get_encrypted_passwd(const char *user)
164 { /* First check the shadow passwords. */
165 PWTYPE p = GETPW((char *) user);
166 if (p && passwd_known_p (p->PWPSLOT))
167 return strdup(p->PWPSLOT);
170 { /* Check non-shadow passwords too. */
171 struct passwd *p = getpwnam(user);
172 if (p && passwd_known_p (p->pw_passwd))
173 return strdup(p->pw_passwd);
177 fprintf (stderr, "%s: couldn't get password of \"%s\"\n",
178 blurb(), (user ? user : "(null)"));
185 /* This has to be called before we've changed our effective user ID,
186 because it might need privileges to get at the encrypted passwords.
187 Returns false if we weren't able to get any passwords, and therefore,
188 locking isn't possible. (It will also have written to stderr.)
194 lock_init (int argc, char **argv)
198 #ifdef HAVE_ENHANCED_PASSWD
199 set_auth_parameters(argc, argv);
200 check_auth_parameters();
201 #endif /* HAVE_DEC_ENHANCED */
204 encrypted_user_passwd = get_encrypted_passwd(u);
205 encrypted_root_passwd = get_encrypted_passwd(ROOT);
208 if (encrypted_user_passwd)
215 /* This can be called at any time, and says whether the typed password
216 belongs to either the logged in user (real uid, not effective); or
220 passwd_valid_p (const char *typed_passwd)
222 char *s = 0; /* note that on some systems, crypt() may return null */
224 if (encrypted_user_passwd &&
225 (s = (char *) crypt (typed_passwd, encrypted_user_passwd)) &&
226 !strcmp (s, encrypted_user_passwd))
229 /* do not allow root to have a null password. */
230 else if (typed_passwd[0] &&
231 encrypted_root_passwd &&
232 (s = (char *) crypt (typed_passwd, encrypted_root_passwd)) &&
233 !strcmp (s, encrypted_root_passwd))
241 Bool lock_init (int argc, char **argv) { return True; }
244 #endif /* NO_LOCKING -- whole file */