From: David Quigley <dpquigl@xxxxxxxxxxxxx> This patch adds several functions which are large sections of code taken from the existing code base to make the code more readable. Signed-Off-By: David Quigley <dpquigl@xxxxxxxxxxxxx> --- pam_namespace.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) diff -uprN -X dontdiff pam_namespace_header/pam_namespace.c pam_namespace_functions/pam_namespace.c --- pam_namespace_header/pam_namespace.c 2006-07-24 12:40:13.000000000 -0400 +++ pam_namespace_functions/pam_namespace.c 2006-07-24 13:01:34.000000000 -0400 @@ -33,6 +33,32 @@ #include "pam_namespace.h" /* + * Copies the contents of ent into pent + */ +static int copy_ent(const struct polydir_s *ent, struct polydir_s *pent) +{ + unsigned int i; + + 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)) { + return -1; + } + for (i = 0, pptr = pent->uid, eptr = ent->uid; i < ent->num_uids; + i++, eptr++, pptr++) + *pptr = *eptr; + } else + pent->uid = NULL; + return 0; +} + +/* * 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. @@ -413,6 +439,54 @@ static int ns_override(struct polydir_s return 0; } +#ifdef WITH_SELINUX +static int form_context(const struct polydir_s *polyptr, + security_context_t *i_context, security_context_t *origcon, + struct instance_data *idata) +{ + int rc = PAM_SUCCESS; + security_context_t scon = NULL; + security_class_t tclass; + + /* + * 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); + } + return PAM_SUCCESS; +} +#endif /* * poly_name returns the name of the polyinstantiated instance directory @@ -516,6 +590,122 @@ static int poly_name(const struct polydi return rc; } +static int check_inst_parent(char *ipath, struct instance_data *idata) +{ + struct stat instpbuf; + char *inst_parent, *trailing_slash; + /* + * stat the instance parent path to make sure it exists + * and is a directory. Check that its mode is 000 (unless the + * admin explicitly instructs to ignore the instance parent + * mode by the "ignore_instance_parent_mode" argument). + */ + inst_parent = (char *) malloc(strlen(ipath)+1); + if (!inst_parent) { + pam_syslog(idata->pamh, LOG_ERR, "Error allocating pathname string"); + return PAM_SESSION_ERR; + } + + strcpy(inst_parent, ipath); + trailing_slash = strrchr(inst_parent, '/'); + if (trailing_slash) + *trailing_slash = '\0'; + + if (stat(inst_parent, &instpbuf) < 0) { + pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m", inst_parent); + free(inst_parent); + return PAM_SESSION_ERR; + } + + /* + * Make sure we are dealing with a directory + */ + if (!S_ISDIR(instpbuf.st_mode)) { + pam_syslog(idata->pamh, LOG_ERR, "Instance parent %s is not a dir", + inst_parent); + free(inst_parent); + return PAM_SESSION_ERR; + } + + if ((idata->flags & PAMNS_IGN_INST_PARENT_MODE) == 0) { + if (instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) { + pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000", + inst_parent); + free(inst_parent); + return PAM_SESSION_ERR; + } + } + free(inst_parent); + return PAM_SUCCESS; +} + +/* +* Check to see if there is a namespace initialization script in +* the /etc/security directory. If such a script exists +* execute it and pass directory to polyinstantiate and instance +* directory as arguments. +*/ +static int inst_init(const struct polydir_s *polyptr, char *ipath, + struct instance_data *idata) +{ + 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; + } + + if (access(NAMESPACE_INIT_SCRIPT, F_OK) == 0) { + if (access(NAMESPACE_INIT_SCRIPT, X_OK) < 0) { + if (idata->flags & PAMNS_DEBUG) + pam_syslog(idata->pamh, LOG_ERR, + "Namespace init script not executable"); + rc = PAM_SESSION_ERR; + goto out; + } else { + pid = fork(); + if (pid == 0) { +#ifdef WITH_SELINUX + if (idata->flags & PAMNS_SELINUX_ENABLED) { + if (setexeccon(NULL) < 0) + exit(1); + } +#endif + if (execl(NAMESPACE_INIT_SCRIPT, NAMESPACE_INIT_SCRIPT, + polyptr->dir, ipath, (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 initializing instance"); + rc = PAM_SESSION_ERR; + goto out; + } + } 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: + (void) signal(SIGCHLD, osighand); + + return rc; +} /* * Create polyinstantiated instance directory (ipath). _______________________________________________ Pam-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/pam-list