Merge branch 'f13' into f12
Conflicts: pam.spec
This commit is contained in:
commit
777d84fae4
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
*.src.rpm
|
||||
*.tar.bz2
|
||||
pam-redhat-0.99.10-1.tar.bz2
|
||||
Linux-PAM-1.1.0.tar.bz2
|
||||
Linux-PAM-1.1.1.tar.bz2
|
||||
|
@ -2,7 +2,7 @@
|
||||
Version: GnuPG v1.4.9 (GNU/Linux)
|
||||
Comment: See http://www.kernel.org/signature.html for info
|
||||
|
||||
iD8DBQBKO6X0yGugalF9Dw4RAmz7AKCV6q08/CrmPtHX6geM3zrUpeFIIwCfSO12
|
||||
WRW5yU2bG4x+Bb0Ie6ppBbk=
|
||||
=D3mX
|
||||
iD8DBQBLKOWYyGugalF9Dw4RAqYlAJ9st1NRPyZjWFD+Pl+7ifeiDcDTAwCfeyt7
|
||||
l6BKIgA/0NQzw+md5nFXVy4=
|
||||
=Kxq6
|
||||
-----END PGP SIGNATURE-----
|
@ -1,42 +0,0 @@
|
||||
Index: modules/pam_cracklib/pam_cracklib.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_cracklib/pam_cracklib.c,v
|
||||
retrieving revision 1.33
|
||||
retrieving revision 1.34
|
||||
diff -u -p -r1.33 -r1.34
|
||||
--- Linux-PAM/modules/pam_cracklib/pam_cracklib.c 11 Dec 2008 19:41:49 -0000 1.33
|
||||
+++ Linux-PAM/modules/pam_cracklib/pam_cracklib.c 21 Jul 2009 13:59:24 -0000 1.34
|
||||
@@ -545,7 +545,7 @@ static int _pam_unix_approve_pass(pam_ha
|
||||
const char *pass_new)
|
||||
{
|
||||
const char *msg = NULL;
|
||||
- const void *user;
|
||||
+ const char *user;
|
||||
int retval;
|
||||
|
||||
if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) {
|
||||
@@ -556,7 +556,7 @@ static int _pam_unix_approve_pass(pam_ha
|
||||
return PAM_AUTHTOK_ERR;
|
||||
}
|
||||
|
||||
- retval = pam_get_item(pamh, PAM_USER, &user);
|
||||
+ retval = pam_get_user(pamh, &user, NULL);
|
||||
if (retval != PAM_SUCCESS || user == NULL) {
|
||||
if (ctrl & PAM_DEBUG_ARG)
|
||||
pam_syslog(pamh,LOG_ERR,"Can not get username");
|
||||
@@ -658,6 +658,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand
|
||||
pam_error (pamh, _("BAD PASSWORD: %s"), crack_msg);
|
||||
if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
|
||||
{
|
||||
+ pam_set_item (pamh, PAM_AUTHTOK, NULL);
|
||||
retval = PAM_AUTHTOK_ERR;
|
||||
continue;
|
||||
}
|
||||
@@ -670,6 +671,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand
|
||||
if (retval != PAM_SUCCESS) {
|
||||
if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
|
||||
{
|
||||
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
|
||||
retval = PAM_AUTHTOK_ERR;
|
||||
continue;
|
||||
}
|
78
pam-1.1.1-authtok-prompt.patch
Normal file
78
pam-1.1.1-authtok-prompt.patch
Normal file
@ -0,0 +1,78 @@
|
||||
Index: libpam/pam_get_authtok.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/pam/Linux-PAM/libpam/pam_get_authtok.c,v
|
||||
retrieving revision 1.3
|
||||
diff -u -p -r1.3 pam_get_authtok.c
|
||||
--- libpam/pam_get_authtok.c 10 Nov 2009 15:52:20 -0000 1.3
|
||||
+++ libpam/pam_get_authtok.c 22 Jan 2010 17:31:40 -0000
|
||||
@@ -81,7 +81,7 @@ pam_get_authtok_internal (pam_handle_t *
|
||||
char *resp[2] = {NULL, NULL};
|
||||
const void *prevauthtok;
|
||||
const char *authtok_type = "";
|
||||
- int ask_twice = 0; /* Password change, ask twice for it */
|
||||
+ int chpass = 0; /* Password change, ask twice for it */
|
||||
int retval;
|
||||
|
||||
if (authtok == NULL)
|
||||
@@ -91,8 +91,9 @@ pam_get_authtok_internal (pam_handle_t *
|
||||
which needs to be verified. */
|
||||
if (item == PAM_AUTHTOK && pamh->choice == PAM_CHAUTHTOK)
|
||||
{
|
||||
+ chpass = 1;
|
||||
if (!(flags & PAM_GETAUTHTOK_NOVERIFY))
|
||||
- ask_twice = 1;
|
||||
+ ++chpass;
|
||||
|
||||
authtok_type = get_option (pamh, "authtok_type");
|
||||
if (authtok_type == NULL)
|
||||
@@ -110,11 +111,11 @@ pam_get_authtok_internal (pam_handle_t *
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
else if (get_option (pamh, "use_first_pass") ||
|
||||
- (ask_twice && get_option (pamh, "use_authtok")))
|
||||
+ (chpass && get_option (pamh, "use_authtok")))
|
||||
{
|
||||
if (prevauthtok == NULL)
|
||||
{
|
||||
- if (ask_twice)
|
||||
+ if (chpass)
|
||||
return PAM_AUTHTOK_ERR;
|
||||
else
|
||||
return PAM_AUTH_ERR;
|
||||
@@ -127,16 +128,16 @@ pam_get_authtok_internal (pam_handle_t *
|
||||
{
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0],
|
||||
"%s", prompt);
|
||||
- if (retval == PAM_SUCCESS && ask_twice && resp[0] != NULL)
|
||||
+ if (retval == PAM_SUCCESS && chpass > 1 && resp[0] != NULL)
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[1],
|
||||
_("Retype %s"), prompt);
|
||||
}
|
||||
- else if (ask_twice)
|
||||
+ else if (chpass)
|
||||
{
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0],
|
||||
PROMPT1, authtok_type,
|
||||
strlen (authtok_type) > 0?" ":"");
|
||||
- if (retval == PAM_SUCCESS && ask_twice && resp[0] != NULL)
|
||||
+ if (retval == PAM_SUCCESS && chpass > 1 && resp[0] != NULL)
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[1],
|
||||
PROMPT2, authtok_type,
|
||||
strlen (authtok_type) > 0?" ":"");
|
||||
@@ -146,14 +147,14 @@ pam_get_authtok_internal (pam_handle_t *
|
||||
PROMPT);
|
||||
|
||||
if (retval != PAM_SUCCESS || resp[0] == NULL ||
|
||||
- (ask_twice && resp[1] == NULL))
|
||||
+ (chpass > 1 && resp[1] == NULL))
|
||||
{
|
||||
/* We want to abort the password change */
|
||||
pam_error (pamh, _("Password change aborted."));
|
||||
return PAM_AUTHTOK_ERR;
|
||||
}
|
||||
|
||||
- if (ask_twice && strcmp (resp[0], resp[1]) != 0)
|
||||
+ if (chpass > 1 && strcmp (resp[0], resp[1]) != 0)
|
||||
{
|
||||
pam_error (pamh, MISTYPED_PASS);
|
||||
_pam_overwrite (resp[0]);
|
37
pam-1.1.1-cve-2010-3853.patch
Normal file
37
pam-1.1.1-cve-2010-3853.patch
Normal file
@ -0,0 +1,37 @@
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_namespace/pam_namespace.c.execle Linux-PAM-1.1.1/modules/pam_namespace/pam_namespace.c
|
||||
--- Linux-PAM-1.1.1/modules/pam_namespace/pam_namespace.c.execle 2009-04-09 10:07:19.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_namespace/pam_namespace.c 2010-10-20 10:42:19.000000000 +0200
|
||||
@@ -1181,14 +1181,15 @@ static int inst_init(const struct polydi
|
||||
} else {
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
+ static char *envp[] = { NULL };
|
||||
#ifdef WITH_SELINUX
|
||||
if (idata->flags & PAMNS_SELINUX_ENABLED) {
|
||||
if (setexeccon(NULL) < 0)
|
||||
_exit(1);
|
||||
}
|
||||
#endif
|
||||
- if (execl(init_script, init_script,
|
||||
- polyptr->dir, ipath, newdir?"1":"0", idata->user, (char *)NULL) < 0)
|
||||
+ if (execle(init_script, init_script,
|
||||
+ polyptr->dir, ipath, newdir?"1":"0", idata->user, NULL, envp) < 0)
|
||||
_exit(1);
|
||||
} else if (pid > 0) {
|
||||
while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
|
||||
@@ -1608,13 +1609,14 @@ static int cleanup_tmpdirs(struct instan
|
||||
if (pptr->method == TMPDIR && access(pptr->instance_prefix, F_OK) == 0) {
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
+ static char *envp[] = { NULL };
|
||||
#ifdef WITH_SELINUX
|
||||
if (idata->flags & PAMNS_SELINUX_ENABLED) {
|
||||
if (setexeccon(NULL) < 0)
|
||||
_exit(1);
|
||||
}
|
||||
#endif
|
||||
- if (execl("/bin/rm", "/bin/rm", "-rf", pptr->instance_prefix, (char *)NULL) < 0)
|
||||
+ if (execle("/bin/rm", "/bin/rm", "-rf", pptr->instance_prefix, NULL, envp) < 0)
|
||||
_exit(1);
|
||||
} else if (pid > 0) {
|
||||
while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
|
814
pam-1.1.1-drop-privs.patch
Normal file
814
pam-1.1.1-drop-privs.patch
Normal file
@ -0,0 +1,814 @@
|
||||
diff -up Linux-PAM-1.1.1/libpam/include/security/_pam_dropprivs.h.drop-privs Linux-PAM-1.1.1/libpam/include/security/_pam_dropprivs.h
|
||||
--- Linux-PAM-1.1.1/libpam/include/security/_pam_dropprivs.h.drop-privs 2010-10-20 15:33:27.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/libpam/include/security/_pam_dropprivs.h 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2010 Dmitry V. Levin
|
||||
+ *
|
||||
+ * <security/_pam_dropprivs.h>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _SECURITY__PAM_DROPPRIVS_H
|
||||
+#define _SECURITY__PAM_DROPPRIVS_H
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#include <security/_pam_types.h>
|
||||
+
|
||||
+struct pam_modutil_privs {
|
||||
+ gid_t *grplist;
|
||||
+ int number_of_groups;
|
||||
+ int allocated;
|
||||
+ gid_t old_gid;
|
||||
+ uid_t old_uid;
|
||||
+ int is_dropped;
|
||||
+};
|
||||
+
|
||||
+#define PAM_MODUTIL_NGROUPS 64
|
||||
+#define PAM_MODUTIL_DEF_PRIVS(n) \
|
||||
+ gid_t n##_grplist[PAM_MODUTIL_NGROUPS]; \
|
||||
+ struct pam_modutil_privs n = { n##_grplist, PAM_MODUTIL_NGROUPS, 0, -1, -1, 0 }
|
||||
+
|
||||
+extern int PAM_NONNULL((1,2,3))
|
||||
+pam_modutil_drop_priv(pam_handle_t *pamh,
|
||||
+ struct pam_modutil_privs *p,
|
||||
+ const struct passwd *pw);
|
||||
+
|
||||
+extern int PAM_NONNULL((1,2))
|
||||
+pam_modutil_regain_priv(pam_handle_t *pamh,
|
||||
+ struct pam_modutil_privs *p);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _SECURITY__PAM_DROPPRIVS_H */
|
||||
diff -up Linux-PAM-1.1.1/libpam/Makefile.am.drop-privs Linux-PAM-1.1.1/libpam/Makefile.am
|
||||
--- Linux-PAM-1.1.1/libpam/Makefile.am.drop-privs 2009-11-04 15:04:49.000000000 +0100
|
||||
+++ Linux-PAM-1.1.1/libpam/Makefile.am 2010-10-20 15:46:14.000000000 +0200
|
||||
@@ -18,11 +18,15 @@ include_HEADERS = include/security/_pam_
|
||||
include/security/pam_ext.h include/security/pam_modutil.h
|
||||
|
||||
noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
|
||||
- pam_modutil_private.h pam_static_modules.h
|
||||
+ pam_modutil_private.h pam_static_modules.h include/security/_pam_dropprivs.h
|
||||
|
||||
libpam_la_LDFLAGS = -no-undefined -version-info 82:2:82
|
||||
libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@
|
||||
|
||||
+noinst_LIBRARIES = libdropprivs.a
|
||||
+libdropprivs_a_SOURCES = pam_modutil_priv.c
|
||||
+libdropprivs_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
+
|
||||
if STATIC_MODULES
|
||||
libpam_la_LIBADD += $(shell ls ../modules/pam_*/*.lo) \
|
||||
@LIBDB@ @LIBCRYPT@ @LIBNSL@ @LIBCRACK@ -lutil
|
||||
@@ -41,4 +45,4 @@ libpam_la_SOURCES = pam_account.c pam_au
|
||||
pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \
|
||||
pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \
|
||||
pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \
|
||||
- pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c
|
||||
+ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c
|
||||
diff -up Linux-PAM-1.1.1/libpam/pam_modutil_priv.c.drop-privs Linux-PAM-1.1.1/libpam/pam_modutil_priv.c
|
||||
--- Linux-PAM-1.1.1/libpam/pam_modutil_priv.c.drop-privs 2010-10-20 15:33:27.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/libpam/pam_modutil_priv.c 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -0,0 +1,171 @@
|
||||
+/*
|
||||
+ * $Id: pam_modutil_priv.c,v 1.1 2010/10/03 21:02:07 ldv Exp $
|
||||
+ *
|
||||
+ * This file provides two functions:
|
||||
+ * pam_modutil_drop_priv:
|
||||
+ * temporarily lower process fs privileges by switching to another uid/gid,
|
||||
+ * pam_modutil_regain_priv:
|
||||
+ * regain process fs privileges lowered by pam_modutil_drop_priv().
|
||||
+ */
|
||||
+
|
||||
+#include "pam_modutil_private.h"
|
||||
+#include <security/_pam_dropprivs.h>
|
||||
+#include <security/pam_ext.h>
|
||||
+#include <unistd.h>
|
||||
+#include <syslog.h>
|
||||
+#include <pwd.h>
|
||||
+#include <grp.h>
|
||||
+#include <sys/fsuid.h>
|
||||
+
|
||||
+/*
|
||||
+ * Two setfsuid() calls in a row are necessary to check
|
||||
+ * whether setfsuid() succeeded or not.
|
||||
+ */
|
||||
+static int change_uid(uid_t uid, uid_t *save)
|
||||
+{
|
||||
+ uid_t tmp = setfsuid(uid);
|
||||
+ if (save)
|
||||
+ *save = tmp;
|
||||
+ return (uid_t) setfsuid(uid) == uid ? 0 : -1;
|
||||
+}
|
||||
+static int change_gid(gid_t gid, gid_t *save)
|
||||
+{
|
||||
+ gid_t tmp = setfsgid(gid);
|
||||
+ if (save)
|
||||
+ *save = tmp;
|
||||
+ return (gid_t) setfsgid(gid) == gid ? 0 : -1;
|
||||
+}
|
||||
+
|
||||
+static int cleanup(struct pam_modutil_privs *p)
|
||||
+{
|
||||
+ if (p->allocated) {
|
||||
+ p->allocated = 0;
|
||||
+ free(p->grplist);
|
||||
+ }
|
||||
+ p->grplist = NULL;
|
||||
+ p->number_of_groups = 0;
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+#define PRIV_MAGIC 0x1004000a
|
||||
+#define PRIV_MAGIC_DONOTHING 0xdead000a
|
||||
+
|
||||
+int pam_modutil_drop_priv(pam_handle_t *pamh,
|
||||
+ struct pam_modutil_privs *p,
|
||||
+ const struct passwd *pw)
|
||||
+{
|
||||
+ int res;
|
||||
+
|
||||
+ if (p->is_dropped) {
|
||||
+ pam_syslog(pamh, LOG_CRIT,
|
||||
+ "pam_modutil_drop_priv: called with dropped privileges");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If not root, we can do nothing.
|
||||
+ * If switching to root, we have nothing to do.
|
||||
+ * That is, in both cases, we do not care.
|
||||
+ */
|
||||
+ if (geteuid() != 0 || pw->pw_uid == 0) {
|
||||
+ p->is_dropped = PRIV_MAGIC_DONOTHING;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!p->grplist || p->number_of_groups <= 0) {
|
||||
+ pam_syslog(pamh, LOG_CRIT,
|
||||
+ "pam_modutil_drop_priv: called without room for supplementary groups");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ res = getgroups(0, NULL);
|
||||
+ if (res < 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_drop_priv: getgroups failed: %m");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ p->allocated = 0;
|
||||
+ if (res > p->number_of_groups) {
|
||||
+ p->grplist = calloc(res, sizeof(gid_t));
|
||||
+ if (!p->grplist) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "out of memory");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+ p->allocated = 1;
|
||||
+ p->number_of_groups = res;
|
||||
+ }
|
||||
+
|
||||
+ res = getgroups(p->number_of_groups, p->grplist);
|
||||
+ if (res < 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_drop_priv: getgroups failed: %m");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+
|
||||
+ p->number_of_groups = res;
|
||||
+
|
||||
+ /*
|
||||
+ * We should care to leave process credentials in consistent state.
|
||||
+ * That is, e.g. if change_gid() succeeded but change_uid() failed,
|
||||
+ * we should try to restore old gid.
|
||||
+ */
|
||||
+ if (setgroups(0, NULL)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_drop_priv: setgroups failed: %m");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+ if (change_gid(pw->pw_gid, &p->old_gid)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_drop_priv: change_gid failed: %m");
|
||||
+ (void) setgroups(p->number_of_groups, p->grplist);
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+ if (change_uid(pw->pw_uid, &p->old_uid)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_drop_priv: change_uid failed: %m");
|
||||
+ (void) change_gid(p->old_gid, NULL);
|
||||
+ (void) setgroups(p->number_of_groups, p->grplist);
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+
|
||||
+ p->is_dropped = PRIV_MAGIC;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int pam_modutil_regain_priv(pam_handle_t *pamh,
|
||||
+ struct pam_modutil_privs *p)
|
||||
+{
|
||||
+ switch (p->is_dropped) {
|
||||
+ case PRIV_MAGIC_DONOTHING:
|
||||
+ p->is_dropped = 0;
|
||||
+ return 0;
|
||||
+
|
||||
+ case PRIV_MAGIC:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ pam_syslog(pamh, LOG_CRIT,
|
||||
+ "pam_modutil_regain_priv: called with invalid state");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (change_uid(p->old_uid, NULL)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_regain_priv: change_uid failed: %m");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+ if (change_gid(p->old_gid, NULL)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_regain_priv: change_gid failed: %m");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+ if (setgroups(p->number_of_groups, p->grplist)) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "pam_modutil_regain_priv: setgroups failed: %m");
|
||||
+ return cleanup(p);
|
||||
+ }
|
||||
+
|
||||
+ p->is_dropped = 0;
|
||||
+ cleanup(p);
|
||||
+ return 0;
|
||||
+}
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_env/Makefile.am.drop-privs Linux-PAM-1.1.1/modules/pam_env/Makefile.am
|
||||
--- Linux-PAM-1.1.1/modules/pam_env/Makefile.am.drop-privs 2009-06-29 09:24:27.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_env/Makefile.am 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -22,7 +22,7 @@ if HAVE_VERSIONING
|
||||
endif
|
||||
|
||||
securelib_LTLIBRARIES = pam_env.la
|
||||
-pam_env_la_LIBADD = -L$(top_builddir)/libpam -lpam
|
||||
+pam_env_la_LIBADD = -L$(top_builddir)/libpam -ldropprivs -lpam
|
||||
|
||||
secureconf_DATA = pam_env.conf
|
||||
sysconf_DATA = environment
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_env/pam_env.c.drop-privs Linux-PAM-1.1.1/modules/pam_env/pam_env.c
|
||||
--- Linux-PAM-1.1.1/modules/pam_env/pam_env.c.drop-privs 2009-06-29 09:24:27.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_env/pam_env.c 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -10,7 +10,7 @@
|
||||
#define DEFAULT_READ_ENVFILE 1
|
||||
|
||||
#define DEFAULT_USER_ENVFILE ".pam_environment"
|
||||
-#define DEFAULT_USER_READ_ENVFILE 1
|
||||
+#define DEFAULT_USER_READ_ENVFILE 0
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <security/pam_modutil.h>
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_ext.h>
|
||||
+#include <security/_pam_dropprivs.h>
|
||||
|
||||
/* This little structure makes it easier to keep variables together */
|
||||
|
||||
@@ -772,13 +773,14 @@ handle_env (pam_handle_t *pamh, int argc
|
||||
|
||||
if(user_readenv && retval == PAM_SUCCESS) {
|
||||
char *envpath = NULL;
|
||||
- struct passwd *user_entry;
|
||||
+ struct passwd *user_entry = NULL;
|
||||
const char *username;
|
||||
struct stat statbuf;
|
||||
|
||||
username = _pam_get_item_byname(pamh, "PAM_USER");
|
||||
|
||||
- user_entry = pam_modutil_getpwnam (pamh, username);
|
||||
+ if (username)
|
||||
+ user_entry = pam_modutil_getpwnam (pamh, username);
|
||||
if (!user_entry) {
|
||||
pam_syslog(pamh, LOG_ERR, "No such user!?");
|
||||
}
|
||||
@@ -789,7 +791,15 @@ handle_env (pam_handle_t *pamh, int argc
|
||||
return PAM_BUF_ERR;
|
||||
}
|
||||
if (stat(envpath, &statbuf) == 0) {
|
||||
- retval = _parse_config_file(pamh, envpath);
|
||||
+ PAM_MODUTIL_DEF_PRIVS(privs);
|
||||
+
|
||||
+ if (pam_modutil_drop_priv(pamh, &privs, user_entry)) {
|
||||
+ retval = PAM_SESSION_ERR;
|
||||
+ } else {
|
||||
+ retval = _parse_config_file(pamh, envpath);
|
||||
+ if (pam_modutil_regain_priv(pamh, &privs))
|
||||
+ retval = PAM_SESSION_ERR;
|
||||
+ }
|
||||
if (retval == PAM_IGNORE)
|
||||
retval = PAM_SUCCESS;
|
||||
}
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_env/pam_env.8.xml.drop-privs Linux-PAM-1.1.1/modules/pam_env/pam_env.8.xml
|
||||
--- Linux-PAM-1.1.1/modules/pam_env/pam_env.8.xml.drop-privs 2009-06-16 09:35:09.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_env/pam_env.8.xml 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -143,7 +143,10 @@
|
||||
<listitem>
|
||||
<para>
|
||||
Turns on or off the reading of the user specific environment
|
||||
- file. 0 is off, 1 is on. By default this option is on.
|
||||
+ file. 0 is off, 1 is on. By default this option is off as user
|
||||
+ supplied environment variables in the PAM environment could affect
|
||||
+ behavior of subsequent modules in the stack without the consent
|
||||
+ of the system administrator.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_mail/Makefile.am.drop-privs Linux-PAM-1.1.1/modules/pam_mail/Makefile.am
|
||||
--- Linux-PAM-1.1.1/modules/pam_mail/Makefile.am.drop-privs 2009-06-29 09:24:27.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_mail/Makefile.am 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -22,7 +22,7 @@ if HAVE_VERSIONING
|
||||
endif
|
||||
|
||||
securelib_LTLIBRARIES = pam_mail.la
|
||||
-pam_mail_la_LIBADD = -L$(top_builddir)/libpam -lpam
|
||||
+pam_mail_la_LIBADD = -L$(top_builddir)/libpam -ldropprivs -lpam
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
||||
noinst_DATA = README
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_mail/pam_mail.c.drop-privs Linux-PAM-1.1.1/modules/pam_mail/pam_mail.c
|
||||
--- Linux-PAM-1.1.1/modules/pam_mail/pam_mail.c.drop-privs 2008-09-25 13:53:03.000000000 +0200
|
||||
+++ Linux-PAM-1.1.1/modules/pam_mail/pam_mail.c 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_modutil.h>
|
||||
#include <security/pam_ext.h>
|
||||
+#include <security/_pam_dropprivs.h>
|
||||
|
||||
/* argument parsing */
|
||||
|
||||
@@ -124,29 +125,16 @@ _pam_parse (const pam_handle_t *pamh, in
|
||||
|
||||
static int
|
||||
get_folder(pam_handle_t *pamh, int ctrl,
|
||||
- const char *path_mail, char **folder_p, size_t hashcount)
|
||||
+ const char *path_mail, char **folder_p, size_t hashcount,
|
||||
+ const struct passwd *pwd)
|
||||
{
|
||||
int retval;
|
||||
- const char *user, *path;
|
||||
+ const char *path;
|
||||
char *folder = NULL;
|
||||
- const struct passwd *pwd = NULL;
|
||||
-
|
||||
- retval = pam_get_user(pamh, &user, NULL);
|
||||
- if (retval != PAM_SUCCESS || user == NULL) {
|
||||
- pam_syslog(pamh, LOG_ERR, "cannot determine username");
|
||||
- retval = PAM_USER_UNKNOWN;
|
||||
- goto get_folder_cleanup;
|
||||
- }
|
||||
|
||||
if (ctrl & PAM_NEW_MAIL_DIR) {
|
||||
path = path_mail;
|
||||
if (*path == '~') { /* support for $HOME delivery */
|
||||
- pwd = pam_modutil_getpwnam(pamh, user);
|
||||
- if (pwd == NULL) {
|
||||
- pam_syslog(pamh, LOG_ERR, "user unknown");
|
||||
- retval = PAM_USER_UNKNOWN;
|
||||
- goto get_folder_cleanup;
|
||||
- }
|
||||
/*
|
||||
* "~/xxx" and "~xxx" are treated as same
|
||||
*/
|
||||
@@ -168,18 +156,11 @@ get_folder(pam_handle_t *pamh, int ctrl,
|
||||
|
||||
/* put folder together */
|
||||
|
||||
- hashcount = hashcount < strlen(user) ? hashcount : strlen(user);
|
||||
+ hashcount = hashcount < strlen(pwd->pw_name) ?
|
||||
+ hashcount : strlen(pwd->pw_name);
|
||||
|
||||
retval = PAM_BUF_ERR;
|
||||
if (ctrl & PAM_HOME_MAIL) {
|
||||
- if (pwd == NULL) {
|
||||
- pwd = pam_modutil_getpwnam(pamh, user);
|
||||
- if (pwd == NULL) {
|
||||
- pam_syslog(pamh, LOG_ERR, "user unknown");
|
||||
- retval = PAM_USER_UNKNOWN;
|
||||
- goto get_folder_cleanup;
|
||||
- }
|
||||
- }
|
||||
if (asprintf(&folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path) < 0)
|
||||
goto get_folder_cleanup;
|
||||
} else {
|
||||
@@ -192,11 +173,11 @@ get_folder(pam_handle_t *pamh, int ctrl,
|
||||
|
||||
for (i = 0; i < hashcount; i++) {
|
||||
hash[2 * i] = '/';
|
||||
- hash[2 * i + 1] = user[i];
|
||||
+ hash[2 * i + 1] = pwd->pw_name[i];
|
||||
}
|
||||
hash[2 * i] = '\0';
|
||||
|
||||
- rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, user);
|
||||
+ rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, pwd->pw_name);
|
||||
_pam_overwrite(hash);
|
||||
_pam_drop(hash);
|
||||
if (rc < 0)
|
||||
@@ -208,7 +189,6 @@ get_folder(pam_handle_t *pamh, int ctrl,
|
||||
/* tidy up */
|
||||
|
||||
get_folder_cleanup:
|
||||
- user = NULL;
|
||||
path = NULL;
|
||||
|
||||
*folder_p = folder;
|
||||
@@ -402,7 +382,9 @@ static int _do_mail(pam_handle_t *pamh,
|
||||
int retval, ctrl, type;
|
||||
size_t hashcount;
|
||||
char *folder = NULL;
|
||||
+ const char *user;
|
||||
const char *path_mail = NULL;
|
||||
+ const struct passwd *pwd = NULL;
|
||||
|
||||
/*
|
||||
* this module (un)sets the MAIL environment variable, and checks if
|
||||
@@ -411,9 +393,21 @@ static int _do_mail(pam_handle_t *pamh,
|
||||
|
||||
ctrl = _pam_parse(pamh, flags, argc, argv, &path_mail, &hashcount);
|
||||
|
||||
+ retval = pam_get_user(pamh, &user, NULL);
|
||||
+ if (retval != PAM_SUCCESS || user == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "cannot determine username");
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ pwd = pam_modutil_getpwnam (pamh, user);
|
||||
+ if (pwd == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "user unknown");
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
/* which folder? */
|
||||
|
||||
- retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount);
|
||||
+ retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount, pwd);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
D(("failed to find folder"));
|
||||
return retval;
|
||||
@@ -450,7 +444,19 @@ static int _do_mail(pam_handle_t *pamh,
|
||||
|
||||
if ((est && !(ctrl & PAM_NO_LOGIN))
|
||||
|| (!est && (ctrl & PAM_LOGOUT_TOO))) {
|
||||
- type = get_mail_status(pamh, ctrl, folder);
|
||||
+ PAM_MODUTIL_DEF_PRIVS(privs);
|
||||
+
|
||||
+ if (pam_modutil_drop_priv(pamh, &privs, pwd)) {
|
||||
+ retval = PAM_SESSION_ERR;
|
||||
+ goto do_mail_cleanup;
|
||||
+ } else {
|
||||
+ type = get_mail_status(pamh, ctrl, folder);
|
||||
+ if (pam_modutil_regain_priv(pamh, &privs)) {
|
||||
+ retval = PAM_SESSION_ERR;
|
||||
+ goto do_mail_cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (type != 0) {
|
||||
retval = report_mail(pamh, ctrl, type, folder);
|
||||
type = 0;
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_xauth/Makefile.am.drop-privs Linux-PAM-1.1.1/modules/pam_xauth/Makefile.am
|
||||
--- Linux-PAM-1.1.1/modules/pam_xauth/Makefile.am.drop-privs 2009-11-04 13:04:53.000000000 +0100
|
||||
+++ Linux-PAM-1.1.1/modules/pam_xauth/Makefile.am 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -17,7 +17,7 @@ secureconfdir = $(SCONFIGDIR)
|
||||
|
||||
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
|
||||
AM_LDFLAGS = -no-undefined -avoid-version -module \
|
||||
- -L$(top_builddir)/libpam -lpam @LIBSELINUX@
|
||||
+ -L$(top_builddir)/libpam -ldropprivs -lpam @LIBSELINUX@
|
||||
if HAVE_VERSIONING
|
||||
AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_xauth/pam_xauth.c.drop-privs Linux-PAM-1.1.1/modules/pam_xauth/pam_xauth.c
|
||||
--- Linux-PAM-1.1.1/modules/pam_xauth/pam_xauth.c.drop-privs 2009-11-04 13:04:53.000000000 +0100
|
||||
+++ Linux-PAM-1.1.1/modules/pam_xauth/pam_xauth.c 2010-10-20 15:33:27.000000000 +0200
|
||||
@@ -35,8 +35,10 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
-#include <sys/fsuid.h>
|
||||
#include <sys/wait.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <grp.h>
|
||||
@@ -56,6 +58,7 @@
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_modutil.h>
|
||||
#include <security/pam_ext.h>
|
||||
+#include <security/_pam_dropprivs.h>
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
@@ -87,7 +90,7 @@ static const char * const xauthpaths[] =
|
||||
/* Run a given command (with a NULL-terminated argument list), feeding it the
|
||||
* given input on stdin, and storing any output it generates. */
|
||||
static int
|
||||
-run_coprocess(const char *input, char **output,
|
||||
+run_coprocess(pam_handle_t *pamh, const char *input, char **output,
|
||||
uid_t uid, gid_t gid, const char *command, ...)
|
||||
{
|
||||
int ipipe[2], opipe[2], i;
|
||||
@@ -126,9 +129,26 @@ run_coprocess(const char *input, char **
|
||||
const char *tmp;
|
||||
int maxopened;
|
||||
/* Drop privileges. */
|
||||
- setgid(gid);
|
||||
- setgroups(0, NULL);
|
||||
- setuid(uid);
|
||||
+ if (setgid(gid) == -1)
|
||||
+ {
|
||||
+ int err = errno;
|
||||
+ pam_syslog (pamh, LOG_ERR, "setgid(%lu) failed: %m",
|
||||
+ (unsigned long) getegid ());
|
||||
+ _exit (err);
|
||||
+ }
|
||||
+ if (setgroups(0, NULL) == -1)
|
||||
+ {
|
||||
+ int err = errno;
|
||||
+ pam_syslog (pamh, LOG_ERR, "setgroups() failed: %m");
|
||||
+ _exit (err);
|
||||
+ }
|
||||
+ if (setuid(uid) == -1)
|
||||
+ {
|
||||
+ int err = errno;
|
||||
+ pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m",
|
||||
+ (unsigned long) geteuid ());
|
||||
+ _exit (err);
|
||||
+ }
|
||||
/* Initialize the argument list. */
|
||||
memset(args, 0, sizeof(args));
|
||||
/* Set the pipe descriptors up as stdin and stdout, and close
|
||||
@@ -215,9 +235,11 @@ check_acl(pam_handle_t *pamh,
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct passwd *pwd;
|
||||
- FILE *fp;
|
||||
- int i;
|
||||
- uid_t euid;
|
||||
+ FILE *fp = NULL;
|
||||
+ int i, fd = -1, save_errno;
|
||||
+ struct stat st;
|
||||
+ PAM_MODUTIL_DEF_PRIVS(privs);
|
||||
+
|
||||
/* Check this user's <sense> file. */
|
||||
pwd = pam_modutil_getpwnam(pamh, this_user);
|
||||
if (pwd == NULL) {
|
||||
@@ -233,11 +255,33 @@ check_acl(pam_handle_t *pamh,
|
||||
"name of user's home directory is too long");
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
- euid = geteuid();
|
||||
- setfsuid(pwd->pw_uid);
|
||||
- fp = fopen(path, "r");
|
||||
- setfsuid(euid);
|
||||
- if (fp != NULL) {
|
||||
+ if (pam_modutil_drop_priv(pamh, &privs, pwd))
|
||||
+ return PAM_SESSION_ERR;
|
||||
+ if (!stat(path, &st)) {
|
||||
+ if (!S_ISREG(st.st_mode))
|
||||
+ errno = EINVAL;
|
||||
+ else
|
||||
+ fd = open(path, O_RDONLY | O_NOCTTY);
|
||||
+ }
|
||||
+ save_errno = errno;
|
||||
+ if (pam_modutil_regain_priv(pamh, &privs)) {
|
||||
+ if (fd >= 0)
|
||||
+ close(fd);
|
||||
+ return PAM_SESSION_ERR;
|
||||
+ }
|
||||
+ if (fd >= 0) {
|
||||
+ if (!fstat(fd, &st)) {
|
||||
+ if (!S_ISREG(st.st_mode))
|
||||
+ errno = EINVAL;
|
||||
+ else
|
||||
+ fp = fdopen(fd, "r");
|
||||
+ }
|
||||
+ if (!fp) {
|
||||
+ save_errno = errno;
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ }
|
||||
+ if (fp) {
|
||||
char buf[LINE_MAX], *tmp;
|
||||
/* Scan the file for a list of specs of users to "trust". */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
@@ -268,6 +312,7 @@ check_acl(pam_handle_t *pamh,
|
||||
return PAM_PERM_DENIED;
|
||||
} else {
|
||||
/* Default to okay if the file doesn't exist. */
|
||||
+ errno = save_errno;
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
if (noent_code == PAM_SUCCESS) {
|
||||
@@ -305,7 +350,7 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
struct passwd *tpwd, *rpwd;
|
||||
int fd, i, debug = 0;
|
||||
int retval = PAM_SUCCESS;
|
||||
- uid_t systemuser = 499, targetuser = 0, euid;
|
||||
+ uid_t systemuser = 499, targetuser = 0;
|
||||
|
||||
/* Parse arguments. We don't understand many, so no sense in breaking
|
||||
* this into a separate function. */
|
||||
@@ -463,14 +508,15 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
xauth, "-f", cookiefile, "nlist", display,
|
||||
(unsigned long) getuid(), (unsigned long) getgid());
|
||||
}
|
||||
- if (run_coprocess(NULL, &cookie,
|
||||
+ if (run_coprocess(pamh, NULL, &cookie,
|
||||
getuid(), getgid(),
|
||||
xauth, "-f", cookiefile, "nlist", display,
|
||||
NULL) == 0) {
|
||||
- int save_errno;
|
||||
#ifdef WITH_SELINUX
|
||||
security_context_t context = NULL;
|
||||
#endif
|
||||
+ PAM_MODUTIL_DEF_PRIVS(privs);
|
||||
+
|
||||
/* Check that we got a cookie. If not, we get creative. */
|
||||
if (((cookie == NULL) || (strlen(cookie) == 0)) &&
|
||||
((strncmp(display, "localhost:", 10) == 0) ||
|
||||
@@ -521,7 +567,7 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
(unsigned long) getuid(),
|
||||
(unsigned long) getgid());
|
||||
}
|
||||
- run_coprocess(NULL, &cookie,
|
||||
+ run_coprocess(pamh, NULL, &cookie,
|
||||
getuid(), getgid(),
|
||||
xauth, "-f", cookiefile,
|
||||
"nlist", t, NULL);
|
||||
@@ -553,9 +599,10 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
}
|
||||
|
||||
/* Generate a new file to hold the data. */
|
||||
- euid = geteuid();
|
||||
- setfsuid(tpwd->pw_uid);
|
||||
-
|
||||
+ if (pam_modutil_drop_priv(pamh, &privs, tpwd)) {
|
||||
+ retval = PAM_SESSION_ERR;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
#ifdef WITH_SELINUX
|
||||
if (is_selinux_enabled() > 0) {
|
||||
struct selabel_handle *ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||
@@ -573,31 +620,24 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif /* WITH_SELINUX */
|
||||
fd = mkstemp(xauthority + sizeof(XAUTHENV));
|
||||
- save_errno = errno;
|
||||
+ if (fd < 0)
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "error creating temporary file `%s': %m",
|
||||
+ xauthority + sizeof(XAUTHENV));
|
||||
+#ifdef WITH_SELINUX
|
||||
if (context != NULL) {
|
||||
free(context);
|
||||
setfscreatecon(NULL);
|
||||
}
|
||||
-#else
|
||||
- fd = mkstemp(xauthority + sizeof(XAUTHENV));
|
||||
- save_errno = errno;
|
||||
-#endif
|
||||
-
|
||||
- setfsuid(euid);
|
||||
- if (fd == -1) {
|
||||
- errno = save_errno;
|
||||
- pam_syslog(pamh, LOG_ERR,
|
||||
- "error creating temporary file `%s': %m",
|
||||
- xauthority + sizeof(XAUTHENV));
|
||||
+#endif /* WITH_SELINUX */
|
||||
+ if (fd >= 0)
|
||||
+ close(fd);
|
||||
+ if (pam_modutil_regain_priv(pamh, &privs) || fd < 0) {
|
||||
retval = PAM_SESSION_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
- /* Set permissions on the new file and dispose of the
|
||||
- * descriptor. */
|
||||
- if (fchown(fd, tpwd->pw_uid, tpwd->pw_gid) < 0)
|
||||
- pam_syslog (pamh, LOG_ERR, "fchown: %m");
|
||||
- close(fd);
|
||||
|
||||
/* Get a copy of the filename to save as a data item for
|
||||
* removal at session-close time. */
|
||||
@@ -669,7 +709,7 @@ pam_sm_open_session (pam_handle_t *pamh,
|
||||
(unsigned long) tpwd->pw_uid,
|
||||
(unsigned long) tpwd->pw_gid);
|
||||
}
|
||||
- run_coprocess(cookie, &tmp,
|
||||
+ run_coprocess(pamh, cookie, &tmp,
|
||||
tpwd->pw_uid, tpwd->pw_gid,
|
||||
xauth, "-f", cookiefile, "nmerge", "-", NULL);
|
||||
|
||||
@@ -691,11 +731,21 @@ int
|
||||
pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
- void *cookiefile;
|
||||
int i, debug = 0;
|
||||
+ const char *user;
|
||||
+ const void *data;
|
||||
+ const char *cookiefile;
|
||||
+ struct passwd *tpwd;
|
||||
+ PAM_MODUTIL_DEF_PRIVS(privs);
|
||||
+
|
||||
+ /* Try to retrieve the name of a file we created when
|
||||
+ * the session was opened. */
|
||||
+ if (pam_get_data(pamh, DATANAME, &data) != PAM_SUCCESS)
|
||||
+ return PAM_SUCCESS;
|
||||
+ cookiefile = data;
|
||||
|
||||
- /* Parse arguments. We don't understand many, so no sense in breaking
|
||||
- * this into a separate function. */
|
||||
+ /* Parse arguments. We don't understand many, so
|
||||
+ * no sense in breaking this into a separate function. */
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0) {
|
||||
debug = 1;
|
||||
@@ -714,19 +764,26 @@ pam_sm_close_session (pam_handle_t *pamh
|
||||
argv[i]);
|
||||
}
|
||||
|
||||
- /* Try to retrieve the name of a file we created when the session was
|
||||
- * opened. */
|
||||
- if (pam_get_data(pamh, DATANAME, (const void**) &cookiefile) == PAM_SUCCESS) {
|
||||
- /* We'll only try to remove the file once. */
|
||||
- if (strlen((char*)cookiefile) > 0) {
|
||||
- if (debug) {
|
||||
- pam_syslog(pamh, LOG_DEBUG, "removing `%s'",
|
||||
- (char*)cookiefile);
|
||||
- }
|
||||
- unlink((char*)cookiefile);
|
||||
- *((char*)cookiefile) = '\0';
|
||||
- }
|
||||
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "error determining target user's name");
|
||||
+ return PAM_SESSION_ERR;
|
||||
+ }
|
||||
+ if (!(tpwd = pam_modutil_getpwnam(pamh, user))) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "error determining target user's UID");
|
||||
+ return PAM_SESSION_ERR;
|
||||
}
|
||||
+
|
||||
+ if (debug)
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "removing `%s'", cookiefile);
|
||||
+ if (pam_modutil_drop_priv(pamh, &privs, tpwd))
|
||||
+ return PAM_SESSION_ERR;
|
||||
+ if (unlink(cookiefile) == -1 && errno != ENOENT)
|
||||
+ pam_syslog(pamh, LOG_WARNING, "Couldn't remove `%s': %m", cookiefile);
|
||||
+ if (pam_modutil_regain_priv(pamh, &privs))
|
||||
+ return PAM_SESSION_ERR;
|
||||
+
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
50
pam.spec
50
pam.spec
@ -2,8 +2,8 @@
|
||||
|
||||
Summary: An extensible library which provides authentication for applications
|
||||
Name: pam
|
||||
Version: 1.1.0
|
||||
Release: 7%{?dist}
|
||||
Version: 1.1.1
|
||||
Release: 6%{?dist}
|
||||
# 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+
|
||||
@ -23,11 +23,13 @@ Source13: config-util.5
|
||||
Source14: 90-nproc.conf
|
||||
Patch1: pam-1.0.90-redhat-modules.patch
|
||||
Patch2: pam-1.0.91-std-noclose.patch
|
||||
Patch3: pam-1.1.0-cracklib-authtok.patch
|
||||
Patch4: pam-1.1.0-console-nochmod.patch
|
||||
Patch5: pam-1.1.0-notally.patch
|
||||
Patch6: pam-1.1.0-xauth-context.patch
|
||||
Patch7: pam-1.1.0-console-fixes.patch
|
||||
Patch8: pam-1.1.1-authtok-prompt.patch
|
||||
# Fixes CVE-2010-3435 and CVE-2010-3316
|
||||
Patch9: pam-1.1.1-drop-privs.patch
|
||||
Patch10: pam-1.1.1-cve-2010-3853.patch
|
||||
|
||||
%define _sbindir /sbin
|
||||
%define _moduledir /%{_lib}/security
|
||||
@ -90,11 +92,12 @@ mv pam-redhat-%{pam_redhat_version}/* modules
|
||||
|
||||
%patch1 -p1 -b .redhat-modules
|
||||
%patch2 -p1 -b .std-noclose
|
||||
%patch3 -p1 -b .authtok
|
||||
%patch4 -p1 -b .nochmod
|
||||
%patch5 -p1 -b .notally
|
||||
%patch6 -p1 -b .xauth-context
|
||||
%patch7 -p1 -b .console-fixes
|
||||
%patch8 -p0 -b .prompt
|
||||
%patch9 -p1 -b .drop-privs
|
||||
%patch10 -p1 -b .execle
|
||||
|
||||
libtoolize -f
|
||||
autoreconf
|
||||
@ -180,7 +183,11 @@ install -m755 -d $RPM_BUILD_ROOT/lib/security
|
||||
for dir in modules/pam_* ; do
|
||||
if [ -d ${dir} ] ; then
|
||||
%if ! %{WITH_SELINUX}
|
||||
[ ${dir} = "modules/pam_selinux" ] && continue
|
||||
[ ${dir} = "modules/pam_selinux" ] && continue
|
||||
[ ${dir} = "modules/pam_sepermit" ] && continue
|
||||
%endif
|
||||
%if ! %{WITH_AUDIT}
|
||||
[ ${dir} = "modules/pam_tty_audit" ] && continue
|
||||
%endif
|
||||
[ ${dir} = "modules/pam_tally" ] && continue
|
||||
if ! ls -1 $RPM_BUILD_ROOT%{_moduledir}/`basename ${dir}`*.so ; then
|
||||
@ -206,7 +213,7 @@ rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
/sbin/ldconfig
|
||||
if [ ! -a /var/log/tallylog ] ; then
|
||||
if [ ! -e /var/log/tallylog ] ; then
|
||||
install -m 600 /dev/null /var/log/tallylog
|
||||
fi
|
||||
|
||||
@ -280,7 +287,9 @@ fi
|
||||
%{_moduledir}/pam_tally2.so
|
||||
%{_moduledir}/pam_time.so
|
||||
%{_moduledir}/pam_timestamp.so
|
||||
%if %{WITH_AUDIT}
|
||||
%{_moduledir}/pam_tty_audit.so
|
||||
%endif
|
||||
%{_moduledir}/pam_umask.so
|
||||
%{_moduledir}/pam_unix.so
|
||||
%{_moduledir}/pam_unix_acct.so
|
||||
@ -305,13 +314,15 @@ fi
|
||||
%dir %{_secconfdir}/namespace.d
|
||||
%attr(755,root,root) %config(noreplace) %{_secconfdir}/namespace.init
|
||||
%config(noreplace) %{_secconfdir}/pam_env.conf
|
||||
%config(noreplace) %{_secconfdir}/sepermit.conf
|
||||
%config(noreplace) %{_secconfdir}/time.conf
|
||||
%config(noreplace) %{_secconfdir}/opasswd
|
||||
%dir %{_secconfdir}/console.apps
|
||||
%dir %{_secconfdir}/console.perms.d
|
||||
%dir /var/run/console
|
||||
%if %{WITH_SELINUX}
|
||||
%config(noreplace) %{_secconfdir}/sepermit.conf
|
||||
%dir /var/run/sepermit
|
||||
%endif
|
||||
%ghost %verify(not md5 size mtime) /var/log/tallylog
|
||||
%{_mandir}/man5/*
|
||||
%{_mandir}/man8/*
|
||||
@ -327,6 +338,27 @@ fi
|
||||
%doc doc/adg/*.txt doc/adg/html
|
||||
|
||||
%changelog
|
||||
* Tue Nov 2 2010 Tomas Mraz <tmraz@redhat.com> 1.1.1-6
|
||||
- fix insecure dropping of priviledges in pam_xauth, pam_env,
|
||||
and pam_mail - CVE-2010-3316 (#637898), CVE-2010-3435 (#641335)
|
||||
- fix insecure executing of scripts with user supplied environment
|
||||
variables in pam_namespace - CVE-2010-3853 (#643043)
|
||||
|
||||
* Thu Jul 15 2010 Tomas Mraz <tmraz@redhat.com> 1.1.1-5
|
||||
- do not overwrite tallylog with empty file on upgrade
|
||||
|
||||
* Mon Feb 15 2010 Tomas Mraz <tmraz@redhat.com> 1.1.1-4
|
||||
- change the default password hash to sha512
|
||||
|
||||
* Fri Jan 22 2010 Tomas Mraz <tmraz@redhat.com> 1.1.1-3
|
||||
- fix wrong prompt when pam_get_authtok is used for new password
|
||||
|
||||
* Mon Jan 18 2010 Tomas Mraz <tmraz@redhat.com> 1.1.1-2
|
||||
- fix build with disabled audit and SELinux (#556211, #556212)
|
||||
|
||||
* Thu Dec 17 2009 Tomas Mraz <tmraz@redhat.com> 1.1.1-1
|
||||
- new upstream version with minor changes
|
||||
|
||||
* Mon Nov 2 2009 Tomas Mraz <tmraz@redhat.com> 1.1.0-7
|
||||
- pam_console: fix memory corruption when executing handlers (patch by
|
||||
Stas Sergeev) and a few more fixes in the handler execution code (#532302)
|
||||
|
@ -2,16 +2,13 @@
|
||||
# This file is auto-generated.
|
||||
# User changes will be destroyed the next time authconfig is run.
|
||||
auth required pam_env.so
|
||||
auth sufficient pam_unix.so nullok try_first_pass
|
||||
auth sufficient pam_unix.so try_first_pass nullok
|
||||
auth required pam_deny.so
|
||||
|
||||
account required pam_unix.so
|
||||
account sufficient pam_localuser.so
|
||||
account sufficient pam_succeed_if.so uid < 500 quiet
|
||||
account required pam_permit.so
|
||||
|
||||
password requisite pam_cracklib.so try_first_pass retry=3 type=
|
||||
password sufficient pam_unix.so nullok try_first_pass use_authtok
|
||||
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
|
||||
password required pam_deny.so
|
||||
|
||||
session optional pam_keyinit.so revoke
|
||||
|
2
sources
2
sources
@ -1,2 +1,2 @@
|
||||
c115640346a987356f6b76ec1d425185 pam-redhat-0.99.10-1.tar.bz2
|
||||
9cda791c827dfcd9f2888caf0a64cc4a Linux-PAM-1.1.0.tar.bz2
|
||||
9b3d952b173d5b9836cbc7e8de108bee Linux-PAM-1.1.1.tar.bz2
|
||||
|
@ -7,8 +7,8 @@ auth required pam_deny.so
|
||||
|
||||
account required pam_unix.so
|
||||
|
||||
password required pam_cracklib.so try_first_pass retry=3
|
||||
password sufficient pam_unix.so try_first_pass use_authtok nullok md5 shadow
|
||||
password requisite pam_cracklib.so try_first_pass retry=3 type=
|
||||
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
|
||||
password required pam_deny.so
|
||||
|
||||
session optional pam_keyinit.so revoke
|
||||
|
Loading…
Reference in New Issue
Block a user