1 /* passwd.c --- verifying typed passwords with the OS.
2 * xscreensaver, Copyright (c) 1993-1997 Jamie Zawinski <jwz@netscape.com>
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>
35 # include <sys/param.h>
36 # if _BSDI_VERSION >= 199608
42 #if defined(HAVE_SHADOW_PASSWD) /* passwds live in /etc/shadow */
45 # define PWTYPE struct spwd *
46 # define PWPSLOT sp_pwdp
47 # define GETPW getspnam
49 #elif defined(HAVE_ENHANCED_PASSWD) /* passwds live in /tcb/files/auth/ */
50 /* M.Matsumoto <matsu@yao.sharp.co.jp> */
51 # include <sys/security.h>
54 # define PWTYPE struct pr_passwd *
55 # define PWPSLOT ufld.fd_encrypt
56 # define GETPW getprpwnam
58 #elif defined(HAVE_ADJUNCT_PASSWD)
60 # include <sys/label.h>
61 # include <sys/audit.h>
64 # define PRTYPE passwd_adjunct *
65 # define PWPSLOT pwa_passwd
66 # define GETPW getpwanam
68 #elif defined(HAVE_HPUX_PASSWD)
70 # include <hpsecurity.h>
73 # define PRTYPE struct s_passwd *
74 # define PWPSLOT pw_passwd
75 # define GETPW getspwnam
76 # define crypt bigcrypt
90 extern char *progname;
92 static char *encrypted_root_passwd = 0;
93 static char *encrypted_user_passwd = 0;
96 # define ROOT "SYSTEM"
108 /* I think that just checking $USER here is not the best idea. */
112 /* It has been reported that getlogin() returns the wrong user id on some
113 very old SGI systems... And I've seen it return the string "rlogin"
114 sometimes! Screw it, using getpwuid() should be enough...
116 /* u = (char *) getlogin ();
119 /* getlogin() fails if not attached to a terminal; in that case, use
120 getpwuid(). (Note that in this case, we're not doing shadow stuff, since
121 all we're interested in is the name, not the password. So that should
122 still work. Right?) */
125 struct passwd *p = getpwuid (getuid ());
126 u = (p ? p->pw_name : 0);
129 return (u ? strdup(u) : 0);
137 char *u = getenv("USER");
138 return (u ? strdup(u) : 0);
145 passwd_known_p (const char *pw)
148 pw[0] != '*' && /* This would be sensible... */
149 strlen(pw) > 4); /* ...but this is what Solaris does. */
154 get_encrypted_passwd(const char *user)
159 { /* First check the shadow passwords. */
160 PWTYPE p = GETPW((char *) user);
161 if (p && passwd_known_p (p->PWPSLOT))
162 return strdup(p->PWPSLOT);
165 { /* Check non-shadow passwords too. */
166 struct passwd *p = getpwnam(user);
167 if (p && passwd_known_p (p->pw_passwd))
168 return strdup(p->pw_passwd);
172 fprintf (stderr, "%s: couldn't get password of \"%s\"\n",
173 progname, (user ? user : "(null)"));
180 /* This has to be called before we've changed our effective user ID,
181 because it might need priveleges to get at the encrypted passwords.
182 Returns false if we weren't able to get any passwords, and therefore,
183 locking isn't possible. (It will also have written to stderr.)
189 lock_init (int argc, char **argv)
193 #ifdef HAVE_ENHANCED_PASSWD
194 set_auth_parameters(argc, argv);
195 check_auth_parameters();
196 #endif /* HAVE_DEC_ENHANCED */
199 encrypted_user_passwd = get_encrypted_passwd(u);
200 encrypted_root_passwd = get_encrypted_passwd(ROOT);
203 if (encrypted_user_passwd)
210 /* This can be called at any time, and says whether the typed password
211 belongs to either the logged in user (real uid, not effective); or
215 passwd_valid_p (const char *typed_passwd)
217 char *s = 0; /* note that on some systems, crypt() may return null */
219 if (encrypted_user_passwd &&
220 (s = (char *) crypt (typed_passwd, encrypted_user_passwd)) &&
221 !strcmp (s, encrypted_user_passwd))
224 /* do not allow root to have a null password. */
225 else if (typed_passwd[0] &&
226 encrypted_root_passwd &&
227 (s = (char *) crypt (typed_passwd, encrypted_root_passwd)) &&
228 !strcmp (s, encrypted_root_passwd))
236 Bool lock_init (int argc, char **argv) { return True; }
240 #endif /* NO_LOCKING -- whole file */