diff --git a/findutils-4.4.0.diff b/findutils-4.4.0.diff index 15a4230..206f9f9 100644 --- a/findutils-4.4.0.diff +++ b/findutils-4.4.0.diff @@ -118,3 +118,38 @@ else prunefs_exp='' fi +@@ -252,13 +251,12 @@ if test -n "$SEARCHPATHS"; then + # : A1 + su $LOCALUSER `select_shell $LOCALUSER` -c \ + "$find $SEARCHPATHS $FINDOPTIONS \ +- \\( $prunefs_exp \ +- -type d -regex '$PRUNEREGEX' \\) -prune -o $print_option" ++ -type d \\( $prunefs_exp -regex '$PRUNEREGEX' \\) -prune \ ++ -o $print_option" + else + # : A2 + $find $SEARCHPATHS $FINDOPTIONS \ +- \( $prunefs_exp \ +- -type d -regex "$PRUNEREGEX" \) -prune -o $print_option ++ -type d \( $prunefs_exp -regex "$PRUNEREGEX" \) -prune -o $print_option + fi + fi + +@@ -321,13 +319,13 @@ if test -n "$SEARCHPATHS"; then + # : A5 + su $LOCALUSER `select_shell $LOCALUSER` -c \ + "$find $SEARCHPATHS $FINDOPTIONS \ +- \( $prunefs_exp \ +- -type d -regex '$PRUNEREGEX' \) -prune -o $print_option" || exit $? ++ -type d \( $prunefs_exp -regex '$PRUNEREGEX' \) -prune \ ++ -o $print_option" || exit $? + else + # : A6 + $find $SEARCHPATHS $FINDOPTIONS \ +- \( $prunefs_exp \ +- -type d -regex "$PRUNEREGEX" \) -prune -o $print_option || exit $? ++ -type d \( $prunefs_exp -regex "$PRUNEREGEX" \) -prune \ ++ -o $print_option || exit $? + fi + fi + diff --git a/findutils-4.4.0-selinux.patch b/findutils-selinux.diff similarity index 63% rename from findutils-4.4.0-selinux.patch rename to findutils-selinux.diff index 4fc32ac..e677bf2 100644 --- a/findutils-4.4.0-selinux.patch +++ b/findutils-selinux.diff @@ -1,6 +1,5 @@ -diff -up findutils-4.4.0/configure.ac.selinux findutils-4.4.0/configure.ac ---- findutils-4.4.0/configure.ac.selinux 2008-03-15 12:45:00.000000000 +0100 -+++ findutils-4.4.0/configure.ac 2008-04-25 16:52:54.000000000 +0200 +--- findutils-4.4.0/configure.ac ++++ findutils-4.4.0/configure.ac @@ -114,6 +114,16 @@ AC_CHECK_LIB([m],[fabs],[FINDLIBS="-lm $ AC_DEFINE_UNQUOTED(HAVE_FABS_IN_LIBM,1,[fabs is defined in -lm])) AC_SUBST([FINDLIBS]) @@ -18,18 +17,9 @@ diff -up findutils-4.4.0/configure.ac.selinux findutils-4.4.0/configure.ac dnl Checks for header files. AC_HEADER_STDC dnl Assume unistd.h is present - coreutils does too. -diff -up findutils-4.4.0/doc/find.texi.selinux findutils-4.4.0/doc/find.texi ---- findutils-4.4.0/doc/find.texi.selinux 2008-03-10 21:31:16.000000000 +0100 -+++ findutils-4.4.0/doc/find.texi 2008-04-29 14:57:42.000000000 +0200 -@@ -7,7 +7,6 @@ - @c %**end of header - - @include version.texi --@include ../locate/dblocation.texi - - @iftex - @finalout -@@ -1242,6 +1241,14 @@ situation. +--- findutils-4.4.0/doc/find.texi ++++ findutils-4.4.0/doc/find.texi +@@ -1242,6 +1242,14 @@ situation. @end deffn @@ -44,7 +34,7 @@ diff -up findutils-4.4.0/doc/find.texi.selinux findutils-4.4.0/doc/find.texi @node Contents @section Contents -@@ -1826,6 +1833,9 @@ value used for BLOCKSIZE is system-depen +@@ -1826,6 +1834,9 @@ value used for BLOCKSIZE is system-depen bytes. If the file size is zero, the value printed is undefined. On systems which lack support for st_blocks, a file's sparseness is assumed to be 1.0. @@ -54,188 +44,8 @@ diff -up findutils-4.4.0/doc/find.texi.selinux findutils-4.4.0/doc/find.texi @end table @node Location Directives -diff -up findutils-4.4.0/find/find.c.selinux findutils-4.4.0/find/find.c ---- findutils-4.4.0/find/find.c.selinux 2008-03-10 21:26:34.000000000 +0100 -+++ findutils-4.4.0/find/find.c 2008-04-28 17:19:26.000000000 +0200 -@@ -120,6 +120,36 @@ int get_current_dirfd(void) - return AT_FDCWD; - } - -+#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; -+ } -+} -+#endif /* WITH_SELINUX */ -+ - - int - main (int argc, char **argv) -@@ -1270,7 +1300,7 @@ process_path (char *pathname, char *name - static void - process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent) - { -- int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */ -+ int subdirs_left = 0; /* Number of unexamined subdirs in PATHNAME. */ - boolean subdirs_unreliable; /* if true, cannot use dir link count as subdir limif (if false, it may STILL be unreliable) */ - unsigned int idx; /* Which entry are we on? */ - struct stat stat_buf; -diff -up findutils-4.4.0/find/find.1.selinux findutils-4.4.0/find/find.1 ---- findutils-4.4.0/find/find.1.selinux 2007-12-19 20:53:14.000000000 +0100 -+++ findutils-4.4.0/find/find.1 2008-04-25 16:52:54.000000000 +0200 -@@ -934,6 +934,8 @@ if \fIc\fR is `l'. In other words, for - checks the type of the file that - .B \-type - does not check. -+.IP "\-context \fIpattern\fR" -+(SELinux only) Security context of the file matches glob \fIpattern\fR. - - .SS ACTIONS - .IP "\-delete\fR" -@@ -1340,6 +1342,8 @@ File's type (like in - 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 (don't rely on this, as further format -diff -up findutils-4.4.0/find/pred.c.selinux findutils-4.4.0/find/pred.c ---- findutils-4.4.0/find/pred.c.selinux 2008-03-10 10:37:22.000000000 +0100 -+++ findutils-4.4.0/find/pred.c 2008-04-28 17:09:17.000000000 +0200 -@@ -47,6 +47,10 @@ - #include "error.h" - #include "verify.h" - -+#ifdef WITH_SELINUX -+#include -+#endif /*WITH_SELINUX*/ -+ - #if ENABLE_NLS - # include - # define _(Text) gettext (Text) -@@ -229,6 +233,9 @@ struct pred_assoc pred_table[] = - {pred_user, "user "}, - {pred_writable, "writable "}, - {pred_xtype, "xtype "}, -+#ifdef WITH_SELINUX -+ {pred_context, "context"}, -+#endif /*WITH_SELINUX*/ - {0, "none "} - }; - #endif -@@ -1053,6 +1060,27 @@ do_fprintf(struct format_val *dest, - mode_to_filetype(stat_buf->st_mode & S_IFMT)); - } - break; -+ case 'Z': /* SELinux security context */ -+#ifdef WITH_SELINUX -+ { -+ security_context_t scontext; -+ int rv; -+ rv = (*options.x_getfilecon) (state.rel_pathname, &scontext); -+ -+ if (rv < 0) -+ { -+ fprintf (stderr, "getfilecon(%s): %s", pathname, -+ strerror(errno)); -+ fflush (stderr); -+ } -+ else -+ { -+ checked_fprintf (dest, segment->text, scontext); -+ freecon (scontext); -+ } -+ } -+#endif /* WITH_SELINUX */ -+ break; - } - /* end of KIND_FORMAT case */ - break; -@@ -1841,6 +1869,33 @@ pred_xtype (const char *pathname, struct - */ - return (pred_type (pathname, &sbuf, pred_ptr)); - } -+ -+ -+#ifdef WITH_SELINUX -+ -+boolean -+pred_context (const 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) -+ { -+ fprintf (stderr, "getfilecon(%s): %s\n", pathname, strerror(errno)); -+ 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 -diff -up findutils-4.4.0/find/tree.c.selinux findutils-4.4.0/find/tree.c ---- findutils-4.4.0/find/tree.c.selinux 2007-12-20 22:40:35.000000000 +0100 -+++ findutils-4.4.0/find/tree.c 2008-04-30 11:12:46.000000000 +0200 -@@ -953,7 +953,8 @@ static struct pred_cost_lookup costlooku - { pred_used , NeedsStatInfo }, - { pred_user , NeedsStatInfo }, - { pred_writable , NeedsAccessInfo }, -- { pred_xtype , NeedsType } /* roughly correct unless most files are symlinks */ -+ { pred_xtype , NeedsType }, /* roughly correct unless most files are symlinks */ -+ { pred_context , NeedsNothing } /* remove warning only:) */ - }; - static int pred_table_sorted = 0; - -@@ -1434,6 +1435,9 @@ get_new_pred (const struct parser_table - 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; -diff -up findutils-4.4.0/find/Makefile.am.selinux findutils-4.4.0/find/Makefile.am ---- findutils-4.4.0/find/Makefile.am.selinux 2007-07-22 14:29:31.000000000 +0200 -+++ findutils-4.4.0/find/Makefile.am 2008-04-25 16:52:54.000000000 +0200 +--- findutils-4.4.0/find/Makefile.am ++++ findutils-4.4.0/find/Makefile.am @@ -26,7 +26,7 @@ endif EXTRA_DIST = defs.h $(man_MANS) @@ -245,236 +55,8 @@ diff -up findutils-4.4.0/find/Makefile.am.selinux findutils-4.4.0/find/Makefile. man_MANS = find.1 SUBDIRS = . testsuite -diff -up findutils-4.4.0/find/parser.c.selinux findutils-4.4.0/find/parser.c ---- findutils-4.4.0/find/parser.c.selinux 2008-03-10 10:37:21.000000000 +0100 -+++ findutils-4.4.0/find/parser.c 2008-04-28 15:34:45.000000000 +0200 -@@ -53,6 +53,10 @@ - #include - #include - -+#ifdef WITH_SELINUX -+#include -+#endif -+ - #if ENABLE_NLS - # include - # define _(Text) gettext (Text) -@@ -156,6 +160,9 @@ static boolean parse_noignore_race PARAM - static boolean parse_warn PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - static boolean parse_xtype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - static boolean parse_quit PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); -+#ifdef WITH_SELINUX -+static boolean parse_context PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); -+#endif - - boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - -@@ -252,6 +259,9 @@ static struct parser_table const parse_t - PARSE_TEST ("cmin", cmin), /* GNU */ - PARSE_TEST ("cnewer", cnewer), /* GNU */ - {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */ -+#ifdef WITH_SELINUX -+ PARSE_TEST ("context", context), /* GNU */ -+#endif - PARSE_POSOPT ("daystart", daystart), /* GNU */ - PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */ - PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */ -@@ -348,6 +358,89 @@ static struct parser_table const parse_t - static const char *first_nonoption_arg = NULL; - static const struct parser_table *noop = NULL; - -+#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 */ - - void - check_option_combinations(const struct predicate *p) -@@ -451,11 +544,17 @@ set_follow_state(enum SymlinkOption opt) - { - case SYMLINK_ALWAYS_DEREF: /* -L */ - options.xstat = optionl_stat; -+#ifdef WITH_SELINUX -+ options.x_getfilecon = optionl_getfilecon; -+#endif - 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 - /* Can't turn no_leaf_check off because the user might have specified - * -noleaf anyway - */ -@@ -463,6 +562,9 @@ set_follow_state(enum SymlinkOption opt) - - case SYMLINK_DEREF_ARGSONLY: /* -H */ - options.xstat = optionh_stat; -+#ifdef WITH_SELINUX -+ options.x_getfilecon = optionh_getfilecon; -+#endif - options.no_leaf_check = true; - } - } -@@ -1128,8 +1230,12 @@ tests (N can be +N or -N or N): -amin N - -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\ - -readable -writable -executable\n\ - -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\ -- -used N -user NAME -xtype [bcdpfls]\n")); -+ -used N -user NAME -xtype [bcdpfls]")); -+#ifdef WITH_SELINUX - puts (_("\ -+ -context CONTEXT\n")); -+#endif -+ puts (_("\n\ - actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\ - -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\ - -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\ -@@ -2492,6 +2598,10 @@ parse_version (const struct parser_table - printf("LEAF_OPTIMISATION "); - ++features; - #endif -+#if defined(WITH_SELINUX) -+ printf("SELINUX "); -+ ++features; -+#endif - - flags = 0; - if (is_fts_enabled(&flags)) -@@ -2526,6 +2636,32 @@ parse_version (const struct parser_table - exit (0); - } - -+#ifdef WITH_SELINUX -+static boolean -+parse_context (const struct parser_table* entry, char **argv, int *arg_ptr) -+{ -+ struct predicate *our_pred; -+ -+ if ((argv == NULL) || (argv[*arg_ptr] == NULL)) -+ return false; -+ -+ if (is_selinux_enabled() <= 0) -+ { -+ error (1, 0, _("invalid predicate -context: SELinux is not enabled.")); -+ return false; -+ } -+ our_pred = insert_primary (entry); -+ our_pred->need_stat = false; -+#ifdef DEBUG -+ our_pred->p_name = find_pred_name (pred_context); -+#endif /*DEBUG*/ -+ our_pred->args.scontext = argv[*arg_ptr]; -+ -+ (*arg_ptr)++; -+ return true; -+} -+#endif /* WITH_SELINUX */ -+ - static boolean - parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr) - { -@@ -2777,7 +2913,7 @@ insert_fprintf (struct format_val *vec, - if (*scan2 == '.') - for (scan2++; ISDIGIT (*scan2); scan2++) - /* Do nothing. */ ; -- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2)) -+ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2)) - { - segmentp = make_segment (segmentp, format, scan2 - format, - KIND_FORMAT, *scan2, 0, -@@ -2904,6 +3040,7 @@ make_segment (struct segment **segment, - case 'h': /* leading directories part of path */ - case 'p': /* pathname */ - case 'P': /* pathname with ARGV element stripped */ -+ case 'Z': /* SELinux security context */ - *fmt++ = 's'; - break; - -diff -up findutils-4.4.0/find/defs.h.selinux findutils-4.4.0/find/defs.h ---- findutils-4.4.0/find/defs.h.selinux 2008-03-10 10:37:21.000000000 +0100 -+++ findutils-4.4.0/find/defs.h 2008-04-25 16:52:54.000000000 +0200 +--- findutils-4.4.0/find/defs.h ++++ findutils-4.4.0/find/defs.h @@ -91,6 +91,9 @@ int get_statinfo PARAMS((const char *pat #define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW) #define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX) @@ -510,9 +92,395 @@ diff -up findutils-4.4.0/find/defs.h.selinux findutils-4.4.0/find/defs.h int regex_options; +#ifdef WITH_SELINUX -+ int (*x_getfilecon) (); ++ int (*x_getfilecon) (const char *name, security_context_t *context); +#endif + /* Optimisation level. One is the default. */ unsigned short optimisation_level; +--- findutils-4.4.0/find/find.1 ++++ findutils-4.4.0/find/find.1 +@@ -934,6 +934,8 @@ if \fIc\fR is `l'. In other words, for + checks the type of the file that + .B \-type + does not check. ++.IP "\-context \fIpattern\fR" ++(SELinux only) Security context of the file matches glob \fIpattern\fR. + + .SS ACTIONS + .IP "\-delete\fR" +@@ -1340,6 +1342,8 @@ File's type (like in + 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 (don't rely on this, as further format +--- findutils-4.4.0/find/find.c ++++ findutils-4.4.0/find/find.c +@@ -120,6 +120,35 @@ int get_current_dirfd(void) + return AT_FDCWD; + } + ++#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; ++ } ++} ++#endif /* WITH_SELINUX */ ++ + + int + main (int argc, char **argv) +--- findutils-4.4.0/find/parser.c ++++ findutils-4.4.0/find/parser.c +@@ -53,6 +53,10 @@ + #include + #include + ++#ifdef WITH_SELINUX ++#include ++#endif ++ + #if ENABLE_NLS + # include + # define _(Text) gettext (Text) +@@ -156,6 +160,9 @@ static boolean parse_noignore_race PARAM + static boolean parse_warn PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + static boolean parse_xtype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + static boolean parse_quit PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); ++#ifdef WITH_SELINUX ++static boolean parse_context PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); ++#endif + + boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + +@@ -252,6 +259,9 @@ static struct parser_table const parse_t + PARSE_TEST ("cmin", cmin), /* GNU */ + PARSE_TEST ("cnewer", cnewer), /* GNU */ + {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */ ++#ifdef WITH_SELINUX ++ PARSE_TEST ("context", context), /* GNU */ ++#endif + PARSE_POSOPT ("daystart", daystart), /* GNU */ + PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */ + PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */ +@@ -348,6 +358,85 @@ static struct parser_table const parse_t + static const char *first_nonoption_arg = NULL; + static const struct parser_table *noop = NULL; + ++#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 (state.curdepth == 0) ++ { ++ /* 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 (rv == 0) ++ 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 */ + + void + check_option_combinations(const struct predicate *p) +@@ -451,11 +540,17 @@ set_follow_state(enum SymlinkOption opt) + { + case SYMLINK_ALWAYS_DEREF: /* -L */ + options.xstat = optionl_stat; ++#ifdef WITH_SELINUX ++ options.x_getfilecon = optionl_getfilecon; ++#endif + 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 + /* Can't turn no_leaf_check off because the user might have specified + * -noleaf anyway + */ +@@ -463,6 +558,9 @@ set_follow_state(enum SymlinkOption opt) + + case SYMLINK_DEREF_ARGSONLY: /* -H */ + options.xstat = optionh_stat; ++#ifdef WITH_SELINUX ++ options.x_getfilecon = optionh_getfilecon; ++#endif + options.no_leaf_check = true; + } + } +@@ -1124,6 +1222,10 @@ tests (N can be +N or -N or N): -amin N + -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\ + -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\ + -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE")); ++#ifdef WITH_SELINUX ++ puts (_("\ ++ -context CONTEXT")); ++#endif + puts (_("\ + -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\ + -readable -writable -executable\n\ +@@ -2492,6 +2594,10 @@ parse_version (const struct parser_table + printf("LEAF_OPTIMISATION "); + ++features; + #endif ++#if defined (WITH_SELINUX) ++ printf ("SELINUX "); ++ ++features; ++#endif + + flags = 0; + if (is_fts_enabled(&flags)) +@@ -2526,6 +2632,32 @@ parse_version (const struct parser_table + exit (0); + } + ++#ifdef WITH_SELINUX ++static boolean ++parse_context (const struct parser_table* entry, char **argv, int *arg_ptr) ++{ ++ struct predicate *our_pred; ++ ++ if (argv == NULL || argv[*arg_ptr] == NULL) ++ return false; ++ ++ if (is_selinux_enabled () <= 0) ++ { ++ error (1, 0, _("invalid predicate -context: SELinux is not enabled.")); ++ return false; ++ } ++ our_pred = insert_primary (entry); ++ our_pred->need_stat = false; ++#ifdef DEBUG ++ our_pred->p_name = find_pred_name (pred_context); ++#endif /*DEBUG*/ ++ our_pred->args.scontext = argv[*arg_ptr]; ++ ++ (*arg_ptr)++; ++ return true; ++} ++#endif /* WITH_SELINUX */ ++ + static boolean + parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr) + { +@@ -2777,7 +2909,7 @@ insert_fprintf (struct format_val *vec, + if (*scan2 == '.') + for (scan2++; ISDIGIT (*scan2); scan2++) + /* Do nothing. */ ; +- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2)) ++ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2)) + { + segmentp = make_segment (segmentp, format, scan2 - format, + KIND_FORMAT, *scan2, 0, +@@ -2904,6 +3036,7 @@ make_segment (struct segment **segment, + case 'h': /* leading directories part of path */ + case 'p': /* pathname */ + case 'P': /* pathname with ARGV element stripped */ ++ case 'Z': /* SELinux security context */ + *fmt++ = 's'; + break; + +--- findutils-4.4.0/find/pred.c ++++ findutils-4.4.0/find/pred.c +@@ -47,6 +47,10 @@ + #include "error.h" + #include "verify.h" + ++#ifdef WITH_SELINUX ++#include ++#endif /*WITH_SELINUX*/ ++ + #if ENABLE_NLS + # include + # define _(Text) gettext (Text) +@@ -229,6 +233,9 @@ struct pred_assoc pred_table[] = + {pred_user, "user "}, + {pred_writable, "writable "}, + {pred_xtype, "xtype "}, ++#ifdef WITH_SELINUX ++ {pred_context, "context"}, ++#endif /*WITH_SELINUX*/ + {0, "none "} + }; + #endif +@@ -1053,6 +1060,27 @@ do_fprintf(struct format_val *dest, + mode_to_filetype(stat_buf->st_mode & S_IFMT)); + } + break; ++ case 'Z': /* SELinux security context */ ++#ifdef WITH_SELINUX ++ { ++ security_context_t scontext; ++ int rv; ++ rv = options.x_getfilecon (state.rel_pathname, &scontext); ++ ++ if (rv < 0) ++ { ++ fprintf (stderr, "getfilecon(%s): %s", pathname, ++ strerror (errno)); ++ fflush (stderr); ++ } ++ else ++ { ++ checked_fprintf (dest, segment->text, scontext); ++ freecon (scontext); ++ } ++ } ++#endif /* WITH_SELINUX */ ++ break; + } + /* end of KIND_FORMAT case */ + break; +@@ -1841,6 +1869,33 @@ pred_xtype (const char *pathname, struct + */ + return (pred_type (pathname, &sbuf, pred_ptr)); + } ++ ++ ++#ifdef WITH_SELINUX ++ ++boolean ++pred_context (const 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) ++ { ++ fprintf (stderr, "getfilecon(%s): %s\n", pathname, strerror (errno)); ++ 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 +--- findutils-4.4.0/find/tree.c ++++ findutils-4.4.0/find/tree.c +@@ -953,7 +953,10 @@ static struct pred_cost_lookup costlooku + { pred_used , NeedsStatInfo }, + { pred_user , NeedsStatInfo }, + { pred_writable , NeedsAccessInfo }, +- { pred_xtype , NeedsType } /* roughly correct unless most files are symlinks */ ++ { pred_xtype , NeedsType }, /* roughly correct unless most files are symlinks */ ++#ifdef WITH_SELINUX ++ { pred_context , NeedsNothing } /* remove warning only:) */ ++#endif + }; + static int pred_table_sorted = 0; + +@@ -1434,6 +1437,9 @@ get_new_pred (const struct parser_table + 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; diff --git a/findutils.changes b/findutils.changes index 56f5aed..e522e60 100644 --- a/findutils.changes +++ b/findutils.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Sep 1 10:24:34 CEST 2008 - schwab@suse.de + +- Fix last change. +- Optimize find expressions in updatedb. + ------------------------------------------------------------------- Mon Aug 25 14:44:40 CEST 2008 - prusnak@suse.cz diff --git a/findutils.spec b/findutils.spec index bef6c8c..8001c6f 100644 --- a/findutils.spec +++ b/findutils.spec @@ -18,6 +18,9 @@ Name: findutils +%if %suse_version > 1100 +BuildRequires: libselinux-devel +%endif Url: http://www.gnu.org/software/findutils/ License: GNU Free Documentation License, Version 1.2 (GFDL 1.2); GPL v3 or later Group: Productivity/File utilities @@ -26,15 +29,14 @@ Obsoletes: find AutoReqProv: on PreReq: %{install_info_prereq} Version: 4.4.0 -Release: 35 +Release: 38 Summary: GNU find--Finding Files Source: findutils-%{version}.tar.bz2 Source1: sysconfig.locate Source2: cron.daily.updatedb Patch: findutils-%{version}.diff -Patch1: findutils-%{version}-selinux.patch +Patch1: findutils-selinux.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: libselinux-devel %description This package contains GNU find and xargs. The programs comply with @@ -60,6 +62,7 @@ Group: Productivity/File utilities Provides: findutils:/usr/bin/locate AutoReqProv: on PreReq: %fillup_prereq +Requires: cron %description locate This package contains the locate program which is part of the GNU @@ -141,6 +144,9 @@ rm -rf $RPM_BUILD_ROOT /var/adm/fillup-templates/* %changelog +* Mon Sep 01 2008 schwab@suse.de +- Fix last change. +- Optimize find expressions in updatedb. * Mon Aug 25 2008 prusnak@suse.cz - enabled SELinux support [Fate#303662] * Mon Aug 11 2008 schwab@suse.de