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/smbd.h"
27 #include "smbd/globals.h"
28 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "ntlmssp_wrap.h"
31 #include "librpc/gen_ndr/messaging.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "libads/kerberos_proto.h"
34 #include "../lib/util/asn1.h"
36 /* For split krb5 SPNEGO blobs. */
37 struct pending_auth_data {
38 struct pending_auth_data *prev, *next;
39 uint16 vuid; /* Tag for this entry. */
40 uint16 smbpid; /* Alternate tag for this entry. */
42 DATA_BLOB partial_data;
46 on a logon error possibly map the error to success if "map to guest"
49 NTSTATUS do_map_to_guest(NTSTATUS status,
50 struct auth_serversupplied_info **server_info,
51 const char *user, const char *domain)
53 user = user ? user : "";
54 domain = domain ? domain : "";
56 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
57 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
58 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
59 DEBUG(3,("No such user %s [%s] - using guest account\n",
61 status = make_server_info_guest(NULL, server_info);
65 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
66 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
67 DEBUG(3,("Registered username %s for guest access\n",
69 status = make_server_info_guest(NULL, server_info);
76 /****************************************************************************
77 Add the standard 'Samba' signature to the end of the session setup.
78 ****************************************************************************/
80 static int push_signature(uint8 **outbuf)
87 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
89 if (tmp == -1) return -1;
92 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
93 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
97 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
100 if (tmp == -1) return -1;
103 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
105 if (tmp == -1) return -1;
111 /****************************************************************************
112 Send a security blob via a session setup reply.
113 ****************************************************************************/
115 static void reply_sesssetup_blob(struct smb_request *req,
119 if (!NT_STATUS_IS_OK(nt_status) &&
120 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
121 reply_nterror(req, nt_status_squash(nt_status));
125 nt_status = nt_status_squash(nt_status);
126 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
127 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
128 SSVAL(req->outbuf, smb_vwv3, blob.length);
130 if ((message_push_blob(&req->outbuf, blob) == -1)
131 || (push_signature(&req->outbuf) == -1)) {
132 reply_nterror(req, NT_STATUS_NO_MEMORY);
136 /****************************************************************************
137 Do a 'guest' logon, getting back the
138 ****************************************************************************/
140 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
142 struct auth_context *auth_context;
143 struct auth_usersupplied_info *user_info = NULL;
146 static unsigned char chal[8] = { 0, };
148 DEBUG(3,("Got anonymous request\n"));
150 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
151 if (!NT_STATUS_IS_OK(nt_status)) {
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->security_token ) {
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 /* Set the kerberos-derived session key onto the server_info */
409 server_info->user_session_key = session_key;
410 talloc_steal(server_info, session_key.data);
412 session_key = data_blob_null;
414 /* register_existing_vuid keeps the server info */
415 /* register_existing_vuid takes ownership of session_key on success,
416 * no need to free after this on success. A better interface would copy
419 sess_vuid = register_existing_vuid(sconn, sess_vuid,
420 server_info, nullblob, user);
422 reply_outbuf(req, 4, 0);
423 SSVAL(req->outbuf,smb_uid,sess_vuid);
425 if (sess_vuid == UID_FIELD_INVALID ) {
426 ret = NT_STATUS_LOGON_FAILURE;
428 /* current_user_info is changed on new vuid */
429 reload_services(sconn->msg_ctx, sconn->sock, True);
431 SSVAL(req->outbuf, smb_vwv3, 0);
433 if (server_info->guest) {
434 SSVAL(req->outbuf,smb_vwv2,1);
437 SSVAL(req->outbuf, smb_uid, sess_vuid);
439 /* Successful logon. Keep this vuid. */
440 *p_invalidate_vuid = False;
443 /* wrap that up in a nice GSS-API wrapping */
444 if (NT_STATUS_IS_OK(ret)) {
445 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
448 ap_rep_wrapped = data_blob_null;
450 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
452 reply_sesssetup_blob(req, response, ret);
454 data_blob_free(&ap_rep);
455 data_blob_free(&ap_rep_wrapped);
456 data_blob_free(&response);
457 TALLOC_FREE(mem_ctx);
462 /****************************************************************************
463 Send a session setup reply, wrapped in SPNEGO.
464 Get vuid and check first.
465 End the NTLMSSP exchange context if we are OK/complete fail
466 This should be split into two functions, one to handle each
467 leg of the NTLM auth steps.
468 ***************************************************************************/
470 static void reply_spnego_ntlmssp(struct smb_request *req,
472 struct auth_ntlmssp_state **auth_ntlmssp_state,
473 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
477 bool do_invalidate = true;
479 struct auth_serversupplied_info *session_info = NULL;
480 struct smbd_server_connection *sconn = req->sconn;
482 if (NT_STATUS_IS_OK(nt_status)) {
483 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
484 (*auth_ntlmssp_state), &session_info);
486 /* Note that this session_info won't have a session
487 * key. But for map to guest, that's exactly the right
488 * thing - we can't reasonably guess the key the
489 * client wants, as the password was wrong */
490 nt_status = do_map_to_guest(nt_status,
492 auth_ntlmssp_get_username(*auth_ntlmssp_state),
493 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
496 reply_outbuf(req, 4, 0);
498 SSVAL(req->outbuf, smb_uid, vuid);
500 if (NT_STATUS_IS_OK(nt_status)) {
501 DATA_BLOB nullblob = data_blob_null;
503 if (!is_partial_auth_vuid(sconn, vuid)) {
504 nt_status = NT_STATUS_LOGON_FAILURE;
508 /* register_existing_vuid keeps the server info */
509 if (register_existing_vuid(sconn, vuid,
510 session_info, nullblob,
511 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
513 /* The problem is, *auth_ntlmssp_state points
514 * into the vuser this will have
515 * talloc_free()'ed in
516 * register_existing_vuid() */
517 do_invalidate = false;
518 nt_status = NT_STATUS_LOGON_FAILURE;
522 /* current_user_info is changed on new vuid */
523 reload_services(sconn->msg_ctx, sconn->sock, True);
525 SSVAL(req->outbuf, smb_vwv3, 0);
527 if (session_info->guest) {
528 SSVAL(req->outbuf,smb_vwv2,1);
535 response = spnego_gen_auth_response(talloc_tos(),
539 response = *ntlmssp_blob;
542 reply_sesssetup_blob(req, response, nt_status);
544 data_blob_free(&response);
547 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
548 and the other end, that we are not finished yet. */
550 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
551 /* NB. This is *NOT* an error case. JRA */
553 TALLOC_FREE(*auth_ntlmssp_state);
554 if (!NT_STATUS_IS_OK(nt_status)) {
555 /* Kill the intermediate vuid */
556 invalidate_vuid(sconn, vuid);
562 /****************************************************************************
563 Is this a krb5 mechanism ?
564 ****************************************************************************/
566 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
568 DATA_BLOB *pblob_out,
571 char *OIDs[ASN1_MAX_OIDS];
573 NTSTATUS ret = NT_STATUS_OK;
575 *kerb_mechOID = NULL;
577 /* parse out the OIDs and the first sec blob */
578 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
580 return NT_STATUS_LOGON_FAILURE;
583 /* only look at the first OID for determining the mechToken --
584 according to RFC2478, we should choose the one we want
585 and renegotiate, but i smell a client bug here..
587 Problem observed when connecting to a member (samba box)
588 of an AD domain as a user in a Samba domain. Samba member
589 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
590 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
591 NTLMSSP mechtoken. --jerry */
594 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
595 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
596 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
597 if (*kerb_mechOID == NULL) {
598 ret = NT_STATUS_NO_MEMORY;
603 for (i=0;OIDs[i];i++) {
604 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
605 talloc_free(OIDs[i]);
610 /****************************************************************************
611 Fall back from krb5 to NTLMSSP.
612 ****************************************************************************/
614 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
619 reply_outbuf(req, 4, 0);
620 SSVAL(req->outbuf,smb_uid,vuid);
622 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
623 "but set to downgrade to NTLMSSP\n"));
625 response = spnego_gen_auth_response(talloc_tos(), NULL,
626 NT_STATUS_MORE_PROCESSING_REQUIRED,
628 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
629 data_blob_free(&response);
632 /****************************************************************************
633 Reply to a session setup spnego negotiate packet.
634 ****************************************************************************/
636 static void reply_spnego_negotiate(struct smb_request *req,
639 struct auth_ntlmssp_state **auth_ntlmssp_state)
643 char *kerb_mech = NULL;
645 struct smbd_server_connection *sconn = req->sconn;
647 status = parse_spnego_mechanisms(talloc_tos(),
648 blob1, &secblob, &kerb_mech);
649 if (!NT_STATUS_IS_OK(status)) {
650 /* Kill the intermediate vuid */
651 invalidate_vuid(sconn, vuid);
652 reply_nterror(req, nt_status_squash(status));
656 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
657 (unsigned long)secblob.length));
660 if (kerb_mech && ((lp_security()==SEC_ADS) ||
661 USE_KERBEROS_KEYTAB) ) {
662 bool destroy_vuid = True;
663 reply_spnego_kerberos(req, &secblob, kerb_mech,
664 vuid, &destroy_vuid);
665 data_blob_free(&secblob);
667 /* Kill the intermediate vuid */
668 invalidate_vuid(sconn, vuid);
670 TALLOC_FREE(kerb_mech);
675 if (*auth_ntlmssp_state) {
676 TALLOC_FREE(*auth_ntlmssp_state);
680 data_blob_free(&secblob);
681 /* The mechtoken is a krb5 ticket, but
682 * we need to fall back to NTLM. */
683 reply_spnego_downgrade_to_ntlmssp(req, vuid);
684 TALLOC_FREE(kerb_mech);
688 status = auth_ntlmssp_start(auth_ntlmssp_state);
689 if (!NT_STATUS_IS_OK(status)) {
690 /* Kill the intermediate vuid */
691 invalidate_vuid(sconn, vuid);
692 reply_nterror(req, nt_status_squash(status));
696 status = auth_ntlmssp_update(*auth_ntlmssp_state,
699 data_blob_free(&secblob);
701 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
702 &chal, status, OID_NTLMSSP, true);
704 data_blob_free(&chal);
706 /* already replied */
710 /****************************************************************************
711 Reply to a session setup spnego auth packet.
712 ****************************************************************************/
714 static void reply_spnego_auth(struct smb_request *req,
717 struct auth_ntlmssp_state **auth_ntlmssp_state)
719 DATA_BLOB auth = data_blob_null;
720 DATA_BLOB auth_reply = data_blob_null;
721 DATA_BLOB secblob = data_blob_null;
722 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
723 struct smbd_server_connection *sconn = req->sconn;
725 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
727 file_save("auth.dat", blob1.data, blob1.length);
729 /* Kill the intermediate vuid */
730 invalidate_vuid(sconn, vuid);
732 reply_nterror(req, nt_status_squash(
733 NT_STATUS_LOGON_FAILURE));
737 if (auth.data[0] == ASN1_APPLICATION(0)) {
738 /* Might be a second negTokenTarg packet */
739 char *kerb_mech = NULL;
741 status = parse_spnego_mechanisms(talloc_tos(),
742 auth, &secblob, &kerb_mech);
744 if (!NT_STATUS_IS_OK(status)) {
745 /* Kill the intermediate vuid */
746 invalidate_vuid(sconn, vuid);
747 reply_nterror(req, nt_status_squash(status));
751 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
752 (unsigned long)secblob.length));
754 if (kerb_mech && ((lp_security()==SEC_ADS) ||
755 USE_KERBEROS_KEYTAB)) {
756 bool destroy_vuid = True;
757 reply_spnego_kerberos(req, &secblob, kerb_mech,
758 vuid, &destroy_vuid);
759 data_blob_free(&secblob);
760 data_blob_free(&auth);
762 /* Kill the intermediate vuid */
763 invalidate_vuid(sconn, vuid);
765 TALLOC_FREE(kerb_mech);
769 /* Can't blunder into NTLMSSP auth if we have
773 /* Kill the intermediate vuid */
774 invalidate_vuid(sconn, vuid);
775 DEBUG(3,("reply_spnego_auth: network "
776 "misconfiguration, client sent us a "
777 "krb5 ticket and kerberos security "
779 reply_nterror(req, nt_status_squash(
780 NT_STATUS_LOGON_FAILURE));
781 TALLOC_FREE(kerb_mech);
785 /* If we get here it wasn't a negTokenTarg auth packet. */
786 data_blob_free(&secblob);
788 if (!*auth_ntlmssp_state) {
789 status = auth_ntlmssp_start(auth_ntlmssp_state);
790 if (!NT_STATUS_IS_OK(status)) {
791 /* Kill the intermediate vuid */
792 invalidate_vuid(sconn, vuid);
793 reply_nterror(req, nt_status_squash(status));
798 status = auth_ntlmssp_update(*auth_ntlmssp_state,
801 data_blob_free(&auth);
803 /* Don't send the mechid as we've already sent this (RFC4178). */
805 reply_spnego_ntlmssp(req, vuid,
807 &auth_reply, status, NULL, true);
809 data_blob_free(&auth_reply);
811 /* and tell smbd that we have already replied to this packet */
815 /****************************************************************************
816 Delete an entry on the list.
817 ****************************************************************************/
819 static void delete_partial_auth(struct smbd_server_connection *sconn,
820 struct pending_auth_data *pad)
825 DLIST_REMOVE(sconn->smb1.pd_list, pad);
826 data_blob_free(&pad->partial_data);
830 /****************************************************************************
831 Search for a partial SPNEGO auth fragment matching an smbpid.
832 ****************************************************************************/
834 static struct pending_auth_data *get_pending_auth_data(
835 struct smbd_server_connection *sconn,
838 struct pending_auth_data *pad;
840 * NOTE: using the smbpid here is completely wrong...
842 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
844 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
845 if (pad->smbpid == smbpid) {
852 /****************************************************************************
853 Check the size of an SPNEGO blob. If we need more return
854 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
855 the blob to be more than 64k.
856 ****************************************************************************/
858 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
859 uint16 smbpid, uint16 vuid,
862 struct pending_auth_data *pad = NULL;
864 size_t needed_len = 0;
866 pad = get_pending_auth_data(sconn, smbpid);
868 /* Ensure we have some data. */
869 if (pblob->length == 0) {
870 /* Caller can cope. */
871 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
872 delete_partial_auth(sconn, pad);
876 /* Were we waiting for more data ? */
879 size_t copy_len = MIN(65536, pblob->length);
881 /* Integer wrap paranoia.... */
883 if (pad->partial_data.length + copy_len <
884 pad->partial_data.length ||
885 pad->partial_data.length + copy_len < copy_len) {
887 DEBUG(2,("check_spnego_blob_complete: integer wrap "
888 "pad->partial_data.length = %u, "
890 (unsigned int)pad->partial_data.length,
891 (unsigned int)copy_len ));
893 delete_partial_auth(sconn, pad);
894 return NT_STATUS_INVALID_PARAMETER;
897 DEBUG(10,("check_spnego_blob_complete: "
898 "pad->partial_data.length = %u, "
899 "pad->needed_len = %u, "
901 "pblob->length = %u,\n",
902 (unsigned int)pad->partial_data.length,
903 (unsigned int)pad->needed_len,
904 (unsigned int)copy_len,
905 (unsigned int)pblob->length ));
907 tmp_blob = data_blob(NULL,
908 pad->partial_data.length + copy_len);
910 /* Concatenate the two (up to copy_len) bytes. */
911 memcpy(tmp_blob.data,
912 pad->partial_data.data,
913 pad->partial_data.length);
914 memcpy(tmp_blob.data + pad->partial_data.length,
918 /* Replace the partial data. */
919 data_blob_free(&pad->partial_data);
920 pad->partial_data = tmp_blob;
921 ZERO_STRUCT(tmp_blob);
924 if (pblob->length >= pad->needed_len) {
925 /* Yes, replace pblob. */
926 data_blob_free(pblob);
927 *pblob = pad->partial_data;
928 ZERO_STRUCT(pad->partial_data);
929 delete_partial_auth(sconn, pad);
933 /* Still need more data. */
934 pad->needed_len -= copy_len;
935 return NT_STATUS_MORE_PROCESSING_REQUIRED;
938 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
939 (pblob->data[0] != ASN1_CONTEXT(1))) {
940 /* Not something we can determine the
946 /* This is a new SPNEGO sessionsetup - see if
947 * the data given in this blob is enough.
950 data = asn1_init(NULL);
952 return NT_STATUS_NO_MEMORY;
955 asn1_load(data, *pblob);
956 asn1_start_tag(data, pblob->data[0]);
957 if (data->has_error || data->nesting == NULL) {
959 /* Let caller catch. */
963 /* Integer wrap paranoia.... */
965 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
966 data->nesting->taglen + data->nesting->start < data->nesting->start) {
968 DEBUG(2,("check_spnego_blob_complete: integer wrap "
969 "data.nesting->taglen = %u, "
970 "data.nesting->start = %u\n",
971 (unsigned int)data->nesting->taglen,
972 (unsigned int)data->nesting->start ));
975 return NT_STATUS_INVALID_PARAMETER;
978 /* Total length of the needed asn1 is the tag length
979 * plus the current offset. */
981 needed_len = data->nesting->taglen + data->nesting->start;
984 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
985 "pblob->length = %u\n",
986 (unsigned int)needed_len,
987 (unsigned int)pblob->length ));
989 if (needed_len <= pblob->length) {
990 /* Nothing to do - blob is complete. */
994 /* Refuse the blob if it's bigger than 64k. */
995 if (needed_len > 65536) {
996 DEBUG(2,("check_spnego_blob_complete: needed_len "
998 (unsigned int)needed_len ));
999 return NT_STATUS_INVALID_PARAMETER;
1002 /* We must store this blob until complete. */
1003 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1004 return NT_STATUS_NO_MEMORY;
1006 pad->needed_len = needed_len - pblob->length;
1007 pad->partial_data = data_blob(pblob->data, pblob->length);
1008 if (pad->partial_data.data == NULL) {
1010 return NT_STATUS_NO_MEMORY;
1012 pad->smbpid = smbpid;
1014 DLIST_ADD(sconn->smb1.pd_list, pad);
1016 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1019 /****************************************************************************
1020 Reply to a session setup command.
1021 conn POINTER CAN BE NULL HERE !
1022 ****************************************************************************/
1024 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1030 const char *native_os;
1031 const char *native_lanman;
1032 const char *primary_domain;
1034 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1035 enum remote_arch_types ra_type = get_remote_arch();
1036 int vuid = req->vuid;
1037 user_struct *vuser = NULL;
1038 NTSTATUS status = NT_STATUS_OK;
1039 uint16 smbpid = req->smbpid;
1040 struct smbd_server_connection *sconn = req->sconn;
1042 DEBUG(3,("Doing spnego session setup\n"));
1044 if (global_client_caps == 0) {
1045 global_client_caps = IVAL(req->vwv+10, 0);
1047 if (!(global_client_caps & CAP_STATUS32)) {
1048 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1055 if (data_blob_len == 0) {
1056 /* an invalid request */
1057 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1061 bufrem = smbreq_bufrem(req, p);
1062 /* pull the spnego blob */
1063 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1066 file_save("negotiate.dat", blob1.data, blob1.length);
1069 p2 = (char *)req->buf + blob1.length;
1071 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1073 native_os = tmp ? tmp : "";
1075 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1077 native_lanman = tmp ? tmp : "";
1079 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1081 primary_domain = tmp ? tmp : "";
1083 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1084 native_os, native_lanman, primary_domain));
1086 if ( ra_type == RA_WIN2K ) {
1087 /* Vista sets neither the OS or lanman strings */
1089 if ( !strlen(native_os) && !strlen(native_lanman) )
1090 set_remote_arch(RA_VISTA);
1092 /* Windows 2003 doesn't set the native lanman string,
1093 but does set primary domain which is a bug I think */
1095 if ( !strlen(native_lanman) ) {
1096 ra_lanman_string( primary_domain );
1098 ra_lanman_string( native_lanman );
1100 } else if ( ra_type == RA_VISTA ) {
1101 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1102 set_remote_arch(RA_OSX);
1106 /* Did we get a valid vuid ? */
1107 if (!is_partial_auth_vuid(sconn, vuid)) {
1108 /* No, then try and see if this is an intermediate sessionsetup
1109 * for a large SPNEGO packet. */
1110 struct pending_auth_data *pad;
1111 pad = get_pending_auth_data(sconn, smbpid);
1113 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1114 "pending vuid %u\n",
1115 (unsigned int)pad->vuid ));
1120 /* Do we have a valid vuid now ? */
1121 if (!is_partial_auth_vuid(sconn, vuid)) {
1122 /* No, start a new authentication setup. */
1123 vuid = register_initial_vuid(sconn);
1124 if (vuid == UID_FIELD_INVALID) {
1125 data_blob_free(&blob1);
1126 reply_nterror(req, nt_status_squash(
1127 NT_STATUS_INVALID_PARAMETER));
1132 vuser = get_partial_auth_user_struct(sconn, vuid);
1133 /* This MUST be valid. */
1135 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1138 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1139 * sessionsetup requests as the Windows limit on the security blob
1140 * field is 4k. Bug #4400. JRA.
1143 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1144 if (!NT_STATUS_IS_OK(status)) {
1145 if (!NT_STATUS_EQUAL(status,
1146 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1147 /* Real error - kill the intermediate vuid */
1148 invalidate_vuid(sconn, vuid);
1150 data_blob_free(&blob1);
1151 reply_nterror(req, nt_status_squash(status));
1155 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1157 /* its a negTokenTarg packet */
1159 reply_spnego_negotiate(req, vuid, blob1,
1160 &vuser->auth_ntlmssp_state);
1161 data_blob_free(&blob1);
1165 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1167 /* its a auth packet */
1169 reply_spnego_auth(req, vuid, blob1,
1170 &vuser->auth_ntlmssp_state);
1171 data_blob_free(&blob1);
1175 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1178 if (!vuser->auth_ntlmssp_state) {
1179 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1180 if (!NT_STATUS_IS_OK(status)) {
1181 /* Kill the intermediate vuid */
1182 invalidate_vuid(sconn, vuid);
1183 data_blob_free(&blob1);
1184 reply_nterror(req, nt_status_squash(status));
1189 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1192 data_blob_free(&blob1);
1194 reply_spnego_ntlmssp(req, vuid,
1195 &vuser->auth_ntlmssp_state,
1196 &chal, status, OID_NTLMSSP, false);
1197 data_blob_free(&chal);
1201 /* what sort of packet is this? */
1202 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1204 data_blob_free(&blob1);
1206 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1209 /****************************************************************************
1210 On new VC == 0, shutdown *all* old connections and users.
1211 It seems that only NT4.x does this. At W2K and above (XP etc.).
1212 a new session setup with VC==0 is ignored.
1213 ****************************************************************************/
1215 struct shutdown_state {
1217 struct messaging_context *msg_ctx;
1220 static int shutdown_other_smbds(const struct connections_key *key,
1221 const struct connections_data *crec,
1224 struct shutdown_state *state = (struct shutdown_state *)private_data;
1226 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1227 procid_str(talloc_tos(), &crec->pid), crec->addr));
1229 if (!process_exists(crec->pid)) {
1230 DEBUG(10, ("process does not exist\n"));
1234 if (procid_is_me(&crec->pid)) {
1235 DEBUG(10, ("It's me\n"));
1239 if (strcmp(state->ip, crec->addr) != 0) {
1240 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1244 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1245 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1248 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1253 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1255 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1256 "compatible we would close all old resources.\n"));
1259 invalidate_all_vuids();
1261 if (lp_reset_on_zero_vc()) {
1263 struct shutdown_state state;
1265 addr = tsocket_address_inet_addr_string(
1266 sconn->remote_address, talloc_tos());
1271 state.msg_ctx = sconn->msg_ctx;
1272 connections_forall_read(shutdown_other_smbds, &state);
1277 /****************************************************************************
1278 Reply to a session setup command.
1279 ****************************************************************************/
1281 void reply_sesssetup_and_X(struct smb_request *req)
1287 DATA_BLOB plaintext_password;
1290 fstring sub_user; /* Sanitised username for substituion */
1292 const char *native_os;
1293 const char *native_lanman;
1294 const char *primary_domain;
1295 struct auth_usersupplied_info *user_info = NULL;
1296 struct auth_serversupplied_info *server_info = NULL;
1297 uint16 smb_flag2 = req->flags2;
1300 struct smbd_server_connection *sconn = req->sconn;
1302 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1304 START_PROFILE(SMBsesssetupX);
1306 ZERO_STRUCT(lm_resp);
1307 ZERO_STRUCT(nt_resp);
1308 ZERO_STRUCT(plaintext_password);
1310 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1312 /* a SPNEGO session setup has 12 command words, whereas a normal
1313 NT1 session setup has 13. See the cifs spec. */
1314 if (req->wct == 12 &&
1315 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1317 if (!sconn->smb1.negprot.spnego) {
1318 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1319 "at SPNEGO session setup when it was not "
1321 reply_nterror(req, nt_status_squash(
1322 NT_STATUS_LOGON_FAILURE));
1323 END_PROFILE(SMBsesssetupX);
1327 if (SVAL(req->vwv+4, 0) == 0) {
1328 setup_new_vc_session(req->sconn);
1331 reply_sesssetup_and_X_spnego(req);
1332 END_PROFILE(SMBsesssetupX);
1336 smb_bufsize = SVAL(req->vwv+2, 0);
1338 if (get_Protocol() < PROTOCOL_NT1) {
1339 uint16 passlen1 = SVAL(req->vwv+7, 0);
1341 /* Never do NT status codes with protocols before NT1 as we
1342 * don't get client caps. */
1343 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1345 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1346 reply_nterror(req, nt_status_squash(
1347 NT_STATUS_INVALID_PARAMETER));
1348 END_PROFILE(SMBsesssetupX);
1353 lm_resp = data_blob(req->buf, passlen1);
1355 plaintext_password = data_blob(req->buf, passlen1+1);
1356 /* Ensure null termination */
1357 plaintext_password.data[passlen1] = 0;
1360 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1361 req->buf + passlen1, STR_TERMINATE);
1362 user = tmp ? tmp : "";
1367 uint16 passlen1 = SVAL(req->vwv+7, 0);
1368 uint16 passlen2 = SVAL(req->vwv+8, 0);
1369 enum remote_arch_types ra_type = get_remote_arch();
1370 const uint8_t *p = req->buf;
1371 const uint8_t *save_p = req->buf;
1375 if(global_client_caps == 0) {
1376 global_client_caps = IVAL(req->vwv+11, 0);
1378 if (!(global_client_caps & CAP_STATUS32)) {
1379 remove_from_common_flags2(
1380 FLAGS2_32_BIT_ERROR_CODES);
1383 /* client_caps is used as final determination if
1384 * client is NT or Win95. This is needed to return
1385 * the correct error codes in some circumstances.
1388 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1389 ra_type == RA_WIN95) {
1390 if(!(global_client_caps & (CAP_NT_SMBS|
1392 set_remote_arch( RA_WIN95);
1398 /* both Win95 and WinNT stuff up the password
1399 * lengths for non-encrypting systems. Uggh.
1401 if passlen1==24 its a win95 system, and its setting
1402 the password length incorrectly. Luckily it still
1403 works with the default code because Win95 will null
1404 terminate the password anyway
1406 if passlen1>0 and passlen2>0 then maybe its a NT box
1407 and its setting passlen2 to some random value which
1408 really stuffs things up. we need to fix that one. */
1410 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1416 /* check for nasty tricks */
1417 if (passlen1 > MAX_PASS_LEN
1418 || passlen1 > smbreq_bufrem(req, p)) {
1419 reply_nterror(req, nt_status_squash(
1420 NT_STATUS_INVALID_PARAMETER));
1421 END_PROFILE(SMBsesssetupX);
1425 if (passlen2 > MAX_PASS_LEN
1426 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1427 reply_nterror(req, nt_status_squash(
1428 NT_STATUS_INVALID_PARAMETER));
1429 END_PROFILE(SMBsesssetupX);
1433 /* Save the lanman2 password and the NT md4 password. */
1435 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1440 lm_resp = data_blob(p, passlen1);
1441 nt_resp = data_blob(p+passlen1, passlen2);
1442 } else if (lp_security() != SEC_SHARE) {
1444 * In share level we should ignore any passwords, so
1445 * only read them if we're not.
1448 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1450 if (unic && (passlen2 == 0) && passlen1) {
1451 /* Only a ascii plaintext password was sent. */
1452 (void)srvstr_pull_talloc(talloc_tos(),
1458 STR_TERMINATE|STR_ASCII);
1460 (void)srvstr_pull_talloc(talloc_tos(),
1465 unic ? passlen2 : passlen1,
1469 reply_nterror(req, nt_status_squash(
1470 NT_STATUS_INVALID_PARAMETER));
1471 END_PROFILE(SMBsesssetupX);
1474 plaintext_password = data_blob(pass, strlen(pass)+1);
1477 p += passlen1 + passlen2;
1479 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1481 user = tmp ? tmp : "";
1483 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1485 domain = tmp ? tmp : "";
1487 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1489 native_os = tmp ? tmp : "";
1491 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1493 native_lanman = tmp ? tmp : "";
1495 /* not documented or decoded by Ethereal but there is one more
1496 * string in the extra bytes which is the same as the
1497 * PrimaryDomain when using extended security. Windows NT 4
1498 * and 2003 use this string to store the native lanman string.
1499 * Windows 9x does not include a string here at all so we have
1500 * to check if we have any extra bytes left */
1502 byte_count = SVAL(req->vwv+13, 0);
1503 if ( PTR_DIFF(p, save_p) < byte_count) {
1504 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1506 primary_domain = tmp ? tmp : "";
1508 primary_domain = talloc_strdup(talloc_tos(), "null");
1511 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1512 "PrimaryDomain=[%s]\n",
1513 domain, native_os, native_lanman, primary_domain));
1515 if ( ra_type == RA_WIN2K ) {
1516 if ( strlen(native_lanman) == 0 )
1517 ra_lanman_string( primary_domain );
1519 ra_lanman_string( native_lanman );
1524 if (SVAL(req->vwv+4, 0) == 0) {
1525 setup_new_vc_session(req->sconn);
1528 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1529 domain, user, get_remote_machine_name()));
1532 if (sconn->smb1.negprot.spnego) {
1534 /* This has to be here, because this is a perfectly
1535 * valid behaviour for guest logons :-( */
1537 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1538 "at 'normal' session setup after "
1539 "negotiating spnego.\n"));
1540 reply_nterror(req, nt_status_squash(
1541 NT_STATUS_LOGON_FAILURE));
1542 END_PROFILE(SMBsesssetupX);
1545 fstrcpy(sub_user, user);
1547 fstrcpy(sub_user, lp_guestaccount());
1550 sub_set_smb_name(sub_user);
1552 reload_services(sconn->msg_ctx, sconn->sock, True);
1554 if (lp_security() == SEC_SHARE) {
1555 char *sub_user_mapped = NULL;
1556 /* In share level we should ignore any passwords */
1558 data_blob_free(&lm_resp);
1559 data_blob_free(&nt_resp);
1560 data_blob_clear_free(&plaintext_password);
1562 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1563 if (!sub_user_mapped) {
1564 reply_nterror(req, NT_STATUS_NO_MEMORY);
1565 END_PROFILE(SMBsesssetupX);
1568 fstrcpy(sub_user, sub_user_mapped);
1569 add_session_user(sconn, sub_user);
1570 add_session_workgroup(sconn, domain);
1571 /* Then force it to null for the benfit of the code below */
1577 nt_status = check_guest_password(&server_info);
1579 } else if (doencrypt) {
1580 struct auth_context *negprot_auth_context = NULL;
1581 negprot_auth_context = sconn->smb1.negprot.auth_context;
1582 if (!negprot_auth_context) {
1583 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1584 "session setup without negprot denied!\n"));
1585 reply_nterror(req, nt_status_squash(
1586 NT_STATUS_LOGON_FAILURE));
1587 END_PROFILE(SMBsesssetupX);
1590 nt_status = make_user_info_for_reply_enc(&user_info, user,
1593 if (NT_STATUS_IS_OK(nt_status)) {
1594 nt_status = negprot_auth_context->check_ntlm_password(
1595 negprot_auth_context,
1600 struct auth_context *plaintext_auth_context = NULL;
1602 nt_status = make_auth_context_subsystem(
1603 talloc_tos(), &plaintext_auth_context);
1605 if (NT_STATUS_IS_OK(nt_status)) {
1608 plaintext_auth_context->get_ntlm_challenge(
1609 plaintext_auth_context, chal);
1611 if (!make_user_info_for_reply(&user_info,
1613 plaintext_password)) {
1614 nt_status = NT_STATUS_NO_MEMORY;
1617 if (NT_STATUS_IS_OK(nt_status)) {
1618 nt_status = plaintext_auth_context->check_ntlm_password(
1619 plaintext_auth_context,
1623 TALLOC_FREE(plaintext_auth_context);
1628 free_user_info(&user_info);
1630 if (!NT_STATUS_IS_OK(nt_status)) {
1631 nt_status = do_map_to_guest(nt_status, &server_info,
1635 if (!NT_STATUS_IS_OK(nt_status)) {
1636 data_blob_free(&nt_resp);
1637 data_blob_free(&lm_resp);
1638 data_blob_clear_free(&plaintext_password);
1639 reply_nterror(req, nt_status_squash(nt_status));
1640 END_PROFILE(SMBsesssetupX);
1644 /* Ensure we can't possible take a code path leading to a
1647 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1648 END_PROFILE(SMBsesssetupX);
1652 if (!server_info->security_token) {
1653 nt_status = create_local_token(server_info);
1655 if (!NT_STATUS_IS_OK(nt_status)) {
1656 DEBUG(10, ("create_local_token failed: %s\n",
1657 nt_errstr(nt_status)));
1658 data_blob_free(&nt_resp);
1659 data_blob_free(&lm_resp);
1660 data_blob_clear_free(&plaintext_password);
1661 reply_nterror(req, nt_status_squash(nt_status));
1662 END_PROFILE(SMBsesssetupX);
1667 data_blob_clear_free(&plaintext_password);
1669 /* it's ok - setup a reply */
1670 reply_outbuf(req, 3, 0);
1671 if (get_Protocol() >= PROTOCOL_NT1) {
1672 push_signature(&req->outbuf);
1673 /* perhaps grab OS version here?? */
1676 if (server_info->guest) {
1677 SSVAL(req->outbuf,smb_vwv2,1);
1680 /* register the name and uid as being validated, so further connections
1681 to a uid can get through without a password, on the same VC */
1683 if (lp_security() == SEC_SHARE) {
1684 sess_vuid = UID_FIELD_INVALID;
1685 TALLOC_FREE(server_info);
1687 /* Ignore the initial vuid. */
1688 sess_vuid = register_initial_vuid(sconn);
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);
1697 /* register_existing_vuid keeps the server info */
1698 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1700 nt_resp.data ? nt_resp : lm_resp,
1702 if (sess_vuid == UID_FIELD_INVALID) {
1703 data_blob_free(&nt_resp);
1704 data_blob_free(&lm_resp);
1705 reply_nterror(req, nt_status_squash(
1706 NT_STATUS_LOGON_FAILURE));
1707 END_PROFILE(SMBsesssetupX);
1711 /* current_user_info is changed on new vuid */
1712 reload_services(sconn->msg_ctx, sconn->sock, True);
1715 data_blob_free(&nt_resp);
1716 data_blob_free(&lm_resp);
1718 SSVAL(req->outbuf,smb_uid,sess_vuid);
1719 SSVAL(req->inbuf,smb_uid,sess_vuid);
1720 req->vuid = sess_vuid;
1722 if (!sconn->smb1.sessions.done_sesssetup) {
1723 sconn->smb1.sessions.max_send =
1724 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1726 sconn->smb1.sessions.done_sesssetup = true;
1728 END_PROFILE(SMBsesssetupX);