#include "dsdb/common/util.h"
#include "libds/common/flag_mapping.h"
#include "../lib/util/dlinklist.h"
-#include "../lib/crypto/crypto.h"
+#include "lib/crypto/md4.h"
+#include "libcli/ldap/ldap_ndr.h"
NTSTATUS dsdb_trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
const struct lsa_ForestTrustInformation *lfti,
ftr->flags = lftr->flags;
ftr->timestamp = lftr->time;
- ftr->type = lftr->type;
+ ftr->type = (enum ForestTrustInfoRecordType)lftr->type;
switch (lftr->type) {
case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
lftr->flags = ftr->flags;
lftr->time = ftr->timestamp;
- lftr->type = ftr->type;
+ lftr->type = (enum lsa_ForestTrustRecordType)ftr->type;
switch (lftr->type) {
case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
}
lfti = talloc_zero(mem_ctx, struct lsa_ForestTrustInformation);
- if (fti == NULL) {
+ if (lfti == NULL) {
return NT_STATUS_NO_MEMORY;
}
const char *dns = NULL;
const char *netbios = NULL;
struct ldb_dn *nc_dn = NULL;
- struct dom_sid sid = {};
+ struct dom_sid sid = {
+ .num_auths = 0,
+ };
NTSTATUS status;
*_tdo = NULL;
*_trust_parent_tdo = NULL;
}
- domain_dn = ldb_get_default_basedn(sam_ctx);
- if (domain_dn == NULL) {
- TALLOC_FREE(frame);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
partitions_dn = samdb_partitions_dn(sam_ctx, frame);
if (partitions_dn == NULL) {
TALLOC_FREE(frame);
size_t l1 = 0;
const char *p1 = NULL;
size_t num_comp1 = 0;
- uint16_t comp1[UINT8_MAX] = {};
+ uint16_t comp1[UINT8_MAX] = {0};
size_t l2 = 0;
const char *p2 = NULL;
size_t num_comp2 = 0;
- uint16_t comp2[UINT8_MAX] = {};
+ uint16_t comp2[UINT8_MAX] = {0};
size_t i;
if (s1 != NULL) {
if (i == 0) {
p1 = s1;
- if (l1 == 0 && l1 >= UINT16_MAX) {
+ if (l1 == 0 || l1 >= UINT16_MAX) {
/* just use one single component on overflow */
break;
}
if (i == 0) {
p2 = s2;
- if (l2 == 0 && l2 >= UINT16_MAX) {
+ if (l2 == 0 || l2 >= UINT16_MAX) {
/* just use one single component on overflow */
break;
}
return false;
}
+NTSTATUS dsdb_trust_local_tdo_info(TALLOC_CTX *mem_ctx,
+ struct ldb_context *sam_ctx,
+ struct lsa_TrustDomainInfoInfoEx **_tdo)
+{
+ struct ldb_dn *domain_dn = NULL;
+
+ domain_dn = ldb_get_default_basedn(sam_ctx);
+ if (domain_dn == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ return dsdb_trust_crossref_tdo_info(mem_ctx, sam_ctx,
+ domain_dn, NULL,
+ _tdo, NULL, NULL);
+}
+
NTSTATUS dsdb_trust_xref_tdo_info(TALLOC_CTX *mem_ctx,
struct ldb_context *sam_ctx,
struct lsa_TrustDomainInfoInfoEx **_tdo)
const char *dns = NULL;
const char *netbios = NULL;
struct ldb_dn *nc_dn = NULL;
- struct dom_sid sid = {};
- struct lsa_ForestTrustRecord e = {};
+ struct dom_sid sid = {
+ .num_auths = 0,
+ };
+ struct lsa_ForestTrustRecord e = {
+ .flags = 0,
+ };
struct lsa_ForestTrustDomainInfo *d = NULL;
struct lsa_StringLarge *t = NULL;
bool match = false;
for (i=0; (tln_el != NULL) && i < tln_el->num_values; i++) {
const struct ldb_val *v = &tln_el->values[i];
const char *dns = (const char *)v->data;
- struct lsa_ForestTrustRecord e = {};
+ struct lsa_ForestTrustRecord e = {
+ .flags = 0,
+ };
struct lsa_StringLarge *t = NULL;
bool match = false;
NTSTATUS status;
*/
for (ni = 0; ni < nfti->count; ni++) {
const struct lsa_ForestTrustRecord *nftr = nfti->entries[ni];
- struct lsa_ForestTrustRecord tftr = {};
+ struct lsa_ForestTrustRecord tftr = {
+ .flags = 0,
+ };
const char *ndns = NULL;
bool ignore_new = false;
bool found_old = false;
*/
for (ni = 0; ni < nfti->count; ni++) {
const struct lsa_ForestTrustRecord *nftr = nfti->entries[ni];
- struct lsa_ForestTrustRecord tftr = {};
+ struct lsa_ForestTrustRecord tftr = {
+ .flags = 0,
+ };
const struct lsa_ForestTrustDomainInfo *nd = NULL;
const char *ndns = NULL;
const char *nnbt = NULL;
return NT_STATUS_OK;
}
+NTSTATUS dsdb_trust_search_tdo_by_sid(struct ldb_context *sam_ctx,
+ const struct dom_sid *sid,
+ const char * const *attrs,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_message **msg)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ int ret;
+ struct ldb_dn *system_dn = NULL;
+ char *encoded_sid = NULL;
+ char *filter = NULL;
+
+ *msg = NULL;
+
+ if (sid == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ }
+
+ encoded_sid = ldap_encode_ndr_dom_sid(frame, sid);
+ if (encoded_sid == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ system_dn = ldb_dn_copy(frame, ldb_get_default_basedn(sam_ctx));
+ if (system_dn == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!ldb_dn_add_child_fmt(system_dn, "CN=System")) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ filter = talloc_asprintf(frame,
+ "(&"
+ "(objectClass=trustedDomain)"
+ "(securityIdentifier=%s)"
+ ")",
+ encoded_sid);
+ if (filter == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = dsdb_search_one(sam_ctx, mem_ctx, msg,
+ system_dn,
+ LDB_SCOPE_ONELEVEL, attrs,
+ DSDB_SEARCH_NO_GLOBAL_CATALOG,
+ "%s", filter);
+ if (ret != LDB_SUCCESS) {
+ NTSTATUS status = dsdb_ldb_err_to_ntstatus(ret);
+ DEBUG(3, ("Failed to search for %s: %s - %s\n",
+ filter, nt_errstr(status), ldb_errstring(sam_ctx)));
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+}
+
NTSTATUS dsdb_trust_get_incoming_passwords(struct ldb_message *msg,
TALLOC_CTX *mem_ctx,
struct samr_Password **_current,
struct samr_Password **_previous)
{
TALLOC_CTX *frame = talloc_stackframe();
- struct samr_Password __current = {};
- struct samr_Password __previous = {};
+ struct samr_Password __current = {
+ .hash = {0},
+ };
+ struct samr_Password __previous = {
+ .hash = {0},
+ };
struct samr_Password *current = NULL;
struct samr_Password *previous = NULL;
const struct ldb_val *blob = NULL;
enum ndr_err_code ndr_err;
- struct trustAuthInOutBlob incoming = {};
+ struct trustAuthInOutBlob incoming = {
+ .count = 0,
+ };
uint32_t i;
if (_current != NULL) {
if (_previous != NULL) {
*_previous = talloc(mem_ctx, struct samr_Password);
if (*_previous == NULL) {
- TALLOC_FREE(*_current);
+ if (_current != NULL) {
+ TALLOC_FREE(*_current);
+ }
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
struct dsdb_trust_routing_domain *prev, *next;
struct lsa_TrustDomainInfoInfoEx *tdo;
+
+ struct lsa_ForestTrustDomainInfo di;
+
struct lsa_ForestTrustInformation *fti;
};
return status;
}
+ /*
+ * d->tdo should not be NULL of status above is 'NT_STATUS_OK'
+ * check is needed to satisfy clang static checker
+ */
+ if (d->tdo == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ d->di.domain_sid = d->tdo->sid;
+ d->di.netbios_domain_name.string = d->tdo->netbios_name.string;
+ d->di.dns_domain_name.string = d->tdo->domain_name.string;
+
if (root_trust_tdo != NULL) {
root_direction_tdo = root_trust_tdo;
} else if (trust_parent_tdo != NULL) {
return status;
}
- DLIST_ADD_END(table->domains, d, NULL);
+ d->di.domain_sid = d->tdo->sid;
+ d->di.netbios_domain_name.string = d->tdo->netbios_name.string;
+ d->di.dns_domain_name.string = d->tdo->domain_name.string;
+
+ DLIST_ADD_END(table->domains, d);
if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
struct ForestTrustInfo *fti = NULL;
return NULL;
}
+
+const struct lsa_TrustDomainInfoInfoEx *dsdb_trust_domain_by_sid(
+ const struct dsdb_trust_routing_table *table,
+ const struct dom_sid *sid,
+ const struct lsa_ForestTrustDomainInfo **pdi)
+{
+ const struct dsdb_trust_routing_domain *d = NULL;
+
+ if (pdi != NULL) {
+ *pdi = NULL;
+ }
+
+ if (sid == NULL) {
+ return NULL;
+ }
+
+ for (d = table->domains; d != NULL; d = d->next) {
+ bool transitive = false;
+ uint32_t i;
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
+ transitive = true;
+ }
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
+ transitive = true;
+ }
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) {
+ transitive = false;
+ }
+
+ if (d->tdo->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
+ transitive = false;
+ }
+
+ if (!transitive || d->fti == NULL) {
+ bool match = false;
+
+ match = dom_sid_equal(d->di.domain_sid, sid);
+ if (match) {
+ /*
+ * exact match, it's the domain itself.
+ */
+ if (pdi != NULL) {
+ *pdi = &d->di;
+ }
+ return d->tdo;
+ }
+ continue;
+ }
+
+ for (i = 0; i < d->fti->count; i++ ) {
+ const struct lsa_ForestTrustRecord *f = d->fti->entries[i];
+ const struct lsa_ForestTrustDomainInfo *di = NULL;
+ const struct dom_sid *fti_sid = NULL;
+ bool match = false;
+
+ if (f == NULL) {
+ /* broken record */
+ continue;
+ }
+
+ if (f->type != LSA_FOREST_TRUST_DOMAIN_INFO) {
+ continue;
+ }
+
+ if (f->flags & LSA_SID_DISABLED_MASK) {
+ /*
+ * any flag disables the entry.
+ */
+ continue;
+ }
+
+ di = &f->forest_trust_data.domain_info;
+ fti_sid = di->domain_sid;
+ if (fti_sid == NULL) {
+ /* broken record */
+ continue;
+ }
+
+ match = dom_sid_equal(fti_sid, sid);
+ if (match) {
+ /*
+ * exact match, it's a domain in the forest.
+ */
+ if (pdi != NULL) {
+ *pdi = di;
+ }
+ return d->tdo;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+const struct lsa_TrustDomainInfoInfoEx *dsdb_trust_domain_by_name(
+ const struct dsdb_trust_routing_table *table,
+ const char *name,
+ const struct lsa_ForestTrustDomainInfo **pdi)
+{
+ const struct dsdb_trust_routing_domain *d = NULL;
+
+ if (pdi != NULL) {
+ *pdi = NULL;
+ }
+
+ if (name == NULL) {
+ return NULL;
+ }
+
+ for (d = table->domains; d != NULL; d = d->next) {
+ bool transitive = false;
+ uint32_t i;
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
+ transitive = true;
+ }
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
+ transitive = true;
+ }
+
+ if (d->tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) {
+ transitive = false;
+ }
+
+ if (d->tdo->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
+ transitive = false;
+ }
+
+ if (!transitive || d->fti == NULL) {
+ bool match = false;
+
+ match = strequal_m(d->di.netbios_domain_name.string,
+ name);
+ if (match) {
+ /*
+ * exact match for netbios name,
+ * it's the domain itself.
+ */
+ if (pdi != NULL) {
+ *pdi = &d->di;
+ }
+ return d->tdo;
+ }
+ match = strequal_m(d->di.dns_domain_name.string,
+ name);
+ if (match) {
+ /*
+ * exact match for dns name,
+ * it's the domain itself.
+ */
+ if (pdi != NULL) {
+ *pdi = &d->di;
+ }
+ return d->tdo;
+ }
+ continue;
+ }
+
+ for (i = 0; i < d->fti->count; i++ ) {
+ const struct lsa_ForestTrustRecord *f = d->fti->entries[i];
+ const struct lsa_ForestTrustDomainInfo *di = NULL;
+ bool match = false;
+
+ if (f == NULL) {
+ /* broken record */
+ continue;
+ }
+
+ if (f->type != LSA_FOREST_TRUST_DOMAIN_INFO) {
+ continue;
+ }
+ di = &f->forest_trust_data.domain_info;
+
+ if (!(f->flags & LSA_NB_DISABLED_MASK)) {
+ match = strequal_m(di->netbios_domain_name.string,
+ name);
+ if (match) {
+ /*
+ * exact match for netbios name,
+ * it's a domain in the forest.
+ */
+ if (pdi != NULL) {
+ *pdi = di;
+ }
+ return d->tdo;
+ }
+ }
+
+ if (!(f->flags & LSA_TLN_DISABLED_MASK)) {
+ match = strequal_m(di->dns_domain_name.string,
+ name);
+ if (match) {
+ /*
+ * exact match for dns name,
+ * it's a domain in the forest.
+ */
+ if (pdi != NULL) {
+ *pdi = di;
+ }
+ return d->tdo;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}