http://ftp.x.org/contrib/applications/xscreensaver-3.10.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 (*priv_init) (int argc, char **argv, Bool verbose_p);
43   Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
44   Bool initted_p;
45   Bool priv_initted_p;
46 };
47
48
49 #ifdef HAVE_KERBEROS
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);
52 #endif
53 #ifdef HAVE_PAM
54 extern Bool pam_lock_init (int argc, char **argv, Bool verbose_p);
55 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
56 #endif
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);
60
61
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.)
66  */
67 struct auth_methods methods[] = {
68 # ifdef HAVE_KERBEROS
69   { "Kerberos",         kerberos_lock_init, 0, kerberos_passwd_valid_p,
70                         False, False },
71 # endif
72 # ifdef HAVE_PAM
73   { "PAM",              pam_lock_init, 0, pam_passwd_valid_p, 
74                         False, False },
75 # endif
76   { "normal",           pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p,
77                         False, False }
78 };
79
80
81 Bool
82 lock_priv_init (int argc, char **argv, Bool verbose_p)
83 {
84   int i;
85   Bool any_ok = False;
86   for (i = 0; i < countof(methods); i++)
87     {
88       if (!methods[i].priv_init)
89         methods[i].priv_initted_p = True;
90       else
91         methods[i].priv_initted_p = methods[i].priv_init (argc, argv,
92                                                           verbose_p);
93
94       if (methods[i].priv_initted_p)
95         any_ok = True;
96       else if (verbose_p)
97         fprintf (stderr, "%s: initialization of %s passwords failed.\n",
98                  blurb(), methods[i].name);
99     }
100   return any_ok;
101 }
102
103
104 Bool
105 lock_init (int argc, char **argv, Bool verbose_p)
106 {
107   int i;
108   Bool any_ok = False;
109   for (i = 0; i < countof(methods); i++)
110     {
111       if (!methods[i].priv_initted_p)   /* Bail if lock_priv_init failed. */
112         continue;
113
114       methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
115       if (methods[i].initted_p)
116         any_ok = True;
117       else if (verbose_p)
118         fprintf (stderr, "%s: initialization of %s passwords failed.\n",
119                  blurb(), methods[i].name);
120     }
121   return any_ok;
122 }
123
124
125 Bool 
126 passwd_valid_p (const char *typed_passwd, Bool verbose_p)
127 {
128   int i, j;
129   for (i = 0; i < countof(methods); i++)
130     {
131       if (methods[i].initted_p &&
132           methods[i].valid_p (typed_passwd, verbose_p))
133         {
134           /* If we successfully authenticated by method N, but attempting
135              to authenticate by method N-1 failed, mention that (since if
136              an earlier authentication method fails and a later one succeeds,
137              something screwy is probably going on.)
138            */
139           if (verbose_p)
140             {
141               for (j = 0; j < i; j++)
142                 if (methods[j].initted_p)
143                   fprintf (stderr,
144                            "%s: authentication via %s passwords failed.\n",
145                            blurb(), methods[j].name);
146               fprintf (stderr,
147                        "%s: but authentication via %s passwords succeeded.\n",
148                        blurb(), methods[i].name);
149             }
150
151           return True;          /* Successfully authenticated! */
152         }
153     }
154
155   return False;                 /* Authentication failure. */
156 }
157
158 #endif /* NO_LOCKING -- whole file */