winbindd: Do not overwrite domain list with conflicting info from a trusted domain
[sfrench/samba-autobuild/.git] / source3 / auth / auth_winbind.c
index d534e59cfc8308ee57fec10b9a401c9dfedeb5fe..2b5c84d2760e1a0205b04da1a8117abc808c4fec 100644 (file)
@@ -21,6 +21,8 @@
 */
 
 #include "includes.h"
+#include "auth.h"
+#include "nsswitch/libwbclient/wbclient.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -39,28 +41,36 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
        struct wbcAuthUserInfo *info = NULL;
        struct wbcAuthErrorInfo *err = NULL;
 
+       ZERO_STRUCT(params);
+
        if (!user_info) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       DEBUG(10, ("Check auth for: [%s]", user_info->internal_username));
+       DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
 
        if (!auth_context) {
                DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n", 
-                        user_info->internal_username));
+                        user_info->mapped.account_name));
                return NT_STATUS_INVALID_PARAMETER;
        }               
 
-       if (strequal(user_info->domain, get_global_sam_name())) {
+       if (strequal(user_info->mapped.domain_name, get_global_sam_name())) {
                DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
-                       user_info->domain));
+                       user_info->mapped.domain_name));
                return NT_STATUS_NOT_IMPLEMENTED;
        }
 
        /* Send off request */
-
-       params.account_name     = user_info->smb_name;
-       params.domain_name      = user_info->domain;
+       params.account_name     = user_info->client.account_name;
+       /*
+        * We need to send the domain name from the client to the DC. With
+        * NTLMv2 the domain name is part of the hashed second challenge,
+        * if we change the domain name, the DC will fail to verify the
+        * challenge cause we changed the domain name, this is like a
+        * man in the middle attack.
+        */
+       params.domain_name      = user_info->client.domain_name;
        params.workstation_name = user_info->workstation_name;
 
        params.flags            = 0;
@@ -72,10 +82,18 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
               auth_context->challenge.data,
               sizeof(params.password.response.challenge));
 
-       params.password.response.nt_length      = user_info->nt_resp.length;
-       params.password.response.nt_data        = user_info->nt_resp.data;
-       params.password.response.lm_length      = user_info->lm_resp.length;
-       params.password.response.lm_data        = user_info->lm_resp.data;
+       if (user_info->password.response.nt.length != 0) {
+               params.password.response.nt_length =
+                       user_info->password.response.nt.length;
+               params.password.response.nt_data =
+                       user_info->password.response.nt.data;
+       }
+       if (user_info->password.response.lanman.length != 0) {
+               params.password.response.lm_length =
+                       user_info->password.response.lanman.length;
+               params.password.response.lm_data =
+                       user_info->password.response.lanman.data;
+       }
 
        /* we are contacting the privileged pipe */
        become_root();
@@ -98,9 +116,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
                if ( auth_method )
                        return auth_method->auth(auth_context, auth_method->private_data, 
                                mem_ctx, user_info, server_info);
-               else
-                       /* log an error since this should not happen */
-                       DEBUG(0,("check_winbind_security: ERROR!  my_private_data == NULL!\n"));
+               return NT_STATUS_LOGON_FAILURE;
        }
 
        if (wbc_status == WBC_ERR_AUTH_ERROR) {
@@ -114,8 +130,8 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
        }
 
        nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
-                                                    user_info->smb_name,
-                                                    user_info->domain,
+                                                    user_info->client.account_name,
+                                                    user_info->mapped.domain_name,
                                                     info, server_info);
        wbcFreeMemory(info);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -132,7 +148,7 @@ static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char
 {
        struct auth_methods *result;
 
-       result = TALLOC_ZERO_P(auth_context, struct auth_methods);
+       result = talloc_zero(auth_context, struct auth_methods);
        if (result == NULL) {
                return NT_STATUS_NO_MEMORY;
        }