From: Stefan Metzmacher Date: Wed, 5 Feb 2025 17:05:46 +0000 (+0100) Subject: s4:rpc_server/lsa: always add msDS-TrustForestTrustInfo if FOREST_TRANSITIVE is set X-Git-Tag: tevent-0.17.0~708 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddf2fe42443590e7e05d30797758c846ea2f2319;p=thirdparty%2Fsamba.git s4:rpc_server/lsa: always add msDS-TrustForestTrustInfo if FOREST_TRANSITIVE is set Windows (at least server 2025) always creates the default msDS-TrustForestTrustInfo, with just a TOP_LEVEL_NAME and DOMAIN_INFO representing the forest root domain of the trust. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 2acdb9b6fb6..d4c3b6acf71 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -77,6 +77,10 @@ static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_c return lsarpc__op_init_server(dce_ctx, ep_server); } +static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + struct lsa_TrustDomainInfoInfoEx *info_ex); + /* this type allows us to distinguish handle types */ @@ -1243,6 +1247,40 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_precheck( return NT_STATUS_OK; } +static NTSTATUS dcesrv_lsa_default_forest_trust_info(TALLOC_CTX *mem_ctx, + const struct dom_sid *sid, + const char *dns_name, + const char *nbt_name, + DATA_BLOB *_ft_blob) +{ + struct ForestTrustInfo *trust_fti = NULL; + DATA_BLOB ft_blob = {}; + enum ndr_err_code ndr_err; + struct timeval tv = timeval_current(); + NTTIME now = timeval_to_nttime(&tv); + NTSTATUS status; + + status = dsdb_trust_default_forest_info(mem_ctx, + sid, + dns_name, + nbt_name, + now, + &trust_fti); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti, + (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo); + TALLOC_FREE(trust_fti); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + *_ft_blob = ft_blob; + return NT_STATUS_OK; +} + static NTSTATUS dcesrv_lsa_CreateTrustedDomain_common(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dcesrv_handle *policy_handle, @@ -1429,6 +1467,29 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_common(struct dcesrv_call_state * } } + if (info->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { + DATA_BLOB ft_blob = {}; + + status = dcesrv_lsa_default_forest_trust_info(mem_ctx, + info->sid, + dns_name, + netbios_name, + &ft_blob); + if (!NT_STATUS_IS_OK(status)) { + ldb_transaction_cancel(sam_ldb); + return status; + } + + ret = ldb_msg_add_value(msg, + "msDS-TrustForestTrustInfo", + &ft_blob, + NULL); + if (ret != LDB_SUCCESS) { + ldb_transaction_cancel(sam_ldb); + return NT_STATUS_NO_MEMORY; + } + } + trusted_domain_state->trusted_domain_dn = ldb_dn_copy( trusted_domain_state, msg->dn); @@ -2066,6 +2127,7 @@ static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, bool del_outgoing = false; bool del_incoming = false; bool del_forest_info = false; + bool add_forest_info = false; bool in_transaction = false; int ret; bool am_rodc; @@ -2288,6 +2350,14 @@ static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, if (orig_forest_el != NULL) { del_forest_info = true; } + } else if (changed_attrs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { + struct ldb_message_element *orig_forest_el = NULL; + + orig_forest_el = ldb_msg_find_element(dom_msg, + "msDS-TrustForestTrustInfo"); + if (orig_forest_el == NULL) { + add_forest_info = true; + } } } @@ -2338,6 +2408,34 @@ static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, return NT_STATUS_NO_MEMORY; } } + if (add_forest_info) { + struct lsa_TrustDomainInfoInfoEx tmp = {}; + DATA_BLOB ft_blob = {}; + + nt_status = fill_trust_domain_ex(mem_ctx, + dom_msg, + &tmp); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + nt_status = dcesrv_lsa_default_forest_trust_info(mem_ctx, + tmp.sid, + tmp.domain_name.string, + tmp.netbios_name.string, + &ft_blob); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + ret = ldb_msg_add_value(msg, + "msDS-TrustForestTrustInfo", + &ft_blob, + NULL); + if (ret != LDB_SUCCESS) { + return NT_STATUS_NO_MEMORY; + } + } /* start transaction */ ret = ldb_transaction_start(p_state->sam_ldb);