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"
38 #include "../libcli/security/security.h"
40 /* For split krb5 SPNEGO blobs. */
41 struct pending_auth_data {
42 struct pending_auth_data *prev, *next;
43 uint16 vuid; /* Tag for this entry. */
44 uint16 smbpid; /* Alternate tag for this entry. */
46 DATA_BLOB partial_data;
49 /****************************************************************************
50 Add the standard 'Samba' signature to the end of the session setup.
51 ****************************************************************************/
53 static int push_signature(uint8 **outbuf)
60 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
62 if (tmp == -1) return -1;
65 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
66 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
70 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
73 if (tmp == -1) return -1;
76 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
78 if (tmp == -1) return -1;
84 /****************************************************************************
85 Send a security blob via a session setup reply.
86 ****************************************************************************/
88 static void reply_sesssetup_blob(struct smb_request *req,
92 if (!NT_STATUS_IS_OK(nt_status) &&
93 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
94 reply_nterror(req, nt_status_squash(nt_status));
98 nt_status = nt_status_squash(nt_status);
99 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
100 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
101 SSVAL(req->outbuf, smb_vwv3, blob.length);
103 if ((message_push_blob(&req->outbuf, blob) == -1)
104 || (push_signature(&req->outbuf) == -1)) {
105 reply_nterror(req, NT_STATUS_NO_MEMORY);
109 /****************************************************************************
110 Do a 'guest' logon, getting back the
111 ****************************************************************************/
113 static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
114 struct auth_serversupplied_info **server_info)
116 struct auth_context *auth_context;
117 struct auth_usersupplied_info *user_info = NULL;
120 static unsigned char chal[8] = { 0, };
122 DEBUG(3,("Got anonymous request\n"));
124 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
125 if (!NT_STATUS_IS_OK(nt_status)) {
129 if (!make_user_info_guest(remote_address, &user_info)) {
130 TALLOC_FREE(auth_context);
131 return NT_STATUS_NO_MEMORY;
134 nt_status = auth_context->check_ntlm_password(auth_context,
137 TALLOC_FREE(auth_context);
138 free_user_info(&user_info);
146 /* Experiment that failed. See "only happens with a KDC" comment below. */
147 /****************************************************************************
148 Cerate a clock skew error blob for a Windows client.
149 ****************************************************************************/
151 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
153 krb5_context context = NULL;
154 krb5_error_code kerr = 0;
156 krb5_principal host_princ = NULL;
157 char *host_princ_s = NULL;
160 *pblob_out = data_blob_null;
162 initialize_krb5_error_table();
163 kerr = krb5_init_context(&context);
167 /* Create server principal. */
168 asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
172 strlower_m(host_princ_s);
174 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
176 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
177 "for name %s: Error %s\n",
178 host_princ_s, error_message(kerr) ));
182 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
185 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
186 "failed: Error %s\n",
187 error_message(kerr) ));
191 *pblob_out = data_blob(reply.data, reply.length);
192 kerberos_free_data_contents(context,&reply);
198 SAFE_FREE(host_princ_s);
201 krb5_free_principal(context, host_princ);
203 krb5_free_context(context);
208 /****************************************************************************
209 Reply to a session setup spnego negotiate packet for kerberos.
210 ****************************************************************************/
212 static void reply_spnego_kerberos(struct smb_request *req,
216 bool *p_invalidate_vuid)
221 int sess_vuid = req->vuid;
222 NTSTATUS ret = NT_STATUS_OK;
223 DATA_BLOB ap_rep, ap_rep_wrapped, response;
224 struct auth_session_info *session_info = NULL;
225 DATA_BLOB session_key = data_blob_null;
227 DATA_BLOB nullblob = data_blob_null;
228 bool map_domainuser_to_guest = False;
229 bool username_was_mapped;
230 struct PAC_LOGON_INFO *logon_info = NULL;
231 struct smbd_server_connection *sconn = req->sconn;
239 ZERO_STRUCT(ap_rep_wrapped);
240 ZERO_STRUCT(response);
242 /* Normally we will always invalidate the intermediate vuid. */
243 *p_invalidate_vuid = True;
245 mem_ctx = talloc_init("reply_spnego_kerberos");
246 if (mem_ctx == NULL) {
247 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
251 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
252 talloc_destroy(mem_ctx);
253 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
257 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
258 &principal, &logon_info, &ap_rep,
261 data_blob_free(&ticket);
263 if (!NT_STATUS_IS_OK(ret)) {
265 /* Experiment that failed.
266 * See "only happens with a KDC" comment below. */
268 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
271 * Windows in this case returns
272 * NT_STATUS_MORE_PROCESSING_REQUIRED
273 * with a negTokenTarg blob containing an krb5_error
274 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
275 * The client then fixes its clock and continues rather
276 * than giving an error. JRA.
277 * -- Looks like this only happens with a KDC. JRA.
280 bool ok = make_krb5_skew_error(&ap_rep);
282 talloc_destroy(mem_ctx);
283 return ERROR_NT(nt_status_squash(
284 NT_STATUS_LOGON_FAILURE));
286 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
288 response = spnego_gen_auth_response(&ap_rep_wrapped,
289 ret, OID_KERBEROS5_OLD);
290 reply_sesssetup_blob(conn, inbuf, outbuf, response,
291 NT_STATUS_MORE_PROCESSING_REQUIRED);
294 * In this one case we don't invalidate the
295 * intermediate vuid as we're expecting the client
296 * to re-use it for the next sessionsetupX packet. JRA.
299 *p_invalidate_vuid = False;
301 data_blob_free(&ap_rep);
302 data_blob_free(&ap_rep_wrapped);
303 data_blob_free(&response);
304 talloc_destroy(mem_ctx);
305 return -1; /* already replied */
308 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
309 ret = NT_STATUS_LOGON_FAILURE;
312 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
314 talloc_destroy(mem_ctx);
315 reply_nterror(req, nt_status_squash(ret));
319 ret = get_user_from_kerberos_info(talloc_tos(),
320 sconn->remote_hostname,
321 principal, logon_info,
322 &username_was_mapped,
323 &map_domainuser_to_guest,
325 &real_username, &pw);
326 if (!NT_STATUS_IS_OK(ret)) {
327 data_blob_free(&ap_rep);
328 data_blob_free(&session_key);
329 talloc_destroy(mem_ctx);
330 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
334 /* save the PAC data if we have it */
336 netsamlogon_cache_store(user, &logon_info->info3);
339 /* setup the string used by %U */
340 sub_set_smb_name(real_username);
342 /* reload services so that the new %U is taken into account */
343 reload_services(sconn->msg_ctx, sconn->sock, True);
345 ret = make_session_info_krb5(mem_ctx,
346 user, domain, real_username, pw,
347 logon_info, map_domainuser_to_guest,
351 data_blob_free(&session_key);
352 if (!NT_STATUS_IS_OK(ret)) {
353 DEBUG(1, ("make_server_info_krb5 failed!\n"));
354 data_blob_free(&ap_rep);
355 TALLOC_FREE(mem_ctx);
356 reply_nterror(req, nt_status_squash(ret));
360 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
361 sess_vuid = register_initial_vuid(sconn);
364 /* register_existing_vuid keeps the server info */
365 /* register_existing_vuid takes ownership of session_key on success,
366 * no need to free after this on success. A better interface would copy
369 sess_vuid = register_existing_vuid(sconn, sess_vuid,
370 session_info, nullblob, user);
372 reply_outbuf(req, 4, 0);
373 SSVAL(req->outbuf,smb_uid,sess_vuid);
375 if (sess_vuid == UID_FIELD_INVALID ) {
376 ret = NT_STATUS_LOGON_FAILURE;
378 /* current_user_info is changed on new vuid */
379 reload_services(sconn->msg_ctx, sconn->sock, True);
381 SSVAL(req->outbuf, smb_vwv3, 0);
383 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
384 SSVAL(req->outbuf,smb_vwv2,1);
387 SSVAL(req->outbuf, smb_uid, sess_vuid);
389 /* Successful logon. Keep this vuid. */
390 *p_invalidate_vuid = False;
393 /* wrap that up in a nice GSS-API wrapping */
394 if (NT_STATUS_IS_OK(ret)) {
395 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
398 ap_rep_wrapped = data_blob_null;
400 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
402 reply_sesssetup_blob(req, response, ret);
404 data_blob_free(&ap_rep);
405 data_blob_free(&ap_rep_wrapped);
406 data_blob_free(&response);
407 TALLOC_FREE(mem_ctx);
412 /****************************************************************************
413 Send a session setup reply, wrapped in SPNEGO.
414 Get vuid and check first.
415 End the NTLMSSP exchange context if we are OK/complete fail
416 This should be split into two functions, one to handle each
417 leg of the NTLM auth steps.
418 ***************************************************************************/
420 static void reply_spnego_ntlmssp(struct smb_request *req,
422 struct auth_ntlmssp_state **auth_ntlmssp_state,
423 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
427 bool do_invalidate = true;
429 struct auth_session_info *session_info = NULL;
430 struct smbd_server_connection *sconn = req->sconn;
432 if (NT_STATUS_IS_OK(nt_status)) {
433 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
434 (*auth_ntlmssp_state), &session_info);
437 reply_outbuf(req, 4, 0);
439 SSVAL(req->outbuf, smb_uid, vuid);
441 if (NT_STATUS_IS_OK(nt_status)) {
442 DATA_BLOB nullblob = data_blob_null;
444 if (!is_partial_auth_vuid(sconn, vuid)) {
445 nt_status = NT_STATUS_LOGON_FAILURE;
449 /* register_existing_vuid keeps the server info */
450 if (register_existing_vuid(sconn, vuid,
451 session_info, nullblob,
452 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
454 /* The problem is, *auth_ntlmssp_state points
455 * into the vuser this will have
456 * talloc_free()'ed in
457 * register_existing_vuid() */
458 do_invalidate = false;
459 nt_status = NT_STATUS_LOGON_FAILURE;
463 /* current_user_info is changed on new vuid */
464 reload_services(sconn->msg_ctx, sconn->sock, True);
466 SSVAL(req->outbuf, smb_vwv3, 0);
468 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
469 SSVAL(req->outbuf,smb_vwv2,1);
476 response = spnego_gen_auth_response(talloc_tos(),
480 response = *ntlmssp_blob;
483 reply_sesssetup_blob(req, response, nt_status);
485 data_blob_free(&response);
488 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
489 and the other end, that we are not finished yet. */
491 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
492 /* NB. This is *NOT* an error case. JRA */
494 TALLOC_FREE(*auth_ntlmssp_state);
495 if (!NT_STATUS_IS_OK(nt_status)) {
496 /* Kill the intermediate vuid */
497 invalidate_vuid(sconn, vuid);
503 /****************************************************************************
504 Is this a krb5 mechanism ?
505 ****************************************************************************/
507 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
509 DATA_BLOB *pblob_out,
512 char *OIDs[ASN1_MAX_OIDS];
514 NTSTATUS ret = NT_STATUS_OK;
516 *kerb_mechOID = NULL;
518 /* parse out the OIDs and the first sec blob */
519 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
521 return NT_STATUS_LOGON_FAILURE;
524 /* only look at the first OID for determining the mechToken --
525 according to RFC2478, we should choose the one we want
526 and renegotiate, but i smell a client bug here..
528 Problem observed when connecting to a member (samba box)
529 of an AD domain as a user in a Samba domain. Samba member
530 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
531 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
532 NTLMSSP mechtoken. --jerry */
535 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
536 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
537 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
538 if (*kerb_mechOID == NULL) {
539 ret = NT_STATUS_NO_MEMORY;
544 for (i=0;OIDs[i];i++) {
545 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
546 talloc_free(OIDs[i]);
551 /****************************************************************************
552 Fall back from krb5 to NTLMSSP.
553 ****************************************************************************/
555 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
560 reply_outbuf(req, 4, 0);
561 SSVAL(req->outbuf,smb_uid,vuid);
563 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
564 "but set to downgrade to NTLMSSP\n"));
566 response = spnego_gen_auth_response(talloc_tos(), NULL,
567 NT_STATUS_MORE_PROCESSING_REQUIRED,
569 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
570 data_blob_free(&response);
573 /****************************************************************************
574 Reply to a session setup spnego negotiate packet.
575 ****************************************************************************/
577 static void reply_spnego_negotiate(struct smb_request *req,
580 struct auth_ntlmssp_state **auth_ntlmssp_state)
584 char *kerb_mech = NULL;
586 struct smbd_server_connection *sconn = req->sconn;
588 status = parse_spnego_mechanisms(talloc_tos(),
589 blob1, &secblob, &kerb_mech);
590 if (!NT_STATUS_IS_OK(status)) {
591 /* Kill the intermediate vuid */
592 invalidate_vuid(sconn, vuid);
593 reply_nterror(req, nt_status_squash(status));
597 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
598 (unsigned long)secblob.length));
601 if (kerb_mech && ((lp_security()==SEC_ADS) ||
602 USE_KERBEROS_KEYTAB) ) {
603 bool destroy_vuid = True;
604 reply_spnego_kerberos(req, &secblob, kerb_mech,
605 vuid, &destroy_vuid);
606 data_blob_free(&secblob);
608 /* Kill the intermediate vuid */
609 invalidate_vuid(sconn, vuid);
611 TALLOC_FREE(kerb_mech);
616 TALLOC_FREE(*auth_ntlmssp_state);
619 data_blob_free(&secblob);
620 /* The mechtoken is a krb5 ticket, but
621 * we need to fall back to NTLM. */
622 reply_spnego_downgrade_to_ntlmssp(req, vuid);
623 TALLOC_FREE(kerb_mech);
627 status = auth_ntlmssp_start(sconn->remote_address,
629 if (!NT_STATUS_IS_OK(status)) {
630 /* Kill the intermediate vuid */
631 invalidate_vuid(sconn, vuid);
632 reply_nterror(req, nt_status_squash(status));
636 auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
638 status = auth_ntlmssp_update(*auth_ntlmssp_state, talloc_tos(),
641 data_blob_free(&secblob);
643 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
644 &chal, status, OID_NTLMSSP, true);
646 data_blob_free(&chal);
648 /* already replied */
652 /****************************************************************************
653 Reply to a session setup spnego auth packet.
654 ****************************************************************************/
656 static void reply_spnego_auth(struct smb_request *req,
659 struct auth_ntlmssp_state **auth_ntlmssp_state)
661 DATA_BLOB auth = data_blob_null;
662 DATA_BLOB auth_reply = data_blob_null;
663 DATA_BLOB secblob = data_blob_null;
664 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
665 struct smbd_server_connection *sconn = req->sconn;
667 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
669 file_save("auth.dat", blob1.data, blob1.length);
671 /* Kill the intermediate vuid */
672 invalidate_vuid(sconn, vuid);
674 reply_nterror(req, nt_status_squash(
675 NT_STATUS_LOGON_FAILURE));
679 if (auth.data[0] == ASN1_APPLICATION(0)) {
680 /* Might be a second negTokenTarg packet */
681 char *kerb_mech = NULL;
683 status = parse_spnego_mechanisms(talloc_tos(),
684 auth, &secblob, &kerb_mech);
686 if (!NT_STATUS_IS_OK(status)) {
687 /* Kill the intermediate vuid */
688 invalidate_vuid(sconn, vuid);
689 reply_nterror(req, nt_status_squash(status));
693 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
694 (unsigned long)secblob.length));
696 if (kerb_mech && ((lp_security()==SEC_ADS) ||
697 USE_KERBEROS_KEYTAB)) {
698 bool destroy_vuid = True;
699 reply_spnego_kerberos(req, &secblob, kerb_mech,
700 vuid, &destroy_vuid);
701 data_blob_free(&secblob);
702 data_blob_free(&auth);
704 /* Kill the intermediate vuid */
705 invalidate_vuid(sconn, vuid);
707 TALLOC_FREE(kerb_mech);
711 /* Can't blunder into NTLMSSP auth if we have
715 /* Kill the intermediate vuid */
716 invalidate_vuid(sconn, vuid);
717 DEBUG(3,("reply_spnego_auth: network "
718 "misconfiguration, client sent us a "
719 "krb5 ticket and kerberos security "
721 reply_nterror(req, nt_status_squash(
722 NT_STATUS_LOGON_FAILURE));
723 TALLOC_FREE(kerb_mech);
727 /* If we get here it wasn't a negTokenTarg auth packet. */
728 data_blob_free(&secblob);
730 if (!*auth_ntlmssp_state) {
731 status = auth_ntlmssp_start(sconn->remote_address,
733 if (!NT_STATUS_IS_OK(status)) {
734 /* Kill the intermediate vuid */
735 invalidate_vuid(sconn, vuid);
736 reply_nterror(req, nt_status_squash(status));
741 status = auth_ntlmssp_update(*auth_ntlmssp_state, talloc_tos(),
744 data_blob_free(&auth);
746 /* Don't send the mechid as we've already sent this (RFC4178). */
748 reply_spnego_ntlmssp(req, vuid,
750 &auth_reply, status, NULL, true);
752 data_blob_free(&auth_reply);
754 /* and tell smbd that we have already replied to this packet */
758 /****************************************************************************
759 Delete an entry on the list.
760 ****************************************************************************/
762 static void delete_partial_auth(struct smbd_server_connection *sconn,
763 struct pending_auth_data *pad)
768 DLIST_REMOVE(sconn->smb1.pd_list, pad);
769 data_blob_free(&pad->partial_data);
773 /****************************************************************************
774 Search for a partial SPNEGO auth fragment matching an smbpid.
775 ****************************************************************************/
777 static struct pending_auth_data *get_pending_auth_data(
778 struct smbd_server_connection *sconn,
781 struct pending_auth_data *pad;
783 * NOTE: using the smbpid here is completely wrong...
785 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
787 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
788 if (pad->smbpid == smbpid) {
795 /****************************************************************************
796 Check the size of an SPNEGO blob. If we need more return
797 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
798 the blob to be more than 64k.
799 ****************************************************************************/
801 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
802 uint16 smbpid, uint16 vuid,
805 struct pending_auth_data *pad = NULL;
807 size_t needed_len = 0;
809 pad = get_pending_auth_data(sconn, smbpid);
811 /* Ensure we have some data. */
812 if (pblob->length == 0) {
813 /* Caller can cope. */
814 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
815 delete_partial_auth(sconn, pad);
819 /* Were we waiting for more data ? */
822 size_t copy_len = MIN(65536, pblob->length);
824 /* Integer wrap paranoia.... */
826 if (pad->partial_data.length + copy_len <
827 pad->partial_data.length ||
828 pad->partial_data.length + copy_len < copy_len) {
830 DEBUG(2,("check_spnego_blob_complete: integer wrap "
831 "pad->partial_data.length = %u, "
833 (unsigned int)pad->partial_data.length,
834 (unsigned int)copy_len ));
836 delete_partial_auth(sconn, pad);
837 return NT_STATUS_INVALID_PARAMETER;
840 DEBUG(10,("check_spnego_blob_complete: "
841 "pad->partial_data.length = %u, "
842 "pad->needed_len = %u, "
844 "pblob->length = %u,\n",
845 (unsigned int)pad->partial_data.length,
846 (unsigned int)pad->needed_len,
847 (unsigned int)copy_len,
848 (unsigned int)pblob->length ));
850 tmp_blob = data_blob(NULL,
851 pad->partial_data.length + copy_len);
853 /* Concatenate the two (up to copy_len) bytes. */
854 memcpy(tmp_blob.data,
855 pad->partial_data.data,
856 pad->partial_data.length);
857 memcpy(tmp_blob.data + pad->partial_data.length,
861 /* Replace the partial data. */
862 data_blob_free(&pad->partial_data);
863 pad->partial_data = tmp_blob;
864 ZERO_STRUCT(tmp_blob);
867 if (pblob->length >= pad->needed_len) {
868 /* Yes, replace pblob. */
869 data_blob_free(pblob);
870 *pblob = pad->partial_data;
871 ZERO_STRUCT(pad->partial_data);
872 delete_partial_auth(sconn, pad);
876 /* Still need more data. */
877 pad->needed_len -= copy_len;
878 return NT_STATUS_MORE_PROCESSING_REQUIRED;
881 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
882 (pblob->data[0] != ASN1_CONTEXT(1))) {
883 /* Not something we can determine the
889 /* This is a new SPNEGO sessionsetup - see if
890 * the data given in this blob is enough.
893 data = asn1_init(NULL);
895 return NT_STATUS_NO_MEMORY;
898 asn1_load(data, *pblob);
899 if (asn1_start_tag(data, pblob->data[0])) {
900 /* asn1_start_tag checks if the given
901 length of the blob is enough to complete
902 the tag. If it returns true we know
903 there is nothing to do - the blob is
909 if (data->nesting == NULL) {
910 /* Incorrect tag, allocation failed,
911 or reading the tag length failed.
912 Let the caller catch. */
917 /* Here we know asn1_start_tag() has set data->has_error to true.
918 asn1_tag_remaining() will have failed due to the given blob
919 being too short. We need to work out how short. */
921 /* Integer wrap paranoia.... */
923 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
924 data->nesting->taglen + data->nesting->start < data->nesting->start) {
926 DEBUG(2,("check_spnego_blob_complete: integer wrap "
927 "data.nesting->taglen = %u, "
928 "data.nesting->start = %u\n",
929 (unsigned int)data->nesting->taglen,
930 (unsigned int)data->nesting->start ));
933 return NT_STATUS_INVALID_PARAMETER;
936 /* Total length of the needed asn1 is the tag length
937 * plus the current offset. */
939 needed_len = data->nesting->taglen + data->nesting->start;
942 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
943 "pblob->length = %u\n",
944 (unsigned int)needed_len,
945 (unsigned int)pblob->length ));
947 if (needed_len <= pblob->length) {
948 /* Nothing to do - blob is complete. */
949 /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
950 above should have caught this !!! */
951 DEBUG(0,("check_spnego_blob_complete: logic "
952 "error (needed_len = %u, "
953 "pblob->length = %u).\n",
954 (unsigned int)needed_len,
955 (unsigned int)pblob->length ));
959 /* Refuse the blob if it's bigger than 64k. */
960 if (needed_len > 65536) {
961 DEBUG(2,("check_spnego_blob_complete: needed_len "
963 (unsigned int)needed_len ));
964 return NT_STATUS_INVALID_PARAMETER;
967 /* We must store this blob until complete. */
968 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
969 return NT_STATUS_NO_MEMORY;
971 pad->needed_len = needed_len - pblob->length;
972 pad->partial_data = data_blob(pblob->data, pblob->length);
973 if (pad->partial_data.data == NULL) {
975 return NT_STATUS_NO_MEMORY;
977 pad->smbpid = smbpid;
979 DLIST_ADD(sconn->smb1.pd_list, pad);
981 return NT_STATUS_MORE_PROCESSING_REQUIRED;
984 /****************************************************************************
985 Reply to a session setup command.
986 conn POINTER CAN BE NULL HERE !
987 ****************************************************************************/
989 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
995 const char *native_os;
996 const char *native_lanman;
997 const char *primary_domain;
999 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1000 enum remote_arch_types ra_type = get_remote_arch();
1001 int vuid = req->vuid;
1002 user_struct *vuser = NULL;
1003 NTSTATUS status = NT_STATUS_OK;
1004 uint16 smbpid = req->smbpid;
1005 struct smbd_server_connection *sconn = req->sconn;
1007 DEBUG(3,("Doing spnego session setup\n"));
1009 if (global_client_caps == 0) {
1010 global_client_caps = IVAL(req->vwv+10, 0);
1012 if (!(global_client_caps & CAP_STATUS32)) {
1013 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1020 if (data_blob_len == 0) {
1021 /* an invalid request */
1022 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1026 bufrem = smbreq_bufrem(req, p);
1027 /* pull the spnego blob */
1028 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1031 file_save("negotiate.dat", blob1.data, blob1.length);
1034 p2 = (const char *)req->buf + blob1.length;
1036 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1038 native_os = tmp ? tmp : "";
1040 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1042 native_lanman = tmp ? tmp : "";
1044 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1046 primary_domain = tmp ? tmp : "";
1048 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1049 native_os, native_lanman, primary_domain));
1051 if ( ra_type == RA_WIN2K ) {
1052 /* Vista sets neither the OS or lanman strings */
1054 if ( !strlen(native_os) && !strlen(native_lanman) )
1055 set_remote_arch(RA_VISTA);
1057 /* Windows 2003 doesn't set the native lanman string,
1058 but does set primary domain which is a bug I think */
1060 if ( !strlen(native_lanman) ) {
1061 ra_lanman_string( primary_domain );
1063 ra_lanman_string( native_lanman );
1065 } else if ( ra_type == RA_VISTA ) {
1066 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1067 set_remote_arch(RA_OSX);
1071 /* Did we get a valid vuid ? */
1072 if (!is_partial_auth_vuid(sconn, vuid)) {
1073 /* No, then try and see if this is an intermediate sessionsetup
1074 * for a large SPNEGO packet. */
1075 struct pending_auth_data *pad;
1076 pad = get_pending_auth_data(sconn, smbpid);
1078 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1079 "pending vuid %u\n",
1080 (unsigned int)pad->vuid ));
1085 /* Do we have a valid vuid now ? */
1086 if (!is_partial_auth_vuid(sconn, vuid)) {
1087 /* No, start a new authentication setup. */
1088 vuid = register_initial_vuid(sconn);
1089 if (vuid == UID_FIELD_INVALID) {
1090 data_blob_free(&blob1);
1091 reply_nterror(req, nt_status_squash(
1092 NT_STATUS_INVALID_PARAMETER));
1097 vuser = get_partial_auth_user_struct(sconn, vuid);
1098 /* This MUST be valid. */
1100 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1103 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1104 * sessionsetup requests as the Windows limit on the security blob
1105 * field is 4k. Bug #4400. JRA.
1108 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1109 if (!NT_STATUS_IS_OK(status)) {
1110 if (!NT_STATUS_EQUAL(status,
1111 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1112 /* Real error - kill the intermediate vuid */
1113 invalidate_vuid(sconn, vuid);
1115 data_blob_free(&blob1);
1116 reply_nterror(req, nt_status_squash(status));
1120 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1122 /* its a negTokenTarg packet */
1124 reply_spnego_negotiate(req, vuid, blob1,
1125 &vuser->auth_ntlmssp_state);
1126 data_blob_free(&blob1);
1130 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1132 /* its a auth packet */
1134 reply_spnego_auth(req, vuid, blob1,
1135 &vuser->auth_ntlmssp_state);
1136 data_blob_free(&blob1);
1140 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1143 if (!vuser->auth_ntlmssp_state) {
1144 status = auth_ntlmssp_start(sconn->remote_address,
1145 &vuser->auth_ntlmssp_state);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 /* Kill the intermediate vuid */
1148 invalidate_vuid(sconn, vuid);
1149 data_blob_free(&blob1);
1150 reply_nterror(req, nt_status_squash(status));
1155 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1159 data_blob_free(&blob1);
1161 reply_spnego_ntlmssp(req, vuid,
1162 &vuser->auth_ntlmssp_state,
1163 &chal, status, OID_NTLMSSP, false);
1164 data_blob_free(&chal);
1168 /* what sort of packet is this? */
1169 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1171 data_blob_free(&blob1);
1173 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1176 /****************************************************************************
1177 On new VC == 0, shutdown *all* old connections and users.
1178 It seems that only NT4.x does this. At W2K and above (XP etc.).
1179 a new session setup with VC==0 is ignored.
1180 ****************************************************************************/
1182 struct shutdown_state {
1184 struct messaging_context *msg_ctx;
1187 static int shutdown_other_smbds(const struct connections_key *key,
1188 const struct connections_data *crec,
1191 struct shutdown_state *state = (struct shutdown_state *)private_data;
1193 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1194 server_id_str(talloc_tos(), &crec->pid), crec->addr));
1196 if (!process_exists(crec->pid)) {
1197 DEBUG(10, ("process does not exist\n"));
1201 if (procid_is_me(&crec->pid)) {
1202 DEBUG(10, ("It's me\n"));
1206 if (strcmp(state->ip, crec->addr) != 0) {
1207 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1211 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1212 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1215 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1220 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1222 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1223 "compatible we would close all old resources.\n"));
1226 invalidate_all_vuids();
1228 if (lp_reset_on_zero_vc()) {
1230 struct shutdown_state state;
1232 addr = tsocket_address_inet_addr_string(
1233 sconn->remote_address, talloc_tos());
1238 state.msg_ctx = sconn->msg_ctx;
1239 connections_forall_read(shutdown_other_smbds, &state);
1244 /****************************************************************************
1245 Reply to a session setup command.
1246 ****************************************************************************/
1248 void reply_sesssetup_and_X(struct smb_request *req)
1254 DATA_BLOB plaintext_password;
1257 fstring sub_user; /* Sanitised username for substituion */
1259 const char *native_os;
1260 const char *native_lanman;
1261 const char *primary_domain;
1262 struct auth_usersupplied_info *user_info = NULL;
1263 struct auth_serversupplied_info *server_info = NULL;
1264 struct auth_session_info *session_info = NULL;
1265 uint16 smb_flag2 = req->flags2;
1268 struct smbd_server_connection *sconn = req->sconn;
1270 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1272 START_PROFILE(SMBsesssetupX);
1274 ZERO_STRUCT(lm_resp);
1275 ZERO_STRUCT(nt_resp);
1276 ZERO_STRUCT(plaintext_password);
1278 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1280 /* a SPNEGO session setup has 12 command words, whereas a normal
1281 NT1 session setup has 13. See the cifs spec. */
1282 if (req->wct == 12 &&
1283 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1285 if (!sconn->smb1.negprot.spnego) {
1286 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1287 "at SPNEGO session setup when it was not "
1289 reply_nterror(req, nt_status_squash(
1290 NT_STATUS_LOGON_FAILURE));
1291 END_PROFILE(SMBsesssetupX);
1295 if (SVAL(req->vwv+4, 0) == 0) {
1296 setup_new_vc_session(req->sconn);
1299 reply_sesssetup_and_X_spnego(req);
1300 END_PROFILE(SMBsesssetupX);
1304 smb_bufsize = SVAL(req->vwv+2, 0);
1306 if (get_Protocol() < PROTOCOL_NT1) {
1307 uint16 passlen1 = SVAL(req->vwv+7, 0);
1309 /* Never do NT status codes with protocols before NT1 as we
1310 * don't get client caps. */
1311 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1313 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1314 reply_nterror(req, nt_status_squash(
1315 NT_STATUS_INVALID_PARAMETER));
1316 END_PROFILE(SMBsesssetupX);
1321 lm_resp = data_blob(req->buf, passlen1);
1323 plaintext_password = data_blob(req->buf, passlen1+1);
1324 /* Ensure null termination */
1325 plaintext_password.data[passlen1] = 0;
1328 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1329 req->buf + passlen1, STR_TERMINATE);
1330 user = tmp ? tmp : "";
1335 uint16 passlen1 = SVAL(req->vwv+7, 0);
1336 uint16 passlen2 = SVAL(req->vwv+8, 0);
1337 enum remote_arch_types ra_type = get_remote_arch();
1338 const uint8_t *p = req->buf;
1339 const uint8_t *save_p = req->buf;
1343 if(global_client_caps == 0) {
1344 global_client_caps = IVAL(req->vwv+11, 0);
1346 if (!(global_client_caps & CAP_STATUS32)) {
1347 remove_from_common_flags2(
1348 FLAGS2_32_BIT_ERROR_CODES);
1351 /* client_caps is used as final determination if
1352 * client is NT or Win95. This is needed to return
1353 * the correct error codes in some circumstances.
1356 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1357 ra_type == RA_WIN95) {
1358 if(!(global_client_caps & (CAP_NT_SMBS|
1360 set_remote_arch( RA_WIN95);
1366 /* both Win95 and WinNT stuff up the password
1367 * lengths for non-encrypting systems. Uggh.
1369 if passlen1==24 its a win95 system, and its setting
1370 the password length incorrectly. Luckily it still
1371 works with the default code because Win95 will null
1372 terminate the password anyway
1374 if passlen1>0 and passlen2>0 then maybe its a NT box
1375 and its setting passlen2 to some random value which
1376 really stuffs things up. we need to fix that one. */
1378 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1384 /* check for nasty tricks */
1385 if (passlen1 > MAX_PASS_LEN
1386 || passlen1 > smbreq_bufrem(req, p)) {
1387 reply_nterror(req, nt_status_squash(
1388 NT_STATUS_INVALID_PARAMETER));
1389 END_PROFILE(SMBsesssetupX);
1393 if (passlen2 > MAX_PASS_LEN
1394 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1395 reply_nterror(req, nt_status_squash(
1396 NT_STATUS_INVALID_PARAMETER));
1397 END_PROFILE(SMBsesssetupX);
1401 /* Save the lanman2 password and the NT md4 password. */
1403 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1408 lm_resp = data_blob(p, passlen1);
1409 nt_resp = data_blob(p+passlen1, passlen2);
1410 } else if (lp_security() != SEC_SHARE) {
1412 * In share level we should ignore any passwords, so
1413 * only read them if we're not.
1416 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1418 if (unic && (passlen2 == 0) && passlen1) {
1419 /* Only a ascii plaintext password was sent. */
1420 (void)srvstr_pull_talloc(talloc_tos(),
1426 STR_TERMINATE|STR_ASCII);
1428 (void)srvstr_pull_talloc(talloc_tos(),
1433 unic ? passlen2 : passlen1,
1437 reply_nterror(req, nt_status_squash(
1438 NT_STATUS_INVALID_PARAMETER));
1439 END_PROFILE(SMBsesssetupX);
1442 plaintext_password = data_blob(pass, strlen(pass)+1);
1445 p += passlen1 + passlen2;
1447 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1449 user = tmp ? tmp : "";
1451 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1453 domain = tmp ? tmp : "";
1455 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1457 native_os = tmp ? tmp : "";
1459 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1461 native_lanman = tmp ? tmp : "";
1463 /* not documented or decoded by Ethereal but there is one more
1464 * string in the extra bytes which is the same as the
1465 * PrimaryDomain when using extended security. Windows NT 4
1466 * and 2003 use this string to store the native lanman string.
1467 * Windows 9x does not include a string here at all so we have
1468 * to check if we have any extra bytes left */
1470 byte_count = SVAL(req->vwv+13, 0);
1471 if ( PTR_DIFF(p, save_p) < byte_count) {
1472 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1474 primary_domain = tmp ? tmp : "";
1476 primary_domain = talloc_strdup(talloc_tos(), "null");
1479 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1480 "PrimaryDomain=[%s]\n",
1481 domain, native_os, native_lanman, primary_domain));
1483 if ( ra_type == RA_WIN2K ) {
1484 if ( strlen(native_lanman) == 0 )
1485 ra_lanman_string( primary_domain );
1487 ra_lanman_string( native_lanman );
1492 if (SVAL(req->vwv+4, 0) == 0) {
1493 setup_new_vc_session(req->sconn);
1496 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1497 domain, user, get_remote_machine_name()));
1500 if (sconn->smb1.negprot.spnego) {
1502 /* This has to be here, because this is a perfectly
1503 * valid behaviour for guest logons :-( */
1505 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1506 "at 'normal' session setup after "
1507 "negotiating spnego.\n"));
1508 reply_nterror(req, nt_status_squash(
1509 NT_STATUS_LOGON_FAILURE));
1510 END_PROFILE(SMBsesssetupX);
1513 fstrcpy(sub_user, user);
1515 fstrcpy(sub_user, lp_guestaccount());
1518 sub_set_smb_name(sub_user);
1520 reload_services(sconn->msg_ctx, sconn->sock, True);
1522 if (lp_security() == SEC_SHARE) {
1523 char *sub_user_mapped = NULL;
1524 /* In share level we should ignore any passwords */
1526 data_blob_free(&lm_resp);
1527 data_blob_free(&nt_resp);
1528 data_blob_clear_free(&plaintext_password);
1530 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1531 if (!sub_user_mapped) {
1532 reply_nterror(req, NT_STATUS_NO_MEMORY);
1533 END_PROFILE(SMBsesssetupX);
1536 fstrcpy(sub_user, sub_user_mapped);
1537 add_session_user(sconn, sub_user);
1538 add_session_workgroup(sconn, domain);
1539 /* Then force it to null for the benfit of the code below */
1545 nt_status = check_guest_password(sconn->remote_address, &server_info);
1547 } else if (doencrypt) {
1548 struct auth_context *negprot_auth_context = NULL;
1549 negprot_auth_context = sconn->smb1.negprot.auth_context;
1550 if (!negprot_auth_context) {
1551 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1552 "session setup without negprot denied!\n"));
1553 reply_nterror(req, nt_status_squash(
1554 NT_STATUS_LOGON_FAILURE));
1555 END_PROFILE(SMBsesssetupX);
1558 nt_status = make_user_info_for_reply_enc(&user_info, user,
1560 sconn->remote_address,
1562 if (NT_STATUS_IS_OK(nt_status)) {
1563 nt_status = negprot_auth_context->check_ntlm_password(
1564 negprot_auth_context,
1569 struct auth_context *plaintext_auth_context = NULL;
1571 nt_status = make_auth_context_subsystem(
1572 talloc_tos(), &plaintext_auth_context);
1574 if (NT_STATUS_IS_OK(nt_status)) {
1577 plaintext_auth_context->get_ntlm_challenge(
1578 plaintext_auth_context, chal);
1580 if (!make_user_info_for_reply(&user_info,
1582 sconn->remote_address,
1584 plaintext_password)) {
1585 nt_status = NT_STATUS_NO_MEMORY;
1588 if (NT_STATUS_IS_OK(nt_status)) {
1589 nt_status = plaintext_auth_context->check_ntlm_password(
1590 plaintext_auth_context,
1594 TALLOC_FREE(plaintext_auth_context);
1599 free_user_info(&user_info);
1601 if (!NT_STATUS_IS_OK(nt_status)) {
1602 nt_status = do_map_to_guest_server_info(nt_status, &server_info,
1606 if (!NT_STATUS_IS_OK(nt_status)) {
1607 data_blob_free(&nt_resp);
1608 data_blob_free(&lm_resp);
1609 data_blob_clear_free(&plaintext_password);
1610 reply_nterror(req, nt_status_squash(nt_status));
1611 END_PROFILE(SMBsesssetupX);
1615 nt_status = create_local_token(req, server_info, NULL, &session_info);
1616 TALLOC_FREE(server_info);
1618 if (!NT_STATUS_IS_OK(nt_status)) {
1619 DEBUG(10, ("create_local_token failed: %s\n",
1620 nt_errstr(nt_status)));
1621 data_blob_free(&nt_resp);
1622 data_blob_free(&lm_resp);
1623 data_blob_clear_free(&plaintext_password);
1624 reply_nterror(req, nt_status_squash(nt_status));
1625 END_PROFILE(SMBsesssetupX);
1629 data_blob_clear_free(&plaintext_password);
1631 /* it's ok - setup a reply */
1632 reply_outbuf(req, 3, 0);
1633 if (get_Protocol() >= PROTOCOL_NT1) {
1634 push_signature(&req->outbuf);
1635 /* perhaps grab OS version here?? */
1638 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
1639 SSVAL(req->outbuf,smb_vwv2,1);
1642 /* register the name and uid as being validated, so further connections
1643 to a uid can get through without a password, on the same VC */
1645 if (lp_security() == SEC_SHARE) {
1646 sess_vuid = UID_FIELD_INVALID;
1647 TALLOC_FREE(session_info);
1649 /* Ignore the initial vuid. */
1650 sess_vuid = register_initial_vuid(sconn);
1651 if (sess_vuid == UID_FIELD_INVALID) {
1652 data_blob_free(&nt_resp);
1653 data_blob_free(&lm_resp);
1654 reply_nterror(req, nt_status_squash(
1655 NT_STATUS_LOGON_FAILURE));
1656 END_PROFILE(SMBsesssetupX);
1659 /* register_existing_vuid keeps the session_info */
1660 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1662 nt_resp.data ? nt_resp : lm_resp,
1664 if (sess_vuid == UID_FIELD_INVALID) {
1665 data_blob_free(&nt_resp);
1666 data_blob_free(&lm_resp);
1667 reply_nterror(req, nt_status_squash(
1668 NT_STATUS_LOGON_FAILURE));
1669 END_PROFILE(SMBsesssetupX);
1673 /* current_user_info is changed on new vuid */
1674 reload_services(sconn->msg_ctx, sconn->sock, True);
1677 data_blob_free(&nt_resp);
1678 data_blob_free(&lm_resp);
1680 SSVAL(req->outbuf,smb_uid,sess_vuid);
1681 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1682 req->vuid = sess_vuid;
1684 if (!sconn->smb1.sessions.done_sesssetup) {
1685 sconn->smb1.sessions.max_send =
1686 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1688 sconn->smb1.sessions.done_sesssetup = true;
1690 END_PROFILE(SMBsesssetupX);