--- 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 <bsd_auth.h>
 #endif
 
+#if HAVE_PAM
+#include <security/pam_appl.h>
+#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);
