Imported Debian patch 1.6.6-1.4 debian/1.6.6-1.4
authorMartin Schulze <joey@infodrom.org>
Thu, 22 Sep 2005 21:32:16 +0000 (23:32 +0200)
committerBdale Garbee <bdale@gag.com>
Wed, 14 May 2008 18:03:21 +0000 (12:03 -0600)
auth/pam.c.orig [new file with mode: 0644]
auth/pam.c.rej [new file with mode: 0644]
debian/changelog
env.c
parse.yacc
sudo.c
sudo.tab.c
sudo.tab.h

diff --git a/auth/pam.c.orig b/auth/pam.c.orig
new file mode 100644 (file)
index 0000000..554a0e1
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1999-2001 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include <security/pam_appl.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: pam.c,v 1.29 2002/01/22 16:43:23 millert Exp $";
+#endif /* lint */
+
+static int sudo_conv __P((int, PAM_CONST struct pam_message **,
+                         struct pam_response **, VOID *));
+static char *def_prompt;
+
+#ifndef PAM_DATA_SILENT
+#define PAM_DATA_SILENT        0
+#endif
+
+int
+pam_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+    static struct pam_conv pam_conv;
+    pam_handle_t *pamh;
+
+    /* Initial PAM setup */
+    pam_conv.conv = sudo_conv;
+    if (pam_start("sudo", pw->pw_name, &pam_conv, &pamh) != PAM_SUCCESS) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, 
+           "unable to initialize PAM");
+       return(AUTH_FATAL);
+    }
+    if (strcmp(user_tty, "unknown"))
+       (void) pam_set_item(pamh, PAM_TTY, user_tty);
+
+    auth->data = (VOID *) pamh;
+    return(AUTH_SUCCESS);
+}
+
+int
+pam_verify(pw, prompt, auth)
+    struct passwd *pw;
+    char *prompt;
+    sudo_auth *auth;
+{
+    int error;
+    const char *s;
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
+
+    def_prompt = prompt;       /* for sudo_conv */
+
+    /* PAM_SILENT prevents the authentication service from generating output. */
+    error = pam_authenticate(pamh, PAM_SILENT);
+    switch (error) {
+       case PAM_SUCCESS:
+           return(AUTH_SUCCESS);
+       case PAM_AUTH_ERR:
+       case PAM_MAXTRIES:
+           return(AUTH_FAILURE);
+       default:
+           if ((s = pam_strerror(pamh, error)))
+               log_error(NO_EXIT|NO_MAIL, "pam_authenticate: %s", s);
+           return(AUTH_FATAL);
+    }
+}
+
+int
+pam_cleanup(pw, auth)
+    struct passwd *pw;
+    sudo_auth *auth;
+{
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
+    int status = PAM_DATA_SILENT;
+
+    /* Convert AUTH_FOO -> PAM_FOO as best we can. */
+    /* XXX - store real value somewhere in auth->data and use it */
+    switch (auth->status) {
+       case AUTH_SUCCESS:
+           status |= PAM_SUCCESS;
+           break;
+       case AUTH_FAILURE:
+           status |= PAM_AUTH_ERR;
+           break;
+       case AUTH_FATAL:
+       default:
+           status |= PAM_ABORT;
+           break;
+    }
+
+    if (pam_end(pamh, status) == PAM_SUCCESS)
+       return(AUTH_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
+
+int
+pam_prep_user(pw)
+    struct passwd *pw;
+{
+    struct pam_conv pam_conv;
+    pam_handle_t *pamh;
+
+    /* We need to setup a new PAM session for the user we are changing *to*. */
+    pam_conv.conv = sudo_conv;
+    if (pam_start("sudo", pw->pw_name, &pam_conv, &pamh) != PAM_SUCCESS) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, 
+           "unable to initialize PAM");
+       return(AUTH_FATAL);
+    }
+    (void) pam_set_item(pamh, PAM_RUSER, user_name);
+    if (strcmp(user_tty, "unknown"))
+       (void) pam_set_item(pamh, PAM_TTY, user_tty);
+
+    /*
+     * Set credentials (may include resource limits, device ownership, etc).
+     * We don't check the return value here because in Linux-PAM 0.75
+     * it returns the last saved return code, not the return code
+     * for the setcred module.  Because we haven't called pam_authenticate(),
+     * this is not set and so pam_setcred() returns PAM_PERM_DENIED.
+     * We can't call pam_acct_mgmt() with Linux-PAM for a similar reason.
+     */
+    (void) pam_setcred(pamh, PAM_ESTABLISH_CRED);
+
+    if (pam_end(pamh, PAM_SUCCESS) == PAM_SUCCESS)
+       return(PAM_SUCCESS);
+    else
+       return(AUTH_FAILURE);
+}
+
+/*
+ * ``Conversation function'' for PAM.
+ * XXX - does not handle PAM_BINARY_PROMPT
+ */
+static int
+sudo_conv(num_msg, msg, response, appdata_ptr)
+    int num_msg;
+    PAM_CONST struct pam_message **msg;
+    struct pam_response **response;
+    VOID *appdata_ptr;
+{
+    struct pam_response *pr;
+    PAM_CONST struct pam_message *pm;
+    const char *p = def_prompt;
+    char *pass;
+    int n;
+    extern int nil_pw;
+
+    if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
+       return(PAM_CONV_ERR);
+    (void) memset(*response, 0, num_msg * sizeof(struct pam_response));
+
+    for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
+       switch (pm->msg_style) {
+           case PAM_PROMPT_ECHO_ON:
+               tgetpass_flags |= TGP_ECHO;
+           case PAM_PROMPT_ECHO_OFF:
+               /* Only override PAM prompt if it matches /^Password: ?/ */
+               if (strncmp(pm->msg, "Password:", 9) || (pm->msg[9] != '\0'
+                   && (pm->msg[9] != ' ' || pm->msg[10] != '\0')))
+                   p = pm->msg;
+               /* Read the password. */
+               pr->resp = estrdup((char *) tgetpass(p,
+                   def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags));
+               if (pr->resp == NULL)
+                   pr->resp = strdup("");
+               if (*pr->resp == '\0')
+                   nil_pw = 1;         /* empty password */
+               else
+                   memset(pass, 0, strlen(pass));
+               break;
+           case PAM_TEXT_INFO:
+               if (pm->msg)
+                   (void) puts(pm->msg);
+               break;
+           case PAM_ERROR_MSG:
+               if (pm->msg) {
+                   (void) fputs(pm->msg, stderr);
+                   (void) fputc('\n', stderr);
+               }
+               break;
+           default:
+               /* Zero and free allocated memory and return an error. */
+               for (pr = *response, n = num_msg; n--; pr++) {
+                   if (pr->resp != NULL) {
+                       (void) memset(pr->resp, 0, strlen(pr->resp));
+                       free(pr->resp);
+                       pr->resp = NULL;
+                   }
+               }
+               (void) memset(*response, 0,
+                   num_msg * sizeof(struct pam_response));
+               free(*response);
+               *response = NULL;
+               return(PAM_CONV_ERR);
+       }
+    }
+
+    return(PAM_SUCCESS);
+}
diff --git a/auth/pam.c.rej b/auth/pam.c.rej
new file mode 100644 (file)
index 0000000..86273af
--- /dev/null
@@ -0,0 +1,22 @@
+***************
+*** 222,231 ****
+                   &amp;&amp; (pm-&gt;msg[9] != ' ' || pm-&gt;msg[10] != '\0')))
+                   p = pm-&gt;msg;
+               /* Read the password. */
+-              pr-&gt;resp = estrdup((char *) tgetpass(p,
+-                  def_ival(I_PASSWD_TIMEOUT) * 60, tgetpass_flags));
+-              if (pr-&gt;resp == NULL)
+-                  pr-&gt;resp = strdup(&quot;&quot;);
+               if (*pr-&gt;resp == '\0')
+                   nil_pw = 1;         /* empty password */
+               else
+--- 222,230 ----
+                   &amp;&amp; (pm-&gt;msg[9] != ' ' || pm-&gt;msg[10] != '\0')))
+                   p = pm-&gt;msg;
+               /* Read the password. */
++              pass = tgetpass(p, def_ival(I_PASSWD_TIMEOUT) * 60,
++                  tgetpass_flags);
++              pr-&gt;resp = estrdup(pass ? pass : &quot;&quot;);
+               if (*pr-&gt;resp == '\0')
+                   nil_pw = 1;         /* empty password */
+               else
index b69108ebe0891c79ffd6c35740c20c0812e1f7eb..06a710306c0f8335068bd44767a38bdaf1184717 100644 (file)
@@ -1,10 +1,10 @@
-sudo (1.6.6-1.3woody1) oldstable-security; urgency=high
+sudo (1.6.6-1.4) oldstable-security; urgency=high
 
-  * Security upload
-  * Fix race condition in pathname validation [CAN-2005-1993]
-    (Closes: #315115)
+  * Non-maintainer upload by the Security Team
+  * Clean SHELLOPTS and PS4 from the environment before executing programs
+    with sudo permissions [env.c, CAN-2005-2959]
 
- -- Jeroen van Wolffelaar <jeroen@wolffelaar.nl>  Wed, 29 Jun 2005 03:56:11 +0200
+ -- Martin Schulze <joey@infodrom.org>  Thu, 22 Sep 2005 23:32:16 +0200
 
 sudo (1.6.6-1.3) stable-security; urgency=high
 
diff --git a/env.c b/env.c
index b4feef151e581c34bb910c68cdf42694538c9a2d..5a53b5d3234161f6dc5e15e0ed1c0b812c058f2f 100644 (file)
--- a/env.c
+++ b/env.c
@@ -96,6 +96,8 @@ static char *format_env               __P((char *, char *));
 char *initial_badenv_table[] = {
     "IFS",
     "CDPATH",
+    "SHELLOPTS",
+    "PS4",
     "LOCALDOMAIN",
     "RES_OPTIONS",
     "HOSTALIASES",
index 04794aeb6cc96fc763a66a97751fdae50a3214e6..7a6fb4ef57c435fa5e361afacb8b8c74fd784b73 100644 (file)
@@ -638,6 +638,10 @@ cmnd               :       ALL {
                            }
 
                            $$ = TRUE;
+
+                           if (safe_cmnd)
+                               free(safe_cmnd);
+                           safe_cmnd = estrdup(user_cmnd);
                        }
                |       ALIAS {
                            aliasinfo *aip;
diff --git a/sudo.c b/sudo.c
index 4052ad4911d8fa397ba42c9f106104f06b347a02..7c6f532e88c33ff64513bc012e079978fc79ffcc 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -286,8 +286,6 @@ main(argc, argv, envp)
        if (runas_pw == NULL)
            log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
     }
-    if (safe_cmnd == NULL)
-       safe_cmnd = user_cmnd;
 
     /* This goes after the sudoers parse since we honor sudoers options. */
     if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
@@ -356,6 +354,14 @@ main(argc, argv, envp)
            exit(0);
        }
 
+       /* This *must* have been set if we got a match but... */
+       if (safe_cmnd == NULL) {
+           log_error(MSG_ONLY,
+               "internal error, safe_cmnd never got set for %s; %s",
+               user_cmnd,
+               "please report this error at http://courtesan.com/sudo/bugs/");
+       }
+
        /* Reset signal handlers before we exec. */
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART;
index ca77a2bb04894fe7e6e5e184dc92f50c67bf8ca5..db81c132ecac3496ffe963e82b0f028d7e3cdc8f 100644 (file)
@@ -1,31 +1,22 @@
-/* A Bison parser, made from parse.yacc
-   by GNU bison 1.35.  */
-
-#define YYBISON 1  /* Identify Bison output.  */
-
-# define       COMMAND 257
-# define       ALIAS   258
-# define       DEFVAR  259
-# define       NTWKADDR        260
-# define       NETGROUP        261
-# define       USERGROUP       262
-# define       WORD    263
-# define       DEFAULTS        264
-# define       DEFAULTS_HOST   265
-# define       DEFAULTS_USER   266
-# define       RUNAS   267
-# define       NOPASSWD        268
-# define       PASSWD  269
-# define       ALL     270
-# define       COMMENT 271
-# define       HOSTALIAS       272
-# define       CMNDALIAS       273
-# define       USERALIAS       274
-# define       RUNASALIAS      275
-# define       ERROR   276
-
-#line 1 "parse.yacc"
-
+#ifndef lint
+/*static char yysccsid[] = "from: @(#)yaccpar  1.9 (Berkeley) 02/21/93";*/
+static char yyrcsid[]
+#if __GNUC__ == 2
+  __attribute__ ((unused))
+#endif /* __GNUC__ == 2 */
+  = "$OpenBSD: skeleton.c,v 1.18 2001/11/19 19:02:18 mpech Exp $";
+#endif
+#include <stdlib.h>
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYLEX yylex()
+#define YYEMPTY -1
+#define yyclearin (yychar=(YYEMPTY))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING() (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 2 "parse.yacc"
 /*
  * Copyright (c) 1996, 1998-2001 Todd C. Miller <Todd.Miller@courtesan.com>
  * All rights reserved.
 #endif /* HAVE_LSEARCH */
 
 #ifndef lint
-static const char rcsid[] = "$Sudo: parse.yacc,v 1.180 2002/03/16 00:44:47 millert Exp $";
+static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.58 2002/03/16 00:45:48 millert Exp $";
 #endif /* lint */
 
 /*
@@ -236,1039 +227,984 @@ yyerror(s)
     }
     parse_error = TRUE;
 }
-
 #line 214 "parse.yacc"
-#ifndef YYSTYPE
 typedef union {
     char *string;
     int BOOLEAN;
     struct sudo_command command;
     int tok;
-} yystype;
-# define YYSTYPE yystype
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-
-
-#define        YYFINAL         129
-#define        YYFLAG          -32768
-#define        YYNTBASE        29
-
-/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
-#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 70)
-
-/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
-static const char yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    25,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    26,    24,    27,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    22,     2,
-       2,    23,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    28
-};
-
-#if YYDEBUG
-static const short yyprhs[] =
-{
-       0,     0,     2,     5,     7,    10,    11,    15,    18,    21,
-      24,    27,    29,    32,    34,    35,    39,    40,    44,    46,
-      50,    52,    55,    59,    63,    67,    69,    73,    77,    79,
-      82,    84,    86,    88,    90,    92,    94,    98,   102,   104,
-     105,   109,   110,   113,   115,   119,   121,   122,   126,   128,
-     130,   132,   134,   136,   137,   139,   141,   143,   145,   147,
-     149,   153,   154,   159,   161,   165,   167,   171,   172,   177,
-     179,   183,   185,   189,   190,   195,   197,   201,   202,   207,
-     209,   213,   215,   218,   220,   222,   224,   226
-};
-static const short yyrhs[] =
-{
-      30,     0,    29,    30,     0,    17,     0,     1,    17,     0,
-       0,    31,    67,    38,     0,    20,    64,     0,    18,    53,
-       0,    19,    57,     0,    21,    61,     0,    32,     0,    33,
-      36,     0,    10,     0,     0,    12,    34,    67,     0,     0,
-      11,    35,    56,     0,    37,     0,    37,    24,    36,     0,
-       5,     0,    25,     5,     0,     5,    23,     9,     0,     5,
-      26,     9,     0,     5,    27,     9,     0,    39,     0,    38,
-      22,    39,     0,    56,    23,    42,     0,    41,     0,    25,
-      41,     0,    16,     0,     6,     0,     7,     0,     9,     0,
-       4,     0,    43,     0,    42,    24,    43,     0,    46,    51,
-      44,     0,    52,     0,     0,    25,    45,    52,     0,     0,
-      13,    47,     0,    48,     0,    47,    24,    48,     0,    50,
-       0,     0,    25,    49,    50,     0,     9,     0,     8,     0,
-       7,     0,     4,     0,    16,     0,     0,    14,     0,    15,
-       0,    16,     0,     4,     0,     3,     0,    54,     0,    53,
-      22,    54,     0,     0,     4,    55,    23,    56,     0,    40,
-       0,    56,    24,    40,     0,    58,     0,    57,    22,    58,
-       0,     0,     4,    59,    23,    60,     0,    44,     0,    60,
-      24,    44,     0,    62,     0,    61,    22,    62,     0,     0,
-       4,    63,    23,    47,     0,    65,     0,    64,    22,    65,
-       0,     0,     4,    66,    23,    67,     0,    68,     0,    67,
-      24,    68,     0,    69,     0,    25,    69,     0,     9,     0,
-       8,     0,     7,     0,     4,     0,    16,     0
-};
-
-#endif
-
-#if YYDEBUG
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const short yyrline[] =
-{
-       0,   259,   260,   263,   265,   267,   267,   271,   273,   275,
-     277,   279,   283,   285,   288,   288,   292,   292,   298,   299,
-     301,   309,   317,   326,   335,   345,   346,   349,   364,   368,
-     373,   376,   383,   390,   397,   421,   422,   425,   452,   456,
-     456,   470,   493,   498,   499,   508,   509,   509,   522,   536,
-     550,   564,   593,   605,   615,   621,   629,   642,   671,   699,
-     700,   703,   703,   711,   712,   715,   716,   719,   719,   740,
-     741,   744,   745,   748,   748,   767,   768,   771,   771,   780,
-     781,   784,   788,   793,   800,   807,   814,   834
-};
-#endif
-
-
-#if (YYDEBUG) || defined YYERROR_VERBOSE
-
-/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
-static const char *const yytname[] =
-{
-  "$", "error", "$undefined.", "COMMAND", "ALIAS", "DEFVAR", "NTWKADDR", 
-  "NETGROUP", "USERGROUP", "WORD", "DEFAULTS", "DEFAULTS_HOST", 
-  "DEFAULTS_USER", "RUNAS", "NOPASSWD", "PASSWD", "ALL", "COMMENT", 
-  "HOSTALIAS", "CMNDALIAS", "USERALIAS", "RUNASALIAS", "':'", "'='", 
-  "','", "'!'", "'+'", "'-'", "ERROR", "file", "entry", "@1", 
-  "defaults_line", "defaults_type", "@2", "@3", "defaults_list", 
-  "defaults_entry", "privileges", "privilege", "ophost", "host", 
-  "cmndspeclist", "cmndspec", "opcmnd", "@4", "runasspec", "runaslist", 
-  "oprunasuser", "@5", "runasuser", "nopasswd", "cmnd", "hostaliases", 
-  "hostalias", "@6", "hostlist", "cmndaliases", "cmndalias", "@7", 
-  "cmndlist", "runasaliases", "runasalias", "@8", "useraliases", 
-  "useralias", "@9", "userlist", "opuser", "user", 0
-};
-#endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const short yyr1[] =
-{
-       0,    29,    29,    30,    30,    31,    30,    30,    30,    30,
-      30,    30,    32,    33,    34,    33,    35,    33,    36,    36,
-      37,    37,    37,    37,    37,    38,    38,    39,    40,    40,
-      41,    41,    41,    41,    41,    42,    42,    43,    44,    45,
-      44,    46,    46,    47,    47,    48,    49,    48,    50,    50,
-      50,    50,    50,    51,    51,    51,    52,    52,    52,    53,
-      53,    55,    54,    56,    56,    57,    57,    59,    58,    60,
-      60,    61,    61,    63,    62,    64,    64,    66,    65,    67,
-      67,    68,    68,    69,    69,    69,    69,    69
+} YYSTYPE;
+#line 238 "sudo.tab.c"
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DEFAULTS 264
+#define DEFAULTS_HOST 265
+#define DEFAULTS_USER 266
+#define RUNAS 267
+#define NOPASSWD 268
+#define PASSWD 269
+#define ALL 270
+#define COMMENT 271
+#define HOSTALIAS 272
+#define CMNDALIAS 273
+#define USERALIAS 274
+#define RUNASALIAS 275
+#define ERROR 276
+#define YYERRCODE 256
+short yylhs[] = {                                        -1,
+    0,    0,    7,    7,    9,    7,    7,    7,    7,    7,
+    7,   15,   16,   18,   16,   20,   16,   17,   17,   21,
+   21,   21,   21,   21,   10,   10,   22,   24,   24,    2,
+    2,    2,    2,    2,   23,   23,   25,   28,   29,   28,
+   26,   26,    5,    5,    4,   30,    4,    3,    3,    3,
+    3,    3,   27,   27,   27,    1,    1,    1,   12,   12,
+   32,   31,   19,   19,   13,   13,   34,   33,   35,   35,
+   14,   14,   37,   36,   11,   11,   39,   38,    8,    8,
+   40,   40,    6,    6,    6,    6,    6,
 };
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const short yyr2[] =
-{
-       0,     1,     2,     1,     2,     0,     3,     2,     2,     2,
-       2,     1,     2,     1,     0,     3,     0,     3,     1,     3,
-       1,     2,     3,     3,     3,     1,     3,     3,     1,     2,
-       1,     1,     1,     1,     1,     1,     3,     3,     1,     0,
-       3,     0,     2,     1,     3,     1,     0,     3,     1,     1,
-       1,     1,     1,     0,     1,     1,     1,     1,     1,     1,
-       3,     0,     4,     1,     3,     1,     3,     0,     4,     1,
-       3,     1,     3,     0,     4,     1,     3,     0,     4,     1,
-       3,     1,     2,     1,     1,     1,     1,     1
+short yylen[] = {                                         2,
+    1,    2,    1,    2,    0,    3,    2,    2,    2,    2,
+    1,    2,    1,    0,    3,    0,    3,    1,    3,    1,
+    2,    3,    3,    3,    1,    3,    3,    1,    2,    1,
+    1,    1,    1,    1,    1,    3,    3,    1,    0,    3,
+    0,    2,    1,    3,    1,    0,    3,    1,    1,    1,
+    1,    1,    0,    1,    1,    1,    1,    1,    1,    3,
+    0,    4,    1,    3,    1,    3,    0,    4,    1,    3,
+    1,    3,    0,    4,    1,    3,    0,    4,    1,    3,
+    1,    2,    1,    1,    1,    1,    1,
 };
-
-/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
-   doesn't specify something else to do.  Zero means the default is an
-   error. */
-static const short yydefact[] =
-{
-       0,     0,    13,    16,    14,     3,     0,     0,     0,     0,
-       0,     1,     0,    11,     0,     4,     0,     0,    61,     8,
-      59,    67,     9,    65,    77,     7,    75,    73,    10,    71,
-       2,    86,    85,    84,    83,    87,     0,     0,    79,    81,
-      20,     0,    12,    18,    34,    31,    32,    33,    30,     0,
-      63,    28,    17,    15,     0,     0,     0,     0,     0,     0,
-       0,     0,    82,     0,     6,    25,     0,     0,     0,     0,
-      21,     0,    29,     0,     0,    60,     0,    66,     0,    76,
-       0,    72,    80,     0,    41,    22,    23,    24,    19,    64,
-      62,    58,    57,    56,    39,    69,    38,    68,    78,    51,
-      50,    49,    48,    52,    46,    74,    43,    45,    26,     0,
-      27,    35,    53,     0,     0,     0,     0,    42,    41,    54,
-      55,     0,    40,    70,    47,    44,    36,    37,     0,     0
+short yydefred[] = {                                      0,
+    0,   13,   16,   14,    3,    0,    0,    0,    0,    0,
+    1,    0,   11,    0,    4,    0,    0,   61,    0,   59,
+   67,    0,   65,   77,    0,   75,   73,    0,   71,    2,
+   86,   85,   84,   83,   87,    0,   81,    0,   79,    0,
+    0,   12,    0,   34,   31,   32,   33,   30,    0,   28,
+    0,   63,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   82,    0,    0,    0,   25,    0,    0,    0,   21,
+    0,   29,    0,    0,   60,    0,   66,    0,   76,    0,
+   72,   80,    0,    0,   22,   23,   24,   19,   64,    0,
+   58,   57,   56,   39,   38,   69,    0,    0,   51,   50,
+   49,   48,   52,   46,   45,   43,    0,   26,    0,    0,
+   35,    0,    0,    0,    0,    0,    0,    0,   54,   55,
+    0,   40,   70,   47,   44,   36,   37,
 };
-
-static const short yydefgoto[] =
-{
-      10,    11,    12,    13,    14,    17,    16,    42,    43,    64,
-      65,    50,    51,   110,   111,    95,   113,   112,   105,   106,
-     115,   107,   121,    96,    19,    20,    54,    66,    22,    23,
-      56,    97,    28,    29,    60,    25,    26,    58,    37,    38,
-      39
+short yydgoto[] = {                                      10,
+   95,   50,  105,  106,  107,   37,   11,   38,   12,   64,
+   25,   19,   22,   28,   13,   14,   42,   17,   65,   16,
+   43,   66,  110,   52,  111,  112,  121,   96,  113,  115,
+   20,   54,   23,   56,   97,   29,   60,   26,   58,   39,
 };
-
-static const short yypact[] =
-{
-      24,   -10,-32768,-32768,-32768,-32768,    12,    20,    35,    50,
-       2,-32768,    48,-32768,    33,-32768,    68,    48,-32768,    15,
-  -32768,-32768,    40,-32768,-32768,    41,-32768,-32768,    45,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,    78,    44,-32768,-32768,
-      83,    65,-32768,    47,-32768,-32768,-32768,-32768,-32768,    92,
-  -32768,-32768,    59,    66,    69,    12,    79,    20,    84,    35,
-      88,    50,-32768,    48,    67,-32768,     6,    82,    86,   104,
-  -32768,    33,-32768,    68,    68,-32768,     1,-32768,    48,-32768,
-      72,-32768,-32768,    68,   101,-32768,-32768,-32768,-32768,-32768,
-      59,-32768,-32768,-32768,-32768,-32768,-32768,    91,    66,-32768,
-  -32768,-32768,-32768,-32768,-32768,    93,-32768,-32768,-32768,    72,
-      94,-32768,    32,    62,     1,    96,    72,    93,   101,-32768,
-  -32768,     1,-32768,-32768,-32768,-32768,-32768,-32768,   116,-32768
+short yysindex[] = {                                   -236,
+ -264,    0,    0,    0,    0, -249, -243, -231, -227, -236,
+    0,  -23,    0,  -30,    0,  -17,  -23,    0,  -36,    0,
+    0,  -26,    0,    0,  -14,    0,    0,   -7,    0,    0,
+    0,    0,    0,    0,    0, -215,    0,  -33,    0,   -3,
+ -226,    0,    5,    0,    0,    0,    0,    0, -194,    0,
+    6,    0,    8,   -5, -249,   -4, -243,   -2, -231,   -1,
+ -227,    0,  -23,    7,  -38,    0, -210, -193, -188,    0,
+  -30,    0,  -17,  -17,    0,  -25,    0,  -23,    0,  245,
+    0,    0,  -17, -189,    0,    0,    0,    0,    0,    6,
+    0,    0,    0,    0,    0,    0,   33,    8,    0,    0,
+    0,    0,    0,    0,    0,    0,   38,    0,  245,   39,
+    0, -251, -244,  -25, -190,  245,   38, -189,    0,    0,
+  -25,    0,    0,    0,    0,    0,    0,
 };
-
-static const short yypgoto[] =
-{
-  -32768,   109,-32768,-32768,-32768,-32768,-32768,    49,-32768,-32768,
-      38,    51,    73,-32768,     5,  -106,-32768,-32768,    16,    10,
-  -32768,    13,-32768,    14,-32768,    74,-32768,   -15,-32768,    75,
-  -32768,-32768,-32768,    70,-32768,-32768,    71,-32768,   -17,    76,
-      97
+short yyrindex[] = {                                    255,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  255,
+    0,    0,    0,    0,    0,    0,    0,    0,  121,    0,
+    0,  141,    0,    0,  161,    0,    0,  181,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
+    0,    0,  201,    0,    0,    0,    0,    0,    0,    0,
+  -28,    0,   -8,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  221,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  265,    0,    0,    0,    0,    0,   21,
+    0,    0,    0,    0,    0,    0,   41,   61,    0,    0,
+    0,    0,    0,    0,    0,    0,   81,    0,    0,  101,
+    0,   -9,    0,    0,    0,    0,  285,  265,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,
 };
-
-
-#define        YYLAST          139
-
-
-static const short yytable[] =
-{
-      53,    52,   128,     1,    91,    92,    -5,    15,   123,    -5,
-      -5,    -5,     2,     3,     4,   127,    18,    93,    -5,     5,
-       6,     7,     8,     9,    21,     1,    94,    -5,    -5,    84,
-      73,    -5,    -5,    -5,     2,     3,     4,    55,    40,    24,
-      -5,     5,     6,     7,     8,     9,   119,   120,    44,    -5,
-      45,    46,    31,    47,    27,    32,    33,    34,    41,    90,
-      48,    98,    57,    59,    35,    91,    92,    61,    63,    49,
-      70,    71,    44,    36,    45,    46,    99,    47,    93,   100,
-     101,   102,    31,    73,    48,    32,    33,    34,   103,    83,
-      63,    85,    74,    49,    35,    86,    44,   104,    45,    46,
-      99,    47,    76,   100,   101,   102,    67,    78,    48,    68,
-      69,    80,   103,    87,   109,   114,   129,   116,   118,    30,
-      88,   108,    72,   126,    89,   117,   125,   122,   124,    75,
-      79,    81,    77,    62,     0,     0,     0,     0,     0,    82
+short yygindex[] = {                                      0,
+  -29,   36,  -27,  -24,  -22,   50,   79,  -15,    0,    0,
+    0,    0,    0,    0,    0,    0,   19,    0,  -12,    0,
+    0,   10,    0,   18,  -21,    0,    0, -102,    0,    0,
+   40,    0,   43,    0,    0,   35,    0,   44,    0,   42,
 };
-
-static const short yycheck[] =
-{
-      17,    16,     0,     1,     3,     4,     4,    17,   114,     7,
-       8,     9,    10,    11,    12,   121,     4,    16,    16,    17,
-      18,    19,    20,    21,     4,     1,    25,    25,     4,    23,
-      24,     7,     8,     9,    10,    11,    12,    22,     5,     4,
-      16,    17,    18,    19,    20,    21,    14,    15,     4,    25,
-       6,     7,     4,     9,     4,     7,     8,     9,    25,    74,
-      16,    78,    22,    22,    16,     3,     4,    22,    24,    25,
-       5,    24,     4,    25,     6,     7,     4,     9,    16,     7,
-       8,     9,     4,    24,    16,     7,     8,     9,    16,    22,
-      24,     9,    23,    25,    16,     9,     4,    25,     6,     7,
-       4,     9,    23,     7,     8,     9,    23,    23,    16,    26,
-      27,    23,    16,     9,    13,    24,     0,    24,    24,    10,
-      71,    83,    49,   118,    73,   109,   116,   113,   115,    55,
-      59,    61,    57,    36,    -1,    -1,    -1,    -1,    -1,    63
+#define YYTABLESIZE 555
+short yytable[] = {                                      49,
+   20,   53,   41,   51,   17,   73,   15,   94,   18,   36,
+   63,  123,   91,   92,   21,   49,  119,  120,  127,    1,
+   62,   55,   84,   53,   15,   93,   24,    2,    3,    4,
+   27,   57,   70,   20,    5,    6,    7,    8,    9,   68,
+   68,   69,   31,   59,   20,   32,   33,   34,   71,   73,
+   61,   63,   85,   62,   35,   74,   76,   67,   78,   80,
+   78,   90,   98,   44,   83,   45,   46,   99,   47,   86,
+  100,  101,  102,   68,   87,   48,  114,  109,   62,  103,
+   74,  116,  118,  122,   72,   62,  117,  124,   30,   88,
+   89,  125,  108,   78,   75,   81,  126,    0,   68,   77,
+   27,    0,   79,    0,   82,    0,    0,    0,    0,    0,
+    0,    0,    0,   74,    0,    0,    0,    0,   78,    0,
+    8,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   27,    0,    0,    0,    0,   74,    0,
+    9,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    8,    0,    0,    0,    0,   27,    0,
+    7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    9,    0,    0,    0,    0,    0,    0,
+   10,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    7,    0,    0,    0,    0,    0,    0,
+   18,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   10,    0,    0,    0,    0,    0,    0,
+    6,    0,    0,    0,   44,    0,   45,   46,   40,   47,
+   17,   91,   92,   18,   31,    0,   48,   32,   33,   34,
+   44,    0,   45,   46,   93,   47,   35,   53,   53,    0,
+   15,    0,   48,    6,    0,    0,   20,    0,   20,    0,
+   53,   20,   20,   20,   20,   20,   20,    0,    0,    0,
+   20,   20,   20,   20,   20,   20,   62,  104,   62,    0,
+    0,   62,   62,   62,   62,   62,   62,    5,    0,    0,
+   62,   62,   62,   62,   62,   62,   68,   41,   68,    0,
+    0,   68,   68,   68,   68,   68,   68,    0,    0,    0,
+   68,   68,   68,   68,   68,   68,   78,   42,   78,    0,
+    0,   78,   78,   78,   78,   78,   78,    0,    0,    0,
+   78,   78,   78,   78,   78,   78,   74,    0,   74,    0,
+    0,   74,   74,   74,   74,   74,   74,    0,    0,    0,
+   74,   74,   74,   74,   74,   74,   27,    0,   27,    0,
+    0,   27,   27,   27,   27,   27,   27,    0,    0,    0,
+   27,   27,   27,   27,   27,   27,    8,    0,    8,    0,
+    0,    8,    8,    8,    8,    8,    8,    0,    0,    0,
+    8,    8,    8,    8,    8,    8,    9,    0,    9,    0,
+    0,    9,    9,    9,    9,    9,    9,    0,    0,    0,
+    9,    9,    9,    9,    9,    9,    7,    0,    7,    0,
+    0,    7,    7,    7,    7,    7,    7,    0,    0,    0,
+    7,    7,    7,    7,    7,    7,   10,    0,   10,    0,
+    0,   10,   10,   10,   10,   10,   10,    0,    0,    0,
+   10,   10,   10,   10,   10,   10,   18,    0,   18,    0,
+    0,   18,   18,   18,   18,   18,   18,    0,    0,    0,
+   18,   18,   18,   18,   18,   18,    6,    0,    6,    0,
+    0,    6,    6,    6,    6,    6,    6,    0,    0,    0,
+    6,    6,    6,    6,    6,    6,    0,    0,    0,    0,
+    0,    0,   99,    0,    0,  100,  101,  102,    0,    0,
+    0,    0,    5,    0,  103,    5,    5,    5,    0,    0,
+    0,   41,   41,    0,    5,    0,    0,    0,    0,    0,
+    0,    0,   41,   41,   41,    0,    0,    0,    0,    0,
+    0,   42,   42,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   42,   42,   42,
 };
-/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
-#line 3 "/usr/share/bison/bison.simple"
-
-/* Skeleton output parser for bison,
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
-   Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
-
-/* This is the parser code that is written into each bison parser when
-   the %semantic_parser declaration is not specified in the grammar.
-   It was written by Richard Stallman by simplifying the hairy parser
-   used when %semantic_parser is specified.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# if YYSTACK_USE_ALLOCA
-#  define YYSTACK_ALLOC alloca
-# else
-#  ifndef YYSTACK_USE_ALLOCA
-#   if defined (alloca) || defined (_ALLOCA_H)
-#    define YYSTACK_ALLOC alloca
-#   else
-#    ifdef __GNUC__
-#     define YYSTACK_ALLOC __builtin_alloca
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning. */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-#  if defined (__STDC__) || defined (__cplusplus)
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   define YYSIZE_T size_t
-#  endif
-#  define YYSTACK_ALLOC malloc
-#  define YYSTACK_FREE free
-# endif
-#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
-
-
-#if (! defined (yyoverflow) \
-     && (! defined (__cplusplus) \
-        || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  short yyss;
-  YYSTYPE yyvs;
-# if YYLSP_NEEDED
-  YYLTYPE yyls;
-# endif
+short yycheck[] = {                                      33,
+    0,   17,   33,   16,   33,   44,  271,   33,  258,   33,
+   44,  114,  257,  258,  258,   33,  268,  269,  121,  256,
+    0,   58,   61,   33,   33,  270,  258,  264,  265,  266,
+  258,   58,  259,   33,  271,  272,  273,  274,  275,   43,
+    0,   45,  258,   58,   44,  261,  262,  263,   44,   44,
+   58,   44,  263,   33,  270,   61,   61,   61,   61,   61,
+    0,   74,   78,  258,   58,  260,  261,  258,  263,  263,
+  261,  262,  263,   33,  263,  270,   44,  267,   58,  270,
+    0,   44,   44,  113,   49,   36,  109,  115,   10,   71,
+   73,  116,   83,   33,   55,   61,  118,   -1,   58,   57,
+    0,   -1,   59,   -1,   63,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   58,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,  258,   -1,  260,  261,  259,  263,
+  259,  257,  258,   33,  258,   -1,  270,  261,  262,  263,
+  258,   -1,  260,  261,  270,  263,  270,  257,  258,   -1,
+  259,   -1,  270,   33,   -1,   -1,  256,   -1,  258,   -1,
+  270,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   33,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   33,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,   -1,   -1,   -1,
+  270,  271,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
+   -1,   -1,  258,   -1,   -1,  261,  262,  263,   -1,   -1,
+   -1,   -1,  258,   -1,  270,  261,  262,  263,   -1,   -1,
+   -1,  257,  258,   -1,  270,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  268,  269,  270,   -1,   -1,   -1,   -1,   -1,
+   -1,  257,  258,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  268,  269,  270,
 };
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# if YYLSP_NEEDED
-#  define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))     \
-      + 2 * YYSTACK_GAP_MAX)
-# else
-#  define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                \
-      + YYSTACK_GAP_MAX)
-# endif
-
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         register YYSIZE_T yyi;                \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (0)
-#  endif
-# endif
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack)                                       \
-    do                                                                 \
-      {                                                                        \
-       YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
-       Stack = &yyptr->Stack;                                          \
-       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;   \
-       yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                        \
-    while (0)
-
+#define YYFINAL 10
+#ifndef YYDEBUG
+#define YYDEBUG 0
 #endif
-
-
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
+#define YYMAXTOKEN 276
+#if YYDEBUG
+#if defined(__cplusplus) || __STDC__
+const char * const yyname[] =
+#else
+char *yyname[] =
 #endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
+       {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'!'",0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,
+"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
+"DEFAULTS_HOST","DEFAULTS_USER","RUNAS","NOPASSWD","PASSWD","ALL","COMMENT",
+"HOSTALIAS","CMNDALIAS","USERALIAS","RUNASALIAS","ERROR",
+};
+#if defined(__cplusplus) || __STDC__
+const char * const yyrule[] =
+#else
+char *yyrule[] =
 #endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# endif
+       {"$accept : file",
+"file : entry",
+"file : file entry",
+"entry : COMMENT",
+"entry : error COMMENT",
+"$$1 :",
+"entry : $$1 userlist privileges",
+"entry : USERALIAS useraliases",
+"entry : HOSTALIAS hostaliases",
+"entry : CMNDALIAS cmndaliases",
+"entry : RUNASALIAS runasaliases",
+"entry : defaults_line",
+"defaults_line : defaults_type defaults_list",
+"defaults_type : DEFAULTS",
+"$$2 :",
+"defaults_type : DEFAULTS_USER $$2 userlist",
+"$$3 :",
+"defaults_type : DEFAULTS_HOST $$3 hostlist",
+"defaults_list : defaults_entry",
+"defaults_list : defaults_entry ',' defaults_list",
+"defaults_entry : DEFVAR",
+"defaults_entry : '!' DEFVAR",
+"defaults_entry : DEFVAR '=' WORD",
+"defaults_entry : DEFVAR '+' WORD",
+"defaults_entry : DEFVAR '-' WORD",
+"privileges : privilege",
+"privileges : privileges ':' privilege",
+"privilege : hostlist '=' cmndspeclist",
+"ophost : host",
+"ophost : '!' host",
+"host : ALL",
+"host : NTWKADDR",
+"host : NETGROUP",
+"host : WORD",
+"host : ALIAS",
+"cmndspeclist : cmndspec",
+"cmndspeclist : cmndspeclist ',' cmndspec",
+"cmndspec : runasspec nopasswd opcmnd",
+"opcmnd : cmnd",
+"$$4 :",
+"opcmnd : '!' $$4 cmnd",
+"runasspec :",
+"runasspec : RUNAS runaslist",
+"runaslist : oprunasuser",
+"runaslist : runaslist ',' oprunasuser",
+"oprunasuser : runasuser",
+"$$5 :",
+"oprunasuser : '!' $$5 runasuser",
+"runasuser : WORD",
+"runasuser : USERGROUP",
+"runasuser : NETGROUP",
+"runasuser : ALIAS",
+"runasuser : ALL",
+"nopasswd :",
+"nopasswd : NOPASSWD",
+"nopasswd : PASSWD",
+"cmnd : ALL",
+"cmnd : ALIAS",
+"cmnd : COMMAND",
+"hostaliases : hostalias",
+"hostaliases : hostaliases ':' hostalias",
+"$$6 :",
+"hostalias : ALIAS $$6 '=' hostlist",
+"hostlist : ophost",
+"hostlist : hostlist ',' ophost",
+"cmndaliases : cmndalias",
+"cmndaliases : cmndaliases ':' cmndalias",
+"$$7 :",
+"cmndalias : ALIAS $$7 '=' cmndlist",
+"cmndlist : opcmnd",
+"cmndlist : cmndlist ',' opcmnd",
+"runasaliases : runasalias",
+"runasaliases : runasaliases ':' runasalias",
+"$$8 :",
+"runasalias : ALIAS $$8 '=' runaslist",
+"useraliases : useralias",
+"useraliases : useraliases ':' useralias",
+"$$9 :",
+"useralias : ALIAS $$9 '=' userlist",
+"userlist : opuser",
+"userlist : userlist ',' opuser",
+"opuser : user",
+"opuser : '!' user",
+"user : WORD",
+"user : USERGROUP",
+"user : NETGROUP",
+"user : ALIAS",
+"user : ALL",
+};
 #endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
 #endif
-
-#define yyerrok                (yyerrstatus = 0)
-#define yyclearin      (yychar = YYEMPTY)
-#define YYEMPTY                -2
-#define YYEOF          0
-#define YYACCEPT       goto yyacceptlab
-#define YYABORT        goto yyabortlab
-#define YYERROR                goto yyerrlab1
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
-#define YYFAIL         goto yyerrlab
-#define YYRECOVERING()  (!!yyerrstatus)
-#define YYBACKUP(Token, Value)                                 \
-do                                                             \
-  if (yychar == YYEMPTY && yylen == 1)                         \
-    {                                                          \
-      yychar = (Token);                                                \
-      yylval = (Value);                                                \
-      yychar1 = YYTRANSLATE (yychar);                          \
-      YYPOPSTACK;                                              \
-      goto yybackup;                                           \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      yyerror ("syntax error: cannot back up");                        \
-      YYERROR;                                                 \
-    }                                                          \
-while (0)
-
-#define YYTERROR       1
-#define YYERRCODE      256
-
-
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
-   are run).
-
-   When YYLLOC_DEFAULT is run, CURRENT is set the location of the
-   first token.  By default, to implement support for ranges, extend
-   its range to the last symbol.  */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)               \
-   Current.last_line   = Rhs[N].last_line;     \
-   Current.last_column = Rhs[N].last_column;
 #endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments.  */
-
-#if YYPURE
-# if YYLSP_NEEDED
-#  ifdef YYLEX_PARAM
-#   define YYLEX               yylex (&yylval, &yylloc, YYLEX_PARAM)
-#  else
-#   define YYLEX               yylex (&yylval, &yylloc)
-#  endif
-# else /* !YYLSP_NEEDED */
-#  ifdef YYLEX_PARAM
-#   define YYLEX               yylex (&yylval, YYLEX_PARAM)
-#  else
-#   define YYLEX               yylex (&yylval)
-#  endif
-# endif /* !YYLSP_NEEDED */
-#else /* !YYPURE */
-# define YYLEX                 yylex ()
-#endif /* !YYPURE */
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                       \
-do {                                           \
-  if (yydebug)                                 \
-    YYFPRINTF Args;                            \
-} while (0)
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
+#define YYINITSTACKSIZE 200
 int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-#endif /* !YYDEBUG */
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short *yyss;
+short *yysslim;
+YYSTYPE *yyvs;
+int yystacksize;
+#line 844 "parse.yacc"
 
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef        YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
+#define MOREALIASES (32)
+aliasinfo *aliases = NULL;
+size_t naliases = 0;
+size_t nslots = 0;
 
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
 
-   Do not make this value too large; the results are undefined if
-   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
+/*
+ * Compare two aliasinfo structures, strcmp() style.
+ * Note that we do *not* compare their values.
+ */
+static int
+aliascmp(a1, a2)
+    const VOID *a1, *a2;
+{
+    int r;
+    aliasinfo *ai1, *ai2;
 
-#if YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
+    ai1 = (aliasinfo *) a1;
+    ai2 = (aliasinfo *) a2;
+    if ((r = strcmp(ai1->name, ai2->name)) == 0)
+       r = ai1->type - ai2->type;
 
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-\f
-#ifdef YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined (__GLIBC__) && defined (_STRING_H)
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-static YYSIZE_T
-#   if defined (__STDC__) || defined (__cplusplus)
-yystrlen (const char *yystr)
-#   else
-yystrlen (yystr)
-     const char *yystr;
-#   endif
-{
-  register const char *yys = yystr;
-
-  while (*yys++ != '\0')
-    continue;
-
-  return yys - yystr - 1;
+    return(r);
 }
-#  endif
-# endif
 
-# ifndef yystpcpy
-#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-#   if defined (__STDC__) || defined (__cplusplus)
-yystpcpy (char *yydest, const char *yysrc)
-#   else
-yystpcpy (yydest, yysrc)
-     char *yydest;
-     const char *yysrc;
-#   endif
-{
-  register char *yyd = yydest;
-  register const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-#endif
-\f
-#line 315 "/usr/share/bison/bison.simple"
-
-
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
-   into yyparse.  The argument should have type void *.
-   It should actually point to an object.
-   Grammar actions can access the variable by casting it
-   to the proper pointer type.  */
-
-#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-#  define YYPARSE_PARAM_DECL
-# else
-#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-# endif
-#else /* !YYPARSE_PARAM */
-# define YYPARSE_PARAM_ARG
-# define YYPARSE_PARAM_DECL
-#endif /* !YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes.  */
-#ifdef __GNUC__
-# ifdef YYPARSE_PARAM
-int yyparse (void *);
-# else
-int yyparse (void);
-# endif
-#endif
+/*
+ * Compare two generic_alias structures, strcmp() style.
+ */
+static int
+genaliascmp(entry, key)
+    const VOID *entry, *key;
+{
+    int r;
+    struct generic_alias *ga1, *ga2;
 
-/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
-   variables are global, or local to YYPARSE.  */
-
-#define YY_DECL_NON_LSP_VARIABLES                      \
-/* The lookahead symbol.  */                           \
-int yychar;                                            \
-                                                       \
-/* The semantic value of the lookahead symbol. */      \
-YYSTYPE yylval;                                                \
-                                                       \
-/* Number of parse errors so far.  */                  \
-int yynerrs;
+    ga1 = (struct generic_alias *) key;
+    ga2 = (struct generic_alias *) entry;
+    if ((r = strcmp(ga1->alias, ga2->alias)) == 0)
+       r = ga1->type - ga2->type;
 
-#if YYLSP_NEEDED
-# define YY_DECL_VARIABLES                     \
-YY_DECL_NON_LSP_VARIABLES                      \
-                                               \
-/* Location data for the lookahead symbol.  */ \
-YYLTYPE yylloc;
-#else
-# define YY_DECL_VARIABLES                     \
-YY_DECL_NON_LSP_VARIABLES
-#endif
+    return(r);
+}
 
 
-/* If nonreentrant, generate the variables here. */
+/*
+ * Adds the named alias of the specified type to the aliases list.
+ */
+static int
+add_alias(alias, type, val)
+    char *alias;
+    int type;
+    int val;
+{
+    aliasinfo ai, *aip;
+    size_t onaliases;
+    char s[512];
 
-#if !YYPURE
-YY_DECL_VARIABLES
-#endif  /* !YYPURE */
+    if (naliases >= nslots && !more_aliases()) {
+       (void) snprintf(s, sizeof(s), "Out of memory defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
 
-int
-yyparse (YYPARSE_PARAM_ARG)
-     YYPARSE_PARAM_DECL
-{
-  /* If reentrant, generate the variables here. */
-#if YYPURE
-  YY_DECL_VARIABLES
-#endif  /* !YYPURE */
-
-  register int yystate;
-  register int yyn;
-  int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yychar1 = 0;
-
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
-
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
-
-  /* The state stack. */
-  short        yyssa[YYINITDEPTH];
-  short *yyss = yyssa;
-  register short *yyssp;
-
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
-  register YYSTYPE *yyvsp;
-
-#if YYLSP_NEEDED
-  /* The location stack.  */
-  YYLTYPE yylsa[YYINITDEPTH];
-  YYLTYPE *yyls = yylsa;
-  YYLTYPE *yylsp;
-#endif
+    ai.type = type;
+    ai.val = val;
+    ai.name = estrdup(alias);
+    onaliases = naliases;
 
-#if YYLSP_NEEDED
-# define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
-#else
-# define YYPOPSTACK   (yyvsp--, yyssp--)
-#endif
+    aip = (aliasinfo *) lsearch((VOID *)&ai, (VOID *)aliases, &naliases,
+                               sizeof(ai), aliascmp);
+    if (aip == NULL) {
+       (void) snprintf(s, sizeof(s), "Aliases corrupted defining alias `%s'",
+                       alias);
+       yyerror(s);
+       return(FALSE);
+    }
+    if (onaliases == naliases) {
+       (void) snprintf(s, sizeof(s), "Alias `%s' already defined", alias);
+       yyerror(s);
+       return(FALSE);
+    }
 
-  YYSIZE_T yystacksize = YYINITDEPTH;
+    return(TRUE);
+}
 
+/*
+ * Searches for the named alias of the specified type.
+ */
+static aliasinfo *
+find_alias(alias, type)
+    char *alias;
+    int type;
+{
+    aliasinfo ai;
 
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-#if YYLSP_NEEDED
-  YYLTYPE yyloc;
-#endif
+    ai.name = alias;
+    ai.type = type;
 
-  /* When reducing, the number of symbols on the RHS of the reduced
-     rule. */
-  int yylen;
+    return((aliasinfo *) lfind((VOID *)&ai, (VOID *)aliases, &naliases,
+                sizeof(ai), aliascmp));
+}
 
-  YYDPRINTF ((stderr, "Starting parse\n"));
+/*
+ * Allocates more space for the aliases list.
+ */
+static int
+more_aliases()
+{
 
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY;            /* Cause a token to be read.  */
+    nslots += MOREALIASES;
+    if (nslots == MOREALIASES)
+       aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
+    else
+       aliases = (aliasinfo *) realloc(aliases, nslots * sizeof(aliasinfo));
 
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
+    return(aliases != NULL);
+}
 
-  yyssp = yyss;
-  yyvsp = yyvs;
-#if YYLSP_NEEDED
-  yylsp = yyls;
-#endif
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed. so pushing a state here evens the stacks.
-     */
-  yyssp++;
+/*
+ * Lists the contents of the aliases list.
+ */
+void
+dumpaliases()
+{
+    size_t n;
 
- yysetstate:
-  *yyssp = yystate;
+    for (n = 0; n < naliases; n++) {
+       if (aliases[n].val == -1)
+           continue;
 
-  if (yyssp >= yyss + yystacksize - 1)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-       /* Give user a chance to reallocate the stack. Use copies of
-          these so that the &'s don't force the real ones into
-          memory.  */
-       YYSTYPE *yyvs1 = yyvs;
-       short *yyss1 = yyss;
-
-       /* Each stack pointer address is followed by the size of the
-          data in use in that stack, in bytes.  */
-# if YYLSP_NEEDED
-       YYLTYPE *yyls1 = yyls;
-       /* This used to be a conditional around just the two extra args,
-          but that might be undefined if yyoverflow is a macro.  */
-       yyoverflow ("parser stack overflow",
-                   &yyss1, yysize * sizeof (*yyssp),
-                   &yyvs1, yysize * sizeof (*yyvsp),
-                   &yyls1, yysize * sizeof (*yylsp),
-                   &yystacksize);
-       yyls = yyls1;
-# else
-       yyoverflow ("parser stack overflow",
-                   &yyss1, yysize * sizeof (*yyssp),
-                   &yyvs1, yysize * sizeof (*yyvsp),
-                   &yystacksize);
-# endif
-       yyss = yyss1;
-       yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyoverflowlab;
-# else
-      /* Extend the stack our own way.  */
-      if (yystacksize >= YYMAXDEPTH)
-       goto yyoverflowlab;
-      yystacksize *= 2;
-      if (yystacksize > YYMAXDEPTH)
-       yystacksize = YYMAXDEPTH;
-
-      {
-       short *yyss1 = yyss;
-       union yyalloc *yyptr =
-         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-       if (! yyptr)
-         goto yyoverflowlab;
-       YYSTACK_RELOCATE (yyss);
-       YYSTACK_RELOCATE (yyvs);
-# if YYLSP_NEEDED
-       YYSTACK_RELOCATE (yyls);
-# endif
-# undef YYSTACK_RELOCATE
-       if (yyss1 != yyssa)
-         YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
+       switch (aliases[n].type) {
+       case HOST_ALIAS:
+           (void) puts("HOST_ALIAS");
+           break;
 
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-#if YYLSP_NEEDED
-      yylsp = yyls + yysize - 1;
-#endif
+       case CMND_ALIAS:
+           (void) puts("CMND_ALIAS");
+           break;
 
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                 (unsigned long int) yystacksize));
+       case USER_ALIAS:
+           (void) puts("USER_ALIAS");
+           break;
 
-      if (yyssp >= yyss + yystacksize - 1)
-       YYABORT;
+       case RUNAS_ALIAS:
+           (void) puts("RUNAS_ALIAS");
+           break;
+       }
+       (void) printf("\t%s: %d\n", aliases[n].name, aliases[n].val);
     }
+}
 
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+/*
+ * Lists the contents of cm_list and ga_list for `sudo -l'.
+ */
+void
+list_matches()
+{
+    int i; 
+    char *p;
+    struct generic_alias *ga, key;
 
-  goto yybackup;
+    (void) printf("User %s may run the following commands on this host:\n",
+       user_name);
+    for (i = 0; i < cm_list_len; i++) {
 
+       /* Print the runas list. */
+       (void) fputs("    ", stdout);
+       if (cm_list[i].runas) {
+           (void) putchar('(');
+           p = strtok(cm_list[i].runas, ", ");
+           do {
+               if (p != cm_list[i].runas)
+                   (void) fputs(", ", stdout);
 
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
+               key.alias = p;
+               key.type = RUNAS_ALIAS;
+               if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+                   (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+                   (void) fputs(ga->entries, stdout);
+               else
+                   (void) fputs(p, stdout);
+           } while ((p = strtok(NULL, ", ")));
+           (void) fputs(") ", stdout);
+       } else {
+           (void) printf("(%s) ", def_str(I_RUNAS_DEFAULT));
+       }
 
-/* Do appropriate processing given the current state.  */
-/* Read a lookahead token if we need one and don't already have one.  */
-/* yyresume: */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-
-  yyn = yypact[yystate];
-  if (yyn == YYFLAG)
-    goto yydefault;
+       /* Is a password required? */
+       if (cm_list[i].nopasswd == TRUE && def_flag(I_AUTHENTICATE))
+           (void) fputs("NOPASSWD: ", stdout);
+       else if (cm_list[i].nopasswd == FALSE && !def_flag(I_AUTHENTICATE))
+           (void) fputs("PASSWD: ", stdout);
 
-  /* Not known => get a lookahead token if don't already have one.  */
+       /* Print the actual command or expanded Cmnd_Alias. */
+       key.alias = cm_list[i].cmnd;
+       key.type = CMND_ALIAS;
+       if ((ga = (struct generic_alias *) lfind((VOID *) &key,
+           (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
+           (void) puts(ga->entries);
+       else
+           (void) puts(cm_list[i].cmnd);
+    }
 
-  /* yychar is either YYEMPTY or YYEOF
-     or a valid token in external form.  */
+    /* Be nice and free up space now that we are done. */
+    for (i = 0; i < ga_list_len; i++) {
+       free(ga_list[i].alias);
+       free(ga_list[i].entries);
+    }
+    free(ga_list);
+    ga_list = NULL;
 
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+    for (i = 0; i < cm_list_len; i++) {
+       free(cm_list[i].runas);
+       free(cm_list[i].cmnd);
     }
+    free(cm_list);
+    cm_list = NULL;
+    cm_list_len = 0;
+    cm_list_size = 0;
+}
 
-  /* Convert token to internal form (in yychar1) for indexing tables with */
+/*
+ * Appends a source string to the destination, optionally prefixing a separator.
+ */
+static void
+append(src, dstp, dst_len, dst_size, separator)
+    char *src, **dstp;
+    size_t *dst_len, *dst_size;
+    char *separator;
+{
+    size_t src_len = strlen(src);
+    char *dst = *dstp;
 
-  if (yychar <= 0)             /* This means end of input. */
-    {
-      yychar1 = 0;
-      yychar = YYEOF;          /* Don't call YYLEX any more */
+    /*
+     * Only add the separator if there is something to separate from.
+     * If the last char is a '!', don't apply the separator (XXX).
+     */
+    if (separator && dst && dst[*dst_len - 1] != '!')
+       src_len += strlen(separator);
+    else
+       separator = NULL;
 
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    /* Assumes dst will be NULL if not set. */
+    if (dst == NULL) {
+       dst = (char *) emalloc(BUFSIZ);
+       *dst_size = BUFSIZ;
+       *dst_len = 0;
+       *dstp = dst;
     }
-  else
-    {
-      yychar1 = YYTRANSLATE (yychar);
 
-#if YYDEBUG
-     /* We have to keep this `#if YYDEBUG', since we use variables
-       which are defined only if `YYDEBUG' is set.  */
-      if (yydebug)
-       {
-         YYFPRINTF (stderr, "Next token is %d (%s",
-                    yychar, yytname[yychar1]);
-         /* Give the individual parser a way to print the precise
-            meaning of a token, for further debugging info.  */
-# ifdef YYPRINT
-         YYPRINT (stderr, yychar, yylval);
-# endif
-         YYFPRINTF (stderr, ")\n");
-       }
-#endif
-    }
+    /* Allocate more space if necessary. */
+    if (*dst_size <= *dst_len + src_len) {
+       while (*dst_size <= *dst_len + src_len)
+           *dst_size += BUFSIZ;
 
-  yyn += yychar1;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
-    goto yydefault;
+       dst = (char *) erealloc(dst, *dst_size);
+       *dstp = dst;
+    }
 
-  yyn = yytable[yyn];
+    /* Copy src -> dst adding a separator if appropriate and adjust len. */
+    dst += *dst_len;
+    *dst_len += src_len;
+    *dst = '\0';
+    if (separator)
+       (void) strcat(dst, separator);
+    (void) strcat(dst, src);
+}
 
-  /* yyn is what to do for this token type in this state.
-     Negative => reduce, -yyn is rule number.
-     Positive => shift, yyn is new state.
-       New state is final state => don't bother to shift,
-       just return success.
-     0, or most negative number => error.  */
+/*
+ * Frees up space used by the aliases list and resets the associated counters.
+ */
+void
+reset_aliases()
+{
+    size_t n;
 
-  if (yyn < 0)
-    {
-      if (yyn == YYFLAG)
-       goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
+    if (aliases) {
+       for (n = 0; n < naliases; n++)
+           free(aliases[n].name);
+       free(aliases);
+       aliases = NULL;
     }
-  else if (yyn == 0)
-    goto yyerrlab;
+    naliases = nslots = 0;
+}
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
+/*
+ * Increments ga_list_len, allocating more space as necessary.
+ */
+static void
+expand_ga_list()
+{
 
-  /* Shift the lookahead token.  */
-  YYDPRINTF ((stderr, "Shifting token %d (%s), ",
-             yychar, yytname[yychar1]));
+    if (++ga_list_len >= ga_list_size) {
+       while ((ga_list_size += STACKINCREMENT) < ga_list_len)
+           ;
+       ga_list = (struct generic_alias *)
+           erealloc(ga_list, sizeof(struct generic_alias) * ga_list_size);
+    }
 
-  /* Discard the token being shifted unless it is eof.  */
-  if (yychar != YYEOF)
-    yychar = YYEMPTY;
+    ga_list[ga_list_len - 1].entries = NULL;
+}
 
-  *++yyvsp = yylval;
-#if YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
+/*
+ * Increments cm_list_len, allocating more space as necessary.
+ */
+static void
+expand_match_list()
+{
 
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
+    if (++cm_list_len >= cm_list_size) {
+       while ((cm_list_size += STACKINCREMENT) < cm_list_len)
+           ;
+       if (cm_list == NULL)
+           cm_list_len = 0;            /* start at 0 since it is a subscript */
+       cm_list = (struct command_match *)
+           erealloc(cm_list, sizeof(struct command_match) * cm_list_size);
+    }
 
-  yystate = yyn;
-  goto yynewstate;
+    cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
+    cm_list[cm_list_len].nopasswd = FALSE;
+}
 
+/*
+ * Frees up spaced used by a previous parser run and allocates new space
+ * for various data structures.
+ */
+void
+init_parser()
+{
 
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
+    /* Free up old data structures if we run the parser more than once. */
+    if (match) {
+       free(match);
+       match = NULL;
+       top = 0;
+       parse_error = FALSE;
+       errorlineno = -1;   
+       sudolineno = 1;     
+    }
 
+    /* Allocate space for the matching stack. */
+    stacksize = STACKINCREMENT;
+    match = (struct matchstack *) emalloc(sizeof(struct matchstack) * stacksize);
 
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to the semantic value of
-     the lookahead token.  This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-#if YYLSP_NEEDED
-  /* Similarly for the default location.  Let the user run additional
-     commands if for instance locations are ranges.  */
-  yyloc = yylsp[1-yylen];
-  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+    /* Allocate space for the match list (for `sudo -l'). */
+    if (printmatches == TRUE)
+       expand_match_list();
+}
+#line 940 "sudo.tab.c"
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+#if defined(__cplusplus) || __STDC__
+static int yygrowstack(void)
+#else
+static int yygrowstack()
 #endif
+{
+    int newsize, i;
+    short *newss;
+    YYSTYPE *newvs;
+
+    if ((newsize = yystacksize) == 0)
+        newsize = YYINITSTACKSIZE;
+    else if (newsize >= YYMAXDEPTH)
+        return -1;
+    else if ((newsize *= 2) > YYMAXDEPTH)
+        newsize = YYMAXDEPTH;
+    i = yyssp - yyss;
+    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
+      (short *)malloc(newsize * sizeof *newss);
+    if (newss == NULL)
+        goto bail;
+    yyss = newss;
+    yyssp = newss + i;
+    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
+      (YYSTYPE *)malloc(newsize * sizeof *newvs);
+    if (newvs == NULL)
+        goto bail;
+    yyvs = newvs;
+    yyvsp = newvs + i;
+    yystacksize = newsize;
+    yysslim = yyss + newsize - 1;
+    return 0;
+bail:
+    if (yyss)
+            free(yyss);
+    if (yyvs)
+            free(yyvs);
+    yyss = yyssp = NULL;
+    yyvs = yyvsp = NULL;
+    yystacksize = 0;
+    return -1;
+}
 
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+#if defined(__cplusplus) || __STDC__
+yyparse(void)
+#else
+yyparse()
+#endif
+{
+    int yym, yyn, yystate;
 #if YYDEBUG
-  /* We have to keep this `#if YYDEBUG', since we use variables which
-     are defined only if `YYDEBUG' is set.  */
-  if (yydebug)
+#if defined(__cplusplus) || __STDC__
+    const char *yys;
+#else /* !(defined(__cplusplus) || __STDC__) */
+    char *yys;
+#endif /* !(defined(__cplusplus) || __STDC__) */
+
+    if ((yys = getenv("YYDEBUG")))
     {
-      int yyi;
+        yyn = *yys;
+        if (yyn >= '0' && yyn <= '9')
+            yydebug = yyn - '0';
+    }
+#endif /* YYDEBUG */
 
-      YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
-                yyn, yyrline[yyn]);
+    yynerrs = 0;
+    yyerrflag = 0;
+    yychar = (-1);
 
-      /* Print the symbols being reduced, and their result.  */
-      for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
-       YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
-      YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    if (yyss == NULL && yygrowstack()) goto yyoverflow;
+    yyssp = yyss;
+    yyvsp = yyvs;
+    *yyssp = yystate = 0;
+
+yyloop:
+    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+    if (yychar < 0)
+    {
+        if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+        if (yydebug)
+        {
+            yys = 0;
+            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+            if (!yys) yys = "illegal-symbol";
+            printf("%sdebug: state %d, reading %d (%s)\n",
+                    YYPREFIX, yystate, yychar, yys);
+        }
+#endif
+    }
+    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+    {
+#if YYDEBUG
+        if (yydebug)
+            printf("%sdebug: state %d, shifting to state %d\n",
+                    YYPREFIX, yystate, yytable[yyn]);
+#endif
+        if (yyssp >= yysslim && yygrowstack())
+        {
+            goto yyoverflow;
+        }
+        *++yyssp = yystate = yytable[yyn];
+        *++yyvsp = yylval;
+        yychar = (-1);
+        if (yyerrflag > 0)  --yyerrflag;
+        goto yyloop;
+    }
+    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+    {
+        yyn = yytable[yyn];
+        goto yyreduce;
     }
+    if (yyerrflag) goto yyinrecovery;
+#if defined(lint) || defined(__GNUC__)
+    goto yynewerror;
 #endif
-
-  switch (yyn) {
-
+yynewerror:
+    yyerror("syntax error");
+#if defined(lint) || defined(__GNUC__)
+    goto yyerrlab;
+#endif
+yyerrlab:
+    ++yynerrs;
+yyinrecovery:
+    if (yyerrflag < 3)
+    {
+        yyerrflag = 3;
+        for (;;)
+        {
+            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+            {
+#if YYDEBUG
+                if (yydebug)
+                    printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+                if (yyssp >= yysslim && yygrowstack())
+                {
+                    goto yyoverflow;
+                }
+                *++yyssp = yystate = yytable[yyn];
+                *++yyvsp = yylval;
+                goto yyloop;
+            }
+            else
+            {
+#if YYDEBUG
+                if (yydebug)
+                    printf("%sdebug: error recovery discarding state %d\n",
+                            YYPREFIX, *yyssp);
+#endif
+                if (yyssp <= yyss) goto yyabort;
+                --yyssp;
+                --yyvsp;
+            }
+        }
+    }
+    else
+    {
+        if (yychar == 0) goto yyabort;
+#if YYDEBUG
+        if (yydebug)
+        {
+            yys = 0;
+            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+            if (!yys) yys = "illegal-symbol";
+            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+                    YYPREFIX, yystate, yychar, yys);
+        }
+#endif
+        yychar = (-1);
+        goto yyloop;
+    }
+yyreduce:
+#if YYDEBUG
+    if (yydebug)
+        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+                YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+    yym = yylen[yyn];
+    yyval = yyvsp[1-yym];
+    switch (yyn)
+    {
 case 3:
 #line 264 "parse.yacc"
 { ; }
-    break;
+break;
 case 4:
 #line 266 "parse.yacc"
 { yyerrok; }
-    break;
+break;
 case 5:
 #line 267 "parse.yacc"
 { push; }
-    break;
+break;
 case 6:
 #line 267 "parse.yacc"
 {
                            while (top && user_matches != TRUE)
                                pop;
                        }
-    break;
+break;
 case 7:
 #line 272 "parse.yacc"
 { ; }
-    break;
+break;
 case 8:
 #line 274 "parse.yacc"
 { ; }
-    break;
+break;
 case 9:
 #line 276 "parse.yacc"
 { ; }
-    break;
+break;
 case 10:
 #line 278 "parse.yacc"
 { ; }
-    break;
+break;
 case 11:
 #line 280 "parse.yacc"
 { ; }
-    break;
+break;
 case 13:
 #line 285 "parse.yacc"
 {
                            defaults_matches = TRUE;
                        }
-    break;
+break;
 case 14:
 #line 288 "parse.yacc"
 { push; }
-    break;
+break;
 case 15:
 #line 288 "parse.yacc"
 {
                            defaults_matches = user_matches;
                            pop;
                        }
-    break;
+break;
 case 16:
 #line 292 "parse.yacc"
 { push; }
-    break;
+break;
 case 17:
 #line 292 "parse.yacc"
 {
                            defaults_matches = host_matches;
                            pop;
                        }
-    break;
+break;
 case 20:
 #line 301 "parse.yacc"
 {
@@ -1279,7 +1215,7 @@ case 20:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 21:
 #line 309 "parse.yacc"
 {
@@ -1290,7 +1226,7 @@ case 21:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 22:
 #line 317 "parse.yacc"
 {
@@ -1302,7 +1238,7 @@ case 22:
                            free(yyvsp[-2].string);
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 23:
 #line 326 "parse.yacc"
 {
@@ -1314,7 +1250,7 @@ case 23:
                            free(yyvsp[-2].string);
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 24:
 #line 335 "parse.yacc"
 {
@@ -1326,7 +1262,7 @@ case 24:
                            free(yyvsp[-2].string);
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 27:
 #line 349 "parse.yacc"
 {
@@ -1342,27 +1278,27 @@ case 27:
                            else
                                no_passwd = TRUE;
                        }
-    break;
+break;
 case 28:
 #line 364 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                host_matches = yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 29:
 #line 368 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                host_matches = ! yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 30:
 #line 373 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
-    break;
+break;
 case 31:
 #line 376 "parse.yacc"
 {
@@ -1372,7 +1308,7 @@ case 31:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 32:
 #line 383 "parse.yacc"
 {
@@ -1382,7 +1318,7 @@ case 32:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 33:
 #line 390 "parse.yacc"
 {
@@ -1392,7 +1328,7 @@ case 33:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 34:
 #line 397 "parse.yacc"
 {
@@ -1417,7 +1353,7 @@ case 34:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 37:
 #line 425 "parse.yacc"
 {
@@ -1445,14 +1381,14 @@ case 37:
                                pushcp;
                            cmnd_matches = -1;
                        }
-    break;
+break;
 case 38:
 #line 452 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                cmnd_matches = yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 39:
 #line 456 "parse.yacc"
 {
@@ -1464,14 +1400,14 @@ case 39:
                                    append_cmnd("!", NULL);
                            }
                        }
-    break;
+break;
 case 40:
 #line 464 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                cmnd_matches = ! yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 41:
 #line 470 "parse.yacc"
 {
@@ -1497,17 +1433,17 @@ case 41:
                                runas_matches = (strcmp(*user_runas,
                                    def_str(I_RUNAS_DEFAULT)) == 0);
                        }
-    break;
+break;
 case 42:
 #line 493 "parse.yacc"
 {
                            runas_matches = (yyvsp[0].BOOLEAN == TRUE ? TRUE : FALSE);
                        }
-    break;
+break;
 case 43:
 #line 498 "parse.yacc"
 { ; }
-    break;
+break;
 case 44:
 #line 499 "parse.yacc"
 {
@@ -1517,11 +1453,11 @@ case 44:
                            else
                                yyval.BOOLEAN = yyvsp[-2].BOOLEAN;
                        }
-    break;
+break;
 case 45:
 #line 508 "parse.yacc"
 { ; }
-    break;
+break;
 case 46:
 #line 509 "parse.yacc"
 {
@@ -1533,14 +1469,14 @@ case 46:
                                    append_runas("!", ", ");
                            }
                        }
-    break;
+break;
 case 47:
 #line 517 "parse.yacc"
 {
                            /* Set $$ to the negation of runasuser */
                            yyval.BOOLEAN = (yyvsp[0].BOOLEAN == -1 ? -1 : ! yyvsp[0].BOOLEAN);
                        }
-    break;
+break;
 case 48:
 #line 522 "parse.yacc"
 {
@@ -1557,7 +1493,7 @@ case 48:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 49:
 #line 536 "parse.yacc"
 {
@@ -1574,7 +1510,7 @@ case 49:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 50:
 #line 550 "parse.yacc"
 {
@@ -1591,7 +1527,7 @@ case 50:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 51:
 #line 564 "parse.yacc"
 {
@@ -1623,7 +1559,7 @@ case 51:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 52:
 #line 593 "parse.yacc"
 {
@@ -1636,7 +1572,7 @@ case 52:
                            }
                            yyval.BOOLEAN = TRUE;
                        }
-    break;
+break;
 case 53:
 #line 605 "parse.yacc"
 {
@@ -1649,7 +1585,7 @@ case 53:
                                    cm_list[cm_list_len].nopasswd = FALSE;
                            }
                        }
-    break;
+break;
 case 54:
 #line 615 "parse.yacc"
 {
@@ -1658,7 +1594,7 @@ case 54:
                                user_matches == TRUE)
                                cm_list[cm_list_len].nopasswd = TRUE;
                        }
-    break;
+break;
 case 55:
 #line 621 "parse.yacc"
 {
@@ -1667,7 +1603,7 @@ case 55:
                                user_matches == TRUE)
                                cm_list[cm_list_len].nopasswd = FALSE;
                        }
-    break;
+break;
 case 56:
 #line 629 "parse.yacc"
 {
@@ -1682,10 +1618,14 @@ case 56:
                            }
 
                            yyval.BOOLEAN = TRUE;
+
+                           if (safe_cmnd)
+                               free(safe_cmnd);
+                           safe_cmnd = estrdup(user_cmnd);
                        }
-    break;
+break;
 case 57:
-#line 642 "parse.yacc"
+#line 646 "parse.yacc"
 {
                            aliasinfo *aip;
 
@@ -1715,9 +1655,9 @@ case 57:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 58:
-#line 671 "parse.yacc"
+#line 675 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE) {
@@ -1744,22 +1684,22 @@ case 58:
                            if (yyvsp[0].command.args)
                                free(yyvsp[0].command.args);
                        }
-    break;
+break;
 case 61:
-#line 703 "parse.yacc"
+#line 707 "parse.yacc"
 { push; }
-    break;
+break;
 case 62:
-#line 703 "parse.yacc"
+#line 707 "parse.yacc"
 {
                            if ((host_matches != -1 || pedantic) &&
                                !add_alias(yyvsp[-3].string, HOST_ALIAS, host_matches))
                                YYERROR;
                            pop;
                        }
-    break;
+break;
 case 67:
-#line 719 "parse.yacc"
+#line 723 "parse.yacc"
 {
                            push;
                            if (printmatches == TRUE) {
@@ -1770,9 +1710,9 @@ case 67:
                                ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
                             }
                        }
-    break;
+break;
 case 68:
-#line 728 "parse.yacc"
+#line 732 "parse.yacc"
 {
                            if ((cmnd_matches != -1 || pedantic) &&
                                !add_alias(yyvsp[-3].string, CMND_ALIAS, cmnd_matches))
@@ -1783,13 +1723,13 @@ case 68:
                            if (printmatches == TRUE)
                                in_alias = FALSE;
                        }
-    break;
+break;
 case 69:
-#line 740 "parse.yacc"
+#line 744 "parse.yacc"
 { ; }
-    break;
+break;
 case 73:
-#line 748 "parse.yacc"
+#line 752 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                in_alias = TRUE;
@@ -1799,9 +1739,9 @@ case 73:
                                ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
                            }
                        }
-    break;
+break;
 case 74:
-#line 756 "parse.yacc"
+#line 760 "parse.yacc"
 {
                            if ((yyvsp[0].BOOLEAN != -1 || pedantic) &&
                                !add_alias(yyvsp[-3].string, RUNAS_ALIAS, yyvsp[0].BOOLEAN))
@@ -1811,13 +1751,13 @@ case 74:
                            if (printmatches == TRUE)
                                in_alias = FALSE;
                        }
-    break;
+break;
 case 77:
-#line 771 "parse.yacc"
+#line 775 "parse.yacc"
 { push; }
-    break;
+break;
 case 78:
-#line 771 "parse.yacc"
+#line 775 "parse.yacc"
 {
                            if ((user_matches != -1 || pedantic) &&
                                !add_alias(yyvsp[-3].string, USER_ALIAS, user_matches))
@@ -1825,23 +1765,23 @@ case 78:
                            pop;
                            free(yyvsp[-3].string);
                        }
-    break;
+break;
 case 81:
-#line 784 "parse.yacc"
+#line 788 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                user_matches = yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 82:
-#line 788 "parse.yacc"
+#line 792 "parse.yacc"
 {
                            if (yyvsp[0].BOOLEAN != -1)
                                user_matches = ! yyvsp[0].BOOLEAN;
                        }
-    break;
+break;
 case 83:
-#line 793 "parse.yacc"
+#line 797 "parse.yacc"
 {
                            if (strcmp(yyvsp[0].string, user_name) == 0)
                                yyval.BOOLEAN = TRUE;
@@ -1849,9 +1789,9 @@ case 83:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 84:
-#line 800 "parse.yacc"
+#line 804 "parse.yacc"
 {
                            if (usergr_matches(yyvsp[0].string, user_name))
                                yyval.BOOLEAN = TRUE;
@@ -1859,9 +1799,9 @@ case 84:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 85:
-#line 807 "parse.yacc"
+#line 811 "parse.yacc"
 {
                            if (netgr_matches(yyvsp[0].string, NULL, NULL, user_name))
                                yyval.BOOLEAN = TRUE;
@@ -1869,9 +1809,9 @@ case 85:
                                yyval.BOOLEAN = -1;
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 86:
-#line 814 "parse.yacc"
+#line 818 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, USER_ALIAS);
 
@@ -1892,595 +1832,67 @@ case 86:
                            }
                            free(yyvsp[0].string);
                        }
-    break;
+break;
 case 87:
-#line 834 "parse.yacc"
+#line 838 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
-    break;
-}
-
-#line 705 "/usr/share/bison/bison.simple"
-
-\f
-  yyvsp -= yylen;
-  yyssp -= yylen;
-#if YYLSP_NEEDED
-  yylsp -= yylen;
-#endif
-
-#if YYDEBUG
-  if (yydebug)
-    {
-      short *yyssp1 = yyss - 1;
-      YYFPRINTF (stderr, "state stack now");
-      while (yyssp1 != yyssp)
-       YYFPRINTF (stderr, " %d", *++yyssp1);
-      YYFPRINTF (stderr, "\n");
-    }
-#endif
-
-  *++yyvsp = yyval;
-#if YYLSP_NEEDED
-  *++yylsp = yyloc;
-#endif
-
-  /* Now `shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
-  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTBASE];
-
-  goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
-      yyn = yypact[yystate];
-
-      if (yyn > YYFLAG && yyn < YYLAST)
-       {
-         YYSIZE_T yysize = 0;
-         char *yymsg;
-         int yyx, yycount;
-
-         yycount = 0;
-         /* Start YYX at -YYN if negative to avoid negative indexes in
-            YYCHECK.  */
-         for (yyx = yyn < 0 ? -yyn : 0;
-              yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
-           if (yycheck[yyx + yyn] == yyx)
-             yysize += yystrlen (yytname[yyx]) + 15, yycount++;
-         yysize += yystrlen ("parse error, unexpected ") + 1;
-         yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
-         yymsg = (char *) YYSTACK_ALLOC (yysize);
-         if (yymsg != 0)
-           {
-             char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
-             yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
-
-             if (yycount < 5)
-               {
-                 yycount = 0;
-                 for (yyx = yyn < 0 ? -yyn : 0;
-                      yyx < (int) (sizeof (yytname) / sizeof (char *));
-                      yyx++)
-                   if (yycheck[yyx + yyn] == yyx)
-                     {
-                       const char *yyq = ! yycount ? ", expecting " : " or ";
-                       yyp = yystpcpy (yyp, yyq);
-                       yyp = yystpcpy (yyp, yytname[yyx]);
-                       yycount++;
-                     }
-               }
-             yyerror (yymsg);
-             YYSTACK_FREE (yymsg);
-           }
-         else
-           yyerror ("parse error; also virtual memory exhausted");
-       }
-      else
-#endif /* defined (YYERROR_VERBOSE) */
-       yyerror ("parse error");
+break;
+#line 1834 "sudo.tab.c"
     }
-  goto yyerrlab1;
-
-
-/*--------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action |
-`--------------------------------------------------*/
-yyerrlab1:
-  if (yyerrstatus == 3)
+    yyssp -= yym;
+    yystate = *yyssp;
+    yyvsp -= yym;
+    yym = yylhs[yyn];
+    if (yystate == 0 && yym == 0)
     {
-      /* If just tried and failed to reuse lookahead token after an
-        error, discard it.  */
-
-      /* return failure if at end of input */
-      if (yychar == YYEOF)
-       YYABORT;
-      YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
-                 yychar, yytname[yychar1]));
-      yychar = YYEMPTY;
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-
-  yyerrstatus = 3;             /* Each real token shifted decrements this */
-
-  goto yyerrhandle;
-
-
-/*-------------------------------------------------------------------.
-| yyerrdefault -- current state does not do anything special for the |
-| error token.                                                       |
-`-------------------------------------------------------------------*/
-yyerrdefault:
-#if 0
-  /* This is wrong; only states that explicitly want error tokens
-     should shift them.  */
-
-  /* If its default is to accept any token, ok.  Otherwise pop it.  */
-  yyn = yydefact[yystate];
-  if (yyn)
-    goto yydefault;
-#endif
-
-
-/*---------------------------------------------------------------.
-| yyerrpop -- pop the current state because it cannot handle the |
-| error token                                                    |
-`---------------------------------------------------------------*/
-yyerrpop:
-  if (yyssp == yyss)
-    YYABORT;
-  yyvsp--;
-  yystate = *--yyssp;
-#if YYLSP_NEEDED
-  yylsp--;
+#if YYDEBUG
+        if (yydebug)
+            printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
 #endif
-
+        yystate = YYFINAL;
+        *++yyssp = YYFINAL;
+        *++yyvsp = yyval;
+        if (yychar < 0)
+        {
+            if ((yychar = yylex()) < 0) yychar = 0;
 #if YYDEBUG
-  if (yydebug)
-    {
-      short *yyssp1 = yyss - 1;
-      YYFPRINTF (stderr, "Error: state stack now");
-      while (yyssp1 != yyssp)
-       YYFPRINTF (stderr, " %d", *++yyssp1);
-      YYFPRINTF (stderr, "\n");
+            if (yydebug)
+            {
+                yys = 0;
+                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+                if (!yys) yys = "illegal-symbol";
+                printf("%sdebug: state %d, reading %d (%s)\n",
+                        YYPREFIX, YYFINAL, yychar, yys);
+            }
+#endif
+        }
+        if (yychar == 0) goto yyaccept;
+        goto yyloop;
     }
+    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+        yystate = yytable[yyn];
+    else
+        yystate = yydgoto[yym];
+#if YYDEBUG
+    if (yydebug)
+        printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
 #endif
-
-/*--------------.
-| yyerrhandle.  |
-`--------------*/
-yyerrhandle:
-  yyn = yypact[yystate];
-  if (yyn == YYFLAG)
-    goto yyerrdefault;
-
-  yyn += YYTERROR;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
-    goto yyerrdefault;
-
-  yyn = yytable[yyn];
-  if (yyn < 0)
+    if (yyssp >= yysslim && yygrowstack())
     {
-      if (yyn == YYFLAG)
-       goto yyerrpop;
-      yyn = -yyn;
-      goto yyreduce;
+        goto yyoverflow;
     }
-  else if (yyn == 0)
-    goto yyerrpop;
-
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
-  YYDPRINTF ((stderr, "Shifting error token, "));
-
-  *++yyvsp = yylval;
-#if YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-/*---------------------------------------------.
-| yyoverflowab -- parser overflow comes here.  |
-`---------------------------------------------*/
-yyoverflowlab:
-  yyerror ("parser stack overflow");
-  yyresult = 2;
-  /* Fall through.  */
-
-yyreturn:
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-  return yyresult;
-}
-#line 839 "parse.yacc"
-
-
-#define MOREALIASES (32)
-aliasinfo *aliases = NULL;
-size_t naliases = 0;
-size_t nslots = 0;
-
-
-/*
- * Compare two aliasinfo structures, strcmp() style.
- * Note that we do *not* compare their values.
- */
-static int
-aliascmp(a1, a2)
-    const VOID *a1, *a2;
-{
-    int r;
-    aliasinfo *ai1, *ai2;
-
-    ai1 = (aliasinfo *) a1;
-    ai2 = (aliasinfo *) a2;
-    if ((r = strcmp(ai1->name, ai2->name)) == 0)
-       r = ai1->type - ai2->type;
-
-    return(r);
-}
-
-/*
- * Compare two generic_alias structures, strcmp() style.
- */
-static int
-genaliascmp(entry, key)
-    const VOID *entry, *key;
-{
-    int r;
-    struct generic_alias *ga1, *ga2;
-
-    ga1 = (struct generic_alias *) key;
-    ga2 = (struct generic_alias *) entry;
-    if ((r = strcmp(ga1->alias, ga2->alias)) == 0)
-       r = ga1->type - ga2->type;
-
-    return(r);
-}
-
-
-/*
- * Adds the named alias of the specified type to the aliases list.
- */
-static int
-add_alias(alias, type, val)
-    char *alias;
-    int type;
-    int val;
-{
-    aliasinfo ai, *aip;
-    size_t onaliases;
-    char s[512];
-
-    if (naliases >= nslots && !more_aliases()) {
-       (void) snprintf(s, sizeof(s), "Out of memory defining alias `%s'",
-                       alias);
-       yyerror(s);
-       return(FALSE);
-    }
-
-    ai.type = type;
-    ai.val = val;
-    ai.name = estrdup(alias);
-    onaliases = naliases;
-
-    aip = (aliasinfo *) lsearch((VOID *)&ai, (VOID *)aliases, &naliases,
-                               sizeof(ai), aliascmp);
-    if (aip == NULL) {
-       (void) snprintf(s, sizeof(s), "Aliases corrupted defining alias `%s'",
-                       alias);
-       yyerror(s);
-       return(FALSE);
-    }
-    if (onaliases == naliases) {
-       (void) snprintf(s, sizeof(s), "Alias `%s' already defined", alias);
-       yyerror(s);
-       return(FALSE);
-    }
-
-    return(TRUE);
-}
-
-/*
- * Searches for the named alias of the specified type.
- */
-static aliasinfo *
-find_alias(alias, type)
-    char *alias;
-    int type;
-{
-    aliasinfo ai;
-
-    ai.name = alias;
-    ai.type = type;
-
-    return((aliasinfo *) lfind((VOID *)&ai, (VOID *)aliases, &naliases,
-                sizeof(ai), aliascmp));
-}
-
-/*
- * Allocates more space for the aliases list.
- */
-static int
-more_aliases()
-{
-
-    nslots += MOREALIASES;
-    if (nslots == MOREALIASES)
-       aliases = (aliasinfo *) malloc(nslots * sizeof(aliasinfo));
-    else
-       aliases = (aliasinfo *) realloc(aliases, nslots * sizeof(aliasinfo));
-
-    return(aliases != NULL);
-}
-
-/*
- * Lists the contents of the aliases list.
- */
-void
-dumpaliases()
-{
-    size_t n;
-
-    for (n = 0; n < naliases; n++) {
-       if (aliases[n].val == -1)
-           continue;
-
-       switch (aliases[n].type) {
-       case HOST_ALIAS:
-           (void) puts("HOST_ALIAS");
-           break;
-
-       case CMND_ALIAS:
-           (void) puts("CMND_ALIAS");
-           break;
-
-       case USER_ALIAS:
-           (void) puts("USER_ALIAS");
-           break;
-
-       case RUNAS_ALIAS:
-           (void) puts("RUNAS_ALIAS");
-           break;
-       }
-       (void) printf("\t%s: %d\n", aliases[n].name, aliases[n].val);
-    }
-}
-
-/*
- * Lists the contents of cm_list and ga_list for `sudo -l'.
- */
-void
-list_matches()
-{
-    int i; 
-    char *p;
-    struct generic_alias *ga, key;
-
-    (void) printf("User %s may run the following commands on this host:\n",
-       user_name);
-    for (i = 0; i < cm_list_len; i++) {
-
-       /* Print the runas list. */
-       (void) fputs("    ", stdout);
-       if (cm_list[i].runas) {
-           (void) putchar('(');
-           p = strtok(cm_list[i].runas, ", ");
-           do {
-               if (p != cm_list[i].runas)
-                   (void) fputs(", ", stdout);
-
-               key.alias = p;
-               key.type = RUNAS_ALIAS;
-               if ((ga = (struct generic_alias *) lfind((VOID *) &key,
-                   (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
-                   (void) fputs(ga->entries, stdout);
-               else
-                   (void) fputs(p, stdout);
-           } while ((p = strtok(NULL, ", ")));
-           (void) fputs(") ", stdout);
-       } else {
-           (void) printf("(%s) ", def_str(I_RUNAS_DEFAULT));
-       }
-
-       /* Is a password required? */
-       if (cm_list[i].nopasswd == TRUE && def_flag(I_AUTHENTICATE))
-           (void) fputs("NOPASSWD: ", stdout);
-       else if (cm_list[i].nopasswd == FALSE && !def_flag(I_AUTHENTICATE))
-           (void) fputs("PASSWD: ", stdout);
-
-       /* Print the actual command or expanded Cmnd_Alias. */
-       key.alias = cm_list[i].cmnd;
-       key.type = CMND_ALIAS;
-       if ((ga = (struct generic_alias *) lfind((VOID *) &key,
-           (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
-           (void) puts(ga->entries);
-       else
-           (void) puts(cm_list[i].cmnd);
-    }
-
-    /* Be nice and free up space now that we are done. */
-    for (i = 0; i < ga_list_len; i++) {
-       free(ga_list[i].alias);
-       free(ga_list[i].entries);
-    }
-    free(ga_list);
-    ga_list = NULL;
-
-    for (i = 0; i < cm_list_len; i++) {
-       free(cm_list[i].runas);
-       free(cm_list[i].cmnd);
-    }
-    free(cm_list);
-    cm_list = NULL;
-    cm_list_len = 0;
-    cm_list_size = 0;
-}
-
-/*
- * Appends a source string to the destination, optionally prefixing a separator.
- */
-static void
-append(src, dstp, dst_len, dst_size, separator)
-    char *src, **dstp;
-    size_t *dst_len, *dst_size;
-    char *separator;
-{
-    size_t src_len = strlen(src);
-    char *dst = *dstp;
-
-    /*
-     * Only add the separator if there is something to separate from.
-     * If the last char is a '!', don't apply the separator (XXX).
-     */
-    if (separator && dst && dst[*dst_len - 1] != '!')
-       src_len += strlen(separator);
-    else
-       separator = NULL;
-
-    /* Assumes dst will be NULL if not set. */
-    if (dst == NULL) {
-       dst = (char *) emalloc(BUFSIZ);
-       *dst_size = BUFSIZ;
-       *dst_len = 0;
-       *dstp = dst;
-    }
-
-    /* Allocate more space if necessary. */
-    if (*dst_size <= *dst_len + src_len) {
-       while (*dst_size <= *dst_len + src_len)
-           *dst_size += BUFSIZ;
-
-       dst = (char *) erealloc(dst, *dst_size);
-       *dstp = dst;
-    }
-
-    /* Copy src -> dst adding a separator if appropriate and adjust len. */
-    dst += *dst_len;
-    *dst_len += src_len;
-    *dst = '\0';
-    if (separator)
-       (void) strcat(dst, separator);
-    (void) strcat(dst, src);
-}
-
-/*
- * Frees up space used by the aliases list and resets the associated counters.
- */
-void
-reset_aliases()
-{
-    size_t n;
-
-    if (aliases) {
-       for (n = 0; n < naliases; n++)
-           free(aliases[n].name);
-       free(aliases);
-       aliases = NULL;
-    }
-    naliases = nslots = 0;
-}
-
-/*
- * Increments ga_list_len, allocating more space as necessary.
- */
-static void
-expand_ga_list()
-{
-
-    if (++ga_list_len >= ga_list_size) {
-       while ((ga_list_size += STACKINCREMENT) < ga_list_len)
-           ;
-       ga_list = (struct generic_alias *)
-           erealloc(ga_list, sizeof(struct generic_alias) * ga_list_size);
-    }
-
-    ga_list[ga_list_len - 1].entries = NULL;
-}
-
-/*
- * Increments cm_list_len, allocating more space as necessary.
- */
-static void
-expand_match_list()
-{
-
-    if (++cm_list_len >= cm_list_size) {
-       while ((cm_list_size += STACKINCREMENT) < cm_list_len)
-           ;
-       if (cm_list == NULL)
-           cm_list_len = 0;            /* start at 0 since it is a subscript */
-       cm_list = (struct command_match *)
-           erealloc(cm_list, sizeof(struct command_match) * cm_list_size);
-    }
-
-    cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
-    cm_list[cm_list_len].nopasswd = FALSE;
-}
-
-/*
- * Frees up spaced used by a previous parser run and allocates new space
- * for various data structures.
- */
-void
-init_parser()
-{
-
-    /* Free up old data structures if we run the parser more than once. */
-    if (match) {
-       free(match);
-       match = NULL;
-       top = 0;
-       parse_error = FALSE;
-       errorlineno = -1;   
-       sudolineno = 1;     
-    }
-
-    /* Allocate space for the matching stack. */
-    stacksize = STACKINCREMENT;
-    match = (struct matchstack *) emalloc(sizeof(struct matchstack) * stacksize);
-
-    /* Allocate space for the match list (for `sudo -l'). */
-    if (printmatches == TRUE)
-       expand_match_list();
+    *++yyssp = yystate;
+    *++yyvsp = yyval;
+    goto yyloop;
+yyoverflow:
+    yyerror("yacc stack overflow");
+yyabort:
+    return (1);
+yyaccept:
+    return (0);
 }
index b2afd8db3a3587d3d327a3b226b634e99371d1b1..71b1255f6362b1f66f5d1deda3cd41346b179352 100644 (file)
@@ -1,38 +1,27 @@
-#ifndef BISON_SUDO_TAB_H
-# define BISON_SUDO_TAB_H
-
-#ifndef YYSTYPE
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DEFAULTS 264
+#define DEFAULTS_HOST 265
+#define DEFAULTS_USER 266
+#define RUNAS 267
+#define NOPASSWD 268
+#define PASSWD 269
+#define ALL 270
+#define COMMENT 271
+#define HOSTALIAS 272
+#define CMNDALIAS 273
+#define USERALIAS 274
+#define RUNASALIAS 275
+#define ERROR 276
 typedef union {
     char *string;
     int BOOLEAN;
     struct sudo_command command;
     int tok;
-} yystype;
-# define YYSTYPE yystype
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-# define       COMMAND 257
-# define       ALIAS   258
-# define       DEFVAR  259
-# define       NTWKADDR        260
-# define       NETGROUP        261
-# define       USERGROUP       262
-# define       WORD    263
-# define       DEFAULTS        264
-# define       DEFAULTS_HOST   265
-# define       DEFAULTS_USER   266
-# define       RUNAS   267
-# define       NOPASSWD        268
-# define       PASSWD  269
-# define       ALL     270
-# define       COMMENT 271
-# define       HOSTALIAS       272
-# define       CMNDALIAS       273
-# define       USERALIAS       274
-# define       RUNASALIAS      275
-# define       ERROR   276
-
-
+} YYSTYPE;
 extern YYSTYPE yylval;
-
-#endif /* not BISON_SUDO_TAB_H */