summaryrefslogtreecommitdiffstats
path: root/daemons/ipa-kdb
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 2ed093d30..7e6e71d5b 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -900,8 +900,8 @@ done:
return kerr;
}
-static krb5_error_code filter_pac(krb5_context context, krb5_data *old_data,
- krb5_data *new_data)
+static krb5_error_code add_local_groups(krb5_context context,
+ krb5_data *pac_blob)
{
DATA_BLOB pac_data;
union PAC_INFO pac_info;
@@ -918,8 +918,8 @@ static krb5_error_code filter_pac(krb5_context context, krb5_data *old_data,
return ENOMEM;
}
- pac_data.length = old_data->length;
- pac_data.data = (uint8_t *) old_data->data;
+ pac_data.length = pac_blob->length;
+ pac_data.data = (uint8_t *)pac_blob->data;
ndr_err = ndr_pull_union_blob(&pac_data, tmpctx, &pac_info,
PAC_TYPE_LOGON_INFO,
@@ -962,14 +962,15 @@ static krb5_error_code filter_pac(krb5_context context, krb5_data *old_data,
goto done;
}
- new_data->magic = KV5M_DATA;
- new_data->data = malloc(pac_data.length);
- if (new_data->data == NULL) {
+ free(pac_blob->data);
+ pac_blob->data = malloc(pac_data.length);
+ if (pac_blob->data == NULL) {
+ pac_blob->length = 0;
kerr = ENOMEM;
goto done;
}
- memcpy(new_data->data, pac_data.data, pac_data.length);
- new_data->length = pac_data.length;
+ memcpy(pac_blob->data, pac_data.data, pac_data.length);
+ pac_blob->length = pac_data.length;
kerr = 0;
@@ -993,12 +994,13 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
krb5_keyblock *srv_key = NULL;
krb5_keyblock *priv_key = NULL;
krb5_error_code kerr;
- krb5_ui_4 *buffer_types = NULL;
+ krb5_ui_4 *types = NULL;
size_t num_buffers;
krb5_pac old_pac = NULL;
krb5_pac new_pac = NULL;
krb5_data data;
- krb5_data filtered_data;
+ krb5_data pac_blob = { 0 , 0, NULL};
+ bool is_cross_realm = false;
size_t i;
kerr = krb5_pac_parse(context,
@@ -1009,7 +1011,6 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
goto done;
}
- memset(&filtered_data, 0, sizeof(filtered_data));
/* for cross realm trusts cases we need to check the right checksum.
* when the PAC is signed by our realm, we can always just check it
* passing our realm krbtgt key as the kdc checksum key (privsvr).
@@ -1018,6 +1019,7 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
* realm krbtgt to check the 'server' checksum instead. */
if (is_cross_realm_krbtgt(krbtgt->princ)) {
/* krbtgt from a trusted realm */
+ is_cross_realm = true;
/* FIXME:
* We must refuse a PAC that comes signed with a cross realm TGT
@@ -1028,15 +1030,6 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
/* TODO: Here is where we need to plug our PAC Filtering, later on */
srv_key = krbtgt_key;
- kerr = krb5_pac_get_buffer(context, old_pac, KRB5_PAC_LOGON_INFO, &data);
- if (kerr != 0) {
- goto done;
- }
-
- kerr = filter_pac(context, &data, &filtered_data);
- if (kerr != 0) {
- goto done;
- }
} else {
/* krbtgt from our own realm */
priv_key = krbtgt_key;
@@ -1048,6 +1041,20 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
goto done;
}
+ /* Now that the PAc is verified augment it with additional info if
+ * it is coming from a different realm */
+ if (is_cross_realm) {
+ kerr = krb5_pac_get_buffer(context, old_pac,
+ KRB5_PAC_LOGON_INFO, &pac_blob);
+ if (kerr != 0) {
+ goto done;
+ }
+
+ kerr = add_local_groups(context, &pac_blob);
+ if (kerr != 0) {
+ goto done;
+ }
+ }
/* extract buffers and rebuilt pac from scratch so that when re-signing
* with a different cksum type does not cause issues due to mismatching
* signature buffer lengths */
@@ -1056,22 +1063,20 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
goto done;
}
- kerr = krb5_pac_get_types(context, old_pac, &num_buffers, &buffer_types);
+ kerr = krb5_pac_get_types(context, old_pac, &num_buffers, &types);
if (kerr) {
goto done;
}
for (i = 0; i < num_buffers; i++) {
- if (buffer_types[i] == KRB5_PAC_SERVER_CHECKSUM ||
- buffer_types[i] == KRB5_PAC_PRIVSVR_CHECKSUM) {
+ if (types[i] == KRB5_PAC_SERVER_CHECKSUM ||
+ types[i] == KRB5_PAC_PRIVSVR_CHECKSUM) {
continue;
}
- if (buffer_types[i] == KRB5_PAC_LOGON_INFO &&
- filtered_data.length != 0) {
- kerr = krb5_pac_add_buffer(context, new_pac,
- buffer_types[i], &filtered_data);
- krb5_free_data_contents(context, &filtered_data);
+ if (types[i] == KRB5_PAC_LOGON_INFO &&
+ pac_blob.length != 0) {
+ kerr = krb5_pac_add_buffer(context, new_pac, types[i], &pac_blob);
if (kerr) {
krb5_pac_free(context, new_pac);
goto done;
@@ -1080,13 +1085,11 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
continue;
}
- kerr = krb5_pac_get_buffer(context, old_pac,
- buffer_types[i], &data);
+ kerr = krb5_pac_get_buffer(context, old_pac, types[i], &data);
if (kerr == 0) {
- kerr = krb5_pac_add_buffer(context, new_pac,
- buffer_types[i], &data);
+ kerr = krb5_pac_add_buffer(context, new_pac, types[i], &data);
+ krb5_free_data_contents(context, &data);
}
- krb5_free_data_contents(context, &data);
if (kerr) {
krb5_pac_free(context, new_pac);
goto done;
@@ -1098,7 +1101,8 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
done:
krb5_free_authdata(context, authdata);
krb5_pac_free(context, old_pac);
- free(buffer_types);
+ krb5_free_data_contents(context, &pac_blob);
+ free(types);
return kerr;
}