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"
38 /* For split krb5 SPNEGO blobs. */
39 struct pending_auth_data {
40 struct pending_auth_data *prev, *next;
41 uint16 vuid; /* Tag for this entry. */
42 uint16 smbpid; /* Alternate tag for this entry. */
44 DATA_BLOB partial_data;
48 on a logon error possibly map the error to success if "map to guest"
51 NTSTATUS do_map_to_guest(NTSTATUS status,
52 struct auth_serversupplied_info **server_info,
53 const char *user, const char *domain)
55 user = user ? user : "";
56 domain = domain ? domain : "";
58 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
59 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
60 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
61 DEBUG(3,("No such user %s [%s] - using guest account\n",
63 status = make_server_info_guest(NULL, server_info);
67 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
68 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
69 DEBUG(3,("Registered username %s for guest access\n",
71 status = make_server_info_guest(NULL, server_info);
78 /****************************************************************************
79 Add the standard 'Samba' signature to the end of the session setup.
80 ****************************************************************************/
82 static int push_signature(uint8 **outbuf)
89 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
91 if (tmp == -1) return -1;
94 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
95 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
99 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
102 if (tmp == -1) return -1;
105 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
107 if (tmp == -1) return -1;
113 /****************************************************************************
114 Send a security blob via a session setup reply.
115 ****************************************************************************/
117 static void reply_sesssetup_blob(struct smb_request *req,
121 if (!NT_STATUS_IS_OK(nt_status) &&
122 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
123 reply_nterror(req, nt_status_squash(nt_status));
127 nt_status = nt_status_squash(nt_status);
128 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
129 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
130 SSVAL(req->outbuf, smb_vwv3, blob.length);
132 if ((message_push_blob(&req->outbuf, blob) == -1)
133 || (push_signature(&req->outbuf) == -1)) {
134 reply_nterror(req, NT_STATUS_NO_MEMORY);
138 /****************************************************************************
139 Do a 'guest' logon, getting back the
140 ****************************************************************************/
142 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
144 struct auth_context *auth_context;
145 struct auth_usersupplied_info *user_info = NULL;
148 static unsigned char chal[8] = { 0, };
150 DEBUG(3,("Got anonymous request\n"));
152 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
153 if (!NT_STATUS_IS_OK(nt_status)) {
157 if (!make_user_info_guest(&user_info)) {
158 TALLOC_FREE(auth_context);
159 return NT_STATUS_NO_MEMORY;
162 nt_status = auth_context->check_ntlm_password(auth_context,
165 TALLOC_FREE(auth_context);
166 free_user_info(&user_info);
174 /* Experiment that failed. See "only happens with a KDC" comment below. */
175 /****************************************************************************
176 Cerate a clock skew error blob for a Windows client.
177 ****************************************************************************/
179 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
181 krb5_context context = NULL;
182 krb5_error_code kerr = 0;
184 krb5_principal host_princ = NULL;
185 char *host_princ_s = NULL;
188 *pblob_out = data_blob_null;
190 initialize_krb5_error_table();
191 kerr = krb5_init_context(&context);
195 /* Create server principal. */
196 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
200 strlower_m(host_princ_s);
202 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
204 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
205 "for name %s: Error %s\n",
206 host_princ_s, error_message(kerr) ));
210 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
213 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
214 "failed: Error %s\n",
215 error_message(kerr) ));
219 *pblob_out = data_blob(reply.data, reply.length);
220 kerberos_free_data_contents(context,&reply);
226 SAFE_FREE(host_princ_s);
229 krb5_free_principal(context, host_princ);
231 krb5_free_context(context);
236 /****************************************************************************
237 Reply to a session setup spnego negotiate packet for kerberos.
238 ****************************************************************************/
240 static void reply_spnego_kerberos(struct smb_request *req,
244 bool *p_invalidate_vuid)
249 int sess_vuid = req->vuid;
250 NTSTATUS ret = NT_STATUS_OK;
251 DATA_BLOB ap_rep, ap_rep_wrapped, response;
252 struct auth_serversupplied_info *server_info = NULL;
253 DATA_BLOB session_key = data_blob_null;
255 DATA_BLOB nullblob = data_blob_null;
256 bool map_domainuser_to_guest = False;
257 bool username_was_mapped;
258 struct PAC_LOGON_INFO *logon_info = NULL;
259 struct smbd_server_connection *sconn = req->sconn;
267 ZERO_STRUCT(ap_rep_wrapped);
268 ZERO_STRUCT(response);
270 /* Normally we will always invalidate the intermediate vuid. */
271 *p_invalidate_vuid = True;
273 mem_ctx = talloc_init("reply_spnego_kerberos");
274 if (mem_ctx == NULL) {
275 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
279 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
280 talloc_destroy(mem_ctx);
281 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
285 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
286 &principal, &logon_info, &ap_rep,
289 data_blob_free(&ticket);
291 if (!NT_STATUS_IS_OK(ret)) {
293 /* Experiment that failed.
294 * See "only happens with a KDC" comment below. */
296 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
299 * Windows in this case returns
300 * NT_STATUS_MORE_PROCESSING_REQUIRED
301 * with a negTokenTarg blob containing an krb5_error
302 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
303 * The client then fixes its clock and continues rather
304 * than giving an error. JRA.
305 * -- Looks like this only happens with a KDC. JRA.
308 bool ok = make_krb5_skew_error(&ap_rep);
310 talloc_destroy(mem_ctx);
311 return ERROR_NT(nt_status_squash(
312 NT_STATUS_LOGON_FAILURE));
314 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
316 response = spnego_gen_auth_response(&ap_rep_wrapped,
317 ret, OID_KERBEROS5_OLD);
318 reply_sesssetup_blob(conn, inbuf, outbuf, response,
319 NT_STATUS_MORE_PROCESSING_REQUIRED);
322 * In this one case we don't invalidate the
323 * intermediate vuid as we're expecting the client
324 * to re-use it for the next sessionsetupX packet. JRA.
327 *p_invalidate_vuid = False;
329 data_blob_free(&ap_rep);
330 data_blob_free(&ap_rep_wrapped);
331 data_blob_free(&response);
332 talloc_destroy(mem_ctx);
333 return -1; /* already replied */
336 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
337 ret = NT_STATUS_LOGON_FAILURE;
340 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
342 talloc_destroy(mem_ctx);
343 reply_nterror(req, nt_status_squash(ret));
347 ret = get_user_from_kerberos_info(talloc_tos(),
348 sconn->client_id.name,
349 principal, logon_info,
350 &username_was_mapped,
351 &map_domainuser_to_guest,
353 &real_username, &pw);
354 if (!NT_STATUS_IS_OK(ret)) {
355 data_blob_free(&ap_rep);
356 data_blob_free(&session_key);
357 talloc_destroy(mem_ctx);
358 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
362 /* save the PAC data if we have it */
364 netsamlogon_cache_store(user, &logon_info->info3);
367 /* setup the string used by %U */
368 sub_set_smb_name(real_username);
370 /* reload services so that the new %U is taken into account */
371 reload_services(sconn->msg_ctx, sconn->sock, True);
373 ret = make_server_info_krb5(mem_ctx,
374 user, domain, real_username, pw,
375 logon_info, map_domainuser_to_guest,
377 if (!NT_STATUS_IS_OK(ret)) {
378 DEBUG(1, ("make_server_info_krb5 failed!\n"));
379 data_blob_free(&ap_rep);
380 data_blob_free(&session_key);
381 TALLOC_FREE(mem_ctx);
382 reply_nterror(req, nt_status_squash(ret));
386 server_info->nss_token |= username_was_mapped;
388 /* we need to build the token for the user. make_server_info_guest()
391 if ( !server_info->security_token ) {
392 ret = create_local_token( server_info );
393 if ( !NT_STATUS_IS_OK(ret) ) {
394 DEBUG(10,("failed to create local token: %s\n",
396 data_blob_free(&ap_rep);
397 data_blob_free(&session_key);
398 TALLOC_FREE( mem_ctx );
399 TALLOC_FREE( server_info );
400 reply_nterror(req, nt_status_squash(ret));
405 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
406 sess_vuid = register_initial_vuid(sconn);
409 data_blob_free(&server_info->user_session_key);
410 /* Set the kerberos-derived session key onto the server_info */
411 server_info->user_session_key = session_key;
412 talloc_steal(server_info, session_key.data);
414 session_key = data_blob_null;
416 /* register_existing_vuid keeps the server info */
417 /* register_existing_vuid takes ownership of session_key on success,
418 * no need to free after this on success. A better interface would copy
421 sess_vuid = register_existing_vuid(sconn, sess_vuid,
422 server_info, nullblob, user);
424 reply_outbuf(req, 4, 0);
425 SSVAL(req->outbuf,smb_uid,sess_vuid);
427 if (sess_vuid == UID_FIELD_INVALID ) {
428 ret = NT_STATUS_LOGON_FAILURE;
430 /* current_user_info is changed on new vuid */
431 reload_services(sconn->msg_ctx, sconn->sock, True);
433 SSVAL(req->outbuf, smb_vwv3, 0);
435 if (server_info->guest) {
436 SSVAL(req->outbuf,smb_vwv2,1);
439 SSVAL(req->outbuf, smb_uid, sess_vuid);
441 /* Successful logon. Keep this vuid. */
442 *p_invalidate_vuid = False;
445 /* wrap that up in a nice GSS-API wrapping */
446 if (NT_STATUS_IS_OK(ret)) {
447 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
450 ap_rep_wrapped = data_blob_null;
452 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
454 reply_sesssetup_blob(req, response, ret);
456 data_blob_free(&ap_rep);
457 data_blob_free(&ap_rep_wrapped);
458 data_blob_free(&response);
459 TALLOC_FREE(mem_ctx);
464 /****************************************************************************
465 Send a session setup reply, wrapped in SPNEGO.
466 Get vuid and check first.
467 End the NTLMSSP exchange context if we are OK/complete fail
468 This should be split into two functions, one to handle each
469 leg of the NTLM auth steps.
470 ***************************************************************************/
472 static void reply_spnego_ntlmssp(struct smb_request *req,
474 struct auth_ntlmssp_state **auth_ntlmssp_state,
475 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
479 bool do_invalidate = true;
481 struct auth_serversupplied_info *session_info = NULL;
482 struct smbd_server_connection *sconn = req->sconn;
484 if (NT_STATUS_IS_OK(nt_status)) {
485 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
486 (*auth_ntlmssp_state), &session_info);
488 /* Note that this session_info won't have a session
489 * key. But for map to guest, that's exactly the right
490 * thing - we can't reasonably guess the key the
491 * client wants, as the password was wrong */
492 nt_status = do_map_to_guest(nt_status,
494 auth_ntlmssp_get_username(*auth_ntlmssp_state),
495 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
498 reply_outbuf(req, 4, 0);
500 SSVAL(req->outbuf, smb_uid, vuid);
502 if (NT_STATUS_IS_OK(nt_status)) {
503 DATA_BLOB nullblob = data_blob_null;
505 if (!is_partial_auth_vuid(sconn, vuid)) {
506 nt_status = NT_STATUS_LOGON_FAILURE;
510 /* register_existing_vuid keeps the server info */
511 if (register_existing_vuid(sconn, vuid,
512 session_info, nullblob,
513 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
515 /* The problem is, *auth_ntlmssp_state points
516 * into the vuser this will have
517 * talloc_free()'ed in
518 * register_existing_vuid() */
519 do_invalidate = false;
520 nt_status = NT_STATUS_LOGON_FAILURE;
524 /* current_user_info is changed on new vuid */
525 reload_services(sconn->msg_ctx, sconn->sock, True);
527 SSVAL(req->outbuf, smb_vwv3, 0);
529 if (session_info->guest) {
530 SSVAL(req->outbuf,smb_vwv2,1);
537 response = spnego_gen_auth_response(talloc_tos(),
541 response = *ntlmssp_blob;
544 reply_sesssetup_blob(req, response, nt_status);
546 data_blob_free(&response);
549 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
550 and the other end, that we are not finished yet. */
552 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
553 /* NB. This is *NOT* an error case. JRA */
555 TALLOC_FREE(*auth_ntlmssp_state);
556 if (!NT_STATUS_IS_OK(nt_status)) {
557 /* Kill the intermediate vuid */
558 invalidate_vuid(sconn, vuid);
564 /****************************************************************************
565 Is this a krb5 mechanism ?
566 ****************************************************************************/
568 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
570 DATA_BLOB *pblob_out,
573 char *OIDs[ASN1_MAX_OIDS];
575 NTSTATUS ret = NT_STATUS_OK;
577 *kerb_mechOID = NULL;
579 /* parse out the OIDs and the first sec blob */
580 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
582 return NT_STATUS_LOGON_FAILURE;
585 /* only look at the first OID for determining the mechToken --
586 according to RFC2478, we should choose the one we want
587 and renegotiate, but i smell a client bug here..
589 Problem observed when connecting to a member (samba box)
590 of an AD domain as a user in a Samba domain. Samba member
591 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
592 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
593 NTLMSSP mechtoken. --jerry */
596 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
597 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
598 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
599 if (*kerb_mechOID == NULL) {
600 ret = NT_STATUS_NO_MEMORY;
605 for (i=0;OIDs[i];i++) {
606 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
607 talloc_free(OIDs[i]);
612 /****************************************************************************
613 Fall back from krb5 to NTLMSSP.
614 ****************************************************************************/
616 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
621 reply_outbuf(req, 4, 0);
622 SSVAL(req->outbuf,smb_uid,vuid);
624 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
625 "but set to downgrade to NTLMSSP\n"));
627 response = spnego_gen_auth_response(talloc_tos(), NULL,
628 NT_STATUS_MORE_PROCESSING_REQUIRED,
630 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
631 data_blob_free(&response);
634 /****************************************************************************
635 Reply to a session setup spnego negotiate packet.
636 ****************************************************************************/
638 static void reply_spnego_negotiate(struct smb_request *req,
641 struct auth_ntlmssp_state **auth_ntlmssp_state)
645 char *kerb_mech = NULL;
647 struct smbd_server_connection *sconn = req->sconn;
649 status = parse_spnego_mechanisms(talloc_tos(),
650 blob1, &secblob, &kerb_mech);
651 if (!NT_STATUS_IS_OK(status)) {
652 /* Kill the intermediate vuid */
653 invalidate_vuid(sconn, vuid);
654 reply_nterror(req, nt_status_squash(status));
658 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
659 (unsigned long)secblob.length));
662 if (kerb_mech && ((lp_security()==SEC_ADS) ||
663 USE_KERBEROS_KEYTAB) ) {
664 bool destroy_vuid = True;
665 reply_spnego_kerberos(req, &secblob, kerb_mech,
666 vuid, &destroy_vuid);
667 data_blob_free(&secblob);
669 /* Kill the intermediate vuid */
670 invalidate_vuid(sconn, vuid);
672 TALLOC_FREE(kerb_mech);
677 if (*auth_ntlmssp_state) {
678 TALLOC_FREE(*auth_ntlmssp_state);
682 data_blob_free(&secblob);
683 /* The mechtoken is a krb5 ticket, but
684 * we need to fall back to NTLM. */
685 reply_spnego_downgrade_to_ntlmssp(req, vuid);
686 TALLOC_FREE(kerb_mech);
690 status = auth_ntlmssp_start(auth_ntlmssp_state);
691 if (!NT_STATUS_IS_OK(status)) {
692 /* Kill the intermediate vuid */
693 invalidate_vuid(sconn, vuid);
694 reply_nterror(req, nt_status_squash(status));
698 status = auth_ntlmssp_update(*auth_ntlmssp_state,
701 data_blob_free(&secblob);
703 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
704 &chal, status, OID_NTLMSSP, true);
706 data_blob_free(&chal);
708 /* already replied */
712 /****************************************************************************
713 Reply to a session setup spnego auth packet.
714 ****************************************************************************/
716 static void reply_spnego_auth(struct smb_request *req,
719 struct auth_ntlmssp_state **auth_ntlmssp_state)
721 DATA_BLOB auth = data_blob_null;
722 DATA_BLOB auth_reply = data_blob_null;
723 DATA_BLOB secblob = data_blob_null;
724 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
725 struct smbd_server_connection *sconn = req->sconn;
727 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
729 file_save("auth.dat", blob1.data, blob1.length);
731 /* Kill the intermediate vuid */
732 invalidate_vuid(sconn, vuid);
734 reply_nterror(req, nt_status_squash(
735 NT_STATUS_LOGON_FAILURE));
739 if (auth.data[0] == ASN1_APPLICATION(0)) {
740 /* Might be a second negTokenTarg packet */
741 char *kerb_mech = NULL;
743 status = parse_spnego_mechanisms(talloc_tos(),
744 auth, &secblob, &kerb_mech);
746 if (!NT_STATUS_IS_OK(status)) {
747 /* Kill the intermediate vuid */
748 invalidate_vuid(sconn, vuid);
749 reply_nterror(req, nt_status_squash(status));
753 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
754 (unsigned long)secblob.length));
756 if (kerb_mech && ((lp_security()==SEC_ADS) ||
757 USE_KERBEROS_KEYTAB)) {
758 bool destroy_vuid = True;
759 reply_spnego_kerberos(req, &secblob, kerb_mech,
760 vuid, &destroy_vuid);
761 data_blob_free(&secblob);
762 data_blob_free(&auth);
764 /* Kill the intermediate vuid */
765 invalidate_vuid(sconn, vuid);
767 TALLOC_FREE(kerb_mech);
771 /* Can't blunder into NTLMSSP auth if we have
775 /* Kill the intermediate vuid */
776 invalidate_vuid(sconn, vuid);
777 DEBUG(3,("reply_spnego_auth: network "
778 "misconfiguration, client sent us a "
779 "krb5 ticket and kerberos security "
781 reply_nterror(req, nt_status_squash(
782 NT_STATUS_LOGON_FAILURE));
783 TALLOC_FREE(kerb_mech);
787 /* If we get here it wasn't a negTokenTarg auth packet. */
788 data_blob_free(&secblob);
790 if (!*auth_ntlmssp_state) {
791 status = auth_ntlmssp_start(auth_ntlmssp_state);
792 if (!NT_STATUS_IS_OK(status)) {
793 /* Kill the intermediate vuid */
794 invalidate_vuid(sconn, vuid);
795 reply_nterror(req, nt_status_squash(status));
800 status = auth_ntlmssp_update(*auth_ntlmssp_state,
803 data_blob_free(&auth);
805 /* Don't send the mechid as we've already sent this (RFC4178). */
807 reply_spnego_ntlmssp(req, vuid,
809 &auth_reply, status, NULL, true);
811 data_blob_free(&auth_reply);
813 /* and tell smbd that we have already replied to this packet */
817 /****************************************************************************
818 Delete an entry on the list.
819 ****************************************************************************/
821 static void delete_partial_auth(struct smbd_server_connection *sconn,
822 struct pending_auth_data *pad)
827 DLIST_REMOVE(sconn->smb1.pd_list, pad);
828 data_blob_free(&pad->partial_data);
832 /****************************************************************************
833 Search for a partial SPNEGO auth fragment matching an smbpid.
834 ****************************************************************************/
836 static struct pending_auth_data *get_pending_auth_data(
837 struct smbd_server_connection *sconn,
840 struct pending_auth_data *pad;
842 * NOTE: using the smbpid here is completely wrong...
844 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
846 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
847 if (pad->smbpid == smbpid) {
854 /****************************************************************************
855 Check the size of an SPNEGO blob. If we need more return
856 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
857 the blob to be more than 64k.
858 ****************************************************************************/
860 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
861 uint16 smbpid, uint16 vuid,
864 struct pending_auth_data *pad = NULL;
866 size_t needed_len = 0;
868 pad = get_pending_auth_data(sconn, smbpid);
870 /* Ensure we have some data. */
871 if (pblob->length == 0) {
872 /* Caller can cope. */
873 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
874 delete_partial_auth(sconn, pad);
878 /* Were we waiting for more data ? */
881 size_t copy_len = MIN(65536, pblob->length);
883 /* Integer wrap paranoia.... */
885 if (pad->partial_data.length + copy_len <
886 pad->partial_data.length ||
887 pad->partial_data.length + copy_len < copy_len) {
889 DEBUG(2,("check_spnego_blob_complete: integer wrap "
890 "pad->partial_data.length = %u, "
892 (unsigned int)pad->partial_data.length,
893 (unsigned int)copy_len ));
895 delete_partial_auth(sconn, pad);
896 return NT_STATUS_INVALID_PARAMETER;
899 DEBUG(10,("check_spnego_blob_complete: "
900 "pad->partial_data.length = %u, "
901 "pad->needed_len = %u, "
903 "pblob->length = %u,\n",
904 (unsigned int)pad->partial_data.length,
905 (unsigned int)pad->needed_len,
906 (unsigned int)copy_len,
907 (unsigned int)pblob->length ));
909 tmp_blob = data_blob(NULL,
910 pad->partial_data.length + copy_len);
912 /* Concatenate the two (up to copy_len) bytes. */
913 memcpy(tmp_blob.data,
914 pad->partial_data.data,
915 pad->partial_data.length);
916 memcpy(tmp_blob.data + pad->partial_data.length,
920 /* Replace the partial data. */
921 data_blob_free(&pad->partial_data);
922 pad->partial_data = tmp_blob;
923 ZERO_STRUCT(tmp_blob);
926 if (pblob->length >= pad->needed_len) {
927 /* Yes, replace pblob. */
928 data_blob_free(pblob);
929 *pblob = pad->partial_data;
930 ZERO_STRUCT(pad->partial_data);
931 delete_partial_auth(sconn, pad);
935 /* Still need more data. */
936 pad->needed_len -= copy_len;
937 return NT_STATUS_MORE_PROCESSING_REQUIRED;
940 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
941 (pblob->data[0] != ASN1_CONTEXT(1))) {
942 /* Not something we can determine the
948 /* This is a new SPNEGO sessionsetup - see if
949 * the data given in this blob is enough.
952 data = asn1_init(NULL);
954 return NT_STATUS_NO_MEMORY;
957 asn1_load(data, *pblob);
958 asn1_start_tag(data, pblob->data[0]);
959 if (data->has_error || data->nesting == NULL) {
961 /* Let caller catch. */
965 /* Integer wrap paranoia.... */
967 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
968 data->nesting->taglen + data->nesting->start < data->nesting->start) {
970 DEBUG(2,("check_spnego_blob_complete: integer wrap "
971 "data.nesting->taglen = %u, "
972 "data.nesting->start = %u\n",
973 (unsigned int)data->nesting->taglen,
974 (unsigned int)data->nesting->start ));
977 return NT_STATUS_INVALID_PARAMETER;
980 /* Total length of the needed asn1 is the tag length
981 * plus the current offset. */
983 needed_len = data->nesting->taglen + data->nesting->start;
986 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
987 "pblob->length = %u\n",
988 (unsigned int)needed_len,
989 (unsigned int)pblob->length ));
991 if (needed_len <= pblob->length) {
992 /* Nothing to do - blob is complete. */
996 /* Refuse the blob if it's bigger than 64k. */
997 if (needed_len > 65536) {
998 DEBUG(2,("check_spnego_blob_complete: needed_len "
1000 (unsigned int)needed_len ));
1001 return NT_STATUS_INVALID_PARAMETER;
1004 /* We must store this blob until complete. */
1005 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1006 return NT_STATUS_NO_MEMORY;
1008 pad->needed_len = needed_len - pblob->length;
1009 pad->partial_data = data_blob(pblob->data, pblob->length);
1010 if (pad->partial_data.data == NULL) {
1012 return NT_STATUS_NO_MEMORY;
1014 pad->smbpid = smbpid;
1016 DLIST_ADD(sconn->smb1.pd_list, pad);
1018 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1021 /****************************************************************************
1022 Reply to a session setup command.
1023 conn POINTER CAN BE NULL HERE !
1024 ****************************************************************************/
1026 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1032 const char *native_os;
1033 const char *native_lanman;
1034 const char *primary_domain;
1036 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1037 enum remote_arch_types ra_type = get_remote_arch();
1038 int vuid = req->vuid;
1039 user_struct *vuser = NULL;
1040 NTSTATUS status = NT_STATUS_OK;
1041 uint16 smbpid = req->smbpid;
1042 struct smbd_server_connection *sconn = req->sconn;
1044 DEBUG(3,("Doing spnego session setup\n"));
1046 if (global_client_caps == 0) {
1047 global_client_caps = IVAL(req->vwv+10, 0);
1049 if (!(global_client_caps & CAP_STATUS32)) {
1050 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1057 if (data_blob_len == 0) {
1058 /* an invalid request */
1059 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1063 bufrem = smbreq_bufrem(req, p);
1064 /* pull the spnego blob */
1065 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1068 file_save("negotiate.dat", blob1.data, blob1.length);
1071 p2 = (char *)req->buf + blob1.length;
1073 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1075 native_os = tmp ? tmp : "";
1077 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1079 native_lanman = tmp ? tmp : "";
1081 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1083 primary_domain = tmp ? tmp : "";
1085 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1086 native_os, native_lanman, primary_domain));
1088 if ( ra_type == RA_WIN2K ) {
1089 /* Vista sets neither the OS or lanman strings */
1091 if ( !strlen(native_os) && !strlen(native_lanman) )
1092 set_remote_arch(RA_VISTA);
1094 /* Windows 2003 doesn't set the native lanman string,
1095 but does set primary domain which is a bug I think */
1097 if ( !strlen(native_lanman) ) {
1098 ra_lanman_string( primary_domain );
1100 ra_lanman_string( native_lanman );
1102 } else if ( ra_type == RA_VISTA ) {
1103 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1104 set_remote_arch(RA_OSX);
1108 /* Did we get a valid vuid ? */
1109 if (!is_partial_auth_vuid(sconn, vuid)) {
1110 /* No, then try and see if this is an intermediate sessionsetup
1111 * for a large SPNEGO packet. */
1112 struct pending_auth_data *pad;
1113 pad = get_pending_auth_data(sconn, smbpid);
1115 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1116 "pending vuid %u\n",
1117 (unsigned int)pad->vuid ));
1122 /* Do we have a valid vuid now ? */
1123 if (!is_partial_auth_vuid(sconn, vuid)) {
1124 /* No, start a new authentication setup. */
1125 vuid = register_initial_vuid(sconn);
1126 if (vuid == UID_FIELD_INVALID) {
1127 data_blob_free(&blob1);
1128 reply_nterror(req, nt_status_squash(
1129 NT_STATUS_INVALID_PARAMETER));
1134 vuser = get_partial_auth_user_struct(sconn, vuid);
1135 /* This MUST be valid. */
1137 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1140 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1141 * sessionsetup requests as the Windows limit on the security blob
1142 * field is 4k. Bug #4400. JRA.
1145 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 if (!NT_STATUS_EQUAL(status,
1148 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1149 /* Real error - kill the intermediate vuid */
1150 invalidate_vuid(sconn, vuid);
1152 data_blob_free(&blob1);
1153 reply_nterror(req, nt_status_squash(status));
1157 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1159 /* its a negTokenTarg packet */
1161 reply_spnego_negotiate(req, vuid, blob1,
1162 &vuser->auth_ntlmssp_state);
1163 data_blob_free(&blob1);
1167 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1169 /* its a auth packet */
1171 reply_spnego_auth(req, vuid, blob1,
1172 &vuser->auth_ntlmssp_state);
1173 data_blob_free(&blob1);
1177 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1180 if (!vuser->auth_ntlmssp_state) {
1181 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 /* Kill the intermediate vuid */
1184 invalidate_vuid(sconn, vuid);
1185 data_blob_free(&blob1);
1186 reply_nterror(req, nt_status_squash(status));
1191 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1194 data_blob_free(&blob1);
1196 reply_spnego_ntlmssp(req, vuid,
1197 &vuser->auth_ntlmssp_state,
1198 &chal, status, OID_NTLMSSP, false);
1199 data_blob_free(&chal);
1203 /* what sort of packet is this? */
1204 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1206 data_blob_free(&blob1);
1208 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1211 /****************************************************************************
1212 On new VC == 0, shutdown *all* old connections and users.
1213 It seems that only NT4.x does this. At W2K and above (XP etc.).
1214 a new session setup with VC==0 is ignored.
1215 ****************************************************************************/
1217 struct shutdown_state {
1219 struct messaging_context *msg_ctx;
1222 static int shutdown_other_smbds(const struct connections_key *key,
1223 const struct connections_data *crec,
1226 struct shutdown_state *state = (struct shutdown_state *)private_data;
1228 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1229 procid_str(talloc_tos(), &crec->pid), crec->addr));
1231 if (!process_exists(crec->pid)) {
1232 DEBUG(10, ("process does not exist\n"));
1236 if (procid_is_me(&crec->pid)) {
1237 DEBUG(10, ("It's me\n"));
1241 if (strcmp(state->ip, crec->addr) != 0) {
1242 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1246 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1247 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1250 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1255 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1257 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1258 "compatible we would close all old resources.\n"));
1261 invalidate_all_vuids();
1263 if (lp_reset_on_zero_vc()) {
1265 struct shutdown_state state;
1267 addr = tsocket_address_inet_addr_string(
1268 sconn->remote_address, talloc_tos());
1273 state.msg_ctx = sconn->msg_ctx;
1274 connections_forall_read(shutdown_other_smbds, &state);
1279 /****************************************************************************
1280 Reply to a session setup command.
1281 ****************************************************************************/
1283 void reply_sesssetup_and_X(struct smb_request *req)
1289 DATA_BLOB plaintext_password;
1292 fstring sub_user; /* Sanitised username for substituion */
1294 const char *native_os;
1295 const char *native_lanman;
1296 const char *primary_domain;
1297 struct auth_usersupplied_info *user_info = NULL;
1298 struct auth_serversupplied_info *server_info = NULL;
1299 uint16 smb_flag2 = req->flags2;
1302 struct smbd_server_connection *sconn = req->sconn;
1304 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1306 START_PROFILE(SMBsesssetupX);
1308 ZERO_STRUCT(lm_resp);
1309 ZERO_STRUCT(nt_resp);
1310 ZERO_STRUCT(plaintext_password);
1312 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1314 /* a SPNEGO session setup has 12 command words, whereas a normal
1315 NT1 session setup has 13. See the cifs spec. */
1316 if (req->wct == 12 &&
1317 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1319 if (!sconn->smb1.negprot.spnego) {
1320 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1321 "at SPNEGO session setup when it was not "
1323 reply_nterror(req, nt_status_squash(
1324 NT_STATUS_LOGON_FAILURE));
1325 END_PROFILE(SMBsesssetupX);
1329 if (SVAL(req->vwv+4, 0) == 0) {
1330 setup_new_vc_session(req->sconn);
1333 reply_sesssetup_and_X_spnego(req);
1334 END_PROFILE(SMBsesssetupX);
1338 smb_bufsize = SVAL(req->vwv+2, 0);
1340 if (get_Protocol() < PROTOCOL_NT1) {
1341 uint16 passlen1 = SVAL(req->vwv+7, 0);
1343 /* Never do NT status codes with protocols before NT1 as we
1344 * don't get client caps. */
1345 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1347 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1348 reply_nterror(req, nt_status_squash(
1349 NT_STATUS_INVALID_PARAMETER));
1350 END_PROFILE(SMBsesssetupX);
1355 lm_resp = data_blob(req->buf, passlen1);
1357 plaintext_password = data_blob(req->buf, passlen1+1);
1358 /* Ensure null termination */
1359 plaintext_password.data[passlen1] = 0;
1362 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1363 req->buf + passlen1, STR_TERMINATE);
1364 user = tmp ? tmp : "";
1369 uint16 passlen1 = SVAL(req->vwv+7, 0);
1370 uint16 passlen2 = SVAL(req->vwv+8, 0);
1371 enum remote_arch_types ra_type = get_remote_arch();
1372 const uint8_t *p = req->buf;
1373 const uint8_t *save_p = req->buf;
1377 if(global_client_caps == 0) {
1378 global_client_caps = IVAL(req->vwv+11, 0);
1380 if (!(global_client_caps & CAP_STATUS32)) {
1381 remove_from_common_flags2(
1382 FLAGS2_32_BIT_ERROR_CODES);
1385 /* client_caps is used as final determination if
1386 * client is NT or Win95. This is needed to return
1387 * the correct error codes in some circumstances.
1390 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1391 ra_type == RA_WIN95) {
1392 if(!(global_client_caps & (CAP_NT_SMBS|
1394 set_remote_arch( RA_WIN95);
1400 /* both Win95 and WinNT stuff up the password
1401 * lengths for non-encrypting systems. Uggh.
1403 if passlen1==24 its a win95 system, and its setting
1404 the password length incorrectly. Luckily it still
1405 works with the default code because Win95 will null
1406 terminate the password anyway
1408 if passlen1>0 and passlen2>0 then maybe its a NT box
1409 and its setting passlen2 to some random value which
1410 really stuffs things up. we need to fix that one. */
1412 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1418 /* check for nasty tricks */
1419 if (passlen1 > MAX_PASS_LEN
1420 || passlen1 > smbreq_bufrem(req, p)) {
1421 reply_nterror(req, nt_status_squash(
1422 NT_STATUS_INVALID_PARAMETER));
1423 END_PROFILE(SMBsesssetupX);
1427 if (passlen2 > MAX_PASS_LEN
1428 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1429 reply_nterror(req, nt_status_squash(
1430 NT_STATUS_INVALID_PARAMETER));
1431 END_PROFILE(SMBsesssetupX);
1435 /* Save the lanman2 password and the NT md4 password. */
1437 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1442 lm_resp = data_blob(p, passlen1);
1443 nt_resp = data_blob(p+passlen1, passlen2);
1444 } else if (lp_security() != SEC_SHARE) {
1446 * In share level we should ignore any passwords, so
1447 * only read them if we're not.
1450 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1452 if (unic && (passlen2 == 0) && passlen1) {
1453 /* Only a ascii plaintext password was sent. */
1454 (void)srvstr_pull_talloc(talloc_tos(),
1460 STR_TERMINATE|STR_ASCII);
1462 (void)srvstr_pull_talloc(talloc_tos(),
1467 unic ? passlen2 : passlen1,
1471 reply_nterror(req, nt_status_squash(
1472 NT_STATUS_INVALID_PARAMETER));
1473 END_PROFILE(SMBsesssetupX);
1476 plaintext_password = data_blob(pass, strlen(pass)+1);
1479 p += passlen1 + passlen2;
1481 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1483 user = tmp ? tmp : "";
1485 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1487 domain = tmp ? tmp : "";
1489 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1491 native_os = tmp ? tmp : "";
1493 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1495 native_lanman = tmp ? tmp : "";
1497 /* not documented or decoded by Ethereal but there is one more
1498 * string in the extra bytes which is the same as the
1499 * PrimaryDomain when using extended security. Windows NT 4
1500 * and 2003 use this string to store the native lanman string.
1501 * Windows 9x does not include a string here at all so we have
1502 * to check if we have any extra bytes left */
1504 byte_count = SVAL(req->vwv+13, 0);
1505 if ( PTR_DIFF(p, save_p) < byte_count) {
1506 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1508 primary_domain = tmp ? tmp : "";
1510 primary_domain = talloc_strdup(talloc_tos(), "null");
1513 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1514 "PrimaryDomain=[%s]\n",
1515 domain, native_os, native_lanman, primary_domain));
1517 if ( ra_type == RA_WIN2K ) {
1518 if ( strlen(native_lanman) == 0 )
1519 ra_lanman_string( primary_domain );
1521 ra_lanman_string( native_lanman );
1526 if (SVAL(req->vwv+4, 0) == 0) {
1527 setup_new_vc_session(req->sconn);
1530 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1531 domain, user, get_remote_machine_name()));
1534 if (sconn->smb1.negprot.spnego) {
1536 /* This has to be here, because this is a perfectly
1537 * valid behaviour for guest logons :-( */
1539 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1540 "at 'normal' session setup after "
1541 "negotiating spnego.\n"));
1542 reply_nterror(req, nt_status_squash(
1543 NT_STATUS_LOGON_FAILURE));
1544 END_PROFILE(SMBsesssetupX);
1547 fstrcpy(sub_user, user);
1549 fstrcpy(sub_user, lp_guestaccount());
1552 sub_set_smb_name(sub_user);
1554 reload_services(sconn->msg_ctx, sconn->sock, True);
1556 if (lp_security() == SEC_SHARE) {
1557 char *sub_user_mapped = NULL;
1558 /* In share level we should ignore any passwords */
1560 data_blob_free(&lm_resp);
1561 data_blob_free(&nt_resp);
1562 data_blob_clear_free(&plaintext_password);
1564 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1565 if (!sub_user_mapped) {
1566 reply_nterror(req, NT_STATUS_NO_MEMORY);
1567 END_PROFILE(SMBsesssetupX);
1570 fstrcpy(sub_user, sub_user_mapped);
1571 add_session_user(sconn, sub_user);
1572 add_session_workgroup(sconn, domain);
1573 /* Then force it to null for the benfit of the code below */
1579 nt_status = check_guest_password(&server_info);
1581 } else if (doencrypt) {
1582 struct auth_context *negprot_auth_context = NULL;
1583 negprot_auth_context = sconn->smb1.negprot.auth_context;
1584 if (!negprot_auth_context) {
1585 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1586 "session setup without negprot denied!\n"));
1587 reply_nterror(req, nt_status_squash(
1588 NT_STATUS_LOGON_FAILURE));
1589 END_PROFILE(SMBsesssetupX);
1592 nt_status = make_user_info_for_reply_enc(&user_info, user,
1595 if (NT_STATUS_IS_OK(nt_status)) {
1596 nt_status = negprot_auth_context->check_ntlm_password(
1597 negprot_auth_context,
1602 struct auth_context *plaintext_auth_context = NULL;
1604 nt_status = make_auth_context_subsystem(
1605 talloc_tos(), &plaintext_auth_context);
1607 if (NT_STATUS_IS_OK(nt_status)) {
1610 plaintext_auth_context->get_ntlm_challenge(
1611 plaintext_auth_context, chal);
1613 if (!make_user_info_for_reply(&user_info,
1615 plaintext_password)) {
1616 nt_status = NT_STATUS_NO_MEMORY;
1619 if (NT_STATUS_IS_OK(nt_status)) {
1620 nt_status = plaintext_auth_context->check_ntlm_password(
1621 plaintext_auth_context,
1625 TALLOC_FREE(plaintext_auth_context);
1630 free_user_info(&user_info);
1632 if (!NT_STATUS_IS_OK(nt_status)) {
1633 nt_status = do_map_to_guest(nt_status, &server_info,
1637 if (!NT_STATUS_IS_OK(nt_status)) {
1638 data_blob_free(&nt_resp);
1639 data_blob_free(&lm_resp);
1640 data_blob_clear_free(&plaintext_password);
1641 reply_nterror(req, nt_status_squash(nt_status));
1642 END_PROFILE(SMBsesssetupX);
1646 /* Ensure we can't possible take a code path leading to a
1649 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1650 END_PROFILE(SMBsesssetupX);
1654 if (!server_info->security_token) {
1655 nt_status = create_local_token(server_info);
1657 if (!NT_STATUS_IS_OK(nt_status)) {
1658 DEBUG(10, ("create_local_token failed: %s\n",
1659 nt_errstr(nt_status)));
1660 data_blob_free(&nt_resp);
1661 data_blob_free(&lm_resp);
1662 data_blob_clear_free(&plaintext_password);
1663 reply_nterror(req, nt_status_squash(nt_status));
1664 END_PROFILE(SMBsesssetupX);
1669 data_blob_clear_free(&plaintext_password);
1671 /* it's ok - setup a reply */
1672 reply_outbuf(req, 3, 0);
1673 if (get_Protocol() >= PROTOCOL_NT1) {
1674 push_signature(&req->outbuf);
1675 /* perhaps grab OS version here?? */
1678 if (server_info->guest) {
1679 SSVAL(req->outbuf,smb_vwv2,1);
1682 /* register the name and uid as being validated, so further connections
1683 to a uid can get through without a password, on the same VC */
1685 if (lp_security() == SEC_SHARE) {
1686 sess_vuid = UID_FIELD_INVALID;
1687 TALLOC_FREE(server_info);
1689 /* Ignore the initial vuid. */
1690 sess_vuid = register_initial_vuid(sconn);
1691 if (sess_vuid == UID_FIELD_INVALID) {
1692 data_blob_free(&nt_resp);
1693 data_blob_free(&lm_resp);
1694 reply_nterror(req, nt_status_squash(
1695 NT_STATUS_LOGON_FAILURE));
1696 END_PROFILE(SMBsesssetupX);
1699 /* register_existing_vuid keeps the server info */
1700 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1702 nt_resp.data ? nt_resp : lm_resp,
1704 if (sess_vuid == UID_FIELD_INVALID) {
1705 data_blob_free(&nt_resp);
1706 data_blob_free(&lm_resp);
1707 reply_nterror(req, nt_status_squash(
1708 NT_STATUS_LOGON_FAILURE));
1709 END_PROFILE(SMBsesssetupX);
1713 /* current_user_info is changed on new vuid */
1714 reload_services(sconn->msg_ctx, sconn->sock, True);
1717 data_blob_free(&nt_resp);
1718 data_blob_free(&lm_resp);
1720 SSVAL(req->outbuf,smb_uid,sess_vuid);
1721 SSVAL(req->inbuf,smb_uid,sess_vuid);
1722 req->vuid = sess_vuid;
1724 if (!sconn->smb1.sessions.done_sesssetup) {
1725 sconn->smb1.sessions.max_send =
1726 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1728 sconn->smb1.sessions.done_sesssetup = true;
1730 END_PROFILE(SMBsesssetupX);