http://ftp.x.org/contrib/applications/xscreensaver-3.03.tar.gz
[xscreensaver] / driver / passwd.c
1 /* passwd.c --- verifying typed passwords with the OS.
2  * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
3  *
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 
10  * implied warranty.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #ifndef NO_LOCKING  /* whole file */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #ifdef HAVE_UNISTD_H
22 # include <unistd.h>
23 #endif
24
25 extern char *blurb(void);
26
27
28 /* blargh */
29 #undef  Bool
30 #undef  True
31 #undef  False
32 #define Bool  int
33 #define True  1
34 #define False 0
35
36 #undef countof
37 #define countof(x) (sizeof((x))/sizeof(*(x)))
38
39 struct auth_methods {
40   const char *name;
41   Bool (*init) (int argc, char **argv, Bool verbose_p);
42   Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
43   Bool initted_p;
44 };
45
46
47 #ifdef HAVE_KERBEROS
48 extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p);
49 extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
50 #endif
51 #ifdef HAVE_PAM
52 extern Bool pam_lock_init (int argc, char **argv, Bool verbose_p);
53 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
54 #endif
55 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
56 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
57
58
59 /* The authorization methods to try, in order.
60    Note that the last one (the pwent version) is actually two auth methods,
61    since that code tries shadow passwords, and then non-shadow passwords.
62    (It's all in the same file since the APIs are randomly nearly-identical.)
63  */
64 struct auth_methods methods[] = {
65 # ifdef HAVE_KERBEROS
66   { "Kerberos", kerberos_lock_init,     kerberos_passwd_valid_p, False },
67 # endif
68 # ifdef HAVE_PAM
69   { "PAM",      pam_lock_init,          pam_passwd_valid_p,      False },
70 # endif
71   { "normal",   pwent_lock_init,        pwent_passwd_valid_p,    False }
72 };
73
74
75 Bool
76 lock_init (int argc, char **argv, Bool verbose_p)
77 {
78   int i;
79   Bool any_ok = False;
80   for (i = 0; i < countof(methods); i++)
81     {
82       methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
83       if (methods[i].initted_p)
84         any_ok = True;
85       else if (verbose_p)
86         fprintf (stderr, "%s: initialization of %s passwords failed.\n",
87                  blurb(), methods[i].name);
88     }
89   return any_ok;
90 }
91
92
93 Bool 
94 passwd_valid_p (const char *typed_passwd, Bool verbose_p)
95 {
96   int i, j;
97   for (i = 0; i < countof(methods); i++)
98     {
99       if (methods[i].initted_p &&
100           methods[i].valid_p (typed_passwd, verbose_p))
101         {
102           /* If we successfully authenticated by method N, but attempting
103              to authenticate by method N-1 failed, mention that (since if
104              an earlier authentication method fails and a later one succeeds,
105              something screwy is probably going on.)
106            */
107           if (verbose_p)
108             {
109               for (j = 0; j < i; j++)
110                 if (methods[j].initted_p)
111                   fprintf (stderr,
112                            "%s: authentication via %s passwords failed.\n",
113                            blurb(), methods[j].name);
114               fprintf (stderr,
115                        "%s: but authentication via %s passwords succeeded.\n",
116                        blurb(), methods[i].name);
117             }
118
119           return True;          /* Successfully authenticated! */
120         }
121     }
122
123   return False;                 /* Authentication failure. */
124 }
125
126 #endif /* NO_LOCKING -- whole file */