1/* 2 Unix SMB/CIFS implementation. 3 Password and authentication handling 4 Copyright (C) Andrew Bartlett 2001-2002 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "includes.h" 21 22extern struct auth_context *negprot_global_auth_context; 23extern bool global_encrypted_passwords_negotiated; 24 25#undef DBGC_CLASS 26#define DBGC_CLASS DBGC_AUTH 27 28/**************************************************************************** 29 COMPATIBILITY INTERFACES: 30 ***************************************************************************/ 31 32/**************************************************************************** 33check if a username/password is OK assuming the password is a 24 byte 34SMB hash 35return True if the password is correct, False otherwise 36****************************************************************************/ 37 38NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info) 39{ 40 struct auth_context *plaintext_auth_context = NULL; 41 auth_usersupplied_info *user_info = NULL; 42 uint8_t chal[8]; 43 NTSTATUS nt_status; 44 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { 45 return nt_status; 46 } 47 48 plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context, 49 chal); 50 51 if (!make_user_info_for_reply(&user_info, 52 smb_name, lp_workgroup(), chal, 53 plaintext_password)) { 54 return NT_STATUS_NO_MEMORY; 55 } 56 57 nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 58 user_info, server_info); 59 60 (plaintext_auth_context->free)(&plaintext_auth_context); 61 free_user_info(&user_info); 62 return nt_status; 63} 64 65static NTSTATUS pass_check_smb(struct auth_context *actx, 66 const char *smb_name, 67 const char *domain, 68 DATA_BLOB lm_pwd, 69 DATA_BLOB nt_pwd, 70 DATA_BLOB plaintext_password, 71 bool encrypted) 72 73{ 74 NTSTATUS nt_status; 75 auth_serversupplied_info *server_info = NULL; 76 if (encrypted) { 77 auth_usersupplied_info *user_info = NULL; 78 if (actx == NULL) { 79 return NT_STATUS_INTERNAL_ERROR; 80 } 81 make_user_info_for_reply_enc(&user_info, smb_name, 82 domain, 83 lm_pwd, 84 nt_pwd); 85 nt_status = actx->check_ntlm_password(actx, user_info, &server_info); 86 free_user_info(&user_info); 87 } else { 88 nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info); 89 } 90 TALLOC_FREE(server_info); 91 return nt_status; 92} 93 94/**************************************************************************** 95check if a username/password pair is ok via the auth subsystem. 96return True if the password is correct, False otherwise 97****************************************************************************/ 98 99bool password_ok(struct auth_context *actx, bool global_encrypted, 100 const char *session_workgroup, 101 const char *smb_name, DATA_BLOB password_blob) 102{ 103 104 DATA_BLOB null_password = data_blob_null; 105 bool encrypted = (global_encrypted && (password_blob.length == 24 || password_blob.length > 46)); 106 107 if (encrypted) { 108 /* 109 * The password could be either NTLM or plain LM. Try NTLM first, 110 * but fall-through as required. 111 * Vista sends NTLMv2 here - we need to try the client given workgroup. 112 */ 113 if (session_workgroup) { 114 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob, null_password, encrypted))) { 115 return True; 116 } 117 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password, null_password, encrypted))) { 118 return True; 119 } 120 } 121 122 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) { 123 return True; 124 } 125 126 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) { 127 return True; 128 } 129 } else { 130 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) { 131 return True; 132 } 133 } 134 135 return False; 136} 137