[PATCH] More preparatory patches for winbindd and trusts
Ralph Böhme
slow at samba.org
Wed Jan 10 19:59:35 UTC 2018
Hi!
Attached is another preparatory patchset from my winbindd-trusts branch [1],
this one should be applied on-top of the previous patchset.
Patches are already reviewed by metze. I'm currently running a final private
autobuild. If that passes and no-one objects, I will push later.
-slow
[1] https://git.samba.org/?p=slow/samba.git;a=shortlog;h=refs/heads/trusts
--
Ralph Boehme, Samba Team https://samba.org/
Samba Developer, SerNet GmbH https://sernet.de/en/samba/
-------------- next part --------------
From 87dbf842cbfee593c9b25b1d20010ee582935f17 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 29 Nov 2017 15:10:38 +0100
Subject: [PATCH 01/23] winbindd: remember the secure_channel_type in
winbindd_domain
This way we have an indication of non direct trusts with
SEC_CHAN_NULL.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd.h | 1 +
source3/winbindd/winbindd_util.c | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 396f7f7946e..682040fd1a7 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -139,6 +139,7 @@ struct winbindd_domain {
char *alt_name; /* alt Domain name, if any (FQDN for ADS) */
char *forest_name; /* Name of the AD forest we're in */
struct dom_sid sid; /* SID for this domain */
+ enum netr_SchannelType secure_channel_type;
uint32_t domain_flags; /* Domain flags from netlogon.h */
uint32_t domain_type; /* Domain type from netlogon.h */
uint32_t domain_trust_attribs; /* Trust attribs from netlogon.h */
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index c45d6acb0ad..3b8fae141bb 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -125,6 +125,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
uint32_t trust_type,
uint32_t trust_flags,
uint32_t trust_attribs,
+ enum netr_SchannelType secure_channel_type,
struct winbindd_domain **_d)
{
struct winbindd_domain *domain = NULL;
@@ -240,6 +241,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
domain->backend = NULL;
domain->internal = is_internal_domain(sid);
+ domain->secure_channel_type = secure_channel_type;
domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
domain->initialized = false;
@@ -249,6 +251,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
domain->domain_flags = trust_flags;
domain->domain_type = trust_type;
domain->domain_trust_attribs = trust_attribs;
+ domain->secure_channel_type = secure_channel_type;
sid_copy(&domain->sid, sid);
/* Is this our primary domain ? */
@@ -464,6 +467,7 @@ static void trustdom_list_done(struct tevent_req *req)
trust_type,
trust_flags,
trust_attribs,
+ SEC_CHAN_NULL,
&domain);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
@@ -546,6 +550,7 @@ static void rescan_forest_root_trusts( void )
dom_list[i].trust_type,
dom_list[i].trust_flags,
dom_list[i].trust_attribs,
+ SEC_CHAN_NULL,
&d);
if (!NT_STATUS_IS_OK(status) &&
@@ -627,6 +632,7 @@ static void rescan_forest_trusts( void )
type,
flags,
attribs,
+ SEC_CHAN_NULL,
&d);
if (!NT_STATUS_IS_OK(status) &&
NT_STATUS_EQUAL(status,
@@ -736,6 +742,7 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
DATA_BLOB *data)
{
TALLOC_CTX *frame = talloc_stackframe();
+ enum netr_SchannelType secure_channel_type = SEC_CHAN_DOMAIN;
struct lsa_TrustDomainInfoInfoEx info;
enum ndr_err_code ndr_err;
struct winbindd_domain *d = NULL;
@@ -762,6 +769,9 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
return;
}
+ if (info.trust_type == LSA_TRUST_TYPE_UPLEVEL) {
+ secure_channel_type = SEC_CHAN_DNS_DOMAIN;
+ }
if (info.trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
trust_flags |= NETR_TRUST_FLAG_INBOUND;
}
@@ -778,6 +788,7 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
info.trust_type,
trust_flags,
info.trust_attributes,
+ secure_channel_type,
&d);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
@@ -852,6 +863,7 @@ bool init_domain_list(void)
LSA_TRUST_TYPE_DOWNLEVEL,
0, /* trust_flags */
0, /* trust_attribs */
+ SEC_CHAN_LOCAL,
&domain);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("add_trusted_domain BUILTIN returned %s\n",
@@ -903,6 +915,7 @@ bool init_domain_list(void)
LSA_TRUST_TYPE_UPLEVEL,
trust_flags,
LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
+ SEC_CHAN_BDC,
&domain);
TALLOC_FREE(pdb_domain_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -946,24 +959,34 @@ bool init_domain_list(void)
return false;
}
}
+
+ domain->secure_channel_type = sec_chan_type;
if (sec_chan_type == SEC_CHAN_RODC) {
domain->rodc = true;
}
} else {
uint32_t trust_flags;
+ enum netr_SchannelType secure_channel_type;
trust_flags = NETR_TRUST_FLAG_OUTBOUND;
if (role != ROLE_DOMAIN_MEMBER) {
trust_flags |= NETR_TRUST_FLAG_PRIMARY;
}
+ if (role > ROLE_DOMAIN_MEMBER) {
+ secure_channel_type = SEC_CHAN_BDC;
+ } else {
+ secure_channel_type = SEC_CHAN_LOCAL;
+ }
+
status = add_trusted_domain(get_global_sam_name(),
NULL,
get_global_sam_sid(),
LSA_TRUST_TYPE_DOWNLEVEL,
trust_flags,
0, /* trust_attribs */
+ secure_channel_type,
&domain);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Failed to add local SAM to "
@@ -995,6 +1018,7 @@ bool init_domain_list(void)
NETR_TRUST_FLAG_PRIMARY|
NETR_TRUST_FLAG_OUTBOUND,
0, /* trust_attribs */
+ SEC_CHAN_WKSTA,
&domain);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Failed to add local SAM to "
--
2.13.6
From 4c44de52d75c4ff723a0cf2c888729d39a7baff3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 29 Nov 2017 15:23:36 +0100
Subject: [PATCH 02/23] winbindd: add find_trust_from_{name,sid}_noinit()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_proto.h | 2 ++
source3/winbindd/winbindd_util.c | 44 +++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 8af79324c69..dd6767a02ab 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -445,8 +445,10 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai
struct winbindd_cli_state *state);
bool init_domain_list(void);
struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name);
+struct winbindd_domain *find_trust_from_name_noinit(const char *domain_name);
struct winbindd_domain *find_domain_from_name(const char *domain_name);
struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid);
+struct winbindd_domain *find_trust_from_sid_noinit(const struct dom_sid *sid);
struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid);
struct winbindd_domain *find_our_domain(void);
struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 3b8fae141bb..9c8e39f79c1 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -1082,6 +1082,28 @@ struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name)
return NULL;
}
+/**
+ * Given a domain name, return the struct winbindd domain if it's a direct
+ * outgoing trust
+ *
+ * @return The domain structure for the named domain, if it is a direct outgoing trust
+ */
+struct winbindd_domain *find_trust_from_name_noinit(const char *domain_name)
+{
+ struct winbindd_domain *domain = NULL;
+
+ domain = find_domain_from_name_noinit(domain_name);
+ if (domain == NULL) {
+ return NULL;
+ }
+
+ if (domain->secure_channel_type != SEC_CHAN_NULL) {
+ return domain;
+ }
+
+ return NULL;
+}
+
struct winbindd_domain *find_domain_from_name(const char *domain_name)
{
struct winbindd_domain *domain;
@@ -1115,6 +1137,28 @@ struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid)
return NULL;
}
+/**
+ * Given a domain sid, return the struct winbindd domain if it's a direct
+ * outgoing trust
+ *
+ * @return The domain structure for the specified domain, if it is a direct outgoing trust
+ */
+struct winbindd_domain *find_trust_from_sid_noinit(const struct dom_sid *sid)
+{
+ struct winbindd_domain *domain = NULL;
+
+ domain = find_domain_from_sid_noinit(sid);
+ if (domain == NULL) {
+ return NULL;
+ }
+
+ if (domain->secure_channel_type != SEC_CHAN_NULL) {
+ return domain;
+ }
+
+ return NULL;
+}
+
/* Given a domain sid, return the struct winbindd domain info for it */
struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid)
--
2.13.6
From d5d84ca59faaefd7cf8c22ced8dd59be47fa3e19 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 30 Nov 2017 13:04:56 +0100
Subject: [PATCH 03/23] winbindd: use find_trust_from_name_noinit when we
require a direct trust
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_irpc.c | 2 +-
source3/winbindd/winbindd_misc.c | 2 +-
source3/winbindd/winbindd_ping_dc.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
index d0d68c89411..4101469ad99 100644
--- a/source3/winbindd/winbindd_irpc.c
+++ b/source3/winbindd/winbindd_irpc.c
@@ -282,7 +282,7 @@ static NTSTATUS wb_irpc_GetForestTrustInformation(struct irpc_message *msg,
return NT_STATUS_OK;
}
- domain = find_domain_from_name_noinit(req->in.trusted_domain_name);
+ domain = find_trust_from_name_noinit(req->in.trusted_domain_name);
if (domain == NULL) {
req->out.result = WERR_NO_SUCH_DOMAIN;
return NT_STATUS_OK;
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 6cf33420768..c80e7844bc2 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -336,7 +336,7 @@ void winbindd_dc_info(struct winbindd_cli_state *cli)
cli->request->domain_name));
if (cli->request->domain_name[0] != '\0') {
- domain = find_domain_from_name_noinit(
+ domain = find_trust_from_name_noinit(
cli->request->domain_name);
if (domain == NULL) {
DEBUG(10, ("Could not find domain %s\n",
diff --git a/source3/winbindd/winbindd_ping_dc.c b/source3/winbindd/winbindd_ping_dc.c
index 05e84020625..a6cea79ee2a 100644
--- a/source3/winbindd/winbindd_ping_dc.c
+++ b/source3/winbindd/winbindd_ping_dc.c
@@ -47,7 +47,7 @@ struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx,
/* preserve old behavior, when no domain name is given */
domain = find_our_domain();
} else {
- domain = find_domain_from_name_noinit(request->domain_name);
+ domain = find_trust_from_name_noinit(request->domain_name);
}
if (domain == NULL) {
tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
--
2.13.6
From 846570273b3fe5fbd1ef27f64bae9f3dacc8aae5 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Mon, 11 Dec 2017 07:56:02 +0100
Subject: [PATCH 04/23] s3/torture/pdbtest: creating a trusted domain requires
a valid SID
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/torture/pdbtest.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index adbd982ab44..71b5c61fc58 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -450,6 +450,7 @@ static bool test_trusted_domains(TALLOC_CTX *ctx,
struct trustAuthInOutBlob taiob;
struct AuthenticationInformation aia;
enum ndr_err_code ndr_err;
+ bool ok;
td = talloc_zero(ctx ,struct pdb_trusted_domain);
if (!td) {
@@ -463,6 +464,11 @@ static bool test_trusted_domains(TALLOC_CTX *ctx,
fprintf(stderr, "talloc failed\n");
return false;
}
+ ok = dom_sid_parse("S-1-5-21-123-456-789", &td->security_identifier);
+ if (!ok) {
+ fprintf(stderr, "dom_sid_parse S-1-5-21-123-456-789 failed\n");
+ return false;
+ }
td->trust_auth_incoming = data_blob_null;
--
2.13.6
From 3e3e656949a474018c82adffe708c854389d36b0 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Mon, 11 Dec 2017 07:56:40 +0100
Subject: [PATCH 05/23] s3/torture/pdbtest: delete trusted domain at test end
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/torture/pdbtest.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index 71b5c61fc58..64bc45e6a7c 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -526,6 +526,13 @@ static bool test_trusted_domains(TALLOC_CTX *ctx,
*error = true;
}
+ rv = pdb->del_trusted_domain(pdb, TRUST_DOM);
+ if (!NT_STATUS_IS_OK(rv)) {
+ fprintf(stderr, "Error in del_trusted_domain %s\n",
+ get_friendly_nt_error_msg(rv));
+ *error = true;
+ }
+
return true;
}
--
2.13.6
From 288137472cc76e91468a99d3b1a8215fbcf4d20a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 1 Dec 2017 08:33:51 +0100
Subject: [PATCH 06/23] s4:dsdb: add dsdb_trust_search_tdo_by_sid() helper
function
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source4/dsdb/common/util_trusts.c | 65 +++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/source4/dsdb/common/util_trusts.c b/source4/dsdb/common/util_trusts.c
index a083d869f6e..1534829199b 100644
--- a/source4/dsdb/common/util_trusts.c
+++ b/source4/dsdb/common/util_trusts.c
@@ -33,6 +33,7 @@
#include "libds/common/flag_mapping.h"
#include "../lib/util/dlinklist.h"
#include "../lib/crypto/crypto.h"
+#include "libcli/ldap/ldap_ndr.h"
NTSTATUS dsdb_trust_forest_info_from_lsa(TALLOC_CTX *mem_ctx,
const struct lsa_ForestTrustInformation *lfti,
@@ -2567,6 +2568,70 @@ NTSTATUS dsdb_trust_search_tdo_by_type(struct ldb_context *sam_ctx,
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,
--
2.13.6
From b7d91a46e857dada59810ec8ebf96aa24f18e5de Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 1 Dec 2017 07:59:59 +0100
Subject: [PATCH 07/23] pdb_samba_dsdb: implement
pdb_samba_dsdb_enum_trusteddoms()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/passdb/pdb_samba_dsdb.c | 86 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 4 deletions(-)
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index 58168d843aa..d70a867505d 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -2878,11 +2878,89 @@ static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
TALLOC_CTX *mem_ctx,
- uint32_t *num_domains,
- struct trustdom_info ***domains)
+ uint32_t *_num_domains,
+ struct trustdom_info ***_domains)
{
- *num_domains = 0;
- *domains = NULL;
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ const char * const attrs[] = {
+ "securityIdentifier",
+ "flatName",
+ "trustDirection",
+ NULL
+ };
+ struct ldb_result *res = NULL;
+ unsigned int i;
+ struct trustdom_info **domains = NULL;
+ NTSTATUS status;
+ uint32_t di = 0;
+
+ *_num_domains = 0;
+ *_domains = NULL;
+
+ status = dsdb_trust_search_tdos(state->ldb, NULL,
+ attrs, tmp_ctx, &res);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dsdb_trust_search_tdos() - %s ", nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ if (res->count == 0) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
+ domains = talloc_zero_array(tmp_ctx, struct trustdom_info *,
+ res->count);
+ if (domains == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < res->count; i++) {
+ struct ldb_message *msg = res->msgs[i];
+ struct trustdom_info *d = NULL;
+ const char *name = NULL;
+ struct dom_sid *sid = NULL;
+ uint32_t direction;
+
+ d = talloc_zero(domains, struct trustdom_info);
+ if (d == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ name = ldb_msg_find_attr_as_string(msg, "flatName", NULL);
+ if (name == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ sid = samdb_result_dom_sid(msg, msg, "securityIdentifier");
+ if (sid == NULL) {
+ continue;
+ }
+
+ direction = ldb_msg_find_attr_as_uint(msg, "trustDirection", 0);
+ if (!(direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
+ continue;
+ }
+
+ d->name = talloc_strdup(d, name);
+ if (d->name == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ d->sid = *sid;
+
+ domains[di++] = d;
+ }
+
+ talloc_realloc(domains, domains, struct trustdom_info *, di);
+ *_domains = talloc_move(mem_ctx, &domains);
+ *_num_domains = di;
+ TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
--
2.13.6
From f5ba51e84c10af3e59eae1b96e2a770a757a15ca Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 1 Dec 2017 08:41:29 +0100
Subject: [PATCH 08/23] pdb_samba_dsdb: implement PDB_CAP_TRUSTED_DOMAINS_EX
related functions
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/passdb/pdb_samba_dsdb.c | 284 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 284 insertions(+)
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index d70a867505d..e629416974a 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -2964,6 +2964,285 @@ static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
return NT_STATUS_OK;
}
+static NTSTATUS pdb_samba_dsdb_msg_to_trusted_domain(const struct ldb_message *msg,
+ TALLOC_CTX *mem_ctx,
+ struct pdb_trusted_domain **_d)
+{
+ struct pdb_trusted_domain *d = NULL;
+ const char *str = NULL;
+ struct dom_sid *sid = NULL;
+ const struct ldb_val *val = NULL;
+ uint64_t val64;
+
+ *_d = NULL;
+
+ d = talloc_zero(mem_ctx, struct pdb_trusted_domain);
+ if (d == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ str = ldb_msg_find_attr_as_string(msg, "flatName", NULL);
+ if (str == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ d->netbios_name = talloc_strdup(d, str);
+ if (d->netbios_name == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ str = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
+ if (str != NULL) {
+ d->domain_name = talloc_strdup(d, str);
+ if (d->domain_name == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ sid = samdb_result_dom_sid(d, msg, "securityIdentifier");
+ if (sid != NULL) {
+ d->security_identifier = *sid;
+ TALLOC_FREE(sid);
+ }
+
+ val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
+ if (val != NULL) {
+ d->trust_auth_outgoing = data_blob_dup_talloc(d, *val);
+ if (d->trust_auth_outgoing.data == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming");
+ if (val != NULL) {
+ d->trust_auth_incoming = data_blob_dup_talloc(d, *val);
+ if (d->trust_auth_incoming.data == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ d->trust_direction = ldb_msg_find_attr_as_uint(msg, "trustDirection", 0);
+ d->trust_type = ldb_msg_find_attr_as_uint(msg, "trustType", 0);
+ d->trust_attributes = ldb_msg_find_attr_as_uint(msg, "trustAttributes", 0);
+
+ val64 = ldb_msg_find_attr_as_uint64(msg, "trustPosixOffset", UINT64_MAX);
+ if (val64 != UINT64_MAX) {
+ d->trust_posix_offset = talloc(d, uint32_t);
+ if (d->trust_posix_offset == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *d->trust_posix_offset = (uint32_t)val64;
+ }
+
+ val64 = ldb_msg_find_attr_as_uint64(msg, "msDS-SupportedEncryptionTypes", UINT64_MAX);
+ if (val64 != UINT64_MAX) {
+ d->supported_enc_type = talloc(d, uint32_t);
+ if (d->supported_enc_type == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *d->supported_enc_type = (uint32_t)val64;
+ }
+
+ val = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
+ if (val != NULL) {
+ d->trust_forest_trust_info = data_blob_dup_talloc(d, *val);
+ if (d->trust_forest_trust_info.data == NULL) {
+ TALLOC_FREE(d);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ *_d = d;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_samba_dsdb_get_trusted_domain(struct pdb_methods *m,
+ TALLOC_CTX *mem_ctx,
+ const char *domain,
+ struct pdb_trusted_domain **td)
+{
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ const char * const attrs[] = {
+ "securityIdentifier",
+ "flatName",
+ "trustPartner",
+ "trustAuthOutgoing",
+ "trustAuthIncoming",
+ "trustAttributes",
+ "trustDirection",
+ "trustType",
+ "trustPosixOffset",
+ "msDS-SupportedEncryptionTypes",
+ "msDS-TrustForestTrustInfo",
+ NULL
+ };
+ struct ldb_message *msg = NULL;
+ struct pdb_trusted_domain *d = NULL;
+ NTSTATUS status;
+
+ status = dsdb_trust_search_tdo(state->ldb, domain, NULL,
+ attrs, tmp_ctx, &msg);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dsdb_trust_search_tdo(%s) - %s ",
+ domain, nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ status = pdb_samba_dsdb_msg_to_trusted_domain(msg, mem_ctx, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("pdb_samba_dsdb_msg_to_trusted_domain(%s) - %s ",
+ domain, nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ *td = d;
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_samba_dsdb_get_trusted_domain_by_sid(struct pdb_methods *m,
+ TALLOC_CTX *mem_ctx,
+ struct dom_sid *sid,
+ struct pdb_trusted_domain **td)
+{
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ const char * const attrs[] = {
+ "securityIdentifier",
+ "flatName",
+ "trustPartner",
+ "trustAuthOutgoing",
+ "trustAuthIncoming",
+ "trustAttributes",
+ "trustDirection",
+ "trustType",
+ "trustPosixOffset",
+ "msDS-SupportedEncryptionTypes",
+ "msDS-TrustForestTrustInfo",
+ NULL
+ };
+ struct ldb_message *msg = NULL;
+ struct pdb_trusted_domain *d = NULL;
+ NTSTATUS status;
+
+ status = dsdb_trust_search_tdo_by_sid(state->ldb, sid,
+ attrs, tmp_ctx, &msg);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dsdb_trust_search_tdo_by_sid(%s) - %s ",
+ dom_sid_string(tmp_ctx, sid), nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ status = pdb_samba_dsdb_msg_to_trusted_domain(msg, mem_ctx, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("pdb_samba_dsdb_msg_to_trusted_domain(%s) - %s ",
+ dom_sid_string(tmp_ctx, sid), nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ *td = d;
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_samba_dsdb_set_trusted_domain(struct pdb_methods *methods,
+ const char* domain,
+ const struct pdb_trusted_domain *td)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_samba_dsdb_del_trusted_domain(struct pdb_methods *methods,
+ const char *domain)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_samba_dsdb_enum_trusted_domains(struct pdb_methods *m,
+ TALLOC_CTX *mem_ctx,
+ uint32_t *_num_domains,
+ struct pdb_trusted_domain ***_domains)
+{
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ const char * const attrs[] = {
+ "securityIdentifier",
+ "flatName",
+ "trustPartner",
+ "trustAuthOutgoing",
+ "trustAuthIncoming",
+ "trustAttributes",
+ "trustDirection",
+ "trustType",
+ "trustPosixOffset",
+ "msDS-SupportedEncryptionTypes",
+ "msDS-TrustForestTrustInfo",
+ NULL
+ };
+ struct ldb_result *res = NULL;
+ unsigned int i;
+ struct pdb_trusted_domain **domains = NULL;
+ NTSTATUS status;
+ uint32_t di = 0;
+
+ *_num_domains = 0;
+ *_domains = NULL;
+
+ status = dsdb_trust_search_tdos(state->ldb, NULL,
+ attrs, tmp_ctx, &res);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dsdb_trust_search_tdos() - %s ", nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ if (res->count == 0) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
+ domains = talloc_zero_array(tmp_ctx, struct pdb_trusted_domain *,
+ res->count);
+ if (domains == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < res->count; i++) {
+ struct ldb_message *msg = res->msgs[i];
+ struct pdb_trusted_domain *d = NULL;
+
+ status = pdb_samba_dsdb_msg_to_trusted_domain(msg, domains, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("pdb_samba_dsdb_msg_to_trusted_domain() - %s ",
+ nt_errstr(status));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+
+ domains[di++] = d;
+ }
+
+ talloc_realloc(domains, domains, struct pdb_trusted_domain *, di);
+ *_domains = talloc_move(mem_ctx, &domains);
+ *_num_domains = di;
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+}
+
static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
{
return true;
@@ -3025,6 +3304,11 @@ static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
+ m->get_trusted_domain = pdb_samba_dsdb_get_trusted_domain;
+ m->get_trusted_domain_by_sid = pdb_samba_dsdb_get_trusted_domain_by_sid;
+ m->set_trusted_domain = pdb_samba_dsdb_set_trusted_domain;
+ m->del_trusted_domain = pdb_samba_dsdb_del_trusted_domain;
+ m->enum_trusted_domains = pdb_samba_dsdb_enum_trusted_domains;
m->is_responsible_for_wellknown =
pdb_samba_dsdb_is_responsible_for_wellknown;
m->is_responsible_for_everything_else =
--
2.13.6
From 6be8aee4f3ecc4c13b404b9c3c130f7754d8ba49 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 10 Dec 2017 20:03:37 +0100
Subject: [PATCH 09/23] pdb_samba_dsdb: implement
pdb_samba_dsdb_set_trusted_domain
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/passdb/pdb_samba_dsdb.c | 390 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 389 insertions(+), 1 deletion(-)
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index e629416974a..a325c4e551f 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -40,6 +40,7 @@
#include "source4/auth/auth_sam.h"
#include "auth/credentials/credentials.h"
#include "lib/util/base64.h"
+#include "libcli/ldap/ldap_ndr.h"
struct pdb_samba_dsdb_state {
struct tevent_context *ev;
@@ -3157,11 +3158,398 @@ static NTSTATUS pdb_samba_dsdb_get_trusted_domain_by_sid(struct pdb_methods *m,
return NT_STATUS_OK;
}
+static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
+ struct ldb_context *sam_ldb,
+ struct ldb_dn *base_dn,
+ const char *netbios_name,
+ struct trustAuthInOutBlob *taiob)
+{
+ struct ldb_request *req = NULL;
+ struct ldb_message *msg = NULL;
+ struct ldb_dn *dn = NULL;
+ uint32_t i;
+ int ret;
+ bool ok;
+
+ dn = ldb_dn_copy(mem_ctx, base_dn);
+ if (dn == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ ok = ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name);
+ if (!ok) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ msg->dn = dn;
+
+ ret = ldb_msg_add_string(msg, "objectClass", "user");
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
+ UF_INTERDOMAIN_TRUST_ACCOUNT);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < taiob->count; i++) {
+ struct AuthenticationInformation *auth_info =
+ &taiob->current.array[i];
+ const char *attribute = NULL;
+ struct ldb_val v;
+
+ switch (taiob->current.array[i].AuthType) {
+ case TRUST_AUTH_TYPE_NT4OWF:
+ attribute = "unicodePwd";
+ v.data = (uint8_t *)&auth_info->AuthInfo.nt4owf.password;
+ v.length = 16;
+ break;
+
+ case TRUST_AUTH_TYPE_CLEAR:
+ attribute = "clearTextPassword";
+ v.data = auth_info->AuthInfo.clear.password;
+ v.length = auth_info->AuthInfo.clear.size;
+ break;
+
+ default:
+ continue;
+ }
+
+ ret = ldb_msg_add_value(msg, attribute, &v, NULL);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ /* create the trusted_domain user account */
+ ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
+ ldb_op_default_callback, NULL);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = ldb_request_add_control(
+ req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = dsdb_autotransaction_request(sam_ldb, req);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("Failed to create user record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(sam_ldb)));
+
+ switch (ret) {
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ return NT_STATUS_DOMAIN_EXISTS;
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ return NT_STATUS_ACCESS_DENIED;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS pdb_samba_dsdb_set_trusted_domain(struct pdb_methods *methods,
const char* domain,
const struct pdb_trusted_domain *td)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ methods->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ bool in_txn = false;
+ struct ldb_dn *base_dn = NULL;
+ struct ldb_message *msg = NULL;
+ const char *attrs[] = {
+ NULL
+ };
+ char *netbios_encoded = NULL;
+ char *dns_encoded = NULL;
+ struct dom_sid *tmp_sid1;
+ struct dom_sid *tmp_sid2;
+ uint32_t tmp_rid;
+ char *sid_encoded = NULL;
+ int ret;
+ struct trustAuthInOutBlob taiob;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+ bool ok;
+
+ base_dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->ldb));
+ if (base_dn == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ /*
+ * We expect S-1-5-21-A-B-C, but we don't
+ * allow S-1-5-21-0-0-0 as this is used
+ * for claims and compound identities.
+ *
+ * So we call dom_sid_split_rid() 3 times
+ * and compare the result to S-1-5-21
+ */
+ status = dom_sid_split_rid(tmp_ctx,
+ &td->security_identifier,
+ &tmp_sid1, &tmp_rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ status = dom_sid_split_rid(tmp_ctx, tmp_sid1, &tmp_sid2, &tmp_rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ status = dom_sid_split_rid(tmp_ctx, tmp_sid2, &tmp_sid1, &tmp_rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ ok = dom_sid_parse("S-1-5-21", tmp_sid2);
+ if (!ok) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto out;
+ }
+ ok = dom_sid_equal(tmp_sid1, tmp_sid2);
+ if (!ok) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ ok = dom_sid_parse("S-1-5-21-0-0-0", tmp_sid2);
+ if (!ok) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ ok = !dom_sid_equal(&td->security_identifier, tmp_sid2);
+ if (!ok) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (strequal(td->netbios_name, "BUILTIN")) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ if (strequal(td->domain_name, "BUILTIN")) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ dns_encoded = ldb_binary_encode_string(tmp_ctx, td->domain_name);
+ if (dns_encoded == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ netbios_encoded = ldb_binary_encode_string(tmp_ctx, td->netbios_name);
+ if (netbios_encoded == NULL) {
+ status =NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ sid_encoded = ldap_encode_ndr_dom_sid(tmp_ctx, &td->security_identifier);
+ if (sid_encoded == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ok = samdb_is_pdc(state->ldb);
+ if (!ok) {
+ DBG_ERR("Adding TDO is only allowed on a PDC.\n");
+ TALLOC_FREE(tmp_ctx);
+ status = NT_STATUS_INVALID_DOMAIN_ROLE;
+ goto out;
+ }
+
+ status = dsdb_trust_search_tdo(state->ldb,
+ td->netbios_name,
+ td->domain_name,
+ attrs,
+ tmp_ctx,
+ &msg);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ DBG_ERR("dsdb_trust_search_tdo returned %s\n",
+ nt_errstr(status));
+ status = NT_STATUS_INVALID_DOMAIN_STATE;
+ goto out;
+ }
+
+ ret = ldb_transaction_start(state->ldb);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto out;
+ }
+ in_txn = true;
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (msg == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ msg->dn = ldb_dn_copy(tmp_ctx, base_dn);
+
+ ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s,cn=System", td->domain_name);
+ if (!ok) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = ldb_msg_add_string(msg, "flatname", td->netbios_name);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = ldb_msg_add_string(msg, "trustPartner", td->domain_name);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = samdb_msg_add_dom_sid(state->ldb,
+ tmp_ctx,
+ msg,
+ "securityIdentifier",
+ &td->security_identifier);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = samdb_msg_add_int(state->ldb,
+ tmp_ctx,
+ msg,
+ "trustType",
+ td->trust_type);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = samdb_msg_add_int(state->ldb,
+ tmp_ctx,
+ msg,
+ "trustAttributes",
+ td->trust_attributes);
+ if (ret != LDB_SUCCESS) {
+ status =NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = samdb_msg_add_int(state->ldb,
+ tmp_ctx,
+ msg,
+ "trustDirection",
+ td->trust_direction);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ if (td->trust_auth_incoming.data != NULL) {
+ ret = ldb_msg_add_value(msg,
+ "trustAuthIncoming",
+ &td->trust_auth_incoming,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ }
+ if (td->trust_auth_outgoing.data != NULL) {
+ ret = ldb_msg_add_value(msg,
+ "trustAuthOutgoing",
+ &td->trust_auth_outgoing,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ }
+
+ /* create the trusted_domain */
+ ret = ldb_add(state->ldb, msg);
+ switch (ret) {
+ case LDB_SUCCESS:
+ break;
+
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ DBG_ERR("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(state->ldb));
+ status = NT_STATUS_DOMAIN_EXISTS;
+ goto out;
+
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ DBG_ERR("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(state->ldb));
+ status = NT_STATUS_ACCESS_DENIED;
+ goto out;
+
+ default:
+ DBG_ERR("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(state->ldb));
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto out;
+ }
+
+ ndr_err = ndr_pull_struct_blob(
+ &td->trust_auth_outgoing,
+ tmp_ctx,
+ &taiob,
+ (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ goto out;
+ }
+
+ if (td->trust_direction == LSA_TRUST_DIRECTION_INBOUND) {
+ status = add_trust_user(tmp_ctx,
+ state->ldb,
+ base_dn,
+ td->netbios_name,
+ &taiob);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ }
+
+ ret = ldb_transaction_commit(state->ldb);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ in_txn = false;
+
+ /*
+ * TODO: Notify winbindd that we have a new trust
+ */
+
+ status = NT_STATUS_OK;
+
+out:
+ if (in_txn) {
+ ldb_transaction_cancel(state->ldb);
+ }
+ TALLOC_FREE(tmp_ctx);
+ return status;
}
static NTSTATUS pdb_samba_dsdb_del_trusted_domain(struct pdb_methods *methods,
--
2.13.6
From 905ddd8067ae612d2cd5ab7115da33527466b262 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Mon, 11 Dec 2017 07:57:27 +0100
Subject: [PATCH 10/23] pdb_samba_dsdb: implement
pdb_samba_dsdb_del_trusted_domain
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/passdb/pdb_samba_dsdb.c | 119 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 118 insertions(+), 1 deletion(-)
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index a325c4e551f..97fba0e7f89 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -41,6 +41,7 @@
#include "auth/credentials/credentials.h"
#include "lib/util/base64.h"
#include "libcli/ldap/ldap_ndr.h"
+#include "lib/util/util_ldb.h"
struct pdb_samba_dsdb_state {
struct tevent_context *ev;
@@ -3552,10 +3553,126 @@ static NTSTATUS pdb_samba_dsdb_set_trusted_domain(struct pdb_methods *methods,
return status;
}
+static NTSTATUS delete_trust_user(TALLOC_CTX *mem_ctx,
+ struct pdb_samba_dsdb_state *state,
+ const char *trust_user)
+{
+ const char *attrs[] = { "userAccountControl", NULL };
+ struct ldb_message **msgs;
+ uint32_t uac;
+ int ret;
+
+ ret = gendb_search(state->ldb,
+ mem_ctx,
+ ldb_get_default_basedn(state->ldb),
+ &msgs,
+ attrs,
+ "samAccountName=%s$",
+ trust_user);
+ if (ret > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (ret == 0) {
+ return NT_STATUS_OK;
+ }
+
+ uac = ldb_msg_find_attr_as_uint(msgs[0],
+ "userAccountControl",
+ 0);
+ if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ ret = ldb_delete(state->ldb, msgs[0]->dn);
+ switch (ret) {
+ case LDB_SUCCESS:
+ break;
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ return NT_STATUS_ACCESS_DENIED;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS pdb_samba_dsdb_del_trusted_domain(struct pdb_methods *methods,
const char *domain)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ methods->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ struct pdb_trusted_domain *td = NULL;
+ struct ldb_dn *tdo_dn = NULL;
+ bool in_txn = false;
+ NTSTATUS status;
+ int ret;
+ bool ok;
+
+ status = pdb_samba_dsdb_get_trusted_domain(methods,
+ tmp_ctx,
+ domain,
+ &td);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ DBG_ERR("Searching TDO for %s returned %s\n",
+ domain, nt_errstr(status));
+ return status;
+ }
+ DBG_NOTICE("No TDO object for %s\n", domain);
+ return NT_STATUS_OK;
+ }
+
+ tdo_dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->ldb));
+ if (tdo_dn == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ok = ldb_dn_add_child_fmt(tdo_dn, "cn=%s,cn=System", domain);
+ if (!ok) {
+ TALLOC_FREE(tmp_ctx);
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ ret = ldb_transaction_start(state->ldb);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto out;
+ }
+ in_txn = true;
+
+ ret = ldb_delete(state->ldb, tdo_dn);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_INVALID_HANDLE;
+ goto out;
+ }
+
+ if (td->trust_direction == LSA_TRUST_DIRECTION_INBOUND) {
+ status = delete_trust_user(tmp_ctx, state, domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ }
+
+ ret = ldb_transaction_commit(state->ldb);
+ if (ret != LDB_SUCCESS) {
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto out;
+ }
+ in_txn = false;
+
+ status = NT_STATUS_OK;
+
+out:
+ if (in_txn) {
+ ldb_transaction_cancel(state->ldb);
+ }
+ TALLOC_FREE(tmp_ctx);
+
+ return status;
}
static NTSTATUS pdb_samba_dsdb_enum_trusted_domains(struct pdb_methods *m,
--
2.13.6
From 9e10df93201360fbbe632a857841881e4f307b07 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Tue, 19 Dec 2017 23:44:00 +0100
Subject: [PATCH 11/23] pdb_samba_dsdb: set PDB_CAP_TRUSTED_DOMAINS_EX
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/passdb/pdb_samba_dsdb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index 97fba0e7f89..16a7a85bdfd 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -2134,7 +2134,7 @@ static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid
static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
{
- return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
+ return PDB_CAP_STORE_RIDS | PDB_CAP_ADS | PDB_CAP_TRUSTED_DOMAINS_EX;
}
static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32_t *rid)
--
2.13.6
From e298a70dd297b6673552c72cbfb9cc36a324f8fe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 29 Nov 2017 15:55:12 +0100
Subject: [PATCH 12/23] winbindd: load the trusted domains on a DC already in
init_domain_list()
We should do that in the parent as early as possible.
Similar to our primary domain, which is also a direct trust.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_util.c | 175 +++++++++++++++++++++++++++++++++++++++
1 file changed, 175 insertions(+)
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 9c8e39f79c1..2f145cdd48a 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -30,6 +30,7 @@
#include "passdb.h"
#include "source4/lib/messaging/messaging.h"
#include "librpc/gen_ndr/ndr_lsa.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "auth/credentials/credentials.h"
#include "libsmb/samlogon_cache.h"
@@ -1035,6 +1036,180 @@ bool init_domain_list(void)
}
+ if (IS_DC && (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
+ uint32_t num_domains = 0;
+ struct pdb_trusted_domain **domains = NULL;
+ uint32_t i;
+
+ status = pdb_enum_trusted_domains(talloc_tos(), &num_domains, &domains);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("pdb_enum_trusted_domains() failed - %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ for (i = 0; i < num_domains; i++) {
+ enum netr_SchannelType sec_chan_type = SEC_CHAN_DOMAIN;
+ uint32_t trust_flags = 0;
+
+ if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
+ sec_chan_type = SEC_CHAN_DNS_DOMAIN;
+ }
+
+ if (!(domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
+ sec_chan_type = SEC_CHAN_NULL;
+ }
+
+ if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
+ trust_flags |= NETR_TRUST_FLAG_INBOUND;
+ }
+ if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
+ trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
+ }
+ if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
+ trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
+ }
+
+ status = add_trusted_domain(domains[i]->netbios_name,
+ domains[i]->domain_name,
+ &domains[i]->security_identifier,
+ domains[i]->trust_type,
+ trust_flags,
+ domains[i]->trust_attributes,
+ sec_chan_type,
+ &domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_NOTICE("add_trusted_domain returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
+ domain->active_directory = true;
+ }
+ domain->domain_type = domains[i]->trust_type;
+ domain->domain_trust_attribs = domains[i]->trust_attributes;
+
+ if (sec_chan_type != SEC_CHAN_NULL) {
+ /* Even in the parent winbindd we'll need to
+ talk to the DC, so try and see if we can
+ contact it. Theoretically this isn't neccessary
+ as the init_dc_connection() in init_child_recv()
+ will do this, but we can start detecting the DC
+ early here. */
+ set_domain_online_request(domain);
+ }
+ }
+
+ for (i = 0; i < num_domains; i++) {
+ struct ForestTrustInfo fti;
+ uint32_t fi;
+ enum ndr_err_code ndr_err;
+
+ 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;
+ }
+
+ 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,
+ &domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_NOTICE("add_trusted_domain returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ }
+ }
+ } else if (IS_DC) {
+ uint32_t num_domains = 0;
+ struct trustdom_info **domains = NULL;
+ uint32_t i;
+
+ status = pdb_enum_trusteddoms(talloc_tos(), &num_domains, &domains);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("pdb_enum_trusteddoms() failed - %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ for (i = 0; i < num_domains; i++) {
+ status = add_trusted_domain(domains[i]->name,
+ NULL,
+ &domains[i]->sid,
+ LSA_TRUST_TYPE_DOWNLEVEL,
+ NETR_TRUST_FLAG_OUTBOUND,
+ 0,
+ SEC_CHAN_DOMAIN,
+ &domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_NOTICE("add_trusted_domain returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ /* Even in the parent winbindd we'll need to
+ talk to the DC, so try and see if we can
+ contact it. Theoretically this isn't neccessary
+ as the init_dc_connection() in init_child_recv()
+ will do this, but we can start detecting the DC
+ early here. */
+ set_domain_online_request(domain);
+ }
+ }
+
status = imessaging_register(winbind_imessaging_context(), NULL,
MSG_WINBIND_NEW_TRUSTED_DOMAIN,
wb_imsg_new_trusted_domain);
--
2.13.6
From cab6a9a446cd215a4d8dbbfe675f125ebed71fc7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 13 Dec 2017 17:08:10 +0100
Subject: [PATCH 13/23] winbindd: add find_default_route_domain()
On a member server this is just our primary domain. The logic for DCs is
not yet implemented, on a DC of a child-domain in a forrest this would
be the parent domain.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_proto.h | 1 +
source3/winbindd/winbindd_util.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index dd6767a02ab..5ab1e8fd590 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -451,6 +451,7 @@ struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid);
struct winbindd_domain *find_trust_from_sid_noinit(const struct dom_sid *sid);
struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid);
struct winbindd_domain *find_our_domain(void);
+struct winbindd_domain *find_default_route_domain(void);
struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid);
struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name);
bool parse_domain_user(const char *domuser, fstring domain, fstring user);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 2f145cdd48a..dd3206c01f4 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -1366,6 +1366,15 @@ struct winbindd_domain *find_our_domain(void)
return NULL;
}
+struct winbindd_domain *find_default_route_domain(void)
+{
+ if (!IS_DC) {
+ return find_our_domain();
+ }
+ DBG_ERR("Routing logic not yet implemented on a DC");
+ return NULL;
+}
+
/* Find the appropriate domain to lookup a name or SID */
struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid)
--
2.13.6
From c347902a1d052ad1ea63f4533071ad362369c770 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 13 Dec 2017 17:11:25 +0100
Subject: [PATCH 14/23] winbindd: add set_routing_domain()
---
source3/winbindd/winbindd.h | 1 +
source3/winbindd/winbindd_proto.h | 2 ++
source3/winbindd/winbindd_util.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 682040fd1a7..b60094bafcd 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -143,6 +143,7 @@ struct winbindd_domain {
uint32_t domain_flags; /* Domain flags from netlogon.h */
uint32_t domain_type; /* Domain type from netlogon.h */
uint32_t domain_trust_attribs; /* Trust attribs from netlogon.h */
+ const struct winbindd_domain *routing_domain;
bool initialized; /* Did we already ask for the domain mode? */
bool native_mode; /* is this a win2k domain in native mode ? */
bool active_directory; /* is this a win2k active directory ? */
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 5ab1e8fd590..4ab52a42ba5 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -438,6 +438,8 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
struct winbindd_domain *domain_list(void);
struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain);
+bool set_routing_domain(struct winbindd_domain *domain,
+ const struct winbindd_domain *routing_domain);
bool domain_is_forest_root(const struct winbindd_domain *domain);
void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
struct timeval now, void *private_data);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index dd3206c01f4..fb1793d250a 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -290,6 +290,19 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
return NT_STATUS_OK;
}
+bool set_routing_domain(struct winbindd_domain *domain,
+ const struct winbindd_domain *routing_domain)
+{
+ if (domain->routing_domain == NULL) {
+ domain->routing_domain = routing_domain;
+ return true;
+ }
+ if (domain->routing_domain != routing_domain) {
+ return false;
+ }
+ return true;
+}
+
bool domain_is_forest_root(const struct winbindd_domain *domain)
{
const uint32_t fr_flags =
@@ -1105,6 +1118,8 @@ bool init_domain_list(void)
struct ForestTrustInfo fti;
uint32_t fi;
enum ndr_err_code ndr_err;
+ struct winbindd_domain *routing_domain = NULL;
+ bool ok;
if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
continue;
@@ -1118,6 +1133,14 @@ bool init_domain_list(void)
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,
@@ -1171,6 +1194,17 @@ bool init_domain_list(void)
nt_errstr(status));
return false;
}
+ if (domain == NULL) {
+ continue;
+ }
+ ok = set_routing_domain(domain, routing_domain);
+ if (!ok) {
+ DBG_ERR("set_routing_domain on [%s] to "
+ "[%s] failed\n",
+ domain->name,
+ routing_domain->name);
+ return false;
+ }
}
}
} else if (IS_DC) {
--
2.13.6
From 1cdbd1ae9692879f3ec875e106d00e1f9bce163c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 29 Nov 2017 10:10:38 +0100
Subject: [PATCH 15/23] winbindd: add add_trusted_domain_from_auth
Function to add a new trusted domain to the domain list and TDC after an
successfull authentication. On Member servers only, not on DCs though.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_proto.h | 3 +++
source3/winbindd/winbindd_util.c | 55 +++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 4ab52a42ba5..39cdef54531 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -440,6 +440,9 @@ struct winbindd_domain *domain_list(void);
struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain);
bool set_routing_domain(struct winbindd_domain *domain,
const struct winbindd_domain *routing_domain);
+bool add_trusted_domain_from_auth(uint16_t validation_level,
+ struct info3_text *info3,
+ struct info6_text *info6);
bool domain_is_forest_root(const struct winbindd_domain *domain);
void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
struct timeval now, void *private_data);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index fb1793d250a..2a975220ad0 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -303,6 +303,61 @@ bool set_routing_domain(struct winbindd_domain *domain,
return true;
}
+bool add_trusted_domain_from_auth(uint16_t validation_level,
+ struct info3_text *info3,
+ struct info6_text *info6)
+{
+ struct winbindd_domain *domain = NULL;
+ struct dom_sid domain_sid;
+ const char *dns_domainname = NULL;
+ NTSTATUS status;
+ bool ok;
+
+ /*
+ * We got a successfull auth from a domain that might not yet be in our
+ * domain list. If we're a member we trust our DC who authenticated the
+ * user from that domain and add the domain to our list on-the-fly. If
+ * we're a DC we rely on configured trusts and don't add on-the-fly.
+ */
+
+ if (IS_DC) {
+ return true;
+ }
+
+ ok = dom_sid_parse(info3->dom_sid, &domain_sid);
+ if (!ok) {
+ DBG_NOTICE("dom_sid_parse [%s] failed\n", info3->dom_sid);
+ return false;
+ }
+
+ if (validation_level == 6) {
+ dns_domainname = &info6->dns_domainname[0];
+ }
+
+ status = add_trusted_domain(info3->logon_dom,
+ dns_domainname,
+ &domain_sid,
+ 0,
+ NETR_TRUST_FLAG_OUTBOUND,
+ 0,
+ SEC_CHAN_NULL,
+ &domain);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
+ {
+ DBG_DEBUG("Adding domain [%s] with sid [%s] failed\n",
+ info3->logon_dom, info3->dom_sid);
+ return false;
+ }
+
+ ok = set_routing_domain(domain, find_default_route_domain());
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
bool domain_is_forest_root(const struct winbindd_domain *domain)
{
const uint32_t fr_flags =
--
2.13.6
From 3b91a39c3aa3e30ed2b6e7031e606633183a1377 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 29 Nov 2017 10:55:25 +0100
Subject: [PATCH 16/23] winbindd: use add_trusted_domain_from_auth
After a successfully authentication, ensure we have the users domain in our
domain list and the TDC.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_pam_auth.c | 15 +++++++++++++++
source3/winbindd/winbindd_pam_auth_crap.c | 24 +++++++++++++++++++++---
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/source3/winbindd/winbindd_pam_auth.c b/source3/winbindd/winbindd_pam_auth.c
index 7ff44888975..b35a17cf319 100644
--- a/source3/winbindd/winbindd_pam_auth.c
+++ b/source3/winbindd/winbindd_pam_auth.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "winbindd.h"
+#include "libcli/security/dom_sid.h"
struct winbindd_pam_auth_state {
struct winbindd_request *request;
@@ -127,6 +128,20 @@ NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req,
return status;
}
+ if (state->request->flags & WBFLAG_PAM_INFO3_TEXT) {
+ bool ok;
+
+ ok = add_trusted_domain_from_auth(
+ state->response->data.auth.validation_level,
+ &state->response->data.auth.info3,
+ &state->response->data.auth.info6);
+ if (!ok) {
+ DBG_ERR("add_trusted_domain_from_auth failed\n");
+ set_auth_errors(response, NT_STATUS_LOGON_FAILURE);
+ return NT_STATUS_LOGON_FAILURE;
+ }
+ }
+
if (state->request->flags & WBFLAG_PAM_CACHED_LOGIN) {
/* Store in-memory creds for single-signon using ntlm_auth. */
diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
index 695ee1d0864..eb4087b1c2c 100644
--- a/source3/winbindd/winbindd_pam_auth_crap.c
+++ b/source3/winbindd/winbindd_pam_auth_crap.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "winbindd.h"
#include "rpc_client/util_netlogon.h"
+#include "libcli/security/dom_sid.h"
struct winbindd_pam_auth_crap_state {
struct winbindd_response *response;
@@ -46,10 +47,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
return NULL;
}
- if (request->flags & WBFLAG_PAM_AUTH_PAC) {
+ state->flags = request->flags;
+
+ if (state->flags & WBFLAG_PAM_AUTH_PAC) {
NTSTATUS status;
- state->flags = request->flags;
status = winbindd_pam_auth_pac_send(cli, &state->info3);
if (NT_STATUS_IS_OK(status)) {
/* Defer filling out response to recv */
@@ -132,7 +134,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
return status;
}
- if (state->flags & WBFLAG_PAM_AUTH_PAC) {
+ if (state->flags & WBFLAG_PAM_AUTH_PAC) {
uint16_t validation_level;
union netr_Validation *validation = NULL;
@@ -155,6 +157,22 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
}
+ if (NT_STATUS_IS_OK(NT_STATUS(state->response->data.auth.nt_status)) &&
+ (state->flags & WBFLAG_PAM_INFO3_TEXT))
+ {
+ bool ok;
+
+ ok = add_trusted_domain_from_auth(
+ state->response->data.auth.validation_level,
+ &state->response->data.auth.info3,
+ &state->response->data.auth.info6);
+ if (!ok) {
+ DBG_ERR("add_trusted_domain_from_auth failed\n");
+ set_auth_errors(response, NT_STATUS_LOGON_FAILURE);
+ return NT_STATUS_LOGON_FAILURE;
+ }
+ }
+
*response = *state->response;
response->result = WINBINDD_PENDING;
state->response = talloc_move(response, &state->response);
--
2.13.6
From c605a0c9c0444e8b68aac32b45229e9e8359f411 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Tue, 28 Nov 2017 17:32:59 +0100
Subject: [PATCH 17/23] winbindd: transitive trust logic in
trust_is_transitive()
trust_is_transitive() currently defaults to transitive=true, unless
LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE, LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN or
LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL trust attribute is set.
This is not correct, for the trust to be transative,
LSA_TRUST_ATTRIBUTE_WITHIN_FOREST or LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE must
be set.
Logic taken from dsdb_trust_routing_by_name().
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_misc.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index c80e7844bc2..51c8799de32 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -78,11 +78,33 @@ static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
{
- if ((domain->trust_attribs == LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
- (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
- (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
- return False;
- return True;
+ bool transitive = false;
+
+ /*
+ * Beware: order matters
+ */
+
+ if (domain->trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
+ transitive = true;
+ }
+
+ if (domain->trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
+ transitive = true;
+ }
+
+ if (domain->trust_attribs & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) {
+ transitive = false;
+ }
+
+ if (domain->trust_attribs & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) {
+ transitive = false;
+ }
+
+ if (domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) {
+ transitive = true;
+ }
+
+ return transitive;
}
void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
--
2.13.6
From fd9b95bb9c8441d3d658ad0e110549f33d99efd4 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Tue, 28 Nov 2017 17:44:41 +0100
Subject: [PATCH 18/23] winbindd: fix trust_is_inbound()
A trust is only inbound if NETR_TRUST_FLAG_INBOUND is set. Trust flags = 0x0
does not imply an inbound trust, nor does NETR_TRUST_FLAG_IN_FOREST.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_misc.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 51c8799de32..051e9515f31 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -60,11 +60,10 @@ static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
{
- return (domain->trust_flags == 0x0) ||
- ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
- NETR_TRUST_FLAG_IN_FOREST) ||
- ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) ==
- NETR_TRUST_FLAG_INBOUND);
+ if (domain->trust_flags & NETR_TRUST_FLAG_INBOUND) {
+ return true;
+ }
+ return false;
}
static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
--
2.13.6
From 47d51f3ecf7395ee56a4cbaf63c8dbe1d2aba4d4 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Tue, 28 Nov 2017 17:46:03 +0100
Subject: [PATCH 19/23] winbindd: fix trust_is_oubound()
A trust is only inbound if NETR_TRUST_FLAG_OUTBOUND is set. Trust flags = 0x0
does not imply an outbound trust, nor does NETR_TRUST_FLAG_IN_FOREST.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_misc.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 051e9515f31..d2741cb6b6f 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -68,11 +68,10 @@ static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
{
- return (domain->trust_flags == 0x0) ||
- ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
- NETR_TRUST_FLAG_IN_FOREST) ||
- ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) ==
- NETR_TRUST_FLAG_OUTBOUND);
+ if (domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) {
+ return true;
+ }
+ return false;
}
static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
--
2.13.6
From 75b76c200e12af5bd37b05dda53ae40136ee4891 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Tue, 19 Dec 2017 17:26:46 +0100
Subject: [PATCH 20/23] libwbclient: add trust routing and more trust-types
This adds the struct member and the defines, the implementation comes
later.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
nsswitch/libwbclient/wbclient.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index ed97a673739..81a6a6a069b 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -187,6 +187,7 @@ struct wbcDomainInfo {
uint32_t domain_flags;
uint32_t trust_flags;
uint32_t trust_type;
+ char *trust_routing;
};
/* wbcDomainInfo->domain_flags */
@@ -209,6 +210,12 @@ struct wbcDomainInfo {
#define WBC_DOMINFO_TRUSTTYPE_FOREST 0x00000001
#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002
#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003
+#define WBC_DOMINFO_TRUSTTYPE_LOCAL 0x00000004
+#define WBC_DOMINFO_TRUSTTYPE_WKSTA 0x00000005
+#define WBC_DOMINFO_TRUSTTYPE_RWDC 0x00000006
+#define WBC_DOMINFO_TRUSTTYPE_RODC 0x00000007
+#define WBC_DOMINFO_TRUSTTYPE_PDC 0x00000008
+
/**
* @brief Generic Blob
--
2.13.6
From 4427f4d4f7a5757a886a98cb3a769bd828d379e2 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 13 Dec 2017 16:02:22 +0100
Subject: [PATCH 21/23] wbinfo: support for local, workstation and routed trust
types
Prepare wbinfo for additional trust types and trust routing.
This also modifies the output line for a "None" trust type by skipping
the transitivity and direction -- that just doesn't make sense without a
trust.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
nsswitch/wbinfo.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 9cd299a2174..54d5758aa6c 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -536,7 +536,26 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
switch(domain_list[i].trust_type) {
case WBC_DOMINFO_TRUSTTYPE_NONE:
- d_printf("None ");
+ if (domain_list[i].trust_routing != NULL) {
+ d_printf("%s\n", domain_list[i].trust_routing);
+ } else {
+ d_printf("None\n");
+ }
+ continue;
+ case WBC_DOMINFO_TRUSTTYPE_LOCAL:
+ d_printf("Local\n");
+ continue;
+ case WBC_DOMINFO_TRUSTTYPE_RWDC:
+ d_printf("RWDC\n");
+ continue;
+ case WBC_DOMINFO_TRUSTTYPE_RODC:
+ d_printf("RODC\n");
+ continue;
+ case WBC_DOMINFO_TRUSTTYPE_PDC:
+ d_printf("PDC\n");
+ continue;
+ case WBC_DOMINFO_TRUSTTYPE_WKSTA:
+ d_printf("Workstation ");
break;
case WBC_DOMINFO_TRUSTTYPE_FOREST:
d_printf("Forest ");
--
2.13.6
From 1faad25ac4a2b811a9c8f71c7626af9c7621e69b Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 13 Dec 2017 16:01:50 +0100
Subject: [PATCH 22/23] libwbclient: add more trust types
Prepare libwbclient for additional trust types and trust routing.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
nsswitch/libwbclient/wbc_util.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/nsswitch/libwbclient/wbc_util.c b/nsswitch/libwbclient/wbc_util.c
index 3dab0a2de1b..ecfcaa0fb60 100644
--- a/nsswitch/libwbclient/wbc_util.c
+++ b/nsswitch/libwbclient/wbc_util.c
@@ -455,8 +455,22 @@ static wbcErr process_domain_info_string(struct wbcDomainInfo *info,
*s = '\0';
s++;
- if (strcmp(r, "None") == 0) {
+ if (strcmp(r, "Local") == 0) {
info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
+ } else if (strncmp(r, "Routed", strlen("Routed")) == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
+ info->trust_routing = strdup(r);
+ BAIL_ON_PTR_ERROR(info->trust_routing, wbc_status);
+ } else if (strcmp(r, "Local") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_LOCAL;
+ } else if (strcmp(r, "Workstation") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_WKSTA;
+ } else if (strcmp(r, "RWDC") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_RWDC;
+ } else if (strcmp(r, "RODC") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_RODC;
+ } else if (strcmp(r, "PDC") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_PDC;
} else if (strcmp(r, "External") == 0) {
info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
} else if (strcmp(r, "Forest") == 0) {
--
2.13.6
From 6840a7d887ffbf9450ddaa8709902c3d23d2eca6 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 13 Dec 2017 08:53:16 +0100
Subject: [PATCH 23/23] winbindd: add more trust types to get_trust_type_string
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add support for the following trust types: "Local", "Workstation",
"RWDC", "RODC"´and "Routed (via ...)".
Where we previously returned "None" this now returns "Routed (via ...)",
otherwise (hopefully) no change in behaviour.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
source3/winbindd/winbindd_misc.c | 159 ++++++++++++++++++++++++++++++++-------
1 file changed, 133 insertions(+), 26 deletions(-)
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index d2741cb6b6f..964190e7c62 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -27,35 +27,133 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
-/* Constants and helper functions for determining domain trust types */
+static char *get_trust_type_string(TALLOC_CTX *mem_ctx,
+ struct winbindd_tdc_domain *tdc,
+ struct winbindd_domain *domain)
+{
+ enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
+ char *s = NULL;
-enum trust_type {
- EXTERNAL = 0,
- FOREST,
- IN_FOREST,
- NONE,
-};
+ if (domain != NULL) {
+ secure_channel_type = domain->secure_channel_type;
+ }
-const char *trust_type_strings[] = {"External",
- "Forest",
- "In Forest",
- "None"};
+ switch (secure_channel_type) {
+ case SEC_CHAN_NULL: {
+ if (domain == NULL) {
+ DBG_ERR("Missing domain [%s]\n",
+ tdc->domain_name);
+ return NULL;
+ }
+ if (domain->routing_domain == NULL) {
+ DBG_ERR("Missing routing for domain [%s]\n",
+ tdc->domain_name);
+ return NULL;
+ }
+ s = talloc_asprintf(mem_ctx, "Routed (via %s)",
+ domain->routing_domain->name);
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
-static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
-{
- if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
- return EXTERNAL;
- else if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
- return FOREST;
- else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
- ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0))
- return IN_FOREST;
- return NONE;
-}
+ case SEC_CHAN_LOCAL:
+ s = talloc_strdup(mem_ctx, "Local");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
-static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
-{
- return trust_type_strings[get_trust_type(domain)];
+ case SEC_CHAN_WKSTA:
+ s = talloc_strdup(mem_ctx, "Workstation");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+
+ case SEC_CHAN_BDC: {
+ int role = lp_server_role();
+
+ if (role == ROLE_DOMAIN_PDC) {
+ s = talloc_strdup(mem_ctx, "PDC");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+
+ if (role == ROLE_DOMAIN_BDC) {
+ s = talloc_strdup(mem_ctx, "BDC");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+
+ s = talloc_strdup(mem_ctx, "RWDC");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+
+ case SEC_CHAN_RODC:
+ s = talloc_strdup(mem_ctx, "RODC");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+
+ case SEC_CHAN_DNS_DOMAIN:
+ if (tdc->trust_attribs & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) {
+ s = talloc_strdup(mem_ctx, "External");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+ if (tdc->trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
+ s = talloc_strdup(mem_ctx, "In Forest");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+ if (tdc->trust_attribs & LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) {
+ s = talloc_strdup(mem_ctx, "External");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+ if (tdc->trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
+ s = talloc_strdup(mem_ctx, "Forest");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+ }
+ s = talloc_strdup(mem_ctx, "External");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+
+ case SEC_CHAN_DOMAIN:
+ s = talloc_strdup(mem_ctx, "External");
+ if (s == NULL) {
+ return NULL;
+ }
+ break;
+
+ default:
+ DBG_ERR("Unhandled secure_channel_type %d for domain[%s]\n",
+ secure_channel_type, tdc->domain_name);
+ return NULL;
+ }
+
+ return s;
}
static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
@@ -131,23 +229,32 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
struct winbindd_domain *domain;
bool is_online = true;
struct winbindd_tdc_domain *d = NULL;
+ char *trust_type = NULL;
d = &dom_list[i];
domain = find_domain_from_name_noinit(d->domain_name);
if (domain) {
is_online = domain->online;
}
+
+ trust_type = get_trust_type_string(talloc_tos(), d, domain);
+ if (trust_type == NULL) {
+ continue;
+ }
+
extra_data = talloc_asprintf_append_buffer(
extra_data,
"%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n",
d->domain_name,
d->dns_name ? d->dns_name : "",
sid_string_talloc(state->mem_ctx, &d->sid),
- get_trust_type_string(d),
+ trust_type,
trust_is_transitive(d) ? "Yes" : "No",
trust_is_inbound(d) ? "Yes" : "No",
trust_is_outbound(d) ? "Yes" : "No",
is_online ? "Online" : "Offline" );
+
+ TALLOC_FREE(trust_type);
}
state->response->data.num_entries = num_domains;
--
2.13.6
More information about the samba-technical
mailing list