Exemplo n.º 1
0
static context_t runcon_compute_new_context(char *user, char *role, char *type, char *range,
			char *command, int compute_trans)
{
	context_t con;
	security_context_t cur_context;

	if (getcon(&cur_context))
		bb_error_msg_and_die("can't get current context");

	if (compute_trans) {
		security_context_t file_context, new_context;

		if (getfilecon(command, &file_context) < 0)
			bb_error_msg_and_die("can't retrieve attributes of '%s'",
					command);
		if (security_compute_create(cur_context, file_context,
					SECCLASS_PROCESS, &new_context))
			bb_error_msg_and_die("unable to compute a new context");
		cur_context = new_context;
	}

	con = context_new(cur_context);
	if (!con)
		bb_error_msg_and_die("'%s' is not a valid context", cur_context);
	if (user && context_user_set(con, user))
		bb_error_msg_and_die("can't set new user '%s'", user);
	if (type && context_type_set(con, type))
		bb_error_msg_and_die("can't set new type '%s'", type);
	if (range && context_range_set(con, range))
		bb_error_msg_and_die("can't set new range '%s'", range);
	if (role && context_role_set(con, role))
		bb_error_msg_and_die("can't set new role '%s'", role);

	return con;
}
Exemplo n.º 2
0
static int check_dominance(const char *pattern, const char *raw) {
	security_context_t ctx;
	context_t con;
	struct av_decision avd;
	int rc = -1;
	context_t my_tmp;
	const char *raw_range;
	security_class_t context_class = string_to_security_class("context");
	access_vector_t context_contains_perm = string_to_av_perm(context_class, "contains");

	con = context_new(raw);
	if (!con)
		return -1;
	raw_range = context_range_get(con);

	my_tmp = context_new(my_context);
	if (!my_tmp) {
		context_free(con);
		return -1;
	}

	ctx = NULL;
	if (context_range_set(my_tmp, pattern))
		goto out;
	ctx = strdup(context_str(my_tmp));
	if (!ctx)
		goto out;

	if (context_range_set(my_tmp, raw_range))
		goto out;
	raw = context_str(my_tmp);
	if (!raw)
		goto out;

	rc = security_compute_av_raw(ctx, (security_context_t)raw, context_class, context_contains_perm, &avd);
	if (rc)
		goto out;

	rc = (context_contains_perm & avd.allowed) != context_contains_perm;
out:
	free(ctx);
	context_free(my_tmp);
	context_free(con);
	return rc;
}
Exemplo n.º 3
0
static int set_context_from_socket( const struct service_config *scp, int fd )
{
   security_context_t curr_context = NULL;
   security_context_t peer_context = NULL;
   security_context_t exec_context = NULL;
   context_t bcon = NULL;
   context_t pcon = NULL;
   security_context_t new_context = NULL;
   security_context_t new_exec_context = NULL;
   int retval = -1;
   const char *exepath = NULL;

   if (getcon(&curr_context) < 0)
     goto fail;
   
   if (getpeercon(fd, &peer_context) < 0)
     goto fail;

   exepath = SC_SERVER_ARGV( scp )[0];
   if (getfilecon(exepath, &exec_context) < 0)
     goto fail;

   if (!(bcon = context_new(curr_context)))
     goto fail;

   if (!(pcon = context_new(peer_context)))
     goto fail;

   if (!context_range_get(pcon))
     goto fail;
   
   if (context_range_set(bcon, context_range_get(pcon)))
     goto fail;

   if (!(new_context = context_str(bcon)))
     goto fail;
   
   if (security_compute_create(new_context, exec_context, SECCLASS_PROCESS,
                               &new_exec_context) < 0)
     goto fail;

   retval = set_context(new_exec_context);

   freecon(new_exec_context);

 fail:
   context_free(pcon);
   context_free(bcon);
   freecon(exec_context);   
   freecon(peer_context);
   freecon(curr_context);

   return retval;
}
Exemplo n.º 4
0
/*  Set the context of all files associated with this VM to the new context
 *  complete with the unique generated category.
 */
static int
file_con_fixup (data_t *data)
{
        security_context_t sec_con = { 0, };
        context_t con = { 0, };
        char mcs_str[9] = { 0, };
        int ret = 0, p_ret = 0, i = 0;;
        
        p_ret = snprintf (mcs_str, sizeof (mcs_str), "s0:c%d", data->category);
        if (p_ret < 0 || p_ret > 9) {
                syslog (LOG_CRIT, "insufficient buffer size");
                return -1;
        }
        for (i = 0; data->files [i] != NULL; ++i) {
                if (getfilecon (data->files [i], &sec_con) == -1) {
                        syslog (LOG_CRIT,
                                "error getting context from file: %s, error %s",
                                data->files [i], strerror (errno));
                        continue;
                }
                con = context_new (sec_con);
                if (con == NULL) {
                        syslog (LOG_CRIT, 
                                "Error creating new context from string: %s",
                                sec_con);
                        ret = -1;
                        goto err_freecon;
                }
                if (context_range_set (con, mcs_str) == -1) {
                        syslog (LOG_CRIT, 
                                "Error setting context range to %s, "
                                "error: %s", mcs_str, strerror (errno));
                        ret = -1;
                        goto err_confree;
                }
                syslog (LOG_INFO, "Setting context for file %s to %s",
                        data->files [i], context_str (con));
                ret = setfilecon (data->files [i], context_str (con));
                if (ret != 0)
                        syslog (LOG_CRIT, "setfilecon error:%s",
                                strerror (errno));
                context_free (con);
                freecon (sec_con);
        }
        return ret;

 err_confree:
        context_free (con);
 err_freecon:
        freecon (sec_con);
        return ret;
}
Exemplo n.º 5
0
static char *
SELinuxGenNewContext(const char *oldcontext, const char *mcs)
{
    char *newcontext = NULL;
    char *scontext = strdup(oldcontext);
    context_t con;
    if (!scontext) goto err;
    con = context_new(scontext);
    if (!con) goto err;
    context_range_set(con, mcs);
    newcontext = strdup(context_str(con));
    context_free(con);
err:
    freecon(scontext);
    return newcontext;
}
Exemplo n.º 6
0
int get_default_context_with_rolelevel(const char *user,
				       const char *role,
				       const char *level,
				       security_context_t fromcon,
				       security_context_t * newcon)
{

	int rc = 0;
	int freefrom = 0;
	context_t con;
	char *newfromcon;
	if (!level)
		return get_default_context_with_role(user, role, fromcon,
						     newcon);

	if (!fromcon) {
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	rc = -1;
	con = context_new(fromcon);
	if (!con)
		goto out;

	if (context_range_set(con, level))
		goto out;

	newfromcon = context_str(con);
	if (!newfromcon)
		goto out;

	rc = get_default_context_with_role(user, role, newfromcon, newcon);

      out:
	context_free(con);
	if (freefrom)
		freecon(fromcon);
	return rc;

}
Exemplo n.º 7
0
static int mls_range_allowed(pam_handle_t *pamh, security_context_t src, security_context_t dst, int debug)
{
  struct av_decision avd;
  int retval;
  unsigned int bit = CONTEXT__CONTAINS;
  context_t src_context = context_new (src);
  context_t dst_context = context_new (dst);
  context_range_set(dst_context, context_range_get(src_context));
  if (debug)
    pam_syslog(pamh, LOG_NOTICE, "Checking if %s mls range valid for  %s", dst, context_str(dst_context));

  retval = security_compute_av(context_str(dst_context), dst, SECCLASS_CONTEXT, bit, &avd);
  context_free(src_context);
  context_free(dst_context);
  if (retval || ((bit & avd.allowed) != bit))
    return 0;
  
  return 1;
}
Exemplo n.º 8
0
/*  Basic function to build string representation of context from
 *  user:role:type component and sensitivity:category.
 *  Returned string must be free'd by caller.
 */
static char*
create_context (char *oldcontext, char *mcs)
{
        char *newcontext = NULL, *scontext = NULL;
        context_t con = { 0, };

        scontext = strdup(oldcontext);
        if (!scontext)
                return scontext;
        con = context_new(scontext);
        if (!con) {
                perror ("context_new");
                return NULL;
        }

        context_range_set(con, mcs);
        newcontext = strdup(context_str(con));
        context_free(con);
        return (newcontext);
}
Exemplo n.º 9
0
static context_t compute_context_from_mask(security_context_t context, unsigned long opts)
{
	context_t new_context = context_new(context);
	if (!new_context)
		return NULL;

	if ((opts & OPT_CHCON_USER) && context_user_set(new_context, user))
		goto error;
	if ((opts & OPT_CHCON_RANGE) && context_range_set(new_context, range))
		goto error;
	if ((opts & OPT_CHCON_ROLE) && context_role_set(new_context, role))
		goto error;
	if ((opts & OPT_CHCON_TYPE) && context_type_set(new_context, type))
		goto error;

	return new_context;
error:
	context_free (new_context);
	return NULL;
}
context_t FAST_FUNC set_security_context_component(security_context_t cur_context,
					 char *user, char *role, char *type, char *range)
{
	context_t con = context_new(cur_context);
	if (!con)
		return NULL;

	if (user && context_user_set(con, user))
		goto error;
	if (type && context_type_set(con, type))
		goto error;
	if (range && context_range_set(con, range))
		goto error;
	if (role && context_role_set(con, role))
		goto error;
	return con;

error:
	context_free(con);
	return NULL;
}
Exemplo n.º 11
0
int get_ordered_context_list_with_level(const char *user,
					const char *level,
					security_context_t fromcon,
					security_context_t ** list)
{
	int rc;
	int freefrom = 0;
	context_t con;
	char *newfromcon;

	if (!level)
		return get_ordered_context_list(user, fromcon, list);

	if (!fromcon) {
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	rc = -1;
	con = context_new(fromcon);
	if (!con)
		goto out;

	if (context_range_set(con, level))
		goto out;

	newfromcon = context_str(con);
	if (!newfromcon)
		goto out;

	rc = get_ordered_context_list(user, newfromcon, list);

      out:
	context_free(con);
	if (freefrom)
		freecon(fromcon);
	return rc;
}
Exemplo n.º 12
0
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label) {
        int r = -EOPNOTSUPP;

#ifdef HAVE_SELINUX
        _cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL;
        _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
        security_class_t sclass;
        const char *range = NULL;

        assert(socket_fd >= 0);
        assert(exe);
        assert(label);

        if (!mac_selinux_have())
                return -EOPNOTSUPP;

        r = getcon_raw(&mycon);
        if (r < 0)
                return -errno;

        r = getpeercon_raw(socket_fd, &peercon);
        if (r < 0)
                return -errno;

        if (!exec_label) {
                /* If there is no context set for next exec let's use context
                   of target executable */
                r = getfilecon_raw(exe, &fcon);
                if (r < 0)
                        return -errno;
        }

        bcon = context_new(mycon);
        if (!bcon)
                return -ENOMEM;

        pcon = context_new(peercon);
        if (!pcon)
                return -ENOMEM;

        range = context_range_get(pcon);
        if (!range)
                return -errno;

        r = context_range_set(bcon, range);
        if (r)
                return -errno;

        freecon(mycon);
        mycon = strdup(context_str(bcon));
        if (!mycon)
                return -ENOMEM;

        sclass = string_to_security_class("process");
        r = security_compute_create_raw(mycon, fcon, sclass, label);
        if (r < 0)
                return -errno;
#endif

        return r;
}
Exemplo n.º 13
0
/*
 * do_set_domain
 *   It tries to replace the domain/range of the current context.
 */
static int
do_set_domain(security_context_t old_context, char *domain, server_rec *s)
{
    security_context_t  new_context;
    security_context_t  raw_context;
    context_t           context;
    char               *range;

    /*
     * Compute the new security context
     */
    context = context_new(old_context);
    if (!context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_new(\"%s\") failed",
                     old_context);
        return -1;
    }

    range = strchr(domain, ':');
    if (range)
        *range++ = '\0';

    if (domain && strcmp(domain, "*") != 0)
        context_type_set(context, domain);
    if (range  && strcmp(range, "*") != 0)
        context_range_set(context, range);

    if (range)
        *--range = ':';     /* fixup */

    new_context = context_str(context);
    if (!new_context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_str(\"%s:%s:%s:%s\") failed",
                     context_user_get(context),
                     context_role_get(context),
                     context_type_get(context),
                     context_range_get(context));
        context_free(context);
        return -1;
    }

    /*
     * If old_context == new_context, we don't need to do anything
     */
    if (selinux_trans_to_raw_context(new_context, &raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: selinux_trans_to_raw_context(\"%s\") failed",
                     new_context);
        context_free(context);
        return -1;
    }
    context_free(context);

    if (!strcmp(old_context, raw_context)) {
        freecon(raw_context);
        return 1;
    }

    if (setcon_raw(raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: setcon_raw(\"%s\") failed",
                     raw_context);
        freecon(raw_context);
        return -1;
    }

    freecon(raw_context);

    return 0;
}
Exemplo n.º 14
0
static security_context_t
config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
{
  security_context_t newcon=NULL;
  context_t new_context;
  int mls_enabled = is_selinux_mls_enabled();
  char *response=NULL;
  char *type=NULL;
  char resp_val = 0;

  pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), defaultcon);

  while (1) {
    if (query_response(pamh,
		   _("Would you like to enter a different role or level?"), "n", 
		   &response, debug) == PAM_SUCCESS) {
	resp_val = response[0];
	_pam_drop(response);
    } else {
	resp_val = 'N';
    }
    if ((resp_val == 'y') || (resp_val == 'Y'))
      {
        if ((new_context = context_new(defaultcon)) == NULL)
    	    goto fail_set;

	/* Allow the user to enter role and level individually */
	if (query_response(pamh, _("role:"), context_role_get(new_context), 
		       &response, debug) == PAM_SUCCESS && response[0]) {
	  if (get_default_type(response, &type)) {
	    pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), response);
	    _pam_drop(response);
	    continue;
	  } else {
	    if (context_role_set(new_context, response)) 
	      goto fail_set;
	    if (context_type_set (new_context, type))
	      goto fail_set;
	  } 
	}
	_pam_drop(response);

	if (mls_enabled)
	  {
	    if (use_current_range) {
	        security_context_t mycon = NULL;
	        context_t my_context;

		if (getcon(&mycon) != 0)
		    goto fail_set;
    		my_context = context_new(mycon);
	        if (my_context == NULL) {
    		    freecon(mycon);
		    goto fail_set;
		}
		freecon(mycon);
		if (context_range_set(new_context, context_range_get(my_context))) {
		    context_free(my_context);
		    goto fail_set;
		}
		context_free(my_context);
	    } else if (query_response(pamh, _("level:"), context_range_get(new_context), 
			   &response, debug) == PAM_SUCCESS && response[0]) {
		if (context_range_set(new_context, response))
		    goto fail_set;
	    } 
	    _pam_drop(response);
	  }

	if (debug)
	  pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));

        /* 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));
	  if (newcon == NULL)
	    goto fail_set;
	  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(pamh, defaultcon, newcon, debug)) {
	    pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);

    	    send_audit_message(pamh, 0, defaultcon, newcon);

	    free(newcon);
            goto fail_range;
	  }
	  return newcon;
	}
	else {
	  send_audit_message(pamh, 0, defaultcon, context_str(new_context));
	  send_text(pamh,_("Not a valid security context"),debug);
	}
        context_free(new_context); /* next time around allocates another */
      }
    else
      return strdup(defaultcon);
  } /* end while */

  return NULL;

 fail_set:
  free(type);
  _pam_drop(response);
  context_free (new_context);
  send_audit_message(pamh, 0, defaultcon, NULL);
 fail_range:
  return NULL;  
}
Exemplo n.º 15
0
static security_context_t
manual_context (pam_handle_t *pamh, const char *user, int debug)
{
  security_context_t newcon=NULL;
  context_t new_context;
  int mls_enabled = is_selinux_mls_enabled();
  char *type=NULL;
  char *response=NULL;

  while (1) {
    if (query_response(pamh,
		   _("Would you like to enter a security context? [N] "), NULL,
		   &response, debug) != PAM_SUCCESS)
	return NULL;

    if ((response[0] == 'y') || (response[0] == 'Y'))
      {
	if (mls_enabled)
	  new_context = context_new ("user:role:type:level");
	else
	  new_context = context_new ("user:role:type");

	if (!new_context)
              goto fail_set;

	if (context_user_set (new_context, user))
              goto fail_set;

	_pam_drop(response);
	/* Allow the user to enter each field of the context individually */
	if (query_response(pamh, _("role:"), NULL, &response, debug) == PAM_SUCCESS &&
	    response[0] != '\0') {
	   if (context_role_set (new_context, response)) 
              goto fail_set;
	   if (get_default_type(response, &type)) 
              goto fail_set;
	   if (context_type_set (new_context, type)) 
              goto fail_set;
	}
	_pam_drop(response);

	if (mls_enabled)
	  {
	    if (query_response(pamh, _("level:"), NULL, &response, debug) == PAM_SUCCESS &&
		response[0] != '\0') {
	      if (context_range_set (new_context, response))
		goto fail_set;
	    }
	    _pam_drop(response);
	  }

	/* 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);
	  return newcon;
	}
	else
	  send_text(pamh,_("Not a valid security context"),debug);

        context_free (new_context);
      }
    else {
      _pam_drop(response);
      return NULL;
    }
  } /* end while */
 fail_set:
  free(type);
  _pam_drop(response);
  context_free (new_context);
  return NULL;
}
Exemplo n.º 16
0
static int seapp_context_lookup(enum seapp_kind kind,
				uid_t uid,
				int isSystemServer,
				const char *seinfo,
				const char *pkgname,
				const char *path,
				context_t ctx)
{
	const char *username = NULL;
	struct seapp_context *cur = NULL;
	int i;
	size_t n;
	uid_t userid;
	uid_t appid;

	__selinux_once(once, seapp_context_init);

	userid = uid / AID_USER;
	appid = uid % AID_USER;
	if (appid < AID_APP) {
		for (n = 0; n < android_id_count; n++) {
			if (android_ids[n].aid == appid) {
				username = android_ids[n].name;
				break;
			}
		}
		if (!username)
			goto err;
	} else if (appid < AID_ISOLATED_START) {
		username = "******";
		appid -= AID_APP;
	} else {
		username = "******";
		appid -= AID_ISOLATED_START;
	}

	if (appid >= CAT_MAPPING_MAX_ID || userid >= CAT_MAPPING_MAX_ID)
		goto err;

	for (i = 0; i < nspec; i++) {
		cur = seapp_contexts[i];

		if (cur->isSystemServer != isSystemServer)
			continue;

		if (cur->user.str) {
			if (cur->user.is_prefix) {
				if (strncasecmp(username, cur->user.str, cur->user.len-1))
					continue;
			} else {
				if (strcasecmp(username, cur->user.str))
					continue;
			}
		}

		if (cur->seinfo) {
			if (!seinfo || strcasecmp(seinfo, cur->seinfo))
				continue;
		}

		if (cur->name.str) {
			if(!pkgname)
				continue;

			if (cur->name.is_prefix) {
				if (strncasecmp(pkgname, cur->name.str, cur->name.len-1))
					continue;
			} else {
				if (strcasecmp(pkgname, cur->name.str))
					continue;
			}
		}

		if (cur->path.str) {
			if (!path)
				continue;

			if (cur->path.is_prefix) {
				if (strncmp(path, cur->path.str, cur->path.len-1))
					continue;
			} else {
				if (strcmp(path, cur->path.str))
					continue;
			}
		}

		if (kind == SEAPP_TYPE && !cur->type)
			continue;
		else if (kind == SEAPP_DOMAIN && !cur->domain)
			continue;

		if (cur->sebool) {
			int value = security_get_boolean_active(cur->sebool);
			if (value == 0)
				continue;
			else if (value == -1) {
				selinux_log(SELINUX_ERROR, \
				"Could not find boolean: %s ", cur->sebool);
				goto err;
			}
		}

		if (kind == SEAPP_TYPE) {
			if (context_type_set(ctx, cur->type))
				goto oom;
		} else if (kind == SEAPP_DOMAIN) {
			if (context_type_set(ctx, cur->domain))
				goto oom;
		}

		if (cur->levelFrom != LEVELFROM_NONE) {
			char level[255];
			switch (cur->levelFrom) {
			case LEVELFROM_APP:
				snprintf(level, sizeof level, "s0:c%u,c%u",
					 appid & 0xff,
					 256 + (appid>>8 & 0xff));
				break;
			case LEVELFROM_USER:
				snprintf(level, sizeof level, "s0:c%u,c%u",
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			case LEVELFROM_ALL:
				snprintf(level, sizeof level, "s0:c%u,c%u,c%u,c%u",
					 appid & 0xff,
					 256 + (appid>>8 & 0xff),
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			default:
				goto err;
			}
			if (context_range_set(ctx, level))
				goto oom;
		} else if (cur->level) {
Exemplo n.º 17
0
static security_context_t
context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_params, int use_current_range, int debug)
{
  security_context_t newcon = NULL;
  context_t new_context;
  context_t my_context = NULL;
  int mls_enabled = is_selinux_mls_enabled();
  const char *env = NULL;
  char *type = NULL;

  if ((new_context = context_new(defaultcon)) == NULL)
    goto fail_set;

  if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') {
    if (debug)
	pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env);

    if (get_default_type(env, &type)) {
	pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env);
	goto fail_set;
    } else {
	if (context_role_set(new_context, env)) 
	    goto fail_set;
	if (context_type_set(new_context, type))
	    goto fail_set;
    }
  }

  if (mls_enabled) {
    if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') {
        if (debug)
	    pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set");
	use_current_range = 1;
    }

    if (use_current_range) {
        security_context_t mycon = NULL;

	if (getcon(&mycon) != 0)
	    goto fail_set;
        my_context = context_new(mycon);
        if (my_context == NULL) {
            freecon(mycon);
	    goto fail_set;
	}
	freecon(mycon);
	env = context_range_get(my_context);
    } else {
        env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED");
    }

    if (env != NULL && env[0] != '\0') {
        if (debug)
	    pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env);
	if (context_range_set(new_context, env))
	    goto fail_set;
    }
  }

  newcon = strdup(context_str(new_context));
  if (newcon == NULL)
    goto fail_set;

  if (debug)
    pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon);
  
  /* Get the string value of the context and see if it is valid. */
  if (security_check_context(newcon)) {
    pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon);
    send_audit_message(pamh, 0, defaultcon, newcon);
    freecon(newcon);
    newcon = NULL;

    goto fail_set;
  }

  /* 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(pamh, defaultcon, newcon, debug)) {
    pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
    send_audit_message(pamh, 0, defaultcon, newcon);
    freecon(newcon);
    newcon = NULL;
  }

 fail_set:
  free(type);
  context_free(my_context);
  context_free(new_context);
  send_audit_message(pamh, 0, defaultcon, NULL);
  return newcon;
}