http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.16.tar.gz
[xscreensaver] / driver / passwd.c
index 25b3b04880ab2d41d7b2b279aa64b380fbc8931e..d5a358c571569daafc7c892bd3413a921175eac5 100644 (file)
@@ -1,5 +1,5 @@
 /* passwd.c --- verifying typed passwords with the OS.
- * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2004 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -23,6 +23,7 @@
 #endif
 
 extern char *blurb(void);
+extern void check_for_leaks (const char *where);
 
 
 /* blargh */
@@ -39,8 +40,10 @@ extern char *blurb(void);
 struct auth_methods {
   const char *name;
   Bool (*init) (int argc, char **argv, Bool verbose_p);
+  Bool (*priv_init) (int argc, char **argv, Bool verbose_p);
   Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
   Bool initted_p;
+  Bool priv_initted_p;
 };
 
 
@@ -49,10 +52,15 @@ extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p);
 extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 #endif
 #ifdef HAVE_PAM
-extern Bool pam_lock_init (int argc, char **argv, Bool verbose_p);
+extern Bool pam_priv_init (int argc, char **argv, Bool verbose_p);
 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 #endif
+#ifdef PASSWD_HELPER_PROGRAM
+extern Bool ext_priv_init (int argc, char **argv, Bool verbose_p);
+extern Bool ext_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
+#endif
 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
+extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p);
 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 
 
@@ -63,15 +71,45 @@ extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
  */
 struct auth_methods methods[] = {
 # ifdef HAVE_KERBEROS
-  { "Kerberos",        kerberos_lock_init,     kerberos_passwd_valid_p, False },
+  { "Kerberos",         kerberos_lock_init, 0, kerberos_passwd_valid_p,
+                        False, False },
 # endif
 # ifdef HAVE_PAM
-  { "PAM",     pam_lock_init,          pam_passwd_valid_p,      False },
+  { "PAM",              0, pam_priv_init, pam_passwd_valid_p, 
+                        False, False },
 # endif
-  { "normal",  pwent_lock_init,        pwent_passwd_valid_p,    False }
+# ifdef PASSWD_HELPER_PROGRAM
+  { "external",                0, ext_priv_init, ext_passwd_valid_p,
+                       False, False },
+#endif
+  { "normal",           pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p,
+                        False, False }
 };
 
 
+Bool
+lock_priv_init (int argc, char **argv, Bool verbose_p)
+{
+  int i;
+  Bool any_ok = False;
+  for (i = 0; i < countof(methods); i++)
+    {
+      if (!methods[i].priv_init)
+        methods[i].priv_initted_p = True;
+      else
+        methods[i].priv_initted_p = methods[i].priv_init (argc, argv,
+                                                          verbose_p);
+
+      if (methods[i].priv_initted_p)
+        any_ok = True;
+      else if (verbose_p)
+        fprintf (stderr, "%s: initialization of %s passwords failed.\n",
+                 blurb(), methods[i].name);
+    }
+  return any_ok;
+}
+
+
 Bool
 lock_init (int argc, char **argv, Bool verbose_p)
 {
@@ -79,7 +117,14 @@ lock_init (int argc, char **argv, Bool verbose_p)
   Bool any_ok = False;
   for (i = 0; i < countof(methods); i++)
     {
-      methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
+      if (!methods[i].priv_initted_p)  /* Bail if lock_priv_init failed. */
+        continue;
+
+      if (!methods[i].init)
+        methods[i].initted_p = True;
+      else
+        methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
+
       if (methods[i].initted_p)
         any_ok = True;
       else if (verbose_p)
@@ -96,15 +141,19 @@ passwd_valid_p (const char *typed_passwd, Bool verbose_p)
   int i, j;
   for (i = 0; i < countof(methods); i++)
     {
-      if (methods[i].initted_p &&
-          methods[i].valid_p (typed_passwd, verbose_p))
+      int ok_p = (methods[i].initted_p &&
+                  methods[i].valid_p (typed_passwd, verbose_p));
+
+      check_for_leaks (methods[i].name);
+
+      if (ok_p)
         {
           /* If we successfully authenticated by method N, but attempting
              to authenticate by method N-1 failed, mention that (since if
              an earlier authentication method fails and a later one succeeds,
              something screwy is probably going on.)
            */
-          if (verbose_p)
+          if (verbose_p && i > 0)
             {
               for (j = 0; j < i; j++)
                 if (methods[j].initted_p)
@@ -112,7 +161,7 @@ passwd_valid_p (const char *typed_passwd, Bool verbose_p)
                            "%s: authentication via %s passwords failed.\n",
                            blurb(), methods[j].name);
               fprintf (stderr,
-                       "%s: but authentication via %s passwords succeeded.\n",
+                       "%s: authentication via %s passwords succeeded.\n",
                        blurb(), methods[i].name);
             }