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 "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
);
93 main (int argc
, char **argv
, char **envp
)
100 security_context_t cur_context
= NULL
;
101 security_context_t file_context
= NULL
;
102 security_context_t new_context
= NULL
;
103 bool compute_trans
= false;
107 initialize_main (&argc
, &argv
);
108 program_name
= argv
[0];
109 setlocale (LC_ALL
, "");
110 bindtextdomain (PACKAGE
, LOCALEDIR
);
111 textdomain (PACKAGE
);
113 atexit (close_stdout
);
117 int option_index
= 0;
118 int c
= getopt_long (argc
, argv
, "+r:t:u:l:c", long_options
,
126 error (EXIT_FAILURE
, 0, _("multiple roles"));
131 error (EXIT_FAILURE
, 0, _("multiple types"));
136 error (EXIT_FAILURE
, 0, _("multiple users"));
141 error (EXIT_FAILURE
, 0, _("multiple levelranges"));
145 compute_trans
= true;
148 case_GETOPT_HELP_CHAR
;
149 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
151 usage (EXIT_FAILURE
);
156 if (argc
- optind
== 0)
158 if (getcon (&cur_context
) < 0)
159 error (EXIT_FAILURE
, errno
, _("failed to get current context"));
160 fputs (cur_context
, stdout
);
161 fputc ('\n', stdout
);
165 if (!(user
|| role
|| type
|| range
|| compute_trans
))
169 error (0, 0, _("you must specify -c, -t, -u, -l, -r, or context"));
172 context
= argv
[optind
++];
177 error (0, 0, _("no command specified"));
181 if (is_selinux_enabled () != 1)
182 error (EXIT_FAILURE
, 0,
183 _("runcon may be used only on a SELinux kernel"));
187 con
= context_new (context
);
189 error (EXIT_FAILURE
, errno
, _("failed to create security context: %s"),
190 quotearg_colon (context
));
194 if (getcon (&cur_context
) < 0)
195 error (EXIT_FAILURE
, errno
, _("failed to get current context"));
197 /* We will generate context based on process transition */
200 /* Get context of file to be executed */
201 if (getfilecon (argv
[optind
], &file_context
) == -1)
202 error (EXIT_FAILURE
, errno
,
203 _("failed to get security context of %s"),
204 quote (argv
[optind
]));
205 /* compute result of process transition */
206 if (security_compute_create (cur_context
, file_context
,
207 SECCLASS_PROCESS
, &new_context
) != 0)
208 error (EXIT_FAILURE
, errno
,
209 _("failed to compute a new context"));
211 freecon (file_context
);
212 freecon (cur_context
);
214 /* set cur_context equal to new_context */
215 cur_context
= new_context
;
218 con
= context_new (cur_context
);
220 error (EXIT_FAILURE
, errno
, _("failed to create security context: %s"),
221 quotearg_colon (cur_context
));
222 if (user
&& context_user_set (con
, user
))
223 error (EXIT_FAILURE
, errno
, _("failed to set new user %s"), user
);
224 if (type
&& context_type_set (con
, type
))
225 error (EXIT_FAILURE
, errno
, _("failed to set new type %s"), type
);
226 if (range
&& context_range_set (con
, range
))
227 error (EXIT_FAILURE
, errno
, _("failed to set new range %s"), range
);
228 if (role
&& context_role_set (con
, role
))
229 error (EXIT_FAILURE
, errno
, _("failed to set new role %s"), role
);
232 if (security_check_context (context_str (con
)) < 0)
233 error (EXIT_FAILURE
, errno
, _("invalid context: %s"),
234 quotearg_colon (context_str (con
)));
236 if (setexeccon (context_str (con
)) != 0)
237 error (EXIT_FAILURE
, errno
, _("unable to set security context %s"),
238 quote (context_str (con
)));
239 if (cur_context
!= NULL
)
240 freecon (cur_context
);
242 execvp (argv
[optind
], argv
+ optind
);
245 int exit_status
= (errno
== ENOENT
? EXIT_ENOENT
: EXIT_CANNOT_INVOKE
);
246 error (0, errno
, "%s", argv
[optind
]);