]> granicus.if.org Git - sudo/commitdiff
When checking aliases, also check the contents of the alias in case there
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 25 May 2011 17:04:13 +0000 (13:04 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 25 May 2011 17:04:13 +0000 (13:04 -0400)
are problems with an alias that is referenced inside another.
Replace the self reference check with real alias cycle detection.

plugins/sudoers/visudo.c

index 4d6e3f777109ed83259b74339dca037c3ab9f27d..43119e233c57e35517baedfe2e776a86d8dee974 100644 (file)
@@ -109,8 +109,6 @@ static int print_unused(void *, void *);
 static int reparse_sudoers(char *, char *, int, int);
 static int run_command(char *, char **);
 static int visudo_printf(int msg_type, const char *fmt, ...);
-static void print_selfref(char *name, int, int, int);
-static void print_undefined(char *name, int, int, int);
 static void setup_signals(void);
 static void help(void) __attribute__((__noreturn__));
 static void usage(int);
@@ -955,13 +953,8 @@ alias_remove_recursive(char *name, int type, int strict, int 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;
-               }
            }
        }
     }
@@ -972,6 +965,42 @@ alias_remove_recursive(char *name, int type, int strict, int quiet)
     return error;
 }
 
+static int
+check_alias(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.
@@ -993,38 +1022,26 @@ check_aliases(int strict, int 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);
                }
            }
        }
@@ -1102,34 +1119,6 @@ check_aliases(int strict, int quiet)
     return strict ? error : 0;
 }
 
-static void
-print_undefined(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(void *v1, void *v2)
 {