]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libcli/security: split trust_forest_info_* functions into samba-security-trusts
authorStefan Metzmacher <metze@samba.org>
Fri, 14 Mar 2025 08:30:03 +0000 (09:30 +0100)
committerRalph Boehme <slow@samba.org>
Thu, 3 Apr 2025 09:36:31 +0000 (09:36 +0000)
This will avoid dependency loops in following commits.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
libcli/lsarpc/util_lsarpc.c
libcli/lsarpc/util_lsarpc.h
libcli/security/security.h
libcli/security/trust_forest_info.c [new file with mode: 0644]
libcli/security/trust_forest_info.h [new file with mode: 0644]
libcli/security/wscript_build
source3/wscript_build
source4/dsdb/wscript_build

index 2a5752b4610af528aef23dce3843d043fb136cf6..96c98487a7e94a2a303eb47f81bccf77a8eddc04 100644 (file)
 */
 
 #include "includes.h"
-#include "lib/util/dns_cmp.h"
 #include "../librpc/gen_ndr/ndr_drsblobs.h"
 #include "../librpc/gen_ndr/ndr_lsa.h"
 #include "libcli/lsarpc/util_lsarpc.h"
-#include "libcli/security/dom_sid.h"
 
 static NTSTATUS ai_array_2_trust_domain_info_buffer(TALLOC_CTX *mem_ctx,
                                uint32_t count,
@@ -359,948 +357,3 @@ NTSTATUS auth_info_2_auth_blob(TALLOC_CTX *mem_ctx,
 
        return NT_STATUS_OK;
 }
-
-static NTSTATUS trust_forest_record_from_lsa(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustRecord2 *lftr,
-                               struct ForestTrustInfoRecord *ftr)
-{
-       struct ForestTrustString *str = NULL;
-       const struct lsa_StringLarge *lstr = NULL;
-       const struct lsa_ForestTrustDomainInfo *linfo = NULL;
-       struct ForestTrustDataDomainInfo *info = NULL;
-       DATA_BLOB blob = { .length = 0, };
-
-       if (lftr == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       ftr->flags = lftr->flags;
-       ftr->timestamp = lftr->time;
-
-       switch (lftr->type) {
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
-               ftr->type = FOREST_TRUST_TOP_LEVEL_NAME;
-
-               lstr = &lftr->forest_trust_data.top_level_name;
-               str = &ftr->data.name;
-
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
-               ftr->type = FOREST_TRUST_TOP_LEVEL_NAME_EX;
-
-               lstr = &lftr->forest_trust_data.top_level_name_ex;
-               str = &ftr->data.name;
-
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_DOMAIN_INFO:
-               ftr->type = FOREST_TRUST_DOMAIN_INFO;
-
-               linfo = &lftr->forest_trust_data.domain_info;
-               info = &ftr->data.info;
-
-               if (linfo->domain_sid == NULL) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-               info->sid = *linfo->domain_sid;
-
-               lstr = &linfo->dns_domain_name;
-               str = &info->dns_name;
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lstr = &linfo->netbios_domain_name;
-               str = &info->netbios_name;
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_BINARY_DATA:
-               ftr->type = FOREST_TRUST_BINARY_DATA;
-
-               blob = data_blob_talloc_named(mem_ctx,
-                                             lftr->forest_trust_data.data.data,
-                                             lftr->forest_trust_data.data.length,
-                                             "BINARY_DATA");
-               if (blob.length != lftr->forest_trust_data.data.length) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               ftr->data.binary.data = blob.data;
-               ftr->data.binary.size = blob.length;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_SCANNER_INFO:
-               ftr->type = FOREST_TRUST_SCANNER_INFO;
-
-               linfo = &lftr->forest_trust_data.scanner_info;
-               info = &ftr->data.scanner_info.info;
-
-               ftr->data.scanner_info.sub_type = FOREST_TRUST_SCANNER_INFO;
-
-               if (linfo->domain_sid != NULL) {
-                       info->sid = *linfo->domain_sid;
-               } else {
-                       info->sid = (struct dom_sid) { .sid_rev_num = 0, };
-               }
-
-               lstr = &linfo->dns_domain_name;
-               str = &info->dns_name;
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lstr = &linfo->netbios_domain_name;
-               str = &info->netbios_name;
-               str->string = talloc_strdup(mem_ctx, lstr->string);
-               if (str->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-       }
-
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-static NTSTATUS trust_forest_record_lsa_resolve_binary(TALLOC_CTX *mem_ctx,
-                               uint32_t flags,
-                               NTTIME time,
-                               const struct lsa_ForestTrustBinaryData *binary,
-                               struct lsa_ForestTrustRecord2 *lftr2)
-{
-       enum ForestTrustInfoRecordType sub_type = FOREST_TRUST_BINARY_DATA;
-       DATA_BLOB blob = { .length = 0, };
-
-       if (binary == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       /*
-        * Note 'binary' may points to
-        * lftr2->forest_trust_data.data
-        *
-        * So we remember the relevant
-        * information in blob and clear
-        * the binary pointer in order
-        * to avoid touching it again.
-        *
-        * Because we likely change
-        * the lftr2->forest_trust_data union
-        */
-       blob.data = binary->data;
-       blob.length = binary->length;
-       binary = NULL;
-
-       /*
-        * We need at least size and subtype
-        */
-       if (blob.length < 5) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       sub_type = PULL_LE_U8(blob.data, 4);
-
-       /*
-        * Only levels above LSA_FOREST_TRUST_DOMAIN_INFO
-        * are handled as binary.
-        */
-       if (sub_type <= FOREST_TRUST_BINARY_DATA) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       lftr2->flags = flags;
-       lftr2->time = time;
-
-       /*
-        * Depending if the sub_type is wellknown the information is upgraded,
-        * currently only for the LSA_FOREST_TRUST_SCANNER_INFO records.
-        */
-
-       if (sub_type == FOREST_TRUST_SCANNER_INFO) {
-               struct lsa_ForestTrustDomainInfo *d_sdi = NULL;
-               union ForestTrustData fta = { .unknown = { .size = 0, }, };
-               const struct ForestTrustDataDomainInfo *s_sdi = NULL;
-               enum ndr_err_code ndr_err;
-
-               ndr_err = ndr_pull_union_blob(&blob,
-                                             mem_ctx,
-                                             &fta,
-                                             FOREST_TRUST_SCANNER_INFO,
-                                             (ndr_pull_flags_fn_t)ndr_pull_ForestTrustData);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       return ndr_map_error2ntstatus(ndr_err);
-               }
-
-               if (fta.scanner_info.sub_type != FOREST_TRUST_SCANNER_INFO) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-
-               s_sdi = &fta.scanner_info.info;
-               d_sdi = &lftr2->forest_trust_data.scanner_info;
-
-               d_sdi->dns_domain_name.string = s_sdi->dns_name.string;
-               d_sdi->netbios_domain_name.string = s_sdi->netbios_name.string;
-
-               if (s_sdi->sid_size != 0) {
-                       d_sdi->domain_sid = dom_sid_dup(mem_ctx,
-                                                       &s_sdi->sid);
-                       if (d_sdi->domain_sid == NULL) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-               } else {
-                       d_sdi->domain_sid = NULL;
-               }
-
-               lftr2->type = LSA_FOREST_TRUST_SCANNER_INFO;
-
-               return NT_STATUS_OK;
-       }
-
-       /*
-        * In all other cases lftr->type is downgraded to
-        * LSA_FOREST_TRUST_BINARY_DATA.
-        */
-
-       lftr2->type = LSA_FOREST_TRUST_BINARY_DATA;
-       lftr2->forest_trust_data.data.data = blob.data;
-       lftr2->forest_trust_data.data.length = blob.length;
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS trust_forest_record_lsa_1to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustRecord *lftr,
-                               struct lsa_ForestTrustRecord2 *lftr2)
-{
-       const struct lsa_ForestTrustBinaryData *binary = NULL;
-
-       if (lftr == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       lftr2->flags = lftr->flags;
-       lftr2->time = lftr->time;
-
-       switch (lftr->type) {
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
-               lftr2->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
-               lftr2->forest_trust_data.top_level_name =
-                       lftr->forest_trust_data.top_level_name;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
-               lftr2->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
-               lftr2->forest_trust_data.top_level_name_ex =
-                       lftr->forest_trust_data.top_level_name_ex;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_DOMAIN_INFO:
-               lftr2->type = LSA_FOREST_TRUST_DOMAIN_INFO;
-               lftr2->forest_trust_data.domain_info =
-                       lftr->forest_trust_data.domain_info;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_BINARY_DATA:
-       case LSA_FOREST_TRUST_SCANNER_INFO:
-               /* just to avoid the missing enum switch warning */
-               break;
-       }
-
-       /*
-        * All levels above LSA_FOREST_TRUST_DOMAIN_INFO are handled as binary.
-        *
-        * Depending if the sub_type is wellknown the information is upgraded,
-        * currently only for the LSA_FOREST_TRUST_SCANNER_INFO records.
-        *
-        * In all other cases lftr->type is downgraded to
-        * LSA_FOREST_TRUST_BINARY_DATA.
-        */
-
-       binary = &lftr->forest_trust_data.data;
-
-       return trust_forest_record_lsa_resolve_binary(mem_ctx,
-                                                     lftr->flags,
-                                                     lftr->time,
-                                                     binary,
-                                                     lftr2);
-}
-
-NTSTATUS trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation *lfti,
-                               struct ForestTrustInfo **_fti)
-{
-       struct ForestTrustInfo *fti;
-       uint32_t i;
-
-       *_fti = NULL;
-
-       fti = talloc_zero(mem_ctx, struct ForestTrustInfo);
-       if (fti == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       fti->version = 1;
-       fti->count = lfti->count;
-       fti->records = talloc_zero_array(fti,
-                                        struct ForestTrustInfoRecordArmor,
-                                        fti->count);
-       if (fti->records == NULL) {
-               TALLOC_FREE(fti);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i = 0; i < fti->count; i++) {
-               const struct lsa_ForestTrustRecord *lftr = lfti->entries[i];
-               struct lsa_ForestTrustRecord2 lftr2 = { .flags = 0, };
-               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
-               TALLOC_CTX *frame = talloc_stackframe();
-               NTSTATUS status;
-
-               status = trust_forest_record_lsa_1to2(frame,
-                                                     lftr,
-                                                     &lftr2);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(frame);
-                       TALLOC_FREE(fti);
-                       return status;
-               }
-
-               status = trust_forest_record_from_lsa(fti->records,
-                                                     &lftr2,
-                                                     ftr);
-               TALLOC_FREE(frame);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(fti);
-                       return status;
-               }
-       }
-
-       *_fti = fti;
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS trust_forest_record_to_lsa(TALLOC_CTX *mem_ctx,
-                                       const struct ForestTrustInfoRecord *ftr,
-                                       struct lsa_ForestTrustRecord2 *lftr)
-{
-       const struct ForestTrustString *str = NULL;
-       struct lsa_StringLarge *lstr = NULL;
-       const struct ForestTrustDataDomainInfo *info = NULL;
-       struct lsa_ForestTrustDomainInfo *linfo = NULL;
-       DATA_BLOB blob = { .length = 0, };
-
-       lftr->flags = ftr->flags;
-       lftr->time = ftr->timestamp;
-
-       switch (ftr->type) {
-       case FOREST_TRUST_TOP_LEVEL_NAME:
-               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
-
-               lstr = &lftr->forest_trust_data.top_level_name;
-               str = &ftr->data.name;
-
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case FOREST_TRUST_TOP_LEVEL_NAME_EX:
-               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
-
-               lstr = &lftr->forest_trust_data.top_level_name_ex;
-               str = &ftr->data.name;
-
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case FOREST_TRUST_DOMAIN_INFO:
-               lftr->type = LSA_FOREST_TRUST_DOMAIN_INFO;
-
-               linfo = &lftr->forest_trust_data.domain_info;
-               info = &ftr->data.info;
-
-               linfo->domain_sid = dom_sid_dup(mem_ctx, &info->sid);
-               if (linfo->domain_sid == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lstr = &linfo->dns_domain_name;
-               str = &info->dns_name;
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lstr = &linfo->netbios_domain_name;
-               str = &info->netbios_name;
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-
-       case FOREST_TRUST_BINARY_DATA:
-               lftr->type = LSA_FOREST_TRUST_BINARY_DATA;
-
-               blob = data_blob_talloc_named(mem_ctx,
-                                             ftr->data.binary.data,
-                                             ftr->data.binary.size,
-                                             "BINARY_DATA");
-               if (blob.length != ftr->data.binary.size) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lftr->forest_trust_data.data.data = blob.data;
-               lftr->forest_trust_data.data.length = blob.length;
-
-               return NT_STATUS_OK;
-
-       case FOREST_TRUST_SCANNER_INFO:
-               lftr->type = LSA_FOREST_TRUST_SCANNER_INFO;
-
-               linfo = &lftr->forest_trust_data.scanner_info;
-               info = &ftr->data.scanner_info.info;
-
-               if (info->sid_size != 0) {
-                       linfo->domain_sid = dom_sid_dup(mem_ctx,
-                                                       &info->sid);
-                       if (linfo->domain_sid == NULL) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-               } else {
-                       linfo->domain_sid = NULL;
-               }
-
-               lstr = &linfo->dns_domain_name;
-               str = &info->dns_name;
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               lstr = &linfo->netbios_domain_name;
-               str = &info->netbios_name;
-               lstr->string = talloc_strdup(mem_ctx, str->string);
-               if (lstr->string == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               return NT_STATUS_OK;
-       }
-
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-static NTSTATUS trust_forest_record_lsa_2to1(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustRecord2 *lftr2,
-                               struct lsa_ForestTrustRecord *lftr)
-{
-       const struct lsa_ForestTrustDomainInfo *s_sdi = NULL;
-       union ForestTrustData fta = { .unknown = { .size = 0, }, };
-       struct ForestTrustDataDomainInfo *d_sdi = NULL;
-       enum ndr_err_code ndr_err;
-       DATA_BLOB blob = { .length = 0, };
-
-       if (lftr2 == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       lftr->flags = lftr2->flags;
-       lftr->time = lftr2->time;
-
-       switch (lftr2->type) {
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
-               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
-               lftr->forest_trust_data.top_level_name =
-                       lftr2->forest_trust_data.top_level_name;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
-               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
-               lftr->forest_trust_data.top_level_name_ex =
-                       lftr2->forest_trust_data.top_level_name_ex;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_DOMAIN_INFO:
-               lftr->type = LSA_FOREST_TRUST_DOMAIN_INFO;
-               lftr->forest_trust_data.domain_info =
-                       lftr2->forest_trust_data.domain_info;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_BINARY_DATA:
-               lftr->type = LSA_FOREST_TRUST_BINARY_DATA;
-               lftr->forest_trust_data.data =
-                       lftr2->forest_trust_data.data;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_SCANNER_INFO:
-               fta.scanner_info.sub_type = FOREST_TRUST_SCANNER_INFO;
-               s_sdi = &lftr2->forest_trust_data.scanner_info;
-               d_sdi = &fta.scanner_info.info;
-
-               if (s_sdi->domain_sid != NULL) {
-                       d_sdi->sid = *s_sdi->domain_sid;
-               } else {
-                       d_sdi->sid = (struct dom_sid) { .sid_rev_num = 0, };
-               }
-
-               d_sdi->dns_name.string = s_sdi->dns_domain_name.string;
-               d_sdi->netbios_name.string = s_sdi->netbios_domain_name.string;
-
-               ndr_err = ndr_push_union_blob(&blob,
-                                             mem_ctx,
-                                             &fta,
-                                             FOREST_TRUST_SCANNER_INFO,
-                                             (ndr_push_flags_fn_t)ndr_push_ForestTrustData);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       return ndr_map_error2ntstatus(ndr_err);
-               }
-
-               lftr->type = LSA_FOREST_TRUST_SCANNER_INFO;
-               lftr->forest_trust_data.data.data = blob.data;
-               lftr->forest_trust_data.data.length = blob.length;
-
-               return NT_STATUS_OK;
-       }
-
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-NTSTATUS trust_forest_info_to_lsa(TALLOC_CTX *mem_ctx,
-                                 const struct ForestTrustInfo *fti,
-                                 struct lsa_ForestTrustInformation **_lfti)
-{
-       struct lsa_ForestTrustInformation *lfti;
-       uint32_t i;
-
-       *_lfti = NULL;
-
-       if (fti->version != 1) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       lfti = talloc_zero(mem_ctx, struct lsa_ForestTrustInformation);
-       if (lfti == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       lfti->count = fti->count;
-       lfti->entries = talloc_zero_array(mem_ctx,
-                                         struct lsa_ForestTrustRecord *,
-                                         lfti->count);
-       if (lfti->entries == NULL) {
-               TALLOC_FREE(lfti);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i = 0; i < fti->count; i++) {
-               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
-               struct lsa_ForestTrustRecord2 lftr2 = { .flags = 0, };
-               struct lsa_ForestTrustRecord *lftr = NULL;
-               NTSTATUS status;
-
-               lftr = talloc_zero(lfti->entries,
-                                  struct lsa_ForestTrustRecord);
-               if (lftr == NULL) {
-                       TALLOC_FREE(lfti);
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               status = trust_forest_record_to_lsa(lftr, ftr, &lftr2);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(lfti);
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               status = trust_forest_record_lsa_2to1(lftr, &lftr2, lftr);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(lfti);
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lfti->entries[i] = lftr;
-       }
-
-       *_lfti = lfti;
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS trust_forest_record_lsa_2to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustRecord2 *in,
-                               struct lsa_ForestTrustRecord2 *out)
-{
-       const struct lsa_ForestTrustBinaryData *binary = NULL;
-
-       if (in == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       out->flags = in->flags;
-       out->time = in->time;
-
-       switch (in->type) {
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
-               out->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
-               out->forest_trust_data.top_level_name =
-                       in->forest_trust_data.top_level_name;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
-               out->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
-               out->forest_trust_data.top_level_name_ex =
-                       in->forest_trust_data.top_level_name_ex;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_DOMAIN_INFO:
-               out->type = LSA_FOREST_TRUST_DOMAIN_INFO;
-               out->forest_trust_data.domain_info =
-                       in->forest_trust_data.domain_info;
-
-               return NT_STATUS_OK;
-
-       case LSA_FOREST_TRUST_BINARY_DATA:
-               binary = &in->forest_trust_data.data;
-
-               return trust_forest_record_lsa_resolve_binary(mem_ctx,
-                                                             in->flags,
-                                                             in->time,
-                                                             binary,
-                                                             out);
-
-       case LSA_FOREST_TRUST_SCANNER_INFO:
-               out->type = LSA_FOREST_TRUST_SCANNER_INFO;
-               out->forest_trust_data.domain_info =
-                       in->forest_trust_data.domain_info;
-
-               return NT_STATUS_OK;
-       }
-
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-NTSTATUS trust_forest_info_from_lsa2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *lfti,
-                               struct ForestTrustInfo **_fti)
-{
-       struct ForestTrustInfo *fti;
-       uint32_t i;
-
-       *_fti = NULL;
-
-       fti = talloc_zero(mem_ctx, struct ForestTrustInfo);
-       if (fti == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       fti->version = 1;
-       fti->count = lfti->count;
-       fti->records = talloc_zero_array(fti,
-                                        struct ForestTrustInfoRecordArmor,
-                                        fti->count);
-       if (fti->records == NULL) {
-               TALLOC_FREE(fti);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i = 0; i < fti->count; i++) {
-               const struct lsa_ForestTrustRecord2 *lftr2 = lfti->entries[i];
-               struct lsa_ForestTrustRecord2 _lftr2 = { .flags = 0, };
-               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
-               TALLOC_CTX *frame = talloc_stackframe();
-               NTSTATUS status;
-
-               status = trust_forest_record_lsa_2to2(frame,
-                                                     lftr2,
-                                                     &_lftr2);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(frame);
-                       TALLOC_FREE(fti);
-                       return status;
-               }
-
-               status = trust_forest_record_from_lsa(fti->records,
-                                                     &_lftr2,
-                                                     ftr);
-               TALLOC_FREE(frame);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(fti);
-                       return status;
-               }
-       }
-
-       *_fti = fti;
-       return NT_STATUS_OK;
-}
-
-NTSTATUS trust_forest_info_to_lsa2(TALLOC_CTX *mem_ctx,
-                                  const struct ForestTrustInfo *fti,
-                                  struct lsa_ForestTrustInformation2 **_lfti)
-{
-       struct lsa_ForestTrustInformation2 *lfti;
-       uint32_t i;
-
-       *_lfti = NULL;
-
-       if (fti->version != 1) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       lfti = talloc_zero(mem_ctx, struct lsa_ForestTrustInformation2);
-       if (lfti == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       lfti->count = fti->count;
-       lfti->entries = talloc_zero_array(mem_ctx,
-                                         struct lsa_ForestTrustRecord2 *,
-                                         lfti->count);
-       if (lfti->entries == NULL) {
-               TALLOC_FREE(lfti);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i = 0; i < fti->count; i++) {
-               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
-               struct lsa_ForestTrustRecord2 *lftr2 = NULL;
-               NTSTATUS status;
-
-               lftr2 = talloc_zero(lfti->entries,
-                                   struct lsa_ForestTrustRecord2);
-               if (lftr2 == NULL) {
-                       TALLOC_FREE(lfti);
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               status = trust_forest_record_to_lsa(lftr2, ftr, lftr2);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(lfti);
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               lfti->entries[i] = lftr2;
-       }
-
-       *_lfti = lfti;
-       return NT_STATUS_OK;
-}
-
-NTSTATUS trust_forest_info_lsa_1to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation *lfti,
-                               struct lsa_ForestTrustInformation2 **_lfti2)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct ForestTrustInfo *fti = NULL;
-       struct lsa_ForestTrustInformation2 *lfti2 = NULL;
-       NTSTATUS status;
-
-       status = trust_forest_info_from_lsa(frame, lfti, &fti);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       status = trust_forest_info_to_lsa2(mem_ctx,
-                                          fti,
-                                          &lfti2);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       *_lfti2 = lfti2;
-       TALLOC_FREE(frame);
-       return NT_STATUS_OK;
-}
-
-NTSTATUS trust_forest_info_lsa_2to1(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *lfti2,
-                               struct lsa_ForestTrustInformation **_lfti)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct ForestTrustInfo *fti = NULL;
-       struct lsa_ForestTrustInformation *lfti = NULL;
-       NTSTATUS status;
-
-       status = trust_forest_info_from_lsa2(frame, lfti2, &fti);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       status = trust_forest_info_to_lsa(mem_ctx,
-                                         fti,
-                                         &lfti);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       *_lfti = lfti;
-       TALLOC_FREE(frame);
-       return NT_STATUS_OK;
-}
-
-NTSTATUS trust_forest_info_lsa_2to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *in,
-                               struct lsa_ForestTrustInformation2 **_out)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct ForestTrustInfo *fti = NULL;
-       struct lsa_ForestTrustInformation2 *out = NULL;
-       NTSTATUS status;
-
-       status = trust_forest_info_from_lsa2(frame, in, &fti);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       status = trust_forest_info_to_lsa2(mem_ctx,
-                                          fti,
-                                          &out);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
-               return status;
-       }
-
-       *_out = out;
-       TALLOC_FREE(frame);
-       return NT_STATUS_OK;
-}
-
-static int trust_forest_info_tln_match_internal(
-               const struct lsa_ForestTrustInformation2 *info,
-               enum lsa_ForestTrustRecordType type,
-               uint32_t disable_mask,
-               const char *tln)
-{
-       uint32_t i;
-
-       for (i = 0; i < info->count; i++) {
-               struct lsa_ForestTrustRecord2 *e = info->entries[i];
-               struct lsa_StringLarge *t = NULL;
-               int cmp;
-
-               if (e == NULL) {
-                       continue;
-               }
-
-               if (e->type != type) {
-                       continue;
-               }
-
-               if (e->flags & disable_mask) {
-                       continue;
-               }
-
-               switch (type) {
-               case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
-                       t = &e->forest_trust_data.top_level_name;
-                       break;
-               case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
-                       t = &e->forest_trust_data.top_level_name_ex;
-                       break;
-               default:
-                       break;
-               }
-
-               if (t == NULL) {
-                       continue;
-               }
-
-               cmp = dns_cmp(tln, t->string);
-               switch (cmp) {
-               case DNS_CMP_MATCH:
-               case DNS_CMP_FIRST_IS_CHILD:
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-bool trust_forest_info_tln_match(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln)
-{
-       int m;
-
-       m = trust_forest_info_tln_match_internal(info,
-                                       LSA_FOREST_TRUST_TOP_LEVEL_NAME,
-                                       LSA_TLN_DISABLED_MASK,
-                                       tln);
-       if (m != -1) {
-               return true;
-       }
-
-       return false;
-}
-
-bool trust_forest_info_tln_ex_match(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln)
-{
-       int m;
-
-       m = trust_forest_info_tln_match_internal(info,
-                                       LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX,
-                                       0,
-                                       tln);
-       if (m != -1) {
-               return true;
-       }
-
-       return false;
-}
-
-bool trust_forest_info_match_tln_namespace(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln)
-{
-       bool match;
-
-       match = trust_forest_info_tln_ex_match(info, tln);
-       if (match) {
-               return false;
-       }
-
-       match = trust_forest_info_tln_match(info, tln);
-       if (!match) {
-               return false;
-       }
-
-       return true;
-}
index 5fa6fed1e3e0c6a31848382faa37dfcd9024ebef..4dc6546743642af59e179c5a42352ada74ac03b9 100644 (file)
@@ -24,9 +24,6 @@
 struct lsa_TrustDomainInfoAuthInfo;
 struct lsa_TrustDomainInfoBuffer;
 struct trustAuthInOutBlob;
-struct ForestTrustInfo;
-struct lsa_ForestTrustInformation;
-struct lsa_ForestTrustInformation2;
 
 NTSTATUS auth_blob_2_auth_info(TALLOC_CTX *mem_ctx,
                               DATA_BLOB incoming, DATA_BLOB outgoing,
@@ -40,36 +37,4 @@ NTSTATUS auth_info_2_auth_blob(TALLOC_CTX *mem_ctx,
                               struct lsa_TrustDomainInfoAuthInfo *auth_info,
                               DATA_BLOB *incoming, DATA_BLOB *outgoing);
 
-NTSTATUS trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation *lfti,
-                               struct ForestTrustInfo **_fti);
-NTSTATUS trust_forest_info_to_lsa(TALLOC_CTX *mem_ctx,
-                                 const struct ForestTrustInfo *fti,
-                                 struct lsa_ForestTrustInformation **_lfti);
-NTSTATUS trust_forest_info_from_lsa2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *lfti,
-                               struct ForestTrustInfo **_fti);
-NTSTATUS trust_forest_info_to_lsa2(TALLOC_CTX *mem_ctx,
-                                  const struct ForestTrustInfo *fti,
-                                  struct lsa_ForestTrustInformation2 **_lfti);
-NTSTATUS trust_forest_info_lsa_1to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation *lfti,
-                               struct lsa_ForestTrustInformation2 **_lfti2);
-NTSTATUS trust_forest_info_lsa_2to1(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *lfti2,
-                               struct lsa_ForestTrustInformation **_lfti);
-NTSTATUS trust_forest_info_lsa_2to2(TALLOC_CTX *mem_ctx,
-                               const struct lsa_ForestTrustInformation2 *in,
-                               struct lsa_ForestTrustInformation2 **_out);
-
-bool trust_forest_info_tln_match(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln);
-bool trust_forest_info_tln_ex_match(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln);
-bool trust_forest_info_match_tln_namespace(
-               const struct lsa_ForestTrustInformation2 *info,
-               const char *tln);
-
 #endif /* _LIBCLI_AUTH_UTIL_LSARPC_H_ */
index a1c26ed57f4797fe4be8a1ec7b6e4e42acd766d6..d42e4c6973b5d7c445782d06969cb5fb4c1cb9a5 100644 (file)
@@ -117,5 +117,6 @@ struct object_tree {
 #include "libcli/security/access_check.h"
 #include "libcli/security/session.h"
 #include "libcli/security/display_sec.h"
+#include "libcli/security/trust_forest_info.h"
 
 #endif
diff --git a/libcli/security/trust_forest_info.c b/libcli/security/trust_forest_info.c
new file mode 100644 (file)
index 0000000..7bb2c40
--- /dev/null
@@ -0,0 +1,971 @@
+/*
+   Unix SMB/CIFS implementation.
+   Authentication utility functions
+   Copyright (C) Stefan Metzmacher 2018,2025
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "libcli/security/security.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
+#include "lib/util/talloc_stack.h"
+#include "lib/util/bytearray.h"
+#include "lib/util/dns_cmp.h"
+
+static NTSTATUS trust_forest_record_from_lsa(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustRecord2 *lftr,
+                               struct ForestTrustInfoRecord *ftr)
+{
+       struct ForestTrustString *str = NULL;
+       const struct lsa_StringLarge *lstr = NULL;
+       const struct lsa_ForestTrustDomainInfo *linfo = NULL;
+       struct ForestTrustDataDomainInfo *info = NULL;
+       DATA_BLOB blob = { .length = 0, };
+
+       if (lftr == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       ftr->flags = lftr->flags;
+       ftr->timestamp = lftr->time;
+
+       switch (lftr->type) {
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+               ftr->type = FOREST_TRUST_TOP_LEVEL_NAME;
+
+               lstr = &lftr->forest_trust_data.top_level_name;
+               str = &ftr->data.name;
+
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+               ftr->type = FOREST_TRUST_TOP_LEVEL_NAME_EX;
+
+               lstr = &lftr->forest_trust_data.top_level_name_ex;
+               str = &ftr->data.name;
+
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_DOMAIN_INFO:
+               ftr->type = FOREST_TRUST_DOMAIN_INFO;
+
+               linfo = &lftr->forest_trust_data.domain_info;
+               info = &ftr->data.info;
+
+               if (linfo->domain_sid == NULL) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               info->sid = *linfo->domain_sid;
+
+               lstr = &linfo->dns_domain_name;
+               str = &info->dns_name;
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lstr = &linfo->netbios_domain_name;
+               str = &info->netbios_name;
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_BINARY_DATA:
+               ftr->type = FOREST_TRUST_BINARY_DATA;
+
+               blob = data_blob_talloc_named(mem_ctx,
+                                             lftr->forest_trust_data.data.data,
+                                             lftr->forest_trust_data.data.length,
+                                             "BINARY_DATA");
+               if (blob.length != lftr->forest_trust_data.data.length) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               ftr->data.binary.data = blob.data;
+               ftr->data.binary.size = blob.length;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_SCANNER_INFO:
+               ftr->type = FOREST_TRUST_SCANNER_INFO;
+
+               linfo = &lftr->forest_trust_data.scanner_info;
+               info = &ftr->data.scanner_info.info;
+
+               ftr->data.scanner_info.sub_type = FOREST_TRUST_SCANNER_INFO;
+
+               if (linfo->domain_sid != NULL) {
+                       info->sid = *linfo->domain_sid;
+               } else {
+                       info->sid = (struct dom_sid) { .sid_rev_num = 0, };
+               }
+
+               lstr = &linfo->dns_domain_name;
+               str = &info->dns_name;
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lstr = &linfo->netbios_domain_name;
+               str = &info->netbios_name;
+               str->string = talloc_strdup(mem_ctx, lstr->string);
+               if (str->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+       }
+
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS trust_forest_record_lsa_resolve_binary(TALLOC_CTX *mem_ctx,
+                               uint32_t flags,
+                               NTTIME time,
+                               const struct lsa_ForestTrustBinaryData *binary,
+                               struct lsa_ForestTrustRecord2 *lftr2)
+{
+       enum ForestTrustInfoRecordType sub_type = FOREST_TRUST_BINARY_DATA;
+       DATA_BLOB blob = { .length = 0, };
+
+       if (binary == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /*
+        * Note 'binary' may points to
+        * lftr2->forest_trust_data.data
+        *
+        * So we remember the relevant
+        * information in blob and clear
+        * the binary pointer in order
+        * to avoid touching it again.
+        *
+        * Because we likely change
+        * the lftr2->forest_trust_data union
+        */
+       blob.data = binary->data;
+       blob.length = binary->length;
+       binary = NULL;
+
+       /*
+        * We need at least size and subtype
+        */
+       if (blob.length < 5) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       sub_type = PULL_LE_U8(blob.data, 4);
+
+       /*
+        * Only levels above LSA_FOREST_TRUST_DOMAIN_INFO
+        * are handled as binary.
+        */
+       if (sub_type <= FOREST_TRUST_BINARY_DATA) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       lftr2->flags = flags;
+       lftr2->time = time;
+
+       /*
+        * Depending if the sub_type is wellknown the information is upgraded,
+        * currently only for the LSA_FOREST_TRUST_SCANNER_INFO records.
+        */
+
+       if (sub_type == FOREST_TRUST_SCANNER_INFO) {
+               struct lsa_ForestTrustDomainInfo *d_sdi = NULL;
+               union ForestTrustData fta = { .unknown = { .size = 0, }, };
+               const struct ForestTrustDataDomainInfo *s_sdi = NULL;
+               enum ndr_err_code ndr_err;
+
+               ndr_err = ndr_pull_union_blob(&blob,
+                                             mem_ctx,
+                                             &fta,
+                                             FOREST_TRUST_SCANNER_INFO,
+                                             (ndr_pull_flags_fn_t)ndr_pull_ForestTrustData);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return ndr_map_error2ntstatus(ndr_err);
+               }
+
+               if (fta.scanner_info.sub_type != FOREST_TRUST_SCANNER_INFO) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               s_sdi = &fta.scanner_info.info;
+               d_sdi = &lftr2->forest_trust_data.scanner_info;
+
+               d_sdi->dns_domain_name.string = s_sdi->dns_name.string;
+               d_sdi->netbios_domain_name.string = s_sdi->netbios_name.string;
+
+               if (s_sdi->sid_size != 0) {
+                       d_sdi->domain_sid = dom_sid_dup(mem_ctx,
+                                                       &s_sdi->sid);
+                       if (d_sdi->domain_sid == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       d_sdi->domain_sid = NULL;
+               }
+
+               lftr2->type = LSA_FOREST_TRUST_SCANNER_INFO;
+
+               return NT_STATUS_OK;
+       }
+
+       /*
+        * In all other cases lftr->type is downgraded to
+        * LSA_FOREST_TRUST_BINARY_DATA.
+        */
+
+       lftr2->type = LSA_FOREST_TRUST_BINARY_DATA;
+       lftr2->forest_trust_data.data.data = blob.data;
+       lftr2->forest_trust_data.data.length = blob.length;
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS trust_forest_record_lsa_1to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustRecord *lftr,
+                               struct lsa_ForestTrustRecord2 *lftr2)
+{
+       const struct lsa_ForestTrustBinaryData *binary = NULL;
+
+       if (lftr == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       lftr2->flags = lftr->flags;
+       lftr2->time = lftr->time;
+
+       switch (lftr->type) {
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+               lftr2->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+               lftr2->forest_trust_data.top_level_name =
+                       lftr->forest_trust_data.top_level_name;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+               lftr2->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
+               lftr2->forest_trust_data.top_level_name_ex =
+                       lftr->forest_trust_data.top_level_name_ex;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_DOMAIN_INFO:
+               lftr2->type = LSA_FOREST_TRUST_DOMAIN_INFO;
+               lftr2->forest_trust_data.domain_info =
+                       lftr->forest_trust_data.domain_info;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_BINARY_DATA:
+       case LSA_FOREST_TRUST_SCANNER_INFO:
+               /* just to avoid the missing enum switch warning */
+               break;
+       }
+
+       /*
+        * All levels above LSA_FOREST_TRUST_DOMAIN_INFO are handled as binary.
+        *
+        * Depending if the sub_type is wellknown the information is upgraded,
+        * currently only for the LSA_FOREST_TRUST_SCANNER_INFO records.
+        *
+        * In all other cases lftr->type is downgraded to
+        * LSA_FOREST_TRUST_BINARY_DATA.
+        */
+
+       binary = &lftr->forest_trust_data.data;
+
+       return trust_forest_record_lsa_resolve_binary(mem_ctx,
+                                                     lftr->flags,
+                                                     lftr->time,
+                                                     binary,
+                                                     lftr2);
+}
+
+NTSTATUS trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation *lfti,
+                               struct ForestTrustInfo **_fti)
+{
+       struct ForestTrustInfo *fti;
+       uint32_t i;
+
+       *_fti = NULL;
+
+       fti = talloc_zero(mem_ctx, struct ForestTrustInfo);
+       if (fti == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       fti->version = 1;
+       fti->count = lfti->count;
+       fti->records = talloc_zero_array(fti,
+                                        struct ForestTrustInfoRecordArmor,
+                                        fti->count);
+       if (fti->records == NULL) {
+               TALLOC_FREE(fti);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i = 0; i < fti->count; i++) {
+               const struct lsa_ForestTrustRecord *lftr = lfti->entries[i];
+               struct lsa_ForestTrustRecord2 lftr2 = { .flags = 0, };
+               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
+               TALLOC_CTX *frame = talloc_stackframe();
+               NTSTATUS status;
+
+               status = trust_forest_record_lsa_1to2(frame,
+                                                     lftr,
+                                                     &lftr2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(frame);
+                       TALLOC_FREE(fti);
+                       return status;
+               }
+
+               status = trust_forest_record_from_lsa(fti->records,
+                                                     &lftr2,
+                                                     ftr);
+               TALLOC_FREE(frame);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(fti);
+                       return status;
+               }
+       }
+
+       *_fti = fti;
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS trust_forest_record_to_lsa(TALLOC_CTX *mem_ctx,
+                                       const struct ForestTrustInfoRecord *ftr,
+                                       struct lsa_ForestTrustRecord2 *lftr)
+{
+       const struct ForestTrustString *str = NULL;
+       struct lsa_StringLarge *lstr = NULL;
+       const struct ForestTrustDataDomainInfo *info = NULL;
+       struct lsa_ForestTrustDomainInfo *linfo = NULL;
+       DATA_BLOB blob = { .length = 0, };
+
+       lftr->flags = ftr->flags;
+       lftr->time = ftr->timestamp;
+
+       switch (ftr->type) {
+       case FOREST_TRUST_TOP_LEVEL_NAME:
+               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+
+               lstr = &lftr->forest_trust_data.top_level_name;
+               str = &ftr->data.name;
+
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case FOREST_TRUST_TOP_LEVEL_NAME_EX:
+               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
+
+               lstr = &lftr->forest_trust_data.top_level_name_ex;
+               str = &ftr->data.name;
+
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case FOREST_TRUST_DOMAIN_INFO:
+               lftr->type = LSA_FOREST_TRUST_DOMAIN_INFO;
+
+               linfo = &lftr->forest_trust_data.domain_info;
+               info = &ftr->data.info;
+
+               linfo->domain_sid = dom_sid_dup(mem_ctx, &info->sid);
+               if (linfo->domain_sid == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lstr = &linfo->dns_domain_name;
+               str = &info->dns_name;
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lstr = &linfo->netbios_domain_name;
+               str = &info->netbios_name;
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+
+       case FOREST_TRUST_BINARY_DATA:
+               lftr->type = LSA_FOREST_TRUST_BINARY_DATA;
+
+               blob = data_blob_talloc_named(mem_ctx,
+                                             ftr->data.binary.data,
+                                             ftr->data.binary.size,
+                                             "BINARY_DATA");
+               if (blob.length != ftr->data.binary.size) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lftr->forest_trust_data.data.data = blob.data;
+               lftr->forest_trust_data.data.length = blob.length;
+
+               return NT_STATUS_OK;
+
+       case FOREST_TRUST_SCANNER_INFO:
+               lftr->type = LSA_FOREST_TRUST_SCANNER_INFO;
+
+               linfo = &lftr->forest_trust_data.scanner_info;
+               info = &ftr->data.scanner_info.info;
+
+               if (info->sid_size != 0) {
+                       linfo->domain_sid = dom_sid_dup(mem_ctx,
+                                                       &info->sid);
+                       if (linfo->domain_sid == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       linfo->domain_sid = NULL;
+               }
+
+               lstr = &linfo->dns_domain_name;
+               str = &info->dns_name;
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               lstr = &linfo->netbios_domain_name;
+               str = &info->netbios_name;
+               lstr->string = talloc_strdup(mem_ctx, str->string);
+               if (lstr->string == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               return NT_STATUS_OK;
+       }
+
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS trust_forest_record_lsa_2to1(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustRecord2 *lftr2,
+                               struct lsa_ForestTrustRecord *lftr)
+{
+       const struct lsa_ForestTrustDomainInfo *s_sdi = NULL;
+       union ForestTrustData fta = { .unknown = { .size = 0, }, };
+       struct ForestTrustDataDomainInfo *d_sdi = NULL;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob = { .length = 0, };
+
+       if (lftr2 == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       lftr->flags = lftr2->flags;
+       lftr->time = lftr2->time;
+
+       switch (lftr2->type) {
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+               lftr->forest_trust_data.top_level_name =
+                       lftr2->forest_trust_data.top_level_name;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+               lftr->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
+               lftr->forest_trust_data.top_level_name_ex =
+                       lftr2->forest_trust_data.top_level_name_ex;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_DOMAIN_INFO:
+               lftr->type = LSA_FOREST_TRUST_DOMAIN_INFO;
+               lftr->forest_trust_data.domain_info =
+                       lftr2->forest_trust_data.domain_info;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_BINARY_DATA:
+               lftr->type = LSA_FOREST_TRUST_BINARY_DATA;
+               lftr->forest_trust_data.data =
+                       lftr2->forest_trust_data.data;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_SCANNER_INFO:
+               fta.scanner_info.sub_type = FOREST_TRUST_SCANNER_INFO;
+               s_sdi = &lftr2->forest_trust_data.scanner_info;
+               d_sdi = &fta.scanner_info.info;
+
+               if (s_sdi->domain_sid != NULL) {
+                       d_sdi->sid = *s_sdi->domain_sid;
+               } else {
+                       d_sdi->sid = (struct dom_sid) { .sid_rev_num = 0, };
+               }
+
+               d_sdi->dns_name.string = s_sdi->dns_domain_name.string;
+               d_sdi->netbios_name.string = s_sdi->netbios_domain_name.string;
+
+               ndr_err = ndr_push_union_blob(&blob,
+                                             mem_ctx,
+                                             &fta,
+                                             FOREST_TRUST_SCANNER_INFO,
+                                             (ndr_push_flags_fn_t)ndr_push_ForestTrustData);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return ndr_map_error2ntstatus(ndr_err);
+               }
+
+               lftr->type = LSA_FOREST_TRUST_SCANNER_INFO;
+               lftr->forest_trust_data.data.data = blob.data;
+               lftr->forest_trust_data.data.length = blob.length;
+
+               return NT_STATUS_OK;
+       }
+
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS trust_forest_info_to_lsa(TALLOC_CTX *mem_ctx,
+                                 const struct ForestTrustInfo *fti,
+                                 struct lsa_ForestTrustInformation **_lfti)
+{
+       struct lsa_ForestTrustInformation *lfti;
+       uint32_t i;
+
+       *_lfti = NULL;
+
+       if (fti->version != 1) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       lfti = talloc_zero(mem_ctx, struct lsa_ForestTrustInformation);
+       if (lfti == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       lfti->count = fti->count;
+       lfti->entries = talloc_zero_array(mem_ctx,
+                                         struct lsa_ForestTrustRecord *,
+                                         lfti->count);
+       if (lfti->entries == NULL) {
+               TALLOC_FREE(lfti);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i = 0; i < fti->count; i++) {
+               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
+               struct lsa_ForestTrustRecord2 lftr2 = { .flags = 0, };
+               struct lsa_ForestTrustRecord *lftr = NULL;
+               NTSTATUS status;
+
+               lftr = talloc_zero(lfti->entries,
+                                  struct lsa_ForestTrustRecord);
+               if (lftr == NULL) {
+                       TALLOC_FREE(lfti);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               status = trust_forest_record_to_lsa(lftr, ftr, &lftr2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(lfti);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               status = trust_forest_record_lsa_2to1(lftr, &lftr2, lftr);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(lfti);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lfti->entries[i] = lftr;
+       }
+
+       *_lfti = lfti;
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS trust_forest_record_lsa_2to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustRecord2 *in,
+                               struct lsa_ForestTrustRecord2 *out)
+{
+       const struct lsa_ForestTrustBinaryData *binary = NULL;
+
+       if (in == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       out->flags = in->flags;
+       out->time = in->time;
+
+       switch (in->type) {
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+               out->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+               out->forest_trust_data.top_level_name =
+                       in->forest_trust_data.top_level_name;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+               out->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX;
+               out->forest_trust_data.top_level_name_ex =
+                       in->forest_trust_data.top_level_name_ex;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_DOMAIN_INFO:
+               out->type = LSA_FOREST_TRUST_DOMAIN_INFO;
+               out->forest_trust_data.domain_info =
+                       in->forest_trust_data.domain_info;
+
+               return NT_STATUS_OK;
+
+       case LSA_FOREST_TRUST_BINARY_DATA:
+               binary = &in->forest_trust_data.data;
+
+               return trust_forest_record_lsa_resolve_binary(mem_ctx,
+                                                             in->flags,
+                                                             in->time,
+                                                             binary,
+                                                             out);
+
+       case LSA_FOREST_TRUST_SCANNER_INFO:
+               out->type = LSA_FOREST_TRUST_SCANNER_INFO;
+               out->forest_trust_data.domain_info =
+                       in->forest_trust_data.domain_info;
+
+               return NT_STATUS_OK;
+       }
+
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS trust_forest_info_from_lsa2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *lfti,
+                               struct ForestTrustInfo **_fti)
+{
+       struct ForestTrustInfo *fti;
+       uint32_t i;
+
+       *_fti = NULL;
+
+       fti = talloc_zero(mem_ctx, struct ForestTrustInfo);
+       if (fti == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       fti->version = 1;
+       fti->count = lfti->count;
+       fti->records = talloc_zero_array(fti,
+                                        struct ForestTrustInfoRecordArmor,
+                                        fti->count);
+       if (fti->records == NULL) {
+               TALLOC_FREE(fti);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i = 0; i < fti->count; i++) {
+               const struct lsa_ForestTrustRecord2 *lftr2 = lfti->entries[i];
+               struct lsa_ForestTrustRecord2 _lftr2 = { .flags = 0, };
+               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
+               TALLOC_CTX *frame = talloc_stackframe();
+               NTSTATUS status;
+
+               status = trust_forest_record_lsa_2to2(frame,
+                                                     lftr2,
+                                                     &_lftr2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(frame);
+                       TALLOC_FREE(fti);
+                       return status;
+               }
+
+               status = trust_forest_record_from_lsa(fti->records,
+                                                     &_lftr2,
+                                                     ftr);
+               TALLOC_FREE(frame);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(fti);
+                       return status;
+               }
+       }
+
+       *_fti = fti;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS trust_forest_info_to_lsa2(TALLOC_CTX *mem_ctx,
+                                  const struct ForestTrustInfo *fti,
+                                  struct lsa_ForestTrustInformation2 **_lfti)
+{
+       struct lsa_ForestTrustInformation2 *lfti;
+       uint32_t i;
+
+       *_lfti = NULL;
+
+       if (fti->version != 1) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       lfti = talloc_zero(mem_ctx, struct lsa_ForestTrustInformation2);
+       if (lfti == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       lfti->count = fti->count;
+       lfti->entries = talloc_zero_array(mem_ctx,
+                                         struct lsa_ForestTrustRecord2 *,
+                                         lfti->count);
+       if (lfti->entries == NULL) {
+               TALLOC_FREE(lfti);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i = 0; i < fti->count; i++) {
+               struct ForestTrustInfoRecord *ftr = &fti->records[i].record;
+               struct lsa_ForestTrustRecord2 *lftr2 = NULL;
+               NTSTATUS status;
+
+               lftr2 = talloc_zero(lfti->entries,
+                                   struct lsa_ForestTrustRecord2);
+               if (lftr2 == NULL) {
+                       TALLOC_FREE(lfti);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               status = trust_forest_record_to_lsa(lftr2, ftr, lftr2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(lfti);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               lfti->entries[i] = lftr2;
+       }
+
+       *_lfti = lfti;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS trust_forest_info_lsa_1to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation *lfti,
+                               struct lsa_ForestTrustInformation2 **_lfti2)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct ForestTrustInfo *fti = NULL;
+       struct lsa_ForestTrustInformation2 *lfti2 = NULL;
+       NTSTATUS status;
+
+       status = trust_forest_info_from_lsa(frame, lfti, &fti);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = trust_forest_info_to_lsa2(mem_ctx,
+                                          fti,
+                                          &lfti2);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       *_lfti2 = lfti2;
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+}
+
+NTSTATUS trust_forest_info_lsa_2to1(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *lfti2,
+                               struct lsa_ForestTrustInformation **_lfti)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct ForestTrustInfo *fti = NULL;
+       struct lsa_ForestTrustInformation *lfti = NULL;
+       NTSTATUS status;
+
+       status = trust_forest_info_from_lsa2(frame, lfti2, &fti);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = trust_forest_info_to_lsa(mem_ctx,
+                                         fti,
+                                         &lfti);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       *_lfti = lfti;
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+}
+
+NTSTATUS trust_forest_info_lsa_2to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *in,
+                               struct lsa_ForestTrustInformation2 **_out)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct ForestTrustInfo *fti = NULL;
+       struct lsa_ForestTrustInformation2 *out = NULL;
+       NTSTATUS status;
+
+       status = trust_forest_info_from_lsa2(frame, in, &fti);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = trust_forest_info_to_lsa2(mem_ctx,
+                                          fti,
+                                          &out);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       *_out = out;
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+}
+
+static int trust_forest_info_tln_match_internal(
+               const struct lsa_ForestTrustInformation2 *info,
+               enum lsa_ForestTrustRecordType type,
+               uint32_t disable_mask,
+               const char *tln)
+{
+       uint32_t i;
+
+       for (i = 0; i < info->count; i++) {
+               struct lsa_ForestTrustRecord2 *e = info->entries[i];
+               struct lsa_StringLarge *t = NULL;
+               int cmp;
+
+               if (e == NULL) {
+                       continue;
+               }
+
+               if (e->type != type) {
+                       continue;
+               }
+
+               if (e->flags & disable_mask) {
+                       continue;
+               }
+
+               switch (type) {
+               case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+                       t = &e->forest_trust_data.top_level_name;
+                       break;
+               case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+                       t = &e->forest_trust_data.top_level_name_ex;
+                       break;
+               default:
+                       break;
+               }
+
+               if (t == NULL) {
+                       continue;
+               }
+
+               cmp = dns_cmp(tln, t->string);
+               switch (cmp) {
+               case DNS_CMP_MATCH:
+               case DNS_CMP_FIRST_IS_CHILD:
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+bool trust_forest_info_tln_match(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln)
+{
+       int m;
+
+       m = trust_forest_info_tln_match_internal(info,
+                                       LSA_FOREST_TRUST_TOP_LEVEL_NAME,
+                                       LSA_TLN_DISABLED_MASK,
+                                       tln);
+       if (m != -1) {
+               return true;
+       }
+
+       return false;
+}
+
+bool trust_forest_info_tln_ex_match(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln)
+{
+       int m;
+
+       m = trust_forest_info_tln_match_internal(info,
+                                       LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX,
+                                       0,
+                                       tln);
+       if (m != -1) {
+               return true;
+       }
+
+       return false;
+}
+
+bool trust_forest_info_match_tln_namespace(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln)
+{
+       bool match;
+
+       match = trust_forest_info_tln_ex_match(info, tln);
+       if (match) {
+               return false;
+       }
+
+       match = trust_forest_info_tln_match(info, tln);
+       if (!match) {
+               return false;
+       }
+
+       return true;
+}
diff --git a/libcli/security/trust_forest_info.h b/libcli/security/trust_forest_info.h
new file mode 100644 (file)
index 0000000..903cff2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+   Unix SMB/CIFS implementation.
+   Authentication utility functions
+   Copyright (C) Stefan Metzmacher 2018,2025
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBCLI_SECURITY_TRUST_FOREST_INFO_H_
+#define _LIBCLI_SECURITY_TRUST_FOREST_INFO_H_
+
+struct ForestTrustInfo;
+struct lsa_ForestTrustInformation;
+struct lsa_ForestTrustInformation2;
+
+NTSTATUS trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation *lfti,
+                               struct ForestTrustInfo **_fti);
+NTSTATUS trust_forest_info_to_lsa(TALLOC_CTX *mem_ctx,
+                                 const struct ForestTrustInfo *fti,
+                                 struct lsa_ForestTrustInformation **_lfti);
+NTSTATUS trust_forest_info_from_lsa2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *lfti,
+                               struct ForestTrustInfo **_fti);
+NTSTATUS trust_forest_info_to_lsa2(TALLOC_CTX *mem_ctx,
+                                  const struct ForestTrustInfo *fti,
+                                  struct lsa_ForestTrustInformation2 **_lfti);
+NTSTATUS trust_forest_info_lsa_1to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation *lfti,
+                               struct lsa_ForestTrustInformation2 **_lfti2);
+NTSTATUS trust_forest_info_lsa_2to1(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *lfti2,
+                               struct lsa_ForestTrustInformation **_lfti);
+NTSTATUS trust_forest_info_lsa_2to2(TALLOC_CTX *mem_ctx,
+                               const struct lsa_ForestTrustInformation2 *in,
+                               struct lsa_ForestTrustInformation2 **_out);
+
+bool trust_forest_info_tln_match(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln);
+bool trust_forest_info_tln_ex_match(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln);
+bool trust_forest_info_match_tln_namespace(
+               const struct lsa_ForestTrustInformation2 *info,
+               const char *tln);
+
+#endif /* _LIBCLI_SECURITY_TRUST_FOREST_INFO_H_ */
index d6b133d1a87b436f9566776b11c237035b2085b1..945e5c3c8464190f20184a2f06edcf6e2d182e84 100644 (file)
@@ -16,6 +16,18 @@ bld.SAMBA_LIBRARY('samba-security',
                   private_library=True,
                   deps='stable_sort talloc ndr NDR_SECURITY NDR_CONDITIONAL_ACE')
 
+bld.SAMBA_LIBRARY('samba-security-trusts',
+                  source='''
+                      trust_forest_info.c
+                  ''',
+                  deps='''
+                      talloc
+                      samba-util
+                      samba-security
+                      ndr-samba
+                  ''',
+                  private_library=True)
+
 pytalloc_util = bld.pyembed_libname('pytalloc-util')
 pyrpc_util = bld.pyembed_libname('pyrpc_util')
 bld.SAMBA_PYTHON('pysecurity',
index 9e42b046e3899e32c1755f0a9ddea3d880446b26..2870f1a704bc04260c7c7be0be46e7c0ee7a509c 100644 (file)
@@ -311,6 +311,7 @@ bld.SAMBA3_SUBSYSTEM('samba3util',
                         LIBTSOCKET
                         util_tsock
                         samba-security
+                        samba-security-trusts
                         NDR_SECURITY
                         samba-util
                         util_tdb
index 1b03dc9f077a9f6c89b29a1c9a9e123d2a3964a2..c2200f5ce638e1238d7032722a1fdfa46f5eab74 100644 (file)
@@ -16,7 +16,7 @@ bld.SAMBA_LIBRARY('samdb-common',
        source='common/util.c common/util_trusts.c common/util_groups.c common/util_samr.c common/dsdb_dn.c common/dsdb_access.c common/util_links.c common/rodc_helper.c gmsa/gkdi.c gmsa/util.c',
        autoproto='common/proto.h',
        private_library=True,
-       deps='ldb NDR_DRSBLOBS util_ldb LIBCLI_AUTH samba-hostconfig samba_socket cli-ldap-common flag_mapping UTIL_RUNCMD SAMBA_VERSION samba-security gkdi gmsa'
+       deps='ldb NDR_DRSBLOBS util_ldb LIBCLI_AUTH samba-hostconfig samba_socket cli-ldap-common flag_mapping UTIL_RUNCMD SAMBA_VERSION samba-security samba-security-trusts gkdi gmsa'
        )