]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
id: Add SELinux support: -Z option.
authorJim Meyering <jim@meyering.net>
Sat, 13 Jan 2007 15:15:41 +0000 (16:15 +0100)
committerJim Meyering <jim@meyering.net>
Thu, 29 Mar 2007 19:37:05 +0000 (21:37 +0200)
* src/id.c (main): Apply patches from Fedora, with these changes:
Remove #ifdef WITH_SELINUX.
Use error (EXIT_FAILURE, not fprintf+exit(1).
* src/Makefile.am (id_LDADD): Define, so as to add $(LIB_SELINUX).

ChangeLog-selinux
src/Makefile.am
src/id.c

index cb5f4b3984e9406a6831317a8e98900a18ec2142..4993bd88e6a69f081ec0e4b87d99ccd3fc987c1e 100644 (file)
@@ -1,3 +1,11 @@
+2007-01-13  Jim Meyering  <jim@meyering.net>
+
+       id: Add SELinux support: -Z option.
+       * src/id.c (main): Apply patches from Fedora, with these changes:
+       Remove #ifdef WITH_SELINUX.
+       Use error (EXIT_FAILURE, not fprintf+exit(1).
+       * src/Makefile.am (id_LDADD): Define, so as to add $(LIB_SELINUX).
+
 2007-01-06  Jim Meyering  <jim@meyering.net>
 
        stat: Add support for SELinux in the form of a %C format directive.
index 4bc4faefb0047ed4a9879d661a7a5c382b2ebb1d..3f65a1e37ef19e05531682a319c0ac11cf977720 100644 (file)
@@ -73,6 +73,7 @@ __LDADD = $(LDADD) $(LIB_EACCESS)
 # for clock_gettime and fdatasync
 dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
 dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX)
+id_LDADD = $(LDADD) $(LIB_SELINUX)
 ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX)
 pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
 shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
index 7ed7167eeaf7a973a0d2471092157d0c2f1cb31c..cc34d2f4af234fec1dbf813547774af8c1ae500e 100644 (file)
--- a/src/id.c
+++ b/src/id.c
@@ -1,5 +1,5 @@
 /* id -- print real and effective UIDs and GIDs
-   Copyright (C) 1989-2005 Free Software Foundation, Inc.
+   Copyright (C) 1989-2007 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <pwd.h>
 #include <grp.h>
 #include <getopt.h>
+#include <selinux/selinux.h>
 
 #include "system.h"
 #include "error.h"
@@ -37,6 +38,9 @@
 
 int getugroups ();
 
+/* If nonzero, output only the SELinux context. -Z */
+static int just_context = 0;
+
 static void print_user (uid_t uid);
 static void print_group (gid_t gid);
 static void print_group_list (const char *username);
@@ -55,8 +59,13 @@ static gid_t rgid, egid;
 /* True unless errors have been encountered.  */
 static bool ok = true;
 
+/* The SELinux context.  Start with a known invalid value so print_full_info
+   knows when `context' has not been set to a meaningful value.  */
+static security_context_t context = NULL;
+
 static struct option const longopts[] =
 {
+  {"context", no_argument, NULL, 'Z'},
   {"group", no_argument, NULL, 'g'},
   {"groups", no_argument, NULL, 'G'},
   {"name", no_argument, NULL, 'n'},
@@ -80,6 +89,7 @@ usage (int status)
 Print information for USERNAME, or the current user.\n\
 \n\
   -a              ignore, for compatibility with other versions\n\
+  -Z, --context   print only the security context of the current user\n\
   -g, --group     print only the effective group ID\n\
   -G, --groups    print all group IDs\n\
   -n, --name      print a name instead of a number, for -ugG\n\
@@ -101,6 +111,7 @@ int
 main (int argc, char **argv)
 {
   int optc;
+  int selinux_enabled = (is_selinux_enabled () > 0);
 
   /* If true, output the list of all group IDs. -G */
   bool just_group_list = false;
@@ -119,13 +130,22 @@ main (int argc, char **argv)
 
   atexit (close_stdout);
 
-  while ((optc = getopt_long (argc, argv, "agnruG", longopts, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1)
     {
       switch (optc)
        {
        case 'a':
          /* Ignore -a, for compatibility with SVR4.  */
          break;
+
+        case 'Z':
+         /* politely decline if we're not on a selinux-enabled kernel. */
+         if (!selinux_enabled)
+           error (EXIT_FAILURE, 0, _("--context (-Z) can be used only on "
+                                     "an SELinux-enabled kernel"));
+          just_context = 1;
+          break;
+
        case 'g':
          just_group = true;
          break;
@@ -148,19 +168,38 @@ main (int argc, char **argv)
        }
     }
 
-  if (just_user + just_group + just_group_list > 1)
-    error (EXIT_FAILURE, 0, _("cannot print only user and only group"));
-
-  if (just_user + just_group + just_group_list == 0 && (use_real | use_name))
-    error (EXIT_FAILURE, 0,
-          _("cannot print only names or real IDs in default format"));
-
-  if (argc - optind > 1)
+  if (1 < argc - optind)
     {
       error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
       usage (EXIT_FAILURE);
     }
 
+  if (argc - optind == 1 && just_context)
+    error (EXIT_FAILURE, 0,
+          _("cannot print security context when user specified"));
+
+  if (just_context && !selinux_enabled)
+    error (EXIT_FAILURE, 0, _("\
+cannot display context when selinux not enabled or when displaying the id\n\
+of a different user"));
+
+  /* If we are on a selinux-enabled kernel, get our context.
+     Otherwise, leave the context variable alone - it has
+     been initialized known invalid value; if we see this invalid
+     value later, we will know we are on a non-selinux kernel.  */
+  if (selinux_enabled)
+    {
+      if (getcon (&context) && just_context)
+        error (EXIT_FAILURE, 0, _("can't get process context"));
+    }
+
+  if (just_user + just_group + just_group_list + just_context > 1)
+    error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
+
+  if (just_user + just_group + just_group_list == 0 && (use_real | use_name))
+    error (EXIT_FAILURE, 0,
+          _("cannot print only names or real IDs in default format"));
+
   if (argc - optind == 1)
     {
       struct passwd *pwd = getpwnam (argv[optind]);
@@ -183,6 +222,8 @@ main (int argc, char **argv)
     print_group (use_real ? rgid : egid);
   else if (just_group_list)
     print_group_list (argv[optind]);
+  else if (just_context)
+    fputs (context, stdout);
   else
     print_full_info (argv[optind]);
   putchar ('\n');
@@ -385,4 +426,6 @@ print_full_info (const char *username)
     free (groups);
   }
 #endif /* HAVE_GETGROUPS */
+  if (context != NULL)
+    printf (" context=%s", context);
 }