rpms/pam/devel pam-0.99.7.1-namespace-temp-logon.patch, NONE, 1.1 pam-0.99.6.2-namespace-temp-logon.patch, 1.1, NONE

Tomas Mraz (tmraz) fedora-extras-commits at redhat.com
Mon Jun 4 14:24:30 UTC 2007


Author: tmraz

Update of /cvs/extras/rpms/pam/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv30501

Added Files:
	pam-0.99.7.1-namespace-temp-logon.patch 
Removed Files:
	pam-0.99.6.2-namespace-temp-logon.patch 
Log Message:
- oops wrong patch version


pam-0.99.7.1-namespace-temp-logon.patch:

--- NEW FILE pam-0.99.7.1-namespace-temp-logon.patch ---
--- Linux-PAM-0.99.7.1/modules/pam_namespace/pam_namespace.h.temp-logon	2007-06-01 15:29:11.000000000 +0200
+++ Linux-PAM-0.99.7.1/modules/pam_namespace/pam_namespace.h	2007-06-01 15:29:11.000000000 +0200
@@ -90,6 +90,7 @@
 #define PAMNS_NO_UNMOUNT_ON_CLOSE  0x00010000 /* no unmount at session close */
 
 #define NAMESPACE_MAX_DIR_LEN 80
+#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data"
 
 /*
  * Polyinstantiation method options, based on user, security context
@@ -100,6 +101,8 @@
     USER,
     CONTEXT,
     LEVEL,
+    TMPDIR,
+    TMPFS
 };
 
 /*
@@ -128,6 +131,7 @@
     enum polymethod method;		/* method used to polyinstantiate */
     unsigned int num_uids;		/* number of override uids */
     uid_t *uid;				/* list of override uids */
+    int exclusive;			/* polyinstatiate exclusively for override uids */
     struct polydir_s *next;		/* pointer to the next polydir entry */
 };
 
--- Linux-PAM-0.99.7.1/modules/pam_namespace/pam_namespace.c.temp-logon	2007-06-01 15:29:11.000000000 +0200
+++ Linux-PAM-0.99.7.1/modules/pam_namespace/pam_namespace.c	2007-06-01 15:33:30.000000000 +0200
@@ -43,6 +43,7 @@
 	strcpy(pent->instance_prefix, ent->instance_prefix);
 	pent->method = ent->method;
 	pent->num_uids = ent->num_uids;
+	pent->exclusive = ent->exclusive;
 	if (ent->num_uids) {
 		uid_t *pptr, *eptr;
 
@@ -120,6 +121,10 @@
 	}
 }
 
+static void cleanup_data(pam_handle_t *pamh, void *data, int err)
+{
+	del_polydir_list(data);
+}
 
 /*
  * Called from parse_config_file, this function processes a single line
@@ -140,6 +145,7 @@
 
     poly.uid = NULL;
     poly.num_uids = 0;
+    poly.exclusive = 0;
 
     /*
      * skip the leading white space
@@ -223,24 +229,13 @@
     }
 
     /*
-     * Ensure that all pathnames are absolute path names.
-     */
-    if ((dir[0] != '/') || (instance_prefix[0] != '/')) {
-        pam_syslog(idata->pamh, LOG_NOTICE,"Pathnames must start with '/'");
-        goto skipping;
-    }
-    if (strstr(dir, "..") || strstr(instance_prefix, "..")) {
-        pam_syslog(idata->pamh, LOG_NOTICE,"Pathnames must not contain '..'");
-        goto skipping;
-    }
-
-    /*
      * Populate polyinstantiated directory structure with appropriate
      * pathnames and the method with which to polyinstantiate.
      */
     if (strlen(dir) >= sizeof(poly.dir)
 	|| strlen(instance_prefix) >= sizeof(poly.instance_prefix)) {
 	pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long");
+	goto skipping;
     }
     strcpy(poly.dir, dir);
     strcpy(poly.instance_prefix, instance_prefix);
@@ -248,6 +243,18 @@
     poly.method = NONE;
     if (strcmp(method, "user") == 0) 
 	    poly.method = USER;
+    
+    if (strcmp(method, "tmpdir") == 0) {
+    	    poly.method = TMPDIR;
+    	    if (sizeof(poly.instance_prefix) - strlen(poly.instance_prefix) < 7) {
+    		pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long");
+    		goto skipping;
+    	    }
+    	    strcat(poly.instance_prefix, "XXXXXX");
+    }
+    
+    if (strcmp(method, "tmpfs") == 0)
+            poly.method = TMPFS;
 
 #ifdef WITH_SELINUX
     if (strcmp(method, "level") == 0) {
@@ -266,12 +273,24 @@
 
 #endif
 
-    if ( poly.method == NONE) {
+    if (poly.method == NONE) {
         pam_syslog(idata->pamh, LOG_NOTICE, "Illegal method");
         goto skipping;
     }
 
     /*
+     * Ensure that all pathnames are absolute path names.
+     */
+    if ((dir[0] != '/') || (poly.method != TMPFS && instance_prefix[0] != '/')) {
+        pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must start with '/'");
+        goto skipping;
+    }
+    if (strstr(dir, "..") || strstr(instance_prefix, "..")) {
+        pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must not contain '..'");
+        goto skipping;
+    }
+
+    /*
      * If the line in namespace.conf for a directory to polyinstantiate
      * contains a list of override users (users for whom polyinstantiation
      * is not performed), read the user ids, convert names into uids, and
@@ -281,7 +300,11 @@
         uid_t *uidptr;
         const char *ustr, *sstr;
         int count, i;
-
+	
+	if (*uids == '~') {
+		poly.exclusive = 1;
+		uids++;
+	}
         for (count = 0, ustr = sstr = uids; sstr; ustr = sstr + 1, count++)
            sstr = strchr(ustr, ',');
 
@@ -419,6 +442,7 @@
  * directory's list of override uids. If the uid is one of the override
  * uids for the polyinstantiated directory, polyinstantiation is not
  * performed for that user for that directory.
+ * If exclusive is set the returned values are opposite.
  */
 static int ns_override(struct polydir_s *polyptr, struct instance_data *idata,
 		uid_t uid)
@@ -432,11 +456,11 @@
 
     for (i = 0; i < polyptr->num_uids; i++) {
         if (uid == polyptr->uid[i]) {
-            return 1;
+            return !polyptr->exclusive;
         }
     }
 
-    return 0;
+    return polyptr->exclusive;
 }
 
 /*
@@ -622,6 +646,12 @@
 
 #endif /* WITH_SELINUX */
 
+	case TMPDIR:
+	case TMPFS:
+	    if ((*i_name=strdup("")) == NULL)
+	    	goto fail;
+	    return PAM_SUCCESS;
+
     	default:
     	    if (idata->flags & PAMNS_DEBUG)
     	        pam_syslog(idata->pamh, LOG_ERR, "Unknown method");
@@ -725,7 +755,7 @@
 * execute it and pass directory to polyinstantiate and instance
 * directory as arguments.
 */
-static int inst_init(const struct polydir_s *polyptr, char *ipath,
+static int inst_init(const struct polydir_s *polyptr, const char *ipath,
 	   struct instance_data *idata)
 {
 	pid_t rc, pid;
@@ -791,11 +821,11 @@
  * Create polyinstantiated instance directory (ipath).
  */
 #ifdef WITH_SELINUX
-static int create_dirs(const struct polydir_s *polyptr, char *ipath,
+static int create_dirs(struct polydir_s *polyptr, char *ipath,
         security_context_t icontext, security_context_t ocontext,
 	struct instance_data *idata)
 #else
-static int create_dirs(const struct polydir_s *polyptr, char *ipath,
+static int create_dirs(struct polydir_s *polyptr, char *ipath,
 	struct instance_data *idata)
 #endif
 {
@@ -834,7 +864,17 @@
      * attributes to match that of the original directory that is being
      * polyinstantiated.
      */
-    if (mkdir(ipath, S_IRUSR) < 0) {
+    
+    if (polyptr->method == TMPDIR) {
+    	if (mkdtemp(polyptr->instance_prefix) == NULL) {
+            pam_syslog(idata->pamh, LOG_ERR, "Error creating temporary instance %s, %m",
+			polyptr->instance_prefix);
+	    polyptr->method = NONE; /* do not clean up! */
+	    return PAM_SESSION_ERR;
+    	}
+	/* copy the actual directory name to ipath */
+	strcpy(ipath, polyptr->instance_prefix);
+    } else if (mkdir(ipath, S_IRUSR) < 0) {
         if (errno == EEXIST)
             goto inst_init;
         else {
@@ -920,13 +960,12 @@
  * security attributes, and performs bind mount to setup the process
  * namespace.
  */
-static int ns_setup(const struct polydir_s *polyptr,
+static int ns_setup(struct polydir_s *polyptr,
 	struct instance_data *idata)
 {
     int retval = 0;
     char *inst_dir = NULL;
     char *instname = NULL;
-    char *dir;
 #ifdef WITH_SELINUX
     security_context_t instcontext = NULL, origcontext = NULL;
 #endif
@@ -935,9 +974,15 @@
         pam_syslog(idata->pamh, LOG_DEBUG,
                "Set namespace for directory %s", polyptr->dir);
 
-    dir = strrchr(polyptr->dir, '/');
-    if (dir && strlen(dir) > 1)
-        dir++;
+    if (polyptr->method == TMPFS) {
+	if (mount("tmpfs", polyptr->dir, "tmpfs", 0, NULL) < 0) {
+	    pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
+        	polyptr->dir);
+            return PAM_SESSION_ERR;
+	}
+	/* we must call inst_init after the mount in this case */
+	return inst_init(polyptr, "tmpfs", idata);
+    }
 
     /*
      * Obtain the name of instance pathname based on the
@@ -1043,6 +1088,58 @@
     return retval;
 }
 
+static int cleanup_tmpdirs(struct instance_data *idata)
+{
+    struct polydir_s *pptr;
+    pid_t rc, pid;
+    sighandler_t osighand = NULL;
+    int status;
+
+    osighand = signal(SIGCHLD, SIG_DFL);
+    if (osighand == SIG_ERR) {
+	pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
+	rc = PAM_SESSION_ERR;
+	goto out;
+    }
+
+    for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+	if (pptr->method == TMPDIR && access(pptr->instance_prefix, F_OK) == 0) {
+	    pid = fork();
+	    if (pid == 0) {
+#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)
+			exit(1);
+	    } else if (pid > 0) {
+		while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
+		    (errno == EINTR));
+		if (rc == (pid_t)-1) {
+		    pam_syslog(idata->pamh, LOG_ERR, "waitpid failed- %m");
+		    rc = PAM_SESSION_ERR;
+		    goto out;
+		}
+		if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) {
+		    pam_syslog(idata->pamh, LOG_ERR,
+		    	"Error removing %s", pptr->instance_prefix);
+		}
+	    } else if (pid < 0) {
+		pam_syslog(idata->pamh, LOG_ERR,
+			"Cannot fork to run namespace init script, %m");
+		rc = PAM_SESSION_ERR;
+		goto out;
+	    }
+        }
+    }
+
+    rc = PAM_SUCCESS;
+out:
+    signal(SIGCHLD, osighand);
+    return rc;
+}
 
 /*
  * This function checks to see if polyinstantiation is needed for any
@@ -1111,13 +1208,22 @@
      * disassociate from the parent namespace.
      */
     if (need_poly) {
+	if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
+    		cleanup_data) != PAM_SUCCESS) {
+    	    pam_syslog(idata->pamh, LOG_ERR,
+    	    	"Unable to set namespace data");
+    	    return PAM_SYSTEM_ERR;
+    	}
         if (unshare(CLONE_NEWNS) < 0) {
-            pam_syslog(idata->pamh, LOG_ERR,
+		pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+		pam_syslog(idata->pamh, LOG_ERR,
 		"Unable to unshare from parent namespace, %m");
             return PAM_SESSION_ERR;
         }
-    } else
+    } else {
+    	del_polydir_list(idata->polydirs_ptr);
         return PAM_SUCCESS;
+    }
 
     /*
      * Again cycle through all polyinstantiated directories, this time,
@@ -1144,7 +1250,8 @@
                  * umount
                  */
                 if ((changing_dir = cwd_in(pptr->dir, idata)) < 0) {
-                    return PAM_SESSION_ERR;
+                    retval = PAM_SESSION_ERR;
+                    goto out;
                 } else if (changing_dir) {
                     if (idata->flags & PAMNS_DEBUG)
                         pam_syslog(idata->pamh, LOG_DEBUG, "changing cwd");
@@ -1172,8 +1279,10 @@
             	    int saved_errno = errno;
             	    pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
                     	pptr->dir);
-            	    if (saved_errno != EINVAL)
-                	return PAM_SESSION_ERR;
+            	    if (saved_errno != EINVAL) {
+                	retval = PAM_SESSION_ERR;
+                	goto out;
+                    }
                 } else if (idata->flags & PAMNS_DEBUG)
                     pam_syslog(idata->pamh, LOG_DEBUG, "Umount succeeded %s",
 				pptr->dir);
@@ -1185,7 +1294,9 @@
                      break;
         }
     }
-
+out:
+    if (retval != PAM_SUCCESS)
+    	cleanup_tmpdirs(idata);
     return retval;
 }
 
@@ -1224,8 +1335,10 @@
             } else if (idata->flags & PAMNS_DEBUG)
                 pam_syslog(idata->pamh, LOG_DEBUG, "Unmount of %s succeeded",
 			pptr->dir);
-        }
+	}
     }
+
+    cleanup_tmpdirs(idata);
     return 0;
 }
 
@@ -1350,7 +1463,8 @@
     } else if (idata.flags & PAMNS_DEBUG)
         pam_syslog(idata.pamh, LOG_DEBUG, "Nothing to polyinstantiate");
 
-    del_polydir_list(idata.polydirs_ptr);
+    if (retval != PAM_SUCCESS)
+	del_polydir_list(idata.polydirs_ptr);
     return retval;
 }
 
@@ -1365,6 +1479,7 @@
     struct instance_data idata;
     char *user_name;
     struct passwd *pwd;
+    const void *polyptr;
 
     /* init instance data */
     idata.flags = 0;
@@ -1428,16 +1543,12 @@
     strncat(idata.user, user_name, sizeof(idata.user) - 1);
     idata.uid = pwd->pw_uid;
 
-    /*
-     * Parse namespace configuration file which lists directories that
-     * are polyinstantiated, directories where instance directories are
-     * created and the method used for polyinstantiation.
-     */
-    retval = parse_config_file(&idata);
-    if ((retval != PAM_SUCCESS) || !idata.polydirs_ptr) {
-	del_polydir_list(idata.polydirs_ptr);
-        return PAM_SESSION_ERR;
-    }
+    retval = pam_get_data(idata.pamh, NAMESPACE_POLYDIR_DATA, &polyptr);
+    if (retval != PAM_SUCCESS || polyptr == NULL)
+    	/* nothing to reset */
+    	return PAM_SUCCESS;
+    	
+    idata.polydirs_ptr = polyptr;
 
     if (idata.flags & PAMNS_DEBUG)
         pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d",
@@ -1452,7 +1563,9 @@
             pam_syslog(idata.pamh, LOG_DEBUG,
 		"resetting namespace ok for pid %d", getpid());
     }
-    del_polydir_list(idata.polydirs_ptr);
+
+    pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+    
     return PAM_SUCCESS;
 }
 


--- pam-0.99.6.2-namespace-temp-logon.patch DELETED ---




More information about the fedora-extras-commits mailing list