]> git.pld-linux.org Git - packages/findutils.git/blob - findutils-selinux.patch
- dropped pre-cvs changelog
[packages/findutils.git] / findutils-selinux.patch
1 diff -up findutils-4.4.2/configure.ac_old findutils-4.4.2/configure.ac
2 --- findutils-4.4.2/configure.ac_old    2009-07-01 10:24:04.000000000 +0200
3 +++ findutils-4.4.2/configure.ac        2009-07-01 10:24:46.000000000 +0200
4 @@ -114,6 +114,16 @@ AC_CHECK_LIB([m],[fabs],[FINDLIBS="-lm $
5    AC_DEFINE_UNQUOTED(HAVE_FABS_IN_LIBM,1,[fabs is defined in -lm]))
6  AC_SUBST([FINDLIBS])
7  
8 +AC_ARG_WITH([selinux],
9 +           AS_HELP_STRING([--without-selinux], [disable SELinux support]),
10 +           [:],
11 +[AC_CHECK_LIB([selinux], [is_selinux_enabled],
12 +             [with_selinux=yes], [with_selinux=no])])
13 +if test x$with_selinux != xno; then
14 +   AC_DEFINE([WITH_SELINUX], [1], [Define to support SELinux])
15 +   AC_SUBST([LIBSELINUX], [-lselinux])
16 +fi
17 +
18  dnl Checks for header files.
19  AC_HEADER_STDC
20  dnl Assume unistd.h is present - coreutils does too.
21 diff -up findutils-4.4.2/doc/find.texi_old findutils-4.4.2/doc/find.texi
22 --- findutils-4.4.2/doc/find.texi_old   2009-07-01 10:25:09.000000000 +0200
23 +++ findutils-4.4.2/doc/find.texi       2009-07-01 10:26:37.000000000 +0200
24 @@ -7,7 +7,6 @@
25  @c %**end of header
26  
27  @include version.texi
28 -@include ../locate/dblocation.texi
29  
30  @iftex
31  @finalout
32 @@ -1242,6 +1241,14 @@ situation.
33  
34  @end deffn
35  
36 +@deffn Test -context pattern
37 +True if file's SELinux context matches the pattern @var{pattern}.
38 +The pattern uses shell glob matching.
39 +
40 +This predicate is supported only on @code{find} versions compiled with
41 +SELinux support and only when SELinux is enabled.
42 +@end deffn
43 +
44  @node Contents
45  @section Contents
46  
47 @@ -1826,6 +1833,9 @@ value used for BLOCKSIZE is system-depen
48  bytes.  If the file size is zero, the value printed is undefined.  On
49  systems which lack support for st_blocks, a file's sparseness is
50  assumed to be 1.0.
51 +@item %Z
52 +File's SELinux context, or empty string if the file has no SELinux context
53 +or this version of find does not support SELinux.
54  @end table
55  
56  @node Location Directives
57 diff -up findutils-4.4.2/find/defs.h_old findutils-4.4.2/find/defs.h
58 --- findutils-4.4.2/find/defs.h_old     2009-07-01 12:38:32.000000000 +0200
59 +++ findutils-4.4.2/find/defs.h 2009-07-01 12:52:47.000000000 +0200
60 @@ -91,6 +91,9 @@ int get_statinfo PARAMS((const char *pat
61  #define MODE_RWX       (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
62  #define MODE_ALL       (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
63  
64 +#ifdef WITH_SELINUX
65 +#include <selinux/selinux.h>
66 +#endif
67  
68  struct predicate;
69  struct options;
70 @@ -315,6 +318,9 @@ struct predicate
71      struct samefile_file_id samefileid; /* samefile */
72      mode_t type;               /* type */
73      struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
74 +#ifdef WITH_SELINUX
75 +    security_context_t scontext; /* scontext */
76 +#endif
77    } args;
78  
79    /* The next predicate in the user input sequence,
80 @@ -459,6 +465,9 @@ PREDICATEFUNCTION pred_used;
81  PREDICATEFUNCTION pred_user;
82  PREDICATEFUNCTION pred_writable;
83  PREDICATEFUNCTION pred_xtype;
84 +#ifdef WITH_SELINUX
85 +PREDICATEFUNCTION pred_context;
86 +#endif
87  
88  
89  
90 @@ -601,6 +610,10 @@ struct options
91     */
92    int regex_options;
93  
94 +#ifdef WITH_SELINUX
95 +  int (*x_getfilecon) ();
96 +#endif
97 +
98    /* Optimisation level.  One is the default. 
99     */
100    unsigned short optimisation_level;
101 diff -up findutils-4.4.2/find/find.1_old findutils-4.4.2/find/find.1
102 --- findutils-4.4.2/find/find.1_old     2009-07-01 10:30:04.000000000 +0200
103 +++ findutils-4.4.2/find/find.1 2009-07-01 10:30:59.000000000 +0200
104 @@ -933,6 +933,8 @@ if \fIc\fR is `l'.  In other words, for 
105  checks the type of the file that 
106  .B \-type
107  does not check.
108 +.IP "\-context \fIpattern\fR"
109 +(SELinux only) Security context of the file matches glob \fIpattern\fR.
110  
111  .SS ACTIONS
112  .IP "\-delete\fR"
113 @@ -1354,6 +1356,8 @@ File's type (like in 
114  U=unknown type (shouldn't happen)
115  .IP %Y
116  File's type (like %y), plus follow symlinks: L=loop, N=nonexistent
117 +.IP %Z
118 +(SELinux only) file's security context.
119  .PP
120  A `%' character followed by any other character is discarded, but the
121  other character is printed (don't rely on this, as further format
122 diff -up findutils-4.4.2/find/find.c_old findutils-4.4.2/find/find.c
123 --- findutils-4.4.2/find/find.c_old     2009-07-01 10:26:53.000000000 +0200
124 +++ findutils-4.4.2/find/find.c 2009-07-01 10:29:52.000000000 +0200
125 @@ -120,6 +120,36 @@ int get_current_dirfd(void)
126    return AT_FDCWD;
127  }
128  
129 +#ifdef WITH_SELINUX
130 +static int
131 +fallback_getfilecon(const char *name, security_context_t *p, int prev_rv)
132 +{
133 +  /* Our original getfilecon() call failed.  Perhaps we can't follow a
134 +   * symbolic link.  If that might be the problem, lgetfilecon() the link.
135 +   * Otherwise, admit defeat.
136 +   */
137 +  switch (errno)
138 +    {
139 +    case ENOENT:
140 +    case ENOTDIR:
141 +#ifdef DEBUG_STAT
142 +      fprintf(stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling back on lgetfilecon()\n", name);
143 +#endif
144 +      return lgetfilecon(name, p);
145 +
146 +    case EACCES:
147 +    case EIO:
148 +    case ELOOP:
149 +    case ENAMETOOLONG:
150 +#ifdef EOVERFLOW
151 +    case EOVERFLOW:        /* EOVERFLOW is not #defined on UNICOS. */
152 +#endif
153 +    default:
154 +      return prev_rv;         
155 +    }
156 +}
157 +#endif /* WITH_SELINUX */
158 +
159  \f
160  int
161  main (int argc, char **argv)
162 @@ -1270,7 +1300,7 @@ process_path (char *pathname, char *name
163  static void
164  process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent)
165  {
166 -  int subdirs_left;            /* Number of unexamined subdirs in PATHNAME. */
167 +  int subdirs_left = 0;                /* Number of unexamined subdirs in PATHNAME. */
168    boolean subdirs_unreliable;  /* if true, cannot use dir link count as subdir limif (if false, it may STILL be unreliable) */
169    unsigned int idx;            /* Which entry are we on? */
170    struct stat stat_buf;
171 diff -up findutils-4.4.2/find/Makefile.am_old findutils-4.4.2/find/Makefile.am
172 --- findutils-4.4.2/find/Makefile.am_old        2009-07-01 10:35:04.000000000 +0200
173 +++ findutils-4.4.2/find/Makefile.am    2009-07-01 10:35:37.000000000 +0200
174 @@ -26,7 +26,7 @@ endif
175  
176  EXTRA_DIST = defs.h $(man_MANS)
177  INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
178 -LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@
179 +LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@ @LIBSELINUX@
180  man_MANS = find.1
181  SUBDIRS = . testsuite
182  
183 diff -up findutils-4.4.2/find/parser.c_old findutils-4.4.2/find/parser.c
184 --- findutils-4.4.2/find/parser.c_old   2009-07-01 10:35:43.000000000 +0200
185 +++ findutils-4.4.2/find/parser.c       2009-07-01 12:38:19.000000000 +0200
186 @@ -53,6 +53,10 @@
187  #include <unistd.h>
188  #include <sys/stat.h>
189  
190 +#ifdef WITH_SELINUX
191 +#include <selinux/selinux.h>
192 +#endif
193 +
194  #if ENABLE_NLS
195  # include <libintl.h>
196  # define _(Text) gettext (Text)
197 @@ -155,6 +159,9 @@ static boolean parse_noignore_race PARAM
198  static boolean parse_warn          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
199  static boolean parse_xtype         PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
200  static boolean parse_quit          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
201 +#ifdef WITH_SELINUX
202 +static boolean parse_context       PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
203 +#endif
204  
205  boolean parse_print             PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
206  
207 @@ -251,6 +258,9 @@ static struct parser_table const parse_t
208    PARSE_TEST       ("cmin",                  cmin),         /* GNU */
209    PARSE_TEST       ("cnewer",                cnewer),       /* GNU */
210    {ARG_TEST,       "ctime",                  parse_time, pred_ctime}, /* POSIX */
211 +#ifdef WITH_SELINUX
212 +  PARSE_TEST       ("context",               context),      /* GNU */
213 +#endif
214    PARSE_POSOPT     ("daystart",              daystart),             /* GNU */
215    PARSE_ACTION     ("delete",                delete), /* GNU, Mac OS, FreeBSD */
216    PARSE_OPTION     ("d",                     d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated  in favour of -depth */
217 @@ -347,6 +357,89 @@ static struct parser_table const parse_t
218  static const char *first_nonoption_arg = NULL;
219  static const struct parser_table *noop = NULL;
220  
221 +#ifdef WITH_SELINUX
222 +static int
223 +fallback_getfilecon(const char *name, security_context_t *p, int prev_rv)
224 +{
225 +  /* Our original getfilecon() call failed.  Perhaps we can't follow a
226 +   * symbolic link.  If that might be the problem, lgetfilecon() the link.
227 +   * Otherwise, admit defeat.
228 +   */
229 +  switch (errno)
230 +    {
231 +    case ENOENT:
232 +    case ENOTDIR:
233 +#ifdef DEBUG_STAT
234 +      fprintf(stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling back on lgetfilecon()\n", name);
235 +#endif
236 +      return lgetfilecon(name, p);
237 +
238 +    case EACCES:
239 +    case EIO:
240 +    case ELOOP:
241 +    case ENAMETOOLONG:
242 +#ifdef EOVERFLOW
243 +    case EOVERFLOW:        /* EOVERFLOW is not #defined on UNICOS. */
244 +#endif
245 +    default:
246 +      return prev_rv;         
247 +    }
248 +}
249 +
250 +/* optionh_getfilecon() implements the getfilecon operation when the
251 + * -H option is in effect.
252 + *
253 + * If the item to be examined is a command-line argument, we follow
254 + * symbolic links.  If the getfilecon() call fails on the command-line
255 + * item, we fall back on the properties of the symbolic link.
256 + *
257 + * If the item to be examined is not a command-line argument, we
258 + * examine the link itself.
259 + */
260 +int
261 +optionh_getfilecon(const char *name, security_context_t *p)
262 +{
263 +  if (0 == state.curdepth)
264 +    {
265 +      /* This file is from the command line; deference the link (if it
266 +       * is a link).
267 +       */
268 +      int rv = getfilecon(name, p);
269 +      if (0 == rv)
270 +       return 0;               /* success */
271 +      else
272 +       return fallback_getfilecon(name, p, rv);
273 +    }
274 +  else
275 +    {
276 +      /* Not a file on the command line; do not derefernce the link.
277 +       */
278 +      return lgetfilecon(name, p);
279 +    }
280 +}
281 +/* optionl_getfilecon() implements the getfilecon operation when the
282 + * -L option is in effect.  That option makes us examine the thing the
283 + * symbolic link points to, not the symbolic link itself.
284 + */
285 +int
286 +optionl_getfilecon(const char *name, security_context_t *p)
287 +{
288 +  int rv = getfilecon(name, p);
289 +  if (0 == rv)
290 +    return 0;                  /* normal case. */
291 +  else
292 +    return fallback_getfilecon(name, p, rv);
293 +}
294 +/* optionp_getfilecon() implements the stat operation when the -P
295 + * option is in effect (this is also the default).  That option makes
296 + * us examine the symbolic link itself, not the thing it points to.
297 + */
298 +int
299 +optionp_getfilecon(const char *name, security_context_t *p)
300 +{
301 +  return lgetfilecon(name, p);
302 +}
303 +#endif /* WITH_SELINUX */
304  
305  void
306  check_option_combinations(const struct predicate *p)
307 @@ -450,11 +543,17 @@ set_follow_state(enum SymlinkOption opt)
308         {
309         case SYMLINK_ALWAYS_DEREF:  /* -L */
310           options.xstat = optionl_stat;
311 +#ifdef WITH_SELINUX
312 +         options.x_getfilecon = optionl_getfilecon;
313 +#endif
314           options.no_leaf_check = true;
315           break;
316  
317         case SYMLINK_NEVER_DEREF:       /* -P (default) */
318           options.xstat = optionp_stat;
319 +#ifdef WITH_SELINUX
320 +         options.x_getfilecon = optionp_getfilecon;
321 +#endif
322           /* Can't turn no_leaf_check off because the user might have specified
323            * -noleaf anyway
324            */
325 @@ -462,6 +561,9 @@ set_follow_state(enum SymlinkOption opt)
326  
327         case SYMLINK_DEREF_ARGSONLY: /* -H */
328           options.xstat = optionh_stat;
329 +#ifdef WITH_SELINUX
330 +         options.x_getfilecon = optionh_getfilecon;
331 +#endif
332           options.no_leaf_check = true;
333         }
334      }
335 @@ -1127,8 +1229,12 @@ tests (N can be +N or -N or N): -amin N 
336        -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
337        -readable -writable -executable\n\
338        -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
339 -      -used N -user NAME -xtype [bcdpfls]\n"));
340 +      -used N -user NAME -xtype [bcdpfls]"));
341 +#ifdef WITH_SELINUX
342    puts (_("\
343 +      -context CONTEXT\n"));
344 +#endif
345 +  puts (_("\n\
346  actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
347        -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
348        -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\
349 @@ -2518,6 +2624,10 @@ parse_version (const struct parser_table
350    printf("LEAF_OPTIMISATION ");
351    ++features;
352  #endif
353 +#if defined(WITH_SELINUX)
354 +  printf("SELINUX ");
355 +  ++features;
356 +#endif
357  
358    flags = 0;
359    if (is_fts_enabled(&flags))
360 @@ -2552,6 +2662,32 @@ parse_version (const struct parser_table
361    exit (0);
362  }
363  
364 +#ifdef WITH_SELINUX
365 +static boolean
366 +parse_context (const struct parser_table* entry, char **argv, int *arg_ptr)
367 +{
368 +  struct predicate *our_pred;
369 +
370 +  if ((argv == NULL) || (argv[*arg_ptr] == NULL))
371 +    return false;
372 +
373 +  if (is_selinux_enabled() <= 0)
374 +    {
375 +      error (1, 0, _("invalid predicate -context: SELinux is not enabled."));
376 +      return false;
377 +    }
378 +  our_pred = insert_primary (entry);
379 +  our_pred->need_stat = false;
380 +#ifdef DEBUG
381 +  our_pred->p_name = find_pred_name (pred_context);
382 +#endif /*DEBUG*/
383 +  our_pred->args.scontext = argv[*arg_ptr];
384 +
385 +  (*arg_ptr)++;
386 +  return true;
387 +}
388 +#endif /* WITH_SELINUX */
389 +
390  static boolean
391  parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr)
392  {
393 @@ -2803,7 +2939,7 @@ insert_fprintf (struct format_val *vec,
394           if (*scan2 == '.')
395             for (scan2++; ISDIGIT (*scan2); scan2++)
396               /* Do nothing. */ ;
397 -         if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2))
398 +         if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2))
399             {
400               segmentp = make_segment (segmentp, format, scan2 - format,
401                                        KIND_FORMAT, *scan2, 0,
402 @@ -2930,6 +3066,7 @@ make_segment (struct segment **segment,
403      case 'h':                  /* leading directories part of path */
404      case 'p':                  /* pathname */
405      case 'P':                  /* pathname with ARGV element stripped */
406 +    case 'Z':                  /* SELinux security context */
407        *fmt++ = 's';
408        break;
409  
410 diff -up findutils-4.4.2/find/pred.c_old findutils-4.4.2/find/pred.c
411 --- findutils-4.4.2/find/pred.c_old     2009-07-01 10:31:11.000000000 +0200
412 +++ findutils-4.4.2/find/pred.c 2009-07-01 10:33:45.000000000 +0200
413 @@ -48,6 +48,10 @@
414  #include "error.h"
415  #include "verify.h"
416  
417 +#ifdef WITH_SELINUX
418 +#include <selinux/selinux.h>
419 +#endif /*WITH_SELINUX*/
420 +
421  #if ENABLE_NLS
422  # include <libintl.h>
423  # define _(Text) gettext (Text)
424 @@ -230,6 +234,9 @@ struct pred_assoc pred_table[] =
425    {pred_user, "user    "},
426    {pred_writable, "writable "},
427    {pred_xtype, "xtype   "},
428 +#ifdef WITH_SELINUX
429 +  {pred_context, "context"},
430 +#endif /*WITH_SELINUX*/
431    {0, "none    "}
432  };
433  #endif
434 @@ -1054,6 +1061,27 @@ do_fprintf(struct format_val *dest,
435                              mode_to_filetype(stat_buf->st_mode & S_IFMT));
436           }
437           break;
438 +       case 'Z':               /* SELinux security context */
439 +#ifdef WITH_SELINUX
440 +         {
441 +           security_context_t scontext;
442 +           int rv;
443 +           rv = (*options.x_getfilecon) (state.rel_pathname, &scontext);
444 +
445 +           if (rv < 0)
446 +             {
447 +               fprintf (stderr, "getfilecon(%s): %s", pathname,
448 +                        strerror(errno));
449 +               fflush (stderr);
450 +             }
451 +           else
452 +             {
453 +               checked_fprintf (dest, segment->text, scontext);
454 +               freecon (scontext);
455 +             }
456 +         }
457 +#endif /* WITH_SELINUX */
458 +         break;
459         }
460        /* end of KIND_FORMAT case */
461        break;
462 @@ -1844,6 +1872,32 @@ pred_xtype (const char *pathname, struct
463     */
464    return (pred_type (pathname, &sbuf, pred_ptr));
465  }
466 +  
467 +#ifdef WITH_SELINUX
468 +
469 +boolean
470 +pred_context (const char *pathname, struct stat *stat_buf,
471 +             struct predicate *pred_ptr)
472 +{
473 +  int rv;
474 +  security_context_t scontext;
475 +
476 +  rv = (*options.x_getfilecon) (state.rel_pathname, &scontext);
477 +
478 +  if (rv < 0)
479 +    {
480 +      fprintf (stderr, "getfilecon(%s): %s\n", pathname, strerror(errno));
481 +      fflush (stderr);
482 +      return false;
483 +    }
484 +
485 +  rv = (fnmatch (pred_ptr->args.scontext, scontext, 0) == 0);
486 +  freecon (scontext);
487 +  return rv;
488 +}
489 +
490 +#endif /*WITH_SELINUX*/
491 +
492  \f
493  /*  1) fork to get a child; parent remembers the child pid
494      2) child execs the command requested
495 diff -up findutils-4.4.2/find/tree.c_old findutils-4.4.2/find/tree.c
496 --- findutils-4.4.2/find/tree.c_old     2009-07-01 10:33:57.000000000 +0200
497 +++ findutils-4.4.2/find/tree.c 2009-07-01 10:34:54.000000000 +0200
498 @@ -953,7 +953,8 @@ static struct pred_cost_lookup costlooku
499      { pred_used      ,  NeedsStatInfo        },
500      { pred_user      ,  NeedsStatInfo        },
501      { pred_writable  ,  NeedsAccessInfo      },
502 -    { pred_xtype     ,  NeedsType            } /* roughly correct unless most files are symlinks */
503 +    { pred_xtype     ,  NeedsType            }, /* roughly correct unless most files are symlinks */
504 +    { pred_context   ,  NeedsNothing         } /* remove warning only:) */
505    };
506  static int pred_table_sorted = 0;
507  \f
508 @@ -1434,6 +1435,9 @@ get_new_pred (const struct parser_table 
509    last_pred->need_stat = true;
510    last_pred->need_type = true;
511    last_pred->args.str = NULL;
512 +#ifdef WITH_SELINUX
513 +  last_pred->args.scontext = NULL;
514 +#endif
515    last_pred->pred_next = NULL;
516    last_pred->pred_left = NULL;
517    last_pred->pred_right = NULL;
This page took 0.780325 seconds and 3 git commands to generate.