From: Stefan Metzmacher Date: Thu, 20 Feb 2025 14:04:08 +0000 (+0100) Subject: s4:kdc: move samba_kdc_check_s4u2proxy_rbcd() from db-glue to pac-glue X-Git-Tag: tevent-0.17.0~660 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58df2bd733a351a91ef840d100faec83a0068c25;p=thirdparty%2Fsamba.git s4:kdc: move samba_kdc_check_s4u2proxy_rbcd() from db-glue to pac-glue This will allow us to make more functions static in the next steps. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index 71bb83e7398..f2e1c993bd5 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -4072,179 +4072,6 @@ bad_option: return KRB5KDC_ERR_BADOPTION; } -/* - * This method is called for S4U2Proxy requests and implements the - * resource-based constrained delegation variant, which can support - * cross-realm delegation. - */ -krb5_error_code samba_kdc_check_s4u2proxy_rbcd( - krb5_context context, - struct samba_kdc_db_context *kdc_db_ctx, - krb5_const_principal client_principal, - krb5_const_principal server_principal, - const struct auth_user_info_dc *user_info_dc, - const struct auth_user_info_dc *device_info_dc, - const struct auth_claims auth_claims, - struct samba_kdc_entry *proxy_skdc_entry) -{ - krb5_error_code code; - enum ndr_err_code ndr_err; - char *client_name = NULL; - char *server_name = NULL; - const char *proxy_dn = NULL; - const DATA_BLOB *data = NULL; - struct security_descriptor *rbcd_security_descriptor = NULL; - struct security_token *security_token = NULL; - uint32_t session_info_flags = - AUTH_SESSION_INFO_DEFAULT_GROUPS | - AUTH_SESSION_INFO_DEVICE_DEFAULT_GROUPS | - AUTH_SESSION_INFO_SIMPLE_PRIVILEGES | - AUTH_SESSION_INFO_FORCE_COMPOUNDED_AUTHENTICATION; - /* - * Testing shows that although Windows grants SEC_ADS_GENERIC_ALL access - * in security descriptors it creates for RBCD, its KDC only requires - * SEC_ADS_CONTROL_ACCESS for the access check to succeed. - */ - uint32_t access_desired = SEC_ADS_CONTROL_ACCESS; - uint32_t access_granted = 0; - NTSTATUS nt_status; - TALLOC_CTX *mem_ctx = NULL; - - mem_ctx = talloc_named(kdc_db_ctx, - 0, - "samba_kdc_check_s4u2proxy_rbcd"); - if (mem_ctx == NULL) { - errno = ENOMEM; - code = errno; - - return code; - } - - proxy_dn = ldb_dn_get_linearized(proxy_skdc_entry->msg->dn); - if (proxy_dn == NULL) { - DBG_ERR("ldb_dn_get_linearized failed for proxy_dn!\n"); - if (errno == 0) { - errno = ENOMEM; - } - code = errno; - - goto out; - } - - rbcd_security_descriptor = talloc_zero(mem_ctx, - struct security_descriptor); - if (rbcd_security_descriptor == NULL) { - errno = ENOMEM; - code = errno; - - goto out; - } - - code = krb5_unparse_name_flags(context, - client_principal, - KRB5_PRINCIPAL_UNPARSE_DISPLAY, - &client_name); - if (code != 0) { - DBG_ERR("Unable to parse client_principal!\n"); - goto out; - } - - code = krb5_unparse_name_flags(context, - server_principal, - KRB5_PRINCIPAL_UNPARSE_DISPLAY, - &server_name); - if (code != 0) { - DBG_ERR("Unable to parse server_principal!\n"); - goto out; - } - - DBG_INFO("Check delegation from client[%s] to server[%s] via " - "proxy[%s]\n", - client_name, - server_name, - proxy_dn); - - if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) { - session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; - } - - if (device_info_dc != NULL && !(device_info_dc->info->user_flags & NETLOGON_GUEST)) { - session_info_flags |= AUTH_SESSION_INFO_DEVICE_AUTHENTICATED; - } - - nt_status = auth_generate_security_token(mem_ctx, - kdc_db_ctx->lp_ctx, - kdc_db_ctx->samdb, - user_info_dc, - device_info_dc, - auth_claims, - session_info_flags, - &security_token); - if (!NT_STATUS_IS_OK(nt_status)) { - code = map_errno_from_nt_status(nt_status); - goto out; - } - - data = ldb_msg_find_ldb_val(proxy_skdc_entry->msg, - "msDS-AllowedToActOnBehalfOfOtherIdentity"); - if (data == NULL) { - DBG_WARNING("Could not find security descriptor " - "msDS-AllowedToActOnBehalfOfOtherIdentity in " - "proxy[%s]\n", - proxy_dn); - code = KRB5KDC_ERR_BADOPTION; - goto out; - } - - ndr_err = ndr_pull_struct_blob( - data, - mem_ctx, - rbcd_security_descriptor, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - errno = ndr_map_error2errno(ndr_err); - DBG_ERR("Failed to unmarshall " - "msDS-AllowedToActOnBehalfOfOtherIdentity " - "security descriptor of proxy[%s]\n", - proxy_dn); - code = KRB5KDC_ERR_BADOPTION; - goto out; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(security_token, security_token); - NDR_PRINT_DEBUG(security_descriptor, rbcd_security_descriptor); - } - - nt_status = sec_access_check_ds(rbcd_security_descriptor, - security_token, - access_desired, - &access_granted, - NULL, - NULL); - - if (!NT_STATUS_IS_OK(nt_status)) { - DBG_WARNING("RBCD: sec_access_check_ds(access_desired=%#08x, " - "access_granted:%#08x) failed with: %s\n", - access_desired, - access_granted, - nt_errstr(nt_status)); - - code = KRB5KDC_ERR_BADOPTION; - goto out; - } - - DBG_NOTICE("RBCD: Access granted for client[%s]\n", client_name); - - code = 0; -out: - SAFE_FREE(client_name); - SAFE_FREE(server_name); - - TALLOC_FREE(mem_ctx); - return code; -} - NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx, struct samba_kdc_db_context **kdc_db_ctx_out) { diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h index f06cca4b42b..297916ed823 100644 --- a/source4/kdc/db-glue.h +++ b/source4/kdc/db-glue.h @@ -93,16 +93,6 @@ samba_kdc_check_s4u2proxy(krb5_context context, struct samba_kdc_entry *skdc_entry, krb5_const_principal target_principal); -krb5_error_code samba_kdc_check_s4u2proxy_rbcd( - krb5_context context, - struct samba_kdc_db_context *kdc_db_ctx, - krb5_const_principal client_principal, - krb5_const_principal server_principal, - const struct auth_user_info_dc *user_info_dc, - const struct auth_user_info_dc *device_info_dc, - const struct auth_claims auth_claims, - struct samba_kdc_entry *proxy_skdc_entry); - NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx, struct samba_kdc_db_context **kdc_db_ctx_out); diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index dd37b8cb948..0d46d03f9df 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -33,6 +33,7 @@ #include "auth/kerberos/pac_utils.h" #include "auth/authn_policy.h" #include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" #include "libds/common/flags.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "param/param.h" @@ -3424,3 +3425,176 @@ out: talloc_free(frame); return code; } + +/* + * This method is called for S4U2Proxy requests and implements the + * resource-based constrained delegation variant, which can support + * cross-realm delegation. + */ +krb5_error_code samba_kdc_check_s4u2proxy_rbcd( + krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + krb5_const_principal client_principal, + krb5_const_principal server_principal, + const struct auth_user_info_dc *user_info_dc, + const struct auth_user_info_dc *device_info_dc, + const struct auth_claims auth_claims, + struct samba_kdc_entry *proxy_skdc_entry) +{ + krb5_error_code code; + enum ndr_err_code ndr_err; + char *client_name = NULL; + char *server_name = NULL; + const char *proxy_dn = NULL; + const DATA_BLOB *data = NULL; + struct security_descriptor *rbcd_security_descriptor = NULL; + struct security_token *security_token = NULL; + uint32_t session_info_flags = + AUTH_SESSION_INFO_DEFAULT_GROUPS | + AUTH_SESSION_INFO_DEVICE_DEFAULT_GROUPS | + AUTH_SESSION_INFO_SIMPLE_PRIVILEGES | + AUTH_SESSION_INFO_FORCE_COMPOUNDED_AUTHENTICATION; + /* + * Testing shows that although Windows grants SEC_ADS_GENERIC_ALL access + * in security descriptors it creates for RBCD, its KDC only requires + * SEC_ADS_CONTROL_ACCESS for the access check to succeed. + */ + uint32_t access_desired = SEC_ADS_CONTROL_ACCESS; + uint32_t access_granted = 0; + NTSTATUS nt_status; + TALLOC_CTX *mem_ctx = NULL; + + mem_ctx = talloc_named(kdc_db_ctx, + 0, + "samba_kdc_check_s4u2proxy_rbcd"); + if (mem_ctx == NULL) { + errno = ENOMEM; + code = errno; + + return code; + } + + proxy_dn = ldb_dn_get_linearized(proxy_skdc_entry->msg->dn); + if (proxy_dn == NULL) { + DBG_ERR("ldb_dn_get_linearized failed for proxy_dn!\n"); + if (errno == 0) { + errno = ENOMEM; + } + code = errno; + + goto out; + } + + rbcd_security_descriptor = talloc_zero(mem_ctx, + struct security_descriptor); + if (rbcd_security_descriptor == NULL) { + errno = ENOMEM; + code = errno; + + goto out; + } + + code = krb5_unparse_name_flags(context, + client_principal, + KRB5_PRINCIPAL_UNPARSE_DISPLAY, + &client_name); + if (code != 0) { + DBG_ERR("Unable to parse client_principal!\n"); + goto out; + } + + code = krb5_unparse_name_flags(context, + server_principal, + KRB5_PRINCIPAL_UNPARSE_DISPLAY, + &server_name); + if (code != 0) { + DBG_ERR("Unable to parse server_principal!\n"); + goto out; + } + + DBG_INFO("Check delegation from client[%s] to server[%s] via " + "proxy[%s]\n", + client_name, + server_name, + proxy_dn); + + if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) { + session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } + + if (device_info_dc != NULL && !(device_info_dc->info->user_flags & NETLOGON_GUEST)) { + session_info_flags |= AUTH_SESSION_INFO_DEVICE_AUTHENTICATED; + } + + nt_status = auth_generate_security_token(mem_ctx, + kdc_db_ctx->lp_ctx, + kdc_db_ctx->samdb, + user_info_dc, + device_info_dc, + auth_claims, + session_info_flags, + &security_token); + if (!NT_STATUS_IS_OK(nt_status)) { + code = map_errno_from_nt_status(nt_status); + goto out; + } + + data = ldb_msg_find_ldb_val(proxy_skdc_entry->msg, + "msDS-AllowedToActOnBehalfOfOtherIdentity"); + if (data == NULL) { + DBG_WARNING("Could not find security descriptor " + "msDS-AllowedToActOnBehalfOfOtherIdentity in " + "proxy[%s]\n", + proxy_dn); + code = KRB5KDC_ERR_BADOPTION; + goto out; + } + + ndr_err = ndr_pull_struct_blob( + data, + mem_ctx, + rbcd_security_descriptor, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + errno = ndr_map_error2errno(ndr_err); + DBG_ERR("Failed to unmarshall " + "msDS-AllowedToActOnBehalfOfOtherIdentity " + "security descriptor of proxy[%s]\n", + proxy_dn); + code = KRB5KDC_ERR_BADOPTION; + goto out; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(security_token, security_token); + NDR_PRINT_DEBUG(security_descriptor, rbcd_security_descriptor); + } + + nt_status = sec_access_check_ds(rbcd_security_descriptor, + security_token, + access_desired, + &access_granted, + NULL, + NULL); + + if (!NT_STATUS_IS_OK(nt_status)) { + DBG_WARNING("RBCD: sec_access_check_ds(access_desired=%#08x, " + "access_granted:%#08x) failed with: %s\n", + access_desired, + access_granted, + nt_errstr(nt_status)); + + code = KRB5KDC_ERR_BADOPTION; + goto out; + } + + DBG_NOTICE("RBCD: Access granted for client[%s]\n", client_name); + + code = 0; +out: + SAFE_FREE(client_name); + SAFE_FREE(server_name); + + TALLOC_FREE(mem_ctx); + return code; +} diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h index 3d092525eea..aac9f85f55d 100644 --- a/source4/kdc/pac-glue.h +++ b/source4/kdc/pac-glue.h @@ -140,3 +140,13 @@ krb5_error_code samba_kdc_get_claims_data(TALLOC_CTX *mem_ctx, struct samba_kdc_db_context *kdc_db_ctx, struct samba_kdc_entry_pac entry, struct claims_data **claims_data_out); + +krb5_error_code samba_kdc_check_s4u2proxy_rbcd( + krb5_context context, + struct samba_kdc_db_context *kdc_db_ctx, + krb5_const_principal client_principal, + krb5_const_principal server_principal, + const struct auth_user_info_dc *user_info_dc, + const struct auth_user_info_dc *device_info_dc, + const struct auth_claims auth_claims, + struct samba_kdc_entry *proxy_skdc_entry);