2 Unix SMB/CIFS implementation.
4 dcerpc authentication operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "auth/auth.h"
28 struct gensec_ntlmssp_state {
29 struct auth_context *auth_context;
30 struct auth_serversupplied_info *server_info;
31 struct ntlmssp_state *ntlmssp_state;
36 * Return the challenge as determined by the authentication subsystem
37 * @return an 8 byte random challenge
40 static const uint8_t *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
42 struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context;
44 return gensec_ntlmssp_state->auth_context->get_ntlm_challenge(gensec_ntlmssp_state->auth_context);
48 * Some authentication methods 'fix' the challenge, so we may not be able to set it
50 * @return If the effective challenge used by the auth subsystem may be modified
52 static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
54 struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context;
56 return gensec_ntlmssp_state->auth_context->challenge_may_be_modified;
60 * NTLM2 authentication modifies the effective challenge,
61 * @param challenge The new challenge value
63 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
65 struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context;
66 struct auth_context *auth_context = gensec_ntlmssp_state->auth_context;
68 SMB_ASSERT(challenge->length == 8);
70 auth_context->challenge = data_blob_talloc(auth_context,
71 challenge->data, challenge->length);
73 auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
75 DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
76 DEBUG(5, ("challenge is: \n"));
77 dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
82 * Check the password on an NTLMSSP login.
84 * Return the session keys used on the connection.
87 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
89 struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context;
90 struct auth_usersupplied_info *user_info = NULL;
94 /* the client has given us its machine name (which we otherwise would not get on port 445).
95 we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
97 set_remote_machine_name(gensec_ntlmssp_state->ntlmssp_state->workstation, True);
99 /* setup the string used by %U */
100 /* sub_set_smb_name checks for weird internally */
101 sub_set_smb_name(gensec_ntlmssp_state->ntlmssp_state->user);
103 reload_services(True);
106 nt_status = make_user_info_map(ntlmssp_state,
108 gensec_ntlmssp_state->ntlmssp_state->user,
109 gensec_ntlmssp_state->ntlmssp_state->domain,
110 gensec_ntlmssp_state->ntlmssp_state->workstation,
111 gensec_ntlmssp_state->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->lm_resp : NULL,
112 gensec_ntlmssp_state->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->nt_resp : NULL,
116 if (!NT_STATUS_IS_OK(nt_status)) {
120 nt_status = gensec_ntlmssp_state->
121 auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context,
123 gensec_ntlmssp_state,
124 &gensec_ntlmssp_state->server_info);
126 free_user_info(&user_info);
128 if (!NT_STATUS_IS_OK(nt_status)) {
131 if (gensec_ntlmssp_state->server_info->user_session_key.length) {
132 DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length));
133 *user_session_key = data_blob_talloc(ntlmssp_state,
134 gensec_ntlmssp_state->server_info->user_session_key.data,
135 gensec_ntlmssp_state->server_info->user_session_key.length);
137 if (gensec_ntlmssp_state->server_info->lm_session_key.length) {
138 DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length));
139 *lm_session_key = data_blob_talloc(ntlmssp_state,
140 gensec_ntlmssp_state->server_info->lm_session_key.data,
141 gensec_ntlmssp_state->server_info->lm_session_key.length);
146 static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security)
148 struct gensec_ntlmssp_state *gensec_ntlmssp_state;
150 gensec_ntlmssp_state = talloc_p(gensec_security, struct gensec_ntlmssp_state);
151 if (!gensec_ntlmssp_state) {
152 return NT_STATUS_NO_MEMORY;
155 gensec_ntlmssp_state->ntlmssp_state = NULL;
156 gensec_ntlmssp_state->auth_context = NULL;
157 gensec_ntlmssp_state->server_info = NULL;
159 gensec_security->private_data = gensec_ntlmssp_state;
163 static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
167 struct ntlmssp_state *ntlmssp_state;
168 struct gensec_ntlmssp_state *gensec_ntlmssp_state;
170 status = gensec_ntlmssp_start(gensec_security);
171 if (!NT_STATUS_IS_OK(status)) {
175 gensec_ntlmssp_state = gensec_security->private_data;
177 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(gensec_security,
178 &gensec_ntlmssp_state->ntlmssp_state))) {
182 if (gensec_security->want_features & GENSEC_WANT_SIGN) {
183 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
185 if (gensec_security->want_features & GENSEC_WANT_SEAL) {
186 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
189 /* IF we are not doing Signing or Sealing, we can actually do
190 * NTLM2. When we crack the crypto puzzle, then we can enable
191 * this always, in the constant flags */
193 if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) {
194 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
197 ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
198 nt_status = make_auth_context_subsystem(gensec_security, &gensec_ntlmssp_state->auth_context);
199 if (!NT_STATUS_IS_OK(nt_status)) {
203 ntlmssp_state->auth_context = gensec_ntlmssp_state;
204 ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
205 ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
206 ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
207 ntlmssp_state->check_password = auth_ntlmssp_check_password;
208 ntlmssp_state->server_role = lp_server_role();
213 static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
215 struct gensec_ntlmssp_state *gensec_ntlmssp_state;
216 char *password = NULL;
219 status = gensec_ntlmssp_start(gensec_security);
220 if (!NT_STATUS_IS_OK(status)) {
224 gensec_ntlmssp_state = gensec_security->private_data;
225 status = ntlmssp_client_start(gensec_security,
226 &gensec_ntlmssp_state->ntlmssp_state);
227 if (!NT_STATUS_IS_OK(status)) {
231 if (gensec_security->want_features & GENSEC_WANT_SESSION_KEY) {
233 * We need to set this to allow a later SetPassword
234 * via the SAMR pipe to succeed. Strange.... We could
235 * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
237 * Without this, Windows will not create the master key
238 * that it thinks is only used for NTLMSSP signing and
239 * sealing. (It is actually pulled out and used directly)
241 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
243 if (gensec_security->want_features & GENSEC_WANT_SIGN) {
244 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
246 if (gensec_security->want_features & GENSEC_WANT_SEAL) {
247 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
250 /* IF we are not doing Signing or Sealing, we can actually do
251 * NTLM2. When we crack the crypto puzzle, then we can enable
252 * this always, in the constant flags */
254 if (!(gensec_security->want_features & GENSEC_WANT_SIGN) && !(gensec_security->want_features & GENSEC_WANT_SEAL)) {
255 gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
258 status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state,
259 gensec_security->user.domain);
260 if (!NT_STATUS_IS_OK(status)) {
264 status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state,
265 gensec_security->user.name);
266 if (!NT_STATUS_IS_OK(status)) {
270 status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password);
271 if (!NT_STATUS_IS_OK(status)) {
276 status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state,
278 if (!NT_STATUS_IS_OK(status)) {
283 gensec_security->private_data = gensec_ntlmssp_state;
289 wrappers for the ntlmssp_*() functions
291 static NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
293 uint8_t *data, size_t length,
294 const uint8_t *whole_pdu, size_t pdu_length,
297 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
299 return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig);
302 static NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
304 const uint8_t *data, size_t length,
305 const uint8_t *whole_pdu, size_t pdu_length,
306 const DATA_BLOB *sig)
308 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
310 return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig);
313 static NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
315 uint8_t *data, size_t length,
316 const uint8_t *whole_pdu, size_t pdu_length,
319 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
321 return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig);
324 static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
326 const uint8_t *data, size_t length,
327 const uint8_t *whole_pdu, size_t pdu_length,
330 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
332 return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, whole_pdu, pdu_length, sig);
335 static size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security)
337 return NTLMSSP_SIG_SIZE;
340 static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security,
341 DATA_BLOB *session_key)
343 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
345 return ntlmssp_session_key(gensec_ntlmssp_state->ntlmssp_state, session_key);
349 * Next state function for the wrapped NTLMSSP state machine
351 * @param gensec_security GENSEC state, initialised to NTLMSSP
352 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
353 * @param in The request, as a DATA_BLOB
354 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
355 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
356 * or NT_STATUS_OK if the user is authenticated.
359 static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
360 const DATA_BLOB in, DATA_BLOB *out)
362 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
364 return ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out);
368 * Return the credentials of a logged on user, including session keys
371 * Only valid after a successful authentication
373 * May only be called once per authentication.
377 static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
378 struct auth_session_info **session_info)
381 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
382 nt_status = make_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info);
384 if (!NT_STATUS_IS_OK(nt_status)) {
388 (*session_info)->session_key = data_blob_talloc(*session_info,
389 gensec_ntlmssp_state->ntlmssp_state->session_key.data,
390 gensec_ntlmssp_state->ntlmssp_state->session_key.length);
392 (*session_info)->workstation = talloc_strdup(*session_info,
393 gensec_ntlmssp_state->ntlmssp_state->workstation);
398 static void gensec_ntlmssp_end(struct gensec_security *gensec_security)
400 struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
402 if (gensec_ntlmssp_state->ntlmssp_state) {
403 ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state);
406 if (gensec_ntlmssp_state->auth_context) {
407 free_auth_context(&gensec_ntlmssp_state->auth_context);
409 if (gensec_ntlmssp_state->server_info) {
410 free_server_info(&gensec_ntlmssp_state->server_info);
412 talloc_free(gensec_ntlmssp_state);
413 gensec_security->private_data = NULL;
416 static const struct gensec_security_ops gensec_ntlmssp_security_ops = {
419 .auth_type = DCERPC_AUTH_TYPE_NTLMSSP,
421 .client_start = gensec_ntlmssp_client_start,
422 .server_start = gensec_ntlmssp_server_start,
423 .update = gensec_ntlmssp_update,
424 .seal_packet = gensec_ntlmssp_seal_packet,
425 .sig_size = gensec_ntlmssp_sig_size,
426 .sign_packet = gensec_ntlmssp_sign_packet,
427 .check_packet = gensec_ntlmssp_check_packet,
428 .unseal_packet = gensec_ntlmssp_unseal_packet,
429 .session_key = gensec_ntlmssp_session_key,
430 .session_info = gensec_ntlmssp_session_info,
431 .end = gensec_ntlmssp_end
435 NTSTATUS gensec_ntlmssp_init(void)
438 ret = register_backend("gensec", &gensec_ntlmssp_security_ops);
439 if (!NT_STATUS_IS_OK(ret)) {
440 DEBUG(0,("Failed to register '%s' gensec backend!\n",
441 gensec_ntlmssp_security_ops.name));