2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998-2001
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7 Copyright (C) Luke Howard 2003
8 Copyright (C) Volker Lendecke 2007
9 Copyright (C) Jeremy Allison 2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "../lib/tsocket/tsocket.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "../libcli/auth/spnego.h"
30 #include "../libcli/auth/ntlmssp.h"
31 #include "ntlmssp_wrap.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "libads/kerberos_proto.h"
34 #include "../lib/util/asn1.h"
37 #include "smbprofile.h"
39 /* For split krb5 SPNEGO blobs. */
40 struct pending_auth_data {
41 struct pending_auth_data *prev, *next;
42 uint16 vuid; /* Tag for this entry. */
43 uint16 smbpid; /* Alternate tag for this entry. */
45 DATA_BLOB partial_data;
49 on a logon error possibly map the error to success if "map to guest"
52 NTSTATUS do_map_to_guest(NTSTATUS status,
53 struct auth_serversupplied_info **server_info,
54 const char *user, const char *domain)
56 user = user ? user : "";
57 domain = domain ? domain : "";
59 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
60 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
61 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
62 DEBUG(3,("No such user %s [%s] - using guest account\n",
64 status = make_server_info_guest(NULL, server_info);
68 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
69 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
70 DEBUG(3,("Registered username %s for guest access\n",
72 status = make_server_info_guest(NULL, server_info);
79 /****************************************************************************
80 Add the standard 'Samba' signature to the end of the session setup.
81 ****************************************************************************/
83 static int push_signature(uint8 **outbuf)
90 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
92 if (tmp == -1) return -1;
95 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
96 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
100 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
103 if (tmp == -1) return -1;
106 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
108 if (tmp == -1) return -1;
114 /****************************************************************************
115 Send a security blob via a session setup reply.
116 ****************************************************************************/
118 static void reply_sesssetup_blob(struct smb_request *req,
122 if (!NT_STATUS_IS_OK(nt_status) &&
123 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
124 reply_nterror(req, nt_status_squash(nt_status));
128 nt_status = nt_status_squash(nt_status);
129 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
130 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
131 SSVAL(req->outbuf, smb_vwv3, blob.length);
133 if ((message_push_blob(&req->outbuf, blob) == -1)
134 || (push_signature(&req->outbuf) == -1)) {
135 reply_nterror(req, NT_STATUS_NO_MEMORY);
139 /****************************************************************************
140 Do a 'guest' logon, getting back the
141 ****************************************************************************/
143 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
145 struct auth_context *auth_context;
146 struct auth_usersupplied_info *user_info = NULL;
149 static unsigned char chal[8] = { 0, };
151 DEBUG(3,("Got anonymous request\n"));
153 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
154 if (!NT_STATUS_IS_OK(nt_status)) {
158 if (!make_user_info_guest(&user_info)) {
159 TALLOC_FREE(auth_context);
160 return NT_STATUS_NO_MEMORY;
163 nt_status = auth_context->check_ntlm_password(auth_context,
166 TALLOC_FREE(auth_context);
167 free_user_info(&user_info);
175 /* Experiment that failed. See "only happens with a KDC" comment below. */
176 /****************************************************************************
177 Cerate a clock skew error blob for a Windows client.
178 ****************************************************************************/
180 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
182 krb5_context context = NULL;
183 krb5_error_code kerr = 0;
185 krb5_principal host_princ = NULL;
186 char *host_princ_s = NULL;
189 *pblob_out = data_blob_null;
191 initialize_krb5_error_table();
192 kerr = krb5_init_context(&context);
196 /* Create server principal. */
197 asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
201 strlower_m(host_princ_s);
203 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
205 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
206 "for name %s: Error %s\n",
207 host_princ_s, error_message(kerr) ));
211 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
214 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
215 "failed: Error %s\n",
216 error_message(kerr) ));
220 *pblob_out = data_blob(reply.data, reply.length);
221 kerberos_free_data_contents(context,&reply);
227 SAFE_FREE(host_princ_s);
230 krb5_free_principal(context, host_princ);
232 krb5_free_context(context);
237 /****************************************************************************
238 Reply to a session setup spnego negotiate packet for kerberos.
239 ****************************************************************************/
241 static void reply_spnego_kerberos(struct smb_request *req,
245 bool *p_invalidate_vuid)
250 int sess_vuid = req->vuid;
251 NTSTATUS ret = NT_STATUS_OK;
252 DATA_BLOB ap_rep, ap_rep_wrapped, response;
253 struct auth_serversupplied_info *session_info = NULL;
254 DATA_BLOB session_key = data_blob_null;
256 DATA_BLOB nullblob = data_blob_null;
257 bool map_domainuser_to_guest = False;
258 bool username_was_mapped;
259 struct PAC_LOGON_INFO *logon_info = NULL;
260 struct smbd_server_connection *sconn = req->sconn;
268 ZERO_STRUCT(ap_rep_wrapped);
269 ZERO_STRUCT(response);
271 /* Normally we will always invalidate the intermediate vuid. */
272 *p_invalidate_vuid = True;
274 mem_ctx = talloc_init("reply_spnego_kerberos");
275 if (mem_ctx == NULL) {
276 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
280 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
281 talloc_destroy(mem_ctx);
282 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
286 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
287 &principal, &logon_info, &ap_rep,
290 data_blob_free(&ticket);
292 if (!NT_STATUS_IS_OK(ret)) {
294 /* Experiment that failed.
295 * See "only happens with a KDC" comment below. */
297 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
300 * Windows in this case returns
301 * NT_STATUS_MORE_PROCESSING_REQUIRED
302 * with a negTokenTarg blob containing an krb5_error
303 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
304 * The client then fixes its clock and continues rather
305 * than giving an error. JRA.
306 * -- Looks like this only happens with a KDC. JRA.
309 bool ok = make_krb5_skew_error(&ap_rep);
311 talloc_destroy(mem_ctx);
312 return ERROR_NT(nt_status_squash(
313 NT_STATUS_LOGON_FAILURE));
315 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
317 response = spnego_gen_auth_response(&ap_rep_wrapped,
318 ret, OID_KERBEROS5_OLD);
319 reply_sesssetup_blob(conn, inbuf, outbuf, response,
320 NT_STATUS_MORE_PROCESSING_REQUIRED);
323 * In this one case we don't invalidate the
324 * intermediate vuid as we're expecting the client
325 * to re-use it for the next sessionsetupX packet. JRA.
328 *p_invalidate_vuid = False;
330 data_blob_free(&ap_rep);
331 data_blob_free(&ap_rep_wrapped);
332 data_blob_free(&response);
333 talloc_destroy(mem_ctx);
334 return -1; /* already replied */
337 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
338 ret = NT_STATUS_LOGON_FAILURE;
341 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
343 talloc_destroy(mem_ctx);
344 reply_nterror(req, nt_status_squash(ret));
348 ret = get_user_from_kerberos_info(talloc_tos(),
349 sconn->client_id.name,
350 principal, logon_info,
351 &username_was_mapped,
352 &map_domainuser_to_guest,
354 &real_username, &pw);
355 if (!NT_STATUS_IS_OK(ret)) {
356 data_blob_free(&ap_rep);
357 data_blob_free(&session_key);
358 talloc_destroy(mem_ctx);
359 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
363 /* save the PAC data if we have it */
365 netsamlogon_cache_store(user, &logon_info->info3);
368 /* setup the string used by %U */
369 sub_set_smb_name(real_username);
371 /* reload services so that the new %U is taken into account */
372 reload_services(sconn->msg_ctx, sconn->sock, True);
374 ret = make_session_info_krb5(mem_ctx,
375 user, domain, real_username, pw,
376 logon_info, map_domainuser_to_guest,
380 data_blob_free(&session_key);
381 if (!NT_STATUS_IS_OK(ret)) {
382 DEBUG(1, ("make_server_info_krb5 failed!\n"));
383 data_blob_free(&ap_rep);
384 TALLOC_FREE(mem_ctx);
385 reply_nterror(req, nt_status_squash(ret));
389 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
390 sess_vuid = register_initial_vuid(sconn);
393 /* register_existing_vuid keeps the server info */
394 /* register_existing_vuid takes ownership of session_key on success,
395 * no need to free after this on success. A better interface would copy
398 sess_vuid = register_existing_vuid(sconn, sess_vuid,
399 session_info, nullblob, user);
401 reply_outbuf(req, 4, 0);
402 SSVAL(req->outbuf,smb_uid,sess_vuid);
404 if (sess_vuid == UID_FIELD_INVALID ) {
405 ret = NT_STATUS_LOGON_FAILURE;
407 /* current_user_info is changed on new vuid */
408 reload_services(sconn->msg_ctx, sconn->sock, True);
410 SSVAL(req->outbuf, smb_vwv3, 0);
412 if (session_info->guest) {
413 SSVAL(req->outbuf,smb_vwv2,1);
416 SSVAL(req->outbuf, smb_uid, sess_vuid);
418 /* Successful logon. Keep this vuid. */
419 *p_invalidate_vuid = False;
422 /* wrap that up in a nice GSS-API wrapping */
423 if (NT_STATUS_IS_OK(ret)) {
424 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
427 ap_rep_wrapped = data_blob_null;
429 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
431 reply_sesssetup_blob(req, response, ret);
433 data_blob_free(&ap_rep);
434 data_blob_free(&ap_rep_wrapped);
435 data_blob_free(&response);
436 TALLOC_FREE(mem_ctx);
441 /****************************************************************************
442 Send a session setup reply, wrapped in SPNEGO.
443 Get vuid and check first.
444 End the NTLMSSP exchange context if we are OK/complete fail
445 This should be split into two functions, one to handle each
446 leg of the NTLM auth steps.
447 ***************************************************************************/
449 static void reply_spnego_ntlmssp(struct smb_request *req,
451 struct auth_ntlmssp_state **auth_ntlmssp_state,
452 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
456 bool do_invalidate = true;
458 struct auth_serversupplied_info *session_info = NULL;
459 struct smbd_server_connection *sconn = req->sconn;
461 if (NT_STATUS_IS_OK(nt_status)) {
462 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
463 (*auth_ntlmssp_state), &session_info);
465 /* Note that this session_info won't have a session
466 * key. But for map to guest, that's exactly the right
467 * thing - we can't reasonably guess the key the
468 * client wants, as the password was wrong */
469 nt_status = do_map_to_guest(nt_status,
471 auth_ntlmssp_get_username(*auth_ntlmssp_state),
472 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
475 reply_outbuf(req, 4, 0);
477 SSVAL(req->outbuf, smb_uid, vuid);
479 if (NT_STATUS_IS_OK(nt_status)) {
480 DATA_BLOB nullblob = data_blob_null;
482 if (!is_partial_auth_vuid(sconn, vuid)) {
483 nt_status = NT_STATUS_LOGON_FAILURE;
487 /* register_existing_vuid keeps the server info */
488 if (register_existing_vuid(sconn, vuid,
489 session_info, nullblob,
490 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
492 /* The problem is, *auth_ntlmssp_state points
493 * into the vuser this will have
494 * talloc_free()'ed in
495 * register_existing_vuid() */
496 do_invalidate = false;
497 nt_status = NT_STATUS_LOGON_FAILURE;
501 /* current_user_info is changed on new vuid */
502 reload_services(sconn->msg_ctx, sconn->sock, True);
504 SSVAL(req->outbuf, smb_vwv3, 0);
506 if (session_info->guest) {
507 SSVAL(req->outbuf,smb_vwv2,1);
514 response = spnego_gen_auth_response(talloc_tos(),
518 response = *ntlmssp_blob;
521 reply_sesssetup_blob(req, response, nt_status);
523 data_blob_free(&response);
526 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
527 and the other end, that we are not finished yet. */
529 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
530 /* NB. This is *NOT* an error case. JRA */
532 TALLOC_FREE(*auth_ntlmssp_state);
533 if (!NT_STATUS_IS_OK(nt_status)) {
534 /* Kill the intermediate vuid */
535 invalidate_vuid(sconn, vuid);
541 /****************************************************************************
542 Is this a krb5 mechanism ?
543 ****************************************************************************/
545 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
547 DATA_BLOB *pblob_out,
550 char *OIDs[ASN1_MAX_OIDS];
552 NTSTATUS ret = NT_STATUS_OK;
554 *kerb_mechOID = NULL;
556 /* parse out the OIDs and the first sec blob */
557 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
559 return NT_STATUS_LOGON_FAILURE;
562 /* only look at the first OID for determining the mechToken --
563 according to RFC2478, we should choose the one we want
564 and renegotiate, but i smell a client bug here..
566 Problem observed when connecting to a member (samba box)
567 of an AD domain as a user in a Samba domain. Samba member
568 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
569 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
570 NTLMSSP mechtoken. --jerry */
573 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
574 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
575 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
576 if (*kerb_mechOID == NULL) {
577 ret = NT_STATUS_NO_MEMORY;
582 for (i=0;OIDs[i];i++) {
583 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
584 talloc_free(OIDs[i]);
589 /****************************************************************************
590 Fall back from krb5 to NTLMSSP.
591 ****************************************************************************/
593 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
598 reply_outbuf(req, 4, 0);
599 SSVAL(req->outbuf,smb_uid,vuid);
601 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
602 "but set to downgrade to NTLMSSP\n"));
604 response = spnego_gen_auth_response(talloc_tos(), NULL,
605 NT_STATUS_MORE_PROCESSING_REQUIRED,
607 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
608 data_blob_free(&response);
611 /****************************************************************************
612 Reply to a session setup spnego negotiate packet.
613 ****************************************************************************/
615 static void reply_spnego_negotiate(struct smb_request *req,
618 struct auth_ntlmssp_state **auth_ntlmssp_state)
622 char *kerb_mech = NULL;
624 struct smbd_server_connection *sconn = req->sconn;
626 status = parse_spnego_mechanisms(talloc_tos(),
627 blob1, &secblob, &kerb_mech);
628 if (!NT_STATUS_IS_OK(status)) {
629 /* Kill the intermediate vuid */
630 invalidate_vuid(sconn, vuid);
631 reply_nterror(req, nt_status_squash(status));
635 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
636 (unsigned long)secblob.length));
639 if (kerb_mech && ((lp_security()==SEC_ADS) ||
640 USE_KERBEROS_KEYTAB) ) {
641 bool destroy_vuid = True;
642 reply_spnego_kerberos(req, &secblob, kerb_mech,
643 vuid, &destroy_vuid);
644 data_blob_free(&secblob);
646 /* Kill the intermediate vuid */
647 invalidate_vuid(sconn, vuid);
649 TALLOC_FREE(kerb_mech);
654 TALLOC_FREE(*auth_ntlmssp_state);
657 data_blob_free(&secblob);
658 /* The mechtoken is a krb5 ticket, but
659 * we need to fall back to NTLM. */
660 reply_spnego_downgrade_to_ntlmssp(req, vuid);
661 TALLOC_FREE(kerb_mech);
665 status = auth_ntlmssp_start(sconn->remote_address,
667 if (!NT_STATUS_IS_OK(status)) {
668 /* Kill the intermediate vuid */
669 invalidate_vuid(sconn, vuid);
670 reply_nterror(req, nt_status_squash(status));
674 status = auth_ntlmssp_update(*auth_ntlmssp_state,
677 data_blob_free(&secblob);
679 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
680 &chal, status, OID_NTLMSSP, true);
682 data_blob_free(&chal);
684 /* already replied */
688 /****************************************************************************
689 Reply to a session setup spnego auth packet.
690 ****************************************************************************/
692 static void reply_spnego_auth(struct smb_request *req,
695 struct auth_ntlmssp_state **auth_ntlmssp_state)
697 DATA_BLOB auth = data_blob_null;
698 DATA_BLOB auth_reply = data_blob_null;
699 DATA_BLOB secblob = data_blob_null;
700 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
701 struct smbd_server_connection *sconn = req->sconn;
703 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
705 file_save("auth.dat", blob1.data, blob1.length);
707 /* Kill the intermediate vuid */
708 invalidate_vuid(sconn, vuid);
710 reply_nterror(req, nt_status_squash(
711 NT_STATUS_LOGON_FAILURE));
715 if (auth.data[0] == ASN1_APPLICATION(0)) {
716 /* Might be a second negTokenTarg packet */
717 char *kerb_mech = NULL;
719 status = parse_spnego_mechanisms(talloc_tos(),
720 auth, &secblob, &kerb_mech);
722 if (!NT_STATUS_IS_OK(status)) {
723 /* Kill the intermediate vuid */
724 invalidate_vuid(sconn, vuid);
725 reply_nterror(req, nt_status_squash(status));
729 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
730 (unsigned long)secblob.length));
732 if (kerb_mech && ((lp_security()==SEC_ADS) ||
733 USE_KERBEROS_KEYTAB)) {
734 bool destroy_vuid = True;
735 reply_spnego_kerberos(req, &secblob, kerb_mech,
736 vuid, &destroy_vuid);
737 data_blob_free(&secblob);
738 data_blob_free(&auth);
740 /* Kill the intermediate vuid */
741 invalidate_vuid(sconn, vuid);
743 TALLOC_FREE(kerb_mech);
747 /* Can't blunder into NTLMSSP auth if we have
751 /* Kill the intermediate vuid */
752 invalidate_vuid(sconn, vuid);
753 DEBUG(3,("reply_spnego_auth: network "
754 "misconfiguration, client sent us a "
755 "krb5 ticket and kerberos security "
757 reply_nterror(req, nt_status_squash(
758 NT_STATUS_LOGON_FAILURE));
759 TALLOC_FREE(kerb_mech);
763 /* If we get here it wasn't a negTokenTarg auth packet. */
764 data_blob_free(&secblob);
766 if (!*auth_ntlmssp_state) {
767 status = auth_ntlmssp_start(sconn->remote_address,
769 if (!NT_STATUS_IS_OK(status)) {
770 /* Kill the intermediate vuid */
771 invalidate_vuid(sconn, vuid);
772 reply_nterror(req, nt_status_squash(status));
777 status = auth_ntlmssp_update(*auth_ntlmssp_state,
780 data_blob_free(&auth);
782 /* Don't send the mechid as we've already sent this (RFC4178). */
784 reply_spnego_ntlmssp(req, vuid,
786 &auth_reply, status, NULL, true);
788 data_blob_free(&auth_reply);
790 /* and tell smbd that we have already replied to this packet */
794 /****************************************************************************
795 Delete an entry on the list.
796 ****************************************************************************/
798 static void delete_partial_auth(struct smbd_server_connection *sconn,
799 struct pending_auth_data *pad)
804 DLIST_REMOVE(sconn->smb1.pd_list, pad);
805 data_blob_free(&pad->partial_data);
809 /****************************************************************************
810 Search for a partial SPNEGO auth fragment matching an smbpid.
811 ****************************************************************************/
813 static struct pending_auth_data *get_pending_auth_data(
814 struct smbd_server_connection *sconn,
817 struct pending_auth_data *pad;
819 * NOTE: using the smbpid here is completely wrong...
821 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
823 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
824 if (pad->smbpid == smbpid) {
831 /****************************************************************************
832 Check the size of an SPNEGO blob. If we need more return
833 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
834 the blob to be more than 64k.
835 ****************************************************************************/
837 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
838 uint16 smbpid, uint16 vuid,
841 struct pending_auth_data *pad = NULL;
843 size_t needed_len = 0;
845 pad = get_pending_auth_data(sconn, smbpid);
847 /* Ensure we have some data. */
848 if (pblob->length == 0) {
849 /* Caller can cope. */
850 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
851 delete_partial_auth(sconn, pad);
855 /* Were we waiting for more data ? */
858 size_t copy_len = MIN(65536, pblob->length);
860 /* Integer wrap paranoia.... */
862 if (pad->partial_data.length + copy_len <
863 pad->partial_data.length ||
864 pad->partial_data.length + copy_len < copy_len) {
866 DEBUG(2,("check_spnego_blob_complete: integer wrap "
867 "pad->partial_data.length = %u, "
869 (unsigned int)pad->partial_data.length,
870 (unsigned int)copy_len ));
872 delete_partial_auth(sconn, pad);
873 return NT_STATUS_INVALID_PARAMETER;
876 DEBUG(10,("check_spnego_blob_complete: "
877 "pad->partial_data.length = %u, "
878 "pad->needed_len = %u, "
880 "pblob->length = %u,\n",
881 (unsigned int)pad->partial_data.length,
882 (unsigned int)pad->needed_len,
883 (unsigned int)copy_len,
884 (unsigned int)pblob->length ));
886 tmp_blob = data_blob(NULL,
887 pad->partial_data.length + copy_len);
889 /* Concatenate the two (up to copy_len) bytes. */
890 memcpy(tmp_blob.data,
891 pad->partial_data.data,
892 pad->partial_data.length);
893 memcpy(tmp_blob.data + pad->partial_data.length,
897 /* Replace the partial data. */
898 data_blob_free(&pad->partial_data);
899 pad->partial_data = tmp_blob;
900 ZERO_STRUCT(tmp_blob);
903 if (pblob->length >= pad->needed_len) {
904 /* Yes, replace pblob. */
905 data_blob_free(pblob);
906 *pblob = pad->partial_data;
907 ZERO_STRUCT(pad->partial_data);
908 delete_partial_auth(sconn, pad);
912 /* Still need more data. */
913 pad->needed_len -= copy_len;
914 return NT_STATUS_MORE_PROCESSING_REQUIRED;
917 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
918 (pblob->data[0] != ASN1_CONTEXT(1))) {
919 /* Not something we can determine the
925 /* This is a new SPNEGO sessionsetup - see if
926 * the data given in this blob is enough.
929 data = asn1_init(NULL);
931 return NT_STATUS_NO_MEMORY;
934 asn1_load(data, *pblob);
935 if (asn1_start_tag(data, pblob->data[0])) {
936 /* asn1_start_tag checks if the given
937 length of the blob is enough to complete
938 the tag. If it returns true we know
939 there is nothing to do - the blob is
945 if (data->nesting == NULL) {
946 /* Incorrect tag, allocation failed,
947 or reading the tag length failed.
948 Let the caller catch. */
953 /* Here we know asn1_start_tag() has set data->has_error to true.
954 asn1_tag_remaining() will have failed due to the given blob
955 being too short. We need to work out how short. */
957 /* Integer wrap paranoia.... */
959 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
960 data->nesting->taglen + data->nesting->start < data->nesting->start) {
962 DEBUG(2,("check_spnego_blob_complete: integer wrap "
963 "data.nesting->taglen = %u, "
964 "data.nesting->start = %u\n",
965 (unsigned int)data->nesting->taglen,
966 (unsigned int)data->nesting->start ));
969 return NT_STATUS_INVALID_PARAMETER;
972 /* Total length of the needed asn1 is the tag length
973 * plus the current offset. */
975 needed_len = data->nesting->taglen + data->nesting->start;
978 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
979 "pblob->length = %u\n",
980 (unsigned int)needed_len,
981 (unsigned int)pblob->length ));
983 if (needed_len <= pblob->length) {
984 /* Nothing to do - blob is complete. */
985 /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
986 above should have caught this !!! */
987 DEBUG(0,("check_spnego_blob_complete: logic "
988 "error (needed_len = %u, "
989 "pblob->length = %u).\n",
990 (unsigned int)needed_len,
991 (unsigned int)pblob->length ));
995 /* Refuse the blob if it's bigger than 64k. */
996 if (needed_len > 65536) {
997 DEBUG(2,("check_spnego_blob_complete: needed_len "
999 (unsigned int)needed_len ));
1000 return NT_STATUS_INVALID_PARAMETER;
1003 /* We must store this blob until complete. */
1004 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1005 return NT_STATUS_NO_MEMORY;
1007 pad->needed_len = needed_len - pblob->length;
1008 pad->partial_data = data_blob(pblob->data, pblob->length);
1009 if (pad->partial_data.data == NULL) {
1011 return NT_STATUS_NO_MEMORY;
1013 pad->smbpid = smbpid;
1015 DLIST_ADD(sconn->smb1.pd_list, pad);
1017 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1020 /****************************************************************************
1021 Reply to a session setup command.
1022 conn POINTER CAN BE NULL HERE !
1023 ****************************************************************************/
1025 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1031 const char *native_os;
1032 const char *native_lanman;
1033 const char *primary_domain;
1035 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1036 enum remote_arch_types ra_type = get_remote_arch();
1037 int vuid = req->vuid;
1038 user_struct *vuser = NULL;
1039 NTSTATUS status = NT_STATUS_OK;
1040 uint16 smbpid = req->smbpid;
1041 struct smbd_server_connection *sconn = req->sconn;
1043 DEBUG(3,("Doing spnego session setup\n"));
1045 if (global_client_caps == 0) {
1046 global_client_caps = IVAL(req->vwv+10, 0);
1048 if (!(global_client_caps & CAP_STATUS32)) {
1049 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1056 if (data_blob_len == 0) {
1057 /* an invalid request */
1058 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1062 bufrem = smbreq_bufrem(req, p);
1063 /* pull the spnego blob */
1064 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1067 file_save("negotiate.dat", blob1.data, blob1.length);
1070 p2 = (const char *)req->buf + blob1.length;
1072 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1074 native_os = tmp ? tmp : "";
1076 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1078 native_lanman = tmp ? tmp : "";
1080 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1082 primary_domain = tmp ? tmp : "";
1084 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1085 native_os, native_lanman, primary_domain));
1087 if ( ra_type == RA_WIN2K ) {
1088 /* Vista sets neither the OS or lanman strings */
1090 if ( !strlen(native_os) && !strlen(native_lanman) )
1091 set_remote_arch(RA_VISTA);
1093 /* Windows 2003 doesn't set the native lanman string,
1094 but does set primary domain which is a bug I think */
1096 if ( !strlen(native_lanman) ) {
1097 ra_lanman_string( primary_domain );
1099 ra_lanman_string( native_lanman );
1101 } else if ( ra_type == RA_VISTA ) {
1102 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1103 set_remote_arch(RA_OSX);
1107 /* Did we get a valid vuid ? */
1108 if (!is_partial_auth_vuid(sconn, vuid)) {
1109 /* No, then try and see if this is an intermediate sessionsetup
1110 * for a large SPNEGO packet. */
1111 struct pending_auth_data *pad;
1112 pad = get_pending_auth_data(sconn, smbpid);
1114 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1115 "pending vuid %u\n",
1116 (unsigned int)pad->vuid ));
1121 /* Do we have a valid vuid now ? */
1122 if (!is_partial_auth_vuid(sconn, vuid)) {
1123 /* No, start a new authentication setup. */
1124 vuid = register_initial_vuid(sconn);
1125 if (vuid == UID_FIELD_INVALID) {
1126 data_blob_free(&blob1);
1127 reply_nterror(req, nt_status_squash(
1128 NT_STATUS_INVALID_PARAMETER));
1133 vuser = get_partial_auth_user_struct(sconn, vuid);
1134 /* This MUST be valid. */
1136 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1139 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1140 * sessionsetup requests as the Windows limit on the security blob
1141 * field is 4k. Bug #4400. JRA.
1144 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1145 if (!NT_STATUS_IS_OK(status)) {
1146 if (!NT_STATUS_EQUAL(status,
1147 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1148 /* Real error - kill the intermediate vuid */
1149 invalidate_vuid(sconn, vuid);
1151 data_blob_free(&blob1);
1152 reply_nterror(req, nt_status_squash(status));
1156 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1158 /* its a negTokenTarg packet */
1160 reply_spnego_negotiate(req, vuid, blob1,
1161 &vuser->auth_ntlmssp_state);
1162 data_blob_free(&blob1);
1166 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1168 /* its a auth packet */
1170 reply_spnego_auth(req, vuid, blob1,
1171 &vuser->auth_ntlmssp_state);
1172 data_blob_free(&blob1);
1176 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1179 if (!vuser->auth_ntlmssp_state) {
1180 status = auth_ntlmssp_start(sconn->remote_address,
1181 &vuser->auth_ntlmssp_state);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 /* Kill the intermediate vuid */
1184 invalidate_vuid(sconn, vuid);
1185 data_blob_free(&blob1);
1186 reply_nterror(req, nt_status_squash(status));
1191 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1194 data_blob_free(&blob1);
1196 reply_spnego_ntlmssp(req, vuid,
1197 &vuser->auth_ntlmssp_state,
1198 &chal, status, OID_NTLMSSP, false);
1199 data_blob_free(&chal);
1203 /* what sort of packet is this? */
1204 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1206 data_blob_free(&blob1);
1208 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1211 /****************************************************************************
1212 On new VC == 0, shutdown *all* old connections and users.
1213 It seems that only NT4.x does this. At W2K and above (XP etc.).
1214 a new session setup with VC==0 is ignored.
1215 ****************************************************************************/
1217 struct shutdown_state {
1219 struct messaging_context *msg_ctx;
1222 static int shutdown_other_smbds(const struct connections_key *key,
1223 const struct connections_data *crec,
1226 struct shutdown_state *state = (struct shutdown_state *)private_data;
1228 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1229 server_id_str(talloc_tos(), &crec->pid), crec->addr));
1231 if (!process_exists(crec->pid)) {
1232 DEBUG(10, ("process does not exist\n"));
1236 if (procid_is_me(&crec->pid)) {
1237 DEBUG(10, ("It's me\n"));
1241 if (strcmp(state->ip, crec->addr) != 0) {
1242 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1246 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1247 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1250 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1255 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1257 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1258 "compatible we would close all old resources.\n"));
1261 invalidate_all_vuids();
1263 if (lp_reset_on_zero_vc()) {
1265 struct shutdown_state state;
1267 addr = tsocket_address_inet_addr_string(
1268 sconn->remote_address, talloc_tos());
1273 state.msg_ctx = sconn->msg_ctx;
1274 connections_forall_read(shutdown_other_smbds, &state);
1279 /****************************************************************************
1280 Reply to a session setup command.
1281 ****************************************************************************/
1283 void reply_sesssetup_and_X(struct smb_request *req)
1289 DATA_BLOB plaintext_password;
1292 fstring sub_user; /* Sanitised username for substituion */
1294 const char *native_os;
1295 const char *native_lanman;
1296 const char *primary_domain;
1297 struct auth_usersupplied_info *user_info = NULL;
1298 struct auth_serversupplied_info *server_info = NULL;
1299 struct auth_serversupplied_info *session_info = NULL;
1300 uint16 smb_flag2 = req->flags2;
1303 struct smbd_server_connection *sconn = req->sconn;
1305 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1307 START_PROFILE(SMBsesssetupX);
1309 ZERO_STRUCT(lm_resp);
1310 ZERO_STRUCT(nt_resp);
1311 ZERO_STRUCT(plaintext_password);
1313 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1315 /* a SPNEGO session setup has 12 command words, whereas a normal
1316 NT1 session setup has 13. See the cifs spec. */
1317 if (req->wct == 12 &&
1318 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1320 if (!sconn->smb1.negprot.spnego) {
1321 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1322 "at SPNEGO session setup when it was not "
1324 reply_nterror(req, nt_status_squash(
1325 NT_STATUS_LOGON_FAILURE));
1326 END_PROFILE(SMBsesssetupX);
1330 if (SVAL(req->vwv+4, 0) == 0) {
1331 setup_new_vc_session(req->sconn);
1334 reply_sesssetup_and_X_spnego(req);
1335 END_PROFILE(SMBsesssetupX);
1339 smb_bufsize = SVAL(req->vwv+2, 0);
1341 if (get_Protocol() < PROTOCOL_NT1) {
1342 uint16 passlen1 = SVAL(req->vwv+7, 0);
1344 /* Never do NT status codes with protocols before NT1 as we
1345 * don't get client caps. */
1346 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1348 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1349 reply_nterror(req, nt_status_squash(
1350 NT_STATUS_INVALID_PARAMETER));
1351 END_PROFILE(SMBsesssetupX);
1356 lm_resp = data_blob(req->buf, passlen1);
1358 plaintext_password = data_blob(req->buf, passlen1+1);
1359 /* Ensure null termination */
1360 plaintext_password.data[passlen1] = 0;
1363 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1364 req->buf + passlen1, STR_TERMINATE);
1365 user = tmp ? tmp : "";
1370 uint16 passlen1 = SVAL(req->vwv+7, 0);
1371 uint16 passlen2 = SVAL(req->vwv+8, 0);
1372 enum remote_arch_types ra_type = get_remote_arch();
1373 const uint8_t *p = req->buf;
1374 const uint8_t *save_p = req->buf;
1378 if(global_client_caps == 0) {
1379 global_client_caps = IVAL(req->vwv+11, 0);
1381 if (!(global_client_caps & CAP_STATUS32)) {
1382 remove_from_common_flags2(
1383 FLAGS2_32_BIT_ERROR_CODES);
1386 /* client_caps is used as final determination if
1387 * client is NT or Win95. This is needed to return
1388 * the correct error codes in some circumstances.
1391 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1392 ra_type == RA_WIN95) {
1393 if(!(global_client_caps & (CAP_NT_SMBS|
1395 set_remote_arch( RA_WIN95);
1401 /* both Win95 and WinNT stuff up the password
1402 * lengths for non-encrypting systems. Uggh.
1404 if passlen1==24 its a win95 system, and its setting
1405 the password length incorrectly. Luckily it still
1406 works with the default code because Win95 will null
1407 terminate the password anyway
1409 if passlen1>0 and passlen2>0 then maybe its a NT box
1410 and its setting passlen2 to some random value which
1411 really stuffs things up. we need to fix that one. */
1413 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1419 /* check for nasty tricks */
1420 if (passlen1 > MAX_PASS_LEN
1421 || passlen1 > smbreq_bufrem(req, p)) {
1422 reply_nterror(req, nt_status_squash(
1423 NT_STATUS_INVALID_PARAMETER));
1424 END_PROFILE(SMBsesssetupX);
1428 if (passlen2 > MAX_PASS_LEN
1429 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1430 reply_nterror(req, nt_status_squash(
1431 NT_STATUS_INVALID_PARAMETER));
1432 END_PROFILE(SMBsesssetupX);
1436 /* Save the lanman2 password and the NT md4 password. */
1438 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1443 lm_resp = data_blob(p, passlen1);
1444 nt_resp = data_blob(p+passlen1, passlen2);
1445 } else if (lp_security() != SEC_SHARE) {
1447 * In share level we should ignore any passwords, so
1448 * only read them if we're not.
1451 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1453 if (unic && (passlen2 == 0) && passlen1) {
1454 /* Only a ascii plaintext password was sent. */
1455 (void)srvstr_pull_talloc(talloc_tos(),
1461 STR_TERMINATE|STR_ASCII);
1463 (void)srvstr_pull_talloc(talloc_tos(),
1468 unic ? passlen2 : passlen1,
1472 reply_nterror(req, nt_status_squash(
1473 NT_STATUS_INVALID_PARAMETER));
1474 END_PROFILE(SMBsesssetupX);
1477 plaintext_password = data_blob(pass, strlen(pass)+1);
1480 p += passlen1 + passlen2;
1482 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1484 user = tmp ? tmp : "";
1486 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1488 domain = tmp ? tmp : "";
1490 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1492 native_os = tmp ? tmp : "";
1494 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1496 native_lanman = tmp ? tmp : "";
1498 /* not documented or decoded by Ethereal but there is one more
1499 * string in the extra bytes which is the same as the
1500 * PrimaryDomain when using extended security. Windows NT 4
1501 * and 2003 use this string to store the native lanman string.
1502 * Windows 9x does not include a string here at all so we have
1503 * to check if we have any extra bytes left */
1505 byte_count = SVAL(req->vwv+13, 0);
1506 if ( PTR_DIFF(p, save_p) < byte_count) {
1507 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1509 primary_domain = tmp ? tmp : "";
1511 primary_domain = talloc_strdup(talloc_tos(), "null");
1514 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1515 "PrimaryDomain=[%s]\n",
1516 domain, native_os, native_lanman, primary_domain));
1518 if ( ra_type == RA_WIN2K ) {
1519 if ( strlen(native_lanman) == 0 )
1520 ra_lanman_string( primary_domain );
1522 ra_lanman_string( native_lanman );
1527 if (SVAL(req->vwv+4, 0) == 0) {
1528 setup_new_vc_session(req->sconn);
1531 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1532 domain, user, get_remote_machine_name()));
1535 if (sconn->smb1.negprot.spnego) {
1537 /* This has to be here, because this is a perfectly
1538 * valid behaviour for guest logons :-( */
1540 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1541 "at 'normal' session setup after "
1542 "negotiating spnego.\n"));
1543 reply_nterror(req, nt_status_squash(
1544 NT_STATUS_LOGON_FAILURE));
1545 END_PROFILE(SMBsesssetupX);
1548 fstrcpy(sub_user, user);
1550 fstrcpy(sub_user, lp_guestaccount());
1553 sub_set_smb_name(sub_user);
1555 reload_services(sconn->msg_ctx, sconn->sock, True);
1557 if (lp_security() == SEC_SHARE) {
1558 char *sub_user_mapped = NULL;
1559 /* In share level we should ignore any passwords */
1561 data_blob_free(&lm_resp);
1562 data_blob_free(&nt_resp);
1563 data_blob_clear_free(&plaintext_password);
1565 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1566 if (!sub_user_mapped) {
1567 reply_nterror(req, NT_STATUS_NO_MEMORY);
1568 END_PROFILE(SMBsesssetupX);
1571 fstrcpy(sub_user, sub_user_mapped);
1572 add_session_user(sconn, sub_user);
1573 add_session_workgroup(sconn, domain);
1574 /* Then force it to null for the benfit of the code below */
1580 nt_status = check_guest_password(&server_info);
1582 } else if (doencrypt) {
1583 struct auth_context *negprot_auth_context = NULL;
1584 negprot_auth_context = sconn->smb1.negprot.auth_context;
1585 if (!negprot_auth_context) {
1586 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1587 "session setup without negprot denied!\n"));
1588 reply_nterror(req, nt_status_squash(
1589 NT_STATUS_LOGON_FAILURE));
1590 END_PROFILE(SMBsesssetupX);
1593 nt_status = make_user_info_for_reply_enc(&user_info, user,
1596 if (NT_STATUS_IS_OK(nt_status)) {
1597 nt_status = negprot_auth_context->check_ntlm_password(
1598 negprot_auth_context,
1603 struct auth_context *plaintext_auth_context = NULL;
1605 nt_status = make_auth_context_subsystem(
1606 talloc_tos(), &plaintext_auth_context);
1608 if (NT_STATUS_IS_OK(nt_status)) {
1611 plaintext_auth_context->get_ntlm_challenge(
1612 plaintext_auth_context, chal);
1614 if (!make_user_info_for_reply(&user_info,
1616 plaintext_password)) {
1617 nt_status = NT_STATUS_NO_MEMORY;
1620 if (NT_STATUS_IS_OK(nt_status)) {
1621 nt_status = plaintext_auth_context->check_ntlm_password(
1622 plaintext_auth_context,
1626 TALLOC_FREE(plaintext_auth_context);
1631 free_user_info(&user_info);
1633 if (!NT_STATUS_IS_OK(nt_status)) {
1634 nt_status = do_map_to_guest(nt_status, &server_info,
1638 if (!NT_STATUS_IS_OK(nt_status)) {
1639 data_blob_free(&nt_resp);
1640 data_blob_free(&lm_resp);
1641 data_blob_clear_free(&plaintext_password);
1642 reply_nterror(req, nt_status_squash(nt_status));
1643 END_PROFILE(SMBsesssetupX);
1647 nt_status = create_local_token(req, server_info, NULL, &session_info);
1648 TALLOC_FREE(server_info);
1650 if (!NT_STATUS_IS_OK(nt_status)) {
1651 DEBUG(10, ("create_local_token failed: %s\n",
1652 nt_errstr(nt_status)));
1653 data_blob_free(&nt_resp);
1654 data_blob_free(&lm_resp);
1655 data_blob_clear_free(&plaintext_password);
1656 reply_nterror(req, nt_status_squash(nt_status));
1657 END_PROFILE(SMBsesssetupX);
1661 data_blob_clear_free(&plaintext_password);
1663 /* it's ok - setup a reply */
1664 reply_outbuf(req, 3, 0);
1665 if (get_Protocol() >= PROTOCOL_NT1) {
1666 push_signature(&req->outbuf);
1667 /* perhaps grab OS version here?? */
1670 if (session_info->guest) {
1671 SSVAL(req->outbuf,smb_vwv2,1);
1674 /* register the name and uid as being validated, so further connections
1675 to a uid can get through without a password, on the same VC */
1677 if (lp_security() == SEC_SHARE) {
1678 sess_vuid = UID_FIELD_INVALID;
1679 TALLOC_FREE(session_info);
1681 /* Ignore the initial vuid. */
1682 sess_vuid = register_initial_vuid(sconn);
1683 if (sess_vuid == UID_FIELD_INVALID) {
1684 data_blob_free(&nt_resp);
1685 data_blob_free(&lm_resp);
1686 reply_nterror(req, nt_status_squash(
1687 NT_STATUS_LOGON_FAILURE));
1688 END_PROFILE(SMBsesssetupX);
1691 /* register_existing_vuid keeps the session_info */
1692 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1694 nt_resp.data ? nt_resp : lm_resp,
1696 if (sess_vuid == UID_FIELD_INVALID) {
1697 data_blob_free(&nt_resp);
1698 data_blob_free(&lm_resp);
1699 reply_nterror(req, nt_status_squash(
1700 NT_STATUS_LOGON_FAILURE));
1701 END_PROFILE(SMBsesssetupX);
1705 /* current_user_info is changed on new vuid */
1706 reload_services(sconn->msg_ctx, sconn->sock, True);
1709 data_blob_free(&nt_resp);
1710 data_blob_free(&lm_resp);
1712 SSVAL(req->outbuf,smb_uid,sess_vuid);
1713 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1714 req->vuid = sess_vuid;
1716 if (!sconn->smb1.sessions.done_sesssetup) {
1717 sconn->smb1.sessions.max_send =
1718 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1720 sconn->smb1.sessions.done_sesssetup = true;
1722 END_PROFILE(SMBsesssetupX);