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/globals.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "librpc/gen_ndr/messaging.h"
31 /* For split krb5 SPNEGO blobs. */
32 struct pending_auth_data {
33 struct pending_auth_data *prev, *next;
34 uint16 vuid; /* Tag for this entry. */
35 uint16 smbpid; /* Alternate tag for this entry. */
37 DATA_BLOB partial_data;
41 on a logon error possibly map the error to success if "map to guest"
44 static NTSTATUS do_map_to_guest(NTSTATUS status,
45 struct auth_serversupplied_info **server_info,
46 const char *user, const char *domain)
48 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
49 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
50 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
51 DEBUG(3,("No such user %s [%s] - using guest account\n",
53 status = make_server_info_guest(NULL, server_info);
57 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
58 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
59 DEBUG(3,("Registered username %s for guest access\n",
61 status = make_server_info_guest(NULL, server_info);
68 /****************************************************************************
69 Add the standard 'Samba' signature to the end of the session setup.
70 ****************************************************************************/
72 static int push_signature(uint8 **outbuf)
79 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
81 if (tmp == -1) return -1;
84 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
85 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
89 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
92 if (tmp == -1) return -1;
95 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
97 if (tmp == -1) return -1;
103 /****************************************************************************
104 Send a security blob via a session setup reply.
105 ****************************************************************************/
107 static void reply_sesssetup_blob(struct smb_request *req,
111 if (!NT_STATUS_IS_OK(nt_status) &&
112 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
113 reply_nterror(req, nt_status_squash(nt_status));
117 nt_status = nt_status_squash(nt_status);
118 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
119 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
120 SSVAL(req->outbuf, smb_vwv3, blob.length);
122 if ((message_push_blob(&req->outbuf, blob) == -1)
123 || (push_signature(&req->outbuf) == -1)) {
124 reply_nterror(req, NT_STATUS_NO_MEMORY);
128 /****************************************************************************
129 Do a 'guest' logon, getting back the
130 ****************************************************************************/
132 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
134 struct auth_context *auth_context;
135 struct 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,
149 if (!make_user_info_guest(&user_info)) {
150 (auth_context->free)(&auth_context);
151 return NT_STATUS_NO_MEMORY;
154 nt_status = auth_context->check_ntlm_password(auth_context,
157 (auth_context->free)(&auth_context);
158 free_user_info(&user_info);
166 /* Experiment that failed. See "only happens with a KDC" comment below. */
167 /****************************************************************************
168 Cerate a clock skew error blob for a Windows client.
169 ****************************************************************************/
171 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
173 krb5_context context = NULL;
174 krb5_error_code kerr = 0;
176 krb5_principal host_princ = NULL;
177 char *host_princ_s = NULL;
180 *pblob_out = data_blob_null;
182 initialize_krb5_error_table();
183 kerr = krb5_init_context(&context);
187 /* Create server principal. */
188 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
192 strlower_m(host_princ_s);
194 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
196 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
197 "for name %s: Error %s\n",
198 host_princ_s, error_message(kerr) ));
202 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
205 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
206 "failed: Error %s\n",
207 error_message(kerr) ));
211 *pblob_out = data_blob(reply.data, reply.length);
212 kerberos_free_data_contents(context,&reply);
218 SAFE_FREE(host_princ_s);
221 krb5_free_principal(context, host_princ);
223 krb5_free_context(context);
228 /****************************************************************************
229 Reply to a session setup spnego negotiate packet for kerberos.
230 ****************************************************************************/
232 static void reply_spnego_kerberos(struct smb_request *req,
236 bool *p_invalidate_vuid)
240 char *client, *p, *domain;
241 fstring netbios_domain_name;
244 int sess_vuid = req->vuid;
245 NTSTATUS ret = NT_STATUS_OK;
246 DATA_BLOB ap_rep, ap_rep_wrapped, response;
247 struct auth_serversupplied_info *server_info = NULL;
248 DATA_BLOB session_key = data_blob_null;
250 DATA_BLOB nullblob = data_blob_null;
251 fstring real_username;
252 bool map_domainuser_to_guest = False;
253 bool username_was_mapped;
254 struct PAC_LOGON_INFO *logon_info = NULL;
255 struct smbd_server_connection *sconn = req->sconn;
259 ZERO_STRUCT(ap_rep_wrapped);
260 ZERO_STRUCT(response);
262 /* Normally we will always invalidate the intermediate vuid. */
263 *p_invalidate_vuid = True;
265 mem_ctx = talloc_init("reply_spnego_kerberos");
266 if (mem_ctx == NULL) {
267 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
271 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
272 talloc_destroy(mem_ctx);
273 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
277 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
278 &client, &logon_info, &ap_rep,
281 data_blob_free(&ticket);
283 if (!NT_STATUS_IS_OK(ret)) {
285 /* Experiment that failed.
286 * See "only happens with a KDC" comment below. */
288 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
291 * Windows in this case returns
292 * NT_STATUS_MORE_PROCESSING_REQUIRED
293 * with a negTokenTarg blob containing an krb5_error
294 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
295 * The client then fixes its clock and continues rather
296 * than giving an error. JRA.
297 * -- Looks like this only happens with a KDC. JRA.
300 bool ok = make_krb5_skew_error(&ap_rep);
302 talloc_destroy(mem_ctx);
303 return ERROR_NT(nt_status_squash(
304 NT_STATUS_LOGON_FAILURE));
306 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
308 response = spnego_gen_auth_response(&ap_rep_wrapped,
309 ret, OID_KERBEROS5_OLD);
310 reply_sesssetup_blob(conn, inbuf, outbuf, response,
311 NT_STATUS_MORE_PROCESSING_REQUIRED);
314 * In this one case we don't invalidate the
315 * intermediate vuid as we're expecting the client
316 * to re-use it for the next sessionsetupX packet. JRA.
319 *p_invalidate_vuid = False;
321 data_blob_free(&ap_rep);
322 data_blob_free(&ap_rep_wrapped);
323 data_blob_free(&response);
324 talloc_destroy(mem_ctx);
325 return -1; /* already replied */
328 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
329 ret = NT_STATUS_LOGON_FAILURE;
332 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
334 talloc_destroy(mem_ctx);
335 reply_nterror(req, nt_status_squash(ret));
339 DEBUG(3,("Ticket name is [%s]\n", client));
341 p = strchr_m(client, '@');
343 DEBUG(3,("Doesn't look like a valid principal\n"));
344 data_blob_free(&ap_rep);
345 data_blob_free(&session_key);
346 talloc_destroy(mem_ctx);
347 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
353 /* save the PAC data if we have it */
356 netsamlogon_cache_store( client, &logon_info->info3 );
359 if (!strequal(p+1, lp_realm())) {
360 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
361 if (!lp_allow_trusted_domains()) {
362 data_blob_free(&ap_rep);
363 data_blob_free(&session_key);
364 talloc_destroy(mem_ctx);
365 reply_nterror(req, nt_status_squash(
366 NT_STATUS_LOGON_FAILURE));
371 /* this gives a fully qualified user name (ie. with full realm).
372 that leads to very long usernames, but what else can we do? */
376 if (logon_info && logon_info->info3.base.domain.string) {
377 fstrcpy(netbios_domain_name,
378 logon_info->info3.base.domain.string);
379 domain = netbios_domain_name;
380 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
384 /* If we have winbind running, we can (and must) shorten the
385 username by using the short netbios name. Otherwise we will
386 have inconsistent user names. With Kerberos, we get the
387 fully qualified realm, with ntlmssp we get the short
388 name. And even w2k3 does use ntlmssp if you for example
389 connect to an ip address. */
392 struct wbcDomainInfo *info = NULL;
394 DEBUG(10, ("Mapping [%s] to short name\n", domain));
396 wbc_status = wbcDomainInfo(domain, &info);
398 if (WBC_ERROR_IS_OK(wbc_status)) {
400 fstrcpy(netbios_domain_name,
404 domain = netbios_domain_name;
405 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
407 DEBUG(3, ("Could not find short name: %s\n",
408 wbcErrorString(wbc_status)));
412 fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
414 /* lookup the passwd struct, create a new user if necessary */
416 username_was_mapped = map_username(user);
418 pw = smb_getpwnam( mem_ctx, user, real_username, True );
421 /* if a real user check pam account restrictions */
422 /* only really perfomed if "obey pam restriction" is true */
423 /* do this before an eventual mapping to guest occurs */
424 ret = smb_pam_accountcheck(pw->pw_name);
425 if ( !NT_STATUS_IS_OK(ret)) {
426 DEBUG(1,("PAM account restriction "
427 "prevents user login\n"));
428 data_blob_free(&ap_rep);
429 data_blob_free(&session_key);
430 TALLOC_FREE(mem_ctx);
431 reply_nterror(req, nt_status_squash(ret));
438 /* this was originally the behavior of Samba 2.2, if a user
439 did not have a local uid but has been authenticated, then
440 map them to a guest account */
442 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
443 map_domainuser_to_guest = True;
444 fstrcpy(user,lp_guestaccount());
445 pw = smb_getpwnam( mem_ctx, user, real_username, True );
448 /* extra sanity check that the guest account is valid */
451 DEBUG(1,("Username %s is invalid on this system\n",
453 data_blob_free(&ap_rep);
454 data_blob_free(&session_key);
455 TALLOC_FREE(mem_ctx);
456 reply_nterror(req, nt_status_squash(
457 NT_STATUS_LOGON_FAILURE));
462 /* setup the string used by %U */
464 sub_set_smb_name( real_username );
465 reload_services(True);
467 if ( map_domainuser_to_guest ) {
468 make_server_info_guest(NULL, &server_info);
469 } else if (logon_info) {
470 /* pass the unmapped username here since map_username()
471 will be called again from inside make_server_info_info3() */
473 ret = make_server_info_info3(mem_ctx, client, domain,
474 &server_info, &logon_info->info3);
475 if ( !NT_STATUS_IS_OK(ret) ) {
476 DEBUG(1,("make_server_info_info3 failed: %s!\n",
478 data_blob_free(&ap_rep);
479 data_blob_free(&session_key);
480 TALLOC_FREE(mem_ctx);
481 reply_nterror(req, nt_status_squash(ret));
487 * We didn't get a PAC, we have to make up the user
488 * ourselves. Try to ask the pdb backend to provide
489 * SID consistency with ntlmssp session setup
491 struct samu *sampass;
493 sampass = samu_new(talloc_tos());
494 if (sampass == NULL) {
495 ret = NT_STATUS_NO_MEMORY;
496 data_blob_free(&ap_rep);
497 data_blob_free(&session_key);
498 TALLOC_FREE(mem_ctx);
499 reply_nterror(req, nt_status_squash(ret));
503 if (pdb_getsampwnam(sampass, real_username)) {
504 DEBUG(10, ("found user %s in passdb, calling "
505 "make_server_info_sam\n", real_username));
506 ret = make_server_info_sam(&server_info, sampass);
507 TALLOC_FREE(sampass);
510 * User not in passdb, make it up artificially
512 TALLOC_FREE(sampass);
513 DEBUG(10, ("didn't find user %s in passdb, calling "
514 "make_server_info_pw\n", real_username));
515 ret = make_server_info_pw(&server_info, real_username,
519 if ( !NT_STATUS_IS_OK(ret) ) {
520 DEBUG(1,("make_server_info_[sam|pw] failed: %s!\n",
522 data_blob_free(&ap_rep);
523 data_blob_free(&session_key);
524 TALLOC_FREE(mem_ctx);
525 reply_nterror(req, nt_status_squash(ret));
529 /* make_server_info_pw does not set the domain. Without this
530 * we end up with the local netbios name in substitutions for
533 if (server_info->info3 != NULL) {
534 server_info->info3->base.domain.string =
535 talloc_strdup(server_info->info3, domain);
539 server_info->nss_token |= username_was_mapped;
541 /* we need to build the token for the user. make_server_info_guest()
544 if ( !server_info->ptok ) {
545 ret = create_local_token( server_info );
546 if ( !NT_STATUS_IS_OK(ret) ) {
547 DEBUG(10,("failed to create local token: %s\n",
549 data_blob_free(&ap_rep);
550 data_blob_free(&session_key);
551 TALLOC_FREE( mem_ctx );
552 TALLOC_FREE( server_info );
553 reply_nterror(req, nt_status_squash(ret));
558 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
559 sess_vuid = register_initial_vuid(sconn);
562 data_blob_free(&server_info->user_session_key);
563 server_info->user_session_key = session_key;
564 session_key = data_blob_null;
566 /* register_existing_vuid keeps the server info */
567 /* register_existing_vuid takes ownership of session_key on success,
568 * no need to free after this on success. A better interface would copy
571 sess_vuid = register_existing_vuid(sconn,
577 reply_outbuf(req, 4, 0);
578 SSVAL(req->outbuf,smb_uid,sess_vuid);
580 if (sess_vuid == UID_FIELD_INVALID ) {
581 ret = NT_STATUS_LOGON_FAILURE;
583 /* current_user_info is changed on new vuid */
584 reload_services( True );
586 SSVAL(req->outbuf, smb_vwv3, 0);
588 if (server_info->guest) {
589 SSVAL(req->outbuf,smb_vwv2,1);
592 SSVAL(req->outbuf, smb_uid, sess_vuid);
594 /* Successful logon. Keep this vuid. */
595 *p_invalidate_vuid = False;
598 /* wrap that up in a nice GSS-API wrapping */
599 if (NT_STATUS_IS_OK(ret)) {
600 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
603 ap_rep_wrapped = data_blob_null;
605 response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
607 reply_sesssetup_blob(req, response, ret);
609 data_blob_free(&ap_rep);
610 data_blob_free(&ap_rep_wrapped);
611 data_blob_free(&response);
612 TALLOC_FREE(mem_ctx);
617 /****************************************************************************
618 Send a session setup reply, wrapped in SPNEGO.
619 Get vuid and check first.
620 End the NTLMSSP exchange context if we are OK/complete fail
621 This should be split into two functions, one to handle each
622 leg of the NTLM auth steps.
623 ***************************************************************************/
625 static void reply_spnego_ntlmssp(struct smb_request *req,
627 struct auth_ntlmssp_state **auth_ntlmssp_state,
628 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
633 struct auth_serversupplied_info *server_info = NULL;
634 struct smbd_server_connection *sconn = req->sconn;
636 if (NT_STATUS_IS_OK(nt_status)) {
637 server_info = auth_ntlmssp_server_info(talloc_tos(), (*auth_ntlmssp_state));
639 /* Note that this server_info won't have a session
640 * key. But for map to guest, that's exactly the right
641 * thing - we can't reasonably guess the key the
642 * client wants, as the password was wrong */
643 nt_status = do_map_to_guest(nt_status,
645 auth_ntlmssp_get_username(*auth_ntlmssp_state),
646 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
649 reply_outbuf(req, 4, 0);
651 SSVAL(req->outbuf, smb_uid, vuid);
653 if (NT_STATUS_IS_OK(nt_status)) {
654 DATA_BLOB nullblob = data_blob_null;
656 if (!is_partial_auth_vuid(sconn, vuid)) {
657 nt_status = NT_STATUS_LOGON_FAILURE;
661 /* register_existing_vuid keeps the server info */
662 if (register_existing_vuid(sconn, vuid,
663 server_info, nullblob,
664 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
666 nt_status = NT_STATUS_LOGON_FAILURE;
670 /* current_user_info is changed on new vuid */
671 reload_services( True );
673 SSVAL(req->outbuf, smb_vwv3, 0);
675 if (server_info->guest) {
676 SSVAL(req->outbuf,smb_vwv2,1);
683 response = spnego_gen_auth_response(ntlmssp_blob,
686 response = *ntlmssp_blob;
689 reply_sesssetup_blob(req, response, nt_status);
691 data_blob_free(&response);
694 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
695 and the other end, that we are not finished yet. */
697 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
698 /* NB. This is *NOT* an error case. JRA */
699 auth_ntlmssp_end(auth_ntlmssp_state);
700 if (!NT_STATUS_IS_OK(nt_status)) {
701 /* Kill the intermediate vuid */
702 invalidate_vuid(sconn, vuid);
707 /****************************************************************************
708 Is this a krb5 mechanism ?
709 ****************************************************************************/
711 NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
712 DATA_BLOB *pblob_out,
715 char *OIDs[ASN1_MAX_OIDS];
717 NTSTATUS ret = NT_STATUS_OK;
719 *kerb_mechOID = NULL;
721 /* parse out the OIDs and the first sec blob */
722 if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
723 return NT_STATUS_LOGON_FAILURE;
726 /* only look at the first OID for determining the mechToken --
727 according to RFC2478, we should choose the one we want
728 and renegotiate, but i smell a client bug here..
730 Problem observed when connecting to a member (samba box)
731 of an AD domain as a user in a Samba domain. Samba member
732 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
733 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
734 NTLMSSP mechtoken. --jerry */
737 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
738 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
739 *kerb_mechOID = SMB_STRDUP(OIDs[0]);
740 if (*kerb_mechOID == NULL) {
741 ret = NT_STATUS_NO_MEMORY;
746 for (i=0;OIDs[i];i++) {
747 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
748 talloc_free(OIDs[i]);
753 /****************************************************************************
754 Fall back from krb5 to NTLMSSP.
755 ****************************************************************************/
757 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
762 reply_outbuf(req, 4, 0);
763 SSVAL(req->outbuf,smb_uid,vuid);
765 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
766 "but set to downgrade to NTLMSSP\n"));
768 response = spnego_gen_auth_response(NULL,
769 NT_STATUS_MORE_PROCESSING_REQUIRED,
771 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
772 data_blob_free(&response);
775 /****************************************************************************
776 Reply to a session setup spnego negotiate packet.
777 ****************************************************************************/
779 static void reply_spnego_negotiate(struct smb_request *req,
782 struct auth_ntlmssp_state **auth_ntlmssp_state)
786 char *kerb_mech = NULL;
788 struct smbd_server_connection *sconn = req->sconn;
790 status = parse_spnego_mechanisms(blob1, &secblob, &kerb_mech);
791 if (!NT_STATUS_IS_OK(status)) {
792 /* Kill the intermediate vuid */
793 invalidate_vuid(sconn, vuid);
794 reply_nterror(req, nt_status_squash(status));
798 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
799 (unsigned long)secblob.length));
802 if (kerb_mech && ((lp_security()==SEC_ADS) ||
803 USE_KERBEROS_KEYTAB) ) {
804 bool destroy_vuid = True;
805 reply_spnego_kerberos(req, &secblob, kerb_mech,
806 vuid, &destroy_vuid);
807 data_blob_free(&secblob);
809 /* Kill the intermediate vuid */
810 invalidate_vuid(sconn, vuid);
812 SAFE_FREE(kerb_mech);
817 if (*auth_ntlmssp_state) {
818 auth_ntlmssp_end(auth_ntlmssp_state);
822 data_blob_free(&secblob);
823 /* The mechtoken is a krb5 ticket, but
824 * we need to fall back to NTLM. */
825 reply_spnego_downgrade_to_ntlmssp(req, vuid);
826 SAFE_FREE(kerb_mech);
830 status = auth_ntlmssp_start(auth_ntlmssp_state);
831 if (!NT_STATUS_IS_OK(status)) {
832 /* Kill the intermediate vuid */
833 invalidate_vuid(sconn, vuid);
834 reply_nterror(req, nt_status_squash(status));
838 status = auth_ntlmssp_update(*auth_ntlmssp_state,
841 data_blob_free(&secblob);
843 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
844 &chal, status, OID_NTLMSSP, true);
846 data_blob_free(&chal);
848 /* already replied */
852 /****************************************************************************
853 Reply to a session setup spnego auth packet.
854 ****************************************************************************/
856 static void reply_spnego_auth(struct smb_request *req,
859 struct auth_ntlmssp_state **auth_ntlmssp_state)
861 DATA_BLOB auth = data_blob_null;
862 DATA_BLOB auth_reply = data_blob_null;
863 DATA_BLOB secblob = data_blob_null;
864 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
865 struct smbd_server_connection *sconn = req->sconn;
867 if (!spnego_parse_auth(blob1, &auth)) {
869 file_save("auth.dat", blob1.data, blob1.length);
871 /* Kill the intermediate vuid */
872 invalidate_vuid(sconn, vuid);
874 reply_nterror(req, nt_status_squash(
875 NT_STATUS_LOGON_FAILURE));
879 if (auth.data[0] == ASN1_APPLICATION(0)) {
880 /* Might be a second negTokenTarg packet */
881 char *kerb_mech = NULL;
883 status = parse_spnego_mechanisms(auth, &secblob, &kerb_mech);
885 if (!NT_STATUS_IS_OK(status)) {
886 /* Kill the intermediate vuid */
887 invalidate_vuid(sconn, vuid);
888 reply_nterror(req, nt_status_squash(status));
892 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
893 (unsigned long)secblob.length));
895 if (kerb_mech && ((lp_security()==SEC_ADS) ||
896 USE_KERBEROS_KEYTAB)) {
897 bool destroy_vuid = True;
898 reply_spnego_kerberos(req, &secblob, kerb_mech,
899 vuid, &destroy_vuid);
900 data_blob_free(&secblob);
901 data_blob_free(&auth);
903 /* Kill the intermediate vuid */
904 invalidate_vuid(sconn, vuid);
906 SAFE_FREE(kerb_mech);
910 /* Can't blunder into NTLMSSP auth if we have
914 /* Kill the intermediate vuid */
915 invalidate_vuid(sconn, vuid);
916 DEBUG(3,("reply_spnego_auth: network "
917 "misconfiguration, client sent us a "
918 "krb5 ticket and kerberos security "
920 reply_nterror(req, nt_status_squash(
921 NT_STATUS_LOGON_FAILURE));
922 SAFE_FREE(kerb_mech);
926 /* If we get here it wasn't a negTokenTarg auth packet. */
927 data_blob_free(&secblob);
929 if (!*auth_ntlmssp_state) {
930 status = auth_ntlmssp_start(auth_ntlmssp_state);
931 if (!NT_STATUS_IS_OK(status)) {
932 /* Kill the intermediate vuid */
933 invalidate_vuid(sconn, vuid);
934 reply_nterror(req, nt_status_squash(status));
939 status = auth_ntlmssp_update(*auth_ntlmssp_state,
942 data_blob_free(&auth);
944 /* Don't send the mechid as we've already sent this (RFC4178). */
946 reply_spnego_ntlmssp(req, vuid,
948 &auth_reply, status, NULL, true);
950 data_blob_free(&auth_reply);
952 /* and tell smbd that we have already replied to this packet */
956 /****************************************************************************
957 Delete an entry on the list.
958 ****************************************************************************/
960 static void delete_partial_auth(struct smbd_server_connection *sconn,
961 struct pending_auth_data *pad)
966 DLIST_REMOVE(sconn->smb1.pd_list, pad);
967 data_blob_free(&pad->partial_data);
971 /****************************************************************************
972 Search for a partial SPNEGO auth fragment matching an smbpid.
973 ****************************************************************************/
975 static struct pending_auth_data *get_pending_auth_data(
976 struct smbd_server_connection *sconn,
979 struct pending_auth_data *pad;
981 * NOTE: using the smbpid here is completely wrong...
983 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
985 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
986 if (pad->smbpid == smbpid) {
993 /****************************************************************************
994 Check the size of an SPNEGO blob. If we need more return
995 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
996 the blob to be more than 64k.
997 ****************************************************************************/
999 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
1000 uint16 smbpid, uint16 vuid,
1003 struct pending_auth_data *pad = NULL;
1005 size_t needed_len = 0;
1007 pad = get_pending_auth_data(sconn, smbpid);
1009 /* Ensure we have some data. */
1010 if (pblob->length == 0) {
1011 /* Caller can cope. */
1012 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
1013 delete_partial_auth(sconn, pad);
1014 return NT_STATUS_OK;
1017 /* Were we waiting for more data ? */
1020 size_t copy_len = MIN(65536, pblob->length);
1022 /* Integer wrap paranoia.... */
1024 if (pad->partial_data.length + copy_len <
1025 pad->partial_data.length ||
1026 pad->partial_data.length + copy_len < copy_len) {
1028 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1029 "pad->partial_data.length = %u, "
1031 (unsigned int)pad->partial_data.length,
1032 (unsigned int)copy_len ));
1034 delete_partial_auth(sconn, pad);
1035 return NT_STATUS_INVALID_PARAMETER;
1038 DEBUG(10,("check_spnego_blob_complete: "
1039 "pad->partial_data.length = %u, "
1040 "pad->needed_len = %u, "
1042 "pblob->length = %u,\n",
1043 (unsigned int)pad->partial_data.length,
1044 (unsigned int)pad->needed_len,
1045 (unsigned int)copy_len,
1046 (unsigned int)pblob->length ));
1048 tmp_blob = data_blob(NULL,
1049 pad->partial_data.length + copy_len);
1051 /* Concatenate the two (up to copy_len) bytes. */
1052 memcpy(tmp_blob.data,
1053 pad->partial_data.data,
1054 pad->partial_data.length);
1055 memcpy(tmp_blob.data + pad->partial_data.length,
1059 /* Replace the partial data. */
1060 data_blob_free(&pad->partial_data);
1061 pad->partial_data = tmp_blob;
1062 ZERO_STRUCT(tmp_blob);
1065 if (pblob->length >= pad->needed_len) {
1066 /* Yes, replace pblob. */
1067 data_blob_free(pblob);
1068 *pblob = pad->partial_data;
1069 ZERO_STRUCT(pad->partial_data);
1070 delete_partial_auth(sconn, pad);
1071 return NT_STATUS_OK;
1074 /* Still need more data. */
1075 pad->needed_len -= copy_len;
1076 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1079 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
1080 (pblob->data[0] != ASN1_CONTEXT(1))) {
1081 /* Not something we can determine the
1084 return NT_STATUS_OK;
1087 /* This is a new SPNEGO sessionsetup - see if
1088 * the data given in this blob is enough.
1091 data = asn1_init(NULL);
1093 return NT_STATUS_NO_MEMORY;
1096 asn1_load(data, *pblob);
1097 asn1_start_tag(data, pblob->data[0]);
1098 if (data->has_error || data->nesting == NULL) {
1100 /* Let caller catch. */
1101 return NT_STATUS_OK;
1104 /* Integer wrap paranoia.... */
1106 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
1107 data->nesting->taglen + data->nesting->start < data->nesting->start) {
1109 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1110 "data.nesting->taglen = %u, "
1111 "data.nesting->start = %u\n",
1112 (unsigned int)data->nesting->taglen,
1113 (unsigned int)data->nesting->start ));
1116 return NT_STATUS_INVALID_PARAMETER;
1119 /* Total length of the needed asn1 is the tag length
1120 * plus the current offset. */
1122 needed_len = data->nesting->taglen + data->nesting->start;
1125 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
1126 "pblob->length = %u\n",
1127 (unsigned int)needed_len,
1128 (unsigned int)pblob->length ));
1130 if (needed_len <= pblob->length) {
1131 /* Nothing to do - blob is complete. */
1132 return NT_STATUS_OK;
1135 /* Refuse the blob if it's bigger than 64k. */
1136 if (needed_len > 65536) {
1137 DEBUG(2,("check_spnego_blob_complete: needed_len "
1139 (unsigned int)needed_len ));
1140 return NT_STATUS_INVALID_PARAMETER;
1143 /* We must store this blob until complete. */
1144 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1145 return NT_STATUS_NO_MEMORY;
1147 pad->needed_len = needed_len - pblob->length;
1148 pad->partial_data = data_blob(pblob->data, pblob->length);
1149 if (pad->partial_data.data == NULL) {
1151 return NT_STATUS_NO_MEMORY;
1153 pad->smbpid = smbpid;
1155 DLIST_ADD(sconn->smb1.pd_list, pad);
1157 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1160 /****************************************************************************
1161 Reply to a session setup command.
1162 conn POINTER CAN BE NULL HERE !
1163 ****************************************************************************/
1165 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1171 const char *native_os;
1172 const char *native_lanman;
1173 const char *primary_domain;
1175 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1176 enum remote_arch_types ra_type = get_remote_arch();
1177 int vuid = req->vuid;
1178 user_struct *vuser = NULL;
1179 NTSTATUS status = NT_STATUS_OK;
1180 uint16 smbpid = req->smbpid;
1181 struct smbd_server_connection *sconn = req->sconn;
1183 DEBUG(3,("Doing spnego session setup\n"));
1185 if (global_client_caps == 0) {
1186 global_client_caps = IVAL(req->vwv+10, 0);
1188 if (!(global_client_caps & CAP_STATUS32)) {
1189 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1196 if (data_blob_len == 0) {
1197 /* an invalid request */
1198 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1202 bufrem = smbreq_bufrem(req, p);
1203 /* pull the spnego blob */
1204 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1207 file_save("negotiate.dat", blob1.data, blob1.length);
1210 p2 = (char *)req->buf + blob1.length;
1212 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1214 native_os = tmp ? tmp : "";
1216 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1218 native_lanman = tmp ? tmp : "";
1220 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1222 primary_domain = tmp ? tmp : "";
1224 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1225 native_os, native_lanman, primary_domain));
1227 if ( ra_type == RA_WIN2K ) {
1228 /* Vista sets neither the OS or lanman strings */
1230 if ( !strlen(native_os) && !strlen(native_lanman) )
1231 set_remote_arch(RA_VISTA);
1233 /* Windows 2003 doesn't set the native lanman string,
1234 but does set primary domain which is a bug I think */
1236 if ( !strlen(native_lanman) ) {
1237 ra_lanman_string( primary_domain );
1239 ra_lanman_string( native_lanman );
1243 /* Did we get a valid vuid ? */
1244 if (!is_partial_auth_vuid(sconn, vuid)) {
1245 /* No, then try and see if this is an intermediate sessionsetup
1246 * for a large SPNEGO packet. */
1247 struct pending_auth_data *pad;
1248 pad = get_pending_auth_data(sconn, smbpid);
1250 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1251 "pending vuid %u\n",
1252 (unsigned int)pad->vuid ));
1257 /* Do we have a valid vuid now ? */
1258 if (!is_partial_auth_vuid(sconn, vuid)) {
1259 /* No, start a new authentication setup. */
1260 vuid = register_initial_vuid(sconn);
1261 if (vuid == UID_FIELD_INVALID) {
1262 data_blob_free(&blob1);
1263 reply_nterror(req, nt_status_squash(
1264 NT_STATUS_INVALID_PARAMETER));
1269 vuser = get_partial_auth_user_struct(sconn, vuid);
1270 /* This MUST be valid. */
1272 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1275 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1276 * sessionsetup requests as the Windows limit on the security blob
1277 * field is 4k. Bug #4400. JRA.
1280 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1281 if (!NT_STATUS_IS_OK(status)) {
1282 if (!NT_STATUS_EQUAL(status,
1283 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1284 /* Real error - kill the intermediate vuid */
1285 invalidate_vuid(sconn, vuid);
1287 data_blob_free(&blob1);
1288 reply_nterror(req, nt_status_squash(status));
1292 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1294 /* its a negTokenTarg packet */
1296 reply_spnego_negotiate(req, vuid, blob1,
1297 &vuser->auth_ntlmssp_state);
1298 data_blob_free(&blob1);
1302 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1304 /* its a auth packet */
1306 reply_spnego_auth(req, vuid, blob1,
1307 &vuser->auth_ntlmssp_state);
1308 data_blob_free(&blob1);
1312 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1315 if (!vuser->auth_ntlmssp_state) {
1316 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 /* Kill the intermediate vuid */
1319 invalidate_vuid(sconn, vuid);
1320 data_blob_free(&blob1);
1321 reply_nterror(req, nt_status_squash(status));
1326 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1329 data_blob_free(&blob1);
1331 reply_spnego_ntlmssp(req, vuid,
1332 &vuser->auth_ntlmssp_state,
1333 &chal, status, OID_NTLMSSP, false);
1334 data_blob_free(&chal);
1338 /* what sort of packet is this? */
1339 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1341 data_blob_free(&blob1);
1343 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1346 /****************************************************************************
1347 On new VC == 0, shutdown *all* old connections and users.
1348 It seems that only NT4.x does this. At W2K and above (XP etc.).
1349 a new session setup with VC==0 is ignored.
1350 ****************************************************************************/
1352 static int shutdown_other_smbds(const struct connections_key *key,
1353 const struct connections_data *crec,
1356 const char *ip = (const char *)private_data;
1358 if (!process_exists(crec->pid)) {
1362 if (procid_is_me(&crec->pid)) {
1366 if (strcmp(ip, crec->addr) != 0) {
1370 DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
1371 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip));
1373 messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN,
1378 static void setup_new_vc_session(void)
1380 char addr[INET6_ADDRSTRLEN];
1382 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1383 "compatible we would close all old resources.\n"));
1386 invalidate_all_vuids();
1388 if (lp_reset_on_zero_vc()) {
1389 connections_forall_read(shutdown_other_smbds,
1390 CONST_DISCARD(void *,
1391 client_addr(get_client_fd(),addr,sizeof(addr))));
1395 /****************************************************************************
1396 Reply to a session setup command.
1397 ****************************************************************************/
1399 void reply_sesssetup_and_X(struct smb_request *req)
1405 DATA_BLOB plaintext_password;
1408 fstring sub_user; /* Sanitised username for substituion */
1410 const char *native_os;
1411 const char *native_lanman;
1412 const char *primary_domain;
1413 struct auth_usersupplied_info *user_info = NULL;
1414 struct auth_serversupplied_info *server_info = NULL;
1415 uint16 smb_flag2 = req->flags2;
1418 struct smbd_server_connection *sconn = smbd_server_conn;
1420 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1422 START_PROFILE(SMBsesssetupX);
1424 ZERO_STRUCT(lm_resp);
1425 ZERO_STRUCT(nt_resp);
1426 ZERO_STRUCT(plaintext_password);
1428 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1430 /* a SPNEGO session setup has 12 command words, whereas a normal
1431 NT1 session setup has 13. See the cifs spec. */
1432 if (req->wct == 12 &&
1433 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1435 if (!sconn->smb1.negprot.spnego) {
1436 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1437 "at SPNEGO session setup when it was not "
1439 reply_nterror(req, nt_status_squash(
1440 NT_STATUS_LOGON_FAILURE));
1441 END_PROFILE(SMBsesssetupX);
1445 if (SVAL(req->vwv+4, 0) == 0) {
1446 setup_new_vc_session();
1449 reply_sesssetup_and_X_spnego(req);
1450 END_PROFILE(SMBsesssetupX);
1454 smb_bufsize = SVAL(req->vwv+2, 0);
1456 if (get_Protocol() < PROTOCOL_NT1) {
1457 uint16 passlen1 = SVAL(req->vwv+7, 0);
1459 /* Never do NT status codes with protocols before NT1 as we
1460 * don't get client caps. */
1461 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1463 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1464 reply_nterror(req, nt_status_squash(
1465 NT_STATUS_INVALID_PARAMETER));
1466 END_PROFILE(SMBsesssetupX);
1471 lm_resp = data_blob(req->buf, passlen1);
1473 plaintext_password = data_blob(req->buf, passlen1+1);
1474 /* Ensure null termination */
1475 plaintext_password.data[passlen1] = 0;
1478 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1479 req->buf + passlen1, STR_TERMINATE);
1480 user = tmp ? tmp : "";
1485 uint16 passlen1 = SVAL(req->vwv+7, 0);
1486 uint16 passlen2 = SVAL(req->vwv+8, 0);
1487 enum remote_arch_types ra_type = get_remote_arch();
1488 const uint8_t *p = req->buf;
1489 const uint8_t *save_p = req->buf;
1493 if(global_client_caps == 0) {
1494 global_client_caps = IVAL(req->vwv+11, 0);
1496 if (!(global_client_caps & CAP_STATUS32)) {
1497 remove_from_common_flags2(
1498 FLAGS2_32_BIT_ERROR_CODES);
1501 /* client_caps is used as final determination if
1502 * client is NT or Win95. This is needed to return
1503 * the correct error codes in some circumstances.
1506 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1507 ra_type == RA_WIN95) {
1508 if(!(global_client_caps & (CAP_NT_SMBS|
1510 set_remote_arch( RA_WIN95);
1516 /* both Win95 and WinNT stuff up the password
1517 * lengths for non-encrypting systems. Uggh.
1519 if passlen1==24 its a win95 system, and its setting
1520 the password length incorrectly. Luckily it still
1521 works with the default code because Win95 will null
1522 terminate the password anyway
1524 if passlen1>0 and passlen2>0 then maybe its a NT box
1525 and its setting passlen2 to some random value which
1526 really stuffs things up. we need to fix that one. */
1528 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1534 /* check for nasty tricks */
1535 if (passlen1 > MAX_PASS_LEN
1536 || passlen1 > smbreq_bufrem(req, p)) {
1537 reply_nterror(req, nt_status_squash(
1538 NT_STATUS_INVALID_PARAMETER));
1539 END_PROFILE(SMBsesssetupX);
1543 if (passlen2 > MAX_PASS_LEN
1544 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1545 reply_nterror(req, nt_status_squash(
1546 NT_STATUS_INVALID_PARAMETER));
1547 END_PROFILE(SMBsesssetupX);
1551 /* Save the lanman2 password and the NT md4 password. */
1553 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1558 lm_resp = data_blob(p, passlen1);
1559 nt_resp = data_blob(p+passlen1, passlen2);
1560 } else if (lp_security() != SEC_SHARE) {
1562 * In share level we should ignore any passwords, so
1563 * only read them if we're not.
1566 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1568 if (unic && (passlen2 == 0) && passlen1) {
1569 /* Only a ascii plaintext password was sent. */
1570 (void)srvstr_pull_talloc(talloc_tos(),
1576 STR_TERMINATE|STR_ASCII);
1578 (void)srvstr_pull_talloc(talloc_tos(),
1583 unic ? passlen2 : passlen1,
1587 reply_nterror(req, nt_status_squash(
1588 NT_STATUS_INVALID_PARAMETER));
1589 END_PROFILE(SMBsesssetupX);
1592 plaintext_password = data_blob(pass, strlen(pass)+1);
1595 p += passlen1 + passlen2;
1597 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1599 user = tmp ? tmp : "";
1601 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1603 domain = tmp ? tmp : "";
1605 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1607 native_os = tmp ? tmp : "";
1609 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1611 native_lanman = tmp ? tmp : "";
1613 /* not documented or decoded by Ethereal but there is one more
1614 * string in the extra bytes which is the same as the
1615 * PrimaryDomain when using extended security. Windows NT 4
1616 * and 2003 use this string to store the native lanman string.
1617 * Windows 9x does not include a string here at all so we have
1618 * to check if we have any extra bytes left */
1620 byte_count = SVAL(req->vwv+13, 0);
1621 if ( PTR_DIFF(p, save_p) < byte_count) {
1622 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1624 primary_domain = tmp ? tmp : "";
1626 primary_domain = talloc_strdup(talloc_tos(), "null");
1629 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1630 "PrimaryDomain=[%s]\n",
1631 domain, native_os, native_lanman, primary_domain));
1633 if ( ra_type == RA_WIN2K ) {
1634 if ( strlen(native_lanman) == 0 )
1635 ra_lanman_string( primary_domain );
1637 ra_lanman_string( native_lanman );
1642 if (SVAL(req->vwv+4, 0) == 0) {
1643 setup_new_vc_session();
1646 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1647 domain, user, get_remote_machine_name()));
1650 if (sconn->smb1.negprot.spnego) {
1652 /* This has to be here, because this is a perfectly
1653 * valid behaviour for guest logons :-( */
1655 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1656 "at 'normal' session setup after "
1657 "negotiating spnego.\n"));
1658 reply_nterror(req, nt_status_squash(
1659 NT_STATUS_LOGON_FAILURE));
1660 END_PROFILE(SMBsesssetupX);
1663 fstrcpy(sub_user, user);
1665 fstrcpy(sub_user, lp_guestaccount());
1668 sub_set_smb_name(sub_user);
1670 reload_services(True);
1672 if (lp_security() == SEC_SHARE) {
1673 /* In share level we should ignore any passwords */
1675 data_blob_free(&lm_resp);
1676 data_blob_free(&nt_resp);
1677 data_blob_clear_free(&plaintext_password);
1679 map_username(sub_user);
1680 add_session_user(sconn, sub_user);
1681 add_session_workgroup(sconn, domain);
1682 /* Then force it to null for the benfit of the code below */
1688 nt_status = check_guest_password(&server_info);
1690 } else if (doencrypt) {
1691 struct auth_context *negprot_auth_context = NULL;
1692 negprot_auth_context = sconn->smb1.negprot.auth_context;
1693 if (!negprot_auth_context) {
1694 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1695 "session setup without negprot denied!\n"));
1696 reply_nterror(req, nt_status_squash(
1697 NT_STATUS_LOGON_FAILURE));
1698 END_PROFILE(SMBsesssetupX);
1701 nt_status = make_user_info_for_reply_enc(&user_info, user,
1704 if (NT_STATUS_IS_OK(nt_status)) {
1705 nt_status = negprot_auth_context->check_ntlm_password(
1706 negprot_auth_context,
1711 struct auth_context *plaintext_auth_context = NULL;
1713 nt_status = make_auth_context_subsystem(
1714 &plaintext_auth_context);
1716 if (NT_STATUS_IS_OK(nt_status)) {
1719 plaintext_auth_context->get_ntlm_challenge(
1720 plaintext_auth_context, chal);
1722 if (!make_user_info_for_reply(&user_info,
1724 plaintext_password)) {
1725 nt_status = NT_STATUS_NO_MEMORY;
1728 if (NT_STATUS_IS_OK(nt_status)) {
1729 nt_status = plaintext_auth_context->check_ntlm_password(
1730 plaintext_auth_context,
1734 (plaintext_auth_context->free)(
1735 &plaintext_auth_context);
1740 free_user_info(&user_info);
1742 if (!NT_STATUS_IS_OK(nt_status)) {
1743 nt_status = do_map_to_guest(nt_status, &server_info,
1747 if (!NT_STATUS_IS_OK(nt_status)) {
1748 data_blob_free(&nt_resp);
1749 data_blob_free(&lm_resp);
1750 data_blob_clear_free(&plaintext_password);
1751 reply_nterror(req, nt_status_squash(nt_status));
1752 END_PROFILE(SMBsesssetupX);
1756 /* Ensure we can't possible take a code path leading to a
1759 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1760 END_PROFILE(SMBsesssetupX);
1764 if (!server_info->ptok) {
1765 nt_status = create_local_token(server_info);
1767 if (!NT_STATUS_IS_OK(nt_status)) {
1768 DEBUG(10, ("create_local_token failed: %s\n",
1769 nt_errstr(nt_status)));
1770 data_blob_free(&nt_resp);
1771 data_blob_free(&lm_resp);
1772 data_blob_clear_free(&plaintext_password);
1773 reply_nterror(req, nt_status_squash(nt_status));
1774 END_PROFILE(SMBsesssetupX);
1779 data_blob_clear_free(&plaintext_password);
1781 /* it's ok - setup a reply */
1782 reply_outbuf(req, 3, 0);
1783 if (get_Protocol() >= PROTOCOL_NT1) {
1784 push_signature(&req->outbuf);
1785 /* perhaps grab OS version here?? */
1788 if (server_info->guest) {
1789 SSVAL(req->outbuf,smb_vwv2,1);
1792 /* register the name and uid as being validated, so further connections
1793 to a uid can get through without a password, on the same VC */
1795 if (lp_security() == SEC_SHARE) {
1796 sess_vuid = UID_FIELD_INVALID;
1797 TALLOC_FREE(server_info);
1799 /* Ignore the initial vuid. */
1800 sess_vuid = register_initial_vuid(sconn);
1801 if (sess_vuid == UID_FIELD_INVALID) {
1802 data_blob_free(&nt_resp);
1803 data_blob_free(&lm_resp);
1804 reply_nterror(req, nt_status_squash(
1805 NT_STATUS_LOGON_FAILURE));
1806 END_PROFILE(SMBsesssetupX);
1809 /* register_existing_vuid keeps the server info */
1810 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1812 nt_resp.data ? nt_resp : lm_resp,
1814 if (sess_vuid == UID_FIELD_INVALID) {
1815 data_blob_free(&nt_resp);
1816 data_blob_free(&lm_resp);
1817 reply_nterror(req, nt_status_squash(
1818 NT_STATUS_LOGON_FAILURE));
1819 END_PROFILE(SMBsesssetupX);
1823 /* current_user_info is changed on new vuid */
1824 reload_services( True );
1827 data_blob_free(&nt_resp);
1828 data_blob_free(&lm_resp);
1830 SSVAL(req->outbuf,smb_uid,sess_vuid);
1831 SSVAL(req->inbuf,smb_uid,sess_vuid);
1832 req->vuid = sess_vuid;
1834 if (!sconn->smb1.sessions.done_sesssetup) {
1835 sconn->smb1.sessions.max_send =
1836 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1838 sconn->smb1.sessions.done_sesssetup = true;
1840 END_PROFILE(SMBsesssetupX);