summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorTomas Mraz <tm@t8m.info>2007-12-05 10:03:29 +0000
committerTomas Mraz <tm@t8m.info>2007-12-05 10:03:29 +0000
commit39483af547d33022ff9e18b741165f0551bdc090 (patch)
tree59a4540554e2c50d8840676459dd09f8789e5bd3 /modules
parent2431111ad5a49bce6bb943f599b7ab3509e9f181 (diff)
Relevant BUGIDs:
Purpose of commit: cleanup Commit summary: --------------- 2007-12-05 Tomas Mraz <t8m@centrum.cz> * modules/pam_unix/Makefile.am: Add passverify.h and passverify.c as first part of pam_unix refactorization. * modules/pam_unix/pam_unix/pam_unix_acct.c: Include passverify.h. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_unix/passverify.c: New file with common functions. * modules/pam_unix/passverify.h: Prototypes for the common functions. * modules/pam_unix/support.c: Include passverify.h, move _unix_shadowed() to passverify.c. (_unix_verify_password): Refactor out verify_pwd_hash() function. * modules/pam_unix/support.h: Move _unix_shadowed() prototype to passverify.h * modules/pam_unix/unix_chkpwd.c: Use _unix_shadowed() and verify_pwd_hash() from passverify.c.
Diffstat (limited to 'modules')
-rw-r--r--modules/pam_unix/Makefile.am7
-rw-r--r--modules/pam_unix/pam_unix_acct.c1
-rw-r--r--modules/pam_unix/pam_unix_passwd.c1
-rw-r--r--modules/pam_unix/passverify.c125
-rw-r--r--modules/pam_unix/passverify.h43
-rw-r--r--modules/pam_unix/support.c64
-rw-r--r--modules/pam_unix/support.h1
-rw-r--r--modules/pam_unix/unix_chkpwd.c82
8 files changed, 181 insertions, 143 deletions
diff --git a/modules/pam_unix/Makefile.am b/modules/pam_unix/Makefile.am
index caccdf05..a74d9762 100644
--- a/modules/pam_unix/Makefile.am
+++ b/modules/pam_unix/Makefile.am
@@ -34,7 +34,7 @@ pam_unix_la_LIBADD = @LIBCRACK@ @LIBNSL@ -L$(top_builddir)/libpam -lpam \
securelib_LTLIBRARIES = pam_unix.la
-noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h
+noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h passverify.h
sbin_PROGRAMS = unix_chkpwd
@@ -42,13 +42,14 @@ noinst_PROGRAMS = bigcrypt
pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \
pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \
- yppasswd_xdr.c md5_good.c md5_broken.c
+ passverify.c yppasswd_xdr.c md5_good.c md5_broken.c
bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c
bigcrypt_CFLAGS = $(AM_CFLAGS)
bigcrypt_LDADD = @LIBCRYPT@
-unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c
+unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \
+ passverify.c
unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@
unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
index 6b04ed2f..aeecb132 100644
--- a/modules/pam_unix/pam_unix_acct.c
+++ b/modules/pam_unix/pam_unix_acct.c
@@ -63,6 +63,7 @@
#include <security/pam_modutil.h>
#include "support.h"
+#include "passverify.h"
#ifdef WITH_SELINUX
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index c8ee5492..3a61925e 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -84,6 +84,7 @@ static security_context_t prev_context=NULL;
#include "yppasswd.h"
#include "md5.h"
#include "support.h"
+#include "passverify.h"
#include "bigcrypt.h"
#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
new file mode 100644
index 00000000..6587bace
--- /dev/null
+++ b/modules/pam_unix/passverify.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright information at end of file.
+ */
+#include "config.h"
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include "support.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "md5.h"
+#include "bigcrypt.h"
+#include "passverify.h"
+
+int
+verify_pwd_hash(const char *p, const char *hash, unsigned int nullok)
+{
+ size_t hash_len = strlen(hash);
+ char *pp = NULL;
+ int retval;
+ D(("called"));
+
+ if (!hash_len) {
+ /* the stored password is NULL */
+ if (nullok) { /* this means we've succeeded */
+ D(("user has empty password - access granted"));
+ retval = PAM_SUCCESS;
+ } else {
+ D(("user has empty password - access denied"));
+ retval = PAM_AUTH_ERR;
+ }
+ } else if (!p || *hash == '*' || *hash == '!') {
+ retval = PAM_AUTH_ERR;
+ } else {
+ if (!strncmp(hash, "$1$", 3)) {
+ pp = Goodcrypt_md5(p, hash);
+ if (pp && strcmp(pp, hash) != 0) {
+ _pam_delete(pp);
+ pp = Brokencrypt_md5(p, hash);
+ }
+ } else if (*hash != '$' && hash_len >= 13) {
+ pp = bigcrypt(p, hash);
+ if (pp && hash_len == 13 && strlen(pp) > hash_len) {
+ _pam_overwrite(pp + hash_len);
+ }
+ } else {
+ /*
+ * Ok, we don't know the crypt algorithm, but maybe
+ * libcrypt nows about it? We should try it.
+ */
+ pp = x_strdup(crypt(p, hash));
+ }
+ p = NULL; /* no longer needed here */
+
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if (pp && strcmp(pp, hash) == 0) {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
+ }
+
+ if (pp)
+ _pam_delete(pp);
+ D(("done [%d].", retval));
+
+ return retval;
+}
+
+int _unix_shadowed(const struct passwd *pwd)
+{
+ if (pwd != NULL) {
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ return 1;
+ }
+ if ((pwd->pw_passwd[0] == '#') &&
+ (pwd->pw_passwd[1] == '#') &&
+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* ****************************************************************** *
+ * Copyright (c) Jan Rêkorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ * Copyright (c) Red Hat, Inc. 2007.
+ *
+ * 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/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h
new file mode 100644
index 00000000..a3ae9210
--- /dev/null
+++ b/modules/pam_unix/passverify.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright information at end of file.
+ */
+int
+verify_pwd_hash(const char *p, const char *hash, unsigned int nullok);
+
+int
+_unix_shadowed(const struct passwd *pwd);
+
+/* ****************************************************************** *
+ * Copyright (c) Red Hat, Inc. 2007.
+ *
+ * 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/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 1472b966..60acc958 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -26,9 +26,8 @@
#include <security/pam_ext.h>
#include <security/pam_modutil.h>
-#include "md5.h"
#include "support.h"
-#include "bigcrypt.h"
+#include "passverify.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#define SELINUX_ENABLED is_selinux_enabled()>0
@@ -579,7 +578,6 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
struct passwd *pwd = NULL;
struct spwd *spwdent = NULL;
char *salt = NULL;
- char *pp = NULL;
char *data_name;
int retval;
@@ -679,48 +677,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
}
}
} else {
- size_t salt_len = strlen(salt);
- if (!salt_len) {
- /* the stored password is NULL */
- if (off(UNIX__NONULL, ctrl)) {/* this means we've succeeded */
- D(("user has empty password - access granted"));
- retval = PAM_SUCCESS;
- } else {
- D(("user has empty password - access denied"));
- retval = PAM_AUTH_ERR;
- }
- } else if (!p || *salt == '*' || *salt == '!') {
- retval = PAM_AUTH_ERR;
- } else {
- if (!strncmp(salt, "$1$", 3)) {
- pp = Goodcrypt_md5(p, salt);
- if (pp && strcmp(pp, salt) != 0) {
- _pam_delete(pp);
- pp = Brokencrypt_md5(p, salt);
- }
- } else if (*salt != '$' && salt_len >= 13) {
- pp = bigcrypt(p, salt);
- if (pp && salt_len == 13 && strlen(pp) > salt_len) {
- _pam_overwrite(pp + salt_len);
- }
- } else {
- /*
- * Ok, we don't know the crypt algorithm, but maybe
- * libcrypt nows about it? We should try it.
- */
- pp = x_strdup (crypt(p, salt));
- }
- p = NULL; /* no longer needed here */
-
- /* the moment of truth -- do we agree with the password? */
- D(("comparing state of pp[%s] and salt[%s]", pp, salt));
-
- if (pp && strcmp(pp, salt) == 0) {
- retval = PAM_SUCCESS;
- } else {
- retval = PAM_AUTH_ERR;
- }
- }
+ retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl));
}
if (retval == PAM_SUCCESS) {
@@ -809,8 +766,6 @@ cleanup:
_pam_delete(data_name);
if (salt)
_pam_delete(salt);
- if (pp)
- _pam_delete(pp);
D(("done [%d].", retval));
@@ -971,21 +926,6 @@ int _unix_read_password(pam_handle_t * pamh
return PAM_SUCCESS;
}
-int _unix_shadowed(const struct passwd *pwd)
-{
- if (pwd != NULL) {
- if (strcmp(pwd->pw_passwd, "x") == 0) {
- return 1;
- }
- if ((pwd->pw_passwd[0] == '#') &&
- (pwd->pw_passwd[1] == '#') &&
- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) {
- return 1;
- }
- }
- return 0;
-}
-
/* ****************************************************************** *
* Copyright (c) Jan Rêkorajski 1999.
* Copyright (c) Andrew G. Morgan 1996-8.
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
index 9873b161..94a9b393 100644
--- a/modules/pam_unix/support.h
+++ b/modules/pam_unix/support.h
@@ -149,7 +149,6 @@ extern int _unix_read_password(pam_handle_t * pamh
,const char *prompt2
,const char *data_name
,const void **pass);
-extern int _unix_shadowed(const struct passwd *pwd);
extern struct spwd *_unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user);
#endif /* _PAM_UNIX_SUPPORT_H */
diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c
index 486a8498..1e8944e9 100644
--- a/modules/pam_unix/unix_chkpwd.c
+++ b/modules/pam_unix/unix_chkpwd.c
@@ -39,8 +39,7 @@ static int selinux_enabled=-1;
#include <security/_pam_types.h>
#include <security/_pam_macros.h>
-#include "md5.h"
-#include "bigcrypt.h"
+#include "passverify.h"
/* syslogging function for errors and other information */
@@ -55,24 +54,6 @@ static void _log_err(int err, const char *format,...)
closelog();
}
-static int _unix_shadowed(const struct passwd *pwd)
-{
- char hashpass[1024];
- if (pwd != NULL) {
- if (strcmp(pwd->pw_passwd, "x") == 0) {
- return 1;
- }
- if (strlen(pwd->pw_name) < sizeof(hashpass) - 2) {
- strcpy(hashpass, "##");
- strcpy(hashpass + 2, pwd->pw_name);
- if (strcmp(pwd->pw_passwd, hashpass) == 0) {
- return 1;
- }
- }
- }
- return 0;
-}
-
static void su_sighandler(int sig)
{
#ifndef SA_RESETHAND
@@ -142,9 +123,7 @@ static int _unix_verify_password(const char *name, const char *p, int nullok)
struct passwd *pwd = NULL;
struct spwd *spwdent = NULL;
char *salt = NULL;
- char *pp = NULL;
int retval = PAM_AUTH_ERR;
- size_t salt_len;
/* UNIX passwords area */
setpwent();
@@ -180,69 +159,18 @@ static int _unix_verify_password(const char *name, const char *p, int nullok)
}
if (pwd == NULL || salt == NULL) {
_log_err(LOG_WARNING, "check pass; user unknown");
- p = NULL;
- return PAM_USER_UNKNOWN;
+ retval = PAM_USER_UNKNOWN;
+ } else {
+ retval = verify_pwd_hash(p, salt, nullok);
}
- salt_len = strlen(salt);
- if (salt_len == 0) {
- return (nullok == 0) ? PAM_AUTH_ERR : PAM_SUCCESS;
- }
- if (p == NULL || strlen(p) == 0) {
+ if (salt) {
_pam_overwrite(salt);
_pam_drop(salt);
- return PAM_AUTHTOK_ERR;
}
- /* the moment of truth -- do we agree with the password? */
- retval = PAM_AUTH_ERR;
- if (!strncmp(salt, "$1$", 3)) {
- pp = Goodcrypt_md5(p, salt);
- if (pp && strcmp(pp, salt) == 0) {
- retval = PAM_SUCCESS;
- } else {
- _pam_overwrite(pp);
- _pam_drop(pp);
- pp = Brokencrypt_md5(p, salt);
- if (pp && strcmp(pp, salt) == 0)
- retval = PAM_SUCCESS;
- }
- } else if (*salt == '$') {
- /*
- * Ok, we don't know the crypt algorithm, but maybe
- * libcrypt nows about it? We should try it.
- */
- pp = x_strdup (crypt(p, salt));
- if (pp && strcmp(pp, salt) == 0) {
- retval = PAM_SUCCESS;
- }
- } else if (*salt == '*' || *salt == '!' || salt_len < 13) {
- retval = PAM_AUTH_ERR;
- } else {
- pp = bigcrypt(p, salt);
- /*
- * Note, we are comparing the bigcrypt of the password with
- * the contents of the password field. If the latter was
- * encrypted with regular crypt (and not bigcrypt) it will
- * have been truncated for storage relative to the output
- * of bigcrypt here. As such we need to compare only the
- * stored string with the subset of bigcrypt's result.
- * Bug 521314.
- */
- if (pp && salt_len == 13 && strlen(pp) > salt_len) {
- _pam_overwrite(pp+salt_len);
- }
-
- if (pp && strcmp(pp, salt) == 0) {
- retval = PAM_SUCCESS;
- }
- }
p = NULL; /* no longer needed here */
- /* clean up */
- _pam_overwrite(pp);
- _pam_drop(pp);
-
return retval;
}