Diff for /embedaddon/sudo/plugins/sudoers/match.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.4, 2013/07/22 10:46:12
Line 1 Line 1
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2012 * Copyright (c) 1996, 1998-2005, 2007-2013
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 24 Line 24
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
Line 41 Line 40
 #ifdef HAVE_STRINGS_H  #ifdef HAVE_STRINGS_H
 # include <strings.h>  # include <strings.h>
 #endif /* HAVE_STRINGS_H */  #endif /* HAVE_STRINGS_H */
   #if defined(HAVE_STDINT_H)
   # include <stdint.h>
   #elif defined(HAVE_INTTYPES_H)
   # include <inttypes.h>
   #endif
 #ifdef HAVE_UNISTD_H  #ifdef HAVE_UNISTD_H
 # include <unistd.h>  # include <unistd.h>
 #endif /* HAVE_UNISTD_H */  #endif /* HAVE_UNISTD_H */
 #ifdef HAVE_FNMATCH  #ifdef HAVE_FNMATCH
 # include <fnmatch.h>  # include <fnmatch.h>
   #else
   # include "compat/fnmatch.h"
 #endif /* HAVE_FNMATCH */  #endif /* HAVE_FNMATCH */
#ifdef HAVE_GLOB#ifndef SUDOERS_NAME_MATCH
include <glob.h># ifdef HAVE_GLOB
#endif /* HAVE_GLOB */#  include <glob.h>
 else
 #  include "compat/glob.h"
 # endif /* HAVE_GLOB */
 #endif /* SUDOERS_NAME_MATCH */
 #ifdef HAVE_NETGROUP_H  #ifdef HAVE_NETGROUP_H
 # include <netgroup.h>  # include <netgroup.h>
   #else
   # include <netdb.h>
 #endif /* HAVE_NETGROUP_H */  #endif /* HAVE_NETGROUP_H */
 #include <ctype.h>  
 #include <pwd.h>  
 #include <grp.h>  
 #include <netdb.h>  
 #ifdef HAVE_DIRENT_H  #ifdef HAVE_DIRENT_H
 # include <dirent.h>  # include <dirent.h>
 # define NAMLEN(dirent) strlen((dirent)->d_name)  # define NAMLEN(dirent) strlen((dirent)->d_name)
Line 73 Line 81
 #  include <ndir.h>  #  include <ndir.h>
 # endif  # endif
 #endif  #endif
   #include <ctype.h>
   #include <pwd.h>
   #include <grp.h>
   #include <errno.h>
   
 #include "sudoers.h"  #include "sudoers.h"
 #include "parse.h"  #include "parse.h"
   #include "sha2.h"
 #include <gram.h>  #include <gram.h>
   
 #ifndef HAVE_FNMATCH  
 # include "compat/fnmatch.h"  
 #endif /* HAVE_FNMATCH */  
 #ifndef HAVE_GLOB  
 # include "compat/glob.h"  
 #endif /* HAVE_GLOB */  
   
 static struct member_list empty;  static struct member_list empty;
   
 static bool command_matches_dir(char *, size_t);  static bool command_matches_dir(char *, size_t);
   #ifndef SUDOERS_NAME_MATCH
 static bool command_matches_glob(char *, char *);  static bool command_matches_glob(char *, char *);
   #endif
 static bool command_matches_fnmatch(char *, char *);  static bool command_matches_fnmatch(char *, char *);
static bool command_matches_normal(char *, char *);static bool command_matches_normal(char *, char *, struct sudo_digest *);
   
 /*  /*
  * Returns true if string 's' contains meta characters.   * Returns true if string 's' contains meta characters.
Line 101  static bool command_matches_normal(char *, char *); Line 109  static bool command_matches_normal(char *, char *);
  * Check for user described by pw in a list of members.   * Check for user described by pw in a list of members.
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
static intint
_userlist_matches(struct passwd *pw, struct member_list *list)userlist_matches(struct passwd *pw, 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) {      tq_foreach_rev(list, m) {
         switch (m->type) {          switch (m->type) {
Line 123  _userlist_matches(struct passwd *pw, struct member_lis Line 131  _userlist_matches(struct passwd *pw, struct member_lis
                     matched = !m->negated;                      matched = !m->negated;
                 break;                  break;
             case ALIAS:              case ALIAS:
                if ((a = alias_find(m->name, USERALIAS)) != NULL) {                if ((a = alias_get(m->name, USERALIAS)) != NULL) {
                    rval = _userlist_matches(pw, &a->members);                    rval = userlist_matches(pw, &a->members);
                     if (rval != UNSPEC)                      if (rval != UNSPEC)
                         matched = m->negated ? !rval : rval;                          matched = m->negated ? !rval : rval;
                       alias_put(a);
                     break;                      break;
                 }                  }
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
Line 141  _userlist_matches(struct passwd *pw, struct member_lis Line 150  _userlist_matches(struct passwd *pw, struct member_lis
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }
   
 int  
 userlist_matches(struct passwd *pw, struct member_list *list)  
 {  
     alias_seqno++;  
     return _userlist_matches(pw, list);  
 }  
   
 /*  /*
  * Check for user described by pw in a list of members.   * Check for user described by pw in a list of members.
  * If both lists are empty compare against def_runas_default.   * If both lists are empty compare against def_runas_default.
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
static intint
_runaslist_matches(struct member_list *user_list,runaslist_matches(struct member_list *user_list,
     struct member_list *group_list, struct member **matching_user,      struct member_list *group_list, struct member **matching_user,
     struct member **matching_group)      struct member **matching_group)
 {  {
Line 163  _runaslist_matches(struct member_list *user_list, Line 165  _runaslist_matches(struct member_list *user_list,
     int rval;      int rval;
     int user_matched = UNSPEC;      int user_matched = UNSPEC;
     int group_matched = UNSPEC;      int group_matched = UNSPEC;
    debug_decl(_runaslist_matches, SUDO_DEBUG_MATCH)    debug_decl(runaslist_matches, SUDO_DEBUG_MATCH)
   
     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. */
Line 184  _runaslist_matches(struct member_list *user_list, Line 186  _runaslist_matches(struct member_list *user_list,
                         user_matched = !m->negated;                          user_matched = !m->negated;
                     break;                      break;
                 case ALIAS:                  case ALIAS:
                    if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {                    if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
                        rval = _runaslist_matches(&a->members, &empty,                        rval = runaslist_matches(&a->members, &empty,
                             matching_user, NULL);                              matching_user, NULL);
                         if (rval != UNSPEC)                          if (rval != UNSPEC)
                             user_matched = m->negated ? !rval : rval;                              user_matched = m->negated ? !rval : rval;
                           alias_put(a);
                         break;                          break;
                     }                      }
                     /* FALLTHROUGH */                      /* FALLTHROUGH */
Line 221  _runaslist_matches(struct member_list *user_list, Line 224  _runaslist_matches(struct member_list *user_list,
                     group_matched = !m->negated;                      group_matched = !m->negated;
                     break;                      break;
                 case ALIAS:                  case ALIAS:
                    if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {                    if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
                        rval = _runaslist_matches(&empty, &a->members,                        rval = runaslist_matches(&empty, &a->members,
                             NULL, matching_group);                              NULL, matching_group);
                         if (rval != UNSPEC)                          if (rval != UNSPEC)
                             group_matched = m->negated ? !rval : rval;                              group_matched = m->negated ? !rval : rval;
                           alias_put(a);
                         break;                          break;
                     }                      }
                     /* FALLTHROUGH */                      /* FALLTHROUGH */
Line 253  _runaslist_matches(struct member_list *user_list, Line 257  _runaslist_matches(struct member_list *user_list,
     debug_return_int(UNSPEC);      debug_return_int(UNSPEC);
 }  }
   
 int  
 runaslist_matches(struct member_list *user_list,  
     struct member_list *group_list, struct member **matching_user,  
     struct member **matching_group)  
 {  
     alias_seqno++;  
     return _runaslist_matches(user_list ? user_list : &empty,  
         group_list ? group_list : &empty, matching_user, matching_group);  
 }  
   
 /*  /*
  * Check for host and shost in a list of members.   * Check for host and shost in a list of members.
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
static intint
_hostlist_matches(struct member_list *list)hostlist_matches(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) {      tq_foreach_rev(list, m) {
         switch (m->type) {          switch (m->type) {
Line 289  _hostlist_matches(struct member_list *list) Line 283  _hostlist_matches(struct member_list *list)
                     matched = !m->negated;                      matched = !m->negated;
                 break;                  break;
             case ALIAS:              case ALIAS:
                if ((a = alias_find(m->name, HOSTALIAS)) != NULL) {                if ((a = alias_get(m->name, HOSTALIAS)) != NULL) {
                    rval = _hostlist_matches(&a->members);                    rval = hostlist_matches(&a->members);
                     if (rval != UNSPEC)                      if (rval != UNSPEC)
                         matched = m->negated ? !rval : rval;                          matched = m->negated ? !rval : rval;
                       alias_put(a);
                     break;                      break;
                 }                  }
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
Line 307  _hostlist_matches(struct member_list *list) Line 302  _hostlist_matches(struct member_list *list)
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }
   
 int  
 hostlist_matches(struct member_list *list)  
 {  
     alias_seqno++;  
     return _hostlist_matches(list);  
 }  
   
 /*  /*
  * Check for cmnd and args in a list of members.   * Check for cmnd and args in a list of members.
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
  */   */
static intint
_cmndlist_matches(struct member_list *list)cmndlist_matches(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) {      tq_foreach_rev(list, m) {
         matched = cmnd_matches(m);          matched = cmnd_matches(m);
Line 333  _cmndlist_matches(struct member_list *list) Line 321  _cmndlist_matches(struct member_list *list)
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }
   
 int  
 cmndlist_matches(struct member_list *list)  
 {  
     alias_seqno++;  
     return _cmndlist_matches(list);  
 }  
   
 /*  /*
  * Check cmnd and args.   * Check cmnd and args.
  * Returns ALLOW, DENY or UNSPEC.   * Returns ALLOW, DENY or UNSPEC.
Line 357  cmnd_matches(struct member *m) Line 338  cmnd_matches(struct member *m)
             matched = !m->negated;              matched = !m->negated;
             break;              break;
         case ALIAS:          case ALIAS:
            alias_seqno++;            if ((a = alias_get(m->name, CMNDALIAS)) != NULL) {
            if ((a = alias_find(m->name, CMNDALIAS)) != NULL) {                rval = cmndlist_matches(&a->members);
                rval = _cmndlist_matches(&a->members); 
                 if (rval != UNSPEC)                  if (rval != UNSPEC)
                     matched = m->negated ? !rval : rval;                      matched = m->negated ? !rval : rval;
                   alias_put(a);
             }              }
             break;              break;
         case COMMAND:          case COMMAND:
             c = (struct sudo_command *)m->name;              c = (struct sudo_command *)m->name;
            if (command_matches(c->cmnd, c->args))            if (command_matches(c->cmnd, c->args, c->digest))
                 matched = !m->negated;                  matched = !m->negated;
             break;              break;
     }      }
Line 374  cmnd_matches(struct member *m) Line 355  cmnd_matches(struct member *m)
 }  }
   
 static bool  static bool
command_args_match(sudoers_cmnd, sudoers_args)command_args_match(char *sudoers_cmnd, char *sudoers_args)
    char *sudoers_cmnd; 
    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 407  command_args_match(sudoers_cmnd, sudoers_args) Line 386  command_args_match(sudoers_cmnd, sudoers_args)
  * 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)command_matches(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)
 {  {
     debug_decl(command_matches, SUDO_DEBUG_MATCH)      debug_decl(command_matches, SUDO_DEBUG_MATCH)
   
Line 435  command_matches(char *sudoers_cmnd, char *sudoers_args Line 414  command_matches(char *sudoers_cmnd, char *sudoers_args
          * If sudoers_cmnd has meta characters in it, we need to           * If sudoers_cmnd has meta characters in it, we need to
          * 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
           debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));
   #else
         if (def_fast_glob)          if (def_fast_glob)
             debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));              debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));
         debug_return_bool(command_matches_glob(sudoers_cmnd, sudoers_args));          debug_return_bool(command_matches_glob(sudoers_cmnd, sudoers_args));
   #endif
     }      }
    debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args));    debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args, digest));
 }  }
   
 static bool  static bool
Line 465  command_matches_fnmatch(char *sudoers_cmnd, char *sudo Line 448  command_matches_fnmatch(char *sudoers_cmnd, char *sudo
     debug_return_bool(false);      debug_return_bool(false);
 }  }
   
   #ifndef SUDOERS_NAME_MATCH
 static bool  static bool
 command_matches_glob(char *sudoers_cmnd, char *sudoers_args)  command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
 {  {
Line 535  command_matches_glob(char *sudoers_cmnd, char *sudoers Line 519  command_matches_glob(char *sudoers_cmnd, char *sudoers
     }      }
     debug_return_bool(false);      debug_return_bool(false);
 }  }
   #endif /* SUDOERS_NAME_MATCH */
   
   #ifdef SUDOERS_NAME_MATCH
 static bool  static bool
command_matches_normal(char *sudoers_cmnd, char *sudoers_args)command_matches_normal(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)
 {  {
       size_t dlen;
       debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)
   
       dlen = strlen(sudoers_cmnd);
   
       /* If it ends in '/' it is a directory spec. */
       if (sudoers_cmnd[dlen - 1] == '/')
           debug_return_bool(command_matches_dir(sudoers_cmnd, dlen));
   
       if (strcmp(user_cmnd, sudoers_cmnd) == 0) {
           if (command_args_match(sudoers_cmnd, sudoers_args)) {
               efree(safe_cmnd);
               safe_cmnd = estrdup(sudoers_cmnd);
               debug_return_bool(true);
           }
       }
       debug_return_bool(false);
   }
   #else /* !SUDOERS_NAME_MATCH */
   
   static struct digest_function {
       const char *digest_name;
       const unsigned int digest_len;
       void (*init)(SHA2_CTX *);
       void (*update)(SHA2_CTX *, const unsigned char *, size_t);
       void (*final)(unsigned char *, SHA2_CTX *);
   } digest_functions[] = {
       {
           "SHA224",
           SHA224_DIGEST_LENGTH,
           SHA224Init,
           SHA224Update,
           SHA224Final
       }, {
           "SHA256",
           SHA256_DIGEST_LENGTH,
           SHA256Init,
           SHA256Update,
           SHA256Final
       }, {
           "SHA384",
           SHA384_DIGEST_LENGTH,
           SHA384Init,
           SHA384Update,
           SHA384Final
       }, {
           "SHA512",
           SHA512_DIGEST_LENGTH,
           SHA512Init,
           SHA512Update,
           SHA512Final
       }, {
           NULL
       }
   };
   
   static bool
   digest_matches(char *file, struct sudo_digest *sd)
   {
       unsigned char file_digest[SHA512_DIGEST_LENGTH];
       unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];
       unsigned char buf[32 * 1024];
       struct digest_function *func = NULL;
       size_t nread;
       SHA2_CTX ctx;
       FILE *fp;
       unsigned int i;
       debug_decl(digest_matches, SUDO_DEBUG_MATCH)
   
       for (i = 0; digest_functions[i].digest_name != NULL; i++) {
           if (sd->digest_type == i) {
               func = &digest_functions[i];
               break;
           }
       }
       if (func == NULL) {
           warningx(_("unsupported digest type %d for %s"), sd->digest_type, file);
           debug_return_bool(false);
       }
       if (strlen(sd->digest_str) == func->digest_len * 2) {
           /* Convert the command digest from ascii hex to binary. */
           for (i = 0; i < func->digest_len; i++) {
               if (!isxdigit((unsigned char)sd->digest_str[i + i]) ||
                   !isxdigit((unsigned char)sd->digest_str[i + i + 1])) {
                   goto bad_format;
               }
               sudoers_digest[i] = hexchar(&sd->digest_str[i + i]);
           }
       } else {
           size_t len = base64_decode(sd->digest_str, sudoers_digest,
               sizeof(sudoers_digest));
           if (len != func->digest_len)
               goto bad_format;
       }
   
       if ((fp = fopen(file, "r")) == NULL) {
           sudo_debug_printf(SUDO_DEBUG_INFO, "unable to open %s: %s",
               file, strerror(errno));
           debug_return_bool(false);
       }
   
       func->init(&ctx);
       while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) {
           func->update(&ctx, buf, nread);
       }
       if (ferror(fp)) {
           warningx(_("%s: read error"), file);
           fclose(fp);
           debug_return_bool(false);
       }
       fclose(fp);
       func->final(file_digest, &ctx);
   
       debug_return_bool(memcmp(file_digest, sudoers_digest, func->digest_len) == 0);
   bad_format:
       warningx(_("digest for %s (%s) is not in %s form"), file,
           sd->digest_str, func->digest_name);
       debug_return_bool(false);
   }
   
   static bool
   command_matches_normal(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest)
   {
     struct stat sudoers_stat;      struct stat sudoers_stat;
     char *base;      char *base;
     size_t dlen;      size_t dlen;
Line 563  command_matches_normal(char *sudoers_cmnd, char *sudoe Line 672  command_matches_normal(char *sudoers_cmnd, char *sudoe
      *  a) there are no args in sudoers OR       *  a) there are no args in sudoers OR
      *  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
        *  d) there is a digest and it matches
      */       */
     if (user_stat != NULL &&      if (user_stat != NULL &&
         (user_stat->st_dev != sudoers_stat.st_dev ||          (user_stat->st_dev != sudoers_stat.st_dev ||
         user_stat->st_ino != sudoers_stat.st_ino))          user_stat->st_ino != sudoers_stat.st_ino))
         debug_return_bool(false);          debug_return_bool(false);
    if (command_args_match(sudoers_cmnd, sudoers_args)) {    if (!command_args_match(sudoers_cmnd, sudoers_args))
        efree(safe_cmnd);        debug_return_bool(false);
        safe_cmnd = estrdup(sudoers_cmnd);    if (digest != NULL && !digest_matches(sudoers_cmnd, digest)) {
        debug_return_bool(true);        /* XXX - log functions not available but we should log very loudly */
         debug_return_bool(false);
     }      }
    debug_return_bool(false);    efree(safe_cmnd);
     safe_cmnd = estrdup(sudoers_cmnd);
     debug_return_bool(true);
 }  }
   #endif /* SUDOERS_NAME_MATCH */
   
   #ifdef SUDOERS_NAME_MATCH
 /*  /*
    * Return true if user_cmnd begins with sudoers_dir, else false.
    * Note that sudoers_dir include the trailing '/'
    */
   static bool
   command_matches_dir(char *sudoers_dir, size_t dlen)
   {
       debug_decl(command_matches_dir, SUDO_DEBUG_MATCH)
       debug_return_bool(strncmp(user_cmnd, sudoers_dir, dlen) == 0);
   }
   #else /* !SUDOERS_NAME_MATCH */
   /*
  * 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
Line 621  command_matches_dir(char *sudoers_dir, size_t dlen) Line 747  command_matches_dir(char *sudoers_dir, size_t dlen)
     closedir(dirp);      closedir(dirp);
     debug_return_bool(dent != NULL);      debug_return_bool(dent != NULL);
 }  }
   #endif /* SUDOERS_NAME_MATCH */
   
 /*  /*
  * Returns true if the hostname matches the pattern, else false   * Returns true if the hostname matches the pattern, else false
Line 722  done: Line 849  done:
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }
   
   #ifdef HAVE_INNETGR
 /*  /*
    * Get NIS-style domain name and return a malloc()ed copy or NULL if none.
    */
   static char *
   sudo_getdomainname(void)
   {
       char *domain = NULL;
   #ifdef HAVE_GETDOMAINNAME
       char *buf, *cp;
   
       buf = emalloc(HOST_NAME_MAX + 1);
       if (getdomainname(buf, HOST_NAME_MAX + 1) == 0 && *buf != '\0') {
           domain = buf;
           for (cp = buf; *cp != '\0'; cp++) {
               /* Check for illegal characters, Linux may use "(none)". */
               if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ') {
                   domain = NULL;
                   break;
               }
           }
       }
       if (domain == NULL)
           efree(buf);
   #endif /* HAVE_GETDOMAINNAME */
       return domain;
   }
   #endif /* HAVE_INNETGR */
   
   /*
  * 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 "host", "shost" or "user" may be NULL
  * in which case that argument is not checked...   * in which case that argument is not checked...
Line 732  done: Line 888  done:
 bool  bool
 netgr_matches(char *netgr, char *lhost, char *shost, char *user)  netgr_matches(char *netgr, char *lhost, char *shost, char *user)
 {  {
   #ifdef HAVE_INNETGR
     static char *domain;      static char *domain;
 #ifdef HAVE_GETDOMAINNAME  
     static int initialized;      static int initialized;
 #endif  #endif
     debug_decl(netgr_matches, SUDO_DEBUG_MATCH)      debug_decl(netgr_matches, SUDO_DEBUG_MATCH)
   
   #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++ != '+')
         debug_return_bool(false);          debug_return_bool(false);
   
 #ifdef HAVE_GETDOMAINNAME  
     /* get the domain name (if any) */      /* get the domain name (if any) */
     if (!initialized) {      if (!initialized) {
        domain = (char *) emalloc(MAXHOSTNAMELEN + 1);        domain = sudo_getdomainname();
        if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0') { 
            efree(domain); 
            domain = NULL; 
        } 
         initialized = 1;          initialized = 1;
     }      }
 #endif /* HAVE_GETDOMAINNAME */  
   
 #ifdef HAVE_INNETGR  
     if (innetgr(netgr, lhost, user, domain))      if (innetgr(netgr, lhost, user, domain))
         debug_return_bool(true);          debug_return_bool(true);
     else if (lhost != shost && innetgr(netgr, shost, user, domain))      else if (lhost != shost && innetgr(netgr, shost, user, domain))

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


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