PATCH: crypt(3) password support for pam_userdb
Paul Walmsley
paul at booyaka.com
Fri Aug 20 02:11:06 UTC 2004
Hello,
while converting a PureFTPd installation to vsftpd, we needed pam_userdb
to authenticate against crypt(3)'d passwords stored in its password
database. The following patch against pam_userdb in Linux-PAM-0.77
implements this.
After this patch is installed, the default behavior is to use plaintext
passwords, the same as the current version of pam_userdb. But if
'crypt=crypt' is included in the PAM service configuration file,
pam_userdb will expect to find crypted passwords in its database.
Comments welcome.
- Paul
diff -ru Linux-PAM-0.77-old/modules/pam_userdb/Makefile Linux-PAM-0.77/modules/pam_userdb/Makefile
--- Linux-PAM-0.77-old/modules/pam_userdb/Makefile 2001-05-08 01:03:55.000000000 -0500
+++ Linux-PAM-0.77/modules/pam_userdb/Makefile 2004-08-19 20:51:52.000000000 -0500
@@ -24,6 +24,11 @@
endif
endif
+ifeq ($(HAVE_LIBCRYPT),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lcrypt
+endif
+
+
ifeq ($(WHICH_DB),none)
include ../dont_makefile
diff -ru Linux-PAM-0.77-old/modules/pam_userdb/pam_userdb.c Linux-PAM-0.77/modules/pam_userdb/pam_userdb.c
--- Linux-PAM-0.77-old/modules/pam_userdb/pam_userdb.c 2001-11-25 21:27:40.000000000 -0600
+++ Linux-PAM-0.77/modules/pam_userdb/pam_userdb.c 2004-08-19 20:51:52.000000000 -0500
@@ -57,6 +57,7 @@
}
char * database = NULL;
+char * cryptmode = NULL;
static int ctrl = 0;
static int _pam_parse(int argc, const char **argv)
@@ -77,6 +78,11 @@
if (database == NULL)
_pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
*argv);
+ } else if (!strncasecmp(*argv,"crypt=", 6)) {
+ cryptmode = strdup((*argv) + 6);
+ if (cryptmode == NULL)
+ _pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
+ *argv);
} else {
_pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
}
@@ -138,15 +144,58 @@
if (data.dptr != NULL) {
int compare = 0;
-
- if (strlen(pass) != data.dsize) {
+
+ if (strncasecmp(cryptmode, "crypt", 5) == 0) {
+
+ /* crypt(3) password storage */
+
+ char *cryptpw;
+ char salt[2];
+
+ if (data.dsize != 13) {
+ compare = -2;
+ } else if (ctrl & PAM_ICASE_ARG) {
+ compare = -2;
+ } else {
+ salt[0] = *data.dptr;
+ salt[1] = *(data.dptr + 1);
+
+ cryptpw = crypt (pass, salt);
+
+ if (cryptpw) {
+ compare = strncasecmp (data.dptr, cryptpw, data.dsize);
+ } else {
+ compare = -2;
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "crypt() returned NULL");
+ }
+ };
+
+ };
+
+ } else {
+
+ /* Unknown password encryption method -
+ * default to plaintext password storage
+ */
+
+ if (strlen(pass) != data.dsize) {
compare = 1;
- } else if (ctrl & PAM_ICASE_ARG) {
+ } else if (ctrl & PAM_ICASE_ARG) {
compare = strncasecmp(data.dptr, pass, data.dsize);
- } else {
+ } else {
compare = strncmp(data.dptr, pass, data.dsize);
+ }
+
+ if (strncasecmp(cryptmode, "none", 4) && ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "invalid value for crypt parameter: %s",
+ cryptmode);
+ _pam_log(LOG_INFO, "defaulting to plaintext password mode");
+ }
+
}
- dbm_close(dbm);
+
+ dbm_close(dbm);
if (compare == 0)
return 0; /* match */
else
diff -ru Linux-PAM-0.77-old/modules/pam_userdb/README Linux-PAM-0.77/modules/pam_userdb/README
--- Linux-PAM-0.77-old/modules/pam_userdb/README 2000-06-20 17:12:09.000000000 -0500
+++ Linux-PAM-0.77/modules/pam_userdb/README 2004-08-19 20:51:52.000000000 -0500
@@ -9,9 +9,17 @@
db=[path] use the [path] database for performing lookup. There
is no default; the module will return PAM_IGNORE if
no database is provided.
-
+
+ crypt=[mode] indicates whether encrypted or plaintext passwords
+ are stored in the database. If [mode] is "crypt",
+ passwords should be stored in the database in
+ crypt(3) form. If [mode] is "none" or any other
+ value, passwords should be stored in the database in
+ plaintext.
+
icase make the password verification to be case insensitive
(ie when working with registration numbers and such)
+ only works with plaintext password storage.
dump dump all the entries in the database to the log (eek,
don't do this by default!)
More information about the Pam-list
mailing list