+
+ for (i = 0; i < num_domains; i++) {
+ struct ForestTrustInfo fti;
+ uint32_t fi;
+ enum ndr_err_code ndr_err;
+ struct winbindd_domain *routing_domain = NULL;
+
+ if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
+ continue;
+ }
+
+ if (!(domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
+ continue;
+ }
+
+ if (domains[i]->trust_forest_trust_info.length == 0) {
+ continue;
+ }
+
+ routing_domain = find_domain_from_name_noinit(
+ domains[i]->netbios_name);
+ if (routing_domain == NULL) {
+ DBG_ERR("Can't find winbindd domain [%s]\n",
+ domains[i]->netbios_name);
+ return false;
+ }
+
+ ndr_err = ndr_pull_struct_blob_all(
+ &domains[i]->trust_forest_trust_info,
+ talloc_tos(), &fti,
+ (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DBG_ERR("ndr_pull_ForestTrustInfo(%s) - %s\n",
+ domains[i]->netbios_name,
+ ndr_map_error2string(ndr_err));
+ return false;
+ }
+
+ for (fi = 0; fi < fti.count; fi++) {
+ struct ForestTrustInfoRecord *rec =
+ &fti.records[fi].record;
+ struct ForestTrustDataDomainInfo *drec = NULL;
+
+ if (rec->type != FOREST_TRUST_DOMAIN_INFO) {
+ continue;
+ }
+ drec = &rec->data.info;
+
+ if (rec->flags & LSA_NB_DISABLED_MASK) {
+ continue;
+ }
+
+ if (rec->flags & LSA_SID_DISABLED_MASK) {
+ continue;
+ }
+
+ /*
+ * TODO:
+ * also try to find a matching
+ * LSA_TLN_DISABLED_MASK ???
+ */
+
+ domain = find_domain_from_name_noinit(drec->netbios_name.string);
+ if (domain != NULL) {
+ continue;
+ }
+
+ status = add_trusted_domain(drec->netbios_name.string,
+ drec->dns_name.string,
+ &drec->sid,
+ LSA_TRUST_TYPE_UPLEVEL,
+ NETR_TRUST_FLAG_OUTBOUND,
+ 0,
+ SEC_CHAN_NULL,
+ routing_domain,
+ &domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_NOTICE("add_trusted_domain returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ if (domain == NULL) {
+ continue;
+ }
+ }