diff options
author | Matthias Dieter Wallnöfer <mdw@samba.org> | 2010-04-13 22:49:48 +0200 |
---|---|---|
committer | Matthias Dieter Wallnöfer <mdw@samba.org> | 2010-04-27 08:09:12 +0200 |
commit | 2654e34cf092f1ec49e1462b67a10c681da4d3df (patch) | |
tree | 8a58cc76927e72110b800de73d31d54ebff2c33e /source4/rpc_server/netlogon | |
parent | bb91afe50c2fb1ab8dc102ddef339bd7d46ff84a (diff) | |
download | samba-2654e34cf092f1ec49e1462b67a10c681da4d3df.tar.gz samba-2654e34cf092f1ec49e1462b67a10c681da4d3df.tar.bz2 samba-2654e34cf092f1ec49e1462b67a10c681da4d3df.zip |
s4:netr_DsRAddressToSitenames[Ex]W calls - implement them correctly with the client site information
This behaviour should be similar to the one of Windows Server (in my case 2008)
Diffstat (limited to 'source4/rpc_server/netlogon')
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 114 |
1 files changed, 98 insertions, 16 deletions
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index f65b5a65b9..a62a2acf41 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1516,16 +1516,6 @@ static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, /* - netr_DsRAddressToSitenamesW -*/ -static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_DsRAddressToSitenamesW *r) -{ - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); -} - - -/* netr_DsRGetDCNameEx2 */ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, @@ -1676,12 +1666,27 @@ static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_DsRAddressToSitenamesExW *r) { + struct ldb_context *sam_ctx; struct netr_DsRAddressToSitenamesExWCtr *ctr; - int i; + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + uint16_t sin_family; + struct sockaddr_in *addr; +#ifdef HAVE_IPV6 + struct sockaddr_in6 *addr6; + char addr_str[INET6_ADDRSTRLEN]; +#else + char addr_str[INET_ADDRSTRLEN]; +#endif + char *subnet_name; + const char *res; + uint32_t i; + + sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, + dce_call->conn->auth_state.session_info); + if (sam_ctx == NULL) { + return WERR_DS_UNAVAILABLE; + } - /* we should map the provided IPs to site names, once we have - * sites support - */ ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr); W_ERROR_HAVE_NO_MEMORY(ctr); @@ -1694,9 +1699,47 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce W_ERROR_HAVE_NO_MEMORY(ctr->subnetname); for (i=0; i<ctr->count; i++) { - /* FIXME: Hardcoded site name */ - ctr->sitename[i].string = "Default-First-Site-Name"; + ctr->sitename[i].string = NULL; ctr->subnetname[i].string = NULL; + + if (r->in.addresses[i].size < sizeof(sin_family)) { + continue; + } + sin_family = SVAL(r->in.addresses[i].buffer, 0); + + switch (sin_family) { + case AF_INET: + if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) { + continue; + } + addr = (struct sockaddr_in *) r->in.addresses[i].buffer; + res = inet_ntop(AF_INET, &addr->sin_addr, + addr_str, sizeof(addr_str)); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) { + continue; + } + addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer; + res = inet_ntop(AF_INET6, &addr6->sin6_addr, + addr_str, sizeof(addr_str)); + break; +#endif + default: + continue; + } + + if (res == NULL) { + continue; + } + + ctr->sitename[i].string = samdb_client_site_name(sam_ctx, + mem_ctx, + addr_str, + &subnet_name); + W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string); + ctr->subnetname[i].string = subnet_name; } return WERR_OK; @@ -1704,6 +1747,45 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce /* + netr_DsRAddressToSitenamesW +*/ +static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct netr_DsRAddressToSitenamesW *r) +{ + struct netr_DsRAddressToSitenamesExW r2; + struct netr_DsRAddressToSitenamesWCtr *ctr; + uint32_t i; + WERROR werr; + + ZERO_STRUCT(r2); + + r2.in.server_name = r->in.server_name; + r2.in.count = r->in.count; + r2.in.addresses = r->in.addresses; + + r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *); + W_ERROR_HAVE_NO_MEMORY(r2.out.ctr); + + ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr); + W_ERROR_HAVE_NO_MEMORY(ctr); + + *r->out.ctr = ctr; + + ctr->count = r->in.count; + ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count); + W_ERROR_HAVE_NO_MEMORY(ctr->sitename); + + werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2); + + for (i=0; i<ctr->count; i++) { + ctr->sitename[i].string = (*r2.out.ctr)->sitename[i].string; + } + + return werr; +} + + +/* netr_DsrGetDcSiteCoverageW */ static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, |