aboutsummaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_userdb
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_userdb')
-rw-r--r--Linux-PAM/modules/pam_userdb/Makefile41
-rw-r--r--Linux-PAM/modules/pam_userdb/README61
-rw-r--r--Linux-PAM/modules/pam_userdb/conv.c123
-rw-r--r--Linux-PAM/modules/pam_userdb/create.pl23
-rw-r--r--Linux-PAM/modules/pam_userdb/pam_userdb.c490
-rw-r--r--Linux-PAM/modules/pam_userdb/pam_userdb.h64
6 files changed, 802 insertions, 0 deletions
diff --git a/Linux-PAM/modules/pam_userdb/Makefile b/Linux-PAM/modules/pam_userdb/Makefile
new file mode 100644
index 00000000..4da7310d
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/Makefile
@@ -0,0 +1,41 @@
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+
+# $Id: Makefile,v 1.6 2004/09/14 14:22:40 kukuk Exp $
+# Created by Cristian Gafton <gafton@redhat.com>
+
+include ../../Make.Rules
+
+TITLE=pam_userdb
+
+ifeq ($(HAVE_NDBM_H),yes)
+ WHICH_DB=ndbm
+ ifeq ($(HAVE_LIBNDBM),yes)
+ MODULE_SIMPLE_EXTRALIBS = -lndbm
+ endif
+else
+ifeq ($(HAVE_LIBDB),yes)
+ WHICH_DB=db
+ MODULE_SIMPLE_EXTRALIBS = -ldb
+else
+ WHICH_DB=none
+endif
+endif
+
+ifeq ($(HAVE_LIBCRYPT),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lcrypt
+endif
+
+ifeq ($(WHICH_DB),none)
+
+include ../dont_makefile
+
+else
+
+MODULE_SIMPLE_EXTRAFILES = conv
+
+include ../Simple.Rules
+
+endif
diff --git a/Linux-PAM/modules/pam_userdb/README b/Linux-PAM/modules/pam_userdb/README
new file mode 100644
index 00000000..1cab7b74
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/README
@@ -0,0 +1,61 @@
+pam_userdb:
+ Look up users in a .db database and verify their password against
+ 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
+ failure.
+
+ db=[path] use the [path] database for performing lookup. There
+ is no default; the module will return PAM_IGNORE if
+ 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",
+ 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!)
+
+ 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 _authentication and _setcred (blank)
+
+EXAMPLE USE:
+ auth sufficient pam_userdb.so icase db=/tmp/dbtest.db
+
+AUTHOR:
+ Cristian Gafton <gafton@redhat.com>
+
+
+
+$Id: README,v 1.3 2004/09/28 13:48:47 kukuk Exp $
diff --git a/Linux-PAM/modules/pam_userdb/conv.c b/Linux-PAM/modules/pam_userdb/conv.c
new file mode 100644
index 00000000..de5d12f2
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/conv.c
@@ -0,0 +1,123 @@
+/*
+ * Conversation related functions
+ */
+
+/* $Id */
+/* Copyright at the end of the file */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+#include "pam_userdb.h"
+
+/*
+ * dummy conversation function sending exactly one prompt
+ * and expecting exactly one response from the other party
+ */
+static int converse(pam_handle_t *pamh,
+ struct pam_message **message,
+ struct pam_response **response)
+{
+ int retval;
+ const struct pam_conv *conv;
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ;
+ if (retval == PAM_SUCCESS)
+ retval = conv->conv(1, (const struct pam_message **)message,
+ response, conv->appdata_ptr);
+
+ return retval; /* propagate error status */
+}
+
+
+static char *_pam_delete(register char *xx)
+{
+ _pam_overwrite(xx);
+ _pam_drop(xx);
+ return NULL;
+}
+
+/*
+ * This is a conversation function to obtain the user's password
+ */
+int conversation(pam_handle_t *pamh)
+{
+ struct pam_message msg[2],*pmsg[2];
+ struct pam_response *resp;
+ int retval;
+ char * token = NULL;
+
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = "Password: ";
+
+ /* so call the conversation expecting i responses */
+ resp = NULL;
+ retval = converse(pamh, pmsg, &resp);
+
+ if (resp != NULL) {
+ const char * item;
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token = x_strdup(resp[0].resp);
+ if (token == NULL) {
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+ }
+
+ /* set the auth token */
+ retval = pam_set_item(pamh, PAM_AUTHTOK, token);
+ token = _pam_delete(token); /* clean it up */
+ if ( (retval != PAM_SUCCESS) ||
+ (retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item))
+ != PAM_SUCCESS ) {
+ return retval;
+ }
+
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS)
+ ? PAM_AUTHTOK_RECOVER_ERR:retval ;
+ }
+
+ return retval;
+}
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/Linux-PAM/modules/pam_userdb/create.pl b/Linux-PAM/modules/pam_userdb/create.pl
new file mode 100644
index 00000000..28088102
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/create.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+# this program creates a database in ARGV[1] from pairs given on
+# stdandard input
+#
+# $Id: create.pl,v 1.2 2004/09/28 13:48:47 kukuk Exp $
+
+use DB_File;
+
+my $database = $ARGV[0];
+die "Use: create.pl <database>\n" unless ($database);
+print "Using database: $database\n";
+
+my %lusers = ();
+
+tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ;
+while (<STDIN>) {
+ my ($user, $pass) = split;
+
+ $lusers{$user} = $pass;
+}
+untie %lusers;
+
+
diff --git a/Linux-PAM/modules/pam_userdb/pam_userdb.c b/Linux-PAM/modules/pam_userdb/pam_userdb.c
new file mode 100644
index 00000000..86c7238b
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/pam_userdb.c
@@ -0,0 +1,490 @@
+/* pam_userdb module */
+
+/*
+ * $Id: pam_userdb.c,v 1.7 2004/09/28 13:48:47 kukuk Exp $
+ * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
+ * See the end of the file for Copyright Information
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "pam_userdb.h"
+
+#ifdef HAVE_NDBM_H
+# include <ndbm.h>
+#else
+# ifdef HAVE_DB_H
+# define DB_DBM_HSEARCH 1 /* use the dbm interface */
+# include <db.h>
+# else
+# error "failed to find a libdb or equivalent"
+# endif
+#endif
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static int
+_pam_parse (int argc, const char **argv,
+ char **database, char **cryptmode)
+{
+ 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;
+}
+
+
+/*
+ * Looks up an user name in a database and checks the password
+ *
+ * return values:
+ * 1 = User not found
+ * 0 = OK
+ * -1 = Password incorrect
+ * -2 = System error
+ */
+static int
+user_lookup (const char *database, const char *cryptmode,
+ const char *user, const char *pass, int ctrl)
+{
+ DBM *dbm;
+ datum key, data;
+
+ /* Open the DB file. */
+ dbm = dbm_open(database, O_RDONLY, 0644);
+ if (dbm == NULL) {
+ _pam_log(LOG_ERR, "user_lookup: could not open database `%s'",
+ database);
+ return -2;
+ }
+
+ /* 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)) {
+ data = dbm_fetch(dbm, key);
+ _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 */
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ 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);
+ memset(key.dptr, 0, key.dsize);
+ free(key.dptr);
+ }
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "password in database is [%p]`%s', len is %d",
+ data.dptr, (char *) data.dptr, data.dsize);
+ }
+
+ 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 */
+
+ 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; /* 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) {
+ _pam_log(LOG_INFO, "invalid value for crypt parameter: %s",
+ cryptmode);
+ _pam_log(LOG_INFO, "defaulting to plaintext password mode");
+ }
+
+ }
+
+ dbm_close(dbm);
+ if (compare == 0)
+ return 0; /* match */
+ else
+ return -1; /* wrong */
+ } else {
+ int saw_user = 0;
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "error returned by dbm_fetch: %s",
+ strerror(errno));
+ }
+
+ /* probably we should check dbm_error() here */
+
+ 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 */
+ return -2;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *username;
+ const char *password;
+ char *database = NULL;
+ char *cryptmode = NULL;
+ int retval = PAM_AUTH_ERR, ctrl;
+
+ /* parse arguments */
+ 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);
+ if ((retval != PAM_SUCCESS) || (!username)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"can not get the username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* 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 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 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(database, cryptmode, username, password, ctrl);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password */
+ _pam_log(LOG_WARNING,
+ "user `%s' denied access (incorrect password)",
+ username);
+ return PAM_AUTH_ERR;
+ case 1:
+ /* the user does not exist in the database */
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_NOTICE, "user `%s' not found in the database",
+ username);
+ return PAM_USER_UNKNOWN;
+ case 0:
+ /* Otherwise, the authentication looked good */
+ _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
+ return PAM_SUCCESS;
+ 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;
+ }
+
+ /* should not be reached */
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN
+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;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_userdb_modstruct = {
+ "pam_userdb",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ pam_sm_acct_mgmt,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/Linux-PAM/modules/pam_userdb/pam_userdb.h b/Linux-PAM/modules/pam_userdb/pam_userdb.h
new file mode 100644
index 00000000..af03676b
--- /dev/null
+++ b/Linux-PAM/modules/pam_userdb/pam_userdb.h
@@ -0,0 +1,64 @@
+
+#ifndef _PAM_USERSDB_H
+#define _PAM_USERSDB_H
+/* $Id: pam_userdb.h,v 1.2 2004/09/28 13:48:47 kukuk Exp $ */
+
+/* Header files */
+#include <security/pam_appl.h>
+
+/* argument parsing */
+#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 )
+
+/* The name of the module we are compiling */
+#ifndef MODULE_NAME
+#define MODULE_NAME "pam_userdb"
+#endif /* MODULE_NAME */
+
+/* function prototypes */
+int conversation(pam_handle_t *);
+
+#endif /* _PAM_USERSDB_H */
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */