コード例 #1
0
ファイル: utils.c プロジェクト: JJediny/bubblewrap
void
die_unless_label_valid (const char *label)
{
#ifdef HAVE_SELINUX
  if (is_selinux_enabled () == 1)
    {
      if (security_check_context ((security_context_t) label) < 0)
        die_with_error ("invalid label %s", label);
      return;
    }
#endif
  die ("labeling not supported on this system");
}
コード例 #2
0
static int get_failsafe_context(const char *user, security_context_t * newcon)
{
	FILE *fp;
	char buf[255], *ptr;
	size_t plen, nlen;
	int rc;

	fp = fopen(selinux_failsafe_context_path(), "r");
	if (!fp)
		return -1;

	ptr = fgets_unlocked(buf, sizeof buf, fp);
	fclose(fp);

	if (!ptr)
		return -1;
	plen = strlen(ptr);
	if (buf[plen - 1] == '\n')
		buf[plen - 1] = 0;

      retry:
	nlen = strlen(user) + 1 + plen + 1;
	*newcon = malloc(nlen);
	if (!(*newcon))
		return -1;
	rc = snprintf(*newcon, nlen, "%s:%s", user, ptr);
	if (rc < 0 || (size_t) rc >= nlen) {
		free(*newcon);
		*newcon = 0;
		return -1;
	}

	/* If possible, check the context to catch
	   errors early rather than waiting until the
	   caller tries to use setexeccon on the context.
	   But this may not always be possible, e.g. if
	   selinuxfs isn't mounted. */
	if (security_check_context(*newcon) && errno != ENOENT) {
		free(*newcon);
		*newcon = 0;
		if (strcmp(user, SELINUX_DEFAULTUSER)) {
			user = SELINUX_DEFAULTUSER;
			goto retry;
		}
		return -1;
	}

	return 0;
}
コード例 #3
0
ファイル: runcon.c プロジェクト: nhanh0/hah
int runcon_main(int argc UNUSED_PARAM, char **argv)
{
    char *role = NULL;
    char *range = NULL;
    char *user = NULL;
    char *type = NULL;
    char *context = NULL;
    unsigned opts;
    context_t con;

    selinux_or_die();

#if ENABLE_FEATURE_RUNCON_LONG_OPTIONS
    applet_long_options = runcon_longopts;
#endif
    opt_complementary = "-1";
    opts = getopt32(argv, "r:t:u:l:ch", &role, &type, &user, &range);
    argv += optind;

    if (!(opts & OPTS_CONTEXT_COMPONENT)) {
        context = *argv++;
        if (!argv[0])
            bb_error_msg_and_die("no command given");
    }

    if (context) {
        con = context_new(context);
        if (!con)
            bb_error_msg_and_die("'%s' is not a valid context", context);
    } else {
        con = runcon_compute_new_context(user, role, type, range,
                                         argv[0], opts & OPTS_COMPUTE);
    }

    if (security_check_context(context_str(con)))
        bb_error_msg_and_die("'%s' is not a valid context",
                             context_str(con));

    if (setexeccon(context_str(con)))
        bb_error_msg_and_die("cannot set up security context '%s'",
                             context_str(con));

    execvp(argv[0], argv);

    bb_perror_msg_and_die("cannot execute '%s'", argv[0]);
}
コード例 #4
0
ファイル: runcon.c プロジェクト: nawawi/busybox
int runcon_main(int argc UNUSED_PARAM, char **argv)
{
	char *role = NULL;
	char *range = NULL;
	char *user = NULL;
	char *type = NULL;
	char *context = NULL;
	unsigned opts;
	context_t con;

	selinux_or_die();

	opts = getopt32long(argv, "^"
			"r:t:u:l:ch"
			"\0" "-1",
			runcon_longopts,
			&role, &type, &user, &range
	);
	argv += optind;

	if (!(opts & OPTS_CONTEXT_COMPONENT)) {
		context = *argv++;
		if (!argv[0])
			bb_error_msg_and_die("no command given");
	}

	if (context) {
		con = context_new(context);
		if (!con)
			bb_error_msg_and_die("'%s' is not a valid context", context);
	} else {
		con = runcon_compute_new_context(user, role, type, range,
				argv[0], opts & OPTS_COMPUTE);
	}

	if (security_check_context(context_str(con)))
		bb_error_msg_and_die("'%s' is not a valid context",
				context_str(con));

	if (setexeccon(context_str(con)))
		bb_error_msg_and_die("can't set up security context '%s'",
				context_str(con));

	BB_EXECVP_or_die(argv);
}
コード例 #5
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;
}
コード例 #6
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;  
}
コード例 #7
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;
}
コード例 #8
0
ファイル: selinux.c プロジェクト: radosroka/sudo
/*
 * Returns a new security context based on the old context and the
 * specified role and type.
 */
security_context_t
get_exec_context(security_context_t old_context, const char *role, const char *type)
{
    security_context_t new_context = NULL;
    context_t context = NULL;
    char *typebuf = NULL;
    debug_decl(get_exec_context, SUDO_DEBUG_SELINUX)
    
    /* We must have a role, the type is optional (we can use the default). */
    if (!role) {
	sudo_warnx(U_("you must specify a role for type %s"), type);
	errno = EINVAL;
	goto bad;
    }
    if (!type) {
	if (get_default_type(role, &typebuf)) {
	    sudo_warnx(U_("unable to get default type for role %s"), role);
	    errno = EINVAL;
	    goto bad;
	}
	type = typebuf;
    }
    
    /* 
     * Expand old_context into a context_t so that we extract and modify 
     * its components easily. 
     */
    context = context_new(old_context);
    
    /*
     * Replace the role and type in "context" with the role and
     * type we will be running the command as.
     */
    if (context_role_set(context, role)) {
	sudo_warn(U_("failed to set new role %s"), role);
	goto bad;
    }
    if (context_type_set(context, type)) {
	sudo_warn(U_("failed to set new type %s"), type);
	goto bad;
    }
      
    /*
     * Convert "context" back into a string and verify it.
     */
    if ((new_context = strdup(context_str(context))) == NULL) {
	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
	goto bad;
    }
    if (security_check_context(new_context) < 0) {
	sudo_warnx(U_("%s is not a valid context"), new_context);
	errno = EINVAL;
	goto bad;
    }

#ifdef DEBUG
    sudo_warnx("Your new context is %s", new_context);
#endif

    context_free(context);
    debug_return_ptr(new_context);

bad:
    free(typebuf);
    context_free(context);
    freecon(new_context);
    debug_return_ptr(NULL);
}
コード例 #9
0
ファイル: selinux.c プロジェクト: aosm/sudo
/*
 * Returns a new security context based on the old context and the
 * specified role and type.
 */
security_context_t
get_exec_context(security_context_t old_context, const char *role, const char *type)
{
    security_context_t new_context = NULL;
    context_t context = NULL;
    char *typebuf = NULL;
    
    /* We must have a role, the type is optional (we can use the default). */
    if (!role) {
	warningx("you must specify a role for type %s", type);
	errno = EINVAL;
	return NULL;
    }
    if (!type) {
	if (get_default_type(role, &typebuf)) {
	    warningx("unable to get default type for role %s", role);
	    errno = EINVAL;
	    return NULL;
	}
	type = typebuf;
    }
    
    /* 
     * Expand old_context into a context_t so that we extract and modify 
     * its components easily. 
     */
    context = context_new(old_context);
    
    /*
     * Replace the role and type in "context" with the role and
     * type we will be running the command as.
     */
    if (context_role_set(context, role)) {
	warning("failed to set new role %s", role);
	goto bad;
    }
    if (context_type_set(context, type)) {
	warning("failed to set new type %s", type);
	goto bad;
    }
      
    /*
     * Convert "context" back into a string and verify it.
     */
    new_context = estrdup(context_str(context));
    if (security_check_context(new_context) < 0) {
	warningx("%s is not a valid context", new_context);
	errno = EINVAL;
	goto bad;
    }

#ifdef DEBUG
    warningx("Your new context is %s", new_context);
#endif

    context_free(context);
    return new_context;

bad:
    free(typebuf);
    context_free(context);
    freecon(new_context);
    return NULL;
}