605 lines
19 KiB
Diff
605 lines
19 KiB
Diff
From 30fb296a38a72fd91161c4f48be3a0472479f2ff Mon Sep 17 00:00:00 2001
|
|
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
|
Date: Tue, 26 Oct 2021 20:41:31 +1300
|
|
Subject: [PATCH] CVE-2020-25719 s4:kdc: Add KDC support for
|
|
PAC_ATTRIBUTES_INFO PAC buffer
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
|
|
|
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
Conflict: remove selftest/knownfail_heimdal_kdc
|
|
source4/heimdal/kdc/kerberos5.c
|
|
source4/heimdal/kdc/krb5tgs.c
|
|
---
|
|
source4/heimdal/kdc/kerberos5.c | 23 +++--
|
|
source4/heimdal/kdc/krb5tgs.c | 2 +-
|
|
source4/heimdal/kdc/windc.c | 7 +-
|
|
source4/heimdal/kdc/windc_plugin.h | 2 +
|
|
source4/kdc/mit_samba.c | 7 +-
|
|
source4/kdc/pac-glue.c | 147 ++++++++++++++++++++++++++++-
|
|
source4/kdc/pac-glue.h | 10 +-
|
|
source4/kdc/wdc-samba4.c | 45 ++++++++-
|
|
8 files changed, 223 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
|
|
index 27d38ad..cb34c8f 100644
|
|
--- a/source4/heimdal/kdc/kerberos5.c
|
|
+++ b/source4/heimdal/kdc/kerberos5.c
|
|
@@ -913,27 +913,30 @@ _kdc_check_addresses(krb5_context context,
|
|
*/
|
|
|
|
static krb5_boolean
|
|
-send_pac_p(krb5_context context, KDC_REQ *req)
|
|
+send_pac_p(krb5_context context, KDC_REQ *req, krb5_boolean *pac_request)
|
|
{
|
|
krb5_error_code ret;
|
|
PA_PAC_REQUEST pacreq;
|
|
const PA_DATA *pa;
|
|
int i = 0;
|
|
|
|
+ *pac_request = TRUE;
|
|
+
|
|
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
|
|
if (pa == NULL)
|
|
- return TRUE;
|
|
+ return FALSE;
|
|
|
|
ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
|
|
pa->padata_value.length,
|
|
&pacreq,
|
|
NULL);
|
|
if (ret)
|
|
- return TRUE;
|
|
+ return FALSE;
|
|
i = pacreq.include_pac;
|
|
free_PA_PAC_REQUEST(&pacreq);
|
|
- if (i == 0)
|
|
- return FALSE;
|
|
+ if (i == 0) {
|
|
+ *pac_request = FALSE;
|
|
+ }
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -1709,11 +1712,17 @@ _kdc_as_rep(krb5_context context,
|
|
}
|
|
|
|
/* Add the PAC */
|
|
- if (send_pac_p(context, req)) {
|
|
+ {
|
|
krb5_pac p = NULL;
|
|
krb5_data data;
|
|
+ krb5_boolean sent_pac_request;
|
|
+ krb5_boolean pac_request;
|
|
+
|
|
+ sent_pac_request = send_pac_p(context, req, &pac_request);
|
|
|
|
- ret = _kdc_pac_generate(context, client, pk_reply_key, &p);
|
|
+ ret = _kdc_pac_generate(context, client, pk_reply_key,
|
|
+ sent_pac_request ? &pac_request : NULL,
|
|
+ &p);
|
|
if (ret) {
|
|
kdc_log(context, config, 0, "PAC generation failed for -- %s",
|
|
client_name);
|
|
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
|
|
index 701c04c..56b4ebe 100644
|
|
--- a/source4/heimdal/kdc/krb5tgs.c
|
|
+++ b/source4/heimdal/kdc/krb5tgs.c
|
|
@@ -2015,7 +2015,7 @@ server_lookup:
|
|
if(rspac.data) {
|
|
krb5_pac p = NULL;
|
|
krb5_data_free(&rspac);
|
|
- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p);
|
|
+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, NULL, &p);
|
|
if (ret) {
|
|
kdc_log(context, config, 0, "PAC generation failed for -- %s",
|
|
tpn);
|
|
diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c
|
|
index fb1c8a6..01b5b88 100644
|
|
--- a/source4/heimdal/kdc/windc.c
|
|
+++ b/source4/heimdal/kdc/windc.c
|
|
@@ -74,6 +74,7 @@ krb5_error_code
|
|
_kdc_pac_generate(krb5_context context,
|
|
hdb_entry_ex *client,
|
|
const krb5_keyblock *pk_reply_key,
|
|
+ const krb5_boolean *pac_request,
|
|
krb5_pac *pac)
|
|
{
|
|
*pac = NULL;
|
|
@@ -81,8 +82,10 @@ _kdc_pac_generate(krb5_context context,
|
|
return 0;
|
|
if (windcft->pac_pk_generate != NULL && pk_reply_key != NULL)
|
|
return (windcft->pac_pk_generate)(windcctx, context,
|
|
- client, pk_reply_key, pac);
|
|
- return (windcft->pac_generate)(windcctx, context, client, pac);
|
|
+ client, pk_reply_key,
|
|
+ pac_request, pac);
|
|
+ return (windcft->pac_generate)(windcctx, context, client,
|
|
+ pac_request, pac);
|
|
}
|
|
|
|
krb5_error_code
|
|
diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h
|
|
index bf90826..8c83f1d 100644
|
|
--- a/source4/heimdal/kdc/windc_plugin.h
|
|
+++ b/source4/heimdal/kdc/windc_plugin.h
|
|
@@ -54,12 +54,14 @@ struct hdb_entry_ex;
|
|
typedef krb5_error_code
|
|
(*krb5plugin_windc_pac_generate)(void *, krb5_context,
|
|
struct hdb_entry_ex *, /* client */
|
|
+ const krb5_boolean *, /* pac_request */
|
|
krb5_pac *);
|
|
|
|
typedef krb5_error_code
|
|
(*krb5plugin_windc_pac_pk_generate)(void *, krb5_context,
|
|
struct hdb_entry_ex *, /* client */
|
|
const krb5_keyblock *, /* pk_replykey */
|
|
+ const krb5_boolean *, /* pac_request */
|
|
krb5_pac *);
|
|
|
|
typedef krb5_error_code
|
|
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
|
|
index 710b23c..f63d80e 100644
|
|
--- a/source4/kdc/mit_samba.c
|
|
+++ b/source4/kdc/mit_samba.c
|
|
@@ -439,7 +439,8 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
|
|
skdc_entry,
|
|
&logon_info_blob,
|
|
cred_ndr_ptr,
|
|
- &upn_dns_info_blob);
|
|
+ &upn_dns_info_blob,
|
|
+ NULL, NULL);
|
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
|
talloc_free(tmp_ctx);
|
|
return EINVAL;
|
|
@@ -463,6 +464,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
|
|
pcred_blob,
|
|
upn_dns_info_blob,
|
|
NULL,
|
|
+ NULL,
|
|
pac);
|
|
|
|
talloc_free(tmp_ctx);
|
|
@@ -547,7 +549,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
|
|
client_skdc_entry,
|
|
&pac_blob,
|
|
NULL,
|
|
- &upn_blob);
|
|
+ &upn_blob,
|
|
+ NULL, NULL);
|
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
|
code = EINVAL;
|
|
goto done;
|
|
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
|
|
index c7faab9..75bb3a5 100644
|
|
--- a/source4/kdc/pac-glue.c
|
|
+++ b/source4/kdc/pac-glue.c
|
|
@@ -121,6 +121,43 @@ NTSTATUS samba_get_upn_info_pac_blob(TALLOC_CTX *mem_ctx,
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
+static
|
|
+NTSTATUS samba_get_pac_attrs_blob(TALLOC_CTX *mem_ctx,
|
|
+ const krb5_boolean *pac_request,
|
|
+ DATA_BLOB *pac_attrs_data)
|
|
+{
|
|
+ union PAC_INFO pac_attrs;
|
|
+ enum ndr_err_code ndr_err;
|
|
+ NTSTATUS nt_status;
|
|
+
|
|
+ ZERO_STRUCT(pac_attrs);
|
|
+
|
|
+ *pac_attrs_data = data_blob_null;
|
|
+
|
|
+ /* Set the length of the flags in bits. */
|
|
+ pac_attrs.attributes_info.flags_length = 2;
|
|
+
|
|
+ if (pac_request == NULL) {
|
|
+ pac_attrs.attributes_info.flags
|
|
+ |= PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY;
|
|
+ } else if (*pac_request) {
|
|
+ pac_attrs.attributes_info.flags
|
|
+ |= PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED;
|
|
+ }
|
|
+
|
|
+ ndr_err = ndr_push_union_blob(pac_attrs_data, mem_ctx, &pac_attrs,
|
|
+ PAC_TYPE_ATTRIBUTES_INFO,
|
|
+ (ndr_push_flags_fn_t)ndr_push_PAC_INFO);
|
|
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
|
+ nt_status = ndr_map_error2ntstatus(ndr_err);
|
|
+ DEBUG(1, ("PAC ATTRIBUTES_INFO (presig) push failed: %s\n",
|
|
+ nt_errstr(nt_status)));
|
|
+ return nt_status;
|
|
+ }
|
|
+
|
|
+ return NT_STATUS_OK;
|
|
+}
|
|
+
|
|
static
|
|
NTSTATUS samba_get_cred_info_ndr_blob(TALLOC_CTX *mem_ctx,
|
|
const struct ldb_message *msg,
|
|
@@ -421,12 +458,14 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
const DATA_BLOB *logon_blob,
|
|
const DATA_BLOB *cred_blob,
|
|
const DATA_BLOB *upn_blob,
|
|
+ const DATA_BLOB *pac_attrs_blob,
|
|
const DATA_BLOB *deleg_blob,
|
|
krb5_pac *pac)
|
|
{
|
|
krb5_data logon_data;
|
|
krb5_data cred_data;
|
|
krb5_data upn_data;
|
|
+ krb5_data pac_attrs_data;
|
|
krb5_data deleg_data;
|
|
krb5_error_code ret;
|
|
#ifdef SAMBA4_USES_HEIMDAL
|
|
@@ -471,6 +510,19 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
}
|
|
}
|
|
|
|
+ ZERO_STRUCT(pac_attrs_data);
|
|
+ if (pac_attrs_blob != NULL) {
|
|
+ ret = smb_krb5_copy_data_contents(&pac_attrs_data,
|
|
+ pac_attrs_blob->data,
|
|
+ pac_attrs_blob->length);
|
|
+ if (ret != 0) {
|
|
+ smb_krb5_free_data_contents(context, &logon_data);
|
|
+ smb_krb5_free_data_contents(context, &cred_data);
|
|
+ smb_krb5_free_data_contents(context, &upn_data);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
ZERO_STRUCT(deleg_data);
|
|
if (deleg_blob != NULL) {
|
|
ret = smb_krb5_copy_data_contents(&deleg_data,
|
|
@@ -480,6 +532,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
smb_krb5_free_data_contents(context, &logon_data);
|
|
smb_krb5_free_data_contents(context, &cred_data);
|
|
smb_krb5_free_data_contents(context, &upn_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -489,6 +542,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
smb_krb5_free_data_contents(context, &logon_data);
|
|
smb_krb5_free_data_contents(context, &cred_data);
|
|
smb_krb5_free_data_contents(context, &upn_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
smb_krb5_free_data_contents(context, &deleg_data);
|
|
return ret;
|
|
}
|
|
@@ -496,8 +550,9 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
ret = krb5_pac_add_buffer(context, *pac, PAC_TYPE_LOGON_INFO, &logon_data);
|
|
smb_krb5_free_data_contents(context, &logon_data);
|
|
if (ret != 0) {
|
|
- smb_krb5_free_data_contents(context, &upn_data);
|
|
smb_krb5_free_data_contents(context, &cred_data);
|
|
+ smb_krb5_free_data_contents(context, &upn_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
smb_krb5_free_data_contents(context, &deleg_data);
|
|
return ret;
|
|
}
|
|
@@ -509,6 +564,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
smb_krb5_free_data_contents(context, &cred_data);
|
|
if (ret != 0) {
|
|
smb_krb5_free_data_contents(context, &upn_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
smb_krb5_free_data_contents(context, &deleg_data);
|
|
return ret;
|
|
}
|
|
@@ -527,6 +583,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
&null_data);
|
|
if (ret != 0) {
|
|
smb_krb5_free_data_contents(context, &upn_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
smb_krb5_free_data_contents(context, &deleg_data);
|
|
return ret;
|
|
}
|
|
@@ -537,6 +594,18 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
PAC_TYPE_UPN_DNS_INFO,
|
|
&upn_data);
|
|
smb_krb5_free_data_contents(context, &upn_data);
|
|
+ if (ret != 0) {
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
+ smb_krb5_free_data_contents(context, &deleg_data);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (pac_attrs_blob != NULL) {
|
|
+ ret = krb5_pac_add_buffer(context, *pac,
|
|
+ PAC_TYPE_ATTRIBUTES_INFO,
|
|
+ &pac_attrs_data);
|
|
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
|
|
if (ret != 0) {
|
|
smb_krb5_free_data_contents(context, &deleg_data);
|
|
return ret;
|
|
@@ -570,6 +639,48 @@ bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry)
|
|
return true;
|
|
}
|
|
|
|
+int samba_client_requested_pac(krb5_context context,
|
|
+ krb5_pac *pac,
|
|
+ TALLOC_CTX *mem_ctx,
|
|
+ bool *requested_pac)
|
|
+{
|
|
+ enum ndr_err_code ndr_err;
|
|
+ krb5_data k5pac_attrs_in;
|
|
+ DATA_BLOB pac_attrs_in;
|
|
+ union PAC_INFO pac_attrs;
|
|
+ int ret;
|
|
+
|
|
+ *requested_pac = true;
|
|
+
|
|
+ ret = krb5_pac_get_buffer(context, *pac, PAC_TYPE_ATTRIBUTES_INFO,
|
|
+ &k5pac_attrs_in);
|
|
+ if (ret != 0) {
|
|
+ return ret == ENOENT ? 0 : ret;
|
|
+ }
|
|
+
|
|
+ pac_attrs_in = data_blob_const(k5pac_attrs_in.data,
|
|
+ k5pac_attrs_in.length);
|
|
+
|
|
+ ndr_err = ndr_pull_union_blob(&pac_attrs_in, mem_ctx, &pac_attrs,
|
|
+ PAC_TYPE_ATTRIBUTES_INFO,
|
|
+ (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
|
|
+ smb_krb5_free_data_contents(context, &k5pac_attrs_in);
|
|
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
|
+ NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
|
|
+ DEBUG(0,("can't parse the PAC ATTRIBUTES_INFO: %s\n", nt_errstr(nt_status)));
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ if (pac_attrs.attributes_info.flags & (PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY
|
|
+ | PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED)) {
|
|
+ *requested_pac = true;
|
|
+ } else {
|
|
+ *requested_pac = false;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Was the krbtgt in this DB (ie, should we check the incoming signature) and was it an RODC */
|
|
int samba_krbtgt_is_in_db(struct samba_kdc_entry *p,
|
|
bool *is_in_db,
|
|
@@ -645,12 +756,15 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
|
|
struct samba_kdc_entry *p,
|
|
DATA_BLOB **_logon_info_blob,
|
|
DATA_BLOB **_cred_ndr_blob,
|
|
- DATA_BLOB **_upn_info_blob)
|
|
+ DATA_BLOB **_upn_info_blob,
|
|
+ DATA_BLOB **_pac_attrs_blob,
|
|
+ const krb5_boolean *pac_request)
|
|
{
|
|
struct auth_user_info_dc *user_info_dc;
|
|
DATA_BLOB *logon_blob = NULL;
|
|
DATA_BLOB *cred_blob = NULL;
|
|
DATA_BLOB *upn_blob = NULL;
|
|
+ DATA_BLOB *pac_attrs_blob = NULL;
|
|
NTSTATUS nt_status;
|
|
|
|
*_logon_info_blob = NULL;
|
|
@@ -658,6 +772,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
|
|
*_cred_ndr_blob = NULL;
|
|
}
|
|
*_upn_info_blob = NULL;
|
|
+ if (_pac_attrs_blob != NULL) {
|
|
+ *_pac_attrs_blob = NULL;
|
|
+ }
|
|
|
|
/* The user account may be set not to want the PAC */
|
|
if ( ! samba_princ_needs_pac(p)) {
|
|
@@ -681,6 +798,13 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
|
|
return NT_STATUS_NO_MEMORY;
|
|
}
|
|
|
|
+ if (_pac_attrs_blob != NULL) {
|
|
+ pac_attrs_blob = talloc_zero(mem_ctx, DATA_BLOB);
|
|
+ if (pac_attrs_blob == NULL) {
|
|
+ return NT_STATUS_NO_MEMORY;
|
|
+ }
|
|
+ }
|
|
+
|
|
nt_status = authsam_make_user_info_dc(mem_ctx, p->kdc_db_ctx->samdb,
|
|
lpcfg_netbios_name(p->kdc_db_ctx->lp_ctx),
|
|
lpcfg_sam_name(p->kdc_db_ctx->lp_ctx),
|
|
@@ -725,12 +849,27 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
|
|
return nt_status;
|
|
}
|
|
|
|
+ if (pac_attrs_blob != NULL) {
|
|
+ nt_status = samba_get_pac_attrs_blob(pac_attrs_blob,
|
|
+ pac_request,
|
|
+ pac_attrs_blob);
|
|
+
|
|
+ if (!NT_STATUS_IS_OK(nt_status)) {
|
|
+ DEBUG(0, ("Building PAC ATTRIBUTES failed: %s\n",
|
|
+ nt_errstr(nt_status)));
|
|
+ return nt_status;
|
|
+ }
|
|
+ }
|
|
+
|
|
TALLOC_FREE(user_info_dc);
|
|
*_logon_info_blob = logon_blob;
|
|
if (_cred_ndr_blob != NULL) {
|
|
*_cred_ndr_blob = cred_blob;
|
|
}
|
|
*_upn_info_blob = upn_blob;
|
|
+ if (_pac_attrs_blob != NULL) {
|
|
+ *_pac_attrs_blob = pac_attrs_blob;
|
|
+ }
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
@@ -744,7 +883,9 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
|
|
nt_status = samba_kdc_get_pac_blobs(mem_ctx, p,
|
|
_logon_info_blob,
|
|
NULL, /* cred_blob */
|
|
- &upn_blob);
|
|
+ &upn_blob,
|
|
+ NULL,
|
|
+ NULL);
|
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
|
return nt_status;
|
|
}
|
|
diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h
|
|
index 7b51b03..64ea3d8 100644
|
|
--- a/source4/kdc/pac-glue.h
|
|
+++ b/source4/kdc/pac-glue.h
|
|
@@ -31,11 +31,17 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
|
|
const DATA_BLOB *logon_blob,
|
|
const DATA_BLOB *cred_blob,
|
|
const DATA_BLOB *upn_blob,
|
|
+ const DATA_BLOB *pac_attrs_blob,
|
|
const DATA_BLOB *deleg_blob,
|
|
krb5_pac *pac);
|
|
|
|
bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry);
|
|
|
|
+int samba_client_requested_pac(krb5_context context,
|
|
+ krb5_pac *pac,
|
|
+ TALLOC_CTX *mem_ctx,
|
|
+ bool *requested_pac);
|
|
+
|
|
int samba_krbtgt_is_in_db(struct samba_kdc_entry *skdc_entry,
|
|
bool *is_in_db,
|
|
bool *is_untrusted);
|
|
@@ -44,7 +50,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
|
|
struct samba_kdc_entry *skdc_entry,
|
|
DATA_BLOB **_logon_info_blob,
|
|
DATA_BLOB **_cred_ndr_blob,
|
|
- DATA_BLOB **_upn_info_blob);
|
|
+ DATA_BLOB **_upn_info_blob,
|
|
+ DATA_BLOB **_pac_attrs_blob,
|
|
+ const krb5_boolean *pac_request);
|
|
NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
|
|
struct samba_kdc_entry *skdc_entry,
|
|
DATA_BLOB **_logon_info_blob);
|
|
diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c
|
|
index 318bf60..f7a9366 100644
|
|
--- a/source4/kdc/wdc-samba4.c
|
|
+++ b/source4/kdc/wdc-samba4.c
|
|
@@ -37,6 +37,7 @@
|
|
static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
|
|
struct hdb_entry_ex *client,
|
|
const krb5_keyblock *pk_reply_key,
|
|
+ const krb5_boolean *pac_request,
|
|
krb5_pac *pac)
|
|
{
|
|
TALLOC_CTX *mem_ctx;
|
|
@@ -46,6 +47,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
|
|
DATA_BLOB _cred_blob = data_blob_null;
|
|
DATA_BLOB *cred_blob = NULL;
|
|
DATA_BLOB *upn_blob = NULL;
|
|
+ DATA_BLOB *pac_attrs_blob = NULL;
|
|
krb5_error_code ret;
|
|
NTSTATUS nt_status;
|
|
struct samba_kdc_entry *skdc_entry =
|
|
@@ -64,7 +66,9 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
|
|
nt_status = samba_kdc_get_pac_blobs(mem_ctx, skdc_entry,
|
|
&logon_blob,
|
|
cred_ndr_ptr,
|
|
- &upn_blob);
|
|
+ &upn_blob,
|
|
+ &pac_attrs_blob,
|
|
+ pac_request);
|
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
|
talloc_free(mem_ctx);
|
|
return EINVAL;
|
|
@@ -84,7 +88,8 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
|
|
}
|
|
|
|
ret = samba_make_krb5_pac(context, logon_blob, cred_blob,
|
|
- upn_blob, NULL, pac);
|
|
+ upn_blob, pac_attrs_blob,
|
|
+ NULL, pac);
|
|
|
|
talloc_free(mem_ctx);
|
|
return ret;
|
|
@@ -92,9 +97,10 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
|
|
|
|
static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context,
|
|
struct hdb_entry_ex *client,
|
|
+ const krb5_boolean *pac_request,
|
|
krb5_pac *pac)
|
|
{
|
|
- return samba_wdc_get_pac(priv, context, client, NULL, pac);
|
|
+ return samba_wdc_get_pac(priv, context, client, NULL, pac_request, pac);
|
|
}
|
|
|
|
static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
@@ -132,6 +138,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
ssize_t srv_checksum_idx = -1;
|
|
ssize_t kdc_checksum_idx = -1;
|
|
ssize_t tkt_checksum_idx = -1;
|
|
+ ssize_t attrs_info_idx = -1;
|
|
|
|
if (!mem_ctx) {
|
|
return ENOMEM;
|
|
@@ -222,7 +229,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
struct samba_kdc_entry);
|
|
|
|
nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry,
|
|
- &pac_blob, NULL, &upn_blob);
|
|
+ &pac_blob, NULL, &upn_blob,
|
|
+ NULL, NULL);
|
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
|
talloc_free(mem_ctx);
|
|
return EINVAL;
|
|
@@ -339,6 +347,18 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
}
|
|
tkt_checksum_idx = i;
|
|
break;
|
|
+ case PAC_TYPE_ATTRIBUTES_INFO:
|
|
+ if (attrs_info_idx != -1) {
|
|
+ DEBUG(1, ("attributes info type[%"PRIu32"] twice [%zd] and [%zu]: \n",
|
|
+ types[i],
|
|
+ attrs_info_idx,
|
|
+ i));
|
|
+ SAFE_FREE(types);
|
|
+ talloc_free(mem_ctx);
|
|
+ return EINVAL;
|
|
+ }
|
|
+ attrs_info_idx = i;
|
|
+ break;
|
|
default:
|
|
continue;
|
|
}
|
|
@@ -386,6 +406,20 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
goto out;
|
|
}
|
|
|
|
+ if (!server_skdc_entry->is_krbtgt) {
|
|
+ /*
|
|
+ * The client may have requested no PAC when obtaining the
|
|
+ * TGT.
|
|
+ */
|
|
+ bool requested_pac;
|
|
+ ret = samba_client_requested_pac(context, pac, mem_ctx,
|
|
+ &requested_pac);
|
|
+ if (ret != 0 || !requested_pac) {
|
|
+ new_pac = NULL;
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
/* Otherwise build an updated PAC */
|
|
ret = krb5_pac_init(context, &new_pac);
|
|
if (ret != 0) {
|
|
@@ -471,6 +505,9 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
|
|
*/
|
|
type_blob = data_blob_const(&zero_byte, 1);
|
|
break;
|
|
+ case PAC_TYPE_ATTRIBUTES_INFO:
|
|
+ /* just copy... */
|
|
+ break;
|
|
default:
|
|
/* just copy... */
|
|
break;
|
|
--
|
|
2.27.0
|
|
|