diff options
author | Alexander Bokovoy <ab@samba.org> | 2013-04-03 16:52:45 +0300 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2013-04-09 22:19:34 +0200 |
commit | a308db6587c866826a280a60b841f0a3926c1078 (patch) | |
tree | ce759d7398741be17535e506fda5925e489b256c | |
parent | 5952755755fb0ea7f942bb564ca1cfdca5730113 (diff) | |
download | samba-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.c | 106 |
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; |