Back out the crazy notion that the NTLMSSP flags actually mean anything...
[ira/wip.git] / source3 / auth / auth_util.c
index 04b3cbbecf4dda36a62ebb4e1d960ad9d205990f..a747cf8a35183b672552d3821b85f7fb1e9cfa25 100644 (file)
@@ -50,7 +50,7 @@ static int smb_create_user(const char *unix_user, const char *homedir)
  Delete a UNIX user on demand.
 ****************************************************************************/
 
-int smb_delete_user(char *unix_user)
+int smb_delete_user(const char *unix_user)
 {
        pstring del_script;
        int ret;
@@ -85,23 +85,6 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli
                        if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
                                smb_create_user(user_info->internal_username.str, NULL);
                        }
-               } else {                        
-                       if(lp_adduser_script()) {
-                               SMB_STRUCT_STAT st;
-                               const char *home_dir = pdb_get_homedir(server_info->sam_account);
-                               /*
-                                * Also call smb_create_user if the users
-                                * home directory doesn't exist. Used with
-                                * winbindd to allow the script to create
-                                * the home directory for a user mapped
-                                * with winbindd.
-                                */
-
-                               if (home_dir && 
-                                   (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
-                                               smb_create_user(user_info->internal_username.str, home_dir);
-                               }
-                       }
                }
        } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
                /*
@@ -128,7 +111,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
                           const char *wksta_name, 
                           DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                           DATA_BLOB plaintext, 
-                          uint32 ntlmssp_flags, BOOL encrypted)
+                          uint32 auth_flags, BOOL encrypted)
 {
 
        DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
@@ -190,7 +173,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
        (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
 
        (*user_info)->encrypted = encrypted;
-       (*user_info)->ntlmssp_flags = ntlmssp_flags;
+       (*user_info)->auth_flags = auth_flags;
 
        DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
 
@@ -215,7 +198,26 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
        map_username(internal_username); 
        
        if (lp_allow_trusted_domains()) {
-               domain = client_domain;
+               char *user;
+               /* the client could have given us a workstation name
+                  or other crap for the workgroup - we really need a
+                  way of telling if this domain name is one of our
+                  trusted domain names 
+
+                  The way I do it here is by checking if the fully
+                  qualified username exists. This is rather reliant
+                  on winbind, but until we have a better method this
+                  will have to do 
+               */
+               asprintf(&user, "%s%s%s", 
+                        client_domain, lp_winbind_separator(), 
+                        smb_name);
+               if (Get_Pwnam(user) != NULL) {
+                       domain = client_domain;
+               } else {
+                       domain = lp_workgroup();
+               }
+               free(user);
        } else {
                domain = lp_workgroup();
        }
@@ -246,14 +248,14 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        if (lm_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               auth_flags |= AUTH_FLAG_LM_RESP;
        if (nt_pwd_len == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM
+               auth_flags |= AUTH_FLAG_NTLM_RESP
        } else if (nt_pwd_len != 0) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2
+               auth_flags |= AUTH_FLAG_NTLMv2_RESP
        }
 
        ret = make_user_info_map(user_info, 
@@ -261,7 +263,7 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
                                 wksta_name, 
                                 lm_blob, nt_blob,
                                 plaintext_blob, 
-                                ntlmssp_flags, True);
+                                auth_flags, True);
                
        data_blob_free(&lm_blob);
        data_blob_free(&nt_blob);
@@ -274,20 +276,20 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
-                                        char *smb_name, 
-                                        char *client_domain, 
-                                        char *wksta_name, 
-                                        char chal[8], 
-                                        uchar lm_interactive_pwd[16], 
-                                        uchar nt_interactive_pwd[16], 
-                                        uchar *dc_sess_key)
+                                        const char *smb_name, 
+                                        const char *client_domain, 
+                                        const char *wksta_name, 
+                                        const uchar chal[8], 
+                                        const uchar lm_interactive_pwd[16], 
+                                        const uchar nt_interactive_pwd[16], 
+                                        const uchar *dc_sess_key)
 {
        char lm_pwd[16];
        char nt_pwd[16];
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
        unsigned char key[16];
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
        
        ZERO_STRUCT(key);
        memcpy(key, dc_sess_key, 8);
@@ -332,9 +334,9 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                DATA_BLOB plaintext_blob = data_blob(NULL, 0);
 
                if (lm_interactive_pwd)
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+                       auth_flags |= AUTH_FLAG_LM_RESP;
                if (nt_interactive_pwd)
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM
+                       auth_flags |= AUTH_FLAG_NTLM_RESP
 
                ret = make_user_info_map(user_info, 
                                         smb_name, client_domain, 
@@ -342,7 +344,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                                         local_lm_blob,
                                         local_nt_blob,
                                         plaintext_blob, 
-                                        ntlmssp_flags, True);
+                                        auth_flags, True);
                
                data_blob_free(&local_lm_blob);
                data_blob_free(&local_nt_blob);
@@ -350,114 +352,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
        }
 }
 
-/****************************************************************************
- Create an auth_usersupplied_data structure
-****************************************************************************/
-
-BOOL make_user_info_winbind(auth_usersupplied_info **user_info, 
-                            const char *username,
-                            const char *domain, 
-                            const char *password,
-                           char chal[8] /* Give winbind back the challenge we used */
-       )
-{
-       unsigned char local_lm_response[24];
-       unsigned char local_nt_response[24];
-       DATA_BLOB local_lm_blob;
-       DATA_BLOB local_nt_blob;
-       DATA_BLOB plaintext_blob;
-       uint32 ntlmssp_flags = 0;
-
-       /*
-        * Not encrypted - do so.
-        */
-       
-       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
-       
-       generate_random_buffer(chal, 8, False);
-
-       if (*password) {
-               SMBencrypt( (const uchar *)password, chal, local_lm_response);
-               
-               /* This encrypts the lm_pwd field, which actually contains
-                  the password rather than the nt_pwd field because that
-                  contains nothing */
-               
-               /* WATCH OUT. This doesn't work if the incoming password is
-                  incorrectly cased.  We might want to add a check here
-                  and only do an LM in that case */
-               
-               SMBNTencrypt((const uchar *)password, chal, local_nt_response);
-
-               local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
-               local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
-               plaintext_blob = data_blob(password, strlen(password)+1);
-               if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
-                       data_blob_free(&local_lm_blob);
-                       data_blob_free(&local_nt_blob);
-                       data_blob_clear_free(&plaintext_blob);
-                       return False;
-               }
-               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
-       } else {
-               local_lm_blob = data_blob(NULL, 0);
-               local_nt_blob = data_blob(NULL, 0);
-               plaintext_blob = data_blob(NULL, 0);
-       }
-
-       {
-               BOOL ret;
-
-               ret = make_user_info(user_info, 
-                                    username, username,
-                                    domain, domain, 
-                                    global_myname, 
-                                    local_nt_blob,
-                                    local_lm_blob,
-                                    plaintext_blob, 
-                                    ntlmssp_flags, False);
-               
-               data_blob_free(&local_lm_blob);
-               data_blob_free(&local_nt_blob);
-               data_blob_clear_free(&plaintext_blob);
-               return ret;
-       }
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data, making the DATA_BLOBs here. 
- Decrypt and encrypt the passwords.
-****************************************************************************/
-
-BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
-                                char *smb_name, 
-                                char *client_domain, 
-                                uchar *lm_network_pwd, int lm_pwd_len,
-                                uchar *nt_network_pwd, int nt_pwd_len)
-{
-       BOOL ret;
-       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
-       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
-       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
-
-       if (lm_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
-       if (nt_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
-       
-       ret = make_user_info(user_info, 
-                            smb_name, smb_name, 
-                            client_domain, client_domain, 
-                            global_myname, 
-                            nt_blob, lm_blob,
-                            plaintext_blob, 
-                            ntlmssp_flags, True);
-
-       data_blob_free(&lm_blob);
-       data_blob_free(&nt_blob);
-       return ret;
-}
 
 /****************************************************************************
  Create an auth_usersupplied_data structure
@@ -466,14 +360,14 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
                              char *smb_name, 
                              char *client_domain,
-                             char chal[8],
+                             const uint8 chal[8],
                              DATA_BLOB plaintext_password)
 {
 
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
        BOOL ret = False;
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
                        
        /*
         * Not encrypted - do so.
@@ -489,14 +383,14 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                dump_data(100, plaintext_password.data, plaintext_password.length);
 #endif
 
-               SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
+               SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
                local_lm_blob = data_blob(local_lm_response, 24);
                
                /* We can't do an NT hash here, as the password needs to be
                   case insensitive */
                local_nt_blob = data_blob(NULL, 0); 
                
-               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
+               auth_flags = (AUTH_FLAG_PLAINTEXT | AUTH_FLAG_LM_RESP);
        } else {
                local_lm_blob = data_blob(NULL, 0); 
                local_nt_blob = data_blob(NULL, 0); 
@@ -508,7 +402,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                                 local_lm_blob,
                                 local_nt_blob,
                                 plaintext_password, 
-                                ntlmssp_flags, False);
+                                auth_flags, False);
        
        data_blob_free(&local_lm_blob);
        return ret;
@@ -521,21 +415,20 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
 BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
                              char *smb_name,
                              char *client_domain, 
-                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
-                             DATA_BLOB plaintext_password)
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp)
 {
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
        
        if (lm_resp.length == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               auth_flags |= AUTH_FLAG_LM_RESP;
        }
        if (nt_resp.length == 0) {
        } else if (nt_resp.length == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+               auth_flags |= AUTH_FLAG_NTLM_RESP;
        } else {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+               auth_flags |= AUTH_FLAG_NTLMv2_RESP;
        }
 
        return make_user_info_map(user_info, smb_name, 
@@ -544,7 +437,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
                                 lm_resp, 
                                 nt_resp, 
                                 no_plaintext_blob, 
-                                ntlmssp_flags, True);
+                                auth_flags, True);
 }
 
 /****************************************************************************
@@ -556,7 +449,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
        DATA_BLOB lm_blob = data_blob(NULL, 0);
        DATA_BLOB nt_blob = data_blob(NULL, 0);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        return make_user_info(user_info, 
                              "","", 
@@ -564,7 +457,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
                              "", 
                              nt_blob, lm_blob,
                              plaintext_blob, 
-                             ntlmssp_flags, True);
+                             auth_flags, True);
 }
 
 /***************************************************************************
@@ -678,9 +571,17 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
  Make an auth_methods struct
 ***************************************************************************/
 
-BOOL make_auth_methods(auth_methods **auth_method) 
+BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       *auth_method = malloc(sizeof(**auth_method));
+       if (!auth_context) {
+               smb_panic("no auth_context supplied to make_auth_methods()!\n");
+       }
+
+       if (!auth_method) {
+               smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
+       }
+
+       *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
        if (!*auth_method) {
                DEBUG(0,("make_auth_method: malloc failed!\n"));
                return False;
@@ -729,3 +630,33 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
 
        return token;
 }
+
+/**
+ * Squash an NT_STATUS in line with security requirements.
+ * In an attempt to avoid giving the whole game away when users
+ * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
+ * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
+ * (session setups in particular).
+ *
+ * @param nt_status NTSTATUS input for squashing.
+ * @return the 'squashed' nt_status
+ **/
+
+NTSTATUS nt_status_squash(NTSTATUS nt_status)
+{
+       if NT_STATUS_IS_OK(nt_status) {
+               return nt_status;               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+       } else {
+               return nt_status;
+       }  
+}
+
+
+