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

version 1.1.1.2, 2012/05/29 12:26:49 version 1.1.1.3, 2012/10/09 09:29:52
Line 145  sudoers_policy_open(unsigned int version, sudo_conv_t  Line 145  sudoers_policy_open(unsigned int version, sudo_conv_t 
     volatile int sources = 0;      volatile int sources = 0;
     sigaction_t sa;      sigaction_t sa;
     struct sudo_nss *nss;      struct sudo_nss *nss;
       struct sudo_nss *nss_next;
     debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)      debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
   
     sudo_version = version;      sudo_version = version;
Line 201  sudoers_policy_open(unsigned int version, sudo_conv_t  Line 202  sudoers_policy_open(unsigned int version, sudo_conv_t 
     set_perms(PERM_ROOT);      set_perms(PERM_ROOT);
   
     /* Open and parse sudoers, set global defaults */      /* Open and parse sudoers, set global defaults */
    tq_foreach_fwd(snl, nss) {    for (nss = snl->first; nss != NULL; nss = nss_next) {
        if (nss->open(nss) == 0 && nss->parse(nss) == 0) {        nss_next = nss->next;
            sources++;        if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
            if (nss->setdefs(nss) != 0)            sources++;
                log_error(NO_STDERR, _("problem with defaults entries"));            if (nss->setdefs(nss) != 0)
        }                log_error(NO_STDERR, _("problem with defaults entries"));
         } else {
             tq_remove(snl, nss);
         }
     }      }
     if (sources == 0) {      if (sources == 0) {
         warningx(_("no valid sudoers sources found, quitting"));          warningx(_("no valid sudoers sources found, quitting"));
Line 268  sudoers_policy_close(int exit_status, int error_code) Line 272  sudoers_policy_close(int exit_status, int error_code)
         (void)sudo_auth_end_session(runas_pw);          (void)sudo_auth_end_session(runas_pw);
   
     /* Free remaining references to password and group entries. */      /* Free remaining references to password and group entries. */
    pw_delref(sudo_user.pw);    sudo_pw_delref(sudo_user.pw);
    pw_delref(runas_pw);    sudo_user.pw = NULL;
    if (runas_gr != NULL)    sudo_pw_delref(runas_pw);
        gr_delref(runas_gr);    runas_pw = NULL;
    if (user_group_list != NULL)    if (runas_gr != NULL) {
        grlist_delref(user_group_list);        sudo_gr_delref(runas_gr);
         runas_gr = NULL;
     }
     if (user_group_list != NULL) {
         sudo_grlist_delref(user_group_list);
         user_group_list = NULL;
     }
     efree(user_gids);
     user_gids = NULL;
   
     debug_return;      debug_return;
 }  }
Line 281  sudoers_policy_close(int exit_status, int error_code) Line 293  sudoers_policy_close(int exit_status, int error_code)
 /*  /*
  * The init_session function is called before executing the command   * The init_session function is called before executing the command
  * and before uid/gid changes occur.   * and before uid/gid changes occur.
    * Returns 1 on success, 0 on failure and -1 on error.
  */   */
 static int  static int
 sudoers_policy_init_session(struct passwd *pwd, char **user_env[])  sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
Line 293  sudoers_policy_init_session(struct passwd *pwd, char * Line 306  sudoers_policy_init_session(struct passwd *pwd, char *
   
     if (sigsetjmp(error_jmp, 1)) {      if (sigsetjmp(error_jmp, 1)) {
         /* called via error(), errorx() or log_fatal() */          /* called via error(), errorx() or log_fatal() */
        return -1;        debug_return_bool(-1);
     }      }
   
     debug_return_bool(sudo_auth_begin_session(pwd, user_env));      debug_return_bool(sudo_auth_begin_session(pwd, user_env));
Line 363  sudoers_policy_main(int argc, char * const argv[], int Line 376  sudoers_policy_main(int argc, char * const argv[], int
   
     /* Find command in path */      /* Find command in path */
     cmnd_status = set_cmnd();      cmnd_status = set_cmnd();
     if (cmnd_status == -1) {  
         rval = -1;  
         goto done;  
     }  
   
 #ifdef HAVE_SETLOCALE  #ifdef HAVE_SETLOCALE
     if (!setlocale(LC_ALL, def_sudoers_locale)) {      if (!setlocale(LC_ALL, def_sudoers_locale)) {
Line 384  sudoers_policy_main(int argc, char * const argv[], int Line 393  sudoers_policy_main(int argc, char * const argv[], int
         validated = nss->lookup(nss, validated, pwflag);          validated = nss->lookup(nss, validated, pwflag);
   
         if (ISSET(validated, VALIDATE_OK)) {          if (ISSET(validated, VALIDATE_OK)) {
            /* Handle "= auth" in netsvc.conf */            /* Handle [SUCCESS=return] */
             if (nss->ret_if_found)              if (nss->ret_if_found)
                 break;                  break;
         } else {          } else {
Line 417  sudoers_policy_main(int argc, char * const argv[], int Line 426  sudoers_policy_main(int argc, char * const argv[], int
             pw = sudo_getpwnam(def_timestampowner);              pw = sudo_getpwnam(def_timestampowner);
         if (pw != NULL) {          if (pw != NULL) {
             timestamp_uid = pw->pw_uid;              timestamp_uid = pw->pw_uid;
            pw_delref(pw);            sudo_pw_delref(pw);
         } else {          } else {
             log_error(0, _("timestamp owner (%s): No such user"),              log_error(0, _("timestamp owner (%s): No such user"),
                 def_timestampowner);                  def_timestampowner);
Line 455  sudoers_policy_main(int argc, char * const argv[], int Line 464  sudoers_policy_main(int argc, char * const argv[], int
   
     /* Require a password if sudoers says so.  */      /* Require a password if sudoers says so.  */
     rval = check_user(validated, sudo_mode);      rval = check_user(validated, sudo_mode);
    if (rval != true)    if (rval != true) {
         if (!ISSET(validated, VALIDATE_OK))
             log_failure(validated, cmnd_status);
         goto done;          goto done;
       }
   
     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */      /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
     /* XXX - causes confusion when root is not listed in sudoers */      /* XXX - causes confusion when root is not listed in sudoers */
Line 466  sudoers_policy_main(int argc, char * const argv[], int Line 478  sudoers_policy_main(int argc, char * const argv[], int
   
             if ((pw = sudo_getpwnam(prev_user)) != NULL) {              if ((pw = sudo_getpwnam(prev_user)) != NULL) {
                     if (sudo_user.pw != NULL)                      if (sudo_user.pw != NULL)
                        pw_delref(sudo_user.pw);                        sudo_pw_delref(sudo_user.pw);
                     sudo_user.pw = pw;                      sudo_user.pw = pw;
             }              }
         }          }
Line 474  sudoers_policy_main(int argc, char * const argv[], int Line 486  sudoers_policy_main(int argc, char * const argv[], int
   
     /* If the user was not allowed to run the command we are done. */      /* If the user was not allowed to run the command we are done. */
     if (!ISSET(validated, VALIDATE_OK)) {      if (!ISSET(validated, VALIDATE_OK)) {
        if (ISSET(validated, FLAG_NO_USER | FLAG_NO_HOST)) {        log_failure(validated, cmnd_status);
            audit_failure(NewArgv, _("No user or host")); 
            log_denial(validated, 1); 
        } else { 
            if (def_path_info) { 
                /* 
                 * We'd like to not leak path info at all here, but that can 
                 * *really* confuse the users.  To really close the leak we'd 
                 * have to say "not allowed to run foo" even when the problem 
                 * is just "no foo in path" since the user can trivially set 
                 * their path to just contain a single dir. 
                 */ 
                log_denial(validated, 
                    !(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND)); 
                if (cmnd_status == NOT_FOUND) 
                    warningx(_("%s: command not found"), user_cmnd); 
                else if (cmnd_status == NOT_FOUND_DOT) 
                    warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd); 
            } else { 
                /* Just tell the user they are not allowed to run foo. */ 
                log_denial(validated, 1); 
            } 
            audit_failure(NewArgv, _("validation failure")); 
        } 
         goto bad;          goto bad;
     }      }
   
Line 664  sudoers_policy_main(int argc, char * const argv[], int Line 653  sudoers_policy_main(int argc, char * const argv[], int
         gid_t egid;          gid_t egid;
         size_t glsize;          size_t glsize;
         char *cp, *gid_list;          char *cp, *gid_list;
        struct group_list *grlist = get_group_list(runas_pw);        struct group_list *grlist = sudo_get_grlist(runas_pw);
   
         /* We reserve an extra spot in the list for the effective gid. */          /* We reserve an extra spot in the list for the effective gid. */
         glsize = sizeof("runas_groups=") - 1 +          glsize = sizeof("runas_groups=") - 1 +
Line 678  sudoers_policy_main(int argc, char * const argv[], int Line 667  sudoers_policy_main(int argc, char * const argv[], int
             (unsigned int)runas_pw->pw_gid;              (unsigned int)runas_pw->pw_gid;
         len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);          len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);
         if (len < 0 || len >= glsize - (cp - gid_list))          if (len < 0 || len >= glsize - (cp - gid_list))
            errorx(1, _("internal error, runas_groups overflow"));            errorx(1, _("internal error, %s overflow"), "runas_groups");
         cp += len;          cp += len;
         for (i = 0; i < grlist->ngids; i++) {          for (i = 0; i < grlist->ngids; i++) {
             if (grlist->gids[i] != egid) {              if (grlist->gids[i] != egid) {
                 len = snprintf(cp, glsize - (cp - gid_list), ",%u",                  len = snprintf(cp, glsize - (cp - gid_list), ",%u",
                      (unsigned int) grlist->gids[i]);                       (unsigned int) grlist->gids[i]);
                 if (len < 0 || len >= glsize - (cp - gid_list))                  if (len < 0 || len >= glsize - (cp - gid_list))
                    errorx(1, _("internal error, runas_groups overflow"));                    errorx(1, _("internal error, %s overflow"), "runas_groups");
                 cp += len;                  cp += len;
             }              }
         }          }
         command_info[info_len++] = gid_list;          command_info[info_len++] = gid_list;
        grlist_delref(grlist);        sudo_grlist_delref(grlist);
     }      }
     if (def_closefrom >= 0)      if (def_closefrom >= 0)
         easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);          easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
Line 712  sudoers_policy_main(int argc, char * const argv[], int Line 701  sudoers_policy_main(int argc, char * const argv[], int
     if (user_type != NULL)      if (user_type != NULL)
         command_info[info_len++] = fmt_string("selinux_type", user_type);          command_info[info_len++] = fmt_string("selinux_type", user_type);
 #endif /* HAVE_SELINUX */  #endif /* HAVE_SELINUX */
   #ifdef HAVE_PRIV_SET
       if (runas_privs != NULL)
           command_info[info_len++] = fmt_string("runas_privs", runas_privs);
       if (runas_limitprivs != NULL)
           command_info[info_len++] = fmt_string("runas_limitprivs", runas_limitprivs);
   #endif /* HAVE_SELINUX */
   
     /* Must audit before uid change. */      /* Must audit before uid change. */
     audit_success(NewArgv);      audit_success(NewArgv);
Line 800  sudoers_policy_list(int argc, char * const argv[], int Line 795  sudoers_policy_list(int argc, char * const argv[], int
     }      }
     rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL);      rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL);
     if (list_user) {      if (list_user) {
        pw_delref(list_pw);        sudo_pw_delref(list_pw);
         list_pw = NULL;          list_pw = NULL;
     }      }
   
Line 865  init_vars(char * const envp[]) Line 860  init_vars(char * const envp[])
      * Get group list.       * Get group list.
      */       */
     if (user_group_list == NULL)      if (user_group_list == NULL)
        user_group_list = get_group_list(sudo_user.pw);        user_group_list = sudo_get_grlist(sudo_user.pw);
   
     /* Set runas callback. */      /* Set runas callback. */
     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;      sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
Line 938  set_cmnd(void) Line 933  set_cmnd(void)
                 for (to = user_args, av = NewArgv + 1; *av; av++) {                  for (to = user_args, av = NewArgv + 1; *av; av++) {
                     n = strlcpy(to, *av, size - (to - user_args));                      n = strlcpy(to, *av, size - (to - user_args));
                     if (n >= size - (to - user_args))                      if (n >= size - (to - user_args))
                        errorx(1, _("internal error, set_cmnd() overflow"));                        errorx(1, _("internal error, %s overflow"), "set_cmnd()");
                     to += n;                      to += n;
                     *to++ = ' ';                      *to++ = ' ';
                 }                  }
Line 975  open_sudoers(const char *sudoers, bool doedit, bool *k Line 970  open_sudoers(const char *sudoers, bool doedit, bool *k
   
     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {      switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
         case SUDO_PATH_SECURE:          case SUDO_PATH_SECURE:
               /*
                * If we are expecting sudoers to be group readable but
                * it is not, we must open the file as root, not uid 1.
                */
               if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) {
                   if ((sb.st_mode & S_IRGRP) == 0) {
                       restore_perms();
                       set_perms(PERM_ROOT);
                   }
               }
               /*
                * Open sudoers and make sure we can read it so we can present
                * the user with a reasonable error message (unlike the lexer).
                */
             if ((fp = fopen(sudoers, "r")) == NULL) {              if ((fp = fopen(sudoers, "r")) == NULL) {
                 log_error(USE_ERRNO, _("unable to open %s"), sudoers);                  log_error(USE_ERRNO, _("unable to open %s"), sudoers);
             } else {              } else {
                 /*  
                  * Make sure we can actually read sudoers so we can present the  
                  * user with a reasonable error message (unlike the lexer).  
                  */  
                 if (sb.st_size != 0 && fgetc(fp) == EOF) {                  if (sb.st_size != 0 && fgetc(fp) == EOF) {
                     log_error(USE_ERRNO, _("unable to read %s"),                      log_error(USE_ERRNO, _("unable to read %s"),
                         sudoers);                          sudoers);
Line 1067  set_loginclass(struct passwd *pw) Line 1072  set_loginclass(struct passwd *pw)
 }  }
 #endif /* HAVE_LOGIN_CAP_H */  #endif /* HAVE_LOGIN_CAP_H */
   
   #ifndef AI_FQDN
   # define AI_FQDN AI_CANONNAME
   #endif
   
 /*  /*
  * Look up the fully qualified domain name and set user_host and user_shost.   * Look up the fully qualified domain name and set user_host and user_shost.
    * Use AI_FQDN if available since "canonical" is not always the same as fqdn.
  */   */
 void  void
 set_fqdn(void)  set_fqdn(void)
Line 1079  set_fqdn(void) Line 1089  set_fqdn(void)
   
     zero_bytes(&hint, sizeof(hint));      zero_bytes(&hint, sizeof(hint));
     hint.ai_family = PF_UNSPEC;      hint.ai_family = PF_UNSPEC;
    hint.ai_flags = AI_CANONNAME;    hint.ai_flags = AI_FQDN;
     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {      if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
         log_error(MSG_ONLY, _("unable to resolve host %s"), user_host);          log_error(MSG_ONLY, _("unable to resolve host %s"), user_host);
     } else {      } else {
Line 1088  set_fqdn(void) Line 1098  set_fqdn(void)
         efree(user_host);          efree(user_host);
         user_host = estrdup(res0->ai_canonname);          user_host = estrdup(res0->ai_canonname);
         freeaddrinfo(res0);          freeaddrinfo(res0);
           if ((p = strchr(user_host, '.')) != NULL)
               user_shost = estrndup(user_host, (size_t)(p - user_host));
           else
               user_shost = user_host;
     }      }
     if ((p = strchr(user_host, '.')) != NULL)  
         user_shost = estrndup(user_host, (size_t)(p - user_host));  
     else  
         user_shost = user_host;  
     debug_return;      debug_return;
 }  }
   
Line 1106  set_runaspw(const char *user) Line 1116  set_runaspw(const char *user)
     debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)      debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
   
     if (runas_pw != NULL)      if (runas_pw != NULL)
        pw_delref(runas_pw);        sudo_pw_delref(runas_pw);
     if (*user == '#') {      if (*user == '#') {
         if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)          if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
             runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);              runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
Line 1127  set_runasgr(const char *group) Line 1137  set_runasgr(const char *group)
     debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)      debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
   
     if (runas_gr != NULL)      if (runas_gr != NULL)
        gr_delref(runas_gr);        sudo_gr_delref(runas_gr);
     if (*group == '#') {      if (*group == '#') {
         if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)          if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
             runas_gr = sudo_fakegrnam(group);              runas_gr = sudo_fakegrnam(group);
Line 1254  deserialize_info(char * const args[], char * const set Line 1264  deserialize_info(char * const args[], char * const set
         }          }
         if (MATCHES(*cur, "runas_user=")) {          if (MATCHES(*cur, "runas_user=")) {
             runas_user = *cur + sizeof("runas_user=") - 1;              runas_user = *cur + sizeof("runas_user=") - 1;
               sudo_user.flags |= RUNAS_USER_SPECIFIED;
             continue;              continue;
         }          }
         if (MATCHES(*cur, "runas_group=")) {          if (MATCHES(*cur, "runas_group=")) {
             runas_group = *cur + sizeof("runas_group=") - 1;              runas_group = *cur + sizeof("runas_group=") - 1;
               sudo_user.flags |= RUNAS_GROUP_SPECIFIED;
             continue;              continue;
         }          }
         if (MATCHES(*cur, "prompt=")) {          if (MATCHES(*cur, "prompt=")) {
Line 1317  deserialize_info(char * const args[], char * const set Line 1329  deserialize_info(char * const args[], char * const set
             def_use_loginclass = true;              def_use_loginclass = true;
             continue;              continue;
         }          }
   #ifdef HAVE_PRIV_SET
           if (MATCHES(*cur, "runas_privs=")) {
               def_privs = *cur + sizeof("runas_privs=") - 1;
               continue;
           }
           if (MATCHES(*cur, "runas_limitprivs=")) {
               def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1;
               continue;
           }
   #endif /* HAVE_PRIV_SET */
 #ifdef HAVE_SELINUX  #ifdef HAVE_SELINUX
         if (MATCHES(*cur, "selinux_role=")) {          if (MATCHES(*cur, "selinux_role=")) {
             user_role = *cur + sizeof("selinux_role=") - 1;              user_role = *cur + sizeof("selinux_role=") - 1;
Line 1420  deserialize_info(char * const args[], char * const set Line 1442  deserialize_info(char * const args[], char * const set
                 break;                  break;
             cp++; /* skip over comma */              cp++; /* skip over comma */
         }          }
        set_group_list(user_name, gids, ngids);        user_gids = gids;
        efree(gids);        user_ngids = ngids;
     }      }
   
     /* Setup debugging if indicated. */      /* Setup debugging if indicated. */
Line 1586  sudoers_policy_register_hooks(int version, int (*regis Line 1608  sudoers_policy_register_hooks(int version, int (*regis
     register_hook(&hook);      register_hook(&hook);
 }  }
   
struct policy_plugin sudoers_policy = {__dso_public struct policy_plugin sudoers_policy = {
     SUDO_POLICY_PLUGIN,      SUDO_POLICY_PLUGIN,
     SUDO_API_VERSION,      SUDO_API_VERSION,
     sudoers_policy_open,      sudoers_policy_open,

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


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