kadmin: LIST interrupt message needs no reply

The online LIST interrupt message is a NOP, but it's expected to not
have a reply (the server doesn't send one if it receives it before the
LIST finishes).

However, if the interrupt message arrives after the LIST finished, then
it does get a reply, and this causes the client to get out of step with
the server.

Fixes include:

1) flavor the interrupt NOP to make sure it never gets a reply,
2) introduce a new kadm_list_interrtupt message that is like a NOP that
   produces no reply
3) always consume -after the LIST ends- a reply to any list interrupt
   NOP on the client side.

This implements (1).
This commit is contained in:
Nicolas Williams
2022-03-22 17:00:23 -05:00
parent f037a0a57f
commit 6b45c3512e
2 changed files with 21 additions and 3 deletions

View File

@@ -238,6 +238,15 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
* interrupt a long-running LIST operation.
*/
op = "NOP";
ret = krb5_ret_int32(sp, &tmp);
if (ret == 0 && tmp == 0) {
/*
* Reply not wanted. This would be a LIST interrupt request.
*/
krb5_storage_free(rsp);
krb5_storage_free(sp);
return 0;
}
ret_sp = krb5_store_int32(rsp, ret = 0);
break;
}
@@ -1027,7 +1036,8 @@ v5_loop (krb5_context contextp,
if (ret)
krb5_err(contextp, 1, ret, "kadmind_dispatch");
krb5_data_free(&in);
ret = krb5_write_priv_message(contextp, ac, &fd, &out);
if (out.length)
ret = krb5_write_priv_message(contextp, ac, &fd, &out);
krb5_data_free(&out);
if(ret)
krb5_err(contextp, 1, ret, "krb5_write_priv_message");

View File

@@ -232,10 +232,18 @@ kadm5_c_iter_principals(void *server_handle,
if (!stop) {
stop = cb(cbdata, princ);
if (stop) {
/* Tell the server to stop */
/*
* Tell the server to stop.
*
* We use a NOP for this, but with a payload that says
* "don't reply to the NOP" just in case the NOP
* arrives and is processed _after_ the LISTing has
* finished.
*/
krb5_storage_free(sp);
if ((sp = krb5_storage_emem()) &&
krb5_store_int32(sp, kadm_nop) == 0)
krb5_store_int32(sp, kadm_nop) == 0 &&
krb5_store_int32(sp, 0))
(void) _kadm5_client_send(context, sp);
}
}