mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
binutils: Add the --namespace option to C based aa-exec
Switch to the policy in the namespace specified by the --namespace option. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
897fa17b0d
commit
b75cbff332
1 changed files with 46 additions and 9 deletions
|
@ -19,6 +19,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#define _(s) gettext(s)
|
#define _(s) gettext(s)
|
||||||
|
|
||||||
static const char *opt_profile = NULL;
|
static const char *opt_profile = NULL;
|
||||||
|
static const char *opt_namespace = NULL;
|
||||||
static bool opt_debug = false;
|
static bool opt_debug = false;
|
||||||
static bool opt_immediate = false;
|
static bool opt_immediate = false;
|
||||||
static bool opt_verbose = false;
|
static bool opt_verbose = false;
|
||||||
|
@ -49,6 +51,7 @@ static void usage(const char *name, bool error)
|
||||||
"\n"
|
"\n"
|
||||||
"OPTIONS:\n"
|
"OPTIONS:\n"
|
||||||
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
|
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
|
||||||
|
" -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n"
|
||||||
" -d, --debug show messages with debugging information\n"
|
" -d, --debug show messages with debugging information\n"
|
||||||
" -i, --immediate change profile immediately instead of at exec\n"
|
" -i, --immediate change profile immediately instead of at exec\n"
|
||||||
" -v, --verbose show messages with stats\n"
|
" -v, --verbose show messages with stats\n"
|
||||||
|
@ -112,11 +115,12 @@ static char **parse_args(int argc, char **argv)
|
||||||
{"debug", no_argument, 0, 'd'},
|
{"debug", no_argument, 0, 'd'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"profile", required_argument, 0, 'p'},
|
{"profile", required_argument, 0, 'p'},
|
||||||
|
{"namespace", required_argument, 0, 'n'},
|
||||||
{"immediate", no_argument, 0, 'i'},
|
{"immediate", no_argument, 0, 'i'},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "+dhp:iv", long_opts, NULL)) != -1) {
|
while ((opt = getopt_long(argc, argv, "+dhp:n:iv", long_opts, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
opt_debug = true;
|
opt_debug = true;
|
||||||
|
@ -127,6 +131,9 @@ static char **parse_args(int argc, char **argv)
|
||||||
case 'p':
|
case 'p':
|
||||||
opt_profile = optarg;
|
opt_profile = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
opt_namespace = optarg;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
opt_immediate = true;
|
opt_immediate = true;
|
||||||
break;
|
break;
|
||||||
|
@ -145,28 +152,58 @@ static char **parse_args(int argc, char **argv)
|
||||||
return argv + optind;
|
return argv + optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void build_name(char *name, size_t name_len,
|
||||||
|
const char *namespace, const char *profile)
|
||||||
|
{
|
||||||
|
size_t required_len = 1; /* reserve 1 byte for NUL-terminator */
|
||||||
|
|
||||||
|
if (namespace)
|
||||||
|
required_len += 1 + strlen(namespace) + 3; /* :<NAMESPACE>:// */
|
||||||
|
|
||||||
|
if (profile)
|
||||||
|
required_len += strlen(profile);
|
||||||
|
|
||||||
|
if (required_len > name_len)
|
||||||
|
error("name too long (%zu > %zu)", required_len, name_len);
|
||||||
|
|
||||||
|
name[0] = '\0';
|
||||||
|
|
||||||
|
if (namespace) {
|
||||||
|
strcat(name, ":");
|
||||||
|
strcat(name, namespace);
|
||||||
|
strcat(name, "://");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile)
|
||||||
|
strcat(name, profile);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char name[PATH_MAX];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
argv = parse_args(argc, argv);
|
argv = parse_args(argc, argv);
|
||||||
|
|
||||||
if (!opt_profile)
|
if (opt_namespace || opt_profile)
|
||||||
|
build_name(name, sizeof(name), opt_namespace, opt_profile);
|
||||||
|
else
|
||||||
goto exec;
|
goto exec;
|
||||||
|
|
||||||
if (opt_immediate) {
|
if (opt_immediate) {
|
||||||
verbose("aa_change_profile(\"%s\")", opt_profile);
|
verbose("aa_change_profile(\"%s\")", name);
|
||||||
rc = aa_change_profile(opt_profile);
|
rc = aa_change_profile(name);
|
||||||
debug("%d = aa_change_profile(\"%s\")", rc, opt_profile);
|
debug("%d = aa_change_profile(\"%s\")", rc, name);
|
||||||
} else {
|
} else {
|
||||||
verbose("aa_change_onexec(\"%s\")", opt_profile);
|
verbose("aa_change_onexec(\"%s\")", name);
|
||||||
rc = aa_change_onexec(opt_profile);
|
rc = aa_change_onexec(name);
|
||||||
debug("%d = aa_change_onexec(\"%s\")", rc, opt_profile);
|
debug("%d = aa_change_onexec(\"%s\")", rc, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (errno == ENOENT || errno == EACCES) {
|
if (errno == ENOENT || errno == EACCES) {
|
||||||
error("profile '%s' does not exist", opt_profile);
|
error("%s '%s' does not exist\n",
|
||||||
|
opt_profile ? "profile" : "namespace", name);
|
||||||
} else if (errno == EINVAL) {
|
} else if (errno == EINVAL) {
|
||||||
error("AppArmor interface not available");
|
error("AppArmor interface not available");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue