diff options
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 62 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 22 |
2 files changed, 57 insertions, 27 deletions
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 79d2cbc151..ea4ea23a50 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -5,7 +5,7 @@ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005 - Copyright (C) Matthias Dieter Wallnöfer 2009 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1296,10 +1296,9 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal struct netlogon_creds_CredentialState *creds; const char * const attrs[] = { "objectSid", "objectGUID", "flatName", "securityIdentifier", "trustPartner", NULL }; - const char * const attrs2[] = { "dNSHostName", + const char * const attrs2[] = { "sAMAccountName", "dNSHostName", "msDS-SupportedEncryptionTypes", NULL }; - const char *temp_str, *temp_str2; - const char *old_dns_hostname; + const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2; struct ldb_context *sam_ctx; struct ldb_message **res1, **res2, **res3, *new_msg; struct ldb_dn *workstation_dn; @@ -1336,35 +1335,48 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal return NT_STATUS_INVALID_PARAMETER; } - /* - * Checks that the computer name parameter without possible "$" - * matches as prefix with the DNS hostname in the workstation - * info structure. - */ - temp_str = talloc_strndup(mem_ctx, - r->in.computer_name, - strcspn(r->in.computer_name, "$")); - NT_STATUS_HAVE_NO_MEMORY(temp_str); - temp_str2 = talloc_strndup(mem_ctx, - r->in.query->workstation_info->dns_hostname, - strcspn(r->in.query->workstation_info->dns_hostname, ".")); - NT_STATUS_HAVE_NO_MEMORY(temp_str2); - if (strcasecmp(temp_str, temp_str2) != 0) { - update_dns_hostname = false; - } - - /* Prepare the workstation DN */ + /* Prepares the workstation DN */ workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", - dom_sid_string(mem_ctx, creds->sid)); + dom_sid_string(mem_ctx, creds->sid)); NT_STATUS_HAVE_NO_MEMORY(workstation_dn); /* Lookup for attributes in workstation object */ - ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, - &res1, attrs2); + ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1, + attrs2); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* Gets the sam account name which is checked against the DNS + * hostname parameter. */ + sam_account_name = ldb_msg_find_attr_as_string(res1[0], + "sAMAccountName", + NULL); + if (sam_account_name == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* + * Checks that the sam account name without a possible "$" + * matches as prefix with the DNS hostname in the workstation + * info structure. + */ + prefix1 = talloc_strndup(mem_ctx, sam_account_name, + strcspn(sam_account_name, "$")); + NT_STATUS_HAVE_NO_MEMORY(prefix1); + if (r->in.query->workstation_info->dns_hostname != NULL) { + prefix2 = talloc_strndup(mem_ctx, + r->in.query->workstation_info->dns_hostname, + strcspn(r->in.query->workstation_info->dns_hostname, ".")); + NT_STATUS_HAVE_NO_MEMORY(prefix2); + + if (strcasecmp(prefix1, prefix2) != 0) { + update_dns_hostname = false; + } + } else { + update_dns_hostname = false; + } + /* Gets the old DNS hostname */ old_dns_hostname = ldb_msg_find_attr_as_string(res1[0], "dNSHostName", diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 9758185046..b1739a015c 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -3203,6 +3203,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, info.domain_info->dns_hostname.string, query.workstation_info->dns_hostname, "In/Out 'DNS hostnames' don't match!"); + old_dnsname = info.domain_info->dns_hostname.string; /* Checks "workstation flags" */ torture_assert(tctx, @@ -3246,12 +3247,29 @@ static bool test_GetDomainInfo(struct torture_context *tctx, "Trusted domains have been requested!"); + torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n"); + netlogon_creds_client_authenticator(creds, &a); + + query.workstation_info->dns_hostname = NULL; + + torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r), + "LogonGetDomainInfo failed"); + torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed"); + torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); + + /* The old DNS hostname should stick */ + torture_assert_str_equal(tctx, + info.domain_info->dns_hostname.string, + old_dnsname, + "'DNS hostname' changed!"); + + if (!torture_setting_bool(tctx, "dangerous", false)) { - torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 6th call (no workstation info) - enable dangerous tests in order to do so\n"); + torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n"); } else { /* Try a call without the workstation information structure */ - torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no workstation info)\n"); + torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n"); netlogon_creds_client_authenticator(creds, &a); query.workstation_info = NULL; |