On Mon, 2006-10-30 at 15:16 -0500, James Antill wrote:
> On Mon, 2006-10-30 at 15:03 -0500, James Antill wrote:
> > On Fri, 2006-10-27 at 14:38 -0400, Stephen Smalley wrote:
> > 
> > > Look at Darrel's patch for mcstransd to apply a permission check between
> > > the level of the caller and the level being translated for context
> > > translations. 
> > 
> >  Thanks to much discussion with Dan and Stephen, I'm pretty sure I have
> > this correct now.


 Here is the PAM part of the patches (libselinux and reference policy
came previously). This requires the libselinux changes.

-- 
James Antill <[EMAIL PROTECTED]>
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-27 12:49:05.000000000 -0400
@@ -36,6 +36,9 @@
       <arg choice="opt">
 	verbose
       </arg>
+      <arg choice="opt">
+	config_role
+      </arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -121,6 +124,17 @@
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>config_role</option>
+        </term>
+        <listitem>
+          <para>
+            attempt to ask the user for a custom security context role (and
+            level, if MLS is on).
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
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-30 15:20:28.000000000 -0500
@@ -63,6 +63,7 @@
 #include <selinux/selinux.h>
 #include <selinux/get_context_list.h>
 #include <selinux/flask.h>
+#include <selinux/av_permissions.h>
 #include <selinux/selinux.h>
 #include <selinux/context.h>
 
@@ -151,6 +152,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 +164,90 @@ manual_context (pam_handle_t *pamh, cons
   return NULL;
 }
 
+static int mls_range_allowed(security_context_t src, security_context_t dst)
+{
+  struct av_decision avd;
+  int retval;
+  int bit = CONTEXT__TRANSITION;
+  
+  retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd);
+  if (retval || ((bit & avd.allowed) != bit))
+    return 0;
+  
+  return 1;
+}
+
+static security_context_t
+config_context (pam_handle_t *pamh, 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;
+  
+  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);
+	  }
+
+        /* Get the string value of the context and see if it is valid. */
+        if (!security_check_context(context_str(new_context))) {
+	  newcon = strdup(context_str(new_context));
+	  context_free (new_context);
+
+          /* we have to check that this user is allowed to go into the
+             range they have specified ... role is tied to an seuser, so that'll
+             be checked at setexeccon time */
+          if (mls_enabled && !mls_range_allowed(puser_context, newcon))
+            goto fail_range;
+
+          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:
+  _pam_drop(responses);
+ fail_range:
+  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 +360,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 +384,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 +402,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 +415,32 @@ 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]);
+
+    if (config_role && has_tty) {
+      user_context = config_context(pamh, 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;
+      }
+    }
+    
     freeconary(contextlist);
   } 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 +449,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 +490,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 +498,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 +511,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 +519,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

Attachment: signature.asc
Description: This is a digitally signed message part

--
redhat-lspp mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-lspp

Reply via email to