rpms/pam/devel pam_namespace-7.patch, NONE, 1.1 pam_namespace-have-unshare.patch, NONE, 1.1 pam_namespace-no-mans.patch, NONE, 1.1 .cvsignore, 1.33, 1.34 pam.spec, 1.105, 1.106 sources, 1.35, 1.36 pam-0.99.3.0-pie.patch, 1.1, NONE
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Tue Apr 25 14:53:42 UTC 2006
- Previous message (by thread): rpms/selinux-policy/devel policygentool,1.5,1.6
- Next message (by thread): rpms/ethereal/FC-4 ethereal-column.patch, NONE, 1.1 .cvsignore, 1.25, 1.26 ethereal.spec, 1.41, 1.42 sources, 1.28, 1.29
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: tmraz
Update of /cvs/dist/rpms/pam/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv11669
Modified Files:
.cvsignore pam.spec sources
Added Files:
pam_namespace-7.patch pam_namespace-have-unshare.patch
pam_namespace-no-mans.patch
Removed Files:
pam-0.99.3.0-pie.patch
Log Message:
* Tue Apr 25 2006 Tomas Mraz <tmraz at redhat.com> 0.99.3.0-3
- added pam_namespace module written by Janak Desai (per-user /tmp
support)
- new pam-redhat modules version
pam_namespace-7.patch:
config.h.in | 3
configure.in | 4
modules/Makefile.am | 3
modules/pam_namespace/Makefile.am | 27
modules/pam_namespace/README | 100 ++
modules/pam_namespace/namespace.conf | 15
modules/pam_namespace/namespace.conf.5.xml | 137 ++
modules/pam_namespace/pam_namespace.8.xml | 221 ++++
modules/pam_namespace/pam_namespace.c | 1326 +++++++++++++++++++++++++++++
9 files changed, 1835 insertions(+), 1 deletion(-)
--- NEW FILE pam_namespace-7.patch ---
--- Linux-PAM-0.99.3.0/config.h.in.namespace 2006-01-13 22:04:47.000000000 +0100
+++ Linux-PAM-0.99.3.0/config.h.in 2006-04-25 16:41:28.000000000 +0200
@@ -248,6 +248,9 @@
/* Version number of package */
#undef VERSION
+/* Defined if SE Linux support is compiled in */
+#undef WITH_SELINUX
+
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/README 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,100 @@
+
+pam_namespace module:
+Setup a private namespace with polyinstantiated directories.
+
+THEORY OF OPERATION:
+The pam namespace module consults /etc/security/namespace.conf
+configuration file and sets up a private namespace with polyinstantiated
+directories for a session managed by PAM. A skeleton namespace.conf
+installed by default provides example for polyinstantiating /tmp
+and users' home directory.
+
+Each line in namespace.conf describes a limit for a user in the form:
+
+<polydir> <instance_prefix> <method> <list_of_uids>
+
+Where:
+<polydir> - is the absolute pathname of the directory to polyinstantiate
+ Special entry $HOME is supported to designate user's home directory.
+ This field cannot be blank.
+
+<instance_prefix> - is the string prefix used to build the pathname for the
+ instantiation of <polydir>. The directory security context, or
+ optionally its md5sum string (32 hex characters), is appended to
+ the prefix to generate the final instance directory path.
+ This directory is created if it did not exist already, and is then
+ bind mounted on the <polydir> to provide an instance of <polydir>
+ based on the <method> column. The special string $HOME is replaced with
+ the user's home directory, and $USER with the username.
+ This field cannot be blank.
+
+<method> - is the method used for polyinstantiation. It can take 3 different
+ values; "user" for polyinstantiation based on user name, "context"
+ for polyinstantiation based on process security context, and "both"
+ for polyinstantiation based on both user name and security context.
+ Methods "context" and "both" are only available with SELinux. This
+ field cannot be blank.
+
+<list_of_uids> - is a comma separated list of user names for whom the
+ polyinstantiation is not performed. If left blank, polyinstantiation
+ will be performed for all users.
+
+EXAMPLE /etc/security/namespace.conf configuration file:
+=======================================================
+# Following three lines will polyinstantiate /tmp, /var/tmp and user's home
+# directories. /tmp and /var/tmp will be polyinstantiated based on both
+# security context as well as user name, whereas home directory will
+# be polyinstantiated based on security context only. Polyinstantiation
+# will not be performed for user root and adm for directories /tmp and
+# /var/tmp, whereas home directories will be polyinstantiated for all
+# users.
+#
+/tmp /tmp/tmp.inst-$USER- both root,adm
+/var/tmp /var/tmp/tmp.inst-$USER- both root,adm
+$HOME $HOME.inst- context
+
+ARGUMENTS RECOGNIZED:
+ debug Verbose logging by syslog
+
+ unmnt_remnt For programs such as su and newrole, the login
+ session has already setup a polyinstantiated
+ namespace. For these programs, polyinstantiation
+ is performed based on new user id or security
+ context, however the command first needs to
+ undo the polyinstantiation performed by login.
+ This argument instructs the command to
+ first undo previous polyinstantiation before
+ proceeding with new polyinstantiation based on
+ new id/context.
+
+ unmnt_only For trusted programs that want to undo any
+ existing bind mounts and process instance
+ directories on their own, this argument allows
+ them to unmount currently mounted instance
+ directories.
+
+ require_selinux If selinux is not enabled, return failure.
+
+ gen_hash Instead of using the security context string
+ for the instance name, generate and use its
+ md5 hash.
+
+ ignore_config_error If a line in the configuration file corresponding
+ to a polyinstantiated directory contains format
+ error, skip that line process the next line.
+ Without this option, pam will return an error
+ to the calling program resulting in termination
+ of the session.
+
+
+MODULE SERVICES PROVIDED:
+ session _open_session and _close_session (blank)
+
+USAGE:
+ For the <service>s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/<service> as the last line for
+ session group:
+
+ session required pam_namespace.so [arguments]
+
+ This module also depends on pam_selinux.so setting the context.
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/pam_namespace.c 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,1326 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default namespace after
+ * establishing a session via PAM.
+ *
+ * (C) Copyright IBM Corporation 2005
+ * (C) Copyright Red Hat 2006
+ * All Rights Reserved.
+ *
+ * Written by: Janak Desai <janak at us.ibm.com>
+ * With Revisions by: Steve Grubb <sgrubb at redhat.com>
+ * Derived from a namespace setup patch by Chad Sellers <cdselle at tycho.nsa.gov>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#if !(defined(linux))
+#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <openssl/md5.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <sched.h>
+#include "security/pam_modules.h"
+#include "security/pam_modutil.h"
+#include "security/pam_ext.h"
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#ifndef CLONE_NEWNS
+#define CLONE_NEWNS 0x00020000 /* Flag to create new namespace */
+#endif
+
+/*
+ * Module defines
+ */
+#define MD5_DIGEST_LENGTH 16
+#ifndef PAM_NAMESPACE_CONFIG
+#define PAM_NAMESPACE_CONFIG "/etc/security/namespace.conf"
+#endif
+
+#ifndef INST_INIT_SCRIPT
+#define INST_INIT_SCRIPT "inst_init_script.sh"
+#endif
+
+#define PAMNS_DEBUG 0x00000100 /* Running in debug mode */
+#define PAMNS_SELINUX_ENABLED 0x00000400 /* SELinux is enabled */
+#define PAMNS_CTXT_BASED_INST 0x00000800 /* Context based instance needed */
+#define PAMNS_GEN_HASH 0x00002000 /* Generate md5 hash for inst names */
+#define PAMNS_IGN_CONFIG_ERR 0x00004000 /* Ignore format error in conf file */
+
+/*
+ * Polyinstantiation method options, based on user, security context
+ * or both
+ */
+enum polymethod {
+ USER,
+ CONTEXT,
+ BOTH,
+};
+
+/*
+ * Depending on the application using this namespace module, we
+ * may need to unmount priviously bind mounted instance directory.
+ * Applications such as login and sshd, that establish a new
+ * session unmount of instance directory is not needed. For applications
+ * such as su and newrole, that switch the identity, this module
+ * has to unmount previous instance directory first and re-mount
+ * based on the new indentity. For other trusted applications that
+ * just want to undo polyinstantiation, only unmount of previous
+ * instance directory is needed.
+ */
+enum unmnt_op {
+ NO_UNMNT,
+ UNMNT_REMNT,
+ UNMNT_ONLY,
+};
+
+/*
+ * Structure that holds information about a directory to polyinstantiate
+ */
+struct polydir_s {
+ char dir[PATH_MAX]; /* directory to polyinstantiate */
+ char instance_prefix[PATH_MAX]; /* prefix for instance dir path name */
+ enum polymethod method; /* method used to polyinstantiate */
+ unsigned int num_uids; /* number of override uids */
+ uid_t *uid; /* list of override uids */
+ struct polydir_s *next; /* pointer to the next polydir entry */
+};
+
+struct instance_data {
+ pam_handle_t *pamh; /* The pam handle for this instance */
+ struct polydir_s *polydirs_ptr; /* The linked list pointer */
+ char user[LOGIN_NAME_MAX]; /* User name */
+ uid_t uid; /* The uid of the user */
+ unsigned long flags; /* Flags for debug, selinux etc */
+};
+
+/*
+ * Adds an entry for a polyinstantiated directory to the linked list of
+ * polyinstantiated directories. It is called from process_line() while
+ * parsing the namespace configuration file.
+ */
+static int add_polydir_entry(struct instance_data *idata,
+ const struct polydir_s *ent)
+{
+ struct polydir_s *pent;
+ unsigned int i;
+
+ /*
+ * Allocate an entry to hold information about a directory to
+ * polyinstantiate, populate it with information from 2nd argument
+ * and add the entry to the linked list of polyinstantiated
+ * directories.
+ */
+ pent = (struct polydir_s *) malloc(sizeof(struct polydir_s));
+ if (!pent)
+ return -1;
+
+ /* Make copy */
+ strcpy(pent->dir, ent->dir);
+ strcpy(pent->instance_prefix, ent->instance_prefix);
+ pent->method = ent->method;
+ pent->num_uids = ent->num_uids;
+ if (ent->num_uids) {
+ uid_t *pptr, *eptr;
+
+ pent->uid = (uid_t *) malloc(ent->num_uids * sizeof(uid_t));
+ if (!(pent->uid)) {
+ free(pent);
+ return -1;
+ }
+ for (i = 0, pptr = pent->uid, eptr = ent->uid; i < ent->num_uids;
+ i++, eptr++, pptr++)
+ *pptr = *eptr;
+ } else
+ pent->uid = NULL;
+
+ /* Now attach to linked list */
+ pent->next = NULL;
+ if (idata->polydirs_ptr == NULL)
+ idata->polydirs_ptr = pent;
+ else {
+ struct polydir_s *tail;
+
+ tail = idata->polydirs_ptr;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = pent;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Deletes all the entries in the linked list.
+ */
+static void del_polydir_list(struct polydir_s *polydirs_ptr)
+{
+ struct polydir_s *dptr = polydirs_ptr;
+
+ while (dptr) {
+ struct polydir_s *tptr = dptr;
+ dptr = dptr->next;
+ free(tptr->uid);
+ free(tptr);
+ }
+}
+
+
+/*
+ * Called from parse_config_file, this function processes a single line
+ * of the namespace configuration file. It skips over comments and incomplete
+ * or malformed lines. It processes a valid line with information on
+ * polyinstantiating a directory by populating appropriate fields of a
+ * polyinstatiated directory structure and then calling add_polydir_entry to
+ * add that entry to the linked list of polyinstantiated directories.
+ */
+static int process_line(char *line, const char *home,
+ struct instance_data *idata)
+{
+ const char *dir, *instance_prefix;
+ const char *method, *uids;
+ char *tptr;
+ struct polydir_s poly;
+ int retval = 0;
+
+ poly.uid = NULL;
+ poly.num_uids = 0;
+
+ /*
+ * skip the leading white space
+ */
+ while (*line && isspace(*line))
+ line++;
+
+ /*
+ * Rip off the comments
+ */
+ tptr = strchr(line,'#');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Rip off the newline char
+ */
+ tptr = strchr(line,'\n');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Anything left ?
+ */
+ if (line[0] == 0)
+ return 0;
+
+ /*
+ * Initialize and scan the five strings from the line from the
+ * namespace configuration file.
+ */
+ dir = strtok_r(line, " \t", &tptr);
+ if (dir == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing polydir");
+ goto skipping;
+ }
+ instance_prefix = strtok_r(NULL, " \t", &tptr);
+ if (instance_prefix == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing instance_prefix");
+ goto skipping;
+ }
+ method = strtok_r(NULL, " \t", &tptr);
+ if (method == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing method");
+ goto skipping;
+ }
+
+ /*
+ * Only the uids field is allowed to be blank, to indicate no
+ * override users for polyinstantiation of that directory. If
+ * any of the other fields are blank, the line is incomplete so
+ * skip it.
+ */
+ uids = strtok_r(NULL, " \t", &tptr);
+
+ /*
+ * If the directory being polyinstantiated is the home directory
+ * of the user who is establishing a session, we have to swap
+ * the "$HOME" string with the user's home directory that is
+ * passed in as an argument.
+ */
+ if (strcmp(dir, "$HOME") == 0) {
+ dir = home;
+ }
+
+ /*
+ * Expand $HOME and $USER in instance dir prefix
+ */
+ if ((tptr = strstr(instance_prefix, "$USER")) != 0) {
+ /* FIXME: should only support this if method is USER or BOTH */
+ char *expanded = alloca(strlen(idata->user) + strlen(instance_prefix)-5+1);
+ *tptr = 0;
+ sprintf(expanded, "%s%s%s", instance_prefix, idata->user, tptr+5);
+ instance_prefix = expanded;
+ }
+ if ((tptr = strstr(instance_prefix, "$HOME")) != 0) {
+ char *expanded = alloca(strlen(home)+strlen(instance_prefix)-5+1);
+ *tptr = 0;
+ sprintf(expanded, "%s%s%s", instance_prefix, home, tptr+5);
+ instance_prefix = expanded;
+ }
+
+ /*
+ * 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");
+ }
+ strcpy(poly.dir, dir);
+ strcpy(poly.instance_prefix, instance_prefix);
+ if (strcmp(method, "user") == 0)
+ poly.method = USER;
+#ifdef WITH_SELINUX
+ else if (strcmp(method, "context") == 0) {
+ if (idata->flags & PAMNS_CTXT_BASED_INST)
+ poly.method = CONTEXT;
+ else
+ poly.method = USER;
+ } else if (strcmp(method, "both") == 0) {
+ if (idata->flags & PAMNS_CTXT_BASED_INST)
+ poly.method = BOTH;
+ else
+ poly.method = USER;
+ }
+
+#endif
+ else {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Illegal method");
+ 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
+ * add to polyinstantiated directory structure.
+ */
+ if (uids) {
+ uid_t *uidptr;
+ const char *ustr, *sstr;
+ int count, i;
+
+ for (count = 0, ustr = sstr = uids; sstr; ustr = sstr + 1, count++)
+ sstr = strchr(ustr, ',');
+
+ poly.num_uids = count;
+ poly.uid = (uid_t *) malloc(count * sizeof (uid_t));
+ uidptr = poly.uid;
+ if (uidptr == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "out of memory");
+ goto skipping;
+ }
+
+ ustr = uids;
+ for (i = 0; i < count; i++) {
+ struct passwd *pwd;
+
+ tptr = strchr(ustr, ',');
+ if (tptr)
+ *tptr = '\0';
+
+ pwd = getpwnam(ustr);
+ *uidptr = pwd->pw_uid;
+ if (i < count - 1) {
+ ustr = tptr + 1;
+ uidptr++;
+ }
+ }
+ }
+
+ /*
+ * Add polyinstantiated directory structure to the linked list
+ * of all polyinstantiated directory structures.
+ */
+ if (add_polydir_entry(idata, &poly) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Allocation Error");
+ retval = PAM_SERVICE_ERR;
+ }
+ free(poly.uid);
+
+ goto out;
+
+skipping:
+ if (idata->flags & PAMNS_IGN_CONFIG_ERR)
+ retval = 0;
+ else
+ retval = PAM_SERVICE_ERR;
+out:
+ return retval;
+}
+
+
+/*
+ * Parses /etc/security/namespace.conf file to build a linked list of
+ * polyinstantiated directory structures of type polydir_s. Each entry
+ * in the linked list contains information needed to polyinstantiate
+ * one directory.
+ */
+static int parse_config_file(struct instance_data *idata)
+{
+ FILE *fil;
+ char *home;
+ struct passwd *cpwd;
+ char *line = NULL;
+ int retval;
+ size_t len = 0;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Parsing config file %s",
+ PAM_NAMESPACE_CONFIG);
+
+ /*
+ * Extract the user's home directory to resolve $HOME entries
+ * in the namespace configuration file.
+ */
+ cpwd = getpwnam(idata->user);
+ if (!cpwd) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting home dir for '%s'", idata->user);
+ return PAM_SESSION_ERR;
+ }
+ home = strdupa(cpwd->pw_dir);
+
+ /*
+ * Open configuration file, read one line at a time and call
+ * process_line to process each line.
+ */
+ fil = fopen(PAM_NAMESPACE_CONFIG, "r");
+ if (fil == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening config file");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Use unlocked IO */
+ __fsetlocking(fil, FSETLOCKING_BYCALLER);
+
+ /* loop reading the file */
+ while (getline(&line, &len, fil) > 0) {
+ retval = process_line(line, home, idata);
+ if (retval) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error processing conf file line %s", line);
+ fclose(fil);
+ free(line);
+ return PAM_SERVICE_ERR;
+ }
+ }
+ fclose(fil);
+ free(line);
+
+ /* All done...just some debug stuff */
+ if (idata->flags & PAMNS_DEBUG) {
+ struct polydir_s *dptr = idata->polydirs_ptr;
+ uid_t *iptr;
+
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ dptr?"Configured poly dirs:":"No configured poly dirs");
+ while (dptr) {
+ pam_syslog(idata->pamh, LOG_DEBUG, "dir='%s' iprefix='%s' meth=%d",
+ dptr->dir, dptr->instance_prefix, dptr->method);
+ for (i = 0, iptr = dptr->uid; i < dptr->num_uids; i++, iptr++)
+ pam_syslog(idata->pamh, LOG_DEBUG, "override user %d ", *iptr);
+ dptr = dptr->next;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+
+/*
+ * This funtion returns true if a given uid is present in the polyinstantiated
+ * 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.
+ */
+static int ns_override(struct polydir_s *polyptr, struct instance_data *idata)
+{
+ unsigned int i;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Checking for ns override in dir %s for uid %d",
+ polyptr->dir, idata->uid);
+
+ for (i = 0; i < polyptr->num_uids; i++) {
+ if (idata->uid == polyptr->uid[i]) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * poly_name returns the name of the polyinstantiated instance directory
+ * based on the method used for polyinstantiation (user, context or both)
+ * In addition, the function also returns the security contexts of the
+ * original directory to polyinstantiate and the polyinstantiated instance
+ * directory.
+ */
+#ifdef WITH_SELINUX
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ security_context_t *i_context, security_context_t *origcon,
+ struct instance_data *idata)
+#else
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ struct instance_data *idata)
+#endif
+{
+#ifdef WITH_SELINUX
+ security_context_t scon = NULL;
+ security_class_t tclass;
+#endif
+ int rc;
+
+# ifdef WITH_SELINUX
+ /*
+ * Get the security context of the directory to polyinstantiate.
+ */
+ rc = getfilecon(polyptr->dir, origcon);
+ if (rc < 0 || *origcon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting poly dir context, %m");
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * If polyinstantiating based on security context, get current
+ * process security context, get security class for directories,
+ * and ask the policy to provide security context of the
+ * polyinstantiated instance directory.
+ */
+ if ((polyptr->method == CONTEXT) || (polyptr->method == BOTH)) {
+ rc = getexeccon(&scon);
+ if (rc < 0 || scon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting exec context, %m");
+ return PAM_SESSION_ERR;
+ }
+ tclass = string_to_security_class("dir");
+
+ if (security_compute_member(scon, *origcon, tclass,
+ i_context) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error computing poly dir member context");
+ freecon(scon);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "member context returned by policy %s", *i_context);
+ freecon(scon);
+ }
+#endif
+ rc = PAM_SUCCESS;
+
+ /*
+ * Set the name of the polyinstantiated instance dir based on the
+ * polyinstantiation method.
+ */
+ switch (polyptr->method) {
+ case USER:
+ if (asprintf(i_name, "%s", idata->user) < 0)
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ break;
+
+#ifdef WITH_SELINUX
+ case CONTEXT:
+ if (asprintf(i_name, "%s", *i_context) < 0)
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ break;
+
+ case BOTH:
+ if (asprintf(i_name, "%s_%s", *i_context, idata->user) < 0)
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ break;
+#endif /* WITH_SELINUX */
+
+ default:
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR, "Unknown method");
+ rc = PAM_SESSION_ERR;
+ }
+
+ if ((idata->flags & PAMNS_DEBUG) && rc == PAM_SUCCESS)
+ pam_syslog(idata->pamh, LOG_DEBUG, "poly_name %s", *i_name);
+
+ return rc;
+}
+
+
+/*
+ * Create polyinstantiated instance directory (ipath).
+ */
+#ifdef WITH_SELINUX
+static int create_dirs(const 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,
+ struct instance_data *idata)
+#endif
+{
+ struct stat statbuf, newstatbuf;
+ int fd, pid, status;
+ char *inst_init_script = NULL;
+
+ /*
+ * stat the directory to polyinstantiate, so its owner-group-mode
+ * can be propagated to instance directory
+ */
+ if (stat(polyptr->dir, &statbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Make sure we are dealing with a directory
+ */
+ if (!S_ISDIR(statbuf.st_mode)) {
+ pam_syslog(idata->pamh, LOG_ERR, "poly dir %s is not a dir",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Create instance directory and set its security context to the context
+ * returned by the security policy. Set its mode and ownership
+ * attributes to match that of the original directory that is being
+ * polyinstantiated.
+ */
+ if (mkdir(ipath, S_IRUSR) < 0) {
+ if (errno == EEXIST)
+ return PAM_SUCCESS;
+ else {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
+ ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ /* Open a descriptor to it to prevent races */
+ fd = open(ipath, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening %s, %m", ipath);
+ return PAM_SESSION_ERR;
+ }
+#ifdef WITH_SELINUX
+ /* If SE Linux is disabled, no need to label it */
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ /* If method is USER, icontext is NULL */
+ if (icontext) {
+ if (fsetfilecon(fd, icontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, icontext);
+ close(fd);
+ return PAM_SESSION_ERR;
+ }
+ } else {
+ if (fsetfilecon(fd, ocontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, ocontext);
+ close(fd);
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+#endif
+ if (fstat(fd, &newstatbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
+ ipath);
+ return PAM_SESSION_ERR;
+ }
+ if (newstatbuf.st_uid != statbuf.st_uid ||
+ newstatbuf.st_gid != statbuf.st_gid) {
+ if (fchown(fd, statbuf.st_uid, statbuf.st_gid) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error changing owner for %s, %m",
+ ipath);
+ close(fd);
+ return PAM_SESSION_ERR;
+ }
+ }
+ if (fchmod(fd, statbuf.st_mode & 07777) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error changing mode for %s, %m",
+ ipath);
+ close(fd);
+ return PAM_SESSION_ERR;
+ }
+ close(fd);
+
+ /*
+ * Check to see if there is an instance initialization script in
+ * the polyinstantiated directory. If such a script exists
+ * execute it.
+ */
+ if (asprintf(&inst_init_script, "%s/%s", polyptr->dir,
+ INST_INIT_SCRIPT) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error allocating string for a path");
+ return PAM_SESSION_ERR;
+ }
+
+ if (access(inst_init_script, F_OK) == 0) {
+ if (access(inst_init_script, X_OK) < 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Inst init script not executable");
+ return PAM_SESSION_ERR;
+ } else {
+ pid = fork();
+ if (pid == 0) {
+ /*
+ * Change current directory to the instance directory
+ * before executing the instance initialization script.
+ */
+ if (chdir(ipath) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Can't chdir to %s, %m",
+ ipath);
+ exit(1);
+ }
+ if (execl(inst_init_script, inst_init_script, (char *)NULL) < 0)
+ exit(1);
+ } else if (pid > 0) {
+ while (waitpid (pid, &status, 0) != pid);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) > 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error initializing instance");
+ free(inst_init_script);
+ return PAM_SESSION_ERR;
+ }
+ } else if (pid < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Cannot fork to run instance init script, %m");
+ if (inst_init_script)
+ free(inst_init_script);
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+
+/*
+ * md5hash generates a hash of the passed in instance directory name.
+ */
+static int md5hash(char **instname, struct instance_data *idata)
+{
+ int i;
+ char *md5inst = NULL;
+ char *to;
+ unsigned char inst_digest[MD5_DIGEST_LENGTH];
+
+ /*
+ * Create MD5 hashes for instance pathname.
+ */
+
+ if (MD5(*instname, strlen(*instname),
+ inst_digest) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to generate hash for instname");
+ return PAM_SESSION_ERR;
+ }
+
+ if ((md5inst = malloc(MD5_DIGEST_LENGTH * 2 + 1)) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to allocate buffer");
+ return PAM_SESSION_ERR;
+ }
+
+ to = md5inst;
+ for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
+ snprintf(to, 3, "%02x", (unsigned int)inst_digest[i]);
+ to += 3;
+ }
+
+ free(*instname);
+ *instname = md5inst;
+
+ return PAM_SUCCESS;
+}
+
+/*
+ * This function performs the namespace setup for a particular directory
+ * that is being polyinstantiated. It creates an MD5 hash of instance
+ * directory, calls create_dirs to create it with appropriate
+ * security attributes, and performs bind mount to setup the process
+ * namespace.
+ */
+static int ns_setup(const 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
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Set namespace for directory %s", polyptr->dir);
+
+ dir = strrchr(polyptr->dir, '/');
+ if (dir && strlen(dir) > 1)
+ dir++;
+
+ /*
+ * Obtain the name of instance pathname based on the
+ * polyinstantiation method and instance context returned by
+ * security policy.
+ */
+#ifdef WITH_SELINUX
+ retval = poly_name(polyptr, &instname, &instcontext,
+ &origcontext, idata);
+#else
+ retval = poly_name(polyptr, &instname, idata);
+#endif
+
+ if (retval) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error getting instance name");
+ goto error_out;
+ } else {
+#ifdef WITH_SELINUX
+ if ((idata->flags & PAMNS_DEBUG) &&
+ (idata->flags & PAMNS_SELINUX_ENABLED))
+ pam_syslog(idata->pamh, LOG_DEBUG, "Inst context %s Orig context %s",
+ instcontext, origcontext);
+#endif
+ }
+
+ if (idata->flags & PAMNS_GEN_HASH) {
+ retval = md5hash(&instname, idata);
+ if (retval < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error generating md5 hash");
+ goto error_out;
+ }
+ }
+
+ if (asprintf(&inst_dir, "%s%s", polyptr->instance_prefix, instname) < 0)
+ goto error_out;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "instance_dir %s",
+ inst_dir);
+
+ /*
+ * Create instance directory with appropriate security
+ * contexts, owner, group and mode bits.
+ */
+#ifdef WITH_SELINUX
+ retval = create_dirs(polyptr, inst_dir, instcontext,
+ origcontext, idata);
+#else
+ retval = create_dirs(polyptr, inst_dir, idata);
+#endif
+
+ if (retval < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir");
+ goto error_out;
+ }
+
+ /*
+ * Bind mount instance directory on top of the polyinstantiated
+ * directory to provide an instance of polyinstantiated directory
+ * based on polyinstantiated method.
+ */
+ if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
+
+ goto cleanup;
+
+ /*
+ * various error exit points. Free allocated memory and set return
+ * value to indicate a pam session error.
+ */
+error_out:
+ retval = PAM_SESSION_ERR;
+
+cleanup:
+ free(inst_dir);
+ free(instname);
+#ifdef WITH_SELINUX
+ freecon(instcontext);
+ freecon(origcontext);
+#endif
+ return retval;
+}
+
+
+/*
+ * This function checks to see if the current working directory is
+ * inside the directory passed in as the first argument.
+ */
+static int cwd_in(char *dir, struct instance_data *idata)
+{
+ int retval = 0;
+ char cwd[PATH_MAX];
+
+ if (getcwd(cwd, PATH_MAX) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Can't get current dir, %m");
+ return -1;
+ }
+
+ if (strncmp(cwd, dir, strlen(dir)) == 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is inside %s", dir);
+ retval = 1;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is outside %s", dir);
+ }
+
+ return retval;
+}
+
+
+/*
+ * This function checks to see if polyinstantiation is needed for any
+ * of the directories listed in the configuration file. If needed,
+ * cycles through all polyinstantiated directory entries and calls
+ * ns_setup to setup polyinstantiation for each one of them.
+ */
+static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt)
+{
+ int retval = 0, need_poly = 0, changing_dir = 0;
+ char *cptr, *fptr, poly_parent[PATH_MAX];
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Set up namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directory entries to see if
+ * polyinstantiation is needed at all.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata)) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Overriding poly for user %d for dir %s",
+ idata->uid, pptr->dir);
+ continue;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Need poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+ need_poly = 1;
+ break;
+ }
+ }
+
+ /*
+ * If polyinstnatiation is needed, call the unshare system call to
+ * disassociate from the parent namespace.
+ */
+ if (need_poly) {
+ if (unshare(CLONE_NEWNS) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to unshare from parent namespace, %m");
+ return PAM_SESSION_ERR;
+ }
+ } else
+ return PAM_SUCCESS;
+
+ /*
+ * Again cycle through all polyinstantiated directories, this time,
+ * call ns_setup to setup polyinstantiation for a particular entry.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata))
+ continue;
+ else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Setting poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+
+ if ((unmnt == UNMNT_REMNT) || (unmnt == UNMNT_ONLY)) {
+ /*
+ * Check to see if process current directory is in the
+ * bind mounted instance_parent directory that we are trying to
+ * umount
+ */
+ if ((changing_dir = cwd_in(pptr->dir, idata)) < 0) {
+ return PAM_SESSION_ERR;
+ } else if (changing_dir) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "changing cwd");
+
+ /*
+ * Change current working directory to the parent of
+ * the mount point, that is parent of the orig
+ * directory where original contents of the polydir
+ * are available from
+ */
+ strcpy(poly_parent, pptr->dir);
+ fptr = strchr(poly_parent, '/');
+ cptr = strrchr(poly_parent, '/');
+ if (fptr && cptr && (fptr == cptr))
+ strcpy(poly_parent, "/");
+ else if (cptr)
+ *cptr = '\0';
+ if (chdir(poly_parent) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Can't chdir to %s, %m", poly_parent);
+ }
+ }
+
+ if (umount(pptr->dir) < 0) {
+ 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;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Umount succeeded %s",
+ pptr->dir);
+ }
+
+ if (unmnt != UNMNT_ONLY) {
+ retval = ns_setup(pptr, idata);
+ if (retval != PAM_SUCCESS)
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+
+/*
+ * Orig namespace. This function is called from when closing a pam
+ * session. If authorized, it unmounts instance directory.
+ */
+static int orig_namespace(struct instance_data *idata)
+{
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "orig namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directories from the namespace
+ * configuration file to see if polyinstantiation was performed for
+ * this user for each of the entry. If it was, try and unmount
+ * appropriate polyinstantiated instance directories.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata))
+ continue;
+ else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Unmounting instance dir for user %d & dir %s",
+ idata->uid, pptr->dir);
+
+ if (umount(pptr->dir) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
+ pptr->dir);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Unmount of %s succeeded",
+ pptr->dir);
+ }
+ }
+ return 0;
+}
+
+
+#ifdef WITH_SELINUX
+/*
+ * This function checks if the calling program has requested context
+ * change by calling setexeccon(). If context change is not requested
+ * then it does not make sense to polyinstantiate based on context.
+ * The return value from this function is used when selecting the
+ * polyinstantiation method. If context change is not requested then
+ * the polyinstantiation method is set to USER, even if the configuration
+ * file lists the method as "context" or "both".
+ */
+static int ctxt_based_inst_needed(void)
+{
+ security_context_t scon = NULL;
+ int rc = 0;
+
+ rc = getexeccon(&scon);
+ if (rc < 0 || scon == NULL)
+ return 0;
+ else {
+ freecon(scon);
+ return 1;
+ }
+}
+#endif
+
+
+/*
+ * Entry point from pam_open_session call.
+ */
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ char *user_name;
+ struct passwd *pwd;
+ enum unmnt_op unmnt = NO_UNMNT;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "gen_hash") == 0)
+ idata.flags |= PAMNS_GEN_HASH;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ if (strcmp(argv[i], "unmnt_remnt") == 0)
+ unmnt = UNMNT_REMNT;
+ if (strcmp(argv[i], "unmnt_only") == 0)
+ unmnt = UNMNT_ONLY;
+ if (strcmp(argv[i], "require_selinux") == 0) {
+ if (~(idata.flags & PAMNS_SELINUX_ENABLED)) {
+ pam_syslog(idata.pamh, LOG_ERR,
+ "selinux_required option given and selinux is disabled");
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "open_session - start");
+
+ /*
+ * Lookup user and fill struct items
+ */
+ retval = pam_get_item(idata.pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(idata.pamh, LOG_ERR, "Error recovering pam user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = getpwnam(user_name);
+ if (!pwd) {
+ pam_syslog(idata.pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Add the user info to the instance data so we can refer to them later.
+ */
+ idata.user[0] = 0;
+ strncat(idata.user, user_name, sizeof(idata.user));
+ idata.uid = pwd->pw_uid;
+
+ /*
+ * Parse namespace configuration file which lists directories to
+ * polyinstantiate, directory where instance directories are to
+ * be created and the method used for polyinstantiation.
+ */
+ retval = parse_config_file(&idata);
+ if (retval != PAM_SUCCESS) {
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SESSION_ERR;
+ }
+
+ if (idata.polydirs_ptr) {
+ retval = setup_namespace(&idata, unmnt);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup ok for pid %d", getpid());
+ }
+ } else if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Nothing to polyinstantiate");
+
+ del_polydir_list(idata.polydirs_ptr);
+ return retval;
+}
+
+
+/*
+ * Entry point from pam_close_session call.
+ */
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ char *user_name;
+ struct passwd *pwd;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ }
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "close_session - start");
+
+ /*
+ * Lookup user and fill struct items
+ */
+ retval = pam_get_item(idata.pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(idata.pamh, LOG_ERR, "Error recovering pam user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = getpwnam(user_name);
+ if (!pwd) {
+ pam_syslog(idata.pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Add the user info to the instance data so we can refer to them later.
+ */
+ idata.user[0] = 0;
+ strncat(idata.user, user_name, sizeof(idata.user));
+ 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;
+ }
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d",
+ getpid());
+
+ retval = orig_namespace(&idata);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace ok for pid %d", getpid());
+ }
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_namespace_modstruct = {
+ "pam_namespace",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL
+};
+#endif
+
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/Makefile.am 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2006 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAN5 = namespace.conf.5
+MAN8 = pam_namespace.8
+
+man_MANS = $(MAN5) $(MAN8)
+
+EXTRA_DIST = README namespace.conf $(man_MANS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_NAMESPACE_CONFIG=\"$(SCONFIGDIR)/namespace.conf\"
+AM_LDFLAGS = -no-undefined -avoid-version -module \
+ -L$(top_builddir)/libpam -lpam -lssl @LIBSELINUX@
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_namespace.la
+
+secureconf_DATA = namespace.conf
+
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/pam_namespace.8.xml 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_namespace'>
+
+ <refmeta>
+ <refentrytitle>pam_namespace</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_namespace-name'>
+ <refname>pam_namespace</refname>
+ <refpurpose>
+ PAM module for configuring namespace for a session
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_namespace-cmdsynopsis">
+ <command>pam_namespace.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ unmnt_remnt
+ </arg>
+ <arg choice="opt">
+ unmnt_only
+ </arg>
+ <arg choice="opt">
+ require_selinux
+ </arg>
+ <arg choice="opt">
+ gen_hash
+ </arg>
+ <arg choice="opt">
+ ignore_config_error
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_namespace-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_namespace PAM module sets up a private namespace for a
+ session with polyinstantiated directories. A polyinstantiated
+ directory provides a different instance of itself based on user
+ name, or when using SELinux, user name, security context or both.
+ </refsect1>
+
+ <refsect1 id="pam_namespace-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ A lot of debug informations is logged using syslog
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_remnt</option>
+ </term>
+ <listitem>
+ <para>
+ For programs such as su and newrole, the login
+ session has already setup a polyinstantiated
+ namespace. For these programs, polyinstantiation
+ is performed based on new user id or security
+ context, however the command first needs to
+ undo the polyinstantiation performed by login.
+ This argument instructs the command to
+ first undo previous polyinstantiation before
+ proceeding with new polyinstantiation based on
+ new id/context
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_only</option>
+ </term>
+ <listitem>
+ <para>
+ For trusted programs that want to undo any
+ existing bind mounts and process instance
+ directories on their own, this argument allows
+ them to unmount currently mounted instance
+ directories
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>require_selinux</option>
+ </term>
+ <listitem>
+ <para>
+ If selinux is not enabled, return failure
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>gen_hash</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of using the security context string
+ for the instance name, generate and use its
+ md5 hash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore_config_error</option>
+ </term>
+ <listitem>
+ <para>
+ If a line in the configuration file corresponding
+ to a polyinstantiated directory contains format
+ error, skip that line process the next line.
+ Without this option, pam will return an error
+ to the calling program resulting in termination
+ of the session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-services">
+ <title>MODULE SERVICES PROVIDED</title>
+ <para>
+ The <option>session</option> service is supported.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Namespace setup was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Unexpected system error occurred while setting up namespace.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Unexpected namespace configuration error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/namespace.conf</filename></term>
+ <listitem>
+ <para>Configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>namespace.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-authors">
+ <title>AUTHORS</title>
+ <para>
+ The namespace setup scheme was designed by Stephen Smalley, Janak Desai
+ and Chad Sellers.
+ The pam_namespace PAM module was developed by Janak Desai <janak at us.ibm.com>, Chad Sellers <csellers at tresys.com> and Steve Grubb <sgrubb at redhat.com>.
+ </para>
+ </refsect1>
+</refentry>
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/namespace.conf 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,15 @@
+# /etc/security/namespace.conf
+#
+# See /usr/share/doc/pam-*/txts/README.pam_namespace for more information.
+#
+# Uncommenting the following three lines will polyinstantiate
+# /tmp, /var/tmp and user's home directories. /tmp and /var/tmp will
+# be polyinstantiated based on both security context as well as user
+# name, whereas home directory will be polyinstantiated based on
+# security context only. Polyinstantion will not be performed for
+# user root and adm for directories /tmp and /var/tmp, whereas home
+# directories will be polyinstantiated for all users.
+#
+#/tmp /tmp/tmp.inst-$USER- both adm
+#/var/tmp /var/tmp/tmp.inst-$USER- both adm
+#$HOME $HOME/$USER.inst- context
--- /dev/null 2006-04-25 10:12:36.092931750 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/namespace.conf.5.xml 2006-04-25 16:41:28.000000000 +0200
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="namespace.conf">
+
+ <refmeta>
+ <refentrytitle>namespace.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>namespace.conf</refname>
+ <refpurpose>the namespace configuration file</refpurpose>
+ </refnamediv>
+
+
+ <refsect1 id='namespace.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module allows setup of private namespaces with polyinstantiated
+ directories. Directories can be polyinstantiated based on user name
+ or, in the case of SELinux, user name, security context or both.
+ </para>
+
+ <para>
+ The <filename>/etc/security/namespace.conf</filename> file specifies
+ which directories are polyinstantiated, how they are polyinstantiated,
+ how instance directories would be named, and any users for whom
+ polyinstantiation would not be performed.
+ </para>
+
+ <para>
+ When someone logs in, the file <filename>namespace.conf</filename> is
+ scanned where each non comment line represents one polyinstantiated
+ directory with space separated fields as follows:
+ </para>
+
+ <para>
+ <replaceable>polydir</replaceable> <replaceable>instance_prefex</replaceable> <replaceable>method</replaceable> <replaceable>list_of_uids</replaceable>
+ </para>
+
+ <para>
+ The first field, <replaceable>polydir</replaceable>, is the absolute
+ pathname of the directory to polyinstantiate. Special entry $HOME is
+ supported to designate user's home directory. This field cannot be
+ blank.
+ </para>
+
+ <para>
+ The second field, <replaceable>instance_prefix</replaceable> is
+ the string prefix used to build the pathname for the instantiation
+ of <polydir>. The directory security context, or optionally its
+ md5sum string (32 hex characters), is appended to the prefix to
+ generate the final instance directory path. This directory is
+ created if it did not exist already, and is then bind mounted on
+ the <polydir> to provide an instance of <polydir> based on the
+ <method> column. The special string $HOME is replaced with the
+ user's home directory, and $USER with the username. This field
+ cannot be blank.
+ </para>
+
+ <para>
+ The third field, <replaceable>method</replaceable>, is the method
+ used for polyinstantiation. It can take 3 different values; "user"
+ for polyinstantiation based on user name, "context" for
+ polyinstantiation based on process security context, and "both"
+ for polyinstantiation based on both user name and security context.
+ Methods "context" and "both" are only available with SELinux. This
+ field cannot be blank.
+ </para>
+
+ <para>
+ The fourth field, <replaceable>list_of_uids</replaceable>, is
+ a comma separated list of user names for whom the polyinstantiation
+ is not performed. If left blank, polyinstantiation will be performed
+ for all users.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/namespace.conf</filename>.
+ </para>
+
+ <para>
+ # The following three lines will polyinstantiate /tmp,
+ # /var/tmp and user's home directories. /tmp and /var/tmp
+ # will be polyinstantiated based on both security context as well
+ # as user name, whereas home directory will be polyinstantiated
+ # based on security context only. Polyinstantiation will not be
+ # performed for user root and adm for directories /tmp and
+ # /var/tmp, whereas home directories will be polyinstantiated for
+ # all users.
+ #
+ /tmp /tmp/tmp.inst-$USER- both root,adm
+ /var/tmp /var/tmp/tmp.inst-$USER- both root,adm
+ $HOME $HOME.inst- context
+ </para>
+
+ <para>
+ For the <service>s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/<service> as the last line for
+ session group:
+ </para>
+
+ <para>
+ session required pam_namespace.so [arguments]
+ </para>
+
+ <para>
+ This module also depends on pam_selinux.so setting the context.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_namespace</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="namespace.conf-author">
+ <title>AUTHORS</title>
+ <para>
+ The namespace.conf manual page was written by Janak Desai <janak at us.ibm.com>.
+ </para>
+ </refsect1>
+</refentry>
--- Linux-PAM-0.99.3.0/modules/Makefile.am.namespace 2006-04-25 16:41:28.000000000 +0200
+++ Linux-PAM-0.99.3.0/modules/Makefile.am 2006-04-25 16:41:28.000000000 +0200
@@ -5,7 +5,8 @@
SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
pam_env pam_filter pam_ftp pam_group pam_issue pam_lastlog \
pam_limits pam_listfile pam_localuser pam_mail pam_mkhomedir \
- pam_motd pam_nologin pam_permit pam_pwdb pam_rhosts pam_rootok \
+ pam_motd pam_namespace pam_nologin pam_permit pam_pwdb \
+ pam_rhosts pam_rootok \
pam_securetty pam_selinux pam_shells pam_stress pam_succeed_if \
pam_tally pam_time pam_umask pam_unix pam_userdb pam_warn \
pam_wheel pam_xauth \
--- Linux-PAM-0.99.3.0/configure.in.namespace 2006-04-25 16:41:28.000000000 +0200
+++ Linux-PAM-0.99.3.0/configure.in 2006-04-25 16:41:28.000000000 +0200
@@ -348,6 +348,9 @@
LIBS=$BACKUP_LIBS
AC_SUBST(LIBSELINUX)
AM_CONDITIONAL([HAVE_LIBSELINUX], [test ! -z "$LIBSELINUX"])
+if test ! -z "$LIBSELINUX" ; then
+ AC_DEFINE([WITH_SELINUX], 1, [Defined if SE Linux support is compiled in])
+fi
dnl Checks for Libcap
BACKUP_LIBS=$LIBS
@@ -454,6 +457,7 @@
modules/pam_limits/Makefile modules/pam_listfile/Makefile \
modules/pam_localuser/Makefile modules/pam_mail/Makefile \
modules/pam_mkhomedir/Makefile modules/pam_motd/Makefile \
+ modules/pam_namespace/Makefile \
modules/pam_nologin/Makefile modules/pam_permit/Makefile \
modules/pam_pwdb/Makefile modules/pam_rhosts/Makefile \
modules/pam_rootok/Makefile \
pam_namespace-have-unshare.patch:
config.h.in | 3 +++
configure.in | 2 ++
modules/pam_namespace/Makefile.am | 3 ++-
3 files changed, 7 insertions(+), 1 deletion(-)
--- NEW FILE pam_namespace-have-unshare.patch ---
--- Linux-PAM-0.99.3.0/configure.in.have-unshare 2006-04-20 15:33:07.000000000 +0200
+++ Linux-PAM-0.99.3.0/configure.in 2006-04-20 15:57:54.000000000 +0200
@@ -402,6 +402,8 @@
AC_CHECK_FUNCS(strcspn strdup strspn strstr strtol uname)
AC_CHECK_FUNCS(getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r)
AC_CHECK_FUNCS(getgrouplist getline getdelim)
+AC_CHECK_FUNCS(unshare, [UNSHARE=yes], [UNSHARE=no])
+AM_CONDITIONAL([HAVE_UNSHARE], [test "$UNSHARE" = yes])
dnl Checks for programs/utilities
AC_CHECK_PROG(SGML2PS, sgml2ps, yes, no)
--- Linux-PAM-0.99.3.0/config.h.in.have-unshare 2006-04-20 15:33:07.000000000 +0200
+++ Linux-PAM-0.99.3.0/config.h.in 2006-04-20 15:33:07.000000000 +0200
@@ -188,6 +188,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `unshare' function. */
+#undef HAVE_UNSHARE
+
/* Define to 1 if you have the <utmpx.h> header file. */
#undef HAVE_UTMPX_H
--- Linux-PAM-0.99.3.0/modules/pam_namespace/Makefile.am.have-unshare 2006-04-20 15:33:07.000000000 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/Makefile.am 2006-04-20 15:33:07.000000000 +0200
@@ -21,7 +21,8 @@
AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
endif
+if HAVE_UNSHARE
securelib_LTLIBRARIES = pam_namespace.la
secureconf_DATA = namespace.conf
-
+endif
pam_namespace-no-mans.patch:
Makefile.am | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
--- NEW FILE pam_namespace-no-mans.patch ---
--- Linux-PAM-0.99.3.0/modules/pam_namespace/Makefile.am.no-mans 2006-04-20 12:58:35.000000000 +0200
+++ Linux-PAM-0.99.3.0/modules/pam_namespace/Makefile.am 2006-04-20 14:28:23.000000000 +0200
@@ -6,7 +6,7 @@
MAN5 = namespace.conf.5
MAN8 = pam_namespace.8
-man_MANS = $(MAN5) $(MAN8)
+#man_MANS = $(MAN5) $(MAN8)
EXTRA_DIST = README namespace.conf $(man_MANS)
Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/pam/devel/.cvsignore,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- .cvsignore 3 Feb 2006 12:41:29 -0000 1.33
+++ .cvsignore 25 Apr 2006 14:53:39 -0000 1.34
@@ -1,3 +1,3 @@
Linux-PAM-0.99.3.0.tar.bz2
db-4.3.29.tar.gz
-pam-redhat-0.99.3-1.tar.bz2
+pam-redhat-0.99.4-1.tar.bz2
Index: pam.spec
===================================================================
RCS file: /cvs/dist/rpms/pam/devel/pam.spec,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -r1.105 -r1.106
--- pam.spec 24 Feb 2006 10:46:47 -0000 1.105
+++ pam.spec 25 Apr 2006 14:53:39 -0000 1.106
@@ -6,12 +6,12 @@
%define pwdb_version 0.62
%define db_version 4.3.29
%define db_conflicting_version 4.4.0
-%define pam_redhat_version 0.99.3-1
+%define pam_redhat_version 0.99.4-1
Summary: A security tool which provides authentication for applications.
Name: pam
Version: 0.99.3.0
-Release: 2
+Release: 3
License: GPL or BSD
Group: System Environment/Base
Source0: ftp.us.kernel.org:/pub/linux/libs/pam/pre/library/Linux-PAM-%{version}.tar.bz2
@@ -29,23 +29,27 @@
Patch28: pam-0.75-sgml2latex.patch
Patch34: pam-0.99.2.1-dbpam.patch
Patch70: pam-0.99.2.1-selinux-nofail.patch
-Patch72: pam-0.99.3.0-pie.patch
Patch80: pam-0.99.2.1-selinux-drop-multiple.patch
Patch81: pam-0.99.3.0-cracklib-try-first-pass.patch
+Patch90: pam_namespace-7.patch
+Patch91: pam_namespace-no-mans.patch
+Patch92: pam_namespace-have-unshare.patch
BuildRoot: %{_tmppath}/%{name}-root
Requires: cracklib, cracklib-dicts >= 2.8
Obsoletes: pamconfig
Prereq: grep, mktemp, sed, coreutils, /sbin/ldconfig
-BuildPrereq: autoconf, bison, flex, glib2-devel, sed
+BuildPrereq: autoconf, automake, bison, flex, glib2-devel, sed
BuildPrereq: cracklib, cracklib-dicts >= 2.8
-BuildPrereq: perl, pkgconfig
+BuildPrereq: perl, pkgconfig, openssl-devel
%if %{WITH_AUDIT}
BuildPrereq: audit-libs-devel >= 1.0.8
Requires: audit-libs >= 1.0.8
%endif
BuildPrereq: libselinux-devel >= 1.27.7
Requires: libselinux >= 1.27.7
+BuildPrereq: glibc >= 2.3.90-37
+Requires: glibc >= 2.3.90-37
# Following deps are necessary only to build the pam library documentation.
# They can be safely removed if the documentation is not needed.
BuildPrereq: linuxdoc-tools
@@ -85,9 +89,11 @@
%patch28 -p1 -b .doc
%patch34 -p1 -b .dbpam
%patch70 -p1 -b .nofail
-%patch72 -p1 -b .pie
%patch80 -p1 -b .drop-multiple
%patch81 -p1 -b .try-first-pass
+%patch90 -p1 -b .namespace
+%patch91 -p1 -b .no-mans
+%patch92 -p1 -b .have-unshare
for readme in modules/pam_*/README ; do
cp -f ${readme} doc/txts/README.`dirname ${readme} | sed -e 's|^modules/||'`
@@ -300,6 +306,7 @@
/%{_lib}/security/pam_mail.so
/%{_lib}/security/pam_mkhomedir.so
/%{_lib}/security/pam_motd.so
+/%{_lib}/security/pam_namespace.so
/%{_lib}/security/pam_nologin.so
/%{_lib}/security/pam_permit.so
/%{_lib}/security/pam_postgresok.so
@@ -334,6 +341,7 @@
%config(noreplace) %{_sysconfdir}/security/console.handlers
%config(noreplace) %{_sysconfdir}/security/group.conf
%config(noreplace) %{_sysconfdir}/security/limits.conf
+%config(noreplace) %{_sysconfdir}/security/namespace.conf
%config(noreplace) %{_sysconfdir}/security/pam_env.conf
%config(noreplace) %{_sysconfdir}/security/time.conf
%config(noreplace) %{_sysconfdir}/security/opasswd
@@ -353,6 +361,11 @@
%{_libdir}/libpam_misc.so
%changelog
+* Tue Apr 25 2006 Tomas Mraz <tmraz at redhat.com> 0.99.3.0-3
+- added pam_namespace module written by Janak Desai (per-user /tmp
+support)
+- new pam-redhat modules version
+
* Fri Feb 24 2006 Tomas Mraz <tmraz at redhat.com> 0.99.3.0-2
- added try_first_pass option to pam_cracklib
- use try_first_pass for pam_unix and pam_cracklib in
Index: sources
===================================================================
RCS file: /cvs/dist/rpms/pam/devel/sources,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- sources 3 Feb 2006 12:41:29 -0000 1.35
+++ sources 25 Apr 2006 14:53:39 -0000 1.36
@@ -1,3 +1,3 @@
aabed0543f57dc3e4eebbb0779daf898 Linux-PAM-0.99.3.0.tar.bz2
13585a20ce32f113b8e8cdb57f52e3bb db-4.3.29.tar.gz
-d1a3f1190c8c9b7ce3cf27660f59a2ab pam-redhat-0.99.3-1.tar.bz2
+754c2bd7c117aa898f477478b8bfb727 pam-redhat-0.99.4-1.tar.bz2
--- pam-0.99.3.0-pie.patch DELETED ---
- Previous message (by thread): rpms/selinux-policy/devel policygentool,1.5,1.6
- Next message (by thread): rpms/ethereal/FC-4 ethereal-column.patch, NONE, 1.1 .cvsignore, 1.25, 1.26 ethereal.spec, 1.41, 1.42 sources, 1.28, 1.29
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list