]> granicus.if.org Git - sudo/commitdiff
added support for new `sudo -l' stuff
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 9 Aug 1996 22:07:51 +0000 (22:07 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 9 Aug 1996 22:07:51 +0000 (22:07 +0000)
parse.c
parse.yacc

diff --git a/parse.c b/parse.c
index f9030e13ec2eaa2c03901fb74f668b0fd9f18f64..a2c0febc9c24bcac14116b2b168f147f1d855b9c 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -90,6 +90,8 @@ static char rcsid[] = "$Id$";
  */
 int parse_error = FALSE;
 extern FILE *yyin, *yyout;
+extern struct sudo_match *matches;
+extern int printmatches;
 
 /*
  * Prototypes for static (local) functions
@@ -97,7 +99,7 @@ extern FILE *yyin, *yyout;
 static int has_meta    __P((char *));
 
 /*
- * this routine is called from the sudo.c module and tries to validate
+ * This routine is called from the sudo.c module and tries to validate
  * the user, host and command triplet.
  */
 int validate(check_cmnd)
@@ -118,13 +120,28 @@ int validate(check_cmnd)
     yyout = stdout;
 
     /*
-     * need to be root while stat'ing things in the parser.
+     * Allocate space for matches if printmatches is set.
+     */
+    if (printmatches) {
+       if ((matches = (struct sudo_match *)
+                 malloc(sizeof(struct sudo_match) * MATCHSTACKSIZE)) == NULL) {
+           perror("malloc");
+           (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+           exit(1);
+       }
+       /* XXX - maybe just set sizes to 0??? */
+       matches[0].runas = matches[0].cmnd = NULL;
+       matches[0].nopasswd = FALSE;
+    }
+
+    /*
+     * Need to be root while stat'ing things in the parser.
      */
     set_perms(PERM_ROOT);
     return_code = yyparse();
 
     /*
-     * don't need to keep this open...
+     * Don't need to keep this open...
      */
     (void) fclose(sudoers_fp);
 
index 57f5b1e3e562b475de1459b14e57eaeb90d1e550..167001e9f7d2d106096d0e7d09973ef1c850d900 100644 (file)
@@ -82,7 +82,6 @@ int printmatches = 0;
  * The matching stack, we should not have to initialize this,
  * since it is global but some compilers are just too braindamaged...
  */
-#define MATCHSTACKSIZE (40)
 struct matchstack match[MATCHSTACKSIZE] = { FALSE };
 int top = 0;
 
@@ -103,6 +102,21 @@ int top = 0;
     else \
        top--;
 
+/*
+ * The stack for printmatches.  A list of allowed commands for the user.
+ * Space for cmndstack is malloc'd in parse.c
+ */
+struct sudo_match *matches;
+int nummatches;
+
+#define cmndpush \
+    if (nummatches++ > MATCHSTACKSIZE) \
+       yyerror("cmnd stack overflow"); \
+    else { \
+       matches[nummatches].runas = matches[nummatches].cmnd = NULL; \
+       matches[nummatches].nopasswd = FALSE; \
+    }
+
 /*
  * Protoypes
  */
@@ -241,6 +255,10 @@ cmndspec   :       runasspec nopasswd opcmnd {
                                runas_matches = TRUE;
                                if ($2 == TRUE)
                                    no_passwd = TRUE;
+                           } else if (printmatches) {
+                               matches[nummatches].runas_len = 0;
+                               matches[nummatches].cmnd_len = 0;
+                               matches[nummatches].nopasswd = FALSE;
                            }
                        }
                ;
@@ -249,7 +267,7 @@ opcmnd              :       cmnd { ; }
                |       '!' {
                            if (printmatches == TRUE && host_matches == TRUE
                                && user_matches == TRUE) {
-                               (void) putchar('!');
+                               append_cmnd(&matches[nummatches], "!");
                                push;
                                user_matches = TRUE;
                                host_matches = TRUE;
@@ -286,44 +304,71 @@ runaslist :       runasuser {
 
 runasuser      :       NAME {
                            $$ = (strcmp($1, runas_user) == 0);
+                           if (printmatches == TRUE && host_matches == TRUE
+                               && user_matches == TRUE)
+                               append_runas(&matches[nummatches], $1);
                            (void) free($1);
                        }
                |       USERGROUP {
                            $$ = usergr_matches($1, runas_user);
+                           if (printmatches == TRUE && host_matches == TRUE
+                               && user_matches == TRUE) {
+                               append_runas(&matches[nummatches], "%");
+                               append_runas(&matches[nummatches], $1);
+                           }
                            (void) free($1);
                        }
                |       NETGROUP {
                            $$ = netgr_matches($1, NULL, runas_user);
+                           if (printmatches == TRUE && host_matches == TRUE
+                               && user_matches == TRUE) {
+                               append_runas(&matches[nummatches], "+");
+                               append_runas(&matches[nummatches], $1);
+                           }
                            (void) free($1);
                        }
                |       ALIAS {
                            $$ = find_alias($1, USER);
+                           if (printmatches == TRUE && host_matches == TRUE
+                               && user_matches == TRUE)
+                               append_runas(&matches[nummatches], $1);
                            (void) free($1);
                        }
                |       ALL {
                            $$ = TRUE;
+                           if (printmatches == TRUE && host_matches == TRUE
+                               && user_matches == TRUE)
+                               append_runas(&matches[nummatches], "ALL");
                        }
                ;
 
-nopasswd       :       /* empty */
-                       { $$ = FALSE; }
+nopasswd       :       /* empty */ {
+                           $$ = FALSE;
+                       }
                |       NOPASSWD {
                            $$ = TRUE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               matches[nummatches].nopasswd = TRUE;
                        }
                ;
 
 cmnd           :       ALL {
                            if (printmatches == TRUE && host_matches == TRUE &&
-                               user_matches == TRUE)
-                               (void) puts("ALL");
+                               user_matches == TRUE) {
+                               append_cmnd(&matches[nummatches], "ALL");
+                               cmndpush;
+                           }
 
                            cmnd_matches = TRUE;
                            $$ = TRUE;
                        }
                |       ALIAS {
                            if (printmatches == TRUE && host_matches == TRUE &&
-                               user_matches == TRUE)
-                               (void) puts($1);
+                               user_matches == TRUE) {
+                               append_cmnd(&matches[nummatches], $1);
+                               cmndpush;
+                           }
                            if (find_alias($1, CMND)) {
                                cmnd_matches = TRUE;
                                $$ = TRUE;
@@ -331,16 +376,14 @@ cmnd              :       ALL {
                            (void) free($1);
                        }
                |        COMMAND {
-                           char **t;
-
                            if (printmatches == TRUE && host_matches == TRUE &&
                                user_matches == TRUE)  {
-                               (void) fputs($1.cmnd, stdout);
-                               if (NewArgc > 1) {
-                                   (void) putchar(' ');
-                                   (void) fputs($1.args, stdout);
+                               append_cmnd(&matches[nummatches], $1.cmnd);
+                               if ($1.args) {
+                                   append_cmnd(&matches[nummatches], " ");
+                                   append_cmnd(&matches[nummatches], $1.args);
                                }
-                               (void) putchar('\n');
+                               cmndpush;
                            }
 
                            /* if NewArgc > 1 pass ptr to 1st arg, else NULL */
@@ -351,7 +394,8 @@ cmnd                :       ALL {
                            }
 
                            (void) free($1.cmnd);
-                           (void) free($1.args);
+                           if ($1.args)
+                               (void) free($1.args);
                        }
                ;
 
@@ -552,9 +596,110 @@ void dumpaliases()
 }
 
 
+void list_matches()
+{
+    int i; 
+    char *p;
+
+    for (i = 0; i < nummatches; i++) {
+
+       /* Print the runas list. */
+       if (matches[i].runas) {
+           (void) putchar('(');
+           if ((p = strtok(matches[i].runas, ":")))
+               (void) fputs(p, stdout);
+           while ((p = strtok(NULL, ":"))) {
+               (void) fputs(", ", stdout);
+               (void) fputs(p, stdout);
+           }
+           (void) fputs(") ", stdout);
+       } else {
+           (void) fputs("(root) ", stdout);
+       }
+
+       /* Is a password required? */
+       if (matches[i].nopasswd == TRUE)
+           (void) fputs("NOPASSWD: ", stdout);
+
+       /* Print the actual command. */
+       (void) puts(matches[i].cmnd);
+    }
+}
+
+
 void reset_aliases()
 {
     if (aliases)
        (void) free(aliases);
     naliases = nslots = 0;
 }
+
+
+/* XXX - merge into one function? (note: one always adds a ':' */
+static void append_runas(match, runas)
+struct sudo_match *match;
+char *runas;
+{
+size_t len = strlen(runas) + 1;
+
+if (match->runas == NULL) {
+    if (!(match->runas = (char *) malloc(BUFSIZ))) {
+       perror("malloc");
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+
+    /* Assumes BUFSIZ > max username length */
+    match->runas_size = BUFSIZ;
+    match->runas_len = len - 1;
+    (void) strcpy(match->runas, runas);
+} else {
+    /* Allocate more space if necesary. */
+    while (match->runas_size <= match->runas_len + len) {
+       match->runas_size += BUFSIZ;
+       if (!(match->runas = (char *) realloc(match->runas, match->runas_size))) {
+           perror("malloc");
+           (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+           exit(1);
+       }
+    }
+
+    *(match->runas + match->runas_len) = ':';
+    (void) strcpy(match->runas + match->runas_len + 1, runas);
+    match->runas_len += len;
+}
+}
+
+
+static void append_cmnd(match, cmnd)
+struct sudo_match *match;
+char *cmnd;
+{
+size_t len = strlen(cmnd);
+
+if (match->cmnd == NULL) {
+    if (!(match->cmnd = (char *) malloc(BUFSIZ))) {
+       perror("malloc");
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+
+    /* Assumes BUFSIZ > max username length */
+    match->cmnd_size = BUFSIZ;
+    match->cmnd_len = len;
+    (void) strcpy(match->cmnd, cmnd);
+} else {
+    /* Allocate more space if necesary. */
+    while (match->cmnd_size <= match->cmnd_len + len) {
+       match->cmnd_size += BUFSIZ;
+       if (!(match->cmnd = (char *) realloc(match->cmnd, match->cmnd_size))) {
+           perror("malloc");
+           (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+           exit(1);
+       }
+    }
+
+    (void) strcpy(match->cmnd + match->cmnd_len, cmnd);
+    match->cmnd_len += len;
+}
+}