s4:netlogon/LogonGetDomainInfo - handle a NULL "dns_hostname"
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Thu, 18 Nov 2010 21:26:13 +0000 (22:26 +0100)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Fri, 19 Nov 2010 11:50:32 +0000 (12:50 +0100)
- Performs the short computer name check against the sam account name.
- Enhances the LogonGetDomainInfo testsuite which checks the NULL
  "dns_hostname" behaviour

Autobuild-User: Matthias Dieter Wallnöfer <mdw@samba.org>
Autobuild-Date: Fri Nov 19 12:50:33 CET 2010 on sn-devel-104

source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/torture/rpc/netlogon.c

index 79d2cbc1519d5db46e64b73aaf0304c83d60587a..ea4ea23a50c434b4887302ff4a8e2b74ead44493 100644 (file)
@@ -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",
index 97581850460f0438096aa90fa26768ebe1f99869..b1739a015c11dc0b4585c07c06846fe481287c72 100644 (file)
@@ -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;