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 "smbd/globals.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "librpc/gen_ndr/messaging.h"
31 #include "../librpc/gen_ndr/krb5pac.h"
32 #include "libads/kerberos_proto.h"
34 /* For split krb5 SPNEGO blobs. */
35 struct pending_auth_data {
36 struct pending_auth_data *prev, *next;
37 uint16 vuid; /* Tag for this entry. */
38 uint16 smbpid; /* Alternate tag for this entry. */
40 DATA_BLOB partial_data;
44 on a logon error possibly map the error to success if "map to guest"
47 NTSTATUS do_map_to_guest(NTSTATUS status,
48 struct auth_serversupplied_info **server_info,
49 const char *user, const char *domain)
51 user = user ? user : "";
52 domain = domain ? domain : "";
54 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
55 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
56 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
57 DEBUG(3,("No such user %s [%s] - using guest account\n",
59 status = make_server_info_guest(NULL, server_info);
63 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
64 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
65 DEBUG(3,("Registered username %s for guest access\n",
67 status = make_server_info_guest(NULL, server_info);
74 /****************************************************************************
75 Add the standard 'Samba' signature to the end of the session setup.
76 ****************************************************************************/
78 static int push_signature(uint8 **outbuf)
85 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
87 if (tmp == -1) return -1;
90 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
91 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
95 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
98 if (tmp == -1) return -1;
101 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
103 if (tmp == -1) return -1;
109 /****************************************************************************
110 Send a security blob via a session setup reply.
111 ****************************************************************************/
113 static void reply_sesssetup_blob(struct smb_request *req,
117 if (!NT_STATUS_IS_OK(nt_status) &&
118 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
119 reply_nterror(req, nt_status_squash(nt_status));
123 nt_status = nt_status_squash(nt_status);
124 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
125 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
126 SSVAL(req->outbuf, smb_vwv3, blob.length);
128 if ((message_push_blob(&req->outbuf, blob) == -1)
129 || (push_signature(&req->outbuf) == -1)) {
130 reply_nterror(req, NT_STATUS_NO_MEMORY);
134 /****************************************************************************
135 Do a 'guest' logon, getting back the
136 ****************************************************************************/
138 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
140 struct auth_context *auth_context;
141 struct auth_usersupplied_info *user_info = NULL;
144 unsigned char chal[8];
148 DEBUG(3,("Got anonymous request\n"));
150 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context,
155 if (!make_user_info_guest(&user_info)) {
156 TALLOC_FREE(auth_context);
157 return NT_STATUS_NO_MEMORY;
160 nt_status = auth_context->check_ntlm_password(auth_context,
163 TALLOC_FREE(auth_context);
164 free_user_info(&user_info);
172 /* Experiment that failed. See "only happens with a KDC" comment below. */
173 /****************************************************************************
174 Cerate a clock skew error blob for a Windows client.
175 ****************************************************************************/
177 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
179 krb5_context context = NULL;
180 krb5_error_code kerr = 0;
182 krb5_principal host_princ = NULL;
183 char *host_princ_s = NULL;
186 *pblob_out = data_blob_null;
188 initialize_krb5_error_table();
189 kerr = krb5_init_context(&context);
193 /* Create server principal. */
194 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
198 strlower_m(host_princ_s);
200 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
202 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
203 "for name %s: Error %s\n",
204 host_princ_s, error_message(kerr) ));
208 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
211 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
212 "failed: Error %s\n",
213 error_message(kerr) ));
217 *pblob_out = data_blob(reply.data, reply.length);
218 kerberos_free_data_contents(context,&reply);
224 SAFE_FREE(host_princ_s);
227 krb5_free_principal(context, host_princ);
229 krb5_free_context(context);
234 /****************************************************************************
235 Reply to a session setup spnego negotiate packet for kerberos.
236 ****************************************************************************/
238 static void reply_spnego_kerberos(struct smb_request *req,
242 bool *p_invalidate_vuid)
247 int sess_vuid = req->vuid;
248 NTSTATUS ret = NT_STATUS_OK;
249 DATA_BLOB ap_rep, ap_rep_wrapped, response;
250 struct auth_serversupplied_info *server_info = NULL;
251 DATA_BLOB session_key = data_blob_null;
253 DATA_BLOB nullblob = data_blob_null;
254 bool map_domainuser_to_guest = False;
255 bool username_was_mapped;
256 struct PAC_LOGON_INFO *logon_info = NULL;
257 struct smbd_server_connection *sconn = req->sconn;
265 ZERO_STRUCT(ap_rep_wrapped);
266 ZERO_STRUCT(response);
268 /* Normally we will always invalidate the intermediate vuid. */
269 *p_invalidate_vuid = True;
271 mem_ctx = talloc_init("reply_spnego_kerberos");
272 if (mem_ctx == NULL) {
273 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
277 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
278 talloc_destroy(mem_ctx);
279 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
283 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
284 &principal, &logon_info, &ap_rep,
287 data_blob_free(&ticket);
289 if (!NT_STATUS_IS_OK(ret)) {
291 /* Experiment that failed.
292 * See "only happens with a KDC" comment below. */
294 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
297 * Windows in this case returns
298 * NT_STATUS_MORE_PROCESSING_REQUIRED
299 * with a negTokenTarg blob containing an krb5_error
300 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
301 * The client then fixes its clock and continues rather
302 * than giving an error. JRA.
303 * -- Looks like this only happens with a KDC. JRA.
306 bool ok = make_krb5_skew_error(&ap_rep);
308 talloc_destroy(mem_ctx);
309 return ERROR_NT(nt_status_squash(
310 NT_STATUS_LOGON_FAILURE));
312 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
314 response = spnego_gen_auth_response(&ap_rep_wrapped,
315 ret, OID_KERBEROS5_OLD);
316 reply_sesssetup_blob(conn, inbuf, outbuf, response,
317 NT_STATUS_MORE_PROCESSING_REQUIRED);
320 * In this one case we don't invalidate the
321 * intermediate vuid as we're expecting the client
322 * to re-use it for the next sessionsetupX packet. JRA.
325 *p_invalidate_vuid = False;
327 data_blob_free(&ap_rep);
328 data_blob_free(&ap_rep_wrapped);
329 data_blob_free(&response);
330 talloc_destroy(mem_ctx);
331 return -1; /* already replied */
334 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
335 ret = NT_STATUS_LOGON_FAILURE;
338 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
340 talloc_destroy(mem_ctx);
341 reply_nterror(req, nt_status_squash(ret));
345 ret = get_user_from_kerberos_info(talloc_tos(),
346 sconn->client_id.name,
347 principal, logon_info,
348 &username_was_mapped,
349 &map_domainuser_to_guest,
351 &real_username, &pw);
352 if (!NT_STATUS_IS_OK(ret)) {
353 data_blob_free(&ap_rep);
354 data_blob_free(&session_key);
355 talloc_destroy(mem_ctx);
356 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
360 /* save the PAC data if we have it */
362 netsamlogon_cache_store(user, &logon_info->info3);
365 /* setup the string used by %U */
366 sub_set_smb_name(real_username);
368 /* reload services so that the new %U is taken into account */
369 reload_services(sconn->msg_ctx, sconn->sock, True);
371 ret = make_server_info_krb5(mem_ctx,
372 user, domain, real_username, pw,
373 logon_info, map_domainuser_to_guest,
375 if (!NT_STATUS_IS_OK(ret)) {
376 DEBUG(1, ("make_server_info_krb5 failed!\n"));
377 data_blob_free(&ap_rep);
378 data_blob_free(&session_key);
379 TALLOC_FREE(mem_ctx);
380 reply_nterror(req, nt_status_squash(ret));
384 server_info->nss_token |= username_was_mapped;
386 /* we need to build the token for the user. make_server_info_guest()
389 if ( !server_info->ptok ) {
390 ret = create_local_token( server_info );
391 if ( !NT_STATUS_IS_OK(ret) ) {
392 DEBUG(10,("failed to create local token: %s\n",
394 data_blob_free(&ap_rep);
395 data_blob_free(&session_key);
396 TALLOC_FREE( mem_ctx );
397 TALLOC_FREE( server_info );
398 reply_nterror(req, nt_status_squash(ret));
403 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
404 sess_vuid = register_initial_vuid(sconn);
407 data_blob_free(&server_info->user_session_key);
408 server_info->user_session_key = session_key;
409 talloc_steal(server_info, session_key.data);
411 session_key = data_blob_null;
413 /* register_existing_vuid keeps the server info */
414 /* register_existing_vuid takes ownership of session_key on success,
415 * no need to free after this on success. A better interface would copy
418 sess_vuid = register_existing_vuid(sconn, sess_vuid,
419 server_info, nullblob, user);
421 reply_outbuf(req, 4, 0);
422 SSVAL(req->outbuf,smb_uid,sess_vuid);
424 if (sess_vuid == UID_FIELD_INVALID ) {
425 ret = NT_STATUS_LOGON_FAILURE;
427 /* current_user_info is changed on new vuid */
428 reload_services(sconn->msg_ctx, sconn->sock, True);
430 SSVAL(req->outbuf, smb_vwv3, 0);
432 if (server_info->guest) {
433 SSVAL(req->outbuf,smb_vwv2,1);
436 SSVAL(req->outbuf, smb_uid, sess_vuid);
438 /* Successful logon. Keep this vuid. */
439 *p_invalidate_vuid = False;
442 /* wrap that up in a nice GSS-API wrapping */
443 if (NT_STATUS_IS_OK(ret)) {
444 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
447 ap_rep_wrapped = data_blob_null;
449 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
451 reply_sesssetup_blob(req, response, ret);
453 data_blob_free(&ap_rep);
454 data_blob_free(&ap_rep_wrapped);
455 data_blob_free(&response);
456 TALLOC_FREE(mem_ctx);
461 /****************************************************************************
462 Send a session setup reply, wrapped in SPNEGO.
463 Get vuid and check first.
464 End the NTLMSSP exchange context if we are OK/complete fail
465 This should be split into two functions, one to handle each
466 leg of the NTLM auth steps.
467 ***************************************************************************/
469 static void reply_spnego_ntlmssp(struct smb_request *req,
471 struct auth_ntlmssp_state **auth_ntlmssp_state,
472 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
476 bool do_invalidate = true;
478 struct auth_serversupplied_info *server_info = NULL;
479 struct smbd_server_connection *sconn = req->sconn;
481 if (NT_STATUS_IS_OK(nt_status)) {
482 nt_status = auth_ntlmssp_steal_server_info(talloc_tos(),
483 (*auth_ntlmssp_state), &server_info);
485 /* Note that this server_info won't have a session
486 * key. But for map to guest, that's exactly the right
487 * thing - we can't reasonably guess the key the
488 * client wants, as the password was wrong */
489 nt_status = do_map_to_guest(nt_status,
491 auth_ntlmssp_get_username(*auth_ntlmssp_state),
492 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
495 reply_outbuf(req, 4, 0);
497 SSVAL(req->outbuf, smb_uid, vuid);
499 if (NT_STATUS_IS_OK(nt_status)) {
500 DATA_BLOB nullblob = data_blob_null;
502 if (!is_partial_auth_vuid(sconn, vuid)) {
503 nt_status = NT_STATUS_LOGON_FAILURE;
507 /* register_existing_vuid keeps the server info */
508 if (register_existing_vuid(sconn, vuid,
509 server_info, nullblob,
510 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
512 /* The problem is, *auth_ntlmssp_state points
513 * into the vuser this will have
514 * talloc_free()'ed in
515 * register_existing_vuid() */
516 do_invalidate = false;
517 nt_status = NT_STATUS_LOGON_FAILURE;
521 /* current_user_info is changed on new vuid */
522 reload_services(sconn->msg_ctx, sconn->sock, True);
524 SSVAL(req->outbuf, smb_vwv3, 0);
526 if (server_info->guest) {
527 SSVAL(req->outbuf,smb_vwv2,1);
534 response = spnego_gen_auth_response(talloc_tos(),
538 response = *ntlmssp_blob;
541 reply_sesssetup_blob(req, response, nt_status);
543 data_blob_free(&response);
546 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
547 and the other end, that we are not finished yet. */
549 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
550 /* NB. This is *NOT* an error case. JRA */
552 TALLOC_FREE(*auth_ntlmssp_state);
553 if (!NT_STATUS_IS_OK(nt_status)) {
554 /* Kill the intermediate vuid */
555 invalidate_vuid(sconn, vuid);
561 /****************************************************************************
562 Is this a krb5 mechanism ?
563 ****************************************************************************/
565 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
567 DATA_BLOB *pblob_out,
570 char *OIDs[ASN1_MAX_OIDS];
572 NTSTATUS ret = NT_STATUS_OK;
574 *kerb_mechOID = NULL;
576 /* parse out the OIDs and the first sec blob */
577 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out)) {
578 return NT_STATUS_LOGON_FAILURE;
581 /* only look at the first OID for determining the mechToken --
582 according to RFC2478, we should choose the one we want
583 and renegotiate, but i smell a client bug here..
585 Problem observed when connecting to a member (samba box)
586 of an AD domain as a user in a Samba domain. Samba member
587 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
588 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
589 NTLMSSP mechtoken. --jerry */
592 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
593 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
594 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
595 if (*kerb_mechOID == NULL) {
596 ret = NT_STATUS_NO_MEMORY;
601 for (i=0;OIDs[i];i++) {
602 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
603 talloc_free(OIDs[i]);
608 /****************************************************************************
609 Fall back from krb5 to NTLMSSP.
610 ****************************************************************************/
612 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
617 reply_outbuf(req, 4, 0);
618 SSVAL(req->outbuf,smb_uid,vuid);
620 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
621 "but set to downgrade to NTLMSSP\n"));
623 response = spnego_gen_auth_response(talloc_tos(), NULL,
624 NT_STATUS_MORE_PROCESSING_REQUIRED,
626 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
627 data_blob_free(&response);
630 /****************************************************************************
631 Reply to a session setup spnego negotiate packet.
632 ****************************************************************************/
634 static void reply_spnego_negotiate(struct smb_request *req,
637 struct auth_ntlmssp_state **auth_ntlmssp_state)
641 char *kerb_mech = NULL;
643 struct smbd_server_connection *sconn = req->sconn;
645 status = parse_spnego_mechanisms(talloc_tos(),
646 blob1, &secblob, &kerb_mech);
647 if (!NT_STATUS_IS_OK(status)) {
648 /* Kill the intermediate vuid */
649 invalidate_vuid(sconn, vuid);
650 reply_nterror(req, nt_status_squash(status));
654 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
655 (unsigned long)secblob.length));
658 if (kerb_mech && ((lp_security()==SEC_ADS) ||
659 USE_KERBEROS_KEYTAB) ) {
660 bool destroy_vuid = True;
661 reply_spnego_kerberos(req, &secblob, kerb_mech,
662 vuid, &destroy_vuid);
663 data_blob_free(&secblob);
665 /* Kill the intermediate vuid */
666 invalidate_vuid(sconn, vuid);
668 TALLOC_FREE(kerb_mech);
673 if (*auth_ntlmssp_state) {
674 TALLOC_FREE(*auth_ntlmssp_state);
678 data_blob_free(&secblob);
679 /* The mechtoken is a krb5 ticket, but
680 * we need to fall back to NTLM. */
681 reply_spnego_downgrade_to_ntlmssp(req, vuid);
682 TALLOC_FREE(kerb_mech);
686 status = auth_ntlmssp_start(auth_ntlmssp_state);
687 if (!NT_STATUS_IS_OK(status)) {
688 /* Kill the intermediate vuid */
689 invalidate_vuid(sconn, vuid);
690 reply_nterror(req, nt_status_squash(status));
694 status = auth_ntlmssp_update(*auth_ntlmssp_state,
697 data_blob_free(&secblob);
699 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
700 &chal, status, OID_NTLMSSP, true);
702 data_blob_free(&chal);
704 /* already replied */
708 /****************************************************************************
709 Reply to a session setup spnego auth packet.
710 ****************************************************************************/
712 static void reply_spnego_auth(struct smb_request *req,
715 struct auth_ntlmssp_state **auth_ntlmssp_state)
717 DATA_BLOB auth = data_blob_null;
718 DATA_BLOB auth_reply = data_blob_null;
719 DATA_BLOB secblob = data_blob_null;
720 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
721 struct smbd_server_connection *sconn = req->sconn;
723 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
725 file_save("auth.dat", blob1.data, blob1.length);
727 /* Kill the intermediate vuid */
728 invalidate_vuid(sconn, vuid);
730 reply_nterror(req, nt_status_squash(
731 NT_STATUS_LOGON_FAILURE));
735 if (auth.data[0] == ASN1_APPLICATION(0)) {
736 /* Might be a second negTokenTarg packet */
737 char *kerb_mech = NULL;
739 status = parse_spnego_mechanisms(talloc_tos(),
740 auth, &secblob, &kerb_mech);
742 if (!NT_STATUS_IS_OK(status)) {
743 /* Kill the intermediate vuid */
744 invalidate_vuid(sconn, vuid);
745 reply_nterror(req, nt_status_squash(status));
749 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
750 (unsigned long)secblob.length));
752 if (kerb_mech && ((lp_security()==SEC_ADS) ||
753 USE_KERBEROS_KEYTAB)) {
754 bool destroy_vuid = True;
755 reply_spnego_kerberos(req, &secblob, kerb_mech,
756 vuid, &destroy_vuid);
757 data_blob_free(&secblob);
758 data_blob_free(&auth);
760 /* Kill the intermediate vuid */
761 invalidate_vuid(sconn, vuid);
763 TALLOC_FREE(kerb_mech);
767 /* Can't blunder into NTLMSSP auth if we have
771 /* Kill the intermediate vuid */
772 invalidate_vuid(sconn, vuid);
773 DEBUG(3,("reply_spnego_auth: network "
774 "misconfiguration, client sent us a "
775 "krb5 ticket and kerberos security "
777 reply_nterror(req, nt_status_squash(
778 NT_STATUS_LOGON_FAILURE));
779 TALLOC_FREE(kerb_mech);
783 /* If we get here it wasn't a negTokenTarg auth packet. */
784 data_blob_free(&secblob);
786 if (!*auth_ntlmssp_state) {
787 status = auth_ntlmssp_start(auth_ntlmssp_state);
788 if (!NT_STATUS_IS_OK(status)) {
789 /* Kill the intermediate vuid */
790 invalidate_vuid(sconn, vuid);
791 reply_nterror(req, nt_status_squash(status));
796 status = auth_ntlmssp_update(*auth_ntlmssp_state,
799 data_blob_free(&auth);
801 /* Don't send the mechid as we've already sent this (RFC4178). */
803 reply_spnego_ntlmssp(req, vuid,
805 &auth_reply, status, NULL, true);
807 data_blob_free(&auth_reply);
809 /* and tell smbd that we have already replied to this packet */
813 /****************************************************************************
814 Delete an entry on the list.
815 ****************************************************************************/
817 static void delete_partial_auth(struct smbd_server_connection *sconn,
818 struct pending_auth_data *pad)
823 DLIST_REMOVE(sconn->smb1.pd_list, pad);
824 data_blob_free(&pad->partial_data);
828 /****************************************************************************
829 Search for a partial SPNEGO auth fragment matching an smbpid.
830 ****************************************************************************/
832 static struct pending_auth_data *get_pending_auth_data(
833 struct smbd_server_connection *sconn,
836 struct pending_auth_data *pad;
838 * NOTE: using the smbpid here is completely wrong...
840 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
842 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
843 if (pad->smbpid == smbpid) {
850 /****************************************************************************
851 Check the size of an SPNEGO blob. If we need more return
852 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
853 the blob to be more than 64k.
854 ****************************************************************************/
856 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
857 uint16 smbpid, uint16 vuid,
860 struct pending_auth_data *pad = NULL;
862 size_t needed_len = 0;
864 pad = get_pending_auth_data(sconn, smbpid);
866 /* Ensure we have some data. */
867 if (pblob->length == 0) {
868 /* Caller can cope. */
869 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
870 delete_partial_auth(sconn, pad);
874 /* Were we waiting for more data ? */
877 size_t copy_len = MIN(65536, pblob->length);
879 /* Integer wrap paranoia.... */
881 if (pad->partial_data.length + copy_len <
882 pad->partial_data.length ||
883 pad->partial_data.length + copy_len < copy_len) {
885 DEBUG(2,("check_spnego_blob_complete: integer wrap "
886 "pad->partial_data.length = %u, "
888 (unsigned int)pad->partial_data.length,
889 (unsigned int)copy_len ));
891 delete_partial_auth(sconn, pad);
892 return NT_STATUS_INVALID_PARAMETER;
895 DEBUG(10,("check_spnego_blob_complete: "
896 "pad->partial_data.length = %u, "
897 "pad->needed_len = %u, "
899 "pblob->length = %u,\n",
900 (unsigned int)pad->partial_data.length,
901 (unsigned int)pad->needed_len,
902 (unsigned int)copy_len,
903 (unsigned int)pblob->length ));
905 tmp_blob = data_blob(NULL,
906 pad->partial_data.length + copy_len);
908 /* Concatenate the two (up to copy_len) bytes. */
909 memcpy(tmp_blob.data,
910 pad->partial_data.data,
911 pad->partial_data.length);
912 memcpy(tmp_blob.data + pad->partial_data.length,
916 /* Replace the partial data. */
917 data_blob_free(&pad->partial_data);
918 pad->partial_data = tmp_blob;
919 ZERO_STRUCT(tmp_blob);
922 if (pblob->length >= pad->needed_len) {
923 /* Yes, replace pblob. */
924 data_blob_free(pblob);
925 *pblob = pad->partial_data;
926 ZERO_STRUCT(pad->partial_data);
927 delete_partial_auth(sconn, pad);
931 /* Still need more data. */
932 pad->needed_len -= copy_len;
933 return NT_STATUS_MORE_PROCESSING_REQUIRED;
936 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
937 (pblob->data[0] != ASN1_CONTEXT(1))) {
938 /* Not something we can determine the
944 /* This is a new SPNEGO sessionsetup - see if
945 * the data given in this blob is enough.
948 data = asn1_init(NULL);
950 return NT_STATUS_NO_MEMORY;
953 asn1_load(data, *pblob);
954 asn1_start_tag(data, pblob->data[0]);
955 if (data->has_error || data->nesting == NULL) {
957 /* Let caller catch. */
961 /* Integer wrap paranoia.... */
963 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
964 data->nesting->taglen + data->nesting->start < data->nesting->start) {
966 DEBUG(2,("check_spnego_blob_complete: integer wrap "
967 "data.nesting->taglen = %u, "
968 "data.nesting->start = %u\n",
969 (unsigned int)data->nesting->taglen,
970 (unsigned int)data->nesting->start ));
973 return NT_STATUS_INVALID_PARAMETER;
976 /* Total length of the needed asn1 is the tag length
977 * plus the current offset. */
979 needed_len = data->nesting->taglen + data->nesting->start;
982 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
983 "pblob->length = %u\n",
984 (unsigned int)needed_len,
985 (unsigned int)pblob->length ));
987 if (needed_len <= pblob->length) {
988 /* Nothing to do - blob is complete. */
992 /* Refuse the blob if it's bigger than 64k. */
993 if (needed_len > 65536) {
994 DEBUG(2,("check_spnego_blob_complete: needed_len "
996 (unsigned int)needed_len ));
997 return NT_STATUS_INVALID_PARAMETER;
1000 /* We must store this blob until complete. */
1001 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1002 return NT_STATUS_NO_MEMORY;
1004 pad->needed_len = needed_len - pblob->length;
1005 pad->partial_data = data_blob(pblob->data, pblob->length);
1006 if (pad->partial_data.data == NULL) {
1008 return NT_STATUS_NO_MEMORY;
1010 pad->smbpid = smbpid;
1012 DLIST_ADD(sconn->smb1.pd_list, pad);
1014 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1017 /****************************************************************************
1018 Reply to a session setup command.
1019 conn POINTER CAN BE NULL HERE !
1020 ****************************************************************************/
1022 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1028 const char *native_os;
1029 const char *native_lanman;
1030 const char *primary_domain;
1032 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1033 enum remote_arch_types ra_type = get_remote_arch();
1034 int vuid = req->vuid;
1035 user_struct *vuser = NULL;
1036 NTSTATUS status = NT_STATUS_OK;
1037 uint16 smbpid = req->smbpid;
1038 struct smbd_server_connection *sconn = req->sconn;
1040 DEBUG(3,("Doing spnego session setup\n"));
1042 if (global_client_caps == 0) {
1043 global_client_caps = IVAL(req->vwv+10, 0);
1045 if (!(global_client_caps & CAP_STATUS32)) {
1046 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1053 if (data_blob_len == 0) {
1054 /* an invalid request */
1055 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1059 bufrem = smbreq_bufrem(req, p);
1060 /* pull the spnego blob */
1061 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1064 file_save("negotiate.dat", blob1.data, blob1.length);
1067 p2 = (char *)req->buf + blob1.length;
1069 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1071 native_os = tmp ? tmp : "";
1073 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1075 native_lanman = tmp ? tmp : "";
1077 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1079 primary_domain = tmp ? tmp : "";
1081 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1082 native_os, native_lanman, primary_domain));
1084 if ( ra_type == RA_WIN2K ) {
1085 /* Vista sets neither the OS or lanman strings */
1087 if ( !strlen(native_os) && !strlen(native_lanman) )
1088 set_remote_arch(RA_VISTA);
1090 /* Windows 2003 doesn't set the native lanman string,
1091 but does set primary domain which is a bug I think */
1093 if ( !strlen(native_lanman) ) {
1094 ra_lanman_string( primary_domain );
1096 ra_lanman_string( native_lanman );
1100 /* Did we get a valid vuid ? */
1101 if (!is_partial_auth_vuid(sconn, vuid)) {
1102 /* No, then try and see if this is an intermediate sessionsetup
1103 * for a large SPNEGO packet. */
1104 struct pending_auth_data *pad;
1105 pad = get_pending_auth_data(sconn, smbpid);
1107 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1108 "pending vuid %u\n",
1109 (unsigned int)pad->vuid ));
1114 /* Do we have a valid vuid now ? */
1115 if (!is_partial_auth_vuid(sconn, vuid)) {
1116 /* No, start a new authentication setup. */
1117 vuid = register_initial_vuid(sconn);
1118 if (vuid == UID_FIELD_INVALID) {
1119 data_blob_free(&blob1);
1120 reply_nterror(req, nt_status_squash(
1121 NT_STATUS_INVALID_PARAMETER));
1126 vuser = get_partial_auth_user_struct(sconn, vuid);
1127 /* This MUST be valid. */
1129 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1132 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1133 * sessionsetup requests as the Windows limit on the security blob
1134 * field is 4k. Bug #4400. JRA.
1137 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1138 if (!NT_STATUS_IS_OK(status)) {
1139 if (!NT_STATUS_EQUAL(status,
1140 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1141 /* Real error - kill the intermediate vuid */
1142 invalidate_vuid(sconn, vuid);
1144 data_blob_free(&blob1);
1145 reply_nterror(req, nt_status_squash(status));
1149 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1151 /* its a negTokenTarg packet */
1153 reply_spnego_negotiate(req, vuid, blob1,
1154 &vuser->auth_ntlmssp_state);
1155 data_blob_free(&blob1);
1159 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1161 /* its a auth packet */
1163 reply_spnego_auth(req, vuid, blob1,
1164 &vuser->auth_ntlmssp_state);
1165 data_blob_free(&blob1);
1169 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1172 if (!vuser->auth_ntlmssp_state) {
1173 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1174 if (!NT_STATUS_IS_OK(status)) {
1175 /* Kill the intermediate vuid */
1176 invalidate_vuid(sconn, vuid);
1177 data_blob_free(&blob1);
1178 reply_nterror(req, nt_status_squash(status));
1183 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1186 data_blob_free(&blob1);
1188 reply_spnego_ntlmssp(req, vuid,
1189 &vuser->auth_ntlmssp_state,
1190 &chal, status, OID_NTLMSSP, false);
1191 data_blob_free(&chal);
1195 /* what sort of packet is this? */
1196 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1198 data_blob_free(&blob1);
1200 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1203 /****************************************************************************
1204 On new VC == 0, shutdown *all* old connections and users.
1205 It seems that only NT4.x does this. At W2K and above (XP etc.).
1206 a new session setup with VC==0 is ignored.
1207 ****************************************************************************/
1209 struct shutdown_state {
1211 struct messaging_context *msg_ctx;
1214 static int shutdown_other_smbds(const struct connections_key *key,
1215 const struct connections_data *crec,
1218 struct shutdown_state *state = (struct shutdown_state *)private_data;
1220 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1221 procid_str(talloc_tos(), &crec->pid), crec->addr));
1223 if (!process_exists(crec->pid)) {
1224 DEBUG(10, ("process does not exist\n"));
1228 if (procid_is_me(&crec->pid)) {
1229 DEBUG(10, ("It's me\n"));
1233 if (strcmp(state->ip, crec->addr) != 0) {
1234 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1238 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1239 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1242 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1247 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1249 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1250 "compatible we would close all old resources.\n"));
1253 invalidate_all_vuids();
1255 if (lp_reset_on_zero_vc()) {
1257 struct shutdown_state state;
1259 addr = tsocket_address_inet_addr_string(
1260 sconn->remote_address, talloc_tos());
1265 state.msg_ctx = sconn->msg_ctx;
1266 connections_forall_read(shutdown_other_smbds, &state);
1271 /****************************************************************************
1272 Reply to a session setup command.
1273 ****************************************************************************/
1275 void reply_sesssetup_and_X(struct smb_request *req)
1281 DATA_BLOB plaintext_password;
1284 fstring sub_user; /* Sanitised username for substituion */
1286 const char *native_os;
1287 const char *native_lanman;
1288 const char *primary_domain;
1289 struct auth_usersupplied_info *user_info = NULL;
1290 struct auth_serversupplied_info *server_info = NULL;
1291 uint16 smb_flag2 = req->flags2;
1294 struct smbd_server_connection *sconn = req->sconn;
1296 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1298 START_PROFILE(SMBsesssetupX);
1300 ZERO_STRUCT(lm_resp);
1301 ZERO_STRUCT(nt_resp);
1302 ZERO_STRUCT(plaintext_password);
1304 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1306 /* a SPNEGO session setup has 12 command words, whereas a normal
1307 NT1 session setup has 13. See the cifs spec. */
1308 if (req->wct == 12 &&
1309 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1311 if (!sconn->smb1.negprot.spnego) {
1312 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1313 "at SPNEGO session setup when it was not "
1315 reply_nterror(req, nt_status_squash(
1316 NT_STATUS_LOGON_FAILURE));
1317 END_PROFILE(SMBsesssetupX);
1321 if (SVAL(req->vwv+4, 0) == 0) {
1322 setup_new_vc_session(req->sconn);
1325 reply_sesssetup_and_X_spnego(req);
1326 END_PROFILE(SMBsesssetupX);
1330 smb_bufsize = SVAL(req->vwv+2, 0);
1332 if (get_Protocol() < PROTOCOL_NT1) {
1333 uint16 passlen1 = SVAL(req->vwv+7, 0);
1335 /* Never do NT status codes with protocols before NT1 as we
1336 * don't get client caps. */
1337 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1339 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1340 reply_nterror(req, nt_status_squash(
1341 NT_STATUS_INVALID_PARAMETER));
1342 END_PROFILE(SMBsesssetupX);
1347 lm_resp = data_blob(req->buf, passlen1);
1349 plaintext_password = data_blob(req->buf, passlen1+1);
1350 /* Ensure null termination */
1351 plaintext_password.data[passlen1] = 0;
1354 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1355 req->buf + passlen1, STR_TERMINATE);
1356 user = tmp ? tmp : "";
1361 uint16 passlen1 = SVAL(req->vwv+7, 0);
1362 uint16 passlen2 = SVAL(req->vwv+8, 0);
1363 enum remote_arch_types ra_type = get_remote_arch();
1364 const uint8_t *p = req->buf;
1365 const uint8_t *save_p = req->buf;
1369 if(global_client_caps == 0) {
1370 global_client_caps = IVAL(req->vwv+11, 0);
1372 if (!(global_client_caps & CAP_STATUS32)) {
1373 remove_from_common_flags2(
1374 FLAGS2_32_BIT_ERROR_CODES);
1377 /* client_caps is used as final determination if
1378 * client is NT or Win95. This is needed to return
1379 * the correct error codes in some circumstances.
1382 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1383 ra_type == RA_WIN95) {
1384 if(!(global_client_caps & (CAP_NT_SMBS|
1386 set_remote_arch( RA_WIN95);
1392 /* both Win95 and WinNT stuff up the password
1393 * lengths for non-encrypting systems. Uggh.
1395 if passlen1==24 its a win95 system, and its setting
1396 the password length incorrectly. Luckily it still
1397 works with the default code because Win95 will null
1398 terminate the password anyway
1400 if passlen1>0 and passlen2>0 then maybe its a NT box
1401 and its setting passlen2 to some random value which
1402 really stuffs things up. we need to fix that one. */
1404 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1410 /* check for nasty tricks */
1411 if (passlen1 > MAX_PASS_LEN
1412 || passlen1 > smbreq_bufrem(req, p)) {
1413 reply_nterror(req, nt_status_squash(
1414 NT_STATUS_INVALID_PARAMETER));
1415 END_PROFILE(SMBsesssetupX);
1419 if (passlen2 > MAX_PASS_LEN
1420 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1421 reply_nterror(req, nt_status_squash(
1422 NT_STATUS_INVALID_PARAMETER));
1423 END_PROFILE(SMBsesssetupX);
1427 /* Save the lanman2 password and the NT md4 password. */
1429 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1434 lm_resp = data_blob(p, passlen1);
1435 nt_resp = data_blob(p+passlen1, passlen2);
1436 } else if (lp_security() != SEC_SHARE) {
1438 * In share level we should ignore any passwords, so
1439 * only read them if we're not.
1442 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1444 if (unic && (passlen2 == 0) && passlen1) {
1445 /* Only a ascii plaintext password was sent. */
1446 (void)srvstr_pull_talloc(talloc_tos(),
1452 STR_TERMINATE|STR_ASCII);
1454 (void)srvstr_pull_talloc(talloc_tos(),
1459 unic ? passlen2 : passlen1,
1463 reply_nterror(req, nt_status_squash(
1464 NT_STATUS_INVALID_PARAMETER));
1465 END_PROFILE(SMBsesssetupX);
1468 plaintext_password = data_blob(pass, strlen(pass)+1);
1471 p += passlen1 + passlen2;
1473 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1475 user = tmp ? tmp : "";
1477 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1479 domain = tmp ? tmp : "";
1481 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1483 native_os = tmp ? tmp : "";
1485 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1487 native_lanman = tmp ? tmp : "";
1489 /* not documented or decoded by Ethereal but there is one more
1490 * string in the extra bytes which is the same as the
1491 * PrimaryDomain when using extended security. Windows NT 4
1492 * and 2003 use this string to store the native lanman string.
1493 * Windows 9x does not include a string here at all so we have
1494 * to check if we have any extra bytes left */
1496 byte_count = SVAL(req->vwv+13, 0);
1497 if ( PTR_DIFF(p, save_p) < byte_count) {
1498 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1500 primary_domain = tmp ? tmp : "";
1502 primary_domain = talloc_strdup(talloc_tos(), "null");
1505 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1506 "PrimaryDomain=[%s]\n",
1507 domain, native_os, native_lanman, primary_domain));
1509 if ( ra_type == RA_WIN2K ) {
1510 if ( strlen(native_lanman) == 0 )
1511 ra_lanman_string( primary_domain );
1513 ra_lanman_string( native_lanman );
1518 if (SVAL(req->vwv+4, 0) == 0) {
1519 setup_new_vc_session(req->sconn);
1522 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1523 domain, user, get_remote_machine_name()));
1526 if (sconn->smb1.negprot.spnego) {
1528 /* This has to be here, because this is a perfectly
1529 * valid behaviour for guest logons :-( */
1531 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1532 "at 'normal' session setup after "
1533 "negotiating spnego.\n"));
1534 reply_nterror(req, nt_status_squash(
1535 NT_STATUS_LOGON_FAILURE));
1536 END_PROFILE(SMBsesssetupX);
1539 fstrcpy(sub_user, user);
1541 fstrcpy(sub_user, lp_guestaccount());
1544 sub_set_smb_name(sub_user);
1546 reload_services(sconn->msg_ctx, sconn->sock, True);
1548 if (lp_security() == SEC_SHARE) {
1549 /* In share level we should ignore any passwords */
1551 data_blob_free(&lm_resp);
1552 data_blob_free(&nt_resp);
1553 data_blob_clear_free(&plaintext_password);
1555 map_username(sub_user);
1556 add_session_user(sconn, sub_user);
1557 add_session_workgroup(sconn, domain);
1558 /* Then force it to null for the benfit of the code below */
1564 nt_status = check_guest_password(&server_info);
1566 } else if (doencrypt) {
1567 struct auth_context *negprot_auth_context = NULL;
1568 negprot_auth_context = sconn->smb1.negprot.auth_context;
1569 if (!negprot_auth_context) {
1570 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1571 "session setup without negprot denied!\n"));
1572 reply_nterror(req, nt_status_squash(
1573 NT_STATUS_LOGON_FAILURE));
1574 END_PROFILE(SMBsesssetupX);
1577 nt_status = make_user_info_for_reply_enc(&user_info, user,
1580 if (NT_STATUS_IS_OK(nt_status)) {
1581 nt_status = negprot_auth_context->check_ntlm_password(
1582 negprot_auth_context,
1587 struct auth_context *plaintext_auth_context = NULL;
1589 nt_status = make_auth_context_subsystem(
1590 &plaintext_auth_context);
1592 if (NT_STATUS_IS_OK(nt_status)) {
1595 plaintext_auth_context->get_ntlm_challenge(
1596 plaintext_auth_context, chal);
1598 if (!make_user_info_for_reply(&user_info,
1600 plaintext_password)) {
1601 nt_status = NT_STATUS_NO_MEMORY;
1604 if (NT_STATUS_IS_OK(nt_status)) {
1605 nt_status = plaintext_auth_context->check_ntlm_password(
1606 plaintext_auth_context,
1610 TALLOC_FREE(plaintext_auth_context);
1615 free_user_info(&user_info);
1617 if (!NT_STATUS_IS_OK(nt_status)) {
1618 nt_status = do_map_to_guest(nt_status, &server_info,
1622 if (!NT_STATUS_IS_OK(nt_status)) {
1623 data_blob_free(&nt_resp);
1624 data_blob_free(&lm_resp);
1625 data_blob_clear_free(&plaintext_password);
1626 reply_nterror(req, nt_status_squash(nt_status));
1627 END_PROFILE(SMBsesssetupX);
1631 /* Ensure we can't possible take a code path leading to a
1634 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1635 END_PROFILE(SMBsesssetupX);
1639 if (!server_info->ptok) {
1640 nt_status = create_local_token(server_info);
1642 if (!NT_STATUS_IS_OK(nt_status)) {
1643 DEBUG(10, ("create_local_token failed: %s\n",
1644 nt_errstr(nt_status)));
1645 data_blob_free(&nt_resp);
1646 data_blob_free(&lm_resp);
1647 data_blob_clear_free(&plaintext_password);
1648 reply_nterror(req, nt_status_squash(nt_status));
1649 END_PROFILE(SMBsesssetupX);
1654 data_blob_clear_free(&plaintext_password);
1656 /* it's ok - setup a reply */
1657 reply_outbuf(req, 3, 0);
1658 if (get_Protocol() >= PROTOCOL_NT1) {
1659 push_signature(&req->outbuf);
1660 /* perhaps grab OS version here?? */
1663 if (server_info->guest) {
1664 SSVAL(req->outbuf,smb_vwv2,1);
1667 /* register the name and uid as being validated, so further connections
1668 to a uid can get through without a password, on the same VC */
1670 if (lp_security() == SEC_SHARE) {
1671 sess_vuid = UID_FIELD_INVALID;
1672 TALLOC_FREE(server_info);
1674 /* Ignore the initial vuid. */
1675 sess_vuid = register_initial_vuid(sconn);
1676 if (sess_vuid == UID_FIELD_INVALID) {
1677 data_blob_free(&nt_resp);
1678 data_blob_free(&lm_resp);
1679 reply_nterror(req, nt_status_squash(
1680 NT_STATUS_LOGON_FAILURE));
1681 END_PROFILE(SMBsesssetupX);
1684 /* register_existing_vuid keeps the server info */
1685 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1687 nt_resp.data ? nt_resp : lm_resp,
1689 if (sess_vuid == UID_FIELD_INVALID) {
1690 data_blob_free(&nt_resp);
1691 data_blob_free(&lm_resp);
1692 reply_nterror(req, nt_status_squash(
1693 NT_STATUS_LOGON_FAILURE));
1694 END_PROFILE(SMBsesssetupX);
1698 /* current_user_info is changed on new vuid */
1699 reload_services(sconn->msg_ctx, sconn->sock, True);
1702 data_blob_free(&nt_resp);
1703 data_blob_free(&lm_resp);
1705 SSVAL(req->outbuf,smb_uid,sess_vuid);
1706 SSVAL(req->inbuf,smb_uid,sess_vuid);
1707 req->vuid = sess_vuid;
1709 if (!sconn->smb1.sessions.done_sesssetup) {
1710 sconn->smb1.sessions.max_send =
1711 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1713 sconn->smb1.sessions.done_sesssetup = true;
1715 END_PROFILE(SMBsesssetupX);