summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2013-04-03 16:52:45 +0300
committerAndreas Schneider <asn@cryptomilk.org>2013-04-09 22:19:34 +0200
commita308db6587c866826a280a60b841f0a3926c1078 (patch)
treece759d7398741be17535e506fda5925e489b256c
parent5952755755fb0ea7f942bb564ca1cfdca5730113 (diff)
downloadsamba-a308db6587c866826a280a60b841f0a3926c1078.tar.gz
samba-a308db6587c866826a280a60b841f0a3926c1078.tar.bz2
samba-a308db6587c866826a280a60b841f0a3926c1078.zip
s3-netlogon: enumerate UPN suffixes from PASSDB when available
Optionally append list of UPN suffixes if PDB module returns non-empty one. Refactor fill_forest_trust_array() in source3 to allow reuse of the code between _netr_DsRGetForestTrustInformation() and _netr_GetForestTrustInformation() Implement a special case of _netr_DsRGetForestTrustInformation in smbd when trusted_domain_name is NULL (covered by test_DsrEnumerateDomainTrusts() in rpc.netlogon torture tests, see comment in source4/torture/rpc/netlogon.c). Reviewed-by: Andreas Schneider <asn@samba.org> Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> Autobuild-Date(master): Tue Apr 9 22:19:34 CEST 2013 on sn-devel-104
-rw-r--r--source3/rpc_server/netlogon/srv_netlog_nt.c106
1 files changed, 94 insertions, 12 deletions
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index e5da138491..6a6c125da9 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -2292,22 +2292,16 @@ NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
/****************************************************************
****************************************************************/
-WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
- struct netr_DsRGetForestTrustInformation *r)
-{
- p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
-****************************************************************/
-
static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
struct lsa_ForestTrustInformation *info)
{
struct lsa_ForestTrustRecord *e;
struct pdb_domain_info *dom_info;
struct lsa_ForestTrustDomainInfo *domain_info;
+ char **upn_suffixes = NULL;
+ uint32_t num_suffixes = 0;
+ uint32_t i = 0;
+ NTSTATUS status;
dom_info = pdb_get_domain_info(mem_ctx);
if (dom_info == NULL) {
@@ -2315,7 +2309,15 @@ static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
}
info->count = 2;
- info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2);
+
+ become_root();
+ status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
+ unbecome_root();
+ if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
+ info->count += num_suffixes;
+ }
+
+ info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
if (info->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -2333,6 +2335,21 @@ static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
info->entries[0] = e;
+ if (num_suffixes > 0) {
+ for (i = 0; i < num_suffixes ; i++) {
+ e = talloc(info, struct lsa_ForestTrustRecord);
+ if (e == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ e->flags = 0;
+ e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+ e->time = 0; /* so far always 0 in traces. */
+ e->forest_trust_data.top_level_name.string = upn_suffixes[i];
+ info->entries[1 + i] = e;
+ }
+ }
+
e = talloc(info, struct lsa_ForestTrustRecord);
if (e == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -2351,12 +2368,76 @@ static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
domain_info->netbios_domain_name.string = talloc_steal(info,
dom_info->name);
- info->entries[1] = e;
+ info->entries[info->count - 1] = e;
return NT_STATUS_OK;
}
/****************************************************************
+****************************************************************/
+
+WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
+ struct netr_DsRGetForestTrustInformation *r)
+{
+ NTSTATUS status;
+ struct lsa_ForestTrustInformation *info, **info_ptr;
+
+ if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
+ && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
+ p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
+ return WERR_ACCESS_DENIED;
+ }
+
+ if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_INVALID_FLAGS;
+ }
+
+ if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NERR_NOTPRIMARY;
+ }
+
+ if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_INVALID_PARAMETER;
+ }
+
+ /* retrieve forest trust information and stop further processing */
+ if (r->in.trusted_domain_name == NULL) {
+ info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
+ if (info_ptr == NULL) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+ info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
+ if (info == NULL) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+
+ /* Fill forest trust information and expand UPN suffixes list */
+ status = fill_forest_trust_array(p->mem_ctx, info);
+ if (!NT_STATUS_IS_OK(status)) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+
+ *info_ptr = info;
+ r->out.forest_trust_info = info_ptr;
+
+ return WERR_OK;
+
+ }
+
+ /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
+ * when trusted_domain_name is not NULL */
+
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
_netr_GetForestTrustInformation
****************************************************************/
@@ -2400,6 +2481,7 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
return NT_STATUS_NO_MEMORY;
}
+ /* Fill forest trust information, do expand UPN suffixes list */
status = fill_forest_trust_array(p->mem_ctx, info);
if (!NT_STATUS_IS_OK(status)) {
return status;