1 /* passwd.c --- verifying typed passwords with the OS.
2 * xscreensaver, Copyright (c) 1993-2004 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);
26 extern void check_for_leaks (const char *where);
38 #define countof(x) (sizeof((x))/sizeof(*(x)))
42 Bool (*init) (int argc, char **argv, Bool verbose_p);
43 Bool (*priv_init) (int argc, char **argv, Bool verbose_p);
44 Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
51 extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p);
52 extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
55 extern Bool pam_priv_init (int argc, char **argv, Bool verbose_p);
56 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
58 #ifdef PASSWD_HELPER_PROGRAM
59 extern Bool ext_priv_init (int argc, char **argv, Bool verbose_p);
60 extern Bool ext_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
62 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
63 extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p);
64 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
66 Bool lock_priv_init (int argc, char **argv, Bool verbose_p);
67 Bool lock_init (int argc, char **argv, Bool verbose_p);
68 Bool passwd_valid_p (const char *typed_passwd, Bool verbose_p);
70 /* The authorization methods to try, in order.
71 Note that the last one (the pwent version) is actually two auth methods,
72 since that code tries shadow passwords, and then non-shadow passwords.
73 (It's all in the same file since the APIs are randomly nearly-identical.)
75 struct auth_methods methods[] = {
77 { "Kerberos", kerberos_lock_init, 0, kerberos_passwd_valid_p,
81 { "PAM", 0, pam_priv_init, pam_passwd_valid_p,
84 # ifdef PASSWD_HELPER_PROGRAM
85 { "external", 0, ext_priv_init, ext_passwd_valid_p,
88 { "normal", pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p,
94 lock_priv_init (int argc, char **argv, Bool verbose_p)
98 for (i = 0; i < countof(methods); i++)
100 if (!methods[i].priv_init)
101 methods[i].priv_initted_p = True;
103 methods[i].priv_initted_p = methods[i].priv_init (argc, argv,
106 if (methods[i].priv_initted_p)
109 fprintf (stderr, "%s: initialization of %s passwords failed.\n",
110 blurb(), methods[i].name);
117 lock_init (int argc, char **argv, Bool verbose_p)
121 for (i = 0; i < countof(methods); i++)
123 if (!methods[i].priv_initted_p) /* Bail if lock_priv_init failed. */
126 if (!methods[i].init)
127 methods[i].initted_p = True;
129 methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
131 if (methods[i].initted_p)
134 fprintf (stderr, "%s: initialization of %s passwords failed.\n",
135 blurb(), methods[i].name);
142 passwd_valid_p (const char *typed_passwd, Bool verbose_p)
145 for (i = 0; i < countof(methods); i++)
147 int ok_p = (methods[i].initted_p &&
148 methods[i].valid_p (typed_passwd, verbose_p));
150 check_for_leaks (methods[i].name);
154 /* If we successfully authenticated by method N, but attempting
155 to authenticate by method N-1 failed, mention that (since if
156 an earlier authentication method fails and a later one succeeds,
157 something screwy is probably going on.)
159 if (verbose_p && i > 0)
161 for (j = 0; j < i; j++)
162 if (methods[j].initted_p)
164 "%s: authentication via %s passwords failed.\n",
165 blurb(), methods[j].name);
167 "%s: authentication via %s passwords succeeded.\n",
168 blurb(), methods[i].name);
171 return True; /* Successfully authenticated! */
175 return False; /* Authentication failure. */
178 #endif /* NO_LOCKING -- whole file */