Diff for /embedaddon/sudo/plugins/sudoers/auth/pam.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, 2013/07/22 10:46:12
Line 1 Line 1
 /*  /*
 * Copyright (c) 1999-2005, 2007-2011 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1999-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 21 Line 21
 #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 57 Line 56
 # endif  # endif
 #endif  #endif
   
   /* We don't want to translate the strings in the calls to dgt(). */
   #ifdef PAM_TEXT_DOMAIN
   # define dgt(d, t)      dgettext(d, t)
   #endif
   
 #include "sudoers.h"  #include "sudoers.h"
 #include "sudo_auth.h"  #include "sudo_auth.h"
   
Line 68 Line 72
 # define PAM_CONST  # define PAM_CONST
 #endif  #endif
   
 static int converse(int, PAM_CONST struct pam_message **,  
                     struct pam_response **, void *);  
 static char *def_prompt = "Password:";  
 static int getpass_error;  
   
 #ifndef PAM_DATA_SILENT  #ifndef PAM_DATA_SILENT
 #define PAM_DATA_SILENT 0  #define PAM_DATA_SILENT 0
 #endif  #endif
   
   static int converse(int, PAM_CONST struct pam_message **,
                       struct pam_response **, void *);
   static char *def_prompt = "Password:";
   static bool sudo_pam_cred_established;
   static bool sudo_pam_authenticated;
   static int getpass_error;
 static pam_handle_t *pamh;  static pam_handle_t *pamh;
   
 int  int
Line 97  sudo_pam_init(struct passwd *pw, sudo_auth *auth) Line 102  sudo_pam_init(struct passwd *pw, sudo_auth *auth)
 #endif  #endif
         pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);          pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
     if (pam_status != PAM_SUCCESS) {      if (pam_status != PAM_SUCCESS) {
        log_error(USE_ERRNO|NO_MAIL, _("unable to initialize PAM"));        log_warning(USE_ERRNO|NO_MAIL, N_("unable to initialize PAM"));
         debug_return_int(AUTH_FATAL);          debug_return_int(AUTH_FATAL);
     }      }
   
Line 139  sudo_pam_verify(struct passwd *pw, char *prompt, sudo_ Line 144  sudo_pam_verify(struct passwd *pw, char *prompt, sudo_
             *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);              *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);
             switch (*pam_status) {              switch (*pam_status) {
                 case PAM_SUCCESS:                  case PAM_SUCCESS:
                       sudo_pam_authenticated = true;
                     debug_return_int(AUTH_SUCCESS);                      debug_return_int(AUTH_SUCCESS);
                 case PAM_AUTH_ERR:                  case PAM_AUTH_ERR:
                    log_error(NO_MAIL, _("account validation failure, "                    log_warning(NO_MAIL, N_("account validation failure, "
                         "is your account locked?"));                          "is your account locked?"));
                     debug_return_int(AUTH_FATAL);                      debug_return_int(AUTH_FATAL);
                 case PAM_NEW_AUTHTOK_REQD:                  case PAM_NEW_AUTHTOK_REQD:
                    log_error(NO_MAIL, _("Account or password is "                    log_warning(NO_MAIL, N_("Account or password is "
                         "expired, reset your password and try again"));                          "expired, reset your password and try again"));
                     *pam_status = pam_chauthtok(pamh,                      *pam_status = pam_chauthtok(pamh,
                         PAM_CHANGE_EXPIRED_AUTHTOK);                          PAM_CHANGE_EXPIRED_AUTHTOK);
                     if (*pam_status == PAM_SUCCESS)                      if (*pam_status == PAM_SUCCESS)
                         debug_return_int(AUTH_SUCCESS);                          debug_return_int(AUTH_SUCCESS);
                    if ((s = pam_strerror(pamh, *pam_status)))                    if ((s = pam_strerror(pamh, *pam_status)) != NULL) {
                        log_error(NO_MAIL, _("pam_chauthtok: %s"), s);                        log_warning(NO_MAIL,
                             N_("unable to change expired password: %s"), s);
                     }
                     debug_return_int(AUTH_FAILURE);                      debug_return_int(AUTH_FAILURE);
                 case PAM_AUTHTOK_EXPIRED:                  case PAM_AUTHTOK_EXPIRED:
                    log_error(NO_MAIL,                    log_warning(NO_MAIL,
                        _("Password expired, contact your system administrator"));                        N_("Password expired, contact your system administrator"));
                     debug_return_int(AUTH_FATAL);                      debug_return_int(AUTH_FATAL);
                 case PAM_ACCT_EXPIRED:                  case PAM_ACCT_EXPIRED:
                    log_error(NO_MAIL,                    log_warning(NO_MAIL,
                        _("Account expired or PAM config lacks an \"account\" "                        N_("Account expired or PAM config lacks an \"account\" "
                         "section for sudo, contact your system administrator"));                          "section for sudo, contact your system administrator"));
                     debug_return_int(AUTH_FATAL);                      debug_return_int(AUTH_FATAL);
             }              }
Line 176  sudo_pam_verify(struct passwd *pw, char *prompt, sudo_ Line 184  sudo_pam_verify(struct passwd *pw, char *prompt, sudo_
         case PAM_PERM_DENIED:          case PAM_PERM_DENIED:
             debug_return_int(AUTH_FAILURE);              debug_return_int(AUTH_FAILURE);
         default:          default:
            if ((s = pam_strerror(pamh, *pam_status)))            if ((s = pam_strerror(pamh, *pam_status)) != NULL)
                log_error(NO_MAIL, _("pam_authenticate: %s"), s);                log_warning(NO_MAIL, N_("PAM authentication error: %s"), s);
             debug_return_int(AUTH_FATAL);              debug_return_int(AUTH_FATAL);
     }      }
 }  }
Line 230  sudo_pam_begin_session(struct passwd *pw, char **user_ Line 238  sudo_pam_begin_session(struct passwd *pw, char **user_
      * this is not set and so pam_setcred() returns PAM_PERM_DENIED.       * this is not set and so pam_setcred() returns PAM_PERM_DENIED.
      * We can't call pam_acct_mgmt() with Linux-PAM for a similar reason.       * We can't call pam_acct_mgmt() with Linux-PAM for a similar reason.
      */       */
    (void) pam_setcred(pamh, PAM_ESTABLISH_CRED);    status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
     if (status == PAM_SUCCESS) {
         sudo_pam_cred_established = true;
     } else if (sudo_pam_authenticated) {
         const char *s = pam_strerror(pamh, status);
         if (s != NULL)
             log_warning(NO_MAIL, N_("unable to establish credentials: %s"), s);
         goto done;
     }
   
 #ifdef HAVE_PAM_GETENVLIST  #ifdef HAVE_PAM_GETENVLIST
     /*      /*
Line 252  sudo_pam_begin_session(struct passwd *pw, char **user_ Line 268  sudo_pam_begin_session(struct passwd *pw, char **user_
     }      }
 #endif /* HAVE_PAM_GETENVLIST */  #endif /* HAVE_PAM_GETENVLIST */
   
#ifndef NO_PAM_SESSION    if (def_pam_session) {
    status = pam_open_session(pamh, 0);        status = pam_open_session(pamh, 0);
    if (status != PAM_SUCCESS) {        if (status != PAM_SUCCESS) {
        (void) pam_end(pamh, status | PAM_DATA_SILENT);            (void) pam_end(pamh, status | PAM_DATA_SILENT);
        pamh = NULL;            pamh = NULL;
         }
     }      }
 #endif  
   
 done:  done:
     debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);      debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
Line 277  sudo_pam_end_session(struct passwd *pw, sudo_auth *aut Line 293  sudo_pam_end_session(struct passwd *pw, sudo_auth *aut
          * XXX - still needed now that session init is in parent?           * XXX - still needed now that session init is in parent?
          */           */
         (void) pam_set_item(pamh, PAM_USER, pw->pw_name);          (void) pam_set_item(pamh, PAM_USER, pw->pw_name);
#ifndef NO_PAM_SESSION        if (def_pam_session)
        (void) pam_close_session(pamh, PAM_SILENT);            (void) pam_close_session(pamh, PAM_SILENT);
#endif        if (sudo_pam_cred_established)
        (void) pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);            (void) pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
         status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);          status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
         pamh = NULL;          pamh = NULL;
     }      }
Line 321  converse(int num_msg, PAM_CONST struct pam_message **m Line 337  converse(int num_msg, PAM_CONST struct pam_message **m
                 if (getpass_error)                  if (getpass_error)
                     goto done;                      goto done;
   
                /* Is the sudo prompt standard? (If so, we'l just use PAM's) */                /* Is the sudo prompt standard? (If so, we'll just use PAM's) */
                 std_prompt =  strncmp(def_prompt, "Password:", 9) == 0 &&                  std_prompt =  strncmp(def_prompt, "Password:", 9) == 0 &&
                     (def_prompt[9] == '\0' ||                      (def_prompt[9] == '\0' ||
                     (def_prompt[9] == ' ' && def_prompt[10] == '\0'));                      (def_prompt[9] == ' ' && def_prompt[10] == '\0'));
Line 329  converse(int num_msg, PAM_CONST struct pam_message **m Line 345  converse(int num_msg, PAM_CONST struct pam_message **m
                 /* Only override PAM prompt if it matches /^Password: ?/ */                  /* Only override PAM prompt if it matches /^Password: ?/ */
 #if defined(PAM_TEXT_DOMAIN) && defined(HAVE_LIBINTL_H)  #if defined(PAM_TEXT_DOMAIN) && defined(HAVE_LIBINTL_H)
                 if (!def_passprompt_override && (std_prompt ||                  if (!def_passprompt_override && (std_prompt ||
                    (strcmp(pm->msg, dgettext(PAM_TEXT_DOMAIN, "Password: ")) &&                    (strcmp(pm->msg, dgt(PAM_TEXT_DOMAIN, "Password: ")) &&
                    strcmp(pm->msg, dgettext(PAM_TEXT_DOMAIN, "Password:")))))                    strcmp(pm->msg, dgt(PAM_TEXT_DOMAIN, "Password:")))))
                     prompt = pm->msg;                      prompt = pm->msg;
 #else  #else
                 if (!def_passprompt_override && (std_prompt ||                  if (!def_passprompt_override && (std_prompt ||

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


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