1 diff -Nur coreutils-5.0/lib/Makefile.am coreutils-5.0.new/lib/Makefile.am
2 --- coreutils-5.0/lib/Makefile.am 2003-04-02 12:16:19.000000000 +0200
3 +++ coreutils-5.0.new/lib/Makefile.am 2003-06-06 03:01:11.000000000 +0200
6 noinst_LIBRARIES = libfetish.a
8 -INCLUDES = -I.. -I$(srcdir)
9 -DEFS = -DLIBDIR=\"$(libdir)\" @DEFS@
10 +INCLUDES = -I.. -I$(srcdir) -I/usr/include/selinux
11 +DEFS = -DLIBDIR=\"$(libdir)\" -DFLASK_LINUX @DEFS@
13 ## Put relatively complex files at the beginning of the list so
14 ## that parallel compiles finish a tiny bit sooner. I don't see
15 diff -Nur coreutils-5.0/lib/makepath.c coreutils-5.0.new/lib/makepath.c
16 --- coreutils-5.0/lib/makepath.c 2003-03-04 22:19:25.000000000 +0100
17 +++ coreutils-5.0.new/lib/makepath.c 2003-06-06 03:01:11.000000000 +0200
20 #include <sys/types.h>
23 +#include <fs_secure.h>
33 +static security_id_t Sid = -1;
38 +make_dir_s (const char *dir,
39 + const char *dirpath,
45 + return( make_dir(dir, dirpath,mode, created_dir_p));
50 /* Attempt to create directory DIR (aka DIRPATH) with the specified MODE.
51 If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P to non-zero if this
52 function creates DIR and to zero otherwise. Give a diagnostic and
58 + if ( (int) Sid > 0 )
59 + created_dir = (mkdir_secure (dir, mode, Sid) == 0);
62 created_dir = (mkdir (dir, mode) == 0);
72 +make_path_s (const char *argpath,
77 + int preserve_existing,
78 + const char *verbose_fmt_string,
82 + return( make_path(argpath, mode, parent_mode, owner, group, preserve_existing, verbose_fmt_string) );
87 /* Ensure that the directory ARGPATH exists.
89 Create any leading directories that don't already exist, with
90 diff -Nur coreutils-5.0/man/chcon.x coreutils-5.0.new/man/chcon.x
91 --- coreutils-5.0/man/chcon.x 1970-01-01 01:00:00.000000000 +0100
92 +++ coreutils-5.0.new/man/chcon.x 2003-06-06 03:01:11.000000000 +0200
95 +chcon \- change file security context
97 +.\" Add any additional description here
98 diff -Nur coreutils-5.0/man/Makefile.am coreutils-5.0.new/man/Makefile.am
99 --- coreutils-5.0/man/Makefile.am 2003-06-06 02:58:53.000000000 +0200
100 +++ coreutils-5.0.new/man/Makefile.am 2003-06-06 03:04:25.000000000 +0200
102 rm.1 rmdir.1 seq.1 sha1sum.1 shred.1 sleep.1 sort.1 split.1 stat.1 stty.1 \
103 su.1 sum.1 sync.1 tac.1 tail.1 tee.1 test.1 touch.1 tr.1 true.1 tsort.1 \
104 tty.1 uname.1 unexpand.1 uniq.1 unlink.1 uptime.1 users.1 vdir.1 wc.1 \
105 - who.1 whoami.1 yes.1
106 + who.1 whoami.1 yes.1 chcon.1 runas.1
109 man_aux = $(dist_man_MANS:.1=.x)
111 who.1: $(common_dep) $(srcdir)/who.x ../src/who.c
112 whoami.1: $(common_dep) $(srcdir)/whoami.x ../src/whoami.c
113 yes.1: $(common_dep) $(srcdir)/yes.x ../src/yes.c
114 +chcon.1: $(common_dep) $(srcdir)/chcon.x ../src/chcon.c
115 +runas.1: $(common_dep) $(srcdir)/runas.x ../src/runas.c
119 diff -Nur coreutils-5.0/man/runas.x coreutils-5.0.new/man/runas.x
120 --- coreutils-5.0/man/runas.x 1970-01-01 01:00:00.000000000 +0100
121 +++ coreutils-5.0.new/man/runas.x 2003-06-06 03:01:11.000000000 +0200
124 +.\" Add any additional description here
125 diff -Nur coreutils-5.0/README coreutils-5.0.new/README
126 --- coreutils-5.0/README 2003-03-29 15:24:00.000000000 +0100
127 +++ coreutils-5.0.new/README 2003-06-06 03:01:11.000000000 +0200
130 The programs that can be built with this package are:
132 - basename cat chgrp chmod chown chroot cksum comm cp csplit cut date dd
133 + basename cat chcon chgrp chmod chown chroot cksum comm cp csplit cut date dd
134 df dir dircolors dirname du echo env expand expr factor false fmt fold
135 ginstall groups head hostid hostname id join kill link ln logname ls
136 md5sum mkdir mkfifo mknod mv nice nl nohup od paste pathchk pinky pr
137 - printenv printf ptx pwd readlink rm rmdir seq sha1sum shred sleep sort
138 + printenv printf ptx pwd readlink rm rmdir runas seq sha1sum shred sleep sort
139 split stat stty su sum sync tac tail tee test touch tr true tsort tty
140 uname unexpand uniq unlink uptime users vdir wc who whoami yes
142 diff -Nur coreutils-5.0/src/chcon.c coreutils-5.0.new/src/chcon.c
143 --- coreutils-5.0/src/chcon.c 1970-01-01 01:00:00.000000000 +0100
144 +++ coreutils-5.0.new/src/chcon.c 2003-06-06 03:01:11.000000000 +0200
146 +/* chcontext -- change security context of a pathname */
150 +#include <sys/types.h>
153 +#include <fs_secure.h>
157 +#include "savedir.h"
158 +#include "group-member.h"
164 + CH_NO_CHANGE_REQUESTED
169 + /* Print a message for each file that is processed. */
172 + /* Print a message for each file whose attributes we change. */
175 + /* Do not be verbose. This is the default. */
179 +static int change_dir_context PARAMS ((const char *dir, int sid,
180 + const struct stat *statp));
182 +/* The name the program was run with. */
185 +/* If nonzero, and the systems has support for it, change the context
186 + of symbolic links rather than any files they point to. */
187 +static int change_symlinks;
189 +/* If nonzero, change the context of directories recursively. */
192 +/* If nonzero, force silence (no error messages). */
193 +static int force_silent;
195 +/* Level of verbosity. */
196 +static enum Verbosity verbosity = V_off;
198 +/* The name of the context the file is being given. */
199 +static const char *contextname;
201 +/* The argument to the --reference option. Use the context SID of this file.
202 + This file must exist. */
203 +static char *reference_file;
205 +/* If nonzero, display usage information and exit. */
206 +static int show_help;
208 +/* If nonzero, print the version on standard output and exit. */
209 +static int show_version;
211 +static struct option const long_options[] =
213 + {"recursive", no_argument, 0, 'R'},
214 + {"changes", no_argument, 0, 'c'},
215 + {"no-dereference", no_argument, 0, 'h'},
216 + {"silent", no_argument, 0, 'f'},
217 + {"quiet", no_argument, 0, 'f'},
218 + {"reference", required_argument, 0, CHAR_MAX + 1},
219 + {"sid", required_argument, 0, CHAR_MAX + 2},
220 + {"verbose", no_argument, 0, 'v'},
221 + {"help", no_argument, &show_help, 1},
222 + {"version", no_argument, &show_version, 1},
226 +/* Tell the user how/if the context of FILE has been changed.
227 + CHANGED describes what (if anything) has happened. */
230 +describe_change (const char *file, enum Change_status changed)
236 + fmt = _("context of %s changed to %s\n");
239 + fmt = _("failed to change context of %s to %s\n");
241 + case CH_NO_CHANGE_REQUESTED:
242 + fmt = _("context of %s retained as %s\n");
247 + printf (fmt, file, contextname);
250 +/* Change the context of FILE to SID CONTEXT.
251 + If it is a directory and -R is given, recurse.
252 + Return 0 if successful, 1 if errors occurred. */
255 +change_file_context (const char *file, int sid)
257 + struct stat file_stats;
258 + security_id_t file_sid;
261 + if (lstat_secure (file, &file_stats, &file_sid))
263 + if (force_silent == 0)
264 + error (0, errno, "%s", file);
268 + if (sid != file_sid)
272 + if (change_symlinks)
273 + fail = lchsid (file, sid);
275 + fail = chsid (file, sid);
277 + if (verbosity == V_high || (verbosity == V_changes_only && !fail))
278 + describe_change (file, (fail ? CH_FAILED : CH_SUCCEEDED));
283 + if (force_silent == 0)
285 + error (0, errno, "%s", file);
289 + else if (verbosity == V_high)
291 + describe_change (file, CH_NO_CHANGE_REQUESTED);
294 + if (recurse && S_ISDIR (file_stats.st_mode))
295 + errors |= change_dir_context (file, sid, &file_stats);
300 +/* Recursively change context of the files in directory DIR
302 + STATP points to the results of lstat on DIR.
303 + Return 0 if successful, 1 if errors occurred. */
306 +change_dir_context (const char *dir, int sid, const struct stat *statp)
308 + char *name_space, *namep;
309 + char *path; /* Full path of each entry to process. */
310 + unsigned dirlength; /* Length of `dir' and '\0'. */
311 + unsigned filelength; /* Length of each pathname to process. */
312 + unsigned pathlength; /* Bytes allocated for `path'. */
316 + name_space = savedir (dir);
317 + if (name_space == NULL)
321 + if (force_silent == 0)
322 + error (0, errno, "%s", dir);
326 + error (1, 0, _("virtual memory exhausted"));
329 + dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
330 + pathlength = dirlength + 1;
331 + /* Give `path' a dummy value; it will be reallocated before first use. */
332 + path = xmalloc (pathlength);
333 + strcpy (path, dir);
334 + path[dirlength - 1] = '/';
336 + for (namep = name_space; *namep; namep += filelength - dirlength)
338 + filelength = dirlength + strlen (namep) + 1;
339 + if (filelength > pathlength)
341 + pathlength = filelength * 2;
342 + path = xrealloc (path, pathlength);
344 + strcpy (path + dirlength, namep);
345 + errors |= change_file_context (path, sid);
356 + fprintf (stderr, _("Try `%s --help' for more information.\n"),
361 +Usage: %s [OPTION]... CONTEXT FILE...\n\
362 + or: %s [OPTION]... --reference=RFILE FILE...\n\
363 + or: %s [OPTION]... --sid=SID FILE...\n\
365 + program_name, program_name, program_name);
367 +Change the security context of each FILE to CONTEXT.\n\
369 + -c, --changes like verbose but report only when a change is made\n\
370 + -h, --no-dereference affect symbolic links instead of any referenced file\n\
371 + (available only on systems with lchown system call)\n\
372 + -f, --silent, --quiet suppress most error messages\n\
373 + --reference=RFILE use RFILE's group instead of using a CONTEXT value\n\
374 + --sid=SID use context corresponding to SID for CONTEXT value\n\
375 + -R, --recursive change files and directories recursively\n\
376 + -v, --verbose output a diagnostic for every file processed\n\
377 + --help display this help and exit\n\
378 + --version output version information and exit\n\
386 +main (int argc, char **argv)
392 + program_name = argv[0];
393 + setlocale (LC_ALL, "");
394 + bindtextdomain (PACKAGE, LOCALEDIR);
395 + textdomain (PACKAGE);
397 + recurse = force_silent = 0;
399 + while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
406 + reference_file = optarg;
409 + sid = (int)strtol( optarg, (char **)NULL, 10);
410 + /* We use an int to represent sids so we can use -1 for *
411 + * an error condition. All valid sids are positive. *
412 + * Check for an invalid sid. */
413 + if( ( errno == ERANGE ) || ( sid <= 0 ) ) {
414 + error( 1, 0, _("invalid sid"));
421 + verbosity = V_changes_only;
427 + change_symlinks = 1;
430 + verbosity = V_high;
439 + printf ("chcon (%s) %s\n", GNU_PACKAGE, VERSION);
447 + if (argc - optind + ( (reference_file || ( sid > 0 ) ) ? 1 : 0) <= 1)
449 + error (0, 0, _("too few arguments"));
453 + if (reference_file)
455 + struct stat ref_stats;
456 + security_id_t ref_sid;
457 + if (stat_secure (reference_file, &ref_stats, &ref_sid))
458 + error (1, errno, "%s", reference_file);
462 + else if( sid <= 0 ) /* sid > 0 means sid already set by --sid above */
464 + contextname = argv[optind++];
466 + if (*contextname == '\0')
467 + error (1, 0, _("can not change to null context"));
469 + if (security_context_to_sid (contextname, strlen (contextname) + 1, &sid))
470 + error (1, errno, "%s", contextname);
473 + for (; optind < argc; ++optind)
474 + errors |= change_file_context (argv[optind], sid);
476 + if (verbosity != V_off)
480 diff -Nur coreutils-5.0/src/copy.c coreutils-5.0.new/src/copy.c
481 --- coreutils-5.0/src/copy.c 2003-06-06 02:58:57.000000000 +0200
482 +++ coreutils-5.0.new/src/copy.c 2003-06-06 03:01:11.000000000 +0200
485 #include "xreadlink.h"
488 +#include <fs_secure.h>
489 +security_id_t Sid = -1;
492 #define DO_CHOWN(Chown, File, New_uid, New_gid) \
493 (Chown (File, New_uid, New_gid) \
494 /* If non-root uses -p, it's ok if we can't preserve ownership. \
496 off_t n_read_total = 0;
497 int last_write_made_hole = 0;
498 int make_holes = (x->sparse_mode == SPARSE_ALWAYS);
500 + security_id_t lsid;
503 source_desc = open (src_path, O_RDONLY);
505 @@ -780,12 +788,20 @@
506 int copied_as_regular = 0;
507 int dst_mode_valid = 0;
508 int preserve_metadata;
510 + security_id_t lsid;
511 + struct stat tst_sb;
514 if (x->move_mode && rename_succeeded)
515 *rename_succeeded = 0;
519 + if ((*(x->xstat)) (src_path, &src_sb, &lsid))
521 if ((*(x->xstat)) (src_path, &src_sb))
524 error (0, errno, _("cannot stat %s"), quote (src_path));
531 + if ((*(x->xstat)) (dst_path, &dst_sb, &lsid))
533 if ((*(x->xstat)) (dst_path, &dst_sb))
538 @@ -1463,6 +1483,25 @@
539 preserving owner/group is a potential security problem. */
543 + /* Trying to preserve a security context can fail for any UID, and user
544 + * should probably always know about it.
546 + if ( x->preserve_security_context ) {
547 + if ( (int) Sid > 0 ) {
548 + error (0, 0, _("cannot set context to SID==%d and preserve it"), (int)Sid);
551 + if ( stat_secure(src_path, &tst_sb, &lsid) < 0 ) {
552 + error (0, errno, _("getting security context for %s"), src_path);
555 + if ( chsid(dst_path, lsid) < 0 ) {
556 + error (0, errno, _("preserving security context for %s (sid==%d)"), dst_path, (int)lsid);
564 @@ -1596,6 +1635,15 @@
565 quote_n (0, dst_backup), quote_n (1, dst_path));
570 + /* if rename() just failed, so will this */
571 + if ( (int) Sid > 0 && x->preserve_security_context == 0 ) {
572 + if ( chsid(dst_path, Sid) < 0 )
573 + error (0, errno, _("setting scontext (%d) for %s"), (int)Sid, dst_path);
580 @@ -1627,6 +1675,17 @@
581 same as) DST_PATH; otherwise, set it to zero.
582 Return 0 if successful, 1 if an error occurs. */
586 +copy_s (const char *src_path, const char *dst_path,
587 + int nonexistent_dst, const struct cp_options *options,
588 + int *copy_into_self, int *rename_succeeded, security_id_t sid)
591 + return( copy( src_path, dst_path, nonexistent_dst, options, copy_into_self, rename_succeeded) );
596 copy (const char *src_path, const char *dst_path,
597 int nonexistent_dst, const struct cp_options *options,
598 diff -Nur coreutils-5.0/src/copy.h coreutils-5.0.new/src/copy.h
599 --- coreutils-5.0/src/copy.h 2003-06-06 02:58:57.000000000 +0200
600 +++ coreutils-5.0.new/src/copy.h 2003-06-06 03:01:12.000000000 +0200
602 int preserve_ownership;
604 int preserve_timestamps;
606 + int preserve_security_context;
609 /* Enabled for mv, and for cp by the --preserve=links option.
610 If nonzero, attempt to preserve in the destination files any
611 diff -Nur coreutils-5.0/src/copy.h.orig coreutils-5.0.new/src/copy.h.orig
612 --- coreutils-5.0/src/copy.h.orig 2003-03-26 19:46:56.000000000 +0100
613 +++ coreutils-5.0.new/src/copy.h.orig 1970-01-01 01:00:00.000000000 +0100
620 -/* Control creation of sparse files (files with holes). */
625 - /* Never create holes in DEST. */
628 - /* This is the default. Use a crude (and sometimes inaccurate)
629 - heuristic to determine if SOURCE has holes. If so, try to create
633 - /* For every sufficiently long sequence of bytes in SOURCE, try to
634 - create a corresponding hole in DEST. There is a performance penalty
635 - here because CP has to search for holes in SRC. But if the holes are
636 - big enough, that penalty can be offset by the decrease in the amount
637 - of data written to disk. */
641 -/* This type is used to help mv (via copy.c) distinguish these cases. */
650 -/* How to handle symbolic links. */
651 -enum Dereference_symlink
653 - DEREF_UNDEFINED = 1,
655 - /* Copy the symbolic link itself. -P */
658 - /* If the symbolic is a command line argument, then copy
659 - its referent. Otherwise, copy the symbolic link itself. -H */
660 - DEREF_COMMAND_LINE_ARGUMENTS,
662 - /* Copy the referent of the symbolic link. -L */
666 -# define VALID_SPARSE_MODE(Mode) \
667 - ((Mode) == SPARSE_NEVER \
668 - || (Mode) == SPARSE_AUTO \
669 - || (Mode) == SPARSE_ALWAYS)
671 -/* These options control how files are copied by at least the
672 - following programs: mv (when rename doesn't work), cp, install.
673 - So, if you add a new member, be sure to initialize it in
674 - mv.c, cp.c, and install.c. */
677 - enum backup_type backup_type;
679 - /* If nonzero, copy all files except (directories and, if not dereferencing
680 - them, symbolic links,) as if they were regular files. */
681 - int copy_as_regular;
683 - /* How to handle symlinks. */
684 - enum Dereference_symlink dereference;
686 - /* If nonzero, remove each existing destination nondirectory before
687 - trying to open it. */
688 - int unlink_dest_before_opening;
690 - /* If nonzero, first try to open each existing destination nondirectory,
691 - then, if the open fails, unlink and try again.
692 - This option must be set for `cp -f', in case the destination file
693 - exists when the open is attempted. It is irrelevant to `mv' since
694 - any destination is sure to be removed before the open. */
695 - int unlink_dest_after_failed_open;
697 - /* If nonzero, create hard links instead of copying files.
698 - Create destination directories as usual. */
701 - /* This value is used to determine whether to prompt before removing
702 - each existing destination file. It works differently depending on
703 - whether move_mode is set. See code/comments in copy.c. */
704 - enum Interactive interactive;
706 - /* If nonzero, rather than copying, first attempt to use rename.
707 - If that fails, then resort to copying. */
710 - /* This process's effective user ID. */
713 - /* If nonzero, when copying recursively, skip any subdirectories that are
714 - on different filesystems from the one we started on. */
715 - int one_file_system;
717 - /* If nonzero, attempt to give the copies the original files' permissions,
718 - owner, group, and timestamps. */
719 - int preserve_ownership;
721 - int preserve_timestamps;
723 - /* Enabled for mv, and for cp by the --preserve=links option.
724 - If nonzero, attempt to preserve in the destination files any
725 - logical hard links between the source files. If used with cp's
726 - --no-dereference option, and copying two hard-linked files,
727 - the two corresponding destination files will also be hard linked.
729 - If used with cp's --dereference (-L) option, then, as that option implies,
730 - hard links are *not* preserved. However, when copying a file F and
731 - a symlink S to F, the resulting S and F in the destination directory
732 - will be hard links to the same file (a copy of F). */
733 - int preserve_links;
735 - /* If nonzero and any of the above (for preserve) file attributes cannot
736 - be applied to a destination file, treat it as a failure and return
737 - nonzero immediately. E.g. cp -p requires this be nonzero, mv requires
739 - int require_preserve;
741 - /* If nonzero, copy directories recursively and copy special files
742 - as themselves rather than copying their contents. */
745 - /* If nonzero, set file mode to value of MODE. Otherwise,
746 - set it based on current umask modified by UMASK_KILL. */
749 - /* Set the mode of the destination file to exactly this value
750 - if USE_MODE is nonzero. */
753 - /* Control creation of sparse files. */
754 - enum Sparse_type sparse_mode;
756 - /* If nonzero, create symbolic links instead of copying files.
757 - Create destination directories as usual. */
760 - /* The bits to preserve in created files' modes. */
763 - /* If nonzero, do not copy a nondirectory that has an existing destination
764 - with the same or newer modification time. */
767 - /* If nonzero, display the names of the files before copying them. */
770 - /* A pointer to either lstat or stat, depending on
771 - whether the copy should dereference symlinks. */
774 - /* If nonzero, stdin is a tty. */
777 - /* This is a set of destination name/inode/dev triples. Each such triple
778 - represents a file we have created corresponding to a source file name
779 - that was specified on the command line. Use it to avoid clobbering
780 - source files in commands like this:
781 - rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
782 - For now, it protects only regular files when copying (i.e. not renaming).
783 - When renaming, it protects all non-directories.
784 - Use dest_info_init to initialize it, or set it to NULL to disable
786 - Hash_table *dest_info;
789 - Hash_table *src_info;
795 -/* Arrange to make lstat calls go through the wrapper function
796 - on systems with an lstat function that does not dereference symlinks
797 - that are specified with a trailing slash. */
798 -# if ! LSTAT_FOLLOWS_SLASHED_SYMLINK
799 -int rpl_lstat (const char *, struct stat *);
801 -# define lstat rpl_lstat
806 -/* Arrange to make rename calls go through the wrapper function
807 - on systems with a rename function that fails for a source path
808 - specified with a trailing slash. */
809 -# if RENAME_TRAILING_SLASH_BUG
810 -int rpl_rename (const char *, const char *);
812 -# define rename rpl_rename
816 -copy (const char *src_path, const char *dst_path,
817 - int nonexistent_dst, const struct cp_options *options,
818 - int *copy_into_self, int *rename_succeeded);
821 -dest_info_init (struct cp_options *);
823 -src_info_init (struct cp_options *);
826 diff -Nur coreutils-5.0/src/cp.c coreutils-5.0.new/src/cp.c
827 --- coreutils-5.0/src/cp.c 2003-06-06 02:58:57.000000000 +0200
828 +++ coreutils-5.0.new/src/cp.c 2003-06-06 03:01:12.000000000 +0200
831 #define AUTHORS N_ ("Torbjorn Granlund, David MacKenzie, and Jim Meyering")
834 +#include <fs_secure.h>
835 +#include <flask_util.h> /* for is_flask_enabled() */
837 +char *scontext = NULL;
838 +security_id_t sid = -1;
839 +int ctxtlen = CTXTLEN;
843 #ifndef _POSIX_VERSION
847 {"update", no_argument, NULL, 'u'},
848 {"verbose", no_argument, NULL, 'v'},
849 {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
851 + {"sid", required_argument, NULL, 'Z'},
852 + {"context", required_argument, NULL, 'X'},
854 {GETOPT_HELP_OPTION_DECL},
855 {GETOPT_VERSION_OPTION_DECL},
858 additional attributes: links, all\n\
861 + -c same as --preserve=context\n\
864 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
865 --parents append source path to DIRECTORY\n\
866 -P same as `--no-dereference'\n\
868 destination file is missing\n\
869 -v, --verbose explain what is being done\n\
870 -x, --one-file-system stay on this file system\n\
871 + -X, --context=CONTEXT set security context of copy to CONTEXT\n\
872 + -Z, --sid=SID set Security ID of copy to SID\n\
874 fputs (HELP_OPTION_DESCRIPTION, stdout);
875 fputs (VERSION_OPTION_DESCRIPTION, stdout);
877 char *dst_path; /* A copy of CONST_DST_PATH we can change. */
878 char *src_path; /* The source name in `dst_path'. */
879 uid_t myeuid = geteuid ();
881 + security_id_t lsid;
884 dst_path = (char *) alloca (strlen (const_dst_path) + 1);
885 strcpy (dst_path, const_dst_path);
888 dst_path[p->slash_offset] = '\0';
891 + if ((*(x->xstat)) (src_path, &src_sb, &lsid))
893 if ((*(x->xstat)) (src_path, &src_sb))
896 error (0, errno, _("failed to get attributes of %s"),
903 + /* Trying to preserve a security context can fail for any UID, and user
904 + * should probably always know about it.
907 + if ( x->preserve_security_context ) {
910 + security_id_t lsid;
912 + if ( (rv = stat_secure(src_path, &st, &lsid)) < 0 ) {
913 + error (0, errno, _("getting security context for %s"), src_path);
917 + if ( (rv = chsid(dst_path, lsid)) < 0 ) {
918 + error (0, errno, _("preserving security context for %s (sid==%d)"), dst_path, (int)lsid);
924 dst_path[p->slash_offset] = '/';
932 + if ( (int) sid > 0 )
933 + ret |= copy_s (arg, dst_path, new_dst, x, ©_into_self, NULL, sid);
936 ret |= copy (arg, dst_path, new_dst, x, ©_into_self, NULL);
941 new_dest = (char *) dest;
944 - return copy (source, new_dest, new_dst, x, &unused, NULL);
946 + if ( (int) sid > 0 )
947 + return copy_s (source, new_dest, new_dst, x, &unused, NULL, sid);
950 + return copy (source, new_dest, new_dst, x, &unused, NULL);
955 x->preserve_mode = 0;
956 x->preserve_timestamps = 0;
959 + x->preserve_security_context = 0;
962 x->require_preserve = 0;
964 x->sparse_mode = SPARSE_AUTO;
965 @@ -808,19 +869,20 @@
972 static enum File_attribute const preserve_vals[] =
974 PRESERVE_MODE, PRESERVE_TIMESTAMPS,
975 - PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL
976 + PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL
979 /* Valid arguments to the `--preserve' option. */
980 static char const* const preserve_args[] =
982 "mode", "timestamps",
983 - "ownership", "links", "all", 0
984 + "ownership", "links", "context", "all", 0
987 char *arg_writable = xstrdup (arg);
988 @@ -855,11 +917,16 @@
989 x->preserve_links = on_off;
992 + case PRESERVE_CONTEXT:
993 + x->preserve_security_context = on_off;
997 x->preserve_mode = on_off;
998 x->preserve_timestamps = on_off;
999 x->preserve_ownership = on_off;
1000 x->preserve_links = on_off;
1001 + x->preserve_security_context = on_off;
1005 @@ -882,6 +949,11 @@
1006 struct cp_options x;
1007 int copy_contents = 0;
1008 char *target_directory = NULL;
1010 + int is_flask_enabled_flag;
1012 + is_flask_enabled_flag = is_flask_enabled();
1015 program_name = argv[0];
1016 setlocale (LC_ALL, "");
1017 @@ -896,7 +968,11 @@
1018 we'll actually use backup_suffix_string. */
1019 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1022 + while ((c = getopt_long (argc, argv, "abcdfHilLprsuvxPRS:V:X:Z:", long_opts, NULL))
1024 while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:", long_opts, NULL))
1029 @@ -987,6 +1063,85 @@
1030 x.preserve_timestamps = 1;
1031 x.require_preserve = 1;
1035 + if ( (int) sid > 0 ) { /* scontext could be NULL because of calloc() failure */
1037 + (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], scontext);
1039 + (void) fprintf(stderr, "%s: cannot force target context <-- %d and preserve it\n", argv[0], (int) sid);
1042 + else if (is_flask_enabled_flag)
1043 + x.preserve_security_context = 1;
1046 + /* politely decline if we're not on a flask-enabled kernel. */
1047 + if( !is_flask_enabled_flag ) {
1048 + fprintf( stderr, "Warning: ignoring --sid (-Z) "
1049 + "because the kernel is not flask-enabled.\n" );
1052 + if ( x.preserve_security_context ) {
1053 + (void) fprintf(stderr, "%s: can't force target context to '%s' and preserve it\n", argv[0], optarg);
1056 + if ( (int) sid > 0 || scontext != NULL ) {
1057 + (void) fprintf(stderr, "%s: --sid (-Z) and --context (-X) are mutually exclusive\n", argv[0]);
1060 + /* check for typos */
1063 + sid = (security_id_t) strtol(optarg, &ep, 10);
1065 + (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
1069 + /* do a sanity check and save result if SID is OK */
1070 + scontext = calloc(1, ctxtlen+1);
1071 + if ( scontext != NULL ) {
1072 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
1073 + if ( errno != ENOSPC ) {
1074 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
1078 + scontext = calloc(1, ctxtlen+1);
1080 + if ( scontext != NULL )
1081 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
1082 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
1089 + /* politely decline if we're not on a flask-enabled kernel. */
1090 + if( !is_flask_enabled_flag ) {
1091 + fprintf( stderr, "Warning: ignoring --context (-X) "
1092 + "because the kernel is not flask-enabled.\n" );
1095 + if ( x.preserve_security_context ) {
1096 + (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg);
1099 + if ( (int) sid > 0 ) {
1100 + (void) fprintf(stderr, "%s: --context (-X) and --sid (-Z) are mutually exclusive\n", argv[0]);
1103 + scontext = optarg;
1104 + /* sanity check -- also sets sid val */
1105 + if ( security_context_to_sid(scontext, strlen(scontext)+1, &sid) ) {
1106 + (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n",
1107 + argv[0], scontext, strerror(errno));
1113 case PARENTS_OPTION:
1115 @@ -1076,13 +1231,21 @@
1116 of `stat' to call. */
1118 if (x.dereference == DEREF_NEVER)
1120 + x.xstat = lstat_secure;
1126 /* For DEREF_COMMAND_LINE_ARGUMENTS, x.xstat must be stat for
1127 each command line argument, but must later be `lstat' for
1128 any symlinks that are found via recursive traversal. */
1130 + x.xstat = stat_secure;
1137 diff -Nur coreutils-5.0/src/id.c coreutils-5.0.new/src/id.c
1138 --- coreutils-5.0/src/id.c 2003-03-27 23:39:46.000000000 +0100
1139 +++ coreutils-5.0.new/src/id.c 2003-06-06 03:01:12.000000000 +0200
1145 +#include <proc_secure.h>
1146 +#include <flask_util.h>
1149 #include "closeout.h"
1154 +static void print_context PARAMS ((char* context));
1155 +static void print_sid PARAMS ((security_id_t sid));
1156 static void print_user (uid_t uid);
1157 static void print_group (gid_t gid);
1158 static void print_group_list (const char *username);
1160 /* The name this program was run with. */
1163 +/* If nonzero, output only the TOS context. -c */
1164 +static int just_context = 0;
1166 +/* If nonzero, output only the security ID (sid). -s */
1167 +static int just_sid = 0;
1169 /* If nonzero, output user/group name instead of ID number. -n */
1170 static int use_name = 0;
1173 /* The number of errors encountered so far. */
1174 static int problems = 0;
1176 +/* The TOS context */
1177 +static char context[1024];
1179 +/* The security ID ("sid") */
1180 +security_id_t mysid = 0;
1183 static struct option const longopts[] =
1185 + {"context", no_argument, NULL, 'c'},
1186 {"group", no_argument, NULL, 'g'},
1187 {"groups", no_argument, NULL, 'G'},
1188 {"name", no_argument, NULL, 'n'},
1189 {"real", no_argument, NULL, 'r'},
1190 + {"sid", no_argument, NULL, 's'},
1191 {"user", no_argument, NULL, 'u'},
1192 {GETOPT_HELP_OPTION_DECL},
1193 {GETOPT_VERSION_OPTION_DECL},
1194 @@ -89,10 +107,12 @@
1195 Print information for USERNAME, or the current user.\n\
1197 -a ignore, for compatibility with other versions\n\
1198 + -c, --context print only the context\n\
1199 -g, --group print only the effective group ID\n\
1200 -G, --groups print all group IDs\n\
1201 -n, --name print a name instead of a number, for -ugG\n\
1202 -r, --real print the real ID instead of the effective ID, with -ugG\n\
1203 + -s, --sid print only the security ID\n\
1204 -u, --user print only the effective user ID\n\
1206 fputs (HELP_OPTION_DESCRIPTION, stdout);
1208 main (int argc, char **argv)
1211 + int len = sizeof (context);
1212 + int is_flask_enabled_flag;
1214 /* If nonzero, output the list of all group IDs. -G */
1215 int just_group_list = 0;
1216 @@ -125,9 +147,15 @@
1217 bindtextdomain (PACKAGE, LOCALEDIR);
1218 textdomain (PACKAGE);
1220 + /* Set `context' to a known invalid value so print_full_info() will *
1221 + * know when `context' has not been set to a meaningful value. */
1222 + context[ 0 ] = '\0';
1224 + is_flask_enabled_flag = is_flask_enabled();
1226 atexit (close_stdout);
1228 - while ((optc = getopt_long (argc, argv, "agnruG", longopts, NULL)) != -1)
1229 + while ((optc = getopt_long (argc, argv, "acgnrsuG", longopts, NULL)) != -1)
1233 @@ -136,6 +164,15 @@
1235 /* Ignore -a, for compatibility with SVR4. */
1238 + /* politely decline if we're not on a flask-enabled kernel. */
1239 + if( !is_flask_enabled_flag ) {
1240 + fprintf( stderr, "Sorry, --context (-c) can be used only on "
1241 + "a flask-enabled kernel.\n" );
1249 @@ -145,6 +182,15 @@
1254 + /* politely decline if we're not on a flask-enabled kernel. */
1255 + if( !is_flask_enabled_flag ) {
1256 + fprintf( stderr, "Sorry, --sid (-s) can be used only on "
1257 + "a flask-enabled kernel.\n" );
1265 @@ -158,13 +204,32 @@
1269 - if (just_user + just_group + just_group_list > 1)
1270 - error (EXIT_FAILURE, 0, _("cannot print only user and only group"));
1271 + if (argc - optind == 1)
1272 + is_flask_enabled_flag = 0;
1274 + if (just_user + just_group + just_group_list + just_context + just_sid > 1)
1275 + error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
1277 if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
1278 error (EXIT_FAILURE, 0,
1279 _("cannot print only names or real IDs in default format"));
1281 + if( (just_context | just_sid) && !is_flask_enabled_flag)
1283 +cannot display context/sid when flask not enabled or when displaying the id\n\
1284 +of a different user"));
1286 + /* If we are on a flask-enabled kernel, get our sid and context. *
1287 + * Otherwise, leave the sid and context variables alone - they have *
1288 + * been initialized known invalid values; if we see these invalid *
1289 + * values later, we will know we are on a non-flask kernel. */
1290 + if( is_flask_enabled_flag )
1292 + mysid = getsecsid ();
1293 + if( security_sid_to_context(mysid, context, &len) )
1294 + error (1, 0, "can't get process context");
1297 if (argc - optind > 1)
1298 usage (EXIT_FAILURE);
1300 @@ -190,6 +255,10 @@
1301 print_group (use_real ? rgid : egid);
1302 else if (just_group_list)
1303 print_group_list (argv[optind]);
1304 + else if (just_context)
1305 + print_context (context);
1306 + else if (just_sid)
1307 + print_sid (mysid);
1309 print_full_info (argv[optind]);
1311 @@ -197,6 +266,20 @@
1312 exit (problems != 0);
1315 +/* Print the TOS context */
1317 +print_context(char *context)
1319 + printf ("%s", context);
1322 +/* Print the security ID (sid) */
1324 +print_sid( security_id_t sid )
1326 + printf ("%u", sid );
1329 /* Print the name or value of user ID UID. */
1332 @@ -397,4 +480,10 @@
1335 #endif /* HAVE_GETGROUPS */
1336 + if ( context[0] ) {
1337 + printf(" context=%s",context);
1339 + if ( mysid != 0 ) {
1340 + printf(" sid=%u",mysid);
1343 diff -Nur coreutils-5.0/src/install.c coreutils-5.0.new/src/install.c
1344 --- coreutils-5.0/src/install.c 2003-06-06 02:58:57.000000000 +0200
1345 +++ coreutils-5.0.new/src/install.c 2003-06-06 03:01:12.000000000 +0200
1347 # include <sys/wait.h>
1351 +#include <fs_secure.h>
1352 +#include <flask_util.h> /* for is_flask_enabled() */
1353 +#define CTXTLEN 256
1354 +char *scontext = NULL;
1355 +int ctxtlen = CTXTLEN;
1359 struct passwd *getpwnam ();
1360 struct group *getgrnam ();
1362 @@ -126,11 +135,18 @@
1363 static struct option const long_options[] =
1365 {"backup", optional_argument, NULL, 'b'},
1367 + {"context", required_argument, NULL, 'X'},
1369 {"directory", no_argument, NULL, 'd'},
1370 {"group", required_argument, NULL, 'g'},
1371 {"mode", required_argument, NULL, 'm'},
1372 {"owner", required_argument, NULL, 'o'},
1373 {"preserve-timestamps", no_argument, NULL, 'p'},
1375 + {"preserve_context", no_argument, NULL, 'P'},
1376 + {"sid", required_argument, NULL, 'Z'},
1378 {"strip", no_argument, NULL, 's'},
1379 {"suffix", required_argument, NULL, 'S'},
1380 {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
1381 @@ -247,11 +263,20 @@
1386 + x->xstat = stat_secure;
1387 + x->preserve_security_context = 0;
1391 x->dest_info = NULL;
1396 +security_id_t sid = -1;
1400 main (int argc, char **argv)
1402 @@ -265,6 +290,13 @@
1403 struct cp_options x;
1408 + int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
1410 + /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
1411 + is_flask_enabled_flag = is_flask_enabled();
1414 program_name = argv[0];
1415 setlocale (LC_ALL, "");
1416 @@ -338,6 +370,90 @@
1418 backup_suffix_string = optarg;
1422 + /* politely decline if we're not on a flask-enabled kernel. */
1423 + if( !is_flask_enabled_flag ) {
1424 + fprintf( stderr, "Warning: ignoring --preserve_context (-P) "
1425 + "because the kernel is not flask-enabled.\n" );
1428 + if ( (int) sid >= 0 ) { /* scontext could be NULL because of calloc() failure */
1430 + (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], scontext);
1432 + (void) fprintf(stderr, "%s: cannot force target context <-- %d and preserve it\n", argv[0], (int) sid);
1435 + x.preserve_security_context = 1;
1438 + /* politely decline if we're not on a flask-enabled kernel. */
1439 + if( !is_flask_enabled_flag ) {
1440 + fprintf( stderr, "Warning: ignoring --sid (-Z) "
1441 + "because the kernel is not flask-enabled.\n" );
1444 + if ( x.preserve_security_context ) {
1445 + (void) fprintf(stderr, "%s: can't force target context to '%s' and preserve it\n", argv[0], optarg);
1448 + if ( scontext != NULL ) {
1449 + (void) fprintf(stderr, "%s: --sid (-Z) and --context (-X) are mutually exclusive\n", argv[0]);
1452 + /* check for typos */
1455 + sid = (security_id_t) strtol(optarg, &ep, 10);
1457 + (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
1461 + /* do a sanity check and save result if SID is OK */
1462 + scontext = calloc(1, ctxtlen+1);
1463 + if ( scontext != NULL ) {
1464 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
1465 + if ( errno != ENOSPC ) {
1466 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
1470 + scontext = calloc(1, ctxtlen+1);
1471 + if ( scontext != NULL )
1472 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
1473 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
1480 + /* politely decline if we're not on a flask-enabled kernel. */
1481 + if( !is_flask_enabled_flag ) {
1482 + fprintf( stderr, "Warning: ignoring --context (-X) "
1483 + "because the kernel is not flask-enabled.\n" );
1486 + if ( x.preserve_security_context ) {
1487 + (void) fprintf(stderr, "%s: cannot force target context == '%s' and preserve it\n", argv[0], optarg);
1490 + if ( (int) sid >= 0 ) {
1491 + (void) fprintf(stderr, "%s: --context (-X) and --sid (-Z) are mutually exclusive\n", argv[0]);
1494 + scontext = optarg;
1495 + /* sanity check */
1496 + rv = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
1498 + (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n", argv[0], scontext,
1504 case_GETOPT_HELP_CHAR;
1505 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1507 @@ -385,8 +501,13 @@
1508 for (i = 0; i < n_files; i++)
1512 + make_path_s (file[i], mode, mode, owner_id, group_id, 0,
1513 + (x.verbose ? _("creating directory %s") : NULL), sid);
1515 make_path (file[i], mode, mode, owner_id, group_id, 0,
1516 (x.verbose ? _("creating directory %s") : NULL));
1521 @@ -449,8 +570,13 @@
1522 that this option is intended mainly to help installers when the
1523 distribution doesn't provide proper install rules. */
1524 #define DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
1526 + fail = make_path_s (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
1527 + (x->verbose ? _("creating directory %s") : NULL), sid);
1529 fail = make_path (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
1530 (x->verbose ? _("creating directory %s") : NULL));
1537 /* Copy file FROM onto file TO, creating TO if necessary.
1538 Return 0 if the copy is successful, 1 if not. */
1541 copy_file (const char *from, const char *to, const struct cp_options *x)
1543 @@ -721,6 +846,12 @@
1544 -S, --suffix=SUFFIX override the usual backup suffix\n\
1545 -v, --verbose print the name of each directory as it is created\n\
1548 + -P, --preserve_context (Flask) Preserve security context\n\
1549 + -Z, --sid=SID (Flask) Set SID of files and directories\n\
1550 + -X, --context=CONTEXT (Flask) Set security context of files and directories\n\
1553 fputs (HELP_OPTION_DESCRIPTION, stdout);
1554 fputs (VERSION_OPTION_DESCRIPTION, stdout);
1556 diff -Nur coreutils-5.0/src/ls.c coreutils-5.0.new/src/ls.c
1557 --- coreutils-5.0/src/ls.c 2003-06-06 02:58:57.000000000 +0200
1558 +++ coreutils-5.0.new/src/ls.c 2003-06-06 03:01:12.000000000 +0200
1559 @@ -130,6 +130,18 @@
1561 #define AUTHORS N_ ("Richard Stallman and David MacKenzie")
1564 +#include <fs_secure.h>
1565 +#include <flask_util.h> /* for is_flask_enabled() */
1567 +#define CTXTLEN 256
1568 +#define SID_DIGITS 5
1570 +static int print_sid = 0;
1571 +static int print_scontext = 0;
1575 #define obstack_chunk_alloc malloc
1576 #define obstack_chunk_free free
1578 @@ -227,6 +239,10 @@
1579 /* For long listings, true if the file has an access control list. */
1584 + security_id_t sid;
1588 #if HAVE_ACL || USE_ACL
1590 static void sort_files (void);
1591 static void parse_ls_color (void);
1592 void usage (int status);
1594 +static void print_scontext_format PARAMS ((const struct fileinfo *f));
1597 /* The name the program was run with, stripped of any leading path. */
1599 @@ -379,7 +398,12 @@
1600 one_per_line, /* -1 */
1601 many_per_line, /* -C */
1602 horizontal, /* -x */
1603 - with_commas /* -m */
1605 + with_commas, /* -m */
1608 + with_commas /* -m */
1612 static enum format format;
1613 @@ -700,6 +724,13 @@
1614 SHOW_CONTROL_CHARS_OPTION,
1627 @@ -743,6 +774,13 @@
1628 {"time-style", required_argument, 0, TIME_STYLE_OPTION},
1629 {"color", optional_argument, 0, COLOR_OPTION},
1630 {"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
1632 + {"context", no_argument, 0, CONTEXT_OPTION},
1633 + {"lcontext", no_argument, 0, LCONTEXT_OPTION},
1634 + {"scontext", no_argument, 0, SCONTEXT_OPTION},
1635 + {"sid", no_argument, 0, SID_OPTION},
1636 + {"lsid", no_argument, 0, LSID_OPTION},
1638 {"author", no_argument, 0, AUTHOR_OPTION},
1639 {GETOPT_HELP_OPTION_DECL},
1640 {GETOPT_VERSION_OPTION_DECL},
1641 @@ -752,13 +790,21 @@
1642 static char const *const format_args[] =
1644 "verbose", "long", "commas", "horizontal", "across",
1646 + "vertical", "single-column", "context", 0
1648 "vertical", "single-column", 0
1652 static enum format const format_types[] =
1654 long_format, long_format, with_commas, horizontal, horizontal,
1656 + many_per_line, one_per_line, security_format
1658 many_per_line, one_per_line
1662 static char const *const sort_args[] =
1663 @@ -1121,6 +1167,9 @@
1665 format_needs_stat = sort_type == sort_time || sort_type == sort_size
1666 || format == long_format
1668 + || format == security_format || print_sid || print_scontext
1670 || dereference == DEREF_ALWAYS
1671 || print_block_size || print_inode;
1672 format_needs_type = (format_needs_stat == 0
1673 @@ -1243,6 +1292,13 @@
1674 /* Record whether there is an option specifying sort type. */
1675 int sort_type_specified = 0;
1678 + int is_flask_enabled_flag; /* 1 iff kernel has new flask system calls */
1680 + /* Set `is_flask_enabled_flag iff the kernel has new flask system calls. */
1681 + is_flask_enabled_flag = is_flask_enabled();
1684 qmark_funny_chars = 0;
1686 /* initialize all switches to default settings */
1687 @@ -1293,6 +1349,10 @@
1689 really_all_files = 0;
1690 ignore_patterns = 0;
1693 + print_scontext = 0;
1696 /* FIXME: put this in a function. */
1698 @@ -1656,6 +1716,40 @@
1700 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1704 +#define check_selinux() if (!is_flask_enabled_flag) { \
1705 + fprintf( stderr, "Sorry, this option can only be used " \
1706 + "on a SELinux kernel.\n" ); \
1707 + exit( EXIT_FAILURE ); \
1710 + case CONTEXT_OPTION: /* new security format */
1712 + print_scontext = 1;
1713 + format = security_format;
1715 + case LCONTEXT_OPTION: /* long format plus security context */
1717 + print_scontext = 1;
1718 + format = long_format;
1720 + case SCONTEXT_OPTION: /* short form of new security format */
1722 + print_scontext = 0;
1723 + format = security_format;
1725 + case SID_OPTION: /* SID, format unspecified */
1729 + case LSID_OPTION: /* long format plus SID */
1732 + format = long_format;
1737 usage (EXIT_FAILURE);
1739 @@ -2371,7 +2465,11 @@
1744 + err = stat_secure(path, &files[files_index].stat, &files[files_index].sid);
1746 err = stat (path, &files[files_index].stat);
1749 if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
1751 @@ -2389,7 +2487,11 @@
1754 default: /* DEREF_NEVER */
1756 + err = lstat_secure(path, &files[files_index].stat, &files[files_index].sid);
1758 err = lstat (path, &files[files_index].stat);
1763 @@ -2819,6 +2921,16 @@
1764 DIRED_PUTCHAR ('\n');
1769 + case security_format:
1770 + for (i = 0; i < files_index; i++)
1772 + print_scontext_format (files + i);
1773 + DIRED_PUTCHAR ('\n');
1780 @@ -2936,6 +3048,10 @@
1782 int when_ns IF_LINT (= 0);
1783 struct tm *when_local;
1789 /* Compute mode string. On most systems, it's based on st_mode.
1790 On systems with migration (via the stat.st_dm_mode field), use
1791 @@ -3082,6 +3198,34 @@
1797 + if ( print_sid ) {
1798 + sprintf (p, " %3u ", (unsigned int) f->sid);
1802 + if ( print_scontext ) {
1803 + ctxtlen = CTXTLEN;
1804 + scontext = xmalloc(ctxtlen);
1805 + if (security_sid_to_context(f->sid, scontext, &ctxtlen) < 0) {
1806 + if (errno == ENOSPC) {
1807 + scontext = xrealloc(scontext, ctxtlen);
1808 + if (security_sid_to_context(f->sid, scontext, &ctxtlen) < 0) {
1809 + (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
1813 + (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
1817 + sprintf (p, "%-32s ", scontext);
1824 DIRED_FPUTS (buf, stdout, p - buf);
1825 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
1826 @@ -3317,6 +3461,12 @@
1828 printf ("%*s ", INODE_DIGITS, umaxtostr (f->stat.st_ino, buf));
1832 + printf ("%*s ", SID_DIGITS,
1833 + human_readable ((uintmax_t) f->sid, buf, human_group_digits, 1, 1));
1836 if (print_block_size)
1837 printf ("%*s ", block_size_size,
1838 human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
1839 @@ -3454,6 +3604,11 @@
1841 len += INODE_DIGITS + 1;
1845 + len += SID_DIGITS + 1;
1848 if (print_block_size)
1849 len += 1 + block_size_size;
1851 @@ -3874,6 +4029,18 @@
1852 -X sort alphabetically by entry extension\n\
1853 -1 list one file per line\n\
1856 +printf(_("FLASK options:\n\n\
1857 + --lsid Display Security ID (SID). Enable -l\n\
1858 + --sid Display SID.\n\
1859 + --lcontext Display security context. Enable -l. Lines\n\
1860 + will probably be too wide for most displays.\n\
1861 + --context Display security context so it fits on most\n\
1862 + displays. Displays only mode, user, group,\n\
1863 + security context and file name.\n\
1864 + --scontext Display only security context and file name.\n\
1867 fputs (HELP_OPTION_DESCRIPTION, stdout);
1868 fputs (VERSION_OPTION_DESCRIPTION, stdout);
1870 @@ -3892,3 +4059,102 @@
1878 +print_scontext_format (const struct fileinfo *f)
1882 + /* 7 fields that may require LONGEST_HUMAN_READABLE bytes,
1883 + 1 10-byte mode string,
1884 + 9 spaces, one following each of these fields, and
1885 + 1 trailing NUL byte. */
1887 + char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1];
1888 + char *buf = init_bigbuf;
1889 + size_t bufsize = sizeof (init_bigbuf);
1901 + if ( print_scontext ) { /* zero means terse listing */
1902 + mode_string (f->stat.st_mode, modebuf);
1903 + modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' ');
1904 + modebuf[11] = '\0';
1908 + (void) sprintf (p, "%s ", modebuf);
1911 + /* print standard user and group */
1913 + user_name = (numeric_ids ? NULL : getuser (f->stat.st_uid));
1915 + (void) sprintf (p, "%-8.8s ", user_name);
1917 + (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_uid);
1920 + if ( print_group ) {
1921 + group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid));
1923 + (void) sprintf (p, "%-8.8s ", group_name);
1925 + (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_gid);
1930 + if ( print_sid ) {
1931 + sprintf (p, " %3u ", (unsigned int) f->sid);
1935 + /* print security context */
1936 + ctxtlen = CTXTLEN;
1937 + scontext = xmalloc(ctxtlen);
1938 + if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
1939 + if ( errno == ENOSPC ) {
1940 + scontext = xrealloc(scontext, ctxtlen);
1941 + if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
1942 + (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
1946 + (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
1951 + (void) sprintf (p, "%-32s ", scontext);
1956 + DIRED_FPUTS (buf, stdout, p - buf);
1957 + print_name_with_quoting (f->name, f->stat.st_mode, f->linkok, &dired_obstack);
1959 + if (f->filetype == symbolic_link) {
1960 + if (f->linkname) {
1961 + DIRED_FPUTS_LITERAL (" -> ", stdout);
1962 + print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, NULL);
1963 + if (indicator_style != none)
1964 + print_type_indicator (f->linkmode);
1968 + if (indicator_style != none)
1969 + print_type_indicator (f->stat.st_mode);
1973 diff -Nur coreutils-5.0/src/Makefile.am coreutils-5.0.new/src/Makefile.am
1974 --- coreutils-5.0/src/Makefile.am 2003-06-06 02:58:53.000000000 +0200
1975 +++ coreutils-5.0.new/src/Makefile.am 2003-06-06 03:06:13.000000000 +0200
1977 EXTRA_SCRIPTS = nohup
1979 bin_SCRIPTS = groups @OPTIONAL_BIN_ZCRIPTS@
1980 -bin_PROGRAMS = chgrp chown chmod cp dd dircolors du \
1981 +bin_PROGRAMS = chgrp chown chmod chcon cp dd dircolors du \
1982 ginstall link ln dir vdir ls mkdir \
1983 mkfifo mknod mv readlink rm rmdir shred stat sync touch unlink \
1984 cat cksum comm csplit cut expand fmt fold head join md5sum \
1985 nl od paste pr ptx sha1sum sort split sum tac tail tr tsort unexpand uniq wc \
1986 basename date dirname echo env expr factor false getgid \
1987 - hostname id kill logname pathchk printenv printf pwd seq sleep tee \
1988 + hostname id kill logname pathchk printenv printf pwd runas seq sleep tee \
1989 test true tty whoami yes \
1990 @OPTIONAL_BIN_PROGS@ @DF_PROG@
1993 groups.sh nohup.sh wheel-gen.pl
1994 CLEANFILES = $(SCRIPTS) su
1996 -INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../lib
1997 -DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@
1998 +INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../lib -I/usr/include/selinux
1999 +DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" -DFLASK_LINUX @DEFS@
2001 # Sometimes, the expansion of @LIBINTL@ includes -lc which may
2002 # include modules defining variables like `optind', so libfetish.a
2003 # must precede @LIBINTL@ in order to ensure we use GNU getopt.
2004 # But libfetish.a must also follow @LIBINTL@, since libintl uses
2005 # replacement functions defined in libfetish.a.
2006 -LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a
2007 +LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a /usr/lib/libsecure.a
2009 dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2010 ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2011 diff -Nur coreutils-5.0/src/Makefile.am.orig coreutils-5.0.new/src/Makefile.am.orig
2012 --- coreutils-5.0/src/Makefile.am.orig 2003-06-06 02:58:53.000000000 +0200
2013 +++ coreutils-5.0.new/src/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100
2015 -## Process this file with automake to produce Makefile.in -*-Makefile-*-
2017 -EXTRA_PROGRAMS = chroot df hostid nice pinky stty su uname uptime users who
2018 -EXTRA_SCRIPTS = nohup
2020 -bin_SCRIPTS = groups @OPTIONAL_BIN_ZCRIPTS@
2021 -bin_PROGRAMS = chgrp chown chmod cp dd dircolors du \
2022 - ginstall link ln dir vdir ls mkdir \
2023 - mkfifo mknod mv readlink rm rmdir shred stat sync touch unlink \
2024 - cat cksum comm csplit cut expand fmt fold head join md5sum \
2025 - nl od paste pr ptx sha1sum sort split sum tac tail tr tsort unexpand uniq wc \
2026 - basename date dirname echo env expr factor false \
2027 - hostname id kill logname pathchk printenv printf pwd seq sleep tee \
2028 - test true tty whoami yes \
2029 - @OPTIONAL_BIN_PROGS@ @DF_PROG@
2031 -localedir = $(datadir)/locale
2034 - system.h sys2.h checksum.h copy.h cp-hash.h ls.h dircolors.h remove.h \
2035 - chown-core.h fs.h \
2036 - wheel.h wheel-size.h
2037 -EXTRA_DIST = dcgen dircolors.hin tac-pipe.c \
2038 - groups.sh nohup.sh wheel-gen.pl
2039 -CLEANFILES = $(SCRIPTS) su
2041 -INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../lib
2042 -DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@
2044 -# Sometimes, the expansion of @LIBINTL@ includes -lc which may
2045 -# include modules defining variables like `optind', so libfetish.a
2046 -# must precede @LIBINTL@ in order to ensure we use GNU getopt.
2047 -# But libfetish.a must also follow @LIBINTL@, since libintl uses
2048 -# replacement functions defined in libfetish.a.
2049 -LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a
2051 -dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2052 -ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2053 -shred_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2054 -vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2056 -## If necessary, add -lm to resolve use of pow in lib/strtod.c.
2057 -sort_LDADD = $(LDADD) @POW_LIB@
2059 -# for clock_gettime
2060 -date_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
2063 -factor_LDADD = $(LDADD) @SQRT_LIBM@
2065 -# If necessary, add -lm to resolve use of pow in lib/strtod.c.
2066 -# If necessary, add -liconv to resolve use of iconv in lib/unicodeio.c.
2067 -printf_LDADD = $(LDADD) @POW_LIB@ @LIBICONV@
2069 -# If necessary, add -lm to resolve use of floor, rint, modf.
2070 -seq_LDADD = $(LDADD) @SEQ_LIBM@
2072 -# If necessary, add -lm to resolve the `pow' reference in lib/strtod.c
2073 -# or for the fesetround reference in programs using nanosec.c.
2075 - $(LDADD) @FESETROUND_LIBM@ @POW_LIB@ @LIB_CLOCK_GETTIME@ @LIB_NANOSLEEP@
2077 -sleep_LDADD = $(nanosec_libs)
2078 -tail_LDADD = $(nanosec_libs)
2080 -uptime_LDADD = $(LDADD) @GETLOADAVG_LIBS@
2082 -su_LDADD = $(LDADD) @LIB_CRYPT@ @LIB_PAM@
2084 -$(PROGRAMS): ../lib/libfetish.a
2086 -$(SCRIPTS): Makefile
2093 - -e 's!@''bindir''@!$(bindir)!' \
2094 - -e 's/@''GNU_PACKAGE''@/@GNU_PACKAGE@/' \
2095 - -e 's/@''PACKAGE_BUGREPORT''@/@PACKAGE_BUGREPORT@/' \
2096 - -e 's/@''VERSION''@/@VERSION@/' $< > $@-t
2100 -all-local: su$(EXEEXT)
2102 -installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
2104 -setuid_root_mode = a=rx,u+s
2108 - echo " $(INSTALL_PROGRAM) $$p $(installed_su)"; \
2109 - $(INSTALL_PROGRAM) $$p $(installed_su); \
2110 - echo " chown root $(installed_su)"; \
2111 - chown root $(installed_su); \
2112 - echo " chmod $(setuid_root_mode) $(installed_su)"; \
2113 - chmod $(setuid_root_mode) $(installed_su)
2115 -install-root: su$(EXEEXT)
2118 -install-exec-local: su$(EXEEXT)
2119 - @TMPFILE=$(DESTDIR)$(bindir)/.su-$$$$; \
2120 - rm -f $$TMPFILE; \
2121 - echo > $$TMPFILE; \
2122 -## See if we can create a setuid root executable in $(bindir).
2123 -## If not, then don't even try to install su.
2124 - can_create_suid_root_executable=no; \
2125 - chown root $$TMPFILE > /dev/null 2>&1 \
2126 - && chmod $(setuid_root_mode) $$TMPFILE > /dev/null 2>&1 \
2127 - && can_create_suid_root_executable=yes; \
2128 - rm -f $$TMPFILE; \
2129 - if test $$can_create_suid_root_executable = yes; then \
2132 - echo "WARNING: insufficient access; not installing su"; \
2133 - echo "NOTE: to install su, run 'make install-root' as root"; \
2137 -# Remove su only if it's one we installed.
2138 - @if grep '@GNU_PACKAGE@' $(installed_su) > /dev/null 2>&1; then \
2139 - echo " rm -f $(installed_su)"; \
2140 - rm -f $(installed_su); \
2143 -# Use `ginstall' in the definition of PROGRAMS and in dependencies to avoid
2144 -# confusion with the `install' target. The install rule transforms `ginstall'
2145 -# to install before applying any user-specified name transformations.
2147 -transform = s/ginstall/install/; @program_transform_name@
2148 -ginstall_SOURCES = install.c copy.c cp-hash.c
2150 -cp_SOURCES = cp.c copy.c cp-hash.c
2151 -dir_SOURCES = ls.c ls-dir.c
2152 -vdir_SOURCES = ls.c ls-vdir.c
2153 -ls_SOURCES = ls.c ls-ls.c
2154 -chown_SOURCES = chown.c chown-core.c
2155 -chgrp_SOURCES = chgrp.c chown-core.c
2157 -mv_SOURCES = mv.c copy.c cp-hash.c remove.c
2158 -rm_SOURCES = rm.c remove.c
2160 -md5sum_SOURCES = md5sum.c md5.c
2161 -sha1sum_SOURCES = md5sum.c sha1sum.c
2164 -editpl = sed -e 's,@''PERL''@,$(PERL),g'
2166 -MAINTAINERCLEANFILES = dircolors.h \
2167 - wheel.h wheel-size.h
2169 -dircolors.h: dcgen dircolors.hin
2170 - $(PERL) -w -- $(srcdir)/dcgen $(srcdir)/dircolors.hin > $@-t
2175 -wheel-size.h: Makefile.am
2176 - echo '#define WHEEL_SIZE $(wheel_size)' > $@-t
2179 -wheel.h: wheel-gen.pl Makefile.am
2180 - $(srcdir)/wheel-gen.pl $(wheel_size) \
2184 -BUILT_SOURCES = dircolors.h false.c wheel.h wheel-size.h
2186 -# false exits nonzero even with --help or --version.
2187 -# Tell automake to exempt it from that installcheck test.
2188 -AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = false
2193 - -e s/true/false/g \
2194 - -e s/success/failure/g \
2195 - -e 's/(EXIT_SUCCESS)/(EXIT_FAILURE)/g' \
2196 - $(srcdir)/true.c > $@-t
2203 - $(EXTRA_PROGRAMS) \
2206 -pm = progs-makefile
2208 -# Ensure that the list of programs in README matches the list
2209 -# of programs we can build.
2210 -check: check-README check-misc
2211 -.PHONY: check-README
2213 - rm -rf $(pr) $(pm)
2214 - echo $(all_programs) \
2215 - | tr -s ' ' '\n' | sort -u > $(pm)
2216 - sed -n '/^The programs .* are:/,/^[a-zA-Z]/p' $(top_srcdir)/README \
2217 - | sed -n '/^ */s///p' | tr -s ' ' '\n' > $(pr)
2218 - diff $(pm) $(pr) && rm -rf $(pr) $(pm)
2220 -# Make sure we don't define any S_IS* macros in src/*.c files.
2221 -# Not a big deal, but they're already defined via system.h.
2223 -# Also make sure we don't use st_blocks. Use ST_NBLOCKS instead.
2224 -# This is a bit of a kludge, since it prevents use of the string
2225 -# even in comments, but for now it does the job with no false positives.
2228 - cd $(srcdir); grep '^# *define *S_IS' $(SOURCES) && exit 1 || :
2229 - cd $(srcdir); grep st_blocks $(SOURCES) && exit 1 || :
2230 - cd $(srcdir); grep '^# *define .*defined' $(SOURCES) && exit 1 || :
2232 -# Extract the list of authors from each file.
2233 -sed_filter = s/^ *//;s/N_ (//;s/^"//;s/")*$$//
2234 -# Sometimes the string is on the same line as the #define...
2235 -s1 = '/^\#define AUTHORS \([^\\]\)/{;s//\1/;$(sed_filter);p;q;}'
2236 -# Sometimes the string is on the backslash-continued line after the #define.
2237 -s2 = '/^\#define AUTHORS \\\\/{;n;$(sed_filter);p;q;}'
2238 -# FIXME: handle *.sh; and use $(all_programs), not $(SOURCES)
2239 -../AUTHORS: $(SOURCES)
2243 - echo "Here are the names of the programs in this package,"; \
2244 - echo "each followed by the name(s) of its author(s)."; \
2246 - for i in $(SOURCES); do \
2247 - a=`sed -n $(s1) $$i`; \
2249 - || a=`sed -n $(s2) $$i`; \
2250 - if test "$$a"; then \
2251 - prog=`echo $$i|sed 's/\.c$$//'`; \
2252 - echo "$$prog: $$a"; \
2254 - done | sort -u ) > $@-t
2257 diff -Nur coreutils-5.0/src/mkdir.c coreutils-5.0.new/src/mkdir.c
2258 --- coreutils-5.0/src/mkdir.c 2002-09-23 09:35:27.000000000 +0200
2259 +++ coreutils-5.0.new/src/mkdir.c 2003-06-06 03:01:12.000000000 +0200
2262 #define AUTHORS "David MacKenzie"
2265 +#include <fs_secure.h>
2266 +#include <flask_util.h> /* for is_flask_enabled() */
2267 +#define CTXTLEN 256
2268 +char *scontext = NULL;
2269 +int ctxtlen = CTXTLEN;
2273 /* The name this program was run with. */
2278 static struct option const longopts[] =
2281 + {"sid", required_argument, NULL, 's'},
2282 + {"context", required_argument, NULL, 'c'},
2284 {"mode", required_argument, NULL, 'm'},
2285 {"parents", no_argument, NULL, 'p'},
2286 {"verbose", no_argument, NULL, 'v'},
2288 Create the DIRECTORY(ies), if they do not already exist.\n\
2293 + -s, --sid=SID (Flask) set security ID to SID\n\
2294 + -c, --context=CONTEXT (Flask) set security context to CONTEXT\n\
2298 Mandatory arguments to long options are mandatory for short options too.\n\
2301 const char *verbose_fmt_string = NULL;
2305 + security_id_t sid = -1;
2306 + char *scontext = NULL;
2308 + int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
2309 + is_flask_enabled_flag = is_flask_enabled();
2312 program_name = argv[0];
2313 setlocale (LC_ALL, "");
2319 + while ((optc = getopt_long (argc, argv, "pm:s:c:v", longopts, NULL)) != -1)
2321 while ((optc = getopt_long (argc, argv, "pm:v", longopts, NULL)) != -1)
2326 @@ -112,6 +142,66 @@
2327 case 'v': /* --verbose */
2328 verbose_fmt_string = _("created directory %s");
2332 + /* politely decline if we're not on a flask-enabled kernel. */
2333 + if( !is_flask_enabled_flag ) {
2334 + fprintf( stderr, "Sorry, --sid (-s) can be used only on "
2335 + "a flask-enabled kernel.\n" );
2338 + if ( ((int) sid > 0) || (scontext != NULL) ) {
2339 + (void) fprintf(stderr, "%s: --sid (-s) and --context (-c) are mutually exclusive\n", argv[0]);
2343 + /* check for typos */
2345 + sid = (security_id_t) strtol(optarg, &ep, 10);
2347 + (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
2351 + /* do sanity check, save result on success */
2352 + scontext = calloc(1, ctxtlen+1);
2353 + if ( scontext != NULL ) {
2354 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
2355 + if ( errno != ENOSPC ) {
2356 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
2360 + scontext = calloc(1, ctxtlen+1);
2361 + /* nonfatal, so if there's an error we punt */
2362 + if ( scontext != NULL )
2363 + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
2364 + (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
2371 + /* politely decline if we're not on a flask-enabled kernel. */
2372 + if( !is_flask_enabled_flag ) {
2373 + fprintf( stderr, "Sorry, --context (-c) can be used only on "
2374 + "a flask-enabled kernel.\n" );
2377 + if ( ((int) sid >= 0) || (scontext != NULL) ) {
2378 + (void) fprintf(stderr, "%s: --context (-c) and --sid (-s) are mutually exclusive\n", argv[0]);
2381 + scontext = optarg;
2382 + /* sanity check */
2383 + rv = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
2385 + (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n", argv[0], scontext, strerror(errno));
2390 case_GETOPT_HELP_CHAR;
2391 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
2393 @@ -150,14 +240,23 @@
2396 char *dir = argv[optind];
2398 + fail = make_path_s (dir, newmode, parent_mode,
2399 + -1, -1, 1, verbose_fmt_string, sid);
2401 fail = make_path (dir, newmode, parent_mode,
2402 -1, -1, 1, verbose_fmt_string);
2407 const char *dir = argv[optind];
2410 + fail = make_dir_s (dir, dir, newmode, &dir_created, sid);
2412 fail = make_dir (dir, dir, newmode, &dir_created);
2416 /* make_dir already gave a diagnostic. */
2417 diff -Nur coreutils-5.0/src/mkfifo.c coreutils-5.0.new/src/mkfifo.c
2418 --- coreutils-5.0/src/mkfifo.c 2002-08-31 09:29:21.000000000 +0200
2419 +++ coreutils-5.0.new/src/mkfifo.c 2003-06-06 03:01:12.000000000 +0200
2422 #define AUTHORS "David MacKenzie"
2425 +#include <fs_secure.h>
2426 +#include <flask_util.h> /* for is_flask_enabled() */
2429 /* The name this program was run with. */
2432 static struct option const longopts[] =
2435 + {"sid", required_argument, NULL, 's'},
2436 + {"context", required_argument, NULL, 'c'},
2438 {"mode", required_argument, NULL, 'm'},
2439 {GETOPT_HELP_OPTION_DECL},
2440 {GETOPT_VERSION_OPTION_DECL},
2442 Create named pipes (FIFOs) with the given NAMEs.\n\
2447 + -s, --sid=SID set SID\n\
2448 + -c, --context=CONTEXT set security context (quoted string)\n\
2452 Mandatory arguments to long options are mandatory for short options too.\n\
2455 const char *specified_mode;
2459 + security_id_t sid = -1;
2460 + char *scontext = NULL;
2462 + int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
2464 + /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
2465 + is_flask_enabled_flag = is_flask_enabled();
2468 program_name = argv[0];
2469 setlocale (LC_ALL, "");
2472 error (4, 0, _("fifo files not supported"));
2475 + while ((optc = getopt_long (argc, argv, "m:s:c:", longopts, NULL)) != -1)
2477 while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
2482 diff -Nur coreutils-5.0/src/mknod.c coreutils-5.0.new/src/mknod.c
2483 --- coreutils-5.0/src/mknod.c 2002-12-14 15:14:59.000000000 +0100
2484 +++ coreutils-5.0.new/src/mknod.c 2003-06-06 03:01:12.000000000 +0200
2486 /* The name this program was run with. */
2490 +#include <fs_secure.h>
2491 +#include <flask_util.h> /* for is_flask_enabled() */
2494 static struct option const longopts[] =
2497 + {"sid", required_argument, NULL, 's'},
2498 + {"context", required_argument, NULL, 'c'},
2500 {"mode", required_argument, NULL, 'm'},
2501 {GETOPT_HELP_OPTION_DECL},
2502 {GETOPT_VERSION_OPTION_DECL},
2504 Create the special file NAME of the given TYPE.\n\
2509 + -s, --sid=SID set SID\n\
2510 + -c, --context=CONTEXT set security context (quoted string)\n\
2514 Mandatory arguments to long options are mandatory for short options too.\n\
2517 const char *specified_mode;
2521 + security_id_t sid = -1;
2522 + char *scontext = NULL;
2524 + int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
2526 + /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
2527 + is_flask_enabled_flag = is_flask_enabled();
2530 program_name = argv[0];
2531 setlocale (LC_ALL, "");
2532 @@ -102,7 +126,11 @@
2534 specified_mode = NULL;
2537 + while ((optc = getopt_long (argc, argv, "m:s:c:", longopts, NULL)) != -1)
2539 while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
2544 @@ -111,6 +139,46 @@
2546 specified_mode = optarg;
2550 + /* politely decline if we're not on a flask-enabled kernel. */
2551 + if( !is_flask_enabled_flag ) {
2552 + fprintf( stderr, "Sorry, --sid (-s) can be used only on "
2553 + "a flask-enabled kernel.\n" );
2556 + if ( scontext != NULL ) {
2557 + (void) printf("%s: --sid (-s) and --context (-c) are mutually exclusive\n", argv[0]);
2558 + (void) fflush(stdout);
2562 + sid = atoi(optarg);
2565 + /* politely decline if we're not on a flask-enabled kernel. */
2566 + if( !is_flask_enabled_flag ) {
2567 + fprintf( stderr, "Sorry, --context (-c) can be used only on "
2568 + "a flask-enabled kernel.\n" );
2571 + if ( (int) sid >= 0 ) {
2572 + (void) printf("%s: --context (-c) and --sid (-s) are mutually exclusive\n", argv[0]);
2573 + (void) fflush(stdout);
2577 + scontext = optarg;
2578 + rv = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
2580 + (void) printf("%s: security_context_to_sid(%s): %s\n", argv[0], scontext,
2582 + (void) fflush(stdout);
2588 case_GETOPT_HELP_CHAR;
2589 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
2591 @@ -196,6 +264,18 @@
2592 error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
2596 + /* `sid' will be > 0 iff the --sid (-s) option was specified on the *
2597 + * command line. The --sid argument processing code exits politely *
2598 + * if the kernel doesn't support the new flask system calls. So, *
2599 + * if sid > 0 at this point, we know we're on a flask-enabled kernel *
2600 + * and can call the "_secure" version of mknod. */
2601 + if ( (int) sid > 0 ) {
2602 + if ( mknod_secure (argv[optind], newmode | S_IFBLK, makedev (i_major, i_minor), sid) )
2603 + error (1, errno, "mknod_secure(%s)", argv[optind]);
2607 if (mknod (argv[optind], newmode | node_type, device) != 0)
2608 error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
2610 @@ -211,6 +291,18 @@
2611 major and minor device numbers may not be specified for fifo files"));
2612 usage (EXIT_FAILURE);
2615 + /* `sid' will be > 0 iff the --sid (-s) option was specified on the *
2616 + * command line. The --sid argument processing code exits politely *
2617 + * if the kernel doesn't support the new flask system calls. So, *
2618 + * if sid > 0 at this point, we know we're on a flask-enabled kernel *
2619 + * and can call the "_secure" version of mknod. */
2620 + if( (int) sid > 0 )
2622 + if ( mkfifo_secure (argv[optind], newmode, sid) )
2623 + error (1, errno, "%s", quote (argv[optind]));
2626 if (mkfifo (argv[optind], newmode))
2627 error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
2629 diff -Nur coreutils-5.0/src/mv.c coreutils-5.0.new/src/mv.c
2630 --- coreutils-5.0/src/mv.c 2003-06-06 02:58:57.000000000 +0200
2631 +++ coreutils-5.0.new/src/mv.c 2003-06-06 03:01:12.000000000 +0200
2633 #include "path-concat.h"
2637 +#include <fs_secure.h>
2638 +#include <flask_util.h> /* for is_flask_enabled() */
2641 /* The official name of this program (e.g., no `g' prefix). */
2642 #define PROGRAM_NAME "mv"
2643 @@ -139,7 +143,12 @@
2648 + x->preserve_security_context = 0;
2649 + x->xstat = lstat_secure;
2653 x->dest_info = NULL;
2656 @@ -324,6 +333,10 @@
2657 equivalent to --reply=query\n\
2660 + -c preserve security context when source and\n\
2661 + destination are on different file systems\n\
2664 --reply={yes,no,query} specify how to handle the prompt about an\n\
2665 existing destination file\n\
2666 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
2668 int target_directory_specified;
2669 unsigned int n_files;
2672 + int is_flask_enabled_flag = is_flask_enabled();
2675 program_name = argv[0];
2676 setlocale (LC_ALL, "");
2677 @@ -387,7 +403,11 @@
2682 + while ((c = getopt_long (argc, argv, "bcfiuvS:V:", long_options, NULL)) != -1)
2684 while ((c = getopt_long (argc, argv, "bfiuvS:V:", long_options, NULL)) != -1)
2689 @@ -406,6 +426,12 @@
2691 version_control_string = optarg;
2695 + if (is_flask_enabled_flag)
2696 + x.preserve_security_context = 1;
2700 x.interactive = I_ALWAYS_YES;
2702 diff -Nur coreutils-5.0/src/mv.c.orig coreutils-5.0.new/src/mv.c.orig
2703 --- coreutils-5.0/src/mv.c.orig 1970-01-01 01:00:00.000000000 +0100
2704 +++ coreutils-5.0.new/src/mv.c.orig 2003-06-06 03:00:43.000000000 +0200
2706 +/* mv -- move or rename files
2707 + Copyright (C) 86, 89, 90, 91, 1995-2002 Free Software Foundation, Inc.
2709 + This program is free software; you can redistribute it and/or modify
2710 + it under the terms of the GNU General Public License as published by
2711 + the Free Software Foundation; either version 2, or (at your option)
2712 + any later version.
2714 + This program is distributed in the hope that it will be useful,
2715 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2716 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2717 + GNU General Public License for more details.
2719 + You should have received a copy of the GNU General Public License
2720 + along with this program; if not, write to the Free Software Foundation,
2721 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2723 +/* Written by Mike Parker, David MacKenzie, and Jim Meyering */
2729 +#include <config.h>
2731 +#include <getopt.h>
2732 +#include <sys/types.h>
2733 +#include <assert.h>
2735 +#include "system.h"
2736 +#include "argmatch.h"
2737 +#include "backupfile.h"
2739 +#include "cp-hash.h"
2740 +#include "dirname.h"
2742 +#include "path-concat.h"
2744 +#include "remove.h"
2746 +/* The official name of this program (e.g., no `g' prefix). */
2747 +#define PROGRAM_NAME "mv"
2749 +#define AUTHORS N_ ("Mike Parker, David MacKenzie, and Jim Meyering")
2751 +/* Initial number of entries in each hash table entry's table of inodes. */
2752 +#define INITIAL_HASH_MODULE 100
2754 +/* Initial number of entries in the inode hash table. */
2755 +#define INITIAL_ENTRY_TAB_SIZE 70
2757 +/* For long options that have no equivalent short option, use a
2758 + non-character as a pseudo short option, starting with CHAR_MAX + 1. */
2761 + TARGET_DIRECTORY_OPTION = CHAR_MAX + 1,
2762 + STRIP_TRAILING_SLASHES_OPTION,
2769 +/* The name this program was run with. */
2770 +char *program_name;
2772 +/* Remove any trailing slashes from each SOURCE argument. */
2773 +static int remove_trailing_slashes;
2775 +/* Valid arguments to the `--reply' option. */
2776 +static char const* const reply_args[] =
2778 + "yes", "no", "query", 0
2781 +/* The values that correspond to the above strings. */
2782 +static int const reply_vals[] =
2784 + I_ALWAYS_YES, I_ALWAYS_NO, I_ASK_USER
2787 +static struct option const long_options[] =
2789 + {"backup", optional_argument, NULL, 'b'},
2790 + {"force", no_argument, NULL, 'f'},
2791 + {"interactive", no_argument, NULL, 'i'},
2792 + {"reply", required_argument, NULL, REPLY_OPTION},
2793 + {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
2794 + {"suffix", required_argument, NULL, 'S'},
2795 + {"target-directory", required_argument, NULL, TARGET_DIRECTORY_OPTION},
2796 + {"update", no_argument, NULL, 'u'},
2797 + {"verbose", no_argument, NULL, 'v'},
2798 + {"version-control", required_argument, NULL, 'V'},
2799 + {GETOPT_HELP_OPTION_DECL},
2800 + {GETOPT_VERSION_OPTION_DECL},
2801 + {NULL, 0, NULL, 0}
2805 +rm_option_init (struct rm_options *x)
2807 + x->unlink_dirs = 0;
2809 + x->ignore_missing_files = 0;
2813 + /* Should we prompt for removal, too? No. Prompting for the `move'
2814 + part is enough. It implies removal. */
2815 + x->interactive = 0;
2822 +cp_option_init (struct cp_options *x)
2824 + x->copy_as_regular = 0; /* FIXME: maybe make this an option */
2825 + x->dereference = DEREF_NEVER;
2826 + x->unlink_dest_before_opening = 0;
2827 + x->unlink_dest_after_failed_open = 0;
2829 + x->interactive = I_UNSPECIFIED;
2831 + x->myeuid = geteuid ();
2832 + x->one_file_system = 0;
2833 + x->preserve_ownership = 1;
2834 + x->preserve_links = 1;
2835 + x->preserve_mode = 1;
2836 + x->preserve_timestamps = 1;
2837 + x->require_preserve = 0; /* FIXME: maybe make this an option */
2839 + x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */
2840 + x->symbolic_link = 0;
2843 + x->stdin_tty = isatty (STDIN_FILENO);
2848 + x->dest_info = NULL;
2849 + x->src_info = NULL;
2852 +/* If PATH is an existing directory, return nonzero, else 0. */
2855 +is_real_dir (const char *path)
2857 + struct stat stats;
2859 + return lstat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
2862 +/* Move SOURCE onto DEST. Handles cross-filesystem moves.
2863 + If SOURCE is a directory, DEST must not exist.
2864 + Return 0 if successful, non-zero if an error occurred. */
2867 +do_move (const char *source, const char *dest, const struct cp_options *x)
2869 + static int first = 1;
2870 + int copy_into_self;
2871 + int rename_succeeded;
2878 + /* Allocate space for remembering copied and created files. */
2882 + fail = copy (source, dest, 0, x, ©_into_self, &rename_succeeded);
2886 + char const *dir_to_remove;
2887 + if (copy_into_self)
2889 + /* In general, when copy returns with copy_into_self set, SOURCE is
2890 + the same as, or a parent of DEST. In this case we know it's a
2891 + parent. It doesn't make sense to move a directory into itself, and
2892 + besides in some situations doing so would give highly nonintuitive
2893 + results. Run this `mkdir b; touch a c; mv * b' in an empty
2894 + directory. Here's the result of running echo `find b -print`:
2895 + b b/a b/b b/b/a b/c. Notice that only file `a' was copied
2896 + into b/b. Handle this by giving a diagnostic, removing the
2897 + copied-into-self directory, DEST (`b/b' in the example),
2900 + dir_to_remove = NULL;
2903 + else if (rename_succeeded)
2905 + /* No need to remove anything. SOURCE was successfully
2906 + renamed to DEST. Or the user declined to rename a file. */
2907 + dir_to_remove = NULL;
2911 + /* This may mean SOURCE and DEST referred to different devices.
2912 + It may also conceivably mean that even though they referred
2913 + to the same device, rename wasn't implemented for that device.
2915 + E.g., (from Joel N. Weber),
2916 + [...] there might someday be cases where you can't rename
2917 + but you can copy where the device name is the same, especially
2918 + on Hurd. Consider an ftpfs with a primitive ftp server that
2919 + supports uploading, downloading and deleting, but not renaming.
2921 + Also, note that comparing device numbers is not a reliable
2922 + check for `can-rename'. Some systems can be set up so that
2923 + files from many different physical devices all have the same
2924 + st_dev field. This is a feature of some NFS mounting
2927 + We reach this point if SOURCE has been successfully copied
2928 + to DEST. Now we have to remove SOURCE.
2930 + This function used to resort to copying only when rename
2931 + failed and set errno to EXDEV. */
2933 + dir_to_remove = source;
2936 + if (dir_to_remove != NULL)
2938 + struct rm_options rm_options;
2939 + enum RM_status status;
2941 + rm_option_init (&rm_options);
2942 + rm_options.verbose = x->verbose;
2944 + status = rm (1, &dir_to_remove, &rm_options);
2945 + assert (VALID_STATUS (status));
2946 + if (status == RM_ERROR)
2954 +/* Move file SOURCE onto DEST. Handles the case when DEST is a directory.
2955 + DEST_IS_DIR must be nonzero when DEST is a directory or a symlink to a
2956 + directory and zero otherwise.
2957 + Return 0 if successful, non-zero if an error occurred. */
2960 +movefile (char *source, char *dest, int dest_is_dir,
2961 + const struct cp_options *x)
2963 + int dest_had_trailing_slash = strip_trailing_slashes (dest);
2966 + /* This code was introduced to handle the ambiguity in the semantics
2967 + of mv that is induced by the varying semantics of the rename function.
2968 + Some systems (e.g., Linux) have a rename function that honors a
2969 + trailing slash, while others (like Solaris 5,6,7) have a rename
2970 + function that ignores a trailing slash. I believe the Linux
2971 + rename semantics are POSIX and susv2 compliant. */
2973 + if (remove_trailing_slashes)
2974 + strip_trailing_slashes (source);
2976 + /* In addition to when DEST is a directory, if DEST has a trailing
2977 + slash and neither SOURCE nor DEST is a directory, presume the target
2978 + is DEST/`basename source`. This converts `mv x y/' to `mv x y/x'.
2979 + This change means that the command `mv any file/' will now fail
2980 + rather than performing the move. The case when SOURCE is a
2981 + directory and DEST is not is properly diagnosed by do_move. */
2983 + if (dest_is_dir || (dest_had_trailing_slash && !is_real_dir (source)))
2985 + /* DEST is a directory; build full target filename. */
2986 + char const *src_basename = base_name (source);
2987 + char *new_dest = path_concat (dest, src_basename, NULL);
2988 + if (new_dest == NULL)
2990 + strip_trailing_slashes (new_dest);
2991 + fail = do_move (source, new_dest, x);
2996 + fail = do_move (source, dest, x);
3006 + fprintf (stderr, _("Try `%s --help' for more information.\n"),
3011 +Usage: %s [OPTION]... SOURCE DEST\n\
3012 + or: %s [OPTION]... SOURCE... DIRECTORY\n\
3013 + or: %s [OPTION]... --target-directory=DIRECTORY SOURCE...\n\
3015 + program_name, program_name, program_name);
3017 +Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\
3021 +Mandatory arguments to long options are mandatory for short options too.\n\
3024 + --backup[=CONTROL] make a backup of each existing destination file\n\
3025 + -b like --backup but does not accept an argument\n\
3026 + -f, --force do not prompt before overwriting\n\
3027 + equivalent to --reply=yes\n\
3028 + -i, --interactive prompt before overwrite\n\
3029 + equivalent to --reply=query\n\
3032 + --reply={yes,no,query} specify how to handle the prompt about an\n\
3033 + existing destination file\n\
3034 + --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
3036 + -S, --suffix=SUFFIX override the usual backup suffix\n\
3039 + --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY\n\
3040 + -u, --update move only when the SOURCE file is newer\n\
3041 + than the destination file or when the\n\
3042 + destination file is missing\n\
3043 + -v, --verbose explain what is being done\n\
3045 + fputs (HELP_OPTION_DESCRIPTION, stdout);
3046 + fputs (VERSION_OPTION_DESCRIPTION, stdout);
3049 +The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
3050 +The version control method may be selected via the --backup option or through\n\
3051 +the VERSION_CONTROL environment variable. Here are the values:\n\
3055 + none, off never make backups (even if --backup is given)\n\
3056 + numbered, t make numbered backups\n\
3057 + existing, nil numbered if numbered backups exist, simple otherwise\n\
3058 + simple, never always make simple backups\n\
3060 + printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
3066 +main (int argc, char **argv)
3070 + int make_backups = 0;
3072 + char *backup_suffix_string;
3073 + char *version_control_string = NULL;
3074 + struct cp_options x;
3075 + char *target_directory = NULL;
3076 + int target_directory_specified;
3077 + unsigned int n_files;
3080 + program_name = argv[0];
3081 + setlocale (LC_ALL, "");
3082 + bindtextdomain (PACKAGE, LOCALEDIR);
3083 + textdomain (PACKAGE);
3085 + atexit (close_stdout);
3087 + cp_option_init (&x);
3089 + /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
3090 + we'll actually use backup_suffix_string. */
3091 + backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
3095 + while ((c = getopt_long (argc, argv, "bfiuvS:V:", long_options, NULL)) != -1)
3102 + case 'V': /* FIXME: this is deprecated. Remove it in 2001. */
3104 + _("warning: --version-control (-V) is obsolete; support for\
3105 + it\nwill be removed in some future release. Use --backup=%s instead."
3107 + /* Fall through. */
3112 + version_control_string = optarg;
3115 + x.interactive = I_ALWAYS_YES;
3118 + x.interactive = I_ASK_USER;
3120 + case REPLY_OPTION:
3121 + x.interactive = XARGMATCH ("--reply", optarg,
3122 + reply_args, reply_vals);
3124 + case STRIP_TRAILING_SLASHES_OPTION:
3125 + remove_trailing_slashes = 1;
3127 + case TARGET_DIRECTORY_OPTION:
3128 + target_directory = optarg;
3138 + backup_suffix_string = optarg;
3140 + case_GETOPT_HELP_CHAR;
3141 + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
3143 + usage (EXIT_FAILURE);
3147 + n_files = argc - optind;
3148 + file = argv + optind;
3150 + target_directory_specified = (target_directory != NULL);
3151 + if (target_directory == NULL && n_files != 0)
3152 + target_directory = file[n_files - 1];
3154 + dest_is_dir = (n_files > 0 && isdir (target_directory));
3156 + if (n_files == 0 || (n_files == 1 && !target_directory_specified))
3158 + error (0, 0, _("missing file argument"));
3159 + usage (EXIT_FAILURE);
3162 + if (target_directory_specified)
3166 + error (0, 0, _("specified target, %s is not a directory"),
3167 + quote (target_directory));
3168 + usage (EXIT_FAILURE);
3171 + else if (n_files > 2 && !dest_is_dir)
3174 + _("when moving multiple files, last argument must be a directory"));
3175 + usage (EXIT_FAILURE);
3178 + if (backup_suffix_string)
3179 + simple_backup_suffix = xstrdup (backup_suffix_string);
3181 + x.backup_type = (make_backups
3182 + ? xget_version (_("backup type"),
3183 + version_control_string)
3186 + /* Move each arg but the last into the target_directory. */
3188 + unsigned int last_file_idx = (target_directory_specified
3193 + /* Initialize the hash table only if we'll need it.
3194 + The problem it is used to detect can arise only if there are
3195 + two or more files to move. */
3196 + if (last_file_idx)
3197 + dest_info_init (&x);
3199 + for (i = 0; i <= last_file_idx; ++i)
3200 + errors |= movefile (file[i], target_directory, dest_is_dir, &x);
3205 diff -Nur coreutils-5.0/src/runas.c coreutils-5.0.new/src/runas.c
3206 --- coreutils-5.0/src/runas.c 1970-01-01 01:00:00.000000000 +0100
3207 +++ coreutils-5.0.new/src/runas.c 2003-06-06 03:01:12.000000000 +0200
3210 + * runas [ context | [ -s sid ] |
3211 + * ( [ -r role ] [-t type] [ -u user ] [ -l levelrange ] )
3212 + * command [arg1 [arg2 ...] ]
3214 + * attempt to run the specified command with the specified context.
3216 + * -s sid : use the context corresponding to the specified sid
3217 + * -r role : use the current context with the specified role
3218 + * -t type : use the current context with the specified type
3219 + * -u user : use the current context with the specified user
3220 + * -l level : use the current context with the specified level range
3222 + * Contexts are interpreted as follows:
3225 + * components system?
3229 + * 3 Y role:type:range
3230 + * 3 N user:role:type
3231 + * 4 Y user:role:type:range
3235 +#include <unistd.h>
3237 +#include <getopt.h>
3238 +#include <context.h>
3239 +#include <proc_secure.h>
3249 +/* The name the program was run with. */
3250 +char *program_name;
3255 + printf("Usage: %s [OPTION]... command [args]\n"
3256 + "Run a program in a different security context.\n\n"
3257 + " context Complete security context\n"
3258 + " -s sid Security ID number\n"
3259 + " -t type (for same role as parent)\n"
3260 + " -u user identity\n"
3262 + " -l levelrange\n"
3263 + " --help display this help and exit\n",
3269 +main(int argc,char **argv,char **envp )
3272 + security_id_t sid = 0; /* 0 is not a vaild sid */
3274 + program_name = argv[0];
3278 + int this_option_optind = optind ? optind : 1;
3279 + int option_index = 0;
3280 + static struct option long_options[] = {
3281 + { "sid", 1, 0, 's' },
3282 + { "role", 1, 0, 'r' },
3283 + { "type", 1, 0, 't' },
3284 + { "user", 1, 0, 'u' },
3285 + { "range", 1, 0, 'l' },
3286 + { "help", 0, 0, '?' },
3289 + c = getopt_long(argc, argv, "s:r:t:u:l:?", long_options, &option_index);
3295 + if ( !( sid == 0 ) ) {
3296 + fprintf(stderr,"multiple sids\n");
3299 + sid = (int)strtoul( optarg, (char **)NULL, 10);
3301 + /* Check for an invalid sid. */
3302 + if( ( errno == ERANGE ) || ( sid == 0 ) ) {
3303 + fprintf( stderr, "invalid sid\n" );
3309 + fprintf(stderr,"multiple roles\n");
3316 + fprintf(stderr,"multiple types\n");
3323 + fprintf(stderr,"multiple users\n");
3330 + fprintf(stderr,"multiple levelranges\n");
3336 + fprintf(stderr,"unrecognised option %c\n",c);
3342 + if ( ( !(user || role || type || range) ) &&
3344 + if ( optind >= argc ) {
3345 + usage("must specify -t, -u, -l, -r, -s or context");
3347 + context = argv[optind++];
3351 + con = context_new(context);
3353 + fprintf(stderr,"%s is not a valid context\n", context);
3356 + } else if( sid == 0 ) { /* sid != 0 means sid already set by --sid */
3357 + security_id_t mysid;
3359 + int len = sizeof(buff);
3360 + mysid = getsecsid();
3361 + if ( security_sid_to_context(mysid,
3364 + perror("security_sid_to_context");
3367 + con = context_new(buff);
3369 + fprintf(stderr,"%s is not a valid context\n", buff);
3373 + context_user_set(con,user);
3376 + context_type_set(con,type);
3379 + context_range_set(con,range);
3382 + context_role_set(con,role);
3385 + if ( optind >= argc ) {
3386 + usage("no command found");
3389 +#ifdef DEBUG_BROKEN_NEED_TO_HANDLE_SID_CASE
3390 + fprintf(stderr,"Context to use is \"%s\"\n",context_str(con));
3391 + fprintf(stderr,"Command is \"");
3393 + int tmpoptind = optind;
3394 + while ( tmpoptind < argc ) {
3395 + fprintf(stderr,"%s",argv[tmpoptind++]);
3396 + if ( tmpoptind < argc ) {
3400 + fprintf(stderr,"\"\n");
3404 + if( sid == 0 ) { /* sid != 0 means sid already set by --sid */
3405 + if ( security_context_to_sid(context_str(con),
3406 + strlen(context_str(con))+1,&sid) ) {
3407 + perror("security_context_to_sid");
3413 + fprintf(stderr,"sid = %d\n",sid);
3416 + if ( execve_secure(argv[optind],argv+optind,envp,sid) ) {
3418 + if ( execvp_secure(argv[optind],sid,argv+optind) ) {
3419 + perror("execvp_secure");
3422 + return 1; /* can't reach this statement.... */
3424 diff -Nur coreutils-5.0/src/su.c.orig coreutils-5.0.new/src/su.c.orig
3425 --- coreutils-5.0/src/su.c.orig 2002-08-31 09:28:18.000000000 +0200
3426 +++ coreutils-5.0.new/src/su.c.orig 1970-01-01 01:00:00.000000000 +0100
3428 -/* su for GNU. Run a shell with substitute user and group IDs.
3429 - Copyright (C) 1992-2002 Free Software Foundation, Inc.
3431 - This program is free software; you can redistribute it and/or modify
3432 - it under the terms of the GNU General Public License as published by
3433 - the Free Software Foundation; either version 2, or (at your option)
3434 - any later version.
3436 - This program is distributed in the hope that it will be useful,
3437 - but WITHOUT ANY WARRANTY; without even the implied warranty of
3438 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3439 - GNU General Public License for more details.
3441 - You should have received a copy of the GNU General Public License
3442 - along with this program; if not, write to the Free Software Foundation,
3443 - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
3445 -/* Run a shell with the real and effective UID and GID and groups
3446 - of USER, default `root'.
3448 - The shell run is taken from USER's password entry, /bin/sh if
3449 - none is specified there. If the account has a password, su
3450 - prompts for a password unless run by a user with real UID 0.
3452 - Does not change the current directory.
3453 - Sets `HOME' and `SHELL' from the password entry for USER, and if
3454 - USER is not root, sets `USER' and `LOGNAME' to USER.
3455 - The subshell is not a login shell.
3457 - If one or more ARGs are given, they are passed as additional
3458 - arguments to the subshell.
3460 - Does not handle /bin/sh or other shells specially
3461 - (setting argv[0] to "-su", passing -c only to certain shells, etc.).
3462 - I don't see the point in doing that, and it's ugly.
3464 - This program intentionally does not support a "wheel group" that
3465 - restricts who can su to UID 0 accounts. RMS considers that to
3469 - -, -l, --login Make the subshell a login shell.
3470 - Unset all environment variables except
3471 - TERM, HOME and SHELL (set as above), and USER
3472 - and LOGNAME (set unconditionally as above), and
3473 - set PATH to a default value.
3474 - Change to USER's home directory.
3475 - Prepend "-" to the shell's name.
3476 - -c, --commmand=COMMAND
3477 - Pass COMMAND to the subshell with a -c option
3478 - instead of starting an interactive shell.
3479 - -f, --fast Pass the -f option to the subshell.
3480 - -m, -p, --preserve-environment
3481 - Do not change HOME, USER, LOGNAME, SHELL.
3482 - Run $SHELL instead of USER's shell from /etc/passwd
3483 - unless not the superuser and USER's shell is
3485 - Overridden by --login and --shell.
3486 - -s, --shell=shell Run SHELL instead of USER's shell from /etc/passwd
3487 - unless not the superuser and USER's shell is
3490 - Compile-time options:
3491 - -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog.
3492 - -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog.
3494 - -DSYSLOG_NON_ROOT Log all su's, not just those to root (UID 0).
3495 - Never logs attempted su's to nonexistent accounts.
3497 - Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
3499 -#include <config.h>
3501 -#include <getopt.h>
3502 -#include <sys/types.h>
3506 -/* Hide any system prototype for getusershell.
3507 - This is necessary because some Cray systems have a conflicting
3508 - prototype (returning `int') in <unistd.h>. */
3509 -#define getusershell _getusershell_sys_proto_
3511 -#include "system.h"
3512 -#include "closeout.h"
3513 -#include "dirname.h"
3515 -#undef getusershell
3517 -#if HAVE_SYSLOG_H && HAVE_SYSLOG
3518 -# include <syslog.h>
3520 -# undef SYSLOG_SUCCESS
3521 -# undef SYSLOG_FAILURE
3522 -# undef SYSLOG_NON_ROOT
3525 -#if HAVE_SYS_PARAM_H
3526 -# include <sys/param.h>
3529 -#ifndef HAVE_ENDGRENT
3530 -# define endgrent() ((void) 0)
3533 -#ifndef HAVE_ENDPWENT
3534 -# define endpwent() ((void) 0)
3538 -# include <shadow.h>
3543 -/* The official name of this program (e.g., no `g' prefix). */
3544 -#define PROGRAM_NAME "su"
3546 -#define AUTHORS "David MacKenzie"
3549 -# include <paths.h>
3552 -/* The default PATH for simulated logins to non-superuser accounts. */
3553 -#ifdef _PATH_DEFPATH
3554 -# define DEFAULT_LOGIN_PATH _PATH_DEFPATH
3556 -# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin"
3559 -/* The default PATH for simulated logins to superuser accounts. */
3560 -#ifdef _PATH_DEFPATH_ROOT
3561 -# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT
3563 -# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc"
3566 -/* The shell to run if none is given in the user's passwd entry. */
3567 -#define DEFAULT_SHELL "/bin/sh"
3569 -/* The user to become if none is specified. */
3570 -#define DEFAULT_USER "root"
3574 -char *getusershell ();
3575 -void endusershell ();
3576 -void setusershell ();
3578 -extern char **environ;
3580 -static void run_shell (const char *, const char *, char **)
3581 - ATTRIBUTE_NORETURN;
3583 -/* The name this program was run with. */
3584 -char *program_name;
3586 -/* If nonzero, pass the `-f' option to the subshell. */
3587 -static int fast_startup;
3589 -/* If nonzero, simulate a login instead of just starting a shell. */
3590 -static int simulate_login;
3592 -/* If nonzero, change some environment vars to indicate the user su'd to. */
3593 -static int change_environment;
3595 -static struct option const longopts[] =
3597 - {"command", required_argument, 0, 'c'},
3598 - {"fast", no_argument, NULL, 'f'},
3599 - {"login", no_argument, NULL, 'l'},
3600 - {"preserve-environment", no_argument, &change_environment, 0},
3601 - {"shell", required_argument, 0, 's'},
3602 - {GETOPT_HELP_OPTION_DECL},
3603 - {GETOPT_VERSION_OPTION_DECL},
3607 -/* Add VAL to the environment, checking for out of memory errors. */
3610 -xputenv (char *val)
3616 -/* Return a newly-allocated string whose contents concatenate
3617 - those of S1, S2, S3. */
3620 -concat (const char *s1, const char *s2, const char *s3)
3622 - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
3623 - char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
3625 - strcpy (result, s1);
3626 - strcpy (result + len1, s2);
3627 - strcpy (result + len1 + len2, s3);
3628 - result[len1 + len2 + len3] = 0;
3633 -/* Return the number of elements in ARR, a null-terminated array. */
3636 -elements (char **arr)
3640 - for (n = 0; *arr; ++arr)
3645 -#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE)
3646 -/* Log the fact that someone has run su to the user given by PW;
3647 - if SUCCESSFUL is nonzero, they gave the correct password, etc. */
3650 -log_su (const struct passwd *pw, int successful)
3652 - const char *new_user, *old_user, *tty;
3654 -# ifndef SYSLOG_NON_ROOT
3658 - new_user = pw->pw_name;
3659 - /* The utmp entry (via getlogin) is probably the best way to identify
3660 - the user, especially if someone su's from a su-shell. */
3661 - old_user = getlogin ();
3662 - if (old_user == NULL)
3664 - /* getlogin can fail -- usually due to lack of utmp entry.
3665 - Resort to getpwuid. */
3666 - struct passwd *pwd = getpwuid (getuid ());
3667 - old_user = (pwd ? pwd->pw_name : "");
3669 - tty = ttyname (2);
3672 - /* 4.2BSD openlog doesn't have the third parameter. */
3673 - openlog (base_name (program_name), 0
3678 - syslog (LOG_NOTICE,
3679 -# ifdef SYSLOG_NON_ROOT
3680 - "%s(to %s) %s on %s",
3684 - successful ? "" : "FAILED SU ",
3685 -# ifdef SYSLOG_NON_ROOT
3693 -/* Ask the user for a password.
3694 - Return 1 if the user gives the correct password for entry PW,
3695 - 0 if not. Return 1 without asking for a password if run by UID 0
3696 - or if PW has an empty password. */
3699 -correct_password (const struct passwd *pw)
3701 - char *unencrypted, *encrypted, *correct;
3702 -#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
3703 - /* Shadow passwd stuff for SVR3 and maybe other systems. */
3704 - struct spwd *sp = getspnam (pw->pw_name);
3708 - correct = sp->sp_pwdp;
3711 - correct = pw->pw_passwd;
3713 - if (getuid () == 0 || correct == 0 || correct[0] == '\0')
3716 - unencrypted = getpass (_("Password:"));
3717 - if (unencrypted == NULL)
3719 - error (0, 0, _("getpass: cannot open /dev/tty"));
3722 - encrypted = crypt (unencrypted, correct);
3723 - memset (unencrypted, 0, strlen (unencrypted));
3724 - return strcmp (encrypted, correct) == 0;
3727 -/* Update `environ' for the new shell based on PW, with SHELL being
3728 - the value for the SHELL environment variable. */
3731 -modify_environment (const struct passwd *pw, const char *shell)
3735 - if (simulate_login)
3737 - /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
3738 - Unset all other environment variables. */
3739 - term = getenv ("TERM");
3740 - environ = (char **) xmalloc (2 * sizeof (char *));
3743 - xputenv (concat ("TERM", "=", term));
3744 - xputenv (concat ("HOME", "=", pw->pw_dir));
3745 - xputenv (concat ("SHELL", "=", shell));
3746 - xputenv (concat ("USER", "=", pw->pw_name));
3747 - xputenv (concat ("LOGNAME", "=", pw->pw_name));
3748 - xputenv (concat ("PATH", "=", (pw->pw_uid
3749 - ? DEFAULT_LOGIN_PATH
3750 - : DEFAULT_ROOT_LOGIN_PATH)));
3754 - /* Set HOME, SHELL, and if not becoming a super-user,
3755 - USER and LOGNAME. */
3756 - if (change_environment)
3758 - xputenv (concat ("HOME", "=", pw->pw_dir));
3759 - xputenv (concat ("SHELL", "=", shell));
3762 - xputenv (concat ("USER", "=", pw->pw_name));
3763 - xputenv (concat ("LOGNAME", "=", pw->pw_name));
3769 -/* Become the user and group(s) specified by PW. */
3772 -change_identity (const struct passwd *pw)
3774 -#ifdef HAVE_INITGROUPS
3776 - if (initgroups (pw->pw_name, pw->pw_gid) == -1)
3777 - error (EXIT_FAILURE, errno, _("cannot set groups"));
3780 - if (setgid (pw->pw_gid))
3781 - error (EXIT_FAILURE, errno, _("cannot set group id"));
3782 - if (setuid (pw->pw_uid))
3783 - error (EXIT_FAILURE, errno, _("cannot set user id"));
3786 -/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
3787 - If COMMAND is nonzero, pass it to the shell with the -c option.
3788 - If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
3792 -run_shell (const char *shell, const char *command, char **additional_args)
3794 - const char **args;
3797 - if (additional_args)
3798 - args = (const char **) xmalloc (sizeof (char *)
3799 - * (10 + elements (additional_args)));
3801 - args = (const char **) xmalloc (sizeof (char *) * 10);
3802 - if (simulate_login)
3805 - char *shell_basename;
3807 - shell_basename = base_name (shell);
3808 - arg0 = xmalloc (strlen (shell_basename) + 2);
3810 - strcpy (arg0 + 1, shell_basename);
3814 - args[0] = base_name (shell);
3816 - args[argno++] = "-f";
3819 - args[argno++] = "-c";
3820 - args[argno++] = command;
3822 - if (additional_args)
3823 - for (; *additional_args; ++additional_args)
3824 - args[argno++] = *additional_args;
3825 - args[argno] = NULL;
3826 - execv (shell, (char **) args);
3829 - int exit_status = (errno == ENOENT ? 127 : 126);
3830 - error (0, errno, "%s", shell);
3831 - exit (exit_status);
3835 -/* Return 1 if SHELL is a restricted shell (one not returned by
3836 - getusershell), else 0, meaning it is a standard shell. */
3839 -restricted_shell (const char *shell)
3844 - while ((line = getusershell ()) != NULL)
3846 - if (*line != '#' && strcmp (line, shell) == 0)
3860 - fprintf (stderr, _("Try `%s --help' for more information.\n"),
3864 - printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
3866 -Change the effective user id and group id to that of USER.\n\
3868 - -, -l, --login make the shell a login shell\n\
3869 - -c, --commmand=COMMAND pass a single COMMAND to the shell with -c\n\
3870 - -f, --fast pass -f to the shell (for csh or tcsh)\n\
3871 - -m, --preserve-environment do not reset environment variables\n\
3873 - -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
3875 - fputs (HELP_OPTION_DESCRIPTION, stdout);
3876 - fputs (VERSION_OPTION_DESCRIPTION, stdout);
3879 -A mere - implies -l. If USER not given, assume root.\n\
3881 - printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
3888 -main (int argc, char **argv)
3891 - const char *new_user = DEFAULT_USER;
3892 - char *command = 0;
3893 - char **additional_args = 0;
3895 - struct passwd *pw;
3896 - struct passwd pw_copy;
3898 - program_name = argv[0];
3899 - setlocale (LC_ALL, "");
3900 - bindtextdomain (PACKAGE, LOCALEDIR);
3901 - textdomain (PACKAGE);
3904 - simulate_login = 0;
3905 - change_environment = 1;
3907 - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
3923 - simulate_login = 1;
3928 - change_environment = 0;
3935 - case_GETOPT_HELP_CHAR;
3937 - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
3940 - usage (EXIT_FAILURE);
3944 - if (optind < argc && !strcmp (argv[optind], "-"))
3946 - simulate_login = 1;
3949 - if (optind < argc)
3950 - new_user = argv[optind++];
3951 - if (optind < argc)
3952 - additional_args = argv + optind;
3954 - pw = getpwnam (new_user);
3956 - error (EXIT_FAILURE, 0, _("user %s does not exist"), new_user);
3959 - /* Make sure pw->pw_shell is non-NULL. It may be NULL when NEW_USER
3960 - is a username that is retrieved via NIS (YP), but that doesn't have
3961 - a default shell listed. */
3962 - if (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
3963 - pw->pw_shell = (char *) DEFAULT_SHELL;
3965 - /* Make a copy of the password information and point pw at the local
3966 - copy instead. Otherwise, some systems (e.g. Linux) would clobber
3967 - the static data through the getlogin call from log_su. */
3970 - pw->pw_name = xstrdup (pw->pw_name);
3971 - pw->pw_dir = xstrdup (pw->pw_dir);
3972 - pw->pw_shell = xstrdup (pw->pw_shell);
3974 - if (!correct_password (pw))
3976 -#ifdef SYSLOG_FAILURE
3979 - error (EXIT_FAILURE, 0, _("incorrect password"));
3981 -#ifdef SYSLOG_SUCCESS
3988 - if (shell == 0 && change_environment == 0)
3989 - shell = getenv ("SHELL");
3990 - if (shell != 0 && getuid () && restricted_shell (pw->pw_shell))
3992 - /* The user being su'd to has a nonstandard shell, and so is
3993 - probably a uucp account or has restricted access. Don't
3994 - compromise the account by allowing access with a standard
3996 - error (0, 0, _("using restricted shell %s"), pw->pw_shell);
4001 - shell = xstrdup (pw->pw_shell);
4003 - modify_environment (pw, shell);
4005 - change_identity (pw);
4006 - if (simulate_login && chdir (pw->pw_dir))
4007 - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
4009 - run_shell (shell, command, additional_args);
4011 diff -Nur coreutils-5.0/src/system.h coreutils-5.0.new/src/system.h
4012 --- coreutils-5.0/src/system.h 2003-04-02 12:13:50.000000000 +0200
4013 +++ coreutils-5.0.new/src/system.h 2003-06-06 03:01:12.000000000 +0200
4015 # define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
4019 +#define mkfifo_secure(path, mode, sid) (mknod_secure ((path), (mode) | S_IFIFO, 0, (sid)))
4022 #if HAVE_SYS_PARAM_H
4023 # include <sys/param.h>
4025 diff -Nur coreutils-5.0/tests/cp/Makefile.am coreutils-5.0.new/tests/cp/Makefile.am
4026 --- coreutils-5.0/tests/cp/Makefile.am 2003-02-02 21:08:59.000000000 +0100
4027 +++ coreutils-5.0.new/tests/cp/Makefile.am 2003-06-06 03:01:13.000000000 +0200
4031 preserve-2 r-vs-symlink link-preserve \
4032 - backup-1 no-deref-link1 no-deref-link2 no-deref-link3 backup-is-src \
4033 - same-file cp-mv-backup symlink-slash slink-2-slink fail-perm dir-slash \
4034 + backup-1 backup-is-src \
4035 + cp-mv-backup symlink-slash slink-2-slink fail-perm dir-slash \
4036 perm cp-HL special-bits link dir-rm-dest cp-parents deref-slink \
4037 dir-vs-file into-self
4038 EXTRA_DIST = $(TESTS)
4039 diff -Nur coreutils-5.0/tests/Makefile.am coreutils-5.0.new/tests/Makefile.am
4040 --- coreutils-5.0/tests/Makefile.am 2003-03-31 09:07:35.000000000 +0200
4041 +++ coreutils-5.0.new/tests/Makefile.am 2003-06-06 03:01:12.000000000 +0200
4045 basename chgrp chmod chown cp cut date dd dircolors du expr factor \
4046 - fmt head install join ln ls ls-2 md5sum misc mkdir mv od pr rm rmdir \
4047 + fmt head install join ln ls md5sum misc mkdir mv od pr rm rmdir \
4048 seq sha1sum shred sort stty sum tac tail tail-2 test touch tr tsort \
4051 diff -Nur coreutils-5.0/tests/mv/Makefile.am coreutils-5.0.new/tests/mv/Makefile.am
4052 --- coreutils-5.0/tests/mv/Makefile.am 2003-03-01 00:30:44.000000000 +0100
4053 +++ coreutils-5.0.new/tests/mv/Makefile.am 2003-06-06 03:01:13.000000000 +0200
4057 dup-source childproof i-4 update i-2 mv-special-1 \
4058 - into-self into-self-2 into-self-3 into-self-4 \
4059 + into-self into-self-3 \
4061 i-1 hard-link-1 force partition-perm to-symlink dir-file diag \
4062 - part-symlink part-rename trailing-slash
4063 + part-rename trailing-slash
4065 EXTRA_DIST = $(TESTS) setup
4066 TESTS_ENVIRONMENT = \