version 1.28, 2010/03/04 12:21:36 |
version 1.29, 2010/06/02 19:30:10 |
|
|
static int print_unused __P((void *, void *)); |
static int print_unused __P((void *, void *)); |
static int reparse_sudoers __P((char *, char *, int, int)); |
static int reparse_sudoers __P((char *, char *, int, int)); |
static int run_command __P((char *, char **)); |
static int run_command __P((char *, char **)); |
static void print_undefined __P((char *name, int, int, int)); |
static void print_selfref __P((char *, int, int, int)); |
|
static void print_undefined __P((char *, int, int, int)); |
static void setup_signals __P((void)); |
static void setup_signals __P((void)); |
static void usage __P((void)) __attribute__((__noreturn__)); |
static void usage __P((void)) __attribute__((__noreturn__)); |
|
|
|
|
|
|
/* Parse the sudoers temp file */ |
/* Parse the sudoers temp file */ |
yyrestart(fp); |
yyrestart(fp); |
if (yyparse() && parse_error != TRUE) { |
if (yyparse() && !parse_error) { |
warningx("unabled to parse temporary file (%s), unknown error", |
warningx("unabled to parse temporary file (%s), unknown error", |
sp->tpath); |
sp->tpath); |
parse_error = TRUE; |
parse_error = TRUE; |
|
errorfile = sp->path; |
} |
} |
fclose(yyin); |
fclose(yyin); |
if (check_aliases(strict, quiet) != 0) |
if (!parse_error && check_aliases(strict, quiet) != 0) { |
parse_error = TRUE; |
parse_error = TRUE; |
|
errorfile = sp->path; |
|
} |
|
|
/* |
/* |
* Got an error, prompt the user for what to do now |
* Got an error, prompt the user for what to do now |
|
|
exit(1); |
exit(1); |
} |
} |
init_parser(sudoers_path, quiet); |
init_parser(sudoers_path, quiet); |
if (yyparse() && parse_error != TRUE) { |
if (yyparse() && !parse_error) { |
if (!quiet) |
if (!quiet) |
warningx("failed to parse %s file, unknown error", sudoers_path); |
warningx("failed to parse %s file, unknown error", sudoers_path); |
parse_error = TRUE; |
parse_error = TRUE; |
|
errorfile = sudoers_path; |
} |
} |
if (!parse_error) { |
if (!parse_error && check_aliases(strict, quiet) != 0) { |
if (check_aliases(strict, quiet) != 0) |
parse_error = TRUE; |
parse_error = TRUE; |
errorfile = sudoers_path; |
} |
} |
error = parse_error; |
error = parse_error; |
if (!quiet) { |
if (!quiet) { |
if (parse_error) |
if (parse_error) { |
(void) printf("parse error in %s near line %d\n", errorfile, |
if (errorlineno != -1) |
errorlineno); |
(void) printf("parse error in %s near line %d\n", errorfile, |
else |
errorlineno); |
|
else |
|
(void) printf("parse error in %s\n", errorfile); |
|
} else { |
(void) printf("%s: parsed OK\n", sudoers_path); |
(void) printf("%s: parsed OK\n", sudoers_path); |
|
} |
} |
} |
/* Check mode and owner in strict mode. */ |
/* Check mode and owner in strict mode. */ |
#ifdef HAVE_FSTAT |
#ifdef HAVE_FSTAT |
|
|
} |
} |
} |
} |
|
|
static void |
static int |
alias_remove_recursive(name, type) |
alias_remove_recursive(name, type, strict, quiet) |
char *name; |
char *name; |
int type; |
int type; |
|
int strict; |
|
int quiet; |
{ |
{ |
struct member *m; |
struct member *m; |
struct alias *a; |
struct alias *a; |
|
int error = 0; |
|
|
if ((a = alias_find(name, type)) != NULL) { |
if ((a = alias_find(name, type)) != NULL) { |
tq_foreach_fwd(&a->members, m) { |
tq_foreach_fwd(&a->members, m) { |
if (m->type == ALIAS) { |
if (m->type == ALIAS) { |
alias_remove_recursive(m->name, type); |
if (strcmp(name, m->name) == 0) { |
|
print_selfref(m->name, type, strict, quiet); |
|
error = 1; |
|
} else { |
|
if (!alias_remove_recursive(m->name, type, strict, quiet)) |
|
error = 1; |
|
} |
} |
} |
} |
} |
} |
} |
|
|
a = alias_remove(name, type); |
a = alias_remove(name, type); |
if (a) |
if (a) |
rbinsert(alias_freelist, a); |
rbinsert(alias_freelist, a); |
|
return(error); |
} |
} |
|
|
/* |
/* |
|
|
tq_foreach_fwd(&userspecs, us) { |
tq_foreach_fwd(&userspecs, us) { |
tq_foreach_fwd(&us->users, m) { |
tq_foreach_fwd(&us->users, m) { |
if (m->type == ALIAS) { |
if (m->type == ALIAS) { |
(void) alias_remove_recursive(m->name, USERALIAS); |
if (!alias_remove_recursive(m->name, USERALIAS, strict, quiet)) |
|
error++; |
} |
} |
} |
} |
tq_foreach_fwd(&us->privileges, priv) { |
tq_foreach_fwd(&us->privileges, priv) { |
tq_foreach_fwd(&priv->hostlist, m) { |
tq_foreach_fwd(&priv->hostlist, m) { |
if (m->type == ALIAS) |
if (m->type == ALIAS) |
(void) alias_remove_recursive(m->name, HOSTALIAS); |
if (!alias_remove_recursive(m->name, HOSTALIAS, strict, |
|
quiet)) |
|
error++; |
} |
} |
tq_foreach_fwd(&priv->cmndlist, cs) { |
tq_foreach_fwd(&priv->cmndlist, cs) { |
tq_foreach_fwd(&cs->runasuserlist, m) { |
tq_foreach_fwd(&cs->runasuserlist, m) { |
if (m->type == ALIAS) |
if (m->type == ALIAS) |
(void) alias_remove_recursive(m->name, RUNASALIAS); |
if (!alias_remove_recursive(m->name, RUNASALIAS, |
|
strict, quiet)) |
|
error++; |
} |
} |
if ((m = cs->cmnd)->type == ALIAS) |
if ((m = cs->cmnd)->type == ALIAS) |
(void) alias_remove_recursive(m->name, CMNDALIAS); |
if (!alias_remove_recursive(m->name, CMNDALIAS, strict, |
|
quiet)) |
|
error++; |
} |
} |
} |
} |
} |
} |
|
|
tq_foreach_fwd(&d->binding, binding) { |
tq_foreach_fwd(&d->binding, binding) { |
for (m = binding; m != NULL; m = m->next) { |
for (m = binding; m != NULL; m = m->next) { |
if (m->type == ALIAS) |
if (m->type == ALIAS) |
(void) alias_remove_recursive(m->name, atype); |
if (!alias_remove_recursive(m->name, atype, strict, quiet)) |
|
error++; |
} |
} |
} |
} |
} |
} |
rbdestroy(alias_freelist, alias_free); |
rbdestroy(alias_freelist, alias_free); |
|
|
/* If all aliases were referenced we will have an empty tree. */ |
/* If all aliases were referenced we will have an empty tree. */ |
if (no_aliases()) |
if (!no_aliases() && !quiet) |
return(0); |
|
if (!quiet) { |
|
alias_apply(print_unused, strict ? "Error" : "Warning"); |
alias_apply(print_unused, strict ? "Error" : "Warning"); |
} |
|
return (strict ? 1 : 0); |
return (strict ? error : 0); |
} |
} |
|
|
static void |
static void |
|
|
{ |
{ |
if (!quiet) { |
if (!quiet) { |
warningx("%s: %s_Alias `%s' referenced but not defined", |
warningx("%s: %s_Alias `%s' referenced but not defined", |
|
strict ? "Error" : "Warning", |
|
type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" : |
|
type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" : |
|
"Unknown", name); |
|
} |
|
} |
|
|
|
static void |
|
print_selfref(name, type, strict, quiet) |
|
char *name; |
|
int type; |
|
int strict; |
|
int quiet; |
|
{ |
|
if (!quiet) { |
|
warningx("%s: %s_Alias `%s' references self", |
strict ? "Error" : "Warning", |
strict ? "Error" : "Warning", |
type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" : |
type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" : |
type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" : |
type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" : |