diff -rup Linux-PAM-0.99.6.2-orig/modules/pam_selinux/pam_selinux.8.xml Linux-PAM-0.99.6.2/modules/pam_selinux/pam_selinux.8.xml
--- Linux-PAM-0.99.6.2-orig/modules/pam_selinux/pam_selinux.8.xml 2006-10-23 00:25:53.000000000 -0400
+++ Linux-PAM-0.99.6.2/modules/pam_selinux/pam_selinux.8.xml 2006-10-25 13:18:50.000000000 -0400
@@ -36,6 +36,9 @@
verbose
+
+ config_role
+
@@ -121,6 +124,17 @@
+
+
+
+
+
+
+ attempt to ask the user for a custom security context role (and
+ level, if MLS is on).
+
+
+
Only in Linux-PAM-0.99.6.2/modules/pam_selinux: pam_selinux.8.xml.config_role
diff -rup Linux-PAM-0.99.6.2-orig/modules/pam_selinux/pam_selinux.c Linux-PAM-0.99.6.2/modules/pam_selinux/pam_selinux.c
--- Linux-PAM-0.99.6.2-orig/modules/pam_selinux/pam_selinux.c 2006-10-23 00:25:53.000000000 -0400
+++ Linux-PAM-0.99.6.2/modules/pam_selinux/pam_selinux.c 2006-10-25 13:21:49.000000000 -0400
@@ -151,6 +151,8 @@ manual_context (pam_handle_t *pamh, cons
}
else
send_text(pamh,_("Not a valid security context"),debug);
+
+ context_free (new_context); /* next time around allocates another */
}
else {
_pam_drop(responses);
@@ -161,6 +163,129 @@ manual_context (pam_handle_t *pamh, cons
return NULL;
}
+/* returns TRUE if role is in context list */
+static int listed_role(context_t *clist, int num, const char *role)
+{
+ int scan = 0;
+
+ while (scan < num)
+ {
+ if (!strcmp(context_role_get(clist[scan]), role))
+ return 1;
+ ++scan;
+ }
+
+ return 0;
+}
+
+/* returns TRUE if range is in context list */
+static int listed_range(context_t *clist, int num, const char *range)
+{
+ int scan = 0;
+
+ while (scan < num)
+ {
+ if (!strcmp(context_range_get(clist[scan]), range))
+ return 1;
+ ++scan;
+ }
+
+ return 0;
+}
+
+static security_context_t
+config_context (pam_handle_t *pamh, const char *user,
+ security_context_t puser_context, int debug)
+{
+ security_context_t newcon;
+ context_t new_context;
+ int mls_enabled = is_selinux_mls_enabled();
+ char *responses;
+ char resp_val = 0;
+ int num = 0;
+ security_context_t *list = NULL;
+ context_t *clist = NULL;
+
+ num = get_ordered_context_list(user, NULL /* puser_context */, &list);
+ if (num)
+ {
+ int scan = 0;
+
+ if (!(clist = calloc(sizeof(context_t), num)))
+ return NULL;
+
+ while (scan < num)
+ {
+ clist[scan] = context_new(list[scan]);
+
+ ++scan;
+ }
+
+ freeconary(list);
+ }
+
+ while (1) {
+ query_response(pamh,
+ _("Would you like to enter a role/level? [y] "),
+ &responses,debug);
+
+ resp_val = responses[0];
+ _pam_drop(responses);
+ if ((resp_val == 'y') || (resp_val == 'Y') || (resp_val == '\0'))
+ {
+ new_context = context_new (puser_context);
+
+ /* Allow the user to enter role and level individually */
+ query_response(pamh,_("role: "),&responses,debug);
+ if (responses[0] && context_role_set (new_context, responses))
+ goto fail_set;
+ _pam_drop(responses);
+ if (mls_enabled)
+ {
+ query_response(pamh,_("level: "),&responses,debug);
+ if (responses[0] && context_range_set (new_context, responses))
+ goto fail_set;
+ _pam_drop(responses);
+ }
+
+ if (!listed_role(clist, num, context_role_get(new_context)))
+ send_text(pamh,_("Not a valid role"),debug);
+ else if (!listed_range(clist, num, context_range_get(new_context)))
+ send_text(pamh,_("Not a valid level range"),debug);
+ else if (!security_check_context(context_str(new_context))) {
+ /* Get the string value of the context and see if it is valid. */
+ newcon = strdup(context_str(new_context));
+ context_free (new_context);
+ freecon(puser_context);
+ return newcon;
+ }
+ else
+ send_text(pamh,_("Not a valid security context"),debug);
+
+ context_free (new_context); /* next time around allocates another */
+ }
+ else
+ break;
+ } /* end while */
+
+ while (num-- > 0)
+ context_free(clist[num]);
+ free(clist);
+
+ freecon(puser_context);
+ return NULL;
+
+ fail_set:
+ while (num-- > 0)
+ context_free(clist[num]);
+ free(clist);
+
+ _pam_drop(responses);
+ context_free (new_context);
+ freecon(puser_context);
+ return NULL;
+}
+
static void
security_restorelabel_tty(const pam_handle_t *pamh,
const char *tty, security_context_t context)
@@ -273,10 +398,12 @@ pam_sm_open_session(pam_handle_t *pamh,
{
int i, debug = 0, ttys=1, has_tty=isatty(0);
int verbose=0, close_session=0;
+ int config_role = 0;
int ret = 0;
security_context_t* contextlist = NULL;
int num_contexts = 0;
- const void *username = NULL;
+ const void *pusername = NULL;
+ const char *username = NULL;
const void *tty = NULL;
char *seuser=NULL;
char *level=NULL;
@@ -295,6 +422,12 @@ pam_sm_open_session(pam_handle_t *pamh,
if (strcmp(argv[i], "close") == 0) {
close_session = 1;
}
+ if (strcmp(argv[i], "config_role") == 0) {
+ config_role = 1;
+ }
+ if (strcmp(argv[i], "config_mls") == 0) {
+ config_role = 1;
+ }
}
if (debug)
@@ -307,10 +440,11 @@ pam_sm_open_session(pam_handle_t *pamh,
if (!(selinux_enabled = is_selinux_enabled()>0) )
return PAM_SUCCESS;
- if (pam_get_item(pamh, PAM_USER, &username) != PAM_SUCCESS ||
- username == NULL) {
+ if (pam_get_item(pamh, PAM_USER, &pusername) != PAM_SUCCESS ||
+ pusername == NULL) {
return PAM_USER_UNKNOWN;
}
+ username = pusername;
if (getseuserbyname(username, &seuser, &level)==0) {
num_contexts = get_ordered_context_list_with_level(seuser,
@@ -319,19 +453,31 @@ pam_sm_open_session(pam_handle_t *pamh,
&contextlist);
if (debug)
pam_syslog(pamh, LOG_DEBUG, "Username= %s SELinux User = %s Level= %s",
- (const char *)username, seuser, level);
+ username, seuser, level);
free(seuser);
free(level);
}
if (num_contexts > 0) {
user_context = (security_context_t) strdup(contextlist[0]);
freeconary(contextlist);
+
+ if (config_role && has_tty) {
+ user_context = config_context(pamh, username, user_context, debug);
+ if (user_context == NULL) {
+ pam_syslog (pamh, LOG_ERR, "Unable to get valid context for %s",
+ username);
+ if (security_getenforce() == 1)
+ return PAM_AUTH_ERR;
+ else
+ return PAM_SUCCESS;
+ }
+ }
} else {
if (has_tty) {
user_context = manual_context(pamh,username,debug);
if (user_context == NULL) {
pam_syslog (pamh, LOG_ERR, "Unable to get valid context for %s",
- (const char *)username);
+ username);
if (security_getenforce() == 1)
return PAM_AUTH_ERR;
else
@@ -340,7 +486,7 @@ pam_sm_open_session(pam_handle_t *pamh,
} else {
pam_syslog (pamh, LOG_ERR,
"Unable to get valid context for %s, No valid tty",
- (const char *)username);
+ username);
if (security_getenforce() == 1)
return PAM_AUTH_ERR;
else
@@ -381,7 +527,7 @@ pam_sm_open_session(pam_handle_t *pamh,
if (ret) {
pam_syslog(pamh, LOG_ERR,
"Error! Unable to set %s executable context %s.",
- (const char *)username, user_context);
+ username, user_context);
if (security_getenforce() == 1) {
freecon(user_context);
return PAM_AUTH_ERR;
@@ -389,7 +535,7 @@ pam_sm_open_session(pam_handle_t *pamh,
} else {
if (debug)
pam_syslog(pamh, LOG_NOTICE, "set %s security context to %s",
- (const char *)username, user_context);
+ username, user_context);
}
#ifdef HAVE_SETKEYCREATECON
ret = setkeycreatecon(user_context);
@@ -402,7 +548,7 @@ pam_sm_open_session(pam_handle_t *pamh,
if (ret) {
pam_syslog(pamh, LOG_ERR,
"Error! Unable to set %s key creation context %s.",
- (const char *)username, user_context);
+ username, user_context);
if (security_getenforce() == 1) {
freecon(user_context);
return PAM_AUTH_ERR;
@@ -410,7 +556,7 @@ pam_sm_open_session(pam_handle_t *pamh,
} else {
if (debug)
pam_syslog(pamh, LOG_NOTICE, "set %s key creation context to %s",
- (const char *)username, user_context);
+ username, user_context);
}
#endif
freecon(user_context);
Only in Linux-PAM-0.99.6.2/modules/pam_selinux: pam_selinux.c.config_role