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

version 1.1.1.1, 2012/02/21 16:23:02 version 1.1.1.5, 2014/06/15 16:12:54
Line 1 Line 1
 /*  /*
 * Copyright (c) 2004-2005, 2007-2011 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, 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)
 {  {
       debug_decl(sudo_file_open, SUDO_DEBUG_NSS)
   
     if (def_ignore_local_sudoers)      if (def_ignore_local_sudoers)
        return -1;        debug_return_int(-1);
    nss->handle = open_sudoers(sudoers_file, FALSE, NULL);    nss->handle = open_sudoers(sudoers_file, false, NULL);
    return nss->handle ? 0 : -1;    debug_return_int(nss->handle ? 0 : -1);
 }  }
   
 int  int
 sudo_file_close(struct sudo_nss *nss)  sudo_file_close(struct sudo_nss *nss)
 {  {
       debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
   
     /* Free parser data structures and close sudoers file. */      /* Free parser data structures and close sudoers file. */
    init_parser(NULL, 0);    init_parser(NULL, false);
     if (nss->handle != NULL) {      if (nss->handle != NULL) {
         fclose(nss->handle);          fclose(nss->handle);
         nss->handle = NULL;          nss->handle = NULL;
        yyin = NULL;        sudoersin = NULL;
     }      }
    return 0;    debug_return_int(0);
 }  }
   
 /*  /*
Line 106  sudo_file_close(struct sudo_nss *nss) Line 103  sudo_file_close(struct sudo_nss *nss)
 int  int
 sudo_file_parse(struct sudo_nss *nss)  sudo_file_parse(struct sudo_nss *nss)
 {  {
       debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
   
     if (nss->handle == NULL)      if (nss->handle == NULL)
        return -1;        debug_return_int(-1);
   
    init_parser(sudoers_file, 0);    init_parser(sudoers_file, false);
    yyin = nss->handle;    sudoersin = nss->handle;
    if (yyparse() != 0 || parse_error) {    if (sudoersparse() != 0 || parse_error) {
        log_error(NO_EXIT, _("parse error in %s near line %d"),        if (errorlineno != -1) {
            errorfile, errorlineno);            log_warning(0, N_("parse error in %s near line %d"),
        return -1;                errorfile, errorlineno);
         } else {
             log_warning(0, N_("parse error in %s"), errorfile);
         }
         debug_return_int(-1);
     }      }
    return 0;    debug_return_int(0);
 }  }
   
 /*  /*
Line 125  sudo_file_parse(struct sudo_nss *nss) Line 128  sudo_file_parse(struct sudo_nss *nss)
 int  int
 sudo_file_setdefs(struct sudo_nss *nss)  sudo_file_setdefs(struct sudo_nss *nss)
 {  {
       debug_decl(sudo_file_setdefs, SUDO_DEBUG_NSS)
   
     if (nss->handle == NULL)      if (nss->handle == NULL)
        return -1;        debug_return_int(-1);
   
     if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER))      if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER))
        return -1;        debug_return_int(-1);
    return 0;    debug_return_int(0);
 }  }
   
 /*  /*
Line 145  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 150  sudo_file_lookup(struct sudo_nss *nss, int validated, 
     struct cmndtag *tags = NULL;      struct cmndtag *tags = NULL;
     struct privilege *priv;      struct privilege *priv;
     struct userspec *us;      struct userspec *us;
       struct member *matching_user;
       debug_decl(sudo_file_lookup, SUDO_DEBUG_NSS)
   
     if (nss->handle == NULL)      if (nss->handle == NULL)
        return validated;        debug_return_int(validated);
   
     /*      /*
      * Only check the actual command if pwflag is not set.       * Only check the actual command if pwflag is not set.
Line 159  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 166  sudo_file_lookup(struct sudo_nss *nss, int validated, 
         enum def_tuple pwcheck;          enum def_tuple pwcheck;
   
         pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;          pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
        nopass = (pwcheck == all) ? TRUE : FALSE;        nopass = (pwcheck == all) ? true : false;
   
         if (list_pw == NULL)          if (list_pw == NULL)
             SET(validated, FLAG_NO_CHECK);              SET(validated, FLAG_NO_CHECK);
         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 ||
                         cmnd_matches(cs->cmnd) == ALLOW)                          cmnd_matches(cs->cmnd) == ALLOW)
                             match = ALLOW;                              match = ALLOW;
                    if ((pwcheck == any && cs->tags.nopasswd == TRUE) ||                    if ((pwcheck == any && cs->tags.nopasswd == true) ||
                        (pwcheck == all && cs->tags.nopasswd != TRUE))                        (pwcheck == all && cs->tags.nopasswd != true))
                         nopass = cs->tags.nopasswd;                          nopass = cs->tags.nopasswd;
                 }                  }
             }              }
Line 191  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 198  sudo_file_lookup(struct sudo_nss *nss, int validated, 
             SET(validated, VALIDATE_NOT_OK);              SET(validated, VALIDATE_NOT_OK);
         if (pwcheck == always && def_authenticate)          if (pwcheck == always && def_authenticate)
             SET(validated, FLAG_CHECK_USER);              SET(validated, FLAG_CHECK_USER);
        else if (pwcheck == never || nopass == TRUE)        else if (pwcheck == never || nopass == true)
            def_authenticate = FALSE;            def_authenticate = false;
        return validated;        debug_return_int(validated);
     }      }
   
     /* Need to be runas user while stat'ing things. */      /* Need to be runas user while stat'ing things. */
     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) {
                runas_match = runaslist_matches(&cs->runasuserlist,                matching_user = NULL;
                    &cs->runasgrouplist);                runas_match = runaslist_matches(cs->runasuserlist,
                     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 225  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 233  sudo_file_lookup(struct sudo_nss *nss, int validated, 
                         if (user_type == NULL)                          if (user_type == NULL)
                             user_type = cs->type ? estrdup(cs->type) : def_type;                              user_type = cs->type ? estrdup(cs->type) : def_type;
 #endif /* HAVE_SELINUX */  #endif /* HAVE_SELINUX */
   #ifdef HAVE_PRIV_SET
                           /* Set Solaris privilege sets */
                           if (runas_privs == NULL)
                               runas_privs = cs->privs ? estrdup(cs->privs) : def_privs;
                           if (runas_limitprivs == NULL)
                               runas_limitprivs = cs->limitprivs ? estrdup(cs->limitprivs) : def_limitprivs;
   #endif /* HAVE_PRIV_SET */
                           /*
                            * If user is running command as himself,
                            * set runas_pw = sudo_user.pw.
                            * XXX - hack, want more general solution
                            */
                           if (matching_user && matching_user->type == MYSELF) {
                               sudo_pw_delref(runas_pw);
                               sudo_pw_addref(sudo_user.pw);
                               runas_pw = sudo_user.pw;
                           }
                         goto matched2;                          goto matched2;
                     }                      }
                 }                  }
Line 254  sudo_file_lookup(struct sudo_nss *nss, int validated,  Line 279  sudo_file_lookup(struct sudo_nss *nss, int validated, 
             def_authenticate = !tags->nopasswd;              def_authenticate = !tags->nopasswd;
     }      }
     restore_perms();      restore_perms();
    return 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)
   
   #ifdef HAVE_PRIV_SET
       if (cs->privs)
           lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
       if (cs->limitprivs)
           lbuf_append(lbuf, "LIMITPRIVS=\"%s\" ", cs->limitprivs);
   #endif /* HAVE_PRIV_SET */
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
     if (cs->role)      if (cs->role)
         lbuf_append(lbuf, "ROLE=%s ", cs->role);          lbuf_append(lbuf, "ROLE=%s ", cs->role);
Line 292  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,    debug_return;
        CMNDALIAS); 
 }  }
   
   #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)
   
    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");
     }      }
    return 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)
   
    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++;
         }          }
     }      }
    return nfound;    debug_return_int(nfound);
 }  }
   
 int  int
Line 409  sudo_file_display_privs(struct sudo_nss *nss, struct p Line 519  sudo_file_display_privs(struct sudo_nss *nss, struct p
 {  {
     struct userspec *us;      struct userspec *us;
     int nfound = 0;      int nfound = 0;
       debug_decl(sudo_file_display_priv, SUDO_DEBUG_NSS)
   
     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 423  sudo_file_display_privs(struct sudo_nss *nss, struct p Line 534  sudo_file_display_privs(struct sudo_nss *nss, struct p
             nfound += sudo_file_display_priv_short(pw, us, lbuf);              nfound += sudo_file_display_priv_short(pw, us, lbuf);
     }      }
 done:  done:
    return nfound;    debug_return_int(nfound);
 }  }
   
 /*  /*
Line 436  sudo_file_display_defaults(struct sudo_nss *nss, struc Line 547  sudo_file_display_defaults(struct sudo_nss *nss, struc
     struct defaults *d;      struct defaults *d;
     char *prefix;      char *prefix;
     int nfound = 0;      int nfound = 0;
       debug_decl(sudo_file_display_defaults, SUDO_DEBUG_NSS)
   
     if (nss->handle == NULL)      if (nss->handle == NULL)
         goto done;          goto done;
Line 445  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 470  sudo_file_display_defaults(struct sudo_nss *nss, struc Line 582  sudo_file_display_defaults(struct sudo_nss *nss, struc
                 lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);                  lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
         } else          } else
             lbuf_append(lbuf, "%s%s%s", prefix,              lbuf_append(lbuf, "%s%s%s", prefix,
                d->op == FALSE ? "!" : "", d->var);                d->op == false ? "!" : "", d->var);
         prefix = ", ";          prefix = ", ";
         nfound++;          nfound++;
     }      }
 done:  done:
    return nfound;    debug_return_int(nfound);
 }  }
   
 /*  /*
Line 486  sudo_file_display_bound_defaults(struct sudo_nss *nss, Line 598  sudo_file_display_bound_defaults(struct sudo_nss *nss,
     struct lbuf *lbuf)      struct lbuf *lbuf)
 {  {
     int nfound = 0;      int nfound = 0;
       debug_decl(sudo_file_display_bound_defaults, SUDO_DEBUG_NSS)
   
     /* XXX - should only print ones that match what the user can do. */      /* XXX - should only print ones that match what the user can do. */
     nfound += display_bound_defaults(DEFAULTS_RUNAS, lbuf);      nfound += display_bound_defaults(DEFAULTS_RUNAS, lbuf);
     nfound += display_bound_defaults(DEFAULTS_CMND, lbuf);      nfound += display_bound_defaults(DEFAULTS_CMND, lbuf);
   
    return nfound;    debug_return_int(nfound);
 }  }
   
 /*  /*
Line 501  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)
   
     switch (dtype) {      switch (dtype) {
         case DEFAULTS_HOST:          case DEFAULTS_HOST:
Line 523  display_bound_defaults(int dtype, struct lbuf *lbuf) Line 638  display_bound_defaults(int dtype, struct lbuf *lbuf)
             dsep = "!";              dsep = "!";
             break;              break;
         default:          default:
            return -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 547  display_bound_defaults(int dtype, struct lbuf *lbuf) Line 662  display_bound_defaults(int dtype, struct lbuf *lbuf)
             lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :              lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :
                 d->op == '-' ? "-=" : "=", d->val);                  d->op == '-' ? "-=" : "=", d->val);
         } else          } else
            lbuf_append(lbuf, "%s%s", d->op == FALSE ? "!" : "", d->var);            lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
     }      }
   
    return nfound;    debug_return_int(nfound);
 }  }
   
 int  int
Line 562  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa Line 677  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa
     struct userspec *us;      struct userspec *us;
     int rval = 1;      int rval = 1;
     int host_match, runas_match, cmnd_match;      int host_match, runas_match, cmnd_match;
       debug_decl(sudo_file_display_cmnd, SUDO_DEBUG_NSS)
   
     if (nss->handle == NULL)      if (nss->handle == NULL)
         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);                    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 595  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa Line 712  sudo_file_display_cmnd(struct sudo_nss *nss, struct pa
         rval = 0;          rval = 0;
     }      }
 done:  done:
    return rval;    debug_return_int(rval);
 }  }
   
 /*  /*
Line 603  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;
     struct sudo_command *c;      struct sudo_command *c;
       debug_decl(_print_member, SUDO_DEBUG_NSS)
   
     switch (type) {      switch (type) {
         case ALL:          case ALL:
             lbuf_append(lbuf, "%sALL", negated ? "!" : "");              lbuf_append(lbuf, "%sALL", negated ? "!" : "");
             break;              break;
           case MYSELF:
               lbuf_append(lbuf, "%s%s", negated ? "!" : "", user_name);
               break;
         case COMMAND:          case COMMAND:
             c = (struct sudo_command *) name;              c = (struct sudo_command *) name;
             if (negated)              if (negated)
Line 624  _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 638  _print_member(struct lbuf *lbuf, char *name, int type, Line 761  _print_member(struct lbuf *lbuf, char *name, int type,
             lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);              lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
             break;              break;
     }      }
       debug_return;
 }  }
   
 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.1  
changed lines
  Added in v.1.1.1.5


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