]> git.pld-linux.org Git - packages/coreutils.git/blame - coreutils-selinux.patch
- updated info patch to restore "groups" docs
[packages/coreutils.git] / coreutils-selinux.patch
CommitLineData
0107077f
AM
1diff -urN coreutils-5.0.org/config.hin coreutils-5.0/config.hin
2--- coreutils-5.0.org/config.hin 2003-12-27 12:26:28.926095552 +0100
3+++ coreutils-5.0/config.hin 2003-12-27 12:28:20.345157280 +0100
4@@ -1427,3 +1427,7 @@
5 /* Define to empty if the keyword `volatile' does not work. Warning: valid
6 code using `volatile' can become incorrect without. Disable with care. */
7 #undef volatile
8+
9+/* Define if you want to use SELINUX */
10+#undef WITH_SELINUX
11+
12diff -urN coreutils-5.0.org/configure.ac coreutils-5.0/configure.ac
13--- coreutils-5.0.org/configure.ac 2003-12-27 12:26:28.584147536 +0100
14+++ coreutils-5.0/configure.ac 2003-12-27 12:27:54.896026136 +0100
15@@ -15,6 +15,13 @@
16 LIB_PAM="-ldl -lpam -lpam_misc"
17 )
18
19+dnl Give the chance to enable PAM
20+AC_ARG_ENABLE(selinux, dnl
21+[ --enable-selinux Enable use of the SELINUX libraries],
22+[AC_DEFINE(WITH_SELINUX, 1, [Define if you want to use SELINUX])
23+LIB_SELINUX="-lselinux"
24+AC_SUBST(LIB_SELINUX)])
25+
26 AC_GNU_SOURCE
27 jm_PERL
28 AC_PROG_CC
29diff -urN coreutils-5.0.org/man/chcon.1 coreutils-5.0/man/chcon.1
30--- coreutils-5.0.org/man/chcon.1 1970-01-01 01:00:00.000000000 +0100
31+++ coreutils-5.0/man/chcon.1 2003-12-27 12:26:52.965441016 +0100
32@@ -0,0 +1,52 @@
33+.TH CHCON 1 "July 2003" "chcon (coreutils) 5.0" "User Commands"
34+.SH NAME
35+chcon \- change security context
36+.SH SYNOPSIS
37+.B chcon
38+[\fIOPTION\fR]...\fI CONTEXT FILE\fR...
39+.br
40+.B chcon
41+[\fIOPTION\fR]...\fI --reference=RFILE FILE\fR...
42+.SH DESCRIPTION
43+.PP
44+." Add any additional description here
45+.PP
46+Change the security context of each FILE to CONTEXT.
47+.TP
48+\fB\-c\fR, \fB\-\-changes\fR
49+like verbose but report only when a change is made
50+.TP
51+\fB\-h\fR, \fB\-\-no\-dereference\fR
52+affect symbolic links instead of any referenced file (available only on systems with lchown system call)
53+.TP
54+\fB\-f\fR, \fB\-\-silent\fR, \fB\-\-quiet\fR
55+suppress most error messages
56+.TP
57+\fB\-\-reference\fR=\fIRFILE\fR
58+use RFILE's context instead of using a CONTEXT value
59+.TP
60+\fB\-R\fR, \fB\-\-recursive\fR
61+change files and directories recursively
62+.TP
63+\fB\-v\fR, \fB\-\-verbose\fR
64+output a diagnostic for every file processed
65+.TP
66+\fB\-\-help\fR
67+display this help and exit
68+.TP
69+\fB\-\-version\fR
70+output version information and exit
71+.SH "REPORTING BUGS"
72+Report bugs to <email@host.com>.
73+.SH "SEE ALSO"
74+The full documentation for
75+.B chcon
76+is maintained as a Texinfo manual. If the
77+.B info
78+and
79+.B chcon
80+programs are properly installed at your site, the command
81+.IP
82+.B info chcon
83+.PP
84+should give you access to the complete manual.
85diff -urN coreutils-5.0.org/man/chcon.x coreutils-5.0/man/chcon.x
86--- coreutils-5.0.org/man/chcon.x 1970-01-01 01:00:00.000000000 +0100
87+++ coreutils-5.0/man/chcon.x 2003-12-27 12:26:52.962441472 +0100
88@@ -0,0 +1,4 @@
89+[NAME]
90+chcon \- change file security context
91+[DESCRIPTION]
92+.\" Add any additional description here
93diff -urN coreutils-5.0.org/man/cp.1 coreutils-5.0/man/cp.1
94--- coreutils-5.0.org/man/cp.1 2003-12-27 12:26:28.509158936 +0100
95+++ coreutils-5.0/man/cp.1 2003-12-27 12:26:52.965441016 +0100
96@@ -57,7 +57,7 @@
97 .TP
98 \fB\-\-preserve\fR[=\fIATTR_LIST\fR]
99 preserve the specified attributes (default:
100-mode,ownership,timestamps), if possible
101+mode,ownership,timestamps) and security contexts, if possible
102 additional attributes: links, all
103 .TP
104 \fB\-\-no\-preserve\fR=\fIATTR_LIST\fR
105@@ -109,6 +109,9 @@
106 \fB\-\-help\fR
107 display this help and exit
108 .TP
109+\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR
110+set security context of copy to CONTEXT
111+.TP
112 \fB\-\-version\fR
113 output version information and exit
114 .PP
115diff -urN coreutils-5.0.org/man/dir.1 coreutils-5.0/man/dir.1
116--- coreutils-5.0.org/man/dir.1 2003-12-27 12:26:28.485162584 +0100
117+++ coreutils-5.0/man/dir.1 2003-12-27 12:26:52.966440864 +0100
118@@ -1,5 +1,5 @@
119-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
120-.TH DIR "1" "March 2003" "dir (coreutils) 5.0" "User Commands"
121+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022.
122+.TH DIR "1" "September 2003" "dir (coreutils) 5.0" FSF
123 .SH NAME
124 dir \- list directory contents
125 .SH SYNOPSIS
126@@ -195,6 +195,20 @@
127 .TP
128 \fB\-1\fR
129 list one file per line
130+.PP
842e81f4 131+SELinux options:
0107077f
AM
132+.TP
133+\fB\-\-lcontext\fR
134+Display security context. Enable \fB\-l\fR. Lines
135+will probably be too wide for most displays.
136+.TP
137+\fB\-\-context\fR
138+Display security context so it fits on most
139+displays. Displays only mode, user, group,
140+security context and file name.
141+.TP
142+\fB\-\-scontext\fR
143+Display only security context and file name.
144 .TP
145 \fB\-\-help\fR
146 display this help and exit
147diff -urN coreutils-5.0.org/man/id.1 coreutils-5.0/man/id.1
148--- coreutils-5.0.org/man/id.1 2003-12-27 12:26:28.509158936 +0100
149+++ coreutils-5.0/man/id.1 2003-12-27 12:26:52.967440712 +0100
150@@ -13,6 +13,9 @@
151 \fB\-a\fR
152 ignore, for compatibility with other versions
153 .TP
154+\fB\-Z\fR, \fB\-\-context\fR
155+print only the security context
156+.TP
157 \fB\-g\fR, \fB\-\-group\fR
158 print only the effective group ID
159 .TP
160diff -urN coreutils-5.0.org/man/install.1 coreutils-5.0/man/install.1
161--- coreutils-5.0.org/man/install.1 2003-12-27 12:26:28.509158936 +0100
162+++ coreutils-5.0/man/install.1 2003-12-27 12:26:52.967440712 +0100
163@@ -1,5 +1,5 @@
164-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
165-.TH INSTALL "1" "March 2003" "install (coreutils) 5.0" "User Commands"
166+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022.
167+.TH INSTALL "1" "September 2003" "install (coreutils) 5.0" FSF
168 .SH NAME
169 ginstall \- copy files and set attributes
170 .SH SYNOPSIS
171@@ -56,6 +56,11 @@
172 .TP
173 \fB\-v\fR, \fB\-\-verbose\fR
174 print the name of each directory as it is created
175+.HP
176+\fB\-P\fR, \fB\-\-preserve_context\fR (SELinux) Preserve security context
177+.TP
178+\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR
179+(SELinux) Set security context of files and directories
180 .TP
181 \fB\-\-help\fR
182 display this help and exit
183diff -urN coreutils-5.0.org/man/ls.1 coreutils-5.0/man/ls.1
184--- coreutils-5.0.org/man/ls.1 2003-12-27 12:26:28.509158936 +0100
185+++ coreutils-5.0/man/ls.1 2003-12-27 12:26:52.966440864 +0100
186@@ -1,5 +1,5 @@
187-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
188-.TH LS "1" "March 2003" "ls (coreutils) 5.0" "User Commands"
189+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022.
190+.TH LS "1" "September 2003" "ls (coreutils) 5.0" FSF
191 .SH NAME
192 ls \- list directory contents
193 .SH SYNOPSIS
194@@ -195,6 +195,20 @@
195 .TP
196 \fB\-1\fR
197 list one file per line
198+.PP
199+SELinux options:
200+.TP
201+\fB\-\-lcontext\fR
202+Display security context. Enable \fB\-l\fR. Lines
203+will probably be too wide for most displays.
204+.TP
205+\fB\-Z\fR, \fB\-\-context\fR
206+Display security context so it fits on most
207+displays. Displays only mode, user, group,
208+security context and file name.
209+.TP
210+\fB\-\-scontext\fR
211+Display only security context and file name.
212 .TP
213 \fB\-\-help\fR
214 display this help and exit
215diff -urN coreutils-5.0.org/man/Makefile.am coreutils-5.0/man/Makefile.am
216--- coreutils-5.0.org/man/Makefile.am 2003-12-27 12:26:28.345183864 +0100
217+++ coreutils-5.0/man/Makefile.am 2003-12-27 12:33:28.969239288 +0100
89e7e107 218@@ -9,7 +9,7 @@
219 rm.1 rmdir.1 seq.1 sha1sum.1 shred.1 sleep.1 sort.1 split.1 stat.1 stty.1 \
220 su.1 sum.1 sync.1 tac.1 tail.1 tee.1 test.1 touch.1 tr.1 true.1 tsort.1 \
221 tty.1 uname.1 unexpand.1 uniq.1 unlink.1 uptime.1 users.1 vdir.1 wc.1 \
222- who.1 whoami.1 yes.1
1b2fccf7 223+ who.1 whoami.1 yes.1 chcon.1 runcon.1
89e7e107 224 man_MANS = getgid.1
225
226 man_aux = $(dist_man_MANS:.1=.x)
227@@ -111,6 +111,8 @@
228 who.1: $(common_dep) $(srcdir)/who.x ../src/who.c
229 whoami.1: $(common_dep) $(srcdir)/whoami.x ../src/whoami.c
230 yes.1: $(common_dep) $(srcdir)/yes.x ../src/yes.c
231+chcon.1: $(common_dep) $(srcdir)/chcon.x ../src/chcon.c
1b2fccf7 232+runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
89e7e107 233
234 SUFFIXES = .x .1
235
0107077f
AM
236diff -urN coreutils-5.0.org/man/mkdir.1 coreutils-5.0/man/mkdir.1
237--- coreutils-5.0.org/man/mkdir.1 2003-12-27 12:26:28.407174440 +0100
238+++ coreutils-5.0/man/mkdir.1 2003-12-27 12:26:52.968440560 +0100
239@@ -12,6 +12,8 @@
240 .PP
241 Mandatory arguments to long options are mandatory for short options too.
242 .TP
243+\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR (SELinux) set security context to CONTEXT
244+.TP
245 \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
246 set permission mode (as in chmod), not rwxrwxrwx - umask
247 .TP
248diff -urN coreutils-5.0.org/man/mkfifo.1 coreutils-5.0/man/mkfifo.1
249--- coreutils-5.0.org/man/mkfifo.1 2003-12-27 12:26:28.459166536 +0100
250+++ coreutils-5.0/man/mkfifo.1 2003-12-27 12:26:52.968440560 +0100
251@@ -12,6 +12,9 @@
252 .PP
253 Mandatory arguments to long options are mandatory for short options too.
254 .TP
255+\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR
256+set security context (quoted string)
257+.TP
258 \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
259 set permission mode (as in chmod), not a=rw - umask
260 .TP
261diff -urN coreutils-5.0.org/man/mknod.1 coreutils-5.0/man/mknod.1
262--- coreutils-5.0.org/man/mknod.1 2003-12-27 12:26:28.406174592 +0100
263+++ coreutils-5.0/man/mknod.1 2003-12-27 12:26:52.969440408 +0100
264@@ -12,6 +12,9 @@
265 .PP
266 Mandatory arguments to long options are mandatory for short options too.
267 .TP
268+\fB\-Z\fR, \fB\-\-context\fR=\fICONTEXT\fR
269+set security context (quoted string)
270+.TP
271 \fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
272 set permission mode (as in chmod), not a=rw - umask
273 .TP
274diff -urN coreutils-5.0.org/man/runcon.1 coreutils-5.0/man/runcon.1
275--- coreutils-5.0.org/man/runcon.1 1970-01-01 01:00:00.000000000 +0100
276+++ coreutils-5.0/man/runcon.1 2003-12-27 12:26:52.969440408 +0100
277@@ -0,0 +1,39 @@
278+.TH RUNCON "1" "July 2003" "runcon (coreutils) 5.0" "selinux"
279+.SH NAME
280+runcon \- run command with specified security context
281+.SH SYNOPSIS
282+.B runcon
283+[\fI-t TYPE\fR] [\fI-l LEVEL\fR] [\fI-u USER\fR] [\fI-r ROLE\fR] \fICOMMAND\fR [\fIARGS...\fR]
284+.PP
285+or
286+.PP
287+.B runcon
288+\fICONTEXT\fR \fICOMMAND\fR [\fIargs...\fR]
289+.PP
290+.br
291+.SH DESCRIPTION
292+.PP
293+.\" Add any additional description here
294+.PP
295+Run COMMAND with current security context modified by one or more of LEVEL,
296+ROLE, TYPE, and USER, or with completely-specified CONTEXT.
297+.TP
298+\fB\-t\fR
299+change current type to the specified type
300+.TP
301+\fB\-l\fR
302+change current level range to the specified range
303+.TP
304+\fB\-r\fR
305+change current role to the specified role
306+.TP
307+\fB\-u\fR
308+change current user to the specified user
309+.PP
310+If none of \fI-t\fR, \fI-u\fR, \fI-r\fR, or \fI-l\fR, is specified,
311+the first argument is used as the complete context. Any additional
312+arguments after \fICOMMAND\fR are interpreted as arguments to the
313+command.
314+.PP
315+Note that only carefully-chosen contexts are likely to successfully
316+run.
317diff -urN coreutils-5.0.org/man/runcon.x coreutils-5.0/man/runcon.x
318--- coreutils-5.0.org/man/runcon.x 1970-01-01 01:00:00.000000000 +0100
319+++ coreutils-5.0/man/runcon.x 2003-12-27 12:26:52.964441168 +0100
320@@ -0,0 +1,2 @@
321+[DESCRIPTION]
322+.\" Add any additional description here
323diff -urN coreutils-5.0.org/man/stat.1 coreutils-5.0/man/stat.1
324--- coreutils-5.0.org/man/stat.1 2003-12-27 12:26:28.458166688 +0100
325+++ coreutils-5.0/man/stat.1 2003-12-27 12:26:52.965441016 +0100
326@@ -22,6 +22,9 @@
327 \fB\-t\fR, \fB\-\-terse\fR
328 print the information in terse form
329 .TP
330+\fB\-Z\fR, \fB\-\-context\fR
331+print security context information for SELinux if available.
332+.TP
333 \fB\-\-help\fR
334 display this help and exit
335 .TP
336@@ -42,6 +45,9 @@
337 %b
338 Number of blocks allocated (see %B)
339 .TP
340+%C
341+SELinux security context
342+.TP
343 %D
344 Device number in hex
345 .TP
346diff -urN coreutils-5.0.org/man/vdir.1 coreutils-5.0/man/vdir.1
347--- coreutils-5.0.org/man/vdir.1 2003-12-27 12:26:28.510158784 +0100
348+++ coreutils-5.0/man/vdir.1 2003-12-27 12:26:52.967440712 +0100
349@@ -1,5 +1,5 @@
350-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
351-.TH VDIR "1" "March 2003" "vdir (coreutils) 5.0" "User Commands"
352+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022.
353+.TH VDIR "1" "September 2003" "vdir (coreutils) 5.0" FSF
354 .SH NAME
355 vdir \- list directory contents
356 .SH SYNOPSIS
357@@ -195,6 +195,20 @@
358 .TP
359 \fB\-1\fR
360 list one file per line
361+.PP
842e81f4 362+SELinux options:
0107077f
AM
363+.TP
364+\fB\-\-lcontext\fR
365+Display security context. Enable \fB\-l\fR. Lines
366+will probably be too wide for most displays.
367+.TP
368+\fB\-\-context\fR
369+Display security context so it fits on most
370+displays. Displays only mode, user, group,
371+security context and file name.
372+.TP
373+\fB\-\-scontext\fR
374+Display only security context and file name.
375 .TP
376 \fB\-\-help\fR
377 display this help and exit
378diff -urN coreutils-5.0.org/src/chcon.c coreutils-5.0/src/chcon.c
379--- coreutils-5.0.org/src/chcon.c 1970-01-01 01:00:00.000000000 +0100
380+++ coreutils-5.0/src/chcon.c 2003-12-27 12:26:52.934445728 +0100
381@@ -0,0 +1,415 @@
c30075f4 382+/* chcontext -- change security context of a pathname */
383+
384+#include <config.h>
385+#include <stdio.h>
386+#include <sys/types.h>
387+#include <grp.h>
388+#include <getopt.h>
1b2fccf7 389+#include <selinux/selinux.h>
0107077f 390+#include <selinux/context.h>
c30075f4 391+
392+#include "system.h"
393+#include "error.h"
394+#include "savedir.h"
395+#include "group-member.h"
396+
397+enum Change_status
398+{
399+ CH_SUCCEEDED,
400+ CH_FAILED,
401+ CH_NO_CHANGE_REQUESTED
402+};
403+
404+enum Verbosity
405+{
406+ /* Print a message for each file that is processed. */
407+ V_high,
408+
409+ /* Print a message for each file whose attributes we change. */
410+ V_changes_only,
411+
412+ /* Do not be verbose. This is the default. */
413+ V_off
414+};
415+
0107077f 416+static int change_dir_context PARAMS ((const char *dir, const struct stat *statp));
c30075f4 417+
418+/* The name the program was run with. */
419+char *program_name;
420+
421+/* If nonzero, and the systems has support for it, change the context
422+ of symbolic links rather than any files they point to. */
423+static int change_symlinks;
424+
425+/* If nonzero, change the context of directories recursively. */
426+static int recurse;
427+
428+/* If nonzero, force silence (no error messages). */
429+static int force_silent;
430+
431+/* Level of verbosity. */
432+static enum Verbosity verbosity = V_off;
433+
1b2fccf7 434+/* The name of the context file is being given. */
0107077f
AM
435+static const char *specified_context;
436+
437+/* Specific components of the context */
438+static const char *specified_user;
439+static const char *specified_role;
440+static const char *specified_range;
441+static const char *specified_type;
c30075f4 442+
1b2fccf7 443+/* The argument to the --reference option. Use the context of this file.
c30075f4 444+ This file must exist. */
445+static char *reference_file;
446+
447+/* If nonzero, display usage information and exit. */
448+static int show_help;
449+
450+/* If nonzero, print the version on standard output and exit. */
451+static int show_version;
452+
453+static struct option const long_options[] =
454+{
455+ {"recursive", no_argument, 0, 'R'},
456+ {"changes", no_argument, 0, 'c'},
457+ {"no-dereference", no_argument, 0, 'h'},
458+ {"silent", no_argument, 0, 'f'},
459+ {"quiet", no_argument, 0, 'f'},
460+ {"reference", required_argument, 0, CHAR_MAX + 1},
1b2fccf7 461+ {"context", required_argument, 0, CHAR_MAX + 2},
0107077f
AM
462+ {"user", required_argument, 0, 'u'},
463+ {"role", required_argument, 0, 'r'},
464+ {"type", required_argument, 0, 't'},
465+ {"range", required_argument, 0, 'l'},
c30075f4 466+ {"verbose", no_argument, 0, 'v'},
467+ {"help", no_argument, &show_help, 1},
468+ {"version", no_argument, &show_version, 1},
469+ {0, 0, 0, 0}
470+};
471+
472+/* Tell the user how/if the context of FILE has been changed.
473+ CHANGED describes what (if anything) has happened. */
474+
475+static void
0107077f 476+describe_change (const char *file, security_context_t newcontext, enum Change_status changed)
c30075f4 477+{
478+ const char *fmt;
479+ switch (changed)
480+ {
481+ case CH_SUCCEEDED:
482+ fmt = _("context of %s changed to %s\n");
483+ break;
484+ case CH_FAILED:
485+ fmt = _("failed to change context of %s to %s\n");
486+ break;
487+ case CH_NO_CHANGE_REQUESTED:
488+ fmt = _("context of %s retained as %s\n");
489+ break;
490+ default:
491+ abort ();
492+ }
0107077f
AM
493+ printf (fmt, file, newcontext);
494+}
495+
496+static int
497+compute_context_from_mask (security_context_t context, context_t *ret)
498+{
499+ context_t newcontext = context_new (context);
500+ if (!newcontext)
501+ return 1;
502+#define SETCOMPONENT(comp) \
503+ do { \
504+ if (specified_ ## comp) \
505+ if (context_ ## comp ## _set (newcontext, specified_ ## comp)) \
506+ goto lose; \
507+ } while (0)
508+
509+ SETCOMPONENT(user);
510+ SETCOMPONENT(range);
511+ SETCOMPONENT(role);
512+ SETCOMPONENT(type);
513+#undef SETCOMPONENT
514+
515+ *ret = newcontext;
516+ return 0;
517+ lose:
518+ context_free (newcontext);
519+ return 1;
c30075f4 520+}
521+
0107077f 522+/* Change the context of FILE, using specified components.
c30075f4 523+ If it is a directory and -R is given, recurse.
524+ Return 0 if successful, 1 if errors occurred. */
525+
526+static int
0107077f 527+change_file_context (const char *file)
c30075f4 528+{
529+ struct stat file_stats;
1b2fccf7 530+ security_context_t file_context=NULL;
0107077f
AM
531+ context_t context;
532+ security_context_t context_string;
c30075f4 533+ int errors = 0;
534+
1b2fccf7 535+ if ((lgetfilecon(file, &file_context)<0) && (errno != ENODATA))
c30075f4 536+ {
537+ if (force_silent == 0)
538+ error (0, errno, "%s", file);
539+ return 1;
540+ }
541+
0107077f
AM
542+ /* If the file doesn't have a context, and we're not setting all of
543+ the context components, there isn't really an obvious default.
544+ Thus, we just give up. */
545+ if (file_context == NULL && specified_context == NULL)
546+ {
547+ error (0, 0, _("can't apply partial context to unlabeled file %s"), file);
548+ return 1;
549+ }
550+
551+ if (specified_context == NULL)
552+ {
553+ if (compute_context_from_mask (file_context, &context))
554+ {
555+ error (0, 0, _("couldn't compute security context from %s"), file_context);
556+ return 1;
557+ }
558+ }
559+ else
560+ {
561+ context = context_new (specified_context);
562+ if (!context)
563+ error (1, 0,_("invalid context: %s"),specified_context);
564+ }
565+
566+ context_string = context_str (context);
567+
568+ if (strcmp(context_string,file_context)!=0)
c30075f4 569+ {
570+ int fail;
571+
572+ if (change_symlinks)
0107077f 573+ fail = lsetfilecon (file, context_string);
c30075f4 574+ else
0107077f 575+ fail = setfilecon (file, context_string);
c30075f4 576+
577+ if (verbosity == V_high || (verbosity == V_changes_only && !fail))
0107077f 578+ describe_change (file, context_string, (fail ? CH_FAILED : CH_SUCCEEDED));
c30075f4 579+
580+ if (fail)
581+ {
582+ errors = 1;
583+ if (force_silent == 0)
584+ {
0107077f 585+ error (0, errno, _("failed to change context of %s to %s"), file, context_string);
c30075f4 586+ }
587+ }
588+ }
589+ else if (verbosity == V_high)
590+ {
0107077f 591+ describe_change (file, context_string, CH_NO_CHANGE_REQUESTED);
c30075f4 592+ }
593+
0107077f 594+ context_free(context);
1b2fccf7 595+ freecon(file_context);
c30075f4 596+
1b2fccf7 597+ if (recurse) {
598+ if (lstat(file, &file_stats)==0)
599+ if (S_ISDIR (file_stats.st_mode))
0107077f 600+ errors |= change_dir_context (file, &file_stats);
1b2fccf7 601+ }
c30075f4 602+ return errors;
603+}
604+
605+/* Recursively change context of the files in directory DIR
0107077f 606+ using specified context components.
c30075f4 607+ STATP points to the results of lstat on DIR.
608+ Return 0 if successful, 1 if errors occurred. */
609+
610+static int
0107077f 611+change_dir_context (const char *dir, const struct stat *statp)
c30075f4 612+{
613+ char *name_space, *namep;
614+ char *path; /* Full path of each entry to process. */
615+ unsigned dirlength; /* Length of `dir' and '\0'. */
616+ unsigned filelength; /* Length of each pathname to process. */
617+ unsigned pathlength; /* Bytes allocated for `path'. */
618+ int errors = 0;
619+
620+ errno = 0;
621+ name_space = savedir (dir);
622+ if (name_space == NULL)
623+ {
624+ if (errno)
625+ {
626+ if (force_silent == 0)
627+ error (0, errno, "%s", dir);
628+ return 1;
629+ }
630+ else
631+ error (1, 0, _("virtual memory exhausted"));
632+ }
633+
634+ dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
635+ pathlength = dirlength + 1;
636+ /* Give `path' a dummy value; it will be reallocated before first use. */
637+ path = xmalloc (pathlength);
638+ strcpy (path, dir);
639+ path[dirlength - 1] = '/';
640+
641+ for (namep = name_space; *namep; namep += filelength - dirlength)
642+ {
643+ filelength = dirlength + strlen (namep) + 1;
644+ if (filelength > pathlength)
645+ {
646+ pathlength = filelength * 2;
647+ path = xrealloc (path, pathlength);
648+ }
649+ strcpy (path + dirlength, namep);
0107077f 650+ errors |= change_file_context (path);
c30075f4 651+ }
652+ free (path);
653+ free (name_space);
654+ return errors;
655+}
656+
657+static void
658+usage (int status)
659+{
660+ if (status != 0)
661+ fprintf (stderr, _("Try `%s --help' for more information.\n"),
662+ program_name);
663+ else
664+ {
665+ printf (_("\
666+Usage: %s [OPTION]... CONTEXT FILE...\n\
0107077f 667+ or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\
c30075f4 668+ or: %s [OPTION]... --reference=RFILE FILE...\n\
c30075f4 669+"),
670+ program_name, program_name, program_name);
671+ printf (_("\
672+Change the security context of each FILE to CONTEXT.\n\
673+\n\
674+ -c, --changes like verbose but report only when a change is made\n\
675+ -h, --no-dereference affect symbolic links instead of any referenced file\n\
676+ (available only on systems with lchown system call)\n\
677+ -f, --silent, --quiet suppress most error messages\n\
678+ --reference=RFILE use RFILE's group instead of using a CONTEXT value\n\
0107077f
AM
679+ -u, --user=USER set user USER in the target security context\n\
680+ -r, --role=ROLE set role ROLE in the target security context\n\
681+ -t, --type=TYPE set type TYPE in the target security context\n\
682+ -l, --range=RANGE set range RANGE in the target security context\n\
c30075f4 683+ -R, --recursive change files and directories recursively\n\
684+ -v, --verbose output a diagnostic for every file processed\n\
685+ --help display this help and exit\n\
686+ --version output version information and exit\n\
687+"));
688+ close_stdout ();
689+ }
690+ exit (status);
691+}
692+
693+int
694+main (int argc, char **argv)
695+{
1b2fccf7 696+ security_context_t ref_context = NULL;
c30075f4 697+ int errors = 0;
698+ int optc;
0107077f 699+ int component_specified = 0;
c30075f4 700+
701+ program_name = argv[0];
702+ setlocale (LC_ALL, "");
703+ bindtextdomain (PACKAGE, LOCALEDIR);
704+ textdomain (PACKAGE);
705+
706+ recurse = force_silent = 0;
707+
0107077f 708+ while ((optc = getopt_long (argc, argv, "Rcfhvu:r:t:l:", long_options, NULL)) != -1)
c30075f4 709+ {
710+ switch (optc)
711+ {
712+ case 0:
0107077f
AM
713+ break;
714+ case 'u':
715+ specified_user = optarg;
716+ component_specified = 1;
717+ break;
718+ case 'r':
719+ specified_role = optarg;
720+ component_specified = 1;
721+ break;
722+ case 't':
723+ specified_type = optarg;
724+ component_specified = 1;
725+ break;
726+ case 'l':
727+ specified_range = optarg;
728+ component_specified = 1;
729+ break;
c30075f4 730+ case CHAR_MAX + 1:
731+ reference_file = optarg;
732+ break;
c30075f4 733+ case 'R':
734+ recurse = 1;
735+ break;
736+ case 'c':
737+ verbosity = V_changes_only;
738+ break;
739+ case 'f':
740+ force_silent = 1;
741+ break;
742+ case 'h':
743+ change_symlinks = 1;
744+ break;
745+ case 'v':
746+ verbosity = V_high;
747+ break;
748+ default:
749+ usage (1);
750+ }
751+ }
752+
753+ if (show_version)
754+ {
755+ printf ("chcon (%s) %s\n", GNU_PACKAGE, VERSION);
756+ close_stdout ();
757+ exit (0);
758+ }
759+
760+ if (show_help)
761+ usage (0);
762+
0107077f
AM
763+
764+ if (reference_file && component_specified)
765+ {
766+ error (0, 0, _("conflicting security context specifiers given"));
767+ usage (1);
768+ }
769+
770+ if (!(((reference_file || component_specified)
771+ && (argc - optind > 0))
772+ || (argc - optind > 1)))
773+ {
774+ error (0, 0, _("too few arguments"));
775+ usage (1);
776+ }
c30075f4 777+
778+ if (reference_file)
779+ {
1b2fccf7 780+ if (getfilecon (reference_file, &ref_context)<0)
c30075f4 781+ error (1, errno, "%s", reference_file);
0107077f
AM
782+
783+ specified_context = ref_context;
c30075f4 784+ }
0107077f
AM
785+ else if (!component_specified) {
786+ specified_context = argv[optind++];
1b2fccf7 787+ }
c30075f4 788+ for (; optind < argc; ++optind)
0107077f 789+ errors |= change_file_context (argv[optind]);
c30075f4 790+
791+ if (verbosity != V_off)
792+ close_stdout ();
1b2fccf7 793+ if (ref_context != NULL)
794+ freecon(ref_context);
c30075f4 795+ exit (errors);
796+}
0107077f
AM
797diff -urN coreutils-5.0.org/src/copy.c coreutils-5.0/src/copy.c
798--- coreutils-5.0.org/src/copy.c 2003-12-27 12:26:28.939093576 +0100
799+++ coreutils-5.0/src/copy.c 2003-12-27 12:26:52.935445576 +0100
800@@ -46,6 +46,11 @@
c30075f4 801 #include "same.h"
802 #include "xreadlink.h"
803
1b2fccf7 804+#ifdef WITH_SELINUX
805+#include <selinux/selinux.h> /* for is_selinux_enabled() */
0107077f 806+extern int selinux_enabled;
c30075f4 807+#endif
808+
809 #define DO_CHOWN(Chown, File, New_uid, New_gid) \
810 (Chown (File, New_uid, New_gid) \
811 /* If non-root uses -p, it's ok if we can't preserve ownership. \
0107077f 812@@ -1233,6 +1238,32 @@
1b2fccf7 813 In such cases, set this variable to zero. */
814 preserve_metadata = 1;
89e7e107 815
1b2fccf7 816+#ifdef WITH_SELINUX
0107077f 817+ if (x->preserve_security_context && selinux_enabled)
1b2fccf7 818+ {
819+ security_context_t con;
820+
0107077f 821+ if (lgetfilecon (src_path, &con) >= 0)
1b2fccf7 822+ {
0107077f
AM
823+ if (setfscreatecon(con) < 0)
824+ {
825+ freecon(con);
826+ error (0, errno, _("cannot set setfscreatecon %s"), quote (con));
827+ return 1;
828+ }
829+ freecon(con);
830+ }
831+ else {
832+ if ( errno == ENOTSUP ) {
833+ error (0, errno, _("warning: security context not preserved %s"), quote (src_path));
834+ } else {
1b2fccf7 835+ error (0, errno, _("cannot lgetfilecon %s"), quote (src_path));
836+ return 1;
837+ }
1b2fccf7 838+ }
1b2fccf7 839+ }
89e7e107 840+#endif
1b2fccf7 841+
842 if (S_ISDIR (src_mode))
89e7e107 843 {
1b2fccf7 844 struct dir_list *dir;
0107077f 845@@ -1302,8 +1333,13 @@
1b2fccf7 846 }
89e7e107 847
1b2fccf7 848 /* Are we crossing a file system boundary? */
849- if (x->one_file_system && device != 0 && device != src_sb.st_dev)
850+ if (x->one_file_system && device != 0 && device != src_sb.st_dev) {
851+#ifdef WITH_SELINUX
0107077f 852+ if (x->preserve_security_context && selinux_enabled)
1b2fccf7 853+ setfscreatecon(NULL);
89e7e107 854+#endif
1b2fccf7 855 return 0;
c30075f4 856+ }
1b2fccf7 857
858 /* Copy the contents of the directory. */
859
0107077f 860@@ -1442,6 +1478,11 @@
1b2fccf7 861 }
89e7e107 862 }
1b2fccf7 863
864+#ifdef WITH_SELINUX
0107077f 865+ if (x->preserve_security_context && selinux_enabled)
1b2fccf7 866+ setfscreatecon(NULL);
c30075f4 867+#endif
868+
1b2fccf7 869 /* There's no need to preserve timestamps or permissions. */
870 preserve_metadata = 0;
89e7e107 871
0107077f 872@@ -1474,7 +1515,7 @@
1b2fccf7 873 if (command_line_arg)
874 record_file (x->dest_info, dst_path, NULL);
89e7e107 875
1b2fccf7 876- if ( ! preserve_metadata)
877+ if ( ! preserve_metadata)
878 return 0;
879
880 /* POSIX says that `cp -p' must restore the following:
0107077f 881@@ -1576,6 +1617,11 @@
1b2fccf7 882
883 un_backup:
884
885+#ifdef WITH_SELINUX
0107077f 886+ if (x->preserve_security_context && selinux_enabled)
1b2fccf7 887+ setfscreatecon(NULL);
89e7e107 888+#endif
889+
1b2fccf7 890 /* We have failed to create the destination file.
891 If we've just added a dev/ino entry via the remember_copied
892 call above (i.e., unless we've just failed to create a hard link),
0107077f
AM
893diff -urN coreutils-5.0.org/src/copy.h coreutils-5.0/src/copy.h
894--- coreutils-5.0.org/src/copy.h 2003-12-27 12:26:28.948092208 +0100
895+++ coreutils-5.0/src/copy.h 2003-12-27 12:26:52.937445272 +0100
89e7e107 896@@ -105,6 +105,9 @@
c30075f4 897 int preserve_ownership;
898 int preserve_mode;
899 int preserve_timestamps;
1b2fccf7 900+#ifdef WITH_SELINUX
c30075f4 901+ int preserve_security_context;
902+#endif
903
904 /* Enabled for mv, and for cp by the --preserve=links option.
905 If nonzero, attempt to preserve in the destination files any
0107077f
AM
906diff -urN coreutils-5.0.org/src/cp.c coreutils-5.0/src/cp.c
907--- coreutils-5.0.org/src/cp.c 2003-12-27 12:26:28.939093576 +0100
908+++ coreutils-5.0/src/cp.c 2003-12-27 12:26:52.938445120 +0100
909@@ -52,6 +52,11 @@
c30075f4 910
911 #define AUTHORS N_ ("Torbjorn Granlund, David MacKenzie, and Jim Meyering")
912
1b2fccf7 913+#ifdef WITH_SELINUX
914+#include <selinux/selinux.h> /* for is_selinux_enabled() */
0107077f 915+int selinux_enabled=0;
c30075f4 916+#endif
917+
918 #ifndef _POSIX_VERSION
919 uid_t geteuid ();
920 #endif
0107077f 921@@ -149,6 +154,9 @@
c30075f4 922 {"update", no_argument, NULL, 'u'},
923 {"verbose", no_argument, NULL, 'v'},
924 {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
1b2fccf7 925+#ifdef WITH_SELINUX
0107077f 926+ {"context", required_argument, NULL, 'Z'},
c30075f4 927+#endif
928 {GETOPT_HELP_OPTION_DECL},
929 {GETOPT_VERSION_OPTION_DECL},
930 {NULL, 0, NULL, 0}
0107077f 931@@ -198,6 +206,9 @@
c30075f4 932 additional attributes: links, all\n\
933 "), stdout);
934 fputs (_("\
935+ -c same as --preserve=context\n\
936+"), stdout);
937+ fputs (_("\
938 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
939 --parents append source path to DIRECTORY\n\
940 -P same as `--no-dereference'\n\
0107077f 941@@ -225,6 +236,7 @@
c30075f4 942 destination file is missing\n\
943 -v, --verbose explain what is being done\n\
944 -x, --one-file-system stay on this file system\n\
0107077f 945+ -Z, --context=CONTEXT set security context of copy to CONTEXT\n\
c30075f4 946 "), stdout);
947 fputs (HELP_OPTION_DESCRIPTION, stdout);
948 fputs (VERSION_OPTION_DESCRIPTION, stdout);
0107077f 949@@ -756,8 +768,8 @@
c30075f4 950 {
951 new_dest = (char *) dest;
952 }
953-
954- return copy (source, new_dest, new_dst, x, &unused, NULL);
1b2fccf7 955+ ret=copy (source, new_dest, new_dst, x, &unused, NULL);
956+ return ret;
c30075f4 957 }
958
959 /* unreachable */
0107077f 960@@ -781,6 +793,10 @@
c30075f4 961 x->preserve_mode = 0;
962 x->preserve_timestamps = 0;
963
1b2fccf7 964+#ifdef WITH_SELINUX
c30075f4 965+ x->preserve_security_context = 0;
966+#endif
967+
968 x->require_preserve = 0;
969 x->recursive = 0;
970 x->sparse_mode = SPARSE_AUTO;
0107077f 971@@ -808,19 +824,20 @@
c30075f4 972 PRESERVE_TIMESTAMPS,
973 PRESERVE_OWNERSHIP,
974 PRESERVE_LINK,
975+ PRESERVE_CONTEXT,
976 PRESERVE_ALL
977 };
978 static enum File_attribute const preserve_vals[] =
979 {
980 PRESERVE_MODE, PRESERVE_TIMESTAMPS,
981- PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL
982+ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL
983 };
984
985 /* Valid arguments to the `--preserve' option. */
986 static char const* const preserve_args[] =
987 {
988 "mode", "timestamps",
989- "ownership", "links", "all", 0
990+ "ownership", "links", "context", "all", 0
991 };
992
993 char *arg_writable = xstrdup (arg);
0107077f 994@@ -855,11 +872,16 @@
c30075f4 995 x->preserve_links = on_off;
996 break;
997
998+ case PRESERVE_CONTEXT:
999+ x->preserve_security_context = on_off;
1000+ break;
1001+
1002 case PRESERVE_ALL:
1003 x->preserve_mode = on_off;
1004 x->preserve_timestamps = on_off;
1005 x->preserve_ownership = on_off;
1006 x->preserve_links = on_off;
1007+ x->preserve_security_context = on_off;
1008 break;
1009
1010 default:
0107077f 1011@@ -882,6 +904,10 @@
c30075f4 1012 struct cp_options x;
1013 int copy_contents = 0;
1014 char *target_directory = NULL;
1b2fccf7 1015+#ifdef WITH_SELINUX
1016+ security_context_t scontext = NULL;
0107077f 1017+ selinux_enabled= is_selinux_enabled();
c30075f4 1018+#endif
1019
1020 program_name = argv[0];
1021 setlocale (LC_ALL, "");
0107077f 1022@@ -896,7 +922,11 @@
c30075f4 1023 we'll actually use backup_suffix_string. */
1024 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1025
1b2fccf7 1026+#ifdef WITH_SELINUX
0107077f 1027+ while ((c = getopt_long (argc, argv, "abcdfHilLprsuvxPRS:V:Z:", long_opts, NULL))
c30075f4 1028+#else
1029 while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:", long_opts, NULL))
1030+#endif
1031 != -1)
1032 {
1033 switch (c)
0107077f 1034@@ -987,6 +1017,36 @@
c30075f4 1035 x.preserve_timestamps = 1;
1036 x.require_preserve = 1;
1037 break;
1b2fccf7 1038+#ifdef WITH_SELINUX
c30075f4 1039+ case 'c':
1b2fccf7 1040+ if ( scontext != NULL ) {
842e81f4 1041+ (void) fprintf(stderr, _("%s: cannot force target context <-- %s and preserve it\n"), argv[0], scontext);
c30075f4 1042+ exit( 1 );
1043+ }
0107077f 1044+ else if (selinux_enabled)
c30075f4 1045+ x.preserve_security_context = 1;
1046+ break;
1b2fccf7 1047+
0107077f 1048+ case 'Z':
1b2fccf7 1049+ /* politely decline if we're not on a selinux-enabled kernel. */
0107077f 1050+ if( !selinux_enabled ) {
842e81f4
JB
1051+ fprintf( stderr, _("Warning: ignoring --context (-Z). "
1052+ "It requires a SELinux-enabled kernel.\n") );
c30075f4 1053+ break;
1054+ }
1055+ if ( x.preserve_security_context ) {
842e81f4 1056+ (void) fprintf(stderr, _("%s: cannot force target context to '%s' and preserve it\n"), argv[0], optarg);
c30075f4 1057+ exit( 1 );
1058+ }
1059+ scontext = optarg;
1b2fccf7 1060+ /* if there's a security_context given set new path
1061+ components to that context, too */
1062+ if ( setfscreatecon(scontext) < 0 ) {
1063+ (void) fprintf(stderr, _("cannot set default security context %s"), scontext);
c30075f4 1064+ exit( 1 );
1065+ }
1066+ break;
1067+#endif
1068
1069 case PARENTS_OPTION:
1070 flag_path = 1;
0107077f
AM
1071diff -urN coreutils-5.0.org/src/id.c coreutils-5.0/src/id.c
1072--- coreutils-5.0.org/src/id.c 2003-12-27 12:26:28.951091752 +0100
1073+++ coreutils-5.0/src/id.c 2003-12-27 12:26:52.939444968 +0100
1b2fccf7 1074@@ -46,6 +46,20 @@
c30075f4 1075
1076 int getugroups ();
1077
1b2fccf7 1078+#ifdef WITH_SELINUX
1079+#include <selinux/selinux.h>
c30075f4 1080+static void print_context PARAMS ((char* context));
1b2fccf7 1081+/* Print the SELinux context */
1082+static void
1083+print_context(char *context)
1084+{
1085+ printf ("%s", context);
1086+}
1087+
0107077f 1088+/* If nonzero, output only the SELinux context. -Z */
1b2fccf7 1089+static int just_context = 0;
1090+
1091+#endif
c30075f4 1092 static void print_user (uid_t uid);
1093 static void print_group (gid_t gid);
1094 static void print_group_list (const char *username);
1b2fccf7 1095@@ -64,8 +78,14 @@
c30075f4 1096 /* The number of errors encountered so far. */
1097 static int problems = 0;
1098
1b2fccf7 1099+/* The SELinux context */
1100+/* Set `context' to a known invalid value so print_full_info() will *
1101+ * know when `context' has not been set to a meaningful value. */
1102+static security_context_t context=NULL;
c30075f4 1103+
1104 static struct option const longopts[] =
1105 {
0107077f 1106+ {"context", no_argument, NULL, 'Z'},
c30075f4 1107 {"group", no_argument, NULL, 'g'},
1108 {"groups", no_argument, NULL, 'G'},
1109 {"name", no_argument, NULL, 'n'},
1b2fccf7 1110@@ -89,6 +109,7 @@
c30075f4 1111 Print information for USERNAME, or the current user.\n\
1112 \n\
1113 -a ignore, for compatibility with other versions\n\
0107077f 1114+ -Z, --context print only the context\n\
c30075f4 1115 -g, --group print only the effective group ID\n\
1116 -G, --groups print all group IDs\n\
1117 -n, --name print a name instead of a number, for -ugG\n\
1b2fccf7 1118@@ -110,6 +131,7 @@
c30075f4 1119 main (int argc, char **argv)
1120 {
1121 int optc;
0107077f 1122+ int selinux_enabled=is_selinux_enabled();
c30075f4 1123
1124 /* If nonzero, output the list of all group IDs. -G */
1125 int just_group_list = 0;
1b2fccf7 1126@@ -127,7 +149,7 @@
c30075f4 1127
1128 atexit (close_stdout);
1129
1130- while ((optc = getopt_long (argc, argv, "agnruG", longopts, NULL)) != -1)
0107077f 1131+ while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1)
c30075f4 1132 {
1133 switch (optc)
1134 {
1b2fccf7 1135@@ -136,6 +158,17 @@
c30075f4 1136 case 'a':
1137 /* Ignore -a, for compatibility with SVR4. */
1138 break;
1b2fccf7 1139+#ifdef WITH_SELINUX
0107077f 1140+ case 'Z':
1b2fccf7 1141+ /* politely decline if we're not on a selinux-enabled kernel. */
0107077f 1142+ if( !selinux_enabled ) {
842e81f4
JB
1143+ fprintf( stderr, _("Sorry, --context (-Z) can be used only on "
1144+ "a SELinux-enabled kernel.\n") );
c30075f4 1145+ exit( 1 );
1146+ }
1147+ just_context = 1;
1148+ break;
1b2fccf7 1149+#endif
c30075f4 1150 case 'g':
1151 just_group = 1;
1152 break;
1b2fccf7 1153@@ -158,8 +191,28 @@
c30075f4 1154 }
1155 }
1156
1157- if (just_user + just_group + just_group_list > 1)
1158- error (EXIT_FAILURE, 0, _("cannot print only user and only group"));
1b2fccf7 1159+#ifdef WITH_SELINUX
c30075f4 1160+ if (argc - optind == 1)
0107077f 1161+ selinux_enabled = 0;
c30075f4 1162+
0107077f 1163+ if( just_context && !selinux_enabled)
c30075f4 1164+ error (1, 0, _("\
842e81f4 1165+cannot display context when SELinux not enabled or when displaying the id\n\
c30075f4 1166+of a different user"));
1167+
1b2fccf7 1168+ /* If we are on a selinux-enabled kernel, get our context. *
1169+ * Otherwise, leave the context variable alone - it has *
1170+ * been initialized known invalid value; if we see this invalid *
1171+ * value later, we will know we are on a non-selinux kernel. */
0107077f 1172+ if( selinux_enabled )
c30075f4 1173+ {
1b2fccf7 1174+ if (getcon(&context))
842e81f4 1175+ error (1, 0, _("can't get process context"));
c30075f4 1176+ }
1b2fccf7 1177+#endif
c30075f4 1178+
1b2fccf7 1179+ if (just_user + just_group + just_group_list + just_context > 1)
1180+ error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
c30075f4 1181
1b2fccf7 1182 if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
1183 error (EXIT_FAILURE, 0,
1184@@ -190,6 +243,10 @@
c30075f4 1185 print_group (use_real ? rgid : egid);
1186 else if (just_group_list)
1187 print_group_list (argv[optind]);
1b2fccf7 1188+#ifdef WITH_SELINUX
c30075f4 1189+ else if (just_context)
1190+ print_context (context);
1b2fccf7 1191+#endif
c30075f4 1192 else
1193 print_full_info (argv[optind]);
1194 putchar ('\n');
1b2fccf7 1195@@ -397,4 +454,9 @@
c30075f4 1196 free (groups);
1197 }
1198 #endif /* HAVE_GETGROUPS */
1b2fccf7 1199+#ifdef WITH_SELINUX
1200+ if ( context != NULL ) {
842e81f4 1201+ printf(_(" context=%s"),context);
c30075f4 1202+ }
1b2fccf7 1203+#endif
c30075f4 1204 }
0107077f
AM
1205diff -urN coreutils-5.0.org/src/install.c coreutils-5.0/src/install.c
1206--- coreutils-5.0.org/src/install.c 2003-12-27 12:26:28.932094640 +0100
1207+++ coreutils-5.0/src/install.c 2003-12-27 12:26:52.941444664 +0100
1208@@ -50,6 +50,11 @@
c30075f4 1209 # include <sys/wait.h>
1210 #endif
1211
1b2fccf7 1212+#ifdef WITH_SELINUX
1213+#include <selinux/selinux.h> /* for is_selinux_enabled() */
0107077f 1214+int selinux_enabled=0;
c30075f4 1215+#endif
1216+
1217 struct passwd *getpwnam ();
1218 struct group *getgrnam ();
1219
0107077f 1220@@ -126,11 +131,17 @@
c30075f4 1221 static struct option const long_options[] =
1222 {
1223 {"backup", optional_argument, NULL, 'b'},
1b2fccf7 1224+#ifdef WITH_SELINUX
0107077f 1225+ {"context", required_argument, NULL, 'Z'},
c30075f4 1226+#endif
1227 {"directory", no_argument, NULL, 'd'},
1228 {"group", required_argument, NULL, 'g'},
1229 {"mode", required_argument, NULL, 'm'},
1230 {"owner", required_argument, NULL, 'o'},
1231 {"preserve-timestamps", no_argument, NULL, 'p'},
1b2fccf7 1232+#ifdef WITH_SELINUX
c30075f4 1233+ {"preserve_context", no_argument, NULL, 'P'},
1234+#endif
1235 {"strip", no_argument, NULL, 's'},
1236 {"suffix", required_argument, NULL, 'S'},
1237 {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
0107077f 1238@@ -247,6 +258,9 @@
c30075f4 1239
1240 x->update = 0;
1241 x->verbose = 0;
1b2fccf7 1242+#ifdef WITH_SELINUX
c30075f4 1243+ x->preserve_security_context = 0;
89e7e107 1244+#endif
1b2fccf7 1245 x->xstat = stat;
c30075f4 1246 x->dest_info = NULL;
1247 x->src_info = NULL;
0107077f 1248@@ -265,6 +279,11 @@
c30075f4 1249 struct cp_options x;
1250 int n_files;
1251 char **file;
1b2fccf7 1252+#ifdef WITH_SELINUX
1253+ security_context_t scontext = NULL;
1254+ /* set iff kernel has extra selinux system calls */
0107077f 1255+ selinux_enabled = is_selinux_enabled();
c30075f4 1256+#endif
1257
1258 program_name = argv[0];
1259 setlocale (LC_ALL, "");
0107077f 1260@@ -285,7 +304,11 @@
1b2fccf7 1261 we'll actually use backup_suffix_string. */
1262 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1263
1264+#ifdef WITH_SELINUX
0107077f 1265+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPvV:S:Z:", long_options,
1b2fccf7 1266+#else
1267 while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pvV:S:", long_options,
1268+#endif
1269 NULL)) != -1)
1270 {
1271 switch (optc)
0107077f 1272@@ -338,6 +361,39 @@
c30075f4 1273 make_backups = 1;
1274 backup_suffix_string = optarg;
1275 break;
1b2fccf7 1276+#ifdef WITH_SELINUX
c30075f4 1277+ case 'P':
1b2fccf7 1278+ /* politely decline if we're not on a selinux-enabled kernel. */
0107077f 1279+ if( !selinux_enabled ) {
842e81f4
JB
1280+ fprintf( stderr, _("Warning: ignoring --preserve_context (-P) "
1281+ "because the kernel is not SELinux-enabled.\n") );
c30075f4 1282+ break;
1283+ }
1b2fccf7 1284+ if ( scontext!=NULL ) { /* scontext could be NULL because of calloc() failure */
842e81f4 1285+ (void) fprintf(stderr, _("%s: cannot force target context to '%s' and preserve it\n"), argv[0], scontext);
c30075f4 1286+ exit( 1 );
1287+ }
1288+ x.preserve_security_context = 1;
1289+ break ;
0107077f 1290+ case 'Z':
1b2fccf7 1291+ /* politely decline if we're not on a selinux-enabled kernel. */
0107077f 1292+ if( !selinux_enabled) {
842e81f4
JB
1293+ fprintf( stderr, _("Warning: ignoring --context (-Z) "
1294+ "because the kernel is not SELinux-enabled.\n") );
c30075f4 1295+ break;
1296+ }
1297+ if ( x.preserve_security_context ) {
1b2fccf7 1298+
842e81f4 1299+ (void) fprintf(stderr, _("%s: cannot force target context == '%s' and preserve it\n"), argv[0], optarg);
c30075f4 1300+ exit( 1 );
1301+ }
1302+ scontext = optarg;
1b2fccf7 1303+ if (setfscreatecon(scontext)) {
842e81f4 1304+ (void) fprintf(stderr, _("%s: cannot setup default context == '%s'\n"), argv[0], scontext);
1b2fccf7 1305+ exit(1);
1306+ }
c30075f4 1307+ break;
1308+#endif
1309 case_GETOPT_HELP_CHAR;
1310 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1311 default:
0107077f 1312@@ -721,6 +777,11 @@
c30075f4 1313 -S, --suffix=SUFFIX override the usual backup suffix\n\
1314 -v, --verbose print the name of each directory as it is created\n\
1315 "), stdout);
1316+ fputs (_("\
0107077f
AM
1317+ -P, --preserve_context (SELinux) Preserve security context\n\
1318+ -Z, --context=CONTEXT (SELinux) Set security context of files and directories\n\
c30075f4 1319+"), stdout);
1320+
1321 fputs (HELP_OPTION_DESCRIPTION, stdout);
1322 fputs (VERSION_OPTION_DESCRIPTION, stdout);
1323 fputs (_("\
0107077f
AM
1324diff -urN coreutils-5.0.org/src/ls.c coreutils-5.0/src/ls.c
1325--- coreutils-5.0.org/src/ls.c 2003-12-27 12:26:28.947092360 +0100
1326+++ coreutils-5.0/src/ls.c 2003-12-27 12:42:14.887287592 +0100
1327@@ -130,6 +130,18 @@
c30075f4 1328
1329 #define AUTHORS N_ ("Richard Stallman and David MacKenzie")
1330
1b2fccf7 1331+#ifdef WITH_SELINUX
1332+#include <selinux/selinux.h>
0107077f 1333+int selinux_enabled= 0;
c30075f4 1334+static int print_scontext = 0;
0107077f 1335+#define check_selinux() if (!selinux_enabled) { \
842e81f4
JB
1336+ fprintf( stderr, _("Sorry, this option can only be used " \
1337+ "on a SELinux-enabled kernel.\n" )); \
0107077f
AM
1338+ exit( EXIT_FAILURE ); \
1339+}
1340+
c30075f4 1341+#endif
1342+
1343 #define obstack_chunk_alloc malloc
1344 #define obstack_chunk_free free
1345
0107077f 1346@@ -227,6 +239,10 @@
c30075f4 1347 /* For long listings, true if the file has an access control list. */
1348 bool have_acl;
1349 #endif
1350+
1b2fccf7 1351+#ifdef WITH_SELINUX
1352+ security_context_t scontext;
c30075f4 1353+#endif
1354 };
1355
1356 #if HAVE_ACL || USE_ACL
0107077f 1357@@ -290,6 +306,9 @@
c30075f4 1358 static void sort_files (void);
1359 static void parse_ls_color (void);
1360 void usage (int status);
1b2fccf7 1361+#ifdef WITH_SELINUX
c30075f4 1362+static void print_scontext_format PARAMS ((const struct fileinfo *f));
1363+#endif
1364
1365 /* The name the program was run with, stripped of any leading path. */
1366 char *program_name;
0107077f 1367@@ -379,7 +398,10 @@
c30075f4 1368 one_per_line, /* -1 */
1369 many_per_line, /* -C */
1370 horizontal, /* -x */
1371- with_commas /* -m */
1b2fccf7 1372+#ifdef WITH_SELINUX
0107077f 1373+ security_format, /* -Z */
c30075f4 1374+#endif
0107077f 1375+ with_commas /* -m */
c30075f4 1376 };
1377
1378 static enum format format;
0107077f 1379@@ -700,6 +722,11 @@
c30075f4 1380 SHOW_CONTROL_CHARS_OPTION,
1381 SI_OPTION,
1382 SORT_OPTION,
1b2fccf7 1383+#ifdef WITH_SELINUX
c30075f4 1384+ CONTEXT_OPTION,
1385+ LCONTEXT_OPTION,
1386+ SCONTEXT_OPTION,
1387+#endif
1388 TIME_OPTION,
1389 TIME_STYLE_OPTION
1390 };
0107077f 1391@@ -743,6 +770,11 @@
c30075f4 1392 {"time-style", required_argument, 0, TIME_STYLE_OPTION},
1393 {"color", optional_argument, 0, COLOR_OPTION},
1394 {"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
1b2fccf7 1395+#ifdef WITH_SELINUX
c30075f4 1396+ {"context", no_argument, 0, CONTEXT_OPTION},
1397+ {"lcontext", no_argument, 0, LCONTEXT_OPTION},
1398+ {"scontext", no_argument, 0, SCONTEXT_OPTION},
1399+#endif
1400 {"author", no_argument, 0, AUTHOR_OPTION},
1401 {GETOPT_HELP_OPTION_DECL},
1402 {GETOPT_VERSION_OPTION_DECL},
0107077f 1403@@ -752,12 +784,19 @@
c30075f4 1404 static char const *const format_args[] =
1405 {
1406 "verbose", "long", "commas", "horizontal", "across",
1b2fccf7 1407- "vertical", "single-column", 0
1408+ "vertical", "single-column",
1409+#ifdef WITH_SELINUX
1410+ "context",
c30075f4 1411+#endif
1b2fccf7 1412+ 0
c30075f4 1413 };
1414
1415 static enum format const format_types[] =
1416 {
1417 long_format, long_format, with_commas, horizontal, horizontal,
1b2fccf7 1418+#ifdef WITH_SELINUX
1419+ security_format,
89e7e107 1420+#endif
1b2fccf7 1421 many_per_line, one_per_line
c30075f4 1422 };
1423
0107077f 1424@@ -1121,6 +1160,9 @@
c30075f4 1425
1426 format_needs_stat = sort_type == sort_time || sort_type == sort_size
1427 || format == long_format
1b2fccf7 1428+#ifdef WITH_SELINUX
1429+ || format == security_format || print_scontext
c30075f4 1430+#endif
1431 || dereference == DEREF_ALWAYS
1432 || print_block_size || print_inode;
1433 format_needs_type = (format_needs_stat == 0
0107077f 1434@@ -1243,6 +1285,11 @@
c30075f4 1435 /* Record whether there is an option specifying sort type. */
1436 int sort_type_specified = 0;
1437
1b2fccf7 1438+#ifdef WITH_SELINUX
1439+ /* 1 iff kernel has new selinux system calls */
0107077f 1440+ selinux_enabled= is_selinux_enabled();
c30075f4 1441+#endif
1442+
1443 qmark_funny_chars = 0;
1444
1445 /* initialize all switches to default settings */
0107077f 1446@@ -1293,6 +1340,9 @@
c30075f4 1447 all_files = 0;
1448 really_all_files = 0;
1449 ignore_patterns = 0;
1b2fccf7 1450+#ifdef WITH_SELINUX
c30075f4 1451+ print_scontext = 0;
1452+#endif
1453
1454 /* FIXME: put this in a function. */
1455 {
0107077f
AM
1456@@ -1370,7 +1420,7 @@
1457 }
1458
1459 while ((c = getopt_long (argc, argv,
1460- "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
1461+ "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1Z",
1462 long_options, NULL)) != -1)
1463 {
1464 switch (c)
1465@@ -1490,6 +1540,13 @@
1466 format = horizontal;
1467 break;
1468
1469+#ifdef WITH_SELINUX
1470+ case 'Z':
1471+ check_selinux();
1472+ print_scontext = 1;
1473+ format = security_format;
1474+ break;
1475+#endif
1476 case 'A':
1477 really_all_files = 0;
1478 all_files = 1;
1479@@ -1657,6 +1714,25 @@
c30075f4 1480
1481 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1482
1b2fccf7 1483+#ifdef WITH_SELINUX
c30075f4 1484+
c30075f4 1485+ case CONTEXT_OPTION: /* new security format */
1486+ check_selinux();
1487+ print_scontext = 1;
1488+ format = security_format;
1489+ break;
1490+ case LCONTEXT_OPTION: /* long format plus security context */
1491+ check_selinux();
1492+ print_scontext = 1;
1493+ format = long_format;
1494+ break;
1495+ case SCONTEXT_OPTION: /* short form of new security format */
1496+ check_selinux();
1497+ print_scontext = 0;
1498+ format = security_format;
1499+ break;
1500+#endif
1501+
1502 default:
1503 usage (EXIT_FAILURE);
1504 }
0107077f 1505@@ -2308,6 +2384,12 @@
1b2fccf7 1506 free (files[i].name);
1507 if (files[i].linkname)
1508 free (files[i].linkname);
1509+#ifdef WITH_SELINUX
0107077f 1510+ if (files[i].scontext) {
1b2fccf7 1511+ freecon (files[i].scontext);
0107077f
AM
1512+ files[i].scontext=NULL;
1513+ }
1b2fccf7 1514+#endif
1515 }
1516
1517 files_index = 0;
0107077f
AM
1518@@ -2334,6 +2416,9 @@
1519 files[files_index].linkname = 0;
1520 files[files_index].linkmode = 0;
1521 files[files_index].linkok = 0;
1522+#ifdef WITH_SELINUX
1523+ files[files_index].scontext = NULL;
1524+#endif
1525
1526 if (explicit_arg
1527 || format_needs_stat
1528@@ -2379,6 +2464,11 @@
c30075f4 1529 {
1530 int need_lstat;
1531 err = stat (path, &files[files_index].stat);
1b2fccf7 1532+#ifdef WITH_SELINUX
0107077f
AM
1533+ if (err>=0)
1534+ if (selinux_enabled && (format == security_format || print_scontext))
1535+ getfilecon(path, &files[files_index].scontext);
c30075f4 1536+#endif
1537
1538 if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
1539 break;
0107077f 1540@@ -2397,6 +2487,11 @@
c30075f4 1541
1542 default: /* DEREF_NEVER */
1543 err = lstat (path, &files[files_index].stat);
1b2fccf7 1544+#ifdef WITH_SELINUX
0107077f
AM
1545+ if (err>=0)
1546+ if (selinux_enabled && (format == security_format || print_scontext))
1547+ lgetfilecon(path, &files[files_index].scontext);
c30075f4 1548+#endif
c30075f4 1549 break;
1550 }
1551
0107077f 1552@@ -2825,6 +2920,16 @@
c30075f4 1553 DIRED_PUTCHAR ('\n');
1554 }
1555 break;
1556+
1b2fccf7 1557+#ifdef WITH_SELINUX
c30075f4 1558+ case security_format:
1559+ for (i = 0; i < files_index; i++)
1560+ {
1561+ print_scontext_format (files + i);
1562+ DIRED_PUTCHAR ('\n');
1563+ }
1564+ break;
1565+#endif
1566 }
1567 }
1568
0107077f 1569@@ -3088,6 +3193,14 @@
c30075f4 1570 p += strlen (p);
1571 }
1572
1b2fccf7 1573+#ifdef WITH_SELINUX
c30075f4 1574+
1575+ if ( print_scontext ) {
1b2fccf7 1576+ sprintf (p, "%-32s ", f->scontext);
c30075f4 1577+ p += strlen (p);
1578+ }
1579+#endif
1580+
1581 DIRED_INDENT ();
1582 DIRED_FPUTS (buf, stdout, p - buf);
1583 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
0107077f 1584@@ -3883,6 +3996,16 @@
c30075f4 1585 -X sort alphabetically by entry extension\n\
1586 -1 list one file per line\n\
1587 "), stdout);
1b2fccf7 1588+#ifdef WITH_SELINUX
842e81f4 1589+printf(_("SELinux options:\n\n\
c30075f4 1590+ --lcontext Display security context. Enable -l. Lines\n\
1591+ will probably be too wide for most displays.\n\
1592+ --context Display security context so it fits on most\n\
1593+ displays. Displays only mode, user, group,\n\
1594+ security context and file name.\n\
1595+ --scontext Display only security context and file name.\n\
1596+"));
1597+#endif
1598 fputs (HELP_OPTION_DESCRIPTION, stdout);
1599 fputs (VERSION_OPTION_DESCRIPTION, stdout);
1600 fputs (_("\n\
0107077f 1601@@ -3901,3 +4024,79 @@
c30075f4 1602 }
1603 exit (status);
1604 }
1605+
1b2fccf7 1606+#ifdef WITH_SELINUX
c30075f4 1607+
1608+static void
1609+print_scontext_format (const struct fileinfo *f)
1610+{
1611+ char modebuf[12];
1612+
1613+ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes,
1614+ 1 10-byte mode string,
1615+ 9 spaces, one following each of these fields, and
1616+ 1 trailing NUL byte. */
1617+
1618+ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1];
1619+ char *buf = init_bigbuf;
1620+ size_t bufsize = sizeof (init_bigbuf);
1621+ size_t s;
1622+ char *p;
1623+ const char *fmt;
1624+ char *user_name;
1625+ char *group_name;
1626+ int rv;
1627+ char *scontext;
1628+
1629+ p = buf;
1630+
1631+ if ( print_scontext ) { /* zero means terse listing */
1632+ mode_string (f->stat.st_mode, modebuf);
1633+ modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' ');
1634+ modebuf[11] = '\0';
1635+
1636+ /* print mode */
1637+
1638+ (void) sprintf (p, "%s ", modebuf);
1639+ p += strlen (p);
1640+
1641+ /* print standard user and group */
1642+
1643+ user_name = (numeric_ids ? NULL : getuser (f->stat.st_uid));
1644+ if (user_name)
1645+ (void) sprintf (p, "%-8.8s ", user_name);
1646+ else
1647+ (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_uid);
1648+ p += strlen (p);
1649+
1650+ if ( print_group ) {
1651+ group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid));
1652+ if (group_name)
1653+ (void) sprintf (p, "%-8.8s ", group_name);
1654+ else
1655+ (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_gid);
1656+ p += strlen (p);
1657+ }
1658+ }
1659+
1b2fccf7 1660+ (void) sprintf (p, "%-32s ", f->scontext);
c30075f4 1661+ p += strlen (p);
1662+
1663+ DIRED_INDENT ();
1664+ DIRED_FPUTS (buf, stdout, p - buf);
1665+ print_name_with_quoting (f->name, f->stat.st_mode, f->linkok, &dired_obstack);
1666+
1667+ if (f->filetype == symbolic_link) {
1668+ if (f->linkname) {
1669+ DIRED_FPUTS_LITERAL (" -> ", stdout);
1670+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, NULL);
1671+ if (indicator_style != none)
1672+ print_type_indicator (f->linkmode);
1673+ }
1674+ }
1675+ else {
1676+ if (indicator_style != none)
1677+ print_type_indicator (f->stat.st_mode);
1678+ }
1679+}
1680+#endif
0107077f
AM
1681diff -urN coreutils-5.0.org/src/Makefile.am coreutils-5.0/src/Makefile.am
1682--- coreutils-5.0.org/src/Makefile.am 2003-12-27 12:26:28.928095248 +0100
1683+++ coreutils-5.0/src/Makefile.am 2003-12-27 12:37:59.212156120 +0100
1684@@ -4,13 +4,13 @@
1685 EXTRA_SCRIPTS = nohup
1686
1687 bin_SCRIPTS = groups @OPTIONAL_BIN_ZCRIPTS@
1688-bin_PROGRAMS = chgrp chown chmod cp dd dircolors du \
1689+bin_PROGRAMS = chgrp chown chmod chcon cp dd dircolors du \
1690 ginstall link ln dir vdir ls mkdir \
1691 mkfifo mknod mv readlink rm rmdir shred stat sync touch unlink \
1692 cat cksum comm csplit cut expand fmt fold head join md5sum \
1693 nl od paste pr ptx sha1sum sort split sum tac tail tr tsort unexpand uniq wc \
1694 basename date dirname echo env expr factor false getgid \
1695- hostname id kill logname pathchk printenv printf pwd seq sleep tee \
1696+ hostname id kill logname pathchk printenv printf runcon pwd seq sleep tee \
1697 test true tty whoami yes \
1698 @OPTIONAL_BIN_PROGS@ @DF_PROG@
1699
842e81f4 1700@@ -34,13 +34,20 @@
0107077f
AM
1701 # replacement functions defined in libfetish.a.
1702 LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a
1703
842e81f4
JB
1704-dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL)
1705-ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL)
1706+dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@
1707+ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@
0107077f 1708 shred_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
842e81f4
JB
1709-vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL)
1710-cp_LDADD = $(LDADD) $(LIBACL)
1711-ginstall_LDADD = $(LDADD) $(LIBACL)
1712-mv_LDADD = $(LDADD) $(LIBACL)
1713+vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ $(LIBACL) @LIB_SELINUX@
1714+cp_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@
1715+ginstall_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@
1716+mv_LDADD = $(LDADD) $(LIBACL) @LIB_SELINUX@
0107077f
AM
1717+chcon_LDADD = $(LDADD) @LIB_SELINUX@
1718+id_LDADD = $(LDADD) @LIB_SELINUX@
1719+mkdir_LDADD = $(LDADD) @LIB_SELINUX@
1720+mkfifo_LDADD = $(LDADD) @LIB_SELINUX@
1721+mknod_LDADD = $(LDADD) @LIB_SELINUX@
1722+stat_LDADD = $(LDADD) @LIB_SELINUX@
1723+runcon_LDADD = $(LDADD) @LIB_SELINUX@
1724
1725 ## If necessary, add -lm to resolve use of pow in lib/strtod.c.
1726 sort_LDADD = $(LDADD) @POW_LIB@
1727diff -urN coreutils-5.0.org/src/mkdir.c coreutils-5.0/src/mkdir.c
1728--- coreutils-5.0.org/src/mkdir.c 2003-12-27 12:26:28.950091904 +0100
1729+++ coreutils-5.0/src/mkdir.c 2003-12-27 12:26:52.958442080 +0100
1b2fccf7 1730@@ -34,6 +34,10 @@
c30075f4 1731
1732 #define AUTHORS "David MacKenzie"
1733
1b2fccf7 1734+#ifdef WITH_SELINUX
1735+#include <selinux/selinux.h> /* for is_selinux_enabled() */
c30075f4 1736+#endif
1737+
1738 /* The name this program was run with. */
1739 char *program_name;
1740
1b2fccf7 1741@@ -42,6 +46,9 @@
c30075f4 1742
1743 static struct option const longopts[] =
1744 {
1b2fccf7 1745+#ifdef WITH_SELINUX
0107077f 1746+ {"context", required_argument, NULL, 'Z'},
c30075f4 1747+#endif
1748 {"mode", required_argument, NULL, 'm'},
1749 {"parents", no_argument, NULL, 'p'},
1750 {"verbose", no_argument, NULL, 'v'},
1b2fccf7 1751@@ -63,6 +70,11 @@
c30075f4 1752 Create the DIRECTORY(ies), if they do not already exist.\n\
1753 \n\
1754 "), stdout);
1b2fccf7 1755+#ifdef WITH_SELINUX
c30075f4 1756+ printf (_("\
0107077f 1757+ -Z, --context=CONTEXT (SELinux) set security context to CONTEXT\n\
c30075f4 1758+"));
1759+#endif
1760 fputs (_("\
1761 Mandatory arguments to long options are mandatory for short options too.\n\
1762 "), stdout);
1b2fccf7 1763@@ -97,7 +109,11 @@
c30075f4 1764
1765 create_parents = 0;
1766
1b2fccf7 1767+#ifdef WITH_SELINUX
0107077f 1768+ while ((optc = getopt_long (argc, argv, "pm:vZ:", longopts, NULL)) != -1)
c30075f4 1769+#else
1770 while ((optc = getopt_long (argc, argv, "pm:v", longopts, NULL)) != -1)
1771+#endif
1772 {
1773 switch (optc)
1774 {
1b2fccf7 1775@@ -112,6 +128,20 @@
c30075f4 1776 case 'v': /* --verbose */
1777 verbose_fmt_string = _("created directory %s");
1778 break;
1b2fccf7 1779+#ifdef WITH_SELINUX
0107077f 1780+ case 'Z':
1b2fccf7 1781+ /* politely decline if we're not on a selinux-enabled kernel. */
1782+ if( !is_selinux_enabled()) {
842e81f4
JB
1783+ fprintf( stderr, _("Sorry, --context (-Z) can be used only on "
1784+ "a SELinux-enabled kernel.\n") );
c30075f4 1785+ exit( 1 );
1786+ }
1b2fccf7 1787+ if (setfscreatecon(optarg)) {
842e81f4 1788+ fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg);
c30075f4 1789+ exit( 1 );
1790+ }
1791+ break;
1792+#endif
1793 case_GETOPT_HELP_CHAR;
1794 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1795 default:
0107077f
AM
1796diff -urN coreutils-5.0.org/src/mkfifo.c coreutils-5.0/src/mkfifo.c
1797--- coreutils-5.0.org/src/mkfifo.c 2003-12-27 12:26:28.933094488 +0100
1798+++ coreutils-5.0/src/mkfifo.c 2003-12-27 12:26:52.958442080 +0100
1b2fccf7 1799@@ -32,11 +32,18 @@
c30075f4 1800
1801 #define AUTHORS "David MacKenzie"
1802
1b2fccf7 1803+#ifdef WITH_SELINUX
1804+#include <selinux/selinux.h> /* for is_selinux_enabled() */
c30075f4 1805+#endif
1806+
1807 /* The name this program was run with. */
1808 char *program_name;
1809
1810 static struct option const longopts[] =
1811 {
1b2fccf7 1812+#ifdef WITH_SELINUX
0107077f 1813+ {"context", required_argument, NULL, 'Z'},
c30075f4 1814+#endif
1815 {"mode", required_argument, NULL, 'm'},
1816 {GETOPT_HELP_OPTION_DECL},
1817 {GETOPT_VERSION_OPTION_DECL},
1b2fccf7 1818@@ -57,6 +64,11 @@
c30075f4 1819 Create named pipes (FIFOs) with the given NAMEs.\n\
1820 \n\
1821 "), stdout);
1b2fccf7 1822+#ifdef WITH_SELINUX
c30075f4 1823+ printf (_("\
0107077f 1824+ -Z, --context=CONTEXT set security context (quoted string)\n\
c30075f4 1825+"), stdout);
1826+#endif
1827 fputs (_("\
1828 Mandatory arguments to long options are mandatory for short options too.\n\
1829 "), stdout);
1b2fccf7 1830@@ -92,7 +104,11 @@
c30075f4 1831 #ifndef S_ISFIFO
1832 error (4, 0, _("fifo files not supported"));
1833 #else
1b2fccf7 1834+#ifdef WITH_SELINUX
0107077f 1835+ while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
c30075f4 1836+#else
1837 while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
1838+#endif
1839 {
1840 switch (optc)
1841 {
1b2fccf7 1842@@ -101,6 +117,19 @@
1843 case 'm':
1844 specified_mode = optarg;
1845 break;
1846+#ifdef WITH_SELINUX
0107077f 1847+ case 'Z':
1b2fccf7 1848+ if( !is_selinux_enabled()) {
842e81f4
JB
1849+ fprintf( stderr, _("Sorry, --context (-Z) can be used only on "
1850+ "a SELinux-enabled kernel.\n") );
1b2fccf7 1851+ exit( 1 );
1852+ }
1853+ if (setfscreatecon(optarg)) {
842e81f4 1854+ fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg);
1b2fccf7 1855+ exit( 1 );
1856+ }
1857+ break;
1858+#endif
1859 case_GETOPT_HELP_CHAR;
1860 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1861 default:
0107077f
AM
1862diff -urN coreutils-5.0.org/src/mknod.c coreutils-5.0/src/mknod.c
1863--- coreutils-5.0.org/src/mknod.c 2003-12-27 12:26:28.936094032 +0100
1864+++ coreutils-5.0/src/mknod.c 2003-12-27 12:26:52.959441928 +0100
1b2fccf7 1865@@ -36,8 +36,15 @@
c30075f4 1866 /* The name this program was run with. */
1867 char *program_name;
1868
1b2fccf7 1869+#ifdef WITH_SELINUX
1870+#include <selinux/selinux.h>
c30075f4 1871+#endif
1872+
1873 static struct option const longopts[] =
1874 {
1b2fccf7 1875+#ifdef WITH_SELINUX
0107077f 1876+ {"context", required_argument, NULL, 'Z'},
c30075f4 1877+#endif
1878 {"mode", required_argument, NULL, 'm'},
1879 {GETOPT_HELP_OPTION_DECL},
1880 {GETOPT_VERSION_OPTION_DECL},
1b2fccf7 1881@@ -58,6 +65,11 @@
c30075f4 1882 Create the special file NAME of the given TYPE.\n\
1883 \n\
1884 "), stdout);
1b2fccf7 1885+#ifdef WITH_SELINUX
c30075f4 1886+ fputs(_("\
0107077f 1887+ -Z, --context=CONTEXT set security context (quoted string)\n\
c30075f4 1888+"), stdout);
1889+#endif
1890 fputs (_("\
1891 Mandatory arguments to long options are mandatory for short options too.\n\
1892 "), stdout);
1b2fccf7 1893@@ -102,7 +114,11 @@
c30075f4 1894
1895 specified_mode = NULL;
1896
1b2fccf7 1897+#ifdef WITH_SELINUX
0107077f 1898+ while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
c30075f4 1899+#else
1900 while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
1901+#endif
1902 {
1903 switch (optc)
1904 {
1b2fccf7 1905@@ -111,6 +127,20 @@
c30075f4 1906 case 'm':
1907 specified_mode = optarg;
1908 break;
1b2fccf7 1909+#ifdef WITH_SELINUX
0107077f 1910+ case 'Z':
1b2fccf7 1911+ /* politely decline if we're not on a selinux-enabled kernel. */
1912+ if( !is_selinux_enabled()) {
842e81f4
JB
1913+ fprintf( stderr, _("Sorry, --context (-Z) can be used only on "
1914+ "a SELinux-enabled kernel.\n") );
c30075f4 1915+ exit( 1 );
1916+ }
1b2fccf7 1917+ if (setfscreatecon(optarg)) {
842e81f4 1918+ fprintf( stderr, _("Sorry, cannot set default context to %s.\n"), optarg);
1b2fccf7 1919+ exit( 1 );
c30075f4 1920+ }
1921+ break;
1922+#endif
1923 case_GETOPT_HELP_CHAR;
1924 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1925 default:
0107077f
AM
1926diff -urN coreutils-5.0.org/src/mv.c coreutils-5.0/src/mv.c
1927--- coreutils-5.0.org/src/mv.c 2003-12-27 12:26:28.941093272 +0100
1928+++ coreutils-5.0/src/mv.c 2003-12-27 12:26:52.962441472 +0100
1929@@ -38,6 +38,11 @@
c30075f4 1930 #include "quote.h"
1931 #include "remove.h"
0107077f 1932
1b2fccf7 1933+#ifdef WITH_SELINUX
0107077f
AM
1934+#include <selinux/selinux.h> /* for is_selinux_enabled() */
1935+int selinux_enabled=0;
c30075f4 1936+#endif
0107077f 1937+
c30075f4 1938 /* The official name of this program (e.g., no `g' prefix). */
1939 #define PROGRAM_NAME "mv"
c30075f4 1940
0107077f 1941@@ -381,6 +386,10 @@
c30075f4 1942
0107077f 1943 cp_option_init (&x);
c30075f4 1944
1b2fccf7 1945+#ifdef WITH_SELINUX
0107077f 1946+ selinux_enabled= is_selinux_enabled();
c30075f4 1947+#endif
0107077f
AM
1948+
1949 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
1950 we'll actually use backup_suffix_string. */
1951 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1952diff -urN coreutils-5.0.org/src/runcon.c coreutils-5.0/src/runcon.c
1953--- coreutils-5.0.org/src/runcon.c 1970-01-01 01:00:00.000000000 +0100
1954+++ coreutils-5.0/src/runcon.c 2003-12-27 12:26:52.959441928 +0100
1955@@ -0,0 +1,174 @@
89e7e107 1956+/*
1b2fccf7 1957+ * runcon [ context |
89e7e107 1958+ * ( [ -r role ] [-t type] [ -u user ] [ -l levelrange ] )
1959+ * command [arg1 [arg2 ...] ]
1960+ *
1961+ * attempt to run the specified command with the specified context.
1962+ *
89e7e107 1963+ * -r role : use the current context with the specified role
1964+ * -t type : use the current context with the specified type
1965+ * -u user : use the current context with the specified user
1966+ * -l level : use the current context with the specified level range
1967+ *
1968+ * Contexts are interpreted as follows:
1969+ *
1970+ * Number of MLS
1971+ * components system?
1972+ *
c30075f4 1973+ * 1 - type
1974+ * 2 - role:type
1975+ * 3 Y role:type:range
1976+ * 3 N user:role:type
1977+ * 4 Y user:role:type:range
1978+ * 4 N error
1979+ */
1980+
0107077f 1981+#include <config.h>
c30075f4 1982+#include <unistd.h>
1983+#include <stdio.h>
1984+#include <getopt.h>
1b2fccf7 1985+#include <selinux/context.h>
1986+#include <selinux/selinux.h>
c30075f4 1987+#include <errno.h>
0107077f 1988+#include "system.h"
c30075f4 1989+extern int errno;
1990+
1991+/* The name the program was run with. */
1992+char *program_name;
1993+
1994+void
1995+usage(char *str)
1996+{
0107077f 1997+ printf(_("Usage: %s [OPTION]... command [args]\n"
c30075f4 1998+ "Run a program in a different security context.\n\n"
1999+ " context Complete security context\n"
2000+ " -t type (for same role as parent)\n"
2001+ " -u user identity\n"
2002+ " -r role\n"
2003+ " -l levelrange\n"
0107077f 2004+ " --help display this help and exit\n"),
c30075f4 2005+ program_name);
2006+ exit(1);
2007+}
2008+
2009+int
2010+main(int argc,char **argv,char **envp )
2011+{
1b2fccf7 2012+ char *role = 0;
2013+ char *range = 0;
2014+ char *user = 0;
2015+ char *type = 0;
2016+ char *context = NULL;
2017+ security_context_t cur_context = NULL;
c30075f4 2018+
1b2fccf7 2019+ context_t con;
c30075f4 2020+
1b2fccf7 2021+ program_name = argv[0];
0107077f
AM
2022+ setlocale (LC_ALL, "");
2023+ bindtextdomain (PACKAGE, LOCALEDIR);
2024+ textdomain (PACKAGE);
1b2fccf7 2025+
2026+ while (1) {
2027+ int c;
2028+ int this_option_optind = optind ? optind : 1;
2029+ int option_index = 0;
2030+ static struct option long_options[] = {
2031+ { "role", 1, 0, 'r' },
2032+ { "type", 1, 0, 't' },
2033+ { "user", 1, 0, 'u' },
2034+ { "range", 1, 0, 'l' },
2035+ { "help", 0, 0, '?' },
2036+ { 0, 0, 0, 0 }
2037+ };
2038+ c = getopt_long(argc, argv, "s:r:t:u:l:?", long_options, &option_index);
2039+ if ( c == -1 ) {
2040+ break;
2041+ }
2042+ switch ( c ) {
2043+ case 'r':
2044+ if ( role ) {
0107077f 2045+ fprintf(stderr,_("multiple roles\n"));
1b2fccf7 2046+ exit(1);
2047+ }
2048+ role = optarg;
2049+ break;
2050+ case 't':
2051+ if ( type ) {
0107077f 2052+ fprintf(stderr,_("multiple types\n"));
1b2fccf7 2053+ exit(1);
2054+ }
2055+ type = optarg;
2056+ break;
2057+ case 'u':
2058+ if ( user ) {
0107077f 2059+ fprintf(stderr,_("multiple users\n"));
1b2fccf7 2060+ exit(1);
2061+ }
2062+ user = optarg;
2063+ break;
2064+ case 'l':
2065+ if ( range ) {
0107077f 2066+ fprintf(stderr,_("multiple levelranges\n"));
1b2fccf7 2067+ exit(1);
2068+ }
2069+ range = optarg;
2070+ break;
2071+ default:
0107077f 2072+ fprintf(stderr,_("unrecognised option %c\n"),c);
1b2fccf7 2073+ case '?':
2074+ usage(0);
2075+ break;
2076+ }
2077+ }
2078+ if ( !(user || role || type || range)) {
2079+ if ( optind >= argc ) {
0107077f 2080+ usage(_("must specify -t, -u, -l, -r, or context"));
1b2fccf7 2081+ }
2082+ context = argv[optind++];
2083+ }
2084+
2085+ if ( optind >= argc ) {
0107077f 2086+ usage(_("no command found"));
1b2fccf7 2087+ }
89e7e107 2088+
1b2fccf7 2089+ if ( context ) {
2090+ con = context_new(context);
2091+ if (!con) {
0107077f 2092+ fprintf(stderr,_("%s is not a valid context\n"), context);
1b2fccf7 2093+ exit(1);
2094+ }
2095+ }
2096+ else {
2097+ getcon(&cur_context);
2098+ con = context_new(cur_context);
2099+ if (!con) {
0107077f 2100+ fprintf(stderr,_("%s is not a valid context\n"), context);
1b2fccf7 2101+ exit(1);
2102+ }
2103+ if ( user ) {
2104+ context_user_set(con,user);
2105+ }
2106+ if ( type ) {
2107+ context_type_set(con,type);
2108+ }
2109+ if ( range ) {
2110+ context_range_set(con,range);
2111+ }
2112+ if ( role ) {
2113+ context_role_set(con,role);
2114+ }
2115+ }
2116+
2117+ if (setexeccon(context_str(con))!=0) {
0107077f 2118+ fprintf(stderr,_("unable to setup security context %s\n"), context_str(con));
1b2fccf7 2119+ exit(1);
2120+ }
2121+ if (cur_context!=NULL)
2122+ freecon(cur_context);
2123+
2124+ if ( execvp(argv[optind],argv+optind) ) {
2125+ perror("execvp");
2126+ exit(1);
2127+ }
2128+ return 1; /* can't reach this statement.... */
2129+}
0107077f
AM
2130diff -urN coreutils-5.0.org/src/stat.c coreutils-5.0/src/stat.c
2131--- coreutils-5.0.org/src/stat.c 2003-12-27 12:26:28.951091752 +0100
2132+++ coreutils-5.0/src/stat.c 2003-12-27 12:26:52.961441624 +0100
2133@@ -32,6 +32,13 @@
2134 # include <sys/vfs.h>
2135 #endif
2136
2137+#ifdef WITH_SELINUX
2138+#include <selinux/selinux.h>
2139+#define SECURITY_ID_T security_context_t
2140+#else
2141+#define SECURITY_ID_T char *
2142+#endif
2143+
2144 /* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
2145 #if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H
2146 # if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
2147@@ -93,6 +100,7 @@
2148 {"dereference", no_argument, 0, 'L'},
2149 {"format", required_argument, 0, 'c'},
2150 {"filesystem", no_argument, 0, 'f'},
2151+ {"context", no_argument, 0, 'Z'},
2152 {"terse", no_argument, 0, 't'},
2153 {GETOPT_HELP_OPTION_DECL},
2154 {GETOPT_VERSION_OPTION_DECL},
2155@@ -332,7 +340,7 @@
2156 /* print statfs info */
2157 static void
2158 print_statfs (char *pformat, char m, char const *filename,
2159- void const *data)
2160+ void const *data,SECURITY_ID_T scontext)
2161 {
2162 STRUCT_STATVFS const *statfsbuf = data;
2163
2164@@ -394,7 +402,10 @@
2165 strcat (pformat, PRIdMAX);
2166 printf (pformat, (intmax_t) (statfsbuf->f_ffree));
2167 break;
2168-
2169+ case 'C':
2170+ strcat (pformat, "s");
2171+ printf(scontext);
2172+ break;
2173 default:
2174 strcat (pformat, "c");
2175 printf (pformat, m);
2176@@ -404,7 +415,7 @@
2177
2178 /* print stat info */
2179 static void
2180-print_stat (char *pformat, char m, char const *filename, void const *data)
2181+print_stat (char *pformat, char m, char const *filename, void const *data, SECURITY_ID_T scontext)
2182 {
2183 struct stat *statbuf = (struct stat *) data;
2184 struct passwd *pw_ent;
2185@@ -537,6 +548,10 @@
2186 strcat (pformat, "d");
2187 printf (pformat, (int) statbuf->st_ctime);
2188 break;
2189+ case 'C':
2190+ strcat (pformat, "s");
2191+ printf(pformat,scontext);
2192+ break;
2193 default:
2194 strcat (pformat, "c");
2195 printf (pformat, m);
2196@@ -546,8 +561,8 @@
2197
2198 static void
2199 print_it (char const *masterformat, char const *filename,
2200- void (*print_func) (char *, char, char const *, void const *),
2201- void const *data)
2202+ void (*print_func) (char *, char, char const *, void const *,SECURITY_ID_T ),
2203+ void const *data, SECURITY_ID_T scontext)
2204 {
2205 char *b;
2206
2207@@ -580,7 +595,7 @@
2208 putchar ('%');
2209 break;
2210 default:
2211- print_func (dest, *p, filename, data);
2212+ print_func (dest, *p, filename, data,scontext);
2213 break;
2214 }
2215 b = p + 1;
2216@@ -598,9 +613,17 @@
2217
2218 /* stat the filesystem and print what we find */
2219 static void
2220-do_statfs (char const *filename, int terse, char const *format)
2221+do_statfs (char const *filename, int terse, int secure, char const *format)
2222 {
2223 STRUCT_STATVFS statfsbuf;
2224+ SECURITY_ID_T scontext = NULL;
2225+#ifdef WITH_SELINUX
2226+ if(secure)
2227+ if (getfilecon(filename,&scontext)<0) {
2228+ perror (filename);
2229+ return;
2230+ }
2231+#endif
2232 int i = statfs (filename, &statfsbuf);
2233
2234 if (i == -1)
2235@@ -612,23 +635,40 @@
2236
2237 if (format == NULL)
2238 {
2239- format = (terse
2240- ? "%n %i %l %t %b %f %a %s %c %d"
2241- : " File: \"%n\"\n"
2242- " ID: %-8i Namelen: %-7l Type: %T\n"
2243- "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
2244- "Inodes: Total: %-10c Free: %-10d");
2245- }
2246-
2247- print_it (format, filename, print_statfs, &statfsbuf);
2248+ if (terse) {
2249+ if(secure)
2250+ format = "%n %i %l %t %b %f %a %s %c %d %C";
2251+ else
2252+ format = "%n %i %l %t %b %f %a %s %c %d";
2253+ }
2254+ else
2255+ {
2256+ if(secure)
2257+ format = " File: \"%n\"\n"
2258+ " ID: %-8i Namelen: %-7l Type: %T\n"
2259+ "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
2260+ "Inodes: Total: %-10c Free: %-10d\n"
2261+ " S_Context: %C\n";
2262+ else
2263+ format= " File: \"%n\"\n"
2264+ " ID: %-8i Namelen: %-7l Type: %T\n"
2265+ "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
2266+ "Inodes: Total: %-10c Free: %-10d";
2267+ }
2268+ }
2269+ print_it (format, filename, print_statfs, &statfsbuf,scontext);
2270+#ifdef WITH_SELINUX
2271+ if (scontext != NULL)
2272+ freecon(scontext);
2273+#endif
2274 }
2275-
2276 /* stat the file and print what we find */
2277 static void
2278-do_stat (char const *filename, int follow_links, int terse,
2279+ do_stat (char const *filename, int follow_links, int terse,int secure,
2280 char const *format)
2281 {
2282 struct stat statbuf;
2283+ SECURITY_ID_T scontext = NULL;
2284 int i = ((follow_links == 1)
2285 ? stat (filename, &statbuf)
2286 : lstat (filename, &statbuf));
2287@@ -639,11 +679,28 @@
2288 return;
2289 }
2290
2291+#ifdef WITH_SELINUX
2292+ if(secure) {
2293+ if (link)
2294+ i=lgetfilecon(filename, &scontext);
2295+ else
2296+ i=getfilecon(filename, &scontext);
2297+ if (i == -1)
2298+ {
2299+ perror (filename);
2300+ return;
2301+ }
2302+ }
2303+#endif
2304+
2305 if (format == NULL)
2306 {
2307 if (terse != 0)
2308 {
2309- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
2310+ if (secure)
2311+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C";
2312+ else
2313+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
2314 }
2315 else
2316 {
2317@@ -651,7 +708,17 @@
2318 i = statbuf.st_mode & S_IFMT;
2319 if (i == S_IFCHR || i == S_IFBLK)
2320 {
2321- format =
2322+ if (secure)
2323+ format =
2324+ " File: %N\n"
2325+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
2326+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
2327+ " Device type: %t,%T\n"
2328+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
2329+ " S_Context: %C\n"
2330+ "Access: %x\n" "Modify: %y\n" "Change: %z\n";
2331+ else
2332+ format =
2333 " File: %N\n"
2334 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
2335 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
2336@@ -661,6 +728,15 @@
2337 }
2338 else
2339 {
2340+ if (secure)
2341+ format =
2342+ " File: %N\n"
2343+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
2344+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h\n"
2345+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
2346+ "S_Context: %C\n"
2347+ "Access: %x\n" "Modify: %y\n" "Change: %z\n";
2348+ else
2349 format =
2350 " File: %N\n"
2351 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
2352@@ -670,7 +746,11 @@
2353 }
2354 }
2355 }
2356- print_it (format, filename, print_stat, &statbuf);
2357+ print_it (format, filename, print_stat, &statbuf,scontext);
2358+#ifdef WITH_SELINUX
2359+ if (scontext)
2360+ freecon(scontext);
2361+#endif
2362 }
2363
2364 void
2365@@ -688,6 +768,7 @@
2366 -f, --filesystem display filesystem status instead of file status\n\
2367 -c --format=FORMAT use the specified FORMAT instead of the default\n\
2368 -L, --dereference follow links\n\
842e81f4 2369+ -Z, --context print the security context\n\
0107077f
AM
2370 -t, --terse print the information in terse form\n\
2371 "), stdout);
2372 fputs (HELP_OPTION_DESCRIPTION, stdout);
2373@@ -739,6 +820,7 @@
2374 %c Total file nodes in file system\n\
2375 %d Free file nodes in file system\n\
2376 %f Free blocks in file system\n\
842e81f4 2377+ %C Security context in SELinux\n\
0107077f
AM
2378 "), stdout);
2379 fputs (_("\
2380 %i File System id in hex\n\
2381@@ -761,6 +843,7 @@
2382 int follow_links = 0;
2383 int fs = 0;
2384 int terse = 0;
2385+ int secure = 0;
2386 char *format = NULL;
2387
2388 program_name = argv[0];
2389@@ -770,7 +853,7 @@
2390
2391 atexit (close_stdout);
2392
2393- while ((c = getopt_long (argc, argv, "c:fLlt", long_options, NULL)) != -1)
2394+ while ((c = getopt_long (argc, argv, "c:fLltZ", long_options, NULL)) != -1)
2395 {
2396 switch (c)
2397 {
2398@@ -787,6 +870,14 @@
2399 case 't':
2400 terse = 1;
2401 break;
2402+ case 'Z':
2403+ if(is_selinux_enabled())
2404+ secure = 1;
2405+ else {
842e81f4 2406+ error (0, 0, _("Kernel is not SELinux-enabled"));
0107077f
AM
2407+ usage (EXIT_FAILURE);
2408+ }
2409+ break;
2410
2411 case_GETOPT_HELP_CHAR;
2412
2413@@ -806,9 +897,9 @@
2414 for (i = optind; i < argc; i++)
2415 {
2416 if (fs == 0)
2417- do_stat (argv[i], follow_links, terse, format);
2418+ do_stat (argv[i], follow_links, terse, secure, format);
2419 else
2420- do_statfs (argv[i], terse, format);
2421+ do_statfs (argv[i], terse, secure, format);
2422 }
2423
2424 exit (G_fail ? EXIT_FAILURE : EXIT_SUCCESS);
842e81f4
JB
2425--- coreutils-5.0/po/POTFILES.in.orig 2003-12-29 00:25:44.000000000 +0100
2426+++ coreutils-5.0/po/POTFILES.in 2003-12-29 00:27:23.176769816 +0100
2427@@ -22,6 +22,7 @@
2428
2429 src/basename.c
2430 src/cat.c
2431+src/chcon.c
2432 src/chgrp.c
2433 src/chmod.c
2434 src/chown-core.c
2435@@ -79,6 +80,7 @@
2436 src/remove.c
2437 src/rm.c
2438 src/rmdir.c
2439+src/runcon.c
2440 src/seq.c
2441 src/shred.c
2442 src/sleep.c
2443--- coreutils-5.0/po/pl.po.orig 2003-12-29 01:26:32.456197328 +0100
2444+++ coreutils-5.0/po/pl.po 2003-12-29 01:27:15.382671512 +0100
2445@@ -430,6 +430,95 @@
2446 msgid "closing standard output"
2447