diff -Nur coreutils-6.4/README coreutils-6.4.selinux/README --- coreutils-6.4/README 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/README 2006-10-31 23:39:34.000000000 +0000 @@ -7,11 +7,11 @@ The programs that can be built with this package are: - [ base64 basename cat chgrp chmod chown chroot cksum comm cp csplit cut date + [ 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 ginstall groups head hostid hostname id 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 + 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 diff -Nur coreutils-6.4/configure.ac coreutils-6.4.selinux/configure.ac --- coreutils-6.4/configure.ac 2006-10-31 23:38:15.000000000 +0000 +++ coreutils-6.4.selinux/configure.ac 2006-10-31 23:39:34.000000000 +0000 @@ -264,6 +264,13 @@ LIB_CRYPT= fi +dnl Give the chance to enable SELINUX +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_CONFIG_FILES( Makefile doc/Makefile diff -Nur coreutils-6.4/lib/config.hin coreutils-6.4.selinux/lib/config.hin --- coreutils-6.4/lib/config.hin 2006-10-22 20:36:23.000000000 +0000 +++ coreutils-6.4.selinux/lib/config.hin 2006-10-31 23:39:34.000000000 +0000 @@ -1645,6 +1645,9 @@ 'wint_t'. */ #undef WINT_T_SUFFIX +/* Define if you want to use SELINUX */ +#undef WITH_SELINUX + /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN --- coreutils-6.5/man/Makefile.am.orig 2006-11-22 10:47:32.569505000 +0100 +++ coreutils-6.5/man/Makefile.am 2006-11-22 10:48:11.669505000 +0100 @@ -30,7 +30,7 @@ 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 \ - whoami.1 yes.1 $(MAN) + whoami.1 yes.1 chcon.1 runcon.1 $(MAN) optional_mans = \ chroot.1 hostid.1 nice.1 pinky.1 stty.1 uname.1 uptime.1 users.1 who.1 man_MANS = getgid.1 @@ -142,6 +142,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 -Nur coreutils-6.4/man/chcon.1 coreutils-6.4.selinux/man/chcon.1 --- coreutils-6.4/man/chcon.1 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/man/chcon.1 2006-10-31 23:39:34.000000000 +0000 @@ -0,0 +1,64 @@ +.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\-l\fR, \fB\-\-range\fR +set range RANGE in the target security context +.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\-r\fR, \fB\-\-role\fR +set role ROLE in the target security context +.TP +\fB\-t\fR, \fB\-\-type\fR +set type TYPE in the target security context +.TP +\fB\-u\fR, \fB\-\-user\fR +set user USER in the target security context +.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 -Nur coreutils-6.4/man/chcon.x coreutils-6.4.selinux/man/chcon.x --- coreutils-6.4/man/chcon.x 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/man/chcon.x 2006-10-31 23:39:34.000000000 +0000 @@ -0,0 +1,4 @@ +[NAME] +chcon \- change file security context +[DESCRIPTION] +.\" Add any additional description here diff -Nur coreutils-6.4/man/cp.1 coreutils-6.4.selinux/man/cp.1 --- coreutils-6.4/man/cp.1 2006-10-22 19:56:33.000000000 +0000 +++ coreutils-6.4.selinux/man/cp.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 @@ -106,6 +106,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 -Nur coreutils-6.4/man/dir.1 coreutils-6.4.selinux/man/dir.1 --- coreutils-6.4/man/dir.1 2006-10-22 19:56:34.000000000 +0000 +++ coreutils-6.4.selinux/man/dir.1 2006-10-31 23:39:34.000000000 +0000 @@ -204,6 +204,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 -Nur coreutils-6.4/man/id.1 coreutils-6.4.selinux/man/id.1 --- coreutils-6.4/man/id.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/id.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 -Nur coreutils-6.4/man/install.1 coreutils-6.4.selinux/man/install.1 --- coreutils-6.4/man/install.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/install.1 2006-10-31 23:39:34.000000000 +0000 @@ -66,6 +66,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 -Nur coreutils-6.4/man/ls.1 coreutils-6.4.selinux/man/ls.1 --- coreutils-6.4/man/ls.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/ls.1 2006-10-31 23:39:34.000000000 +0000 @@ -204,6 +204,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 -Nur coreutils-6.4/man/mkdir.1 coreutils-6.4.selinux/man/mkdir.1 --- coreutils-6.4/man/mkdir.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/mkdir.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 file mode (as in chmod), not a=rwx \- umask .TP diff -Nur coreutils-6.4/man/mkfifo.1 coreutils-6.4.selinux/man/mkfifo.1 --- coreutils-6.4/man/mkfifo.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/mkfifo.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 file permission bits to MODE, not a=rw \- umask .TP diff -Nur coreutils-6.4/man/mknod.1 coreutils-6.4.selinux/man/mknod.1 --- coreutils-6.4/man/mknod.1 2006-10-22 19:56:35.000000000 +0000 +++ coreutils-6.4.selinux/man/mknod.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 file permission bits to MODE, not a=rw \- umask .TP diff -Nur coreutils-6.4/man/runcon.1 coreutils-6.4.selinux/man/runcon.1 --- coreutils-6.4/man/runcon.1 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/man/runcon.1 2006-10-31 23:39:34.000000000 +0000 @@ -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 -Nur coreutils-6.4/man/runcon.x coreutils-6.4.selinux/man/runcon.x --- coreutils-6.4/man/runcon.x 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/man/runcon.x 2006-10-31 23:39:34.000000000 +0000 @@ -0,0 +1,2 @@ +[DESCRIPTION] +.\" Add any additional description here diff -Nur coreutils-6.4/man/stat.1 coreutils-6.4.selinux/man/stat.1 --- coreutils-6.4/man/stat.1 2006-10-22 19:56:37.000000000 +0000 +++ coreutils-6.4.selinux/man/stat.1 2006-10-31 23:39:34.000000000 +0000 @@ -28,6 +28,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 @@ -51,6 +54,9 @@ %d Device number in decimal .TP +%C +SELinux security context +.TP %D Device number in hex .TP diff -Nur coreutils-6.4/man/vdir.1 coreutils-6.4.selinux/man/vdir.1 --- coreutils-6.4/man/vdir.1 2006-10-22 19:56:39.000000000 +0000 +++ coreutils-6.4.selinux/man/vdir.1 2006-10-31 23:39:34.000000000 +0000 @@ -204,6 +204,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 -Nur coreutils-6.4/po/POTFILES.in coreutils-6.4.selinux/po/POTFILES.in --- coreutils-6.4/po/POTFILES.in 2006-10-31 23:38:15.000000000 +0000 +++ coreutils-6.4.selinux/po/POTFILES.in 2006-10-31 23:39:34.000000000 +0000 @@ -33,6 +33,7 @@ src/base64.c src/basename.c src/cat.c +src/chcon.c src/chgrp.c src/chmod.c src/chown-core.c @@ -91,6 +92,7 @@ src/remove.c src/rm.c src/rmdir.c +src/runcon.c src/seq.c src/setuidgid.c src/shred.c --- coreutils-6.7/po/pl.po.orig 2006-12-09 20:03:10.686071942 +0100 +++ coreutils-6.7/po/pl.po 2006-12-09 20:06:54.942851606 +0100 @@ -867,6 +867,95 @@ msgid "%s: input file is output file" msgstr "%s: plik wejściowy jest plikiem wyjściowym" +#: 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:172 +#, c-format +msgid "can't apply partial context to unlabeled file %s" +msgstr "nie można zastosować częściowego kontekstu na nieoznakowanym pliku %s" + +#: src/chcon.c:180 +#, c-format +msgid "couldn't compute security context from %s" +msgstr "nie można obliczyć kontekstu bezpieczeństwa z %s" + +#: src/chcon.c:188 +#, c-format +msgid "invalid context: %s" +msgstr "błędny kontekst: %s" + +#: src/chcon.c:210 +#, c-format +msgid "failed to change context of %s to %s" +msgstr "nie można zmienić kontekstu %s na %s" + +#: src/chcon.c:258 +msgid "virtual memory exhausted" +msgstr "pamięć wirtualna wyczerpana" + +#: src/chcon.c:292 +#, 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:298 +#, 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:393 +msgid "conflicting security context specifiers given" +msgstr "konflikt między podanymi określeniami kontekstu bezpieczeństwa" + #: src/chgrp.c:95 src/install.c:612 #, c-format msgid "invalid group %s" @@ -1540,6 +1629,21 @@ "nie udało się przeniesienie między urządzeniami: %s do %s; nie udało się " "usunać pliku docelowego" +#: src/copy.c:1305 +#, c-format +msgid "cannot set setfscreatecon %s" +msgstr "nie można ustawić setfscreatecon %s" + +#: src/copy.c:1315 +#, c-format +msgid "warning: security context not preserved %s" +msgstr "uwaga: nie zachowano kontekstu bezpieczeństwa %s" + +#: src/copy.c:1317 +#, c-format +msgid "cannot lgetfilecon %s" +msgstr "nie można wykonać lgetfilecon %s" + #: src/copy.c:1534 #, c-format msgid "cannot copy cyclic symbolic link %s" @@ -1688,6 +1792,10 @@ " atrybutów: links (dowiązania), all " "(wszystkie))\n" +#: src/cp.c:202 +msgid " -c same as --preserve=context\n" +msgstr " -c to samo co --preserve=context\n" + #: src/cp.c:196 msgid "" " --no-preserve=ATTR_LIST don't preserve the specified attributes\n" @@ -1740,12 +1848,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:225 msgid "" @@ -1874,6 +1983,26 @@ msgid "multiple target directories specified" msgstr "podano wiele katalogów docelowych" +#: src/cp.c:1017 +#, 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:1027 +#, 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:1031 src/install.c:369 +#, 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:1038 +#, c-format +msgid "cannot set default security context %s" +msgstr "nie można ustawić domyślnego kontekstu bezpieczeństwa %s" + #: src/cp.c:1016 #, c-format msgid "cannot make both hard and symbolic links" @@ -3880,6 +4009,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" @@ -3890,6 +4020,7 @@ "\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" @@ -3906,10 +4037,26 @@ "Bez żadnych OPCJI wyświetla zestaw użytecznych informacji, które udało się\n" "zidentyfikować.\n" -#: src/id.c:152 +#: src/id.c:165 src/mkdir.c:136 src/mkfifo.c:124 src/mknod.c:135 #, c-format -msgid "cannot print only user and only group" -msgstr "nie można wypisać tylko użytkownika i tylko grupę równocześnie" +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:198 +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:209 +msgid "can't get process context" +msgstr "nie można uzyskać kontekstu procesu" + +#: src/id.c:214 +msgid "cannot print \"only\" of more than one choice" +msgstr "nie można wypisać \"tylko czegoś\" dla więcej niż jednej rzeczy" #: src/id.c:156 #, c-format @@ -3941,6 +4088,31 @@ msgid " groups=" msgstr " grupy=" +#: src/id.c:458 +#, c-format +msgid " context=%s" +msgstr " kontekst=%s" + +#: src/install.c:365 +#, 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:377 +#, 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:382 +#, 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:387 +#, c-format +msgid "%s: cannot setup default context == '%s'\n" +msgstr "%s: nie można ustawić domyślnego kontekstu '%s'\n" + #: src/install.c:318 #, c-format msgid "the strip option may not be used when installing a directory" @@ -4079,6 +4251,14 @@ " -T, --no-target-directory traktowanie CELU jak zwykłego pliku\n" " -v, --verbose wypisanie nazwy każdego tworzonego katalogu\n" +#: src/install.c:773 +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:693 src/ln.c:365 src/mv.c:318 msgid "" "\n" @@ -4468,6 +4648,11 @@ msgid "no login name" msgstr "brak nazwy użytkownika" +#: src/ls.c:129 +#, 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:677 msgid "%b %e %Y" msgstr "%b %e %Y" @@ -4841,6 +5026,34 @@ " -X sortowanie alfabetyczne wg rozszerzeń\n" " -1 listowanie po jednym pliku w linii\n" +#: src/ls.c:4134 +#, c-format +msgid "" +"\n" +"SELinux options:\n" +"\n" +" --lcontext Display security context. Enable -l. Lines\n" +" will probably be too wide for most displays.\n" +" -Z, --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" +"\n" +"\n" +msgstr "" +"\n" +"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" +"\n" +"\n" + #: src/ls.c:4360 msgid "" "\n" @@ -5043,6 +5256,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:67 msgid "" " -m, --mode=MODE set file mode (as in chmod), not a=rwx - umask\n" @@ -5059,6 +5277,11 @@ msgid "created directory %s" msgstr "utworzony katalog %s" +#: src/mkdir.c:170 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/mkfifo.c:54 #, c-format msgid "Usage: %s [OPTION] NAME...\n" @@ -5072,6 +5295,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:62 src/mknod.c:64 msgid "" " -m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n" @@ -6808,6 +7036,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:74 #, c-format msgid "" @@ -7689,6 +7983,7 @@ " --printf=FORMAT like --format, but interpret backslash escapes,\n" " and do not output a mandatory trailing newline.\n" " If you want a newline, include \\n in FORMAT.\n" +" -Z, --context print the security context\n" " -t, --terse print the information in terse form\n" msgstr "" " -c --format=FORMAT użycie podanego FORMATU zamiast domyślnego; po\n" @@ -7699,6 +7994,7 @@ " ukośnikiem odwrotnym i bez wypisywania znaku " "nowej\n" " linii. Żeby go wypisać użyj \\n w FORMACIE.\n" +" -Z, --context wypisywanie kontekstu bezpieczeństwa\n" " -t, --terse wypisywanie informacji w skróconej formie\n" #: src/stat.c:849 @@ -7786,6 +8082,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" @@ -7794,6 +8091,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:896 msgid "" @@ -7813,6 +8111,10 @@ " %t typ szesnastkowo\n" " %T typ w formie czytelnej dla człowieka\n" +#: src/stat.c:900 +msgid "Kernel is not SELinux enabled" +msgstr "Jądro nie ma obsługi SELinuksa" + #: src/stty.c:511 #, c-format msgid "" diff -Nur coreutils-6.4/src/Makefile.am coreutils-6.4.selinux/src/Makefile.am --- coreutils-6.4/src/Makefile.am 2006-10-31 23:38:15.000000000 +0000 +++ coreutils-6.4.selinux/src/Makefile.am 2006-10-31 23:39:34.000000000 +0000 @@ -20,14 +20,14 @@ EXTRA_PROGRAMS = chroot df hostid nice pinky stty su uname uptime users who bin_SCRIPTS = groups -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 nohup 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 sha224sum sha256sum sha384sum sha512sum \ shuf 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 pwd runcon seq sleep tee \ test true tty whoami yes \ base64 \ $(OPTIONAL_BIN_PROGS) $(DF_PROG) @@ -112,6 +112,20 @@ mv_LDADD += $(LIB_ACL) ginstall_LDADD += $(LIB_ACL) +dir_LDADD += @LIB_SELINUX@ +ls_LDADD += @LIB_SELINUX@ +vdir_LDADD += @LIB_SELINUX@ +cp_LDADD += @LIB_SELINUX@ +ginstall_LDADD += @LIB_SELINUX@ +mv_LDADD += @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@ + $(PROGRAMS): ../lib/libcoreutils.a SUFFIXES = .sh diff -Nur coreutils-6.4/src/chcon.c coreutils-6.4.selinux/src/chcon.c --- coreutils-6.4/src/chcon.c 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/src/chcon.c 2006-10-31 23:39:34.000000000 +0000 @@ -0,0 +1,423 @@ +/* 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 (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; + int status = 0; + + if (change_symlinks) + status = lgetfilecon(file, &file_context); + else + status = getfilecon(file, &file_context); + + if ((status < 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 (file_context == NULL || 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) && + (strcmp(file,"..") !=0) && + (strcmp(file,".") !=0)) + 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 -Nur coreutils-6.4/src/copy.c coreutils-6.4.selinux/src/copy.c --- coreutils-6.4/src/copy.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/copy.c 2006-10-31 23:39:34.000000000 +0000 @@ -53,6 +53,11 @@ #include "xreadlink.h" #include "yesno.h" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +extern int selinux_enabled; +#endif + #ifndef HAVE_FCHOWN # define HAVE_FCHOWN false # define fchown(fd, uid, gid) (-1) @@ -1473,6 +1478,34 @@ In such cases, set this variable to zero. */ preserve_metadata = true; +#ifdef WITH_SELINUX + if (x->preserve_security_context && selinux_enabled) + { + security_context_t con; + + if (lgetfilecon (src_name, &con) >= 0) + { + if (setfscreatecon(con) < 0) + { + error (0, errno, _("cannot set setfscreatecon %s"), quote (con)); + if (x->require_preserve) { + freecon(con); + return 1; + } + } + freecon(con); + } + else { + if ( errno == ENOTSUP ) { + error (0, errno, _("warning: security context not preserved %s"), quote (src_name)); + } else { + error (0, errno, _("cannot lgetfilecon %s"), quote (src_name)); + return 1; + } + } + } +#endif + if (S_ISDIR (src_mode)) { struct dir_list *dir; @@ -1544,8 +1577,14 @@ } /* Are we crossing a file system boundary? */ - if (x->one_file_system && device != 0 && device != src_sb.st_dev) - return true; + + 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 true; + } /* Copy the contents of the directory. */ @@ -1689,6 +1728,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 = false; @@ -1789,6 +1833,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 -Nur coreutils-6.4/src/copy.h coreutils-6.4.selinux/src/copy.h --- coreutils-6.4/src/copy.h 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/copy.h 2006-10-31 23:39:34.000000000 +0000 @@ -128,6 +128,9 @@ bool preserve_mode; bool preserve_timestamps; +#ifdef WITH_SELINUX + bool preserve_security_context; +#endif /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's diff -Nur coreutils-6.4/src/cp.c coreutils-6.4.selinux/src/cp.c --- coreutils-6.4/src/cp.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/cp.c 2006-10-31 23:39:34.000000000 +0000 @@ -51,6 +51,11 @@ #define AUTHORS "Torbjorn Granlund", "David MacKenzie", "Jim Meyering" +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +int selinux_enabled=0; +#endif + /* Used by do_copy, make_dir_parents_private, and re_protect to keep a list of leading directories whose protections need to be fixed after copying. */ @@ -141,6 +146,9 @@ {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, +#ifdef WITH_SELINUX + {"context", required_argument, NULL, 'Z'}, +#endif {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -194,6 +202,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 use full source file name under DIRECTORY\n\ "), stdout); @@ -219,6 +230,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); @@ -729,6 +741,10 @@ x->preserve_mode = false; x->preserve_timestamps = false; +#ifdef WITH_SELINUX + x->preserve_security_context = false; +#endif + x->require_preserve = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; @@ -756,18 +772,19 @@ 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", NULL + "ownership", "links", "context", "all", NULL }; ARGMATCH_VERIFY (preserve_args, preserve_vals); @@ -803,11 +820,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: @@ -832,6 +854,10 @@ bool copy_contents = false; char *target_directory = NULL; bool no_target_directory = false; +#ifdef WITH_SELINUX + security_context_t scontext = NULL; + selinux_enabled= (is_selinux_enabled()>0); +#endif initialize_main (&argc, &argv); program_name = argv[0]; @@ -847,7 +873,13 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T", + + while ((c = getopt_long (argc, argv, +#ifdef WITH_SELINUX + "abcdfHilLprst:uvxPRS:TZ:", +#else + "abdfHilLprst:uvxPRS:T", +#endif long_opts, NULL)) != -1) { @@ -938,6 +970,35 @@ case 'R': x.recursive = true; 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 = true; + 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 REPLY_OPTION: /* Deprecated */ x.interactive = XARGMATCH ("--reply", optarg, diff -Nur coreutils-6.4/src/id.c coreutils-6.4.selinux/src/id.c --- coreutils-6.4/src/id.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/id.c 2006-10-31 23:39:34.000000000 +0000 @@ -37,6 +37,20 @@ int getugroups (); +#ifdef WITH_SELINUX +#include +static void print_context (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); @@ -55,8 +69,14 @@ /* True unless errors have been encountered. */ static bool ok = true; +/* 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'}, @@ -80,6 +100,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\ @@ -101,6 +122,7 @@ main (int argc, char **argv) { int optc; + int selinux_enabled=(is_selinux_enabled()>0); /* If true, output the list of all group IDs. -G */ bool just_group_list = false; @@ -119,13 +141,23 @@ 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) { 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 = true; break; @@ -148,8 +180,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, @@ -183,6 +235,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'); @@ -385,4 +441,9 @@ free (groups); } #endif /* HAVE_GETGROUPS */ +#ifdef WITH_SELINUX + if ( context != NULL ) { + printf(_(" context=%s"),context); + } +#endif } diff -Nur coreutils-6.4/src/install.c coreutils-6.4.selinux/src/install.c --- coreutils-6.4/src/install.c 2006-10-31 23:38:15.000000000 +0000 +++ coreutils-6.4.selinux/src/install.c 2006-10-31 23:39:34.000000000 +0000 @@ -50,6 +50,11 @@ # include #endif +#ifdef WITH_SELINUX +#include /* for is_selinux_enabled() */ +int selinux_enabled=0; +#endif + #if ! HAVE_ENDGRENT # define endgrent() ((void) 0) #endif @@ -128,12 +133,18 @@ 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'}, {"no-target-directory", no_argument, NULL, 'T'}, {"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'}, {"target-directory", required_argument, NULL, 't'}, @@ -250,6 +261,9 @@ x->update = false; x->verbose = false; +#ifdef WITH_SELINUX + x->preserve_security_context = false; +#endif x->dest_info = NULL; x->src_info = NULL; } @@ -302,6 +316,11 @@ bool no_target_directory = false; 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 initialize_main (&argc, &argv); program_name = argv[0]; @@ -323,8 +342,13 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:", long_options, - NULL)) != -1) + while ((optc = getopt_long (argc, argv, +#ifdef WITH_SELINUX + "bcCsDdg:m:o:pPt:TvS:Z:", +#else + "bcCsDdg:m:o:pt:TvS:", +#endif + long_options, NULL)) != -1) { switch (optc) { @@ -388,6 +412,37 @@ case 'T': no_target_directory = true; 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 = true; + 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: @@ -781,6 +836,11 @@ -T, --no-target-directory treat DEST as a normal file\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 -Nur coreutils-6.4/src/ls.c coreutils-6.4.selinux/src/ls.c --- coreutils-6.4/src/ls.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/ls.c 2006-10-31 23:39:34.000000000 +0000 @@ -110,6 +110,17 @@ #define AUTHORS "Richard Stallman", "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 @@ -175,6 +186,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 USE_ACL @@ -245,6 +260,9 @@ static void sort_files (void); static void parse_ls_color (void); void usage (int status); +#ifdef WITH_SELINUX +static void print_scontext_format (const struct fileinfo *f); +#endif /* The name this program was run with. */ char *program_name; @@ -353,7 +371,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; @@ -734,6 +755,11 @@ SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, +#ifdef WITH_SELINUX + CONTEXT_OPTION, + LCONTEXT_OPTION, + SCONTEXT_OPTION, +#endif TIME_OPTION, TIME_STYLE_OPTION }; @@ -780,6 +806,11 @@ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, 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, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -789,11 +820,18 @@ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", - "vertical", "single-column", NULL + "vertical", "single-column", +#ifdef WITH_SELINUX + "context", +#endif + NULL }; 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 }; ARGMATCH_VERIFY (format_args, format_types); @@ -1218,6 +1256,9 @@ format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format +#ifdef WITH_SELINUX + || format == security_format || print_scontext +#endif || print_block_size; format_needs_type = (! format_needs_stat && (recursive @@ -1361,6 +1402,11 @@ /* Record whether there is an option specifying sort type. */ bool sort_type_specified = false; +#ifdef WITH_SELINUX + /* 1 iff kernel has new selinux system calls */ + selinux_enabled= (is_selinux_enabled()>0); +#endif + qmark_funny_chars = false; /* initialize all switches to default settings */ @@ -1411,6 +1457,9 @@ ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; +#ifdef WITH_SELINUX + print_scontext = 0; +#endif /* FIXME: put this in a function. */ { @@ -1486,7 +1535,7 @@ } while ((c = getopt_long (argc, argv, - "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1", + "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1Z", long_options, NULL)) != -1) { switch (c) @@ -1609,6 +1658,13 @@ format = horizontal; break; +#ifdef WITH_SELINUX + case 'Z': + check_selinux(); + print_scontext = 1; + format = security_format; + break; +#endif case 'A': if (ignore_mode == IGNORE_DEFAULT) ignore_mode = IGNORE_DOT_AND_DOTDOT; @@ -1789,6 +1845,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 (LS_FAILURE); } @@ -2485,6 +2560,12 @@ { free (files[i].name); free (files[i].linkname); +#ifdef WITH_SELINUX + if (files[i].scontext) { + freecon (files[i].scontext); + files[i].scontext=NULL; + } +#endif } files_index = 0; @@ -2527,6 +2608,9 @@ memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; +#ifdef WITH_SELINUX + f->scontext = NULL; +#endif if (command_line_arg || format_needs_stat @@ -2582,7 +2666,12 @@ { bool need_lstat; err = stat (absolute_name, &f->stat); - +#ifdef WITH_SELINUX + if (err>=0) + if (selinux_enabled && (format == security_format || print_scontext)) + getfilecon(absolute_name, &f->scontext); +#endif + if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) break; @@ -2600,6 +2689,11 @@ default: /* DEREF_NEVER */ err = lstat (absolute_name, &f->stat); +#ifdef WITH_SELINUX + if (err>=0) + if (selinux_enabled && (format == security_format || print_scontext)) + lgetfilecon(absolute_name, &f->scontext); +#endif break; } @@ -3158,6 +3252,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 } } @@ -3412,6 +3516,14 @@ The latter is wrong when nlink_width is zero. */ p += strlen (p); +#ifdef WITH_SELINUX + + if ( print_scontext ) { + sprintf (p, "%-32s ", f->scontext); + p += strlen (p); + } +#endif + DIRED_INDENT (); if (print_owner | print_group | print_author) @@ -4347,6 +4459,16 @@ -X sort alphabetically by entry extension\n\ -1 list one file per line\n\ "), stdout); +#ifdef WITH_SELINUX +printf(_("\nSELinux options:\n\n\ + --lcontext Display security context. Enable -l. Lines\n\ + will probably be too wide for most displays.\n\ + -Z, --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\ +\n\n")); +#endif fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\n\ @@ -4370,3 +4492,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 */ + filemodestring (&f->stat, 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, f->stat_ok, f->filetype, &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, f->stat_ok, f->filetype, NULL); + if (indicator_style != none) + print_type_indicator (f->stat_ok, f->linkmode, f->filetype); + } + } + else { + if (indicator_style != none) + print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); + } +} +#endif diff -Nur coreutils-6.4/src/mkdir.c coreutils-6.4.selinux/src/mkdir.c --- coreutils-6.4/src/mkdir.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/mkdir.c 2006-10-31 23:39:34.000000000 +0000 @@ -35,11 +35,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'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, @@ -61,6 +68,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); @@ -154,7 +166,11 @@ atexit (close_stdout); +#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) { @@ -167,6 +183,19 @@ case 'v': /* --verbose */ options.created_directory_format = _("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 -Nur coreutils-6.4/src/mkfifo.c coreutils-6.4.selinux/src/mkfifo.c --- coreutils-6.4/src/mkfifo.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/mkfifo.c 2006-10-31 23:39:34.000000000 +0000 @@ -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}, @@ -56,6 +63,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); @@ -85,13 +97,31 @@ atexit (close_stdout); - while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, +#ifdef WITH_SELINUX + "m:Z:", +#else + "m:", +#endif + longopts, NULL)) != -1) { switch (optc) { 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 -Nur coreutils-6.4/src/mknod.c coreutils-6.4.selinux/src/mknod.c --- coreutils-6.4/src/mknod.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/mknod.c 2006-10-31 23:39:34.000000000 +0000 @@ -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); @@ -101,13 +113,30 @@ atexit (close_stdout); +#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) { 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 -Nur coreutils-6.4/src/mv.c coreutils-6.4.selinux/src/mv.c --- coreutils-6.4/src/mv.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/mv.c 2006-10-31 23:39:34.000000000 +0000 @@ -33,6 +33,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" @@ -125,6 +130,9 @@ x->preserve_links = true; x->preserve_mode = true; x->preserve_timestamps = true; +#ifdef WITH_SELINUX + x->preserve_security_context = true; +#endif x->require_preserve = false; /* FIXME: maybe make this an option */ x->recursive = true; x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ @@ -356,6 +364,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 -Nur coreutils-6.4/src/runcon.c coreutils-6.4.selinux/src/runcon.c --- coreutils-6.4/src/runcon.c 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-6.4.selinux/src/runcon.c 2006-10-31 23:39:34.000000000 +0000 @@ -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 -Nur coreutils-6.4/src/stat.c coreutils-6.4.selinux/src/stat.c --- coreutils-6.4/src/stat.c 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/src/stat.c 2006-10-31 23:39:48.000000000 +0000 @@ -55,6 +55,13 @@ # include #endif +#ifdef WITH_SELINUX +#include +#define SECURITY_ID_T security_context_t +#else +#define SECURITY_ID_T char * +#endif + #include "system.h" #include "error.h" @@ -161,6 +168,7 @@ {"dereference", no_argument, NULL, 'L'}, {"file-system", no_argument, NULL, 'f'}, {"filesystem", no_argument, NULL, 'f'}, /* obsolete and undocumented alias */ + {"context", no_argument, 0, 'Z'}, {"format", required_argument, NULL, 'c'}, {"printf", required_argument, NULL, PRINTF_OPTION}, {"terse", no_argument, NULL, 't'}, @@ -397,7 +405,7 @@ /* print statfs info */ static void print_statfs (char *pformat, size_t prefix_len, char m, char const *filename, - void const *data) + void const *data, SECURITY_ID_T scontext) { STRUCT_STATVFS const *statfsbuf = data; @@ -472,7 +480,9 @@ case 'd': out_int (pformat, prefix_len, statfsbuf->f_ffree); break; - + case 'C': + out_string (pformat, prefix_len, scontext); + break; default: fputc ('?', stdout); break; @@ -482,7 +492,7 @@ /* print stat info */ static void print_stat (char *pformat, size_t prefix_len, char m, - char const *filename, void const *data) + char const *filename, void const *data, SECURITY_ID_T scontext) { struct stat *statbuf = (struct stat *) data; struct passwd *pw_ent; @@ -595,6 +605,9 @@ else out_uint (pformat, prefix_len, statbuf->st_ctime); break; + case 'C': + out_string (pformat, prefix_len, scontext); + break; default: fputc ('?', stdout); break; @@ -641,8 +654,8 @@ static void print_it (char const *format, char const *filename, - void (*print_func) (char *, size_t, char, char const *, void const *), - void const *data) + void (*print_func) (char *, size_t, char, char const *, void const *, SECURITY_ID_T), + void const *data, SECURITY_ID_T scontext) { /* Add 2 to accommodate our conversion of the stat `%s' format string to the longer printf `%llu' one. */ @@ -683,7 +696,7 @@ putchar ('%'); break; default: - print_func (dest, len + 1, *fmt_char, filename, data); + print_func (dest, len + 1, *fmt_char, filename, data, scontext); break; } break; @@ -746,9 +759,17 @@ /* Stat the file system and print what we find. */ static bool -do_statfs (char const *filename, bool terse, char const *format) +do_statfs (char const *filename, bool terse, bool 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 false; + } +#endif if (STATFS (filename, &statfsbuf) != 0) { @@ -759,25 +780,45 @@ if (format == NULL) { - format = (terse - ? "%n %i %l %t %s %S %b %f %a %c %d\n" - : " File: \"%n\"\n" - " ID: %-8i Namelen: %-7l Type: %T\n" - "Block size: %-10s Fundamental block size: %S\n" - "Blocks: Total: %-10b Free: %-10f Available: %a\n" - "Inodes: Total: %-10c Free: %d\n"); - } + if (terse) { + if(secure) + format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; + else + format = "%n %i %l %t %s %S %b %f %a %c %d\n"; + } + else + { + if(secure) + format = " File: \"%n\"\n" + " ID: %-8i Namelen: %-7l Type: %T\n" + "Block size: %-10s Fundamental block size: %S\n" + "Blocks: Total: %-10b Free: %-10f Available: %a\n" + "Inodes: Total: %-10c Free: %d\n" + " S_Context: %C\n"; + else + format = " File: \"%n\"\n" + " ID: %-8i Namelen: %-7l Type: %T\n" + "Block size: %-10s Fundamental block size: %S\n" + "Blocks: Total: %-10b Free: %-10f Available: %a\n" + "Inodes: Total: %-10c Free: %d\n"; + } + } + print_it (format, filename, print_statfs, &statfsbuf, scontext); +#ifdef WITH_SELINUX + if (scontext != NULL) + freecon(scontext); +#endif - print_it (format, filename, print_statfs, &statfsbuf); return true; } /* stat the file and print what we find */ static bool -do_stat (char const *filename, bool follow_links, bool terse, +do_stat (char const *filename, bool follow_links, bool terse, bool secure, char const *format) { struct stat statbuf; + SECURITY_ID_T scontext = NULL; if ((follow_links ? stat : lstat) (filename, &statbuf) != 0) { @@ -785,11 +826,29 @@ return false; } +#ifdef WITH_SELINUX + if(secure) { + int i; + if (follow_links) + i=lgetfilecon(filename, &scontext); + else + i=getfilecon(filename, &scontext); + if (i == -1) + { + perror (filename); + return false; + } + } +#endif + if (format == NULL) { if (terse) { - format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; + if (secure) + format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; + else + format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; } else { @@ -797,7 +856,17 @@ implemented. */ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) { - 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" @@ -807,6 +876,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" @@ -816,7 +894,11 @@ } } } - print_it (format, filename, print_stat, &statbuf); + print_it (format, filename, print_stat, &statbuf, scontext); +#ifdef WITH_SELINUX + if (scontext) + freecon(scontext); +#endif return true; } @@ -841,6 +923,7 @@ --printf=FORMAT like --format, but interpret backslash escapes,\n\ and do not output a mandatory trailing newline.\n\ If you want a newline, include \\n in FORMAT.\n\ + -Z, --context print the security context\n\ -t, --terse print the information in terse form\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); @@ -892,6 +975,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\ @@ -915,6 +999,7 @@ int i; bool follow_links = false; bool fs = false; + bool secure = false; bool terse = false; char *format = NULL; bool ok = true; @@ -927,7 +1012,7 @@ atexit (close_stdout); - while ((c = getopt_long (argc, argv, "c:fLt", long_options, NULL)) != -1) + while ((c = getopt_long (argc, argv, "c:fLtZ", long_options, NULL)) != -1) { switch (c) { @@ -946,6 +1031,14 @@ case 'L': follow_links = true; break; + case 'Z': + if((is_selinux_enabled()>0)) + secure = true; + else { + error (0, 0, _("Kernel is not SELinux enabled")); + usage (EXIT_FAILURE); + } + break; case 'f': fs = true; @@ -972,8 +1065,8 @@ for (i = optind; i < argc; i++) ok &= (fs - ? do_statfs (argv[i], terse, format) - : do_stat (argv[i], follow_links, terse, format)); + ? do_statfs (argv[i], terse, secure, format) + : do_stat (argv[i], follow_links, terse, secure, format)); exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } diff -Nur coreutils-6.4/tests/help-version coreutils-6.4.selinux/tests/help-version --- coreutils-6.4/tests/help-version 2006-10-22 16:54:15.000000000 +0000 +++ coreutils-6.4.selinux/tests/help-version 2006-10-31 23:39:34.000000000 +0000 @@ -70,6 +70,8 @@ # 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 @@ -190,7 +192,7 @@ for i in $all_programs; do # Skip these. - case $i in chroot|stty|tty|false) 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