changeset 1660:b84024067049 draft

This patch adds a TOYBOX_SELINUX configuration option to control both the SELinux commands (such as chcon) and the SELinux-specific options to regular commands (such as ls -Z). This lets us #include <selinux/selinux.h> in portability.h. I've also fixed chcon to insist on being given the a context argument. This patch also adds -Z to id and fixes id's regular output (-G should be separated by spaces, non-G output should be separated by commas, and you don't want a double comma where the egid is omitted from the list of groups).
author Elliott Hughes <enh@google.com>
date Fri, 16 Jan 2015 13:36:53 -0600
parents 4a68c2b7787c
children d4bc084916fd
files Config.in lib/portability.h toys/pending/chcon.c toys/posix/id.c
diffstat 4 files changed, 59 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/Config.in	Thu Jan 15 19:09:08 2015 -0600
+++ b/Config.in	Fri Jan 16 13:36:53 2015 -0600
@@ -34,6 +34,13 @@
 
 	  chown root:root toybox; chmod +s toybox
 
+config TOYBOX_SELINUX
+ bool "SELinux support"
+ default n
+ help
+  Include SELinux options in commands such as ls, and add
+  SELinux-specific commands such as chcon.
+
 config TOYBOX_FLOAT
 	bool "Floating point support"
 	default y
--- a/lib/portability.h	Thu Jan 15 19:09:08 2015 -0600
+++ b/lib/portability.h	Fri Jan 16 13:36:53 2015 -0600
@@ -236,3 +236,7 @@
 
 //#define strncpy(...) @@strncpyisbadmmkay@@
 //#define strncat(...) @@strcatisbadmmkay@@
+
+#if CFG_TOYBOX_SELINUX
+#include <selinux/selinux.h>
+#endif
--- a/toys/pending/chcon.c	Thu Jan 15 19:09:08 2015 -0600
+++ b/toys/pending/chcon.c	Fri Jan 16 13:36:53 2015 -0600
@@ -2,11 +2,12 @@
  *
  * Copyright 2014 The Android Open Source Project
 
-USE_CHCON(NEWTOY(chcon, "hRv", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CHCON(NEWTOY(chcon, "<1hRv", TOYFLAG_USR|TOYFLAG_BIN))
 
 config CHCON
   bool "chcon"
-  default n
+  depends on TOYBOX_SELINUX
+  default y
   help
     usage: chcon [-hRv] CONTEXT FILE...
 
@@ -19,7 +20,6 @@
 
 #define FOR_chcon
 #include "toys.h"
-#include <selinux/selinux.h>
 
 GLOBALS(
   char *context;
--- a/toys/posix/id.c	Thu Jan 15 19:09:08 2015 -0600
+++ b/toys/posix/id.c	Fri Jan 16 13:36:53 2015 -0600
@@ -6,7 +6,7 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/id.html
 
-USE_ID(NEWTOY(id, ">1nGgru[!Ggu]", TOYFLAG_BIN))
+USE_ID(NEWTOY(id, ">1"USE_ID_SELINUX("Z")"nGgru[!"USE_ID_SELINUX("Z")"Ggu]", TOYFLAG_BIN))
 USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_BIN))
 USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_BIN))
@@ -25,6 +25,15 @@
     -r	Show real ID instead of effective ID
     -u	Show only the effective user ID
 
+config ID_SELINUX
+  bool
+  default y
+  depends on ID && TOYBOX_SELINUX
+  help
+    usage: id [-Z]
+
+    -Z Show only SELinux context
+
 config GROUPS
   bool "groups"
   default y
@@ -54,7 +63,7 @@
 #include "toys.h"
 
 GLOBALS(
-  int do_u, do_n, do_G, is_groups;
+  int do_u, do_n, do_G, do_Z, is_groups;
 )
 
 static void s_or_u(char *s, unsigned u, int done)
@@ -97,7 +106,7 @@
   grp = xgetgrgid(i ? gid : egid);
   if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
 
-  if (!TT.do_G) {
+  if (!TT.do_G && !TT.do_Z) {
     showid("uid=", pw->pw_uid, pw->pw_name);
     showid(" gid=", grp->gr_gid, grp->gr_name);
 
@@ -115,18 +124,40 @@
     showid(" groups=", grp->gr_gid, grp->gr_name);
   }
 
-  groups = (gid_t *)toybuf;
-  i = sizeof(toybuf)/sizeof(gid_t);
-  ngroups = username ? getgrouplist(username, gid, groups, &i)
-    : getgroups(i, groups);
-  if (ngroups<0) perror_exit(0);
+  if (!TT.do_Z) {
+    groups = (gid_t *)toybuf;
+    i = sizeof(toybuf)/sizeof(gid_t);
+    ngroups = username ? getgrouplist(username, gid, groups, &i)
+      : getgroups(i, groups);
+    if (ngroups<0) perror_exit(0);
 
-  for (i = 0; i<ngroups; i++) {
-    if (i || !TT.do_G) xputc(' ');
-    if (!(grp = getgrgid(groups[i]))) perror_msg(0);
-    else if (TT.do_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
-    else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
+    int show_separator = !TT.do_G;
+    for (i = 0; i<ngroups; i++) {
+      if (show_separator) xputc(TT.do_G ? ' ' : ',');
+      show_separator = 1;
+      if (!(grp = getgrgid(groups[i]))) perror_msg(0);
+      else if (TT.do_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
+      else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
+      else show_separator = 0; // Because we didn't show anything this time.
+    }
+    if (TT.do_G) {
+      xputc('\n');
+      exit(0);
+    }
   }
+
+#if CFG_TOYBOX_SELINUX
+  char *context = NULL;
+  if (is_selinux_enabled() < 1) {
+    if (TT.do_Z)
+      error_exit("SELinux disabled");
+  } else if (getcon(&context) == 0) {
+    if (!TT.do_Z) xputc(' ');
+    printf("context=%s", context);
+  }
+  if (CFG_TOYBOX_FREE) free(context);
+#endif
+
   xputc('\n');
 }
 
@@ -136,6 +167,7 @@
   if (FLAG_u) TT.do_u |= toys.optflags & FLAG_u;
   if (FLAG_n) TT.do_n |= toys.optflags & FLAG_n;
   if (FLAG_G) TT.do_G |= toys.optflags & FLAG_G;
+  if (FLAG_Z) TT.do_Z |= toys.optflags & FLAG_Z;
 
   if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
   else do_id(NULL);