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", global_myname(), 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(auth_ntlmssp_state);
666 if (!NT_STATUS_IS_OK(status)) {
667 /* Kill the intermediate vuid */
668 invalidate_vuid(sconn, vuid);
669 reply_nterror(req, nt_status_squash(status));
673 status = auth_ntlmssp_update(*auth_ntlmssp_state,
676 data_blob_free(&secblob);
678 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
679 &chal, status, OID_NTLMSSP, true);
681 data_blob_free(&chal);
683 /* already replied */
687 /****************************************************************************
688 Reply to a session setup spnego auth packet.
689 ****************************************************************************/
691 static void reply_spnego_auth(struct smb_request *req,
694 struct auth_ntlmssp_state **auth_ntlmssp_state)
696 DATA_BLOB auth = data_blob_null;
697 DATA_BLOB auth_reply = data_blob_null;
698 DATA_BLOB secblob = data_blob_null;
699 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
700 struct smbd_server_connection *sconn = req->sconn;
702 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
704 file_save("auth.dat", blob1.data, blob1.length);
706 /* Kill the intermediate vuid */
707 invalidate_vuid(sconn, vuid);
709 reply_nterror(req, nt_status_squash(
710 NT_STATUS_LOGON_FAILURE));
714 if (auth.data[0] == ASN1_APPLICATION(0)) {
715 /* Might be a second negTokenTarg packet */
716 char *kerb_mech = NULL;
718 status = parse_spnego_mechanisms(talloc_tos(),
719 auth, &secblob, &kerb_mech);
721 if (!NT_STATUS_IS_OK(status)) {
722 /* Kill the intermediate vuid */
723 invalidate_vuid(sconn, vuid);
724 reply_nterror(req, nt_status_squash(status));
728 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
729 (unsigned long)secblob.length));
731 if (kerb_mech && ((lp_security()==SEC_ADS) ||
732 USE_KERBEROS_KEYTAB)) {
733 bool destroy_vuid = True;
734 reply_spnego_kerberos(req, &secblob, kerb_mech,
735 vuid, &destroy_vuid);
736 data_blob_free(&secblob);
737 data_blob_free(&auth);
739 /* Kill the intermediate vuid */
740 invalidate_vuid(sconn, vuid);
742 TALLOC_FREE(kerb_mech);
746 /* Can't blunder into NTLMSSP auth if we have
750 /* Kill the intermediate vuid */
751 invalidate_vuid(sconn, vuid);
752 DEBUG(3,("reply_spnego_auth: network "
753 "misconfiguration, client sent us a "
754 "krb5 ticket and kerberos security "
756 reply_nterror(req, nt_status_squash(
757 NT_STATUS_LOGON_FAILURE));
758 TALLOC_FREE(kerb_mech);
762 /* If we get here it wasn't a negTokenTarg auth packet. */
763 data_blob_free(&secblob);
765 if (!*auth_ntlmssp_state) {
766 status = auth_ntlmssp_start(auth_ntlmssp_state);
767 if (!NT_STATUS_IS_OK(status)) {
768 /* Kill the intermediate vuid */
769 invalidate_vuid(sconn, vuid);
770 reply_nterror(req, nt_status_squash(status));
775 status = auth_ntlmssp_update(*auth_ntlmssp_state,
778 data_blob_free(&auth);
780 /* Don't send the mechid as we've already sent this (RFC4178). */
782 reply_spnego_ntlmssp(req, vuid,
784 &auth_reply, status, NULL, true);
786 data_blob_free(&auth_reply);
788 /* and tell smbd that we have already replied to this packet */
792 /****************************************************************************
793 Delete an entry on the list.
794 ****************************************************************************/
796 static void delete_partial_auth(struct smbd_server_connection *sconn,
797 struct pending_auth_data *pad)
802 DLIST_REMOVE(sconn->smb1.pd_list, pad);
803 data_blob_free(&pad->partial_data);
807 /****************************************************************************
808 Search for a partial SPNEGO auth fragment matching an smbpid.
809 ****************************************************************************/
811 static struct pending_auth_data *get_pending_auth_data(
812 struct smbd_server_connection *sconn,
815 struct pending_auth_data *pad;
817 * NOTE: using the smbpid here is completely wrong...
819 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
821 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
822 if (pad->smbpid == smbpid) {
829 /****************************************************************************
830 Check the size of an SPNEGO blob. If we need more return
831 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
832 the blob to be more than 64k.
833 ****************************************************************************/
835 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
836 uint16 smbpid, uint16 vuid,
839 struct pending_auth_data *pad = NULL;
841 size_t needed_len = 0;
843 pad = get_pending_auth_data(sconn, smbpid);
845 /* Ensure we have some data. */
846 if (pblob->length == 0) {
847 /* Caller can cope. */
848 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
849 delete_partial_auth(sconn, pad);
853 /* Were we waiting for more data ? */
856 size_t copy_len = MIN(65536, pblob->length);
858 /* Integer wrap paranoia.... */
860 if (pad->partial_data.length + copy_len <
861 pad->partial_data.length ||
862 pad->partial_data.length + copy_len < copy_len) {
864 DEBUG(2,("check_spnego_blob_complete: integer wrap "
865 "pad->partial_data.length = %u, "
867 (unsigned int)pad->partial_data.length,
868 (unsigned int)copy_len ));
870 delete_partial_auth(sconn, pad);
871 return NT_STATUS_INVALID_PARAMETER;
874 DEBUG(10,("check_spnego_blob_complete: "
875 "pad->partial_data.length = %u, "
876 "pad->needed_len = %u, "
878 "pblob->length = %u,\n",
879 (unsigned int)pad->partial_data.length,
880 (unsigned int)pad->needed_len,
881 (unsigned int)copy_len,
882 (unsigned int)pblob->length ));
884 tmp_blob = data_blob(NULL,
885 pad->partial_data.length + copy_len);
887 /* Concatenate the two (up to copy_len) bytes. */
888 memcpy(tmp_blob.data,
889 pad->partial_data.data,
890 pad->partial_data.length);
891 memcpy(tmp_blob.data + pad->partial_data.length,
895 /* Replace the partial data. */
896 data_blob_free(&pad->partial_data);
897 pad->partial_data = tmp_blob;
898 ZERO_STRUCT(tmp_blob);
901 if (pblob->length >= pad->needed_len) {
902 /* Yes, replace pblob. */
903 data_blob_free(pblob);
904 *pblob = pad->partial_data;
905 ZERO_STRUCT(pad->partial_data);
906 delete_partial_auth(sconn, pad);
910 /* Still need more data. */
911 pad->needed_len -= copy_len;
912 return NT_STATUS_MORE_PROCESSING_REQUIRED;
915 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
916 (pblob->data[0] != ASN1_CONTEXT(1))) {
917 /* Not something we can determine the
923 /* This is a new SPNEGO sessionsetup - see if
924 * the data given in this blob is enough.
927 data = asn1_init(NULL);
929 return NT_STATUS_NO_MEMORY;
932 asn1_load(data, *pblob);
933 asn1_start_tag(data, pblob->data[0]);
934 if (data->has_error || data->nesting == NULL) {
936 /* Let caller catch. */
940 /* Integer wrap paranoia.... */
942 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
943 data->nesting->taglen + data->nesting->start < data->nesting->start) {
945 DEBUG(2,("check_spnego_blob_complete: integer wrap "
946 "data.nesting->taglen = %u, "
947 "data.nesting->start = %u\n",
948 (unsigned int)data->nesting->taglen,
949 (unsigned int)data->nesting->start ));
952 return NT_STATUS_INVALID_PARAMETER;
955 /* Total length of the needed asn1 is the tag length
956 * plus the current offset. */
958 needed_len = data->nesting->taglen + data->nesting->start;
961 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
962 "pblob->length = %u\n",
963 (unsigned int)needed_len,
964 (unsigned int)pblob->length ));
966 if (needed_len <= pblob->length) {
967 /* Nothing to do - blob is complete. */
971 /* Refuse the blob if it's bigger than 64k. */
972 if (needed_len > 65536) {
973 DEBUG(2,("check_spnego_blob_complete: needed_len "
975 (unsigned int)needed_len ));
976 return NT_STATUS_INVALID_PARAMETER;
979 /* We must store this blob until complete. */
980 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
981 return NT_STATUS_NO_MEMORY;
983 pad->needed_len = needed_len - pblob->length;
984 pad->partial_data = data_blob(pblob->data, pblob->length);
985 if (pad->partial_data.data == NULL) {
987 return NT_STATUS_NO_MEMORY;
989 pad->smbpid = smbpid;
991 DLIST_ADD(sconn->smb1.pd_list, pad);
993 return NT_STATUS_MORE_PROCESSING_REQUIRED;
996 /****************************************************************************
997 Reply to a session setup command.
998 conn POINTER CAN BE NULL HERE !
999 ****************************************************************************/
1001 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1007 const char *native_os;
1008 const char *native_lanman;
1009 const char *primary_domain;
1011 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1012 enum remote_arch_types ra_type = get_remote_arch();
1013 int vuid = req->vuid;
1014 user_struct *vuser = NULL;
1015 NTSTATUS status = NT_STATUS_OK;
1016 uint16 smbpid = req->smbpid;
1017 struct smbd_server_connection *sconn = req->sconn;
1019 DEBUG(3,("Doing spnego session setup\n"));
1021 if (global_client_caps == 0) {
1022 global_client_caps = IVAL(req->vwv+10, 0);
1024 if (!(global_client_caps & CAP_STATUS32)) {
1025 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1032 if (data_blob_len == 0) {
1033 /* an invalid request */
1034 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1038 bufrem = smbreq_bufrem(req, p);
1039 /* pull the spnego blob */
1040 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1043 file_save("negotiate.dat", blob1.data, blob1.length);
1046 p2 = (char *)req->buf + blob1.length;
1048 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1050 native_os = tmp ? tmp : "";
1052 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1054 native_lanman = tmp ? tmp : "";
1056 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1058 primary_domain = tmp ? tmp : "";
1060 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1061 native_os, native_lanman, primary_domain));
1063 if ( ra_type == RA_WIN2K ) {
1064 /* Vista sets neither the OS or lanman strings */
1066 if ( !strlen(native_os) && !strlen(native_lanman) )
1067 set_remote_arch(RA_VISTA);
1069 /* Windows 2003 doesn't set the native lanman string,
1070 but does set primary domain which is a bug I think */
1072 if ( !strlen(native_lanman) ) {
1073 ra_lanman_string( primary_domain );
1075 ra_lanman_string( native_lanman );
1077 } else if ( ra_type == RA_VISTA ) {
1078 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1079 set_remote_arch(RA_OSX);
1083 /* Did we get a valid vuid ? */
1084 if (!is_partial_auth_vuid(sconn, vuid)) {
1085 /* No, then try and see if this is an intermediate sessionsetup
1086 * for a large SPNEGO packet. */
1087 struct pending_auth_data *pad;
1088 pad = get_pending_auth_data(sconn, smbpid);
1090 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1091 "pending vuid %u\n",
1092 (unsigned int)pad->vuid ));
1097 /* Do we have a valid vuid now ? */
1098 if (!is_partial_auth_vuid(sconn, vuid)) {
1099 /* No, start a new authentication setup. */
1100 vuid = register_initial_vuid(sconn);
1101 if (vuid == UID_FIELD_INVALID) {
1102 data_blob_free(&blob1);
1103 reply_nterror(req, nt_status_squash(
1104 NT_STATUS_INVALID_PARAMETER));
1109 vuser = get_partial_auth_user_struct(sconn, vuid);
1110 /* This MUST be valid. */
1112 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1115 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1116 * sessionsetup requests as the Windows limit on the security blob
1117 * field is 4k. Bug #4400. JRA.
1120 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1121 if (!NT_STATUS_IS_OK(status)) {
1122 if (!NT_STATUS_EQUAL(status,
1123 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1124 /* Real error - kill the intermediate vuid */
1125 invalidate_vuid(sconn, vuid);
1127 data_blob_free(&blob1);
1128 reply_nterror(req, nt_status_squash(status));
1132 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1134 /* its a negTokenTarg packet */
1136 reply_spnego_negotiate(req, vuid, blob1,
1137 &vuser->auth_ntlmssp_state);
1138 data_blob_free(&blob1);
1142 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1144 /* its a auth packet */
1146 reply_spnego_auth(req, vuid, blob1,
1147 &vuser->auth_ntlmssp_state);
1148 data_blob_free(&blob1);
1152 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1155 if (!vuser->auth_ntlmssp_state) {
1156 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1157 if (!NT_STATUS_IS_OK(status)) {
1158 /* Kill the intermediate vuid */
1159 invalidate_vuid(sconn, vuid);
1160 data_blob_free(&blob1);
1161 reply_nterror(req, nt_status_squash(status));
1166 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1169 data_blob_free(&blob1);
1171 reply_spnego_ntlmssp(req, vuid,
1172 &vuser->auth_ntlmssp_state,
1173 &chal, status, OID_NTLMSSP, false);
1174 data_blob_free(&chal);
1178 /* what sort of packet is this? */
1179 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1181 data_blob_free(&blob1);
1183 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1186 /****************************************************************************
1187 On new VC == 0, shutdown *all* old connections and users.
1188 It seems that only NT4.x does this. At W2K and above (XP etc.).
1189 a new session setup with VC==0 is ignored.
1190 ****************************************************************************/
1192 struct shutdown_state {
1194 struct messaging_context *msg_ctx;
1197 static int shutdown_other_smbds(const struct connections_key *key,
1198 const struct connections_data *crec,
1201 struct shutdown_state *state = (struct shutdown_state *)private_data;
1203 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1204 procid_str(talloc_tos(), &crec->pid), crec->addr));
1206 if (!process_exists(crec->pid)) {
1207 DEBUG(10, ("process does not exist\n"));
1211 if (procid_is_me(&crec->pid)) {
1212 DEBUG(10, ("It's me\n"));
1216 if (strcmp(state->ip, crec->addr) != 0) {
1217 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1221 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1222 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1225 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1230 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1232 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1233 "compatible we would close all old resources.\n"));
1236 invalidate_all_vuids();
1238 if (lp_reset_on_zero_vc()) {
1240 struct shutdown_state state;
1242 addr = tsocket_address_inet_addr_string(
1243 sconn->remote_address, talloc_tos());
1248 state.msg_ctx = sconn->msg_ctx;
1249 connections_forall_read(shutdown_other_smbds, &state);
1254 /****************************************************************************
1255 Reply to a session setup command.
1256 ****************************************************************************/
1258 void reply_sesssetup_and_X(struct smb_request *req)
1264 DATA_BLOB plaintext_password;
1267 fstring sub_user; /* Sanitised username for substituion */
1269 const char *native_os;
1270 const char *native_lanman;
1271 const char *primary_domain;
1272 struct auth_usersupplied_info *user_info = NULL;
1273 struct auth_serversupplied_info *server_info = NULL;
1274 struct auth_serversupplied_info *session_info = NULL;
1275 uint16 smb_flag2 = req->flags2;
1278 struct smbd_server_connection *sconn = req->sconn;
1280 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1282 START_PROFILE(SMBsesssetupX);
1284 ZERO_STRUCT(lm_resp);
1285 ZERO_STRUCT(nt_resp);
1286 ZERO_STRUCT(plaintext_password);
1288 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1290 /* a SPNEGO session setup has 12 command words, whereas a normal
1291 NT1 session setup has 13. See the cifs spec. */
1292 if (req->wct == 12 &&
1293 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1295 if (!sconn->smb1.negprot.spnego) {
1296 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1297 "at SPNEGO session setup when it was not "
1299 reply_nterror(req, nt_status_squash(
1300 NT_STATUS_LOGON_FAILURE));
1301 END_PROFILE(SMBsesssetupX);
1305 if (SVAL(req->vwv+4, 0) == 0) {
1306 setup_new_vc_session(req->sconn);
1309 reply_sesssetup_and_X_spnego(req);
1310 END_PROFILE(SMBsesssetupX);
1314 smb_bufsize = SVAL(req->vwv+2, 0);
1316 if (get_Protocol() < PROTOCOL_NT1) {
1317 uint16 passlen1 = SVAL(req->vwv+7, 0);
1319 /* Never do NT status codes with protocols before NT1 as we
1320 * don't get client caps. */
1321 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1323 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1324 reply_nterror(req, nt_status_squash(
1325 NT_STATUS_INVALID_PARAMETER));
1326 END_PROFILE(SMBsesssetupX);
1331 lm_resp = data_blob(req->buf, passlen1);
1333 plaintext_password = data_blob(req->buf, passlen1+1);
1334 /* Ensure null termination */
1335 plaintext_password.data[passlen1] = 0;
1338 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1339 req->buf + passlen1, STR_TERMINATE);
1340 user = tmp ? tmp : "";
1345 uint16 passlen1 = SVAL(req->vwv+7, 0);
1346 uint16 passlen2 = SVAL(req->vwv+8, 0);
1347 enum remote_arch_types ra_type = get_remote_arch();
1348 const uint8_t *p = req->buf;
1349 const uint8_t *save_p = req->buf;
1353 if(global_client_caps == 0) {
1354 global_client_caps = IVAL(req->vwv+11, 0);
1356 if (!(global_client_caps & CAP_STATUS32)) {
1357 remove_from_common_flags2(
1358 FLAGS2_32_BIT_ERROR_CODES);
1361 /* client_caps is used as final determination if
1362 * client is NT or Win95. This is needed to return
1363 * the correct error codes in some circumstances.
1366 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1367 ra_type == RA_WIN95) {
1368 if(!(global_client_caps & (CAP_NT_SMBS|
1370 set_remote_arch( RA_WIN95);
1376 /* both Win95 and WinNT stuff up the password
1377 * lengths for non-encrypting systems. Uggh.
1379 if passlen1==24 its a win95 system, and its setting
1380 the password length incorrectly. Luckily it still
1381 works with the default code because Win95 will null
1382 terminate the password anyway
1384 if passlen1>0 and passlen2>0 then maybe its a NT box
1385 and its setting passlen2 to some random value which
1386 really stuffs things up. we need to fix that one. */
1388 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1394 /* check for nasty tricks */
1395 if (passlen1 > MAX_PASS_LEN
1396 || passlen1 > smbreq_bufrem(req, p)) {
1397 reply_nterror(req, nt_status_squash(
1398 NT_STATUS_INVALID_PARAMETER));
1399 END_PROFILE(SMBsesssetupX);
1403 if (passlen2 > MAX_PASS_LEN
1404 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1405 reply_nterror(req, nt_status_squash(
1406 NT_STATUS_INVALID_PARAMETER));
1407 END_PROFILE(SMBsesssetupX);
1411 /* Save the lanman2 password and the NT md4 password. */
1413 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1418 lm_resp = data_blob(p, passlen1);
1419 nt_resp = data_blob(p+passlen1, passlen2);
1420 } else if (lp_security() != SEC_SHARE) {
1422 * In share level we should ignore any passwords, so
1423 * only read them if we're not.
1426 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1428 if (unic && (passlen2 == 0) && passlen1) {
1429 /* Only a ascii plaintext password was sent. */
1430 (void)srvstr_pull_talloc(talloc_tos(),
1436 STR_TERMINATE|STR_ASCII);
1438 (void)srvstr_pull_talloc(talloc_tos(),
1443 unic ? passlen2 : passlen1,
1447 reply_nterror(req, nt_status_squash(
1448 NT_STATUS_INVALID_PARAMETER));
1449 END_PROFILE(SMBsesssetupX);
1452 plaintext_password = data_blob(pass, strlen(pass)+1);
1455 p += passlen1 + passlen2;
1457 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1459 user = tmp ? tmp : "";
1461 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1463 domain = tmp ? tmp : "";
1465 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1467 native_os = tmp ? tmp : "";
1469 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1471 native_lanman = tmp ? tmp : "";
1473 /* not documented or decoded by Ethereal but there is one more
1474 * string in the extra bytes which is the same as the
1475 * PrimaryDomain when using extended security. Windows NT 4
1476 * and 2003 use this string to store the native lanman string.
1477 * Windows 9x does not include a string here at all so we have
1478 * to check if we have any extra bytes left */
1480 byte_count = SVAL(req->vwv+13, 0);
1481 if ( PTR_DIFF(p, save_p) < byte_count) {
1482 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1484 primary_domain = tmp ? tmp : "";
1486 primary_domain = talloc_strdup(talloc_tos(), "null");
1489 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1490 "PrimaryDomain=[%s]\n",
1491 domain, native_os, native_lanman, primary_domain));
1493 if ( ra_type == RA_WIN2K ) {
1494 if ( strlen(native_lanman) == 0 )
1495 ra_lanman_string( primary_domain );
1497 ra_lanman_string( native_lanman );
1502 if (SVAL(req->vwv+4, 0) == 0) {
1503 setup_new_vc_session(req->sconn);
1506 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1507 domain, user, get_remote_machine_name()));
1510 if (sconn->smb1.negprot.spnego) {
1512 /* This has to be here, because this is a perfectly
1513 * valid behaviour for guest logons :-( */
1515 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1516 "at 'normal' session setup after "
1517 "negotiating spnego.\n"));
1518 reply_nterror(req, nt_status_squash(
1519 NT_STATUS_LOGON_FAILURE));
1520 END_PROFILE(SMBsesssetupX);
1523 fstrcpy(sub_user, user);
1525 fstrcpy(sub_user, lp_guestaccount());
1528 sub_set_smb_name(sub_user);
1530 reload_services(sconn->msg_ctx, sconn->sock, True);
1532 if (lp_security() == SEC_SHARE) {
1533 char *sub_user_mapped = NULL;
1534 /* In share level we should ignore any passwords */
1536 data_blob_free(&lm_resp);
1537 data_blob_free(&nt_resp);
1538 data_blob_clear_free(&plaintext_password);
1540 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1541 if (!sub_user_mapped) {
1542 reply_nterror(req, NT_STATUS_NO_MEMORY);
1543 END_PROFILE(SMBsesssetupX);
1546 fstrcpy(sub_user, sub_user_mapped);
1547 add_session_user(sconn, sub_user);
1548 add_session_workgroup(sconn, domain);
1549 /* Then force it to null for the benfit of the code below */
1555 nt_status = check_guest_password(&server_info);
1557 } else if (doencrypt) {
1558 struct auth_context *negprot_auth_context = NULL;
1559 negprot_auth_context = sconn->smb1.negprot.auth_context;
1560 if (!negprot_auth_context) {
1561 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1562 "session setup without negprot denied!\n"));
1563 reply_nterror(req, nt_status_squash(
1564 NT_STATUS_LOGON_FAILURE));
1565 END_PROFILE(SMBsesssetupX);
1568 nt_status = make_user_info_for_reply_enc(&user_info, user,
1571 if (NT_STATUS_IS_OK(nt_status)) {
1572 nt_status = negprot_auth_context->check_ntlm_password(
1573 negprot_auth_context,
1578 struct auth_context *plaintext_auth_context = NULL;
1580 nt_status = make_auth_context_subsystem(
1581 talloc_tos(), &plaintext_auth_context);
1583 if (NT_STATUS_IS_OK(nt_status)) {
1586 plaintext_auth_context->get_ntlm_challenge(
1587 plaintext_auth_context, chal);
1589 if (!make_user_info_for_reply(&user_info,
1591 plaintext_password)) {
1592 nt_status = NT_STATUS_NO_MEMORY;
1595 if (NT_STATUS_IS_OK(nt_status)) {
1596 nt_status = plaintext_auth_context->check_ntlm_password(
1597 plaintext_auth_context,
1601 TALLOC_FREE(plaintext_auth_context);
1606 free_user_info(&user_info);
1608 if (!NT_STATUS_IS_OK(nt_status)) {
1609 nt_status = do_map_to_guest(nt_status, &server_info,
1613 if (!NT_STATUS_IS_OK(nt_status)) {
1614 data_blob_free(&nt_resp);
1615 data_blob_free(&lm_resp);
1616 data_blob_clear_free(&plaintext_password);
1617 reply_nterror(req, nt_status_squash(nt_status));
1618 END_PROFILE(SMBsesssetupX);
1622 nt_status = create_local_token(req, server_info, NULL, &session_info);
1623 TALLOC_FREE(server_info);
1625 if (!NT_STATUS_IS_OK(nt_status)) {
1626 DEBUG(10, ("create_local_token failed: %s\n",
1627 nt_errstr(nt_status)));
1628 data_blob_free(&nt_resp);
1629 data_blob_free(&lm_resp);
1630 data_blob_clear_free(&plaintext_password);
1631 reply_nterror(req, nt_status_squash(nt_status));
1632 END_PROFILE(SMBsesssetupX);
1636 data_blob_clear_free(&plaintext_password);
1638 /* it's ok - setup a reply */
1639 reply_outbuf(req, 3, 0);
1640 if (get_Protocol() >= PROTOCOL_NT1) {
1641 push_signature(&req->outbuf);
1642 /* perhaps grab OS version here?? */
1645 if (session_info->guest) {
1646 SSVAL(req->outbuf,smb_vwv2,1);
1649 /* register the name and uid as being validated, so further connections
1650 to a uid can get through without a password, on the same VC */
1652 if (lp_security() == SEC_SHARE) {
1653 sess_vuid = UID_FIELD_INVALID;
1654 TALLOC_FREE(session_info);
1656 /* Ignore the initial vuid. */
1657 sess_vuid = register_initial_vuid(sconn);
1658 if (sess_vuid == UID_FIELD_INVALID) {
1659 data_blob_free(&nt_resp);
1660 data_blob_free(&lm_resp);
1661 reply_nterror(req, nt_status_squash(
1662 NT_STATUS_LOGON_FAILURE));
1663 END_PROFILE(SMBsesssetupX);
1666 /* register_existing_vuid keeps the session_info */
1667 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1669 nt_resp.data ? nt_resp : lm_resp,
1671 if (sess_vuid == UID_FIELD_INVALID) {
1672 data_blob_free(&nt_resp);
1673 data_blob_free(&lm_resp);
1674 reply_nterror(req, nt_status_squash(
1675 NT_STATUS_LOGON_FAILURE));
1676 END_PROFILE(SMBsesssetupX);
1680 /* current_user_info is changed on new vuid */
1681 reload_services(sconn->msg_ctx, sconn->sock, True);
1684 data_blob_free(&nt_resp);
1685 data_blob_free(&lm_resp);
1687 SSVAL(req->outbuf,smb_uid,sess_vuid);
1688 SSVAL(req->inbuf,smb_uid,sess_vuid);
1689 req->vuid = sess_vuid;
1691 if (!sconn->smb1.sessions.done_sesssetup) {
1692 sconn->smb1.sessions.max_send =
1693 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1695 sconn->smb1.sessions.done_sesssetup = true;
1697 END_PROFILE(SMBsesssetupX);