From 44512030b1f8b6d45c917dd2cb292c981bb7a543 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 5 Feb 2007 15:25:31 +0000 Subject: r21152: Correctly omit pam conversations when PAM_SILENT has been set by the calling application. Guenther (This used to be commit ebfae9a671d2c960178228ba7fdcd07cb2f49a05) --- source3/nsswitch/pam_winbind.c | 98 ++++++++++++++++++++++-------------------- source3/nsswitch/pam_winbind.h | 20 ++++----- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 6929c3f3db..aeab270a86 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -372,13 +372,17 @@ static int converse(pam_handle_t *pamh, int nargs, } -static int _make_remark(pam_handle_t * pamh, int type, const char *text) +static int _make_remark(pam_handle_t * pamh, int flags, int type, const char *text) { int retval = PAM_SUCCESS; struct pam_message *pmsg[1], msg[1]; struct pam_response *resp; + if (flags & WINBIND_SILENT) { + return PAM_SUCCESS; + } + pmsg[0] = &msg[0]; msg[0].msg = CONST_DISCARD(char *, text); msg[0].msg_style = type; @@ -392,7 +396,7 @@ static int _make_remark(pam_handle_t * pamh, int type, const char *text) return retval; } -static int _make_remark_v(pam_handle_t * pamh, int type, const char *format, va_list args) +static int _make_remark_v(pam_handle_t * pamh, int flags, int type, const char *format, va_list args) { char *var; int ret; @@ -403,18 +407,18 @@ static int _make_remark_v(pam_handle_t * pamh, int type, const char *format, va_ return ret; } - ret = _make_remark(pamh, type, var); + ret = _make_remark(pamh, flags, type, var); SAFE_FREE(var); return ret; } -static int _make_remark_format(pam_handle_t * pamh, int type, const char *format, ...) +static int _make_remark_format(pam_handle_t * pamh, int flags, int type, const char *format, ...) { int ret; va_list args; va_start(args, format); - ret = _make_remark_v(pamh, type, format, args); + ret = _make_remark_v(pamh, flags, type, format, args); va_end(args); return ret; } @@ -530,7 +534,7 @@ static int pam_winbind_request_log(pam_handle_t * pamh, } } -static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, time_t next_change, time_t now) +static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time_t next_change, time_t now) { int days = 0; struct tm tm_now, tm_next_change; @@ -549,12 +553,12 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, time_t next_ch days = (tm_next_change.tm_yday+tm_next_change.tm_year*365) - (tm_now.tm_yday+tm_now.tm_year*365); if (days == 0) { - _make_remark(pamh, PAM_TEXT_INFO, "Your password expires today"); + _make_remark(pamh, ctrl, PAM_TEXT_INFO, "Your password expires today"); return True; } if (days > 0 && days < DAYS_TO_WARN_BEFORE_PWD_EXPIRES) { - _make_remark_format(pamh, PAM_TEXT_INFO, "Your password will expire in %d %s", + _make_remark_format(pamh, ctrl, PAM_TEXT_INFO, "Your password will expire in %d %s", days, (days > 1) ? "days":"day"); return True; } @@ -562,7 +566,7 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, time_t next_ch return False; } -static void _pam_warn_password_expires_in_future(pam_handle_t *pamh, struct winbindd_response *response) +static void _pam_warn_password_expires_in_future(pam_handle_t *pamh, int ctrl, struct winbindd_response *response) { time_t now = time(NULL); time_t next_change = 0; @@ -580,7 +584,7 @@ static void _pam_warn_password_expires_in_future(pam_handle_t *pamh, struct winb /* check if the info3 must change timestamp has been set */ next_change = response->data.auth.info3.pass_must_change_time; - if (_pam_send_password_expiry_message(pamh, next_change, now)) { + if (_pam_send_password_expiry_message(pamh, ctrl, next_change, now)) { return; } @@ -592,7 +596,7 @@ static void _pam_warn_password_expires_in_future(pam_handle_t *pamh, struct winb next_change = response->data.auth.info3.pass_last_set_time + response->data.auth.policy.expire; - if (_pam_send_password_expiry_message(pamh, next_change, now)) { + if (_pam_send_password_expiry_message(pamh, ctrl, next_change, now)) { return; } @@ -913,18 +917,18 @@ static int winbind_auth_request(pam_handle_t * pamh, } if (ret) { - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_PASSWORD_EXPIRED"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_PASSWORD_MUST_CHANGE"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_INVALID_WORKSTATION"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_INVALID_LOGON_HOURS"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_ACCOUNT_EXPIRED"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_ACCOUNT_DISABLED"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_ACCOUNT_LOCKED_OUT"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_NO_LOGON_SERVERS"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_PASSWORD_EXPIRED"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_PASSWORD_MUST_CHANGE"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_INVALID_WORKSTATION"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_INVALID_LOGON_HOURS"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCOUNT_EXPIRED"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCOUNT_DISABLED"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCOUNT_LOCKED_OUT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NO_LOGON_SERVERS"); } /* handle the case where the auth was ok, but the password must expire right now */ @@ -942,24 +946,24 @@ static int winbind_auth_request(pam_handle_t * pamh, response.data.auth.info3.pass_last_set_time + response.data.auth.policy.expire, time(NULL)); - PAM_WB_REMARK_DIRECT_RET(pamh, "NT_STATUS_PASSWORD_EXPIRED"); + PAM_WB_REMARK_DIRECT_RET(pamh, ctrl, "NT_STATUS_PASSWORD_EXPIRED"); } /* warn a user if the password is about to expire soon */ - _pam_warn_password_expires_in_future(pamh, &response); + _pam_warn_password_expires_in_future(pamh, ctrl, &response); /* inform about logon type */ if (PAM_WB_GRACE_LOGON(response.data.auth.info3.user_flgs)) { - _make_remark(pamh, PAM_ERROR_MSG, + _make_remark(pamh, ctrl, PAM_ERROR_MSG, "Grace login. Please change your password as soon you're online again"); _pam_log_debug(pamh, ctrl, LOG_DEBUG, "User %s logged on using grace logon\n", user); } else if (PAM_WB_CACHED_LOGON(response.data.auth.info3.user_flgs)) { - _make_remark(pamh, PAM_ERROR_MSG, + _make_remark(pamh, ctrl, PAM_ERROR_MSG, "Logging on using cached account. Network resources can be unavailable"); _pam_log_debug(pamh, ctrl, LOG_DEBUG, "User %s logged on using cached account\n", user); @@ -1055,19 +1059,19 @@ static int winbind_chauthtok_request(pam_handle_t * pamh, return ret; } - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_BACKUP_CONTROLLER"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_NO_LOGON_SERVERS"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_ACCESS_DENIED"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_BACKUP_CONTROLLER"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NO_LOGON_SERVERS"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCESS_DENIED"); /* TODO: tell the min pwd length ? */ - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_PWD_TOO_SHORT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_PWD_TOO_SHORT"); /* TODO: tell the minage ? */ - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_PWD_TOO_RECENT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_PWD_TOO_RECENT"); /* TODO: tell the history length ? */ - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, response, "NT_STATUS_PWD_HISTORY_CONFLICT"); + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_PWD_HISTORY_CONFLICT"); if (!strcasecmp(response.data.auth.nt_status_string, "NT_STATUS_PASSWORD_RESTRICTION")) { @@ -1080,17 +1084,17 @@ static int winbind_chauthtok_request(pam_handle_t * pamh, case REJECT_REASON_OTHER: if ((response.data.auth.policy.min_passwordage > 0) && (pwd_last_set + response.data.auth.policy.min_passwordage > time(NULL))) { - PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_RECENT"); + PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_TOO_RECENT"); } break; case REJECT_REASON_TOO_SHORT: - PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_SHORT"); + PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_TOO_SHORT"); break; case REJECT_REASON_IN_HISTORY: - PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_HISTORY_CONFLICT"); + PAM_WB_REMARK_DIRECT(pamh, ctrl, "NT_STATUS_PWD_HISTORY_CONFLICT"); break; case REJECT_REASON_NOT_COMPLEX: - _make_remark(pamh, PAM_ERROR_MSG, "Password does not meet complexity requirements"); + _make_remark(pamh, ctrl, PAM_ERROR_MSG, "Password does not meet complexity requirements"); break; default: _pam_log_debug(pamh, ctrl, LOG_DEBUG, @@ -1101,7 +1105,7 @@ static int winbind_chauthtok_request(pam_handle_t * pamh, pwd_restriction_string = _pam_compose_pwd_restriction_string(&response); if (pwd_restriction_string) { - _make_remark(pamh, PAM_ERROR_MSG, pwd_restriction_string); + _make_remark(pamh, ctrl, PAM_ERROR_MSG, pwd_restriction_string); SAFE_FREE(pwd_restriction_string); } } @@ -1226,7 +1230,7 @@ static int _winbind_read_password(pam_handle_t * pamh, /* prepare to converse */ - if (comment != NULL) { + if (comment != NULL && off(ctrl, WINBIND_SILENT)) { pmsg[0] = &msg[0]; msg[0].msg_style = PAM_TEXT_INFO; msg[0].msg = CONST_DISCARD(char *, comment); @@ -1264,7 +1268,7 @@ static int _winbind_read_password(pam_handle_t * pamh, || strcmp(token, resp[i - 1].resp)) { _pam_delete(token); /* mistyped */ retval = PAM_AUTHTOK_RECOVER_ERR; - _make_remark(pamh, PAM_ERROR_MSG, MISTYPED_PASS); + _make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS); } } } else { @@ -1829,13 +1833,13 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, iniparser_freedict(d); } /* Deal with offline errors. */ - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NO_LOGON_SERVERS"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCESS_DENIED"); return ret; @@ -1936,13 +1940,13 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, iniparser_freedict(d); } /* Deal with offline errors. */ - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_NO_LOGON_SERVERS"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND"); - PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, + PAM_WB_REMARK_CHECK_RESPONSE_RET(pamh, ctrl, response, "NT_STATUS_ACCESS_DENIED"); return ret; diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 91f662d5d0..d2bf7da9e3 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -110,44 +110,44 @@ do { \ #include "winbind_client.h" -#define PAM_WB_REMARK_DIRECT(h,x)\ +#define PAM_WB_REMARK_DIRECT(h,f,x)\ {\ const char *error_string = NULL; \ error_string = _get_ntstatus_error_string(x);\ if (error_string != NULL) {\ - _make_remark(h, PAM_ERROR_MSG, error_string);\ + _make_remark(h, f, PAM_ERROR_MSG, error_string);\ } else {\ - _make_remark(h, PAM_ERROR_MSG, x);\ + _make_remark(h, f, PAM_ERROR_MSG, x);\ };\ }; -#define PAM_WB_REMARK_DIRECT_RET(h,x)\ +#define PAM_WB_REMARK_DIRECT_RET(h,f,x)\ {\ const char *error_string = NULL; \ error_string = _get_ntstatus_error_string(x);\ if (error_string != NULL) {\ - _make_remark(h, PAM_ERROR_MSG, error_string);\ + _make_remark(h, f, PAM_ERROR_MSG, error_string);\ return ret;\ };\ - _make_remark(h, PAM_ERROR_MSG, x);\ + _make_remark(h, f, PAM_ERROR_MSG, x);\ return ret;\ }; -#define PAM_WB_REMARK_CHECK_RESPONSE_RET(h,x,y)\ +#define PAM_WB_REMARK_CHECK_RESPONSE_RET(h,f,x,y)\ {\ const char *ntstatus = x.data.auth.nt_status_string; \ const char *error_string = NULL; \ if (!strcasecmp(ntstatus,y)) {\ error_string = _get_ntstatus_error_string(y);\ if (error_string != NULL) {\ - _make_remark(h, PAM_ERROR_MSG, error_string);\ + _make_remark(h, f, PAM_ERROR_MSG, error_string);\ return ret;\ };\ if (x.data.auth.error_string[0] != '\0') {\ - _make_remark(h, PAM_ERROR_MSG, x.data.auth.error_string);\ + _make_remark(h, f, PAM_ERROR_MSG, x.data.auth.error_string);\ return ret;\ };\ - _make_remark(h, PAM_ERROR_MSG, y);\ + _make_remark(h, f, PAM_ERROR_MSG, y);\ return ret;\ };\ }; -- cgit