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@@ -37,6 +37,9 @@
+++ fileutils-4.1-selinux/config.h.in Sun Dec 9 17:48:33 2001
+/* 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@@ -7,6 +7,18 @@
+++ fileutils-4.1-selinux/configure.in Sun Dec 9 17:46:33 2001
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@@ -94,6 +94,10 @@
+++ fileutils-4.1-selinux/lib/makepath.c Sun Dec 9 17:49:07 2001
+#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 @@
} \
+
+#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@@ -0,0 +1,336 @@
+++ fileutils-4.1-selinux/src/chcon.c Sun Dec 9 17:49:29 2001
--- fileutils-4.1/src/copy.c Sun Dec 9 17:38:51 2001@@ -37,6 +37,11 @@
+++ fileutils-4.1-selinux/src/copy.c Sun Dec 9 17:50:37 2001
+#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;
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))
{
if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
{
error (0, errno, _("cannot create fifo %s"), quote (dst_path));
@@ -1011,7 +1050,16 @@
)
{
- 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*/
{
error (0, errno, _("cannot create special file %s"),
quote (dst_path));
}
+#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;
}
}
}
+#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;
}
}
return delayed_fail;
@@ -1163,6 +1259,14 @@
quote_n (0, dst_backup), quote_n (1, dst_path));
}
}
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@@ -89,6 +89,9 @@
+++ fileutils-4.1-selinux/src/copy.h Sun Dec 9 17:52:01 2001
int preserve_owner_and_group; int preserve_chmod_bits; int preserve_timestamps;
/* 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));-
--- fileutils-4.1/src/cp.c Sat Feb 3 08:48:34 2001@@ -52,6 +52,16 @@
+++ fileutils-4.1-selinux/src/cp.c Sun Dec 9 17:50:40 2001
#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},
{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 @@
printf (_("\
-The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
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 ();
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] = '/';
}
char *src; /* Source name in `dirpath'. */ char *tmp_dst_dirname; /* Leading path of `dirpath', malloc. */ char *dst_dirname; /* Leading path of `dirpath', alloca. */
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, ©_into_self, NULL);
+#ifdef FLASK_LINUX
+ if ( (int) sid > 0 )
+ ret |= copy_s (arg, dst_path, new_dst, x, ©_into_self, NULL, sid);
+ else
+#endif /*FLASK_LINUX*/
+ ret |= copy (arg, dst_path, new_dst, x, ©_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;
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;
case 'P':
used_P_option = 1;
@@ -859,8 +1036,8 @@
{
error (0, 0,
_("\
}
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;
}
/* 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@@ -41,6 +41,10 @@
+++ fileutils-4.1-selinux/src/df.c Sun Dec 9 17:50:56 2001
#include "path-concat.h" #include "quote.h" #include "save-cwd.h"+#include <flask_util.h>
+#ifdef FLASK_LINUX
+#include <fs_secure.h>
/* 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'},
{"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 @@
+#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;
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");
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, ©_into_self, NULL, sid);
+#else
fail = copy (from, to, nonexistent_dst, x, ©_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@@ -133,6 +133,25 @@
+++ fileutils-4.1-selinux/src/ls.c Sun Dec 9 17:51:19 2001
#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;
};
#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};
static enum format format;
@@ -705,19 +738,34 @@
{"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{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;
}
}
@@ -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\
+"));
}
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@@ -36,6 +36,15 @@
+++ fileutils-4.1-selinux/src/mkdir.c Sun Dec 9 17:51:27 2001
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'},
else
{
printf (_("Usage: %s [OPTION] DIRECTORY...\n"), program_name);
+#ifdef FLASK_LINUX
printf (_("\
-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\
puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
}
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,