--- config.mk.orig 2013-10-09 16:23:24.000000000 +0200 +++ config.mk 2013-10-09 16:25:18.000000000 +0200 @@ -18,6 +18,9 @@ CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} +# To enable PAM-based authentication, remove -DHAVE_SHADOW_H from CPPFLAGS +# and add -DHAVE_PAM instead. Also, add -lpam to LDFLAGS. +# # On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS and add -DHAVE_BSD_AUTH # On OpenBSD and Darwin remove -lcrypt from LIBS --- slock.c.orig 2013-10-09 16:23:14.000000000 +0200 +++ slock.c 2013-10-09 16:23:18.000000000 +0200 @@ -23,6 +23,10 @@ #include #endif +#if HAVE_PAM +#include +#endif + typedef struct { int screen; Window root, win; @@ -44,7 +48,7 @@ exit(EXIT_FAILURE); } -#ifndef HAVE_BSD_AUTH +#if !defined(HAVE_BSD_AUTH) && !defined(HAVE_PAM) static const char * getpw(void) { /* only run as root */ const char *rval; @@ -74,8 +78,41 @@ } #endif +#ifdef HAVE_PAM +static int +slock_conv (int nof_msg, const struct pam_message **msg, struct pam_response **resp, void *data) { + struct pam_response *r = calloc (nof_msg, sizeof **resp); + if (r == NULL) { + die("slock: malloc: %s", strerror(errno)); + } + + while (nof_msg--) { + r[nof_msg].resp_retcode = 0; + r[nof_msg].resp = strdup (data); + } + + *resp = r; + + return PAM_SUCCESS; +} + +static int +auth_pam (const char *user, char *pass) { + static struct pam_conv conv = {slock_conv, NULL}; + pam_handle_t *ph; + + conv.appdata_ptr = pass; + + if (pam_start("slock", user, &conv, &ph) != PAM_SUCCESS) { + die("slock: pam_start"); + } + + return (pam_authenticate(ph, 0) == PAM_SUCCESS); +} +#endif + static void -#ifdef HAVE_BSD_AUTH +#if defined(HAVE_BSD_AUTH) || defined(HAVE_PAM) readpw(Display *dpy) #else readpw(Display *dpy, const char *pws) @@ -111,8 +148,10 @@ switch(ksym) { case XK_Return: passwd[len] = 0; -#ifdef HAVE_BSD_AUTH +#if defined (HAVE_BSD_AUTH) running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); +#elif defined (HAVE_PAM) + running = !auth_pam(getlogin(), passwd); #else running = strcmp(crypt(passwd, pws), pws); #endif @@ -233,7 +272,7 @@ int main(int argc, char **argv) { -#ifndef HAVE_BSD_AUTH +#if !defined(HAVE_BSD_AUTH) && !defined(HAVE_PAM) const char *pws; #endif Display *dpy; @@ -247,7 +286,7 @@ if(!getpwuid(getuid())) die("slock: no passwd entry for you"); -#ifndef HAVE_BSD_AUTH +#if !defined(HAVE_BSD_AUTH) && !defined(HAVE_PAM) pws = getpw(); #endif @@ -273,7 +312,7 @@ } /* Everything is now blank. Now wait for the correct password. */ -#ifdef HAVE_BSD_AUTH +#if defined(HAVE_BSD_AUTH) || defined(HAVE_PAM) readpw(dpy); #else readpw(dpy, pws);