mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
r21152: Correctly omit pam conversations when PAM_SILENT has been set by the
calling application.
Guenther
(This used to be commit ebfae9a671
)
This commit is contained in:
parent
a252038187
commit
44512030b1
@ -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;
|
||||
|
@ -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;\
|
||||
};\
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user