findutils/findutils-selinux.patch

472 lines
14 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- findutils-4.2.15/find/util.c.selinux 2005-01-23 18:04:45.000000000 +0000
+++ findutils-4.2.15/find/util.c 2005-01-31 13:57:16.155474378 +0000
@@ -70,6 +70,9 @@
last_pred->need_stat = true;
last_pred->need_type = true;
last_pred->args.str = NULL;
+#ifdef WITH_SELINUX
+ last_pred->args.scontext = NULL;
+#endif
last_pred->pred_next = NULL;
last_pred->pred_left = NULL;
last_pred->pred_right = NULL;
--- findutils-4.2.15/find/find.c.selinux 2005-01-25 00:30:40.000000000 +0000
+++ findutils-4.2.15/find/find.c 2005-01-31 14:02:01.060964738 +0000
@@ -217,6 +217,93 @@
{
return lstat(name, p);
}
+#ifdef WITH_SELINUX
+
+static int
+fallback_getfilecon(const char *name, security_context_t *p, int prev_rv)
+{
+ /* Our original getfilecon() call failed. Perhaps we can't follow a
+ * symbolic link. If that might be the problem, lgetfilecon() the link.
+ * Otherwise, admit defeat.
+ */
+ switch (errno)
+ {
+ case ENOENT:
+ case ENOTDIR:
+#ifdef DEBUG_STAT
+ fprintf(stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling back on lgetfilecon()\n", name);
+#endif
+ return lgetfilecon(name, p);
+
+ case EACCES:
+ case EIO:
+ case ELOOP:
+ case ENAMETOOLONG:
+#ifdef EOVERFLOW
+ case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
+#endif
+ default:
+ return prev_rv;
+ }
+}
+
+
+/* optionh_getfilecon() implements the getfilecon operation when the
+ * -H option is in effect.
+ *
+ * If the item to be examined is a command-line argument, we follow
+ * symbolic links. If the getfilecon() call fails on the command-line
+ * item, we fall back on the properties of the symbolic link.
+ *
+ * If the item to be examined is not a command-line argument, we
+ * examine the link itself.
+ */
+int
+optionh_getfilecon(const char *name, security_context_t *p)
+{
+ if (0 == state.curdepth)
+ {
+ /* This file is from the command line; deference the link (if it
+ * is a link).
+ */
+ int rv = getfilecon(name, p);
+ if (0 == rv)
+ return 0; /* success */
+ else
+ return fallback_getfilecon(name, p, rv);
+ }
+ else
+ {
+ /* Not a file on the command line; do not derefernce the link.
+ */
+ return lgetfilecon(name, p);
+ }
+}
+
+/* optionl_getfilecon() implements the getfilecon operation when the
+ * -L option is in effect. That option makes us examine the thing the
+ * symbolic link points to, not the symbolic link itself.
+ */
+int
+optionl_getfilecon(const char *name, security_context_t *p)
+{
+ int rv = getfilecon(name, p);
+ if (0 == rv)
+ return 0; /* normal case. */
+ else
+ return fallback_getfilecon(name, p, rv);
+}
+
+/* optionp_getfilecon() implements the stat operation when the -P
+ * option is in effect (this is also the default). That option makes
+ * us examine the symbolic link itself, not the thing it points to.
+ */
+int
+optionp_getfilecon(const char *name, security_context_t *p)
+{
+ return lgetfilecon(name, p);
+}
+#endif /* WITH_SELINUX */
#ifdef DEBUG_STAT
static uintmax_t stat_count = 0u;
@@ -245,11 +332,17 @@
{
case SYMLINK_ALWAYS_DEREF: /* -L */
options.xstat = optionl_stat;
+#ifdef WITH_SELINUX
+ options.x_getfilecon = optionl_getfilecon;
+#endif /* WITH_SELINUX */
options.no_leaf_check = true;
break;
case SYMLINK_NEVER_DEREF: /* -P (default) */
options.xstat = optionp_stat;
+#ifdef WITH_SELINUX
+ options.x_getfilecon = optionp_getfilecon;
+#endif /* WITH_SELINUX */
/* Can't turn no_leaf_check off because the user might have specified
* -noleaf anyway
*/
@@ -257,6 +350,9 @@
case SYMLINK_DEREF_ARGSONLY: /* -H */
options.xstat = optionh_stat;
+#ifdef WITH_SELINUX
+ options.x_getfilecon = optionh_getfilecon;
+#endif /* WITH_SELINUX */
options.no_leaf_check = true;
}
@@ -330,6 +426,9 @@
int
main (int argc, char **argv)
{
+#ifdef WITH_SELINUX
+ int is_selinux_enabled_flag = is_selinux_enabled()>0;
+#endif /* WITH_SELINUX */
int i;
PFB parse_function; /* Pointer to the function which parses. */
struct predicate *cur_pred;
@@ -447,6 +546,14 @@
if (strchr ("-!(),", argv[i][0]) == NULL)
usage (_("paths must precede expression"));
predicate_name = argv[i];
+#ifdef WITH_SELINUX
+ if (! is_selinux_enabled_flag) {
+ if ((strncmp(predicate_name,"-context",strlen("-context"))==0) ||
+ (strncmp(predicate_name,"--context",strlen("--context"))==0)) {
+ error (1, 0,_("Error: invalid predicate %s: the kernel is not selinux-enabled.\n"),predicate_name);
+ }
+ }
+#endif
parse_function = find_parser (predicate_name);
if (parse_function == NULL)
/* Command line option not recognized */
--- findutils-4.2.15/find/find.1.selinux 2005-01-23 18:29:25.000000000 +0000
+++ findutils-4.2.15/find/find.1 2005-01-31 13:57:16.233459455 +0000
@@ -433,6 +433,9 @@
link to a file of type \fIc\fR; if the \-L option has been given, true
if \fIc\fR is `l'. In other words, for symbolic links, \-xtype checks
the type of the file that \-type does not check.
+.IP "\-context \fIscontext\fR"
+.IP "\--context \fIscontext\fR"
+(SELinux only) File has the security context \fIscontext\fR.
.SS ACTIONS
.IP "\-delete\fR"
@@ -703,6 +706,8 @@
File's type (like in ls \-l), U=unknown type (shouldn't happen)
.IP %Y
File's type (like %y), plus follow symlinks: L=loop, N=nonexistent
+.IP %Z
+(SELinux only) file's security context.
.PP
A `%' character followed by any other character is discarded (but the
other character is printed).
--- findutils-4.2.15/find/Makefile.in.selinux 2005-01-29 00:50:23.000000000 +0000
+++ findutils-4.2.15/find/Makefile.in 2005-01-31 13:58:31.031147041 +0000
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -174,7 +174,7 @@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
+DEFS = @DEFS@ -I. -I$(srcdir) -I.. -DWITH_SELINUX
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -266,7 +266,7 @@
localedir = $(datadir)/locale
find_SOURCES = find.c fstype.c parser.c pred.c tree.c util.c version.c
EXTRA_DIST = defs.h $(man_MANS)
-LDADD = ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@
+LDADD = ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ -lselinux
man_MANS = find.1
SUBDIRS = testsuite
all: all-recursive
@@ -282,9 +282,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits find/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu find/Makefile'; \
cd $(top_srcdir) && \
- $(AUTOMAKE) --gnits find/Makefile
+ $(AUTOMAKE) --gnu find/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -334,8 +334,7 @@
f=`echo "$$p" | \
sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
for opt in --help --version; do \
- if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
- 2>c$${pid}_.err </dev/null \
+ if "$(DESTDIR)$(bindir)/$$f" $$opt > c$${pid}_.out 2> c$${pid}_.err \
&& test -n "`cat c$${pid}_.out`" \
&& test -z "`cat c$${pid}_.err`"; then :; \
else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
--- findutils-4.2.15/find/defs.h.selinux 2005-01-25 00:30:40.000000000 +0000
+++ findutils-4.2.15/find/defs.h 2005-01-31 13:57:16.244457351 +0000
@@ -130,6 +130,10 @@
#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif /*WITH_SELINUX*/
+
#if 1
#include <stdbool.h>
typedef bool boolean;
@@ -314,6 +318,9 @@
struct dir_id fileid; /* samefile */
mode_t type; /* type */
FILE *stream; /* fprint fprint0 */
+#ifdef WITH_SELINUX
+ security_context_t scontext; /* scontext */
+#endif /*WITH_SELINUX*/
struct format_val printf_vec; /* printf fprintf */
} args;
@@ -444,6 +451,9 @@
boolean pred_used PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
boolean pred_user PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
boolean pred_xtype PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
+#ifdef WITH_SELINUX
+boolean pred_scontext PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
+#endif /* WITH_SELINUX */
int launch PARAMS((const struct buildcmd_control *ctl,
struct buildcmd_state *buildstate));
@@ -518,6 +528,9 @@
/* Pointer to the function used to stat files. */
int (*xstat) (const char *name, struct stat *statbuf);
+#ifdef WITH_SELINUX
+ int (*x_getfilecon) ();
+#endif /* WITH_SELINUX */
};
extern struct options options;
--- findutils-4.2.15/find/Makefile.am.selinux 2004-11-21 13:37:47.000000000 +0000
+++ findutils-4.2.15/find/Makefile.am 2005-01-31 13:57:16.245457159 +0000
@@ -3,8 +3,9 @@
bin_PROGRAMS = find
find_SOURCES = find.c fstype.c parser.c pred.c tree.c util.c version.c
EXTRA_DIST = defs.h $(man_MANS)
+DEFS = @DEFS@ -I. -I$(srcdir) -I.. -DWITH_SELINUX
INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
-LDADD = ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@
+LDADD = ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ -lselinux
man_MANS = find.1
SUBDIRS = testsuite
--- findutils-4.2.15/find/parser.c.selinux 2005-01-31 13:57:16.145476291 +0000
+++ findutils-4.2.15/find/parser.c 2005-01-31 13:57:16.251456012 +0000
@@ -31,6 +31,10 @@
#include "nextelem.h"
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif /*WITH_SELINUX*/
+
#if ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
@@ -134,6 +138,9 @@
static boolean parse_warn PARAMS((char *argv[], int *arg_ptr));
static boolean parse_xtype PARAMS((char *argv[], int *arg_ptr));
static boolean parse_quit PARAMS((char *argv[], int *arg_ptr));
+#ifdef WITH_SELINUX
+static boolean parse_scontext PARAMS((char *argv[], int *arg_ptr));
+#endif /*WITH_SELINUX*/
static boolean insert_regex PARAMS((char *argv[], int *arg_ptr, boolean ignore_case));
static boolean insert_type PARAMS((char *argv[], int *arg_ptr, boolean (*which_pred )()));
@@ -261,6 +268,8 @@
{ARG_TEST, "wholename", parse_wholename}, /* GNU, replaces -path */
{ARG_OPTION, "xdev", parse_xdev},
{ARG_TEST, "xtype", parse_xtype}, /* GNU */
+ {ARG_TEST, "context", parse_scontext}, /* SELinux */
+ {ARG_TEST, "-context", parse_scontext}, /* SELinux */
{0, 0, 0}
};
@@ -739,6 +748,10 @@
-nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
-used N -user NAME -xtype [bcdpfls]\n"));
+#ifdef WITH_SELINUX
+ puts (_("\
+ -context CONTEXT\n"));
+#endif /*WITH_SELINUX*/
puts (_("\
actions: -exec COMMAND ; -fprint FILE -fprint0 FILE -fprintf FILE FORMAT\n\
-fls FILE -ok COMMAND ; -print -print0 -printf FORMAT -prune -ls -delete\n\
@@ -1591,6 +1604,32 @@
return true;
}
+#ifdef WITH_SELINUX
+
+static boolean
+parse_scontext ( argv, arg_ptr )
+ char *argv[];
+ int *arg_ptr;
+{
+ struct predicate *our_pred;
+
+ if ( (argv == NULL) || (argv[*arg_ptr] == NULL) )
+ return( false );
+
+ our_pred = insert_primary(pred_scontext);
+ our_pred->need_stat = 0;
+#ifdef DEBUG
+ our_pred->p_name = find_pred_name (pred_scontext);
+#endif /*DEBUG*/
+
+ our_pred->args.scontext = argv[*arg_ptr];;
+
+ (*arg_ptr)++;
+ return( true );
+}
+
+#endif /*WITH_SELINUX*/
+
static boolean
parse_xtype (char **argv, int *arg_ptr)
{
@@ -1766,7 +1805,11 @@
if (*scan2 == '.')
for (scan2++; ISDIGIT (*scan2); scan2++)
/* Do nothing. */ ;
+#ifdef WITH_SELINUX
+ if (strchr ("abcdDfFgGhHiklmMnpPstuUyYZ", *scan2))
+#else /* WITH_SELINUX */
if (strchr ("abcdDfFgGhHiklmMnpPstuUyY", *scan2))
+#endif /* WITH_SELINUX */
{
segmentp = make_segment (segmentp, format, scan2 - format,
(int) *scan2);
--- findutils-4.2.15/find/pred.c.selinux 2005-01-25 00:30:40.000000000 +0000
+++ findutils-4.2.15/find/pred.c 2005-01-31 14:37:23.724774302 +0000
@@ -35,6 +35,14 @@
#include "wait.h"
#include "buildcmd.h"
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif /*WITH_SELINUX*/
+
+#ifndef FNM_CASEFOLD
+#define FNM_CASEFOLD (1<<4)
+#endif /*FNM_CASEFOLD*/
+
#if ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
@@ -78,7 +86,6 @@
extern int yesno ();
-
/* Get or fake the disk device blocksize.
Usually defined by sys/param.h (if at all). */
#ifndef DEV_BSIZE
@@ -209,6 +216,9 @@
{pred_used, "used "},
{pred_user, "user "},
{pred_xtype, "xtype "},
+#ifdef WITH_SELINUX
+ {pred_scontext, "context"},
+#endif /*WITH_SELINUX*/
{0, "none "}
};
@@ -874,6 +884,26 @@
}
break;
+#ifdef WITH_SELINUX
+ case 'Z': /* SELinux security context */
+ {
+ security_context_t scontext;
+ int rv;
+ rv = (*options.x_getfilecon)(state.rel_pathname, &scontext);
+
+ if ( rv < 0 ) {
+ (void) fprintf(stderr, "getfileconf(%s): %s",
+ pathname, strerror(errno));
+ (void) fflush(stderr);
+ }
+ else {
+ segment->text[segment->text_len] = 's';
+ (void) fprintf (fp, segment->text, scontext);
+ freecon(scontext);
+ }
+ }
+ break ;
+#endif /* WITH_SELINUX */
}
}
return (true);
@@ -1477,6 +1507,34 @@
*/
return (pred_type (pathname, &sbuf, pred_ptr));
}
+
+
+#ifdef WITH_SELINUX
+
+boolean
+pred_scontext ( pathname, stat_buf, pred_ptr )
+ char *pathname;
+ struct stat *stat_buf;
+ struct predicate *pred_ptr;
+{
+ int rv;
+ security_context_t scontext;
+
+ rv = (* options.x_getfilecon)(state.rel_pathname, &scontext);
+
+ if ( rv < 0 ) {
+ (void) fprintf(stderr, "getfilecon(%s): %s\n", pathname, strerror(errno));
+ (void) fflush(stderr);
+ return ( false );
+ }
+
+ rv = (fnmatch(pred_ptr->args.scontext, scontext,0)==0);
+ freecon(scontext);
+ return rv;
+}
+
+#endif /*WITH_SELINUX*/
+
/* 1) fork to get a child; parent remembers the child pid
2) child execs the command requested