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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern struct auth_context *negprot_global_auth_context;
27 extern BOOL global_encrypted_passwords_negotiated;
28 extern BOOL global_spnego_negotiated;
29 extern enum protocol_types Protocol;
32 uint32 global_client_caps = 0;
35 on a logon error possibly map the error to success if "map to guest"
38 static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info,
39 const char *user, const char *domain)
41 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
42 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
43 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
44 DEBUG(3,("No such user %s [%s] - using guest account\n",
46 status = make_server_info_guest(server_info);
50 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
51 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
52 DEBUG(3,("Registered username %s for guest access\n",user));
53 status = make_server_info_guest(server_info);
60 /****************************************************************************
61 Add the standard 'Samba' signature to the end of the session setup.
62 ****************************************************************************/
64 static int add_signature(char *outbuf, char *p)
69 fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
71 p += srvstr_push(outbuf, p, "Unix", BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
72 p += srvstr_push(outbuf, p, lanman, BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
73 p += srvstr_push(outbuf, p, lp_workgroup(), BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
75 return PTR_DIFF(p, start);
78 /****************************************************************************
79 Start the signing engine if needed. Don't fail signing here.
80 ****************************************************************************/
82 static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, char *inbuf)
84 if (!server_info->guest && !srv_signing_started()) {
85 /* We need to start the signing engine
86 * here but a W2K client sends the old
87 * "BSRSPYL " signature instead of the
88 * correct one. Subsequent packets will
91 srv_check_sign_mac(inbuf, False);
95 /****************************************************************************
96 Send a security blob via a session setup reply.
97 ****************************************************************************/
99 static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
100 DATA_BLOB blob, NTSTATUS nt_status)
104 if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
105 ERROR_NT(nt_status_squash(nt_status));
107 set_message(outbuf,4,0,True);
109 nt_status = nt_status_squash(nt_status);
110 SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status));
111 SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
112 SSVAL(outbuf, smb_vwv3, blob.length);
115 /* should we cap this? */
116 memcpy(p, blob.data, blob.length);
119 p += add_signature( outbuf, p );
121 set_message_end(outbuf,p);
125 return send_smb(smbd_server_fd(),outbuf);
128 /****************************************************************************
129 Do a 'guest' logon, getting back the
130 ****************************************************************************/
132 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
134 struct auth_context *auth_context;
135 auth_usersupplied_info *user_info = NULL;
138 unsigned char chal[8];
142 DEBUG(3,("Got anonymous request\n"));
144 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
148 if (!make_user_info_guest(&user_info)) {
149 (auth_context->free)(&auth_context);
150 return NT_STATUS_NO_MEMORY;
153 nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
154 (auth_context->free)(&auth_context);
155 free_user_info(&user_info);
163 /* Experiment that failed. See "only happens with a KDC" comment below. */
164 /****************************************************************************
165 Cerate a clock skew error blob for a Windows client.
166 ****************************************************************************/
168 static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out)
170 krb5_context context = NULL;
171 krb5_error_code kerr = 0;
173 krb5_principal host_princ = NULL;
174 char *host_princ_s = NULL;
177 *pblob_out = data_blob(NULL,0);
179 initialize_krb5_error_table();
180 kerr = krb5_init_context(&context);
184 /* Create server principal. */
185 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
189 strlower_m(host_princ_s);
191 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
193 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed for name %s: Error %s\n",
194 host_princ_s, error_message(kerr) ));
198 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, host_princ, &reply);
200 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error failed: Error %s\n",
201 error_message(kerr) ));
205 *pblob_out = data_blob(reply.data, reply.length);
206 kerberos_free_data_contents(context,&reply);
212 SAFE_FREE(host_princ_s);
215 krb5_free_principal(context, host_princ);
217 krb5_free_context(context);
222 /****************************************************************************
223 Reply to a session setup spnego negotiate packet for kerberos.
224 ****************************************************************************/
226 static int reply_spnego_kerberos(connection_struct *conn,
227 char *inbuf, char *outbuf,
228 int length, int bufsize,
230 BOOL *p_invalidate_vuid)
234 char *client, *p, *domain;
235 fstring netbios_domain_name;
241 DATA_BLOB ap_rep, ap_rep_wrapped, response;
242 auth_serversupplied_info *server_info = NULL;
243 DATA_BLOB session_key = data_blob(NULL, 0);
245 DATA_BLOB nullblob = data_blob(NULL, 0);
246 fstring real_username;
247 BOOL map_domainuser_to_guest = False;
248 BOOL username_was_mapped;
249 PAC_LOGON_INFO *logon_info = NULL;
252 ZERO_STRUCT(pac_data);
254 ZERO_STRUCT(ap_rep_wrapped);
255 ZERO_STRUCT(response);
257 /* Normally we will always invalidate the intermediate vuid. */
258 *p_invalidate_vuid = True;
260 mem_ctx = talloc_init("reply_spnego_kerberos");
261 if (mem_ctx == NULL) {
262 return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY));
265 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
266 talloc_destroy(mem_ctx);
267 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
270 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key);
272 data_blob_free(&ticket);
274 if (!NT_STATUS_IS_OK(ret)) {
276 /* Experiment that failed. See "only happens with a KDC" comment below. */
278 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
281 * Windows in this case returns NT_STATUS_MORE_PROCESSING_REQUIRED
282 * with a negTokenTarg blob containing an krb5_error struct ASN1 encoded
283 * containing KRB5KRB_AP_ERR_SKEW. The client then fixes its
284 * clock and continues rather than giving an error. JRA.
285 * -- Looks like this only happens with a KDC. JRA.
288 BOOL ok = make_krb5_skew_error(&ap_rep);
290 talloc_destroy(mem_ctx);
291 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
293 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR);
294 response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
295 reply_sesssetup_blob(conn, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
298 * In this one case we don't invalidate the intermediate vuid.
299 * as we're expecting the client to re-use it for the next
300 * sessionsetupX packet. JRA.
303 *p_invalidate_vuid = False;
305 data_blob_free(&ap_rep);
306 data_blob_free(&ap_rep_wrapped);
307 data_blob_free(&response);
308 talloc_destroy(mem_ctx);
309 return -1; /* already replied */
312 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
313 ret = NT_STATUS_LOGON_FAILURE;
316 DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret)));
317 talloc_destroy(mem_ctx);
318 return ERROR_NT(nt_status_squash(ret));
321 DEBUG(3,("Ticket name is [%s]\n", client));
323 p = strchr_m(client, '@');
325 DEBUG(3,("Doesn't look like a valid principal\n"));
326 data_blob_free(&ap_rep);
327 data_blob_free(&session_key);
329 talloc_destroy(mem_ctx);
330 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
335 /* save the PAC data if we have it */
338 logon_info = get_logon_info_from_pac(pac_data);
340 netsamlogon_cache_store( client, &logon_info->info3 );
344 if (!strequal(p+1, lp_realm())) {
345 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
346 if (!lp_allow_trusted_domains()) {
347 data_blob_free(&ap_rep);
348 data_blob_free(&session_key);
350 talloc_destroy(mem_ctx);
351 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
355 /* this gives a fully qualified user name (ie. with full realm).
356 that leads to very long usernames, but what else can we do? */
360 if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) {
362 unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1);
363 domain = netbios_domain_name;
364 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
368 /* If we have winbind running, we can (and must) shorten the
369 username by using the short netbios name. Otherwise we will
370 have inconsistent user names. With Kerberos, we get the
371 fully qualified realm, with ntlmssp we get the short
372 name. And even w2k3 does use ntlmssp if you for example
373 connect to an ip address. */
375 struct winbindd_request wb_request;
376 struct winbindd_response wb_response;
377 NSS_STATUS wb_result;
379 ZERO_STRUCT(wb_request);
380 ZERO_STRUCT(wb_response);
382 DEBUG(10, ("Mapping [%s] to short name\n", domain));
384 fstrcpy(wb_request.domain_name, domain);
386 wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
387 &wb_request, &wb_response);
389 if (wb_result == NSS_STATUS_SUCCESS) {
391 fstrcpy(netbios_domain_name,
392 wb_response.data.domain_info.name);
393 domain = netbios_domain_name;
395 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
397 DEBUG(3, ("Could not find short name -- winbind "
402 fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
404 /* lookup the passwd struct, create a new user if necessary */
406 username_was_mapped = map_username( user );
408 pw = smb_getpwnam( mem_ctx, user, real_username, True );
411 /* if a real user check pam account restrictions */
412 /* only really perfomed if "obey pam restriction" is true */
413 /* do this before an eventual mappign to guest occurs */
414 ret = smb_pam_accountcheck(pw->pw_name);
415 if ( !NT_STATUS_IS_OK(ret)) {
416 DEBUG(1, ("PAM account restriction prevents user login\n"));
417 data_blob_free(&ap_rep);
418 data_blob_free(&session_key);
419 TALLOC_FREE(mem_ctx);
420 return ERROR_NT(nt_status_squash(ret));
426 /* this was originally the behavior of Samba 2.2, if a user
427 did not have a local uid but has been authenticated, then
428 map them to a guest account */
430 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
431 map_domainuser_to_guest = True;
432 fstrcpy(user,lp_guestaccount());
433 pw = smb_getpwnam( mem_ctx, user, real_username, True );
436 /* extra sanity check that the guest account is valid */
439 DEBUG(1,("Username %s is invalid on this system\n", user));
441 data_blob_free(&ap_rep);
442 data_blob_free(&session_key);
443 TALLOC_FREE(mem_ctx);
444 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
448 /* setup the string used by %U */
450 sub_set_smb_name( real_username );
451 reload_services(True);
453 if ( map_domainuser_to_guest ) {
454 make_server_info_guest(&server_info);
455 } else if (logon_info) {
456 /* pass the unmapped username here since map_username()
457 will be called again from inside make_server_info_info3() */
459 ret = make_server_info_info3(mem_ctx, client, domain,
460 &server_info, &logon_info->info3);
461 if ( !NT_STATUS_IS_OK(ret) ) {
462 DEBUG(1,("make_server_info_info3 failed: %s!\n",
465 data_blob_free(&ap_rep);
466 data_blob_free(&session_key);
467 TALLOC_FREE(mem_ctx);
468 return ERROR_NT(nt_status_squash(ret));
472 ret = make_server_info_pw(&server_info, real_username, pw);
474 if ( !NT_STATUS_IS_OK(ret) ) {
475 DEBUG(1,("make_server_info_pw failed: %s!\n",
478 data_blob_free(&ap_rep);
479 data_blob_free(&session_key);
480 TALLOC_FREE(mem_ctx);
481 return ERROR_NT(nt_status_squash(ret));
484 /* make_server_info_pw does not set the domain. Without this
485 * we end up with the local netbios name in substitutions for
488 if (server_info->sam_account != NULL) {
489 pdb_set_domain(server_info->sam_account, domain, PDB_SET);
493 server_info->was_mapped |= username_was_mapped;
495 /* we need to build the token for the user. make_server_info_guest()
498 if ( !server_info->ptok ) {
499 ret = create_local_token( server_info );
500 if ( !NT_STATUS_IS_OK(ret) ) {
502 data_blob_free(&ap_rep);
503 data_blob_free(&session_key);
504 TALLOC_FREE( mem_ctx );
505 TALLOC_FREE( server_info );
506 return ERROR_NT(nt_status_squash(ret));
510 /* register_vuid keeps the server info */
511 /* register_vuid takes ownership of session_key, no need to free after this.
512 A better interface would copy it.... */
513 sess_vuid = register_vuid(server_info, session_key, nullblob, client);
517 if (sess_vuid == UID_FIELD_INVALID ) {
518 ret = NT_STATUS_LOGON_FAILURE;
520 /* current_user_info is changed on new vuid */
521 reload_services( True );
523 set_message(outbuf,4,0,True);
524 SSVAL(outbuf, smb_vwv3, 0);
526 if (server_info->guest) {
527 SSVAL(outbuf,smb_vwv2,1);
530 SSVAL(outbuf, smb_uid, sess_vuid);
532 sessionsetup_start_signing_engine(server_info, inbuf);
535 /* wrap that up in a nice GSS-API wrapping */
536 if (NT_STATUS_IS_OK(ret)) {
537 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
539 ap_rep_wrapped = data_blob(NULL, 0);
541 response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
542 reply_sesssetup_blob(conn, outbuf, response, ret);
544 data_blob_free(&ap_rep);
545 data_blob_free(&ap_rep_wrapped);
546 data_blob_free(&response);
547 TALLOC_FREE(mem_ctx);
549 return -1; /* already replied */
553 /****************************************************************************
554 Send a session setup reply, wrapped in SPNEGO.
555 Get vuid and check first.
556 End the NTLMSSP exchange context if we are OK/complete fail
557 This should be split into two functions, one to handle each
558 leg of the NTLM auth steps.
559 ***************************************************************************/
561 static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
563 AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
564 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
569 struct auth_serversupplied_info *server_info = NULL;
571 if (NT_STATUS_IS_OK(nt_status)) {
572 server_info = (*auth_ntlmssp_state)->server_info;
574 nt_status = do_map_to_guest(nt_status,
576 (*auth_ntlmssp_state)->ntlmssp_state->user,
577 (*auth_ntlmssp_state)->ntlmssp_state->domain);
580 if (NT_STATUS_IS_OK(nt_status)) {
582 DATA_BLOB nullblob = data_blob(NULL, 0);
583 DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
585 /* register_vuid keeps the server info */
586 sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
587 (*auth_ntlmssp_state)->server_info = NULL;
589 if (sess_vuid == UID_FIELD_INVALID ) {
590 nt_status = NT_STATUS_LOGON_FAILURE;
593 /* current_user_info is changed on new vuid */
594 reload_services( True );
596 set_message(outbuf,4,0,True);
597 SSVAL(outbuf, smb_vwv3, 0);
599 if (server_info->guest) {
600 SSVAL(outbuf,smb_vwv2,1);
603 SSVAL(outbuf,smb_uid,sess_vuid);
605 sessionsetup_start_signing_engine(server_info, inbuf);
610 response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP);
612 response = *ntlmssp_blob;
615 ret = reply_sesssetup_blob(conn, outbuf, response, nt_status);
617 data_blob_free(&response);
620 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
621 and the other end, that we are not finished yet. */
623 if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
624 /* NB. This is *NOT* an error case. JRA */
625 auth_ntlmssp_end(auth_ntlmssp_state);
626 /* Kill the intermediate vuid */
627 invalidate_intermediate_vuid(vuid);
633 /****************************************************************************
634 Is this a krb5 mechanism ?
635 ****************************************************************************/
637 static NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5)
639 char *OIDs[ASN1_MAX_OIDS];
644 /* parse out the OIDs and the first sec blob */
645 if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
646 return NT_STATUS_LOGON_FAILURE;
649 /* only look at the first OID for determining the mechToken --
650 accoirding to RFC2478, we should choose the one we want
651 and renegotiate, but i smell a client bug here..
653 Problem observed when connecting to a member (samba box)
654 of an AD domain as a user in a Samba domain. Samba member
655 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
656 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
657 NTLMSSP mechtoken. --jerry */
660 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
661 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
666 for (i=0;OIDs[i];i++) {
667 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
673 /****************************************************************************
674 Reply to a session setup spnego negotiate packet.
675 ****************************************************************************/
677 static int reply_spnego_negotiate(connection_struct *conn,
681 int length, int bufsize,
683 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
687 BOOL got_kerberos_mechanism = False;
690 status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism);
691 if (!NT_STATUS_IS_OK(status)) {
692 /* Kill the intermediate vuid */
693 invalidate_intermediate_vuid(vuid);
694 return ERROR_NT(nt_status_squash(status));
697 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
700 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
701 BOOL destroy_vuid = True;
702 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
703 length, bufsize, &secblob, &destroy_vuid);
704 data_blob_free(&secblob);
706 /* Kill the intermediate vuid */
707 invalidate_intermediate_vuid(vuid);
713 if (got_kerberos_mechanism) {
714 invalidate_intermediate_vuid(vuid);
715 DEBUG(3,("reply_spnego_negotiate: network "
716 "misconfiguration, client sent us a "
717 "krb5 ticket and kerberos security "
719 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
722 if (*auth_ntlmssp_state) {
723 auth_ntlmssp_end(auth_ntlmssp_state);
726 status = auth_ntlmssp_start(auth_ntlmssp_state);
727 if (!NT_STATUS_IS_OK(status)) {
728 /* Kill the intermediate vuid */
729 invalidate_intermediate_vuid(vuid);
730 return ERROR_NT(nt_status_squash(status));
733 status = auth_ntlmssp_update(*auth_ntlmssp_state,
736 data_blob_free(&secblob);
738 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state,
739 &chal, status, True);
741 data_blob_free(&chal);
743 /* already replied */
747 /****************************************************************************
748 Reply to a session setup spnego auth packet.
749 ****************************************************************************/
751 static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
753 int length, int bufsize,
755 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
757 DATA_BLOB auth = data_blob(NULL,0);
758 DATA_BLOB auth_reply = data_blob(NULL,0);
759 DATA_BLOB secblob = data_blob(NULL,0);
760 NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
762 if (!spnego_parse_auth(blob1, &auth)) {
764 file_save("auth.dat", blob1.data, blob1.length);
766 /* Kill the intermediate vuid */
767 invalidate_intermediate_vuid(vuid);
769 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
772 if (auth.data[0] == ASN1_APPLICATION(0)) {
773 /* Might be a second negTokenTarg packet */
775 BOOL got_krb5_mechanism = False;
776 status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism);
777 if (NT_STATUS_IS_OK(status)) {
778 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length));
780 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
781 BOOL destroy_vuid = True;
782 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
783 length, bufsize, &secblob, &destroy_vuid);
784 data_blob_free(&secblob);
785 data_blob_free(&auth);
787 /* Kill the intermediate vuid */
788 invalidate_intermediate_vuid(vuid);
796 /* If we get here it wasn't a negTokenTarg auth packet. */
797 data_blob_free(&secblob);
799 if (!*auth_ntlmssp_state) {
800 /* Kill the intermediate vuid */
801 invalidate_intermediate_vuid(vuid);
803 /* auth before negotiatiate? */
804 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
807 status = auth_ntlmssp_update(*auth_ntlmssp_state,
810 data_blob_free(&auth);
812 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
814 &auth_reply, status, True);
816 data_blob_free(&auth_reply);
818 /* and tell smbd that we have already replied to this packet */
822 /****************************************************************************
823 List to store partial SPNEGO auth fragments.
824 ****************************************************************************/
826 static struct pending_auth_data *pd_list;
828 /****************************************************************************
829 Delete an entry on the list.
830 ****************************************************************************/
832 static void delete_partial_auth(struct pending_auth_data *pad)
837 DLIST_REMOVE(pd_list, pad);
838 data_blob_free(&pad->partial_data);
842 /****************************************************************************
843 Search for a partial SPNEGO auth fragment matching an smbpid.
844 ****************************************************************************/
846 static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
848 struct pending_auth_data *pad;
850 for (pad = pd_list; pad; pad = pad->next) {
851 if (pad->smbpid == smbpid) {
858 /****************************************************************************
859 Check the size of an SPNEGO blob. If we need more return NT_STATUS_MORE_PROCESSING_REQUIRED,
860 else return NT_STATUS_OK. Don't allow the blob to be more than 64k.
861 ****************************************************************************/
863 static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob)
865 struct pending_auth_data *pad = NULL;
867 size_t needed_len = 0;
869 pad = get_pending_auth_data(smbpid);
871 /* Ensure we have some data. */
872 if (pblob->length == 0) {
873 /* Caller can cope. */
874 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
875 delete_partial_auth(pad);
879 /* Were we waiting for more data ? */
882 size_t copy_len = MIN(65536, pblob->length);
884 /* Integer wrap paranoia.... */
886 if (pad->partial_data.length + copy_len < 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(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(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 asn1_load(&data, *pblob);
953 asn1_start_tag(&data, pblob->data[0]);
954 if (data.has_error || data.nesting == NULL) {
956 /* Let caller catch. */
960 /* Integer wrap paranoia.... */
962 if (data.nesting->taglen + data.nesting->start < data.nesting->taglen ||
963 data.nesting->taglen + data.nesting->start < data.nesting->start) {
965 DEBUG(2,("check_spnego_blob_complete: integer wrap "
966 "data.nesting->taglen = %u, "
967 "data.nesting->start = %u\n",
968 (unsigned int)data.nesting->taglen,
969 (unsigned int)data.nesting->start ));
972 return NT_STATUS_INVALID_PARAMETER;
975 /* Total length of the needed asn1 is the tag length
976 * plus the current offset. */
978 needed_len = data.nesting->taglen + data.nesting->start;
981 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
982 "pblob->length = %u\n",
983 (unsigned int)needed_len,
984 (unsigned int)pblob->length ));
986 if (needed_len <= pblob->length) {
987 /* Nothing to do - blob is complete. */
991 /* Refuse the blob if it's bigger than 64k. */
992 if (needed_len > 65536) {
993 DEBUG(2,("check_spnego_blob_complete: needed_len too large (%u)\n",
994 (unsigned int)needed_len ));
995 return NT_STATUS_INVALID_PARAMETER;
998 /* We must store this blob until complete. */
999 pad = SMB_MALLOC(sizeof(struct pending_auth_data));
1001 return NT_STATUS_NO_MEMORY;
1003 pad->needed_len = needed_len - pblob->length;
1004 pad->partial_data = data_blob(pblob->data, pblob->length);
1005 if (pad->partial_data.data == NULL) {
1007 return NT_STATUS_NO_MEMORY;
1009 pad->smbpid = smbpid;
1011 DLIST_ADD(pd_list, pad);
1013 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1016 /****************************************************************************
1017 Reply to a session setup command.
1018 conn POINTER CAN BE NULL HERE !
1019 ****************************************************************************/
1021 static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
1023 int length,int bufsize)
1029 fstring native_os, native_lanman, primary_domain;
1031 uint16 data_blob_len = SVAL(inbuf, smb_vwv7);
1032 enum remote_arch_types ra_type = get_remote_arch();
1033 int vuid = SVAL(inbuf,smb_uid);
1034 user_struct *vuser = NULL;
1035 NTSTATUS status = NT_STATUS_OK;
1036 uint16 smbpid = SVAL(inbuf,smb_pid);
1038 DEBUG(3,("Doing spnego session setup\n"));
1040 if (global_client_caps == 0) {
1041 global_client_caps = IVAL(inbuf,smb_vwv10);
1043 if (!(global_client_caps & CAP_STATUS32)) {
1044 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1049 p = (uint8 *)smb_buf(inbuf);
1051 if (data_blob_len == 0) {
1052 /* an invalid request */
1053 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1056 bufrem = smb_bufrem(inbuf, p);
1057 /* pull the spnego blob */
1058 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1061 file_save("negotiate.dat", blob1.data, blob1.length);
1064 p2 = inbuf + smb_vwv13 + data_blob_len;
1065 p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE);
1066 p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE);
1067 p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE);
1068 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1069 native_os, native_lanman, primary_domain));
1071 if ( ra_type == RA_WIN2K ) {
1072 /* Vista sets neither the OS or lanman strings */
1074 if ( !strlen(native_os) && !strlen(native_lanman) )
1075 set_remote_arch(RA_VISTA);
1077 /* Windows 2003 doesn't set the native lanman string,
1078 but does set primary domain which is a bug I think */
1080 if ( !strlen(native_lanman) ) {
1081 ra_lanman_string( primary_domain );
1083 ra_lanman_string( native_lanman );
1087 vuser = get_partial_auth_user_struct(vuid);
1089 struct pending_auth_data *pad = get_pending_auth_data(smbpid);
1091 DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n",
1092 (unsigned int)pad->vuid ));
1094 vuser = get_partial_auth_user_struct(vuid);
1099 vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL);
1100 if (vuid == UID_FIELD_INVALID ) {
1101 data_blob_free(&blob1);
1102 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
1105 vuser = get_partial_auth_user_struct(vuid);
1109 data_blob_free(&blob1);
1110 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
1113 SSVAL(outbuf,smb_uid,vuid);
1115 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1116 * sessionsetup requests as the Windows limit on the security blob
1117 * field is 4k. Bug #4400. JRA.
1120 status = check_spnego_blob_complete(smbpid, vuid, &blob1);
1121 if (!NT_STATUS_IS_OK(status)) {
1122 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1123 /* Real error - kill the intermediate vuid */
1124 invalidate_intermediate_vuid(vuid);
1126 data_blob_free(&blob1);
1127 return ERROR_NT(nt_status_squash(status));
1130 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1131 /* its a negTokenTarg packet */
1132 ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
1133 &vuser->auth_ntlmssp_state);
1134 data_blob_free(&blob1);
1138 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1139 /* its a auth packet */
1140 ret = reply_spnego_auth(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
1141 &vuser->auth_ntlmssp_state);
1142 data_blob_free(&blob1);
1146 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1148 if (!vuser->auth_ntlmssp_state) {
1149 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 /* Kill the intermediate vuid */
1152 invalidate_intermediate_vuid(vuid);
1153 data_blob_free(&blob1);
1154 return ERROR_NT(nt_status_squash(status));
1158 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1161 data_blob_free(&blob1);
1163 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
1164 &vuser->auth_ntlmssp_state,
1165 &chal, status, False);
1166 data_blob_free(&chal);
1170 /* what sort of packet is this? */
1171 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1173 data_blob_free(&blob1);
1175 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1178 /****************************************************************************
1179 On new VC == 0, shutdown *all* old connections and users.
1180 It seems that only NT4.x does this. At W2K and above (XP etc.).
1181 a new session setup with VC==0 is ignored.
1182 ****************************************************************************/
1184 static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
1187 struct sessionid sessionid;
1188 const char *ip = (const char *)p;
1190 SMB_ASSERT(dbuf.dsize == sizeof(sessionid));
1191 memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
1193 if (!process_exists(pid_to_procid(sessionid.pid))) {
1197 if (sessionid.pid == sys_getpid()) {
1201 if (strcmp(ip, sessionid.ip_addr) != 0) {
1205 message_send_pid(pid_to_procid(sessionid.pid), MSG_SHUTDOWN,
1210 static void setup_new_vc_session(void)
1212 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n"));
1215 invalidate_all_vuids();
1217 if (lp_reset_on_zero_vc()) {
1218 session_traverse(shutdown_other_smbds, client_addr());
1222 /****************************************************************************
1223 Reply to a session setup command.
1224 ****************************************************************************/
1226 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
1227 int length,int bufsize)
1233 DATA_BLOB plaintext_password;
1235 fstring sub_user; /* Sainitised username for substituion */
1238 fstring native_lanman;
1239 fstring primary_domain;
1240 static BOOL done_sesssetup = False;
1241 auth_usersupplied_info *user_info = NULL;
1242 auth_serversupplied_info *server_info = NULL;
1246 BOOL doencrypt = global_encrypted_passwords_negotiated;
1248 DATA_BLOB session_key;
1250 START_PROFILE(SMBsesssetupX);
1252 ZERO_STRUCT(lm_resp);
1253 ZERO_STRUCT(nt_resp);
1254 ZERO_STRUCT(plaintext_password);
1256 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
1258 /* a SPNEGO session setup has 12 command words, whereas a normal
1259 NT1 session setup has 13. See the cifs spec. */
1260 if (CVAL(inbuf, smb_wct) == 12 &&
1261 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
1262 if (!global_spnego_negotiated) {
1263 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
1264 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1267 if (SVAL(inbuf,smb_vwv4) == 0) {
1268 setup_new_vc_session();
1270 return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
1273 smb_bufsize = SVAL(inbuf,smb_vwv2);
1275 if (Protocol < PROTOCOL_NT1) {
1276 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
1278 /* Never do NT status codes with protocols before NT1 as we don't get client caps. */
1279 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1281 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
1282 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
1286 lm_resp = data_blob(smb_buf(inbuf), passlen1);
1288 plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
1289 /* Ensure null termination */
1290 plaintext_password.data[passlen1] = 0;
1293 srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE);
1297 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
1298 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
1299 enum remote_arch_types ra_type = get_remote_arch();
1300 char *p = smb_buf(inbuf);
1301 char *save_p = smb_buf(inbuf);
1305 if(global_client_caps == 0) {
1306 global_client_caps = IVAL(inbuf,smb_vwv11);
1308 if (!(global_client_caps & CAP_STATUS32)) {
1309 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1312 /* client_caps is used as final determination if client is NT or Win95.
1313 This is needed to return the correct error codes in some
1317 if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
1318 if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
1319 set_remote_arch( RA_WIN95);
1325 /* both Win95 and WinNT stuff up the password lengths for
1326 non-encrypting systems. Uggh.
1328 if passlen1==24 its a win95 system, and its setting the
1329 password length incorrectly. Luckily it still works with the
1330 default code because Win95 will null terminate the password
1333 if passlen1>0 and passlen2>0 then maybe its a NT box and its
1334 setting passlen2 to some random value which really stuffs
1335 things up. we need to fix that one. */
1337 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
1341 /* check for nasty tricks */
1342 if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
1343 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
1346 if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
1347 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
1350 /* Save the lanman2 password and the NT md4 password. */
1352 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1357 lm_resp = data_blob(p, passlen1);
1358 nt_resp = data_blob(p+passlen1, passlen2);
1361 BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS;
1364 /* This was the previous fix. Not sure if it's still valid. JRA. */
1365 if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) {
1366 /* NT4.0 stuffs up plaintext unicode password lengths... */
1367 srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1,
1368 sizeof(pass), passlen1, STR_TERMINATE);
1371 if (unic && (passlen2 == 0) && passlen1) {
1372 /* Only a ascii plaintext password was sent. */
1373 srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass),
1374 passlen1, STR_TERMINATE|STR_ASCII);
1376 srvstr_pull(inbuf, pass, smb_buf(inbuf),
1377 sizeof(pass), unic ? passlen2 : passlen1,
1380 plaintext_password = data_blob(pass, strlen(pass)+1);
1383 p += passlen1 + passlen2;
1384 p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE);
1385 p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE);
1386 p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE);
1387 p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE);
1389 /* not documented or decoded by Ethereal but there is one more string
1390 in the extra bytes which is the same as the PrimaryDomain when using
1391 extended security. Windows NT 4 and 2003 use this string to store
1392 the native lanman string. Windows 9x does not include a string here
1393 at all so we have to check if we have any extra bytes left */
1395 byte_count = SVAL(inbuf, smb_vwv13);
1396 if ( PTR_DIFF(p, save_p) < byte_count)
1397 p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE);
1399 fstrcpy( primary_domain, "null" );
1401 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1402 domain, native_os, native_lanman, primary_domain));
1404 if ( ra_type == RA_WIN2K ) {
1405 if ( strlen(native_lanman) == 0 )
1406 ra_lanman_string( primary_domain );
1408 ra_lanman_string( native_lanman );
1413 if (SVAL(inbuf,smb_vwv4) == 0) {
1414 setup_new_vc_session();
1417 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
1420 if (global_spnego_negotiated) {
1422 /* This has to be here, because this is a perfectly valid behaviour for guest logons :-( */
1424 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
1425 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1427 fstrcpy(sub_user, user);
1429 fstrcpy(sub_user, lp_guestaccount());
1432 sub_set_smb_name(sub_user);
1434 reload_services(True);
1436 if (lp_security() == SEC_SHARE) {
1437 /* in share level we should ignore any passwords */
1439 data_blob_free(&lm_resp);
1440 data_blob_free(&nt_resp);
1441 data_blob_clear_free(&plaintext_password);
1443 map_username(sub_user);
1444 add_session_user(sub_user);
1445 add_session_workgroup(domain);
1446 /* Then force it to null for the benfit of the code below */
1452 nt_status = check_guest_password(&server_info);
1454 } else if (doencrypt) {
1455 if (!negprot_global_auth_context) {
1456 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n"));
1457 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1459 nt_status = make_user_info_for_reply_enc(&user_info, user, domain,
1461 if (NT_STATUS_IS_OK(nt_status)) {
1462 nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
1467 struct auth_context *plaintext_auth_context = NULL;
1470 nt_status = make_auth_context_subsystem(&plaintext_auth_context);
1472 if (NT_STATUS_IS_OK(nt_status)) {
1473 chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
1475 if (!make_user_info_for_reply(&user_info,
1477 plaintext_password)) {
1478 nt_status = NT_STATUS_NO_MEMORY;
1481 if (NT_STATUS_IS_OK(nt_status)) {
1482 nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
1486 (plaintext_auth_context->free)(&plaintext_auth_context);
1491 free_user_info(&user_info);
1493 if (!NT_STATUS_IS_OK(nt_status)) {
1494 nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
1497 if (!NT_STATUS_IS_OK(nt_status)) {
1498 data_blob_free(&nt_resp);
1499 data_blob_free(&lm_resp);
1500 data_blob_clear_free(&plaintext_password);
1501 return ERROR_NT(nt_status_squash(nt_status));
1504 /* Ensure we can't possible take a code path leading to a null defref. */
1506 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1509 nt_status = create_local_token(server_info);
1510 if (!NT_STATUS_IS_OK(nt_status)) {
1511 DEBUG(10, ("create_local_token failed: %s\n",
1512 nt_errstr(nt_status)));
1513 data_blob_free(&nt_resp);
1514 data_blob_free(&lm_resp);
1515 data_blob_clear_free(&plaintext_password);
1516 return ERROR_NT(nt_status_squash(nt_status));
1519 if (server_info->user_session_key.data) {
1520 session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length);
1522 session_key = data_blob(NULL, 0);
1525 data_blob_clear_free(&plaintext_password);
1527 /* it's ok - setup a reply */
1528 set_message(outbuf,3,0,True);
1529 if (Protocol >= PROTOCOL_NT1) {
1530 char *p = smb_buf( outbuf );
1531 p += add_signature( outbuf, p );
1532 set_message_end( outbuf, p );
1533 /* perhaps grab OS version here?? */
1536 if (server_info->guest) {
1537 SSVAL(outbuf,smb_vwv2,1);
1540 /* register the name and uid as being validated, so further connections
1541 to a uid can get through without a password, on the same VC */
1543 if (lp_security() == SEC_SHARE) {
1544 sess_vuid = UID_FIELD_INVALID;
1545 data_blob_free(&session_key);
1546 TALLOC_FREE(server_info);
1548 /* register_vuid keeps the server info */
1549 sess_vuid = register_vuid(server_info, session_key,
1550 nt_resp.data ? nt_resp : lm_resp,
1552 if (sess_vuid == UID_FIELD_INVALID) {
1553 data_blob_free(&nt_resp);
1554 data_blob_free(&lm_resp);
1555 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
1558 /* current_user_info is changed on new vuid */
1559 reload_services( True );
1561 sessionsetup_start_signing_engine(server_info, inbuf);
1564 data_blob_free(&nt_resp);
1565 data_blob_free(&lm_resp);
1567 SSVAL(outbuf,smb_uid,sess_vuid);
1568 SSVAL(inbuf,smb_uid,sess_vuid);
1570 if (!done_sesssetup)
1571 max_send = MIN(max_send,smb_bufsize);
1573 done_sesssetup = True;
1575 END_PROFILE(SMBsesssetupX);
1576 return chain_reply(inbuf,outbuf,length,bufsize);