2 Unix SMB/Netbios implementation.
4 handle NLTMSSP, server side
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett 2001-2003,2011
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.
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.
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/>.
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"
34 NTSTATUS auth_ntlmssp_session_info(TALLOC_CTX *mem_ctx,
35 struct auth_ntlmssp_state *auth_ntlmssp_state,
36 struct auth_session_info **session_info)
39 nt_status = gensec_session_info(auth_ntlmssp_state->gensec_security,
45 static NTSTATUS gensec_ntlmssp3_server_session_info(struct gensec_security *gensec_security,
47 struct auth_session_info **session_info)
49 struct gensec_ntlmssp_context *gensec_ntlmssp =
50 talloc_get_type_abort(gensec_security->private_data,
51 struct gensec_ntlmssp_context);
54 nt_status = create_local_token(mem_ctx,
55 gensec_ntlmssp->server_info,
56 &gensec_ntlmssp->ntlmssp_state->session_key,
57 gensec_ntlmssp->ntlmssp_state->user,
59 if (!NT_STATUS_IS_OK(nt_status)) {
60 DEBUG(10, ("create_local_token failed: %s\n",
61 nt_errstr(nt_status)));
68 static NTSTATUS gensec_ntlmssp3_server_update(struct gensec_security *gensec_security,
69 TALLOC_CTX *out_mem_ctx,
70 struct tevent_context *ev,
71 const DATA_BLOB request,
75 struct gensec_ntlmssp_context *gensec_ntlmssp =
76 talloc_get_type_abort(gensec_security->private_data,
77 struct gensec_ntlmssp_context);
79 status = ntlmssp_update(gensec_ntlmssp->ntlmssp_state, request, reply);
80 if (NT_STATUS_IS_OK(status) ||
81 NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
82 talloc_steal(out_mem_ctx, reply->data);
89 * Return the challenge as determined by the authentication subsystem
90 * @return an 8 byte random challenge
93 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
96 struct gensec_ntlmssp_context *gensec_ntlmssp =
97 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
98 gensec_ntlmssp->auth_context->get_ntlm_challenge(
99 gensec_ntlmssp->auth_context, chal);
104 * Some authentication methods 'fix' the challenge, so we may not be able to set it
106 * @return If the effective challenge used by the auth subsystem may be modified
108 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
110 struct gensec_ntlmssp_context *gensec_ntlmssp =
111 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
112 struct auth_context *auth_context = gensec_ntlmssp->auth_context;
114 return auth_context->challenge_may_be_modified;
118 * NTLM2 authentication modifies the effective challenge,
119 * @param challenge The new challenge value
121 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
123 struct gensec_ntlmssp_context *gensec_ntlmssp =
124 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
125 struct auth_context *auth_context = gensec_ntlmssp->auth_context;
127 SMB_ASSERT(challenge->length == 8);
129 auth_context->challenge = data_blob_talloc(auth_context,
130 challenge->data, challenge->length);
132 auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
134 DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
135 DEBUG(5, ("challenge is: \n"));
136 dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
141 * Check the password on an NTLMSSP login.
143 * Return the session keys used on the connection.
146 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
147 DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
149 struct gensec_ntlmssp_context *gensec_ntlmssp =
150 (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private;
151 struct auth_usersupplied_info *user_info = NULL;
153 bool username_was_mapped;
155 /* the client has given us its machine name (which we otherwise would not get on port 445).
156 we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
158 set_remote_machine_name(gensec_ntlmssp->ntlmssp_state->client.netbios_name, True);
160 /* setup the string used by %U */
161 /* sub_set_smb_name checks for weird internally */
162 sub_set_smb_name(gensec_ntlmssp->ntlmssp_state->user);
164 lp_load(get_dyn_CONFIGFILE(), false, false, true, true);
166 nt_status = make_user_info_map(&user_info,
167 gensec_ntlmssp->ntlmssp_state->user,
168 gensec_ntlmssp->ntlmssp_state->domain,
169 gensec_ntlmssp->ntlmssp_state->client.netbios_name,
170 gensec_get_remote_address(gensec_ntlmssp->gensec_security),
171 gensec_ntlmssp->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp->ntlmssp_state->lm_resp : NULL,
172 gensec_ntlmssp->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp->ntlmssp_state->nt_resp : NULL,
174 AUTH_PASSWORD_RESPONSE);
176 if (!NT_STATUS_IS_OK(nt_status)) {
180 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
182 nt_status = gensec_ntlmssp->auth_context->check_ntlm_password(gensec_ntlmssp->auth_context,
183 user_info, &gensec_ntlmssp->server_info);
185 username_was_mapped = user_info->was_mapped;
187 free_user_info(&user_info);
189 if (!NT_STATUS_IS_OK(nt_status)) {
190 nt_status = do_map_to_guest_server_info(nt_status,
191 &gensec_ntlmssp->server_info,
192 gensec_ntlmssp->ntlmssp_state->user,
193 gensec_ntlmssp->ntlmssp_state->domain);
197 if (!NT_STATUS_IS_OK(nt_status)) {
201 gensec_ntlmssp->server_info->nss_token |= username_was_mapped;
203 /* Clear out the session keys, and pass them to the caller.
204 * They will not be used in this form again - instead the
205 * NTLMSSP code will decide on the final correct session key,
206 * and supply it to create_local_token() */
207 if (gensec_ntlmssp->server_info->session_key.length) {
208 DEBUG(10, ("Got NT session key of length %u\n",
209 (unsigned int)gensec_ntlmssp->server_info->session_key.length));
210 *session_key = gensec_ntlmssp->server_info->session_key;
211 talloc_steal(mem_ctx, gensec_ntlmssp->server_info->session_key.data);
212 gensec_ntlmssp->server_info->session_key = data_blob_null;
214 if (gensec_ntlmssp->server_info->lm_session_key.length) {
215 DEBUG(10, ("Got LM session key of length %u\n",
216 (unsigned int)gensec_ntlmssp->server_info->lm_session_key.length));
217 *lm_session_key = gensec_ntlmssp->server_info->lm_session_key;
218 talloc_steal(mem_ctx, gensec_ntlmssp->server_info->lm_session_key.data);
219 gensec_ntlmssp->server_info->lm_session_key = data_blob_null;
224 NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
225 struct auth_ntlmssp_state **auth_ntlmssp_state)
227 struct auth_context *auth_context;
228 struct auth_ntlmssp_state *ans;
231 ans = talloc_zero(NULL, struct auth_ntlmssp_state);
233 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
234 return NT_STATUS_NO_MEMORY;
237 nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
238 if (!NT_STATUS_IS_OK(nt_status)) {
243 ans->auth_context = talloc_steal(ans, auth_context);
245 if (auth_context->prepare_gensec) {
246 nt_status = auth_context->prepare_gensec(ans,
247 &ans->gensec_security);
248 if (!NT_STATUS_IS_OK(nt_status)) {
252 *auth_ntlmssp_state = ans;
255 struct gensec_settings *gensec_settings;
256 struct loadparm_context *lp_ctx;
258 lp_ctx = loadparm_init_s3(ans, loadparm_s3_context());
259 if (lp_ctx == NULL) {
260 DEBUG(10, ("loadparm_init_s3 failed\n"));
262 return NT_STATUS_INVALID_SERVER_STATE;
265 gensec_settings = lpcfg_gensec_settings(ans, lp_ctx);
266 if (lp_ctx == NULL) {
267 DEBUG(10, ("lpcfg_gensec_settings failed\n"));
269 return NT_STATUS_NO_MEMORY;
272 nt_status = gensec_server_start(ans, gensec_settings,
273 NULL, &ans->gensec_security);
275 if (!NT_STATUS_IS_OK(nt_status)) {
279 talloc_unlink(ans, lp_ctx);
280 talloc_unlink(ans, gensec_settings);
283 nt_status = gensec_set_remote_address(ans->gensec_security,
285 if (!NT_STATUS_IS_OK(nt_status)) {
290 *auth_ntlmssp_state = ans;
294 static NTSTATUS gensec_ntlmssp3_server_start(struct gensec_security *gensec_security)
298 const char *netbios_name;
299 const char *netbios_domain;
300 const char *dns_name;
302 struct gensec_ntlmssp_context *gensec_ntlmssp;
304 if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
305 is_standalone = true;
307 is_standalone = false;
310 netbios_name = lp_netbios_name();
311 netbios_domain = lp_workgroup();
312 /* This should be a 'netbios domain -> DNS domain' mapping */
313 dns_domain = get_mydnsdomname(talloc_tos());
315 strlower_m(dns_domain);
317 dns_name = get_mydnsfullname();
319 nt_status = gensec_ntlmssp_start(gensec_security);
320 NT_STATUS_NOT_OK_RETURN(nt_status);
323 talloc_get_type_abort(gensec_security->private_data,
324 struct gensec_ntlmssp_context);
326 nt_status = ntlmssp_server_start(gensec_ntlmssp,
332 &gensec_ntlmssp->ntlmssp_state);
333 if (!NT_STATUS_IS_OK(nt_status)) {
337 gensec_ntlmssp->ntlmssp_state->callback_private = gensec_ntlmssp;
339 gensec_ntlmssp->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
340 gensec_ntlmssp->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
341 gensec_ntlmssp->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
342 gensec_ntlmssp->ntlmssp_state->check_password = auth_ntlmssp_check_password;
344 if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
345 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
347 if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SIGN) {
348 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
350 if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SEAL) {
351 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
352 gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
358 static const char *gensec_ntlmssp3_server_oids[] = {
363 static const struct gensec_security_ops gensec_ntlmssp3_server_ops = {
364 .name = "ntlmssp3_server",
365 .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */
366 .auth_type = DCERPC_AUTH_TYPE_NTLMSSP,
367 .oid = gensec_ntlmssp3_server_oids,
368 .server_start = gensec_ntlmssp3_server_start,
369 .magic = gensec_ntlmssp_magic,
370 .update = gensec_ntlmssp3_server_update,
371 .sig_size = gensec_ntlmssp_sig_size,
372 .sign_packet = gensec_ntlmssp_sign_packet,
373 .check_packet = gensec_ntlmssp_check_packet,
374 .seal_packet = gensec_ntlmssp_seal_packet,
375 .unseal_packet = gensec_ntlmssp_unseal_packet,
376 .wrap = gensec_ntlmssp_wrap,
377 .unwrap = gensec_ntlmssp_unwrap,
378 .session_key = gensec_ntlmssp_session_key,
379 .session_info = gensec_ntlmssp3_server_session_info,
380 .have_feature = gensec_ntlmssp_have_feature,
382 .priority = GENSEC_NTLMSSP
385 NTSTATUS auth_generic_start(struct auth_ntlmssp_state *auth_ntlmssp_state, const char *oid)
387 struct gensec_ntlmssp_context *gensec_ntlmssp;
390 if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid) {
391 return auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid(
392 auth_ntlmssp_state->gensec_security, oid);
395 if (strcmp(oid, GENSEC_OID_NTLMSSP) != 0) {
396 return NT_STATUS_NOT_IMPLEMENTED;
399 status = gensec_start_mech_by_ops(auth_ntlmssp_state->gensec_security,
400 &gensec_ntlmssp3_server_ops);
401 if (!NT_STATUS_IS_OK(status)) {
406 talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data,
407 struct gensec_ntlmssp_context);
409 gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context);
414 NTSTATUS auth_generic_authtype_start(struct auth_ntlmssp_state *auth_ntlmssp_state,
415 uint8_t auth_type, uint8_t auth_level)
417 struct gensec_ntlmssp_context *gensec_ntlmssp;
420 if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype) {
421 return auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype(
422 auth_ntlmssp_state->gensec_security,
423 auth_type, auth_level);
426 if (auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
427 /* The caller will then free the auth_ntlmssp_state,
428 * undoing what was done in auth_ntlmssp_prepare().
430 * We can't do that logic here, as
431 * auth_ntlmssp_want_feature() may have been called in
434 return NT_STATUS_NOT_IMPLEMENTED;
437 gensec_want_feature(auth_ntlmssp_state->gensec_security,
438 GENSEC_FEATURE_DCE_STYLE);
439 gensec_want_feature(auth_ntlmssp_state->gensec_security,
440 GENSEC_FEATURE_ASYNC_REPLIES);
441 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
442 gensec_want_feature(auth_ntlmssp_state->gensec_security,
443 GENSEC_FEATURE_SIGN);
444 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
445 gensec_want_feature(auth_ntlmssp_state->gensec_security,
446 GENSEC_FEATURE_SIGN);
447 gensec_want_feature(auth_ntlmssp_state->gensec_security,
448 GENSEC_FEATURE_SEAL);
449 } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
450 /* Default features */
452 DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
454 return NT_STATUS_INVALID_PARAMETER;
457 status = gensec_start_mech_by_ops(auth_ntlmssp_state->gensec_security,
458 &gensec_ntlmssp3_server_ops);
459 if (!NT_STATUS_IS_OK(status)) {
464 talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data,
465 struct gensec_ntlmssp_context);
467 gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context);
472 NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state)
474 return auth_generic_start(auth_ntlmssp_state, GENSEC_OID_NTLMSSP);