allow directories to be passed to the parser Allow directories to be passed directly to the parser and handled instead of needing an initscript to find the files in the directory.
Signed-off-by: John Johansen <john.johan...@canonical.com> --- parser/parser.h | 1 + parser/parser_include.c | 4 +-- parser/parser_include.h | 2 +- parser/parser_lex.l | 40 ---------------------------- parser/parser_main.c | 70 ++++++++++++++++++++++++++++++++++++++++++++----- parser/parser_misc.c | 41 +++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 49 deletions(-) diff --git a/parser/parser.h b/parser/parser.h index c1622c3..1dd9895 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -268,6 +268,7 @@ extern struct var_string *split_out_var(char *string); extern void free_var_string(struct var_string *var); /* parser_misc.c */ +extern int is_blacklisted(const char *name, const char *path); extern struct value_list *new_value_list(char *value); extern struct value_list *dup_value_list(struct value_list *list); extern void free_value_list(struct value_list *list); diff --git a/parser/parser_include.c b/parser/parser_include.c index 697fad3..88fe2d6 100644 --- a/parser/parser_include.c +++ b/parser/parser_include.c @@ -279,7 +279,7 @@ struct include_stack_t { struct include_stack_t *include_stack_head = NULL; -static void start_include_position(char *filename) +static void start_include_position(const char *filename) { if (current_filename) free(current_filename); @@ -323,7 +323,7 @@ void pop_include_stack(void) free(include); } -void reset_include_stack(char *filename) +void reset_include_stack(const char *filename) { while (include_stack_head) pop_include_stack(); diff --git a/parser/parser_include.h b/parser/parser_include.h index 08ea8aa..6a5b294 100644 --- a/parser/parser_include.h +++ b/parser/parser_include.h @@ -31,6 +31,6 @@ FILE *search_path(char *filename, char **fullpath); extern void push_include_stack(char *filename); extern void pop_include_stack(void); -extern void reset_include_stack(char *filename); +extern void reset_include_stack(const char *filename); #endif diff --git a/parser/parser_lex.l b/parser/parser_lex.l index 7e4574f..9a4bc6c 100644 --- a/parser/parser_lex.l +++ b/parser/parser_lex.l @@ -107,46 +107,6 @@ do { \ #define STATE_TABLE_ENT(X) [(X)] = #X /* static char *const state_names[]; */ -struct ignored_suffix_t { - const char * text; - int len; - int silent; -}; - -struct ignored_suffix_t ignored_suffixes[] = { - /* Debian packging files, which are in flux during install - should be silently ignored. */ - { ".dpkg-new", 9, 1 }, - { ".dpkg-old", 9, 1 }, - { ".dpkg-dist", 10, 1 }, - { ".dpkg-bak", 9, 1 }, - /* RPM packaging files have traditionally not been silently - ignored */ - { ".rpmnew", 7, 0 }, - { ".rpmsave", 8, 0 }, - /* Backup files should be mentioned */ - { "~", 1, 0 }, - { NULL, 0, 0 } -}; - -static int is_blacklisted(const char *name, const char *path) -{ - int name_len; - struct ignored_suffix_t *suffix; - name_len = strlen(name); - /* skip blacklisted suffixes */ - for (suffix = ignored_suffixes; suffix->text; suffix++) { - char *found; - if ( (found = strstr((char *) name, suffix->text)) && - found - name + suffix->len == name_len ) { - if (!suffix->silent) - PERROR("Ignoring: '%s'\n", path); - return 1; - } - } - - return 0; -} struct cb_struct { const char *fullpath; diff --git a/parser/parser_main.c b/parser/parser_main.c index 75f318f..e3af8a8 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -822,7 +822,7 @@ fail: return; } -int process_binary(int option, char *profilename) +int process_binary(int option, const char *profilename) { char *buffer = NULL; int retval = 0, size = 0, asize = 0, rsize; @@ -883,7 +883,7 @@ int process_binary(int option, char *profilename) return retval; } -void reset_parser(char *filename) +void reset_parser(const char *filename) { memset(&mru_tstamp, 0, sizeof(mru_tstamp)); free_aliases(); @@ -928,7 +928,7 @@ void update_mru_tstamp(FILE *file) mru_tstamp = stat_file.st_ctim; } -int process_profile(int option, char *profilename) +int process_profile(int option, const char *profilename) { struct stat stat_bin; int retval = 0; @@ -953,11 +953,11 @@ int process_profile(int option, char *profilename) if (profilename && option != OPTION_REMOVE) { /* make decisions about disabled or complain-mode profiles */ - basename = strrchr(profilename, '/'); + basename = (char *) strrchr(profilename, '/'); if (basename) basename++; else - basename = profilename; + basename = (char *) profilename; if (test_for_dir_mode(basename, "disable")) { if (!conf_quiet) @@ -1106,6 +1106,48 @@ out: return retval; } +/* data - name of parent dir */ +static int profile_dir_cb(__unused DIR *dir, const char *name, struct stat *st, + void *data) +{ + int rc = 0; + + /* skip dot files and files with no name */ + if (*name == '.' || !strlen(name)) + return 0; + + if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { + const char *dirname = (const char *)data; + char *path; + if (asprintf(&path, "%s/%s", dirname, name) < 0) + PERROR(_("Out of memory")); + rc = process_profile(option, path); + free(path); + } + return rc; +} + +/* data - name of parent dir */ +static int binary_dir_cb(__unused DIR *dir, const char *name, struct stat *st, + void *data) +{ + int rc = 0; + + /* skip dot files and files with no name */ + if (*name == '.' || !strlen(name)) + return 0; + + if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { + const char *dirname = (const char *)data; + char *path; + if (asprintf(&path, "%s/%s", dirname, name) < 0) + PERROR(_("Out of memory")); + rc = process_binary(option, name); + free(path); + } + return rc; +} + static int clear_cache_cb(DIR *dir, const char *path, struct stat *st, __unused void *data) { @@ -1254,6 +1296,8 @@ int main(int argc, char *argv[]) retval = 0; for (i = optind; retval == 0 && i <= argc; i++) { + struct stat stat_file; + if (i < argc && !(profilename = strdup(argv[i]))) { perror("strdup"); return -1; @@ -1262,7 +1306,21 @@ int main(int argc, char *argv[]) if (i == argc && optind != argc) continue; - if (binary_input) { + if (stat(profilename, &stat_file) == -1) { + PERROR("File %s not found, skipping...\n", profilename); + continue; + } + + if (S_ISDIR(stat_file.st_mode)) { + int (*cb)(DIR *dir, const char *name, struct stat *st, + void *data); + cb = binary_input ? binary_dir_cb : profile_dir_cb; + if (dirat_for_each(NULL, profilename, profilename, cb)) { + PDEBUG("Failed loading profiles from %s\n", + profilename); + exit(1); + } + } else if (binary_input) { retval = process_binary(option, profilename); } else { retval = process_profile(option, profilename); diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 67a7779..e3b9d6a 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -51,6 +51,47 @@ #endif #define NPDEBUG(fmt, args...) /* Do nothing */ +struct ignored_suffix_t { + const char * text; + int len; + int silent; +}; + +static struct ignored_suffix_t ignored_suffixes[] = { + /* Debian packging files, which are in flux during install + should be silently ignored. */ + { ".dpkg-new", 9, 1 }, + { ".dpkg-old", 9, 1 }, + { ".dpkg-dist", 10, 1 }, + { ".dpkg-bak", 9, 1 }, + /* RPM packaging files have traditionally not been silently + ignored */ + { ".rpmnew", 7, 0 }, + { ".rpmsave", 8, 0 }, + /* Backup files should be mentioned */ + { "~", 1, 0 }, + { NULL, 0, 0 } +}; + +int is_blacklisted(const char *name, const char *path) +{ + int name_len; + struct ignored_suffix_t *suffix; + name_len = strlen(name); + /* skip blacklisted suffixes */ + for (suffix = ignored_suffixes; suffix->text; suffix++) { + char *found; + if ( (found = strstr((char *) name, suffix->text)) && + found - name + suffix->len == name_len ) { + if (!suffix->silent) + PERROR("Ignoring: '%s'\n", path ? path : name); + return 1; + } + } + + return 0; +} + struct keyword_table { const char *keyword; int token; -- 1.8.3.2 -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor