This will allow us to make more functions static in the next steps.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
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)
{
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);
#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"
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;
+}
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);