Diff for /embedaddon/sudo/plugins/sudoers/gram.y between versions 1.1.1.2 and 1.1.1.5

version 1.1.1.2, 2012/05/29 12:26:49 version 1.1.1.5, 2014/06/15 16:12:54
Line 1 Line 1
 %{  %{
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2012 * Copyright (c) 1996, 1998-2005, 2007-2013
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 25 Line 25
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
 # include <stdlib.h>  # include <stdlib.h>
Line 44 Line 43
 #ifdef HAVE_UNISTD_H  #ifdef HAVE_UNISTD_H
 # include <unistd.h>  # include <unistd.h>
 #endif /* HAVE_UNISTD_H */  #endif /* HAVE_UNISTD_H */
   #ifdef HAVE_INTTYPES_H
   # include <inttypes.h>
   #endif
 #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)  #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
 # include <alloca.h>  # include <alloca.h>
 #endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */  #endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
Line 52 Line 54
 #include "sudoers.h" /* XXX */  #include "sudoers.h" /* XXX */
 #include "parse.h"  #include "parse.h"
 #include "toke.h"  #include "toke.h"
 #include "gram.h"  
   
 /*  /*
  * We must define SIZE_MAX for yacc's skeleton.c.   * We must define SIZE_MAX for yacc's skeleton.c.
Line 70 Line 71
 /*  /*
  * Globals   * Globals
  */   */
 extern int sudolineno;  
 extern int last_token;  
 extern char *sudoers;  
 bool sudoers_warnings = true;  bool sudoers_warnings = true;
 bool parse_error = false;  bool parse_error = false;
 int errorlineno = -1;  int errorlineno = -1;
char *errorfile = NULL;const char *errorfile = NULL;
   
struct defaults_list defaults;struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults);
struct userspec_list userspecs;struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs);
   
 /*  /*
  * Local protoypes   * Local protoypes
Line 88  static void  add_defaults(int, struct member *, struct Line 86  static void  add_defaults(int, struct member *, struct
 static void  add_userspec(struct member *, struct privilege *);  static void  add_userspec(struct member *, struct privilege *);
 static struct defaults *new_default(char *, char *, int);  static struct defaults *new_default(char *, char *, int);
 static struct member *new_member(char *, int);  static struct member *new_member(char *, int);
       void  yyerror(const char *);static struct sudo_digest *new_digest(int, const char *);
 
void 
yyerror(const char *s) 
{ 
    debug_decl(yyerror, SUDO_DEBUG_PARSER) 
 
    /* If we last saw a newline the error is on the preceding line. */ 
    if (last_token == COMMENT) 
        sudolineno--; 
 
    /* Save the line the first error occurred on. */ 
    if (errorlineno == -1) { 
        errorlineno = sudolineno; 
        errorfile = estrdup(sudoers); 
    } 
    if (trace_print != NULL) { 
        LEXTRACE("<*> "); 
    } else if (sudoers_warnings && s != NULL) { 
        warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno); 
    } 
    parse_error = true; 
    debug_return; 
} 
 %}  %}
   
 %union {  %union {
Line 120  yyerror(const char *s) Line 95  yyerror(const char *s)
     struct member *member;      struct member *member;
     struct runascontainer *runas;      struct runascontainer *runas;
     struct privilege *privilege;      struct privilege *privilege;
       struct sudo_digest *digest;
     struct sudo_command command;      struct sudo_command command;
     struct cmndtag tag;      struct cmndtag tag;
     struct selinux_info seinfo;      struct selinux_info seinfo;
       struct solaris_privs_info privinfo;
     char *string;      char *string;
     int tok;      int tok;
 }  }
Line 135  yyerror(const char *s) Line 112  yyerror(const char *s)
 %token <string>  NETGROUP               /* a netgroup (+NAME) */  %token <string>  NETGROUP               /* a netgroup (+NAME) */
 %token <string>  USERGROUP              /* a usergroup (%NAME) */  %token <string>  USERGROUP              /* a usergroup (%NAME) */
 %token <string>  WORD                   /* a word */  %token <string>  WORD                   /* a word */
   %token <string>  DIGEST                 /* a SHA-2 digest */
 %token <tok>     DEFAULTS               /* Defaults entry */  %token <tok>     DEFAULTS               /* Defaults entry */
 %token <tok>     DEFAULTS_HOST          /* Host-specific defaults entry */  %token <tok>     DEFAULTS_HOST          /* Host-specific defaults entry */
 %token <tok>     DEFAULTS_USER          /* User-specific defaults entry */  %token <tok>     DEFAULTS_USER          /* User-specific defaults entry */
Line 161  yyerror(const char *s) Line 139  yyerror(const char *s)
 %token <tok>     ERROR  %token <tok>     ERROR
 %token <tok>     TYPE                   /* SELinux type */  %token <tok>     TYPE                   /* SELinux type */
 %token <tok>     ROLE                   /* SELinux role */  %token <tok>     ROLE                   /* SELinux role */
   %token <tok>     PRIVS                  /* Solaris privileges */
   %token <tok>     LIMITPRIVS             /* Solaris limit privileges */
   %token <tok>     MYSELF                 /* run as myself, not another user */
   %token <tok>     SHA224                 /* sha224 digest */
   %token <tok>     SHA256                 /* sha256 digest */
   %token <tok>     SHA384                 /* sha384 digest */
   %token <tok>     SHA512                 /* sha512 digest */
   
 %type <cmndspec>  cmndspec  %type <cmndspec>  cmndspec
 %type <cmndspec>  cmndspeclist  %type <cmndspec>  cmndspeclist
Line 168  yyerror(const char *s) Line 153  yyerror(const char *s)
 %type <defaults>  defaults_list  %type <defaults>  defaults_list
 %type <member>    cmnd  %type <member>    cmnd
 %type <member>    opcmnd  %type <member>    opcmnd
   %type <member>    digcmnd
 %type <member>    cmndlist  %type <member>    cmndlist
 %type <member>    host  %type <member>    host
 %type <member>    hostlist  %type <member>    hostlist
Line 186  yyerror(const char *s) Line 172  yyerror(const char *s)
 %type <seinfo>    selinux  %type <seinfo>    selinux
 %type <string>    rolespec  %type <string>    rolespec
 %type <string>    typespec  %type <string>    typespec
   %type <privinfo>  solarisprivs
   %type <string>    privsspec
   %type <string>    limitprivsspec
   %type <digest>    digest
   
 %%  %%
   
Line 237  entry  : COMMENT { Line 227  entry  : COMMENT {
   
 defaults_list   :       defaults_entry  defaults_list   :       defaults_entry
                 |       defaults_list ',' defaults_entry {                  |       defaults_list ',' defaults_entry {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
Line 261  defaults_entry : DEFVAR { Line 251  defaults_entry : DEFVAR {
   
 privileges      :       privilege  privileges      :       privilege
                 |       privileges ':' privilege {                  |       privileges ':' privilege {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
   
 privilege       :       hostlist '=' cmndspeclist {  privilege       :       hostlist '=' cmndspeclist {
                             struct privilege *p = ecalloc(1, sizeof(*p));                              struct privilege *p = ecalloc(1, sizeof(*p));
                            list2tq(&p->hostlist, $1);                            HLTQ_TO_TAILQ(&p->hostlist, $1, entries);
                            list2tq(&p->cmndlist, $3);                            HLTQ_TO_TAILQ(&p->cmndlist, $3, entries);
                            p->prev = p;                            HLTQ_INIT(p, entries);
                            /* p->next = NULL; */ 
                             $$ = p;                              $$ = p;
                         }                          }
                 ;                  ;
Line 305  host  : ALIAS { Line 294  host  : ALIAS {
   
 cmndspeclist    :       cmndspec  cmndspeclist    :       cmndspec
                 |       cmndspeclist ',' cmndspec {                  |       cmndspeclist ',' cmndspec {
                            list_append($1, $3);                            struct cmndspec *prev;
                             prev = HLTQ_LAST($1, cmndspec, entries);
                             HLTQ_CONCAT($1, $3, entries);
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
                             /* propagate role and type */                              /* propagate role and type */
                             if ($3->role == NULL)                              if ($3->role == NULL)
                                $3->role = $3->prev->role;                                $3->role = prev->role;
                             if ($3->type == NULL)                              if ($3->type == NULL)
                                $3->type = $3->prev->type;                                $3->type = prev->type;
 #endif /* HAVE_SELINUX */  #endif /* HAVE_SELINUX */
   #ifdef HAVE_PRIV_SET
                               /* propagate privs & limitprivs */
                               if ($3->privs == NULL)
                                   $3->privs = prev->privs;
                               if ($3->limitprivs == NULL)
                                   $3->limitprivs = prev->limitprivs;
   #endif /* HAVE_PRIV_SET */
                             /* propagate tags and runas list */                              /* propagate tags and runas list */
                             if ($3->tags.nopasswd == UNSPEC)                              if ($3->tags.nopasswd == UNSPEC)
                                $3->tags.nopasswd = $3->prev->tags.nopasswd;                                $3->tags.nopasswd = prev->tags.nopasswd;
                             if ($3->tags.noexec == UNSPEC)                              if ($3->tags.noexec == UNSPEC)
                                $3->tags.noexec = $3->prev->tags.noexec;                                $3->tags.noexec = prev->tags.noexec;
                             if ($3->tags.setenv == UNSPEC &&                              if ($3->tags.setenv == UNSPEC &&
                                $3->prev->tags.setenv != IMPLIED)                                prev->tags.setenv != IMPLIED)
                                $3->tags.setenv = $3->prev->tags.setenv;                                $3->tags.setenv = prev->tags.setenv;
                             if ($3->tags.log_input == UNSPEC)                              if ($3->tags.log_input == UNSPEC)
                                $3->tags.log_input = $3->prev->tags.log_input;                                $3->tags.log_input = prev->tags.log_input;
                             if ($3->tags.log_output == UNSPEC)                              if ($3->tags.log_output == UNSPEC)
                                $3->tags.log_output = $3->prev->tags.log_output;                                $3->tags.log_output = prev->tags.log_output;
                            if ((tq_empty(&$3->runasuserlist) &&                            if (($3->runasuserlist == NULL &&
                                 tq_empty(&$3->runasgrouplist)) &&                                 $3->runasgrouplist == NULL) &&
                                (!tq_empty(&$3->prev->runasuserlist) ||                                (prev->runasuserlist != NULL ||
                                 !tq_empty(&$3->prev->runasgrouplist))) {                                 prev->runasgrouplist != NULL)) {
                                $3->runasuserlist = $3->prev->runasuserlist;                                $3->runasuserlist = prev->runasuserlist;
                                $3->runasgrouplist = $3->prev->runasgrouplist;                                $3->runasgrouplist = prev->runasgrouplist;
                             }                              }
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
   
cmndspec        :       runasspec selinux cmndtag opcmnd {cmndspec        :       runasspec selinux solarisprivs cmndtag digcmnd {
                             struct cmndspec *cs = ecalloc(1, sizeof(*cs));                              struct cmndspec *cs = ecalloc(1, sizeof(*cs));
                             if ($1 != NULL) {                              if ($1 != NULL) {
                                list2tq(&cs->runasuserlist, $1->runasusers);                                if ($1->runasusers != NULL) {
                                list2tq(&cs->runasgrouplist, $1->runasgroups);                                    cs->runasuserlist =
                                         emalloc(sizeof(*cs->runasuserlist));
                                     HLTQ_TO_TAILQ(cs->runasuserlist,
                                         $1->runasusers, entries);
                                 }
                                 if ($1->runasgroups != NULL) {
                                     cs->runasgrouplist =
                                         emalloc(sizeof(*cs->runasgrouplist));
                                     HLTQ_TO_TAILQ(cs->runasgrouplist,
                                         $1->runasgroups, entries);
                                 }
                                 efree($1);                                  efree($1);
                             } else {  
                                 tq_init(&cs->runasuserlist);  
                                 tq_init(&cs->runasgrouplist);  
                             }                              }
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
                             cs->role = $2.role;                              cs->role = $2.role;
                             cs->type = $2.type;                              cs->type = $2.type;
 #endif  #endif
                            cs->tags = $3;#ifdef HAVE_PRIV_SET
                            cs->cmnd = $4;                            cs->privs = $3.privs;
                            cs->prev = cs;                            cs->limitprivs = $3.limitprivs;
                            cs->next = NULL;#endif
                             cs->tags = $4;
                             cs->cmnd = $5;
                             HLTQ_INIT(cs, entries);
                             /* sudo "ALL" implies the SETENV tag */                              /* sudo "ALL" implies the SETENV tag */
                             if (cs->cmnd->type == ALL && !cs->cmnd->negated &&                              if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
                                 cs->tags.setenv == UNSPEC)                                  cs->tags.setenv == UNSPEC)
Line 362  cmndspec : runasspec selinux cmndtag opcmnd { Line 370  cmndspec : runasspec selinux cmndtag opcmnd {
                         }                          }
                 ;                  ;
   
   digest          :       SHA224 ':' DIGEST {
                               $$ = new_digest(SUDO_DIGEST_SHA224, $3);
                           }
                   |       SHA256 ':' DIGEST {
                               $$ = new_digest(SUDO_DIGEST_SHA256, $3);
                           }
                   |       SHA384 ':' DIGEST {
                               $$ = new_digest(SUDO_DIGEST_SHA384, $3);
                           }
                   |       SHA512 ':' DIGEST {
                               $$ = new_digest(SUDO_DIGEST_SHA512, $3);
                           }
                   ;
   
   digcmnd         :       opcmnd {
                               $$ = $1;
                           }
                   |       digest opcmnd {
                               /* XXX - yuck */
                               struct sudo_command *c = (struct sudo_command *)($2->name);
                               c->digest = $1;
                               $$ = $2;
                           }
                   ;
   
 opcmnd          :       cmnd {  opcmnd          :       cmnd {
                             $$ = $1;                              $$ = $1;
                             $$->negated = false;                              $$->negated = false;
Line 404  selinux  : /* empty */ { Line 437  selinux  : /* empty */ {
                         }                          }
                 ;                  ;
   
   privsspec       :       PRIVS '=' WORD {
                               $$ = $3;
                           }
                   ;
   limitprivsspec  :       LIMITPRIVS '=' WORD {
                               $$ = $3;
                           }
                   ;
   
   solarisprivs    :       /* empty */ {
                               $$.privs = NULL;
                               $$.limitprivs = NULL;
                           }
                   |       privsspec {
                               $$.privs = $1;
                               $$.limitprivs = NULL;
                           }
                   |       limitprivsspec {
                               $$.privs = NULL;
                               $$.limitprivs = $1;
                           }
                   |       privsspec limitprivsspec {
                               $$.privs = $1;
                               $$.limitprivs = $2;
                           }
                   |       limitprivsspec privsspec {
                               $$.limitprivs = $1;
                               $$.privs = $2;
                           }
                   ;
   
 runasspec       :       /* empty */ {  runasspec       :       /* empty */ {
                             $$ = NULL;                              $$ = NULL;
                         }                          }
Line 412  runasspec : /* empty */ { Line 476  runasspec : /* empty */ {
                         }                          }
                 ;                  ;
   
runaslist       :       userlist {runaslist       :       /* empty */ {
                             $$ = ecalloc(1, sizeof(struct runascontainer));                              $$ = ecalloc(1, sizeof(struct runascontainer));
                               $$->runasusers = new_member(NULL, MYSELF);
                               /* $$->runasgroups = NULL; */
                           }
                   |       userlist {
                               $$ = ecalloc(1, sizeof(struct runascontainer));
                             $$->runasusers = $1;                              $$->runasusers = $1;
                             /* $$->runasgroups = NULL; */                              /* $$->runasgroups = NULL; */
                         }                          }
Line 427  runaslist : userlist { Line 496  runaslist : userlist {
                             /* $$->runasusers = NULL; */                              /* $$->runasusers = NULL; */
                             $$->runasgroups = $2;                              $$->runasgroups = $2;
                         }                          }
                   |       ':' {
                               $$ = ecalloc(1, sizeof(struct runascontainer));
                               $$->runasusers = new_member(NULL, MYSELF);
                               /* $$->runasgroups = NULL; */
                           }
                 ;                  ;
   
 cmndtag         :       /* empty */ {  cmndtag         :       /* empty */ {
Line 486  hostaliases : hostalias Line 560  hostaliases : hostalias
 hostalias       :       ALIAS '=' hostlist {  hostalias       :       ALIAS '=' hostlist {
                             char *s;                              char *s;
                             if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) {                              if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) {
                                yyerror(s);                                sudoerserror(s);
                                 YYERROR;                                  YYERROR;
                             }                              }
                         }                          }
Line 494  hostalias : ALIAS '=' hostlist { Line 568  hostalias : ALIAS '=' hostlist {
   
 hostlist        :       ophost  hostlist        :       ophost
                 |       hostlist ',' ophost {                  |       hostlist ',' ophost {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
Line 506  cmndaliases : cmndalias Line 580  cmndaliases : cmndalias
 cmndalias       :       ALIAS '=' cmndlist {  cmndalias       :       ALIAS '=' cmndlist {
                             char *s;                              char *s;
                             if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) {                              if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) {
                                yyerror(s);                                sudoerserror(s);
                                 YYERROR;                                  YYERROR;
                             }                              }
                         }                          }
                 ;                  ;
   
cmndlist        :       opcmndcmndlist        :       digcmnd
                |       cmndlist ',' opcmnd {                |       cmndlist ',' digcmnd {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
Line 526  runasaliases : runasalias Line 600  runasaliases : runasalias
 runasalias      :       ALIAS '=' userlist {  runasalias      :       ALIAS '=' userlist {
                             char *s;                              char *s;
                             if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) {                              if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) {
                                yyerror(s);                                sudoerserror(s);
                                 YYERROR;                                  YYERROR;
                             }                              }
                         }                          }
Line 539  useraliases : useralias Line 613  useraliases : useralias
 useralias       :       ALIAS '=' userlist {  useralias       :       ALIAS '=' userlist {
                             char *s;                              char *s;
                             if ((s = alias_add($1, USERALIAS, $3)) != NULL) {                              if ((s = alias_add($1, USERALIAS, $3)) != NULL) {
                                yyerror(s);                                sudoerserror(s);
                                 YYERROR;                                  YYERROR;
                             }                              }
                         }                          }
Line 547  useralias : ALIAS '=' userlist { Line 621  useralias : ALIAS '=' userlist {
   
 userlist        :       opuser  userlist        :       opuser
                 |       userlist ',' opuser {                  |       userlist ',' opuser {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
Line 581  user  : ALIAS { Line 655  user  : ALIAS {
   
 grouplist       :       opgroup  grouplist       :       opgroup
                 |       grouplist ',' opgroup {                  |       grouplist ',' opgroup {
                            list_append($1, $3);                            HLTQ_CONCAT($1, $3, entries);
                             $$ = $1;                              $$ = $1;
                         }                          }
                 ;                  ;
Line 608  group  : ALIAS { Line 682  group  : ALIAS {
                 ;                  ;
   
 %%  %%
   void
   sudoerserror(const char *s)
   {
       debug_decl(sudoerserror, SUDO_DEBUG_PARSER)
   
       /* If we last saw a newline the error is on the preceding line. */
       if (last_token == COMMENT)
           sudolineno--;
   
       /* Save the line the first error occurred on. */
       if (errorlineno == -1) {
           errorlineno = sudolineno;
           errorfile = estrdup(sudoers);
       }
       if (sudoers_warnings && s != NULL) {
           LEXTRACE("<*> ");
   #ifndef TRACELEXER
           if (trace_print == NULL || trace_print == sudoers_trace_print) {
               const char fmt[] = ">>> %s: %s near line %d <<<\n";
               int oldlocale;
   
               /* Warnings are displayed in the user's locale. */
               sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
               sudo_printf(SUDO_CONV_ERROR_MSG, _(fmt), sudoers, _(s), sudolineno);
               sudoers_setlocale(oldlocale, NULL);
           }
   #endif
       }
       parse_error = true;
       debug_return;
   }
   
 static struct defaults *  static struct defaults *
 new_default(char *var, char *val, int op)  new_default(char *var, char *val, int op)
 {  {
Line 617  new_default(char *var, char *val, int op) Line 723  new_default(char *var, char *val, int op)
     d = ecalloc(1, sizeof(struct defaults));      d = ecalloc(1, sizeof(struct defaults));
     d->var = var;      d->var = var;
     d->val = val;      d->val = val;
     tq_init(&d->binding);  
     /* d->type = 0; */      /* d->type = 0; */
     d->op = op;      d->op = op;
    d->prev = d;    /* d->binding = NULL */
    /* d->next = NULL; */    HLTQ_INIT(d, entries);
   
     debug_return_ptr(d);      debug_return_ptr(d);
 }  }
Line 635  new_member(char *name, int type) Line 740  new_member(char *name, int type)
     m = ecalloc(1, sizeof(struct member));      m = ecalloc(1, sizeof(struct member));
     m->name = name;      m->name = name;
     m->type = type;      m->type = type;
    m->prev = m;    HLTQ_INIT(m, entries);
    /* m->next = NULL; */ 
   
     debug_return_ptr(m);      debug_return_ptr(m);
 }  }
   
   struct sudo_digest *
   new_digest(int digest_type, const char *digest_str)
   {
       struct sudo_digest *dig;
       debug_decl(new_digest, SUDO_DEBUG_PARSER)
   
       dig = emalloc(sizeof(*dig));
       dig->digest_type = digest_type;
       dig->digest_str = estrdup(digest_str);
   
       debug_return_ptr(dig);
   }
   
 /*  /*
  * Add a list of defaults structures to the defaults list.   * Add a list of defaults structures to the defaults list.
  * The binding, if non-NULL, specifies a list of hosts, users, or   * The binding, if non-NULL, specifies a list of hosts, users, or
Line 650  static void Line 767  static void
 add_defaults(int type, struct member *bmem, struct defaults *defs)  add_defaults(int type, struct member *bmem, struct defaults *defs)
 {  {
     struct defaults *d;      struct defaults *d;
    struct member_list binding;    struct member_list *binding;
     debug_decl(add_defaults, SUDO_DEBUG_PARSER)      debug_decl(add_defaults, SUDO_DEBUG_PARSER)
   
    /*    if (defs != NULL) {
     * We can only call list2tq once on bmem as it will zero        /*
     * out the prev pointer when it consumes bmem.         * We use a single binding for each entry in defs.
     */         */
    list2tq(&binding, bmem);        binding = emalloc(sizeof(*binding));
         if (bmem != NULL)
             HLTQ_TO_TAILQ(binding, bmem, entries);
         else
             TAILQ_INIT(binding);
   
    /*        /*
     * Set type and binding (who it applies to) for new entries.         * Set type and binding (who it applies to) for new entries.
     */         * Then add to the global defaults list.
    for (d = defs; d != NULL; d = d->next) {         */
        d->type = type;        HLTQ_FOREACH(d, defs, entries) {
        d->binding = binding;            d->type = type;
             d->binding = binding;
         }
         TAILQ_CONCAT_HLTQ(&defaults, defs, entries);
     }      }
     tq_append(&defaults, defs);  
   
     debug_return;      debug_return;
 }  }
   
 /*  /*
  * Allocate a new struct userspec, populate it, and insert it at the   * Allocate a new struct userspec, populate it, and insert it at the
 * and of the userspecs list. * end of the userspecs list.
  */   */
 static void  static void
 add_userspec(struct member *members, struct privilege *privs)  add_userspec(struct member *members, struct privilege *privs)
Line 682  add_userspec(struct member *members, struct privilege  Line 805  add_userspec(struct member *members, struct privilege 
     debug_decl(add_userspec, SUDO_DEBUG_PARSER)      debug_decl(add_userspec, SUDO_DEBUG_PARSER)
   
     u = ecalloc(1, sizeof(*u));      u = ecalloc(1, sizeof(*u));
    list2tq(&u->users, members);    HLTQ_TO_TAILQ(&u->users, members, entries);
    list2tq(&u->privileges, privs);    HLTQ_TO_TAILQ(&u->privileges, privs, entries);
    u->prev = u;    TAILQ_INSERT_TAIL(&userspecs, u, entries);
    /* u->next = NULL; */ 
    tq_append(&userspecs, u); 
   
     debug_return;      debug_return;
 }  }
Line 696  add_userspec(struct member *members, struct privilege  Line 817  add_userspec(struct member *members, struct privilege 
  * the current sudoers file to path.   * the current sudoers file to path.
  */   */
 void  void
init_parser(const char *path, int quiet)init_parser(const char *path, bool quiet)
 {  {
    struct defaults *d;    struct member_list *binding;
    struct member *m, *binding;    struct defaults *d, *d_next;
    struct userspec *us;    struct userspec *us, *us_next;
    struct privilege *priv; 
    struct cmndspec *cs; 
    struct sudo_command *c; 
     debug_decl(init_parser, SUDO_DEBUG_PARSER)      debug_decl(init_parser, SUDO_DEBUG_PARSER)
   
    while ((us = tq_pop(&userspecs)) != NULL) {    TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) {
        while ((m = tq_pop(&us->users)) != NULL) {        struct member *m, *m_next;
         struct privilege *priv, *priv_next;
 
         TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
             efree(m->name);              efree(m->name);
             efree(m);              efree(m);
         }          }
        while ((priv = tq_pop(&us->privileges)) != NULL) {        TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, priv_next) {
            struct member *runasuser = NULL, *runasgroup = NULL;            struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
             struct cmndspec *cs, *cs_next;
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
             char *role = NULL, *type = NULL;              char *role = NULL, *type = NULL;
 #endif /* HAVE_SELINUX */  #endif /* HAVE_SELINUX */
   #ifdef HAVE_PRIV_SET
               char *privs = NULL, *limitprivs = NULL;
   #endif /* HAVE_PRIV_SET */
   
            while ((m = tq_pop(&priv->hostlist)) != NULL) {            TAILQ_FOREACH_SAFE(m, &priv->hostlist, entries, m_next) {
                 efree(m->name);                  efree(m->name);
                 efree(m);                  efree(m);
             }              }
            while ((cs = tq_pop(&priv->cmndlist)) != NULL) {            TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) {
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
                 /* Only free the first instance of a role/type. */                  /* Only free the first instance of a role/type. */
                 if (cs->role != role) {                  if (cs->role != role) {
Line 733  init_parser(const char *path, int quiet) Line 858  init_parser(const char *path, int quiet)
                     efree(cs->type);                      efree(cs->type);
                 }                  }
 #endif /* HAVE_SELINUX */  #endif /* HAVE_SELINUX */
                if (tq_last(&cs->runasuserlist) != runasuser) {#ifdef HAVE_PRIV_SET
                    runasuser = tq_last(&cs->runasuserlist);                /* Only free the first instance of privs/limitprivs. */
                    while ((m = tq_pop(&cs->runasuserlist)) != NULL) {                if (cs->privs != privs) {
                     privs = cs->privs;
                     efree(cs->privs);
                 }
                 if (cs->limitprivs != limitprivs) {
                     limitprivs = cs->limitprivs;
                     efree(cs->limitprivs);
                 }
 #endif /* HAVE_PRIV_SET */
                 /* Only free the first instance of runas user/group lists. */
                 if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
                     runasuserlist = cs->runasuserlist;
                     TAILQ_FOREACH_SAFE(m, runasuserlist, entries, m_next) {
                         efree(m->name);                          efree(m->name);
                         efree(m);                          efree(m);
                     }                      }
                       efree(runasuserlist);
                 }                  }
                if (tq_last(&cs->runasgrouplist) != runasgroup) {                if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
                    runasgroup = tq_last(&cs->runasgrouplist);                    runasgrouplist = cs->runasgrouplist;
                    while ((m = tq_pop(&cs->runasgrouplist)) != NULL) {                    TAILQ_FOREACH_SAFE(m, runasgrouplist, entries, m_next) {
                         efree(m->name);                          efree(m->name);
                         efree(m);                          efree(m);
                     }                      }
                       efree(runasgrouplist);
                 }                  }
                 if (cs->cmnd->type == COMMAND) {                  if (cs->cmnd->type == COMMAND) {
                        c = (struct sudo_command *) cs->cmnd->name;                        struct sudo_command *c =
                             (struct sudo_command *) cs->cmnd->name;
                         efree(c->cmnd);                          efree(c->cmnd);
                         efree(c->args);                          efree(c->args);
                 }                  }
Line 760  init_parser(const char *path, int quiet) Line 900  init_parser(const char *path, int quiet)
         }          }
         efree(us);          efree(us);
     }      }
    tq_init(&userspecs);    TAILQ_INIT(&userspecs);
   
     binding = NULL;      binding = NULL;
    while ((d = tq_pop(&defaults)) != NULL) {    TAILQ_FOREACH_SAFE(d, &defaults, entries, d_next) {
        if (tq_last(&d->binding) != binding) {        if (d->binding != binding) {
            binding = tq_last(&d->binding);            struct member *m, *m_next;
            while ((m = tq_pop(&d->binding)) != NULL) {
             binding = d->binding;
             TAILQ_FOREACH_SAFE(m, d->binding, entries, m_next) {
                 if (m->type == COMMAND) {                  if (m->type == COMMAND) {
                        c = (struct sudo_command *) m->name;                        struct sudo_command *c =
                             (struct sudo_command *) m->name;
                         efree(c->cmnd);                          efree(c->cmnd);
                         efree(c->args);                          efree(c->args);
                 }                  }
                 efree(m->name);                  efree(m->name);
                 efree(m);                  efree(m);
             }              }
               efree(d->binding);
         }          }
         efree(d->var);          efree(d->var);
         efree(d->val);          efree(d->val);
         efree(d);          efree(d);
     }      }
    tq_init(&defaults);    TAILQ_INIT(&defaults);
   
     init_aliases();      init_aliases();
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>