Commit
7196c03f18f14695abeb5ae4923004469b172f0f (ticket 8823) gave the
KDB the ability to modify auth indicators, but it happens after the
asserted indicators are checked against the server principal
requirements. In finish_process_as_req(), move the call to
check_indicators() after the call to handle_authdata() so that the
final indicator list is checked.
For the test case, add string attribute functionality to the test KDB
module, and fix a bug where test_get_principal() would return failure
if a principal has no keys. Also add a test case for AS-REQ
enforcement of normally asserted auth indicators.
ticket: 8876 (new)
tags: pullup
target_version: 1.18-next
au_state->stage = ENCR_REP;
- errcode = check_indicators(kdc_context, state->server,
- state->auth_indicators);
- if (errcode) {
- state->status = "HIGHER_AUTHENTICATION_REQUIRED";
- goto egress;
- }
-
state->ticket_reply.enc_part2 = &state->enc_tkt_reply;
errcode = check_kdcpolicy_as(kdc_context, state->request, state->client,
goto egress;
}
+ errcode = check_indicators(kdc_context, state->server,
+ state->auth_indicators);
+ if (errcode) {
+ state->status = "HIGHER_AUTHENTICATION_REQUIRED";
+ goto egress;
+ }
+
errcode = krb5_encrypt_tkt_part(kdc_context, &state->server_keyblock,
&state->ticket_reply);
if (errcode)
* # Initial number is kvno; defaults to 1.
* keys = 3 aes256-cts aes128-cts:normal
* keys = 2 rc4-hmac
+ * strings = key1:value1
+ * strings = key2:value2
* }
* }
* delegation = {
ent->n_key_data = nkeys;
}
+static void
+make_strings(char **stringattrs, krb5_db_entry *ent)
+{
+ struct k5buf buf;
+ char **p;
+ const char *str, *sep;
+ krb5_tl_data *tl;
+
+ k5_buf_init_dynamic(&buf);
+ for (p = stringattrs; *p != NULL; p++) {
+ str = *p;
+ sep = strchr(str, ':');
+ assert(sep != NULL);
+ k5_buf_add_len(&buf, str, sep - str);
+ k5_buf_add_len(&buf, "\0", 1);
+ k5_buf_add_len(&buf, sep + 1, strlen(sep + 1) + 1);
+ }
+ assert(buf.data != NULL);
+
+ tl = ealloc(sizeof(*ent->tl_data));
+ tl->tl_data_next = NULL;
+ tl->tl_data_type = KRB5_TL_STRING_ATTRS;
+ tl->tl_data_length = buf.len;
+ tl->tl_data_contents = buf.data;
+ ent->tl_data = tl;
+}
+
static krb5_error_code
test_init()
{
krb5_principal princ = NULL, tgtprinc;
krb5_principal_data empty_princ = { KV5M_PRINCIPAL };
testhandle h = context->dal_handle->db_context;
- char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings;
+ char *search_name = NULL, *canon = NULL, *flagstr;
+ char **names, **key_strings, **stringattrs;
const char *ename;
krb5_db_entry *ent;
ent->pw_expiration = get_time(h, "princs", ename, "pwexpiration");
/* Leave last_success, last_failed, fail_auth_count zeroed. */
- /* Leave tl_data and e_data empty. */
+ /* Leave e_data empty. */
set_names(h, "princs", ename, "keys");
ret = profile_get_values(h->profile, h->names, &key_strings);
profile_free_list(key_strings);
}
+ set_names(h, "princs", ename, "strings");
+ ret = profile_get_values(h->profile, h->names, &stringattrs);
+ if (ret != PROF_NO_RELATION) {
+ make_strings(stringattrs, ent);
+ profile_free_list(stringattrs);
+ }
+
/* We must include mod-princ data or kadm5_get_principal() won't work and
* we can't extract keys with kadmin.local. */
check(krb5_dbe_update_mod_princ_data(context, ent, 0, &empty_princ));
*entry = ent;
+ ret = 0;
cleanup:
krb5_free_unparsed_name(context, search_name);
mark('auth indicator enforcement')
realm.addprinc('restricted')
realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong'])
+realm.kinit(realm.user_princ, password('user'), ['-S', 'restricted'],
+ expected_code=1, expected_msg='KDC policy rejects request')
realm.run([kvno, 'restricted'], expected_code=1,
expected_msg='KDC policy rejects request')
realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'indcl'])
'krbtgt/FOREIGN': {'keys': 'aes128-cts'},
'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
'user2': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'rservice': {'keys': 'aes128-cts',
+ 'strings': 'require_auth:strong'},
'service/1': {'keys': 'aes128-cts',
'flags': '+ok_to_auth_as_delegate'},
'service/2': {'keys': 'aes128-cts'},
realm.extract_keytab(realm.krbtgt_princ, realm.keytab)
realm.extract_keytab('krbtgt/FOREIGN', realm.keytab)
realm.extract_keytab(realm.user_princ, realm.keytab)
+realm.extract_keytab('ruser', realm.keytab)
realm.extract_keytab('service/1', realm.keytab)
realm.extract_keytab('service/2', realm.keytab)
realm.extract_keytab('noauthdata', realm.keytab)
realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=dummy dbincr1'])
realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [dbincr2]')
realm.run(['./adata', 'service/1'], expected_msg='+97: [dbincr3]')
+realm.kinit(realm.user_princ, None,
+ ['-k', '-X', 'indicators=strong', '-S', 'rservice'])
+# Test enforcement of altered indicators during AS request.
+realm.kinit(realm.user_princ, None,
+ ['-k', '-X', 'indicators=strong dbincr1', '-S', 'rservice'],
+ expected_code=1)
# Test that KDB module authdata is included in an AS request, by
# default or with an explicit PAC request.