s3-auth: Remove unused variable.
[ira/wip.git] / source3 / auth / auth_ntlmssp.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle NLTMSSP, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-2003
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "../libcli/auth/ntlmssp.h"
25
26 struct auth_ntlmssp_state {
27         struct auth_context *auth_context;
28         struct auth_serversupplied_info *server_info;
29         struct ntlmssp_state *ntlmssp_state;
30 };
31
32 NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
33                                   TALLOC_CTX *sig_mem_ctx,
34                                   const uint8_t *data, size_t length,
35                                   const uint8_t *whole_pdu, size_t pdu_length,
36                                   DATA_BLOB *sig)
37 {
38         return ntlmssp_sign_packet(auth_ntlmssp_state->ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
39 }
40
41 NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
42                                    const uint8_t *data, size_t length,
43                                    const uint8_t *whole_pdu, size_t pdu_length,
44                                    const DATA_BLOB *sig)
45 {
46         return ntlmssp_check_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
47 }
48
49 NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
50                                   TALLOC_CTX *sig_mem_ctx,
51                                   uint8_t *data, size_t length,
52                                   const uint8_t *whole_pdu, size_t pdu_length,
53                                   DATA_BLOB *sig)
54 {
55         return ntlmssp_seal_packet(auth_ntlmssp_state->ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
56 }
57
58 NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
59                                     uint8_t *data, size_t length,
60                                     const uint8_t *whole_pdu, size_t pdu_length,
61                                     const DATA_BLOB *sig)
62 {
63         return ntlmssp_unseal_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
64 }
65
66 bool auth_ntlmssp_negotiated_sign(struct auth_ntlmssp_state *auth_ntlmssp_state)
67 {
68         return auth_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN;
69 }
70
71 bool auth_ntlmssp_negotiated_seal(struct auth_ntlmssp_state *auth_ntlmssp_state)
72 {
73         return auth_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL;
74 }
75
76 void auth_ntlmssp_want_sign(struct auth_ntlmssp_state *auth_ntlmssp_state)
77 {
78
79 }
80
81 void auth_ntlmssp_want_seal(struct auth_ntlmssp_state *auth_ntlmssp_state)
82 {
83
84 }
85
86 NTSTATUS auth_ntlmssp_server_info(TALLOC_CTX *mem_ctx,
87                                   struct auth_ntlmssp_state *auth_ntlmssp_state,
88                                   struct auth_serversupplied_info **_server_info)
89 {
90         struct auth_serversupplied_info *server_info = auth_ntlmssp_state->server_info;
91         data_blob_free(&server_info->user_session_key);
92         server_info->user_session_key =
93                 data_blob_talloc(
94                         server_info,
95                         auth_ntlmssp_state->ntlmssp_state->session_key.data,
96                         auth_ntlmssp_state->ntlmssp_state->session_key.length);
97         if (auth_ntlmssp_state->ntlmssp_state->session_key.length && !server_info->user_session_key.data) {
98                 *_server_info = NULL;
99                 return NT_STATUS_NO_MEMORY;
100         }
101         auth_ntlmssp_state->server_info = NULL;
102         *_server_info = talloc_steal(mem_ctx, server_info);
103         return NT_STATUS_OK;
104 }
105
106 struct ntlmssp_state *auth_ntlmssp_get_ntlmssp_state(struct auth_ntlmssp_state *auth_ntlmssp_state)
107 {
108         return auth_ntlmssp_state->ntlmssp_state;
109 }
110
111 /* Needed for 'map to guest' and 'smb username' processing */
112 const char *auth_ntlmssp_get_username(struct auth_ntlmssp_state *auth_ntlmssp_state)
113 {
114         return auth_ntlmssp_state->ntlmssp_state->user;
115 }
116
117 const char *auth_ntlmssp_get_domain(struct auth_ntlmssp_state *auth_ntlmssp_state)
118 {
119         return auth_ntlmssp_state->ntlmssp_state->domain;
120 }
121
122 const char *auth_ntlmssp_get_client(struct auth_ntlmssp_state *auth_ntlmssp_state)
123 {
124         return auth_ntlmssp_state->ntlmssp_state->client.netbios_name;
125 }
126
127 /**
128  * Return the challenge as determined by the authentication subsystem 
129  * @return an 8 byte random challenge
130  */
131
132 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
133                                            uint8_t chal[8])
134 {
135         struct auth_ntlmssp_state *auth_ntlmssp_state =
136                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
137         auth_ntlmssp_state->auth_context->get_ntlm_challenge(
138                 auth_ntlmssp_state->auth_context, chal);
139         return NT_STATUS_OK;
140 }
141
142 /**
143  * Some authentication methods 'fix' the challenge, so we may not be able to set it
144  *
145  * @return If the effective challenge used by the auth subsystem may be modified
146  */
147 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
148 {
149         struct auth_ntlmssp_state *auth_ntlmssp_state =
150                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
151         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
152
153         return auth_context->challenge_may_be_modified;
154 }
155
156 /**
157  * NTLM2 authentication modifies the effective challenge, 
158  * @param challenge The new challenge value
159  */
160 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
161 {
162         struct auth_ntlmssp_state *auth_ntlmssp_state =
163                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
164         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
165
166         SMB_ASSERT(challenge->length == 8);
167
168         auth_context->challenge = data_blob_talloc(auth_context,
169                                                    challenge->data, challenge->length);
170
171         auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
172
173         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
174         DEBUG(5, ("challenge is: \n"));
175         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
176         return NT_STATUS_OK;
177 }
178
179 /**
180  * Check the password on an NTLMSSP login.  
181  *
182  * Return the session keys used on the connection.
183  */
184
185 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
186 {
187         struct auth_ntlmssp_state *auth_ntlmssp_state =
188                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
189         struct auth_usersupplied_info *user_info = NULL;
190         NTSTATUS nt_status;
191         bool username_was_mapped;
192
193         /* the client has given us its machine name (which we otherwise would not get on port 445).
194            we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
195
196         set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->client.netbios_name, True);
197
198         /* setup the string used by %U */
199         /* sub_set_smb_name checks for weird internally */
200         sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
201
202         reload_services(True);
203
204         nt_status = make_user_info_map(&user_info, 
205                                        auth_ntlmssp_state->ntlmssp_state->user, 
206                                        auth_ntlmssp_state->ntlmssp_state->domain, 
207                                        auth_ntlmssp_state->ntlmssp_state->client.netbios_name,
208                                        auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, 
209                                        auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, 
210                                        NULL, NULL, NULL,
211                                        True);
212
213         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
214
215         if (!NT_STATUS_IS_OK(nt_status)) {
216                 return nt_status;
217         }
218
219         nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, 
220                                                                           user_info, &auth_ntlmssp_state->server_info); 
221
222         username_was_mapped = user_info->was_mapped;
223
224         free_user_info(&user_info);
225
226         if (!NT_STATUS_IS_OK(nt_status)) {
227                 return nt_status;
228         }
229
230         auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
231
232         nt_status = create_local_token(auth_ntlmssp_state->server_info);
233
234         if (!NT_STATUS_IS_OK(nt_status)) {
235                 DEBUG(10, ("create_local_token failed: %s\n",
236                         nt_errstr(nt_status)));
237                 return nt_status;
238         }
239
240         if (auth_ntlmssp_state->server_info->user_session_key.length) {
241                 DEBUG(10, ("Got NT session key of length %u\n",
242                         (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
243                 *user_session_key = data_blob_talloc(auth_ntlmssp_state,
244                                                    auth_ntlmssp_state->server_info->user_session_key.data,
245                                                    auth_ntlmssp_state->server_info->user_session_key.length);
246         }
247         if (auth_ntlmssp_state->server_info->lm_session_key.length) {
248                 DEBUG(10, ("Got LM session key of length %u\n",
249                         (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
250                 *lm_session_key = data_blob_talloc(auth_ntlmssp_state,
251                                                    auth_ntlmssp_state->server_info->lm_session_key.data,
252                                                    auth_ntlmssp_state->server_info->lm_session_key.length);
253         }
254         return nt_status;
255 }
256
257 static int auth_ntlmssp_state_destructor(void *ptr);
258
259 NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state)
260 {
261         NTSTATUS nt_status;
262         bool is_standalone;
263         const char *netbios_name;
264         const char *netbios_domain;
265         const char *dns_name;
266         char *dns_domain;
267         struct auth_ntlmssp_state *ans;
268         struct auth_context *auth_context;
269
270         if ((enum server_types)lp_server_role() == ROLE_STANDALONE) {
271                 is_standalone = true;
272         } else {
273                 is_standalone = false;
274         }
275
276         netbios_name = global_myname();
277         netbios_domain = lp_workgroup();
278         /* This should be a 'netbios domain -> DNS domain' mapping */
279         dns_domain = get_mydnsdomname(talloc_tos());
280         if (dns_domain) {
281                 strlower_m(dns_domain);
282         }
283         dns_name = get_mydnsfullname();
284
285         ans = talloc_zero(NULL, struct auth_ntlmssp_state);
286         if (!ans) {
287                 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
288                 return NT_STATUS_NO_MEMORY;
289         }
290
291         nt_status = ntlmssp_server_start(ans,
292                                          is_standalone,
293                                          netbios_name,
294                                          netbios_domain,
295                                          dns_name,
296                                          dns_domain,
297                                          &ans->ntlmssp_state);
298         if (!NT_STATUS_IS_OK(nt_status)) {
299                 return nt_status;
300         }
301
302         nt_status = make_auth_context_subsystem(&auth_context);
303         if (!NT_STATUS_IS_OK(nt_status)) {
304                 return nt_status;
305         }
306         ans->auth_context = talloc_steal(ans, auth_context);
307
308         ans->ntlmssp_state->callback_private = ans;
309         ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
310         ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
311         ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
312         ans->ntlmssp_state->check_password = auth_ntlmssp_check_password;
313
314         talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor);
315
316         *auth_ntlmssp_state = ans;
317         return NT_STATUS_OK;
318 }
319
320 static int auth_ntlmssp_state_destructor(void *ptr)
321 {
322         struct auth_ntlmssp_state *ans;
323
324         ans = talloc_get_type(ptr, struct auth_ntlmssp_state);
325
326         TALLOC_FREE(ans->server_info);
327         TALLOC_FREE(ans->ntlmssp_state);
328         return 0;
329 }
330
331 NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *auth_ntlmssp_state,
332                              const DATA_BLOB request, DATA_BLOB *reply) 
333 {
334         return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
335 }