diff -urN coreutils-5.0.org/config.hin coreutils-5.0/config.hin --- coreutils-5.0.org/config.hin 2003-12-27 12:26:28.926095552 +0100 +++ coreutils-5.0/config.hin 2003-12-27 12:28:20.345157280 +0100 @@ -1427,3 +1427,7 @@ /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ #undef volatile + +/* Define if you want to use SELINUX */ +#undef WITH_SELINUX + diff -urN coreutils-5.0.org/configure.ac coreutils-5.0/configure.ac --- coreutils-5.0.org/configure.ac 2003-12-27 12:26:28.584147536 +0100 +++ coreutils-5.0/configure.ac 2003-12-27 12:27:54.896026136 +0100 @@ -15,6 +15,13 @@ LIB_PAM="-ldl -lpam -lpam_misc" ) +dnl Give the chance to enable PAM +AC_ARG_ENABLE(selinux, dnl +[ --enable-selinux Enable use of the SELINUX libraries], +[AC_DEFINE(WITH_SELINUX, 1, [Define if you want to use SELINUX]) +LIB_SELINUX="-lselinux" +AC_SUBST(LIB_SELINUX)]) + AC_GNU_SOURCE jm_PERL AC_PROG_CC diff -urN coreutils-5.0.org/man/chcon.1 coreutils-5.0/man/chcon.1 --- coreutils-5.0.org/man/chcon.1 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/man/chcon.1 2003-12-27 12:26:52.965441016 +0100 @@ -0,0 +1,52 @@ +.TH CHCON 1 "July 2003" "chcon (coreutils) 5.0" "User Commands" +.SH NAME +chcon \- change security context +.SH SYNOPSIS +.B chcon +[\fIOPTION\fR]...\fI CONTEXT FILE\fR... +.br +.B chcon +[\fIOPTION\fR]...\fI --reference=RFILE FILE\fR... +.SH DESCRIPTION +.PP +." Add any additional description here +.PP +Change the security context of each FILE to CONTEXT. +.TP +\fB\-c\fR, \fB\-\-changes\fR +like verbose but report only when a change is made +.TP +\fB\-h\fR, \fB\-\-no\-dereference\fR +affect symbolic links instead of any referenced file (available only on systems with lchown system call) +.TP +\fB\-f\fR, \fB\-\-silent\fR, \fB\-\-quiet\fR +suppress most error messages +.TP +\fB\-\-reference\fR=\fIRFILE\fR +use RFILE's context instead of using a CONTEXT value +.TP +\fB\-R\fR, \fB\-\-recursive\fR +change files and directories recursively +.TP +\fB\-v\fR, \fB\-\-verbose\fR +output a diagnostic for every file processed +.TP +\fB\-\-help\fR +display this help and exit +.TP +\fB\-\-version\fR +output version information and exit +.SH "REPORTING BUGS" +Report bugs to . +.SH "SEE ALSO" +The full documentation for +.B chcon +is maintained as a Texinfo manual. If the +.B info +and +.B chcon +programs are properly installed at your site, the command +.IP +.B info chcon +.PP +should give you access to the complete manual. diff -urN coreutils-5.0.org/man/chcon.x coreutils-5.0/man/chcon.x --- coreutils-5.0.org/man/chcon.x 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/man/chcon.x 2003-12-27 12:26:52.962441472 +0100 @@ -0,0 +1,4 @@ +[NAME] +chcon \- change file security context +[DESCRIPTION] +.\" Add any additional description here diff -urN coreutils-5.0.org/man/cp.1 coreutils-5.0/man/cp.1 --- coreutils-5.0.org/man/cp.1 2003-12-27 12:26:28.509158936 +0100 +++ coreutils-5.0/man/cp.1 2003-12-27 12:26:52.965441016 +0100 @@ -57,7 +57,7 @@ .TP \fB\-\-preserve\fR[=\fIATTR_LIST\fR] preserve the specified attributes (default: -mode,ownership,timestamps), if possible +mode,ownership,timestamps) and security contexts, if possible additional attributes: links, all .TP \fB\-\-no\-preserve\fR=\fIATTR_LIST\fR @@ -109,6 +109,9 @@ \fB\-\-help\fR display this help and exit .TP +\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR +set security context of copy to CONTEXT +.TP \fB\-\-version\fR output version information and exit .PP diff -urN coreutils-5.0.org/man/dir.1 coreutils-5.0/man/dir.1 --- coreutils-5.0.org/man/dir.1 2003-12-27 12:26:28.485162584 +0100 +++ coreutils-5.0/man/dir.1 2003-12-27 12:26:52.966440864 +0100 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH DIR "1" "March 2003" "dir (coreutils) 5.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022. +.TH DIR "1" "September 2003" "dir (coreutils) 5.0" FSF .SH NAME dir \- list directory contents .SH SYNOPSIS @@ -195,6 +195,20 @@ .TP \fB\-1\fR list one file per line +.PP +SELinux options: +.TP +\fB\-\-lcontext\fR +Display security context. Enable \fB\-l\fR. Lines +will probably be too wide for most displays. +.TP +\fB\-\-context\fR +Display security context so it fits on most +displays. Displays only mode, user, group, +security context and file name. +.TP +\fB\-\-scontext\fR +Display only security context and file name. .TP \fB\-\-help\fR display this help and exit diff -urN coreutils-5.0.org/man/id.1 coreutils-5.0/man/id.1 --- coreutils-5.0.org/man/id.1 2003-12-27 12:26:28.509158936 +0100 +++ coreutils-5.0/man/id.1 2003-12-27 12:26:52.967440712 +0100 @@ -13,6 +13,9 @@ \fB\-a\fR ignore, for compatibility with other versions .TP +\fB\-Z\fR, \fB\-\-context\fR +print only the security context +.TP \fB\-g\fR, \fB\-\-group\fR print only the effective group ID .TP diff -urN coreutils-5.0.org/man/install.1 coreutils-5.0/man/install.1 --- coreutils-5.0.org/man/install.1 2003-12-27 12:26:28.509158936 +0100 +++ coreutils-5.0/man/install.1 2003-12-27 12:26:52.967440712 +0100 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH INSTALL "1" "March 2003" "install (coreutils) 5.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022. +.TH INSTALL "1" "September 2003" "install (coreutils) 5.0" FSF .SH NAME ginstall \- copy files and set attributes .SH SYNOPSIS @@ -56,6 +56,11 @@ .TP \fB\-v\fR, \fB\-\-verbose\fR print the name of each directory as it is created +.HP +\fB\-P\fR, \fB\-\-preserve_context\fR (SELinux) Preserve security context +.TP +\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR +(SELinux) Set security context of files and directories .TP \fB\-\-help\fR display this help and exit diff -urN coreutils-5.0.org/man/ls.1 coreutils-5.0/man/ls.1 --- coreutils-5.0.org/man/ls.1 2003-12-27 12:26:28.509158936 +0100 +++ coreutils-5.0/man/ls.1 2003-12-27 12:26:52.966440864 +0100 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH LS "1" "March 2003" "ls (coreutils) 5.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022. +.TH LS "1" "September 2003" "ls (coreutils) 5.0" FSF .SH NAME ls \- list directory contents .SH SYNOPSIS @@ -195,6 +195,20 @@ .TP \fB\-1\fR list one file per line +.PP +SELinux options: +.TP +\fB\-\-lcontext\fR +Display security context. Enable \fB\-l\fR. Lines +will probably be too wide for most displays. +.TP +\fB\-Z\fR, \fB\-\-context\fR +Display security context so it fits on most +displays. Displays only mode, user, group, +security context and file name. +.TP +\fB\-\-scontext\fR +Display only security context and file name. .TP \fB\-\-help\fR display this help and exit diff -urN coreutils-5.0.org/man/Makefile.am coreutils-5.0/man/Makefile.am --- coreutils-5.0.org/man/Makefile.am 2003-12-27 12:26:28.345183864 +0100 +++ coreutils-5.0/man/Makefile.am 2003-12-27 12:33:28.969239288 +0100 @@ -9,7 +9,7 @@ rm.1 rmdir.1 seq.1 sha1sum.1 shred.1 sleep.1 sort.1 split.1 stat.1 stty.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 uname.1 unexpand.1 uniq.1 unlink.1 uptime.1 users.1 vdir.1 wc.1 \ - who.1 whoami.1 yes.1 + who.1 whoami.1 yes.1 chcon.1 runcon.1 man_MANS = getgid.1 man_aux = $(dist_man_MANS:.1=.x) @@ -111,6 +111,8 @@ who.1: $(common_dep) $(srcdir)/who.x ../src/who.c whoami.1: $(common_dep) $(srcdir)/whoami.x ../src/whoami.c yes.1: $(common_dep) $(srcdir)/yes.x ../src/yes.c +chcon.1: $(common_dep) $(srcdir)/chcon.x ../src/chcon.c +runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c SUFFIXES = .x .1 diff -urN coreutils-5.0.org/man/mkdir.1 coreutils-5.0/man/mkdir.1 --- coreutils-5.0.org/man/mkdir.1 2003-12-27 12:26:28.407174440 +0100 +++ coreutils-5.0/man/mkdir.1 2003-12-27 12:26:52.968440560 +0100 @@ -12,6 +12,8 @@ .PP Mandatory arguments to long options are mandatory for short options too. .TP +\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR (SELinux) set security context to CONTEXT +.TP \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR set permission mode (as in chmod), not rwxrwxrwx - umask .TP diff -urN coreutils-5.0.org/man/mkfifo.1 coreutils-5.0/man/mkfifo.1 --- coreutils-5.0.org/man/mkfifo.1 2003-12-27 12:26:28.459166536 +0100 +++ coreutils-5.0/man/mkfifo.1 2003-12-27 12:26:52.968440560 +0100 @@ -12,6 +12,9 @@ .PP Mandatory arguments to long options are mandatory for short options too. .TP +\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR +set security context (quoted string) +.TP \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR set permission mode (as in chmod), not a=rw - umask .TP diff -urN coreutils-5.0.org/man/mknod.1 coreutils-5.0/man/mknod.1 --- coreutils-5.0.org/man/mknod.1 2003-12-27 12:26:28.406174592 +0100 +++ coreutils-5.0/man/mknod.1 2003-12-27 12:26:52.969440408 +0100 @@ -12,6 +12,9 @@ .PP Mandatory arguments to long options are mandatory for short options too. .TP +\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR +set security context (quoted string) +.TP \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR set permission mode (as in chmod), not a=rw - umask .TP diff -urN coreutils-5.0.org/man/runcon.1 coreutils-5.0/man/runcon.1 --- coreutils-5.0.org/man/runcon.1 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/man/runcon.1 2003-12-27 12:26:52.969440408 +0100 @@ -0,0 +1,39 @@ +.TH RUNCON "1" "July 2003" "runcon (coreutils) 5.0" "selinux" +.SH NAME +runcon \- run command with specified security context +.SH SYNOPSIS +.B runcon +[\fI-t TYPE\fR] [\fI-l LEVEL\fR] [\fI-u USER\fR] [\fI-r ROLE\fR] \fICOMMAND\fR [\fIARGS...\fR] +.PP +or +.PP +.B runcon +\fICONTEXT\fR \fICOMMAND\fR [\fIargs...\fR] +.PP +.br +.SH DESCRIPTION +.PP +.\" Add any additional description here +.PP +Run COMMAND with current security context modified by one or more of LEVEL, +ROLE, TYPE, and USER, or with completely-specified CONTEXT. +.TP +\fB\-t\fR +change current type to the specified type +.TP +\fB\-l\fR +change current level range to the specified range +.TP +\fB\-r\fR +change current role to the specified role +.TP +\fB\-u\fR +change current user to the specified user +.PP +If none of \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. diff -urN coreutils-5.0.org/man/runcon.x coreutils-5.0/man/runcon.x --- coreutils-5.0.org/man/runcon.x 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/man/runcon.x 2003-12-27 12:26:52.964441168 +0100 @@ -0,0 +1,2 @@ +[DESCRIPTION] +.\" Add any additional description here diff -urN coreutils-5.0.org/man/stat.1 coreutils-5.0/man/stat.1 --- coreutils-5.0.org/man/stat.1 2003-12-27 12:26:28.458166688 +0100 +++ coreutils-5.0/man/stat.1 2003-12-27 12:26:52.965441016 +0100 @@ -22,6 +22,9 @@ \fB\-t\fR, \fB\-\-terse\fR print the information in terse form .TP +\fB\-Z\fR, \fB\-\-context\fR +print security context information for SELinux if available. +.TP \fB\-\-help\fR display this help and exit .TP @@ -42,6 +45,9 @@ %b Number of blocks allocated (see %B) .TP +%C +SELinux security context +.TP %D Device number in hex .TP diff -urN coreutils-5.0.org/man/vdir.1 coreutils-5.0/man/vdir.1 --- coreutils-5.0.org/man/vdir.1 2003-12-27 12:26:28.510158784 +0100 +++ coreutils-5.0/man/vdir.1 2003-12-27 12:26:52.967440712 +0100 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH VDIR "1" "March 2003" "vdir (coreutils) 5.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022. +.TH VDIR "1" "September 2003" "vdir (coreutils) 5.0" FSF .SH NAME vdir \- list directory contents .SH SYNOPSIS @@ -195,6 +195,20 @@ .TP \fB\-1\fR list one file per line +.PP +SELinux options: +.TP +\fB\-\-lcontext\fR +Display security context. Enable \fB\-l\fR. Lines +will probably be too wide for most displays. +.TP +\fB\-\-context\fR +Display security context so it fits on most +displays. Displays only mode, user, group, +security context and file name. +.TP +\fB\-\-scontext\fR +Display only security context and file name. .TP \fB\-\-help\fR display this help and exit diff -urN coreutils-5.0.org/src/chcon.c coreutils-5.0/src/chcon.c --- coreutils-5.0.org/src/chcon.c 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/src/chcon.c 2003-12-27 12:26:52.934445728 +0100 @@ -0,0 +1,415 @@ +/* chcontext -- change security context of a pathname */ + +#include +#include +#include +#include +#include +#include +#include + +#include "system.h" +#include "error.h" +#include "savedir.h" +#include "group-member.h" + +enum Change_status +{ + CH_SUCCEEDED, + CH_FAILED, + CH_NO_CHANGE_REQUESTED +}; + +enum Verbosity +{ + /* Print a message for each file that is processed. */ + V_high, + + /* Print a message for each file whose attributes we change. */ + V_changes_only, + + /* Do not be verbose. This is the default. */ + V_off +}; + +static int change_dir_context PARAMS ((const char *dir, const struct stat *statp)); + +/* The name the program was run with. */ +char *program_name; + +/* If nonzero, and the systems has support for it, change the context + of symbolic links rather than any files they point to. */ +static int change_symlinks; + +/* If nonzero, change the context of directories recursively. */ +static int recurse; + +/* If nonzero, force silence (no error messages). */ +static int force_silent; + +/* Level of verbosity. */ +static enum Verbosity verbosity = V_off; + +/* The name of the context file is being given. */ +static const char *specified_context; + +/* Specific components of the context */ +static const char *specified_user; +static const char *specified_role; +static const char *specified_range; +static const char *specified_type; + +/* The argument to the --reference option. Use the context of this file. + This file must exist. */ +static char *reference_file; + +/* If nonzero, display usage information and exit. */ +static int show_help; + +/* If nonzero, print the version on standard output and exit. */ +static int show_version; + +static struct option const long_options[] = +{ + {"recursive", no_argument, 0, 'R'}, + {"changes", no_argument, 0, 'c'}, + {"no-dereference", no_argument, 0, 'h'}, + {"silent", no_argument, 0, 'f'}, + {"quiet", no_argument, 0, 'f'}, + {"reference", required_argument, 0, CHAR_MAX + 1}, + {"context", required_argument, 0, CHAR_MAX + 2}, + {"user", required_argument, 0, 'u'}, + {"role", required_argument, 0, 'r'}, + {"type", required_argument, 0, 't'}, + {"range", required_argument, 0, 'l'}, + {"verbose", no_argument, 0, 'v'}, + {"help", no_argument, &show_help, 1}, + {"version", no_argument, &show_version, 1}, + {0, 0, 0, 0} +}; + +/* Tell the user how/if the context of FILE has been changed. + CHANGED describes what (if anything) has happened. */ + +static void +describe_change (const char *file, security_context_t newcontext, enum Change_status changed) +{ + const char *fmt; + switch (changed) + { + case CH_SUCCEEDED: + fmt = _("context of %s changed to %s\n"); + break; + case CH_FAILED: + fmt = _("failed to change context of %s to %s\n"); + break; + case CH_NO_CHANGE_REQUESTED: + fmt = _("context of %s retained as %s\n"); + break; + default: + abort (); + } + printf (fmt, file, newcontext); +} + +static int +compute_context_from_mask (security_context_t context, context_t *ret) +{ + context_t newcontext = context_new (context); + if (!newcontext) + return 1; +#define SETCOMPONENT(comp) \ + do { \ + if (specified_ ## comp) \ + if (context_ ## comp ## _set (newcontext, specified_ ## comp)) \ + goto lose; \ + } while (0) + + SETCOMPONENT(user); + SETCOMPONENT(range); + SETCOMPONENT(role); + SETCOMPONENT(type); +#undef SETCOMPONENT + + *ret = newcontext; + return 0; + lose: + context_free (newcontext); + return 1; +} + +/* Change the context of FILE, using specified components. + If it is a directory and -R is given, recurse. + Return 0 if successful, 1 if errors occurred. */ + +static int +change_file_context (const char *file) +{ + struct stat file_stats; + security_context_t file_context=NULL; + context_t context; + security_context_t context_string; + int errors = 0; + + if ((lgetfilecon(file, &file_context)<0) && (errno != ENODATA)) + { + if (force_silent == 0) + error (0, errno, "%s", file); + return 1; + } + + /* If the file doesn't have a context, and we're not setting all of + the context components, there isn't really an obvious default. + Thus, we just give up. */ + if (file_context == NULL && specified_context == NULL) + { + error (0, 0, _("can't apply partial context to unlabeled file %s"), file); + return 1; + } + + if (specified_context == NULL) + { + if (compute_context_from_mask (file_context, &context)) + { + error (0, 0, _("couldn't compute security context from %s"), file_context); + return 1; + } + } + else + { + context = context_new (specified_context); + if (!context) + error (1, 0,_("invalid context: %s"),specified_context); + } + + context_string = context_str (context); + + if (strcmp(context_string,file_context)!=0) + { + int fail; + + if (change_symlinks) + fail = lsetfilecon (file, context_string); + else + fail = setfilecon (file, context_string); + + if (verbosity == V_high || (verbosity == V_changes_only && !fail)) + describe_change (file, context_string, (fail ? CH_FAILED : CH_SUCCEEDED)); + + if (fail) + { + errors = 1; + if (force_silent == 0) + { + error (0, errno, _("failed to change context of %s to %s"), file, context_string); + } + } + } + else if (verbosity == V_high) + { + describe_change (file, context_string, CH_NO_CHANGE_REQUESTED); + } + + context_free(context); + freecon(file_context); + + if (recurse) { + if (lstat(file, &file_stats)==0) + if (S_ISDIR (file_stats.st_mode)) + errors |= change_dir_context (file, &file_stats); + } + return errors; +} + +/* Recursively change context of the files in directory DIR + using specified context components. + STATP points to the results of lstat on DIR. + Return 0 if successful, 1 if errors occurred. */ + +static int +change_dir_context (const char *dir, const struct stat *statp) +{ + char *name_space, *namep; + char *path; /* Full path of each entry to process. */ + unsigned dirlength; /* Length of `dir' and '\0'. */ + unsigned filelength; /* Length of each pathname to process. */ + unsigned pathlength; /* Bytes allocated for `path'. */ + int errors = 0; + + errno = 0; + name_space = savedir (dir); + if (name_space == NULL) + { + if (errno) + { + if (force_silent == 0) + error (0, errno, "%s", dir); + return 1; + } + else + error (1, 0, _("virtual memory exhausted")); + } + + dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */ + pathlength = dirlength + 1; + /* Give `path' a dummy value; it will be reallocated before first use. */ + path = xmalloc (pathlength); + strcpy (path, dir); + path[dirlength - 1] = '/'; + + for (namep = name_space; *namep; namep += filelength - dirlength) + { + filelength = dirlength + strlen (namep) + 1; + if (filelength > pathlength) + { + pathlength = filelength * 2; + path = xrealloc (path, pathlength); + } + strcpy (path + dirlength, namep); + errors |= change_file_context (path); + } + free (path); + free (name_space); + return errors; +} + +static void +usage (int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + printf (_("\ +Usage: %s [OPTION]... CONTEXT FILE...\n\ + or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\ + or: %s [OPTION]... --reference=RFILE FILE...\n\ +"), + program_name, program_name, program_name); + printf (_("\ +Change the security context of each FILE to CONTEXT.\n\ +\n\ + -c, --changes like verbose but report only when a change is made\n\ + -h, --no-dereference affect symbolic links instead of any referenced file\n\ + (available only on systems with lchown system call)\n\ + -f, --silent, --quiet suppress most error messages\n\ + --reference=RFILE use RFILE's group instead of using a CONTEXT value\n\ + -u, --user=USER set user USER in the target security context\n\ + -r, --role=ROLE set role ROLE in the target security context\n\ + -t, --type=TYPE set type TYPE in the target security context\n\ + -l, --range=RANGE set range RANGE in the target security context\n\ + -R, --recursive change files and directories recursively\n\ + -v, --verbose output a diagnostic for every file processed\n\ + --help display this help and exit\n\ + --version output version information and exit\n\ +")); + close_stdout (); + } + exit (status); +} + +int +main (int argc, char **argv) +{ + security_context_t ref_context = NULL; + int errors = 0; + int optc; + int component_specified = 0; + + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + recurse = force_silent = 0; + + while ((optc = getopt_long (argc, argv, "Rcfhvu:r:t:l:", long_options, NULL)) != -1) + { + switch (optc) + { + case 0: + break; + case 'u': + specified_user = optarg; + component_specified = 1; + break; + case 'r': + specified_role = optarg; + component_specified = 1; + break; + case 't': + specified_type = optarg; + component_specified = 1; + break; + case 'l': + specified_range = optarg; + component_specified = 1; + break; + case CHAR_MAX + 1: + reference_file = optarg; + break; + case 'R': + recurse = 1; + break; + case 'c': + verbosity = V_changes_only; + break; + case 'f': + force_silent = 1; + break; + case 'h': + change_symlinks = 1; + break; + case 'v': + verbosity = V_high; + break; + default: + usage (1); + } + } + + if (show_version) + { + printf ("chcon (%s) %s\n", GNU_PACKAGE, VERSION); + close_stdout (); + exit (0); + } + + if (show_help) + usage (0); + + + if (reference_file && component_specified) + { + error (0, 0, _("conflicting security context specifiers given")); + usage (1); + } + + if (!(((reference_file || component_specified) + && (argc - optind > 0)) + || (argc - optind > 1))) + { + error (0, 0, _("too few arguments")); + usage (1); + } + + if (reference_file) + { + if (getfilecon (reference_file, &ref_context)<0) + error (1, errno, "%s", reference_file); + + specified_context = ref_context; + } + else if (!component_specified) { + specified_context = argv[optind++]; + } + for (; optind < argc; ++optind) + errors |= change_file_context (argv[optind]); + + if (verbosity != V_off) + close_stdout (); + if (ref_context != NULL) + freecon(ref_context); + exit (errors); +} diff -urN coreutils-5.0.org/src/copy.c coreutils-5.0/src/copy.c --- coreutils-5.0.org/src/copy.c 2003-12-27 12:26:28.939093576 +0100 +++ coreutils-5.0/src/copy.c 2003-12-27 12:26:52.935445576 +0100 @@ -46,6 +46,11 @@ #include "same.h" #include "xreadlink.h" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +extern int selinux_enabled; +#endif + #define DO_CHOWN(Chown, File, New_uid, New_gid) \ (Chown (File, New_uid, New_gid) \ /* If non-root uses -p, it's ok if we can't preserve ownership. \ @@ -1233,6 +1238,32 @@ In such cases, set this variable to zero. */ preserve_metadata = 1; +#ifdef WITH_SELINUX + if (x->preserve_security_context && selinux_enabled) + { + security_context_t con; + + if (lgetfilecon (src_path, &con) >= 0) + { + if (setfscreatecon(con) < 0) + { + freecon(con); + error (0, errno, _("cannot set setfscreatecon %s"), quote (con)); + return 1; + } + freecon(con); + } + else { + if ( errno == ENOTSUP ) { + error (0, errno, _("warning: security context not preserved %s"), quote (src_path)); + } else { + error (0, errno, _("cannot lgetfilecon %s"), quote (src_path)); + return 1; + } + } + } +#endif + if (S_ISDIR (src_mode)) { struct dir_list *dir; @@ -1302,8 +1333,13 @@ } /* Are we crossing a file system boundary? */ - if (x->one_file_system && device != 0 && device != src_sb.st_dev) + if (x->one_file_system && device != 0 && device != src_sb.st_dev) { +#ifdef WITH_SELINUX + if (x->preserve_security_context && selinux_enabled) + setfscreatecon(NULL); +#endif return 0; + } /* Copy the contents of the directory. */ @@ -1442,6 +1478,11 @@ } } +#ifdef WITH_SELINUX + if (x->preserve_security_context && selinux_enabled) + setfscreatecon(NULL); +#endif + /* There's no need to preserve timestamps or permissions. */ preserve_metadata = 0; @@ -1474,7 +1515,7 @@ if (command_line_arg) record_file (x->dest_info, dst_path, NULL); - if ( ! preserve_metadata) + if ( ! preserve_metadata) return 0; /* POSIX says that `cp -p' must restore the following: @@ -1576,6 +1617,11 @@ un_backup: +#ifdef WITH_SELINUX + if (x->preserve_security_context && selinux_enabled) + setfscreatecon(NULL); +#endif + /* We have failed to create the destination file. If we've just added a dev/ino entry via the remember_copied call above (i.e., unless we've just failed to create a hard link), diff -urN coreutils-5.0.org/src/copy.h coreutils-5.0/src/copy.h --- coreutils-5.0.org/src/copy.h 2003-12-27 12:26:28.948092208 +0100 +++ coreutils-5.0/src/copy.h 2003-12-27 12:26:52.937445272 +0100 @@ -105,6 +105,9 @@ int preserve_ownership; int preserve_mode; int preserve_timestamps; +#ifdef WITH_SELINUX + int preserve_security_context; +#endif /* Enabled for mv, and for cp by the --preserve=links option. If nonzero, attempt to preserve in the destination files any diff -urN coreutils-5.0.org/src/cp.c coreutils-5.0/src/cp.c --- coreutils-5.0.org/src/cp.c 2003-12-27 12:26:28.939093576 +0100 +++ coreutils-5.0/src/cp.c 2003-12-27 12:26:52.938445120 +0100 @@ -52,6 +52,11 @@ #define AUTHORS N_ ("Torbjorn Granlund, David MacKenzie, and Jim Meyering") +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +int selinux_enabled=0; +#endif + #ifndef _POSIX_VERSION uid_t geteuid (); #endif @@ -149,6 +154,9 @@ {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */ +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -198,6 +206,9 @@ additional attributes: links, all\n\ "), stdout); fputs (_("\ + -c same as --preserve=context\n\ +"), stdout); + fputs (_("\ --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents append source path to DIRECTORY\n\ -P same as `--no-dereference'\n\ @@ -225,6 +236,7 @@ destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ + -Z, --context=CONTEXT set security context of copy to CONTEXT\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); @@ -756,8 +768,8 @@ { new_dest = (char *) dest; } - - return copy (source, new_dest, new_dst, x, &unused, NULL); + ret=copy (source, new_dest, new_dst, x, &unused, NULL); + return ret; } /* unreachable */ @@ -781,6 +793,10 @@ x->preserve_mode = 0; x->preserve_timestamps = 0; +#ifdef WITH_SELINUX + x->preserve_security_context = 0; +#endif + x->require_preserve = 0; x->recursive = 0; x->sparse_mode = SPARSE_AUTO; @@ -808,19 +824,20 @@ PRESERVE_TIMESTAMPS, PRESERVE_OWNERSHIP, PRESERVE_LINK, + PRESERVE_CONTEXT, PRESERVE_ALL }; static enum File_attribute const preserve_vals[] = { PRESERVE_MODE, PRESERVE_TIMESTAMPS, - PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL + PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL }; /* Valid arguments to the `--preserve' option. */ static char const* const preserve_args[] = { "mode", "timestamps", - "ownership", "links", "all", 0 + "ownership", "links", "context", "all", 0 }; char *arg_writable = xstrdup (arg); @@ -855,11 +872,16 @@ x->preserve_links = on_off; break; + case PRESERVE_CONTEXT: + x->preserve_security_context = on_off; + break; + case PRESERVE_ALL: x->preserve_mode = on_off; x->preserve_timestamps = on_off; x->preserve_ownership = on_off; x->preserve_links = on_off; + x->preserve_security_context = on_off; break; default: @@ -882,6 +904,10 @@ struct cp_options x; int copy_contents = 0; char *target_directory = NULL; +#ifdef WITH_SELINUX + security_context_t scontext = NULL; + selinux_enabled= (is_selinux_enabled() > 0); +#endif program_name = argv[0]; setlocale (LC_ALL, ""); @@ -896,7 +922,11 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); +#ifdef WITH_SELINUX + while ((c = getopt_long (argc, argv, "abcdfHilLprsuvxPRS:V:Z:", long_opts, NULL)) +#else while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:", long_opts, NULL)) +#endif != -1) { switch (c) @@ -987,6 +1017,36 @@ x.preserve_timestamps = 1; x.require_preserve = 1; break; +#ifdef WITH_SELINUX + case 'c': + if ( scontext != NULL ) { + (void) fprintf(stderr, _("%s: cannot force target context <-- %s and preserve it\n"), argv[0], scontext); + exit( 1 ); + } + else if (selinux_enabled) + x.preserve_security_context = 1; + break; + + case 'Z': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( !selinux_enabled ) { + fprintf( stderr, _("Warning: ignoring --context (-Z). " + "It requires a SELinux-enabled kernel.\n") ); + break; + } + if ( x.preserve_security_context ) { + (void) fprintf(stderr, _("%s: cannot force target context to '%s' and preserve it\n"), argv[0], optarg); + exit( 1 ); + } + scontext = optarg; + /* if there's a security_context given set new path + components to that context, too */ + if ( setfscreatecon(scontext) < 0 ) { + (void) fprintf(stderr, _("cannot set default security context %s"), scontext); + exit( 1 ); + } + break; +#endif case PARENTS_OPTION: flag_path = 1; diff -urN coreutils-5.0.org/src/id.c coreutils-5.0/src/id.c --- coreutils-5.0.org/src/id.c 2003-12-27 12:26:28.951091752 +0100 +++ coreutils-5.0/src/id.c 2003-12-27 12:26:52.939444968 +0100 @@ -46,6 +46,20 @@ int getugroups (); +#ifdef WITH_SELINUX +#include +static void print_context PARAMS ((char* context)); +/* Print the SELinux context */ +static void +print_context(char *context) +{ + printf ("%s", context); +} + +/* If nonzero, output only the SELinux context. -Z */ +static int just_context = 0; + +#endif static void print_user (uid_t uid); static void print_group (gid_t gid); static void print_group_list (const char *username); @@ -64,8 +78,14 @@ /* The number of errors encountered so far. */ static int problems = 0; +/* The SELinux context */ +/* Set `context' to a known invalid value so print_full_info() will * + * know when `context' has not been set to a meaningful value. */ +static security_context_t context=NULL; + static struct option const longopts[] = { + {"context", no_argument, NULL, 'Z'}, {"group", no_argument, NULL, 'g'}, {"groups", no_argument, NULL, 'G'}, {"name", no_argument, NULL, 'n'}, @@ -89,6 +109,7 @@ Print information for USERNAME, or the current user.\n\ \n\ -a ignore, for compatibility with other versions\n\ + -Z, --context print only the context\n\ -g, --group print only the effective group ID\n\ -G, --groups print all group IDs\n\ -n, --name print a name instead of a number, for -ugG\n\ @@ -110,6 +131,7 @@ main (int argc, char **argv) { int optc; + int selinux_enabled=(is_selinux_enabled() > 0); /* If nonzero, output the list of all group IDs. -G */ int just_group_list = 0; @@ -127,7 +149,7 @@ atexit (close_stdout); - while ((optc = getopt_long (argc, argv, "agnruG", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1) { switch (optc) { @@ -136,6 +158,17 @@ case 'a': /* Ignore -a, for compatibility with SVR4. */ break; +#ifdef WITH_SELINUX + case 'Z': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( !selinux_enabled ) { + fprintf( stderr, _("Sorry, --context (-Z) can be used only on " + "a SELinux-enabled kernel.\n") ); + exit( 1 ); + } + just_context = 1; + break; +#endif case 'g': just_group = 1; break; @@ -158,8 +191,28 @@ } } - if (just_user + just_group + just_group_list > 1) - error (EXIT_FAILURE, 0, _("cannot print only user and only group")); +#ifdef WITH_SELINUX + if (argc - optind == 1) + selinux_enabled = 0; + + if( just_context && !selinux_enabled) + error (1, 0, _("\ +cannot display context when SELinux not enabled or when displaying the id\n\ +of a different user")); + + /* If we are on a selinux-enabled kernel, get our context. * + * Otherwise, leave the context variable alone - it has * + * been initialized known invalid value; if we see this invalid * + * value later, we will know we are on a non-selinux kernel. */ + if( selinux_enabled ) + { + if (getcon(&context)) + error (1, 0, _("can't get process context")); + } +#endif + + if (just_user + just_group + just_group_list + just_context > 1) + error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice")); if (just_user + just_group + just_group_list == 0 && (use_real || use_name)) error (EXIT_FAILURE, 0, @@ -190,6 +243,10 @@ print_group (use_real ? rgid : egid); else if (just_group_list) print_group_list (argv[optind]); +#ifdef WITH_SELINUX + else if (just_context) + print_context (context); +#endif else print_full_info (argv[optind]); putchar ('\n'); @@ -397,4 +454,9 @@ free (groups); } #endif /* HAVE_GETGROUPS */ +#ifdef WITH_SELINUX + if ( context != NULL ) { + printf(_(" context=%s"),context); + } +#endif } diff -urN coreutils-5.0.org/src/install.c coreutils-5.0/src/install.c --- coreutils-5.0.org/src/install.c 2003-12-27 12:26:28.932094640 +0100 +++ coreutils-5.0/src/install.c 2003-12-27 12:26:52.941444664 +0100 @@ -50,6 +50,11 @@ # include #endif +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +int selinux_enabled=0; +#endif + struct passwd *getpwnam (); struct group *getgrnam (); @@ -126,11 +131,17 @@ static struct option const long_options[] = { {"backup", optional_argument, NULL, 'b'}, +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {"directory", no_argument, NULL, 'd'}, {"group", required_argument, NULL, 'g'}, {"mode", required_argument, NULL, 'm'}, {"owner", required_argument, NULL, 'o'}, {"preserve-timestamps", no_argument, NULL, 'p'}, +#ifdef WITH_SELINUX + {"preserve_context", no_argument, NULL, 'P'}, +#endif {"strip", no_argument, NULL, 's'}, {"suffix", required_argument, NULL, 'S'}, {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */ @@ -247,6 +258,9 @@ x->update = 0; x->verbose = 0; +#ifdef WITH_SELINUX + x->preserve_security_context = 0; +#endif x->xstat = stat; x->dest_info = NULL; x->src_info = NULL; @@ -265,6 +279,11 @@ struct cp_options x; int n_files; char **file; +#ifdef WITH_SELINUX + security_context_t scontext = NULL; + /* set iff kernel has extra selinux system calls */ + selinux_enabled = (is_selinux_enabled() >= 0); +#endif program_name = argv[0]; setlocale (LC_ALL, ""); @@ -285,7 +304,11 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); +#ifdef WITH_SELINUX + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPvV:S:Z:", long_options, +#else while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pvV:S:", long_options, +#endif NULL)) != -1) { switch (optc) @@ -338,6 +361,39 @@ make_backups = 1; backup_suffix_string = optarg; break; +#ifdef WITH_SELINUX + case 'P': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( !selinux_enabled ) { + fprintf( stderr, _("Warning: ignoring --preserve_context (-P) " + "because the kernel is not SELinux-enabled.\n") ); + break; + } + if ( scontext!=NULL ) { /* scontext could be NULL because of calloc() failure */ + (void) fprintf(stderr, _("%s: cannot force target context to '%s' and preserve it\n"), argv[0], scontext); + exit( 1 ); + } + x.preserve_security_context = 1; + break ; + case 'Z': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( !selinux_enabled) { + fprintf( stderr, _("Warning: ignoring --context (-Z) " + "because the kernel is not SELinux-enabled.\n") ); + break; + } + if ( x.preserve_security_context ) { + + (void) fprintf(stderr, _("%s: cannot force target context == '%s' and preserve it\n"), argv[0], optarg); + exit( 1 ); + } + scontext = optarg; + if (setfscreatecon(scontext)) { + (void) fprintf(stderr, _("%s: cannot setup default context == '%s'\n"), argv[0], scontext); + exit(1); + } + break; +#endif case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: @@ -721,6 +777,11 @@ -S, --suffix=SUFFIX override the usual backup suffix\n\ -v, --verbose print the name of each directory as it is created\n\ "), stdout); + fputs (_("\ + -P, --preserve_context (SELinux) Preserve security context\n\ + -Z, --context=CONTEXT (SELinux) Set security context of files and directories\n\ +"), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\ diff -urN coreutils-5.0.org/src/ls.c coreutils-5.0/src/ls.c --- coreutils-5.0.org/src/ls.c 2003-12-27 12:26:28.947092360 +0100 +++ coreutils-5.0/src/ls.c 2003-12-27 12:42:14.887287592 +0100 @@ -130,6 +130,18 @@ #define AUTHORS N_ ("Richard Stallman and David MacKenzie") +#ifdef WITH_SELINUX +#include +int selinux_enabled= 0; +static int print_scontext = 0; +#define check_selinux() if (!selinux_enabled) { \ + fprintf( stderr, _("Sorry, this option can only be used " \ + "on a SELinux-enabled kernel.\n" )); \ + exit( EXIT_FAILURE ); \ +} + +#endif + #define obstack_chunk_alloc malloc #define obstack_chunk_free free @@ -227,6 +239,10 @@ /* For long listings, true if the file has an access control list. */ bool have_acl; #endif + +#ifdef WITH_SELINUX + security_context_t scontext; +#endif }; #if HAVE_ACL || USE_ACL @@ -290,6 +306,9 @@ static void sort_files (void); static void parse_ls_color (void); void usage (int status); +#ifdef WITH_SELINUX +static void print_scontext_format PARAMS ((const struct fileinfo *f)); +#endif /* The name the program was run with, stripped of any leading path. */ char *program_name; @@ -379,7 +398,10 @@ one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ - with_commas /* -m */ +#ifdef WITH_SELINUX + security_format, /* -Z */ +#endif + with_commas /* -m */ }; static enum format format; @@ -700,6 +722,11 @@ SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, +#ifdef WITH_SELINUX + CONTEXT_OPTION, + LCONTEXT_OPTION, + SCONTEXT_OPTION, +#endif TIME_OPTION, TIME_STYLE_OPTION }; @@ -743,6 +770,11 @@ {"time-style", required_argument, 0, TIME_STYLE_OPTION}, {"color", optional_argument, 0, COLOR_OPTION}, {"block-size", required_argument, 0, BLOCK_SIZE_OPTION}, +#ifdef WITH_SELINUX + {"context", no_argument, 0, CONTEXT_OPTION}, + {"lcontext", no_argument, 0, LCONTEXT_OPTION}, + {"scontext", no_argument, 0, SCONTEXT_OPTION}, +#endif {"author", no_argument, 0, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -752,12 +784,19 @@ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", - "vertical", "single-column", 0 + "vertical", "single-column", +#ifdef WITH_SELINUX + "context", +#endif + 0 }; static enum format const format_types[] = { long_format, long_format, with_commas, horizontal, horizontal, +#ifdef WITH_SELINUX + security_format, +#endif many_per_line, one_per_line }; @@ -1121,6 +1160,9 @@ format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format +#ifdef WITH_SELINUX + || format == security_format || print_scontext +#endif || dereference == DEREF_ALWAYS || print_block_size || print_inode; format_needs_type = (format_needs_stat == 0 @@ -1243,6 +1285,11 @@ /* Record whether there is an option specifying sort type. */ int sort_type_specified = 0; +#ifdef WITH_SELINUX + /* 1 iff kernel has new selinux system calls */ + selinux_enabled= (is_selinux_enabled() > 0); +#endif + qmark_funny_chars = 0; /* initialize all switches to default settings */ @@ -1293,6 +1340,9 @@ all_files = 0; really_all_files = 0; ignore_patterns = 0; +#ifdef WITH_SELINUX + print_scontext = 0; +#endif /* FIXME: put this in a function. */ { @@ -1370,7 +1420,7 @@ } while ((c = getopt_long (argc, argv, - "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1", + "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1Z", long_options, NULL)) != -1) { switch (c) @@ -1490,6 +1540,13 @@ format = horizontal; break; +#ifdef WITH_SELINUX + case 'Z': + check_selinux(); + print_scontext = 1; + format = security_format; + break; +#endif case 'A': really_all_files = 0; all_files = 1; @@ -1657,6 +1714,25 @@ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); +#ifdef WITH_SELINUX + + case CONTEXT_OPTION: /* new security format */ + check_selinux(); + print_scontext = 1; + format = security_format; + break; + case LCONTEXT_OPTION: /* long format plus security context */ + check_selinux(); + print_scontext = 1; + format = long_format; + break; + case SCONTEXT_OPTION: /* short form of new security format */ + check_selinux(); + print_scontext = 0; + format = security_format; + break; +#endif + default: usage (EXIT_FAILURE); } @@ -2308,6 +2384,12 @@ free (files[i].name); if (files[i].linkname) free (files[i].linkname); +#ifdef WITH_SELINUX + if (files[i].scontext) { + freecon (files[i].scontext); + files[i].scontext=NULL; + } +#endif } files_index = 0; @@ -2334,6 +2416,9 @@ files[files_index].linkname = 0; files[files_index].linkmode = 0; files[files_index].linkok = 0; +#ifdef WITH_SELINUX + files[files_index].scontext = NULL; +#endif if (explicit_arg || format_needs_stat @@ -2379,6 +2464,11 @@ { int need_lstat; err = stat (path, &files[files_index].stat); +#ifdef WITH_SELINUX + if (err>=0) + if (selinux_enabled && (format == security_format || print_scontext)) + getfilecon(path, &files[files_index].scontext); +#endif if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) break; @@ -2397,6 +2487,11 @@ default: /* DEREF_NEVER */ err = lstat (path, &files[files_index].stat); +#ifdef WITH_SELINUX + if (err>=0) + if (selinux_enabled && (format == security_format || print_scontext)) + lgetfilecon(path, &files[files_index].scontext); +#endif break; } @@ -2825,6 +2920,16 @@ DIRED_PUTCHAR ('\n'); } break; + +#ifdef WITH_SELINUX + case security_format: + for (i = 0; i < files_index; i++) + { + print_scontext_format (files + i); + DIRED_PUTCHAR ('\n'); + } + break; +#endif } } @@ -3088,6 +3193,14 @@ p += strlen (p); } +#ifdef WITH_SELINUX + + if ( print_scontext ) { + sprintf (p, "%-32s ", f->scontext); + p += strlen (p); + } +#endif + DIRED_INDENT (); DIRED_FPUTS (buf, stdout, p - buf); print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, @@ -3883,6 +3996,16 @@ -X sort alphabetically by entry extension\n\ -1 list one file per line\n\ "), stdout); +#ifdef WITH_SELINUX +printf(_("SELinux options:\n\n\ + --lcontext Display security context. Enable -l. Lines\n\ + will probably be too wide for most displays.\n\ + --context Display security context so it fits on most\n\ + displays. Displays only mode, user, group,\n\ + security context and file name.\n\ + --scontext Display only security context and file name.\n\ +")); +#endif fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\n\ @@ -3901,3 +4024,79 @@ } exit (status); } + +#ifdef WITH_SELINUX + +static void +print_scontext_format (const struct fileinfo *f) +{ + char modebuf[12]; + + /* 7 fields that may require LONGEST_HUMAN_READABLE bytes, + 1 10-byte mode string, + 9 spaces, one following each of these fields, and + 1 trailing NUL byte. */ + + char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1]; + char *buf = init_bigbuf; + size_t bufsize = sizeof (init_bigbuf); + size_t s; + char *p; + const char *fmt; + char *user_name; + char *group_name; + int rv; + char *scontext; + + p = buf; + + if ( print_scontext ) { /* zero means terse listing */ + mode_string (f->stat.st_mode, modebuf); + modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' '); + modebuf[11] = '\0'; + + /* print mode */ + + (void) sprintf (p, "%s ", modebuf); + p += strlen (p); + + /* print standard user and group */ + + user_name = (numeric_ids ? NULL : getuser (f->stat.st_uid)); + if (user_name) + (void) sprintf (p, "%-8.8s ", user_name); + else + (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_uid); + p += strlen (p); + + if ( print_group ) { + group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid)); + if (group_name) + (void) sprintf (p, "%-8.8s ", group_name); + else + (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_gid); + p += strlen (p); + } + } + + (void) sprintf (p, "%-32s ", f->scontext); + p += strlen (p); + + DIRED_INDENT (); + DIRED_FPUTS (buf, stdout, p - buf); + print_name_with_quoting (f->name, f->stat.st_mode, f->linkok, &dired_obstack); + + if (f->filetype == symbolic_link) { + if (f->linkname) { + DIRED_FPUTS_LITERAL (" -> ", stdout); + print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, NULL); + if (indicator_style != none) + print_type_indicator (f->linkmode); + } + } + else { + if (indicator_style != none) + print_type_indicator (f->stat.st_mode); + } +} +#endif diff -urN coreutils-5.0.org/src/Makefile.am coreutils-5.0/src/Makefile.am --- coreutils-5.0.org/src/Makefile.am 2003-12-27 12:26:28.928095248 +0100 +++ coreutils-5.0/src/Makefile.am 2003-12-27 12:37:59.212156120 +0100 @@ -4,13 +4,13 @@ EXTRA_SCRIPTS = nohup bin_SCRIPTS = groups @OPTIONAL_BIN_ZCRIPTS@ -bin_PROGRAMS = chgrp chown chmod cp dd dircolors du \ +bin_PROGRAMS = chgrp chown chmod chcon cp dd dircolors du \ ginstall link ln dir vdir ls mkdir \ mkfifo mknod mv readlink rm rmdir shred stat sync touch unlink \ cat cksum comm csplit cut expand fmt fold head join md5sum \ nl od paste pr ptx sha1sum sort split sum tac tail tr tsort unexpand uniq wc \ basename date dirname echo env expr factor false getgid \ - hostname id kill logname pathchk printenv printf pwd seq sleep tee \ + hostname id kill logname pathchk printenv printf runcon pwd seq sleep tee \ test true tty whoami yes \ @OPTIONAL_BIN_PROGS@ @DF_PROG@ @@ -34,13 +34,20 @@ # replacement functions defined in libfetish.a. LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a -dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) -ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) +dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@ +ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@ shred_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ -vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) -cp_LDADD = $(LDADD) $(LIBACL) -ginstall_LDADD = $(LDADD) $(LIBACL) -mv_LDADD = $(LDADD) $(LIBACL) +vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@ +cp_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@ +ginstall_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@ +mv_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@ +chcon_LDADD = $(LDADD) @LIB_SELINUX@ +id_LDADD = $(LDADD) @LIB_SELINUX@ +mkdir_LDADD = $(LDADD) @LIB_SELINUX@ +mkfifo_LDADD = $(LDADD) @LIB_SELINUX@ +mknod_LDADD = $(LDADD) @LIB_SELINUX@ +stat_LDADD = $(LDADD) @LIB_SELINUX@ +runcon_LDADD = $(LDADD) @LIB_SELINUX@ ## If necessary, add -lm to resolve use of pow in lib/strtod.c. sort_LDADD = $(LDADD) @POW_LIB@ diff -urN coreutils-5.0.org/src/mkdir.c coreutils-5.0/src/mkdir.c --- coreutils-5.0.org/src/mkdir.c 2003-12-27 12:26:28.950091904 +0100 +++ coreutils-5.0/src/mkdir.c 2003-12-27 12:26:52.958442080 +0100 @@ -34,6 +34,10 @@ #define AUTHORS "David MacKenzie" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +#endif + /* The name this program was run with. */ char *program_name; @@ -42,6 +46,9 @@ static struct option const longopts[] = { +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, @@ -63,6 +70,11 @@ Create the DIRECTORY(ies), if they do not already exist.\n\ \n\ "), stdout); +#ifdef WITH_SELINUX + printf (_("\ + -Z, --context=CONTEXT (SELinux) set security context to CONTEXT\n\ +")); +#endif fputs (_("\ Mandatory arguments to long options are mandatory for short options too.\n\ "), stdout); @@ -97,7 +109,11 @@ create_parents = 0; +#ifdef WITH_SELINUX + while ((optc = getopt_long (argc, argv, "pm:vZ:", longopts, NULL)) != -1) +#else while ((optc = getopt_long (argc, argv, "pm:v", longopts, NULL)) != -1) +#endif { switch (optc) { @@ -112,6 +128,20 @@ case 'v': /* --verbose */ verbose_fmt_string = _("created directory %s"); break; +#ifdef WITH_SELINUX + case 'Z': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( is_selinux_enabled() <= 0) { + fprintf( stderr, _("Sorry, --context (-Z) can be used only on " + "a SELinux-enabled kernel.\n") ); + exit( 1 ); + } + if (setfscreatecon(optarg)) { + fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg); + exit( 1 ); + } + break; +#endif case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: diff -urN coreutils-5.0.org/src/mkfifo.c coreutils-5.0/src/mkfifo.c --- coreutils-5.0.org/src/mkfifo.c 2003-12-27 12:26:28.933094488 +0100 +++ coreutils-5.0/src/mkfifo.c 2003-12-27 12:26:52.958442080 +0100 @@ -32,11 +32,18 @@ #define AUTHORS "David MacKenzie" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +#endif + /* The name this program was run with. */ char *program_name; static struct option const longopts[] = { +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -57,6 +64,11 @@ Create named pipes (FIFOs) with the given NAMEs.\n\ \n\ "), stdout); +#ifdef WITH_SELINUX + printf (_("\ + -Z, --context=CONTEXT set security context (quoted string)\n\ +"), stdout); +#endif fputs (_("\ Mandatory arguments to long options are mandatory for short options too.\n\ "), stdout); @@ -92,7 +104,11 @@ #ifndef S_ISFIFO error (4, 0, _("fifo files not supported")); #else +#ifdef WITH_SELINUX + while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1) +#else while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1) +#endif { switch (optc) { @@ -101,6 +117,19 @@ case 'm': specified_mode = optarg; break; +#ifdef WITH_SELINUX + case 'Z': + if( is_selinux_enabled() <= 0) { + fprintf( stderr, _("Sorry, --context (-Z) can be used only on " + "a SELinux-enabled kernel.\n") ); + exit( 1 ); + } + if (setfscreatecon(optarg)) { + fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg); + exit( 1 ); + } + break; +#endif case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: diff -urN coreutils-5.0.org/src/mknod.c coreutils-5.0/src/mknod.c --- coreutils-5.0.org/src/mknod.c 2003-12-27 12:26:28.936094032 +0100 +++ coreutils-5.0/src/mknod.c 2003-12-27 12:26:52.959441928 +0100 @@ -36,8 +36,15 @@ /* The name this program was run with. */ char *program_name; +#ifdef WITH_SELINUX +#include +#endif + static struct option const longopts[] = { +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -58,6 +65,11 @@ Create the special file NAME of the given TYPE.\n\ \n\ "), stdout); +#ifdef WITH_SELINUX + fputs(_("\ + -Z, --context=CONTEXT set security context (quoted string)\n\ +"), stdout); +#endif fputs (_("\ Mandatory arguments to long options are mandatory for short options too.\n\ "), stdout); @@ -102,7 +114,11 @@ specified_mode = NULL; +#ifdef WITH_SELINUX + while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1) +#else while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1) +#endif { switch (optc) { @@ -111,6 +127,20 @@ case 'm': specified_mode = optarg; break; +#ifdef WITH_SELINUX + case 'Z': + /* politely decline if we're not on a selinux-enabled kernel. */ + if( is_selinux_enabled() <= 0) { + fprintf( stderr, _("Sorry, --context (-Z) can be used only on " + "a SELinux-enabled kernel.\n") ); + exit( 1 ); + } + if (setfscreatecon(optarg)) { + fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg); + exit( 1 ); + } + break; +#endif case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: diff -urN coreutils-5.0.org/src/mv.c coreutils-5.0/src/mv.c --- coreutils-5.0.org/src/mv.c 2003-12-27 12:26:28.941093272 +0100 +++ coreutils-5.0/src/mv.c 2003-12-27 12:26:52.962441472 +0100 @@ -38,6 +38,11 @@ #include "quote.h" #include "remove.h" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +int selinux_enabled=0; +#endif + /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "mv" @@ -381,6 +386,10 @@ cp_option_init (&x); +#ifdef WITH_SELINUX + selinux_enabled= (is_selinux_enabled() > 0); +#endif + /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); diff -urN coreutils-5.0.org/src/runcon.c coreutils-5.0/src/runcon.c --- coreutils-5.0.org/src/runcon.c 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-5.0/src/runcon.c 2003-12-27 12:26:52.959441928 +0100 @@ -0,0 +1,174 @@ +/* + * runcon [ context | + * ( [ -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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include "system.h" +extern int errno; + +/* The name the program was run with. */ +char *program_name; + +void +usage(char *str) +{ + printf(_("Usage: %s [OPTION]... command [args]\n" + "Run a program in a different security context.\n\n" + " context Complete security context\n" + " -t type (for same role as parent)\n" + " -u user identity\n" + " -r role\n" + " -l levelrange\n" + " --help display this help and exit\n"), + program_name); + exit(1); +} + +int +main(int argc,char **argv,char **envp ) +{ + char *role = 0; + char *range = 0; + char *user = 0; + char *type = 0; + char *context = NULL; + security_context_t cur_context = NULL; + + context_t con; + + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + while (1) { + int c; + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + { "role", 1, 0, 'r' }, + { "type", 1, 0, 't' }, + { "user", 1, 0, 'u' }, + { "range", 1, 0, 'l' }, + { "help", 0, 0, '?' }, + { 0, 0, 0, 0 } + }; + c = getopt_long(argc, argv, "s:r:t:u:l:?", long_options, &option_index); + if ( c == -1 ) { + break; + } + switch ( c ) { + case 'r': + if ( role ) { + fprintf(stderr,_("multiple roles\n")); + exit(1); + } + role = optarg; + break; + case 't': + if ( type ) { + fprintf(stderr,_("multiple types\n")); + exit(1); + } + type = optarg; + break; + case 'u': + if ( user ) { + fprintf(stderr,_("multiple users\n")); + exit(1); + } + user = optarg; + break; + case 'l': + if ( range ) { + fprintf(stderr,_("multiple levelranges\n")); + exit(1); + } + range = optarg; + break; + default: + fprintf(stderr,_("unrecognised option %c\n"),c); + case '?': + usage(0); + break; + } + } + if ( !(user || role || type || range)) { + if ( optind >= argc ) { + usage(_("must specify -t, -u, -l, -r, or context")); + } + context = argv[optind++]; + } + + if ( optind >= argc ) { + usage(_("no command found")); + } + + if ( context ) { + con = context_new(context); + if (!con) { + fprintf(stderr,_("%s is not a valid context\n"), context); + exit(1); + } + } + else { + getcon(&cur_context); + con = context_new(cur_context); + if (!con) { + fprintf(stderr,_("%s is not a valid context\n"), context); + exit(1); + } + if ( user ) { + context_user_set(con,user); + } + if ( type ) { + context_type_set(con,type); + } + if ( range ) { + context_range_set(con,range); + } + if ( role ) { + context_role_set(con,role); + } + } + + if (setexeccon(context_str(con))!=0) { + fprintf(stderr,_("unable to setup security context %s\n"), context_str(con)); + exit(1); + } + if (cur_context!=NULL) + freecon(cur_context); + + if ( execvp(argv[optind],argv+optind) ) { + perror("execvp"); + exit(1); + } + return 1; /* can't reach this statement.... */ +} diff -urN coreutils-5.0.org/src/stat.c coreutils-5.0/src/stat.c --- coreutils-5.0.org/src/stat.c 2003-12-27 12:26:28.951091752 +0100 +++ coreutils-5.0/src/stat.c 2003-12-27 12:26:52.961441624 +0100 @@ -32,6 +32,13 @@ # include #endif +#ifdef WITH_SELINUX +#include +#define SECURITY_ID_T security_context_t +#else +#define SECURITY_ID_T char * +#endif + /* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ #if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H # if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H @@ -93,6 +100,7 @@ {"dereference", no_argument, 0, 'L'}, {"format", required_argument, 0, 'c'}, {"filesystem", no_argument, 0, 'f'}, + {"context", no_argument, 0, 'Z'}, {"terse", no_argument, 0, 't'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -332,7 +340,7 @@ /* print statfs info */ static void print_statfs (char *pformat, char m, char const *filename, - void const *data) + void const *data,SECURITY_ID_T scontext) { STRUCT_STATVFS const *statfsbuf = data; @@ -394,7 +402,10 @@ strcat (pformat, PRIdMAX); printf (pformat, (intmax_t) (statfsbuf->f_ffree)); break; - + case 'C': + strcat (pformat, "s"); + printf(scontext); + break; default: strcat (pformat, "c"); printf (pformat, m); @@ -404,7 +415,7 @@ /* print stat info */ static void -print_stat (char *pformat, char m, char const *filename, void const *data) +print_stat (char *pformat, char m, char const *filename, void const *data, SECURITY_ID_T scontext) { struct stat *statbuf = (struct stat *) data; struct passwd *pw_ent; @@ -537,6 +548,10 @@ strcat (pformat, "d"); printf (pformat, (int) statbuf->st_ctime); break; + case 'C': + strcat (pformat, "s"); + printf(pformat,scontext); + break; default: strcat (pformat, "c"); printf (pformat, m); @@ -546,8 +561,8 @@ static void print_it (char const *masterformat, char const *filename, - void (*print_func) (char *, char, char const *, void const *), - void const *data) + void (*print_func) (char *, char, char const *, void const *,SECURITY_ID_T ), + void const *data, SECURITY_ID_T scontext) { char *b; @@ -580,7 +595,7 @@ putchar ('%'); break; default: - print_func (dest, *p, filename, data); + print_func (dest, *p, filename, data,scontext); break; } b = p + 1; @@ -598,9 +613,17 @@ /* stat the filesystem and print what we find */ static void -do_statfs (char const *filename, int terse, char const *format) +do_statfs (char const *filename, int terse, int secure, char const *format) { STRUCT_STATVFS statfsbuf; + SECURITY_ID_T scontext = NULL; +#ifdef WITH_SELINUX + if(secure) + if (getfilecon(filename,&scontext)<0) { + perror (filename); + return; + } +#endif int i = statfs (filename, &statfsbuf); if (i == -1) @@ -612,23 +635,40 @@ if (format == NULL) { - format = (terse - ? "%n %i %l %t %b %f %a %s %c %d" - : " File: \"%n\"\n" - " ID: %-8i Namelen: %-7l Type: %T\n" - "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n" - "Inodes: Total: %-10c Free: %-10d"); - } - - print_it (format, filename, print_statfs, &statfsbuf); + if (terse) { + if(secure) + format = "%n %i %l %t %b %f %a %s %c %d %C"; + else + format = "%n %i %l %t %b %f %a %s %c %d"; + } + else + { + if(secure) + format = " File: \"%n\"\n" + " ID: %-8i Namelen: %-7l Type: %T\n" + "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n" + "Inodes: Total: %-10c Free: %-10d\n" + " S_Context: %C\n"; + else + format= " File: \"%n\"\n" + " ID: %-8i Namelen: %-7l Type: %T\n" + "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n" + "Inodes: Total: %-10c Free: %-10d"; + } + } + print_it (format, filename, print_statfs, &statfsbuf,scontext); +#ifdef WITH_SELINUX + if (scontext != NULL) + freecon(scontext); +#endif } - /* stat the file and print what we find */ static void -do_stat (char const *filename, int follow_links, int terse, + do_stat (char const *filename, int follow_links, int terse,int secure, char const *format) { struct stat statbuf; + SECURITY_ID_T scontext = NULL; int i = ((follow_links == 1) ? stat (filename, &statbuf) : lstat (filename, &statbuf)); @@ -639,11 +679,28 @@ return; } +#ifdef WITH_SELINUX + if(secure) { + if (link) + i=lgetfilecon(filename, &scontext); + else + i=getfilecon(filename, &scontext); + if (i == -1) + { + perror (filename); + return; + } + } +#endif + if (format == NULL) { if (terse != 0) { - format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; + if (secure) + format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C"; + else + format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; } else { @@ -651,7 +708,17 @@ i = statbuf.st_mode & S_IFMT; if (i == S_IFCHR || i == S_IFBLK) { - format = + if (secure) + format = + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %-5h" + " Device type: %t,%T\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + " S_Context: %C\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + else + format = " File: %N\n" " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" "Device: %Dh/%dd\tInode: %-10i Links: %-5h" @@ -661,6 +728,15 @@ } else { + if (secure) + format = + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %-5h\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + "S_Context: %C\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + else format = " File: %N\n" " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" @@ -670,7 +746,11 @@ } } } - print_it (format, filename, print_stat, &statbuf); + print_it (format, filename, print_stat, &statbuf,scontext); +#ifdef WITH_SELINUX + if (scontext) + freecon(scontext); +#endif } void @@ -688,6 +768,7 @@ -f, --filesystem display filesystem status instead of file status\n\ -c --format=FORMAT use the specified FORMAT instead of the default\n\ -L, --dereference follow links\n\ + -Z, --context print the security context\n\ -t, --terse print the information in terse form\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); @@ -739,6 +820,7 @@ %c Total file nodes in file system\n\ %d Free file nodes in file system\n\ %f Free blocks in file system\n\ + %C Security context in SELinux\n\ "), stdout); fputs (_("\ %i File System id in hex\n\ @@ -761,6 +843,7 @@ int follow_links = 0; int fs = 0; int terse = 0; + int secure = 0; char *format = NULL; program_name = argv[0]; @@ -770,7 +853,7 @@ atexit (close_stdout); - while ((c = getopt_long (argc, argv, "c:fLlt", long_options, NULL)) != -1) + while ((c = getopt_long (argc, argv, "c:fLltZ", long_options, NULL)) != -1) { switch (c) { @@ -787,6 +870,14 @@ case 't': terse = 1; break; + case 'Z': + if(is_selinux_enabled() > 0) + secure = 1; + else { + error (0, 0, _("Kernel is not SELinux-enabled")); + usage (EXIT_FAILURE); + } + break; case_GETOPT_HELP_CHAR; @@ -806,9 +897,9 @@ for (i = optind; i < argc; i++) { if (fs == 0) - do_stat (argv[i], follow_links, terse, format); + do_stat (argv[i], follow_links, terse, secure, format); else - do_statfs (argv[i], terse, format); + do_statfs (argv[i], terse, secure, format); } exit (G_fail ? EXIT_FAILURE : EXIT_SUCCESS); --- coreutils-5.0/po/POTFILES.in.orig 2003-12-29 00:25:44.000000000 +0100 +++ coreutils-5.0/po/POTFILES.in 2003-12-29 00:27:23.176769816 +0100 @@ -22,6 +22,7 @@ src/basename.c src/cat.c +src/chcon.c src/chgrp.c src/chmod.c src/chown-core.c @@ -79,6 +80,7 @@ src/remove.c src/rm.c src/rmdir.c +src/runcon.c src/seq.c src/shred.c src/sleep.c --- coreutils-5.0/po/pl.po.orig 2003-12-29 01:26:32.456197328 +0100 +++ coreutils-5.0/po/pl.po 2003-12-29 01:27:15.382671512 +0100 @@ -430,6 +430,95 @@ msgid "closing standard output" msgstr "zamknięcie standardowego wyjścia" +#: src/chcon.c:101 +#, c-format +msgid "context of %s changed to %s\n" +msgstr "kontekst %s zmieniony na %s\n" + +#: src/chcon.c:104 +#, c-format +msgid "failed to change context of %s to %s\n" +msgstr "nie można zmienić kontekstu %s na %s\n" + +#: src/chcon.c:107 +#, c-format +msgid "context of %s retained as %s\n" +msgstr "kontekst %s zachowany jako %s\n" + +#: src/chcon.c:166 +#, c-format +msgid "can't apply partial context to unlabeled file %s" +msgstr "nie można zastosować częściowego kontekstu na nieoznaczonym pliku %s" + +#: src/chcon.c:174 +#, c-format +msgid "couldn't compute security context from %s" +msgstr "nie można obliczyć kontekstu bezpieczeństwa z %s" + +#: src/chcon.c:182 +#, c-format +msgid "invalid context: %s" +msgstr "błędny kontekst: %s" + +#: src/chcon.c:204 +#, c-format +msgid "failed to change context of %s to %s" +msgstr "nie można zmienić kontekstu %s na %s" + +#: src/chcon.c:250 +msgid "virtual memory exhausted" +msgstr "pamięć wirtualna wyczerpana" + +#: src/chcon.c:284 +#, c-format +msgid "" +"Usage: %s [OPTION]... CONTEXT FILE...\n" +" or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n" +" or: %s [OPTION]... --reference=RFILE FILE...\n" +msgstr "" +"Składnia: %s [OPCJA]... KONTEKST PLIK...\n" +" albo: %s [OPCJA]... [-u UŻYTKOWNIK] [-r ROLA] [-l ZAKRES] [-t TYP] PLIK...\n" +" albo: %s [OPCJA]... --reference=PLIK_WZ PLIK...\n" + +#: src/chcon.c:290 +#, c-format +msgid "" +"Change the security context of each FILE to CONTEXT.\n" +"\n" +" -c, --changes like verbose but report only when a change is made\n" +" -h, --no-dereference affect symbolic links instead of any referenced file\n" +" (available only on systems with lchown system call)\n" +" -f, --silent, --quiet suppress most error messages\n" +" --reference=RFILE use RFILE's group instead of using a CONTEXT value\n" +" -u, --user=USER set user USER in the target security context\n" +" -r, --role=ROLE set role ROLE in the target security context\n" +" -t, --type=TYPE set type TYPE in the target security context\n" +" -l, --range=RANGE set range RANGE in the target security context\n" +" -R, --recursive change files and directories recursively\n" +" -v, --verbose output a diagnostic for every file processed\n" +" --help display this help and exit\n" +" --version output version information and exit\n" +msgstr "" +"Zmiana kontekstu bezpieczeństwa każdego PLIKU na KONTEKST.\n" +"\n" +" -c, --changes jak verbose, ale raportowanie tylko wykonanych zmian\n" +" -h, --no-dereference zmiana dowiązań symbolicznych zamiast wskazywanych\n" +" plików (dostępne tylko na systemach z lchown)\n" +" -f, --silent, --quiet pominięcie większości komunikatów o błędach\n" +" --reference=PLIK użycie grupy PLIKU zamiast wartości KONTEKSTU\n" +" -u, --user=UŻYTKOWNIK ustawienie UŻYTKOWNIK w kontekście bezpieczeństwa\n" +" -r, --role=ROLA ustawienie ROLI w kontekście bezpieczeństwa\n" +" -t, --type=TYP ustawienie TYPU w kontekście bezpieczeństwa\n" +" -l, --range=ZAKRES ustawienie ZAKRESU w kontekście bezpieczeństwa\n" +" -R, --recursive zmiana plików i katalogów rekursywnie\n" +" -v, --verbose wypisywanie diagnostyki dla każdego pliku\n" +" --help wyświetlenie tego opisu i zakończenie\n" +" --version wyświetlenie informacji o wersji i zakończenie\n" + +#: src/chcon.c:385 +msgid "conflicting security context specifiers given" +msgstr "konflikt między podanymi określeniami kontekstu bezpieczeństwa" + #: src/chgrp.c:93 msgid "cannot change to null group" msgstr "nie można zmienić grupy na pustą" @@ -945,6 +1034,21 @@ "nie udało się przeniesienie między urządzeniami: %s do %s; nie udało się " "usunać pliku docelowego" +#: src/copy.c:1251 +#, c-format +msgid "cannot set setfscreatecon %s" +msgstr "nie można ustawić setfscreatecon %s" + +#: src/copy.c:1258 +#, c-format +msgid "warning: security context not preserved %s" +msgstr "uwaga: nie zachowano kontekstu bezpieczeństwa %s" + +#: src/copy.c:1260 +#, c-format +msgid "cannot lgetfilecon %s" +msgstr "nie można wykonać lgetfilecon %s" + #: src/copy.c:1269 #, c-format msgid "cannot copy cyclic symbolic link %s" @@ -1117,6 +1221,10 @@ " atrybutów: links (dowiązania), all " "(wszystkie))\n" +#: src/cp.c:208 +msgid " -c same as --preserve=context\n" +msgstr " -c to samo co --preserve=context\n" + #: src/cp.c:199 msgid "" " --no-preserve=ATTR_LIST don't preserve the specified attributes\n" @@ -1173,12 +1281,13 @@ " destination file is missing\n" " -v, --verbose explain what is being done\n" " -x, --one-file-system stay on this file system\n" +" -Z, --context=CONTEXT set security context of copy to CONTEXT\n" msgstr "" " -u, --update kopiowanie tylko plików, dla których ŹRÓDŁO\n" " jest nowsze niż CEL albo brakuje CELU\n" " -v, --verbose wyjaśnianie co się dzieje\n" " -x, --one-file-system pozostanie w jednym systemie plików\n" -"\n" +" -Z, --context=KONTEKST ustawienie KONTEKSTU bezpieczeństwa kopii\n" #: src/cp.c:230 msgid "" @@ -1293,6 +1402,26 @@ "uwaga: opcja --version-control (-V) jest przestarzała i zostanie usunięta\n" "w jednej z następnych wersji. Używaj --backup=%s ." +#: src/cp.c:1023 +#, c-format +msgid "%s: cannot force target context <-- %s and preserve it\n" +msgstr "%s: nie można wymusić docelowego kontekstu <-- %s i zachować go\n" + +#: src/cp.c:1033 +#, c-format +msgid "Warning: ignoring --context (-Z). It requires a SELinux-enabled kernel.\n" +msgstr "Uwaga: zignorowano --context (-Z). Ta opcja wymaga jądra z obsługą SELinuksa.\n" + +#: src/cp.c:1038 src/install.c:373 +#, c-format +msgid "%s: cannot force target context to '%s' and preserve it\n" +msgstr "%s: nie można wymusić docelowego kontekstu na '%s' i zachować go\n" + +#: src/cp.c:1045 +#, c-format +msgid "cannot set default security context %s" +msgstr "nie można ustawić domyślnego kontekstu %s" + #: src/cp.c:972 src/ln.c:464 msgid "symbolic links are not supported on this system" msgstr "ten system nie ma dowiązań symbolicznych" @@ -2922,6 +3051,7 @@ "Print information for USERNAME, or the current user.\n" "\n" " -a ignore, for compatibility with other versions\n" +" -Z, --context print only the context\n" " -g, --group print only the effective group ID\n" " -G, --groups print all group IDs\n" " -n, --name print a name instead of a number, for -ugG\n" @@ -2930,8 +3060,8 @@ msgstr "" "Wyświetla informację o UŻYTKOWNIKU lub o aktualnym użytkowniku.\n" "\n" -" -a ignorowane, dla zachowania kompatybilności z innymi " -"wersjami\n" +" -a ignorowane, dla zachowania kompatybilności z innymi wersjami\n" +" -Z, --context wyświetlenie tylko kontekstu\n" " -g, --group wyświetlenie tylko efektywnego identyfikatora grupy\n" " -G, --groups wyświetlenie pełnej listy grup\n" " -n, --name wyświetlenie nazw zamiast numerów, dla -ugG\n" @@ -2948,9 +3078,26 @@ "Bez żadnych OPCJI wyświetla zestaw użytecznych informacji, które udało się\n" "zidentyfikować.\n" +#: src/id.c:165 src/mkdir.c:135 src/mkfifo.c:123 src/mknod.c:134 +#, c-format +msgid "Sorry, --context (-Z) can be used only on a SELinux-enabled kernel.\n" +msgstr "Niestety --context (-Z) można używać tylko na jądrze z obsługą SELinuksa.\n" + +#: src/id.c:199 +msgid "" +"cannot display context when SELinux not enabled or when displaying the id\n" +"of a different user" +msgstr "" +"nie można wyświetlić kontekstu kiedy SELinux nie jest włączony lub przy\n" +"wyświetlaniu identyfikatora innego użytkownika" + +#: src/id.c:210 +msgid "can't get process context" +msgstr "nie można uzyskać kontekstu procesu" + #: src/id.c:162 -msgid "cannot print only user and only group" -msgstr "nie można wypisać tylko użytkownika i tylko grupę równocześnie" +msgid "cannot print \"only\" of more than one choice" +msgstr "nie można \"tylko czegoś\" dla więcej niż jednej rzeczy" #: src/id.c:166 msgid "cannot print only names or real IDs in default format" @@ -2980,6 +3127,31 @@ msgid " groups=" msgstr " grupy=" +#: src/id.c:459 +#, c-format +msgid " context=%s" +msgstr " kontekst=%s" + +#: src/install.c:368 +#, c-format +msgid "Warning: ignoring --preserve_context (-P) because the kernel is not SELinux-enabled.\n" +msgstr "Uwaga: zignorowano --preserve_context (-P), ponieważ jądro nie ma obsługi SELinuksa.\n" + +#: src/install.c:381 +#, c-format +msgid "Warning: ignoring --context (-Z) because the kernel is not SELinux-enabled.\n" +msgstr "Uwaga: zignorowano --context (-Z), ponieważ jądro nie ma obsługi SELinuksa.\n" + +#: src/install.c:387 +#, c-format +msgid "%s: cannot force target context == '%s' and preserve it\n" +msgstr "%s: nie można wymusić docelowego kontekstu '%s' i zachować go\n" + +#: src/install.c:392 +#, c-format +msgid "%s: cannot setup default context == '%s'\n" +msgstr "%s: nie można ustawić domyślnego kontekstu '%s'\n" + #: src/install.c:269 msgid "the strip option may not be used when installing a directory" msgstr "opcja obcinania (strip) nie może być użyta przy instalowaniu katalogu" @@ -3117,6 +3289,14 @@ " -S, --suffix=ROZSZERZ zmiana domyślnego ROZSZERZENIA kopii zapasowej\n" " -v, --verbose wypisanie nazwy każdego tworzonego katalogu\n" +#: src/install.c:780 +msgid "" +" -P, --preserve_context (SELinux) Preserve security context\n" +" -Z, --context=CONTEXT (SELinux) Set security context of files and directories\n" +msgstr "" +" -P, --preserve_context (SELinux) zachowanie kontekstu bezpieczeństwa\n" +" -Z, --context=KONTEKST (SELinux) ustawienie kontekstu plików i katalogów\n" + #: src/install.c:635 src/ln.c:377 src/mv.c:348 msgid "" "\n" @@ -3497,6 +3677,11 @@ msgid "%s: no login name\n" msgstr "%s: brak nazwy użytkownika\n" +#: src/ls.c:138 +#, c-format +msgid "Sorry, this option can only be used on a SELinux-enabled kernel.\n" +msgstr "Niestety tej opcji można użyć tylko na jądrze z obsługą SELinuksa.\n" + #: src/ls.c:673 msgid "%b %e %Y" msgstr "%b %e %Y" @@ -3831,6 +4016,28 @@ " -X sortowanie alfabetyczne wg rozszerzeń\n" " -1 listowanie po jednym pliku w linii\n" +#: src/ls.c:4000 +#, c-format +msgid "" +"SELinux options:\n" +"\n" +" --lcontext Display security context. Enable -l. Lines\n" +" will probably be too wide for most displays.\n" +" --context Display security context so it fits on most\n" +" displays. Displays only mode, user, group,\n" +" security context and file name.\n" +" --scontext Display only security context and file name.\n" +msgstr "" +"Opcje dla SELinuksa:\n" +"\n" +" --lcontext wyświetlanie kontekstu bezpieczeństwa; włącza -l,\n" +" linie mogą być zbyt długie dla wielu terminali\n" +" --context wyświetlanie kontekstu tak, żeby zmieścił się na\n" +" większości terminali; wyświetlane są tylko\n" +" uprawnienia, właściciel, grupa, kontekst\n" +" bezpieczeństwa i nazwa pliku\n" +" --scontext wyświetlanie tylko kontekstu i nazwy pliku\n" + #: src/ls.c:3883 msgid "" "\n" @@ -4022,6 +4229,11 @@ "Utworzenie KATALOGU/ÓW, jeżeli jeszcze nie istnieją.\n" "\n" +#: src/mkdir.c:74 +#, c-format +msgid " -Z, --context=CONTEXT (SELinux) set security context to CONTEXT\n" +msgstr " -Z, --context=KONTEKST (SELinux) ustawienie KONTEKSTU bezpieczeństwa\n" + #: src/mkdir.c:69 msgid "" " -m, --mode=MODE set permission mode (as in chmod), not rwxrwxrwx - " @@ -4039,6 +4251,11 @@ msgid "created directory %s" msgstr "utworzony katalog %s" +#: src/mkdir.c:140 src/mkfifo.c:128 src/mknod.c:139 +#, c-format +msgid "Sorry, cannot set default context to %s.\n" +msgstr "Niestety nie można ustawić domyślnego kontekstu na %s.\n" + #: src/mkdir.c:190 #, c-format msgid "cannot set permissions of directory %s" @@ -4057,6 +4274,11 @@ "Tworzenie nazwanych potoków (pipes, FIFOs) o podanych NAZWACH.\n" "\n" +#: src/mkfifo.c:68 src/mknod.c:69 +#, c-format +msgid " -Z, --context=CONTEXT set security context (quoted string)\n" +msgstr " -Z, --context=KONTEKST ustawienie kontekstu bezpieczeństwa (łańcuch cytowany)\n" + #: src/mkfifo.c:63 src/mknod.c:64 msgid "" " -m, --mode=MODE set permission mode (as in chmod), not a=rw - umask\n" @@ -5670,6 +5892,72 @@ " -v, --verbose informacja diagnostyczna o każdym przetworzonym\n" " katalogu\n" +#: src/runcon.c:42 +#, c-format +msgid "" +"Usage: %s [OPTION]... command [args]\n" +"Run a program in a different security context.\n" +"\n" +" context Complete security context\n" +" -t type (for same role as parent)\n" +" -u user identity\n" +" -r role\n" +" -l levelrange\n" +" --help display this help and exit\n" +msgstr "" +"Składnia: %s [OPCJA]... polecenie [argumenty]\n" +"Uruchomienie programu w innym kontekście bezpieczeństwa.\n" +"\n" +" kontekst pełny kontekst bezpieczeństwa\n" +" -t typ (dla tej samej roli jako rodzica)\n" +" -u identyfikator użytkownika\n" +" -r rola\n" +" -l zakres poziomów\n" +" --help wyświetlenie tego opisu i zakończenie\n" + +#: src/runcon.c:90 +#, c-format +msgid "multiple roles\n" +msgstr "wiele ról\n" + +#: src/runcon.c:97 +#, c-format +msgid "multiple types\n" +msgstr "wiele typów\n" + +#: src/runcon.c:104 +#, c-format +msgid "multiple users\n" +msgstr "wielu użytkowników\n" + +#: src/runcon.c:111 +#, c-format +msgid "multiple levelranges\n" +msgstr "wiele zakresów poziomów\n" + +#: src/runcon.c:117 +#, c-format +msgid "unrecognised option %c\n" +msgstr "nierozpoznana opcja %c\n" + +#: src/runcon.c:125 +msgid "must specify -t, -u, -l, -r, or context" +msgstr "trzeba podać -t, -u, -l, -r albo kontekst" + +#: src/runcon.c:131 +msgid "no command found" +msgstr "nie znaleziono polecenia" + +#: src/runcon.c:137 src/runcon.c:145 +#, c-format +msgid "%s is not a valid context\n" +msgstr "%s nie jest poprawnym kontekstem\n" + +#: src/runcon.c:163 +#, c-format +msgid "unable to setup security context %s\n" +msgstr "nie można ustawić kontekstu bezpieczeństwa %s\n" + #: src/seq.c:82 #, c-format msgid "" @@ -6303,6 +6591,7 @@ " -f, --filesystem display filesystem status instead of file status\n" " -c --format=FORMAT use the specified FORMAT instead of the default\n" " -L, --dereference follow links\n" +" -Z, --context print the security context\n" " -t, --terse print the information in terse form\n" msgstr "" "Pokazanie danych pliku albo systemu plików\n" @@ -6310,6 +6599,7 @@ " -f, --filesystem pokazanie danych systemu plików, a nie pliku\n" " -c --format=FORMAT użycie podanego FORMATU zamiast domyślnego\n" " -L, --dereference rozwiązywanie dowiązań symbolicznych\n" +" -Z, --context wypisywanie kontekstu bezpieczeństwa\n" " -t, --terse wypisywanie informacji w skróconej formie\n" #: src/stat.c:696 @@ -6397,6 +6687,7 @@ " %c Total file nodes in file system\n" " %d Free file nodes in file system\n" " %f Free blocks in file system\n" +" %C Security context in SELinux\n" msgstr "" "Prawidłowe specyfikacje formatu dla systemów plików:\n" "\n" @@ -6405,6 +6696,7 @@ " %c całkowita liczba i-węzłów w systemie plików\n" " %d liczba wolnych i-węzłów w systemie plików\n" " %f liczba wolnych bloków w systemie plików\n" +" %C kontekst bezpieczeństwa w SELinuksie\n" #: src/stat.c:743 msgid "" @@ -6422,6 +6714,10 @@ " %T typ w formie czytelnej dla człowieka\n" " %t typ szesnastkowo\n" +#: src/stat.c:877 +msgid "Kernel is not SELinux-enabled" +msgstr "Jądro nie ma obsługi SELinuksa" + #: src/stty.c:498 #, c-format msgid ""