s3-auth rename auth_ntlmssp_state -> auth_generic_state
[samba.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,2011
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 "auth.h"
25 #include "../auth/ntlmssp/ntlmssp.h"
26 #include "ntlmssp_wrap.h"
27 #include "../librpc/gen_ndr/netlogon.h"
28 #include "../librpc/gen_ndr/dcerpc.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "auth/gensec/gensec.h"
31 #include "librpc/rpc/dcerpc.h"
32 #include "lib/param/param.h"
33
34 static NTSTATUS gensec_ntlmssp3_server_session_info(struct gensec_security *gensec_security,
35                                         TALLOC_CTX *mem_ctx,
36                                         struct auth_session_info **session_info)
37 {
38         struct gensec_ntlmssp_context *gensec_ntlmssp =
39                 talloc_get_type_abort(gensec_security->private_data,
40                                       struct gensec_ntlmssp_context);
41         NTSTATUS nt_status;
42
43         nt_status = create_local_token(mem_ctx,
44                                        gensec_ntlmssp->server_info,
45                                        &gensec_ntlmssp->ntlmssp_state->session_key,
46                                        gensec_ntlmssp->ntlmssp_state->user,
47                                        session_info);
48         if (!NT_STATUS_IS_OK(nt_status)) {
49                 DEBUG(10, ("create_local_token failed: %s\n",
50                            nt_errstr(nt_status)));
51                 return nt_status;
52         }
53
54         return NT_STATUS_OK;
55 }
56
57 static NTSTATUS gensec_ntlmssp3_server_update(struct gensec_security *gensec_security,
58                                               TALLOC_CTX *out_mem_ctx,
59                                               struct tevent_context *ev,
60                                               const DATA_BLOB request,
61                                               DATA_BLOB *reply)
62 {
63         NTSTATUS status;
64         struct gensec_ntlmssp_context *gensec_ntlmssp =
65                 talloc_get_type_abort(gensec_security->private_data,
66                                       struct gensec_ntlmssp_context);
67
68         status = ntlmssp_update(gensec_ntlmssp->ntlmssp_state, request, reply);
69         if (NT_STATUS_IS_OK(status) ||
70             NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
71                 talloc_steal(out_mem_ctx, reply->data);
72         }
73
74         return status;
75 }
76
77 /**
78  * Return the challenge as determined by the authentication subsystem 
79  * @return an 8 byte random challenge
80  */
81
82 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
83                                            uint8_t chal[8])
84 {
85         struct gensec_ntlmssp_context *gensec_ntlmssp =
86                 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
87         gensec_ntlmssp->auth_context->get_ntlm_challenge(
88                 gensec_ntlmssp->auth_context, chal);
89         return NT_STATUS_OK;
90 }
91
92 /**
93  * Some authentication methods 'fix' the challenge, so we may not be able to set it
94  *
95  * @return If the effective challenge used by the auth subsystem may be modified
96  */
97 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
98 {
99         struct gensec_ntlmssp_context *gensec_ntlmssp =
100                 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
101         struct auth_context *auth_context = gensec_ntlmssp->auth_context;
102
103         return auth_context->challenge_may_be_modified;
104 }
105
106 /**
107  * NTLM2 authentication modifies the effective challenge, 
108  * @param challenge The new challenge value
109  */
110 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
111 {
112         struct gensec_ntlmssp_context *gensec_ntlmssp =
113                 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
114         struct auth_context *auth_context = gensec_ntlmssp->auth_context;
115
116         SMB_ASSERT(challenge->length == 8);
117
118         auth_context->challenge = data_blob_talloc(auth_context,
119                                                    challenge->data, challenge->length);
120
121         auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
122
123         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
124         DEBUG(5, ("challenge is: \n"));
125         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
126         return NT_STATUS_OK;
127 }
128
129 /**
130  * Check the password on an NTLMSSP login.  
131  *
132  * Return the session keys used on the connection.
133  */
134
135 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
136                                             DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
137 {
138         struct gensec_ntlmssp_context *gensec_ntlmssp =
139                 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
140         struct auth_usersupplied_info *user_info = NULL;
141         NTSTATUS nt_status;
142         bool username_was_mapped;
143
144         /* the client has given us its machine name (which we otherwise would not get on port 445).
145            we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
146
147         set_remote_machine_name(gensec_ntlmssp->ntlmssp_state->client.netbios_name, True);
148
149         /* setup the string used by %U */
150         /* sub_set_smb_name checks for weird internally */
151         sub_set_smb_name(gensec_ntlmssp->ntlmssp_state->user);
152
153         lp_load(get_dyn_CONFIGFILE(), false, false, true, true);
154
155         nt_status = make_user_info_map(&user_info,
156                                        gensec_ntlmssp->ntlmssp_state->user,
157                                        gensec_ntlmssp->ntlmssp_state->domain,
158                                        gensec_ntlmssp->ntlmssp_state->client.netbios_name,
159                                        gensec_get_remote_address(gensec_ntlmssp->gensec_security),
160                                        gensec_ntlmssp->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp->ntlmssp_state->lm_resp : NULL,
161                                        gensec_ntlmssp->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp->ntlmssp_state->nt_resp : NULL,
162                                        NULL, NULL, NULL,
163                                        AUTH_PASSWORD_RESPONSE);
164
165         if (!NT_STATUS_IS_OK(nt_status)) {
166                 return nt_status;
167         }
168
169         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
170
171         nt_status = gensec_ntlmssp->auth_context->check_ntlm_password(gensec_ntlmssp->auth_context,
172                                                                           user_info, &gensec_ntlmssp->server_info);
173
174         username_was_mapped = user_info->was_mapped;
175
176         free_user_info(&user_info);
177
178         if (!NT_STATUS_IS_OK(nt_status)) {
179                 nt_status = do_map_to_guest_server_info(nt_status,
180                                                         &gensec_ntlmssp->server_info,
181                                                         gensec_ntlmssp->ntlmssp_state->user,
182                                                         gensec_ntlmssp->ntlmssp_state->domain);
183                 return nt_status;
184         }
185
186         if (!NT_STATUS_IS_OK(nt_status)) {
187                 return nt_status;
188         }
189
190         gensec_ntlmssp->server_info->nss_token |= username_was_mapped;
191
192         /* Clear out the session keys, and pass them to the caller.
193          * They will not be used in this form again - instead the
194          * NTLMSSP code will decide on the final correct session key,
195          * and supply it to create_local_token() */
196         if (gensec_ntlmssp->server_info->session_key.length) {
197                 DEBUG(10, ("Got NT session key of length %u\n",
198                         (unsigned int)gensec_ntlmssp->server_info->session_key.length));
199                 *session_key = gensec_ntlmssp->server_info->session_key;
200                 talloc_steal(mem_ctx, gensec_ntlmssp->server_info->session_key.data);
201                 gensec_ntlmssp->server_info->session_key = data_blob_null;
202         }
203         if (gensec_ntlmssp->server_info->lm_session_key.length) {
204                 DEBUG(10, ("Got LM session key of length %u\n",
205                         (unsigned int)gensec_ntlmssp->server_info->lm_session_key.length));
206                 *lm_session_key = gensec_ntlmssp->server_info->lm_session_key;
207                 talloc_steal(mem_ctx, gensec_ntlmssp->server_info->lm_session_key.data);
208                 gensec_ntlmssp->server_info->lm_session_key = data_blob_null;
209         }
210         return nt_status;
211 }
212
213 NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
214                               struct auth_generic_state **auth_ntlmssp_state)
215 {
216         struct auth_context *auth_context;
217         struct auth_generic_state *ans;
218         NTSTATUS nt_status;
219
220         ans = talloc_zero(NULL, struct auth_generic_state);
221         if (!ans) {
222                 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
223                 return NT_STATUS_NO_MEMORY;
224         }
225
226         nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
227         if (!NT_STATUS_IS_OK(nt_status)) {
228                 TALLOC_FREE(ans);
229                 return nt_status;
230         }
231
232         ans->auth_context = talloc_steal(ans, auth_context);
233
234         if (auth_context->prepare_gensec) {
235                 nt_status = auth_context->prepare_gensec(ans,
236                                                          &ans->gensec_security);
237                 if (!NT_STATUS_IS_OK(nt_status)) {
238                         TALLOC_FREE(ans);
239                         return nt_status;
240                 }
241                 *auth_ntlmssp_state = ans;
242                 return NT_STATUS_OK;
243         } else {
244                 struct gensec_settings *gensec_settings;
245                 struct loadparm_context *lp_ctx;
246
247                 lp_ctx = loadparm_init_s3(ans, loadparm_s3_context());
248                 if (lp_ctx == NULL) {
249                         DEBUG(10, ("loadparm_init_s3 failed\n"));
250                         TALLOC_FREE(ans);
251                         return NT_STATUS_INVALID_SERVER_STATE;
252                 }
253
254                 gensec_settings = lpcfg_gensec_settings(ans, lp_ctx);
255                 if (lp_ctx == NULL) {
256                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
257                         TALLOC_FREE(ans);
258                         return NT_STATUS_NO_MEMORY;
259                 }
260
261                 nt_status = gensec_server_start(ans, gensec_settings,
262                                                 NULL, &ans->gensec_security);
263
264                 if (!NT_STATUS_IS_OK(nt_status)) {
265                         TALLOC_FREE(ans);
266                         return nt_status;
267                 }
268                 talloc_unlink(ans, lp_ctx);
269                 talloc_unlink(ans, gensec_settings);
270         }
271
272         nt_status = gensec_set_remote_address(ans->gensec_security,
273                                               remote_address);
274         if (!NT_STATUS_IS_OK(nt_status)) {
275                 TALLOC_FREE(ans);
276                 return nt_status;
277         }
278
279         *auth_ntlmssp_state = ans;
280         return NT_STATUS_OK;
281 }
282
283 static NTSTATUS gensec_ntlmssp3_server_start(struct gensec_security *gensec_security)
284 {
285         NTSTATUS nt_status;
286         bool is_standalone;
287         const char *netbios_name;
288         const char *netbios_domain;
289         const char *dns_name;
290         char *dns_domain;
291         struct gensec_ntlmssp_context *gensec_ntlmssp;
292
293         if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
294                 is_standalone = true;
295         } else {
296                 is_standalone = false;
297         }
298
299         netbios_name = lp_netbios_name();
300         netbios_domain = lp_workgroup();
301         /* This should be a 'netbios domain -> DNS domain' mapping */
302         dns_domain = get_mydnsdomname(talloc_tos());
303         if (dns_domain) {
304                 strlower_m(dns_domain);
305         }
306         dns_name = get_mydnsfullname();
307
308         nt_status = gensec_ntlmssp_start(gensec_security);
309         NT_STATUS_NOT_OK_RETURN(nt_status);
310
311         gensec_ntlmssp =
312                 talloc_get_type_abort(gensec_security->private_data,
313                                       struct gensec_ntlmssp_context);
314
315         nt_status = ntlmssp_server_start(gensec_ntlmssp,
316                                          is_standalone,
317                                          netbios_name,
318                                          netbios_domain,
319                                          dns_name,
320                                          dns_domain,
321                                          &gensec_ntlmssp->ntlmssp_state);
322         if (!NT_STATUS_IS_OK(nt_status)) {
323                 return nt_status;
324         }
325
326         gensec_ntlmssp->ntlmssp_state->callback_private = gensec_ntlmssp;
327
328         gensec_ntlmssp->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
329         gensec_ntlmssp->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
330         gensec_ntlmssp->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
331         gensec_ntlmssp->ntlmssp_state->check_password = auth_ntlmssp_check_password;
332
333         if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
334                 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
335         }
336         if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SIGN) {
337                 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
338         }
339         if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SEAL) {
340                 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
341                 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
342         }
343
344         return NT_STATUS_OK;
345 }
346
347 static const char *gensec_ntlmssp3_server_oids[] = {
348         GENSEC_OID_NTLMSSP,
349         NULL
350 };
351
352 static const struct gensec_security_ops gensec_ntlmssp3_server_ops = {
353         .name           = "ntlmssp3_server",
354         .sasl_name      = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */
355         .auth_type      = DCERPC_AUTH_TYPE_NTLMSSP,
356         .oid            = gensec_ntlmssp3_server_oids,
357         .server_start   = gensec_ntlmssp3_server_start,
358         .magic          = gensec_ntlmssp_magic,
359         .update         = gensec_ntlmssp3_server_update,
360         .sig_size       = gensec_ntlmssp_sig_size,
361         .sign_packet    = gensec_ntlmssp_sign_packet,
362         .check_packet   = gensec_ntlmssp_check_packet,
363         .seal_packet    = gensec_ntlmssp_seal_packet,
364         .unseal_packet  = gensec_ntlmssp_unseal_packet,
365         .wrap           = gensec_ntlmssp_wrap,
366         .unwrap         = gensec_ntlmssp_unwrap,
367         .session_key    = gensec_ntlmssp_session_key,
368         .session_info   = gensec_ntlmssp3_server_session_info,
369         .have_feature   = gensec_ntlmssp_have_feature,
370         .enabled        = true,
371         .priority       = GENSEC_NTLMSSP
372 };
373
374 NTSTATUS auth_generic_start(struct auth_generic_state *auth_ntlmssp_state, const char *oid)
375 {
376         struct gensec_ntlmssp_context *gensec_ntlmssp;
377         NTSTATUS status;
378
379         if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid) {
380                 return auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid(
381                                 auth_ntlmssp_state->gensec_security, oid);
382         }
383
384         if (strcmp(oid, GENSEC_OID_NTLMSSP) != 0) {
385                 return NT_STATUS_NOT_IMPLEMENTED;
386         }
387
388         status = gensec_start_mech_by_ops(auth_ntlmssp_state->gensec_security,
389                                           &gensec_ntlmssp3_server_ops);
390         if (!NT_STATUS_IS_OK(status)) {
391                 return status;
392         }
393
394         gensec_ntlmssp =
395                 talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data,
396                                       struct gensec_ntlmssp_context);
397
398         gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context);
399
400         return NT_STATUS_OK;
401 }
402
403 NTSTATUS auth_generic_authtype_start(struct auth_generic_state *auth_ntlmssp_state,
404                                      uint8_t auth_type, uint8_t auth_level)
405 {
406         struct gensec_ntlmssp_context *gensec_ntlmssp;
407         NTSTATUS status;
408
409         if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype) {
410                 return auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype(
411                                 auth_ntlmssp_state->gensec_security,
412                                 auth_type, auth_level);
413         }
414
415         if (auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
416                 /* The caller will then free the auth_ntlmssp_state,
417                  * undoing what was done in auth_ntlmssp_prepare().
418                  *
419                  * We can't do that logic here, as
420                  * auth_ntlmssp_want_feature() may have been called in
421                  * between.
422                  */
423                 return NT_STATUS_NOT_IMPLEMENTED;
424         }
425
426         gensec_want_feature(auth_ntlmssp_state->gensec_security,
427                             GENSEC_FEATURE_DCE_STYLE);
428         gensec_want_feature(auth_ntlmssp_state->gensec_security,
429                             GENSEC_FEATURE_ASYNC_REPLIES);
430         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
431                 gensec_want_feature(auth_ntlmssp_state->gensec_security,
432                                     GENSEC_FEATURE_SIGN);
433         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
434                 gensec_want_feature(auth_ntlmssp_state->gensec_security,
435                                     GENSEC_FEATURE_SIGN);
436                 gensec_want_feature(auth_ntlmssp_state->gensec_security,
437                                     GENSEC_FEATURE_SEAL);
438         } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
439                 /* Default features */
440         } else {
441                 DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
442                          auth_level));
443                 return NT_STATUS_INVALID_PARAMETER;
444         }
445
446         status = gensec_start_mech_by_ops(auth_ntlmssp_state->gensec_security,
447                                           &gensec_ntlmssp3_server_ops);
448         if (!NT_STATUS_IS_OK(status)) {
449                 return status;
450         }
451
452         gensec_ntlmssp =
453                 talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data,
454                                       struct gensec_ntlmssp_context);
455
456         gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context);
457
458         return NT_STATUS_OK;
459 }
460
461 NTSTATUS auth_ntlmssp_start(struct auth_generic_state *auth_ntlmssp_state)
462 {
463         return auth_generic_start(auth_ntlmssp_state, GENSEC_OID_NTLMSSP);
464 }