3 * ( [ -c ] [ -r role ] [-t type] [ -u user ] [ -l levelrange ] )
4 * command [arg1 [arg2 ...] ]
6 * attempt to run the specified command with the specified context.
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
14 * Contexts are interpreted as follows:
23 * 4 Y user:role:type:range
30 #include <selinux/selinux.h>
31 #include <selinux/context.h>
32 #ifdef HAVE_SELINUX_FLASK_H
33 # include <selinux/flask.h>
35 # define SECCLASS_PROCESS 0
37 #include <sys/types.h>
43 /* The official name of this program (e.g., no `g' prefix). */
44 #define PROGRAM_NAME "runcon"
46 #define AUTHORS proper_name ("Russell Coker")
48 static struct option long_options
[] = {
49 {"role", required_argument
, NULL
, 'r'},
50 {"type", required_argument
, NULL
, 't'},
51 {"user", required_argument
, NULL
, 'u'},
52 {"range", required_argument
, NULL
, 'l'},
53 {"compute", no_argument
, NULL
, 'c'},
54 {GETOPT_HELP_OPTION_DECL
},
55 {GETOPT_VERSION_OPTION_DECL
},
59 /* The name the program was run with. */
65 if (status
!= EXIT_SUCCESS
)
66 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
71 Usage: %s CONTEXT COMMAND [args]\n\
72 or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\
73 "), program_name
, program_name
);
75 Run a program in a different security context.\n\
76 With neither CONTEXT nor COMMAND, print the current security context.\n\
78 CONTEXT Complete security context\n\
79 -c, --compute compute process transition context before modifying\n\
80 -t, --type=TYPE type (for same role as parent)\n\
81 -u, --user=USER user identity\n\
82 -r, --role=ROLE role\n\
83 -l, --range=RANGE levelrange\n\
86 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
87 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
88 emit_bug_reporting_address ();
94 main (int argc
, char **argv
)
100 char *context
= NULL
;
101 security_context_t cur_context
= NULL
;
102 security_context_t file_context
= NULL
;
103 security_context_t new_context
= NULL
;
104 bool compute_trans
= false;
108 initialize_main (&argc
, &argv
);
109 program_name
= argv
[0];
110 setlocale (LC_ALL
, "");
111 bindtextdomain (PACKAGE
, LOCALEDIR
);
112 textdomain (PACKAGE
);
114 atexit (close_stdout
);
118 int option_index
= 0;
119 int c
= getopt_long (argc
, argv
, "+r:t:u:l:c", long_options
,
127 error (EXIT_FAILURE
, 0, _("multiple roles"));
132 error (EXIT_FAILURE
, 0, _("multiple types"));
137 error (EXIT_FAILURE
, 0, _("multiple users"));
142 error (EXIT_FAILURE
, 0, _("multiple levelranges"));
146 compute_trans
= true;
149 case_GETOPT_HELP_CHAR
;
150 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
152 usage (EXIT_FAILURE
);
157 if (argc
- optind
== 0)
159 if (getcon (&cur_context
) < 0)
160 error (EXIT_FAILURE
, errno
, _("failed to get current context"));
161 fputs (cur_context
, stdout
);
162 fputc ('\n', stdout
);
166 if (!(user
|| role
|| type
|| range
|| compute_trans
))
170 error (0, 0, _("you must specify -c, -t, -u, -l, -r, or context"));
173 context
= argv
[optind
++];
178 error (0, 0, _("no command specified"));
182 if (is_selinux_enabled () != 1)
183 error (EXIT_FAILURE
, 0,
184 _("runcon may be used only on a SELinux kernel"));
188 con
= context_new (context
);
190 error (EXIT_FAILURE
, errno
, _("failed to create security context: %s"),
191 quotearg_colon (context
));
195 if (getcon (&cur_context
) < 0)
196 error (EXIT_FAILURE
, errno
, _("failed to get current context"));
198 /* We will generate context based on process transition */
201 /* Get context of file to be executed */
202 if (getfilecon (argv
[optind
], &file_context
) == -1)
203 error (EXIT_FAILURE
, errno
,
204 _("failed to get security context of %s"),
205 quote (argv
[optind
]));
206 /* compute result of process transition */
207 if (security_compute_create (cur_context
, file_context
,
208 SECCLASS_PROCESS
, &new_context
) != 0)
209 error (EXIT_FAILURE
, errno
,
210 _("failed to compute a new context"));
212 freecon (file_context
);
213 freecon (cur_context
);
215 /* set cur_context equal to new_context */
216 cur_context
= new_context
;
219 con
= context_new (cur_context
);
221 error (EXIT_FAILURE
, errno
, _("failed to create security context: %s"),
222 quotearg_colon (cur_context
));
223 if (user
&& context_user_set (con
, user
))
224 error (EXIT_FAILURE
, errno
, _("failed to set new user %s"), user
);
225 if (type
&& context_type_set (con
, type
))
226 error (EXIT_FAILURE
, errno
, _("failed to set new type %s"), type
);
227 if (range
&& context_range_set (con
, range
))
228 error (EXIT_FAILURE
, errno
, _("failed to set new range %s"), range
);
229 if (role
&& context_role_set (con
, role
))
230 error (EXIT_FAILURE
, errno
, _("failed to set new role %s"), role
);
233 if (security_check_context (context_str (con
)) < 0)
234 error (EXIT_FAILURE
, errno
, _("invalid context: %s"),
235 quotearg_colon (context_str (con
)));
237 if (setexeccon (context_str (con
)) != 0)
238 error (EXIT_FAILURE
, errno
, _("unable to set security context %s"),
239 quote (context_str (con
)));
240 if (cur_context
!= NULL
)
241 freecon (cur_context
);
243 execvp (argv
[optind
], argv
+ optind
);
246 int exit_status
= (errno
== ENOENT
? EXIT_ENOENT
: EXIT_CANNOT_INVOKE
);
247 error (0, errno
, "%s", argv
[optind
]);