The branch, master has been updated via 1e08449... s4:fill_netlogon_samlogon_reponse - fix a typo via 7d5a8c3... s4:torture/netlogon - enhance test for "dcesrv_netr_DsRGetDCNameEx2" via aa02f44... s4:dcesrv_netr_DsRGetDCNameEx2 - provide a much better implementation via 4d7d6ee... s4:fill_netlogon_samlogon_response - some rework of the detection code from 3909088... s4: prevent the autoconf build from removing source4/librpc/gen_ndr/README
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1e08449136e87f70d581714284f86f88d54c20fd Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Tue Apr 13 15:29:12 2010 +0200 s4:fill_netlogon_samlogon_reponse - fix a typo commit 7d5a8c3506b3bb4005820ce2ab6687bbf9c2dd40 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Tue Apr 13 09:53:28 2010 +0200 s4:torture/netlogon - enhance test for "dcesrv_netr_DsRGetDCNameEx2" Test for right domainname handling. commit aa02f4425579d5fb45da3216462273c973fcaa64 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Apr 12 18:00:49 2010 +0200 s4:dcesrv_netr_DsRGetDCNameEx2 - provide a much better implementation On the base of the "fill_netlogon_samlogon_response" call. This removes duplicated code. commit 4d7d6ee8202f75b44c25a747e83ddda5466aa509 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Tue Apr 13 15:18:02 2010 +0200 s4:fill_netlogon_samlogon_response - some rework of the detection code To make it compatible by the use of the "dcesrv_netr_DsRGetDCName*" calls. Some result checks were redundant so I removed them. In other cases I added debug outputs. Sometimes the debug messages were misleading. ----------------------------------------------------------------------- Summary of changes: source4/cldap_server/cldap_server.h | 14 ++++ source4/cldap_server/netlogon.c | 44 ++++++++----- source4/rpc_server/netlogon/dcerpc_netlogon.c | 89 ++++++++++-------------- source4/torture/rpc/netlogon.c | 20 ++++++ 4 files changed, 98 insertions(+), 69 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/cldap_server/cldap_server.h b/source4/cldap_server/cldap_server.h index da2bd20..2eaf594 100644 --- a/source4/cldap_server/cldap_server.h +++ b/source4/cldap_server/cldap_server.h @@ -31,4 +31,18 @@ struct cldapd_server { struct ldap_SearchRequest; +/* used by netlogon DCE/RPC server */ +NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, + TALLOC_CTX *mem_ctx, + const char *domain, + const char *netbios_domain, + struct dom_sid *domain_sid, + const char *domain_guid, + const char *user, + uint32_t acct_control, + const char *src_address, + uint32_t version, + struct loadparm_context *lp_ctx, + struct netlogon_samlogon_response *netlogon); + #include "cldap_server/proto.h" diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 86f044a..fc9cafd 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -73,36 +73,42 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, bool user_known; NTSTATUS status; - /* the domain has an optional trailing . */ + /* the domain parameter could have an optional trailing "." */ if (domain && domain[strlen(domain)-1] == '.') { domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1); NT_STATUS_HAVE_NO_MEMORY(domain); } - if (domain && strcasecmp_m(domain, lp_dnsdomain(lp_ctx)) == 0) { + /* Lookup using long or short domainname */ + if (domain && (strcasecmp_m(domain, lp_dnsdomain(lp_ctx)) == 0)) { domain_dn = ldb_get_default_basedn(sam_ctx); } - - if (netbios_domain && strcasecmp_m(domain, lp_sam_name(lp_ctx))) { + if (netbios_domain && (strcasecmp_m(netbios_domain, lp_sam_name(lp_ctx)) == 0)) { domain_dn = ldb_get_default_basedn(sam_ctx); } - if (domain_dn) { + const char *domain_identifier = domain != NULL ? domain + : netbios_domain; ret = ldb_search(sam_ctx, mem_ctx, &dom_res, domain_dn, LDB_SCOPE_BASE, dom_attrs, "objectClass=domain"); if (ret != LDB_SUCCESS) { - DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(domain_dn), ldb_errstring(sam_ctx))); + DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", + domain_identifier, + ldb_dn_get_linearized(domain_dn), + ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } if (dom_res->count != 1) { - DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(domain_dn))); + DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", + domain_identifier, + ldb_dn_get_linearized(domain_dn))); return NT_STATUS_NO_SUCH_DOMAIN; } } - if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) { - + /* Lookup using GUID or SID */ + if ((dom_res == NULL) && (domain_guid || domain_sid)) { if (domain_guid) { struct GUID binary_guid; struct ldb_val guid_val; @@ -144,24 +150,28 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, } if (ret != LDB_SUCCESS) { - DEBUG(2,("Unable to find referece to GUID '%s' or SID %s in sam: %s\n", + DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam: %s\n", domain_guid, dom_sid_string(mem_ctx, domain_sid), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (dom_res->count == 1) { /* Ok, now just check it is our domain */ - - if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx), dom_res->msgs[0]->dn) != 0) { + if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx), + dom_res->msgs[0]->dn) != 0) { + DEBUG(2,("The GUID '%s' or SID '%s' doesn't identify our domain\n", + domain_guid, + dom_sid_string(mem_ctx, domain_sid))); return NT_STATUS_NO_SUCH_DOMAIN; } - } else if (dom_res->count > 1) { + } else { + DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam\n", + domain_guid, dom_sid_string(mem_ctx, domain_sid))); return NT_STATUS_NO_SUCH_DOMAIN; } } - - if ((dom_res == NULL || dom_res->count == 0)) { - DEBUG(2,("Unable to find domain with name %s or GUID {%s}\n", domain, domain_guid)); + if (dom_res == NULL) { + DEBUG(2,("Unable to get domain informations if no parameter of the list [long domainname, short domainname, GUID, SID] was specified!\n")); return NT_STATUS_NO_SUCH_DOMAIN; } @@ -190,7 +200,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, ldb_binary_encode_string(mem_ctx, user), UF_ACCOUNTDISABLE, ds_acb2uf(acct_control)); if (ret != LDB_SUCCESS) { - DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n", + DEBUG(2,("Unable to find reference to user '%s' with ACB 0x%8x under %s: %s\n", user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_USER; diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 698930e..5f85353 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -32,6 +32,8 @@ #include "param/param.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_irpc.h" +#include "cldap_server/cldap_server.h" +#include "lib/socket/socket.h" struct netlogon_server_pipe_state { struct netr_Credential client_challenge; @@ -1470,13 +1472,13 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_DsRGetDCNameEx2 *r) { - const char * const attrs[] = { "objectGUID", NULL }; struct ldb_context *sam_ctx; - struct ldb_message **res; - struct ldb_dn *domain_dn; - int ret; struct netr_DsRGetDCNameInfo *info; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + struct socket_address *addr; + char *guid_str; + struct netlogon_samlogon_response response; + NTSTATUS status; ZERO_STRUCTP(r->out.info); @@ -1486,63 +1488,46 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, return WERR_DS_UNAVAILABLE; } - /* Windows 7 sends the domain name in the form the user typed, so we - * have to cope with both the short and long form here */ - if (r->in.domain_name != NULL && - !lp_is_my_domain_or_realm(lp_ctx, r->in.domain_name)) { + addr = dce_call->conn->transport.get_peer_addr(dce_call->conn, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(addr); + + /* "server_unc" is ignored by w2k3 */ + + /* Proof server site parameter "site_name" if it was specified */ + if ((r->in.site_name != NULL) && (strcasecmp(r->in.site_name, + samdb_server_site_name(sam_ctx, mem_ctx)) != 0)) { return WERR_NO_SUCH_DOMAIN; } - domain_dn = ldb_get_default_basedn(sam_ctx); - if (domain_dn == NULL) { - return WERR_DS_UNAVAILABLE; - } + /* TODO: the flags are ignored for now */ - ret = gendb_search_dn(sam_ctx, mem_ctx, - domain_dn, &res, attrs); - if (ret != 1) { - return WERR_GENERAL_FAILURE; + guid_str = r->in.domain_guid != NULL ? + GUID_string(mem_ctx, r->in.domain_guid) : NULL; + + status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx, + r->in.domain_name, + r->in.domain_name, + NULL, guid_str, + r->in.client_account, + r->in.mask, addr->addr, + NETLOGON_NT_VERSION_5EX_WITH_IP, + lp_ctx, &response); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); } info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); W_ERROR_HAVE_NO_MEMORY(info); - - /* TODO: - return real IP address - * - check all r->in.* parameters - * (server_unc is ignored by w2k3!) - */ - info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", - lp_netbios_name(lp_ctx), - lp_dnsdomain(lp_ctx)); - W_ERROR_HAVE_NO_MEMORY(info->dc_unc); - - info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0"); + info->dc_unc = response.data.nt5_ex.pdc_dns_name; + info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", + response.data.nt5_ex.sockaddr.pdc_ip); W_ERROR_HAVE_NO_MEMORY(info->dc_address); - - info->dc_address_type = DS_ADDRESS_TYPE_INET; - info->domain_guid = samdb_result_guid(res[0], "objectGUID"); - info->domain_name = lp_dnsdomain(lp_ctx); - info->forest_name = samdb_forest_name(sam_ctx, mem_ctx); - W_ERROR_HAVE_NO_MEMORY(info->forest_name); - info->dc_flags = DS_DNS_FOREST_ROOT | - DS_DNS_DOMAIN | - DS_DNS_CONTROLLER | - DS_SERVER_WRITABLE | - DS_SERVER_CLOSEST | - DS_SERVER_TIMESERV | - DS_SERVER_KDC | - DS_SERVER_DS | - DS_SERVER_LDAP | - DS_SERVER_GC | - DS_SERVER_PDC; - - info->dc_site_name = samdb_server_site_name(sam_ctx, mem_ctx); - W_ERROR_HAVE_NO_MEMORY(info->dc_site_name); - - /* FIXME: Hardcoded site name */ - info->client_site_name = talloc_strdup(mem_ctx, - "Default-First-Site-Name"); - W_ERROR_HAVE_NO_MEMORY(info->client_site_name); + info->domain_guid = response.data.nt5_ex.domain_uuid; + info->domain_name = response.data.nt5_ex.dns_domain; + info->forest_name = response.data.nt5_ex.forest; + info->dc_flags = response.data.nt5_ex.server_type; + info->dc_site_name = response.data.nt5_ex.server_site; + info->client_site_name = response.data.nt5_ex.client_site; *r->out.info = info; diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index c469de9..5b3bcff 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -2193,6 +2193,13 @@ static bool test_netr_DsRGetDCName(struct torture_context *tctx, status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName"); torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName"); + + r.in.domain_name = lp_workgroup(tctx->lp_ctx); + + status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName"); + torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName"); + return test_netr_DsRGetSiteName(p, tctx, info->dc_unc, info->dc_site_name); @@ -2220,6 +2227,12 @@ static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx"); torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx"); + r.in.domain_name = lp_workgroup(tctx->lp_ctx); + + status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx"); + torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx"); + return test_netr_DsRGetSiteName(p, tctx, info->dc_unc, info->dc_site_name); } @@ -2250,6 +2263,12 @@ static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2"); torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2"); + r.in.domain_name = lp_workgroup(tctx->lp_ctx); + + status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2"); + torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2"); + torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n"); r.in.client_account = TEST_MACHINE_NAME"$"; r.in.mask = ACB_SVRTRUST; @@ -2259,6 +2278,7 @@ static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2"); torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2"); + return test_netr_DsRGetSiteName(p, tctx, info->dc_unc, info->dc_site_name); } -- Samba Shared Repository