^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true
-#
-# PAC requester SID tests
-#
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting
-#
-# PAC tests
-#
-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local
-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc
static
NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
const struct auth_user_info_dc *info,
- DATA_BLOB *pac_data)
+ DATA_BLOB *pac_data,
+ DATA_BLOB *requester_sid_blob)
{
struct netr_SamInfo3 *info3;
union PAC_INFO pac_info;
ZERO_STRUCT(pac_info);
*pac_data = data_blob_null;
+ if (requester_sid_blob != NULL) {
+ *requester_sid_blob = data_blob_null;
+ }
nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, info, &info3);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
+ if (requester_sid_blob != NULL && info->num_sids > 0) {
+ union PAC_INFO pac_requester_sid;
+
+ ZERO_STRUCT(pac_requester_sid);
+
+ pac_requester_sid.requester_sid.sid = info->sids[0];
+
+ ndr_err = ndr_push_union_blob(requester_sid_blob, mem_ctx,
+ &pac_requester_sid,
+ PAC_TYPE_REQUESTER_SID,
+ (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_REQUESTER_SID (presig) push failed: %s\n",
+ nt_errstr(nt_status)));
+ return nt_status;
+ }
+ }
+
return NT_STATUS_OK;
}
const DATA_BLOB *cred_blob,
const DATA_BLOB *upn_blob,
const DATA_BLOB *pac_attrs_blob,
+ const DATA_BLOB *requester_sid_blob,
const DATA_BLOB *deleg_blob,
krb5_pac *pac)
{
krb5_data cred_data;
krb5_data upn_data;
krb5_data pac_attrs_data;
+ krb5_data requester_sid_data;
krb5_data deleg_data;
krb5_error_code ret;
#ifdef SAMBA4_USES_HEIMDAL
}
}
+ ZERO_STRUCT(requester_sid_data);
+ if (requester_sid_blob != NULL) {
+ ret = smb_krb5_copy_data_contents(&requester_sid_data,
+ requester_sid_blob->data,
+ requester_sid_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);
+ smb_krb5_free_data_contents(context, &pac_attrs_data);
+ return ret;
+ }
+ }
+
ZERO_STRUCT(deleg_data);
if (deleg_blob != NULL) {
ret = smb_krb5_copy_data_contents(&deleg_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, &requester_sid_data);
return ret;
}
}
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, &requester_sid_data);
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
}
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, &requester_sid_data);
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
}
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, &requester_sid_data);
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
}
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, &requester_sid_data);
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
}
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, &requester_sid_data);
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
}
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, &requester_sid_data);
+ smb_krb5_free_data_contents(context, &deleg_data);
+ return ret;
+ }
+ }
+
+ if (requester_sid_blob != NULL) {
+ ret = krb5_pac_add_buffer(context, *pac,
+ PAC_TYPE_REQUESTER_SID,
+ &requester_sid_data);
+ smb_krb5_free_data_contents(context, &requester_sid_data);
if (ret != 0) {
smb_krb5_free_data_contents(context, &deleg_data);
return ret;
DATA_BLOB **_upn_info_blob,
DATA_BLOB **_pac_attrs_blob,
const krb5_boolean *pac_request,
+ DATA_BLOB **_requester_sid_blob,
struct auth_user_info_dc **_user_info_dc)
{
struct auth_user_info_dc *user_info_dc;
DATA_BLOB *cred_blob = NULL;
DATA_BLOB *upn_blob = NULL;
DATA_BLOB *pac_attrs_blob = NULL;
+ DATA_BLOB *requester_sid_blob = NULL;
NTSTATUS nt_status;
*_logon_info_blob = NULL;
if (_pac_attrs_blob != NULL) {
*_pac_attrs_blob = NULL;
}
+ if (_requester_sid_blob != NULL) {
+ *_requester_sid_blob = NULL;
+ }
logon_blob = talloc_zero(mem_ctx, DATA_BLOB);
if (logon_blob == NULL) {
}
}
+ if (_requester_sid_blob != NULL) {
+ requester_sid_blob = talloc_zero(mem_ctx, DATA_BLOB);
+ if (requester_sid_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),
nt_status = samba_get_logon_info_pac_blob(logon_blob,
user_info_dc,
- logon_blob);
+ logon_blob,
+ requester_sid_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Building PAC LOGON INFO failed: %s\n",
nt_errstr(nt_status)));
if (_pac_attrs_blob != NULL) {
*_pac_attrs_blob = pac_attrs_blob;
}
+ if (_requester_sid_blob != NULL) {
+ *_requester_sid_blob = requester_sid_blob;
+ }
return NT_STATUS_OK;
}
}
nt_status = samba_get_logon_info_pac_blob(mem_ctx,
- user_info_dc, pac_blob);
+ user_info_dc, pac_blob, NULL);
return nt_status;
}
return nt_status;
}
+static krb5_error_code samba_get_requester_sid(TALLOC_CTX *mem_ctx,
+ krb5_pac pac,
+ krb5_context context,
+ struct dom_sid *sid)
+{
+ NTSTATUS nt_status;
+ enum ndr_err_code ndr_err;
+ krb5_error_code ret;
+
+ DATA_BLOB pac_requester_sid_in;
+ krb5_data k5pac_requester_sid_in;
+
+ union PAC_INFO info;
+
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_REQUESTER_SID,
+ &k5pac_requester_sid_in);
+ if (ret != 0) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ pac_requester_sid_in = data_blob_const(k5pac_requester_sid_in.data,
+ k5pac_requester_sid_in.length);
+
+ ndr_err = ndr_pull_union_blob(&pac_requester_sid_in, tmp_ctx, &info,
+ PAC_TYPE_REQUESTER_SID,
+ (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
+ smb_krb5_free_data_contents(context, &k5pac_requester_sid_in);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ nt_status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(0,("can't parse the PAC REQUESTER_SID: %s\n", nt_errstr(nt_status)));
+ talloc_free(tmp_ctx);
+ return EINVAL;
+ }
+
+ *sid = info.requester_sid.sid;
+
+ talloc_free(tmp_ctx);
+ return 0;
+}
+
/* Does a parse and SID check, but no crypto. */
krb5_error_code samba_kdc_validate_pac_blob(
krb5_context context,
krb5_error_code code;
bool ok;
- code = kerberos_pac_to_user_info_dc(frame,
- pac,
- context,
- &pac_user_info,
- NULL,
- NULL);
- if (code != 0) {
- goto out;
- }
+ /*
+ * First, try to get the SID from the requester SID buffer in the PAC.
+ */
+ code = samba_get_requester_sid(frame, pac, context, &pac_sid);
+
+ if (code == ENOENT) {
+ /*
+ * If the requester SID buffer isn't present, fall back to the
+ * SID in the LOGON_INFO PAC buffer.
+ */
+ code = kerberos_pac_to_user_info_dc(frame,
+ pac,
+ context,
+ &pac_user_info,
+ NULL,
+ NULL);
+ if (code != 0) {
+ goto out;
+ }
+
+ if (pac_user_info->num_sids == 0) {
+ code = EINVAL;
+ goto out;
+ }
- if (pac_user_info->num_sids == 0) {
- code = EINVAL;
+ pac_sid = pac_user_info->sids[0];
+ } else if (code != 0) {
goto out;
}
- pac_sid = pac_user_info->sids[0];
client_sid = samdb_result_dom_sid(frame,
client_skdc_entry->msg,
"objectSid");
DATA_BLOB *cred_blob = NULL;
DATA_BLOB *upn_blob = NULL;
DATA_BLOB *pac_attrs_blob = NULL;
+ DATA_BLOB *requester_sid_blob = NULL;
krb5_error_code ret;
NTSTATUS nt_status;
struct samba_kdc_entry *skdc_entry =
&upn_blob,
&pac_attrs_blob,
pac_request,
+ &requester_sid_blob,
NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
ret = samba_make_krb5_pac(context, logon_blob, cred_blob,
upn_blob, pac_attrs_blob,
- NULL, pac);
+ requester_sid_blob, NULL, pac);
talloc_free(mem_ctx);
return ret;
krb5_pac new_pac = NULL;
DATA_BLOB *pac_blob = NULL;
DATA_BLOB *upn_blob = NULL;
+ DATA_BLOB *requester_sid_blob = NULL;
DATA_BLOB *deleg_blob = NULL;
krb5_error_code ret;
NTSTATUS nt_status;
ssize_t kdc_checksum_idx = -1;
ssize_t tkt_checksum_idx = -1;
ssize_t attrs_info_idx = -1;
+ ssize_t requester_sid_idx = -1;
if (!mem_ctx) {
return ENOMEM;
nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry,
&pac_blob, NULL, &upn_blob,
- NULL, NULL,
+ NULL, NULL, &requester_sid_blob,
&user_info_dc);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
}
attrs_info_idx = i;
break;
+ case PAC_TYPE_REQUESTER_SID:
+ if (requester_sid_idx != -1) {
+ DEBUG(1, ("requester sid type[%"PRIu32"] twice [%zd] and [%zu]: \n",
+ types[i],
+ requester_sid_idx,
+ i));
+ SAFE_FREE(types);
+ talloc_free(mem_ctx);
+ return EINVAL;
+ }
+ requester_sid_idx = i;
+ break;
default:
continue;
}
* we just add a place holder here.
*/
type_blob = data_blob_const(&zero_byte, 1);
+
+ if (requester_sid_idx == -1 && requester_sid_blob != NULL) {
+ /* inject REQUESTER_SID behind */
+ forced_next_type = PAC_TYPE_REQUESTER_SID;
+ }
break;
case PAC_TYPE_KDC_CHECKSUM:
/*
case PAC_TYPE_ATTRIBUTES_INFO:
/* just copy... */
break;
+ case PAC_TYPE_REQUESTER_SID:
+ /*
+ * Replace in the RODC case, otherwise
+ * requester_sid_blob is NULL and we just copy.
+ */
+ if (requester_sid_blob != NULL) {
+ type_blob = *requester_sid_blob;
+ }
+ break;
default:
/* just copy... */
break;