From: Karel Zak Date: Wed, 13 Apr 2022 10:35:40 +0000 (+0200) Subject: namei: add -Z (selinux context report) X-Git-Tag: v2.39-rc1~711 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e928e8ed61996d46be4bfd36367c0e1c798f84d7;p=thirdparty%2Futil-linux.git namei: add -Z (selinux context report) Co-Author: CJ Kucera Addresses: https://github.com/util-linux/util-linux/pull/1630 Signed-off-by: Karel Zak --- diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am index cc18acbab5..52e457d23c 100644 --- a/misc-utils/Makemodule.am +++ b/misc-utils/Makemodule.am @@ -62,6 +62,7 @@ usrbin_exec_PROGRAMS += namei MANPAGES += misc-utils/namei.1 dist_noinst_DATA += misc-utils/namei.1.adoc namei_SOURCES = misc-utils/namei.c lib/strutils.c lib/idcache.c +namei_LDADD = $(LDADD) $(SELINUX_LIBS) endif if BUILD_WHEREIS diff --git a/misc-utils/namei.1.adoc b/misc-utils/namei.1.adoc index c8a317d7f0..181286cee5 100644 --- a/misc-utils/namei.1.adoc +++ b/misc-utils/namei.1.adoc @@ -56,6 +56,10 @@ Vertically align the modes and owners. *-x*, *--mountpoints*:: Show mountpoint directories with a 'D' rather than a 'd'. +*-Z*, *--context*:: +Show security context of the file or "?" if not available. +The support for security contexts is optional and does not have to be compiled to the namei. + include::man-common/help-version.adoc[] == BUGS diff --git a/misc-utils/namei.c b/misc-utils/namei.c index 3d50b200db..3d41407237 100644 --- a/misc-utils/namei.c +++ b/misc-utils/namei.c @@ -19,7 +19,6 @@ * Arkadiusz Miśkiewicz (1999-02-22) * Li Zefan (2007-09-10). */ - #include #include #include @@ -32,6 +31,10 @@ #include #include +#ifdef HAVE_LIBSELINUX +# include +#endif + #include "c.h" #include "xalloc.h" #include "nls.h" @@ -49,6 +52,7 @@ #define NAMEI_MNTS (1 << 3) #define NAMEI_OWNERS (1 << 4) #define NAMEI_VERTICAL (1 << 5) +#define NAMEI_CONTEXT (1 << 6) struct namei { @@ -60,6 +64,10 @@ struct namei { int level; int mountpoint; /* is mount point */ int noent; /* this item not existing (stores errno from stat()) */ +#ifdef HAVE_LIBSELINUX + int context_len; /* length of selinux contexts, as returned by lgetfilecon(3) */ + char *context; /* selinux contexts, as set by lgetfilecon(3) */ +#endif }; static int flags; @@ -71,6 +79,9 @@ free_namei(struct namei *nm) { while (nm) { struct namei *next = nm->next; +#ifdef HAVE_LIBSELINUX + free(nm->context); +#endif free(nm->name); free(nm->abslink); free(nm); @@ -151,6 +162,11 @@ new_namei(struct namei *parent, const char *path, const char *fname, int lev) nm->level = lev; nm->name = xstrdup(fname); +#ifdef HAVE_LIBSELINUX + /* Don't use is_selinux_enabled() here. We need info about a context + * also on systems where SELinux is (temporary) disabled */ + nm->context_len = lgetfilecon(path, &nm->context); +#endif if (lstat(path, &nm->st) != 0) { nm->noent = errno; return nm; @@ -279,6 +295,8 @@ print_namei(struct namei *nm, char *path) blanks += ucache->width + gcache->width + 2; if (!(flags & NAMEI_VERTICAL)) blanks += 1; + if (!(flags & NAMEI_CONTEXT)) + blanks += 1; blanks += nm->level * 2; printf("%*s ", blanks, ""); printf("%s - %s\n", nm->name, strerror(nm->noent)); @@ -307,7 +325,14 @@ print_namei(struct namei *nm, char *path) printf(" %-*s", gcache->width, get_id(gcache, nm->st.st_gid)->name); } - +#ifdef HAVE_LIBSELINUX + if (flags & NAMEI_CONTEXT) { + if (nm->context) + printf(" %-*s", nm->context_len, nm->context); + else + printf(" ?"); + } +#endif if (flags & NAMEI_VERTICAL) for (i = 0; i < nm->level; i++) fputs(" ", stdout); @@ -344,6 +369,10 @@ static void __attribute__((__noreturn__)) usage(void) " -l, --long use a long listing format (-m -o -v) \n" " -n, --nosymlinks don't follow symlinks\n" " -v, --vertical vertical align of modes and owners\n"), out); +#ifdef HAVE_LIBSELINUX + fputs(_( " -Z, --context print any security context of each file \n"), out); +#endif + printf(USAGE_HELP_OPTIONS(21)); printf(USAGE_MAN_TAIL("namei(1)")); @@ -360,6 +389,9 @@ static const struct option longopts[] = { "long", no_argument, NULL, 'l' }, { "nolinks", no_argument, NULL, 'n' }, { "vertical", no_argument, NULL, 'v' }, +#ifdef HAVE_LIBSELINUX + { "context", no_argument, NULL, 'Z' }, +#endif { NULL, 0, NULL, 0 }, }; @@ -368,13 +400,18 @@ main(int argc, char **argv) { int c; int rc = EXIT_SUCCESS; + static const char *shortopts = +#ifdef HAVE_LIBSELINUX + "Z" +#endif + "hVlmnovx"; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); close_stdout_atexit(); - while ((c = getopt_long(argc, argv, "hVlmnovx", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { case 'l': flags |= (NAMEI_OWNERS | NAMEI_MODES | NAMEI_VERTICAL); @@ -394,7 +431,11 @@ main(int argc, char **argv) case 'v': flags |= NAMEI_VERTICAL; break; - +#ifdef HAVE_LIBSELINUX + case 'Z': + flags |= NAMEI_CONTEXT; + break; +#endif case 'h': usage(); case 'V':