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 */
26 #include <sys/types.h>
36 # include <sys/param.h>
37 # if _BSDI_VERSION >= 199608
43 #if defined(HAVE_SHADOW_PASSWD) /* passwds live in /etc/shadow */
46 # define PWTYPE struct spwd *
47 # define PWPSLOT sp_pwdp
48 # define GETPW getspnam
50 #elif defined(HAVE_ENHANCED_PASSWD) /* passwds live in /tcb/files/auth/ */
51 /* M.Matsumoto <matsu@yao.sharp.co.jp> */
52 # include <sys/security.h>
55 # define PWTYPE struct pr_passwd *
56 # define PWPSLOT ufld.fd_encrypt
57 # define GETPW getprpwnam
59 #elif defined(HAVE_ADJUNCT_PASSWD)
61 # include <sys/label.h>
62 # include <sys/audit.h>
65 # define PWTYPE struct passwd_adjunct *
66 # define PWPSLOT pwa_passwd
67 # define GETPW getpwanam
69 #elif defined(HAVE_HPUX_PASSWD)
71 # include <hpsecurity.h>
74 # define PWTYPE struct s_passwd *
75 # define PWPSLOT pw_passwd
76 # define GETPW getspwnam
77 # define crypt bigcrypt
91 extern char *progname;
93 static char *encrypted_root_passwd = 0;
94 static char *encrypted_user_passwd = 0;
97 # define ROOT "SYSTEM"
109 /* I think that just checking $USER here is not the best idea. */
113 /* It has been reported that getlogin() returns the wrong user id on some
114 very old SGI systems... And I've seen it return the string "rlogin"
115 sometimes! Screw it, using getpwuid() should be enough...
117 /* u = (char *) getlogin ();
120 /* getlogin() fails if not attached to a terminal; in that case, use
121 getpwuid(). (Note that in this case, we're not doing shadow stuff, since
122 all we're interested in is the name, not the password. So that should
123 still work. Right?) */
126 struct passwd *p = getpwuid (getuid ());
127 u = (p ? p->pw_name : 0);
130 return (u ? strdup(u) : 0);
138 char *u = getenv("USER");
139 return (u ? strdup(u) : 0);
146 passwd_known_p (const char *pw)
149 pw[0] != '*' && /* This would be sensible... */
150 strlen(pw) > 4); /* ...but this is what Solaris does. */
155 get_encrypted_passwd(const char *user)
160 { /* First check the shadow passwords. */
161 PWTYPE p = GETPW((char *) user);
162 if (p && passwd_known_p (p->PWPSLOT))
163 return strdup(p->PWPSLOT);
166 { /* Check non-shadow passwords too. */
167 struct passwd *p = getpwnam(user);
168 if (p && passwd_known_p (p->pw_passwd))
169 return strdup(p->pw_passwd);
173 fprintf (stderr, "%s: couldn't get password of \"%s\"\n",
174 blurb(), (user ? user : "(null)"));
181 /* This has to be called before we've changed our effective user ID,
182 because it might need priveleges to get at the encrypted passwords.
183 Returns false if we weren't able to get any passwords, and therefore,
184 locking isn't possible. (It will also have written to stderr.)
190 lock_init (int argc, char **argv)
194 #ifdef HAVE_ENHANCED_PASSWD
195 set_auth_parameters(argc, argv);
196 check_auth_parameters();
197 #endif /* HAVE_DEC_ENHANCED */
200 encrypted_user_passwd = get_encrypted_passwd(u);
201 encrypted_root_passwd = get_encrypted_passwd(ROOT);
204 if (encrypted_user_passwd)
211 /* This can be called at any time, and says whether the typed password
212 belongs to either the logged in user (real uid, not effective); or
216 passwd_valid_p (const char *typed_passwd)
218 char *s = 0; /* note that on some systems, crypt() may return null */
220 if (encrypted_user_passwd &&
221 (s = (char *) crypt (typed_passwd, encrypted_user_passwd)) &&
222 !strcmp (s, encrypted_user_passwd))
225 /* do not allow root to have a null password. */
226 else if (typed_passwd[0] &&
227 encrypted_root_passwd &&
228 (s = (char *) crypt (typed_passwd, encrypted_root_passwd)) &&
229 !strcmp (s, encrypted_root_passwd))
237 Bool lock_init (int argc, char **argv) { return True; }
240 #endif /* NO_LOCKING -- whole file */