mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 01:57:43 +00:00
allow multiple profiles to be parsed from the command line
Signed-Off-By: Kees Cook <kees.cook@canonical.com>
This commit is contained in:
parent
af902dddf1
commit
33d01a980a
@ -219,6 +219,9 @@ extern int yyparse(void);
|
||||
extern void yyerror(char *msg, ...);
|
||||
extern int yylex(void);
|
||||
|
||||
/* parser_include.c */
|
||||
extern char *basedir;
|
||||
|
||||
/* parser_regex.c */
|
||||
extern int process_regex(struct codomain *cod);
|
||||
extern int post_process_entry(struct cod_entry *entry);
|
||||
|
@ -67,67 +67,16 @@ static char *path[MAX_PATH] = { NULL };
|
||||
static int npath = 0;
|
||||
|
||||
static int fgetline(FILE * f, char *buffer, size_t len);
|
||||
static int getincludestr(char **inc, int c, FILE *f, int line, char *name,
|
||||
FILE *out);
|
||||
static int stripcomment(char *s);
|
||||
static char *stripblanks(char *s);
|
||||
static int preprocess(FILE *f, char *name, FILE * out, int nest);
|
||||
|
||||
int preprocess_only;
|
||||
|
||||
/* default base directory is /etc/subdomain.d, it can be overriden
|
||||
with the -b option. */
|
||||
|
||||
static char *basedir;
|
||||
char *basedir;
|
||||
static char *default_basedir = "/etc/apparmor.d";
|
||||
static char *old_basedir = "/etc/subdomain.d";
|
||||
|
||||
/* start parsing. */
|
||||
int do_include_preprocessing(char *profilename)
|
||||
{
|
||||
int retval = 0;
|
||||
FILE *tmp, *profile = NULL;
|
||||
|
||||
if (profilename) {
|
||||
profile = fopen(profilename, "r");
|
||||
if (!profile) {
|
||||
PERROR(_("Error: Could not read profile %s: %s.\n"),
|
||||
profilename, strerror(errno));
|
||||
exit(errno);
|
||||
}
|
||||
} else {
|
||||
profile = stdin;
|
||||
}
|
||||
|
||||
/* Change to the base dir */
|
||||
chdir(basedir);
|
||||
|
||||
if (preprocess_only) {
|
||||
retval = preprocess(profile, profilename ? profilename : "stdin",
|
||||
stdout, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmpfile();
|
||||
if (!tmp) {
|
||||
PERROR(_("Error: Could not allocate temporary file.\n"));
|
||||
exit(10);
|
||||
}
|
||||
|
||||
retval = preprocess(profile, profilename ? profilename : "stdin",
|
||||
tmp, 0);
|
||||
|
||||
rewind(tmp);
|
||||
|
||||
dup2(fileno(tmp), 0); /* stdin */
|
||||
fclose(tmp);
|
||||
|
||||
out:
|
||||
if (profilename)
|
||||
fclose(profile);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* set up basedir so that it can be overridden/used later. */
|
||||
void init_base_dir(void)
|
||||
@ -258,233 +207,24 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
const char incword[] = "include";
|
||||
|
||||
/* getincludestr:
|
||||
* returns !0 if error occurred
|
||||
* include string (or not) is returned in 'inc'
|
||||
*/
|
||||
static int getincludestr(char **inc, int c, FILE *f, int line, char *name,
|
||||
FILE *out)
|
||||
{
|
||||
char *b;
|
||||
size_t i = 0, a;
|
||||
int d;
|
||||
int retval = 0;
|
||||
|
||||
*inc = NULL;
|
||||
|
||||
if (c != '#')
|
||||
return retval;
|
||||
|
||||
/* we either have a comment or an include, either process the include
|
||||
or strip the comment to the eol. Leave the eol char so line count
|
||||
gets properly incremented. */
|
||||
|
||||
for (i = 0; i < strlen(incword); i++) {
|
||||
c = fgetc(f);
|
||||
if (c == EOF || c == '\n' || c != incword[i]) {
|
||||
ungetc(c, f);
|
||||
goto comment;
|
||||
}
|
||||
}
|
||||
|
||||
/* found "#include" now search for the file name to include */
|
||||
b = malloc(2048);
|
||||
if (!b) {
|
||||
PERROR(_("Error: Could not allocate buffer for include at line %d in %s.\n"),
|
||||
line, name);
|
||||
retval = 1;
|
||||
goto comment;
|
||||
}
|
||||
|
||||
c = fgetc(f);
|
||||
if (!isspace(c)) {
|
||||
ungetc(c, f);
|
||||
goto comment;
|
||||
}
|
||||
|
||||
while ((c = fgetc(f)) != EOF && c != '\n' && isspace(c))
|
||||
/* eat whitespace */ ;
|
||||
if (c != '\"' && c != '<') {
|
||||
free(b);
|
||||
PERROR(_("Error: Bad include at line %d in %s.\n"), line, name);
|
||||
if (c == '\n')
|
||||
ungetc(c, f);
|
||||
retval = 1;
|
||||
goto comment;
|
||||
}
|
||||
|
||||
b[0] = c;
|
||||
i = 1;
|
||||
while ((d = fgetc(f)) != EOF && d != '\n'
|
||||
&& d != (c == '<' ? '>' : '\"') && i < 2048)
|
||||
b[i++] = d;
|
||||
|
||||
if (d == (c == '<' ? '>' : '\"')) {
|
||||
b[i] = 0;
|
||||
*inc = b;
|
||||
return retval;
|
||||
}
|
||||
|
||||
free(b);
|
||||
PERROR(_("Error: Bad include at line %d in %s.\n"), line, name);
|
||||
ungetc(d, f);
|
||||
retval = 1;
|
||||
/* fall through to comment - this makes trailing stuff a comment */
|
||||
|
||||
comment:
|
||||
fputc('#', out);
|
||||
for (a = 0; a < i; a++) {
|
||||
fputc(incword[a], out);
|
||||
}
|
||||
while ((c = fgetc(f)) != EOF && c != '\n')
|
||||
fputc(c, out);
|
||||
if (c == '\n')
|
||||
ungetc(c, f);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Find the include file or directory by searching the path. */
|
||||
static int process_include(char *inc, char *name, int line, FILE *out, int nest)
|
||||
FILE *search_path(char *filename, char **fullpath)
|
||||
{
|
||||
FILE *newf = NULL;
|
||||
int retval = 0;
|
||||
char *buf;
|
||||
struct stat my_stat;
|
||||
int err;
|
||||
|
||||
if (*inc == '\"') {
|
||||
buf = strdup(inc + 1);
|
||||
if (buf)
|
||||
newf = fopen(buf, "r");
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < npath; i++) {
|
||||
if (asprintf(&buf, "%s/%s", path[i], inc + 1) != -1) {
|
||||
newf = fopen(buf, "r");
|
||||
if (newf)
|
||||
break;
|
||||
free(buf);
|
||||
}
|
||||
buf = NULL;
|
||||
char *buf = NULL;
|
||||
int i;
|
||||
for (i = 0; i < npath; i++) {
|
||||
if (asprintf(&buf, "%s/%s", path[i], filename) < 0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
newf = fopen(buf, "r");
|
||||
if (newf && fullpath) *fullpath = buf;
|
||||
else free(buf);
|
||||
buf = NULL;
|
||||
if (newf)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newf) {
|
||||
PERROR(_("Error: #include %s%c not found at line %d in %s.\n"),
|
||||
inc,
|
||||
*inc == '<' ? '>' : '\"',
|
||||
line,
|
||||
name);
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = fstat(fileno(newf), &my_stat);
|
||||
if (err) {
|
||||
retval = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (S_ISREG(my_stat.st_mode)) {
|
||||
err = preprocess(newf, inc + 1, out, nest + 1);
|
||||
if (err)
|
||||
retval = err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (S_ISDIR(my_stat.st_mode)) {
|
||||
DIR *dir = NULL;
|
||||
struct dirent *dirent;
|
||||
|
||||
/* XXX - fdopendir not available in glibc < 2.4 */
|
||||
/* dir = fdopendir(fileno(newf)); */
|
||||
fclose(newf);
|
||||
dir = opendir(buf);
|
||||
if (!dir) {
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
char *dirbuf;
|
||||
/* skip dotfiles. */
|
||||
if (dirent->d_name[0] == '.')
|
||||
continue;
|
||||
asprintf(&dirbuf, "%s/%s", buf, dirent->d_name);
|
||||
err = stat(dirbuf, &my_stat);
|
||||
if (err) {
|
||||
retval = errno;
|
||||
free(dirbuf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (S_ISREG(my_stat.st_mode)) {
|
||||
newf = fopen(dirbuf, "r");
|
||||
if (newf) {
|
||||
err = preprocess(newf, inc + 1, out, nest + 1);
|
||||
if (err)
|
||||
retval = err;
|
||||
fclose(newf);
|
||||
} else {
|
||||
retval = errno;
|
||||
}
|
||||
}
|
||||
free(dirbuf);
|
||||
}
|
||||
newf = NULL;
|
||||
closedir(dir);
|
||||
}
|
||||
out:
|
||||
if (buf)
|
||||
free(buf);
|
||||
if (newf)
|
||||
fclose(newf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int preprocess(FILE * f, char *name, FILE * out, int nest)
|
||||
{
|
||||
int line = 1;
|
||||
int c;
|
||||
int retval = 0;
|
||||
char *inc = NULL;
|
||||
char *cwd;
|
||||
|
||||
if (nest > MAX_NEST_LEVEL) {
|
||||
PERROR(_("Error: Exceeded %d levels of includes. Not processing %s include.\n"),
|
||||
MAX_NEST_LEVEL, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nest == 0) {
|
||||
fprintf(out, "\n#source %s\n", name);
|
||||
} else {
|
||||
fprintf(out, "\n#included %s\n", name);
|
||||
}
|
||||
|
||||
while ((c = fgetc(f)) != EOF) {
|
||||
int err = getincludestr(&inc, c, f, line, name, out);
|
||||
if (err)
|
||||
retval = err;
|
||||
if (inc) {
|
||||
cwd = get_current_dir_name();
|
||||
err = process_include(inc, name, line, out, nest);
|
||||
if (err)
|
||||
retval = err;
|
||||
chdir(cwd);
|
||||
free(cwd);
|
||||
free(inc);
|
||||
} else {
|
||||
if (c != '#')
|
||||
fputc(c, out);
|
||||
if (c == '\n')
|
||||
line++;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
return newf;
|
||||
}
|
||||
|
||||
/* get a line from the file. If it is to long truncate it. */
|
||||
|
@ -27,5 +27,6 @@ extern void init_base_dir(void);
|
||||
extern void set_base_dir(char *dir);
|
||||
extern void parse_default_paths(void);
|
||||
extern int do_include_preprocessing(char *profilename);
|
||||
FILE *search_path(char *filename, char **fullpath);
|
||||
|
||||
#endif
|
||||
|
@ -28,11 +28,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
#include "parser.h"
|
||||
#include "parser_include.h"
|
||||
#include "parser_yacc.h"
|
||||
|
||||
#ifdef PDEBUG
|
||||
#undef PDEBUG
|
||||
#endif
|
||||
/* #define DEBUG */
|
||||
#ifdef DEBUG
|
||||
#define PDEBUG(fmt, args...) printf("Lexer: " fmt, ## args)
|
||||
@ -43,6 +51,100 @@
|
||||
|
||||
int current_lineno = 1;
|
||||
|
||||
struct ignored_suffix_t {
|
||||
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 },
|
||||
/* 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 }
|
||||
};
|
||||
|
||||
void include_filename(char *filename, int search)
|
||||
{
|
||||
FILE *include_file = NULL;
|
||||
struct stat my_stat;
|
||||
char *fullpath = NULL;
|
||||
|
||||
if (search) include_file = search_path(filename, &fullpath);
|
||||
else {
|
||||
fullpath = strdup(filename);
|
||||
include_file = fopen(fullpath, "r");
|
||||
}
|
||||
|
||||
if (!include_file) yyerror(_("Could not open '%s'"), fullpath);
|
||||
|
||||
if (fstat(fileno(include_file), &my_stat))
|
||||
yyerror(_("fstat failed for '%s'"), fullpath);
|
||||
|
||||
if (S_ISREG(my_stat.st_mode)) {
|
||||
yyin = include_file;
|
||||
PDEBUG("Opened include \"%s\"\n", fullpath);
|
||||
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
|
||||
}
|
||||
|
||||
if (S_ISDIR(my_stat.st_mode)) {
|
||||
DIR *dir = NULL;
|
||||
char *dirent_path = NULL;
|
||||
struct dirent *dirent;
|
||||
|
||||
PDEBUG("Opened include directory \"%s\"\n", fullpath);
|
||||
if (!(dir = opendir(fullpath)))
|
||||
yyerror(_("opendir failed '%s'"), fullpath);
|
||||
fclose(include_file);
|
||||
include_file = NULL;
|
||||
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
int name_len;
|
||||
struct ignored_suffix_t *suffix;
|
||||
/* skip dotfiles silently. */
|
||||
if (dirent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if (dirent_path) free(dirent_path);
|
||||
if (asprintf(&dirent_path, "%s/%s", fullpath, dirent->d_name)<0)
|
||||
yyerror("Out of memory");
|
||||
|
||||
name_len = strlen(dirent->d_name);
|
||||
/* skip blacklisted suffixes */
|
||||
for (suffix = ignored_suffixes; suffix->text; suffix++) {
|
||||
char *found;
|
||||
if ( (found = strstr(dirent->d_name, suffix->text)) &&
|
||||
found - dirent->d_name + suffix->len == name_len ) {
|
||||
name_len = 0;
|
||||
if (!suffix->silent)
|
||||
PERROR("Ignoring: '%s'\n", dirent_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!name_len) continue;
|
||||
|
||||
if (stat(dirent_path, &my_stat))
|
||||
yyerror(_("stat failed for '%s'"), dirent_path);
|
||||
if (S_ISREG(my_stat.st_mode)) {
|
||||
if (!(yyin = fopen(dirent_path,"r")))
|
||||
yyerror(_("Could not open '%s'"), filename);
|
||||
PDEBUG("Opened include \"%s\"\n", filename);
|
||||
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
|
||||
}
|
||||
}
|
||||
if (dirent_path) free(dirent_path);
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
UP "^"
|
||||
@ -88,9 +190,39 @@ LT_EQUAL <=
|
||||
%x ASSIGN_MODE
|
||||
%x RLIMIT_MODE
|
||||
%x CHANGE_PROFILE_MODE
|
||||
%x INCLUDE
|
||||
|
||||
%%
|
||||
|
||||
<INCLUDE>{
|
||||
{WS}+ { /* Eat whitespace */ }
|
||||
\<([^\> \t\n]+)\> { /* <filename> */
|
||||
char *filename = strdup(yytext);
|
||||
filename[strlen(filename)-1]='\0';
|
||||
include_filename(filename+1, 1);
|
||||
free(filename);
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
\"([^\" \t\n]+)\" { /* "filename" */
|
||||
char *filename = strdup(yytext);
|
||||
filename[strlen(filename)-1]='\0';
|
||||
include_filename(filename+1, 0);
|
||||
free(filename);
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
[^\<\>\"{WS}]+ { /* filename */
|
||||
include_filename(yytext, 0);
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
yypop_buffer_state();
|
||||
if ( !YY_CURRENT_BUFFER ) yyterminate();
|
||||
}
|
||||
|
||||
<SUB_NAME>{
|
||||
{ID}+ {
|
||||
/* Ugh, this is a gross hack. I used to use
|
||||
@ -279,11 +411,18 @@ LT_EQUAL <=
|
||||
}
|
||||
}
|
||||
|
||||
#.*\n { /* Comment - ignore */
|
||||
#include/.*\r?\n { /* include */
|
||||
PDEBUG("Matched #include\n");
|
||||
current_lineno++;
|
||||
PDEBUG("Line no++: %d\n", current_lineno);
|
||||
BEGIN(INCLUDE);
|
||||
}
|
||||
|
||||
#.*\r?\n { /* normal comment */
|
||||
PDEBUG("comment(%d): %s\n", current_lineno, yytext);
|
||||
current_lineno++;
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
{END_OF_RULE} { return TOK_END_OF_RULE; }
|
||||
|
||||
{SEPERATOR} {
|
||||
|
@ -49,7 +49,7 @@
|
||||
#define PCRE "pattern=pcre"
|
||||
#define AADFA "pattern=aadfa"
|
||||
|
||||
#define UNPRIVILEGED_OPS (debug || preprocess_only || option == OPTION_STDOUT || names_only || \
|
||||
#define UNPRIVILEGED_OPS (debug || option == OPTION_STDOUT || names_only || \
|
||||
dump_vars || dump_expanded_vars)
|
||||
|
||||
const char *parser_title = "Novell/SUSE AppArmor parser";
|
||||
@ -57,7 +57,7 @@ const char *parser_copyright = "Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006
|
||||
|
||||
char *progname;
|
||||
int option = OPTION_ADD;
|
||||
int force_complain = 0;
|
||||
int opt_force_complain = 0;
|
||||
int binary_input = 0;
|
||||
int names_only = 0;
|
||||
int dump_vars = 0;
|
||||
@ -70,16 +70,18 @@ int read_implies_exec = 0;
|
||||
#endif
|
||||
|
||||
char *subdomainbase = NULL;
|
||||
char *profilename;
|
||||
char *match_string = NULL;
|
||||
char *flags_string = NULL;
|
||||
int regex_type = AARE_DFA;
|
||||
char *profile_namespace = NULL;
|
||||
int flag_changehat_version = FLAG_CHANGEHAT_1_5;
|
||||
|
||||
|
||||
extern int current_lineno;
|
||||
|
||||
/* per-profile settings */
|
||||
int force_complain = 0;
|
||||
char *profilename = NULL;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"add", 0, 0, 'a'},
|
||||
{"binary", 0, 0, 'B'},
|
||||
@ -90,7 +92,6 @@ struct option long_options[] = {
|
||||
{"replace", 0, 0, 'r'},
|
||||
{"reload", 0, 0, 'r'}, /* undocumented reload option == replace */
|
||||
{"version", 0, 0, 'v'},
|
||||
{"preprocess", 0, 0, 'p'},
|
||||
{"complain", 0, 0, 'C'},
|
||||
{"Complain", 0, 0, 'C'}, /* Erk, apparently documented as --Complain */
|
||||
{"dump-variables", 0, 0, 'D'},
|
||||
@ -125,7 +126,6 @@ static void display_usage(char *command)
|
||||
"-R, --remove Remove apparmor definitions\n"
|
||||
"-C, --Complain Force the profile into complain mode\n"
|
||||
"-B, --binary Input is precompiled profile\n"
|
||||
"-p, --preprocess Dump profiles with includes expanded\n"
|
||||
"-N, --names Dump names of profiles in input.\n"
|
||||
"-S, --stdout Dump compiled profile to stdout\n"
|
||||
"-b n, --base n Set base dir and cwd\n"
|
||||
@ -199,10 +199,6 @@ static int process_args(int argc, char *argv[])
|
||||
display_version();
|
||||
exit(0);
|
||||
break;
|
||||
case 'p':
|
||||
count++;
|
||||
preprocess_only = 1;
|
||||
break;
|
||||
case 'I':
|
||||
add_search_dir(optarg);
|
||||
break;
|
||||
@ -213,7 +209,7 @@ static int process_args(int argc, char *argv[])
|
||||
binary_input =1;
|
||||
break;
|
||||
case 'C':
|
||||
force_complain = 1;
|
||||
opt_force_complain = 1;
|
||||
break;
|
||||
case 'N':
|
||||
names_only = 1;
|
||||
@ -251,27 +247,14 @@ static int process_args(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
PERROR("%s: Too many options given on the command line.\n",
|
||||
PERROR("%s: Too many actions given on the command line.\n",
|
||||
progname);
|
||||
goto abort;
|
||||
display_usage(progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PDEBUG("optind = %d argc = %d\n", optind, argc);
|
||||
if (optind < argc) {
|
||||
/* we only support one profile at a time */
|
||||
if (argc - optind == 1) {
|
||||
PDEBUG("Using profile in '%s'\n", argv[optind]);
|
||||
profilename = strndup(argv[optind], PATH_MAX);
|
||||
} else {
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
|
||||
return option;
|
||||
|
||||
abort:
|
||||
display_usage(progname);
|
||||
exit(1);
|
||||
return optind;
|
||||
}
|
||||
|
||||
static inline char *try_subdomainfs_mountpoint(const char *mntpnt,
|
||||
@ -490,16 +473,83 @@ int process_binary(int option, char *profilename)
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (!conf_quiet) {
|
||||
switch (option) {
|
||||
case OPTION_ADD:
|
||||
printf(_("Cached load succeeded for \"%s\".\n"),
|
||||
profilename ? profilename : "stdin");
|
||||
break;
|
||||
case OPTION_REPLACE:
|
||||
printf(_("Cached reload succeeded for \"%s\".\n"),
|
||||
profilename ? profilename : "stdin");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void reset_parser(void)
|
||||
{
|
||||
free_aliases();
|
||||
free_symtabs();
|
||||
free_policies();
|
||||
reset_regex();
|
||||
}
|
||||
|
||||
int process_profile(int option, char *profilename)
|
||||
{
|
||||
struct stat stat_text;
|
||||
struct stat stat_bin;
|
||||
int retval = 0;
|
||||
|
||||
retval = do_include_preprocessing(profilename);
|
||||
if (preprocess_only || retval != 0)
|
||||
return retval;
|
||||
/* per-profile states */
|
||||
force_complain = opt_force_complain;
|
||||
|
||||
if ( profilename ) {
|
||||
if ( !(yyin = fopen(profilename, "r")) ) {
|
||||
PERROR(_("Error: Could not read profile %s: %s.\n"),
|
||||
profilename, strerror(errno));
|
||||
exit(errno);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PERROR("%s: cannot disable or force-complain via stdin\n", progname);
|
||||
}
|
||||
|
||||
if ( profilename && option != OPTION_REMOVE ) {
|
||||
/* make decisions about disabled or complain-mode profiles */
|
||||
char *target = NULL;
|
||||
char *basename = strrchr(profilename, '/');
|
||||
if (basename) basename++;
|
||||
else basename = profilename;
|
||||
|
||||
if (asprintf(&target, "%s/%s/%s", basedir, "disable", basename)<0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
if (access(target, R_OK) == 0) {
|
||||
PERROR("Skipped: %s\n", target);
|
||||
free(target);
|
||||
goto out;
|
||||
}
|
||||
free(target);
|
||||
|
||||
if (asprintf(&target, "%s/%s/%s", basedir, "force-complain", basename)<0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
if (access(target, R_OK) == 0) {
|
||||
PERROR("Warning: found %s, forcing complain mode\n", target);
|
||||
force_complain = 1;
|
||||
}
|
||||
free(target);
|
||||
}
|
||||
|
||||
if (yyin) yyrestart(yyin);
|
||||
reset_parser();
|
||||
|
||||
retval = yyparse();
|
||||
if (retval != 0)
|
||||
@ -517,7 +567,7 @@ int process_profile(int option, char *profilename)
|
||||
retval = post_process_policy();
|
||||
if (retval != 0) {
|
||||
PERROR(_("%s: Errors found in file. Aborting.\n"), progname);
|
||||
return retval;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dump_vars) {
|
||||
@ -550,14 +600,15 @@ out:
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int retval;
|
||||
int option;
|
||||
int i;
|
||||
int optind;
|
||||
|
||||
/* name of executable, for error reporting and usage display */
|
||||
progname = argv[0];
|
||||
|
||||
init_base_dir();
|
||||
|
||||
option = process_args(argc, argv);
|
||||
optind = process_args(argc, argv);
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
@ -575,11 +626,26 @@ int main(int argc, char *argv[])
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (binary_input) {
|
||||
retval = process_binary(option, profilename);
|
||||
} else {
|
||||
parse_default_paths();
|
||||
retval = process_profile(option, profilename);
|
||||
if (!binary_input) parse_default_paths();
|
||||
|
||||
retval = 0;
|
||||
for (i = optind; retval == 0 && i <= argc; i++) {
|
||||
if (i < argc && !(profilename = strdup(argv[i]))) {
|
||||
perror("strdup");
|
||||
return -1;
|
||||
}
|
||||
/* skip stdin if we've seen other command line arguments */
|
||||
if (i == argc && optind != argc)
|
||||
continue;
|
||||
|
||||
if (binary_input) {
|
||||
retval = process_binary(option, profilename);
|
||||
} else {
|
||||
retval = process_profile(option, profilename);
|
||||
}
|
||||
|
||||
if (profilename) free(profilename);
|
||||
profilename = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
Loading…
x
Reference in New Issue
Block a user