New security policy

From: Shaun Savage <savages_at_pcez.com>
Date: Sun, 09 Dec 2001 21:35:16 -0800


Hi Folks

I have worked with RSBAC for about 5 years now and now I trying to work with selinux.
I would like a security policy with

sysdm_r this for root to admin the system but can't change security of "system" types
secoff_r The is for security officer to set up the security for the system
dataoff_r this is the only person that can "see" users personal files/directories
user_r this is for the normal user system_r for normal system stuff

 NEXT I have compiled some of the selinux utils for RH7.2, I hope to do the rest this week.
this is how I did it

I first did >rpm -bp XXXX.spec
the patched the XXXX directory using the patch on some XXXX i needed to autoconf (caution: the autoconf that comes with RH7.2 is bad upgrade to 2.52 from GNU.org) I then go back to the SPEC directory and rpm -bc --short-circuit XXXX.spec then rpm -bi --short-circuit XXXX.spec

then goto /var/tmp/XXXX and get the files.

 More later
Shaun Savage

diff -Nur fileutils-4.1/config.h.in fileutils-4.1-selinux/config.h.in

--- fileutils-4.1/config.h.in	Sun Apr 22 03:19:08 2001

+++ fileutils-4.1-selinux/config.h.in Sun Dec 9 17:48:33 2001
@@ -37,6 +37,9 @@
 /* Define to 1 if NLS is requested. */
 #undef ENABLE_NLS  

+/* Define Flask */
+#undef FLASK_LINUX
+

 /* Define on systems for which file names may have a so-called `drive letter'

    prefix, define this to compute the length of that prefix, including the     colon. */
diff -Nur fileutils-4.1/configure.in fileutils-4.1-selinux/configure.in

--- fileutils-4.1/configure.in	Sun Apr 29 00:02:33 2001

+++ fileutils-4.1-selinux/configure.in Sun Dec 9 17:46:33 2001
@@ -7,6 +7,18 @@  

 ALL_LINGUAS="cs da de el es fr gl it ja ko nl no pl pt pt_BR ru sk sl sv zh"  

+dnl Make Flask security-enhanced versions of fileutils
+dnl Should add existence chackes for libsecure library, etc
+dnl CFLAGS="$CFLAGS -DFLASK_LINUX -I/usr/flask/include -I/usr/src/linux/include"
+dnl LIBS="$LIBS -L/usr/flask/lib -lsecure"])
+
+AC_ARG_WITH(selinux,
+[ --with-selinux include support for SELinux],
+[ AC_DEFINE(FLASK_LINUX)
+ CFLAGS="$CFLAGS -DFLASK_LINUX -I/usr/local/selinux/include"
+ LIBS="$LIBS -L/usr/local/selinux/lib -lsecure"])
+AC_ARG_PROGRAM
+

 jm_PERL
 AC_PROG_CC
 AC_PROG_CPP
diff -Nur fileutils-4.1/lib/makepath.c fileutils-4.1-selinux/lib/makepath.c
--- fileutils-4.1/lib/makepath.c	Sun Nov  5 05:10:25 2000

+++ fileutils-4.1-selinux/lib/makepath.c Sun Dec 9 17:49:07 2001
@@ -94,6 +94,10 @@
 # define S_IXUSR 0100
 #endif  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#endif FLASK_LINUX
+

 #ifndef S_IRWXU
 # define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
 #endif
@@ -143,6 +147,25 @@
     }							\

   while (0)  

+
+#ifdef FLASK_LINUX
+static security_id_t Sid = -1;
+
+int
+make_path_s (const char *argpath,
+ int mode,
+ int parent_mode,
+ uid_t owner,
+ gid_t group,
+ int preserve_existing,
+ const char *verbose_fmt_string,
+ security_id_t sid)
+{
+ Sid = sid;
+ return( make_path(argpath, mode, parent_mode, owner, group, preserve_existing, verbose_fmt_string) );
+}
+#endif FLASK_LINUX
+

 /* Attempt to create directory DIR (aka DIRPATH) with the specified MODE.

    If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P to non-zero if this     function creates DIR and to zero otherwise. Give a diagnostic and @@ -157,6 +180,11 @@

   int fail = 0;
   int created_dir;  

+#ifdef FLASK_LINUX
+ if ( (int) Sid > 0 )
+ created_dir = mkdir_secure (dir, mode, Sid);
+ else
+#endif FLASK_LINUX

   created_dir = (mkdir (dir, mode) == 0);  

   if (!created_dir)
@@ -195,6 +223,7 @@

   return fail;
 }  

+

 /* Ensure that the directory ARGPATH exists.

    Remove any trailing slashes from ARGPATH before calling this function.  

@@ -212,7 +241,6 @@  

    Return 0 if ARGPATH exists as a directory with the proper     ownership and permissions when done, otherwise 1. */ -
 int
 make_path (const char *argpath,

            int mode,
@@ -224,6 +252,7 @@
 {
   struct stat stats;
   int retval = 0;
+ int rv;
 

   if (stat (argpath, &stats))
     {
diff -Nur fileutils-4.1/src/chcon.c fileutils-4.1-selinux/src/chcon.c

--- fileutils-4.1/src/chcon.c	Wed Dec 31 16:00:00 1969

+++ fileutils-4.1-selinux/src/chcon.c Sun Dec 9 17:49:29 2001
@@ -0,0 +1,336 @@
+/* chcontext -- change security context of a pathname */
+
+#include <config.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <getopt.h>
+#include <fs_secure.h>
+
+#include "system.h"
+//#include "xstrtoul.h"
+#include "closeout.h"
+#include "error.h"
+#include "savedir.h"
+#include "group-member.h"
+
+enum Change_status
+{
+ CH_SUCCEEDED,
+ CH_FAILED,
+ CH_NO_CHANGE_REQUESTED
+};
+
+enum Verbosity
+{
+ /* Print a message for each file that is processed. */
+ V_high,
+
+ /* Print a message for each file whose attributes we change. */
+ V_changes_only,
+
+ /* Do not be verbose. This is the default. */
+ V_off
+};
+
+static int change_dir_context PARAMS ((const char *dir, int sid,
+ const struct stat *statp));
+
+/* The name the program was run with. */
+char *program_name;
+
+/* If nonzero, and the systems has support for it, change the context
+ of symbolic links rather than any files they point to. */
+static int change_symlinks;
+
+/* If nonzero, change the context of directories recursively. */
+static int recurse;
+
+/* If nonzero, force silence (no error messages). */
+static int force_silent;
+
+/* Level of verbosity. */
+static enum Verbosity verbosity = V_off;
+
+/* The name of the context the file is being given. */
+static const char *contextname;
+
+/* The argument to the --reference option. Use the context SID of this file.
+ This file must exist. */
+static char *reference_file;
+
+/* If nonzero, display usage information and exit. */
+static int show_help;
+
+/* If nonzero, print the version on standard output and exit. */
+static int show_version;
+
+static struct option const long_options[] =
+{
+ {"recursive", no_argument, 0, 'R'},
+ {"changes", no_argument, 0, 'c'},
+ {"no-dereference", no_argument, 0, 'h'},
+ {"silent", no_argument, 0, 'f'},
+ {"quiet", no_argument, 0, 'f'},
+ {"reference", required_argument, 0, CHAR_MAX + 1},
+ {"sid", required_argument, 0, CHAR_MAX + 2},
+ {"verbose", no_argument, 0, 'v'},
+ {"help", no_argument, &show_help, 1},
+ {"version", no_argument, &show_version, 1},
+ {0, 0, 0, 0}
+};
+
+/* Tell the user how/if the context of FILE has been changed.
+ CHANGED describes what (if anything) has happened. */
+
+static void
+describe_change (const char *file, enum Change_status changed)
+{
+ const char *fmt;
+ switch (changed)
+ {
+ case CH_SUCCEEDED:
+ fmt = _("context of %s changed to %s\n");
+ break;
+ case CH_FAILED:
+ fmt = _("failed to change context of %s to %s\n");
+ break;
+ case CH_NO_CHANGE_REQUESTED:
+ fmt = _("context of %s retained as %s\n");
+ break;
+ default:
+ abort ();
+ }
+ printf (fmt, file, contextname);
+}
+
+/* Change the context of FILE to SID CONTEXT.
+ If it is a directory and -R is given, recurse.
+ Return 0 if successful, 1 if errors occurred. */
+
+static int
+change_file_context (const char *file, int sid)
+{
+ struct stat file_stats;
+ security_id_t file_sid;
+ int errors = 0;
+
+ if (lstat_secure (file, &file_stats, &file_sid))
+ {
+ if (force_silent == 0)
+ error (0, errno, "%s", file);
+ return 1;
+ }
+
+ if (sid != file_sid)
+ {
+ int fail;
+
+ if (change_symlinks)
+ fail = lchsid (file, sid);
+ else
+ fail = chsid (file, sid);
+
+ if (verbosity == V_high || (verbosity == V_changes_only && !fail))
+ describe_change (file, (fail ? CH_FAILED : CH_SUCCEEDED));
+
+ if (fail)
+ {
+ errors = 1;
+ if (force_silent == 0)
+ {
+ error (0, errno, "%s", file);
+ }
+ }
+ }
+ else if (verbosity == V_high)
+ {
+ describe_change (file, CH_NO_CHANGE_REQUESTED);
+ }
+
+ if (recurse && S_ISDIR (file_stats.st_mode))
+ errors |= change_dir_context (file, sid, &file_stats);
+
+ return errors;
+}
+
+/* Recursively change context of the files in directory DIR
+ to SID CONTEXT.
+ STATP points to the results of lstat on DIR.
+ Return 0 if successful, 1 if errors occurred. */
+
+static int
+change_dir_context (const char *dir, int sid, const struct stat *statp)
+{
+ char *name_space, *namep;
+ char *path; /* Full path of each entry to process. */
+ unsigned dirlength; /* Length of `dir' and '\0'. */
+ unsigned filelength; /* Length of each pathname to process. */
+ unsigned pathlength; /* Bytes allocated for `path'. */
+ int errors = 0;
+
+ errno = 0;
+ name_space = savedir (dir, (unsigned int) statp->st_size);
+ if (name_space == NULL)
+ {
+ if (errno)
+ {
+ if (force_silent == 0)
+ error (0, errno, "%s", dir);
+ return 1;
+ }
+ else
+ error (1, 0, _("virtual memory exhausted"));
+ }
+
+ dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
+ pathlength = dirlength + 1;
+ /* Give `path' a dummy value; it will be reallocated before first use. */
+ path = xmalloc (pathlength);
+ strcpy (path, dir);
+ path[dirlength - 1] = '/';
+
+ for (namep = name_space; *namep; namep += filelength - dirlength)
+ {
+ filelength = dirlength + strlen (namep) + 1;
+ if (filelength > pathlength)
+ {
+ pathlength = filelength * 2;
+ path = xrealloc (path, pathlength);
+ }
+ strcpy (path + dirlength, namep);
+ errors |= change_file_context (path, sid);
+ }
+ free (path);
+ free (name_space);
+ return errors;
+}
+
+static void
+usage (int status)
+{
+ if (status != 0)
+ fprintf (stderr, _("Try `%s --help' for more information.\n"),
+ program_name);
+ else
+ {
+ printf (_("\
+Usage: %s [OPTION]... CONTEXT FILE...\n\
+ or: %s [OPTION]... --reference=RFILE FILE...\n\
+ or: %s [OPTION]... --sid=SID FILE...\n\
+"),
+ program_name, program_name, program_name);
+ printf (_("\
+Change the security context of each FILE to CONTEXT.\n\
+\n\
+ -c, --changes like verbose but report only when a change is made\n\
+ -h, --no-dereference affect symbolic links instead of any referenced file\n\
+ (available only on systems with lchown system call)\n\
+ -f, --silent, --quiet suppress most error messages\n\
+ --reference=RFILE use RFILE's group instead of using a CONTEXT value\n\
+ --sid=SID use context corresponding to SID for CONTEXT value\n\
+ -R, --recursive change files and directories recursively\n\
+ -v, --verbose output a diagnostic for every file processed\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
+"));
+ close_stdout ();
+ }
+ exit (status);
+}
+
+int
+main (int argc, char **argv)
+{
+ int sid = -1;
+ int errors = 0;
+ int optc;
+
+ program_name = argv[0];
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ recurse = force_silent = 0;
+
+ while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
+ {
+ switch (optc)
+ {
+ case 0:
+ break;
+ case CHAR_MAX + 1:
+ reference_file = optarg;
+ break;
+ case CHAR_MAX +2:
+ sid = (int)strtol( optarg, (char **)NULL, 10);
+ /* We use an int to represent sids so we can use -1 for *
+ * an error condition. All valid sids are positive. *
+ * Check for an invalid sid. */
+ if( ( errno == ERANGE ) || ( sid <= 0 ) ) {
+ error( 1, 0, _("invalid sid"));
+ }
+ break;
+ case 'R':
+ recurse = 1;
+ break;
+ case 'c':
+ verbosity = V_changes_only;
+ break;
+ case 'f':
+ force_silent = 1;
+ break;
+ case 'h':
+ change_symlinks = 1;
+ break;
+ case 'v':
+ verbosity = V_high;
+ break;
+ default:
+ usage (1);
+ }
+ }
+
+ if (show_version)
+ {
+ printf ("chcon (%s) %s\n", GNU_PACKAGE, VERSION);
+ close_stdout ();
+ exit (0);
+ }
+
+ if (show_help)
+ usage (0);
+
+ if (argc - optind + ( (reference_file || ( sid > 0 ) ) ? 1 : 0) <= 1)
+ {
+ error (0, 0, _("too few arguments"));
+ usage (1);
+ }
+
+ if (reference_file)
+ {
+ struct stat ref_stats;
+ security_id_t ref_sid;
+ if (stat_secure (reference_file, &ref_stats, &ref_sid))
+ error (1, errno, "%s", reference_file);
+
+ sid = ref_sid;
+ }
+ else if( sid <= 0 ) /* sid > 0 means sid already set by --sid above */
+ {
+ contextname = argv[optind++];
+
+ if (*contextname == '\0')
+ error (1, 0, _("can not change to null context"));
+
+ if (security_context_to_sid (contextname, strlen (contextname) + 1, &sid))
+ error (1, errno, "%s", contextname);
+ }
+
+ for (; optind < argc; ++optind)
+ errors |= change_file_context (argv[optind], sid);
+
+ if (verbosity != V_off)
+ close_stdout ();
+ exit (errors);
+}

diff -Nur fileutils-4.1/src/copy.c fileutils-4.1-selinux/src/copy.c
--- fileutils-4.1/src/copy.c	Sun Dec  9 17:38:51 2001

+++ fileutils-4.1-selinux/src/copy.c Sun Dec 9 17:50:37 2001
@@ -37,6 +37,11 @@
 #include "quote.h"
 #include "same.h"  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+security_id_t Sid = -1;
+#endif /*FLASK_LINUX*/
+

 #define DO_CHOWN(Chown, File, New_uid, New_gid)				\
   (Chown (File, New_uid, New_gid)					\
    /* If non-root uses -p, it's ok if we can't preserve ownership.	\
@@ -193,6 +198,9 @@

   off_t n_read_total = 0;
   int last_write_made_hole = 0;
   int make_holes = (x->sparse_mode == SPARSE_ALWAYS);
+#ifdef FLASK_LINUX
+ security_id_t lsid;
+#endif /*FLASK_LINUX*/
 

   source_desc = open (src_path, O_RDONLY);    if (source_desc < 0)
@@ -573,12 +581,21 @@

   int delayed_fail;
   int copied_as_regular = 0;
   int ran_chown = 0;
+#ifdef FLASK_LINUX
+ security_id_t lsid;
+ struct stat tst_sb;
+#endif /*FLASK_LINUX*/
 

   if (move_mode && rename_succeeded)
     *rename_succeeded = 0;  

   *copy_into_self = 0;
+#ifdef FLASK_LINUX
+ /* will be either stat_secure() or fstat_secure() */
+ if ((*(x->xstat)) (src_path, &src_sb, &lsid))
+#else /*FLASK_LINUX*/

   if ((*(x->xstat)) (src_path, &src_sb))
+#endif /*FLASK_LINUX*/

     {
       error (0, errno, _("cannot stat %s"), quote (src_path));
       return 1;

@@ -605,7 +622,11 @@  

   if (!new_dst)
     {
+#ifdef FLASK_LINUX
+ if ((*(x->xstat)) (dst_path, &dst_sb, &lsid))
+#else /*FLASK_LINUX*/

       if ((*(x->xstat)) (dst_path, &dst_sb))
+#endif /*FLASK_LINUX*/

 	{
 	  if (errno != ENOENT)
 	    {
@@ -893,6 +914,15 @@
 	{
 	  /* Create the new directory writable and searchable, so
              we can create new entries in it.  */

+#ifdef FLASK_LINUX
+ if ( (int) Sid > 0 ) {
+ if (mkdir_secure (dst_path, (src_mode & x->umask_kill) | 0700, Sid)) {
+ error (0, errno, _("cannot create directory `%s'"), dst_path);
+ goto un_backup;
+ }
+ }
+ else
+#endif /*FLASK_LINUX*/
 
 	  if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
 	    {

@@ -997,6 +1027,15 @@
 #ifdef S_ISFIFO
   if (S_ISFIFO (src_type))
     {
+#ifdef FLASK_LINUX
+ if ( (int) Sid > 0 ) {
+ if (mkfifo_secure (dst_path, get_dest_mode (x, src_mode), Sid)) {
+ error (0, errno, _("cannot create fifo `%s'"), dst_path);
+ goto un_backup;
+ }
+ }
+ else
+#endif /*FLASK_LINUX*/
       if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
 	{
 	  error (0, errno, _("cannot create fifo %s"), quote (dst_path));
@@ -1011,7 +1050,16 @@
 #endif
 	)
     {
-      if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))

+#ifdef FLASK_LINUX
+ if ( (int) Sid > 0 ) {
+ if (mknod_secure (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev, Sid)) {
+ error (0, errno, _("cannot create special file `%s'"), dst_path);
+ goto un_backup;
+ }
+ }
+ else
+#endif /*FLASK_LINUX*/
+ if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
 	{
 	  error (0, errno, _("cannot create special file %s"),
 		 quote (dst_path));

@@ -1078,6 +1126,26 @@
 # endif

         }  

+#ifdef FLASK_LINUX
+ /* Trying to preserve a security context can fail for any UID, and user
+ * should probably always know about it.
+ */
+ if ( x->preserve_security_context ) {
+ if ( (int) Sid > 0 ) {
+ error (0, 0, _("cannot set context to SID==%d and preserve it"), (int)Sid);
+ return 1;
+ }
+ if ( stat_secure(src_path, &tst_sb, &lsid) < 0 ) {
+ error (0, errno, _("getting security context for %s"), src_path);
+ return 1;
+ }
+ if ( chsid(dst_path, lsid) < 0 ) {
+ error (0, errno, _("preserving security context for %s (sid==%d)"), dst_path, (int)lsid);
+ return 1;
+ }
+ }
+#endif /*FLASK_LINUX*/
+

       return 0;
     }

   else
@@ -1118,6 +1186,27 @@
 	}
     }
 

+#ifdef FLASK_LINUX
+ /* Trying to preserve a security context can fail for any UID, and user
+ * should probably always know about it.
+ */
+
+ if ( x->preserve_security_context ) {
+ if ( (int) Sid > 0 ) {
+ error (0, 0, _("cannot set context to SID==%d and preserve it"), (int) Sid);
+ return 1;
+ }
+ if ( stat_secure(src_path, &tst_sb, &lsid) < 0 ) {
+ error (0, errno, _("getting security context for %s"), src_path);
+ return 1;
+ }
+ if ( chsid(dst_path, lsid) < 0 ) {
+ error (0, errno, _("preserving security context for %s (sid==%d)"), dst_path, (int)lsid);
+ return 1;
+ }
+ }
+#endif /*FLASK_LINUX*/
+

   /* Avoid calling chown if we know it's not necessary. */    if (x->preserve_owner_and_group

       && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb))) @@ -1148,6 +1237,13 @@

 	    return 1;
 	}
     }

+#ifdef FLASK_LINUX
+ if ( (int) Sid > 0 && x->preserve_security_context == 0 ) {
+ if ( chsid(dst_path, Sid) < 0 ) {
+ error (0, errno, _("setting scontext (%d) for %s"), (int)Sid, dst_path); return 1;
+ }
+ }
+#endif /*FLASK_LINUX*/
 

   return delayed_fail;  

@@ -1163,6 +1259,14 @@

 		    quote_n (0, dst_backup), quote_n (1, dst_path));
 	}
     }

+
+#ifdef FLASK_LINUX
+ /* if rename() just failed, so will this */
+ if ( (int) Sid > 0 && x->preserve_security_context == 0 )
+ if ( chsid(dst_path, Sid) < 0 )
+ error (0, errno, _("setting scontext (%d) for %s"), (int)Sid, dst_path);
+#endif /*FLASK_LINUX*/
+

   return 1;
 }  

@@ -1194,6 +1298,17 @@

    same as) DST_PATH; otherwise, set it to zero.     Return 0 if successful, 1 if an error occurs. */  

+#ifdef FLASK_LINUX
+int
+copy_s (const char *src_path, const char *dst_path,
+ int nonexistent_dst, const struct cp_options *options,
+ int *copy_into_self, int *rename_succeeded, security_id_t sid)
+{
+ Sid = sid;
+ return( copy( src_path, dst_path, nonexistent_dst, options, copy_into_self, rename_succeeded) );
+}
+#endif /*FLASK_LINUX*/
+

 int
 copy (const char *src_path, const char *dst_path,

       int nonexistent_dst, const struct cp_options *options, diff -Nur fileutils-4.1/src/copy.h fileutils-4.1-selinux/src/copy.h

--- fileutils-4.1/src/copy.h	Sun Jan 14 03:03:30 2001

+++ fileutils-4.1-selinux/src/copy.h Sun Dec 9 17:52:01 2001
@@ -89,6 +89,9 @@
   int preserve_owner_and_group;
   int preserve_chmod_bits;
   int preserve_timestamps;

+#ifdef FLASK_LINUX
+ int preserve_security_context;
+#endif /*FLASK_LINUX*/
 

   /* If nonzero and any of the above (for preserve) file attributes cannot

      be applied to a destination file, treat it as a failure and return @@ -157,5 +160,4 @@
 copy PARAMS ((const char *src_path, const char *dst_path,

 	      int nonexistent_dst, const struct cp_options *options,
 	      int *copy_into_self, int *rename_succeeded));
-
 #endif
diff -Nur fileutils-4.1/src/cp.c fileutils-4.1-selinux/src/cp.c
--- fileutils-4.1/src/cp.c	Sat Feb  3 08:48:34 2001

+++ fileutils-4.1-selinux/src/cp.c Sun Dec 9 17:50:40 2001
@@ -52,6 +52,16 @@  

 #define AUTHORS "Torbjorn Granlund, David MacKenzie, and Jim Meyering"  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#include <flask_util.h> /* for is_flask_enabled() */
+#define CTXTLEN 256
+char *scontext = NULL;
+security_id_t sid = -1;
+int ctxtlen = CTXTLEN;
+char *calloc();
+#endif /*FLASK_LINUX*/
+

 #ifndef _POSIX_VERSION
 uid_t geteuid ();
 #endif
@@ -133,6 +143,10 @@

   {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},

+#ifdef FLASK_LINUX
+ {"sid", required_argument, NULL, 'Z'},
+ {"context", required_argument, NULL, 'X'},
+#endif /*FLASK_LINUX*/

   {NULL, 0, NULL, 0}
 };  

@@ -161,9 +175,18 @@

                                    opened, remove it and try again\n\
   -i, --interactive            prompt before overwrite\n\
   -H                           follow command-line symbolic links\n\
-  -l, --link                   link files instead of copying\n\

+ -l, --link link files instead of copying\n"));
+#ifdef FLASK_LINUX
+ printf(_("\
+ -p, --preserve preserve file attributes and (if Flask) security contexts if possible\n\
+ -Z, --sid=SID (Flask only) set Security ID of copy to SID\n\
+ -X, --context=CONTEXT (Flask only) set security context of copy to CONTEXT\n"));
+#else /*FLASK_LINUX*/
+ printf(_("\
+ -p, --preserve preserve file attributes if possible\n"));
+#endif /*FLASK_LINUX*/
+ printf(_("\
-L, --dereference always follow symbolic links\n\ - -p, --preserve preserve file attributes if possible\n\ --parents append source path to DIRECTORY\n\ -P same as `--parents' for now; soon to change to\n\ `--no-dereference' to conform to POSIX\n\
@@ -197,7 +220,7 @@
 \n\
 "));

       printf (_("\

-The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\

+The backup suffix is `~`, unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
 The version control method may be selected via the --backup option or through\n\  the VERSION_CONTROL environment variable. Here are the values:\n\  \n\
@@ -245,6 +268,9 @@
   char *dst_path;		/* A copy of CONST_DST_PATH we can change. */
   char *src_path;		/* The source name in `dst_path'. */
   uid_t myeuid = geteuid ();
+#ifdef FLASK_LINUX
+ security_id_t lsid;
+#endif /*FLASK_LINUX*/
 

   dst_path = (char *) alloca (strlen (const_dst_path) + 1);    strcpy (dst_path, const_dst_path);
@@ -256,7 +282,11 @@  

       dst_path[p->slash_offset] = '\0';  

+#ifdef FLASK_LINUX
+ if ((*(x->xstat)) (src_path, &src_sb, &lsid))
+#else /*FLASK_LINUX*/

       if ((*(x->xstat)) (src_path, &src_sb))
+#endif /*FLASK_LINUX*/

 	{
 	  error (0, errno, _("getting attributes of %s"),
 		 quote (src_path));
@@ -309,6 +339,28 @@
 	    }
 	}
 

+#ifdef FLASK_LINUX
+ /* Trying to preserve a security context can fail for any UID, and user
+ * should probably always know about it.
+ */
+
+ if ( x->preserve_security_context ) {
+ int rv;
+ struct stat st;
+ security_id_t lsid;
+
+ if ( (rv = stat_secure(src_path, &st, &lsid)) < 0 ) {
+ error (0, errno, _("getting security context for %s"), src_path);
+ return 1;
+ }
+
+ if ( (rv = chsid(dst_path, lsid)) < 0 ) {
+ error (0, errno, _("preserving security context for %s (sid==%d)"), dst_path, (int)lsid);
+ return 1;
+ }
+ }
+#endif /*FLASK_LINUX*/
+
       dst_path[p->slash_offset] = '/';
     }

   return 0;
@@ -344,6 +396,9 @@
   char *src;			/* Source name in `dirpath'. */
   char *tmp_dst_dirname;	/* Leading path of `dirpath', malloc. */
   char *dst_dirname;		/* Leading path of `dirpath', alloca. */

+#ifdef FLASK_LINUX
+ security_id_t lsid;
+#endif /*FLASK_LINUX*/
 

   dirpath = (char *) alloca (strlen (const_dirpath) + 1);    strcpy (dirpath, const_dirpath);
@@ -356,8 +411,11 @@

   free (tmp_dst_dirname);  

   *attr_list = NULL;
-
+#ifdef FLASK_LINUX
+ if ((*xstat) (dst_dirname, &stats, &lsid))
+#else /*FLASK_LINUX*/

   if ((*xstat) (dst_dirname, &stats))
+#endif /*FLASK_LINUX*/

     {
       /* Parent of CONST_DIRNAME does not exist.
 	 Make all missing intermediate directories. */
@@ -377,7 +435,11 @@
 	  *attr_list = new;
 
 	  *slash = '\0';

+#ifdef FLASK_LINUX
+ if ((*xstat) (dirpath, &stats, &lsid))
+#else /*FLASK_LINUX*/
if ((*xstat) (dirpath, &stats))
+#endif /*FLASK_LINUX*/
{ /* This element of the path does not exist. We must set *new_dst and new->is_new_dir inside this loop because, @@ -386,6 +448,16 @@ exists. */ *new_dst = 1; new->is_new_dir = 1;
+#ifdef FLASK_LINUX
+ /* if there's a SID given set new path components to that SID, too */
+ if ( (int) sid > 0 ) {
+ if ( mkdir_secure (dirpath, mode, sid) < 0 ) {
+ error (0, errno, _("make_secure(%s, 0x%x, SID==%d) failed"), dirpath, (int)mode, (int)sid);
+ return 1;
+ }
+ }
+ else
+#endif /*FLASK_LINUX*/
if (mkdir (dirpath, mode)) { error (0, errno, _("cannot make directory %s"), @@ -574,7 +646,12 @@ else { int copy_into_self; - ret |= copy (arg, dst_path, new_dst, x, &copy_into_self, NULL);
+#ifdef FLASK_LINUX
+ if ( (int) sid > 0 )
+ ret |= copy_s (arg, dst_path, new_dst, x, &copy_into_self, NULL, sid);
+ else
+#endif /*FLASK_LINUX*/
+ ret |= copy (arg, dst_path, new_dst, x, &copy_into_self, NULL);
forget_all (); if (flag_path) @@ -653,8 +730,12 @@ { new_dest = (char *) dest; } - - return copy (source, new_dest, new_dst, x, &unused, NULL);
+#ifdef FLASK_LINUX
+ if ( (int) sid > 0 )
+ return copy_s (source, new_dest, new_dst, x, &unused, NULL, sid);
+ else
+#endif /*FLASK_LINUX*/
+ return copy (source, new_dest, new_dst, x, &unused, NULL);
}

   /* unreachable */
@@ -678,6 +759,10 @@

   x->preserve_chmod_bits = 0;
   x->preserve_timestamps = 0;  

+#ifdef FLASK_LINUX
+ x->preserve_security_context = 0;
+#endif /*FLASK_LINUX*/
+

   x->require_preserve = 0;
   x->recursive = 0;
   x->sparse_mode = SPARSE_AUTO;

@@ -705,6 +790,11 @@

   struct cp_options x;
   char *target_directory = NULL;
   int used_P_option = 0;
+#ifdef FLASK_LINUX
+ int is_flask_enabled_flag;
+
+ is_flask_enabled_flag = is_flask_enabled();
+#endif /*FLASK_LINUX*/
 

   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -719,7 +809,11 @@

      we'll actually use backup_suffix_string. */    backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");  

+#ifdef FLASK_LINUX
+ while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:Z:X:", long_opts, NULL))
+#else /*FLASK_LINUX*/

   while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:", long_opts, NULL))
+#endif /*FLASK_LINUX*/

 	 != -1)
     {
       switch (c)
@@ -740,6 +834,10 @@
 	  x.require_preserve = 1;
 	  x.recursive = 1;
 	  x.copy_as_regular = 0;

+#ifdef FLASK_LINUX
+ if (is_flask_enabled_flag)
+ x.preserve_security_context = 1;
+#endif /*FLASK_LINUX*/
break; case 'V': /* FIXME: this is deprecated. Remove it in 2001. */ @@ -784,7 +882,86 @@ x.preserve_chmod_bits = 1; x.preserve_timestamps = 1; x.require_preserve = 1;
+#ifdef FLASK_LINUX
+ if ( (int) sid > 0 ) { /* scontext could be NULL because of calloc() failure */
+ if ( scontext )
+ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], scontext);
+ else
+ (void) fprintf(stderr, "%s: cannot force target context <-- %d and preserve it\n", argv[0], (int) sid);
+ exit( 1 );
+ }
+ else if (is_flask_enabled_flag)
+ x.preserve_security_context = 1;
+#endif /*FLASK_LINUX*/
+ break;
+#ifdef FLASK_LINUX
+ case 'Z':
+ /* politely decline if we're not on a flask-enabled kernel. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Warning: ignoring --sid (-Z) "
+ "because the kernel is not flask-enabled.\n" );
+ break;
+ }
+ if ( x.preserve_security_context ) {
+ (void) fprintf(stderr, "%s: can`t force target context to `%s` and preserve it\n", argv[0], optarg);
+ exit( 1 );
+ }
+ if ( (int) sid > 0 || scontext != NULL ) {
+ (void) fprintf(stderr, "%s: --sid (-Z) and --context (-X) are mutually exclusive\n", argv[0]);
+ exit( 1 );
+ }
+ /* check for typos */
+ {
+ char *ep;
+ sid = (security_id_t) strtol(optarg, &ep, 10);
+ if ( *ep ) {
+ (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
+ exit( 1 );
+ }
+ }
+ /* do a sanity check and save result if SID is OK */
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext != NULL ) {
+ if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
+ if ( errno != ENOSPC ) {
+ (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
+ exit( 1 );
+ }
+ free(scontext);
+ scontext = calloc(1, ctxtlen+1);
+ /* nonfatal */
+ if ( scontext != NULL )
+ if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
+ (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+ }
+ break;
+ case 'X':
+ /* politely decline if we're not on a flask-enabled kernel. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Warning: ignoring --context (-X) "
+ "because the kernel is not flask-enabled.\n" );
+ break;
+ }
+ if ( x.preserve_security_context ) {
+ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg);
+ exit( 1 );
+ }
+ if ( (int) sid > 0 ) {
+ (void) fprintf(stderr, "%s: --context (-X) and --sid (-Z) are mutually exclusive\n", argv[0]);
+ exit( 1 );
+ }
+ scontext = optarg;
+ /* sanity check -- also sets sid val */
+ if ( security_context_to_sid(scontext, strlen(scontext)+1, &sid) ) {
+ (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n",
+ argv[0], scontext, strerror(errno));
+ exit( 1 );
+ }
break;

+#endif /*FLASK_LINUX*/
 
 	case 'P':
 	  used_P_option = 1;
@@ -859,8 +1036,8 @@
     {
       error (0, 0,
 	     _("\

-Warning: the meaning of `-P' will change in the future to conform to POSIX.\n\ -Use `--parents' for the old meaning, and `--no-dereference' for the new one."));
+Warning: the meaning of `-P` will change in the future to conform to POSIX.\n\
+Use `--parents` for the old meaning, and `--no-dereference` for the new one."));

     }  

   if (backup_suffix_string)
@@ -886,6 +1063,15 @@

   /* The key difference between -d (--no-dereference) and not is the version

      of `stat' to call. */  

+#ifdef FLASK_LINUX
+ /* not sure whether using secure_stat() is strictly necessary,
+ but there's no penalty for using it
+ */
+ if (x.dereference)
+ x.xstat = stat_secure;
+ else
+ x.xstat = lstat_secure;
+#else /*FLASK_LINUX*/

   if (x.dereference == DEREF_NEVER)
     x.xstat = lstat;
   else
@@ -895,7 +1081,7 @@

 	 any symlinks that are found via recursive traversal.  */
       x.xstat = stat;
     }

-
+#endif /*FLASK_LINUX*/

   /* If --force (-f) was specified and we're in link-creation mode,

      first remove any existing destination file. */    if (x.unlink_dest_after_failed_open && (x.hard_link || x.symbolic_link)) diff -Nur fileutils-4.1/src/df.c fileutils-4.1-selinux/src/df.c

--- fileutils-4.1/src/df.c	Sun Dec  9 17:38:51 2001

+++ fileutils-4.1-selinux/src/df.c Sun Dec 9 17:50:56 2001
@@ -41,6 +41,10 @@
 #include "path-concat.h"
 #include "quote.h"
 #include "save-cwd.h"

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#include <flask_util.h>
+#endif
 

 /* The official name of this program (e.g., no `g' prefix). */  #define PROGRAM_NAME "df"
@@ -57,6 +61,9 @@
 /* If nonzero, show inode information. */  static int inode_format;  

+/* If nonzero, show security (sid and context) information */
+static int security_format;
+

 /* If nonzero, show even filesystems with zero size or

    uninteresting types. */
 static int show_all_fs;
@@ -130,6 +137,9 @@

   {"all", no_argument, NULL, 'a'},
   {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
   {"inodes", no_argument, NULL, 'i'},

+#ifdef FLASK_LINUX
+ {"security", no_argument, NULL, 's'},
+#endif
   {"human-readable", no_argument, NULL, 'h'},
   {"si", no_argument, NULL, 'H'},
   {"kilobytes", no_argument, NULL, 'k'},
@@ -158,7 +168,13 @@  

   if (inode_format)
     printf (_(" Inodes IUsed IFree IUse%%")); - else if (output_block_size < 0)
+ else
+#ifdef FLASK_LINUX
+ if (security_format)
+ printf (" SID Context ");
+ else
+#endif
+ if (output_block_size < 0)

     printf (_(" Size Used Avail Use%%"));    else if (posix_format)
     printf (_(" %4d-blocks Used Available Capacity"), output_block_size); @@ -287,6 +303,13 @@

   uintmax_t used;
   int negate_used;
   double pct = -1;
+#ifdef FLASK_LINUX
+ struct statfs filesystem_stats; /* statfs_secure() output stats for fs */
+ security_id_t filesystem_sid; /* statfs_secure() output sid for fs */
+#define CONTEXTLEN 255 /* this is how ps and ls do it, currently */
+ char filesystem_context_s[ CONTEXTLEN ]; /* security context for fs */
+ int context_length = CONTEXTLEN; /* length of `filesystem_context_s' */
+#endif
 

   if (me_remote && show_local_fs)
     return;
@@ -339,6 +362,29 @@

 	printf ("%-20s", disk);
     }
 

+#ifdef FLASK_LINUX
+ if (security_format)
+ {
+ /* Get sid and context for filesystem described by `mount_point'. *
+ * `mount_point' will be null if the filesystem is not mounted. *
+ * We won't be able to report useful sid/context in that case. */
+ if( mount_point ) {
+ if( 0 != statfs_secure( mount_point, &filesystem_stats,
+ &filesystem_sid ) ) {
+ error( 1, errno, "%s", mount_point );
+ }
+ if( security_sid_to_context( filesystem_sid, filesystem_context_s,
+ &context_length ) ) {
+ error( 1, errno, "security_sid_to_context(%u)", filesystem_sid );
+ }
+ printf("%5u %-29s", filesystem_sid, filesystem_context_s );
+ } else {
+ /* filesystem not mounted, we have no meaningful sid or context */
+ printf(" %-29s", "<not mounted>" );
+ }
+ }
+ else
+#endif

   if (inode_format)

     {
       width = 7;
@@ -788,6 +834,7 @@
   -m, --megabytes       like --block-size=1048576\n\
       --no-sync         do not invoke sync before getting usage info (default)\n\
   -P, --portability     use the POSIX output format\n\

+ -s, --security list security information instead of block usage\n\
--sync invoke sync before getting usage info\n\ -t, --type=TYPE limit listing to filesystems of type TYPE\n\ -T, --print-type print filesystem type\n\
@@ -808,6 +855,13 @@

   struct stat *stats IF_LINT (= 0);
   int n_valid_args = 0;  

+#ifdef FLASK_LINUX
+ int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
+
+ /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
+ is_flask_enabled_flag = is_flask_enabled();
+#endif
+

   program_name = argv[0];
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
@@ -818,6 +872,9 @@

   fs_select_list = NULL;
   fs_exclude_list = NULL;
   inode_format = 0;
+#ifdef FLASK_LINUX
+ security_format = 0;
+#endif

   show_all_fs = 0;
   show_listed_fs = 0;  

@@ -827,7 +884,11 @@

   posix_format = 0;
   exit_status = 0;  

+#ifdef FLASK_LINUX
+ while ((c = getopt_long (argc, argv, "aiF:hHklmPTst:vx:", long_options, NULL))
+#else

   while ((c = getopt_long (argc, argv, "aiF:hHklmPTt:vx:", long_options, NULL))
+#endif

 	 != -1)
     {
       switch (c)
@@ -838,8 +899,31 @@
 	  show_all_fs = 1;
 	  break;
 	case 'i':

+#ifdef FLASK_LINUX
+ if( security_format ) {
+ fprintf( stderr, "you cannot specify --security (-s) and "
+ "--inode (-i) simultaneously.\n" );
+ exit( 1 );
+ }
+#endif
inode_format = 1; break;
+#ifdef FLASK_LINUX
+ case 's':
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --security (-s) can be used only on "
+ "a flask-enabled kernel.\n" );
+ exit( 1 );
+ }
+ if( inode_format ) {
+ fprintf( stderr, "you cannot specify --security (-s) and "
+ "--inode (-i) simultaneously.\n" );
+ exit( 1 );
+ }
+
+ security_format = 1;
+ break;
+#endif
case 'h': output_block_size = -1024; break; diff -Nur fileutils-4.1/src/install.c fileutils-4.1-selinux/src/install.c --- fileutils-4.1/src/install.c Sun Dec 9 17:38:51 2001
+++ fileutils-4.1-selinux/src/install.c Sun Dec 9 17:51:05 2001
@@ -54,6 +54,15 @@
 # include <values.h>
 #endif  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#include <flask_util.h> /* for is_flask_enabled() */
+#define CTXTLEN 256
+char *scontext = NULL;
+int ctxtlen = CTXTLEN;
+char *calloc();
+#endif /*FLASK_LINUX*/
+

 struct passwd *getpwnam ();
 struct group *getgrnam ();  

@@ -136,6 +145,11 @@

   {"mode", required_argument, NULL, 'm'},
   {"owner", required_argument, NULL, 'o'},
   {"preserve-timestamps", no_argument, NULL, 'p'},

+#ifdef FLASK_LINUX
+ {"sid" , required_argument, NULL, 'Z'},
+ {"context" , required_argument, NULL, 'X'},
+ {"preserve_context", no_argument , NULL, 'P'},
+#endif /*FLASK_LINUX*/
   {"strip", no_argument, NULL, 's'},
   {"suffix", required_argument, NULL, 'S'},
   {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
@@ -255,9 +269,18 @@
   x->umask_kill = 0;
   x->update = 0;
   x->verbose = 0;

+#ifdef FLASK_LINUX
+ x->xstat = stat_secure;
+ x->preserve_security_context = 0;
+#else /*FLASK_LINUX*/

   x->xstat = stat;
+#endif /*FLASK_LINUX*/

 }  

+#ifdef FLASK_LINUX
+security_id_t sid = -1;
+#endif /*FLASK_LINUX*/
+

 int
 main (int argc, char **argv)
 {
@@ -271,6 +294,13 @@

   struct cp_options x;
   int n_files;
   char **file;
+#ifdef FLASK_LINUX
+ int rv;
+ int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
+
+ /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
+ is_flask_enabled_flag = is_flask_enabled();
+#endif /*FLASK_LINUX*/
 

   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -291,8 +321,13 @@

      we'll actually use backup_suffix_string. */    backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");  

  • while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pvV:S:", long_options,
  • NULL)) != -1)
    +#ifdef FLASK_LINUX
    + while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:Z:X:P", long_options,
    + NULL)) != -1)
    +#else /*FLASK_LINUX*/
    + while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,
    + NULL)) != -1)
    +#endif /*FLASK_LINUX*/
    { switch (optc) { @@ -346,6 +381,91 @@ break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
    +#ifdef FLASK_LINUX
    + case 'P':
    + /* politely decline if we're not on a flask-enabled kernel. */
    + if( !is_flask_enabled_flag ) {
    + fprintf( stderr, "Warning: ignoring --preserve_context (-P) "
    + "because the kernel is not flask-enabled.\n" );
    + break;
    + }
    + if ( (int) sid >= 0 ) { /* scontext could be NULL because of calloc() failure */
    + if ( scontext )
    + (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], scontext);
    + else
    + (void) fprintf(stderr, "%s: cannot force target context <-- %d and preserve it\n", argv[0], (int) sid);
    + exit( 1 );
    + }
    + x.preserve_security_context = 1;
    + break ;
    + case 'Z':
    + /* politely decline if we're not on a flask-enabled kernel. */
    + if( !is_flask_enabled_flag ) {
    + fprintf( stderr, "Warning: ignoring --sid (-Z) "
    + "because the kernel is not flask-enabled.\n" );
    + break;
    + }
    + if ( x.preserve_security_context ) {
    + (void) fprintf(stderr, "%s: can't force target context to '%s' and preserve it\n", argv[0], optarg);
    + exit( 1 );
    + }
    + if ( scontext != NULL ) {
    + (void) fprintf(stderr, "%s: --sid (-Z) and --context (-X) are mutually exclusive\n", argv[0]);
    + exit( 1 );
    + }
    + /* check for typos */
    + {
    + char *ep;
    + sid = (security_id_t) strtol(optarg, &ep, 10);
    + if ( *ep ) {
    + (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
    + exit( 1 );
    + }
    + }
    + /* do a sanity check and save result if SID is OK */
    + scontext = calloc(1, ctxtlen+1);
    + if ( scontext != NULL ) {
    + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
    + if ( errno != ENOSPC ) {
    + (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
    + exit( 1 );
    + }
    + free(scontext);
    + scontext = calloc(1, ctxtlen+1);
    + if ( scontext != NULL )
    + if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
    + (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
    + exit( 1 );
    + }
    + }
    + }
    + break;
    + case 'X':
    + /* politely decline if we're not on a flask-enabled kernel. */
    + if( !is_flask_enabled_flag ) {
    + fprintf( stderr, "Warning: ignoring --context (-X) "
    + "because the kernel is not flask-enabled.\n" );
    + break;
    + }
    + if ( x.preserve_security_context ) {
    + (void) fprintf(stderr, "%s: cannot force target context == '%s' and
    +preserve it\n", argv[0], optarg);
    + exit( 1 );
    + }
    + if ( (int) sid >= 0 ) {
    + (void) fprintf(stderr, "%s: --context (-X) and --sid (-Z) are mutually exclusive\n", argv[0]);
    + exit(1);
    + }
    + scontext = optarg;
    + /* sanity check */
    + rv = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
    + if ( rv ) {
    + (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n", argv[0], scontext,
    + strerror(errno));
    + exit(1);
    + }
    + break;
    +#endif /*FLASK_LINUX*/
    default: usage (1); } @@ -391,8 +511,17 @@ for (i = 0; i < n_files; i++) { errors |=
  • make_path (file[i], mode, mode, owner_id, group_id, 0,
  • (x.verbose ? _("creating directory %s") : NULL));
    +#ifdef FLASK_LINUX
    + errors |=
    + make_path_s (file[i], mode, mode, owner_id, group_id, 0,
    + (x.verbose ? _("creating directory `%s'") : NULL), sid);
    +#else /*FLASK_LINUX*/
    + errors |=
    + make_path (file[i], mode, mode, owner_id, group_id, 0,
    + (x.verbose ? _("creating directory `%s'") : NULL));
    +#endif /*FLASK_LINUX*/
    +// make_path (file[i], mode, mode, owner_id, group_id, 0,
    +// (x.verbose ? _("creating directory %s") : NULL));
    if(errors==0) chmod(file[i], mode); } } @@ -454,8 +583,12 @@ that this option is intended mainly to help installers when the distribution doesn't provide proper install rules. */ #define DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
    +#ifdef FLASK_LINUX
    + fail = make_path_s (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0, (x->verbose ? _("creating directory `%s'") : NULL), sid);
    +#else /*FLASK_LINUX*/
    fail = make_path (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
  • (x->verbose ? _("creating directory %s") : NULL));
    + (x->verbose ? _("creating directory `%s'") : NULL));
    +#endif /*FLASK_LINUX*/
    }

   if (fail == 0)
@@ -506,7 +639,6 @@  

 /* Copy file FROM onto file TO, creating TO if necessary.

    Return 0 if the copy is successful, 1 if not. */ -
 static int
 copy_file (const char *from, const char *to, const struct cp_options *x)  {
@@ -529,7 +661,11 @@

 	return 0;
     }
   

+#ifdef FLASK_LINUX
+ fail = copy_s (from, to, nonexistent_dst, x, &copy_into_self, NULL, sid);
+#else

   fail = copy (from, to, nonexistent_dst, x, &copy_into_self, NULL);
+#endif
 

   return fail;
 }
@@ -695,6 +831,35 @@

   or: %s -d [OPTION]... DIRECTORY... (3rd format)\n\  "),

               program_name, program_name, program_name);
+#ifdef FLASK_LINUX
+ printf (_("\
+In the first two formats, copy SOURCE to DEST or multiple SOURCE(s) to\n\
+the existing DIRECTORY, while setting permission modes and owner/group.\n\
+In the third format, create all components of the given DIRECTORY(ies).\n\
+\n\
+ -b, --backup make backup before removal\n\
+ -c (ignored)\n\
+ -d, --directory treat all arguments as directory names; create all\n\
+ components of the specified directories\n\
+ -D create all leading components of DEST except the last,\n\
+ then copy SOURCE to DEST; useful in the 1st format\n\
+ -g, --group=GROUP set group ownership, instead of process' current group\n\
+ -m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x\n\
+ -o, --owner=OWNER set ownership (super-user only)\n\
+ -p, --preserve-timestamps apply access/modification times of SOURCE files\n\
+ to corresponding destination files\n\
+ -s, --strip strip symbol tables, only for 1st and 2nd formats\n\
+ -S, --suffix=SUFFIX override the usual backup suffix\n\
+ --verbose print the name of each directory as it is created\n\
+ -V, --version-control=WORD override the usual version control\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
+ -P, --preserve_context (Flask) Preserve security context\n\
+ -Z, --sid=SID (Flask) Set SID of files and directories\n\
+ -X, --context=CONTEXT (Flask) Set security context of files and directories\n\
+\n\
+"));
+#else /*FLASK_LINUX*/

       printf (_("\
 In the first two formats, copy SOURCE to DEST or multiple SOURCE(s) to\n\  the existing DIRECTORY, while setting permission modes and owner/group.\n\ @@ -719,6 +884,7 @@

       --version output version information and exit\n\  \n\
 "));
+#endif /*FLASK_LINUX*/

       printf (_("\
 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\  The version control method may be selected via the --backup option or through\n\ diff -Nur fileutils-4.1/src/ls.c fileutils-4.1-selinux/src/ls.c

--- fileutils-4.1/src/ls.c	Sun Dec  9 17:38:51 2001

+++ fileutils-4.1-selinux/src/ls.c Sun Dec 9 17:51:19 2001
@@ -133,6 +133,25 @@  

 #define AUTHORS "Richard Stallman and David MacKenzie"  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#include <flask_util.h> /* for is_flask_enabled() */
+
+#define CTXTLEN 256
+#define P_CTXT 36
+#define SID_DIGITS 5
+
+security_id_t sid;
+char *scontext;
+int ctxtlen = CTXTLEN;
+char *calloc();
+char *generic_error_string = "<error getting security context string>";
+
+static int print_sid = 0;
+static int print_scontext = 0;
+
+#endif /*FLASK_LINUX*/
+

 #define obstack_chunk_alloc malloc
 #define obstack_chunk_free free  

@@ -241,6 +260,9 @@

        otherwise zero.  */
     int have_acl;

 #endif
+#ifdef FLASK_LINUX
+ security_id_t sid;
+#endif /*FLASK_LINUX*/

   };  

 #if USE_ACL
@@ -331,6 +353,9 @@
 static void sort_files PARAMS ((void));  static void parse_ls_color PARAMS ((void));  void usage PARAMS ((int status));
+#ifdef FLASK_LINUX
+static void print_scontext_format PARAMS ((const struct fileinfo *f));
+#endif
 

 /* The name the program was run with, stripped of any leading path. */  char *program_name;
@@ -404,7 +429,15 @@

     one_per_line,		/* -1 */
     many_per_line,		/* -C */
     horizontal,			/* -x */
-    with_commas			/* -m */

+#ifndef FLASK_LINUX
+ with_commas /* -m */
+#else /*FLASK_LINUX*/
+ with_commas, /* -m */
+ /* If we are using the flask security mechanism, we also want
+ an output format that lists all security-relevant
+ information */
+ security
+#endif /*FLASK_LINUX*/

   };  

 static enum format format;
@@ -705,19 +738,34 @@

   {"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},

+#ifdef FLASK_LINUX
+ {"lsid", no_argument, 0, 18},
+ {"context", no_argument, 0, 19},
+ {"lcontext", no_argument, 0, 20},
+ {"sid", no_argument, 0, 21},
+ {"scontext", no_argument, 0, 22},
+#endif /*FLASK_LINUX*/

   {NULL, 0, NULL, 0}
 };  

 static char const *const format_args[] =  {
   "verbose", "long", "commas", "horizontal", "across",
+#ifdef FLASK_LINUX
+ "vertical", "single-column", "context", 0
+#else /*FLASK_LINUX*/

   "vertical", "single-column", 0
+#endif /*FLASK_LINUX*/

 };  

 static enum format const format_types[] =  {
   long_format, long_format, with_commas, horizontal, horizontal,
+#ifdef FLASK_LINUX
+ many_per_line, one_per_line, security
+#else /*FLASK_LINUX*/

   many_per_line, one_per_line
+#endif /*FLASK_LINUX*/

 };  

 static char const *const sort_args[] =
@@ -900,6 +948,9 @@  

   format_needs_stat = sort_type == sort_time || sort_type == sort_size      || format == long_format
+#ifdef FLASK_LINUX
+ || format == security || print_sid
+#endif /*FLASK_LINUX*/

     || trace_links || trace_dirs || print_block_size || print_inode;    format_needs_type = (format_needs_stat == 0

                        && (print_with_color || indicator_style != none)); @@ -995,6 +1046,13 @@

   /* Record whether there is an option specifying sort type. */    int sort_type_specified = 0;  

+#ifdef FLASK_LINUX
+ int is_flask_enabled_flag; /* 1 iff kernel has new flask system calls */
+
+ /* Set `is_flask_enabled_flag iff the kernel has new flask system calls. */
+ is_flask_enabled_flag = is_flask_enabled();
+#endif
+

   qmark_funny_chars = 0;  

   /* initialize all switches to default settings */ @@ -1046,6 +1104,10 @@

   all_files = 0;
   really_all_files = 0;
   ignore_patterns = 0;
+#ifdef FLASK_LINUX
+ print_sid = 0;
+ print_scontext = 0;
+#endif /*FLASK_LINUX*/
 

   /* FIXME: Shouldn't we complain on wrong values? */    if ((p = getenv ("QUOTING_STYLE"))
@@ -1362,6 +1424,72 @@  

         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);  

+#ifdef FLASK_LINUX
+ case 18: /* sid */
+ /* If our kernel is not flask-enabled, decline politely. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --lsid can be used only "
+ "on a flask-enabled kernel.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ /* We are on a flask-enabled kernel. Continue processing. */
+ print_sid = 1;
+ format = long_format;
+ break;
+
+ case 19: /* security context */
+ /* If our kernel is not flask-enabled, decline politely. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --context can be used only "
+ "on a flask-enabled kernel.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ /* We are on a flask-enabled kernel. Continue processing. */
+ print_scontext = 1;
+ format = security;
+ break;
+
+ case 20: /* long-format security context */
+ /* If our kernel is not flask-enabled, decline politely. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --lcontext can be used only "
+ "on a flask-enabled kernel.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ /* We are on a flask-enabled kernel. Continue processing. */
+ print_scontext = 1;
+ format = long_format;
+ break;
+
+ case 21: /* short-format SID (like inode) */
+ /* If our kernel is not flask-enabled, decline politely. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --sid can be used only "
+ "on a flask-enabled kernel.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ /* We are on a flask-enabled kernel. Continue processing. */
+ print_sid = 1;
+ break;
+
+ case 22: /* short-format security context */
+ /* If our kernel is not flask-enabled, decline politely. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --scontext can be used only "
+ "on a flask-enabled kernel.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ /* We are on a flask-enabled kernel. Continue processing. */
+ print_scontext = 0;
+ format = security;
+ break;
+#endif /*FLASK_LINUX*/
+

 	default:
 	  usage (EXIT_FAILURE);
 	}
@@ -1943,8 +2071,18 @@
 	}
 
       val = (trace_links
-	     ? stat (path, &files[files_index].stat)
-	     : lstat (path, &files[files_index].stat));

+ ?
+#ifdef FLASK_LINUX
+ stat_secure (path, &files[files_index].stat, &files[files_index].sid)
+#else /*FLASK_LINUX*/
+ stat (path, &files[files_index].stat)
+#endif /*FLASK_LINUX*/
+ :
+#ifdef FLASK_LINUX
+ lstat_secure (path, &files[files_index].stat, &files[files_index].sid));
+#else /*FLASK_LINUX*/
+ lstat (path, &files[files_index].stat));
+#endif /*FLASK_LINUX*/
 
       if (val < 0)
 	{
@@ -2379,6 +2517,16 @@
 	  DIRED_PUTCHAR ('\n');
 	}
       break;

+
+#ifdef FLASK_LINUX
+ case security:
+ for (i = 0; i < files_index; i++)
+ {
+ print_scontext_format (files + i);
+ DIRED_PUTCHAR ('\n');
+ }
+ break;
+#endif /*FLASK_LINUX*/

     }
 }  

@@ -2622,6 +2770,41 @@

       p += strlen (p);
     }
 

+#ifdef FLASK_LINUX
+
+ if ( print_sid ) {
+ sprintf (p, " %3u ", (unsigned int) f->sid);
+ p += strlen(p);
+ }
+
+ if ( print_scontext ) {
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext == NULL ) {
+ scontext = generic_error_string;
+ }
+ else if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
+ if ( errno == ENOSPC ) {
+ free(scontext);
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext == NULL ) {
+ free(scontext);
+ scontext = generic_error_string; /* punt */
+ }
+ else if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
+ (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+ else {
+ (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+ sprintf (p, "%-32s ", scontext);
+ p += strlen (p);
+ }
+#endif /*FLASK_LINUX*/
+

   DIRED_INDENT ();
   DIRED_FPUTS (buf, stdout, p - buf);
   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
@@ -2846,6 +3029,12 @@
     printf ("%*s ", INODE_DIGITS,
 	    human_readable ((uintmax_t) f->stat.st_ino, buf, 1, 1));
 

+#ifdef FLASK_LINUX
+ if (print_sid)
+ printf ("%*s ", SID_DIGITS,
+ human_readable ((uintmax_t) f->sid, buf, 1, 1));
+#endif /*FLASK_LINUX*/
+

   if (print_block_size)

     printf ("%*s ", block_size_size,
 	    human_readable_inexact ((uintmax_t) ST_NBLOCKS (f->stat), buf,
@@ -2969,6 +3158,11 @@

   if (print_inode)
     len += INODE_DIGITS + 1;  

+#ifdef FLASK_LINUX
+ if (print_sid)
+ len += SID_DIGITS + 1;
+#endif /*FLASK_LINUX*/
+

   if (print_block_size)
     len += 1 + block_size_size;  

@@ -3348,8 +3542,21 @@
   -X                         sort alphabetically by entry extension\n\
   -1                         list one file per line\n\
       --help                 display this help and exit\n\
-      --version              output version information and exit\n\
-\n\

+ --version output version information and exit\n"));
+#ifdef FLASK_LINUX
+ printf(_("\n\n\
+FLASK options:\n\n\
+ --lsid Display Security ID (SID). Enable -l\n\
+ --sid Display SID.\n\
+ --lcontext Display security context. Enable -l. Lines\n\
+ will probably be too wide for most displays.\n\
+ --context Display security context so it fits on most\n\
+ displays. Displays only mode, user, group,\n\
+ security context and file name.\n\
+ --scontext Display only security context and file name.\n\
+"));
+#endif /*FLASK_LINUX*/
+printf(_("\n\

 By default, color is not used to distinguish types of files. That is\n\  equivalent to using --color=none. Using the --color option without the\n\  optional WHEN argument is equivalent to using --color=always. With\n\ @@ -3360,3 +3567,107 @@

     }
   exit (status);
 }
+
+#ifdef FLASK_LINUX
+
+static void
+print_scontext_format (const struct fileinfo *f)
+{
+ char modebuf[11];
+
+ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes,
+ 1 10-byte mode string,
+ 8 spaces, one following each of these fields, and
+ 1 trailing NUL byte. */
+
+ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 8 + 1];
+ char *buf = init_bigbuf;
+ size_t bufsize = sizeof (init_bigbuf);
+ size_t s;
+ char *p;
+ const char *fmt;
+ char *user_name;
+ char *group_name;
+ int rv;
+
+ p = buf;
+
+ if ( print_scontext ) { /* zero means terse listing */
+ mode_string (f->stat.st_mode, modebuf);
+ modebuf[10] = '\0';
+
+ /* print mode */
+
+ (void) sprintf (p, "%s ", modebuf);
+ p += strlen (p);
+
+ /* print standard user and group */
+
+ user_name = (numeric_ids ? NULL : getuser (f->stat.st_uid));
+ if (user_name)
+ (void) sprintf (p, "%-8.8s ", user_name);
+ else
+ (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_uid);
+ p += strlen (p);
+
+ if ( ! inhibit_group ) {
+ group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid));
+ if (group_name)
+ (void) sprintf (p, "%-8.8s ", group_name);
+ else
+ (void) sprintf (p, "%-8u ", (unsigned int) f->stat.st_gid);
+ p += strlen (p);
+ }
+ }
+
+ if ( print_sid ) {
+ sprintf (p, " %3u ", (unsigned int) f->sid);
+ p += strlen(p);
+ }
+
+ /* print security context */
+
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext == NULL ) {
+ scontext = generic_error_string;
+ }
+ else if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
+ if ( errno == ENOSPC ) {
+ free(scontext);
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext == NULL ) {
+ free(scontext);
+ scontext = generic_error_string; /* punt */
+ }
+ else if ( security_sid_to_context(f->sid, scontext, &ctxtlen) ) {
+ (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+ else {
+ (void) fprintf(stderr, "security_sid_to_context(%d): %s\n", f->sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+
+ (void) sprintf (p, "%-32s ", scontext);
+ p += strlen (p);
+
+ DIRED_INDENT ();
+ DIRED_FPUTS (buf, stdout, p - buf);
+ print_name_with_quoting (f->name, f->stat.st_mode, f->linkok, &dired_obstack);
+
+ if (f->filetype == symbolic_link) {
+ if (f->linkname) {
+ DIRED_FPUTS_LITERAL (" -> ", stdout);
+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, NULL);
+ if (indicator_style != none)
+ print_type_indicator (f->linkmode);
+ }
+ }
+ else {
+ if (indicator_style != none)
+ print_type_indicator (f->stat.st_mode);
+ }
+}
+#endif /*FLASK_LINUX*/

diff -Nur fileutils-4.1/src/mkdir.c fileutils-4.1-selinux/src/mkdir.c

--- fileutils-4.1/src/mkdir.c	Wed Feb 21 01:05:00 2001

+++ fileutils-4.1-selinux/src/mkdir.c Sun Dec 9 17:51:27 2001
@@ -36,6 +36,15 @@  

 void strip_trailing_slashes ();  

+#ifdef FLASK_LINUX
+#include <fs_secure.h>
+#include <flask_util.h> /* for is_flask_enabled() */
+#define CTXTLEN 256
+char *scontext = NULL;
+int ctxtlen = CTXTLEN;
+char *calloc();
+#endif /*FLASK_LINUX*/
+

 /* The name this program was run with. */  char *program_name;  

@@ -44,6 +53,10 @@  

 static struct option const longopts[] =  {
+#ifdef FLASK_LINUX
+ {"sid", required_argument, NULL, 's'},
+ {"context", required_argument, NULL, 'c'},
+#endif /*FLASK_LINUX*/

   {"mode", required_argument, NULL, 'm'},
   {"parents", no_argument, NULL, 'p'},
   {"verbose", no_argument, NULL, 'v'},

@@ -61,15 +74,27 @@

   else

     {
       printf (_("Usage: %s [OPTION] DIRECTORY...\n"), program_name);

+#ifdef FLASK_LINUX
printf (_("\

 Create the DIRECTORY(ies), if they do not already exist.\n\  \n\
+ -s, --sid=SID (Flask) set security ID to SID\n\
+ -c, --context=CONTEXT (Flask) set security context to CONTEXT\n\
   -m, --mode=MODE   set permission mode (as in chmod), not rwxrwxrwx - umask\n\
-  -p, --parents     no error if existing, make parent directories as needed\n\
-  -v, --verbose     print a message for each created directory\n\

+ -p, --parents no error if existing, make parent directories as needed\n\ --verbose print a message for each created directory\n\
--help display this help and exit\n\ --version output version information and exit\n\
 "));
+#else /*FLASK_LINUX*/
+ printf (_("\
+Create the DIRECTORY(ies), if they do not already exist.\n\
+\n\
+ -m, --mode=MODE set permission mode (as in chmod), not rwxrwxrwx - umask\n\
+ -p, --parents no error if existing, make parent directories as needed\n\+ --verbose print a message for each created directory\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
+"));
+#endif /*FLASK_LINUX*/
       puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
     }

   exit (status);
@@ -78,12 +103,21 @@
 int
 main (int argc, char **argv)
 {
+#ifdef FLASK_LINUX
+ security_id_t sid = -1;
+ char *scontext = NULL;
+ int rv;
+#endif /*FLASK_LINUX*/

   mode_t newmode;
   mode_t parent_mode;
   const char *specified_mode = NULL;
   const char *verbose_fmt_string = NULL;    int errors = 0;
   int optc;
+ int is_flask_enabled_flag; /* set iff kernel has extra flask system calls */
+
+ /* Set `is_flask_enabled_flag' iff the kernel has the extra flask syscalls */
+ is_flask_enabled_flag = is_flask_enabled();
 

   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -94,7 +128,11 @@  

   create_parents = 0;  

+#ifdef FLASK_LINUX
+ while ((optc = getopt_long (argc, argv, "pm:vs:c:", longopts, NULL)) != -1)
+#else /*FLASK_LINUX*/

   while ((optc = getopt_long (argc, argv, "pm:v", longopts, NULL)) != -1)
+#endif /*FLASK_LINUX*/

     {
       switch (optc)
 	{
@@ -111,6 +149,66 @@
 	  break;
 	case_GETOPT_HELP_CHAR;
 	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);

+#ifdef FLASK_LINUX
+ case 's':
+ /* politely decline if we're not on a flask-enabled kernel. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --sid (-s) can be used only on "
+ "a flask-enabled kernel.\n" );
+ exit( 1 );
+ }
+ if ( ((int) sid > 0) || (scontext != NULL) ) {
+ (void) fprintf(stderr, "%s: --sid (-s) and --context (-c) are mutually exclusive\n", argv[0]);
+ exit( 1 );
+ }
+ {
+ /* check for typos */
+ char *ep;
+ sid = (security_id_t) strtol(optarg, &ep, 10);
+ if ( *ep ) {
+ (void) fprintf(stderr, "%s: non-numeric SID '%s'\n", argv[0], optarg);
+ exit( 1 );
+ }
+ }
+ /* do sanity check, save result on success */
+ scontext = calloc(1, ctxtlen+1);
+ if ( scontext != NULL ) {
+ if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
+ if ( errno != ENOSPC ) {
+ (void) fprintf(stderr, "%s: security_sid_to_context(%d): '%s'\n", argv[0], (int) sid, strerror(errno));
+ exit( 1 );
+ }
+ free(scontext);
+ scontext = calloc(1, ctxtlen+1);
+ /* nonfatal, so if there's an error we punt */
+ if ( scontext != NULL )
+ if ( security_sid_to_context(sid, scontext, &ctxtlen) ) {
+ (void) fprintf(stderr, "%s: security_sid_to_context(%d): %s\n", argv[0], (int) sid, strerror(errno));
+ exit( 1 );
+ }
+ }
+ }
+ break;
+ case 'c':
+ /* politely decline if we're not on a flask-enabled kernel. */
+ if( !is_flask_enabled_flag ) {
+ fprintf( stderr, "Sorry, --context (-c) can be used only on "
+ "a flask-enabled kernel.\n" );
+ exit( 1 );
+ }
+ if ( ((int) sid >= 0) || (scontext != NULL) ) {
+ (void) fprintf(stderr, "%s: --context (-c) and --sid (-s) are mutually exclusive\n", argv[0]);
+ exit( 1 );
+ }
+ scontext = optarg;
+ /* sanity check */
+ rv = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
+ if ( rv ) {
+ (void) fprintf(stderr, "%s: security_context_to_sid(%s): %s\n", argv[0], scontext, strerror(errno));
+ exit( 1 );
+ }
+ break;
+#endif /*FLASK_LINUX*/
default: usage (1); } @@ -153,8 +251,30 @@ if (create_parents) { char *parents = dir_name (argv[optind]); - fail = make_path (parents, parent_mode, parent_mode, - -1, -1, 1, verbose_fmt_string);
+#ifdef FLASK_LINUX
+ /* `sid' will be > 0 iff the --sid (-s) option was specified
+ * on the command line. The --sid argument processing code
+ * exits politely if the kernel doesn't support the new
+ * flask system calls. So, if sid > 0 at this point, we
+ * know we're on a flask-enabled kernel.
+ *
+ * make_path_s() calls make_path(), passing `sid' to it via
+ * a global variable `Sid' made specially for that purpose.
+ * The flask-specific code in make_path() calls
+ * flask-specific system calls only if `sid' (aka `Sid') is
+ * > 0.
+ *
+ * Put these two facts together, and we know that make_path_s()
+ * will make flask-specific system calls only if we are on a
+ * flask-enabled kernel. Consequently, it's safe to call
+ * make_path_s() whether or not we're on a flask-enabled kernel.
+ */
+ fail = make_path_s (argv[optind], newmode, parent_mode,
+ -1, -1, 1, verbose_fmt_string, sid);
+#else /*FLASK_LINUX*/
+ fail = make_path (argv[optind], newmode, parent_mode,