Skip to content

Instantly share code, notes, and snippets.

@apocalyptech
Last active March 24, 2022 18:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apocalyptech/492f53a35e20e7a0c52ef5fd8fff0708 to your computer and use it in GitHub Desktop.
Save apocalyptech/492f53a35e20e7a0c52ef5fd8fff0708 to your computer and use it in GitHub Desktop.
diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am
index cc18acb..07c738e 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) -lselinux
endif
if BUILD_WHEREIS
diff --git a/misc-utils/namei.c b/misc-utils/namei.c
index 3d50b20..de3465d 100644
--- a/misc-utils/namei.c
+++ b/misc-utils/namei.c
@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
+#include <selinux/selinux.h>
#include "c.h"
#include "xalloc.h"
@@ -49,6 +50,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 +62,8 @@ struct namei {
int level;
int mountpoint; /* is mount point */
int noent; /* this item not existing (stores errno from stat()) */
+ int context_len; /* length of selinux contexts, as returned by lgetfilecon(3) */
+ char *context; /* selinux contexts, as set by lgetfilecon(3) */
};
static int flags;
@@ -71,6 +75,7 @@ free_namei(struct namei *nm)
{
while (nm) {
struct namei *next = nm->next;
+ free(nm->context);
free(nm->name);
free(nm->abslink);
free(nm);
@@ -150,6 +155,7 @@ new_namei(struct namei *parent, const char *path, const char *fname, int lev)
nm->level = lev;
nm->name = xstrdup(fname);
+ nm->context_len = lgetfilecon(path, &nm->context);
if (lstat(path, &nm->st) != 0) {
nm->noent = errno;
@@ -279,6 +285,10 @@ print_namei(struct namei *nm, char *path)
blanks += ucache->width + gcache->width + 2;
if (!(flags & NAMEI_VERTICAL))
blanks += 1;
+ if (!(flags & NAMEI_CONTEXT))
+ // TODO: what in the world would you actually do here? Context strings
+ // are somewhat arbitrarily long.
+ blanks += 1;
blanks += nm->level * 2;
printf("%*s ", blanks, "");
printf("%s - %s\n", nm->name, strerror(nm->noent));
@@ -308,6 +318,11 @@ print_namei(struct namei *nm, char *path)
get_id(gcache, nm->st.st_gid)->name);
}
+ if (flags & NAMEI_CONTEXT) {
+ printf(" %-*s", nm->context_len,
+ nm->context);
+ }
+
if (flags & NAMEI_VERTICAL)
for (i = 0; i < nm->level; i++)
fputs(" ", stdout);
@@ -342,6 +357,7 @@ static void __attribute__((__noreturn__)) usage(void)
" -m, --modes show the mode bits of each file\n"
" -o, --owners show owner and group name of each file\n"
" -l, --long use a long listing format (-m -o -v) \n"
+ " -Z, --context print any security context of each file \n"
" -n, --nosymlinks don't follow symlinks\n"
" -v, --vertical vertical align of modes and owners\n"), out);
printf(USAGE_HELP_OPTIONS(21));
@@ -360,6 +376,7 @@ static const struct option longopts[] =
{ "long", no_argument, NULL, 'l' },
{ "nolinks", no_argument, NULL, 'n' },
{ "vertical", no_argument, NULL, 'v' },
+ { "context", no_argument, NULL, 'Z' },
{ NULL, 0, NULL, 0 },
};
@@ -374,7 +391,7 @@ main(int argc, char **argv)
textdomain(PACKAGE);
close_stdout_atexit();
- while ((c = getopt_long(argc, argv, "hVlmnovx", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "hVlmnovxZ", longopts, NULL)) != -1) {
switch(c) {
case 'l':
flags |= (NAMEI_OWNERS | NAMEI_MODES | NAMEI_VERTICAL);
@@ -394,6 +411,9 @@ main(int argc, char **argv)
case 'v':
flags |= NAMEI_VERTICAL;
break;
+ case 'Z':
+ flags |= NAMEI_CONTEXT;
+ break;
case 'h':
usage();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment