}
#endif /* HAVE_KRB5_PAC_IS_TRUSTED */
+static bool samba_kdc_entry_pac_issued_by_trust(const struct samba_kdc_entry_pac entry)
+{
+ return entry.pac != NULL && entry.is_from_trust;
+}
+
/*
* Look up the user's info in the database and create a auth_user_info_dc
* structure. If the resulting structure is not talloc_free()d, it will be
krb5_context context,
struct ldb_context *samdb,
const enum auth_group_inclusion group_inclusion,
- struct samba_kdc_entry *skdc_entry,
- const krb5_const_pac pac,
- const bool pac_is_trusted,
+ const struct samba_kdc_entry_pac entry,
struct auth_user_info_dc **user_info_dc_out,
struct PAC_DOMAIN_GROUP_MEMBERSHIP **resource_groups_out)
{
*resource_groups_out = NULL;
}
- if (pac != NULL && pac_is_trusted) {
+ if (samba_krb5_pac_is_trusted(entry)) {
struct PAC_DOMAIN_GROUP_MEMBERSHIP **resource_groups = NULL;
if (group_inclusion == AUTH_EXCLUDE_RESOURCE_GROUPS) {
}
ret = kerberos_pac_to_user_info_dc(mem_ctx,
- pac,
+ entry.pac,
context,
&user_info_dc,
AUTH_EXCLUDE_RESOURCE_GROUPS,
goto out;
}
} else {
- if (skdc_entry == NULL) {
+ if (entry.entry == NULL) {
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto out;
}
* here.
*/
nt_status = samba_kdc_get_user_info_dc(mem_ctx,
- skdc_entry,
+ entry.entry,
&user_info_dc);
if (!NT_STATUS_IS_OK(nt_status)) {
DBG_ERR("samba_kdc_get_user_info_dc failed: %s\n",
/* Does a parse and SID check, but no crypto. */
static krb5_error_code samba_kdc_validate_pac_blob(
krb5_context context,
- const struct samba_kdc_entry *client_skdc_entry,
- const krb5_const_pac pac)
+ const struct samba_kdc_entry_pac client)
{
TALLOC_CTX *frame = talloc_stackframe();
struct auth_user_info_dc *pac_user_info = NULL;
/*
* First, try to get the SID from the requester SID buffer in the PAC.
*/
- code = samba_get_requester_sid(frame, pac, context, &pac_sid);
+ code = samba_get_requester_sid(frame, client.pac, context, &pac_sid);
if (code == ENOENT) {
/*
* SID in the LOGON_INFO PAC buffer.
*/
code = kerberos_pac_to_user_info_dc(frame,
- pac,
+ client.pac,
context,
&pac_user_info,
AUTH_EXCLUDE_RESOURCE_GROUPS,
goto out;
}
- code = samdb_result_dom_sid_buf(client_skdc_entry->msg,
+ code = samdb_result_dom_sid_buf(client.entry->msg,
"objectSid",
&client_sid);
if (code) {
*
* @param flags Bitwise OR'ed flags
*
- * @param client The client samba kdc entry.
+ * @param client The client samba kdc PAC entry.
* @param krbtgt The krbtgt samba kdc entry.
*
- * @param pac The PAC
-
* @return A Kerberos error code.
*/
krb5_error_code samba_kdc_verify_pac(TALLOC_CTX *mem_ctx,
krb5_context context,
uint32_t flags,
- struct samba_kdc_entry *client,
- const struct samba_kdc_entry *krbtgt,
- const krb5_const_pac pac)
+ const struct samba_kdc_entry_pac client,
+ const struct samba_kdc_entry *krbtgt)
{
TALLOC_CTX *tmp_ctx = NULL;
struct pac_blobs *pac_blobs = NULL;
krb5_error_code code = EINVAL;
NTSTATUS nt_status;
- bool is_trusted = flags & SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
goto done;
}
- if (client != NULL) {
+ if (client.entry != NULL) {
/*
* Check the objectSID of the client and pac data are the same.
* Does a parse and SID check, but no crypto.
*/
- code = samba_kdc_validate_pac_blob(context,
- client,
- pac);
+ code = samba_kdc_validate_pac_blob(context, client);
if (code != 0) {
goto done;
}
}
- if (!is_trusted) {
+ if (!samba_krb5_pac_is_trusted(client)) {
const struct auth_user_info_dc *user_info_dc = NULL;
WERROR werr;
struct dom_sid *object_sids = NULL;
uint32_t j;
- if (client == NULL) {
+ if (client.entry == NULL) {
code = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto done;
}
- nt_status = samba_kdc_get_user_info_from_db(client, client->msg, &user_info_dc);
+ nt_status = samba_kdc_get_user_info_from_db(client.entry,
+ client.entry->msg,
+ &user_info_dc);
if (!NT_STATUS_IS_OK(nt_status)) {
DBG_ERR("Getting user info for PAC failed: %s\n",
nt_errstr(nt_status));
werr = samba_rodc_confirm_user_is_allowed(user_info_dc->num_sids,
object_sids,
krbtgt,
- client);
+ client.entry);
if (!W_ERROR_IS_OK(werr)) {
code = KRB5KDC_ERR_TGT_REVOKED;
if (W_ERROR_EQUAL(werr,
code = pac_blobs_from_krb5_pac(tmp_ctx,
context,
- pac,
+ client.pac,
&pac_blobs);
if (code != 0) {
goto done;
* @param device_pac_is_trusted Whether the device's PAC was issued by a trusted server,
* as opposed to an RODC.
*
- * @param client The client samba kdc entry.
- *
- * @param client_krbtgt The krbtgt samba kdc entry that verified the client
+ * @param client The client samba kdc PAC entry.
*
* @param server_principal The server principal
*
* updating the constrained delegation PAC
* buffer.
*
- * @param delegated_proxy The delegated proxy kdc entry.
+ * @param delegated_proxy The delegated proxy kdc PAC entry.
*
- * @param delegated_proxy_pac The PAC from the primary TGT (i.e., that of
- * the delegating service) during a constrained
- * delegation request.
- *
- * @param device The computer's samba kdc entry; used for compound
+ * @param device The computer's samba kdc PAC entry; used for compound
* authentication.
*
- * @param device_krbtgt The krbtgt samba kdc entry that verified the device
- *
- * @param device_pac The PAC from the computer's TGT; used
- * for compound authentication.
- *
- * @param old_pac The old PAC
- *
* @param new_pac The new already allocated PAC
*
* @return A Kerberos error code. If no PAC should be returned, the code will be
struct ldb_context *samdb,
struct loadparm_context *lp_ctx,
uint32_t flags,
- const struct samba_kdc_entry *client_krbtgt,
- struct samba_kdc_entry *client,
+ const struct samba_kdc_entry_pac client,
const krb5_const_principal server_principal,
const struct samba_kdc_entry *server,
const krb5_const_principal delegated_proxy_principal,
- struct samba_kdc_entry *delegated_proxy,
- const krb5_const_pac delegated_proxy_pac,
- const struct samba_kdc_entry *device_krbtgt,
- struct samba_kdc_entry *device,
- const krb5_const_pac device_pac,
- const krb5_const_pac old_pac,
+ const struct samba_kdc_entry_pac delegated_proxy,
+ const struct samba_kdc_entry_pac device,
krb5_pac new_pac,
struct authn_audit_info **server_audit_info_out,
NTSTATUS *status_out)
DATA_BLOB *deleg_blob = NULL;
DATA_BLOB *requester_sid_blob = NULL;
const DATA_BLOB *client_claims_blob = NULL;
- bool client_pac_is_trusted = flags & SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
- bool device_pac_is_trusted = flags & SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED;
- bool delegated_proxy_pac_is_trusted = flags & SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED;
const DATA_BLOB *device_claims_blob = NULL;
DATA_BLOB *device_info_blob = NULL;
bool is_tgs = false;
group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED;
}
- if (device != NULL && !is_tgs) {
+ if (device.entry != NULL && !is_tgs) {
compounded_auth = SAMBA_COMPOUNDED_AUTH_INCLUDE;
} else {
compounded_auth = SAMBA_COMPOUNDED_AUTH_EXCLUDE;
}
- if (device != NULL && !is_tgs) {
- SMB_ASSERT(device_pac != NULL);
+ if (device.entry != NULL && !is_tgs) {
+ SMB_ASSERT(device.pac != NULL);
- if (device_pac_is_trusted) {
+ if (samba_krb5_pac_is_trusted(device)) {
krb5_data device_claims_data;
/*
* claims from the device PAC become the device claims
* in the new PAC.
*/
- code = krb5_pac_get_buffer(context, device_pac,
+ code = krb5_pac_get_buffer(context, device.pac,
PAC_TYPE_CLIENT_CLAIMS_INFO,
&device_claims_data);
if (code == ENOENT) {
/* no-op */
} else if (code != 0) {
goto done;
- } else if (device_krbtgt->is_trust) {
+ } else if (samba_kdc_entry_pac_issued_by_trust(device)) {
/*
* TODO: we need claim translation over trusts,
* for now we just clear them...
code = samba_kdc_create_device_info_blob(tmp_ctx,
context,
samdb,
- device_pac,
+ device.pac,
&device_info_blob);
if (code != 0) {
goto done;
} else {
/* Don't trust RODC-issued claims. Regenerate them. */
nt_status = samba_kdc_get_claims_blob(tmp_ctx,
- device,
+ device.entry,
&device_claims_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
DBG_ERR("samba_kdc_get_claims_blob failed: %s\n",
/* Also regenerate device info. */
code = samba_kdc_get_device_info_blob(tmp_ctx,
- device,
+ device.entry,
&device_info_blob);
if (code != 0) {
goto done;
nt_status = samba_kdc_update_delegation_info_blob(
deleg_blob,
context,
- old_pac,
+ client.pac,
server_principal,
delegated_proxy_principal,
deleg_blob);
samdb,
group_inclusion,
client,
- old_pac,
- client_pac_is_trusted,
&user_info_dc,
&_resource_groups);
if (code != 0) {
const struct samba_kdc_entry *auth_entry = NULL;
struct auth_user_info_dc *auth_user_info_dc = NULL;
- if (delegated_proxy != NULL) {
- auth_entry = delegated_proxy;
+ if (delegated_proxy.entry != NULL) {
+ auth_entry = delegated_proxy.entry;
code = samba_kdc_obtain_user_info_dc(tmp_ctx,
context,
samdb,
AUTH_INCLUDE_RESOURCE_GROUPS,
delegated_proxy,
- delegated_proxy_pac,
- delegated_proxy_pac_is_trusted,
&auth_user_info_dc,
NULL);
if (code) {
goto done;
}
} else {
- auth_entry = client;
+ auth_entry = client.entry;
auth_user_info_dc = user_info_dc;
}
goto done;
}
- if (client_pac_is_trusted) {
+ if (samba_krb5_pac_is_trusted(client)) {
pac_blob = talloc_zero(tmp_ctx, DATA_BLOB);
if (pac_blob == NULL) {
code = ENOMEM;
* TODO: we need claim translation over trusts,
* for now we just clear them...
*/
- if (client_krbtgt->is_trust) {
+ if (samba_kdc_entry_pac_issued_by_trust(client)) {
client_claims_blob = &data_blob_null;
}
} else {
/* Don't trust RODC-issued claims. Regenerate them. */
nt_status = samba_kdc_get_claims_blob(tmp_ctx,
- client,
+ client.entry,
&client_claims_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
DBG_ERR("samba_kdc_get_claims_blob failed: %s\n",
/* Check the types of the given PAC */
code = pac_blobs_from_krb5_pac(tmp_ctx,
context,
- old_pac,
+ client.pac,
&pac_blobs);
if (code != 0) {
goto done;
goto done;
}
- if (!client_pac_is_trusted || !is_tgs) {
+ if (!samba_krb5_pac_is_trusted(client) || !is_tgs) {
pac_blobs_remove_blob(pac_blobs,
PAC_TYPE_ATTRIBUTES_INFO);
}
goto done;
}
- if (client_pac_is_trusted && !is_tgs) {
+ if (samba_krb5_pac_is_trusted(client) && !is_tgs) {
/*
* The client may have requested no PAC when obtaining the
* TGT.
bool requested_pac = false;
code = samba_client_requested_pac(context,
- old_pac,
+ client.pac,
tmp_ctx,
&requested_pac);
if (code != 0 || !requested_pac) {
(type_data.data != NULL) ? &type_data : &null_data);
} else {
code = krb5_pac_get_buffer(context,
- old_pac,
+ client.pac,
type,
&type_data);
if (code != 0) {
krb5_context context,
struct ldb_context *samdb,
struct loadparm_context *lp_ctx,
- struct samba_kdc_entry *device,
- const krb5_const_pac device_pac,
- const bool device_pac_is_trusted,
+ const struct samba_kdc_entry_pac device,
const struct authn_kerberos_client_policy *client_policy,
struct authn_audit_info **client_audit_info_out,
NTSTATUS *status_out)
return 0;
}
- if (device == NULL || device_pac == NULL) {
+ if (device.entry == NULL || device.pac == NULL) {
NTSTATUS out_status = NT_STATUS_INVALID_WORKSTATION;
nt_status = authn_kerberos_client_policy_audit_info(mem_ctx,
frame = talloc_stackframe();
- if (device_pac_is_trusted) {
+ if (samba_krb5_pac_is_trusted(device)) {
krb5_data device_logon_info;
enum ndr_err_code ndr_err;
union PAC_INFO pac_logon_info;
union netr_Validation validation;
- code = krb5_pac_get_buffer(context, device_pac,
+ code = krb5_pac_get_buffer(context, device.pac,
PAC_TYPE_LOGON_INFO,
&device_logon_info);
if (code != 0) {
}
} else {
nt_status = samba_kdc_get_user_info_dc(frame,
- device,
+ device.entry,
&device_info);
if (!NT_STATUS_IS_OK(nt_status)) {
DBG_ERR("samba_kdc_get_user_info_dc failed: %s\n",
enum {
SAMBA_KDC_FLAG_PROTOCOL_TRANSITION = 0x00000001,
SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION = 0x00000002,
- SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED = 0x00000008,
- SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED = 0x00000020,
- SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED = 0x00000040,
};
bool samba_kdc_entry_is_trust(const struct samba_kdc_entry *entry);
krb5_error_code samba_kdc_verify_pac(TALLOC_CTX *mem_ctx,
krb5_context context,
uint32_t flags,
- struct samba_kdc_entry *client,
- const struct samba_kdc_entry *krbtgt,
- krb5_const_pac pac);
+ const struct samba_kdc_entry_pac client,
+ const struct samba_kdc_entry *krbtgt);
struct authn_audit_info;
krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
struct loadparm_context *lp_ctx,
uint32_t flags,
- const struct samba_kdc_entry *client_krbtgt,
- struct samba_kdc_entry *client,
+ const struct samba_kdc_entry_pac client,
const krb5_const_principal server_principal,
const struct samba_kdc_entry *server,
const krb5_const_principal delegated_proxy_principal,
- struct samba_kdc_entry *delegated_proxy,
- const krb5_const_pac delegated_proxy_pac,
- const struct samba_kdc_entry *device_krbtgt,
- struct samba_kdc_entry *device,
- const krb5_const_pac device_pac,
- const krb5_const_pac old_pac,
+ const struct samba_kdc_entry_pac delegated_proxy,
+ const struct samba_kdc_entry_pac device,
krb5_pac new_pac,
struct authn_audit_info **server_audit_info_out,
NTSTATUS *status_out);
krb5_context context,
struct ldb_context *samdb,
struct loadparm_context *lp_ctx,
- struct samba_kdc_entry *device,
- krb5_const_pac device_pac,
- bool device_pac_is_trusted,
+ const struct samba_kdc_entry_pac device,
const struct authn_kerberos_client_policy *client_policy,
struct authn_audit_info **client_audit_info_out,
NTSTATUS *status_out);
struct samba_kdc_entry *client_skdc_entry = NULL;
struct samba_kdc_entry *krbtgt_skdc_entry =
talloc_get_type_abort(krbtgt->context, struct samba_kdc_entry);
+ struct samba_kdc_entry_pac client_pac_entry = {};
TALLOC_CTX *mem_ctx = NULL;
krb5_error_code ret;
bool is_s4u2self = samba_wdc_is_s4u2self_req(r);
bool is_trusted = false;
uint32_t flags = 0;
+ if (pac == NULL) {
+ return EINVAL;
+ }
+
mem_ctx = talloc_named(NULL, 0, "samba_wdc_verify_pac2 context");
if (mem_ctx == NULL) {
return ENOMEM;
goto out;
}
+ krb5_pac_set_trusted(pac, is_trusted);
+ client_pac_entry = samba_kdc_entry_pac(pac,
+ client_skdc_entry,
+ samba_kdc_entry_is_trust(krbtgt_skdc_entry));
+
if (is_s4u2self) {
flags |= SAMBA_KDC_FLAG_PROTOCOL_TRANSITION;
}
flags |= SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION;
}
- if (is_trusted) {
- flags |= SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
- }
-
ret = samba_kdc_verify_pac(mem_ctx,
context,
flags,
- client_skdc_entry,
- krbtgt_skdc_entry,
- pac);
+ client_pac_entry,
+ krbtgt_skdc_entry);
if (ret != 0) {
goto out;
}
krb5_pac *pac)
{
krb5_context context = kdc_request_get_context((kdc_request_t)r);
- const hdb_entry *device = kdc_request_get_explicit_armor_client(r);
- const krb5_const_pac device_pac = kdc_request_get_explicit_armor_pac(r);
struct samba_kdc_entry *delegated_proxy_skdc_entry = NULL;
krb5_const_principal delegated_proxy_principal = NULL;
+ struct samba_kdc_entry_pac delegated_proxy_pac_entry = {};
struct samba_kdc_entry *client_skdc_entry = NULL;
- struct samba_kdc_entry *device_skdc_entry = NULL;
+ struct samba_kdc_entry_pac client_pac_entry = {};
+ struct samba_kdc_entry_pac device = {};
const struct samba_kdc_entry *server_skdc_entry =
talloc_get_type_abort(server->context, struct samba_kdc_entry);
const struct samba_kdc_entry *krbtgt_skdc_entry =
talloc_get_type_abort(krbtgt->context, struct samba_kdc_entry);
- const struct samba_kdc_entry *client_krbtgt_skdc_entry = krbtgt_skdc_entry;
- const struct samba_kdc_entry *device_krbtgt_skdc_entry = NULL;
TALLOC_CTX *mem_ctx = NULL;
krb5_pac new_pac = NULL;
struct authn_audit_info *server_audit_info = NULL;
NTSTATUS reply_status = NT_STATUS_OK;
uint32_t flags = 0;
+ if (pac == NULL) {
+ return EINVAL;
+ }
+
mem_ctx = talloc_named(NULL, 0, "samba_wdc_reget_pac context");
if (mem_ctx == NULL) {
return ENOMEM;
delegated_proxy_principal = delegated_proxy->principal;
}
+ delegated_proxy_pac_entry = samba_kdc_entry_pac(delegated_proxy_pac,
+ delegated_proxy_skdc_entry,
+ /* The S4U2Proxy
+ * evidence ticket could
+ * not have been signed
+ * or issued by a krbtgt
+ * trust account. */
+ false /* is_from_trust */);
+
if (client != NULL) {
client_skdc_entry = talloc_get_type_abort(client->context,
struct samba_kdc_entry);
}
- if (device != NULL) {
- const hdb_entry *device_krbtgt = NULL;
-
- device_skdc_entry = talloc_get_type_abort(device->context,
- struct samba_kdc_entry);
-
- device_krbtgt = kdc_request_get_explicit_armor_server(r);
- device_krbtgt_skdc_entry = talloc_get_type_abort(device_krbtgt->context,
- struct samba_kdc_entry);
- }
+ device = samba_kdc_get_device_pac(r);
ret = krb5_pac_init(context, &new_pac);
if (ret != 0) {
goto out;
}
- if (krb5_pac_is_trusted(*pac)) {
- flags |= SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
- }
- if (device_pac != NULL && krb5_pac_is_trusted(device_pac)) {
- flags |= SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED;
- }
- if (delegated_proxy_pac != NULL && krb5_pac_is_trusted(delegated_proxy_pac)) {
- flags |= SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED;
- }
+ client_pac_entry = samba_kdc_entry_pac(*pac,
+ client_skdc_entry,
+ samba_kdc_entry_is_trust(krbtgt_skdc_entry));
ret = samba_kdc_update_pac(mem_ctx,
context,
krbtgt_skdc_entry->kdc_db_ctx->samdb,
krbtgt_skdc_entry->kdc_db_ctx->lp_ctx,
flags,
- client_krbtgt_skdc_entry,
- client_skdc_entry,
+ client_pac_entry,
server->principal,
server_skdc_entry,
delegated_proxy_principal,
- delegated_proxy_skdc_entry,
- delegated_proxy_pac,
- device_krbtgt_skdc_entry,
- device_skdc_entry,
- device_pac,
- *pac,
+ delegated_proxy_pac_entry,
+ device,
new_pac,
&server_audit_info,
&reply_status);
TALLOC_CTX *tmp_ctx = NULL;
const hdb_entry *client = NULL;
struct samba_kdc_entry *kdc_entry;
- const hdb_entry *device = kdc_request_get_armor_client(r);
- struct samba_kdc_entry *device_skdc_entry = NULL;
- const krb5_const_pac device_pac = kdc_request_get_armor_pac(r);
+ struct samba_kdc_entry_pac device = {};
struct authn_audit_info *client_audit_info = NULL;
bool password_change;
char *workstation;
NTSTATUS nt_status;
NTSTATUS check_device_status = NT_STATUS_OK;
krb5_error_code ret = 0;
- bool device_pac_is_trusted = false;
client = kdc_request_get_client(r);
kdc_entry = talloc_get_type_abort(client->context, struct samba_kdc_entry);
- if (device != NULL) {
- device_skdc_entry = talloc_get_type_abort(device->context,
- struct samba_kdc_entry);
- }
-
- if (device_pac != NULL) {
- device_pac_is_trusted = krb5_pac_is_trusted(device_pac);
- }
+ device = samba_kdc_get_device_pac(r);
ret = samba_kdc_check_device(tmp_ctx,
context,
kdc_entry->kdc_db_ctx->samdb,
kdc_entry->kdc_db_ctx->lp_ctx,
- device_skdc_entry,
- device_pac,
- device_pac_is_trusted,
+ device,
kdc_entry->client_policy,
&client_audit_info,
&check_device_status);