source: branches/3.2/mindi-busybox/selinux/runcon.c @ 3232

Last change on this file since 3232 was 3232, checked in by Bruno Cornec, 7 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/*
2 * runcon [ context |
3 *         ( [ -c ] [ -r role ] [-t type] [ -u user ] [ -l levelrange ] )
4 *         command [arg1 [arg2 ...] ]
5 *
6 * attempt to run the specified command with the specified context.
7 *
8 * -r role  : use the current context with the specified role
9 * -t type  : use the current context with the specified type
10 * -u user  : use the current context with the specified user
11 * -l level : use the current context with the specified level range
12 * -c       : compute process transition context before modifying
13 *
14 * Contexts are interpreted as follows:
15 *
16 * Number of       MLS
17 * components    system?
18 *
19 *     1            -         type
20 *     2            -         role:type
21 *     3            Y         role:type:range
22 *     3            N         user:role:type
23 *     4            Y         user:role:type:range
24 *     4            N         error
25 *
26 * Port to busybox: KaiGai Kohei <kaigai@kaigai.gr.jp>
27 *                  - based on coreutils-5.97 (in Fedora Core 6)
28 *
29 * Licensed under GPLv2, see file LICENSE in this source tree.
30 */
31
32//usage:#define runcon_trivial_usage
33//usage:       "[-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] PROG ARGS\n"
34//usage:       "runcon CONTEXT PROG ARGS"
35//usage:#define runcon_full_usage "\n\n"
36//usage:       "Run PROG in a different security context\n"
37//usage:     "\n    CONTEXT     Complete security context\n"
38//usage:    IF_FEATURE_RUNCON_LONG_OPTIONS(
39//usage:     "\n    -c,--compute    Compute process transition context before modifying"
40//usage:     "\n    -t,--type=TYPE  Type (for same role as parent)"
41//usage:     "\n    -u,--user=USER  User identity"
42//usage:     "\n    -r,--role=ROLE  Role"
43//usage:     "\n    -l,--range=RNG  Levelrange"
44//usage:    )
45//usage:    IF_NOT_FEATURE_RUNCON_LONG_OPTIONS(
46//usage:     "\n    -c  Compute process transition context before modifying"
47//usage:     "\n    -t TYPE Type (for same role as parent)"
48//usage:     "\n    -u USER User identity"
49//usage:     "\n    -r ROLE Role"
50//usage:     "\n    -l RNG  Levelrange"
51//usage:    )
52
53#include <selinux/context.h>
54#include <selinux/flask.h>
55
56#include "libbb.h"
57
58static context_t runcon_compute_new_context(char *user, char *role, char *type, char *range,
59            char *command, int compute_trans)
60{
61    context_t con;
62    security_context_t cur_context;
63
64    if (getcon(&cur_context))
65        bb_error_msg_and_die("can't get current context");
66
67    if (compute_trans) {
68        security_context_t file_context, new_context;
69
70        if (getfilecon(command, &file_context) < 0)
71            bb_error_msg_and_die("can't retrieve attributes of '%s'",
72                    command);
73        if (security_compute_create(cur_context, file_context,
74                    SECCLASS_PROCESS, &new_context))
75            bb_error_msg_and_die("unable to compute a new context");
76        cur_context = new_context;
77    }
78
79    con = context_new(cur_context);
80    if (!con)
81        bb_error_msg_and_die("'%s' is not a valid context", cur_context);
82    if (user && context_user_set(con, user))
83        bb_error_msg_and_die("can't set new user '%s'", user);
84    if (type && context_type_set(con, type))
85        bb_error_msg_and_die("can't set new type '%s'", type);
86    if (range && context_range_set(con, range))
87        bb_error_msg_and_die("can't set new range '%s'", range);
88    if (role && context_role_set(con, role))
89        bb_error_msg_and_die("can't set new role '%s'", role);
90
91    return con;
92}
93
94#if ENABLE_FEATURE_RUNCON_LONG_OPTIONS
95static const char runcon_longopts[] ALIGN1 =
96    "user\0"    Required_argument "u"
97    "role\0"    Required_argument "r"
98    "type\0"    Required_argument "t"
99    "range\0"   Required_argument "l"
100    "compute\0" No_argument "c"
101    "help\0"    No_argument "h"
102    ;
103#endif
104
105#define OPTS_ROLE   (1<<0)  /* r */
106#define OPTS_TYPE   (1<<1)  /* t */
107#define OPTS_USER   (1<<2)  /* u */
108#define OPTS_RANGE  (1<<3)  /* l */
109#define OPTS_COMPUTE    (1<<4)  /* c */
110#define OPTS_HELP   (1<<5)  /* h */
111#define OPTS_CONTEXT_COMPONENT      (OPTS_ROLE | OPTS_TYPE | OPTS_USER | OPTS_RANGE)
112
113int runcon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
114int runcon_main(int argc UNUSED_PARAM, char **argv)
115{
116    char *role = NULL;
117    char *range = NULL;
118    char *user = NULL;
119    char *type = NULL;
120    char *context = NULL;
121    unsigned opts;
122    context_t con;
123
124    selinux_or_die();
125
126#if ENABLE_FEATURE_RUNCON_LONG_OPTIONS
127    applet_long_options = runcon_longopts;
128#endif
129    opt_complementary = "-1";
130    opts = getopt32(argv, "r:t:u:l:ch", &role, &type, &user, &range);
131    argv += optind;
132
133    if (!(opts & OPTS_CONTEXT_COMPONENT)) {
134        context = *argv++;
135        if (!argv[0])
136            bb_error_msg_and_die("no command given");
137    }
138
139    if (context) {
140        con = context_new(context);
141        if (!con)
142            bb_error_msg_and_die("'%s' is not a valid context", context);
143    } else {
144        con = runcon_compute_new_context(user, role, type, range,
145                argv[0], opts & OPTS_COMPUTE);
146    }
147
148    if (security_check_context(context_str(con)))
149        bb_error_msg_and_die("'%s' is not a valid context",
150                context_str(con));
151
152    if (setexeccon(context_str(con)))
153        bb_error_msg_and_die("can't set up security context '%s'",
154                context_str(con));
155
156    BB_EXECVP_or_die(argv);
157}
Note: See TracBrowser for help on using the repository browser.