From: Andreas Schneider Date: Fri, 15 Dec 2023 15:21:32 +0000 (+0100) Subject: s4:rpc_server: Implement dcesrv_lsa_CreateTrustedDomain_precheck() X-Git-Tag: tdb-1.4.11~1250 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dad8c78edc7fa72d379ff640659f35ccc2689614;p=thirdparty%2Fsamba.git s4:rpc_server: Implement dcesrv_lsa_CreateTrustedDomain_precheck() Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index b19341c976e..f793b24f59e 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1096,103 +1096,92 @@ static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +static NTSTATUS dcesrv_lsa_CreateTrustedDomain_precheck( + TALLOC_CTX *mem_ctx, + struct dcesrv_handle *policy_handle, + struct lsa_TrustDomainInfoInfoEx *info) +{ + struct lsa_policy_state *policy_state = policy_handle->data; + const char *netbios_name = NULL; + const char *dns_name = NULL; + bool ok; + + netbios_name = info->netbios_name.string; + if (netbios_name == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + dns_name = info->domain_name.string; + if (dns_name == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (info->sid == NULL) { + return NT_STATUS_INVALID_SID; + } + + /* + * We expect S-1-5-21-A-B-C, but we don't + * allow S-1-5-21-0-0-0 as this is used + * for claims and compound identities. + */ + ok = dom_sid_is_valid_account_domain(info->sid); + if (!ok) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (strcasecmp(netbios_name, "BUILTIN") == 0 || + strcasecmp(dns_name, "BUILTIN") == 0 || + dom_sid_in_domain(policy_state->builtin_sid, info->sid)) + { + return NT_STATUS_INVALID_PARAMETER; + } + + if (strcasecmp(netbios_name, policy_state->domain_name) == 0 || + strcasecmp(netbios_name, policy_state->domain_dns) == 0 || + strcasecmp(dns_name, policy_state->domain_dns) == 0 || + strcasecmp(dns_name, policy_state->domain_name) == 0 || + dom_sid_equal(policy_state->domain_sid, info->sid)) + { + return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED; + } + + return NT_STATUS_OK; +} + /* lsa_CreateTrustedDomainEx2 */ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct dcesrv_handle *policy_handle, struct lsa_CreateTrustedDomainEx2 *r, int op, struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info) { - struct dcesrv_handle *policy_handle; - struct lsa_policy_state *policy_state; + struct lsa_policy_state *policy_state = policy_handle->data; + struct ldb_context *sam_ldb = policy_state->sam_ldb; struct lsa_trusted_domain_state *trusted_domain_state; struct dcesrv_handle *handle; struct ldb_message **msgs, *msg; const char *attrs[] = { NULL }; - const char *netbios_name; - const char *dns_name; + const char *netbios_name = r->in.info->netbios_name.string; + const char *dns_name = r->in.info->domain_name.string; DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; struct trustDomainPasswords auth_struct; int ret; NTSTATUS nt_status; - struct ldb_context *sam_ldb; struct server_id *server_ids = NULL; uint32_t num_server_ids = 0; NTSTATUS status; - bool ok; char *dns_encoded = NULL; char *netbios_encoded = NULL; char *sid_encoded = NULL; struct imessaging_context *imsg_ctx = dcesrv_imessaging_context(dce_call->conn); - DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY); - ZERO_STRUCTP(r->out.trustdom_handle); - - policy_state = policy_handle->data; - sam_ldb = policy_state->sam_ldb; - - netbios_name = r->in.info->netbios_name.string; - if (!netbios_name) { - return NT_STATUS_INVALID_PARAMETER; - } - - dns_name = r->in.info->domain_name.string; - if (dns_name == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (r->in.info->sid == NULL) { - return NT_STATUS_INVALID_SID; - } - - /* - * We expect S-1-5-21-A-B-C, but we don't - * allow S-1-5-21-0-0-0 as this is used - * for claims and compound identities. - */ - ok = dom_sid_is_valid_account_domain(r->in.info->sid); - if (!ok) { - return NT_STATUS_INVALID_PARAMETER; - } - - dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name); - if (dns_encoded == NULL) { - return NT_STATUS_NO_MEMORY; - } - netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); - if (netbios_encoded == NULL) { - return NT_STATUS_NO_MEMORY; - } - sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid); - if (sid_encoded == NULL) { - return NT_STATUS_NO_MEMORY; - } - - trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); - if (!trusted_domain_state) { - return NT_STATUS_NO_MEMORY; - } - trusted_domain_state->policy = policy_state; - - if (strcasecmp(netbios_name, "BUILTIN") == 0 - || (strcasecmp(dns_name, "BUILTIN") == 0) - || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (strcasecmp(netbios_name, policy_state->domain_name) == 0 - || strcasecmp(netbios_name, policy_state->domain_dns) == 0 - || strcasecmp(dns_name, policy_state->domain_dns) == 0 - || strcasecmp(dns_name, policy_state->domain_name) == 0 - || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) { - return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED; - } - /* While this is a REF pointer, some of the functions that wrap this don't provide this */ if (op == NDR_LSA_CREATETRUSTEDDOMAIN) { /* No secrets are created at this time, for this function */ @@ -1242,6 +1231,25 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc trustAuthOutgoing = data_blob(NULL, 0); } + dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name); + if (dns_encoded == NULL) { + return NT_STATUS_NO_MEMORY; + } + netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); + if (netbios_encoded == NULL) { + return NT_STATUS_NO_MEMORY; + } + sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid); + if (sid_encoded == NULL) { + return NT_STATUS_NO_MEMORY; + } + + trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); + if (!trusted_domain_state) { + return NT_STATUS_NO_MEMORY; + } + trusted_domain_state->policy = policy_state; + ret = ldb_transaction_start(sam_ldb); if (ret != LDB_SUCCESS) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -1423,7 +1431,28 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_ TALLOC_CTX *mem_ctx, struct lsa_CreateTrustedDomainEx2 *r) { - return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2, NULL); + struct dcesrv_handle *policy_handle = NULL; + NTSTATUS status; + + ZERO_STRUCTP(r->out.trustdom_handle); + DCESRV_PULL_HANDLE(policy_handle, + r->in.policy_handle, + LSA_HANDLE_POLICY); + + status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx, + policy_handle, + r->in.info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return dcesrv_lsa_CreateTrustedDomain_base( + dce_call, + mem_ctx, + policy_handle, + r, + NDR_LSA_CREATETRUSTEDDOMAINEX2, + NULL); } /* lsa_CreateTrustedDomainEx @@ -1433,11 +1462,32 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_c struct lsa_CreateTrustedDomainEx *r) { struct lsa_CreateTrustedDomainEx2 r2 = {}; + struct dcesrv_handle *policy_handle = NULL; + NTSTATUS status; + + ZERO_STRUCTP(r->out.trustdom_handle); + DCESRV_PULL_HANDLE(policy_handle, + r->in.policy_handle, + LSA_HANDLE_POLICY); + + status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx, + policy_handle, + r->in.info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } r2.in.policy_handle = r->in.policy_handle; r2.in.info = r->in.info; r2.out.trustdom_handle = r->out.trustdom_handle; - return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX, r->in.auth_info); + + return dcesrv_lsa_CreateTrustedDomain_base( + dce_call, + mem_ctx, + policy_handle, + &r2, + NDR_LSA_CREATETRUSTEDDOMAINEX, + r->in.auth_info); } /* @@ -1447,6 +1497,13 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal struct lsa_CreateTrustedDomain *r) { struct lsa_CreateTrustedDomainEx2 r2 = {}; + struct dcesrv_handle *policy_handle = NULL; + NTSTATUS status; + + ZERO_STRUCTP(r->out.trustdom_handle); + DCESRV_PULL_HANDLE(policy_handle, + r->in.policy_handle, + LSA_HANDLE_POLICY); r2.in.policy_handle = r->in.policy_handle; r2.in.info = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoInfoEx); @@ -1461,10 +1518,23 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL; r2.in.info->trust_attributes = 0; + status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx, + policy_handle, + r2.in.info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + r2.in.access_mask = r->in.access_mask; r2.out.trustdom_handle = r->out.trustdom_handle; - return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL); + return dcesrv_lsa_CreateTrustedDomain_base( + dce_call, + mem_ctx, + policy_handle, + &r2, + NDR_LSA_CREATETRUSTEDDOMAIN, + NULL); } static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(