aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvorlon <Unknown>2007-08-30 06:45:52 +0000
committervorlon <Unknown>2007-08-30 06:45:52 +0000
commit81295bb364b6c70467cae82c55e6cb20f718c9a4 (patch)
tree123a27702ab2c797e1b870ed213304fc6009cfa3
parent6666711f6248b9f7f0ea71392812e3d8bd007cc3 (diff)
downloadpam-81295bb364b6c70467cae82c55e6cb20f718c9a4.tar.gz
pam-81295bb364b6c70467cae82c55e6cb20f718c9a4.tar.bz2
pam-81295bb364b6c70467cae82c55e6cb20f718c9a4.zip
document status of upstream submission
-rw-r--r--patches-applied/setreuid_modutil.patch331
1 files changed, 331 insertions, 0 deletions
diff --git a/patches-applied/setreuid_modutil.patch b/patches-applied/setreuid_modutil.patch
new file mode 100644
index 00000000..7a259202
--- /dev/null
+++ b/patches-applied/setreuid_modutil.patch
@@ -0,0 +1,331 @@
+Refactor uid-handling code into pam_modutil so it can be shared between
+modules
+
+Authors: Steve Langasek <vorlon@debian.org>
+
+Upstream status: submitted in <20070825010039.GA13568@dario.dodds.net>
+
+Index: Linux-PAM/libpam/Makefile.am
+===================================================================
+--- Linux-PAM/libpam/Makefile.am.orig
++++ Linux-PAM/libpam/Makefile.am
+@@ -39,4 +39,5 @@
+ 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 \
++ pam_modutil_setreuid.c
+Index: Linux-PAM/libpam/include/security/pam_modutil.h
+===================================================================
+--- Linux-PAM/libpam/include/security/pam_modutil.h.orig
++++ Linux-PAM/libpam/include/security/pam_modutil.h
+@@ -97,6 +97,12 @@
+ extern int
+ pam_modutil_write(int fd, const char *buffer, int count);
+
++extern int PAM_NONNULL((1,2))
++pam_modutil_set_euid(uid_t *uid, uid_t *euid);
++
++extern int
++pam_modutil_restore_reuid(uid_t uid, uid_t euid);
++
+ #ifdef __cplusplus
+ }
+ #endif
+Index: Linux-PAM/modules/pam_unix/pam_unix_acct.c
+===================================================================
+--- Linux-PAM/modules/pam_unix/pam_unix_acct.c.orig
++++ Linux-PAM/modules/pam_unix/pam_unix_acct.c
+@@ -225,27 +225,12 @@
+ if (!strcmp( pwent->pw_passwd, "*NP*" )) { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+- save_euid = geteuid();
+- save_uid = getuid();
+- if (save_uid == pwent->pw_uid)
+- setreuid( save_euid, save_uid );
+- else {
+- setreuid( 0, -1 );
+- if (setreuid( -1, pwent->pw_uid ) == -1) {
+- setreuid( -1, 0 );
+- setreuid( 0, -1 );
+- if(setreuid( -1, pwent->pw_uid ) == -1)
+- return PAM_CRED_INSUFFICIENT;
+- }
+- }
++ save_euid = pwent->pw_uid;
++ retval = pam_modutil_set_euid(&save_uid,&save_euid);
++ if (retval != PAM_SUCCESS)
++ return retval;
+ spent = pam_modutil_getspnam (pamh, uname);
+- if (save_uid == pwent->pw_uid)
+- setreuid( save_uid, save_euid );
+- else {
+- if (setreuid( -1, 0 ) == -1)
+- setreuid( save_uid, -1 );
+- setreuid( -1, save_euid );
+- }
++ pam_modutil_restore_reuid(save_uid,save_euid);
+
+ } else if (_unix_shadowed (pwent))
+ spent = pam_modutil_getspnam (pamh, uname);
+Index: Linux-PAM/modules/pam_unix/support.c
+===================================================================
+--- Linux-PAM/modules/pam_unix/support.c.orig
++++ Linux-PAM/modules/pam_unix/support.c
+@@ -429,29 +429,12 @@
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+- save_euid = geteuid();
+- save_uid = getuid();
+- if (save_uid == pwd->pw_uid)
+- setreuid( save_euid, save_uid );
+- else {
+- setreuid( 0, -1 );
+- if (setreuid( -1, pwd->pw_uid ) == -1) {
+- setreuid( -1, 0 );
+- setreuid( 0, -1 );
+- if(setreuid( -1, pwd->pw_uid ) == -1)
++ save_euid = pwd->pw_uid;
++ if (pam_modutil_set_euid(&save_uid,&save_euid) != PAM_SUCCESS)
+ /* Will fail elsewhere. */
+ return 0;
+- }
+- }
+-
+ spwdent = pam_modutil_getspnam (pamh, name);
+- if (save_uid == pwd->pw_uid)
+- setreuid( save_uid, save_euid );
+- else {
+- if (setreuid( -1, 0 ) == -1)
+- setreuid( save_uid, -1 );
+- setreuid( -1, save_euid );
+- }
++ pam_modutil_restore_reuid(save_uid,save_euid);
+ } else if (_unix_shadowed(pwd)) {
+ /*
+ * ...and shadow password file entry for this user,
+@@ -633,28 +616,11 @@
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+- save_euid = geteuid();
+- save_uid = getuid();
+- if (save_uid == pwd->pw_uid)
+- setreuid( save_euid, save_uid );
+- else {
+- setreuid( 0, -1 );
+- if (setreuid( -1, pwd->pw_uid ) == -1) {
+- setreuid( -1, 0 );
+- setreuid( 0, -1 );
+- if(setreuid( -1, pwd->pw_uid ) == -1)
++ save_euid = pwd->pw_uid;
++ if (pam_modutil_set_euid(&save_uid,&save_euid) != PAM_SUCCESS)
+ return PAM_CRED_INSUFFICIENT;
+- }
+- }
+-
+ spwdent = pam_modutil_getspnam (pamh, name);
+- if (save_uid == pwd->pw_uid)
+- setreuid( save_uid, save_euid );
+- else {
+- if (setreuid( -1, 0 ) == -1)
+- setreuid( save_uid, -1 );
+- setreuid( -1, save_euid );
+- }
++ pam_modutil_restore_reuid(save_uid,save_euid);
+ } else if (_unix_shadowed(pwd)) {
+ /*
+ * ...and shadow password file entry for this user,
+Index: Linux-PAM/modules/pam_xauth/pam_xauth.c
+===================================================================
+--- Linux-PAM/modules/pam_xauth/pam_xauth.c.orig
++++ Linux-PAM/modules/pam_xauth/pam_xauth.c
+@@ -35,7 +35,9 @@
+
+ #include "config.h"
+ #include <sys/types.h>
++#ifdef HAVE_SYS_FSUID_H
+ #include <sys/fsuid.h>
++#endif /* HAVE_SYS_FSUID_H */
+ #include <sys/wait.h>
+ #include <errno.h>
+ #include <fnmatch.h>
+@@ -210,6 +212,9 @@
+ FILE *fp;
+ int i;
+ uid_t euid;
++#ifdef HAVE_SYS_FSUID_H
++ uid_t uid;
++#endif
+ /* Check this user's <sense> file. */
+ pwd = pam_modutil_getpwnam(pamh, this_user);
+ if (pwd == NULL) {
+@@ -225,10 +230,20 @@
+ "name of user's home directory is too long");
+ return PAM_SESSION_ERR;
+ }
++#ifdef HAVE_SYS_FSUID_H
+ euid = geteuid();
+ setfsuid(pwd->pw_uid);
++#else
++ euid = pwd->pw_uid;
++ if (pam_modutil_set_euid(&uid,&euid) != PAM_SUCCESS)
++ return PAM_SESSION_ERR;
++#endif
+ fp = fopen(path, "r");
++#ifdef HAVE_SYS_FSUID_H
+ setfsuid(euid);
++#else
++ pam_modutil_restore_reuid(uid,euid);
++#endif
+ if (fp != NULL) {
+ char buf[LINE_MAX], *tmp;
+ /* Scan the file for a list of specs of users to "trust". */
+@@ -297,6 +312,9 @@
+ int fd, i, debug = 0;
+ int retval = PAM_SUCCESS;
+ uid_t systemuser = 499, targetuser = 0, euid;
++#ifdef HAVE_SYS_FSUID_H
++ uid_t uid;
++#endif
+
+ /* Parse arguments. We don't understand many, so no sense in breaking
+ * this into a separate function. */
+@@ -540,10 +558,22 @@
+ }
+
+ /* Generate a new file to hold the data. */
++#ifdef HAVE_SYS_FSUID_H
+ euid = geteuid();
+ setfsuid(tpwd->pw_uid);
++#else
++ euid = tpwd->pw_uid;
++ if (pam_modutil_set_euid(&uid,&euid) != PAM_SUCCESS) {
++ retval = PAM_SESSION_ERR;
++ goto cleanup;
++ }
++#endif
+ fd = mkstemp(xauthority + strlen(XAUTHENV) + 1);
++#ifdef HAVE_SYS_FSUID_H
+ setfsuid(euid);
++#else
++ pam_modutil_restore_reuid(uid,euid);
++#endif
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR,
+ "error creating temporary file `%s': %m",
+Index: Linux-PAM/libpam/pam_modutil_setreuid.c
+===================================================================
+--- /dev/null
++++ Linux-PAM/libpam/pam_modutil_setreuid.c
+@@ -0,0 +1,96 @@
++/*
++ * $Id$
++ *
++ * These functions provide a wrapper for changing the effective uid of a
++ * process in a fashion that's reliably reversible, using only the POSIX
++ * setreuid() call.
++ *
++ * On Linux, this would be more reliable in certain corner cases if we
++ * used setresuid(); but setresuid isn't compatible with non-Linux
++ * systems or with the throbbing pain that surfaces behind my left eye
++ * when I think about this code, so leave these corner cases unhandled
++ * and require the calling application to not do outlandish things with
++ * the save set-user-id.
++ *
++ */
++
++#include "pam_modutil_private.h"
++
++#include <unistd.h>
++#include <sys/types.h>
++
++int
++pam_modutil_set_euid(uid_t *uid, uid_t *euid)
++{
++ uid_t save_uid, save_euid;
++
++ save_uid = getuid();
++ save_euid = geteuid();
++
++ if (*euid == save_euid) {
++ *uid = save_uid;
++ return PAM_SUCCESS;
++ }
++
++ if (*euid == save_uid)
++ /*
++ * simple swap; if saved set-user-id is 0 and both the
++ * uid and euid are !0, this will drop the root saved
++ * set-user-id, so don't invoke PAM that way!
++ */
++ setreuid(save_euid, save_uid);
++ else {
++ /*
++ * make sure we save root privs somewhere if we're
++ * suid
++ */
++ setreuid(0,-1);
++ /*
++ * If this fails, we're not running suid root and we don't
++ * have a saved set-user-id matching the target euid; but
++ * we could still have a saved set-user-id of 0 that will
++ * let us continue.
++ */
++ if (setreuid(-1, *euid) == -1) {
++ /* works IFF the saved set-user-id is 0 */
++ setreuid(-1, 0);
++ setreuid(0, -1);
++ /* also changes the saved set-user-id on success */
++ if (setreuid(-1, *euid))
++ /* so nothing worked, no rollback needed */
++ return PAM_CRED_INSUFFICIENT;
++ }
++ }
++ *uid = save_uid;
++ *euid = save_euid;
++ return PAM_SUCCESS;
++}
++
++int
++pam_modutil_restore_reuid(uid_t uid, uid_t euid)
++{
++ /* no-op */
++ if (uid == getuid() && euid == geteuid())
++ return PAM_SUCCESS;
++
++ /* only true if this was a swap in the first place */
++ if (uid == geteuid())
++ /*
++ * simple swap again; saved set-user-id now equals the euid,
++ * whether we wanted that or not
++ */
++ setreuid(uid, euid);
++ else {
++ /*
++ * succeeds if the real uid is 0; otherwise we can't
++ * reach this point unless the uid and euid are both
++ * non-zero and different, in which case the saved
++ * set-user-id will be equal to the euid and this will
++ * fail.
++ */
++ setreuid(-1,0);
++ setreuid(uid,-1);
++ setreuid(-1,euid);
++ }
++ return PAM_SUCCESS;
++}
+Index: Linux-PAM/libpam/libpam.map
+===================================================================
+--- Linux-PAM/libpam/libpam.map.orig
++++ Linux-PAM/libpam/libpam.map
+@@ -44,4 +44,6 @@
+ pam_modutil_getlogin;
+ pam_modutil_read;
+ pam_modutil_write;
++ pam_modutil_set_euid;
++ pam_modutil_restore_reuid;
+ };