e7225a275625d08a078f6c30fa0033a7fed4ef31
[kai/samba.git] / source3 / auth / auth_compat.c
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 #include "auth.h"
22 #include "../lib/tsocket/tsocket.h"
23
24 extern struct auth_context *negprot_global_auth_context;
25 extern bool global_encrypted_passwords_negotiated;
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 /****************************************************************************
31  COMPATIBILITY INTERFACES:
32  ***************************************************************************/
33
34 /****************************************************************************
35 check if a username/password is OK assuming the password is in plaintext
36 return True if the password is correct, False otherwise
37 ****************************************************************************/
38
39 NTSTATUS check_plaintext_password(const char *smb_name,
40                                   const struct tsocket_address *remote_address,
41                                   DATA_BLOB plaintext_blob,
42                                   struct auth_serversupplied_info **server_info)
43 {
44         struct auth_context *plaintext_auth_context = NULL;
45         struct auth_usersupplied_info *user_info = NULL;
46         uint8_t chal[8];
47         NTSTATUS nt_status;
48
49         nt_status = make_auth_context_subsystem(talloc_tos(),
50                                                 &plaintext_auth_context);
51         if (!NT_STATUS_IS_OK(nt_status)) {
52                 return nt_status;
53         }
54
55         plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context,
56                                                    chal);
57
58         if (!make_user_info_for_reply(&user_info, 
59                                       smb_name, lp_workgroup(),
60                                       remote_address,
61                                       chal,
62                                       plaintext_blob)) {
63                 return NT_STATUS_NO_MEMORY;
64         }
65
66         nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 
67                                                                 user_info, server_info); 
68
69         TALLOC_FREE(plaintext_auth_context);
70         free_user_info(&user_info);
71         return nt_status;
72 }
73
74 static NTSTATUS pass_check_smb(struct auth_context *actx,
75                                const char *smb_name,
76                                const char *domain, 
77                                const struct tsocket_address *remote_address,
78                                DATA_BLOB lm_pwd,
79                                DATA_BLOB nt_pwd)
80
81 {
82         NTSTATUS nt_status;
83         struct auth_serversupplied_info *server_info = NULL;
84         struct auth_usersupplied_info *user_info = NULL;
85         if (actx == NULL) {
86                 return NT_STATUS_INTERNAL_ERROR;
87         }
88         make_user_info_for_reply_enc(&user_info, smb_name,
89                                      domain,
90                                      remote_address,
91                                      lm_pwd,
92                                      nt_pwd);
93         nt_status = actx->check_ntlm_password(actx, user_info, &server_info);
94         free_user_info(&user_info);
95         TALLOC_FREE(server_info);
96         return nt_status;
97 }
98
99 /****************************************************************************
100 check if a username/password pair is ok via the auth subsystem.
101 return True if the password is correct, False otherwise
102 ****************************************************************************/
103
104 bool password_ok(struct auth_context *actx, bool global_encrypted,
105                  const char *session_workgroup,
106                  const char *smb_name,
107                  const struct tsocket_address *remote_address,
108                  DATA_BLOB password_blob)
109 {
110
111         DATA_BLOB null_password = data_blob_null;
112         bool encrypted = (global_encrypted && (password_blob.length == 24 || password_blob.length > 46));
113
114         if (encrypted) {
115                 /* 
116                  * The password could be either NTLM or plain LM.  Try NTLM first, 
117                  * but fall-through as required.
118                  * Vista sends NTLMv2 here - we need to try the client given workgroup.
119                  */
120                 if (session_workgroup) {
121                         if (NT_STATUS_IS_OK(pass_check_smb(actx,
122                                                            smb_name,
123                                                            session_workgroup,
124                                                            remote_address,
125                                                            null_password,
126                                                            password_blob))) {
127                                 return True;
128                         }
129                         if (NT_STATUS_IS_OK(pass_check_smb(actx,
130                                                            smb_name,
131                                                            session_workgroup,
132                                                            remote_address,
133                                                            password_blob,
134                                                            null_password))) {
135                                 return True;
136                         }
137                 }
138
139                 if (NT_STATUS_IS_OK(pass_check_smb(actx,
140                                                    smb_name,
141                                                    lp_workgroup(),
142                                                    remote_address,
143                                                    null_password,
144                                                    password_blob))) {
145                         return True;
146                 }
147
148                 if (NT_STATUS_IS_OK(pass_check_smb(actx,
149                                                    smb_name,
150                                                    lp_workgroup(),
151                                                    remote_address,
152                                                    password_blob,
153                                                    null_password))) {
154                         return True;
155                 }
156         } else {
157                 struct auth_serversupplied_info *server_info = NULL;
158                 NTSTATUS nt_status = check_plaintext_password(smb_name,
159                                                               remote_address,
160                                                               password_blob,
161                                                               &server_info);
162                 TALLOC_FREE(server_info);
163                 if (NT_STATUS_IS_OK(nt_status)) {
164                         return True;
165                 }
166         }
167
168         return False;
169 }