So this is a C based version of aa-exec to replace the perl version. ---
/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. */ #define _GNU_SOURCE #include <errno.h> #include <getopt.h> #include <libintl.h> #include <locale.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/apparmor.h> #define _(s) gettext(s) #define aa_verbose(X...) \ do { \ if (opt_verbose) { \ fprintf(g_outfile, X); \ } \ } while (0) #define aa_error(X, Y...) \ do { \ if (X) { \ fprintf(g_outfile, "aborting: " Y); \ exit(-1); \ } \ } while (0) /* Internationalization support. Can be defined in Makefile */ #ifndef PACKAGE #define PACKAGE "apparmor" #endif #ifndef LOCALEDIR #define LOCALEDIR "" #endif const char *g_version = "3.0"; const char *g_copyright = "Copyright (C) 2013 Canonical Ltd."; FILE *g_outfile; char *g_progname; int opt_immediate; int opt_verbose; char *opt_debug; char *opt_file; char *opt_profile; char *opt_namespace; const char *g_options = "Options:\n" "--------\n" "-p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n" "-n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n" "-f FILE, --file=FILE profile file to load\n" "-i, --immediate change profile immediately instead of at exec\n" "-v, --verbose show messages with stats\n" "-d FILE, --debug=FILE dump verbose output to FILE\n" "-h, --help display this help\n"; const char *short_options = "d:hp:n:f:iv"; struct option long_options[] = { {"debug", 1, 0, 'd'}, {"help", 0, 0, 'h'}, {"profile", 1, 0, 'p'}, {"namespace", 1, 0, 'n'}, {"file", 1, 0, 'f'}, {"immediate", 0, 0, 'i'}, {"verbose", 0, 0, 'v'}, {"Version", 0, 0, 'V'}, {NULL, 0, 0, 0}, }; static void display_version(void) { printf("%s version %s\n%s\n", g_progname, g_version, g_copyright); } static void display_usage(void) { display_version(); printf("\nUsage: %s [options] [--] <prog> <args>\n\n%s", g_progname, g_options); } static void process_args(int argc, char *argv[]) { int c, o; int count = 0; while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1) { switch (c) { case 0: display_usage(); exit(0); break; case 'V': display_version(); break; case 'd': opt_verbose = 1; opt_debug = optarg; break; case 'h': display_usage(); exit(0); break; case 'p': opt_profile = optarg; break; case 'n': opt_namespace = optarg; break; case 'f': opt_file = optarg; break; case 'i': opt_immediate = 1; break; case 'v': opt_verbose = 1; break; default: printf("Unknown option %c\n\n", c); display_usage(); exit(0); break; } count++; } } int main(int argc, char *argv[]) { int rc = 0; char *profile = NULL; /* name of executable, for error reporting and usage display */ g_progname = argv[0]; g_outfile = stderr; setlocale(LC_MESSAGES, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); process_args(argc, argv); if (opt_debug) { FILE *tmp = fopen(opt_debug, "w+"); aa_error(tmp == NULL, "could not open debug file %s\n", opt_debug); aa_error(setvbuf(tmp, NULL, _IONBF, 0) != 0, "could not set debug file %s to unbuffered\n", opt_debug); g_outfile = tmp; } if (opt_namespace || opt_profile) { if (opt_namespace) { rc = asprintf(&profile, ":%s:%s", opt_namespace, opt_profile ? opt_profile : ""); aa_error(rc == -1, "%s", strerror(errno)); } else if (opt_profile) { rc = asprintf(&profile, "%s", opt_profile); aa_error(rc == -1, "%s", strerror(errno)); } if (opt_file) { char *cmd; rc = asprintf(&cmd, "apparmor_parser -r %s", opt_file); aa_error(rc == -1, "%s", strerror(errno)); aa_verbose("%s\n", cmd); rc = system(cmd); aa_error(rc == -1, "could not load file %s", opt_file); } if (opt_immediate) { aa_verbose("aa_change_profile(\"%s\")\n", profile); rc = aa_change_profile(profile); } else { aa_verbose("aa_change_onexec(\"%s\")\n", profile); rc = aa_change_onexec(profile); } if (rc == -1) { if (errno == ENOENT || errno == EACCES) aa_error(1, "\'%s\' does not exist", profile); else if (errno == EINVAL) aa_error(1, "AppArmor interface not available"); else aa_error(1, "%s", strerror(errno)); } } aa_verbose("exec %s\n", argv[optind]); (void)execvpe(argv[optind], &argv[optind], environ); /* exec failed, kill outselves to flag parent */ rc = errno; fprintf(g_outfile, "FAIL: exec to '%s' failed (%s)\n", argv[optind], strerror(errno)); return rc; } -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor