/* runcon -- run command with specified security context This is the runcon utility
Copyright (C) 2005-2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ The GNUv3 license
/*
* 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
*/
#include <config.h> Provides system specific information
#include <stdio.h> Provides standard I/O capability
#include <getopt.h> ...!includes auto-comment...
#include <selinux/selinux.h> ...!includes auto-comment......!includes auto-comment...
#include <selinux/context.h> ...!includes auto-comment...
#include <sys/types.h> Provides system data types
#include "system.h" ...!includes auto-comment...
#include "die.h" ...!includes auto-comment...
#include "error.h" ...!includes auto-comment...
#include "quote.h" ...!includes auto-comment...
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "runcon" Line 55
#define AUTHORS proper_name ("Russell Coker") Line 57
static struct option const long_options[] = Line 59
{
{"role", required_argument, NULL, 'r'}, Line 61
{"type", required_argument, NULL, 't'}, Line 62
{"user", required_argument, NULL, 'u'}, Line 63
{"range", required_argument, NULL, 'l'}, Line 64
{"compute", no_argument, NULL, 'c'}, Line 65
{GETOPT_HELP_OPTION_DECL}, Line 66
{GETOPT_VERSION_OPTION_DECL}, Line 67
{NULL, 0, NULL, 0} Line 68
}; Block 1
void Line 71
usage (int status) Line 72
{
if (status != EXIT_SUCCESS) Line 74
emit_try_help (); ...!common auto-comment...
else Line 76
{
printf (_("\ Line 78
Usage: %s CONTEXT COMMAND [args]\n\ Line 79
or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ Line 80
"), program_name, program_name); Line 81
fputs (_("\ Line 82
Run a program in a different SELinux security context.\n\ Line 83
With neither CONTEXT nor COMMAND, print the current security context.\n\ Line 84
"), stdout); Line 85
emit_mandatory_arg_note (); ...!common auto-comment...
fputs (_("\ Line 89
CONTEXT Complete security context\n\ Line 90
-c, --compute compute process transition context before modifying\n\ Line 91
-t, --type=TYPE type (for same role as parent)\n\ Line 92
-u, --user=USER user identity\n\ Line 93
-r, --role=ROLE role\n\ Line 94
-l, --range=RANGE levelrange\n\ Line 95
\n\
"), stdout); Line 97
fputs (HELP_OPTION_DESCRIPTION, stdout); Line 98
fputs (VERSION_OPTION_DESCRIPTION, stdout); Line 99
emit_ancillary_info (PROGRAM_NAME); Line 100
}
exit (status); Line 102
} Block 2
int
main (int argc, char **argv) Line 106
{
char *role = NULL; Line 108
char *range = NULL; Line 109
char *user = NULL; Line 110
char *type = NULL; Line 111
char *context = NULL; Line 112
char *cur_context = NULL; Line 113
char *file_context = NULL; Line 114
char *new_context = NULL; Line 115
bool compute_trans = false; Line 116
context_t con; Line 118
initialize_main (&argc, &argv); VMS-specific entry point handling wildcard expansion
set_program_name (argv[0]); Retains program name and discards path
setlocale (LC_ALL, ""); Sets up internationalization (i18n)
bindtextdomain (PACKAGE, LOCALEDIR); Assigns i18n directorySets text domain for _() [gettext()] function
textdomain (PACKAGE); Sets text domain for _() [gettext()] function
atexit (close_stdout); Close stdout on exit (see gnulib)
while (1) Line 128
{
int option_index = 0; Line 130
int c = getopt_long (argc, argv, "+r:t:u:l:c", long_options, Line 131
&option_index); Line 132
if (c == -1) Line 133
break; Line 134
switch (c) Line 135
{
case 'r': Line 137
if (role) Line 138
die (EXIT_FAILURE, 0, _("multiple roles")); Line 139
role = optarg; Line 140
break; Line 141
case 't': Line 142
if (type) Line 143
die (EXIT_FAILURE, 0, _("multiple types")); Line 144
type = optarg; Line 145
break; Line 146
case 'u': Line 147
if (user) Line 148
die (EXIT_FAILURE, 0, _("multiple users")); Line 149
user = optarg; Line 150
break; Line 151
case 'l': Line 152
if (range) Line 153
die (EXIT_FAILURE, 0, _("multiple levelranges")); Line 154
range = optarg; Line 155
break; Line 156
case 'c': Line 157
compute_trans = true; Line 158
break; Line 159
case_GETOPT_HELP_CHAR; Line 161
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); Line 162
default: Line 163
usage (EXIT_FAILURE); Line 164
break; Line 165
}
}
if (argc - optind == 0) Line 169
{
if (getcon (&cur_context) < 0) Line 171
die (EXIT_FAILURE, errno, _("failed to get current context")); Line 172
fputs (cur_context, stdout); Line 173
fputc ('\n', stdout); Line 174
return EXIT_SUCCESS; Line 175
}
if (!(user || role || type || range || compute_trans)) Line 178
{
if (optind >= argc) Line 180
{
error (0, 0, _("you must specify -c, -t, -u, -l, -r, or context")); Line 182
usage (EXIT_FAILURE); Line 183
}
context = argv[optind++]; Line 185
}
if (optind >= argc) Line 188
{
error (0, 0, _("no command specified")); Line 190
usage (EXIT_FAILURE); Line 191
}
if (is_selinux_enabled () != 1) ...!common auto-comment...
die (EXIT_FAILURE, 0, _("%s may be used only on a SELinux kernel"), Line 195
program_name); Line 196
if (context) Line 198
{
con = context_new (context); Line 200
if (!con) Line 201
die (EXIT_FAILURE, errno, _("failed to create security context: %s"), Line 202
quote (context)); Line 203
}
else Line 205
{
if (getcon (&cur_context) < 0) Line 207
die (EXIT_FAILURE, errno, _("failed to get current context")); Line 208
/* We will generate context based on process transition */
if (compute_trans) Line 211
{
/* Get context of file to be executed */
if (getfilecon (argv[optind], &file_context) == -1) Line 214
die (EXIT_FAILURE, errno, Line 215
_("failed to get security context of %s"), Line 216
quoteaf (argv[optind])); Line 217
/* compute result of process transition */
if (security_compute_create (cur_context, file_context, Line 219
string_to_security_class ("process"), Line 220
&new_context) != 0) Line 221
die (EXIT_FAILURE, errno, _("failed to compute a new context")); Line 222
/* free contexts */
freecon (file_context); Line 224
freecon (cur_context); Line 225
/* set cur_context equal to new_context */
cur_context = new_context; Line 228
}
con = context_new (cur_context); Line 231
if (!con) Line 232
die (EXIT_FAILURE, errno, _("failed to create security context: %s"), Line 233
quote (cur_context)); Line 234
if (user && context_user_set (con, user)) Line 235
die (EXIT_FAILURE, errno, _("failed to set new user: %s"), Line 236
quote (user)); Line 237
if (type && context_type_set (con, type)) Line 238
die (EXIT_FAILURE, errno, _("failed to set new type: %s"), Line 239
quote (type)); Line 240
if (range && context_range_set (con, range)) Line 241
die (EXIT_FAILURE, errno, _("failed to set new range: %s"), Line 242
quote (range)); Line 243
if (role && context_role_set (con, role)) Line 244
die (EXIT_FAILURE, errno, _("failed to set new role: %s"), Line 245
quote (role)); Line 246
}
if (security_check_context (context_str (con)) < 0) Line 249
die (EXIT_FAILURE, errno, _("invalid context: %s"), Line 250
quote (context_str (con))); Line 251
if (setexeccon (context_str (con)) != 0) Line 253
die (EXIT_FAILURE, errno, _("unable to set security context %s"), Line 254
quote (context_str (con))); Line 255
if (cur_context != NULL) Line 256
freecon (cur_context); Line 257
execvp (argv[optind], argv + optind); Line 259
int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE; Line 261
error (0, errno, "%s", quote (argv[optind])); Line 262
return exit_status; Line 263
} Block 3