aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeraphim Mellos <mellos@ceid.upatras.gr>2008-06-18 15:33:32 +0300
committerSeraphim Mellos <mellos@ceid.upatras.gr>2008-06-18 15:33:32 +0300
commit0d40a5b03d76ad60e6346117a28ecb191ef315f1 (patch)
treec98a58ceb5f54fc68a75c63f02ded360a9ec9c3c /modules
parentAdded logging/debug msgs in pam_unix (diff)
downloadopenpam-modules-0d40a5b03d76ad60e6346117a28ecb191ef315f1.tar.gz
openpam-modules-0d40a5b03d76ad60e6346117a28ecb191ef315f1.tar.bz2
openpam-modules-0d40a5b03d76ad60e6346117a28ecb191ef315f1.zip
Fixed a bug with dummy authentication in pam_unix
Diffstat (limited to 'modules')
-rw-r--r--modules/pam_unix/pam_unix.c67
-rw-r--r--modules/pam_unix/pam_unix.c~77
2 files changed, 108 insertions, 36 deletions
diff --git a/modules/pam_unix/pam_unix.c b/modules/pam_unix/pam_unix.c
index 0443a5a..2be7e75 100644
--- a/modules/pam_unix/pam_unix.c
+++ b/modules/pam_unix/pam_unix.c
@@ -2,7 +2,6 @@
#include <pwd.h>
#include <netdb.h>
-#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
@@ -18,10 +17,11 @@
#define PAM_PASSWORD
#ifndef __linux__
-#include <login_cap.h>
+#include <login_cap.h> /* for BSD login classes */
+#else
+#include <shadow.h> /* for linux boxes */
#endif
-
#define PASSWORD_HASH "md5"
#define MAX_RETRIES 3
#define DEFAULT_WARN (2L * 7L * 86400L) /* two weeks */
@@ -32,6 +32,7 @@
#include <security/pam_appl.h>
#include <security/pam_mod_misc.h>
+static char * read_shadow(const char * user) ;
/*
* User authentication
*/
@@ -44,7 +45,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
login_cap_t *lc;
#endif
struct passwd *pwd;
- const char *pass, *crypt_pass, *user;
+ const char *pass, *crypt_pass, *real_hash, *user;
int pam_err;
/* identify user */
@@ -63,6 +64,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
PAM_LOG("Authenticating user: [%s]", user);
+ puts("USER GOT");
/* get password */
if (pwd != NULL) {
@@ -71,23 +73,26 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (pass[0] == '\0') {
if (!(flags & PAM_DISALLOW_NULL_AUTHTOK) &&
openpam_get_option(pamh, PAM_OPT_NULLOK)){
- PAM_ERROR("Authentication failed. Empty passwd not allowed.");
+ PAM_LOG("User [%s] has empty password. Authentication succesfull.");
return (PAM_SUCCESS);
}
- pass = "*";
+ real_hash = "*";
}
+
#ifndef __linux__
lc = login_getpwclass(pwd);
-#endif
+#endif
} else {
PAM_LOG("Doing dummy authentication.");
- pass = "*";
-#ifndef __linux__
+ real_hash = "*";
+
+#ifndef __linux__
lc = login_getpwclass(NULL);
#endif
}
+
#ifndef __linux__
prompt = login_getcapstr(lc, "passwd_prompt", NULL, NULL);
pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, &pass, prompt);
@@ -102,14 +107,24 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (pam_err != PAM_SUCCESS)
return (PAM_AUTH_ERR);
- /* check passwd entry */
- crypt_pass = crypt(pass, pwd->pw_passwd);
- if ( strcmp(crypt_pass, pwd->pw_passwd) != 0 ) {
+ /* check passwd entry */
+
+ if ( strncmp(real_hash, "*", sizeof(char)) !=0 ) {
+#ifndef __linux__
+ real_hash = pwd->pw_passwd;
+#else
+ real_hash = read_shadow(user);
+#endif
+ }
+
+ crypt_pass = crypt(pass,real_hash);
+ if ( strcmp(crypt_pass, real_hash) != 0 ) {
PAM_ERROR("Wrong password. Authentication failed.");
pam_err = PAM_AUTH_ERR;
} else {
PAM_LOG("Authentication completed succesfully.");
+ puts("SUCCESS!");
pam_err = PAM_SUCCESS;
}
@@ -138,8 +153,6 @@ PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags ,
int argc , const char *argv[] ) {
-
-
#ifndef __linux__
login_cap_t *lc;
#endif
@@ -209,7 +222,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags ,
PAM_ERROR("Account has expired!");
return (PAM_ACCT_EXPIRED);
} else if ( ( pwd->sp_expire - curtime < DEFAULT_WARN) ) {
- PAM_ERROR(pamh, "Warning: your account expires on %s",
+ PAM_ERROR("Warning: your account expires on %s",
ctime(&pwd->sp_expire));
}
}
@@ -285,7 +298,8 @@ pam_sm_chautok(pam_handle_t *pamh, int flags,
if (openpam_get_option(pamh, PAM_OPT_AUTH_AS_SELF)) {
PAM_LOG("Authenticating as self.");
- old_pwd = getpwnam(getlogin());
+ user=getlogin();
+ old_pwd = getpwnam(user);
} else {
if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
PAM_ERROR("Authenticating with uname [%s] failed.", user);
@@ -455,6 +469,25 @@ pam_sm_chautok(pam_handle_t *pamh, int flags,
/*
+ * Read hashed password for user from shadow entry.
+ * This is for use on Linux machines only.
+ */
+static char * read_shadow(const char * user) {
+
+ struct spwd * pwd;
+ /*
+ * No error checking. Everything has been tested prior to
+ * calling this function. Nothing can go wrong, right?
+ */
+ pwd = getspnam(user);
+
+ return (pwd->sp_pwdp);
+}
+
+
+
+#ifndef __linux__
+/*
* Mostly stolen from freebsd-lib's pam_unix module which was mostly
* stolen from passwd(1)'s local_passwd.c
*
@@ -484,5 +517,5 @@ makesalt(char salt[SALTSIZE]) {
// to64(&salt[i], arc4random(), 4);
salt[SALTSIZE] = '\0';
}
-
+#endif
PAM_MODULE_ENTRY("pam_unix")
diff --git a/modules/pam_unix/pam_unix.c~ b/modules/pam_unix/pam_unix.c~
index d70693d..601aa89 100644
--- a/modules/pam_unix/pam_unix.c~
+++ b/modules/pam_unix/pam_unix.c~
@@ -2,7 +2,6 @@
#include <pwd.h>
#include <netdb.h>
-#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
@@ -18,10 +17,11 @@
#define PAM_PASSWORD
#ifndef __linux__
-#include <login_cap.h>
+#include <login_cap.h> /* for BSD login classes */
+#else
+#include <shadow.h> /* for linux boxes */
#endif
-
#define PASSWORD_HASH "md5"
#define MAX_RETRIES 3
#define DEFAULT_WARN (2L * 7L * 86400L) /* two weeks */
@@ -32,6 +32,7 @@
#include <security/pam_appl.h>
#include <security/pam_mod_misc.h>
+static char * read_shadow(const char * user) ;
/*
* User authentication
*/
@@ -44,7 +45,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
login_cap_t *lc;
#endif
struct passwd *pwd;
- const char *pass, *crypt_pass, *user;
+ const char *pass, *crypt_pass, *real_hash, *user;
int pam_err;
/* identify user */
@@ -63,6 +64,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
PAM_LOG("Authenticating user: [%s]", user);
+ puts("USER GOT");
/* get password */
if (pwd != NULL) {
@@ -71,23 +73,32 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (pass[0] == '\0') {
if (!(flags & PAM_DISALLOW_NULL_AUTHTOK) &&
openpam_get_option(pamh, PAM_OPT_NULLOK)){
- PAM_ERROR("Authentication failed. Empty passwd not allowed.");
+ PAM_LOG("User [%s] has empty password. Authentication succesfull.");
return (PAM_SUCCESS);
}
- pass = "*";
+ real_hash = "*";
}
-#ifndef __linux__
+
+ /*
+ * Dummy authentication is something that the freebsd-lib
+ * people have implemented. Not sure whether it's needed on
+ * Linux -or BSD- but it'll be left as is for compatibiity
+ * issues. Need to be checked!
+ */
+
lc = login_getpwclass(pwd);
-#endif
+
} else {
PAM_LOG("Doing dummy authentication.");
- pass = "*";
-#ifndef __linux__
+ real_hash = "*";
+
+#ifndef __linux__
lc = login_getpwclass(NULL);
#endif
}
+
#ifndef __linux__
prompt = login_getcapstr(lc, "passwd_prompt", NULL, NULL);
pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, &pass, prompt);
@@ -102,14 +113,24 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (pam_err != PAM_SUCCESS)
return (PAM_AUTH_ERR);
- /* check passwd entry */
- crypt_pass = crypt(pass, pwd->pw_passwd);
- if ( strcmp(crypt_pass, pwd->pw_passwd) != 0 ) {
+ /* check passwd entry */
+
+ if ( strncmp(real_hash, "*", sizeof(char)) !=0 ) {
+#ifndef __linux__
+ real_hash = pwd->pw_passwd;
+#else
+ real_hash = read_shadow(user);
+#endif
+ }
+
+ crypt_pass = crypt(pass,real_hash);
+ if ( strcmp(crypt_pass, real_hash) != 0 ) {
PAM_ERROR("Wrong password. Authentication failed.");
pam_err = PAM_AUTH_ERR;
} else {
PAM_LOG("Authentication completed succesfully.");
+ puts("SUCCESS!");
pam_err = PAM_SUCCESS;
}
@@ -138,8 +159,6 @@ PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags ,
int argc , const char *argv[] ) {
-
-
#ifndef __linux__
login_cap_t *lc;
#endif
@@ -209,7 +228,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags ,
PAM_ERROR("Account has expired!");
return (PAM_ACCT_EXPIRED);
} else if ( ( pwd->sp_expire - curtime < DEFAULT_WARN) ) {
- PAM_ERROR(pamh, "Warning: your account expires on %s",
+ PAM_ERROR("Warning: your account expires on %s",
ctime(&pwd->sp_expire));
}
}
@@ -285,7 +304,8 @@ pam_sm_chautok(pam_handle_t *pamh, int flags,
if (openpam_get_option(pamh, PAM_OPT_AUTH_AS_SELF)) {
PAM_LOG("Authenticating as self.");
- old_pwd = getpwnam(getlogin());
+ user=getlogin();
+ old_pwd = getpwnam(user);
} else {
if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
PAM_ERROR("Authenticating with uname [%s] failed.", user);
@@ -455,6 +475,25 @@ pam_sm_chautok(pam_handle_t *pamh, int flags,
/*
+ * Read hashed password for user from shadow entry.
+ * This is for use on Linux machines only.
+ */
+static char * read_shadow(const char * user) {
+
+ struct spwd * pwd;
+ /*
+ * No error checking. Everything has been tested prior to
+ * calling this function. Nothing can go wrong, right?
+ */
+ pwd = getspnam(user);
+
+ return (pwd->sp_pwdp);
+}
+
+
+
+#ifndef __linux__
+/*
* Mostly stolen from freebsd-lib's pam_unix module which was mostly
* stolen from passwd(1)'s local_passwd.c
*
@@ -481,8 +520,8 @@ makesalt(char salt[SALTSIZE]) {
*/
for (i = 0; i < SALTSIZE; i += 4)
- to64(&salt[i], arc4random(), 4);
+// to64(&salt[i], arc4random(), 4);
salt[SALTSIZE] = '\0';
}
-
+#endif
PAM_MODULE_ENTRY("pam_unix")