mirror of
https://https.git.savannah.gnu.org/git/coreutils.git
synced 2026-01-27 01:44:21 +00:00
* src/runcon.c: New program.
* src/Makefile.am (bin_PROGRAMS): Add runcon. (runcon_LDADD): Define. * README: Add runcon to the list of programs. * AUTHORS: Add this: runcon: Russell Coker * tests/help-version: Add runcon as an exception. * man/Makefile.am (dist_man_MANS): Add runcon.1. (runcon.1): New dependency. * po/POTFILES.in: Add src/runcon.c.
This commit is contained in:
parent
c2bbd117f5
commit
c6922b6f7e
1
AUTHORS
1
AUTHORS
@ -61,6 +61,7 @@ pwd: Jim Meyering
|
||||
readlink: Dmitry V. Levin
|
||||
rm: Paul Rubin, David MacKenzie, Richard Stallman, Jim Meyering
|
||||
rmdir: David MacKenzie
|
||||
runcon: Russell Coker
|
||||
seq: Ulrich Drepper
|
||||
sha1sum: Ulrich Drepper, Scott Miller, David Madore
|
||||
sha224sum: Ulrich Drepper, Scott Miller, David Madore
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
2007-02-02 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* src/runcon.c: New program.
|
||||
* src/Makefile.am (bin_PROGRAMS): Add runcon.
|
||||
(runcon_LDADD): Define.
|
||||
* README: Add runcon to the list of programs.
|
||||
* AUTHORS: Add this: runcon: Russell Coker
|
||||
* tests/help-version: Add runcon as an exception.
|
||||
* man/Makefile.am (dist_man_MANS): Add runcon.1.
|
||||
(runcon.1): New dependency.
|
||||
|
||||
2007-01-31 Jim Meyering <jim@meyering.net>
|
||||
|
||||
mkfifo, mknod: Accept new "-Z, --context=C" option.
|
||||
|
||||
10
README
10
README
@ -10,11 +10,11 @@ The programs that can be built with this package are:
|
||||
[ base64 basename cat chcon chgrp chmod chown chroot cksum comm cp
|
||||
csplit cut date dd df dir dircolors dirname du echo env expand expr
|
||||
factor false fmt fold groups head hostid hostname id install join
|
||||
kill link ln logname ls md5sum mkdir mkfifo mknod mv nice nl nohup od
|
||||
paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir seq
|
||||
sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort
|
||||
split stat stty su sum sync tac tail tee test touch tr true tsort tty
|
||||
uname unexpand uniq unlink uptime users vdir wc who whoami yes
|
||||
kill link ln logname ls md5sum mkdir mkfifo mknod mv nice nl nohup
|
||||
od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
|
||||
runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf
|
||||
sleep sort split stat stty su sum sync tac tail tee test touch tr true
|
||||
tsort tty uname unexpand uniq unlink uptime users vdir wc who whoami yes
|
||||
|
||||
See the file NEWS for a list of major changes in the current release.
|
||||
|
||||
|
||||
@ -25,7 +25,8 @@ dist_man_MANS = \
|
||||
link.1 ln.1 logname.1 \
|
||||
ls.1 md5sum.1 mkdir.1 mkfifo.1 mknod.1 mv.1 nl.1 nohup.1 od.1 \
|
||||
paste.1 pathchk.1 pr.1 printenv.1 printf.1 ptx.1 pwd.1 readlink.1 \
|
||||
rm.1 rmdir.1 seq.1 sha1sum.1 sha224sum.1 sha256sum.1 sha384sum.1 sha512sum.1 \
|
||||
rm.1 rmdir.1 runcon.1 seq.1 \
|
||||
sha1sum.1 sha224sum.1 sha256sum.1 sha384sum.1 sha512sum.1 \
|
||||
shred.1 shuf.1 sleep.1 sort.1 split.1 stat.1 \
|
||||
su.1 sum.1 sync.1 tac.1 tail.1 tee.1 test.1 touch.1 tr.1 true.1 tsort.1 \
|
||||
tty.1 unexpand.1 uniq.1 unlink.1 vdir.1 wc.1 \
|
||||
@ -105,6 +106,7 @@ pwd.1: $(common_dep) $(srcdir)/pwd.x ../src/pwd.c
|
||||
readlink.1: $(common_dep) $(srcdir)/readlink.x ../src/readlink.c
|
||||
rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
|
||||
rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
|
||||
runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
|
||||
seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
|
||||
sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
|
||||
sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
|
||||
|
||||
14
man/runcon.x
Normal file
14
man/runcon.x
Normal file
@ -0,0 +1,14 @@
|
||||
[NAME]
|
||||
runcon \- run command with specified security context
|
||||
[DESCRIPTION]
|
||||
Run COMMAND with completely-specified CONTEXT, or with current or
|
||||
transitioned security context modified by one or more of LEVEL,
|
||||
ROLE, TYPE, and USER.
|
||||
.PP
|
||||
If none of \fI-c\fR, \fI-t\fR, \fI-u\fR, \fI-r\fR, or \fI-l\fR, is specified,
|
||||
the first argument is used as the complete context. Any additional
|
||||
arguments after \fICOMMAND\fR are interpreted as arguments to the
|
||||
command.
|
||||
.PP
|
||||
Note that only carefully-chosen contexts are likely to successfully
|
||||
run.
|
||||
@ -1,3 +1,7 @@
|
||||
2007-02-02 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* POTFILES.in: Add src/runcon.c.
|
||||
|
||||
2007-01-13 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* POTFILES.in: Add src/chcon.c.
|
||||
|
||||
@ -91,6 +91,7 @@ src/readlink.c
|
||||
src/remove.c
|
||||
src/rm.c
|
||||
src/rmdir.c
|
||||
src/runcon.c
|
||||
src/seq.c
|
||||
src/setuidgid.c
|
||||
src/shred.c
|
||||
|
||||
@ -26,7 +26,8 @@ bin_PROGRAMS = [ chcon chgrp chown chmod cp dd dircolors du \
|
||||
nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \
|
||||
shuf sort split sum tac tail tr tsort unexpand uniq wc \
|
||||
basename date dirname echo env expr factor false \
|
||||
hostname id kill logname pathchk printenv printf pwd seq sleep tee \
|
||||
hostname id kill logname pathchk printenv printf pwd \
|
||||
runcon seq sleep tee \
|
||||
test true tty whoami yes \
|
||||
base64 \
|
||||
$(OPTIONAL_BIN_PROGS) $(DF_PROG)
|
||||
@ -67,6 +68,7 @@ mkdir_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mkfifo_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mknod_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mv_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
|
||||
runcon_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
pathchk_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
rm_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
test_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
|
||||
249
src/runcon.c
Normal file
249
src/runcon.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/context.h>
|
||||
#ifdef HAVE_SELINUX_FLASK_H
|
||||
# include <selinux/flask.h>
|
||||
#else
|
||||
# define SECCLASS_PROCESS 0
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include "system.h"
|
||||
#include "error.h"
|
||||
#include "quote.h"
|
||||
#include "quotearg.h"
|
||||
|
||||
/* The official name of this program (e.g., no `g' prefix). */
|
||||
#define PROGRAM_NAME "runcon"
|
||||
|
||||
#define AUTHORS "Russell Coker"
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"role", required_argument, NULL, 'r'},
|
||||
{"type", required_argument, NULL, 't'},
|
||||
{"user", required_argument, NULL, 'u'},
|
||||
{"range", required_argument, NULL, 'l'},
|
||||
{"compute", no_argument, NULL, 'c'},
|
||||
{GETOPT_HELP_OPTION_DECL},
|
||||
{GETOPT_VERSION_OPTION_DECL},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* The name the program was run with. */
|
||||
char *program_name;
|
||||
|
||||
void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s CONTEXT COMMAND [args]\n\
|
||||
or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\
|
||||
"), program_name, program_name);
|
||||
fputs (_("\
|
||||
Run a program in a different security context.\n\
|
||||
With neither CONTEXT nor COMMAND, print the current security context.\n\
|
||||
\n\
|
||||
CONTEXT Complete security context\n\
|
||||
-c, --compute compute process transition context before modifying\n\
|
||||
-t, --type=TYPE type (for same role as parent)\n\
|
||||
-u, --user=USER user identity\n\
|
||||
-r, --role=ROLE role\n\
|
||||
-l, --range=RANGE levelrange\n\
|
||||
\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv, char **envp)
|
||||
{
|
||||
char *role = NULL;
|
||||
char *range = NULL;
|
||||
char *user = NULL;
|
||||
char *type = NULL;
|
||||
char *context = NULL;
|
||||
security_context_t cur_context = NULL;
|
||||
security_context_t file_context = NULL;
|
||||
security_context_t new_context = NULL;
|
||||
bool compute_trans = false;
|
||||
|
||||
context_t con;
|
||||
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
c = getopt_long (argc, argv, "r:t:u:l:c", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
if (role)
|
||||
error (EXIT_FAILURE, 0, _("multiple roles"));
|
||||
role = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if (type)
|
||||
error (EXIT_FAILURE, 0, _("multiple types"));
|
||||
type = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
if (user)
|
||||
error (EXIT_FAILURE, 0, _("multiple users"));
|
||||
user = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
if (range)
|
||||
error (EXIT_FAILURE, 0, _("multiple levelranges"));
|
||||
range = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
compute_trans = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind == 0)
|
||||
{
|
||||
if (getcon (&cur_context) < 0)
|
||||
error (EXIT_FAILURE, errno, _("failed to get current context"));
|
||||
fputs (cur_context, stdout);
|
||||
fputc ('\n', stdout);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!(user || role || type || range || compute_trans))
|
||||
{
|
||||
if (optind >= argc)
|
||||
{
|
||||
error (0, 0, _("you must specify -c, -t, -u, -l, -r, or context"));
|
||||
usage (1);
|
||||
}
|
||||
context = argv[optind++];
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
error (0, 0, _("no command specified"));
|
||||
usage (1);
|
||||
}
|
||||
|
||||
if (is_selinux_enabled () != 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("runcon may be used only on a SELinux kernel."));
|
||||
|
||||
if (context)
|
||||
{
|
||||
con = context_new (context);
|
||||
if (!con)
|
||||
error (EXIT_FAILURE, errno, _("failed to create security context: %s"),
|
||||
quotearg_colon (context));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getcon (&cur_context) < 0)
|
||||
error (EXIT_FAILURE, errno, _("failed to get current context"));
|
||||
|
||||
/* We will generate context based on process transition */
|
||||
if (compute_trans)
|
||||
{
|
||||
/* Get context of file to be executed */
|
||||
if (getfilecon (argv[optind], &file_context) == -1)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to get security context of %s"),
|
||||
quote (argv[optind]));
|
||||
/* compute result of process transition */
|
||||
if (security_compute_create (cur_context, file_context,
|
||||
SECCLASS_PROCESS, &new_context) != 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to compute a new context"));
|
||||
/* free contexts */
|
||||
freecon (file_context);
|
||||
freecon (cur_context);
|
||||
|
||||
/* set cur_context equal to new_context */
|
||||
cur_context = new_context;
|
||||
}
|
||||
|
||||
con = context_new (cur_context);
|
||||
if (!con)
|
||||
error (EXIT_FAILURE, errno, _("failed to create security context: %s"),
|
||||
quotearg_colon (cur_context));
|
||||
if (user && context_user_set (con, user))
|
||||
error (EXIT_FAILURE, errno, _("failed to set new user %s"), user);
|
||||
if (type && context_type_set (con, type))
|
||||
error (EXIT_FAILURE, errno, _("failed to set new type %s"), type);
|
||||
if (range && context_range_set (con, range))
|
||||
error (EXIT_FAILURE, errno, _("failed to set new range %s"), range);
|
||||
if (role && context_role_set (con, role))
|
||||
error (EXIT_FAILURE, errno, _("failed to set new role %s"), role);
|
||||
}
|
||||
|
||||
if (security_check_context (context_str (con)) < 0)
|
||||
error (EXIT_FAILURE, errno, _("invalid context: %s"),
|
||||
quotearg_colon (context_str (con)));
|
||||
|
||||
if (setexeccon (context_str (con)) != 0)
|
||||
error (EXIT_FAILURE, errno, _("unable to set security context %s"),
|
||||
quote (context_str (con)));
|
||||
if (cur_context != NULL)
|
||||
freecon (cur_context);
|
||||
|
||||
execvp (argv[optind], argv + optind);
|
||||
|
||||
{
|
||||
int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
|
||||
error (0, errno, "%s", argv[optind]);
|
||||
exit (exit_status);
|
||||
}
|
||||
}
|
||||
@ -72,6 +72,7 @@ for lang in C fr da; do
|
||||
# Skip `test'; it doesn't accept --help or --version.
|
||||
test $i = test && continue;
|
||||
test $i = chcon && continue;
|
||||
test $i = runcon && continue;
|
||||
|
||||
# false fails even when invoked with --help or --version.
|
||||
if test $i = false; then
|
||||
@ -197,7 +198,7 @@ lbracket_args=": ]"
|
||||
|
||||
for i in $all_programs; do
|
||||
# Skip these.
|
||||
case $i in chroot|stty|tty|false|chcon) continue;; esac
|
||||
case $i in chroot|stty|tty|false|chcon|runcon) continue;; esac
|
||||
|
||||
rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out
|
||||
echo > $tmp_in
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user