Diff for /embedaddon/sudo/plugins/sudoers/match.c between versions 1.1.1.5 and 1.1.1.6

version 1.1.1.5, 2013/10/14 07:56:34 version 1.1.1.6, 2014/06/15 16:12:54
Line 91 Line 91
 #include "sha2.h"  #include "sha2.h"
 #include <gram.h>  #include <gram.h>
   
static struct member_list empty;static struct member_list empty = TAILQ_HEAD_INITIALIZER(empty);
   
static bool command_matches_dir(char *, size_t);static bool command_matches_dir(const char *sudoers_dir, size_t dlen);
 #ifndef SUDOERS_NAME_MATCH  #ifndef SUDOERS_NAME_MATCH
static bool command_matches_glob(char *, char *);static bool command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args);
 #endif  #endif
static bool command_matches_fnmatch(char *, char *);static bool command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args);
static bool command_matches_normal(char *, char *, struct sudo_digest *);static bool command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct sudo_digest *digest);
   
 /*  /*
  * Returns true if string 's' contains meta characters.   * Returns true if string 's' contains meta characters.
Line 110  static bool command_matches_normal(char *, char *, str Line 110  static bool command_matches_normal(char *, char *, str
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
 int  int
userlist_matches(struct passwd *pw, struct member_list *list)userlist_matches(const struct passwd *pw, const struct member_list *list)
 {  {
     struct member *m;      struct member *m;
     struct alias *a;      struct alias *a;
     int rval, matched = UNSPEC;      int rval, matched = UNSPEC;
     debug_decl(userlist_matches, SUDO_DEBUG_MATCH)      debug_decl(userlist_matches, SUDO_DEBUG_MATCH)
   
    tq_foreach_rev(list, m) {    TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
         switch (m->type) {          switch (m->type) {
             case ALL:              case ALL:
                 matched = !m->negated;                  matched = !m->negated;
Line 156  userlist_matches(struct passwd *pw, struct member_list Line 156  userlist_matches(struct passwd *pw, struct member_list
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
 int  int
runaslist_matches(struct member_list *user_list,runaslist_matches(const struct member_list *user_list,
    struct member_list *group_list, struct member **matching_user,    const struct member_list *group_list, struct member **matching_user,
     struct member **matching_group)      struct member **matching_group)
 {  {
     struct member *m;      struct member *m;
Line 169  runaslist_matches(struct member_list *user_list, Line 169  runaslist_matches(struct member_list *user_list,
   
     if (runas_pw != NULL) {      if (runas_pw != NULL) {
         /* If no runas user or runas group listed in sudoers, use default. */          /* If no runas user or runas group listed in sudoers, use default. */
        if (tq_empty(user_list) && tq_empty(group_list))        if (user_list == NULL && group_list == NULL)
             debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));              debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
   
        tq_foreach_rev(user_list, m) {        if (user_list != NULL) {
            switch (m->type) {            TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
                case ALL:                switch (m->type) {
                    user_matched = !m->negated;                    case ALL:
                    break; 
                case NETGROUP: 
                    if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name)) 
                         user_matched = !m->negated;                          user_matched = !m->negated;
                     break;  
                 case USERGROUP:  
                     if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))  
                         user_matched = !m->negated;  
                     break;  
                 case ALIAS:  
                     if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {  
                         rval = runaslist_matches(&a->members, &empty,  
                             matching_user, NULL);  
                         if (rval != UNSPEC)  
                             user_matched = m->negated ? !rval : rval;  
                         alias_put(a);  
                         break;                          break;
                    }                    case NETGROUP:
                    /* FALLTHROUGH */                        if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name))
                case WORD:                            user_matched = !m->negated;
                    if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))                        break;
                        user_matched = !m->negated;                    case USERGROUP:
                         if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
                             user_matched = !m->negated;
                         break;
                     case ALIAS:
                         if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
                             rval = runaslist_matches(&a->members, &empty,
                                 matching_user, NULL);
                             if (rval != UNSPEC)
                                 user_matched = m->negated ? !rval : rval;
                             alias_put(a);
                             break;
                         }
                         /* FALLTHROUGH */
                     case WORD:
                         if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
                             user_matched = !m->negated;
                         break;
                     case MYSELF:
                         if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
                             strcmp(user_name, runas_pw->pw_name) == 0)
                             user_matched = !m->negated;
                         break;
                 }
                 if (user_matched != UNSPEC) {
                     if (matching_user != NULL && m->type != ALIAS)
                         *matching_user = m;
                     break;                      break;
                case MYSELF:                }
                    if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || 
                        strcmp(user_name, runas_pw->pw_name) == 0) 
                        user_matched = !m->negated; 
                    break; 
             }              }
             if (user_matched != UNSPEC) {  
                 if (matching_user != NULL && m->type != ALIAS)  
                     *matching_user = m;  
                 break;  
             }  
         }          }
     }      }
   
Line 218  runaslist_matches(struct member_list *user_list, Line 220  runaslist_matches(struct member_list *user_list,
             if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0)              if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0)
                 user_matched = ALLOW;   /* only changing group */                  user_matched = ALLOW;   /* only changing group */
         }          }
        tq_foreach_rev(group_list, m) {        if (group_list != NULL) {
            switch (m->type) {            TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
                case ALL:                switch (m->type) {
                    group_matched = !m->negated;                    case ALL:
                    break; 
                case ALIAS: 
                    if ((a = alias_get(m->name, RUNASALIAS)) != NULL) { 
                        rval = runaslist_matches(&empty, &a->members, 
                            NULL, matching_group); 
                        if (rval != UNSPEC) 
                            group_matched = m->negated ? !rval : rval; 
                        alias_put(a); 
                        break; 
                    } 
                    /* FALLTHROUGH */ 
                case WORD: 
                    if (group_matches(m->name, runas_gr)) 
                         group_matched = !m->negated;                          group_matched = !m->negated;
                           break;
                       case ALIAS:
                           if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
                               rval = runaslist_matches(&empty, &a->members,
                                   NULL, matching_group);
                               if (rval != UNSPEC)
                                   group_matched = m->negated ? !rval : rval;
                               alias_put(a);
                               break;
                           }
                           /* FALLTHROUGH */
                       case WORD:
                           if (group_matches(m->name, runas_gr))
                               group_matched = !m->negated;
                           break;
                   }
                   if (group_matched != UNSPEC) {
                       if (matching_group != NULL && m->type != ALIAS)
                           *matching_group = m;
                     break;                      break;
                   }
             }              }
             if (group_matched != UNSPEC) {  
                 if (matching_group != NULL && m->type != ALIAS)  
                     *matching_group = m;  
                 break;  
             }  
         }          }
         if (group_matched == UNSPEC) {          if (group_matched == UNSPEC) {
             if (runas_pw != NULL && runas_pw->pw_gid == runas_gr->gr_gid)              if (runas_pw != NULL && runas_pw->pw_gid == runas_gr->gr_gid)
Line 262  runaslist_matches(struct member_list *user_list, Line 266  runaslist_matches(struct member_list *user_list,
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
 int  int
hostlist_matches(struct member_list *list)hostlist_matches(const struct member_list *list)
 {  {
     struct member *m;      struct member *m;
     struct alias *a;      struct alias *a;
     int rval, matched = UNSPEC;      int rval, matched = UNSPEC;
     debug_decl(hostlist_matches, SUDO_DEBUG_MATCH)      debug_decl(hostlist_matches, SUDO_DEBUG_MATCH)
   
    tq_foreach_rev(list, m) {    TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
         switch (m->type) {          switch (m->type) {
             case ALL:              case ALL:
                 matched = !m->negated;                  matched = !m->negated;
Line 307  hostlist_matches(struct member_list *list) Line 311  hostlist_matches(struct member_list *list)
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
 int  int
cmndlist_matches(struct member_list *list)cmndlist_matches(const struct member_list *list)
 {  {
     struct member *m;      struct member *m;
     int matched = UNSPEC;      int matched = UNSPEC;
     debug_decl(cmndlist_matches, SUDO_DEBUG_MATCH)      debug_decl(cmndlist_matches, SUDO_DEBUG_MATCH)
   
    tq_foreach_rev(list, m) {    TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
         matched = cmnd_matches(m);          matched = cmnd_matches(m);
         if (matched != UNSPEC)          if (matched != UNSPEC)
             break;              break;
Line 326  cmndlist_matches(struct member_list *list) Line 330  cmndlist_matches(struct member_list *list)
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
 int  int
cmnd_matches(struct member *m)cmnd_matches(const struct member *m)
 {  {
     struct alias *a;      struct alias *a;
     struct sudo_command *c;      struct sudo_command *c;
Line 355  cmnd_matches(struct member *m) Line 359  cmnd_matches(struct member *m)
 }  }
   
 static bool  static bool
command_args_match(char *sudoers_cmnd, char *sudoers_args)command_args_match(const char *sudoers_cmnd, const char *sudoers_args)
 {  {
     int flags = 0;      int flags = 0;
     debug_decl(command_args_match, SUDO_DEBUG_MATCH)      debug_decl(command_args_match, SUDO_DEBUG_MATCH)
Line 386  command_args_match(char *sudoers_cmnd, char *sudoers_a Line 390  command_args_match(char *sudoers_cmnd, char *sudoers_a
  * otherwise, return true if user_cmnd names one of the inodes in path.   * otherwise, return true if user_cmnd names one of the inodes in path.
  */   */
 bool  bool
command_matches(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct sudo_digest *digest)
 {  {
       bool rc = false;
     debug_decl(command_matches, SUDO_DEBUG_MATCH)      debug_decl(command_matches, SUDO_DEBUG_MATCH)
   
     /* Check for pseudo-commands */      /* Check for pseudo-commands */
Line 398  command_matches(char *sudoers_cmnd, char *sudoers_args Line 403  command_matches(char *sudoers_cmnd, char *sudoers_args
          *  b) there are no args on command line and none req by sudoers OR           *  b) there are no args on command line and none req by sudoers OR
          *  c) there are args in sudoers and on command line and they match           *  c) there are args in sudoers and on command line and they match
          */           */
        if (strcmp(sudoers_cmnd, "sudoedit") != 0 ||        if (strcmp(sudoers_cmnd, "sudoedit") == 0 &&
            strcmp(user_cmnd, "sudoedit") != 0)            strcmp(user_cmnd, "sudoedit") == 0 &&
            debug_return_bool(false);            command_args_match(sudoers_cmnd, sudoers_args)) {
        if (command_args_match(sudoers_cmnd, sudoers_args)) { 
             efree(safe_cmnd);              efree(safe_cmnd);
             safe_cmnd = estrdup(sudoers_cmnd);              safe_cmnd = estrdup(sudoers_cmnd);
            debug_return_bool(true);            rc = true;
        } else        }
            debug_return_bool(false);        goto done;
     }      }
   
     if (has_meta(sudoers_cmnd)) {      if (has_meta(sudoers_cmnd)) {
Line 415  command_matches(char *sudoers_cmnd, char *sudoers_args Line 419  command_matches(char *sudoers_cmnd, char *sudoers_args
          * use glob(3) and/or fnmatch(3) to do the matching.           * use glob(3) and/or fnmatch(3) to do the matching.
          */           */
 #ifdef SUDOERS_NAME_MATCH  #ifdef SUDOERS_NAME_MATCH
        debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));        rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args);
 #else  #else
         if (def_fast_glob)          if (def_fast_glob)
            debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));            rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args);
        debug_return_bool(command_matches_glob(sudoers_cmnd, sudoers_args));        else
             rc = command_matches_glob(sudoers_cmnd, sudoers_args);
 #endif  #endif
       } else {
           rc = command_matches_normal(sudoers_cmnd, sudoers_args, digest);
     }      }
    debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args, digest));done:
     sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
         "user command \"%s%s%s\" matches sudoers command \"%s%s%s\": %s",
         user_cmnd, user_args ? " " : "", user_args ? user_args : "",
         sudoers_cmnd, sudoers_args ? " " : "", sudoers_args ? sudoers_args : "",
         rc ? "true" : "false");
     debug_return_bool(rc);
 }  }
   
 static bool  static bool
command_matches_fnmatch(char *sudoers_cmnd, char *sudoers_args)command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args)
 {  {
     debug_decl(command_matches_fnmatch, SUDO_DEBUG_MATCH)      debug_decl(command_matches_fnmatch, SUDO_DEBUG_MATCH)
   
Line 450  command_matches_fnmatch(char *sudoers_cmnd, char *sudo Line 463  command_matches_fnmatch(char *sudoers_cmnd, char *sudo
   
 #ifndef SUDOERS_NAME_MATCH  #ifndef SUDOERS_NAME_MATCH
 static bool  static bool
command_matches_glob(char *sudoers_cmnd, char *sudoers_args)command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args)
 {  {
     struct stat sudoers_stat;      struct stat sudoers_stat;
     size_t dlen;      size_t dlen;
Line 523  command_matches_glob(char *sudoers_cmnd, char *sudoers Line 536  command_matches_glob(char *sudoers_cmnd, char *sudoers
   
 #ifdef SUDOERS_NAME_MATCH  #ifdef SUDOERS_NAME_MATCH
 static bool  static bool
command_matches_normal(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct sudo_digest *digest)
 {  {
     size_t dlen;      size_t dlen;
     debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)      debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)
Line 582  static struct digest_function { Line 595  static struct digest_function {
 };  };
   
 static bool  static bool
digest_matches(char *file, struct sudo_digest *sd)digest_matches(const char *file, const struct sudo_digest *sd)
 {  {
     unsigned char file_digest[SHA512_DIGEST_LENGTH];      unsigned char file_digest[SHA512_DIGEST_LENGTH];
     unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];      unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];
Line 601  digest_matches(char *file, struct sudo_digest *sd) Line 614  digest_matches(char *file, struct sudo_digest *sd)
         }          }
     }      }
     if (func == NULL) {      if (func == NULL) {
        warningx(_("unsupported digest type %d for %s"), sd->digest_type, file);        warningx(U_("unsupported digest type %d for %s"), sd->digest_type, file);
         debug_return_bool(false);          debug_return_bool(false);
     }      }
     if (strlen(sd->digest_str) == func->digest_len * 2) {      if (strlen(sd->digest_str) == func->digest_len * 2) {
Line 631  digest_matches(char *file, struct sudo_digest *sd) Line 644  digest_matches(char *file, struct sudo_digest *sd)
         func->update(&ctx, buf, nread);          func->update(&ctx, buf, nread);
     }      }
     if (ferror(fp)) {      if (ferror(fp)) {
        warningx(_("%s: read error"), file);        warningx(U_("%s: read error"), file);
         fclose(fp);          fclose(fp);
         debug_return_bool(false);          debug_return_bool(false);
     }      }
     fclose(fp);      fclose(fp);
     func->final(file_digest, &ctx);      func->final(file_digest, &ctx);
   
    debug_return_bool(memcmp(file_digest, sudoers_digest, func->digest_len) == 0);    if (memcmp(file_digest, sudoers_digest, func->digest_len) == 0)
         debug_return_bool(true);
     sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
         "%s digest mismatch for %s, expecting %s",
         func->digest_name, file, sd->digest_str);
     debug_return_bool(false);
 bad_format:  bad_format:
    warningx(_("digest for %s (%s) is not in %s form"), file,    warningx(U_("digest for %s (%s) is not in %s form"), file,
         sd->digest_str, func->digest_name);          sd->digest_str, func->digest_name);
     debug_return_bool(false);      debug_return_bool(false);
 }  }
   
 static bool  static bool
command_matches_normal(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct sudo_digest *digest)
 {  {
     struct stat sudoers_stat;      struct stat sudoers_stat;
    char *base;    const char *base;
     size_t dlen;      size_t dlen;
     debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)      debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)
   
Line 696  command_matches_normal(char *sudoers_cmnd, char *sudoe Line 714  command_matches_normal(char *sudoers_cmnd, char *sudoe
  * Note that sudoers_dir include the trailing '/'   * Note that sudoers_dir include the trailing '/'
  */   */
 static bool  static bool
command_matches_dir(char *sudoers_dir, size_t dlen)command_matches_dir(const char *sudoers_dir, size_t dlen)
 {  {
     debug_decl(command_matches_dir, SUDO_DEBUG_MATCH)      debug_decl(command_matches_dir, SUDO_DEBUG_MATCH)
     debug_return_bool(strncmp(user_cmnd, sudoers_dir, dlen) == 0);      debug_return_bool(strncmp(user_cmnd, sudoers_dir, dlen) == 0);
Line 706  command_matches_dir(char *sudoers_dir, size_t dlen) Line 724  command_matches_dir(char *sudoers_dir, size_t dlen)
  * Return true if user_cmnd names one of the inodes in dir, else false.   * Return true if user_cmnd names one of the inodes in dir, else false.
  */   */
 static bool  static bool
command_matches_dir(char *sudoers_dir, size_t dlen)command_matches_dir(const char *sudoers_dir, size_t dlen)
 {  {
     struct stat sudoers_stat;      struct stat sudoers_stat;
     struct dirent *dent;      struct dirent *dent;
Line 753  command_matches_dir(char *sudoers_dir, size_t dlen) Line 771  command_matches_dir(char *sudoers_dir, size_t dlen)
  * Returns true if the hostname matches the pattern, else false   * Returns true if the hostname matches the pattern, else false
  */   */
 bool  bool
hostname_matches(char *shost, char *lhost, char *pattern)hostname_matches(const char *shost, const char *lhost, const char *pattern)
 {  {
     debug_decl(hostname_matches, SUDO_DEBUG_MATCH)      debug_decl(hostname_matches, SUDO_DEBUG_MATCH)
       const char *host;
       bool rc;
   
       host = strchr(pattern, '.') != NULL ? lhost : shost;
     if (has_meta(pattern)) {      if (has_meta(pattern)) {
        if (strchr(pattern, '.'))        rc = !fnmatch(pattern, host, FNM_CASEFOLD);
            debug_return_bool(!fnmatch(pattern, lhost, FNM_CASEFOLD)); 
        else 
            debug_return_bool(!fnmatch(pattern, shost, FNM_CASEFOLD)); 
     } else {      } else {
        if (strchr(pattern, '.'))        rc = !strcasecmp(host, pattern);
            debug_return_bool(!strcasecmp(lhost, pattern)); 
        else 
            debug_return_bool(!strcasecmp(shost, pattern)); 
     }      }
       sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
           "host %s matches sudoers pattern %s: %s",
           host, pattern, rc ? "true" : "false");
       debug_return_bool(rc);
 }  }
   
 /*  /*
 *  Returns true if the user/uid from sudoers matches the specified user/uid, * Returns true if the user/uid from sudoers matches the specified user/uid,
 *  else returns false. * else returns false.
  */   */
 bool  bool
userpw_matches(char *sudoers_user, char *user, struct passwd *pw)userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw)
 {  {
       const char *errstr;
       uid_t uid;
       bool rc;
     debug_decl(userpw_matches, SUDO_DEBUG_MATCH)      debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
   
     if (pw != NULL && *sudoers_user == '#') {      if (pw != NULL && *sudoers_user == '#') {
        uid_t uid = (uid_t) atoi(sudoers_user + 1);        uid = (uid_t) atoid(sudoers_user + 1, NULL, NULL, &errstr);
        if (uid == pw->pw_uid)        if (errstr == NULL && uid == pw->pw_uid) {
            debug_return_bool(true);            rc = true;
             goto done;
         }
     }      }
    debug_return_bool(strcmp(sudoers_user, user) == 0);    rc = strcmp(sudoers_user, user) == 0;
 done:
     sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
         "user %s matches sudoers user %s: %s",
         user, sudoers_user, rc ? "true" : "false");
     debug_return_bool(rc);
 }  }
   
 /*  /*
 *  Returns true if the group/gid from sudoers matches the specified group/gid, * Returns true if the group/gid from sudoers matches the specified group/gid,
 *  else returns false. * else returns false.
  */   */
 bool  bool
group_matches(char *sudoers_group, struct group *gr)group_matches(const char *sudoers_group, const struct group *gr)
 {  {
       const char *errstr;
       gid_t gid;
       bool rc;
     debug_decl(group_matches, SUDO_DEBUG_MATCH)      debug_decl(group_matches, SUDO_DEBUG_MATCH)
   
     if (*sudoers_group == '#') {      if (*sudoers_group == '#') {
        gid_t gid = (gid_t) atoi(sudoers_group + 1);        gid = (gid_t) atoid(sudoers_group + 1, NULL, NULL, &errstr);
        if (gid == gr->gr_gid)        if (errstr == NULL && gid == gr->gr_gid) {
            debug_return_bool(true);            rc = true;
             goto done;
         }
     }      }
    debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0);    rc = strcmp(gr->gr_name, sudoers_group) == 0;
 done:
     sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
         "group %s matches sudoers group %s: %s",
         gr->gr_name, sudoers_group, rc ? "true" : "false");
     debug_return_bool(rc);
 }  }
   
 /*  /*
 *  Returns true if the given user belongs to the named group, * Returns true if the given user belongs to the named group,
 *  else returns false. * else returns false.
  */   */
 bool  bool
usergr_matches(char *group, char *user, struct passwd *pw)usergr_matches(const char *group, const char *user, const struct passwd *pw)
 {  {
     int matched = false;      int matched = false;
     struct passwd *pw0 = NULL;      struct passwd *pw0 = NULL;
     debug_decl(usergr_matches, SUDO_DEBUG_MATCH)      debug_decl(usergr_matches, SUDO_DEBUG_MATCH)
   
     /* make sure we have a valid usergroup, sudo style */      /* make sure we have a valid usergroup, sudo style */
    if (*group++ != '%')    if (*group++ != '%') {
         sudo_debug_printf(SUDO_DEBUG_DIAG, "user group %s has no leading '%%'",
             group);
         goto done;          goto done;
       }
   
     if (*group == ':' && def_group_plugin) {      if (*group == ':' && def_group_plugin) {
         matched = group_plugin_query(user, group + 1, pw);          matched = group_plugin_query(user, group + 1, pw);
Line 826  usergr_matches(char *group, char *user, struct passwd  Line 868  usergr_matches(char *group, char *user, struct passwd 
   
     /* look up user's primary gid in the passwd file */      /* look up user's primary gid in the passwd file */
     if (pw == NULL) {      if (pw == NULL) {
        if ((pw0 = sudo_getpwnam(user)) == NULL)        if ((pw0 = sudo_getpwnam(user)) == NULL) {
             sudo_debug_printf(SUDO_DEBUG_DIAG, "unable to find %s in passwd db",
                 user);
             goto done;              goto done;
           }
         pw = pw0;          pw = pw0;
     }      }
   
Line 846  done: Line 891  done:
     if (pw0 != NULL)      if (pw0 != NULL)
         sudo_pw_delref(pw0);          sudo_pw_delref(pw0);
   
       sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
           "user %s matches group %s: %s", user, group, matched ? "true" : "false");
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }
   
Line 880  sudo_getdomainname(void) Line 927  sudo_getdomainname(void)
   
 /*  /*
  * Returns true if "host" and "user" belong to the netgroup "netgr",   * Returns true if "host" and "user" belong to the netgroup "netgr",
 * else return false.  Either of "host", "shost" or "user" may be NULL * else return false.  Either of "lhost", "shost" or "user" may be NULL
  * in which case that argument is not checked...   * in which case that argument is not checked...
  *  
  * XXX - swap order of host & shost  
  */   */
 bool  bool
netgr_matches(char *netgr, char *lhost, char *shost, char *user)netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user)
 {  {
 #ifdef HAVE_INNETGR  #ifdef HAVE_INNETGR
     static char *domain;      static char *domain;
     static int initialized;      static int initialized;
 #endif  #endif
       bool rc = false;
     debug_decl(netgr_matches, SUDO_DEBUG_MATCH)      debug_decl(netgr_matches, SUDO_DEBUG_MATCH)
   
       if (!def_use_netgroups) {
           sudo_debug_printf(SUDO_DEBUG_INFO, "netgroups are disabled");
           debug_return_bool(false);
       }
   
 #ifdef HAVE_INNETGR  #ifdef HAVE_INNETGR
     /* make sure we have a valid netgroup, sudo style */      /* make sure we have a valid netgroup, sudo style */
    if (*netgr++ != '+')    if (*netgr++ != '+') {
         sudo_debug_printf(SUDO_DEBUG_DIAG, "netgroup %s has no leading '+'",
             netgr);
         debug_return_bool(false);          debug_return_bool(false);
       }
   
     /* get the domain name (if any) */      /* get the domain name (if any) */
     if (!initialized) {      if (!initialized) {
Line 906  netgr_matches(char *netgr, char *lhost, char *shost, c Line 960  netgr_matches(char *netgr, char *lhost, char *shost, c
     }      }
   
     if (innetgr(netgr, lhost, user, domain))      if (innetgr(netgr, lhost, user, domain))
        debug_return_bool(true);        rc = true;
     else if (lhost != shost && innetgr(netgr, shost, user, domain))      else if (lhost != shost && innetgr(netgr, shost, user, domain))
        debug_return_bool(true);        rc = true;
 #endif /* HAVE_INNETGR */  #endif /* HAVE_INNETGR */
   
    debug_return_bool(false);    sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
         "netgroup %s matches (%s|%s, %s, %s): %s", netgr, lhost ? lhost : "",
         shost ? shost : "", user ? user : "", domain ? domain : "",
         rc ? "true" : "false");
 
     debug_return_bool(rc);
 }  }

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


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