Diff for /embedaddon/sudo/plugins/sudoers/parse.c between versions 1.1.1.3 and 1.1.1.5

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.5, 2014/06/15 16:12:54
Line 1 Line 1
 /*  /*
 * Copyright (c) 2004-2005, 2007-2012 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2004-2005, 2007-2013 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
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 Line 19
 #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 48 Line 47
 #include <gram.h>  #include <gram.h>
   
 /* Characters that must be quoted in sudoers */  /* Characters that must be quoted in sudoers */
#define SUDOERS_QUOTED  ":\\,=#\""#define SUDOERS_QUOTED  ":\\,=#\""
   
 /* sudoers nsswitch routines */  /* sudoers nsswitch routines */
 struct sudo_nss sudo_nss_file = {  struct sudo_nss sudo_nss_file = {
    &sudo_nss_file,    { NULL, NULL },
    NULL, 
     sudo_file_open,      sudo_file_open,
     sudo_file_close,      sudo_file_close,
     sudo_file_parse,      sudo_file_parse,
Line 66  struct sudo_nss sudo_nss_file = { Line 64  struct sudo_nss sudo_nss_file = {
 };  };
   
 /*  /*
  * Parser externs.  
  */  
 extern FILE *yyin;  
 extern char *errorfile;  
 extern int errorlineno;  
 extern bool parse_error;  
   
 /*  
  * Local prototypes.   * Local prototypes.
  */   */
static void print_member(struct lbuf *, char *, int, int, int);static int display_bound_defaults(int dtype, struct lbuf *lbuf);
static int display_bound_defaults(int, struct lbuf *);static void print_member(struct lbuf *lbuf, struct member *m, int alias_type);
 static void print_member2(struct lbuf *lbuf, struct member *m,
     const char *separator, int alias_type);
   
 int  int
 sudo_file_open(struct sudo_nss *nss)  sudo_file_open(struct sudo_nss *nss)
Line 100  sudo_file_close(struct sudo_nss *nss) Line 92  sudo_file_close(struct sudo_nss *nss)
     if (nss->handle != NULL) {      if (nss->handle != NULL) {
         fclose(nss->handle);          fclose(nss->handle);
         nss->handle = NULL;          nss->handle = NULL;
        yyin = NULL;        sudoersin = NULL;
     }      }
     debug_return_int(0);      debug_return_int(0);
 }  }
Line 117  sudo_file_parse(struct sudo_nss *nss) Line 109  sudo_file_parse(struct sudo_nss *nss)
         debug_return_int(-1);          debug_return_int(-1);
   
     init_parser(sudoers_file, false);      init_parser(sudoers_file, false);
    yyin = nss->handle;    sudoersin = nss->handle;
    if (yyparse() != 0 || parse_error) {    if (sudoersparse() != 0 || parse_error) {
         if (errorlineno != -1) {          if (errorlineno != -1) {
            log_error(0, _("parse error in %s near line %d"),            log_warning(0, N_("parse error in %s near line %d"),
                 errorfile, errorlineno);                  errorfile, errorlineno);
         } else {          } else {
            log_error(0, _("parse error in %s"), errorfile);            log_warning(0, N_("parse error in %s"), errorfile);
         }          }
         debug_return_int(-1);          debug_return_int(-1);
     }      }
Line 181  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 173  sudo_file_lookup(struct sudo_nss *nss, int validated, 
         CLR(validated, FLAG_NO_USER);          CLR(validated, FLAG_NO_USER);
         CLR(validated, FLAG_NO_HOST);          CLR(validated, FLAG_NO_HOST);
         match = DENY;          match = DENY;
        tq_foreach_fwd(&userspecs, us) {        TAILQ_FOREACH(us, &userspecs, entries) {
             if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)              if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
                 continue;                  continue;
            tq_foreach_fwd(&us->privileges, priv) {            TAILQ_FOREACH(priv, &us->privileges, entries) {
                 if (hostlist_matches(&priv->hostlist) != ALLOW)                  if (hostlist_matches(&priv->hostlist) != ALLOW)
                     continue;                      continue;
                tq_foreach_fwd(&priv->cmndlist, cs) {                TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
                     /* Only check the command when listing another user. */                      /* Only check the command when listing another user. */
                     if (user_uid == 0 || list_pw == NULL ||                      if (user_uid == 0 || list_pw == NULL ||
                         user_uid == list_pw->pw_uid ||                          user_uid == list_pw->pw_uid ||
Line 215  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 207  sudo_file_lookup(struct sudo_nss *nss, int validated, 
     set_perms(PERM_RUNAS);      set_perms(PERM_RUNAS);
   
     match = UNSPEC;      match = UNSPEC;
    tq_foreach_rev(&userspecs, us) {    TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
         if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)          if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
             continue;              continue;
         CLR(validated, FLAG_NO_USER);          CLR(validated, FLAG_NO_USER);
        tq_foreach_rev(&us->privileges, priv) {        TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
             host_match = hostlist_matches(&priv->hostlist);              host_match = hostlist_matches(&priv->hostlist);
             if (host_match == ALLOW)              if (host_match == ALLOW)
                 CLR(validated, FLAG_NO_HOST);                  CLR(validated, FLAG_NO_HOST);
             else              else
                 continue;                  continue;
            tq_foreach_rev(&priv->cmndlist, cs) {            TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
                 matching_user = NULL;                  matching_user = NULL;
                runas_match = runaslist_matches(&cs->runasuserlist,                runas_match = runaslist_matches(cs->runasuserlist,
                    &cs->runasgrouplist, &matching_user, NULL);                    cs->runasgrouplist, &matching_user, NULL);
                 if (runas_match == ALLOW) {                  if (runas_match == ALLOW) {
                     cmnd_match = cmnd_matches(cs->cmnd);                      cmnd_match = cmnd_matches(cs->cmnd);
                     if (cmnd_match != UNSPEC) {                      if (cmnd_match != UNSPEC) {
Line 290  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 282  sudo_file_lookup(struct sudo_nss *nss, int validated, 
     debug_return_int(validated);      debug_return_int(validated);
 }  }
   
   #define TAG_SET(tt) \
           ((tt) != UNSPEC && (tt) != IMPLIED)
   
 #define TAG_CHANGED(t) \  #define TAG_CHANGED(t) \
        (cs->tags.t != UNSPEC && cs->tags.t != IMPLIED && cs->tags.t != tags->t)        (TAG_SET(cs->tags.t) && cs->tags.t != tags->t)
   
 static void  static void
 sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,  sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
     struct lbuf *lbuf)      struct lbuf *lbuf)
 {  {
     struct member *m;  
     debug_decl(sudo_file_append_cmnd, SUDO_DEBUG_NSS)      debug_decl(sudo_file_append_cmnd, SUDO_DEBUG_NSS)
   
 #ifdef HAVE_PRIV_SET  #ifdef HAVE_PRIV_SET
Line 332  sudo_file_append_cmnd(struct cmndspec *cs, struct cmnd Line 326  sudo_file_append_cmnd(struct cmndspec *cs, struct cmnd
         lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");          lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
         tags->log_output = cs->tags.log_output;          tags->log_output = cs->tags.log_output;
     }      }
    m = cs->cmnd;    print_member(lbuf, cs->cmnd, CMNDALIAS);
    print_member(lbuf, m->name, m->type, m->negated, 
        CMNDALIAS); 
     debug_return;      debug_return;
 }  }
   
   #define RUNAS_CHANGED(cs1, cs2) \
           (cs1 == NULL || cs2 == NULL || \
            cs1->runasuserlist != cs2->runasuserlist || \
            cs1->runasgrouplist != cs2->runasgrouplist)
   
 static int  static int
 sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,  sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
     struct lbuf *lbuf)      struct lbuf *lbuf)
 {  {
    struct cmndspec *cs;    struct cmndspec *cs, *prev_cs;
     struct member *m;      struct member *m;
     struct privilege *priv;      struct privilege *priv;
     struct cmndtag tags;      struct cmndtag tags;
     int nfound = 0;      int nfound = 0;
     debug_decl(sudo_file_display_priv_short, SUDO_DEBUG_NSS)      debug_decl(sudo_file_display_priv_short, SUDO_DEBUG_NSS)
   
    tq_foreach_fwd(&us->privileges, priv) {    /* gcc -Wuninitialized false positive */
     tags.noexec = UNSPEC;
     tags.setenv = UNSPEC;
     tags.nopasswd = UNSPEC;
     tags.log_input = UNSPEC;
     tags.log_output = UNSPEC;
     TAILQ_FOREACH(priv, &us->privileges, entries) {
         if (hostlist_matches(&priv->hostlist) != ALLOW)          if (hostlist_matches(&priv->hostlist) != ALLOW)
             continue;              continue;
        tags.noexec = UNSPEC;        prev_cs = NULL;
        tags.setenv = UNSPEC;        TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
        tags.nopasswd = UNSPEC;            if (RUNAS_CHANGED(cs, prev_cs)) {
        tags.log_input = UNSPEC;                if (cs != TAILQ_FIRST(&priv->cmndlist))
        tags.log_output = UNSPEC;                    lbuf_append(lbuf, "\n");
        lbuf_append(lbuf, "    ");                lbuf_append(lbuf, "    (");
        tq_foreach_fwd(&priv->cmndlist, cs) {                if (cs->runasuserlist != NULL) {
            if (cs != tq_first(&priv->cmndlist))                    TAILQ_FOREACH(m, cs->runasuserlist, entries) {
                lbuf_append(lbuf, ", ");                        if (m != TAILQ_FIRST(cs->runasuserlist))
            lbuf_append(lbuf, "(");                            lbuf_append(lbuf, ", ");
            if (!tq_empty(&cs->runasuserlist)) {                        print_member(lbuf, m, RUNASALIAS);
                tq_foreach_fwd(&cs->runasuserlist, m) {                    }
                    if (m != tq_first(&cs->runasuserlist))                } else if (cs->runasgrouplist == NULL) {
                        lbuf_append(lbuf, ", ");                    lbuf_append(lbuf, "%s", def_runas_default);
                    print_member(lbuf, m->name, m->type, m->negated,                } else {
                        RUNASALIAS);                    lbuf_append(lbuf, "%s", pw->pw_name);
                 }                  }
            } else if (tq_empty(&cs->runasgrouplist)) {                if (cs->runasgrouplist != NULL) {
                lbuf_append(lbuf, "%s", def_runas_default);                    lbuf_append(lbuf, " : ");
            } else {                    TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
                lbuf_append(lbuf, "%s", pw->pw_name);                        if (m != TAILQ_FIRST(cs->runasgrouplist))
            }                            lbuf_append(lbuf, ", ");
            if (!tq_empty(&cs->runasgrouplist)) {                        print_member(lbuf, m, RUNASALIAS);
                lbuf_append(lbuf, " : ");                    }
                tq_foreach_fwd(&cs->runasgrouplist, m) { 
                    if (m != tq_first(&cs->runasgrouplist)) 
                        lbuf_append(lbuf, ", "); 
                    print_member(lbuf, m->name, m->type, m->negated, 
                        RUNASALIAS); 
                 }                  }
                   lbuf_append(lbuf, ") ");
                   tags.noexec = UNSPEC;
                   tags.setenv = UNSPEC;
                   tags.nopasswd = UNSPEC;
                   tags.log_input = UNSPEC;
                   tags.log_output = UNSPEC;
               } else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
                   lbuf_append(lbuf, ", ");
             }              }
             lbuf_append(lbuf, ") ");  
             sudo_file_append_cmnd(cs, &tags, lbuf);              sudo_file_append_cmnd(cs, &tags, lbuf);
               prev_cs = cs;
             nfound++;              nfound++;
         }          }
         lbuf_append(lbuf, "\n");          lbuf_append(lbuf, "\n");
Line 392  sudo_file_display_priv_short(struct passwd *pw, struct Line 398  sudo_file_display_priv_short(struct passwd *pw, struct
     debug_return_int(nfound);      debug_return_int(nfound);
 }  }
   
   #define TAGS_CHANGED(ot, nt) \
           ((TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
            (TAG_SET((nt).noexec) && (nt).noexec != (ot).noexec) || \
            (TAG_SET((nt).nopasswd) && (nt).nopasswd != (ot).nopasswd) || \
            (TAG_SET((nt).log_input) && (nt).log_input != (ot).log_input) || \
            (TAG_SET((nt).log_output) && (nt).log_output != (ot).log_output))
   
   /*
    * Compare the current cmndspec with the previous one to determine
    * whether we need to start a new long entry for "sudo -ll".
    * Returns true if we should start a new long entry, else false.
    */
   static bool
   new_long_entry(struct cmndspec *cs, struct cmndspec *prev_cs)
   {
       if (prev_cs == NULL)
           return true;
       if (RUNAS_CHANGED(cs, prev_cs) || TAGS_CHANGED(cs->tags, prev_cs->tags))
           return true;
   #ifdef HAVE_PRIV_SET
       if (cs->privs && (!prev_cs->privs || strcmp(cs->privs, prev_cs->privs) != 0))
           return true;
       if (cs->limitprivs && (!prev_cs->limitprivs || strcmp(cs->limitprivs, prev_cs->limitprivs) != 0))
           return true;
   #endif /* HAVE_PRIV_SET */
   #ifdef HAVE_SELINUX
       if (cs->role && (!prev_cs->role || strcmp(cs->role, prev_cs->role) != 0))
           return true;
       if (cs->type && (!prev_cs->type || strcmp(cs->type, prev_cs->type) != 0))
           return true;
   #endif /* HAVE_SELINUX */
       return false;
   }
   
 static int  static int
 sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,  sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
     struct lbuf *lbuf)      struct lbuf *lbuf)
 {  {
    struct cmndspec *cs;    struct cmndspec *cs, *prev_cs;
     struct member *m;      struct member *m;
     struct privilege *priv;      struct privilege *priv;
    struct cmndtag tags;    int nfound = 0, olen;
    int nfound = 0; 
     debug_decl(sudo_file_display_priv_long, SUDO_DEBUG_NSS)      debug_decl(sudo_file_display_priv_long, SUDO_DEBUG_NSS)
   
    tq_foreach_fwd(&us->privileges, priv) {    TAILQ_FOREACH(priv, &us->privileges, entries) {
         if (hostlist_matches(&priv->hostlist) != ALLOW)          if (hostlist_matches(&priv->hostlist) != ALLOW)
             continue;              continue;
        tags.noexec = UNSPEC;        prev_cs = NULL;
        tags.setenv = UNSPEC;        TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
        tags.nopasswd = UNSPEC;            if (new_long_entry(cs, prev_cs)) {
        tags.log_input = UNSPEC;                lbuf_append(lbuf, _("\nSudoers entry:\n"));
        tags.log_output = UNSPEC;                lbuf_append(lbuf, _("    RunAsUsers: "));
        lbuf_append(lbuf, _("\nSudoers entry:\n"));                if (cs->runasuserlist != NULL) {
        tq_foreach_fwd(&priv->cmndlist, cs) {                    TAILQ_FOREACH(m, cs->runasuserlist, entries) {
            lbuf_append(lbuf, _("    RunAsUsers: "));                        if (m != TAILQ_FIRST(cs->runasuserlist))
            if (!tq_empty(&cs->runasuserlist)) {                            lbuf_append(lbuf, ", ");
                tq_foreach_fwd(&cs->runasuserlist, m) {                        print_member(lbuf, m, RUNASALIAS);
                    if (m != tq_first(&cs->runasuserlist))                    }
                        lbuf_append(lbuf, ", ");                } else if (cs->runasgrouplist == NULL) {
                    print_member(lbuf, m->name, m->type, m->negated,                    lbuf_append(lbuf, "%s", def_runas_default);
                        RUNASALIAS);                } else {
                     lbuf_append(lbuf, "%s", pw->pw_name);
                 }                  }
             } else if (tq_empty(&cs->runasgrouplist)) {  
                 lbuf_append(lbuf, "%s", def_runas_default);  
             } else {  
                 lbuf_append(lbuf, "%s", pw->pw_name);  
             }  
             lbuf_append(lbuf, "\n");  
             if (!tq_empty(&cs->runasgrouplist)) {  
                 lbuf_append(lbuf, _("    RunAsGroups: "));  
                 tq_foreach_fwd(&cs->runasgrouplist, m) {  
                     if (m != tq_first(&cs->runasgrouplist))  
                         lbuf_append(lbuf, ", ");  
                     print_member(lbuf, m->name, m->type, m->negated,  
                         RUNASALIAS);  
                 }  
                 lbuf_append(lbuf, "\n");                  lbuf_append(lbuf, "\n");
                   if (cs->runasgrouplist != NULL) {
                       lbuf_append(lbuf, _("    RunAsGroups: "));
                       TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
                           if (m != TAILQ_FIRST(cs->runasgrouplist))
                               lbuf_append(lbuf, ", ");
                           print_member(lbuf, m, RUNASALIAS);
                       }
                       lbuf_append(lbuf, "\n");
                   }
                   olen = lbuf->len;
                   lbuf_append(lbuf, _("    Options: "));
                   if (TAG_SET(cs->tags.setenv))
                       lbuf_append(lbuf, "%ssetenv, ", cs->tags.setenv ? "" : "!");
                   if (TAG_SET(cs->tags.noexec))
                       lbuf_append(lbuf, "%snoexec, ", cs->tags.noexec ? "" : "!");
                   if (TAG_SET(cs->tags.nopasswd))
                       lbuf_append(lbuf, "%sauthenticate, ", cs->tags.nopasswd ? "!" : "");
                   if (TAG_SET(cs->tags.log_input))
                       lbuf_append(lbuf, "%slog_input, ", cs->tags.log_input ? "" : "!");
                   if (TAG_SET(cs->tags.log_output))
                       lbuf_append(lbuf, "%slog_output, ", cs->tags.log_output ? "" : "!");
                   if (lbuf->buf[lbuf->len - 2] == ',') {
                       lbuf->len -= 2;     /* remove trailing ", " */
                       lbuf_append(lbuf, "\n");
                   } else {
                       lbuf->len = olen;   /* no options */
                   }
   #ifdef HAVE_PRIV_SET
                   if (cs->privs)
                       lbuf_append(lbuf, "    Privs: %s\n", cs->privs);
                   if (cs->limitprivs)
                       lbuf_append(lbuf, "    Limitprivs: %s\n", cs->limitprivs);
   #endif /* HAVE_PRIV_SET */
   #ifdef HAVE_SELINUX
                   if (cs->role)
                       lbuf_append(lbuf, "    Role: %s\n", cs->role);
                   if (cs->type)
                       lbuf_append(lbuf, "    Type: %s\n", cs->type);
   #endif /* HAVE_SELINUX */
                   lbuf_append(lbuf, _("    Commands:\n"));
             }              }
            lbuf_append(lbuf, _("    Commands:\n\t"));            lbuf_append(lbuf, "\t");
            sudo_file_append_cmnd(cs, &tags, lbuf);            print_member2(lbuf, cs->cmnd, "\n\t", CMNDALIAS);
             lbuf_append(lbuf, "\n");              lbuf_append(lbuf, "\n");
               prev_cs = cs;
             nfound++;              nfound++;
         }          }
     }      }
Line 457  sudo_file_display_privs(struct sudo_nss *nss, struct p Line 524  sudo_file_display_privs(struct sudo_nss *nss, struct p
     if (nss->handle == NULL)      if (nss->handle == NULL)
         goto done;          goto done;
   
    tq_foreach_fwd(&userspecs, us) {    TAILQ_FOREACH(us, &userspecs, entries) {
         if (userlist_matches(pw, &us->users) != ALLOW)          if (userlist_matches(pw, &us->users) != ALLOW)
             continue;              continue;
   
Line 490  sudo_file_display_defaults(struct sudo_nss *nss, struc Line 557  sudo_file_display_defaults(struct sudo_nss *nss, struc
     else      else
         prefix = ", ";          prefix = ", ";
   
    tq_foreach_fwd(&defaults, d) {    TAILQ_FOREACH(d, &defaults, entries) {
         switch (d->type) {          switch (d->type) {
             case DEFAULTS_HOST:              case DEFAULTS_HOST:
                if (hostlist_matches(&d->binding) != ALLOW)                if (hostlist_matches(d->binding) != ALLOW)
                     continue;                      continue;
                 break;                  break;
             case DEFAULTS_USER:              case DEFAULTS_USER:
                if (userlist_matches(pw, &d->binding) != ALLOW)                if (userlist_matches(pw, d->binding) != ALLOW)
                     continue;                      continue;
                 break;                  break;
             case DEFAULTS_RUNAS:              case DEFAULTS_RUNAS:
Line 547  static int Line 614  static int
 display_bound_defaults(int dtype, struct lbuf *lbuf)  display_bound_defaults(int dtype, struct lbuf *lbuf)
 {  {
     struct defaults *d;      struct defaults *d;
    struct member *m, *binding = NULL;    struct member_list *binding = NULL;
     struct member *m;
     char *dsep;      char *dsep;
     int atype, nfound = 0;      int atype, nfound = 0;
     debug_decl(display_bound_defaults, SUDO_DEBUG_NSS)      debug_decl(display_bound_defaults, SUDO_DEBUG_NSS)
Line 572  display_bound_defaults(int dtype, struct lbuf *lbuf) Line 640  display_bound_defaults(int dtype, struct lbuf *lbuf)
         default:          default:
             debug_return_int(-1);              debug_return_int(-1);
     }      }
    tq_foreach_fwd(&defaults, d) {    TAILQ_FOREACH(d, &defaults, entries) {
         if (d->type != dtype)          if (d->type != dtype)
             continue;              continue;
   
         nfound++;          nfound++;
        if (binding != tq_first(&d->binding)) {        if (binding != d->binding) {
            binding = tq_first(&d->binding);            binding = d->binding;
             if (nfound != 1)              if (nfound != 1)
                 lbuf_append(lbuf, "\n");                  lbuf_append(lbuf, "\n");
             lbuf_append(lbuf, "    Defaults%s", dsep);              lbuf_append(lbuf, "    Defaults%s", dsep);
            for (m = binding; m != NULL; m = m->next) {            TAILQ_FOREACH(m, binding, entries) {
                if (m != binding)                if (m != TAILQ_FIRST(binding))
                     lbuf_append(lbuf, ",");                      lbuf_append(lbuf, ",");
                print_member(lbuf, m->name, m->type, m->negated, atype);                print_member(lbuf, m, atype);
                 lbuf_append(lbuf, " ");                  lbuf_append(lbuf, " ");
             }              }
         } else          } else
Line 615  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa Line 683  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa
         goto done;          goto done;
   
     match = NULL;      match = NULL;
    tq_foreach_rev(&userspecs, us) {    TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
         if (userlist_matches(pw, &us->users) != ALLOW)          if (userlist_matches(pw, &us->users) != ALLOW)
             continue;              continue;
   
        tq_foreach_rev(&us->privileges, priv) {        TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
             host_match = hostlist_matches(&priv->hostlist);              host_match = hostlist_matches(&priv->hostlist);
             if (host_match != ALLOW)              if (host_match != ALLOW)
                 continue;                  continue;
            tq_foreach_rev(&priv->cmndlist, cs) {            TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
                runas_match = runaslist_matches(&cs->runasuserlist,                runas_match = runaslist_matches(cs->runasuserlist,
                    &cs->runasgrouplist, NULL, NULL);                    cs->runasgrouplist, NULL, NULL);
                 if (runas_match == ALLOW) {                  if (runas_match == ALLOW) {
                     cmnd_match = cmnd_matches(cs->cmnd);                      cmnd_match = cmnd_matches(cs->cmnd);
                     if (cmnd_match != UNSPEC) {                      if (cmnd_match != UNSPEC) {
                        match = host_match && runas_match ? cs->cmnd : NULL;                        if (cmnd_match == ALLOW)
                             match = cs->cmnd;
                         goto matched;                          goto matched;
                     }                      }
                 }                  }
Line 651  done: Line 720  done:
  */   */
 static void  static void
 _print_member(struct lbuf *lbuf, char *name, int type, int negated,  _print_member(struct lbuf *lbuf, char *name, int type, int negated,
    int alias_type)    const char *separator, int alias_type)
 {  {
     struct alias *a;      struct alias *a;
     struct member *m;      struct member *m;
Line 676  _print_member(struct lbuf *lbuf, char *name, int type, Line 745  _print_member(struct lbuf *lbuf, char *name, int type,
             }              }
             break;              break;
         case ALIAS:          case ALIAS:
            if ((a = alias_find(name, alias_type)) != NULL) {            if ((a = alias_get(name, alias_type)) != NULL) {
                tq_foreach_fwd(&a->members, m) {                TAILQ_FOREACH(m, &a->members, entries) {
                    if (m != tq_first(&a->members))                    if (m != TAILQ_FIRST(&a->members))
                        lbuf_append(lbuf, ", ");                        lbuf_append(lbuf, "%s", separator);
                     _print_member(lbuf, m->name, m->type,                      _print_member(lbuf, m->name, m->type,
                        negated ? !m->negated : m->negated, alias_type);                        negated ? !m->negated : m->negated, separator,
                         alias_type);
                 }                  }
                   alias_put(a);
                 break;                  break;
             }              }
             /* FALLTHROUGH */              /* FALLTHROUGH */
Line 694  _print_member(struct lbuf *lbuf, char *name, int type, Line 765  _print_member(struct lbuf *lbuf, char *name, int type,
 }  }
   
 static void  static void
print_member(struct lbuf *lbuf, char *name, int type, int negated,print_member(struct lbuf *lbuf, struct member *m, int alias_type)
 {
     _print_member(lbuf, m->name, m->type, m->negated, ", ", alias_type);
 }
 
 static void
 print_member2(struct lbuf *lbuf, struct member *m, const char *separator,
     int alias_type)      int alias_type)
 {  {
    alias_seqno++;    _print_member(lbuf, m->name, m->type, m->negated, separator, alias_type);
    _print_member(lbuf, name, type, negated, alias_type); 
 }  }

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


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