1 /* passwd-helper.c --- verifying typed passwords with external helper program
2 * written by Olaf Kirch <okir@suse.de>
3 * xscreensaver, Copyright (c) 1993-2005 Jamie Zawinski <jwz@jwz.org>
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation. No representations are made about the suitability of this
10 * software for any purpose. It is provided "as is" without express or
14 /* The idea here is to be able to run xscreensaver without any setuid bits.
15 * Password verification happens through an external program that you feed
16 * your password to on stdin. The external command is invoked with a user
19 * The external helper does whatever authentication is necessary. Currently,
20 * SuSE uses "unix2_chkpwd", which is a variation of "unix_chkpwd" from the
23 * Normally, the password helper should just authenticate the calling user
24 * (i.e. based on the caller's real uid). This is in order to prevent
25 * brute-forcing passwords in a shadow environment. A less restrictive
26 * approach would be to allow verifying other passwords as well, but always
27 * with a 2 second delay or so. (Not sure what SuSE's "unix2_chkpwd"
29 * -- Olaf Kirch <okir@suse.de>, 16-Dec-2003
36 #ifndef NO_LOCKING /* whole file */
38 #include <X11/Xlib.h> /* not used for much... */
40 /* This file doesn't need the Xt headers, so stub these types out... */
42 #define XtAppContext void*
43 #define XrmDatabase void*
44 #define XtIntervalId void*
45 #define XtPointer void*
48 #include "xscreensaver.h"
57 #include <sys/types.h>
64 ext_run (const char *user, const char *typed_passwd, int verbose_p)
73 fprintf (stderr, "%s: ext_run (%s, %s)\n",
74 blurb(), PASSWD_HELPER_PROGRAM, user);
78 if ((pid = fork()) < 0) {
89 /* Helper is invoked as helper service-name [user] */
90 execlp(PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM, "xscreensaver", user, NULL);
92 fprintf(stderr, "%s: %s\n", PASSWD_HELPER_PROGRAM,
99 /* Write out password to helper process */
102 write(pfd[1], typed_passwd, strlen(typed_passwd));
105 while (waitpid(pid, &status, 0) < 0) {
109 fprintf(stderr, "%s: ext_run: waitpid failed: %s\n",
110 blurb(), strerror(errno));
117 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
124 /* This can be called at any time, and says whether the typed password
125 belongs to either the logged in user (real uid, not effective); or
129 ext_passwd_valid_p (const char *typed_passwd, int verbose_p)
134 if ((pw = getpwuid(getuid())) != NULL)
135 res = ext_run (pw->pw_name, typed_passwd, verbose_p);
138 #ifdef ALLOW_ROOT_PASSWD
140 res = ext_run ("root", typed_passwd, verbose_p);
141 #endif /* ALLOW_ROOT_PASSWD */
148 ext_priv_init (int argc, char **argv, int verbose_p)
150 /* Make sure the passwd helper exists */
151 if (access(PASSWD_HELPER_PROGRAM, X_OK) < 0) {
153 "%s: warning: %s does not exist.\n"
154 "%s: password authentication via "
155 "external helper will not work.\n",
156 blurb(), PASSWD_HELPER_PROGRAM, blurb());
162 #endif /* NO_LOCKING -- whole file */