From 8ae51165b8b97a841880481e6382afa5f666e8d4 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 13 Aug 2011 14:42:57 -0400 Subject: [PATCH] When checking aliases, also check the contents of the alias in case there are problems with an alias that is referenced inside another. Replace the self reference check with real alias cycle detection. --HG-- branch : 1.7 --- visudo.c | 101 +++++++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/visudo.c b/visudo.c index b6d9d440c..57cec798d 100644 --- a/visudo.c +++ b/visudo.c @@ -107,8 +107,6 @@ static int install_sudoers __P((struct sudoersfile *, int)); static int print_unused __P((void *, void *)); static int reparse_sudoers __P((char *, char *, int, int)); static int run_command __P((char *, char **)); -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 help __P((void)) __attribute__((__noreturn__)); static void usage __P((int)); @@ -967,13 +965,8 @@ alias_remove_recursive(name, type, strict, quiet) if ((a = alias_find(name, type)) != NULL) { tq_foreach_fwd(&a->members, m) { if (m->type == ALIAS) { - if (strcmp(name, m->name) == 0) { - print_selfref(m->name, type, strict, quiet); + if (!alias_remove_recursive(m->name, type, strict, quiet)) error = 1; - } else { - if (!alias_remove_recursive(m->name, type, strict, quiet)) - error = 1; - } } } } @@ -984,6 +977,46 @@ alias_remove_recursive(name, type, strict, quiet) return error; } +static int +check_alias(name, type, strict, quiet) + char *name; + int type; + int strict; + int quiet; +{ + struct member *m; + struct alias *a; + int error = 0; + + if ((a = alias_find(name, type)) != NULL) { + /* check alias contents */ + tq_foreach_fwd(&a->members, m) { + if (m->type == ALIAS) + error += check_alias(m->name, type, strict, quiet); + } + } else { + if (!quiet) { + char *fmt; + if (errno == ELOOP) { + fmt = strict ? + "Error: cycle in %s_Alias `%s'" : + "Warning: cycle in %s_Alias `%s'"; + } else { + fmt = strict ? + "Error: %s_Alias `%s' referenced but not defined" : + "Warning: %s_Alias `%s' referenced but not defined"; + } + warningx(fmt, + type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" : + type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" : + "Unknown", name); + } + error++; + } + + return error; +} + /* * Iterate through the sudoers datastructures looking for undefined * aliases or unused aliases. @@ -1007,38 +1040,26 @@ check_aliases(strict, quiet) tq_foreach_fwd(&us->users, m) { if (m->type == ALIAS) { alias_seqno++; - if (alias_find(m->name, USERALIAS) == NULL) { - print_undefined(m->name, USERALIAS, strict, quiet); - error++; - } + error += check_alias(m->name, USERALIAS, strict, quiet); } } tq_foreach_fwd(&us->privileges, priv) { tq_foreach_fwd(&priv->hostlist, m) { if (m->type == ALIAS) { alias_seqno++; - if (alias_find(m->name, HOSTALIAS) == NULL) { - print_undefined(m->name, HOSTALIAS, strict, quiet); - error++; - } + error += check_alias(m->name, HOSTALIAS, strict, quiet); } } tq_foreach_fwd(&priv->cmndlist, cs) { tq_foreach_fwd(&cs->runasuserlist, m) { if (m->type == ALIAS) { alias_seqno++; - if (alias_find(m->name, RUNASALIAS) == NULL) { - print_undefined(m->name, RUNASALIAS, strict, quiet); - error++; - } + error += check_alias(m->name, RUNASALIAS, strict, quiet); } } if ((m = cs->cmnd)->type == ALIAS) { alias_seqno++; - if (alias_find(m->name, CMNDALIAS) == NULL) { - print_undefined(m->name, CMNDALIAS, strict, quiet); - error++; - } + error += check_alias(m->name, CMNDALIAS, strict, quiet); } } } @@ -1116,38 +1137,6 @@ check_aliases(strict, quiet) return strict ? error : 0; } -static void -print_undefined(name, type, strict, quiet) - char *name; - int type; - int strict; - int quiet; -{ - if (!quiet) { - 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", - type == HOSTALIAS ? "Host" : type == CMNDALIAS ? "Cmnd" : - type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" : - "Unknown", name); - } -} - static int print_unused(v1, v2) void *v1; -- 2.40.0