libcli/auth: use unique key_name values in netlogon_creds_cli_context_common()
authorStefan Metzmacher <metze@samba.org>
Fri, 13 Dec 2013 16:31:45 +0000 (17:31 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 7 Jan 2014 11:47:04 +0000 (12:47 +0100)
Until all callers are fixed to pass the same 'server_computer'
value, we try to calculate a server_netbios_name and use this
as unique identifier for a specific domain controller.

Otherwise winbind would use 'hostname.example.com'
while 'net rpc testjoin' would use 'HOSTNAME',
which leads to 2 records in netlogon_creds_cli.tdb
for the same domain controller.

Once all callers are fixed we can think about reverting this
commit.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
libcli/auth/netlogon_creds_cli.c

index 75d6b2c679b9ec309bb8cf8dcc2cb7c435784a59..a872b31bfcc30a974fd97b338611cf08007f6d85 100644 (file)
@@ -106,23 +106,30 @@ static NTSTATUS netlogon_creds_cli_context_common(
                                struct netlogon_creds_cli_context **_context)
 {
        struct netlogon_creds_cli_context *context = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
+       char *_key_name = NULL;
+       char *server_netbios_name = NULL;
+       char *p = NULL;
 
        *_context = NULL;
 
        context = talloc_zero(mem_ctx, struct netlogon_creds_cli_context);
        if (context == NULL) {
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
        context->client.computer = talloc_strdup(context, client_computer);
        if (context->client.computer == NULL) {
-               talloc_free(context);
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
        context->client.account = talloc_strdup(context, client_account);
        if (context->client.account == NULL) {
-               talloc_free(context);
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -133,29 +140,60 @@ static NTSTATUS netlogon_creds_cli_context_common(
 
        context->server.computer = talloc_strdup(context, server_computer);
        if (context->server.computer == NULL) {
-               talloc_free(context);
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
        context->server.netbios_domain = talloc_strdup(context, server_netbios_domain);
        if (context->server.netbios_domain == NULL) {
-               talloc_free(context);
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
-       context->db.key_name = talloc_asprintf(context, "CLI[%s/%s]/SRV[%s/%s]",
-                                            client_computer,
-                                            client_account,
-                                            server_computer,
-                                            server_netbios_domain);
+       /*
+        * TODO:
+        * Force the callers to provide a unique
+        * value for server_computer and use this directly.
+        *
+        * For now we have to deal with
+        * "HOSTNAME" vs. "hostname.example.com".
+        */
+       server_netbios_name = talloc_strdup(frame, server_computer);
+       if (server_netbios_name == NULL) {
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       p = strchr(server_netbios_name, '.');
+       if (p != NULL) {
+               p[0] = '\0';
+       }
+
+       _key_name = talloc_asprintf(frame, "CLI[%s/%s]/SRV[%s/%s]",
+                                   client_computer,
+                                   client_account,
+                                   server_netbios_name,
+                                   server_netbios_domain);
+       if (_key_name == NULL) {
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       context->db.key_name = talloc_strdup_upper(context, _key_name);
        if (context->db.key_name == NULL) {
-               talloc_free(context);
+               TALLOC_FREE(context);
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
        context->db.key_data = string_term_tdb_data(context->db.key_name);
 
        *_context = context;
+       TALLOC_FREE(frame);
        return NT_STATUS_OK;
 }