2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998-2001
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7 Copyright (C) Luke Howard 2003
8 Copyright (C) Volker Lendecke 2007
9 Copyright (C) Jeremy Allison 2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "../lib/tsocket/tsocket.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "../libcli/auth/spnego.h"
30 #include "../libcli/auth/ntlmssp.h"
31 #include "ntlmssp_wrap.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "libads/kerberos_proto.h"
34 #include "../lib/util/asn1.h"
37 #include "smbprofile.h"
39 /* For split krb5 SPNEGO blobs. */
40 struct pending_auth_data {
41 struct pending_auth_data *prev, *next;
42 uint16 vuid; /* Tag for this entry. */
43 uint16 smbpid; /* Alternate tag for this entry. */
45 DATA_BLOB partial_data;
49 on a logon error possibly map the error to success if "map to guest"
52 NTSTATUS do_map_to_guest(NTSTATUS status,
53 struct auth_serversupplied_info **server_info,
54 const char *user, const char *domain)
56 user = user ? user : "";
57 domain = domain ? domain : "";
59 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
60 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
61 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
62 DEBUG(3,("No such user %s [%s] - using guest account\n",
64 status = make_server_info_guest(NULL, server_info);
68 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
69 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
70 DEBUG(3,("Registered username %s for guest access\n",
72 status = make_server_info_guest(NULL, server_info);
79 /****************************************************************************
80 Add the standard 'Samba' signature to the end of the session setup.
81 ****************************************************************************/
83 static int push_signature(uint8 **outbuf)
90 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
92 if (tmp == -1) return -1;
95 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
96 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
100 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
103 if (tmp == -1) return -1;
106 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
108 if (tmp == -1) return -1;
114 /****************************************************************************
115 Send a security blob via a session setup reply.
116 ****************************************************************************/
118 static void reply_sesssetup_blob(struct smb_request *req,
122 if (!NT_STATUS_IS_OK(nt_status) &&
123 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
124 reply_nterror(req, nt_status_squash(nt_status));
128 nt_status = nt_status_squash(nt_status);
129 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
130 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
131 SSVAL(req->outbuf, smb_vwv3, blob.length);
133 if ((message_push_blob(&req->outbuf, blob) == -1)
134 || (push_signature(&req->outbuf) == -1)) {
135 reply_nterror(req, NT_STATUS_NO_MEMORY);
139 /****************************************************************************
140 Do a 'guest' logon, getting back the
141 ****************************************************************************/
143 static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
144 struct auth_serversupplied_info **server_info)
146 struct auth_context *auth_context;
147 struct auth_usersupplied_info *user_info = NULL;
150 static unsigned char chal[8] = { 0, };
152 DEBUG(3,("Got anonymous request\n"));
154 nt_status = make_auth_context_fixed(talloc_tos(), &auth_context, chal);
155 if (!NT_STATUS_IS_OK(nt_status)) {
159 if (!make_user_info_guest(remote_address, &user_info)) {
160 TALLOC_FREE(auth_context);
161 return NT_STATUS_NO_MEMORY;
164 nt_status = auth_context->check_ntlm_password(auth_context,
167 TALLOC_FREE(auth_context);
168 free_user_info(&user_info);
176 /* Experiment that failed. See "only happens with a KDC" comment below. */
177 /****************************************************************************
178 Cerate a clock skew error blob for a Windows client.
179 ****************************************************************************/
181 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
183 krb5_context context = NULL;
184 krb5_error_code kerr = 0;
186 krb5_principal host_princ = NULL;
187 char *host_princ_s = NULL;
190 *pblob_out = data_blob_null;
192 initialize_krb5_error_table();
193 kerr = krb5_init_context(&context);
197 /* Create server principal. */
198 asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
202 strlower_m(host_princ_s);
204 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
206 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
207 "for name %s: Error %s\n",
208 host_princ_s, error_message(kerr) ));
212 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
215 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
216 "failed: Error %s\n",
217 error_message(kerr) ));
221 *pblob_out = data_blob(reply.data, reply.length);
222 kerberos_free_data_contents(context,&reply);
228 SAFE_FREE(host_princ_s);
231 krb5_free_principal(context, host_princ);
233 krb5_free_context(context);
238 /****************************************************************************
239 Reply to a session setup spnego negotiate packet for kerberos.
240 ****************************************************************************/
242 static void reply_spnego_kerberos(struct smb_request *req,
246 bool *p_invalidate_vuid)
251 int sess_vuid = req->vuid;
252 NTSTATUS ret = NT_STATUS_OK;
253 DATA_BLOB ap_rep, ap_rep_wrapped, response;
254 struct auth_serversupplied_info *session_info = NULL;
255 DATA_BLOB session_key = data_blob_null;
257 DATA_BLOB nullblob = data_blob_null;
258 bool map_domainuser_to_guest = False;
259 bool username_was_mapped;
260 struct PAC_LOGON_INFO *logon_info = NULL;
261 struct smbd_server_connection *sconn = req->sconn;
269 ZERO_STRUCT(ap_rep_wrapped);
270 ZERO_STRUCT(response);
272 /* Normally we will always invalidate the intermediate vuid. */
273 *p_invalidate_vuid = True;
275 mem_ctx = talloc_init("reply_spnego_kerberos");
276 if (mem_ctx == NULL) {
277 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
281 if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
282 talloc_destroy(mem_ctx);
283 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
287 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
288 &principal, &logon_info, &ap_rep,
291 data_blob_free(&ticket);
293 if (!NT_STATUS_IS_OK(ret)) {
295 /* Experiment that failed.
296 * See "only happens with a KDC" comment below. */
298 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
301 * Windows in this case returns
302 * NT_STATUS_MORE_PROCESSING_REQUIRED
303 * with a negTokenTarg blob containing an krb5_error
304 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
305 * The client then fixes its clock and continues rather
306 * than giving an error. JRA.
307 * -- Looks like this only happens with a KDC. JRA.
310 bool ok = make_krb5_skew_error(&ap_rep);
312 talloc_destroy(mem_ctx);
313 return ERROR_NT(nt_status_squash(
314 NT_STATUS_LOGON_FAILURE));
316 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
318 response = spnego_gen_auth_response(&ap_rep_wrapped,
319 ret, OID_KERBEROS5_OLD);
320 reply_sesssetup_blob(conn, inbuf, outbuf, response,
321 NT_STATUS_MORE_PROCESSING_REQUIRED);
324 * In this one case we don't invalidate the
325 * intermediate vuid as we're expecting the client
326 * to re-use it for the next sessionsetupX packet. JRA.
329 *p_invalidate_vuid = False;
331 data_blob_free(&ap_rep);
332 data_blob_free(&ap_rep_wrapped);
333 data_blob_free(&response);
334 talloc_destroy(mem_ctx);
335 return -1; /* already replied */
338 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
339 ret = NT_STATUS_LOGON_FAILURE;
342 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
344 talloc_destroy(mem_ctx);
345 reply_nterror(req, nt_status_squash(ret));
349 ret = get_user_from_kerberos_info(talloc_tos(),
350 sconn->client_id.name,
351 principal, logon_info,
352 &username_was_mapped,
353 &map_domainuser_to_guest,
355 &real_username, &pw);
356 if (!NT_STATUS_IS_OK(ret)) {
357 data_blob_free(&ap_rep);
358 data_blob_free(&session_key);
359 talloc_destroy(mem_ctx);
360 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
364 /* save the PAC data if we have it */
366 netsamlogon_cache_store(user, &logon_info->info3);
369 /* setup the string used by %U */
370 sub_set_smb_name(real_username);
372 /* reload services so that the new %U is taken into account */
373 reload_services(sconn->msg_ctx, sconn->sock, True);
375 ret = make_session_info_krb5(mem_ctx,
376 user, domain, real_username, pw,
377 logon_info, map_domainuser_to_guest,
381 data_blob_free(&session_key);
382 if (!NT_STATUS_IS_OK(ret)) {
383 DEBUG(1, ("make_server_info_krb5 failed!\n"));
384 data_blob_free(&ap_rep);
385 TALLOC_FREE(mem_ctx);
386 reply_nterror(req, nt_status_squash(ret));
390 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
391 sess_vuid = register_initial_vuid(sconn);
394 /* register_existing_vuid keeps the server info */
395 /* register_existing_vuid takes ownership of session_key on success,
396 * no need to free after this on success. A better interface would copy
399 sess_vuid = register_existing_vuid(sconn, sess_vuid,
400 session_info, nullblob, user);
402 reply_outbuf(req, 4, 0);
403 SSVAL(req->outbuf,smb_uid,sess_vuid);
405 if (sess_vuid == UID_FIELD_INVALID ) {
406 ret = NT_STATUS_LOGON_FAILURE;
408 /* current_user_info is changed on new vuid */
409 reload_services(sconn->msg_ctx, sconn->sock, True);
411 SSVAL(req->outbuf, smb_vwv3, 0);
413 if (session_info->guest) {
414 SSVAL(req->outbuf,smb_vwv2,1);
417 SSVAL(req->outbuf, smb_uid, sess_vuid);
419 /* Successful logon. Keep this vuid. */
420 *p_invalidate_vuid = False;
423 /* wrap that up in a nice GSS-API wrapping */
424 if (NT_STATUS_IS_OK(ret)) {
425 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
428 ap_rep_wrapped = data_blob_null;
430 response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
432 reply_sesssetup_blob(req, response, ret);
434 data_blob_free(&ap_rep);
435 data_blob_free(&ap_rep_wrapped);
436 data_blob_free(&response);
437 TALLOC_FREE(mem_ctx);
442 /****************************************************************************
443 Send a session setup reply, wrapped in SPNEGO.
444 Get vuid and check first.
445 End the NTLMSSP exchange context if we are OK/complete fail
446 This should be split into two functions, one to handle each
447 leg of the NTLM auth steps.
448 ***************************************************************************/
450 static void reply_spnego_ntlmssp(struct smb_request *req,
452 struct auth_ntlmssp_state **auth_ntlmssp_state,
453 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
457 bool do_invalidate = true;
459 struct auth_serversupplied_info *session_info = NULL;
460 struct smbd_server_connection *sconn = req->sconn;
462 if (NT_STATUS_IS_OK(nt_status)) {
463 nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
464 (*auth_ntlmssp_state), &session_info);
466 /* Note that this session_info won't have a session
467 * key. But for map to guest, that's exactly the right
468 * thing - we can't reasonably guess the key the
469 * client wants, as the password was wrong */
470 nt_status = do_map_to_guest(nt_status,
472 auth_ntlmssp_get_username(*auth_ntlmssp_state),
473 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
476 reply_outbuf(req, 4, 0);
478 SSVAL(req->outbuf, smb_uid, vuid);
480 if (NT_STATUS_IS_OK(nt_status)) {
481 DATA_BLOB nullblob = data_blob_null;
483 if (!is_partial_auth_vuid(sconn, vuid)) {
484 nt_status = NT_STATUS_LOGON_FAILURE;
488 /* register_existing_vuid keeps the server info */
489 if (register_existing_vuid(sconn, vuid,
490 session_info, nullblob,
491 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
493 /* The problem is, *auth_ntlmssp_state points
494 * into the vuser this will have
495 * talloc_free()'ed in
496 * register_existing_vuid() */
497 do_invalidate = false;
498 nt_status = NT_STATUS_LOGON_FAILURE;
502 /* current_user_info is changed on new vuid */
503 reload_services(sconn->msg_ctx, sconn->sock, True);
505 SSVAL(req->outbuf, smb_vwv3, 0);
507 if (session_info->guest) {
508 SSVAL(req->outbuf,smb_vwv2,1);
515 response = spnego_gen_auth_response(talloc_tos(),
519 response = *ntlmssp_blob;
522 reply_sesssetup_blob(req, response, nt_status);
524 data_blob_free(&response);
527 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
528 and the other end, that we are not finished yet. */
530 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
531 /* NB. This is *NOT* an error case. JRA */
533 TALLOC_FREE(*auth_ntlmssp_state);
534 if (!NT_STATUS_IS_OK(nt_status)) {
535 /* Kill the intermediate vuid */
536 invalidate_vuid(sconn, vuid);
542 /****************************************************************************
543 Is this a krb5 mechanism ?
544 ****************************************************************************/
546 NTSTATUS parse_spnego_mechanisms(TALLOC_CTX *ctx,
548 DATA_BLOB *pblob_out,
551 char *OIDs[ASN1_MAX_OIDS];
553 NTSTATUS ret = NT_STATUS_OK;
555 *kerb_mechOID = NULL;
557 /* parse out the OIDs and the first sec blob */
558 if (!spnego_parse_negTokenInit(ctx, blob_in, OIDs, NULL, pblob_out) ||
560 return NT_STATUS_LOGON_FAILURE;
563 /* only look at the first OID for determining the mechToken --
564 according to RFC2478, we should choose the one we want
565 and renegotiate, but i smell a client bug here..
567 Problem observed when connecting to a member (samba box)
568 of an AD domain as a user in a Samba domain. Samba member
569 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
570 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
571 NTLMSSP mechtoken. --jerry */
574 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
575 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
576 *kerb_mechOID = talloc_strdup(ctx, OIDs[0]);
577 if (*kerb_mechOID == NULL) {
578 ret = NT_STATUS_NO_MEMORY;
583 for (i=0;OIDs[i];i++) {
584 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
585 talloc_free(OIDs[i]);
590 /****************************************************************************
591 Fall back from krb5 to NTLMSSP.
592 ****************************************************************************/
594 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
599 reply_outbuf(req, 4, 0);
600 SSVAL(req->outbuf,smb_uid,vuid);
602 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
603 "but set to downgrade to NTLMSSP\n"));
605 response = spnego_gen_auth_response(talloc_tos(), NULL,
606 NT_STATUS_MORE_PROCESSING_REQUIRED,
608 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
609 data_blob_free(&response);
612 /****************************************************************************
613 Reply to a session setup spnego negotiate packet.
614 ****************************************************************************/
616 static void reply_spnego_negotiate(struct smb_request *req,
619 struct auth_ntlmssp_state **auth_ntlmssp_state)
623 char *kerb_mech = NULL;
625 struct smbd_server_connection *sconn = req->sconn;
627 status = parse_spnego_mechanisms(talloc_tos(),
628 blob1, &secblob, &kerb_mech);
629 if (!NT_STATUS_IS_OK(status)) {
630 /* Kill the intermediate vuid */
631 invalidate_vuid(sconn, vuid);
632 reply_nterror(req, nt_status_squash(status));
636 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
637 (unsigned long)secblob.length));
640 if (kerb_mech && ((lp_security()==SEC_ADS) ||
641 USE_KERBEROS_KEYTAB) ) {
642 bool destroy_vuid = True;
643 reply_spnego_kerberos(req, &secblob, kerb_mech,
644 vuid, &destroy_vuid);
645 data_blob_free(&secblob);
647 /* Kill the intermediate vuid */
648 invalidate_vuid(sconn, vuid);
650 TALLOC_FREE(kerb_mech);
655 TALLOC_FREE(*auth_ntlmssp_state);
658 data_blob_free(&secblob);
659 /* The mechtoken is a krb5 ticket, but
660 * we need to fall back to NTLM. */
661 reply_spnego_downgrade_to_ntlmssp(req, vuid);
662 TALLOC_FREE(kerb_mech);
666 status = auth_ntlmssp_start(sconn->remote_address,
668 if (!NT_STATUS_IS_OK(status)) {
669 /* Kill the intermediate vuid */
670 invalidate_vuid(sconn, vuid);
671 reply_nterror(req, nt_status_squash(status));
675 status = auth_ntlmssp_update(*auth_ntlmssp_state,
678 data_blob_free(&secblob);
680 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
681 &chal, status, OID_NTLMSSP, true);
683 data_blob_free(&chal);
685 /* already replied */
689 /****************************************************************************
690 Reply to a session setup spnego auth packet.
691 ****************************************************************************/
693 static void reply_spnego_auth(struct smb_request *req,
696 struct auth_ntlmssp_state **auth_ntlmssp_state)
698 DATA_BLOB auth = data_blob_null;
699 DATA_BLOB auth_reply = data_blob_null;
700 DATA_BLOB secblob = data_blob_null;
701 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
702 struct smbd_server_connection *sconn = req->sconn;
704 if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
706 file_save("auth.dat", blob1.data, blob1.length);
708 /* Kill the intermediate vuid */
709 invalidate_vuid(sconn, vuid);
711 reply_nterror(req, nt_status_squash(
712 NT_STATUS_LOGON_FAILURE));
716 if (auth.data[0] == ASN1_APPLICATION(0)) {
717 /* Might be a second negTokenTarg packet */
718 char *kerb_mech = NULL;
720 status = parse_spnego_mechanisms(talloc_tos(),
721 auth, &secblob, &kerb_mech);
723 if (!NT_STATUS_IS_OK(status)) {
724 /* Kill the intermediate vuid */
725 invalidate_vuid(sconn, vuid);
726 reply_nterror(req, nt_status_squash(status));
730 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
731 (unsigned long)secblob.length));
733 if (kerb_mech && ((lp_security()==SEC_ADS) ||
734 USE_KERBEROS_KEYTAB)) {
735 bool destroy_vuid = True;
736 reply_spnego_kerberos(req, &secblob, kerb_mech,
737 vuid, &destroy_vuid);
738 data_blob_free(&secblob);
739 data_blob_free(&auth);
741 /* Kill the intermediate vuid */
742 invalidate_vuid(sconn, vuid);
744 TALLOC_FREE(kerb_mech);
748 /* Can't blunder into NTLMSSP auth if we have
752 /* Kill the intermediate vuid */
753 invalidate_vuid(sconn, vuid);
754 DEBUG(3,("reply_spnego_auth: network "
755 "misconfiguration, client sent us a "
756 "krb5 ticket and kerberos security "
758 reply_nterror(req, nt_status_squash(
759 NT_STATUS_LOGON_FAILURE));
760 TALLOC_FREE(kerb_mech);
764 /* If we get here it wasn't a negTokenTarg auth packet. */
765 data_blob_free(&secblob);
767 if (!*auth_ntlmssp_state) {
768 status = auth_ntlmssp_start(sconn->remote_address,
770 if (!NT_STATUS_IS_OK(status)) {
771 /* Kill the intermediate vuid */
772 invalidate_vuid(sconn, vuid);
773 reply_nterror(req, nt_status_squash(status));
778 status = auth_ntlmssp_update(*auth_ntlmssp_state,
781 data_blob_free(&auth);
783 /* Don't send the mechid as we've already sent this (RFC4178). */
785 reply_spnego_ntlmssp(req, vuid,
787 &auth_reply, status, NULL, true);
789 data_blob_free(&auth_reply);
791 /* and tell smbd that we have already replied to this packet */
795 /****************************************************************************
796 Delete an entry on the list.
797 ****************************************************************************/
799 static void delete_partial_auth(struct smbd_server_connection *sconn,
800 struct pending_auth_data *pad)
805 DLIST_REMOVE(sconn->smb1.pd_list, pad);
806 data_blob_free(&pad->partial_data);
810 /****************************************************************************
811 Search for a partial SPNEGO auth fragment matching an smbpid.
812 ****************************************************************************/
814 static struct pending_auth_data *get_pending_auth_data(
815 struct smbd_server_connection *sconn,
818 struct pending_auth_data *pad;
820 * NOTE: using the smbpid here is completely wrong...
822 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
824 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
825 if (pad->smbpid == smbpid) {
832 /****************************************************************************
833 Check the size of an SPNEGO blob. If we need more return
834 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
835 the blob to be more than 64k.
836 ****************************************************************************/
838 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
839 uint16 smbpid, uint16 vuid,
842 struct pending_auth_data *pad = NULL;
844 size_t needed_len = 0;
846 pad = get_pending_auth_data(sconn, smbpid);
848 /* Ensure we have some data. */
849 if (pblob->length == 0) {
850 /* Caller can cope. */
851 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
852 delete_partial_auth(sconn, pad);
856 /* Were we waiting for more data ? */
859 size_t copy_len = MIN(65536, pblob->length);
861 /* Integer wrap paranoia.... */
863 if (pad->partial_data.length + copy_len <
864 pad->partial_data.length ||
865 pad->partial_data.length + copy_len < copy_len) {
867 DEBUG(2,("check_spnego_blob_complete: integer wrap "
868 "pad->partial_data.length = %u, "
870 (unsigned int)pad->partial_data.length,
871 (unsigned int)copy_len ));
873 delete_partial_auth(sconn, pad);
874 return NT_STATUS_INVALID_PARAMETER;
877 DEBUG(10,("check_spnego_blob_complete: "
878 "pad->partial_data.length = %u, "
879 "pad->needed_len = %u, "
881 "pblob->length = %u,\n",
882 (unsigned int)pad->partial_data.length,
883 (unsigned int)pad->needed_len,
884 (unsigned int)copy_len,
885 (unsigned int)pblob->length ));
887 tmp_blob = data_blob(NULL,
888 pad->partial_data.length + copy_len);
890 /* Concatenate the two (up to copy_len) bytes. */
891 memcpy(tmp_blob.data,
892 pad->partial_data.data,
893 pad->partial_data.length);
894 memcpy(tmp_blob.data + pad->partial_data.length,
898 /* Replace the partial data. */
899 data_blob_free(&pad->partial_data);
900 pad->partial_data = tmp_blob;
901 ZERO_STRUCT(tmp_blob);
904 if (pblob->length >= pad->needed_len) {
905 /* Yes, replace pblob. */
906 data_blob_free(pblob);
907 *pblob = pad->partial_data;
908 ZERO_STRUCT(pad->partial_data);
909 delete_partial_auth(sconn, pad);
913 /* Still need more data. */
914 pad->needed_len -= copy_len;
915 return NT_STATUS_MORE_PROCESSING_REQUIRED;
918 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
919 (pblob->data[0] != ASN1_CONTEXT(1))) {
920 /* Not something we can determine the
926 /* This is a new SPNEGO sessionsetup - see if
927 * the data given in this blob is enough.
930 data = asn1_init(NULL);
932 return NT_STATUS_NO_MEMORY;
935 asn1_load(data, *pblob);
936 if (asn1_start_tag(data, pblob->data[0])) {
937 /* asn1_start_tag checks if the given
938 length of the blob is enough to complete
939 the tag. If it returns true we know
940 there is nothing to do - the blob is
946 if (data->nesting == NULL) {
947 /* Incorrect tag, allocation failed,
948 or reading the tag length failed.
949 Let the caller catch. */
954 /* Here we know asn1_start_tag() has set data->has_error to true.
955 asn1_tag_remaining() will have failed due to the given blob
956 being too short. We need to work out how short. */
958 /* Integer wrap paranoia.... */
960 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
961 data->nesting->taglen + data->nesting->start < data->nesting->start) {
963 DEBUG(2,("check_spnego_blob_complete: integer wrap "
964 "data.nesting->taglen = %u, "
965 "data.nesting->start = %u\n",
966 (unsigned int)data->nesting->taglen,
967 (unsigned int)data->nesting->start ));
970 return NT_STATUS_INVALID_PARAMETER;
973 /* Total length of the needed asn1 is the tag length
974 * plus the current offset. */
976 needed_len = data->nesting->taglen + data->nesting->start;
979 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
980 "pblob->length = %u\n",
981 (unsigned int)needed_len,
982 (unsigned int)pblob->length ));
984 if (needed_len <= pblob->length) {
985 /* Nothing to do - blob is complete. */
986 /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
987 above should have caught this !!! */
988 DEBUG(0,("check_spnego_blob_complete: logic "
989 "error (needed_len = %u, "
990 "pblob->length = %u).\n",
991 (unsigned int)needed_len,
992 (unsigned int)pblob->length ));
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 = (const 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(sconn->remote_address,
1182 &vuser->auth_ntlmssp_state);
1183 if (!NT_STATUS_IS_OK(status)) {
1184 /* Kill the intermediate vuid */
1185 invalidate_vuid(sconn, vuid);
1186 data_blob_free(&blob1);
1187 reply_nterror(req, nt_status_squash(status));
1192 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1195 data_blob_free(&blob1);
1197 reply_spnego_ntlmssp(req, vuid,
1198 &vuser->auth_ntlmssp_state,
1199 &chal, status, OID_NTLMSSP, false);
1200 data_blob_free(&chal);
1204 /* what sort of packet is this? */
1205 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1207 data_blob_free(&blob1);
1209 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1212 /****************************************************************************
1213 On new VC == 0, shutdown *all* old connections and users.
1214 It seems that only NT4.x does this. At W2K and above (XP etc.).
1215 a new session setup with VC==0 is ignored.
1216 ****************************************************************************/
1218 struct shutdown_state {
1220 struct messaging_context *msg_ctx;
1223 static int shutdown_other_smbds(const struct connections_key *key,
1224 const struct connections_data *crec,
1227 struct shutdown_state *state = (struct shutdown_state *)private_data;
1229 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1230 server_id_str(talloc_tos(), &crec->pid), crec->addr));
1232 if (!process_exists(crec->pid)) {
1233 DEBUG(10, ("process does not exist\n"));
1237 if (procid_is_me(&crec->pid)) {
1238 DEBUG(10, ("It's me\n"));
1242 if (strcmp(state->ip, crec->addr) != 0) {
1243 DEBUG(10, ("%s does not match %s\n", state->ip, crec->addr));
1247 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1248 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1251 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1256 static void setup_new_vc_session(struct smbd_server_connection *sconn)
1258 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1259 "compatible we would close all old resources.\n"));
1262 invalidate_all_vuids();
1264 if (lp_reset_on_zero_vc()) {
1266 struct shutdown_state state;
1268 addr = tsocket_address_inet_addr_string(
1269 sconn->remote_address, talloc_tos());
1274 state.msg_ctx = sconn->msg_ctx;
1275 connections_forall_read(shutdown_other_smbds, &state);
1280 /****************************************************************************
1281 Reply to a session setup command.
1282 ****************************************************************************/
1284 void reply_sesssetup_and_X(struct smb_request *req)
1290 DATA_BLOB plaintext_password;
1293 fstring sub_user; /* Sanitised username for substituion */
1295 const char *native_os;
1296 const char *native_lanman;
1297 const char *primary_domain;
1298 struct auth_usersupplied_info *user_info = NULL;
1299 struct auth_serversupplied_info *server_info = NULL;
1300 struct auth_serversupplied_info *session_info = NULL;
1301 uint16 smb_flag2 = req->flags2;
1304 struct smbd_server_connection *sconn = req->sconn;
1306 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1308 START_PROFILE(SMBsesssetupX);
1310 ZERO_STRUCT(lm_resp);
1311 ZERO_STRUCT(nt_resp);
1312 ZERO_STRUCT(plaintext_password);
1314 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1316 /* a SPNEGO session setup has 12 command words, whereas a normal
1317 NT1 session setup has 13. See the cifs spec. */
1318 if (req->wct == 12 &&
1319 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1321 if (!sconn->smb1.negprot.spnego) {
1322 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1323 "at SPNEGO session setup when it was not "
1325 reply_nterror(req, nt_status_squash(
1326 NT_STATUS_LOGON_FAILURE));
1327 END_PROFILE(SMBsesssetupX);
1331 if (SVAL(req->vwv+4, 0) == 0) {
1332 setup_new_vc_session(req->sconn);
1335 reply_sesssetup_and_X_spnego(req);
1336 END_PROFILE(SMBsesssetupX);
1340 smb_bufsize = SVAL(req->vwv+2, 0);
1342 if (get_Protocol() < PROTOCOL_NT1) {
1343 uint16 passlen1 = SVAL(req->vwv+7, 0);
1345 /* Never do NT status codes with protocols before NT1 as we
1346 * don't get client caps. */
1347 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1349 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1350 reply_nterror(req, nt_status_squash(
1351 NT_STATUS_INVALID_PARAMETER));
1352 END_PROFILE(SMBsesssetupX);
1357 lm_resp = data_blob(req->buf, passlen1);
1359 plaintext_password = data_blob(req->buf, passlen1+1);
1360 /* Ensure null termination */
1361 plaintext_password.data[passlen1] = 0;
1364 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1365 req->buf + passlen1, STR_TERMINATE);
1366 user = tmp ? tmp : "";
1371 uint16 passlen1 = SVAL(req->vwv+7, 0);
1372 uint16 passlen2 = SVAL(req->vwv+8, 0);
1373 enum remote_arch_types ra_type = get_remote_arch();
1374 const uint8_t *p = req->buf;
1375 const uint8_t *save_p = req->buf;
1379 if(global_client_caps == 0) {
1380 global_client_caps = IVAL(req->vwv+11, 0);
1382 if (!(global_client_caps & CAP_STATUS32)) {
1383 remove_from_common_flags2(
1384 FLAGS2_32_BIT_ERROR_CODES);
1387 /* client_caps is used as final determination if
1388 * client is NT or Win95. This is needed to return
1389 * the correct error codes in some circumstances.
1392 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1393 ra_type == RA_WIN95) {
1394 if(!(global_client_caps & (CAP_NT_SMBS|
1396 set_remote_arch( RA_WIN95);
1402 /* both Win95 and WinNT stuff up the password
1403 * lengths for non-encrypting systems. Uggh.
1405 if passlen1==24 its a win95 system, and its setting
1406 the password length incorrectly. Luckily it still
1407 works with the default code because Win95 will null
1408 terminate the password anyway
1410 if passlen1>0 and passlen2>0 then maybe its a NT box
1411 and its setting passlen2 to some random value which
1412 really stuffs things up. we need to fix that one. */
1414 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1420 /* check for nasty tricks */
1421 if (passlen1 > MAX_PASS_LEN
1422 || passlen1 > smbreq_bufrem(req, p)) {
1423 reply_nterror(req, nt_status_squash(
1424 NT_STATUS_INVALID_PARAMETER));
1425 END_PROFILE(SMBsesssetupX);
1429 if (passlen2 > MAX_PASS_LEN
1430 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1431 reply_nterror(req, nt_status_squash(
1432 NT_STATUS_INVALID_PARAMETER));
1433 END_PROFILE(SMBsesssetupX);
1437 /* Save the lanman2 password and the NT md4 password. */
1439 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1444 lm_resp = data_blob(p, passlen1);
1445 nt_resp = data_blob(p+passlen1, passlen2);
1446 } else if (lp_security() != SEC_SHARE) {
1448 * In share level we should ignore any passwords, so
1449 * only read them if we're not.
1452 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1454 if (unic && (passlen2 == 0) && passlen1) {
1455 /* Only a ascii plaintext password was sent. */
1456 (void)srvstr_pull_talloc(talloc_tos(),
1462 STR_TERMINATE|STR_ASCII);
1464 (void)srvstr_pull_talloc(talloc_tos(),
1469 unic ? passlen2 : passlen1,
1473 reply_nterror(req, nt_status_squash(
1474 NT_STATUS_INVALID_PARAMETER));
1475 END_PROFILE(SMBsesssetupX);
1478 plaintext_password = data_blob(pass, strlen(pass)+1);
1481 p += passlen1 + passlen2;
1483 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1485 user = tmp ? tmp : "";
1487 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1489 domain = tmp ? tmp : "";
1491 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1493 native_os = tmp ? tmp : "";
1495 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1497 native_lanman = tmp ? tmp : "";
1499 /* not documented or decoded by Ethereal but there is one more
1500 * string in the extra bytes which is the same as the
1501 * PrimaryDomain when using extended security. Windows NT 4
1502 * and 2003 use this string to store the native lanman string.
1503 * Windows 9x does not include a string here at all so we have
1504 * to check if we have any extra bytes left */
1506 byte_count = SVAL(req->vwv+13, 0);
1507 if ( PTR_DIFF(p, save_p) < byte_count) {
1508 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1510 primary_domain = tmp ? tmp : "";
1512 primary_domain = talloc_strdup(talloc_tos(), "null");
1515 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1516 "PrimaryDomain=[%s]\n",
1517 domain, native_os, native_lanman, primary_domain));
1519 if ( ra_type == RA_WIN2K ) {
1520 if ( strlen(native_lanman) == 0 )
1521 ra_lanman_string( primary_domain );
1523 ra_lanman_string( native_lanman );
1528 if (SVAL(req->vwv+4, 0) == 0) {
1529 setup_new_vc_session(req->sconn);
1532 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1533 domain, user, get_remote_machine_name()));
1536 if (sconn->smb1.negprot.spnego) {
1538 /* This has to be here, because this is a perfectly
1539 * valid behaviour for guest logons :-( */
1541 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1542 "at 'normal' session setup after "
1543 "negotiating spnego.\n"));
1544 reply_nterror(req, nt_status_squash(
1545 NT_STATUS_LOGON_FAILURE));
1546 END_PROFILE(SMBsesssetupX);
1549 fstrcpy(sub_user, user);
1551 fstrcpy(sub_user, lp_guestaccount());
1554 sub_set_smb_name(sub_user);
1556 reload_services(sconn->msg_ctx, sconn->sock, True);
1558 if (lp_security() == SEC_SHARE) {
1559 char *sub_user_mapped = NULL;
1560 /* In share level we should ignore any passwords */
1562 data_blob_free(&lm_resp);
1563 data_blob_free(&nt_resp);
1564 data_blob_clear_free(&plaintext_password);
1566 (void)map_username(talloc_tos(), sub_user, &sub_user_mapped);
1567 if (!sub_user_mapped) {
1568 reply_nterror(req, NT_STATUS_NO_MEMORY);
1569 END_PROFILE(SMBsesssetupX);
1572 fstrcpy(sub_user, sub_user_mapped);
1573 add_session_user(sconn, sub_user);
1574 add_session_workgroup(sconn, domain);
1575 /* Then force it to null for the benfit of the code below */
1581 nt_status = check_guest_password(sconn->remote_address, &server_info);
1583 } else if (doencrypt) {
1584 struct auth_context *negprot_auth_context = NULL;
1585 negprot_auth_context = sconn->smb1.negprot.auth_context;
1586 if (!negprot_auth_context) {
1587 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1588 "session setup without negprot denied!\n"));
1589 reply_nterror(req, nt_status_squash(
1590 NT_STATUS_LOGON_FAILURE));
1591 END_PROFILE(SMBsesssetupX);
1594 nt_status = make_user_info_for_reply_enc(&user_info, user,
1596 sconn->remote_address,
1598 if (NT_STATUS_IS_OK(nt_status)) {
1599 nt_status = negprot_auth_context->check_ntlm_password(
1600 negprot_auth_context,
1605 struct auth_context *plaintext_auth_context = NULL;
1607 nt_status = make_auth_context_subsystem(
1608 talloc_tos(), &plaintext_auth_context);
1610 if (NT_STATUS_IS_OK(nt_status)) {
1613 plaintext_auth_context->get_ntlm_challenge(
1614 plaintext_auth_context, chal);
1616 if (!make_user_info_for_reply(&user_info,
1618 sconn->remote_address,
1620 plaintext_password)) {
1621 nt_status = NT_STATUS_NO_MEMORY;
1624 if (NT_STATUS_IS_OK(nt_status)) {
1625 nt_status = plaintext_auth_context->check_ntlm_password(
1626 plaintext_auth_context,
1630 TALLOC_FREE(plaintext_auth_context);
1635 free_user_info(&user_info);
1637 if (!NT_STATUS_IS_OK(nt_status)) {
1638 nt_status = do_map_to_guest(nt_status, &server_info,
1642 if (!NT_STATUS_IS_OK(nt_status)) {
1643 data_blob_free(&nt_resp);
1644 data_blob_free(&lm_resp);
1645 data_blob_clear_free(&plaintext_password);
1646 reply_nterror(req, nt_status_squash(nt_status));
1647 END_PROFILE(SMBsesssetupX);
1651 nt_status = create_local_token(req, server_info, NULL, &session_info);
1652 TALLOC_FREE(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);
1665 data_blob_clear_free(&plaintext_password);
1667 /* it's ok - setup a reply */
1668 reply_outbuf(req, 3, 0);
1669 if (get_Protocol() >= PROTOCOL_NT1) {
1670 push_signature(&req->outbuf);
1671 /* perhaps grab OS version here?? */
1674 if (session_info->guest) {
1675 SSVAL(req->outbuf,smb_vwv2,1);
1678 /* register the name and uid as being validated, so further connections
1679 to a uid can get through without a password, on the same VC */
1681 if (lp_security() == SEC_SHARE) {
1682 sess_vuid = UID_FIELD_INVALID;
1683 TALLOC_FREE(session_info);
1685 /* Ignore the initial vuid. */
1686 sess_vuid = register_initial_vuid(sconn);
1687 if (sess_vuid == UID_FIELD_INVALID) {
1688 data_blob_free(&nt_resp);
1689 data_blob_free(&lm_resp);
1690 reply_nterror(req, nt_status_squash(
1691 NT_STATUS_LOGON_FAILURE));
1692 END_PROFILE(SMBsesssetupX);
1695 /* register_existing_vuid keeps the session_info */
1696 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1698 nt_resp.data ? nt_resp : lm_resp,
1700 if (sess_vuid == UID_FIELD_INVALID) {
1701 data_blob_free(&nt_resp);
1702 data_blob_free(&lm_resp);
1703 reply_nterror(req, nt_status_squash(
1704 NT_STATUS_LOGON_FAILURE));
1705 END_PROFILE(SMBsesssetupX);
1709 /* current_user_info is changed on new vuid */
1710 reload_services(sconn->msg_ctx, sconn->sock, True);
1713 data_blob_free(&nt_resp);
1714 data_blob_free(&lm_resp);
1716 SSVAL(req->outbuf,smb_uid,sess_vuid);
1717 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1718 req->vuid = sess_vuid;
1720 if (!sconn->smb1.sessions.done_sesssetup) {
1721 sconn->smb1.sessions.max_send =
1722 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1724 sconn->smb1.sessions.done_sesssetup = true;
1726 END_PROFILE(SMBsesssetupX);