5084cc4a929b01ad6055ffafe84ebe2f4696eb99
[sfrench/samba-autobuild/.git] / source4 / auth / ntlm / auth_util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001
6    Copyright (C) Jeremy Allison 2000-2001
7    Copyright (C) Rafal Szczesniak 2002
8    Copyright (C) Stefan Metzmacher 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "auth/auth.h"
26 #include "libcli/auth/libcli_auth.h"
27 #include "param/param.h"
28 #include "auth/ntlm/auth_proto.h"
29 #include "librpc/gen_ndr/drsuapi.h"
30 #include "dsdb/samdb/samdb.h"
31
32 /* this default function can be used by mostly all backends
33  * which don't want to set a challenge
34  */
35 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
36 {
37         /* we don't want to set a challenge */
38         return NT_STATUS_NOT_IMPLEMENTED;
39 }
40
41 /****************************************************************************
42  Create an auth_usersupplied_data structure after appropriate mapping.
43 ****************************************************************************/
44
45 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 
46                            enum auth_password_state to_state,
47                            const struct auth_usersupplied_info *user_info_in,
48                            const struct auth_usersupplied_info **user_info_encrypted)
49 {
50         NTSTATUS nt_status;
51         struct auth_usersupplied_info *user_info_temp;
52         switch (to_state) {
53         case AUTH_PASSWORD_RESPONSE:
54                 switch (user_info_in->password_state) {
55                 case AUTH_PASSWORD_PLAIN:
56                 {
57                         const struct auth_usersupplied_info *user_info_temp2;
58                         nt_status = encrypt_user_info(mem_ctx, auth_context, 
59                                                       AUTH_PASSWORD_HASH, 
60                                                       user_info_in, &user_info_temp2);
61                         if (!NT_STATUS_IS_OK(nt_status)) {
62                                 return nt_status;
63                         }
64                         user_info_in = user_info_temp2;
65
66                         FALL_THROUGH;
67                 }
68                 case AUTH_PASSWORD_HASH:
69                 {
70                         uint8_t chal[8];
71                         DATA_BLOB chall_blob;
72                         user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
73                         if (!user_info_temp) {
74                                 return NT_STATUS_NO_MEMORY;
75                         }
76                         if (!talloc_reference(user_info_temp, user_info_in)) {
77                                 return NT_STATUS_NO_MEMORY;
78                         }
79                         *user_info_temp = *user_info_in;
80                         user_info_temp->mapped_state = to_state;
81                         
82                         nt_status = auth_get_challenge(auth_context, chal);
83                         if (!NT_STATUS_IS_OK(nt_status)) {
84                                 return nt_status;
85                         }
86                         
87                         chall_blob = data_blob_talloc(mem_ctx, chal, 8);
88                         if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) {
89                                 DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx));
90                                 DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key;
91                                 
92                                 if (!SMBNTLMv2encrypt_hash(user_info_temp,
93                                                            user_info_in->client.account_name, 
94                                                            user_info_in->client.domain_name, 
95                                                            user_info_in->password.hash.nt->hash,
96                                                            &chall_blob,
97                                                            NULL, /* server_timestamp */
98                                                            &names_blob,
99                                                            &lmv2_response, &ntlmv2_response, 
100                                                            &lmv2_session_key, &ntlmv2_session_key)) {
101                                         data_blob_free(&names_blob);
102                                         return NT_STATUS_NO_MEMORY;
103                                 }
104                                 data_blob_free(&names_blob);
105                                 user_info_temp->password.response.lanman = lmv2_response;
106                                 user_info_temp->password.response.nt = ntlmv2_response;
107                                 
108                                 data_blob_free(&lmv2_session_key);
109                                 data_blob_free(&ntlmv2_session_key);
110                         } else {
111                                 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
112                                 SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data);
113
114                                 user_info_temp->password.response.nt = blob;
115                                 if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
116                                         DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24);
117                                         SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data);
118                                         user_info_temp->password.response.lanman = lm_blob;
119                                 } else {
120                                         /* if not sending the LM password, send the NT password twice */
121                                         user_info_temp->password.response.lanman = user_info_temp->password.response.nt;
122                                 }
123                         }
124
125                         user_info_in = user_info_temp;
126
127                         FALL_THROUGH;
128                 }
129                 case AUTH_PASSWORD_RESPONSE:
130                         *user_info_encrypted = user_info_in;
131                 }
132                 break;
133         case AUTH_PASSWORD_HASH:
134         {       
135                 switch (user_info_in->password_state) {
136                 case AUTH_PASSWORD_PLAIN:
137                 {
138                         struct samr_Password lanman;
139                         struct samr_Password nt;
140                         
141                         user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
142                         if (!user_info_temp) {
143                                 return NT_STATUS_NO_MEMORY;
144                         }
145                         if (!talloc_reference(user_info_temp, user_info_in)) {
146                                 return NT_STATUS_NO_MEMORY;
147                         }
148                         *user_info_temp = *user_info_in;
149                         user_info_temp->mapped_state = to_state;
150                         
151                         if (E_deshash(user_info_in->password.plaintext, lanman.hash)) {
152                                 user_info_temp->password.hash.lanman = talloc(user_info_temp,
153                                                                               struct samr_Password);
154                                 *user_info_temp->password.hash.lanman = lanman;
155                         } else {
156                                 user_info_temp->password.hash.lanman = NULL;
157                         }
158                         
159                         E_md4hash(user_info_in->password.plaintext, nt.hash);
160                         user_info_temp->password.hash.nt = talloc(user_info_temp,
161                                                                    struct samr_Password);
162                         *user_info_temp->password.hash.nt = nt;
163                         
164                         user_info_in = user_info_temp;
165
166                         FALL_THROUGH;
167                 }
168                 case AUTH_PASSWORD_HASH:
169                         *user_info_encrypted = user_info_in;
170                         break;
171                 default:
172                         return NT_STATUS_INVALID_PARAMETER;
173                         break;
174                 }
175                 break;
176         }
177         default:
178                 return NT_STATUS_INVALID_PARAMETER;
179         }
180
181         return NT_STATUS_OK;
182 }