--- Linux-PAM-0.99.6.2/modules/pam_namespace/pam_namespace.h.dirnames 2007-02-26 23:31:26.000000000 +0100 +++ Linux-PAM-0.99.6.2/modules/pam_namespace/pam_namespace.h 2007-02-27 00:40:04.000000000 +0100 @@ -89,6 +89,8 @@ #define PAMNS_IGN_INST_PARENT_MODE 0x00008000 /* Ignore instance parent mode */ #define PAMNS_NO_UNMOUNT_ON_CLOSE 0x00010000 /* no unmount at session close */ +#define NAMESPACE_MAX_DIR_LEN 80 + /* * Polyinstantiation method options, based on user, security context * or both --- Linux-PAM-0.99.6.2/modules/pam_namespace/pam_namespace.c.dirnames 2007-02-26 23:31:26.000000000 +0100 +++ Linux-PAM-0.99.6.2/modules/pam_namespace/pam_namespace.c 2007-02-27 00:39:51.000000000 +0100 @@ -436,6 +436,36 @@ return 0; } +/* + * md5hash generates a hash of the passed in instance directory name. + */ +static char *md5hash(const 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. + */ + + MD5((const unsigned char *)instname, strlen(instname), inst_digest); + + if ((md5inst = malloc(MD5_DIGEST_LENGTH * 2 + 1)) == NULL) { + pam_syslog(idata->pamh, LOG_ERR, "Unable to allocate buffer"); + return NULL; + } + + to = md5inst; + for (i = 0; i < MD5_DIGEST_LENGTH; i++) { + snprintf(to, 3, "%02x", (unsigned int)inst_digest[i]); + to += 2; + } + + return md5inst; +} + #ifdef WITH_SELINUX static int form_context(const struct polydir_s *polyptr, security_context_t *i_context, security_context_t *origcon, @@ -547,12 +577,21 @@ #endif { int rc; + char *hash = NULL; +#ifdef WITH_SELINUX + security_context_t rawcon = NULL; +#endif -# ifdef WITH_SELINUX - rc = form_context(polyptr, i_context, origcon, idata); + *i_name = NULL; +#ifdef WITH_SELINUX + *i_context = NULL; + *origcon = NULL; + if ((rc=form_context(polyptr, i_context, origcon, idata)) != PAM_SUCCESS) { + return rc; + } #endif - rc = PAM_SUCCESS; + rc = PAM_SESSION_ERR; /* * Set the name of the polyinstantiated instance dir based on the * polyinstantiation method. @@ -561,16 +600,20 @@ case USER: if (asprintf(i_name, "%s", idata->user) < 0) { *i_name = NULL; - rc = PAM_SESSION_ERR; - } + goto fail; + } break; #ifdef WITH_SELINUX case LEVEL: case CONTEXT: - if (asprintf(i_name, "%s_%s", *i_context, idata->user) < 0) { + if (selinux_trans_to_raw_context(*i_context, &rawcon) < 0) { + pam_syslog(idata->pamh, LOG_ERR, "Error translating directory context"); + goto fail; + } + if (asprintf(i_name, "%s_%s", rawcon, idata->user) < 0) { *i_name = NULL; - rc = PAM_SESSION_ERR; + goto fail; } break; @@ -579,12 +622,48 @@ default: if (idata->flags & PAMNS_DEBUG) pam_syslog(idata->pamh, LOG_ERR, "Unknown method"); - rc = PAM_SESSION_ERR; + goto fail; } - if ((idata->flags & PAMNS_DEBUG) && rc == PAM_SUCCESS) + if (idata->flags & PAMNS_DEBUG) pam_syslog(idata->pamh, LOG_DEBUG, "poly_name %s", *i_name); + if ((idata->flags & PAMNS_GEN_HASH) || strlen(*i_name) > NAMESPACE_MAX_DIR_LEN) { + hash = md5hash(*i_name, idata); + if (hash == NULL) { + goto fail; + } + if (idata->flags & PAMNS_GEN_HASH) { + free(*i_name); + *i_name = hash; + hash = NULL; + } else { + char *newname; + if (asprintf(&newname, "%.*s_%s", NAMESPACE_MAX_DIR_LEN-1-strlen(hash), + *i_name, hash) < 0) { + goto fail; + } + free(*i_name); + *i_name = newname; + } + } + rc = PAM_SUCCESS; + +fail: + free(hash); +#ifdef WITH_SELINUX + freecon(rawcon); +#endif + if (rc != PAM_SUCCESS) { +#ifdef WITH_SELINUX + freecon(*i_context); + *i_context = NULL; + freecon(*origcon); + *origcon = NULL; +#endif + free(*i_name); + *i_name = NULL; + } return rc; } @@ -832,39 +911,6 @@ /* - * 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. - */ - - MD5((unsigned char *)*instname, strlen(*instname), inst_digest); - - 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 @@ -914,14 +960,6 @@ #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;