diff --git a/Linux-PAM-1.0.90.tar.bz2.sign b/Linux-PAM-1.0.91.tar.bz2.sign similarity index 61% rename from Linux-PAM-1.0.90.tar.bz2.sign rename to Linux-PAM-1.0.91.tar.bz2.sign index a1547cc..4b52502 100644 --- a/Linux-PAM-1.0.90.tar.bz2.sign +++ b/Linux-PAM-1.0.91.tar.bz2.sign @@ -2,7 +2,7 @@ Version: GnuPG v1.4.9 (GNU/Linux) Comment: See http://www.kernel.org/signature.html for info -iD8DBQBJQnT1yGugalF9Dw4RAmSGAKCOEjM9X5nFa21Ang/N5B9LdQ7f7wCfRPbd -a5H9INJU6W0Ymb4pOq9OFBM= -=V27P +iD8DBQBJtReGyGugalF9Dw4RAoSBAJkB8GXcG7sriiwqGQZnnhXH0zDU4QCfZf54 +LvlqV/O0XyZBhBRfSl/QW/o= +=AocX -----END PGP SIGNATURE----- diff --git a/pam-1.0.90-access-no-resolve.patch b/pam-1.0.90-access-no-resolve.patch deleted file mode 100644 index c005795..0000000 --- a/pam-1.0.90-access-no-resolve.patch +++ /dev/null @@ -1,199 +0,0 @@ -Index: modules/pam_access/pam_access.c -=================================================================== -RCS file: /cvsroot/pam/Linux-PAM/modules/pam_access/pam_access.c,v -retrieving revision 1.31 -diff -u -p -r1.31 pam_access.c ---- modules/pam_access/pam_access.c 21 Apr 2008 11:21:12 -0000 1.31 -+++ modules/pam_access/pam_access.c 24 Feb 2009 16:27:58 -0000 -@@ -627,44 +627,10 @@ from_match (pam_handle_t *pamh UNUSED, c - } - freeaddrinfo (res); - } -- } else if (isipaddr(string, NULL, NULL) == YES) { -+ } else { - /* Assume network/netmask with a IP of a host. */ - if (network_netmask_match(pamh, tok, string, item->debug)) - return YES; -- } else { -- /* Assume network/netmask with a name of a host. */ -- struct addrinfo *res; -- struct addrinfo hint; -- -- memset (&hint, '\0', sizeof (hint)); -- hint.ai_flags = AI_CANONNAME; -- hint.ai_family = AF_UNSPEC; -- -- if (getaddrinfo (string, NULL, &hint, &res) != 0) -- return NO; -- else -- { -- struct addrinfo *runp = res; -- -- while (runp != NULL) -- { -- char buf[INET6_ADDRSTRLEN]; -- -- inet_ntop (runp->ai_family, -- runp->ai_family == AF_INET -- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr -- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, -- buf, sizeof (buf)); -- -- if (network_netmask_match(pamh, tok, buf, item->debug)) -- { -- freeaddrinfo (res); -- return YES; -- } -- runp = runp->ai_next; -- } -- freeaddrinfo (res); -- } - } - - return NO; -@@ -701,69 +667,99 @@ string_match (pam_handle_t *pamh, const - - - /* network_netmask_match - match a string against one token -- * where string is an ip (v4,v6) address and tok represents -- * whether a single ip (v4,v6) address or a network/netmask -+ * where string is a hostname or ip (v4,v6) address and tok -+ * represents either a single ip (v4,v6) address or a network/netmask - */ - static int - network_netmask_match (pam_handle_t *pamh, - const char *tok, const char *string, int debug) - { -- if (debug) -+ char *netmask_ptr; -+ char netmask_string[MAXHOSTNAMELEN + 1]; -+ int addr_type; -+ -+ if (debug) - pam_syslog (pamh, LOG_DEBUG, - "network_netmask_match: tok=%s, item=%s", tok, string); -+ /* OK, check if tok is of type addr/mask */ -+ if ((netmask_ptr = strchr(tok, '/')) != NULL) -+ { -+ long netmask = 0; -+ -+ /* YES */ -+ *netmask_ptr = 0; -+ netmask_ptr++; -+ -+ if (isipaddr(tok, &addr_type, NULL) == NO) -+ { /* no netaddr */ -+ return NO; -+ } - -- if (isipaddr(string, NULL, NULL) == YES) -- { -- char *netmask_ptr = NULL; -- static char netmask_string[MAXHOSTNAMELEN + 1] = ""; -- int addr_type; -- -- /* OK, check if tok is of type addr/mask */ -- if ((netmask_ptr = strchr(tok, '/')) != NULL) -- { -- long netmask = 0; -- -- /* YES */ -- *netmask_ptr = 0; -- netmask_ptr++; -- -- if (isipaddr(tok, &addr_type, NULL) == NO) -- { /* no netaddr */ -- return(NO); -- } -- -- /* check netmask */ -- if (isipaddr(netmask_ptr, NULL, NULL) == NO) -- { /* netmask as integre value */ -- char *endptr = NULL; -- netmask = strtol(netmask_ptr, &endptr, 0); -- if ((endptr == NULL) || (*endptr != '\0')) -+ /* check netmask */ -+ if (isipaddr(netmask_ptr, NULL, NULL) == NO) -+ { /* netmask as integre value */ -+ char *endptr = NULL; -+ netmask = strtol(netmask_ptr, &endptr, 0); -+ if ((endptr == NULL) || (*endptr != '\0')) - { /* invalid netmask value */ -- return(NO); -+ return NO; - } -- if ((netmask < 0) || (netmask >= 128)) -+ if ((netmask < 0) || (netmask >= 128)) - { /* netmask value out of range */ -- return(NO); -+ return NO; - } - -- netmask_ptr = number_to_netmask(netmask, addr_type, -- netmask_string, MAXHOSTNAMELEN); -- } -- -- /* Netmask is now an ipv4/ipv6 address. -- * This works also if netmask_ptr is NULL. -- */ -- return (are_addresses_equal(string, tok, netmask_ptr)); -+ netmask_ptr = number_to_netmask(netmask, addr_type, -+ netmask_string, MAXHOSTNAMELEN); -+ } - } -- else -+ else - /* NO, then check if it is only an addr */ -- if (isipaddr(tok, NULL, NULL) == YES) -- { /* check if they are the same, no netmask */ -- return(are_addresses_equal(string, tok, NULL)); -+ if (isipaddr(tok, NULL, NULL) != YES) -+ { -+ return NO; - } -- } - -- return (NO); -+ if (isipaddr(string, NULL, NULL) != YES) -+ { -+ /* Assume network/netmask with a name of a host. */ -+ struct addrinfo *res; -+ struct addrinfo hint; -+ -+ memset (&hint, '\0', sizeof (hint)); -+ hint.ai_flags = AI_CANONNAME; -+ hint.ai_family = AF_UNSPEC; -+ -+ if (getaddrinfo (string, NULL, &hint, &res) != 0) -+ return NO; -+ else -+ { -+ struct addrinfo *runp = res; -+ -+ while (runp != NULL) -+ { -+ char buf[INET6_ADDRSTRLEN]; -+ -+ inet_ntop (runp->ai_family, -+ runp->ai_family == AF_INET -+ ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr -+ : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, -+ buf, sizeof (buf)); -+ -+ if (are_addresses_equal(buf, tok, netmask_ptr)) -+ { -+ freeaddrinfo (res); -+ return YES; -+ } -+ runp = runp->ai_next; -+ } -+ freeaddrinfo (res); -+ } -+ } -+ else -+ return (are_addresses_equal(string, tok, netmask_ptr)); -+ -+ return NO; - } - - diff --git a/pam-1.0.90-mkhomedir-helper.patch b/pam-1.0.90-mkhomedir-helper.patch deleted file mode 100644 index 46b8534..0000000 --- a/pam-1.0.90-mkhomedir-helper.patch +++ /dev/null @@ -1,1065 +0,0 @@ -diff -up /dev/null Linux-PAM-1.0.90/modules/pam_mkhomedir/mkhomedir_helper.c ---- /dev/null 2009-01-09 08:55:49.164063715 +0100 -+++ Linux-PAM-1.0.90/modules/pam_mkhomedir/mkhomedir_helper.c 2009-01-19 10:15:39.000000000 +0100 -@@ -0,0 +1,422 @@ -+/* mkhomedir_helper - helper for pam_mkhomedir module -+ -+ Released under the GNU LGPL version 2 or later -+ -+ Copyright (c) Red Hat, Inc., 2009 -+ Originally written by Jason Gunthorpe Feb 1999 -+ Structure taken from pam_lastlogin by Andrew Morgan -+ 1996 -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+static unsigned long u_mask = 0022; -+static char skeldir[BUFSIZ] = "/etc/skel"; -+ -+static int -+rec_mkdir(const char *dir, mode_t mode) -+{ -+ char *cp; -+ char *parent = strdup(dir); -+ -+ if (parent == NULL) -+ return 1; -+ -+ cp = strrchr(parent, '/'); -+ -+ if (cp != NULL && cp != parent) -+ { -+ struct stat st; -+ -+ *cp++ = '\0'; -+ if (stat(parent, &st) == -1 && errno == ENOENT) -+ if (rec_mkdir(parent, mode) != 0) -+ { -+ free(parent); -+ return 1; -+ } -+ } -+ -+ free(parent); -+ -+ if (mkdir(dir, mode) != 0 && errno != EEXIST) -+ return 1; -+ -+ return 0; -+} -+ -+/* Do the actual work of creating a home dir */ -+static int -+create_homedir(const struct passwd *pwd, -+ const char *source, const char *dest) -+{ -+ char remark[BUFSIZ]; -+ DIR *d; -+ struct dirent *dent; -+ int retval = PAM_SESSION_ERR; -+ -+ /* Create the new directory */ -+ if (rec_mkdir(dest, 0755) != 0) -+ { -+ pam_syslog(NULL, LOG_ERR, "unable to create directory %s: %m", dest); -+ return PAM_PERM_DENIED; -+ } -+ -+ /* See if we need to copy the skel dir over. */ -+ if ((source == NULL) || (strlen(source) == 0)) -+ { -+ retval = PAM_SUCCESS; -+ goto go_out; -+ } -+ -+ /* Scan the directory */ -+ d = opendir(source); -+ if (d == NULL) -+ { -+ pam_syslog(NULL, LOG_DEBUG, "unable to read directory %s: %m", source); -+ retval = PAM_PERM_DENIED; -+ goto go_out; -+ } -+ -+ for (dent = readdir(d); dent != NULL; dent = readdir(d)) -+ { -+ int srcfd; -+ int destfd; -+ int res; -+ struct stat st; -+#ifndef PATH_MAX -+ char *newsource = NULL, *newdest = NULL; -+ /* track length of buffers */ -+ int nslen = 0, ndlen = 0; -+ int slen = strlen(source), dlen = strlen(dest); -+#else -+ char newsource[PATH_MAX], newdest[PATH_MAX]; -+#endif -+ -+ /* Skip some files.. */ -+ if (strcmp(dent->d_name,".") == 0 || -+ strcmp(dent->d_name,"..") == 0) -+ continue; -+ -+ /* Determine what kind of file it is. */ -+#ifndef PATH_MAX -+ nslen = slen + strlen(dent->d_name) + 2; -+ -+ if (nslen <= 0) -+ { -+ retval = PAM_BUF_ERR; -+ goto go_out; -+ } -+ -+ if ((newsource = malloc(nslen)) == NULL) -+ { -+ retval = PAM_BUF_ERR; -+ goto go_out; -+ } -+ -+ sprintf(newsource, "%s/%s", source, dent->d_name); -+#else -+ snprintf(newsource, sizeof(newsource), "%s/%s", source, dent->d_name); -+#endif -+ -+ if (lstat(newsource, &st) != 0) -+#ifndef PATH_MAX -+ { -+ free(newsource); -+ newsource = NULL; -+ continue; -+ } -+#else -+ continue; -+#endif -+ -+ -+ /* We'll need the new file's name. */ -+#ifndef PATH_MAX -+ ndlen = dlen + strlen(dent->d_name)+2; -+ -+ if (ndlen <= 0) -+ { -+ retval = PAM_BUF_ERR; -+ goto go_out; -+ } -+ -+ if ((newdest = malloc(ndlen)) == NULL) -+ { -+ free (newsource); -+ retval = PAM_BUF_ERR; -+ goto go_out; -+ } -+ -+ sprintf (newdest, "%s/%s", dest, dent->d_name); -+#else -+ snprintf (newdest, sizeof (newdest), "%s/%s", dest, dent->d_name); -+#endif -+ -+ /* If it's a directory, recurse. */ -+ if (S_ISDIR(st.st_mode)) -+ { -+ retval = create_homedir(pwd, newsource, newdest); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ if (retval != PAM_SUCCESS) -+ { -+ closedir(d); -+ goto go_out; -+ } -+ continue; -+ } -+ -+ /* If it's a symlink, create a new link. */ -+ if (S_ISLNK(st.st_mode)) -+ { -+ int pointedlen = 0; -+#ifndef PATH_MAX -+ char *pointed = NULL; -+ { -+ int size = 100; -+ -+ while (1) { -+ pointed = malloc(size); -+ if (pointed == NULL) { -+ free(newsource); -+ free(newdest); -+ return PAM_BUF_ERR; -+ } -+ pointedlen = readlink(newsource, pointed, size); -+ if (pointedlen < 0) break; -+ if (pointedlen < size) break; -+ free(pointed); -+ size *= 2; -+ } -+ } -+ if (pointedlen < 0) -+ free(pointed); -+ else -+ pointed[pointedlen] = 0; -+#else -+ char pointed[PATH_MAX]; -+ memset(pointed, 0, sizeof(pointed)); -+ -+ pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); -+#endif -+ -+ if (pointedlen >= 0) { -+ if(symlink(pointed, newdest) == 0) -+ { -+ if (lchown(newdest, pwd->pw_uid, pwd->pw_gid) != 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, -+ "unable to change perms on link %s: %m", newdest); -+ closedir(d); -+#ifndef PATH_MAX -+ free(pointed); -+ free(newsource); -+ free(newdest); -+#endif -+ return PAM_PERM_DENIED; -+ } -+ } -+#ifndef PATH_MAX -+ free(pointed); -+#endif -+ } -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ continue; -+ } -+ -+ /* If it's not a regular file, it's probably not a good idea to create -+ * the new device node, FIFO, or whatever it is. */ -+ if (!S_ISREG(st.st_mode)) -+ { -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ continue; -+ } -+ -+ /* Open the source file */ -+ if ((srcfd = open(newsource, O_RDONLY)) < 0 || fstat(srcfd, &st) != 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, -+ "unable to open src file %s: %m", newsource); -+ closedir(d); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ return PAM_PERM_DENIED; -+ } -+ if (stat(newsource, &st) != 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, "unable to stat src file %s: %m", -+ newsource); -+ close(srcfd); -+ closedir(d); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ return PAM_PERM_DENIED; -+ } -+ -+ /* Open the dest file */ -+ if ((destfd = open(newdest, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, -+ "unable to open dest file %s: %m", newdest); -+ close(srcfd); -+ closedir(d); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ return PAM_PERM_DENIED; -+ } -+ -+ /* Set the proper ownership and permissions for the module. We make -+ the file a+w and then mask it with the set mask. This preseves -+ execute bits */ -+ if (fchmod(destfd, (st.st_mode | 0222) & (~u_mask)) != 0 || -+ fchown(destfd, pwd->pw_uid, pwd->pw_gid) != 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, -+ "unable to change perms on copy %s: %m", newdest); -+ close(srcfd); -+ close(destfd); -+ closedir(d); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ return PAM_PERM_DENIED; -+ } -+ -+ /* Copy the file */ -+ do -+ { -+ res = pam_modutil_read(srcfd, remark, sizeof(remark)); -+ -+ if (res == 0) -+ continue; -+ -+ if (res > 0) { -+ if (pam_modutil_write(destfd, remark, res) == res) -+ continue; -+ } -+ -+ /* If we get here, pam_modutil_read returned a -1 or -+ pam_modutil_write returned something unexpected. */ -+ pam_syslog(NULL, LOG_DEBUG, "unable to perform IO: %m"); -+ close(srcfd); -+ close(destfd); -+ closedir(d); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ return PAM_PERM_DENIED; -+ } -+ while (res != 0); -+ close(srcfd); -+ close(destfd); -+ -+#ifndef PATH_MAX -+ free(newsource); newsource = NULL; -+ free(newdest); newdest = NULL; -+#endif -+ -+ } -+ closedir(d); -+ -+ retval = PAM_SUCCESS; -+ -+ go_out: -+ -+ if (chmod(dest, 0777 & (~u_mask)) != 0 || -+ chown(dest, pwd->pw_uid, pwd->pw_gid) != 0) -+ { -+ pam_syslog(NULL, LOG_DEBUG, -+ "unable to change perms on directory %s: %m", dest); -+ return PAM_PERM_DENIED; -+ } -+ -+ return retval; -+} -+ -+int -+main(int argc, char *argv[]) -+{ -+ const struct passwd *pwd; -+ struct stat st; -+ -+ if (argc < 2) { -+ fprintf(stderr, "Usage: %s [ []]\n", argv[0]); -+ return PAM_SESSION_ERR; -+ } -+ -+ pwd = getpwnam(argv[1]); -+ if (pwd == NULL) { -+ pam_syslog(NULL, LOG_ERR, "User unknown."); -+ return PAM_CRED_INSUFFICIENT; -+ } -+ -+ if (argc >= 3) { -+ char *eptr; -+ errno = 0; -+ u_mask = strtoul(argv[2], &eptr, 0); -+ if (errno != 0 || *eptr != '\0') { -+ pam_syslog(NULL, LOG_ERR, "Bogus umask value %s", argv[2]); -+ return PAM_SESSION_ERR; -+ } -+ } -+ -+ if (argc >= 4) { -+ if (strlen(argv[3]) >= sizeof(skeldir)) { -+ pam_syslog(NULL, LOG_ERR, "Too long skeldir path."); -+ return PAM_SESSION_ERR; -+ } -+ strcpy(skeldir, argv[3]); -+ } -+ -+ /* Stat the home directory, if something exists then we assume it is -+ correct and return a success */ -+ if (stat(pwd->pw_dir, &st) == 0) -+ return PAM_SUCCESS; -+ -+ return create_homedir(pwd, skeldir, pwd->pw_dir); -+} -+ -diff -up Linux-PAM-1.0.90/modules/pam_mkhomedir/Makefile.am.mkhomedir-helper Linux-PAM-1.0.90/modules/pam_mkhomedir/Makefile.am ---- Linux-PAM-1.0.90/modules/pam_mkhomedir/Makefile.am.mkhomedir-helper 2007-09-03 09:57:30.000000000 +0200 -+++ Linux-PAM-1.0.90/modules/pam_mkhomedir/Makefile.am 2009-01-19 10:15:39.000000000 +0100 -@@ -1,21 +1,23 @@ - # - # Copyright (c) 2005, 2006 Thorsten Kukuk -+# Copyright (c) 2008 Red Hat, Inc. - # - - CLEANFILES = *~ - - EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_mkhomedir - --man_MANS = pam_mkhomedir.8 -+man_MANS = pam_mkhomedir.8 mkhomedir_helper.8 - --XMLS = README.xml pam_mkhomedir.8.xml -+XMLS = README.xml pam_mkhomedir.8.xml mkhomedir_helper.8.xml - - TESTS = tst-pam_mkhomedir - - securelibdir = $(SECUREDIR) - secureconfdir = $(SCONFIGDIR) - --AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -+ -DMKHOMEDIR_HELPER=\"$(sbindir)/mkhomedir_helper\" - AM_LDFLAGS = -no-undefined -avoid-version -module - if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -@@ -25,6 +27,10 @@ securelib_LTLIBRARIES = pam_mkhomedir.la - pam_mkhomedir_la_SOURCES = pam_mkhomedir.c - pam_mkhomedir_la_LIBADD = -L$(top_builddir)/libpam -lpam - -+sbin_PROGRAMS = mkhomedir_helper -+mkhomedir_helper_SOURCES = mkhomedir_helper.c -+mkhomedir_helper_LDADD = -L$(top_builddir)/libpam -lpam -+ - if ENABLE_REGENERATE_MAN - noinst_DATA = README - README: pam_mkhomedir.8.xml -diff -up /dev/null Linux-PAM-1.0.90/modules/pam_mkhomedir/mkhomedir_helper.8.xml ---- /dev/null 2009-01-09 08:55:49.164063715 +0100 -+++ Linux-PAM-1.0.90/modules/pam_mkhomedir/mkhomedir_helper.8.xml 2009-01-19 10:15:39.000000000 +0100 -@@ -0,0 +1,78 @@ -+ -+ -+ -+ -+ -+ -+ mkhomedir_helper -+ 8 -+ Linux-PAM Manual -+ -+ -+ -+ mkhomedir_helper -+ Helper binary that creates home directories -+ -+ -+ -+ -+ mkhomedir_helper -+ -+ user -+ -+ -+ umask -+ -+ path-to-skel -+ -+ -+ -+ -+ -+ -+ -+ DESCRIPTION -+ -+ -+ mkhomedir_helper is a helper program for the -+ pam_mkhomedir module that creates home directories -+ and populates them with contents of the specified skel directory. -+ -+ -+ -+ The default value of umask is 0022 and the -+ default value of path-to-skel is -+ /etc/skel. -+ -+ -+ -+ The helper is separated from the module to not require direct access from -+ login SELinux domains to the contents of user home directories. The -+ SELinux domain transition happens when the module is executing the -+ mkhomedir_helper. -+ -+ -+ -+ The helper never touches home directories if they already exist. -+ -+ -+ -+ -+ SEE ALSO -+ -+ -+ pam_mkhomedir8 -+ -+ -+ -+ -+ -+ AUTHOR -+ -+ Written by Tomas Mraz based on the code originally in -+ pam_mkhomedir module. -+ -+ -+ -+ -diff -up Linux-PAM-1.0.90/modules/pam_mkhomedir/pam_mkhomedir.c.mkhomedir-helper Linux-PAM-1.0.90/modules/pam_mkhomedir/pam_mkhomedir.c ---- Linux-PAM-1.0.90/modules/pam_mkhomedir/pam_mkhomedir.c.mkhomedir-helper 2007-06-28 11:00:30.000000000 +0200 -+++ Linux-PAM-1.0.90/modules/pam_mkhomedir/pam_mkhomedir.c 2009-01-19 10:15:39.000000000 +0100 -@@ -22,6 +22,7 @@ - password required pam_unix.so - - Released under the GNU LGPL version 2 or later -+ Copyright (c) Red Hat, Inc. 2009 - Originally written by Jason Gunthorpe Feb 1999 - Structure taken from pam_lastlogin by Andrew Morgan - 1996 -@@ -29,18 +30,19 @@ - - #include "config.h" - --#include - #include - #include --#include -+#include -+#include -+#include - #include - #include - #include - #include - #include - #include --#include - #include -+#include - - /* - * here, we make a definition for the externally accessible function -@@ -56,12 +58,13 @@ - #include - #include - -+#define MAX_FD_NO 10000 - - /* argument parsing */ - #define MKHOMEDIR_DEBUG 020 /* be verbose about things */ - #define MKHOMEDIR_QUIET 040 /* keep quiet about things */ - --static unsigned int UMask = 0022; -+static char UMask[16] = "0022"; - static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */ - - static int -@@ -81,7 +84,8 @@ _pam_parse (const pam_handle_t *pamh, in - } else if (!strcmp(*argv, "debug")) { - ctrl |= MKHOMEDIR_DEBUG; - } else if (!strncmp(*argv,"umask=",6)) { -- UMask = strtol(*argv+6,0,0); -+ strncpy(SkelDir,*argv+6,sizeof(UMask)); -+ UMask[sizeof(UMask)-1] = '\0'; - } else if (!strncmp(*argv,"skel=",5)) { - strncpy(SkelDir,*argv+5,sizeof(SkelDir)); - SkelDir[sizeof(SkelDir)-1] = '\0'; -@@ -94,357 +98,88 @@ _pam_parse (const pam_handle_t *pamh, in - return ctrl; - } - --static int --rec_mkdir (const char *dir, mode_t mode) --{ -- char *cp; -- char *parent = strdup (dir); -- -- if (parent == NULL) -- return 1; -- -- cp = strrchr (parent, '/'); -- -- if (cp != NULL && cp != parent) -- { -- struct stat st; -- -- *cp++ = '\0'; -- if (stat (parent, &st) == -1 && errno == ENOENT) -- if (rec_mkdir (parent, mode) != 0) -- { -- free (parent); -- return 1; -- } -- } -- -- free (parent); -- -- if (mkdir (dir, mode) != 0 && errno != EEXIST) -- return 1; -- -- return 0; --} -- - /* Do the actual work of creating a home dir */ - static int --create_homedir (pam_handle_t * pamh, int ctrl, -- const struct passwd *pwd, -- const char *source, const char *dest) -+create_homedir (pam_handle_t *pamh, int ctrl, -+ const struct passwd *pwd) - { -- char remark[BUFSIZ]; -- DIR *D; -- struct dirent *Dir; -- int retval = PAM_AUTH_ERR; -+ int retval, child; -+ void (*sighandler)(int) = NULL; - - /* Mention what is happening, if the notification fails that is OK */ -- if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET) -- pam_info(pamh, _("Creating directory '%s'."), dest); -+ if (!(ctrl & MKHOMEDIR_QUIET)) -+ pam_info(pamh, _("Creating directory '%s'."), pwd->pw_dir); - -- /* Create the new directory */ -- if (rec_mkdir (dest,0755) != 0) -- { -- pam_error(pamh, _("Unable to create directory %s: %m"), dest); -- pam_syslog(pamh, LOG_ERR, "unable to create directory %s: %m", dest); -- return PAM_PERM_DENIED; -- } - -- /* See if we need to copy the skel dir over. */ -- if ((source == NULL) || (strlen(source) == 0)) -- { -- retval = PAM_SUCCESS; -- goto go_out; -- } -+ D(("called.")); - -- /* Scan the directory */ -- D = opendir (source); -- if (D == 0) -- { -- pam_syslog(pamh, LOG_DEBUG, "unable to read directory %s: %m", source); -- retval = PAM_PERM_DENIED; -- goto go_out; -- } -- -- for (Dir = readdir(D); Dir != 0; Dir = readdir(D)) -- { -- int SrcFd; -- int DestFd; -- int Res; -- struct stat St; --#ifndef PATH_MAX -- char *newsource = NULL, *newdest = NULL; -- /* track length of buffers */ -- int nslen = 0, ndlen = 0; -- int slen = strlen(source), dlen = strlen(dest); --#else -- char newsource[PATH_MAX], newdest[PATH_MAX]; --#endif -- -- /* Skip some files.. */ -- if (strcmp(Dir->d_name,".") == 0 || -- strcmp(Dir->d_name,"..") == 0) -- continue; -- -- /* Determine what kind of file it is. */ --#ifndef PATH_MAX -- nslen = slen + strlen(Dir->d_name) + 2; -- -- if (nslen <= 0) -- { -- retval = PAM_BUF_ERR; -- goto go_out; -- } -- -- if ((newsource = malloc (nslen)) == NULL) -- { -- retval = PAM_BUF_ERR; -- goto go_out; -- } -- -- sprintf(newsource, "%s/%s", source, Dir->d_name); --#else -- snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name); --#endif -- -- if (lstat(newsource,&St) != 0) --#ifndef PATH_MAX -- { -- free(newsource); -- newsource = NULL; -- continue; -- } --#else -- continue; --#endif -- -- -- /* We'll need the new file's name. */ --#ifndef PATH_MAX -- ndlen = dlen + strlen(Dir->d_name)+2; -- -- if (ndlen <= 0) -- { -- retval = PAM_BUF_ERR; -- goto go_out; -- } -- -- if ((newdest = malloc(ndlen)) == NULL) -- { -- free (newsource); -- retval = PAM_BUF_ERR; -- goto go_out; -+ /* -+ * This code arranges that the demise of the child does not cause -+ * the application to receive a signal it is not expecting - which -+ * may kill the application or worse. -+ */ -+ sighandler = signal(SIGCHLD, SIG_DFL); -+ -+ if (ctrl & MKHOMEDIR_DEBUG) { -+ pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); -+ } -+ -+ /* fork */ -+ child = fork(); -+ if (child == 0) { -+ int i; -+ struct rlimit rlim; -+ static char *envp[] = { NULL }; -+ char *args[] = { NULL, NULL, NULL, NULL, NULL }; -+ -+ if (getrlimit(RLIMIT_NOFILE, &rlim)==0) { -+ if (rlim.rlim_max >= MAX_FD_NO) -+ rlim.rlim_max = MAX_FD_NO; -+ for (i=0; i < (int)rlim.rlim_max; i++) { -+ close(i); -+ } - } - -- sprintf (newdest, "%s/%s", dest, Dir->d_name); --#else -- snprintf (newdest,sizeof (newdest),"%s/%s",dest,Dir->d_name); --#endif -- -- /* If it's a directory, recurse. */ -- if (S_ISDIR(St.st_mode)) -- { -- retval = create_homedir (pamh, ctrl, pwd, newsource, newdest); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -- if (retval != PAM_SUCCESS) -- { -- closedir(D); -- goto go_out; -- } -- continue; -- } -- -- /* If it's a symlink, create a new link. */ -- if (S_ISLNK(St.st_mode)) -- { -- int pointedlen = 0; --#ifndef PATH_MAX -- char *pointed = NULL; -- { -- int size = 100; -- -- while (1) { -- pointed = (char *) malloc(size); -- if ( ! pointed ) { -- free(newsource); -- free(newdest); -- return PAM_BUF_ERR; -- } -- pointedlen = readlink (newsource, pointed, size); -- if ( pointedlen < 0 ) break; -- if ( pointedlen < size ) break; -- free (pointed); -- size *= 2; -- } -- } -- if ( pointedlen < 0 ) -- free(pointed); -- else -- pointed[pointedlen] = 0; --#else -- char pointed[PATH_MAX]; -- memset(pointed, 0, sizeof(pointed)); -- -- pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); --#endif -- -- if ( pointedlen >= 0 ) { -- if(symlink(pointed, newdest) == 0) -- { -- if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0) -- { -- pam_syslog(pamh, LOG_DEBUG, -- "unable to change perms on link %s: %m", newdest); -- closedir(D); --#ifndef PATH_MAX -- free(pointed); -- free(newsource); -- free(newdest); --#endif -- return PAM_PERM_DENIED; -- } -- } --#ifndef PATH_MAX -- free(pointed); --#endif -- } --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- continue; -- } -- -- /* If it's not a regular file, it's probably not a good idea to create -- * the new device node, FIFO, or whatever it is. */ -- if (!S_ISREG(St.st_mode)) -- { --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- continue; -- } -- -- /* Open the source file */ -- if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0) -- { -- pam_syslog(pamh, LOG_DEBUG, -- "unable to open src file %s: %m", newsource); -- closedir(D); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -- return PAM_PERM_DENIED; -- } -- if (stat(newsource,&St) != 0) -- { -- pam_syslog(pamh, LOG_DEBUG, "unable to stat src file %s: %m", -- newsource); -- close(SrcFd); -- closedir(D); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -- return PAM_PERM_DENIED; -+ /* exec the mkhomedir helper */ -+ args[0] = x_strdup(MKHOMEDIR_HELPER); -+ args[1] = pwd->pw_name; -+ args[2] = UMask; -+ args[3] = SkelDir; -+ -+ execve(MKHOMEDIR_HELPER, args, envp); -+ -+ /* should not get here: exit with error */ -+ D(("helper binary is not available")); -+ exit(PAM_SYSTEM_ERR); -+ } else if (child > 0) { -+ int rc; -+ while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR); -+ if (rc < 0) { -+ pam_syslog(pamh, LOG_ERR, "waitpid failed: %m"); -+ retval = PAM_SYSTEM_ERR; -+ } else { -+ retval = WEXITSTATUS(retval); - } -- -- /* Open the dest file */ -- if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0) -- { -- pam_syslog(pamh, LOG_DEBUG, -- "unable to open dest file %s: %m", newdest); -- close(SrcFd); -- closedir(D); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- return PAM_PERM_DENIED; -- } -- -- /* Set the proper ownership and permissions for the module. We make -- the file a+w and then mask it with the set mask. This preseves -- execute bits */ -- if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 || -- fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0) -- { -- pam_syslog(pamh, LOG_DEBUG, -- "unable to change perms on copy %s: %m", newdest); -- close(SrcFd); -- close(DestFd); -- closedir(D); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -- return PAM_PERM_DENIED; -- } -- -- /* Copy the file */ -- do -- { -- Res = pam_modutil_read(SrcFd,remark,sizeof(remark)); -- -- if (Res == 0) -- continue; -- -- if (Res > 0) { -- if (pam_modutil_write(DestFd,remark,Res) == Res) -- continue; -- } -- -- /* If we get here, pam_modutil_read returned a -1 or -- pam_modutil_write returned something unexpected. */ -- pam_syslog(pamh, LOG_DEBUG, "unable to perform IO: %m"); -- close(SrcFd); -- close(DestFd); -- closedir(D); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -- return PAM_PERM_DENIED; -- } -- while (Res != 0); -- close(SrcFd); -- close(DestFd); -- --#ifndef PATH_MAX -- free(newsource); newsource = NULL; -- free(newdest); newdest = NULL; --#endif -- -+ } else { -+ D(("fork failed")); -+ pam_syslog(pamh, LOG_ERR, "fork failed: %m"); -+ retval = PAM_SYSTEM_ERR; - } -- closedir(D); - -- retval = PAM_SUCCESS; -+ if (sighandler != SIG_ERR) { -+ (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ -+ } - -- go_out: -+ if (ctrl & MKHOMEDIR_DEBUG) { -+ pam_syslog(pamh, LOG_DEBUG, "mkhomedir_helper returned %d", retval); -+ } - -- if (chmod(dest,0777 & (~UMask)) != 0 || -- chown(dest,pwd->pw_uid,pwd->pw_gid) != 0) -- { -- pam_syslog(pamh, LOG_DEBUG, -- "unable to change perms on directory %s: %m", dest); -- return PAM_PERM_DENIED; -+ if (retval != PAM_SUCCESS && !(ctrl & MKHOMEDIR_QUIET)) { -+ pam_error(pamh, _("Unable to create and initialize directory '%s'."), -+ pwd->pw_dir); - } - -+ D(("returning %d", retval)); - return retval; - } - -@@ -466,7 +201,7 @@ pam_sm_open_session (pam_handle_t *pamh, - retval = pam_get_item(pamh, PAM_USER, &user); - if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') - { -- pam_syslog(pamh, LOG_NOTICE, "user unknown"); -+ pam_syslog(pamh, LOG_NOTICE, "Cannot obtain the user name."); - return PAM_USER_UNKNOWN; - } - -@@ -474,16 +209,22 @@ pam_sm_open_session (pam_handle_t *pamh, - pwd = pam_modutil_getpwnam (pamh, user); - if (pwd == NULL) - { -+ pam_syslog(pamh, LOG_NOTICE, "User unknown."); - D(("couldn't identify user %s", user)); - return PAM_CRED_INSUFFICIENT; - } - - /* Stat the home directory, if something exists then we assume it is - correct and return a success*/ -- if (stat(pwd->pw_dir,&St) == 0) -+ if (stat(pwd->pw_dir, &St) == 0) { -+ if (ctrl & MKHOMEDIR_DEBUG) { -+ pam_syslog(pamh, LOG_DEBUG, "Home directory %s already exists.", -+ pwd->pw_dir); -+ } - return PAM_SUCCESS; -+ } - -- return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); -+ return create_homedir(pamh, ctrl, pwd); - } - - /* Ignore */ diff --git a/pam-1.0.90-strtok-unsigned.patch b/pam-1.0.90-strtok-unsigned.patch deleted file mode 100644 index 077dbf3..0000000 --- a/pam-1.0.90-strtok-unsigned.patch +++ /dev/null @@ -1,102 +0,0 @@ ---- libpam/pam_misc.c 6 Dec 2007 20:20:07 -0000 1.9 -+++ libpam/pam_misc.c 25 Feb 2009 13:48:23 -0000 -@@ -59,10 +59,11 @@ - - /* initialize table */ - for (i=1; i<256; table[i++] = '\0'); -- for (i=0; format[i] ; table[(int)format[i++]] = 'y'); -+ for (i=0; format[i] ; -+ table[(unsigned char)format[i++]] = 'y'); - - /* look for first non-format char */ -- while (*from && table[(int)*from]) { -+ while (*from && table[(unsigned char)*from]) { - ++from; - } - -@@ -92,7 +93,7 @@ - remains */ - } else if (*from) { - /* simply look for next blank char */ -- for (end=from; *end && !table[(int)*end]; ++end); -+ for (end=from; *end && !table[(unsigned char)*end]; ++end); - } else { - return (*next = NULL); /* no tokens left */ - } ---- tests/Makefile.am 2 Sep 2007 17:02:53 -0000 1.5 -+++ tests/Makefile.am 25 Feb 2009 13:48:24 -0000 -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2006 Thorsten Kukuk -+# Copyright (c) 2006, 2009 Thorsten Kukuk - # - - AM_CFLAGS = -DLIBPAM_COMPILE -I$(top_srcdir)/libpam/include \ -@@ -11,9 +11,9 @@ - TESTS = tst-pam_start tst-pam_end tst-pam_fail_delay tst-pam_open_session \ - tst-pam_close_session tst-pam_acct_mgmt tst-pam_authenticate \ - tst-pam_chauthtok tst-pam_setcred tst-pam_get_item tst-pam_set_item \ -- tst-pam_getenvlist tst-pam_get_user tst-pam_set_data -+ tst-pam_getenvlist tst-pam_get_user tst-pam_set_data \ -+ tst-pam_mkargv - - check_PROGRAMS = ${TESTS} tst-dlopen - - tst_dlopen_LDADD = -ldl -- ---- /dev/null 1 Jan 1970 00:00:00 -0000 -+++ tests/tst-pam_mkargv.c 25 Feb 2009 13:48:24 -0000 -@@ -0,0 +1,52 @@ -+/* -+ Copyright (C) Thorsten Kukuk 2009 -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation in version 2 of the License -+ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include -+ -+#include "libpam/pam_misc.c" -+ -+/* Simple program to see if _pam_mkargv() would succeed. */ -+int main(void) -+{ -+ char *argvstring = "user = XENDT\\userĪ± user=XENDT\\user1"; -+ const char *argvresult[] = {"user", "=", "XENDT\\userĪ±", -+ "user=XENDT\\user1"}; -+ int myargc; -+ char **myargv; -+ int argvlen; -+ int i; -+ -+ argvlen = _pam_mkargv(argvstring, &myargv, &myargc); -+ -+#if 0 -+ printf ("argvlen=%i, argc=%i", argvlen, myargc); -+ for (i = 0; i < myargc; i++) { -+ printf(", argv[%d]=%s", i, myargv[i]); -+ } -+ printf ("\n"); -+#endif -+ -+ if (argvlen != 333) -+ return 1; -+ -+ if (myargc != 4) -+ return 1; -+ -+ for (i = 0; i < 4; i++) -+ { -+ if (strcmp (myargv[i], argvresult[i]) != 0) -+ return 1; -+ } -+ -+ return 0; -+} - diff --git a/pam-1.0.90-unix-mindays.patch b/pam-1.0.90-unix-mindays.patch deleted file mode 100644 index 2bdbf6e..0000000 --- a/pam-1.0.90-unix-mindays.patch +++ /dev/null @@ -1,42 +0,0 @@ -Index: modules/pam_unix/pam_unix_acct.c -=================================================================== -RCS file: /cvsroot/pam/Linux-PAM/modules/pam_unix/pam_unix_acct.c,v -retrieving revision 1.24 -diff -u -r1.24 pam_unix_acct.c ---- modules/pam_unix/pam_unix_acct.c 11 Jul 2008 15:29:00 -0000 1.24 -+++ modules/pam_unix/pam_unix_acct.c 24 Feb 2009 09:57:31 -0000 -@@ -249,6 +249,9 @@ - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); - break; -+ case PAM_AUTHTOK_ERR: -+ retval = PAM_SUCCESS; -+ /* fallthrough */ - case PAM_SUCCESS: - if (daysleft >= 0) { - pam_syslog(pamh, LOG_DEBUG, -Index: modules/pam_unix/passverify.c -=================================================================== -RCS file: /cvsroot/pam/Linux-PAM/modules/pam_unix/passverify.c,v -retrieving revision 1.8 -diff -u -r1.8 passverify.c ---- modules/pam_unix/passverify.c 1 Dec 2008 12:40:41 -0000 1.8 -+++ modules/pam_unix/passverify.c 24 Feb 2009 09:57:32 -0000 -@@ -272,8 +272,16 @@ - *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays); - D(("warn before expiry")); - } -+ if ((curdays - spent->sp_lstchg < spent->sp_min) -+ && (spent->sp_min != -1)) { -+ /* -+ * The last password change was too recent. This error will be ignored -+ * if no password change is attempted. -+ */ -+ D(("password change too recent")); -+ return PAM_AUTHTOK_ERR; -+ } - return PAM_SUCCESS; -- - } - - /* passwd/salt conversion macros */ diff --git a/pam.spec b/pam.spec index dc40404..5e3cffb 100644 --- a/pam.spec +++ b/pam.spec @@ -2,8 +2,8 @@ Summary: An extensible library which provides authentication for applications Name: pam -Version: 1.0.90 -Release: 4%{?dist} +Version: 1.0.91 +Release: 1%{?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+, # pam_rhosts_auth module is BSD with advertising @@ -20,10 +20,6 @@ Source9: system-auth.5 Source10: config-util.5 Source11: 90-nproc.conf Patch1: pam-1.0.90-redhat-modules.patch -Patch2: pam-1.0.90-mkhomedir-helper.patch -Patch3: pam-1.0.90-unix-mindays.patch -Patch4: pam-1.0.90-access-no-resolve.patch -Patch5: pam-1.0.90-strtok-unsigned.patch %define _sbindir /sbin %define _moduledir /%{_lib}/security @@ -86,10 +82,6 @@ PAM-aware applications and modules for use with PAM. mv pam-redhat-%{pam_redhat_version}/* modules %patch1 -p1 -b .redhat-modules -%patch2 -p1 -b .mkhomedir-helper -%patch3 -p0 -b .mindays -%patch4 -p0 -b .no-resolve -%patch5 -p0 -b .strtok-unsigned autoreconf @@ -322,6 +314,9 @@ fi %doc doc/adg/*.txt doc/adg/html %changelog +* Mon Mar 9 2009 Tomas Mraz 1.0.91-1 +- upgrade to new upstream release + * Fri Feb 27 2009 Tomas Mraz 1.0.90-4 - fix parsing of config files containing non-ASCII characters - fix CVE-2009-0579 (mininimum days for password change ignored) (#487216)