mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 18:17:09 +00:00
aa-status: add profile filter
Extend filtering to be able to screen for different profiles by name Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
ee66319d0b
commit
016183cbf4
@ -44,19 +44,23 @@ static const unsigned char aa_status_json_version[] = "2";
|
|||||||
|
|
||||||
struct filter_set {
|
struct filter_set {
|
||||||
regex_t mode;
|
regex_t mode;
|
||||||
|
regex_t profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
regex_t *mode;
|
regex_t *mode;
|
||||||
|
regex_t *profile;
|
||||||
} filters_t;
|
} filters_t;
|
||||||
|
|
||||||
static void init_filters(filters_t *filters, struct filter_set *base) {
|
static void init_filters(filters_t *filters, struct filter_set *base) {
|
||||||
filters->mode = &base->mode;
|
filters->mode = &base->mode;
|
||||||
|
filters->profile = &base->profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void free_filters(filters_t *filters)
|
static void free_filters(filters_t *filters)
|
||||||
{
|
{
|
||||||
regfree(filters->mode);
|
regfree(filters->mode);
|
||||||
|
regfree(filters->profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct profile {
|
struct profile {
|
||||||
@ -104,7 +108,7 @@ bool opt_json = false;
|
|||||||
bool opt_pretty = false;
|
bool opt_pretty = false;
|
||||||
bool opt_count = false;
|
bool opt_count = false;
|
||||||
const char *opt_mode = ".*";
|
const char *opt_mode = ".*";
|
||||||
|
const char *opt_profiles = ".*";
|
||||||
|
|
||||||
const char *profile_statuses[] = {"enforce", "complain", "kill", "unconfined"};
|
const char *profile_statuses[] = {"enforce", "complain", "kill", "unconfined"};
|
||||||
const char *process_statuses[] = {"enforce", "complain", "kill", "unconfined", "mixed"};
|
const char *process_statuses[] = {"enforce", "complain", "kill", "unconfined", "mixed"};
|
||||||
@ -246,7 +250,9 @@ static int filter_profiles(struct profile *profiles,
|
|||||||
*nfiltered = 0;
|
*nfiltered = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (regexec(filters->mode, profiles[i].status, 0, NULL, 0) == 0) {
|
if (regexec(filters->mode, profiles[i].status, 0, NULL, 0) != 0)
|
||||||
|
continue;
|
||||||
|
if (regexec(filters->profile, profiles[i].name, 0, NULL, 0) == 0) {
|
||||||
struct profile *_filtered = realloc(*filtered, (*nfiltered + 1) * sizeof(**filtered));
|
struct profile *_filtered = realloc(*filtered, (*nfiltered + 1) * sizeof(**filtered));
|
||||||
if (_filtered == NULL) {
|
if (_filtered == NULL) {
|
||||||
free_profiles(*filtered, *nfiltered);
|
free_profiles(*filtered, *nfiltered);
|
||||||
@ -417,7 +423,10 @@ static int filter_processes(struct process *processes,
|
|||||||
*nfiltered = 0;
|
*nfiltered = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (regexec(filters->mode, processes[i].mode, 0, NULL, 0) == 0) {
|
if (regexec(filters->mode, processes[i].mode, 0, NULL, 0) != 0)
|
||||||
|
continue;
|
||||||
|
if (regexec(filters->profile, processes[i].profile, 0, NULL, 0) == 0)
|
||||||
|
{
|
||||||
struct process *_filtered = realloc(*filtered, (*nfiltered + 1) * sizeof(**filtered));
|
struct process *_filtered = realloc(*filtered, (*nfiltered + 1) * sizeof(**filtered));
|
||||||
if (_filtered == NULL) {
|
if (_filtered == NULL) {
|
||||||
free_processes(*filtered, *nfiltered);
|
free_processes(*filtered, *nfiltered);
|
||||||
@ -690,6 +699,7 @@ static int usage_filters(void)
|
|||||||
"support filters are below\n\n"
|
"support filters are below\n\n"
|
||||||
" --mode: regular expression to match the profile mode"
|
" --mode: regular expression to match the profile mode"
|
||||||
" modes: enforce, complain, kill, unconfined, mixed\n"
|
" modes: enforce, complain, kill, unconfined, mixed\n"
|
||||||
|
" --profiles: regular expression to match displayed profile names\n"
|
||||||
);
|
);
|
||||||
for (i = 0; i < ARRAY_SIZE(process_statuses); i++) {
|
for (i = 0; i < ARRAY_SIZE(process_statuses); i++) {
|
||||||
printf("%s%s", i ? ", " : "", process_statuses[i]);
|
printf("%s%s", i ? ", " : "", process_statuses[i]);
|
||||||
@ -718,6 +728,7 @@ static int print_usage(const char *command, bool error)
|
|||||||
" --count print the number of entries. Implies --quiet\n"
|
" --count print the number of entries. Implies --quiet\n"
|
||||||
" --mode=filter regular expression to match profile modes. see filters\n"
|
" --mode=filter regular expression to match profile modes. see filters\n"
|
||||||
" or a regular expression\n"
|
" or a regular expression\n"
|
||||||
|
" --profiles=filter which profiles to display. see filters\n"
|
||||||
" --json displays multiple data points in machine-readable JSON format\n"
|
" --json displays multiple data points in machine-readable JSON format\n"
|
||||||
" --pretty-json same data as --json, formatted for human consumption as well\n"
|
" --pretty-json same data as --json, formatted for human consumption as well\n"
|
||||||
" --verbose (default) displays data points about loaded policy set\n"
|
" --verbose (default) displays data points about loaded policy set\n"
|
||||||
@ -743,6 +754,7 @@ static int print_usage(const char *command, bool error)
|
|||||||
#define ARG_COUNT 138
|
#define ARG_COUNT 138
|
||||||
#define ARG_SHOW 139
|
#define ARG_SHOW 139
|
||||||
#define ARG_MODE 140
|
#define ARG_MODE 140
|
||||||
|
#define ARG_PROFILES 141
|
||||||
#define ARG_VERBOSE 'v'
|
#define ARG_VERBOSE 'v'
|
||||||
#define ARG_HELP 'h'
|
#define ARG_HELP 'h'
|
||||||
|
|
||||||
@ -763,6 +775,7 @@ static int parse_args(int argc, char **argv)
|
|||||||
{"help", 2, 0, ARG_HELP},
|
{"help", 2, 0, ARG_HELP},
|
||||||
{"count", no_argument, 0, ARG_COUNT},
|
{"count", no_argument, 0, ARG_COUNT},
|
||||||
{"show", 1, 0, ARG_SHOW},
|
{"show", 1, 0, ARG_SHOW},
|
||||||
|
{"profiles", 1, 0, ARG_PROFILES},
|
||||||
{"mode", 1, 0, ARG_MODE},
|
{"mode", 1, 0, ARG_MODE},
|
||||||
{NULL, 0, 0, 0},
|
{NULL, 0, 0, 0},
|
||||||
};
|
};
|
||||||
@ -853,6 +866,10 @@ static int parse_args(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ARG_PROFILES:
|
||||||
|
opt_profiles = optarg;
|
||||||
|
/* default opt_mode */
|
||||||
|
break;
|
||||||
case ARG_MODE:
|
case ARG_MODE:
|
||||||
opt_mode = optarg;
|
opt_mode = optarg;
|
||||||
break;
|
break;
|
||||||
@ -867,7 +884,6 @@ static int parse_args(int argc, char **argv)
|
|||||||
return optind;
|
return optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
autofree char *buffer = NULL; /* pretty print buffer */
|
autofree char *buffer = NULL; /* pretty print buffer */
|
||||||
@ -900,6 +916,11 @@ int main(int argc, char **argv)
|
|||||||
opt_mode);
|
opt_mode);
|
||||||
return AA_EXIT_INTERNAL_ERROR;
|
return AA_EXIT_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
if (regcomp(filters.profile, opt_profiles, REG_NOSUB) != 0) {
|
||||||
|
dfprintf(stderr, "Error: failed to compile profiles filter '%s'\n",
|
||||||
|
opt_profiles);
|
||||||
|
return AA_EXIT_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* check apparmor is available and we have permissions */
|
/* check apparmor is available and we have permissions */
|
||||||
ret = open_profiles(&fp);
|
ret = open_profiles(&fp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user