* [patch] updated chcon.c
@ 2003-07-14 2:47 Colin Walters
2003-07-15 21:08 ` Stephen Smalley
0 siblings, 1 reply; 2+ messages in thread
From: Colin Walters @ 2003-07-14 2:47 UTC (permalink / raw)
To: selinux
[-- Attachment #1: Type: text/plain, Size: 242 bytes --]
Hi,
Per our previous discussion, I've updated my previous patch for chcon to
the new 2.5 API. I tried to minimize the number of places which had
knowledge of the components of the security context.
Tested on my Debian SELinux 2.5 system.
[-- Attachment #2: chcon.patch --]
[-- Type: text/plain, Size: 9668 bytes --]
--- chcon.c~ 2003-07-13 22:42:47.000000000 -0400
+++ chcon.c 2003-07-13 22:33:06.000000000 -0400
@@ -1,11 +1,15 @@
/* chcontext -- change security context of a pathname */
+/* Added the ability to specify individual components of
+ a security context. -- Colin Walters <walters@debian.org> */
+
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
#include <getopt.h>
#include <selinux/selinux.h>
+#include <selinux/context.h>
#include "system.h"
#include "error.h"
@@ -31,8 +35,7 @@
V_off
};
-static int change_dir_context PARAMS ((const char *dir, security_context_t context,
- const struct stat *statp));
+static int change_dir_context PARAMS ((const char *dir, const struct stat *statp));
/* The name the program was run with. */
char *program_name;
@@ -51,7 +54,13 @@
static enum Verbosity verbosity = V_off;
/* The name of the context file is being given. */
-static const char *contextname;
+static const char *specified_context;
+
+/* Specific components of the context */
+static const char *specified_user;
+static const char *specified_role;
+static const char *specified_range;
+static const char *specified_type;
/* The argument to the --reference option. Use the context of this file.
This file must exist. */
@@ -72,6 +81,10 @@
{"quiet", no_argument, 0, 'f'},
{"reference", required_argument, 0, CHAR_MAX + 1},
{"context", required_argument, 0, CHAR_MAX + 2},
+ {"user", required_argument, 0, 'u'},
+ {"role", required_argument, 0, 'r'},
+ {"type", required_argument, 0, 't'},
+ {"range", required_argument, 0, 'l'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
@@ -82,7 +95,7 @@
CHANGED describes what (if anything) has happened. */
static void
-describe_change (const char *file, enum Change_status changed)
+describe_change (const char *file, security_context_t newcontext, enum Change_status changed)
{
const char *fmt;
switch (changed)
@@ -99,71 +112,128 @@
default:
abort ();
}
- printf (fmt, file, contextname);
+ printf (fmt, file, newcontext);
+}
+
+static int
+compute_context_from_mask (security_context_t context, context_t *ret)
+{
+ context_t newcontext = context_new (context);
+ if (!newcontext)
+ return 1;
+#define SETCOMPONENT(comp) \
+ do { \
+ if (specified_ ## comp) \
+ if (context_ ## comp ## _set (newcontext, specified_ ## comp)) \
+ goto lose; \
+ } while (0)
+
+ SETCOMPONENT(user);
+ SETCOMPONENT(range);
+ SETCOMPONENT(role);
+ SETCOMPONENT(type);
+#undef SETCOMPONENT
+
+ *ret = newcontext;
+ return 0;
+ lose:
+ context_free (newcontext);
+ return 1;
}
-/* Change the context of FILE to CONTEXT.
+/* Change the context of FILE, using specified components.
If it is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
static int
-change_file_context (const char *file, security_context_t context)
+change_file_context (const char *file)
{
struct stat file_stats;
security_context_t file_context=NULL;
+ context_t context;
+ security_context_t context_string;
int errors = 0;
if ((lgetfilecon(file, &file_context)<0) && (errno != ENODATA))
-
{
if (force_silent == 0)
error (0, errno, "%s", file);
return 1;
}
- if ((file_context==NULL) || strcmp(context,file_context)!=0)
+ /* This is kind of a gross hack. But if the file doesn't have a
+ context, and we're not setting all of the context components,
+ there isn't really a sensible default. Thus, we just get the
+ process context, and hope for the best. */
+ if (file_context == NULL && specified_context == NULL)
+ if (getcon (&file_context) < 0)
+ {
+ if (force_silent == 0)
+ error (0, errno, _("couldn't get default context"));
+ return 1;
+ }
+
+ if (specified_context == NULL)
+ {
+ if (compute_context_from_mask (file_context, &context))
+ {
+ error (0, 0, _("couldn't compute security context from %s"), file_context);
+ return 1;
+ }
+ }
+ else
+ {
+ context = context_new (specified_context);
+ if (!context)
+ error (1, 0, _("virtual memory exhausted"));
+ }
+
+ context_string = context_str (context);
+
+ if (strcmp(context_string,file_context)!=0)
{
int fail;
if (change_symlinks)
- fail = lsetfilecon (file, context);
+ fail = lsetfilecon (file, context_string);
else
- fail = setfilecon (file, context);
+ fail = setfilecon (file, context_string);
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
- describe_change (file, (fail ? CH_FAILED : CH_SUCCEEDED));
+ describe_change (file, context_string, (fail ? CH_FAILED : CH_SUCCEEDED));
if (fail)
{
errors = 1;
if (force_silent == 0)
{
- error (0, errno, "%s", file);
+ error (0, errno, _("failed to change context of %s to %s"), file, context_string);
}
}
}
else if (verbosity == V_high)
{
- describe_change (file, CH_NO_CHANGE_REQUESTED);
+ describe_change (file, context_string, CH_NO_CHANGE_REQUESTED);
}
+ context_free(context);
freecon(file_context);
if (recurse) {
if (lstat(file, &file_stats)==0)
if (S_ISDIR (file_stats.st_mode))
- errors |= change_dir_context (file, context, &file_stats);
+ errors |= change_dir_context (file, &file_stats);
}
return errors;
}
/* Recursively change context of the files in directory DIR
- to CONTEXT CONTEXT.
+ using specified context components.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
-change_dir_context (const char *dir, security_context_t context, const struct stat *statp)
+change_dir_context (const char *dir, const struct stat *statp)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
@@ -202,7 +272,7 @@
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
- errors |= change_file_context (path, context);
+ errors |= change_file_context (path);
}
free (path);
free (name_space);
@@ -219,6 +289,7 @@
{
printf (_("\
Usage: %s [OPTION]... CONTEXT FILE...\n\
+ or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\
or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
program_name, program_name, program_name);
@@ -230,6 +301,10 @@
(available only on systems with lchown system call)\n\
-f, --silent, --quiet suppress most error messages\n\
--reference=RFILE use RFILE's group instead of using a CONTEXT value\n\
+ -u, --user=USER set user USER in the target security context\n\
+ -r, --role=ROLE set role ROLE in the target security context\n\
+ -t, --type=TYPE set type TYPE in the target security context\n\
+ -l, --range=RANGE set range RANGE in the target security context\n\
-R, --recursive change files and directories recursively\n\
-v, --verbose output a diagnostic for every file processed\n\
--help display this help and exit\n\
@@ -243,10 +318,10 @@
int
main (int argc, char **argv)
{
- security_context_t context = NULL;
security_context_t ref_context = NULL;
int errors = 0;
int optc;
+ int component_specified = 0;
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -255,12 +330,28 @@
recurse = force_silent = 0;
- while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "Rcfhvu:r:t:l:", long_options, NULL)) != -1)
{
switch (optc)
{
case 0:
- break;
+ break;
+ case 'u':
+ specified_user = optarg;
+ component_specified = 1;
+ break;
+ case 'r':
+ specified_role = optarg;
+ component_specified = 1;
+ break;
+ case 't':
+ specified_type = optarg;
+ component_specified = 1;
+ break;
+ case 'l':
+ specified_range = optarg;
+ component_specified = 1;
+ break;
case CHAR_MAX + 1:
reference_file = optarg;
break;
@@ -294,24 +385,33 @@
if (show_help)
usage (0);
- if (argc - optind + ( (reference_file || ( context > 0 ) ) ? 1 : 0) <= 1)
- {
- error (0, 0, _("too few arguments"));
- usage (1);
- }
+
+ if (reference_file && component_specified)
+ {
+ error (0, 0, _("conflicting security context specifiers given"));
+ usage (1);
+ }
+
+ if (!(((reference_file || component_specified)
+ && (argc - optind > 0))
+ || (argc - optind > 1)))
+ {
+ error (0, 0, _("too few arguments"));
+ usage (1);
+ }
if (reference_file)
{
if (getfilecon (reference_file, &ref_context)<0)
error (1, errno, "%s", reference_file);
-
- context = ref_context;
+
+ specified_context = ref_context;
}
- else {
- context = argv[optind++];
+ else if (!component_specified) {
+ specified_context = argv[optind++];
}
for (; optind < argc; ++optind)
- errors |= change_file_context (argv[optind], context);
+ errors |= change_file_context (argv[optind]);
if (verbosity != V_off)
close_stdout ();
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [patch] updated chcon.c
2003-07-14 2:47 [patch] updated chcon.c Colin Walters
@ 2003-07-15 21:08 ` Stephen Smalley
0 siblings, 0 replies; 2+ messages in thread
From: Stephen Smalley @ 2003-07-15 21:08 UTC (permalink / raw)
To: Colin Walters; +Cc: selinux
On Sun, 2003-07-13 at 22:47, Colin Walters wrote:
> Per our previous discussion, I've updated my previous patch for chcon to
> the new 2.5 API. I tried to minimize the number of places which had
> knowledge of the components of the security context.
>
> Tested on my Debian SELinux 2.5 system.
The coreutils-selinux.patch in the sourceforge CVS tree has been updated
to include the modified chcon.c.
--
Stephen Smalley <sds@epoch.ncsc.mil>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-07-15 21:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-14 2:47 [patch] updated chcon.c Colin Walters
2003-07-15 21:08 ` Stephen Smalley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.