* Arkadiusz MiĆkiewicz (1999-02-22)
* Li Zefan (2007-09-10).
*/
-
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <pwd.h>
#include <grp.h>
+#ifdef HAVE_LIBSELINUX
+# include <selinux/selinux.h>
+#endif
+
#include "c.h"
#include "xalloc.h"
#include "nls.h"
#define NAMEI_MNTS (1 << 3)
#define NAMEI_OWNERS (1 << 4)
#define NAMEI_VERTICAL (1 << 5)
+#define NAMEI_CONTEXT (1 << 6)
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;
{
while (nm) {
struct namei *next = nm->next;
+#ifdef HAVE_LIBSELINUX
+ free(nm->context);
+#endif
free(nm->name);
free(nm->abslink);
free(nm);
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;
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));
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);
" -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)"));
{ "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 },
};
{
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);
case 'v':
flags |= NAMEI_VERTICAL;
break;
-
+#ifdef HAVE_LIBSELINUX
+ case 'Z':
+ flags |= NAMEI_CONTEXT;
+ break;
+#endif
case 'h':
usage();
case 'V':