]> granicus.if.org Git - sudo/commitdiff
When checking aliases, also check the contents of the alias in case
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2011 18:42:57 +0000 (14:42 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2011 18:42:57 +0000 (14:42 -0400)
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

index b6d9d440c9140a5293f4b8d2d976e3d59da403a4..57cec798d4fbafaa308f3da9fbe64dcc124a53d7 100644 (file)
--- 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;