]> granicus.if.org Git - sudo/commitdiff
Refactor common alias code out of cvtsudoers and visudo and into alias.c.
authorTodd C. Miller <Todd.Miller@sudo.ws>
Mon, 2 Apr 2018 13:41:09 +0000 (07:41 -0600)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Mon, 2 Apr 2018 13:41:09 +0000 (07:41 -0600)
plugins/sudoers/alias.c
plugins/sudoers/cvtsudoers.c
plugins/sudoers/parse.h
plugins/sudoers/visudo.c

index efd380f7e3060a0e02eebd0606bffa75c7b983cb..1227deee2a05f24d81d7eea8885f4df49242f0c6 100644 (file)
@@ -237,3 +237,109 @@ alias_type_to_string(int alias_type)
        alias_type == RUNASALIAS ? "Runas_Alias" :
        "Invalid_Alias";
 }
+
+/*
+ * Remove the alias of the specified type as well as any other aliases
+ * referenced by that alias.  Stores removed aliases in a freelist.
+ */
+static bool
+alias_remove_recursive(char *name, int type, struct rbtree *freelist)
+{
+    struct member *m;
+    struct alias *a;
+    bool ret = true;
+    debug_decl(alias_remove_recursive, SUDOERS_DEBUG_ALIAS)
+
+    if ((a = alias_remove(name, type)) != NULL) {
+       TAILQ_FOREACH(m, &a->members, entries) {
+           if (m->type == ALIAS) {
+               if (!alias_remove_recursive(m->name, type, freelist))
+                   ret = false;
+           }
+       }
+       if (rbinsert(freelist, a, NULL) != 0)
+           ret = false;
+    }
+    debug_return_bool(ret);
+}
+
+/*
+ * Move all aliases referenced by userspecs to used_aliases.
+ */
+bool
+alias_find_used(struct rbtree *used_aliases)
+{
+    struct privilege *priv;
+    struct userspec *us;
+    struct cmndspec *cs;
+    struct defaults *d;
+    struct member *m;
+    int atype, errors = 0;
+    debug_decl(alias_find_used, SUDOERS_DEBUG_ALIAS)
+
+    /* Move referenced aliases to used_aliases. */
+    TAILQ_FOREACH(us, &userspecs, entries) {
+       TAILQ_FOREACH(m, &us->users, entries) {
+           if (m->type == ALIAS) {
+               if (!alias_remove_recursive(m->name, USERALIAS, used_aliases))
+                   errors++;
+           }
+       }
+       TAILQ_FOREACH(priv, &us->privileges, entries) {
+           TAILQ_FOREACH(m, &priv->hostlist, entries) {
+               if (m->type == ALIAS) {
+                   if (!alias_remove_recursive(m->name, HOSTALIAS, used_aliases))
+                       errors++;
+               }
+           }
+           TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+               if (cs->runasuserlist != NULL) {
+                   TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+                       if (m->type == ALIAS) {
+                           if (!alias_remove_recursive(m->name, RUNASALIAS, used_aliases))
+                               errors++;
+                       }
+                   }
+               }
+               if (cs->runasgrouplist != NULL) {
+                   TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+                       if (m->type == ALIAS) {
+                           if (!alias_remove_recursive(m->name, RUNASALIAS, used_aliases))
+                               errors++;
+                       }
+                   }
+               }
+               if ((m = cs->cmnd)->type == ALIAS) {
+                   if (!alias_remove_recursive(m->name, CMNDALIAS, used_aliases))
+                       errors++;
+               }
+           }
+       }
+    }
+    TAILQ_FOREACH(d, &defaults, entries) {
+       switch (d->type) {
+           case DEFAULTS_HOST:
+               atype = HOSTALIAS;
+               break;
+           case DEFAULTS_USER:
+               atype = USERALIAS;
+               break;
+           case DEFAULTS_RUNAS:
+               atype = RUNASALIAS;
+               break;
+           case DEFAULTS_CMND:
+               atype = CMNDALIAS;
+               break;
+           default:
+               continue; /* not an alias */
+       }
+       TAILQ_FOREACH(m, d->binding, entries) {
+           if (m->type == ALIAS) {
+               if (!alias_remove_recursive(m->name, atype, used_aliases))
+                   errors++;
+           }
+       }
+    }
+
+    debug_return_int(errors ? false : true);
+}
index 61ebb21731003e948862909b1cf818acccb3b9fb..4a3a5c3e12ae8445661afe555f8f18835dab235c 100644 (file)
@@ -81,13 +81,13 @@ static void usage(int);
 static bool convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf);
 static bool parse_sudoers(const char *input_file, struct cvtsudoers_config *conf);
 static bool cvtsudoers_parse_filter(char *expression);
-static bool alias_remove_unused(void);
 static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
 static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
 static int cvtsudoers_parse_defaults(char *expression);
 static int cvtsudoers_parse_suppression(char *expression);
 static void filter_userspecs(void);
 static void filter_defaults(struct cvtsudoers_config *conf);
+static void alias_remove_unused(void);
 
 int
 main(int argc, char *argv[])
@@ -892,122 +892,29 @@ filter_defaults(struct cvtsudoers_config *conf)
     debug_return;
 }
 
-/*
- * Remove the alias of the specified type as well as any other aliases
- * referenced by that alias.
- * XXX - share with visudo
- */
-static bool
-alias_remove_recursive(char *name, int type, struct rbtree *freelist)
-{
-    struct member *m;
-    struct alias *a;
-    bool ret = true;
-    debug_decl(alias_remove_recursive, SUDOERS_DEBUG_ALIAS)
-
-    if ((a = alias_remove(name, type)) != NULL) {
-       TAILQ_FOREACH(m, &a->members, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, type, freelist))
-                   ret = false;
-           }
-       }
-       if (rbinsert(freelist, a, NULL) != 0)
-           ret = false;
-    }
-    debug_return_bool(ret);
-}
-
 /*
  * Remove unreferenced aliases.
- * XXX - share with visudo
  */
-static bool
+static void
 alias_remove_unused(void)
 {
-    struct cmndspec *cs;
-    struct member *m;
-    struct privilege *priv;
-    struct userspec *us;
-    struct defaults *d;
-    int atype, errors = 0;
     struct rbtree *used_aliases;
     struct rbtree *unused_aliases;
     debug_decl(alias_remove_unused, SUDOERS_DEBUG_ALIAS)
 
     used_aliases = rbcreate(alias_compare);
-    if (used_aliases == NULL) {
-       sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
-       debug_return_int(-1);
-    }
+    if (used_aliases == NULL)
+       sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
 
-    /* Move referenced aliases to used_aliases. */
-    TAILQ_FOREACH(us, &userspecs, entries) {
-       TAILQ_FOREACH(m, &us->users, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, USERALIAS, used_aliases))
-                   errors++;
-           }
-       }
-       TAILQ_FOREACH(priv, &us->privileges, entries) {
-           TAILQ_FOREACH(m, &priv->hostlist, entries) {
-               if (m->type == ALIAS) {
-                   if (!alias_remove_recursive(m->name, HOSTALIAS, used_aliases))
-                       errors++;
-               }
-           }
-           TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
-               if (cs->runasuserlist != NULL) {
-                   TAILQ_FOREACH(m, cs->runasuserlist, entries) {
-                       if (m->type == ALIAS) {
-                           if (!alias_remove_recursive(m->name, RUNASALIAS, used_aliases))
-                               errors++;
-                       }
-                   }
-               }
-               if (cs->runasgrouplist != NULL) {
-                   TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
-                       if (m->type == ALIAS) {
-                           if (!alias_remove_recursive(m->name, RUNASALIAS, used_aliases))
-                               errors++;
-                       }
-                   }
-               }
-               if ((m = cs->cmnd)->type == ALIAS) {
-                   if (!alias_remove_recursive(m->name, CMNDALIAS, used_aliases))
-                       errors++;
-               }
-           }
-       }
-    }
-    TAILQ_FOREACH(d, &defaults, entries) {
-       switch (d->type) {
-           case DEFAULTS_HOST:
-               atype = HOSTALIAS;
-               break;
-           case DEFAULTS_USER:
-               atype = USERALIAS;
-               break;
-           case DEFAULTS_RUNAS:
-               atype = RUNASALIAS;
-               break;
-           case DEFAULTS_CMND:
-               atype = CMNDALIAS;
-               break;
-           default:
-               continue; /* not an alias */
-       }
-       TAILQ_FOREACH(m, d->binding, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, atype, used_aliases))
-                   errors++;
-           }
-       }
-    }
+    /* Move all referenced aliases to used_aliases. */
+    if (!alias_find_used(used_aliases))
+       sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+    /* Only unreferenced aliases are left, swap and free the unused ones. */
     unused_aliases = replace_aliases(used_aliases);
     rbdestroy(unused_aliases, alias_free);
 
-    debug_return_int(errors ? false : true);
+    debug_return;
 }
 
 /*
index 229cf5a7c4ca9c5a3c0693dc9a6fbaf3f97b4733..91555af917e8f4a5ead4557987307a90996767ca 100644 (file)
@@ -258,6 +258,7 @@ const char *alias_type_to_string(int alias_type);
 int alias_compare(const void *a1, const void *a2);
 struct alias *alias_get(char *name, int type);
 struct alias *alias_remove(char *name, int type);
+bool alias_find_used(struct rbtree *used_aliases);
 void alias_apply(int (*func)(void *, void *), void *cookie);
 void alias_free(void *a);
 void alias_put(struct alias *a);
index 749ea9c97a6c54d949571ec8262290f84f2c40f8..cf787fed3d3d6eff290cc2d99dccf49d6b812e3e 100644 (file)
@@ -109,7 +109,6 @@ extern void sudoersrestart(FILE *);
 struct sudo_user sudo_user;
 struct passwd *list_pw;
 static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist);
-static struct rbtree *alias_freelist;
 static bool checkonly;
 static const char short_opts[] =  "cf:hqsVx:";
 static struct option long_opts[] = {
@@ -1014,27 +1013,6 @@ open_sudoers(const char *path, bool doedit, bool *keepopen)
     debug_return_ptr(fp);
 }
 
-static bool
-alias_remove_recursive(char *name, int type)
-{
-    struct member *m;
-    struct alias *a;
-    bool ret = true;
-    debug_decl(alias_remove_recursive, SUDOERS_DEBUG_ALIAS)
-
-    if ((a = alias_remove(name, type)) != NULL) {
-       TAILQ_FOREACH(m, &a->members, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, type))
-                   ret = false;
-           }
-       }
-       if (rbinsert(alias_freelist, a, NULL) != 0)
-           ret = false;
-    }
-    debug_return_bool(ret);
-}
-
 static int
 check_alias(char *name, int type, char *file, int lineno, bool strict, bool quiet)
 {
@@ -1083,16 +1061,16 @@ check_alias(char *name, int type, char *file, int lineno, bool strict, bool quie
 static int
 check_aliases(bool strict, bool quiet)
 {
+    struct rbtree *used_aliases;
     struct cmndspec *cs;
     struct member *m;
     struct privilege *priv;
     struct userspec *us;
-    struct defaults *d;
-    int atype, errors = 0;
+    int errors = 0;
     debug_decl(check_aliases, SUDOERS_DEBUG_ALIAS)
 
-    alias_freelist = rbcreate(alias_compare);
-    if (alias_freelist == NULL) {
+    used_aliases = rbcreate(alias_compare);
+    if (used_aliases == NULL) {
        sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
        debug_return_int(-1);
     }
@@ -1138,69 +1116,9 @@ check_aliases(bool strict, bool quiet)
     }
 
     /* Reverse check (destructive) */
-    TAILQ_FOREACH(us, &userspecs, entries) {
-       TAILQ_FOREACH(m, &us->users, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, USERALIAS))
-                   errors++;
-           }
-       }
-       TAILQ_FOREACH(priv, &us->privileges, entries) {
-           TAILQ_FOREACH(m, &priv->hostlist, entries) {
-               if (m->type == ALIAS) {
-                   if (!alias_remove_recursive(m->name, HOSTALIAS))
-                       errors++;
-               }
-           }
-           TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
-               if (cs->runasuserlist != NULL) {
-                   TAILQ_FOREACH(m, cs->runasuserlist, entries) {
-                       if (m->type == ALIAS) {
-                           if (!alias_remove_recursive(m->name, RUNASALIAS))
-                               errors++;
-                       }
-                   }
-               }
-               if (cs->runasgrouplist != NULL) {
-                   TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
-                       if (m->type == ALIAS) {
-                           if (!alias_remove_recursive(m->name, RUNASALIAS))
-                               errors++;
-                       }
-                   }
-               }
-               if ((m = cs->cmnd)->type == ALIAS) {
-                   if (!alias_remove_recursive(m->name, CMNDALIAS))
-                       errors++;
-               }
-           }
-       }
-    }
-    TAILQ_FOREACH(d, &defaults, entries) {
-       switch (d->type) {
-           case DEFAULTS_HOST:
-               atype = HOSTALIAS;
-               break;
-           case DEFAULTS_USER:
-               atype = USERALIAS;
-               break;
-           case DEFAULTS_RUNAS:
-               atype = RUNASALIAS;
-               break;
-           case DEFAULTS_CMND:
-               atype = CMNDALIAS;
-               break;
-           default:
-               continue; /* not an alias */
-       }
-       TAILQ_FOREACH(m, d->binding, entries) {
-           if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, atype))
-                   errors++;
-           }
-       }
-    }
-    rbdestroy(alias_freelist, alias_free);
+    if (!alias_find_used(used_aliases))
+       errors++;
+    rbdestroy(used_aliases, alias_free);
 
     /* If all aliases were referenced we will have an empty tree. */
     if (!no_aliases() && !quiet)