diff options
-rw-r--r-- | ChangeLog-selinux | 8 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/id.c | 63 |
3 files changed, 62 insertions, 10 deletions
diff --git a/ChangeLog-selinux b/ChangeLog-selinux index cb5f4b398..4993bd88e 100644 --- a/ChangeLog-selinux +++ b/ChangeLog-selinux @@ -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. diff --git a/src/Makefile.am b/src/Makefile.am index 4bc4faefb..3f65a1e37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) @@ -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); } |