mirror of
https://abf.rosa.ru/djam/pam.git
synced 2025-02-23 08:22:53 +00:00
adopt pbuild patch
This commit is contained in:
parent
3fd7089081
commit
2920bf9f9d
17 changed files with 3610 additions and 52 deletions
|
@ -1,11 +0,0 @@
|
|||
--- Linux-PAM-0.99.3.0/modules/pam_console/Makefile.am.pbuild-rh 2005-12-15 23:07:37.000000000 +0100
|
||||
+++ Linux-PAM-0.99.3.0/modules/pam_console/Makefile.am 2006-01-28 00:26:20.000000000 +0100
|
||||
@@ -57,6 +57,8 @@
|
||||
pam_console_la_CFLAGS = $(AM_CFLAGS)
|
||||
pam_console_apply_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
+configfile.tab.h: configfile.tab.c
|
||||
+
|
||||
configfile.tab.c: configfile.y
|
||||
$(YACC) $(BISON_OPTS) -o $@ -p _pc_yy $<
|
||||
sh $(srcdir)/sed-static $@
|
1730
pam-1.1.1-faillock.patch
Normal file
1730
pam-1.1.1-faillock.patch
Normal file
File diff suppressed because it is too large
Load diff
435
pam-1.1.8-audit-grantor.patch
Normal file
435
pam-1.1.8-audit-grantor.patch
Normal file
|
@ -0,0 +1,435 @@
|
|||
From 0d29e379601819c7f7ed8de18b54de803a9f4049 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Fri, 5 Sep 2014 09:09:37 +0200
|
||||
Subject: [PATCH] Add grantor field to audit records of libpam.
|
||||
|
||||
The grantor field gives audit trail of PAM modules which granted access
|
||||
for successful return from libpam calls. In case of failed return
|
||||
the grantor field is set to '?'.
|
||||
libpam/pam_account.c (pam_acct_mgmt): Remove _pam_auditlog() call.
|
||||
libpam/pam_auth.c (pam_authenticate, pam_setcred): Likewise.
|
||||
libpam/pam_password.c (pam_chauthtok): Likewise.
|
||||
libpam/pam_session.c (pam_open_session, pam_close_session): Likewise.
|
||||
libpam/pam_audit.c (_pam_audit_writelog): Add grantors parameter,
|
||||
add grantor= field to the message if grantors is set.
|
||||
(_pam_list_grantors): New function creating the string with grantors list.
|
||||
(_pam_auditlog): Add struct handler pointer parameter, call _pam_list_grantors()
|
||||
to list the grantors from the handler list.
|
||||
(_pam_audit_end): Add NULL handler parameter to _pam_auditlog() call.
|
||||
(pam_modutil_audit_write): Add NULL grantors parameter to _pam_audit_writelog().
|
||||
libpam/pam_dispatch.c (_pam_dispatch_aux): Set h->grantor where appropriate.
|
||||
(_pam_clear_grantors): New function to clear grantor field of handler.
|
||||
(_pam_dispatch): Call _pam_clear_grantors() before executing the stack.
|
||||
Call _pam_auditlog() when appropriate.
|
||||
libpam/pam_handlers.c (extract_modulename): Do not allow empty module name
|
||||
or just "?" to avoid confusing audit trail.
|
||||
(_pam_add_handler): Test for NULL return from extract_modulename().
|
||||
Clear grantor field of handler.
|
||||
libpam/pam_private.h: Add grantor field to struct handler, add handler pointer
|
||||
parameter to _pam_auditlog().
|
||||
---
|
||||
libpam/pam_account.c | 4 ---
|
||||
libpam/pam_audit.c | 84 +++++++++++++++++++++++++++++++++++++++++++--------
|
||||
libpam/pam_auth.c | 8 -----
|
||||
libpam/pam_dispatch.c | 41 ++++++++++++++++++++-----
|
||||
libpam/pam_handlers.c | 14 +++++++--
|
||||
libpam/pam_password.c | 4 ---
|
||||
libpam/pam_private.h | 3 +-
|
||||
libpam/pam_session.c | 7 -----
|
||||
8 files changed, 119 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/libpam/pam_account.c b/libpam/pam_account.c
|
||||
index 572acc4..3a4fb1f 100644
|
||||
--- a/libpam/pam_account.c
|
||||
+++ b/libpam/pam_account.c
|
||||
@@ -19,9 +19,5 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags)
|
||||
|
||||
retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT);
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags);
|
||||
-#endif
|
||||
-
|
||||
return retval;
|
||||
}
|
||||
diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c
|
||||
index 531746a..24fb799 100644
|
||||
--- a/libpam/pam_audit.c
|
||||
+++ b/libpam/pam_audit.c
|
||||
@@ -6,12 +6,12 @@
|
||||
Authors:
|
||||
Steve Grubb <sgrubb@redhat.com> */
|
||||
|
||||
-#include <stdio.h>
|
||||
-#include <syslog.h>
|
||||
#include "pam_private.h"
|
||||
#include "pam_modutil_private.h"
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
+#include <stdio.h>
|
||||
+#include <syslog.h>
|
||||
#include <libaudit.h>
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
@@ -25,17 +25,24 @@
|
||||
|
||||
static int
|
||||
_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type,
|
||||
- const char *message, int retval)
|
||||
+ const char *message, const char *grantors, int retval)
|
||||
{
|
||||
static int old_errno = -1;
|
||||
- int rc;
|
||||
- char buf[32];
|
||||
+ int rc = -ENOMEM;
|
||||
+ char *buf;
|
||||
+ const char *grantors_field = " grantors=";
|
||||
|
||||
- snprintf(buf, sizeof(buf), "PAM:%s", message);
|
||||
+ if (grantors == NULL) {
|
||||
+ grantors = "";
|
||||
+ grantors_field = "";
|
||||
+ }
|
||||
|
||||
- rc = audit_log_acct_message (audit_fd, type, NULL, buf,
|
||||
- (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
|
||||
- -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS );
|
||||
+ if (asprintf(&buf, "PAM:%s%s%s", message, grantors_field, grantors) >= 0) {
|
||||
+ rc = audit_log_acct_message(audit_fd, type, NULL, buf,
|
||||
+ (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
|
||||
+ -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS);
|
||||
+ free(buf);
|
||||
+ }
|
||||
|
||||
/* libaudit sets errno to his own negative error code. This can be
|
||||
an official errno number, but must not. It can also be a audit
|
||||
@@ -78,12 +85,54 @@ _pam_audit_open(pam_handle_t *pamh)
|
||||
return audit_fd;
|
||||
}
|
||||
|
||||
+static int
|
||||
+_pam_list_grantors(struct handler *hlist, int retval, char **list)
|
||||
+{
|
||||
+ *list = NULL;
|
||||
+
|
||||
+ if (retval == PAM_SUCCESS) {
|
||||
+ struct handler *h;
|
||||
+ char *p = NULL;
|
||||
+ size_t len = 0;
|
||||
+
|
||||
+ for (h = hlist; h != NULL; h = h->next) {
|
||||
+ if (h->grantor) {
|
||||
+ len += strlen(h->mod_name) + 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (len == 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ *list = malloc(len);
|
||||
+ if (*list == NULL) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (h = hlist; h != NULL; h = h->next) {
|
||||
+ if (h->grantor) {
|
||||
+ if (p == NULL) {
|
||||
+ p = *list;
|
||||
+ } else {
|
||||
+ p = stpcpy(p, ",");
|
||||
+ }
|
||||
+
|
||||
+ p = stpcpy(p, h->mod_name);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int
|
||||
-_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
|
||||
+_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h)
|
||||
{
|
||||
const char *message;
|
||||
int type;
|
||||
int audit_fd;
|
||||
+ char *grantors;
|
||||
|
||||
if ((audit_fd=_pam_audit_open(pamh)) == -1) {
|
||||
return PAM_SYSTEM_ERR;
|
||||
@@ -134,8 +183,17 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
|
||||
retval = PAM_SYSTEM_ERR;
|
||||
}
|
||||
|
||||
- if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0)
|
||||
+ if (_pam_list_grantors(h, retval, &grantors) < 0) {
|
||||
+ /* allocation failure */
|
||||
+ pam_syslog(pamh, LOG_CRIT, "_pam_list_grantors() failed: %m");
|
||||
retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ if (_pam_audit_writelog(pamh, audit_fd, type, message,
|
||||
+ grantors ? grantors : "?", retval) < 0)
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+
|
||||
+ free(grantors);
|
||||
|
||||
audit_close(audit_fd);
|
||||
return retval;
|
||||
@@ -149,7 +207,7 @@ _pam_audit_end(pam_handle_t *pamh, int status UNUSED)
|
||||
* stacks having been run. Assume that this is sshd faking
|
||||
* things for an unknown user.
|
||||
*/
|
||||
- _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0);
|
||||
+ _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -168,7 +226,7 @@ pam_modutil_audit_write(pam_handle_t *pamh, int type,
|
||||
return retval;
|
||||
}
|
||||
|
||||
- rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval);
|
||||
+ rc = _pam_audit_writelog(pamh, audit_fd, type, message, NULL, retval);
|
||||
|
||||
audit_close(audit_fd);
|
||||
|
||||
diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c
|
||||
index 5984fa5..1e7bc6e 100644
|
||||
--- a/libpam/pam_auth.c
|
||||
+++ b/libpam/pam_auth.c
|
||||
@@ -45,10 +45,6 @@ int pam_authenticate(pam_handle_t *pamh, int flags)
|
||||
prelude_send_alert(pamh, retval);
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags);
|
||||
-#endif
|
||||
-
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -71,10 +67,6 @@ int pam_setcred(pam_handle_t *pamh, int flags)
|
||||
|
||||
retval = _pam_dispatch(pamh, flags, PAM_SETCRED);
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags);
|
||||
-#endif
|
||||
-
|
||||
D(("pam_setcred exit"));
|
||||
|
||||
return retval;
|
||||
diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c
|
||||
index eb52c82..cf632e8 100644
|
||||
--- a/libpam/pam_dispatch.c
|
||||
+++ b/libpam/pam_dispatch.c
|
||||
@@ -217,8 +217,14 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
|
||||
status = retval;
|
||||
}
|
||||
}
|
||||
- if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) {
|
||||
- goto decision_made;
|
||||
+ if ( impression == _PAM_POSITIVE ) {
|
||||
+ if ( retval == PAM_SUCCESS ) {
|
||||
+ h->grantor = 1;
|
||||
+ }
|
||||
+
|
||||
+ if ( action == _PAM_ACTION_DONE ) {
|
||||
+ goto decision_made;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -262,6 +268,9 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
|
||||
|| (impression == _PAM_POSITIVE
|
||||
&& status == PAM_SUCCESS) ) {
|
||||
if ( retval != PAM_IGNORE || cached_retval == retval ) {
|
||||
+ if ( impression == _PAM_UNDEF && retval == PAM_SUCCESS ) {
|
||||
+ h->grantor = 1;
|
||||
+ }
|
||||
impression = _PAM_POSITIVE;
|
||||
status = retval;
|
||||
}
|
||||
@@ -308,6 +317,13 @@ decision_made: /* by getting here we have made a decision */
|
||||
return status;
|
||||
}
|
||||
|
||||
+static void _pam_clear_grantors(struct handler *h)
|
||||
+{
|
||||
+ for (; h != NULL; h = h->next) {
|
||||
+ h->grantor = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function translates the module dispatch request into a pointer
|
||||
* to the stack of modules that will actually be run. the
|
||||
@@ -318,21 +334,21 @@ decision_made: /* by getting here we have made a decision */
|
||||
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
|
||||
{
|
||||
struct handler *h = NULL;
|
||||
- int retval, use_cached_chain;
|
||||
+ int retval = PAM_SYSTEM_ERR, use_cached_chain;
|
||||
_pam_boolean resumed;
|
||||
|
||||
IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);
|
||||
|
||||
if (__PAM_FROM_MODULE(pamh)) {
|
||||
D(("called from a module!?"));
|
||||
- return PAM_SYSTEM_ERR;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
/* Load all modules, resolve all symbols */
|
||||
|
||||
if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
|
||||
pam_syslog(pamh, LOG_ERR, "unable to dispatch function");
|
||||
- return retval;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
use_cached_chain = _PAM_PLEASE_FREEZE;
|
||||
@@ -360,7 +376,8 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
|
||||
break;
|
||||
default:
|
||||
pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice);
|
||||
- return PAM_ABORT;
|
||||
+ retval = PAM_ABORT;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
if (h == NULL) { /* there was no handlers.conf... entry; will use
|
||||
@@ -393,11 +410,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"application failed to re-exec stack [%d:%d]",
|
||||
pamh->former.choice, choice);
|
||||
- return PAM_ABORT;
|
||||
+ retval = PAM_ABORT;
|
||||
+ goto end;
|
||||
}
|
||||
resumed = PAM_TRUE;
|
||||
} else {
|
||||
resumed = PAM_FALSE;
|
||||
+ _pam_clear_grantors(h);
|
||||
}
|
||||
|
||||
__PAM_TO_MODULE(pamh);
|
||||
@@ -417,5 +436,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
|
||||
pamh->former.choice = PAM_NOT_STACKED;
|
||||
}
|
||||
|
||||
+end:
|
||||
+
|
||||
+#ifdef HAVE_LIBAUDIT
|
||||
+ if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) {
|
||||
+ retval = _pam_auditlog(pamh, choice, retval, flags, h);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return retval;
|
||||
}
|
||||
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
|
||||
index 02714f7..df3a1d9 100644
|
||||
--- a/libpam/pam_handlers.c
|
||||
+++ b/libpam/pam_handlers.c
|
||||
@@ -611,6 +611,12 @@ extract_modulename(const char *mod_path)
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
|
||||
+ if (*retval == '\0' || strcmp(retval, "?") == 0) {
|
||||
+ /* do not allow empty module name or "?" to avoid confusing audit trail */
|
||||
+ _pam_drop(retval);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -888,7 +894,9 @@ int _pam_add_handler(pam_handle_t *pamh
|
||||
(*handler_p)->cached_retval_p = &((*handler_p)->cached_retval);
|
||||
(*handler_p)->argc = argc;
|
||||
(*handler_p)->argv = argv; /* not a copy */
|
||||
- (*handler_p)->mod_name = extract_modulename(mod_path);
|
||||
+ if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL)
|
||||
+ return PAM_ABORT;
|
||||
+ (*handler_p)->grantor = 0;
|
||||
(*handler_p)->next = NULL;
|
||||
|
||||
/* some of the modules have a second calling function */
|
||||
@@ -920,7 +928,9 @@ int _pam_add_handler(pam_handle_t *pamh
|
||||
} else {
|
||||
(*handler_p2)->argv = NULL; /* no arguments */
|
||||
}
|
||||
- (*handler_p2)->mod_name = extract_modulename(mod_path);
|
||||
+ if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL)
|
||||
+ return PAM_ABORT;
|
||||
+ (*handler_p2)->grantor = 0;
|
||||
(*handler_p2)->next = NULL;
|
||||
}
|
||||
|
||||
diff --git a/libpam/pam_password.c b/libpam/pam_password.c
|
||||
index 75db5e5..592e01f 100644
|
||||
--- a/libpam/pam_password.c
|
||||
+++ b/libpam/pam_password.c
|
||||
@@ -57,9 +57,5 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
|
||||
D(("will resume when ready", retval));
|
||||
}
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_CHAUTHTOK, retval, flags);
|
||||
-#endif
|
||||
-
|
||||
return retval;
|
||||
}
|
||||
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
|
||||
index 134dc72..d93283c 100644
|
||||
--- a/libpam/pam_private.h
|
||||
+++ b/libpam/pam_private.h
|
||||
@@ -55,6 +55,7 @@ struct handler {
|
||||
struct handler *next;
|
||||
char *mod_name;
|
||||
int stack_level;
|
||||
+ int grantor;
|
||||
};
|
||||
|
||||
#define PAM_HT_MODULE 0
|
||||
@@ -316,7 +317,7 @@ if ((pamh) == NULL) { \
|
||||
do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0)
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
-extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags);
|
||||
+extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h);
|
||||
extern int _pam_audit_end(pam_handle_t *pamh, int pam_status);
|
||||
#endif
|
||||
|
||||
diff --git a/libpam/pam_session.c b/libpam/pam_session.c
|
||||
index 512153f..cb393c1 100644
|
||||
--- a/libpam/pam_session.c
|
||||
+++ b/libpam/pam_session.c
|
||||
@@ -22,9 +22,6 @@ int pam_open_session(pam_handle_t *pamh, int flags)
|
||||
}
|
||||
retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION);
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval, flags);
|
||||
-#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -43,10 +40,6 @@ int pam_close_session(pam_handle_t *pamh, int flags)
|
||||
|
||||
retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);
|
||||
|
||||
-#ifdef HAVE_LIBAUDIT
|
||||
- retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags);
|
||||
-#endif
|
||||
-
|
||||
return retval;
|
||||
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
53
pam-1.1.8-audit-user-mgmt.patch
Normal file
53
pam-1.1.8-audit-user-mgmt.patch
Normal file
|
@ -0,0 +1,53 @@
|
|||
--- a/modules/pam_faillock/main.c.audit-user-mgmt 2014-10-17 12:09:12.928490104 +0200
|
||||
+++ b/modules/pam_faillock/main.c 2014-10-17 12:09:43.001169008 +0200
|
||||
@@ -127,7 +127,6 @@ do_user(struct options *opts, const char
|
||||
}
|
||||
if (opts->reset) {
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
- char buf[64];
|
||||
int audit_fd;
|
||||
#endif
|
||||
|
||||
@@ -141,10 +140,8 @@ do_user(struct options *opts, const char
|
||||
if ((audit_fd=audit_open()) >= 0) {
|
||||
|
||||
if (pwd != NULL) {
|
||||
- snprintf(buf, sizeof(buf), "faillock reset uid=%u",
|
||||
- pwd->pw_uid);
|
||||
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
|
||||
- buf, NULL, NULL, NULL, rv == 0);
|
||||
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
|
||||
+ "faillock-reset", NULL, pwd->pw_uid, NULL, NULL, NULL, rv == 0);
|
||||
}
|
||||
close(audit_fd);
|
||||
}
|
||||
--- a/modules/pam_tally2/pam_tally2.c.audit-user-mgmt 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ b/modules/pam_tally2/pam_tally2.c 2014-10-17 12:09:12.965490940 +0200
|
||||
@@ -997,9 +997,9 @@ main( int argc UNUSED, char **argv )
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
char buf[64];
|
||||
int audit_fd = audit_open();
|
||||
- snprintf(buf, sizeof(buf), "pam_tally2 uid=%u reset=%hu", uid, cline_reset);
|
||||
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
|
||||
- buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
+ snprintf(buf, sizeof(buf), "pam_tally2 reset=%hu", cline_reset);
|
||||
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
|
||||
+ buf, NULL, uid, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
if (audit_fd >=0)
|
||||
close(audit_fd);
|
||||
#endif
|
||||
@@ -1040,11 +1040,10 @@ main( int argc UNUSED, char **argv )
|
||||
}
|
||||
else if ( !cline_reset ) {
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
- char buf[64];
|
||||
int audit_fd = audit_open();
|
||||
- snprintf(buf, sizeof(buf), "pam_tally2 uid=all reset=0");
|
||||
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
|
||||
- buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
|
||||
+ "pam_tally2-reset-all-accts reset=0", "*", -1,
|
||||
+ NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
if (audit_fd >=0)
|
||||
close(audit_fd);
|
||||
#endif
|
21
pam-1.1.8-canonicalize-username.patch
Normal file
21
pam-1.1.8-canonicalize-username.patch
Normal file
|
@ -0,0 +1,21 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c
|
||||
--- Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c 2014-03-06 12:03:54.429639972 +0100
|
||||
@@ -491,12 +491,17 @@ compute_exec_context(pam_handle_t *pamh,
|
||||
char *level = NULL;
|
||||
security_context_t *contextlist = NULL;
|
||||
int num_contexts = 0;
|
||||
+ const struct passwd *pwd;
|
||||
|
||||
if (!(username = get_item(pamh, PAM_USER))) {
|
||||
pam_syslog(pamh, LOG_ERR, "Cannot obtain the user name");
|
||||
return PAM_USER_UNKNOWN;
|
||||
}
|
||||
|
||||
+ if ((pwd = pam_modutil_getpwnam(pamh, username)) != NULL) {
|
||||
+ username = pwd->pw_name;
|
||||
+ } /* ignore error and keep using original username */
|
||||
+
|
||||
/* compute execute context */
|
||||
#ifdef HAVE_GETSEUSER
|
||||
if (!(service = get_item(pamh, PAM_SERVICE))) {
|
108
pam-1.1.8-full-relro.patch
Normal file
108
pam-1.1.8-full-relro.patch
Normal file
|
@ -0,0 +1,108 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_console/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_console/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_console/Makefile.am.relro 2014-08-13 16:02:49.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_console/Makefile.am 2014-09-10 17:14:33.245554314 +0200
|
||||
@@ -33,6 +33,8 @@ pam_console_la_LIBADD = -L$(top_builddir
|
||||
|
||||
pam_console_apply_LDADD = -L$(top_builddir)/libpam -lpam
|
||||
|
||||
+pam_console_apply_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
+
|
||||
securelib_LTLIBRARIES = pam_console.la
|
||||
sbin_PROGRAMS = pam_console_apply
|
||||
|
||||
@@ -47,7 +49,7 @@ pam_console_apply_SOURCES = pam_console_
|
||||
configfile.c configfile.h hashtable.c hashtable.h hashtable_private.h
|
||||
|
||||
pam_console_la_CFLAGS = $(AM_CFLAGS)
|
||||
-pam_console_apply_CFLAGS = $(AM_CFLAGS)
|
||||
+pam_console_apply_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
|
||||
configfile.tab.c: configfile.y
|
||||
$(YACC) $(BISON_OPTS) -o $@ -p _pc_yy $<
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am.relro 2014-08-13 16:02:49.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am 2014-09-10 17:16:11.102808189 +0200
|
||||
@@ -19,7 +19,7 @@ secureconfdir = $(SCONFIGDIR)
|
||||
|
||||
noinst_HEADERS = faillock.h
|
||||
|
||||
-faillock_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
|
||||
+faillock_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include @PIE_CFLAGS@
|
||||
pam_faillock_la_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
|
||||
|
||||
pam_faillock_la_LDFLAGS = -no-undefined -avoid-version -module
|
||||
@@ -28,6 +28,7 @@ if HAVE_VERSIONING
|
||||
pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
|
||||
+faillock_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
faillock_LDADD = -L$(top_builddir)/libpam -lpam $(LIBAUDIT)
|
||||
|
||||
securelib_LTLIBRARIES = pam_faillock.la
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro 2014-09-10 17:17:20.273401344 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am 2014-09-10 17:17:07.857115369 +0200
|
||||
@@ -9,7 +9,7 @@ securelibfilterdir = $(SECUREDIR)/pam_fi
|
||||
|
||||
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
-I$(srcdir)/.. @PIE_CFLAGS@
|
||||
-AM_LDFLAGS = @PIE_LDFLAGS@
|
||||
+AM_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
LDADD = $(top_builddir)/libpam/libpam.la
|
||||
|
||||
securelibfilter_PROGRAMS = upperLOWER
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am 2014-09-10 17:18:42.922304935 +0200
|
||||
@@ -30,6 +30,8 @@ endif
|
||||
|
||||
sbin_PROGRAMS = mkhomedir_helper
|
||||
mkhomedir_helper_SOURCES = mkhomedir_helper.c
|
||||
+mkhomedir_helper_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
+mkhomedir_helper_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
mkhomedir_helper_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am 2014-09-10 17:22:04.339944040 +0200
|
||||
@@ -26,6 +26,8 @@ if HAVE_VERSIONING
|
||||
pam_tally2_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
|
||||
+pam_tally2_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
+pam_tally2_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
pam_tally2_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
|
||||
|
||||
securelib_LTLIBRARIES = pam_tally2.la
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am 2014-08-13 16:02:49.906688139 +0200
|
||||
@@ -36,7 +36,7 @@ pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
|
||||
pam_timestamp_check_SOURCES = pam_timestamp_check.c
|
||||
pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
-pam_timestamp_check_LDFLAGS = @PIE_LDFLAGS@
|
||||
+pam_timestamp_check_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
|
||||
hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
|
||||
hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_unix/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_unix/Makefile.am 2014-08-13 16:02:49.906688139 +0200
|
||||
@@ -55,13 +55,13 @@ bigcrypt_LDADD = @LIBCRYPT@
|
||||
unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \
|
||||
passverify.c
|
||||
unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\"
|
||||
-unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@
|
||||
+unix_chkpwd_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@
|
||||
|
||||
unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \
|
||||
passverify.c
|
||||
unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\"
|
||||
-unix_update_LDFLAGS = @PIE_LDFLAGS@
|
||||
+unix_update_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
37
pam-1.1.8-lastlog-uninitialized.patch
Normal file
37
pam-1.1.8-lastlog-uninitialized.patch
Normal file
|
@ -0,0 +1,37 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.uninitialized Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c
|
||||
--- Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.uninitialized 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c 2014-08-25 16:44:24.365174752 +0200
|
||||
@@ -350,6 +350,8 @@ last_login_write(pam_handle_t *pamh, int
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
+ memset(&last_login, 0, sizeof(last_login));
|
||||
+
|
||||
/* set this login date */
|
||||
D(("set the most recent login time"));
|
||||
(void) time(&ll_time); /* set the time */
|
||||
@@ -364,14 +366,12 @@ last_login_write(pam_handle_t *pamh, int
|
||||
}
|
||||
|
||||
/* copy to last_login */
|
||||
- last_login.ll_host[0] = '\0';
|
||||
strncat(last_login.ll_host, remote_host, sizeof(last_login.ll_host)-1);
|
||||
|
||||
/* set the terminal line */
|
||||
terminal_line = get_tty(pamh);
|
||||
|
||||
/* copy to last_login */
|
||||
- last_login.ll_line[0] = '\0';
|
||||
strncat(last_login.ll_line, terminal_line, sizeof(last_login.ll_line)-1);
|
||||
terminal_line = NULL;
|
||||
|
||||
@@ -628,7 +628,8 @@ pam_sm_authenticate(pam_handle_t *pamh,
|
||||
lltime = (time(NULL) - lltime) / (24*60*60);
|
||||
|
||||
if (lltime > inactive_days) {
|
||||
- pam_syslog(pamh, LOG_INFO, "user %s inactive for %d days - denied", user, lltime);
|
||||
+ pam_syslog(pamh, LOG_INFO, "user %s inactive for %ld days - denied",
|
||||
+ user, (long) lltime);
|
||||
return PAM_AUTH_ERR;
|
||||
}
|
||||
|
41
pam-1.1.8-limits-check-process.patch
Normal file
41
pam-1.1.8-limits-check-process.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c.check-process Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c
|
||||
--- Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c.check-process 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c 2014-09-10 16:39:36.263256066 +0200
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
+#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
@@ -269,16 +270,27 @@ check_logins (pam_handle_t *pamh, const
|
||||
continue;
|
||||
}
|
||||
if (!pl->flag_numsyslogins) {
|
||||
+ char user[sizeof(ut->UT_USER) + 1];
|
||||
+ user[0] = '\0';
|
||||
+ strncat(user, ut->UT_USER, sizeof(ut->UT_USER));
|
||||
+
|
||||
if (((pl->login_limit_def == LIMITS_DEF_USER)
|
||||
|| (pl->login_limit_def == LIMITS_DEF_GROUP)
|
||||
|| (pl->login_limit_def == LIMITS_DEF_DEFAULT))
|
||||
- && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) {
|
||||
+ && strcmp(name, user) != 0) {
|
||||
continue;
|
||||
}
|
||||
if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP)
|
||||
- && !pam_modutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) {
|
||||
+ && !pam_modutil_user_in_group_nam_nam(pamh, user, pl->login_group)) {
|
||||
continue;
|
||||
}
|
||||
+ if (kill(ut->ut_pid, 0) == -1 && errno == ESRCH) {
|
||||
+ /* process does not exist anymore */
|
||||
+ pam_syslog(pamh, LOG_WARNING,
|
||||
+ "Stale utmp entry (pid %d) for '%s' ignored",
|
||||
+ ut->ut_pid, user);
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
if (++count > limit) {
|
||||
break;
|
54
pam-1.1.8-limits-docfix.patch
Normal file
54
pam-1.1.8-limits-docfix.patch
Normal file
|
@ -0,0 +1,54 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_limits/limits.conf.docfix Linux-PAM-1.1.8/modules/pam_limits/limits.conf
|
||||
--- Linux-PAM-1.1.8/modules/pam_limits/limits.conf.docfix 2014-07-14 14:58:05.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_limits/limits.conf 2014-09-10 16:42:51.254747161 +0200
|
||||
@@ -32,7 +32,7 @@
|
||||
# - data - max data size (KB)
|
||||
# - fsize - maximum filesize (KB)
|
||||
# - memlock - max locked-in-memory address space (KB)
|
||||
-# - nofile - max number of open files
|
||||
+# - nofile - max number of open file descriptors
|
||||
# - rss - max resident set size (KB)
|
||||
# - stack - max stack size (KB)
|
||||
# - cpu - max CPU time (MIN)
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml.docfix Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml
|
||||
--- Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml.docfix 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml 2014-09-10 16:44:01.624367933 +0200
|
||||
@@ -178,7 +178,7 @@
|
||||
<varlistentry>
|
||||
<term><option>nofile</option></term>
|
||||
<listitem>
|
||||
- <para>maximum number of open files</para>
|
||||
+ <para>maximum number of open file descriptors</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@@ -214,14 +214,17 @@
|
||||
<varlistentry>
|
||||
<term><option>maxlogins</option></term>
|
||||
<listitem>
|
||||
- <para>maximum number of logins for this user except
|
||||
- for this with <emphasis>uid=0</emphasis></para>
|
||||
+ <para>maximum number of logins for this user (this limit does
|
||||
+ not apply to user with <emphasis>uid=0</emphasis>)</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>maxsyslogins</option></term>
|
||||
<listitem>
|
||||
- <para>maximum number of all logins on system</para>
|
||||
+ <para>maximum number of all logins on system; user is not
|
||||
+ allowed to log-in if total number of all users' logins is
|
||||
+ greater than specified number (this limit does not apply to
|
||||
+ user with <emphasis>uid=0</emphasis>)</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@@ -292,7 +295,7 @@
|
||||
permanent; existing only for the duration of the session.
|
||||
One exception is the <emphasis>maxlogin</emphasis> option, this one
|
||||
is system wide. But there is a race, concurrent logins at the same
|
||||
- time will not always be detect as such but only counted as one.
|
||||
+ time will not always be detected as such but only counted as one.
|
||||
</para>
|
||||
<para>
|
||||
In the <emphasis>limits</emphasis> configuration file, the
|
151
pam-1.1.8-loginuid-container.patch
Normal file
151
pam-1.1.8-loginuid-container.patch
Normal file
|
@ -0,0 +1,151 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c
|
||||
--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c 2014-01-27 17:24:53.000000000 +0100
|
||||
@@ -47,25 +47,56 @@
|
||||
|
||||
/*
|
||||
* This function writes the loginuid to the /proc system. It returns
|
||||
- * 0 on success and 1 on failure.
|
||||
+ * PAM_SUCCESS on success,
|
||||
+ * PAM_IGNORE when /proc/self/loginuid does not exist,
|
||||
+ * PAM_SESSION_ERR in case of any other error.
|
||||
*/
|
||||
static int set_loginuid(pam_handle_t *pamh, uid_t uid)
|
||||
{
|
||||
- int fd, count, rc = 0;
|
||||
- char loginuid[24];
|
||||
+ int fd, count, rc = PAM_SESSION_ERR;
|
||||
+ char loginuid[24], buf[24];
|
||||
+ static const char host_uid_map[] = " 0 0 4294967295\n";
|
||||
+ char uid_map[sizeof(host_uid_map)];
|
||||
+
|
||||
+ /* loginuid in user namespaces currently isn't writable and in some
|
||||
+ case, not even readable, so consider any failure as ignorable (but try
|
||||
+ anyway, in case we hit a kernel which supports it). */
|
||||
+ fd = open("/proc/self/uid_map", O_RDONLY);
|
||||
+ if (fd >= 0) {
|
||||
+ count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
|
||||
+ if (strncmp(uid_map, host_uid_map, count) != 0)
|
||||
+ rc = PAM_IGNORE;
|
||||
+ close(fd);
|
||||
+ }
|
||||
|
||||
- count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
|
||||
- fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
|
||||
+ fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR);
|
||||
if (fd < 0) {
|
||||
- if (errno != ENOENT) {
|
||||
- rc = 1;
|
||||
- pam_syslog(pamh, LOG_ERR,
|
||||
- "Cannot open /proc/self/loginuid: %m");
|
||||
+ if (errno == ENOENT) {
|
||||
+ rc = PAM_IGNORE;
|
||||
+ }
|
||||
+ if (rc != PAM_IGNORE) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
|
||||
+ "/proc/self/loginuid");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
- if (pam_modutil_write(fd, loginuid, count) != count)
|
||||
- rc = 1;
|
||||
+
|
||||
+ count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
|
||||
+ if (pam_modutil_read(fd, buf, sizeof(buf)) == count &&
|
||||
+ memcmp(buf, loginuid, count) == 0) {
|
||||
+ rc = PAM_SUCCESS;
|
||||
+ goto done; /* already correct */
|
||||
+ }
|
||||
+ if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
|
||||
+ pam_modutil_write(fd, loginuid, count) == count) {
|
||||
+ rc = PAM_SUCCESS;
|
||||
+ } else {
|
||||
+ if (rc != PAM_IGNORE) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
|
||||
+ "/proc/self/loginuid");
|
||||
+ }
|
||||
+ }
|
||||
+ done:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
@@ -165,6 +196,7 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||||
{
|
||||
const char *user = NULL;
|
||||
struct passwd *pwd;
|
||||
+ int ret;
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
int require_auditd = 0;
|
||||
#endif
|
||||
@@ -183,9 +215,14 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
|
||||
- if (set_loginuid(pamh, pwd->pw_uid)) {
|
||||
- pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n");
|
||||
- return PAM_SESSION_ERR;
|
||||
+ ret = set_loginuid(pamh, pwd->pw_uid);
|
||||
+ switch (ret) {
|
||||
+ case PAM_SUCCESS:
|
||||
+ case PAM_IGNORE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ pam_syslog(pamh, LOG_ERR, "set_loginuid failed");
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
@@ -195,11 +232,12 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||||
argv++;
|
||||
}
|
||||
|
||||
- if (require_auditd)
|
||||
- return check_auditd();
|
||||
- else
|
||||
+ if (require_auditd) {
|
||||
+ int rc = check_auditd();
|
||||
+ return rc != PAM_SUCCESS ? rc : ret;
|
||||
+ } else
|
||||
#endif
|
||||
- return PAM_SUCCESS;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml
|
||||
--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml 2014-05-22 11:33:14.000000000 +0200
|
||||
@@ -69,14 +69,31 @@
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
+ <term>PAM_SUCCESS</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The loginuid value is set and auditd is running if check requested.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>PAM_IGNORE</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The /proc/self/loginuid file is not present on the system or the
|
||||
+ login process runs inside uid namespace and kernel does not support
|
||||
+ overwriting loginuid.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
<term>PAM_SESSION_ERR</term>
|
||||
<listitem>
|
||||
<para>
|
||||
- An error occurred during session management.
|
||||
+ Any other error prevented setting loginuid or auditd is not running.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
-
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsect1>
|
22
pam-1.1.8-man-dbsuffix.patch
Normal file
22
pam-1.1.8-man-dbsuffix.patch
Normal file
|
@ -0,0 +1,22 @@
|
|||
diff -up Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml.dbsuffix Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml
|
||||
--- Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml.dbsuffix 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml 2014-09-10 16:28:19.916678273 +0200
|
||||
@@ -89,7 +89,8 @@
|
||||
Use the <filename>/path/database</filename> database for
|
||||
performing lookup. There is no default; the module will
|
||||
return <emphasis remap='B'>PAM_IGNORE</emphasis> if no
|
||||
- database is provided.
|
||||
+ database is provided. Note that the path to the database file
|
||||
+ should be specified without the <filename>.db</filename> suffix.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -260,7 +261,7 @@
|
||||
<refsect1 id='pam_userdb-examples'>
|
||||
<title>EXAMPLES</title>
|
||||
<programlisting>
|
||||
-auth sufficient pam_userdb.so icase db=/etc/dbtest.db
|
||||
+auth sufficient pam_userdb.so icase db=/etc/dbtest
|
||||
</programlisting>
|
||||
</refsect1>
|
||||
|
50
pam-1.1.8-opasswd-tolerant.patch
Normal file
50
pam-1.1.8-opasswd-tolerant.patch
Normal file
|
@ -0,0 +1,50 @@
|
|||
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
|
||||
index 836d713..c36628e 100644
|
||||
--- a/modules/pam_pwhistory/opasswd.c
|
||||
+++ b/modules/pam_pwhistory/opasswd.c
|
||||
@@ -82,10 +82,15 @@ parse_entry (char *line, opwd *data)
|
||||
{
|
||||
const char delimiters[] = ":";
|
||||
char *endptr;
|
||||
+ char *count;
|
||||
|
||||
data->user = strsep (&line, delimiters);
|
||||
data->uid = strsep (&line, delimiters);
|
||||
- data->count = strtol (strsep (&line, delimiters), &endptr, 10);
|
||||
+ count = strsep (&line, delimiters);
|
||||
+ if (data->user == NULL || data->uid == NULL || count == NULL)
|
||||
+ return 1;
|
||||
+
|
||||
+ data->count = strtol (count, &endptr, 10);
|
||||
if (endptr != NULL && *endptr != '\0')
|
||||
return 1;
|
||||
|
||||
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
|
||||
index 4840bb2..7f7bc49 100644
|
||||
--- a/modules/pam_unix/passverify.c
|
||||
+++ b/modules/pam_unix/passverify.c
|
||||
@@ -639,11 +639,23 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
|
||||
continue;
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
s_luser = strtok_r(buf, ":", &sptr);
|
||||
+ if (s_luser == NULL) {
|
||||
+ found = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
s_uid = strtok_r(NULL, ":", &sptr);
|
||||
+ if (s_uid == NULL) {
|
||||
+ found = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
s_npas = strtok_r(NULL, ":", &sptr);
|
||||
+ if (s_npas == NULL) {
|
||||
+ found = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
s_pas = strtok_r(NULL, ":", &sptr);
|
||||
npas = strtol(s_npas, NULL, 10) + 1;
|
||||
- while (npas > howmany) {
|
||||
+ while (npas > howmany && s_pas != NULL) {
|
||||
s_pas = strpbrk(s_pas, ",");
|
||||
if (s_pas != NULL)
|
||||
s_pas++;
|
11
pam-1.1.8-pbuild.patch
Normal file
11
pam-1.1.8-pbuild.patch
Normal file
|
@ -0,0 +1,11 @@
|
|||
diff -ur Linux-PAM-1.1.8.old/modules/pam_console/Makefile.am Linux-PAM-1.1.8/modules/pam_console/Makefile.am
|
||||
--- Linux-PAM-1.1.8.old/modules/pam_console/Makefile.am 2015-01-21 13:49:13.000000000 +0300
|
||||
+++ Linux-PAM-1.1.8/modules/pam_console/Makefile.am 2015-01-21 13:54:33.000000000 +0300
|
||||
@@ -51,6 +51,7 @@
|
||||
pam_console_la_CFLAGS = $(AM_CFLAGS)
|
||||
pam_console_apply_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
|
||||
+configfile.tab.h: configfile.tab.c
|
||||
configfile.tab.c: configfile.y
|
||||
$(YACC) $(BISON_OPTS) -o $@ -p _pc_yy $<
|
||||
sh $(srcdir)/sed-static $@
|
813
pam-1.1.8-pwhistory-helper.patch
Normal file
813
pam-1.1.8-pwhistory-helper.patch
Normal file
|
@ -0,0 +1,813 @@
|
|||
diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am
|
||||
index 4bb4d6d..9157b91 100644
|
||||
--- a/modules/pam_pwhistory/Makefile.am
|
||||
+++ b/modules/pam_pwhistory/Makefile.am
|
||||
@@ -1,5 +1,6 @@
|
||||
#
|
||||
# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
|
||||
+# Copyright (c) 2013 Red Hat, Inc.
|
||||
#
|
||||
|
||||
CLEANFILES = *~
|
||||
@@ -9,25 +10,34 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_pwhistory
|
||||
|
||||
TESTS = tst-pam_pwhistory
|
||||
|
||||
-man_MANS = pam_pwhistory.8
|
||||
+man_MANS = pam_pwhistory.8 pwhistory_helper.8
|
||||
|
||||
-XMLS = README.xml pam_pwhistory.8.xml
|
||||
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
|
||||
|
||||
securelibdir = $(SECUREDIR)
|
||||
secureconfdir = $(SCONFIGDIR)
|
||||
|
||||
-AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
|
||||
-AM_LDFLAGS = -no-undefined -avoid-version -module
|
||||
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
+ -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
|
||||
+
|
||||
+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module
|
||||
if HAVE_VERSIONING
|
||||
- AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
+ pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
|
||||
noinst_HEADERS = opasswd.h
|
||||
|
||||
securelib_LTLIBRARIES = pam_pwhistory.la
|
||||
-pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
|
||||
+pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
|
||||
+pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
|
||||
pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
|
||||
|
||||
+sbin_PROGRAMS = pwhistory_helper
|
||||
+pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @PIE_CFLAGS@
|
||||
+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
|
||||
+pwhistory_helper_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
|
||||
+
|
||||
if ENABLE_REGENERATE_MAN
|
||||
noinst_DATA = README
|
||||
README: pam_pwhistory.8.xml
|
||||
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
|
||||
index 836d713..e319ff3 100644
|
||||
--- a/modules/pam_pwhistory/opasswd.c
|
||||
+++ b/modules/pam_pwhistory/opasswd.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -38,6 +39,7 @@
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
+#include <shadow.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@@ -47,6 +49,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
+#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined (HAVE_XCRYPT_H)
|
||||
@@ -55,7 +58,14 @@
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HELPER_COMPILE
|
||||
+#define pam_modutil_getpwnam(h,n) getpwnam(n)
|
||||
+#define pam_modutil_getspnam(h,n) getspnam(n)
|
||||
+#define pam_syslog(h,a,...) helper_log_err(a,__VA_ARGS__)
|
||||
+#else
|
||||
+#include <security/pam_modutil.h>
|
||||
#include <security/pam_ext.h>
|
||||
+#endif
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
#include "opasswd.h"
|
||||
@@ -76,6 +86,19 @@ typedef struct {
|
||||
char *old_passwords;
|
||||
} opwd;
|
||||
|
||||
+#ifdef HELPER_COMPILE
|
||||
+void
|
||||
+helper_log_err(int err, const char *format, ...)
|
||||
+{
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV);
|
||||
+ vsyslog(err, format, args);
|
||||
+ va_end(args);
|
||||
+ closelog();
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static int
|
||||
parse_entry (char *line, opwd *data)
|
||||
@@ -112,8 +135,8 @@ compare_password(const char *newpass, const char *oldpass)
|
||||
}
|
||||
|
||||
/* Check, if the new password is already in the opasswd file. */
|
||||
-int
|
||||
-check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
+PAMH_ARG_DECL(int
|
||||
+check_old_pass, const char *user,
|
||||
const char *newpass, int debug)
|
||||
{
|
||||
int retval = PAM_SUCCESS;
|
||||
@@ -123,6 +146,11 @@ check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
opwd entry;
|
||||
int found = 0;
|
||||
|
||||
+#ifndef HELPER_COMPILE
|
||||
+ if (SELINUX_ENABLED)
|
||||
+ return PAM_PWHISTORY_RUN_HELPER;
|
||||
+#endif
|
||||
+
|
||||
if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
@@ -208,9 +236,9 @@ check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
return retval;
|
||||
}
|
||||
|
||||
-int
|
||||
-save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
- const char *oldpass, int howmany, int debug UNUSED)
|
||||
+PAMH_ARG_DECL(int
|
||||
+save_old_pass, const char *user,
|
||||
+ int howmany, int debug UNUSED)
|
||||
{
|
||||
char opasswd_tmp[] = TMP_PASSWORDS_FILE;
|
||||
struct stat opasswd_stat;
|
||||
@@ -221,10 +249,35 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
char *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
int found = 0;
|
||||
+ struct passwd *pwd;
|
||||
+ const char *oldpass;
|
||||
+
|
||||
+ pwd = pam_modutil_getpwnam (pamh, user);
|
||||
+ if (pwd == NULL)
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
|
||||
if (howmany <= 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
+#ifndef HELPER_COMPILE
|
||||
+ if (SELINUX_ENABLED)
|
||||
+ return PAM_PWHISTORY_RUN_HELPER;
|
||||
+#endif
|
||||
+
|
||||
+ if ((strcmp(pwd->pw_passwd, "x") == 0) ||
|
||||
+ ((pwd->pw_passwd[0] == '#') &&
|
||||
+ (pwd->pw_passwd[1] == '#') &&
|
||||
+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
|
||||
+ {
|
||||
+ struct spwd *spw = pam_modutil_getspnam (pamh, user);
|
||||
+
|
||||
+ if (spw == NULL)
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ oldpass = spw->sp_pwdp;
|
||||
+ }
|
||||
+ else
|
||||
+ oldpass = pwd->pw_passwd;
|
||||
+
|
||||
if (oldpass == NULL || *oldpass == '\0')
|
||||
return PAM_SUCCESS;
|
||||
|
||||
@@ -447,7 +500,7 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
{
|
||||
char *out;
|
||||
|
||||
- if (asprintf (&out, "%s:%d:1:%s\n", user, uid, oldpass) < 0)
|
||||
+ if (asprintf (&out, "%s:%d:1:%s\n", user, pwd->pw_uid, oldpass) < 0)
|
||||
{
|
||||
retval = PAM_AUTHTOK_ERR;
|
||||
if (oldpf)
|
||||
diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h
|
||||
index db3e656..1b08699 100644
|
||||
--- a/modules/pam_pwhistory/opasswd.h
|
||||
+++ b/modules/pam_pwhistory/opasswd.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -36,10 +37,32 @@
|
||||
#ifndef __OPASSWD_H__
|
||||
#define __OPASSWD_H__
|
||||
|
||||
-extern int check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
- const char *newpass, int debug);
|
||||
-extern int save_old_pass (pam_handle_t *pamh, const char *user,
|
||||
- uid_t uid, const char *oldpass,
|
||||
- int howmany, int debug);
|
||||
+#define PAM_PWHISTORY_RUN_HELPER PAM_CRED_INSUFFICIENT
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#define SELINUX_ENABLED is_selinux_enabled()>0
|
||||
+#else
|
||||
+#define SELINUX_ENABLED 0
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HELPER_COMPILE
|
||||
+#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__)
|
||||
+#define PAMH_ARG(...) __VA_ARGS__
|
||||
+#else
|
||||
+#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__)
|
||||
+#define PAMH_ARG(...) pamh, __VA_ARGS__
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HELPER_COMPILE
|
||||
+void
|
||||
+helper_log_err(int err, const char *format, ...);
|
||||
+#endif
|
||||
+
|
||||
+PAMH_ARG_DECL(int
|
||||
+check_old_pass, const char *user, const char *newpass, int debug);
|
||||
+
|
||||
+PAMH_ARG_DECL(int
|
||||
+save_old_pass, const char *user, int howmany, int debug);
|
||||
|
||||
#endif /* __OPASSWD_H__ */
|
||||
diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c
|
||||
index 654edd3..d6c5c47 100644
|
||||
--- a/modules/pam_pwhistory/pam_pwhistory.c
|
||||
+++ b/modules/pam_pwhistory/pam_pwhistory.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012 Thorsten Kukuk
|
||||
* Author: Thorsten Kukuk <kukuk@thkukuk.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -46,10 +47,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
-#include <shadow.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <sys/resource.h>
|
||||
+#include <sys/wait.h>
|
||||
+#include <signal.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/pam_modutil.h>
|
||||
@@ -59,6 +64,7 @@
|
||||
#include "opasswd.h"
|
||||
|
||||
#define DEFAULT_BUFLEN 2048
|
||||
+#define MAX_FD_NO 20000
|
||||
|
||||
struct options_t {
|
||||
int debug;
|
||||
@@ -102,6 +108,184 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
|
||||
pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
|
||||
}
|
||||
|
||||
+static int
|
||||
+run_save_helper(pam_handle_t *pamh, const char *user,
|
||||
+ int howmany, int debug)
|
||||
+{
|
||||
+ int retval, child;
|
||||
+ struct sigaction newsa, oldsa;
|
||||
+
|
||||
+ memset(&newsa, '\0', sizeof(newsa));
|
||||
+ newsa.sa_handler = SIG_DFL;
|
||||
+ sigaction(SIGCHLD, &newsa, &oldsa);
|
||||
+
|
||||
+ child = fork();
|
||||
+ if (child == 0)
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+ struct rlimit rlim;
|
||||
+ int dummyfds[2];
|
||||
+ static char *envp[] = { NULL };
|
||||
+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
+
|
||||
+ /* replace std file descriptors with a dummy pipe */
|
||||
+ if (pipe2(dummyfds, O_NONBLOCK) == 0)
|
||||
+ {
|
||||
+ dup2(dummyfds[0], STDIN_FILENO);
|
||||
+ dup2(dummyfds[1], STDOUT_FILENO);
|
||||
+ dup2(dummyfds[1], STDERR_FILENO);
|
||||
+ }
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0)
|
||||
+ {
|
||||
+ if (rlim.rlim_max >= MAX_FD_NO)
|
||||
+ rlim.rlim_max = MAX_FD_NO;
|
||||
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++)
|
||||
+ {
|
||||
+ if (i != dummyfds[0])
|
||||
+ close(i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* exec binary helper */
|
||||
+ args[0] = strdup(PWHISTORY_HELPER);
|
||||
+ args[1] = strdup("save");
|
||||
+ args[2] = x_strdup(user);
|
||||
+ asprintf(&args[3], "%d", howmany);
|
||||
+ asprintf(&args[4], "%d", debug);
|
||||
+
|
||||
+ execve(args[0], args, envp);
|
||||
+
|
||||
+ _exit(PAM_SYSTEM_ERR);
|
||||
+ }
|
||||
+ else if (child > 0)
|
||||
+ {
|
||||
+ /* wait for child */
|
||||
+ int rc = 0;
|
||||
+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save waitpid returned %d: %m", rc);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else if (!WIFEXITED(retval))
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save abnormal exit: %d", retval);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = WEXITSTATUS(retval);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+run_check_helper(pam_handle_t *pamh, const char *user,
|
||||
+ const char *newpass, int debug)
|
||||
+{
|
||||
+ int retval, child, fds[2];
|
||||
+ struct sigaction newsa, oldsa;
|
||||
+
|
||||
+ /* create a pipe for the password */
|
||||
+ if (pipe(fds) != 0)
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+
|
||||
+ memset(&newsa, '\0', sizeof(newsa));
|
||||
+ newsa.sa_handler = SIG_DFL;
|
||||
+ sigaction(SIGCHLD, &newsa, &oldsa);
|
||||
+
|
||||
+ child = fork();
|
||||
+ if (child == 0)
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+ struct rlimit rlim;
|
||||
+ int dummyfds[2];
|
||||
+ static char *envp[] = { NULL };
|
||||
+ char *args[] = { NULL, NULL, NULL, NULL, NULL };
|
||||
+
|
||||
+ /* reopen stdin as pipe */
|
||||
+ dup2(fds[0], STDIN_FILENO);
|
||||
+
|
||||
+ /* replace std file descriptors with a dummy pipe */
|
||||
+ if (pipe2(dummyfds, O_NONBLOCK) == 0)
|
||||
+ {
|
||||
+ dup2(dummyfds[1], STDOUT_FILENO);
|
||||
+ dup2(dummyfds[1], STDERR_FILENO);
|
||||
+ }
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0)
|
||||
+ {
|
||||
+ if (rlim.rlim_max >= MAX_FD_NO)
|
||||
+ rlim.rlim_max = MAX_FD_NO;
|
||||
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++)
|
||||
+ {
|
||||
+ if (i != dummyfds[0])
|
||||
+ close(i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* exec binary helper */
|
||||
+ args[0] = strdup(PWHISTORY_HELPER);
|
||||
+ args[1] = strdup("check");
|
||||
+ args[2] = x_strdup(user);
|
||||
+ asprintf(&args[3], "%d", debug);
|
||||
+
|
||||
+ execve(args[0], args, envp);
|
||||
+
|
||||
+ _exit(PAM_SYSTEM_ERR);
|
||||
+ }
|
||||
+ else if (child > 0)
|
||||
+ {
|
||||
+ /* wait for child */
|
||||
+ int rc = 0;
|
||||
+ if (newpass == NULL)
|
||||
+ newpass = "";
|
||||
+
|
||||
+ /* send the password to the child */
|
||||
+ if (write(fds[1], newpass, strlen(newpass)+1) == -1)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Cannot send password to helper: %m");
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ newpass = NULL;
|
||||
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
|
||||
+ close(fds[1]);
|
||||
+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check waitpid returned %d: %m", rc);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else if (!WIFEXITED(retval))
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check abnormal exit: %d", retval);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = WEXITSTATUS(retval);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ close(fds[0]);
|
||||
+ close(fds[1]);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
|
||||
/* This module saves the current crypted password in /etc/security/opasswd
|
||||
and then compares the new password with all entries in this file. */
|
||||
@@ -109,7 +293,6 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
|
||||
PAM_EXTERN int
|
||||
pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
- struct passwd *pwd;
|
||||
const char *newpass;
|
||||
const char *user;
|
||||
int retval, tries;
|
||||
@@ -154,31 +337,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
- pwd = pam_modutil_getpwnam (pamh, user);
|
||||
- if (pwd == NULL)
|
||||
- return PAM_USER_UNKNOWN;
|
||||
+ retval = save_old_pass (pamh, user, options.remember, options.debug);
|
||||
|
||||
- if ((strcmp(pwd->pw_passwd, "x") == 0) ||
|
||||
- ((pwd->pw_passwd[0] == '#') &&
|
||||
- (pwd->pw_passwd[1] == '#') &&
|
||||
- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
|
||||
- {
|
||||
- struct spwd *spw = pam_modutil_getspnam (pamh, user);
|
||||
- if (spw == NULL)
|
||||
- return PAM_USER_UNKNOWN;
|
||||
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
|
||||
+ retval = run_save_helper(pamh, user, options.remember, options.debug);
|
||||
|
||||
- retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp,
|
||||
- options.remember, options.debug);
|
||||
- if (retval != PAM_SUCCESS)
|
||||
- return retval;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd,
|
||||
- options.remember, options.debug);
|
||||
- if (retval != PAM_SUCCESS)
|
||||
- return retval;
|
||||
- }
|
||||
+ if (retval != PAM_SUCCESS)
|
||||
+ return retval;
|
||||
|
||||
newpass = NULL;
|
||||
tries = 0;
|
||||
@@ -207,8 +372,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
if (options.debug)
|
||||
pam_syslog (pamh, LOG_DEBUG, "check against old password file");
|
||||
|
||||
- if (check_old_pass (pamh, user, newpass,
|
||||
- options.debug) != PAM_SUCCESS)
|
||||
+ retval = check_old_pass (pamh, user, newpass, options.debug);
|
||||
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
|
||||
+ retval = run_check_helper(pamh, user, newpass, options.debug);
|
||||
+
|
||||
+ if (retval != PAM_SUCCESS)
|
||||
{
|
||||
if (getuid() || options.enforce_for_root ||
|
||||
(flags & PAM_CHANGE_EXPIRED_AUTHTOK))
|
||||
diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml
|
||||
new file mode 100644
|
||||
index 0000000..a030176
|
||||
--- /dev/null
|
||||
+++ b/modules/pam_pwhistory/pwhistory_helper.8.xml
|
||||
@@ -0,0 +1,68 @@
|
||||
+<?xml version="1.0" encoding='UTF-8'?>
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
+
|
||||
+<refentry id="pwhistory_helper">
|
||||
+
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>pwhistory_helper</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv id="pwhistory_helper-name">
|
||||
+ <refname>pwhistory_helper</refname>
|
||||
+ <refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsynopsisdiv>
|
||||
+ <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
|
||||
+ <command>pwhistory_helper</command>
|
||||
+ <arg choice="opt">
|
||||
+ ...
|
||||
+ </arg>
|
||||
+ </cmdsynopsis>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+ <refsect1 id="pwhistory_helper-description">
|
||||
+
|
||||
+ <title>DESCRIPTION</title>
|
||||
+
|
||||
+ <para>
|
||||
+ <emphasis>pwhistory_helper</emphasis> is a helper program for the
|
||||
+ <emphasis>pam_pwhistory</emphasis> module that transfers password hashes
|
||||
+ from passwd or shadow file to the opasswd file and checks a password
|
||||
+ supplied by user against the existing hashes in the opasswd file.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ The purpose of the helper is to enable tighter confinement of
|
||||
+ login and password changing services. The helper is thus called only
|
||||
+ when SELinux is enabled on the system.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ The interface of the helper - command line options, and input/output
|
||||
+ data format are internal to the <emphasis>pam_pwhistory</emphasis>
|
||||
+ module and it should not be called directly from applications.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pwhistory_helper-see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pwhistory_helper-author'>
|
||||
+ <title>AUTHOR</title>
|
||||
+ <para>
|
||||
+ Written by Tomas Mraz based on the code originally in
|
||||
+ <emphasis>pam_pwhistory and pam_unix</emphasis> modules.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+</refentry>
|
||||
diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c
|
||||
new file mode 100644
|
||||
index 0000000..b07ab81
|
||||
--- /dev/null
|
||||
+++ b/modules/pam_pwhistory/pwhistory_helper.c
|
||||
@@ -0,0 +1,209 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
+ * Author: Tomas Mraz <tmraz@redhat.com>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <syslog.h>
|
||||
+#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <signal.h>
|
||||
+#include <security/_pam_types.h>
|
||||
+#include <security/_pam_macros.h>
|
||||
+#include "opasswd.h"
|
||||
+
|
||||
+#define MAXPASS 200
|
||||
+
|
||||
+static void
|
||||
+su_sighandler(int sig)
|
||||
+{
|
||||
+#ifndef SA_RESETHAND
|
||||
+ /* emulate the behaviour of the SA_RESETHAND flag */
|
||||
+ if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) {
|
||||
+ struct sigaction sa;
|
||||
+ memset(&sa, '\0', sizeof(sa));
|
||||
+ sa.sa_handler = SIG_DFL;
|
||||
+ sigaction(sig, &sa, NULL);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (sig > 0) {
|
||||
+ _exit(sig);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+setup_signals(void)
|
||||
+{
|
||||
+ struct sigaction action; /* posix signal structure */
|
||||
+
|
||||
+ /*
|
||||
+ * Setup signal handlers
|
||||
+ */
|
||||
+ (void) memset((void *) &action, 0, sizeof(action));
|
||||
+ action.sa_handler = su_sighandler;
|
||||
+#ifdef SA_RESETHAND
|
||||
+ action.sa_flags = SA_RESETHAND;
|
||||
+#endif
|
||||
+ (void) sigaction(SIGILL, &action, NULL);
|
||||
+ (void) sigaction(SIGTRAP, &action, NULL);
|
||||
+ (void) sigaction(SIGBUS, &action, NULL);
|
||||
+ (void) sigaction(SIGSEGV, &action, NULL);
|
||||
+ action.sa_handler = SIG_IGN;
|
||||
+ action.sa_flags = 0;
|
||||
+ (void) sigaction(SIGTERM, &action, NULL);
|
||||
+ (void) sigaction(SIGHUP, &action, NULL);
|
||||
+ (void) sigaction(SIGINT, &action, NULL);
|
||||
+ (void) sigaction(SIGQUIT, &action, NULL);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_passwords(int fd, int npass, char **passwords)
|
||||
+{
|
||||
+ int rbytes = 0;
|
||||
+ int offset = 0;
|
||||
+ int i = 0;
|
||||
+ char *pptr;
|
||||
+ while (npass > 0)
|
||||
+ {
|
||||
+ rbytes = read(fd, passwords[i]+offset, MAXPASS-offset);
|
||||
+
|
||||
+ if (rbytes < 0)
|
||||
+ {
|
||||
+ if (errno == EINTR) continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (rbytes == 0)
|
||||
+ break;
|
||||
+
|
||||
+ while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes))
|
||||
+ != NULL)
|
||||
+ {
|
||||
+ rbytes -= pptr - (passwords[i]+offset) + 1;
|
||||
+ i++;
|
||||
+ offset = 0;
|
||||
+ npass--;
|
||||
+ if (rbytes > 0)
|
||||
+ {
|
||||
+ if (npass > 0)
|
||||
+ memcpy(passwords[i], pptr+1, rbytes);
|
||||
+ memset(pptr+1, '\0', rbytes);
|
||||
+ }
|
||||
+ }
|
||||
+ offset += rbytes;
|
||||
+ }
|
||||
+
|
||||
+ /* clear up */
|
||||
+ if (offset > 0 && npass > 0)
|
||||
+ memset(passwords[i], '\0', offset);
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+check_history(const char *user, const char *debug)
|
||||
+{
|
||||
+ char pass[MAXPASS + 1];
|
||||
+ char *passwords[] = { pass };
|
||||
+ int npass;
|
||||
+ int dbg = atoi(debug); /* no need to be too fancy here */
|
||||
+ int retval;
|
||||
+
|
||||
+ /* read the password from stdin (a pipe from the pam_pwhistory module) */
|
||||
+ npass = read_passwords(STDIN_FILENO, 1, passwords);
|
||||
+
|
||||
+ if (npass != 1)
|
||||
+ { /* is it a valid password? */
|
||||
+ helper_log_err(LOG_DEBUG, "no password supplied");
|
||||
+ return PAM_AUTHTOK_ERR;
|
||||
+ }
|
||||
+
|
||||
+ retval = check_old_pass(user, pass, dbg);
|
||||
+
|
||||
+ memset(pass, '\0', MAXPASS); /* clear memory of the password */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+save_history(const char *user, const char *howmany, const char *debug)
|
||||
+{
|
||||
+ int num = atoi(howmany);
|
||||
+ int dbg = atoi(debug); /* no need to be too fancy here */
|
||||
+ int retval;
|
||||
+
|
||||
+ retval = save_old_pass(user, num, dbg);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ const char *option;
|
||||
+ const char *user;
|
||||
+
|
||||
+ /*
|
||||
+ * Catch or ignore as many signal as possible.
|
||||
+ */
|
||||
+ setup_signals();
|
||||
+
|
||||
+ /*
|
||||
+ * we establish that this program is running with non-tty stdin.
|
||||
+ * this is to discourage casual use.
|
||||
+ */
|
||||
+
|
||||
+ if (isatty(STDIN_FILENO) || argc < 4)
|
||||
+ {
|
||||
+ fprintf(stderr,
|
||||
+ "This binary is not designed for running in this way.\n");
|
||||
+ sleep(10); /* this should discourage/annoy the user */
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ option = argv[1];
|
||||
+ user = argv[2];
|
||||
+
|
||||
+ if (strcmp(option, "check") == 0 && argc == 4)
|
||||
+ return check_history(user, argv[3]);
|
||||
+ else if (strcmp(option, "save") == 0 && argc == 5)
|
||||
+ return save_history(user, argv[3], argv[4]);
|
||||
+
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+}
|
||||
+
|
|
@ -1,24 +1,37 @@
|
|||
diff -pruN a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
|
||||
--- a/modules/pam_userdb/pam_userdb.c 2011-06-21 16:04:56.000000000 +0700
|
||||
+++ b/modules/pam_userdb/pam_userdb.c 2014-08-28 17:41:35.243954732 +0700
|
||||
@@ -214,24 +214,23 @@ user_lookup (pam_handle_t *pamh, const c
|
||||
/* crypt(3) password storage */
|
||||
|
||||
char *cryptpw;
|
||||
- char salt[2];
|
||||
|
||||
- if (data.dsize != 13) {
|
||||
+ if (data.dsize < 13) {
|
||||
compare = -2;
|
||||
} else if (ctrl & PAM_ICASE_ARG) {
|
||||
compare = -2;
|
||||
From 57a1e2b274d0a6376d92ada9926e5c5741e7da20 Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Fri, 24 Jan 2014 22:18:32 +0000
|
||||
Subject: [PATCH] pam_userdb: fix password hash comparison
|
||||
|
||||
Starting with commit Linux-PAM-0-77-28-g0b3e583 that introduced hashed
|
||||
passwords support in pam_userdb, hashes are compared case-insensitively.
|
||||
This bug leads to accepting hashes for completely different passwords in
|
||||
addition to those that should be accepted.
|
||||
|
||||
Additionally, commit Linux-PAM-1_1_6-13-ge2a8187 that added support for
|
||||
modern password hashes with different lengths and settings, did not
|
||||
update the hash comparison accordingly, which leads to accepting
|
||||
computed hashes longer than stored hashes when the latter is a prefix
|
||||
of the former.
|
||||
|
||||
* modules/pam_userdb/pam_userdb.c (user_lookup): Reject the computed
|
||||
hash whose length differs from the stored hash length.
|
||||
Compare computed and stored hashes case-sensitively.
|
||||
Fixes CVE-2013-7041.
|
||||
|
||||
Bug-Debian: http://bugs.debian.org/731368
|
||||
---
|
||||
modules/pam_userdb/pam_userdb.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
|
||||
index de8b5b1..ff040e6 100644
|
||||
--- a/modules/pam_userdb/pam_userdb.c
|
||||
+++ b/modules/pam_userdb/pam_userdb.c
|
||||
@@ -222,12 +222,15 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
|
||||
} else {
|
||||
- salt[0] = *data.dptr;
|
||||
- salt[1] = *(data.dptr + 1);
|
||||
+ cryptpw = crypt (pass, data.dptr);
|
||||
cryptpw = crypt (pass, data.dptr);
|
||||
|
||||
- cryptpw = crypt (pass, salt);
|
||||
-
|
||||
- if (cryptpw) {
|
||||
- compare = strncasecmp (data.dptr, cryptpw, data.dsize);
|
||||
+ if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
|
||||
|
@ -28,9 +41,12 @@ diff -pruN a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
|
|||
if (ctrl & PAM_DEBUG_ARG) {
|
||||
- pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
|
||||
+ if (cryptpw)
|
||||
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
|
||||
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
|
||||
+ else
|
||||
+ pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
|
||||
+ pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
From 9dcead87e6d7f66d34e7a56d11a30daca367dffb Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Wed, 26 Mar 2014 22:17:23 +0000
|
||||
Subject: [PATCH] pam_timestamp: fix potential directory traversal issue
|
||||
(ticket #27)
|
||||
|
||||
pam_timestamp uses values of PAM_RUSER and PAM_TTY as components of
|
||||
the timestamp pathname it creates, so extra care should be taken to
|
||||
avoid potential directory traversal issues.
|
||||
|
||||
* modules/pam_timestamp/pam_timestamp.c (check_tty): Treat
|
||||
"." and ".." tty values as invalid.
|
||||
(get_ruser): Treat "." and ".." ruser values, as well as any ruser
|
||||
value containing '/', as invalid.
|
||||
|
||||
Fixes CVE-2014-2583.
|
||||
|
||||
Reported-by: Sebastian Krahmer <krahmer@suse.de>
|
||||
---
|
||||
modules/pam_timestamp/pam_timestamp.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
|
||||
index 5193733..b3f08b1 100644
|
||||
|
@ -30,4 +51,6 @@ index 5193733..b3f08b1 100644
|
|||
}
|
||||
if (ruser == NULL || strlen(ruser) >= ruserbuflen) {
|
||||
*ruserbuf = '\0';
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
44
pam.spec
44
pam.spec
|
@ -19,7 +19,7 @@ Epoch: 1
|
|||
Summary: A security tool which provides authentication for applications
|
||||
Name: pam
|
||||
Version: 1.1.8
|
||||
Release: 3
|
||||
Release: 22
|
||||
# The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
|
||||
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
||||
License: BSD and GPLv2+
|
||||
|
@ -51,8 +51,20 @@ Patch9: pam-1.1.6-noflex.patch
|
|||
Patch10: pam-1.1.3-nouserenv.patch
|
||||
Patch11: pam-1.1.3-console-abstract.patch
|
||||
Patch13: pam-1.1.5-limits-user.patch
|
||||
Patch14: pam-1.1.1-faillock.patch
|
||||
Patch22: pam-1.1.7-unix-build.patch
|
||||
Patch32: pam-1.1.7-tty-audit-init.patch
|
||||
Patch33: pam-1.1.8-audit-grantor.patch
|
||||
Patch34: pam-1.1.8-audit-user-mgmt.patch
|
||||
Patch35: pam-1.1.8-canonicalize-username.patch
|
||||
Patch36: pam-1.1.8-full-relro.patch
|
||||
Patch37: pam-1.1.8-lastlog-uninitialized.patch
|
||||
Patch38: pam-1.1.8-limits-check-process.patch
|
||||
Patch39: pam-1.1.8-limits-docfix.patch
|
||||
Patch40: pam-1.1.8-loginuid-container.patch
|
||||
Patch41: pam-1.1.8-man-dbsuffix.patch
|
||||
Patch42: pam-1.1.8-opasswd-tolerant.patch
|
||||
Patch43: pam-1.1.8-pwhistory-helper.patch
|
||||
|
||||
# ROSA specific sources/patches
|
||||
# (fl) fix infinite loop
|
||||
|
@ -64,8 +76,6 @@ Patch508: Linux-PAM-0.99.3.0-pamtimestampadm.patch
|
|||
##Patch512: Linux-PAM-1.1.1-xauth-groups.patch
|
||||
# (tv/blino) add defaults for nice/rtprio in /etc/security/limits.conf
|
||||
Patch517: Linux-PAM-0.99.3.0-enable_rt.patch
|
||||
# (blino) fix parallel build (pam_console)
|
||||
Patch521: Linux-PAM-0.99.3.0-pbuild-rh.patch
|
||||
|
||||
Patch700: pam_fix_static_pam_console.patch
|
||||
# (fc) do not output error when no file is in /etc/security/console.perms.d/
|
||||
|
@ -75,8 +85,10 @@ Patch702: Linux-PAM-1.1.4-add-now-missing-nis-constant.patch
|
|||
|
||||
# (akdengi> add user to default group users which need for Samba
|
||||
Patch801: Linux-PAM-1.1.4-group_add_users.patch
|
||||
#Patch802: pam-CVE-2014-2583.patch
|
||||
#Patch803: pam-CVE-2013-7041.patch
|
||||
Patch802: pam-CVE-2014-2583.patch
|
||||
Patch803: pam-CVE-2013-7041.patch
|
||||
|
||||
Patch804: pam-1.1.8-pbuild.patch
|
||||
|
||||
BuildRequires: selinux-devel >= 2.1.6-7
|
||||
BuildRequires: bison
|
||||
|
@ -169,23 +181,23 @@ mv pam-redhat-%{pam_redhat_version}/* modules
|
|||
|
||||
install -m644 %{SOURCE501} %{SOURCE502} modules/pam_tty_audit/
|
||||
|
||||
mkdir -p doc/txts
|
||||
for readme in modules/pam_*/README ; do
|
||||
cp -f ${readme} doc/txts/README.`dirname ${readme} | sed -e 's|^modules/||'`
|
||||
done
|
||||
#mkdir -p doc/txts
|
||||
#for readme in modules/pam_*/README ; do
|
||||
# cp -f ${readme} doc/txts/README.`dirname ${readme} | sed -e 's|^modules/||'`
|
||||
#done
|
||||
|
||||
#libtoolize -cf
|
||||
autoreconf -ifs -I m4
|
||||
autoreconf -i
|
||||
|
||||
%build
|
||||
export BROWSER=""
|
||||
CFLAGS="$RPM_OPT_FLAGS -fPIC -I%{_includedir}/db_nss -D_GNU_SOURCE" \
|
||||
%configure2_5x \
|
||||
--sbindir=/sbin \
|
||||
--libdir=/%{_lib} \
|
||||
--includedir=%{_includedir}/security \
|
||||
--with-db-uniquename=_nss \
|
||||
--docdir=%{_docdir}/%{name} \
|
||||
--disable-static \
|
||||
--disable-prelude \
|
||||
--enable-selinux \
|
||||
--enable-audit
|
||||
%make
|
||||
|
@ -229,16 +241,11 @@ cp -f %{buildroot}/etc/pam.d/system-auth %{buildroot}/etc/pam.d/system-auth-defa
|
|||
%find_lang Linux-PAM
|
||||
|
||||
%check
|
||||
# (blino) we don't want to test if SE Linux is built, it's disabled
|
||||
# Make sure every module subdirectory gave us a module. Yes, this is hackish.
|
||||
for dir in modules/pam_* ; do
|
||||
#if [ -d ${dir} ] && [[ "${dir}" != "modules/pam_selinux" ]] && [[ "${dir}" != "modules/pam_sepermit" ]]; then
|
||||
# [[ "${dir}" = "modules/pam_tally" ]] && continue
|
||||
if ! ls -1 %{buildroot}/%{_lib}/security/`basename ${dir}`*.so ; then
|
||||
echo ERROR `basename ${dir}` did not build a module.
|
||||
exit 1
|
||||
fi
|
||||
#fi
|
||||
done
|
||||
|
||||
# Check for module problems. Specifically, check that every module we just
|
||||
|
@ -262,9 +269,6 @@ fi
|
|||
if [ ! -a /var/log/tallylog ] ; then
|
||||
install -m 600 /dev/null /var/log/tallylog
|
||||
fi
|
||||
#if [ -f /etc/login.defs ] && ! grep -q USE_TCB /etc/login.defs; then
|
||||
# /usr/sbin/set_tcb --auto --migrate
|
||||
#fi
|
||||
|
||||
%files -f Linux-PAM.lang
|
||||
%doc NEWS
|
||||
|
|
Loading…
Add table
Reference in a new issue