Skip to content

Commit ac2476d

Browse files
sumit-bosealexey-tikhonov
authored andcommitted
krb5: check for PIN locked in error message
Currently the PIN locked message is only displays if the Smartcard authentication is done locally, e.g. if the system is offline. During pkinit libkrb5 does not send a dedicated error code but the error message generated by the library contains a hint. This patch checks the libkrb5 error message in case the authentication fails with the pre-authentication failed error code. This is a bit tricky because 'krb5_get_error_message()' currently only returns a defined result at the first call after a failed library call. Reviewed-by: Alexey Tikhonov <atikhono@redhat.com> Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com> (cherry picked from commit bc3ad16)
1 parent 76c97d5 commit ac2476d

File tree

1 file changed

+60
-5
lines changed

1 file changed

+60
-5
lines changed

src/providers/krb5/krb5_child.c

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,47 @@ struct krb5_req {
125125

126126
static krb5_context krb5_error_ctx;
127127

128+
static inline void debug_and_log(int level, int line,
129+
krb5_error_code krb5_error,
130+
const char *krb5_error_msg)
131+
{
132+
DEBUG(level, "%d: [%d][%s]\n", line, krb5_error, krb5_error_msg);
133+
if (level & (SSSDBG_CRIT_FAILURE | SSSDBG_FATAL_FAILURE)) {
134+
sss_log(SSS_LOG_ERR, "%s", krb5_error_msg);
135+
}
136+
137+
return;
138+
}
139+
128140
#define KRB5_CHILD_DEBUG_INT(level, errctx, krb5_error) do { \
129141
const char *__krb5_error_msg; \
130142
__krb5_error_msg = sss_krb5_get_error_message(errctx, krb5_error); \
131-
DEBUG(level, "%d: [%d][%s]\n", __LINE__, krb5_error, __krb5_error_msg); \
132-
if (level & (SSSDBG_CRIT_FAILURE | SSSDBG_FATAL_FAILURE)) { \
133-
sss_log(SSS_LOG_ERR, "%s", __krb5_error_msg); \
134-
} \
143+
debug_and_log(level, __LINE__, krb5_error, __krb5_error_msg); \
135144
sss_krb5_free_error_message(errctx, __krb5_error_msg); \
136145
} while(0)
137146

138147
#define KRB5_CHILD_DEBUG(level, error) KRB5_CHILD_DEBUG_INT(level, krb5_error_ctx, error)
139148

149+
static bool debug_and_check_if_pin_locked_error(krb5_context ctx, int level,
150+
krb5_error_code krb5_error)
151+
{
152+
const char *krb5_error_msg;
153+
bool res = false;
154+
155+
/* sss_krb5_free_error_message() never returns NULL */
156+
krb5_error_msg = sss_krb5_get_error_message(ctx, krb5_error);
157+
158+
if (strstr(krb5_error_msg, "pin locked") != NULL) {
159+
res = true;
160+
}
161+
162+
debug_and_log(level, __LINE__, krb5_error, krb5_error_msg);
163+
164+
sss_krb5_free_error_message(ctx, krb5_error_msg);
165+
166+
return res;
167+
}
168+
140169
static krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname,
141170
krb5_principal server_principal,
142171
krb5_principal client_principal,
@@ -2418,6 +2447,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24182447
char *cc_name;
24192448
int ret;
24202449
char *identity = NULL;
2450+
const uint32_t user_info_pin_locked = SSS_PAM_USER_INFO_PIN_LOCKED;
24212451

24222452
kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options,
24232453
sss_krb5_expire_callback_func,
@@ -2483,7 +2513,32 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24832513
return 0;
24842514
} else {
24852515
if (kerr != 0) {
2486-
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2516+
/* If
2517+
* - during authentication
2518+
* - the pre-authentication failed
2519+
* - while Smartcard authentication was possible
2520+
* - and Smartcard credentials were available
2521+
* check if the PIN might be locked.
2522+
* Must be called before/instead of KRB5_CHILD_DEBUG because
2523+
* krb5_get_error_message() might only return the proper error
2524+
* message at the first call. */
2525+
if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
2526+
&& kerr == KRB5_PREAUTH_FAILED
2527+
&& kr->pkinit_prompting == true
2528+
&& IS_SC_AUTHTOK(kr->pd->authtok) ) {
2529+
if (debug_and_check_if_pin_locked_error(kr->ctx,
2530+
SSSDBG_CRIT_FAILURE, kerr) ) {
2531+
ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO,
2532+
sizeof(uint32_t),
2533+
(const uint8_t *) &user_info_pin_locked);
2534+
if (ret != EOK) {
2535+
DEBUG(SSSDBG_OP_FAILURE,
2536+
"Failed to add PIN locked message.\n");
2537+
}
2538+
}
2539+
} else {
2540+
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2541+
}
24872542

24882543
if (kerr == EAGAIN) {
24892544
/* The most probable reason for krb5_get_init_creds_password()

0 commit comments

Comments
 (0)