busybox/selinux/runcon.c
Denys Vlasenko f560422fa0 Big cleanup in config help and description
Redundant help texts (one which only repeats the description)
are deleted.

Descriptions and help texts are trimmed.

Some config options are moved, even across menus.

No config option _names_ are changed.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-01-10 14:58:54 +01:00

175 lines
5.3 KiB
C

/*
* runcon [ context |
* ( [ -c ] [ -r role ] [-t type] [ -u user ] [ -l levelrange ] )
* command [arg1 [arg2 ...] ]
*
* attempt to run the specified command with the specified context.
*
* -r role : use the current context with the specified role
* -t type : use the current context with the specified type
* -u user : use the current context with the specified user
* -l level : use the current context with the specified level range
* -c : compute process transition context before modifying
*
* Contexts are interpreted as follows:
*
* Number of MLS
* components system?
*
* 1 - type
* 2 - role:type
* 3 Y role:type:range
* 3 N user:role:type
* 4 Y user:role:type:range
* 4 N error
*
* Port to busybox: KaiGai Kohei <kaigai@kaigai.gr.jp>
* - based on coreutils-5.97 (in Fedora Core 6)
*
* Licensed under GPLv2, see file LICENSE in this source tree.
*/
//config:config RUNCON
//config: bool "runcon"
//config: default n
//config: depends on SELINUX
//config: help
//config: Enable support to run command in specified security context.
//config:
//config:config FEATURE_RUNCON_LONG_OPTIONS
//config: bool "Enable long options"
//config: default y
//config: depends on RUNCON && LONG_OPTS
//applet:IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP))
//kbuild:lib-$(CONFIG_RUNCON) += runcon.o
//usage:#define runcon_trivial_usage
//usage: "[-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] PROG ARGS\n"
//usage: "runcon CONTEXT PROG ARGS"
//usage:#define runcon_full_usage "\n\n"
//usage: "Run PROG in a different security context\n"
//usage: "\n CONTEXT Complete security context\n"
//usage: IF_FEATURE_RUNCON_LONG_OPTIONS(
//usage: "\n -c,--compute Compute process transition context before modifying"
//usage: "\n -t,--type=TYPE Type (for same role as parent)"
//usage: "\n -u,--user=USER User identity"
//usage: "\n -r,--role=ROLE Role"
//usage: "\n -l,--range=RNG Levelrange"
//usage: )
//usage: IF_NOT_FEATURE_RUNCON_LONG_OPTIONS(
//usage: "\n -c Compute process transition context before modifying"
//usage: "\n -t TYPE Type (for same role as parent)"
//usage: "\n -u USER User identity"
//usage: "\n -r ROLE Role"
//usage: "\n -l RNG Levelrange"
//usage: )
#include <selinux/context.h>
/* from deprecated <selinux/flask.h>: */
#undef SECCLASS_PROCESS
#define SECCLASS_PROCESS 2
#include "libbb.h"
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;
}
#if ENABLE_FEATURE_RUNCON_LONG_OPTIONS
static const char runcon_longopts[] ALIGN1 =
"user\0" Required_argument "u"
"role\0" Required_argument "r"
"type\0" Required_argument "t"
"range\0" Required_argument "l"
"compute\0" No_argument "c"
"help\0" No_argument "h"
;
#endif
#define OPTS_ROLE (1<<0) /* r */
#define OPTS_TYPE (1<<1) /* t */
#define OPTS_USER (1<<2) /* u */
#define OPTS_RANGE (1<<3) /* l */
#define OPTS_COMPUTE (1<<4) /* c */
#define OPTS_HELP (1<<5) /* h */
#define OPTS_CONTEXT_COMPONENT (OPTS_ROLE | OPTS_TYPE | OPTS_USER | OPTS_RANGE)
int runcon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
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("can't set up security context '%s'",
context_str(con));
BB_EXECVP_or_die(argv);
}