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/krb5pac.h"
32 #include "libads/kerberos_proto.h"
33 #include "../lib/util/asn1.h"
37 /* For split krb5 SPNEGO blobs. */
38 struct pending_auth_data {
39 struct pending_auth_data *prev, *next;
40 uint16 vuid; /* Tag for this entry. */
41 uint16 smbpid; /* Alternate tag for this entry. */
43 DATA_BLOB partial_data;
47 on a logon error possibly map the error to success if "map to guest"
50 NTSTATUS do_map_to_guest(NTSTATUS status,
51 struct auth_serversupplied_info **server_info,
52 const char *user, const char *domain)
54 user = user ? user : "";
55 domain = domain ? domain : "";
57 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
58 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
59 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
60 DEBUG(3,("No such user %s [%s] - using guest account\n",
62 status = make_server_info_guest(NULL, server_info);
66 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
67 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
68 DEBUG(3,("Registered username %s for guest access\n",
70 status = make_server_info_guest(NULL, server_info);
77 /****************************************************************************
78 Add the standard 'Samba' signature to the end of the session setup.
79 ****************************************************************************/
81 static int push_signature(uint8 **outbuf)
88 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
90 if (tmp == -1) return -1;
93 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
94 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
98 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
101 if (tmp == -1) return -1;
104 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
106 if (tmp == -1) return -1;
112 /****************************************************************************
113 Send a security blob via a session setup reply.
114 ****************************************************************************/
116 static void reply_sesssetup_blob(struct smb_request *req,
120 if (!NT_STATUS_IS_OK(nt_status) &&
121 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
122 reply_nterror(req, nt_status_squash(nt_status));
126 nt_status = nt_status_squash(nt_status);
127 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
128 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
129 SSVAL(req->outbuf, smb_vwv3, blob.length);
131 if ((message_push_blob(&req->outbuf, blob) == -1)
132 || (push_signature(&req->outbuf) == -1)) {
133 reply_nterror(req, NT_STATUS_NO_MEMORY);
137 /****************************************************************************
138 Do a 'guest' logon, getting back the
139 ****************************************************************************/
141 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
143 struct auth_context *auth_context;
144 struct auth_usersupplied_info *user_info = NULL;
147 static unsigned char chal[8] = { 0, };
149 DEBUG(3,("Got anonymous request\n"));
151 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
152 if (!NT_STATUS_IS_OK(nt_status)) {
156 if (!make_user_info_guest(&user_info)) {
157 TALLOC_FREE(auth_context);
158 return NT_STATUS_NO_MEMORY;
161 nt_status = auth_context->check_ntlm_password(auth_context,
164 TALLOC_FREE(auth_context);
165 free_user_info(&user_info);
173 /* Experiment that failed. See "only happens with a KDC" comment below. */
174 /****************************************************************************
175 Cerate a clock skew error blob for a Windows client.
176 ****************************************************************************/
178 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
180 krb5_context context = NULL;
181 krb5_error_code kerr = 0;
183 krb5_principal host_princ = NULL;
184 char *host_princ_s = NULL;
187 *pblob_out = data_blob_null;
189 initialize_krb5_error_table();
190 kerr = krb5_init_context(&context);
194 /* Create server principal. */
195 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
199 strlower_m(host_princ_s);
201 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
203 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
204 "for name %s: Error %s\n",
205 host_princ_s, error_message(kerr) ));
209 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
212 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
213 "failed: Error %s\n",
214 error_message(kerr) ));
218 *pblob_out = data_blob(reply.data, reply.length);
219 kerberos_free_data_contents(context,&reply);
225 SAFE_FREE(host_princ_s);
228 krb5_free_principal(context, host_princ);
230 krb5_free_context(context);
235 /****************************************************************************
236 Reply to a session setup spnego negotiate packet for kerberos.
237 ****************************************************************************/
239 static void reply_spnego_kerberos(struct smb_request *req,
243 bool *p_invalidate_vuid)
248 int sess_vuid = req->vuid;
249 NTSTATUS ret = NT_STATUS_OK;
250 DATA_BLOB ap_rep, ap_rep_wrapped, response;
251 struct auth_serversupplied_info *server_info = NULL;
252 DATA_BLOB session_key = data_blob_null;
254 DATA_BLOB nullblob = data_blob_null;
255 bool map_domainuser_to_guest = False;
256 bool username_was_mapped;
257 struct PAC_LOGON_INFO *logon_info = NULL;
258 struct smbd_server_connection *sconn = req->sconn;
266 ZERO_STRUCT(ap_rep_wrapped);
267 ZERO_STRUCT(response);
269 /* Normally we will always invalidate the intermediate vuid. */
270 *p_invalidate_vuid = True;
272 mem_ctx = talloc_init("reply_spnego_kerberos");
273 if (mem_ctx == NULL) {
274 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
278 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
279 talloc_destroy(mem_ctx);
280 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
284 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
285 &principal, &logon_info, &ap_rep,
288 data_blob_free(&ticket);
290 if (!NT_STATUS_IS_OK(ret)) {
292 /* Experiment that failed.
293 * See "only happens with a KDC" comment below. */
295 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
298 * Windows in this case returns
299 * NT_STATUS_MORE_PROCESSING_REQUIRED
300 * with a negTokenTarg blob containing an krb5_error
301 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
302 * The client then fixes its clock and continues rather
303 * than giving an error. JRA.
304 * -- Looks like this only happens with a KDC. JRA.
307 bool ok = make_krb5_skew_error(&ap_rep);
309 talloc_destroy(mem_ctx);
310 return ERROR_NT(nt_status_squash(
311 NT_STATUS_LOGON_FAILURE));
313 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
315 response = spnego_gen_auth_response(&ap_rep_wrapped,
316 ret, OID_KERBEROS5_OLD);
317 reply_sesssetup_blob(conn, inbuf, outbuf, response,
318 NT_STATUS_MORE_PROCESSING_REQUIRED);
321 * In this one case we don't invalidate the
322 * intermediate vuid as we're expecting the client
323 * to re-use it for the next sessionsetupX packet. JRA.
326 *p_invalidate_vuid = False;
328 data_blob_free(&ap_rep);
329 data_blob_free(&ap_rep_wrapped);
330 data_blob_free(&response);
331 talloc_destroy(mem_ctx);
332 return -1; /* already replied */
335 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
336 ret = NT_STATUS_LOGON_FAILURE;
339 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
341 talloc_destroy(mem_ctx);
342 reply_nterror(req, nt_status_squash(ret));
346 ret = get_user_from_kerberos_info(talloc_tos(),
347 sconn->client_id.name,
348 principal, logon_info,
349 &username_was_mapped,
350 &map_domainuser_to_guest,
352 &real_username, &pw);
353 if (!NT_STATUS_IS_OK(ret)) {
354 data_blob_free(&ap_rep);
355 data_blob_free(&session_key);
356 talloc_destroy(mem_ctx);
357 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
361 /* save the PAC data if we have it */
363 netsamlogon_cache_store(user, &logon_info->info3);
366 /* setup the string used by %U */
367 sub_set_smb_name(real_username);
369 /* reload services so that the new %U is taken into account */
370 reload_services(sconn->msg_ctx, sconn->sock, True);
372 ret = make_server_info_krb5(mem_ctx,
373 user, domain, real_username, pw,
374 logon_info, map_domainuser_to_guest,
376 if (!NT_STATUS_IS_OK(ret)) {
377 DEBUG(1, ("make_server_info_krb5 failed!\n"));
378 data_blob_free(&ap_rep);
379 data_blob_free(&session_key);
380 TALLOC_FREE(mem_ctx);
381 reply_nterror(req, nt_status_squash(ret));
385 server_info->nss_token |= username_was_mapped;
387 /* we need to build the token for the user. make_server_info_guest()
390 if ( !server_info->security_token ) {
391 ret = create_local_token( server_info );
392 if ( !NT_STATUS_IS_OK(ret) ) {
393 DEBUG(10,("failed to create local token: %s\n",
395 data_blob_free(&ap_rep);
396 data_blob_free(&session_key);
397 TALLOC_FREE( mem_ctx );
398 TALLOC_FREE( server_info );
399 reply_nterror(req, nt_status_squash(ret));
404 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
405 sess_vuid = register_initial_vuid(sconn);
408 data_blob_free(&server_info->user_session_key);
409 /* Set the kerberos-derived session key onto the server_info */
410 server_info->user_session_key = session_key;
411 talloc_steal(server_info, session_key.data);
413 session_key = data_blob_null;
415 /* register_existing_vuid keeps the server info */
416 /* register_existing_vuid takes ownership of session_key on success,
417 * no need to free after this on success. A better interface would copy
420 sess_vuid = register_existing_vuid(sconn, sess_vuid,
421 server_info, nullblob, user);
423 reply_outbuf(req, 4, 0);
424 SSVAL(req->outbuf,smb_uid,sess_vuid);
426 if (sess_vuid == UID_FIELD_INVALID ) {
427 ret = NT_STATUS_LOGON_FAILURE;
429 /* current_user_info is changed on new vuid */
430 reload_services(sconn->msg_ctx, sconn->sock, True);
432 SSVAL(req->outbuf, smb_vwv3, 0);
434 if (server_info->guest) {
435 SSVAL(req->outbuf,smb_vwv2,1);
438 SSVAL(req->outbuf, smb_uid, sess_vuid);
440 /* Successful logon. Keep this vuid. */
441 *p_invalidate_vuid = False;
444 /* wrap that up in a nice GSS-API wrapping */
445 if (NT_STATUS_IS_OK(ret)) {
446 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
449 ap_rep_wrapped = data_blob_null;
451 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
453 reply_sesssetup_blob(req, response, ret);
455 data_blob_free(&ap_rep);
456 data_blob_free(&ap_rep_wrapped);
457 data_blob_free(&response);
458 TALLOC_FREE(mem_ctx);
463 /****************************************************************************
464 Send a session setup reply, wrapped in SPNEGO.
465 Get vuid and check first.
466 End the NTLMSSP exchange context if we are OK/complete fail
467 This should be split into two functions, one to handle each
468 leg of the NTLM auth steps.
469 ***************************************************************************/
471 static void reply_spnego_ntlmssp(struct smb_request *req,
473 struct auth_ntlmssp_state **auth_ntlmssp_state,
474 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
478 bool do_invalidate = true;
480 struct auth_serversupplied_info *session_info = NULL;
481 struct smbd_server_connection *sconn = req->sconn;
483 if (NT_STATUS_IS_OK(nt_status)) {
484 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
485 (*auth_ntlmssp_state), &session_info);
487 /* Note that this session_info won't have a session
488 * key. But for map to guest, that's exactly the right
489 * thing - we can't reasonably guess the key the
490 * client wants, as the password was wrong */
491 nt_status = do_map_to_guest(nt_status,
493 auth_ntlmssp_get_username(*auth_ntlmssp_state),
494 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
497 reply_outbuf(req, 4, 0);
499 SSVAL(req->outbuf, smb_uid, vuid);
501 if (NT_STATUS_IS_OK(nt_status)) {
502 DATA_BLOB nullblob = data_blob_null;
504 if (!is_partial_auth_vuid(sconn, vuid)) {
505 nt_status = NT_STATUS_LOGON_FAILURE;
509 /* register_existing_vuid keeps the server info */
510 if (register_existing_vuid(sconn, vuid,
511 session_info, nullblob,
512 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
514 /* The problem is, *auth_ntlmssp_state points
515 * into the vuser this will have
516 * talloc_free()'ed in
517 * register_existing_vuid() */
518 do_invalidate = false;
519 nt_status = NT_STATUS_LOGON_FAILURE;
523 /* current_user_info is changed on new vuid */
524 reload_services(sconn->msg_ctx, sconn->sock, True);
526 SSVAL(req->outbuf, smb_vwv3, 0);
528 if (session_info->guest) {
529 SSVAL(req->outbuf,smb_vwv2,1);
536 response = spnego_gen_auth_response(talloc_tos(),
540 response = *ntlmssp_blob;
543 reply_sesssetup_blob(req, response, nt_status);
545 data_blob_free(&response);
548 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
549 and the other end, that we are not finished yet. */
551 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
552 /* NB. This is *NOT* an error case. JRA */
554 TALLOC_FREE(*auth_ntlmssp_state);
555 if (!NT_STATUS_IS_OK(nt_status)) {
556 /* Kill the intermediate vuid */
557 invalidate_vuid(sconn, vuid);
563 /****************************************************************************
564 Is this a krb5 mechanism ?
565 ****************************************************************************/
567 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
569 DATA_BLOB *pblob_out,
572 char *OIDs[ASN1_MAX_OIDS];
574 NTSTATUS ret = NT_STATUS_OK;
576 *kerb_mechOID = NULL;
578 /* parse out the OIDs and the first sec blob */
579 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
581 return NT_STATUS_LOGON_FAILURE;
584 /* only look at the first OID for determining the mechToken --
585 according to RFC2478, we should choose the one we want
586 and renegotiate, but i smell a client bug here..
588 Problem observed when connecting to a member (samba box)
589 of an AD domain as a user in a Samba domain. Samba member
590 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
591 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
592 NTLMSSP mechtoken. --jerry */
595 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
596 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
597 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
598 if (*kerb_mechOID == NULL) {
599 ret = NT_STATUS_NO_MEMORY;
604 for (i=0;OIDs[i];i++) {
605 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
606 talloc_free(OIDs[i]);
611 /****************************************************************************
612 Fall back from krb5 to NTLMSSP.
613 ****************************************************************************/
615 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
620 reply_outbuf(req, 4, 0);
621 SSVAL(req->outbuf,smb_uid,vuid);
623 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
624 "but set to downgrade to NTLMSSP\n"));
626 response = spnego_gen_auth_response(talloc_tos(), NULL,
627 NT_STATUS_MORE_PROCESSING_REQUIRED,
629 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
630 data_blob_free(&response);
633 /****************************************************************************
634 Reply to a session setup spnego negotiate packet.
635 ****************************************************************************/
637 static void reply_spnego_negotiate(struct smb_request *req,
640 struct auth_ntlmssp_state **auth_ntlmssp_state)
644 char *kerb_mech = NULL;
646 struct smbd_server_connection *sconn = req->sconn;
648 status = parse_spnego_mechanisms(talloc_tos(),
649 blob1, &secblob, &kerb_mech);
650 if (!NT_STATUS_IS_OK(status)) {
651 /* Kill the intermediate vuid */
652 invalidate_vuid(sconn, vuid);
653 reply_nterror(req, nt_status_squash(status));
657 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
658 (unsigned long)secblob.length));
661 if (kerb_mech && ((lp_security()==SEC_ADS) ||
662 USE_KERBEROS_KEYTAB) ) {
663 bool destroy_vuid = True;
664 reply_spnego_kerberos(req, &secblob, kerb_mech,
665 vuid, &destroy_vuid);
666 data_blob_free(&secblob);
668 /* Kill the intermediate vuid */
669 invalidate_vuid(sconn, vuid);
671 TALLOC_FREE(kerb_mech);
676 TALLOC_FREE(*auth_ntlmssp_state);
679 data_blob_free(&secblob);
680 /* The mechtoken is a krb5 ticket, but
681 * we need to fall back to NTLM. */
682 reply_spnego_downgrade_to_ntlmssp(req, vuid);
683 TALLOC_FREE(kerb_mech);
687 status = auth_ntlmssp_start(auth_ntlmssp_state);
688 if (!NT_STATUS_IS_OK(status)) {
689 /* Kill the intermediate vuid */
690 invalidate_vuid(sconn, vuid);
691 reply_nterror(req, nt_status_squash(status));
695 status = auth_ntlmssp_update(*auth_ntlmssp_state,
698 data_blob_free(&secblob);
700 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
701 &chal, status, OID_NTLMSSP, true);
703 data_blob_free(&chal);
705 /* already replied */
709 /****************************************************************************
710 Reply to a session setup spnego auth packet.
711 ****************************************************************************/
713 static void reply_spnego_auth(struct smb_request *req,
716 struct auth_ntlmssp_state **auth_ntlmssp_state)
718 DATA_BLOB auth = data_blob_null;
719 DATA_BLOB auth_reply = data_blob_null;
720 DATA_BLOB secblob = data_blob_null;
721 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
722 struct smbd_server_connection *sconn = req->sconn;
724 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
726 file_save("auth.dat", blob1.data, blob1.length);
728 /* Kill the intermediate vuid */
729 invalidate_vuid(sconn, vuid);
731 reply_nterror(req, nt_status_squash(
732 NT_STATUS_LOGON_FAILURE));
736 if (auth.data[0] == ASN1_APPLICATION(0)) {
737 /* Might be a second negTokenTarg packet */
738 char *kerb_mech = NULL;
740 status = parse_spnego_mechanisms(talloc_tos(),
741 auth, &secblob, &kerb_mech);
743 if (!NT_STATUS_IS_OK(status)) {
744 /* Kill the intermediate vuid */
745 invalidate_vuid(sconn, vuid);
746 reply_nterror(req, nt_status_squash(status));
750 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
751 (unsigned long)secblob.length));
753 if (kerb_mech && ((lp_security()==SEC_ADS) ||
754 USE_KERBEROS_KEYTAB)) {
755 bool destroy_vuid = True;
756 reply_spnego_kerberos(req, &secblob, kerb_mech,
757 vuid, &destroy_vuid);
758 data_blob_free(&secblob);
759 data_blob_free(&auth);
761 /* Kill the intermediate vuid */
762 invalidate_vuid(sconn, vuid);
764 TALLOC_FREE(kerb_mech);
768 /* Can't blunder into NTLMSSP auth if we have
772 /* Kill the intermediate vuid */
773 invalidate_vuid(sconn, vuid);
774 DEBUG(3,("reply_spnego_auth: network "
775 "misconfiguration, client sent us a "
776 "krb5 ticket and kerberos security "
778 reply_nterror(req, nt_status_squash(
779 NT_STATUS_LOGON_FAILURE));
780 TALLOC_FREE(kerb_mech);
784 /* If we get here it wasn't a negTokenTarg auth packet. */
785 data_blob_free(&secblob);
787 if (!*auth_ntlmssp_state) {
788 status = auth_ntlmssp_start(auth_ntlmssp_state);
789 if (!NT_STATUS_IS_OK(status)) {
790 /* Kill the intermediate vuid */
791 invalidate_vuid(sconn, vuid);
792 reply_nterror(req, nt_status_squash(status));
797 status = auth_ntlmssp_update(*auth_ntlmssp_state,
800 data_blob_free(&auth);
802 /* Don't send the mechid as we've already sent this (RFC4178). */
804 reply_spnego_ntlmssp(req, vuid,
806 &auth_reply, status, NULL, true);
808 data_blob_free(&auth_reply);
810 /* and tell smbd that we have already replied to this packet */
814 /****************************************************************************
815 Delete an entry on the list.
816 ****************************************************************************/
818 static void delete_partial_auth(struct smbd_server_connection *sconn,
819 struct pending_auth_data *pad)
824 DLIST_REMOVE(sconn->smb1.pd_list, pad);
825 data_blob_free(&pad->partial_data);
829 /****************************************************************************
830 Search for a partial SPNEGO auth fragment matching an smbpid.
831 ****************************************************************************/
833 static struct pending_auth_data *get_pending_auth_data(
834 struct smbd_server_connection *sconn,
837 struct pending_auth_data *pad;
839 * NOTE: using the smbpid here is completely wrong...
841 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
843 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
844 if (pad->smbpid == smbpid) {
851 /****************************************************************************
852 Check the size of an SPNEGO blob. If we need more return
853 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
854 the blob to be more than 64k.
855 ****************************************************************************/
857 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
858 uint16 smbpid, uint16 vuid,
861 struct pending_auth_data *pad = NULL;
863 size_t needed_len = 0;
865 pad = get_pending_auth_data(sconn, smbpid);
867 /* Ensure we have some data. */
868 if (pblob->length == 0) {
869 /* Caller can cope. */
870 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
871 delete_partial_auth(sconn, pad);
875 /* Were we waiting for more data ? */
878 size_t copy_len = MIN(65536, pblob->length);
880 /* Integer wrap paranoia.... */
882 if (pad->partial_data.length + copy_len <
883 pad->partial_data.length ||
884 pad->partial_data.length + copy_len < copy_len) {
886 DEBUG(2,("check_spnego_blob_complete: integer wrap "
887 "pad->partial_data.length = %u, "
889 (unsigned int)pad->partial_data.length,
890 (unsigned int)copy_len ));
892 delete_partial_auth(sconn, pad);
893 return NT_STATUS_INVALID_PARAMETER;
896 DEBUG(10,("check_spnego_blob_complete: "
897 "pad->partial_data.length = %u, "
898 "pad->needed_len = %u, "
900 "pblob->length = %u,\n",
901 (unsigned int)pad->partial_data.length,
902 (unsigned int)pad->needed_len,
903 (unsigned int)copy_len,
904 (unsigned int)pblob->length ));
906 tmp_blob = data_blob(NULL,
907 pad->partial_data.length + copy_len);
909 /* Concatenate the two (up to copy_len) bytes. */
910 memcpy(tmp_blob.data,
911 pad->partial_data.data,
912 pad->partial_data.length);
913 memcpy(tmp_blob.data + pad->partial_data.length,
917 /* Replace the partial data. */
918 data_blob_free(&pad->partial_data);
919 pad->partial_data = tmp_blob;
920 ZERO_STRUCT(tmp_blob);
923 if (pblob->length >= pad->needed_len) {
924 /* Yes, replace pblob. */
925 data_blob_free(pblob);
926 *pblob = pad->partial_data;
927 ZERO_STRUCT(pad->partial_data);
928 delete_partial_auth(sconn, pad);
932 /* Still need more data. */
933 pad->needed_len -= copy_len;
934 return NT_STATUS_MORE_PROCESSING_REQUIRED;
937 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
938 (pblob->data[0] != ASN1_CONTEXT(1))) {
939 /* Not something we can determine the
945 /* This is a new SPNEGO sessionsetup - see if
946 * the data given in this blob is enough.
949 data = asn1_init(NULL);
951 return NT_STATUS_NO_MEMORY;
954 asn1_load(data, *pblob);
955 asn1_start_tag(data, pblob->data[0]);
956 if (data->has_error || data->nesting == NULL) {
958 /* Let caller catch. */
962 /* Integer wrap paranoia.... */
964 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
965 data->nesting->taglen + data->nesting->start < data->nesting->start) {
967 DEBUG(2,("check_spnego_blob_complete: integer wrap "
968 "data.nesting->taglen = %u, "
969 "data.nesting->start = %u\n",
970 (unsigned int)data->nesting->taglen,
971 (unsigned int)data->nesting->start ));
974 return NT_STATUS_INVALID_PARAMETER;
977 /* Total length of the needed asn1 is the tag length
978 * plus the current offset. */
980 needed_len = data->nesting->taglen + data->nesting->start;
983 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
984 "pblob->length = %u\n",
985 (unsigned int)needed_len,
986 (unsigned int)pblob->length ));
988 if (needed_len <= pblob->length) {
989 /* Nothing to do - blob is complete. */
993 /* Refuse the blob if it's bigger than 64k. */
994 if (needed_len > 65536) {
995 DEBUG(2,("check_spnego_blob_complete: needed_len "
997 (unsigned int)needed_len ));
998 return NT_STATUS_INVALID_PARAMETER;
1001 /* We must store this blob until complete. */
1002 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1003 return NT_STATUS_NO_MEMORY;
1005 pad->needed_len = needed_len - pblob->length;
1006 pad->partial_data = data_blob(pblob->data, pblob->length);
1007 if (pad->partial_data.data == NULL) {
1009 return NT_STATUS_NO_MEMORY;
1011 pad->smbpid = smbpid;
1013 DLIST_ADD(sconn->smb1.pd_list, pad);
1015 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1018 /****************************************************************************
1019 Reply to a session setup command.
1020 conn POINTER CAN BE NULL HERE !
1021 ****************************************************************************/
1023 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1029 const char *native_os;
1030 const char *native_lanman;
1031 const char *primary_domain;
1033 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1034 enum remote_arch_types ra_type = get_remote_arch();
1035 int vuid = req->vuid;
1036 user_struct *vuser = NULL;
1037 NTSTATUS status = NT_STATUS_OK;
1038 uint16 smbpid = req->smbpid;
1039 struct smbd_server_connection *sconn = req->sconn;
1041 DEBUG(3,("Doing spnego session setup\n"));
1043 if (global_client_caps == 0) {
1044 global_client_caps = IVAL(req->vwv+10, 0);
1046 if (!(global_client_caps & CAP_STATUS32)) {
1047 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1054 if (data_blob_len == 0) {
1055 /* an invalid request */
1056 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1060 bufrem = smbreq_bufrem(req, p);
1061 /* pull the spnego blob */
1062 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1065 file_save("negotiate.dat", blob1.data, blob1.length);
1068 p2 = (char *)req->buf + blob1.length;
1070 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1072 native_os = tmp ? tmp : "";
1074 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1076 native_lanman = tmp ? tmp : "";
1078 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1080 primary_domain = tmp ? tmp : "";
1082 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1083 native_os, native_lanman, primary_domain));
1085 if ( ra_type == RA_WIN2K ) {
1086 /* Vista sets neither the OS or lanman strings */
1088 if ( !strlen(native_os) && !strlen(native_lanman) )
1089 set_remote_arch(RA_VISTA);
1091 /* Windows 2003 doesn't set the native lanman string,
1092 but does set primary domain which is a bug I think */
1094 if ( !strlen(native_lanman) ) {
1095 ra_lanman_string( primary_domain );
1097 ra_lanman_string( native_lanman );
1099 } else if ( ra_type == RA_VISTA ) {
1100 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
1101 set_remote_arch(RA_OSX);
1105 /* Did we get a valid vuid ? */
1106 if (!is_partial_auth_vuid(sconn, vuid)) {
1107 /* No, then try and see if this is an intermediate sessionsetup
1108 * for a large SPNEGO packet. */
1109 struct pending_auth_data *pad;
1110 pad = get_pending_auth_data(sconn, smbpid);
1112 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1113 "pending vuid %u\n",
1114 (unsigned int)pad->vuid ));
1119 /* Do we have a valid vuid now ? */
1120 if (!is_partial_auth_vuid(sconn, vuid)) {
1121 /* No, start a new authentication setup. */
1122 vuid = register_initial_vuid(sconn);
1123 if (vuid == UID_FIELD_INVALID) {
1124 data_blob_free(&blob1);
1125 reply_nterror(req, nt_status_squash(
1126 NT_STATUS_INVALID_PARAMETER));
1131 vuser = get_partial_auth_user_struct(sconn, vuid);
1132 /* This MUST be valid. */
1134 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1137 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1138 * sessionsetup requests as the Windows limit on the security blob
1139 * field is 4k. Bug #4400. JRA.
1142 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1143 if (!NT_STATUS_IS_OK(status)) {
1144 if (!NT_STATUS_EQUAL(status,
1145 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1146 /* Real error - kill the intermediate vuid */
1147 invalidate_vuid(sconn, vuid);
1149 data_blob_free(&blob1);
1150 reply_nterror(req, nt_status_squash(status));
1154 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1156 /* its a negTokenTarg packet */
1158 reply_spnego_negotiate(req, vuid, blob1,
1159 &vuser->auth_ntlmssp_state);
1160 data_blob_free(&blob1);
1164 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1166 /* its a auth packet */
1168 reply_spnego_auth(req, vuid, blob1,
1169 &vuser->auth_ntlmssp_state);
1170 data_blob_free(&blob1);
1174 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1177 if (!vuser->auth_ntlmssp_state) {
1178 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1179 if (!NT_STATUS_IS_OK(status)) {
1180 /* Kill the intermediate vuid */
1181 invalidate_vuid(sconn, vuid);
1182 data_blob_free(&blob1);
1183 reply_nterror(req, nt_status_squash(status));
1188 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1191 data_blob_free(&blob1);
1193 reply_spnego_ntlmssp(req, vuid,
1194 &vuser->auth_ntlmssp_state,
1195 &chal, status, OID_NTLMSSP, false);
1196 data_blob_free(&chal);
1200 /* what sort of packet is this? */
1201 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1203 data_blob_free(&blob1);
1205 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1208 /****************************************************************************
1209 On new VC == 0, shutdown *all* old connections and users.
1210 It seems that only NT4.x does this. At W2K and above (XP etc.).
1211 a new session setup with VC==0 is ignored.
1212 ****************************************************************************/
1214 struct shutdown_state {
1216 struct messaging_context *msg_ctx;
1219 static int shutdown_other_smbds(const struct connections_key *key,
1220 const struct connections_data *crec,
1223 struct shutdown_state *state = (struct shutdown_state *)private_data;
1225 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1226 procid_str(talloc_tos(), &crec->pid), crec->addr));
1228 if (!process_exists(crec->pid)) {
1229 DEBUG(10, ("process does not exist\n"));
1233 if (procid_is_me(&crec->pid)) {
1234 DEBUG(10, ("It's me\n"));
1238 if (strcmp(state->ip, crec->addr) != 0) {
1239 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1243 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1244 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1247 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1252 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1254 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1255 "compatible we would close all old resources.\n"));
1258 invalidate_all_vuids();
1260 if (lp_reset_on_zero_vc()) {
1262 struct shutdown_state state;
1264 addr = tsocket_address_inet_addr_string(
1265 sconn->remote_address, talloc_tos());
1270 state.msg_ctx = sconn->msg_ctx;
1271 connections_forall_read(shutdown_other_smbds, &state);
1276 /****************************************************************************
1277 Reply to a session setup command.
1278 ****************************************************************************/
1280 void reply_sesssetup_and_X(struct smb_request *req)
1286 DATA_BLOB plaintext_password;
1289 fstring sub_user; /* Sanitised username for substituion */
1291 const char *native_os;
1292 const char *native_lanman;
1293 const char *primary_domain;
1294 struct auth_usersupplied_info *user_info = NULL;
1295 struct auth_serversupplied_info *server_info = NULL;
1296 uint16 smb_flag2 = req->flags2;
1299 struct smbd_server_connection *sconn = req->sconn;
1301 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1303 START_PROFILE(SMBsesssetupX);
1305 ZERO_STRUCT(lm_resp);
1306 ZERO_STRUCT(nt_resp);
1307 ZERO_STRUCT(plaintext_password);
1309 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1311 /* a SPNEGO session setup has 12 command words, whereas a normal
1312 NT1 session setup has 13. See the cifs spec. */
1313 if (req->wct == 12 &&
1314 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1316 if (!sconn->smb1.negprot.spnego) {
1317 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1318 "at SPNEGO session setup when it was not "
1320 reply_nterror(req, nt_status_squash(
1321 NT_STATUS_LOGON_FAILURE));
1322 END_PROFILE(SMBsesssetupX);
1326 if (SVAL(req->vwv+4, 0) == 0) {
1327 setup_new_vc_session(req->sconn);
1330 reply_sesssetup_and_X_spnego(req);
1331 END_PROFILE(SMBsesssetupX);
1335 smb_bufsize = SVAL(req->vwv+2, 0);
1337 if (get_Protocol() < PROTOCOL_NT1) {
1338 uint16 passlen1 = SVAL(req->vwv+7, 0);
1340 /* Never do NT status codes with protocols before NT1 as we
1341 * don't get client caps. */
1342 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1344 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1345 reply_nterror(req, nt_status_squash(
1346 NT_STATUS_INVALID_PARAMETER));
1347 END_PROFILE(SMBsesssetupX);
1352 lm_resp = data_blob(req->buf, passlen1);
1354 plaintext_password = data_blob(req->buf, passlen1+1);
1355 /* Ensure null termination */
1356 plaintext_password.data[passlen1] = 0;
1359 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1360 req->buf + passlen1, STR_TERMINATE);
1361 user = tmp ? tmp : "";
1366 uint16 passlen1 = SVAL(req->vwv+7, 0);
1367 uint16 passlen2 = SVAL(req->vwv+8, 0);
1368 enum remote_arch_types ra_type = get_remote_arch();
1369 const uint8_t *p = req->buf;
1370 const uint8_t *save_p = req->buf;
1374 if(global_client_caps == 0) {
1375 global_client_caps = IVAL(req->vwv+11, 0);
1377 if (!(global_client_caps & CAP_STATUS32)) {
1378 remove_from_common_flags2(
1379 FLAGS2_32_BIT_ERROR_CODES);
1382 /* client_caps is used as final determination if
1383 * client is NT or Win95. This is needed to return
1384 * the correct error codes in some circumstances.
1387 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1388 ra_type == RA_WIN95) {
1389 if(!(global_client_caps & (CAP_NT_SMBS|
1391 set_remote_arch( RA_WIN95);
1397 /* both Win95 and WinNT stuff up the password
1398 * lengths for non-encrypting systems. Uggh.
1400 if passlen1==24 its a win95 system, and its setting
1401 the password length incorrectly. Luckily it still
1402 works with the default code because Win95 will null
1403 terminate the password anyway
1405 if passlen1>0 and passlen2>0 then maybe its a NT box
1406 and its setting passlen2 to some random value which
1407 really stuffs things up. we need to fix that one. */
1409 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1415 /* check for nasty tricks */
1416 if (passlen1 > MAX_PASS_LEN
1417 || passlen1 > smbreq_bufrem(req, p)) {
1418 reply_nterror(req, nt_status_squash(
1419 NT_STATUS_INVALID_PARAMETER));
1420 END_PROFILE(SMBsesssetupX);
1424 if (passlen2 > MAX_PASS_LEN
1425 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1426 reply_nterror(req, nt_status_squash(
1427 NT_STATUS_INVALID_PARAMETER));
1428 END_PROFILE(SMBsesssetupX);
1432 /* Save the lanman2 password and the NT md4 password. */
1434 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1439 lm_resp = data_blob(p, passlen1);
1440 nt_resp = data_blob(p+passlen1, passlen2);
1441 } else if (lp_security() != SEC_SHARE) {
1443 * In share level we should ignore any passwords, so
1444 * only read them if we're not.
1447 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1449 if (unic && (passlen2 == 0) && passlen1) {
1450 /* Only a ascii plaintext password was sent. */
1451 (void)srvstr_pull_talloc(talloc_tos(),
1457 STR_TERMINATE|STR_ASCII);
1459 (void)srvstr_pull_talloc(talloc_tos(),
1464 unic ? passlen2 : passlen1,
1468 reply_nterror(req, nt_status_squash(
1469 NT_STATUS_INVALID_PARAMETER));
1470 END_PROFILE(SMBsesssetupX);
1473 plaintext_password = data_blob(pass, strlen(pass)+1);
1476 p += passlen1 + passlen2;
1478 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1480 user = tmp ? tmp : "";
1482 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1484 domain = tmp ? tmp : "";
1486 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1488 native_os = tmp ? tmp : "";
1490 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1492 native_lanman = tmp ? tmp : "";
1494 /* not documented or decoded by Ethereal but there is one more
1495 * string in the extra bytes which is the same as the
1496 * PrimaryDomain when using extended security. Windows NT 4
1497 * and 2003 use this string to store the native lanman string.
1498 * Windows 9x does not include a string here at all so we have
1499 * to check if we have any extra bytes left */
1501 byte_count = SVAL(req->vwv+13, 0);
1502 if ( PTR_DIFF(p, save_p) < byte_count) {
1503 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1505 primary_domain = tmp ? tmp : "";
1507 primary_domain = talloc_strdup(talloc_tos(), "null");
1510 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1511 "PrimaryDomain=[%s]\n",
1512 domain, native_os, native_lanman, primary_domain));
1514 if ( ra_type == RA_WIN2K ) {
1515 if ( strlen(native_lanman) == 0 )
1516 ra_lanman_string( primary_domain );
1518 ra_lanman_string( native_lanman );
1523 if (SVAL(req->vwv+4, 0) == 0) {
1524 setup_new_vc_session(req->sconn);
1527 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1528 domain, user, get_remote_machine_name()));
1531 if (sconn->smb1.negprot.spnego) {
1533 /* This has to be here, because this is a perfectly
1534 * valid behaviour for guest logons :-( */
1536 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1537 "at 'normal' session setup after "
1538 "negotiating spnego.\n"));
1539 reply_nterror(req, nt_status_squash(
1540 NT_STATUS_LOGON_FAILURE));
1541 END_PROFILE(SMBsesssetupX);
1544 fstrcpy(sub_user, user);
1546 fstrcpy(sub_user, lp_guestaccount());
1549 sub_set_smb_name(sub_user);
1551 reload_services(sconn->msg_ctx, sconn->sock, True);
1553 if (lp_security() == SEC_SHARE) {
1554 char *sub_user_mapped = NULL;
1555 /* In share level we should ignore any passwords */
1557 data_blob_free(&lm_resp);
1558 data_blob_free(&nt_resp);
1559 data_blob_clear_free(&plaintext_password);
1561 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1562 if (!sub_user_mapped) {
1563 reply_nterror(req, NT_STATUS_NO_MEMORY);
1564 END_PROFILE(SMBsesssetupX);
1567 fstrcpy(sub_user, sub_user_mapped);
1568 add_session_user(sconn, sub_user);
1569 add_session_workgroup(sconn, domain);
1570 /* Then force it to null for the benfit of the code below */
1576 nt_status = check_guest_password(&server_info);
1578 } else if (doencrypt) {
1579 struct auth_context *negprot_auth_context = NULL;
1580 negprot_auth_context = sconn->smb1.negprot.auth_context;
1581 if (!negprot_auth_context) {
1582 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1583 "session setup without negprot denied!\n"));
1584 reply_nterror(req, nt_status_squash(
1585 NT_STATUS_LOGON_FAILURE));
1586 END_PROFILE(SMBsesssetupX);
1589 nt_status = make_user_info_for_reply_enc(&user_info, user,
1592 if (NT_STATUS_IS_OK(nt_status)) {
1593 nt_status = negprot_auth_context->check_ntlm_password(
1594 negprot_auth_context,
1599 struct auth_context *plaintext_auth_context = NULL;
1601 nt_status = make_auth_context_subsystem(
1602 talloc_tos(), &plaintext_auth_context);
1604 if (NT_STATUS_IS_OK(nt_status)) {
1607 plaintext_auth_context->get_ntlm_challenge(
1608 plaintext_auth_context, chal);
1610 if (!make_user_info_for_reply(&user_info,
1612 plaintext_password)) {
1613 nt_status = NT_STATUS_NO_MEMORY;
1616 if (NT_STATUS_IS_OK(nt_status)) {
1617 nt_status = plaintext_auth_context->check_ntlm_password(
1618 plaintext_auth_context,
1622 TALLOC_FREE(plaintext_auth_context);
1627 free_user_info(&user_info);
1629 if (!NT_STATUS_IS_OK(nt_status)) {
1630 nt_status = do_map_to_guest(nt_status, &server_info,
1634 if (!NT_STATUS_IS_OK(nt_status)) {
1635 data_blob_free(&nt_resp);
1636 data_blob_free(&lm_resp);
1637 data_blob_clear_free(&plaintext_password);
1638 reply_nterror(req, nt_status_squash(nt_status));
1639 END_PROFILE(SMBsesssetupX);
1643 /* Ensure we can't possible take a code path leading to a
1646 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1647 END_PROFILE(SMBsesssetupX);
1651 if (!server_info->security_token) {
1652 nt_status = create_local_token(server_info);
1654 if (!NT_STATUS_IS_OK(nt_status)) {
1655 DEBUG(10, ("create_local_token failed: %s\n",
1656 nt_errstr(nt_status)));
1657 data_blob_free(&nt_resp);
1658 data_blob_free(&lm_resp);
1659 data_blob_clear_free(&plaintext_password);
1660 reply_nterror(req, nt_status_squash(nt_status));
1661 END_PROFILE(SMBsesssetupX);
1666 data_blob_clear_free(&plaintext_password);
1668 /* it's ok - setup a reply */
1669 reply_outbuf(req, 3, 0);
1670 if (get_Protocol() >= PROTOCOL_NT1) {
1671 push_signature(&req->outbuf);
1672 /* perhaps grab OS version here?? */
1675 if (server_info->guest) {
1676 SSVAL(req->outbuf,smb_vwv2,1);
1679 /* register the name and uid as being validated, so further connections
1680 to a uid can get through without a password, on the same VC */
1682 if (lp_security() == SEC_SHARE) {
1683 sess_vuid = UID_FIELD_INVALID;
1684 TALLOC_FREE(server_info);
1686 /* Ignore the initial vuid. */
1687 sess_vuid = register_initial_vuid(sconn);
1688 if (sess_vuid == UID_FIELD_INVALID) {
1689 data_blob_free(&nt_resp);
1690 data_blob_free(&lm_resp);
1691 reply_nterror(req, nt_status_squash(
1692 NT_STATUS_LOGON_FAILURE));
1693 END_PROFILE(SMBsesssetupX);
1696 /* register_existing_vuid keeps the server info */
1697 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1699 nt_resp.data ? nt_resp : lm_resp,
1701 if (sess_vuid == UID_FIELD_INVALID) {
1702 data_blob_free(&nt_resp);
1703 data_blob_free(&lm_resp);
1704 reply_nterror(req, nt_status_squash(
1705 NT_STATUS_LOGON_FAILURE));
1706 END_PROFILE(SMBsesssetupX);
1710 /* current_user_info is changed on new vuid */
1711 reload_services(sconn->msg_ctx, sconn->sock, True);
1714 data_blob_free(&nt_resp);
1715 data_blob_free(&lm_resp);
1717 SSVAL(req->outbuf,smb_uid,sess_vuid);
1718 SSVAL(req->inbuf,smb_uid,sess_vuid);
1719 req->vuid = sess_vuid;
1721 if (!sconn->smb1.sessions.done_sesssetup) {
1722 sconn->smb1.sessions.max_send =
1723 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1725 sconn->smb1.sessions.done_sesssetup = true;
1727 END_PROFILE(SMBsesssetupX);