summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile2
-rw-r--r--modules/Simple.Rules2
-rw-r--r--modules/pam_filter/pam_filter.c8
-rw-r--r--modules/pam_limits/Makefile3
-rw-r--r--modules/pam_pwdb/Makefile5
-rw-r--r--modules/pam_rhosts/pam_rhosts_auth.c20
-rw-r--r--modules/pam_unix/Makefile23
-rw-r--r--modules/pam_unix/bigcrypt_main.c18
-rw-r--r--modules/pam_userdb/README29
-rw-r--r--modules/pam_userdb/conv.c2
-rw-r--r--modules/pam_userdb/create.pl2
-rw-r--r--modules/pam_userdb/pam_userdb.c258
-rw-r--r--modules/pam_userdb/pam_userdb.h3
13 files changed, 289 insertions, 86 deletions
diff --git a/modules/Makefile b/modules/Makefile
index 93891029..d16dedcf 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -8,7 +8,7 @@
include ../Make.Rules
-MODDIRS=$(shell /bin/ls -d pam_*)
+MODDIRS=$(shell /bin/ls -d pam_*/Makefile | cut -f1 -d/)
all:
@echo building the static modutil library
diff --git a/modules/Simple.Rules b/modules/Simple.Rules
index 97f419a8..c12ede3a 100644
--- a/modules/Simple.Rules
+++ b/modules/Simple.Rules
@@ -13,6 +13,8 @@
# $(MODULE_SIMPLE_EXTRAFILES) - other files to build (no .c suffix)
#
+-include ../Make.Rules
+
LIBFILES = $(TITLE) $(MODULE_SIMPLE_EXTRAFILES)
LIBSRC = $(addsuffix .c,$(LIBFILES))
LIBOBJ = $(addsuffix .o,$(LIBFILES))
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c
index e9a0494b..d3462f40 100644
--- a/modules/pam_filter/pam_filter.c
+++ b/modules/pam_filter/pam_filter.c
@@ -150,7 +150,7 @@ static int process_args(pam_handle_t *pamh
/* the "ARGS" variable */
-#define ARGS_OFFSET 5 /* sizeof('ARGS='); */
+#define ARGS_OFFSET 5 /* strlen('ARGS='); */
#define ARGS_NAME "ARGS="
size += ARGS_OFFSET;
@@ -174,7 +174,7 @@ static int process_args(pam_handle_t *pamh
/* the "SERVICE" variable */
-#define SERVICE_OFFSET 8 /* sizeof('SERVICE='); */
+#define SERVICE_OFFSET 8 /* strlen('SERVICE='); */
#define SERVICE_NAME "SERVICE="
retval = pam_get_item(pamh, PAM_SERVICE, (const void **)&tmp);
@@ -204,7 +204,7 @@ static int process_args(pam_handle_t *pamh
/* the "USER" variable */
-#define USER_OFFSET 5 /* sizeof('USER='); */
+#define USER_OFFSET 5 /* strlen('USER='); */
#define USER_NAME "USER="
tmp = NULL;
@@ -231,7 +231,7 @@ static int process_args(pam_handle_t *pamh
/* the "USER" variable */
-#define TYPE_OFFSET 5 /* sizeof('TYPE='); */
+#define TYPE_OFFSET 5 /* strlen('TYPE='); */
#define TYPE_NAME "TYPE="
size = TYPE_OFFSET+strlen(type);
diff --git a/modules/pam_limits/Makefile b/modules/pam_limits/Makefile
index 0a481fe8..5aeb73ce 100644
--- a/modules/pam_limits/Makefile
+++ b/modules/pam_limits/Makefile
@@ -27,6 +27,9 @@ endif
include ../Simple.Rules
+#else
+#include ../dont_makefile
+#endif
else
include ../dont_makefile
diff --git a/modules/pam_pwdb/Makefile b/modules/pam_pwdb/Makefile
index 2b581dcd..fa0e1b02 100644
--- a/modules/pam_pwdb/Makefile
+++ b/modules/pam_pwdb/Makefile
@@ -17,6 +17,9 @@ EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
ifeq ($(HAVE_LIBCRYPT),yes)
EXTRALS += -lcrypt
endif
+ifeq ($(HAVE_LIBNSL),yes)
+ EXTRALS += -lnsl
+endif
TITLE=pam_pwdb
CHKPWD=pwdb_chkpwd
@@ -53,7 +56,7 @@ info:
$(CHKPWD): pwdb_chkpwd.o md5_good.o md5_broken.o \
md5_crypt_good.o md5_crypt_broken.o
- $(CC) -o $(CHKPWD) $^ -lpwdb
+ $(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDFLAGS) -lpwdb $(EXTRALS)
pwdb_chkpwd.o: pwdb_chkpwd.c pam_unix_md.-c bigcrypt.-c
diff --git a/modules/pam_rhosts/pam_rhosts_auth.c b/modules/pam_rhosts/pam_rhosts_auth.c
index 374318dc..b41b708d 100644
--- a/modules/pam_rhosts/pam_rhosts_auth.c
+++ b/modules/pam_rhosts/pam_rhosts_auth.c
@@ -178,7 +178,7 @@ static void set_option (struct _options *opts, const char *arg)
return;
}
- if (strcmp(arg, "superuser=") == 0) {
+ if (strncmp(arg, "superuser=", sizeof("superuser=")-1) == 0) {
opts->superuser = arg+sizeof("superuser=")-1;
return;
}
@@ -293,7 +293,7 @@ __icheckhost (pam_handle_t *pamh, struct _options *opts, U32 raddr
hp = gethostbyname(lhost);
if (hp == NULL)
return (0);
-
+
/* Spin through ip addresses. */
for (pp = hp->h_addr_list; *pp; ++pp)
if (!memcmp (&raddr, *pp, sizeof (U32)))
@@ -408,7 +408,7 @@ __ivaliduser (pam_handle_t *pamh, struct _options *opts,
user = p; /* this is the user's name */
while (*p && !isspace(*p))
++p; /* find end of user's name */
- } else
+ } else
user = p;
*p = '\0'; /* <nul> terminate username (+host?) */
@@ -480,7 +480,7 @@ pam_iruserok(pam_handle_t *pamh,
No hosts.equiv file on system.
} */
}
-
+
if ( opts->opt_no_rhosts )
return 1;
@@ -490,10 +490,10 @@ pam_iruserok(pam_handle_t *pamh,
pwd = _pammodutil_getpwnam(pamh, luser);
if (pwd == NULL) {
- /*
+ /*
* luser is assumed to be valid because of an earlier check for uid = 0
* we don't log this error twice. However, this shouldn't happen !
- * --cristiang
+ * --cristiang
*/
return(1);
}
@@ -652,9 +652,9 @@ pam_ruserok (pam_handle_t *pamh,
*/
static int _pam_auth_rhosts (pam_handle_t *pamh,
- int flags,
+ int flags,
int argc,
- const char **argv)
+ const char **argv)
{
int retval;
const char *luser = NULL;
@@ -745,9 +745,9 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
/* --- authentication management functions --- */
PAM_EXTERN
-int pam_sm_authenticate (pam_handle_t *pamh,
+int pam_sm_authenticate (pam_handle_t *pamh,
int flags,
- int argc,
+ int argc,
const char **argv)
{
int retval;
diff --git a/modules/pam_unix/Makefile b/modules/pam_unix/Makefile
index 3fe0e8ae..24ffd4b5 100644
--- a/modules/pam_unix/Makefile
+++ b/modules/pam_unix/Makefile
@@ -18,6 +18,19 @@ include ../../Make.Rules
#USE_CRACKLIB=-D"USE_CRACKLIB"
#endif
+ifeq ($(shell if [ -f /usr/lib/cracklib_dict.hwm ]; then echo yes ; fi),yes)
+ CRACKLIB_DICTPATH=/usr/lib/cracklib_dict
+else
+ CRACKLIB_DICTPATH=/usr/share/dict/cracklib_dict
+endif
+EXTRAS += -DCRACKLIB_DICTS=\"$(CRACKLIB_DICTPATH)\"
+
+ifeq ($(HAVE_LIBCRYPT),yes)
+ EXTRALS += -lcrypt
+endif
+ifeq ($(HAVE_LIBNSL),yes)
+ EXTRALS += -lnsl
+endif
# do you want to use lckpwdf?
ifeq ($(WITH_LCKPWDF),yes)
USE_LCKPWDF=-D"USE_LCKPWDF"
@@ -37,6 +50,8 @@ endif
CHKPWD=unix_chkpwd
+BIGCRYPT=bigcrypt
+
EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
@@ -74,7 +89,8 @@ endif
########################### don't edit below #######################
-all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) register
+all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) $(BIGCRYPT) \
+ register
dynamic/%.o : %.c
$(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
@@ -125,7 +141,10 @@ endif
$(CHKPWD): unix_chkpwd.o md5_good.o md5_broken.o \
md5_crypt_good.o md5_crypt_broken.o \
bigcrypt.o
- $(CC) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
+ $(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
+
+$(BIGCRYPT): bigcrypt_main.o bigcrypt.o
+ $(CC) -o $(BIGCRYPT) $^ $(LDLIBS) $(LIBCRYPT)
unix_chkpwd.o: unix_chkpwd.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
diff --git a/modules/pam_unix/bigcrypt_main.c b/modules/pam_unix/bigcrypt_main.c
new file mode 100644
index 00000000..70819072
--- /dev/null
+++ b/modules/pam_unix/bigcrypt_main.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+extern const char *bigcrypt(const char *password, const char *salt);
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s password salt\n",
+ strchr(argv[0], '/') ?
+ (strchr(argv[0], '/') + 1) :
+ argv[0]);
+ return 0;
+ }
+ fprintf(stdout, "%s\n", bigcrypt(argv[1], argv[2]));
+ return 0;
+}
diff --git a/modules/pam_userdb/README b/modules/pam_userdb/README
index 9fa6519d..fc56cfa0 100644
--- a/modules/pam_userdb/README
+++ b/modules/pam_userdb/README
@@ -1,6 +1,7 @@
pam_userdb:
Look up users in a .db database and verify their password against
- what is contained in that database.
+ what is contained in that database. The database will have been
+ created using db_load.
RECOGNIZED ARGUMENTS:
debug write a message to syslog indicating success or
@@ -8,7 +9,9 @@ RECOGNIZED ARGUMENTS:
db=[path] use the [path] database for performing lookup. There
is no default; the module will return PAM_IGNORE if
- no database is provided.
+ no database is provided. Some versions of DB will
+ automatically append ".db" to whatever pathname you
+ supply here.
crypt=[mode] indicates whether encrypted or plaintext passwords
are stored in the database. If [mode] is "crypt",
@@ -24,8 +27,28 @@ RECOGNIZED ARGUMENTS:
dump dump all the entries in the database to the log (eek,
don't do this by default!)
+ use_authtok use the authentication token previously obtained by
+ another module that did the conversation with the
+ application. If this token can not be obtained then
+ the module will try to converse again. This option can
+ be used for stacking different modules that need to
+ deal with the authentication tokens.
+
+ unknown_ok do not return error when checking for a user that is
+ not in the database. This can be used to stack more
+ than one pam_userdb module that will check a
+ username/password pair in more than a database.
+
+ key_only the username and password are concatenated together
+ in the database hash as 'username-password' with a
+ random value. if the concatenation of the username and
+ password with a dash in the middle returns any result,
+ the user is valid. this is useful in cases where
+ the username may not be unique but the username and
+ password pair are.
+
MODULE SERVICES PROVIDED:
- auth _authetication and _setcred (blank)
+ auth _authentication and _setcred (blank)
EXAMPLE USE:
auth sufficient pam_userdb.so icase db=/tmp/dbtest.db
diff --git a/modules/pam_userdb/conv.c b/modules/pam_userdb/conv.c
index 0f13d03a..de5d12f2 100644
--- a/modules/pam_userdb/conv.c
+++ b/modules/pam_userdb/conv.c
@@ -5,8 +5,6 @@
/* $Id */
/* Copyright at the end of the file */
-#define _BSD_SOURCE
-
#include <stdlib.h>
#include <string.h>
diff --git a/modules/pam_userdb/create.pl b/modules/pam_userdb/create.pl
index 046b55f0..224204b7 100644
--- a/modules/pam_userdb/create.pl
+++ b/modules/pam_userdb/create.pl
@@ -7,7 +7,7 @@
use DB_File;
my $database = $ARGV[0];
-die "Use: check,pl <database>\n" unless ($database);
+die "Use: create.pl <database>\n" unless ($database);
print "Using database: $database\n";
my %lusers = ();
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
index 30f1e578..a0a5b8b5 100644
--- a/modules/pam_userdb/pam_userdb.c
+++ b/modules/pam_userdb/pam_userdb.c
@@ -1,5 +1,5 @@
/* pam_userdb module */
-
+
/*
* $Id$
* Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
@@ -8,6 +8,7 @@
#include <security/_pam_aconf.h>
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -56,39 +57,53 @@ static void _pam_log(int err, const char *format, ...)
closelog();
}
-char * database = NULL;
-char * cryptmode = NULL;
-static int ctrl = 0;
-
-static int _pam_parse(int argc, const char **argv)
+static int
+_pam_parse (int argc, const char **argv,
+ char **database, char **cryptmode)
{
- /* step through arguments */
- for (ctrl = 0; argc-- > 0; ++argv) {
-
- /* generic options */
-
- if (!strcmp(*argv,"debug"))
- ctrl |= PAM_DEBUG_ARG;
- else if (!strcasecmp(*argv, "icase"))
- ctrl |= PAM_ICASE_ARG;
- else if (!strcasecmp(*argv, "dump"))
- ctrl |= PAM_DUMP_ARG;
- else if (!strncasecmp(*argv,"db=", 3)) {
- database = strdup((*argv) + 3);
- 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);
- }
- }
+ int ctrl;
+
+ *database = NULL;
+ *cryptmode = NULL;
+
+ /* step through arguments */
+ for (ctrl = 0; argc-- > 0; ++argv)
+ {
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcasecmp(*argv, "icase"))
+ ctrl |= PAM_ICASE_ARG;
+ else if (!strcasecmp(*argv, "dump"))
+ ctrl |= PAM_DUMP_ARG;
+ else if (!strcasecmp(*argv, "unknown_ok"))
+ ctrl |= PAM_UNKNOWN_OK_ARG;
+ else if (!strcasecmp(*argv, "key_only"))
+ ctrl |= PAM_KEY_ONLY_ARG;
+ else if (!strncasecmp(*argv,"db=", 3))
+ {
+ *database = strdup((*argv) + 3);
+ if ((*database == NULL) || (strlen (*database) == 0))
+ _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) || (strlen (*cryptmode) == 0))
+ _pam_log(LOG_ERR,
+ "pam_parse: could not parse argument \"%s\"",
+ *argv);
+ }
+ else
+ {
+ _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
+ }
+ }
- return ctrl;
+ return ctrl;
}
@@ -101,7 +116,9 @@ static int _pam_parse(int argc, const char **argv)
* -1 = Password incorrect
* -2 = System error
*/
-static int user_lookup(const char *user, const char *pass)
+static int
+user_lookup (const char *database, const char *cryptmode,
+ const char *user, const char *pass, int ctrl)
{
DBM *dbm;
datum key, data;
@@ -114,7 +131,8 @@ static int user_lookup(const char *user, const char *pass)
return -2;
}
- if (ctrl &PAM_DUMP_ARG) {
+ /* dump out the database contents for debugging */
+ if (ctrl & PAM_DUMP_ARG) {
_pam_log(LOG_INFO, "Database dump:");
for (key = dbm_firstkey(dbm); key.dptr != NULL;
key = dbm_nextkey(dbm)) {
@@ -122,14 +140,19 @@ static int user_lookup(const char *user, const char *pass)
_pam_log(LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'",
key.dsize, key.dptr, data.dsize, data.dptr);
}
- }
- /* do some more init work */
+ }
+ /* do some more init work */
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
- key.dptr = x_strdup(user);
- key.dsize = strlen(user);
- user = NULL;
+ if (ctrl & PAM_KEY_ONLY_ARG) {
+ key.dptr = malloc(strlen(user) + 1 + strlen(pass) + 1);
+ sprintf(key.dptr, "%s-%s", user, pass);
+ key.dsize = strlen(key.dptr);
+ } else {
+ key.dptr = x_strdup(user);
+ key.dsize = strlen(user);
+ }
if (key.dptr) {
data = dbm_fetch(dbm, key);
@@ -144,7 +167,13 @@ static int user_lookup(const char *user, const char *pass)
if (data.dptr != NULL) {
int compare = 0;
-
+
+ if (ctrl & PAM_KEY_ONLY_ARG)
+ {
+ dbm_close (dbm);
+ return 0; /* found it, data contents don't matter */
+ }
+
if (strncasecmp(cryptmode, "crypt", 5) == 0) {
/* crypt(3) password storage */
@@ -166,7 +195,7 @@ static int user_lookup(const char *user, const char *pass)
compare = strncasecmp (data.dptr, cryptpw, data.dsize);
} else {
compare = -2;
- if (ctrl & PAM_DEBUG_ARG) {
+ if (ctrl & PAM_DEBUG_ARG) {
_pam_log(LOG_INFO, "crypt() returned NULL");
}
};
@@ -174,20 +203,20 @@ static int user_lookup(const char *user, const char *pass)
};
} else {
-
+
/* Unknown password encryption method -
* default to plaintext password storage
*/
if (strlen(pass) != data.dsize) {
- compare = 1;
+ compare = 1; /* wrong password len -> wrong password */
} else if (ctrl & PAM_ICASE_ARG) {
compare = strncasecmp(data.dptr, pass, data.dsize);
} else {
compare = strncmp(data.dptr, pass, data.dsize);
}
- if (strncasecmp(cryptmode, "none", 4) && ctrl & PAM_DEBUG_ARG) {
+ 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");
@@ -201,13 +230,58 @@ static int user_lookup(const char *user, const char *pass)
else
return -1; /* wrong */
} else {
- if (ctrl & PAM_DEBUG_ARG) {
+ int saw_user = 0;
+
+ if (ctrl & PAM_DEBUG_ARG) {
_pam_log(LOG_INFO, "error returned by dbm_fetch: %s",
strerror(errno));
}
- dbm_close(dbm);
+
/* probably we should check dbm_error() here */
- return 1; /* not found */
+
+ if ((ctrl & PAM_KEY_ONLY_ARG) == 0) {
+ dbm_close(dbm);
+ return 1; /* not key_only, so no entry => no entry for the user */
+ }
+
+ /* now handle the key_only case */
+ for (key = dbm_firstkey(dbm);
+ key.dptr != NULL;
+ key = dbm_nextkey(dbm)) {
+ int compare;
+ /* first compare the user portion (case sensitive) */
+ compare = strncmp(key.dptr, user, strlen(user));
+ if (compare == 0) {
+ /* assume failure */
+ compare = -1;
+ /* if we have the divider where we expect it to be... */
+ if (key.dptr[strlen(user)] == '-') {
+ saw_user = 1;
+ if (key.dsize == strlen(user) + 1 + strlen(pass)) {
+ if (ctrl & PAM_ICASE_ARG) {
+ /* compare the password portion (case insensitive)*/
+ compare = strncasecmp(key.dptr + strlen(user) + 1,
+ pass,
+ strlen(pass));
+ } else {
+ /* compare the password portion (case sensitive) */
+ compare = strncmp(key.dptr + strlen(user) + 1,
+ pass,
+ strlen(pass));
+ }
+ }
+ }
+ if (compare == 0) {
+ dbm_close(dbm);
+ return 0; /* match */
+ }
+ }
+ }
+ dbm_close(dbm);
+ if (saw_user)
+ return -1; /* saw the user, but password mismatch */
+ else
+ return 1; /* not found */
}
/* NOT REACHED */
@@ -222,10 +296,17 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
{
const char *username;
const char *password;
- int retval = PAM_AUTH_ERR;
-
+ char *database = NULL;
+ char *cryptmode = NULL;
+ int retval = PAM_AUTH_ERR, ctrl;
+
/* parse arguments */
- ctrl = _pam_parse(argc, argv);
+ ctrl = _pam_parse(argc, argv, &database, &cryptmode);
+ if ((database == NULL) || (strlen(database) == 0)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"can not get the database name");
+ return PAM_SERVICE_ERR;
+ }
/* Get the username */
retval = pam_get_user(pamh, &username, NULL);
@@ -234,32 +315,47 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
_pam_log(LOG_DEBUG,"can not get the username");
return PAM_SERVICE_ERR;
}
-
- /* Converse just to be sure we have the password */
+
+ /* Converse just to be sure we have a password */
retval = conversation(pamh);
if (retval != PAM_SUCCESS) {
_pam_log(LOG_ERR, "could not obtain password for `%s'",
username);
- return -2;
+ return PAM_CONV_ERR;
+ }
+
+ /* Check if we got a password. The docs say that if we didn't have one,
+ * and use_authtok was specified as an argument, that we converse with the
+ * user anyway, so check for one and handle a failure for that case. If
+ * use_authtok wasn't specified, then we've already asked once and needn't
+ * do so again. */
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &password);
+ if ((retval != PAM_SUCCESS) && ((ctrl & PAM_USE_AUTHTOK_ARG) != 0)) {
+ retval = conversation(pamh);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_ERR, "could not obtain password for `%s'",
+ username);
+ return PAM_CONV_ERR;
+ }
}
-
+
/* Get the password */
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password);
if (retval != PAM_SUCCESS) {
- _pam_log(LOG_ERR, "Could not retrive user's password");
+ _pam_log(LOG_ERR, "Could not retrieve user's password");
return -2;
}
-
+
if (ctrl & PAM_DEBUG_ARG)
_pam_log(LOG_INFO, "Verify user `%s' with password `%s'",
username, password);
-
+
/* Now use the username to look up password in the database file */
- retval = user_lookup(username, password);
+ retval = user_lookup(database, cryptmode, username, password, ctrl);
switch (retval) {
case -2:
/* some sort of system error. The log was already printed */
- return PAM_SERVICE_ERR;
+ return PAM_SERVICE_ERR;
case -1:
/* incorrect password */
_pam_log(LOG_WARNING,
@@ -296,9 +392,47 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
}
PAM_EXTERN
-int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
+ const char *username;
+ char *database = NULL;
+ char *cryptmode = NULL;
+ int retval = PAM_AUTH_ERR, ctrl;
+
+ /* parse arguments */
+ ctrl = _pam_parse(argc, argv, &database, &cryptmode);
+
+ /* Get the username */
+ retval = pam_get_user(pamh, &username, NULL);
+ if ((retval != PAM_SUCCESS) || (!username)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"can not get the username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Now use the username to look up password in the database file */
+ retval = user_lookup(database, cryptmode, username, "", ctrl);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password, but we don't care */
+ /* FALL THROUGH */
+ case 0:
+ /* authentication succeeded. dumbest password ever. */
+ return PAM_SUCCESS;
+ case 1:
+ /* the user does not exist in the database */
+ return PAM_USER_UNKNOWN;
+ default:
+ /* we don't know anything about this return value */
+ _pam_log(LOG_ERR,
+ "internal module error (retval = %d, user = `%s'",
+ retval, username);
+ return PAM_SERVICE_ERR;
+ }
+
return PAM_SUCCESS;
}
@@ -311,7 +445,7 @@ struct pam_module _pam_userdb_modstruct = {
"pam_userdb",
pam_sm_authenticate,
pam_sm_setcred,
- NULL,
+ pam_sm_acct_mgmt,
NULL,
NULL,
NULL,
diff --git a/modules/pam_userdb/pam_userdb.h b/modules/pam_userdb/pam_userdb.h
index 911a7622..a371fa9f 100644
--- a/modules/pam_userdb/pam_userdb.h
+++ b/modules/pam_userdb/pam_userdb.h
@@ -10,6 +10,9 @@
#define PAM_DEBUG_ARG 0x0001
#define PAM_ICASE_ARG 0x0002
#define PAM_DUMP_ARG 0x0004
+#define PAM_USE_AUTHTOK_ARG 0x0008
+#define PAM_UNKNOWN_OK_ARG 0x0010
+#define PAM_KEY_ONLY_ARG 0x0020
/* Useful macros */
#define x_strdup(s) ( (s) ? strdup(s):NULL )