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 */
25 extern char *blurb(void);
37 #define countof(x) (sizeof((x))/sizeof(*(x)))
41 Bool (*init) (int argc, char **argv, Bool verbose_p);
42 Bool (*priv_init) (int argc, char **argv, Bool verbose_p);
43 Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
50 extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p);
51 extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
54 extern Bool pam_priv_init (int argc, char **argv, Bool verbose_p);
55 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
57 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
58 extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p);
59 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
62 /* The authorization methods to try, in order.
63 Note that the last one (the pwent version) is actually two auth methods,
64 since that code tries shadow passwords, and then non-shadow passwords.
65 (It's all in the same file since the APIs are randomly nearly-identical.)
67 struct auth_methods methods[] = {
69 { "Kerberos", kerberos_lock_init, 0, kerberos_passwd_valid_p,
73 { "PAM", 0, pam_priv_init, pam_passwd_valid_p,
76 { "normal", pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p,
82 lock_priv_init (int argc, char **argv, Bool verbose_p)
86 for (i = 0; i < countof(methods); i++)
88 if (!methods[i].priv_init)
89 methods[i].priv_initted_p = True;
91 methods[i].priv_initted_p = methods[i].priv_init (argc, argv,
94 if (methods[i].priv_initted_p)
97 fprintf (stderr, "%s: initialization of %s passwords failed.\n",
98 blurb(), methods[i].name);
105 lock_init (int argc, char **argv, Bool verbose_p)
109 for (i = 0; i < countof(methods); i++)
111 if (!methods[i].priv_initted_p) /* Bail if lock_priv_init failed. */
114 if (!methods[i].init)
115 methods[i].initted_p = True;
117 methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
119 if (methods[i].initted_p)
122 fprintf (stderr, "%s: initialization of %s passwords failed.\n",
123 blurb(), methods[i].name);
130 passwd_valid_p (const char *typed_passwd, Bool verbose_p)
133 for (i = 0; i < countof(methods); i++)
135 if (methods[i].initted_p &&
136 methods[i].valid_p (typed_passwd, verbose_p))
138 /* If we successfully authenticated by method N, but attempting
139 to authenticate by method N-1 failed, mention that (since if
140 an earlier authentication method fails and a later one succeeds,
141 something screwy is probably going on.)
143 if (verbose_p && i > 0)
145 for (j = 0; j < i; j++)
146 if (methods[j].initted_p)
148 "%s: authentication via %s passwords failed.\n",
149 blurb(), methods[j].name);
151 "%s: but authentication via %s passwords succeeded.\n",
152 blurb(), methods[i].name);
155 return True; /* Successfully authenticated! */
159 return False; /* Authentication failure. */
162 #endif /* NO_LOCKING -- whole file */