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/>.
27 extern struct auth_context *negprot_global_auth_context;
28 extern bool global_encrypted_passwords_negotiated;
29 extern bool global_spnego_negotiated;
30 extern enum protocol_types Protocol;
33 uint32 global_client_caps = 0;
36 on a logon error possibly map the error to success if "map to guest"
39 static NTSTATUS do_map_to_guest(NTSTATUS status,
40 auth_serversupplied_info **server_info,
41 const char *user, const char *domain)
43 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
44 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
45 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
46 DEBUG(3,("No such user %s [%s] - using guest account\n",
48 status = make_server_info_guest(server_info);
52 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
53 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
54 DEBUG(3,("Registered username %s for guest access\n",
56 status = make_server_info_guest(server_info);
63 /****************************************************************************
64 Add the standard 'Samba' signature to the end of the session setup.
65 ****************************************************************************/
67 static int push_signature(uint8 **outbuf)
74 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
76 if (tmp == -1) return -1;
79 if (asprintf(&lanman, "Samba %s", SAMBA_VERSION_STRING) != -1) {
80 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
84 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
87 if (tmp == -1) return -1;
90 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
92 if (tmp == -1) return -1;
98 /****************************************************************************
99 Start the signing engine if needed. Don't fail signing here.
100 ****************************************************************************/
102 static void sessionsetup_start_signing_engine(
103 const auth_serversupplied_info *server_info,
106 if (!server_info->guest && !srv_signing_started()) {
107 /* We need to start the signing engine
108 * here but a W2K client sends the old
109 * "BSRSPYL " signature instead of the
110 * correct one. Subsequent packets will
113 srv_check_sign_mac((char *)inbuf, False);
117 /****************************************************************************
118 Send a security blob via a session setup reply.
119 ****************************************************************************/
121 static void reply_sesssetup_blob(struct smb_request *req,
125 if (!NT_STATUS_IS_OK(nt_status) &&
126 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
127 reply_nterror(req, nt_status_squash(nt_status));
129 nt_status = nt_status_squash(nt_status);
130 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
131 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
132 SSVAL(req->outbuf, smb_vwv3, blob.length);
134 if ((message_push_blob(&req->outbuf, blob) == -1)
135 || (push_signature(&req->outbuf) == -1)) {
136 reply_nterror(req, NT_STATUS_NO_MEMORY);
140 show_msg((char *)req->outbuf);
141 srv_send_smb(smbd_server_fd(),(char *)req->outbuf,req->encrypted);
142 TALLOC_FREE(req->outbuf);
145 /****************************************************************************
146 Do a 'guest' logon, getting back the
147 ****************************************************************************/
149 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
151 struct auth_context *auth_context;
152 auth_usersupplied_info *user_info = NULL;
155 unsigned char chal[8];
159 DEBUG(3,("Got anonymous request\n"));
161 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context,
166 if (!make_user_info_guest(&user_info)) {
167 (auth_context->free)(&auth_context);
168 return NT_STATUS_NO_MEMORY;
171 nt_status = auth_context->check_ntlm_password(auth_context,
174 (auth_context->free)(&auth_context);
175 free_user_info(&user_info);
183 /* Experiment that failed. See "only happens with a KDC" comment below. */
184 /****************************************************************************
185 Cerate a clock skew error blob for a Windows client.
186 ****************************************************************************/
188 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
190 krb5_context context = NULL;
191 krb5_error_code kerr = 0;
193 krb5_principal host_princ = NULL;
194 char *host_princ_s = NULL;
197 *pblob_out = data_blob_null;
199 initialize_krb5_error_table();
200 kerr = krb5_init_context(&context);
204 /* Create server principal. */
205 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
209 strlower_m(host_princ_s);
211 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
213 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
214 "for name %s: Error %s\n",
215 host_princ_s, error_message(kerr) ));
219 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
222 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
223 "failed: Error %s\n",
224 error_message(kerr) ));
228 *pblob_out = data_blob(reply.data, reply.length);
229 kerberos_free_data_contents(context,&reply);
235 SAFE_FREE(host_princ_s);
238 krb5_free_principal(context, host_princ);
240 krb5_free_context(context);
245 /****************************************************************************
246 Reply to a session setup spnego negotiate packet for kerberos.
247 ****************************************************************************/
249 static void reply_spnego_kerberos(struct smb_request *req,
252 bool *p_invalidate_vuid)
256 char *client, *p, *domain;
257 fstring netbios_domain_name;
260 int sess_vuid = req->vuid;
261 NTSTATUS ret = NT_STATUS_OK;
262 struct PAC_DATA *pac_data = NULL;
263 DATA_BLOB ap_rep, ap_rep_wrapped, response;
264 auth_serversupplied_info *server_info = NULL;
265 DATA_BLOB session_key = data_blob_null;
267 DATA_BLOB nullblob = data_blob_null;
268 fstring real_username;
269 bool map_domainuser_to_guest = False;
270 bool username_was_mapped;
271 struct PAC_LOGON_INFO *logon_info = NULL;
275 ZERO_STRUCT(ap_rep_wrapped);
276 ZERO_STRUCT(response);
278 /* Normally we will always invalidate the intermediate vuid. */
279 *p_invalidate_vuid = True;
281 mem_ctx = talloc_init("reply_spnego_kerberos");
282 if (mem_ctx == NULL) {
283 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
287 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
288 talloc_destroy(mem_ctx);
289 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
293 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
294 &client, &pac_data, &ap_rep,
297 data_blob_free(&ticket);
299 if (!NT_STATUS_IS_OK(ret)) {
301 /* Experiment that failed.
302 * See "only happens with a KDC" comment below. */
304 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
307 * Windows in this case returns
308 * NT_STATUS_MORE_PROCESSING_REQUIRED
309 * with a negTokenTarg blob containing an krb5_error
310 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
311 * The client then fixes its clock and continues rather
312 * than giving an error. JRA.
313 * -- Looks like this only happens with a KDC. JRA.
316 bool ok = make_krb5_skew_error(&ap_rep);
318 talloc_destroy(mem_ctx);
319 return ERROR_NT(nt_status_squash(
320 NT_STATUS_LOGON_FAILURE));
322 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
324 response = spnego_gen_auth_response(&ap_rep_wrapped,
325 ret, OID_KERBEROS5_OLD);
326 reply_sesssetup_blob(conn, inbuf, outbuf, response,
327 NT_STATUS_MORE_PROCESSING_REQUIRED);
330 * In this one case we don't invalidate the
331 * intermediate vuid as we're expecting the client
332 * to re-use it for the next sessionsetupX packet. JRA.
335 *p_invalidate_vuid = False;
337 data_blob_free(&ap_rep);
338 data_blob_free(&ap_rep_wrapped);
339 data_blob_free(&response);
340 talloc_destroy(mem_ctx);
341 return -1; /* already replied */
344 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
345 ret = NT_STATUS_LOGON_FAILURE;
348 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
350 talloc_destroy(mem_ctx);
351 reply_nterror(req, nt_status_squash(ret));
355 DEBUG(3,("Ticket name is [%s]\n", client));
357 p = strchr_m(client, '@');
359 DEBUG(3,("Doesn't look like a valid principal\n"));
360 data_blob_free(&ap_rep);
361 data_blob_free(&session_key);
363 talloc_destroy(mem_ctx);
364 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
370 /* save the PAC data if we have it */
373 logon_info = get_logon_info_from_pac(pac_data);
375 netsamlogon_cache_store( client, &logon_info->info3 );
379 if (!strequal(p+1, lp_realm())) {
380 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
381 if (!lp_allow_trusted_domains()) {
382 data_blob_free(&ap_rep);
383 data_blob_free(&session_key);
385 talloc_destroy(mem_ctx);
386 reply_nterror(req, nt_status_squash(
387 NT_STATUS_LOGON_FAILURE));
392 /* this gives a fully qualified user name (ie. with full realm).
393 that leads to very long usernames, but what else can we do? */
397 if (logon_info && logon_info->info3.base.domain.string) {
398 fstrcpy(netbios_domain_name,
399 logon_info->info3.base.domain.string);
400 domain = netbios_domain_name;
401 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
405 /* If we have winbind running, we can (and must) shorten the
406 username by using the short netbios name. Otherwise we will
407 have inconsistent user names. With Kerberos, we get the
408 fully qualified realm, with ntlmssp we get the short
409 name. And even w2k3 does use ntlmssp if you for example
410 connect to an ip address. */
413 struct wbcDomainInfo *info = NULL;
415 DEBUG(10, ("Mapping [%s] to short name\n", domain));
417 wbc_status = wbcDomainInfo(domain, &info);
419 if (WBC_ERROR_IS_OK(wbc_status)) {
421 fstrcpy(netbios_domain_name,
425 domain = netbios_domain_name;
426 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
428 DEBUG(3, ("Could not find short name: %s\n",
429 wbcErrorString(wbc_status)));
433 fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
435 /* lookup the passwd struct, create a new user if necessary */
437 username_was_mapped = map_username( user );
439 pw = smb_getpwnam( mem_ctx, user, real_username, True );
442 /* if a real user check pam account restrictions */
443 /* only really perfomed if "obey pam restriction" is true */
444 /* do this before an eventual mappign to guest occurs */
445 ret = smb_pam_accountcheck(pw->pw_name);
446 if ( !NT_STATUS_IS_OK(ret)) {
447 DEBUG(1,("PAM account restriction "
448 "prevents user login\n"));
449 data_blob_free(&ap_rep);
450 data_blob_free(&session_key);
451 TALLOC_FREE(mem_ctx);
452 reply_nterror(req, nt_status_squash(ret));
459 /* this was originally the behavior of Samba 2.2, if a user
460 did not have a local uid but has been authenticated, then
461 map them to a guest account */
463 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
464 map_domainuser_to_guest = True;
465 fstrcpy(user,lp_guestaccount());
466 pw = smb_getpwnam( mem_ctx, user, real_username, True );
469 /* extra sanity check that the guest account is valid */
472 DEBUG(1,("Username %s is invalid on this system\n",
475 data_blob_free(&ap_rep);
476 data_blob_free(&session_key);
477 TALLOC_FREE(mem_ctx);
478 reply_nterror(req, nt_status_squash(
479 NT_STATUS_LOGON_FAILURE));
484 /* setup the string used by %U */
486 sub_set_smb_name( real_username );
487 reload_services(True);
489 if ( map_domainuser_to_guest ) {
490 make_server_info_guest(&server_info);
491 } else if (logon_info) {
492 /* pass the unmapped username here since map_username()
493 will be called again from inside make_server_info_info3() */
495 ret = make_server_info_info3(mem_ctx, client, domain,
496 &server_info, &logon_info->info3);
497 if ( !NT_STATUS_IS_OK(ret) ) {
498 DEBUG(1,("make_server_info_info3 failed: %s!\n",
501 data_blob_free(&ap_rep);
502 data_blob_free(&session_key);
503 TALLOC_FREE(mem_ctx);
504 reply_nterror(req, nt_status_squash(ret));
509 ret = make_server_info_pw(&server_info, real_username, pw);
511 if ( !NT_STATUS_IS_OK(ret) ) {
512 DEBUG(1,("make_server_info_pw failed: %s!\n",
515 data_blob_free(&ap_rep);
516 data_blob_free(&session_key);
517 TALLOC_FREE(mem_ctx);
518 reply_nterror(req, nt_status_squash(ret));
522 /* make_server_info_pw does not set the domain. Without this
523 * we end up with the local netbios name in substitutions for
526 if (server_info->sam_account != NULL) {
527 pdb_set_domain(server_info->sam_account,
532 if (username_was_mapped) {
533 server_info->was_mapped = username_was_mapped;
536 /* we need to build the token for the user. make_server_info_guest()
539 if ( !server_info->ptok ) {
540 ret = create_local_token( server_info );
541 if ( !NT_STATUS_IS_OK(ret) ) {
542 DEBUG(10,("failed to create local token: %s\n",
545 data_blob_free(&ap_rep);
546 data_blob_free(&session_key);
547 TALLOC_FREE( mem_ctx );
548 TALLOC_FREE( server_info );
549 reply_nterror(req, nt_status_squash(ret));
554 /* register_existing_vuid keeps the server info */
555 /* register_existing_vuid takes ownership of session_key on success,
556 * no need to free after this on success. A better interface would copy
559 if (!is_partial_auth_vuid(sess_vuid)) {
560 sess_vuid = register_initial_vuid();
562 sess_vuid = register_existing_vuid(sess_vuid,
570 reply_outbuf(req, 4, 0);
571 SSVAL(req->outbuf,smb_uid,sess_vuid);
573 if (sess_vuid == UID_FIELD_INVALID ) {
574 ret = NT_STATUS_LOGON_FAILURE;
575 data_blob_free(&session_key);
577 /* current_user_info is changed on new vuid */
578 reload_services( True );
580 SSVAL(req->outbuf, smb_vwv3, 0);
582 if (server_info->guest) {
583 SSVAL(req->outbuf,smb_vwv2,1);
586 SSVAL(req->outbuf, smb_uid, sess_vuid);
588 sessionsetup_start_signing_engine(server_info, req->inbuf);
589 /* Successful logon. Keep this vuid. */
590 *p_invalidate_vuid = False;
593 /* wrap that up in a nice GSS-API wrapping */
594 if (NT_STATUS_IS_OK(ret)) {
595 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
598 ap_rep_wrapped = data_blob_null;
600 response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
602 reply_sesssetup_blob(req, response, ret);
604 data_blob_free(&ap_rep);
605 data_blob_free(&ap_rep_wrapped);
606 data_blob_free(&response);
607 TALLOC_FREE(mem_ctx);
612 /****************************************************************************
613 Send a session setup reply, wrapped in SPNEGO.
614 Get vuid and check first.
615 End the NTLMSSP exchange context if we are OK/complete fail
616 This should be split into two functions, one to handle each
617 leg of the NTLM auth steps.
618 ***************************************************************************/
620 static void reply_spnego_ntlmssp(struct smb_request *req,
622 AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
623 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
628 struct auth_serversupplied_info *server_info = NULL;
630 if (NT_STATUS_IS_OK(nt_status)) {
631 server_info = (*auth_ntlmssp_state)->server_info;
633 nt_status = do_map_to_guest(nt_status,
635 (*auth_ntlmssp_state)->ntlmssp_state->user,
636 (*auth_ntlmssp_state)->ntlmssp_state->domain);
639 reply_outbuf(req, 4, 0);
641 SSVAL(req->outbuf, smb_uid, vuid);
643 if (NT_STATUS_IS_OK(nt_status)) {
644 DATA_BLOB nullblob = data_blob_null;
645 DATA_BLOB session_key =
647 (*auth_ntlmssp_state)->ntlmssp_state->session_key.data,
648 (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
650 if (!is_partial_auth_vuid(vuid)) {
651 data_blob_free(&session_key);
652 nt_status = NT_STATUS_LOGON_FAILURE;
655 /* register_existing_vuid keeps the server info */
656 if (register_existing_vuid(vuid,
658 session_key, nullblob,
659 (*auth_ntlmssp_state)->ntlmssp_state->user) !=
661 data_blob_free(&session_key);
662 nt_status = NT_STATUS_LOGON_FAILURE;
666 (*auth_ntlmssp_state)->server_info = NULL;
668 /* current_user_info is changed on new vuid */
669 reload_services( True );
671 SSVAL(req->outbuf, smb_vwv3, 0);
673 if (server_info->guest) {
674 SSVAL(req->outbuf,smb_vwv2,1);
677 sessionsetup_start_signing_engine(server_info,
678 (uint8 *)req->inbuf);
684 response = spnego_gen_auth_response(ntlmssp_blob,
687 response = *ntlmssp_blob;
690 reply_sesssetup_blob(req, response, nt_status);
692 data_blob_free(&response);
695 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
696 and the other end, that we are not finished yet. */
698 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
699 /* NB. This is *NOT* an error case. JRA */
700 auth_ntlmssp_end(auth_ntlmssp_state);
701 if (!NT_STATUS_IS_OK(nt_status)) {
702 /* Kill the intermediate vuid */
703 invalidate_vuid(vuid);
708 /****************************************************************************
709 Is this a krb5 mechanism ?
710 ****************************************************************************/
712 NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
715 char *OIDs[ASN1_MAX_OIDS];
720 /* parse out the OIDs and the first sec blob */
721 if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
722 return NT_STATUS_LOGON_FAILURE;
725 /* only look at the first OID for determining the mechToken --
726 according to RFC2478, we should choose the one we want
727 and renegotiate, but i smell a client bug here..
729 Problem observed when connecting to a member (samba box)
730 of an AD domain as a user in a Samba domain. Samba member
731 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
732 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
733 NTLMSSP mechtoken. --jerry */
736 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
737 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
742 for (i=0;OIDs[i];i++) {
743 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
749 /****************************************************************************
750 Fall back from krb5 to NTLMSSP.
751 ****************************************************************************/
753 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
758 reply_outbuf(req, 4, 0);
759 SSVAL(req->outbuf,smb_uid,vuid);
761 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
762 "but set to downgrade to NTLMSSP\n"));
764 response = spnego_gen_auth_response(NULL,
765 NT_STATUS_MORE_PROCESSING_REQUIRED,
767 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
768 data_blob_free(&response);
771 /****************************************************************************
772 Reply to a session setup spnego negotiate packet.
773 ****************************************************************************/
775 static void reply_spnego_negotiate(struct smb_request *req,
778 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
782 bool got_kerberos_mechanism = False;
785 status = parse_spnego_mechanisms(blob1, &secblob,
786 &got_kerberos_mechanism);
787 if (!NT_STATUS_IS_OK(status)) {
788 /* Kill the intermediate vuid */
789 invalidate_vuid(vuid);
790 reply_nterror(req, nt_status_squash(status));
794 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
795 (unsigned long)secblob.length));
798 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) ||
799 lp_use_kerberos_keytab()) ) {
800 bool destroy_vuid = True;
801 reply_spnego_kerberos(req, &secblob, vuid,
803 data_blob_free(&secblob);
805 /* Kill the intermediate vuid */
806 invalidate_vuid(vuid);
812 if (*auth_ntlmssp_state) {
813 auth_ntlmssp_end(auth_ntlmssp_state);
816 if (got_kerberos_mechanism) {
817 data_blob_free(&secblob);
818 /* The mechtoken is a krb5 ticket, but
819 * we need to fall back to NTLM. */
820 reply_spnego_downgrade_to_ntlmssp(req,
825 status = auth_ntlmssp_start(auth_ntlmssp_state);
826 if (!NT_STATUS_IS_OK(status)) {
827 /* Kill the intermediate vuid */
828 invalidate_vuid(vuid);
829 reply_nterror(req, nt_status_squash(status));
833 status = auth_ntlmssp_update(*auth_ntlmssp_state,
836 data_blob_free(&secblob);
838 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
839 &chal, status, OID_NTLMSSP, true);
841 data_blob_free(&chal);
843 /* already replied */
847 /****************************************************************************
848 Reply to a session setup spnego auth packet.
849 ****************************************************************************/
851 static void reply_spnego_auth(struct smb_request *req,
854 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
856 DATA_BLOB auth = data_blob_null;
857 DATA_BLOB auth_reply = data_blob_null;
858 DATA_BLOB secblob = data_blob_null;
859 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
861 if (!spnego_parse_auth(blob1, &auth)) {
863 file_save("auth.dat", blob1.data, blob1.length);
865 /* Kill the intermediate vuid */
866 invalidate_vuid(vuid);
868 reply_nterror(req, nt_status_squash(
869 NT_STATUS_LOGON_FAILURE));
873 if (auth.data[0] == ASN1_APPLICATION(0)) {
874 /* Might be a second negTokenTarg packet */
876 bool got_krb5_mechanism = False;
877 status = parse_spnego_mechanisms(auth, &secblob,
878 &got_krb5_mechanism);
880 if (!NT_STATUS_IS_OK(status)) {
881 /* Kill the intermediate vuid */
882 invalidate_vuid(vuid);
883 reply_nterror(req, nt_status_squash(status));
887 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
888 (unsigned long)secblob.length));
890 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) ||
891 lp_use_kerberos_keytab()) ) {
892 bool destroy_vuid = True;
893 reply_spnego_kerberos(req, &secblob,
894 vuid, &destroy_vuid);
895 data_blob_free(&secblob);
896 data_blob_free(&auth);
898 /* Kill the intermediate vuid */
899 invalidate_vuid(vuid);
904 /* Can't blunder into NTLMSSP auth if we have
907 if (got_krb5_mechanism) {
908 /* Kill the intermediate vuid */
909 invalidate_vuid(vuid);
910 DEBUG(3,("reply_spnego_auth: network "
911 "misconfiguration, client sent us a "
912 "krb5 ticket and kerberos security "
914 reply_nterror(req, nt_status_squash(
915 NT_STATUS_LOGON_FAILURE));
919 /* If we get here it wasn't a negTokenTarg auth packet. */
920 data_blob_free(&secblob);
922 if (!*auth_ntlmssp_state) {
923 status = auth_ntlmssp_start(auth_ntlmssp_state);
924 if (!NT_STATUS_IS_OK(status)) {
925 /* Kill the intermediate vuid */
926 invalidate_vuid(vuid);
927 reply_nterror(req, nt_status_squash(status));
932 status = auth_ntlmssp_update(*auth_ntlmssp_state,
935 data_blob_free(&auth);
937 /* Don't send the mechid as we've already sent this (RFC4178). */
939 reply_spnego_ntlmssp(req, vuid,
941 &auth_reply, status, NULL, true);
943 data_blob_free(&auth_reply);
945 /* and tell smbd that we have already replied to this packet */
949 /****************************************************************************
950 List to store partial SPNEGO auth fragments.
951 ****************************************************************************/
953 static struct pending_auth_data *pd_list;
955 /****************************************************************************
956 Delete an entry on the list.
957 ****************************************************************************/
959 static void delete_partial_auth(struct pending_auth_data *pad)
964 DLIST_REMOVE(pd_list, pad);
965 data_blob_free(&pad->partial_data);
969 /****************************************************************************
970 Search for a partial SPNEGO auth fragment matching an smbpid.
971 ****************************************************************************/
973 static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
975 struct pending_auth_data *pad;
977 for (pad = pd_list; pad; pad = pad->next) {
978 if (pad->smbpid == smbpid) {
985 /****************************************************************************
986 Check the size of an SPNEGO blob. If we need more return
987 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
988 the blob to be more than 64k.
989 ****************************************************************************/
991 static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
994 struct pending_auth_data *pad = NULL;
996 size_t needed_len = 0;
998 pad = get_pending_auth_data(smbpid);
1000 /* Ensure we have some data. */
1001 if (pblob->length == 0) {
1002 /* Caller can cope. */
1003 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
1004 delete_partial_auth(pad);
1005 return NT_STATUS_OK;
1008 /* Were we waiting for more data ? */
1011 size_t copy_len = MIN(65536, pblob->length);
1013 /* Integer wrap paranoia.... */
1015 if (pad->partial_data.length + copy_len <
1016 pad->partial_data.length ||
1017 pad->partial_data.length + copy_len < copy_len) {
1019 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1020 "pad->partial_data.length = %u, "
1022 (unsigned int)pad->partial_data.length,
1023 (unsigned int)copy_len ));
1025 delete_partial_auth(pad);
1026 return NT_STATUS_INVALID_PARAMETER;
1029 DEBUG(10,("check_spnego_blob_complete: "
1030 "pad->partial_data.length = %u, "
1031 "pad->needed_len = %u, "
1033 "pblob->length = %u,\n",
1034 (unsigned int)pad->partial_data.length,
1035 (unsigned int)pad->needed_len,
1036 (unsigned int)copy_len,
1037 (unsigned int)pblob->length ));
1039 tmp_blob = data_blob(NULL,
1040 pad->partial_data.length + copy_len);
1042 /* Concatenate the two (up to copy_len) bytes. */
1043 memcpy(tmp_blob.data,
1044 pad->partial_data.data,
1045 pad->partial_data.length);
1046 memcpy(tmp_blob.data + pad->partial_data.length,
1050 /* Replace the partial data. */
1051 data_blob_free(&pad->partial_data);
1052 pad->partial_data = tmp_blob;
1053 ZERO_STRUCT(tmp_blob);
1056 if (pblob->length >= pad->needed_len) {
1057 /* Yes, replace pblob. */
1058 data_blob_free(pblob);
1059 *pblob = pad->partial_data;
1060 ZERO_STRUCT(pad->partial_data);
1061 delete_partial_auth(pad);
1062 return NT_STATUS_OK;
1065 /* Still need more data. */
1066 pad->needed_len -= copy_len;
1067 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1070 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
1071 (pblob->data[0] != ASN1_CONTEXT(1))) {
1072 /* Not something we can determine the
1075 return NT_STATUS_OK;
1078 /* This is a new SPNEGO sessionsetup - see if
1079 * the data given in this blob is enough.
1082 asn1_load(&data, *pblob);
1083 asn1_start_tag(&data, pblob->data[0]);
1084 if (data.has_error || data.nesting == NULL) {
1086 /* Let caller catch. */
1087 return NT_STATUS_OK;
1090 /* Integer wrap paranoia.... */
1092 if (data.nesting->taglen + data.nesting->start < data.nesting->taglen ||
1093 data.nesting->taglen + data.nesting->start < data.nesting->start) {
1095 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1096 "data.nesting->taglen = %u, "
1097 "data.nesting->start = %u\n",
1098 (unsigned int)data.nesting->taglen,
1099 (unsigned int)data.nesting->start ));
1102 return NT_STATUS_INVALID_PARAMETER;
1105 /* Total length of the needed asn1 is the tag length
1106 * plus the current offset. */
1108 needed_len = data.nesting->taglen + data.nesting->start;
1111 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
1112 "pblob->length = %u\n",
1113 (unsigned int)needed_len,
1114 (unsigned int)pblob->length ));
1116 if (needed_len <= pblob->length) {
1117 /* Nothing to do - blob is complete. */
1118 return NT_STATUS_OK;
1121 /* Refuse the blob if it's bigger than 64k. */
1122 if (needed_len > 65536) {
1123 DEBUG(2,("check_spnego_blob_complete: needed_len "
1125 (unsigned int)needed_len ));
1126 return NT_STATUS_INVALID_PARAMETER;
1129 /* We must store this blob until complete. */
1130 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1131 return NT_STATUS_NO_MEMORY;
1133 pad->needed_len = needed_len - pblob->length;
1134 pad->partial_data = data_blob(pblob->data, pblob->length);
1135 if (pad->partial_data.data == NULL) {
1137 return NT_STATUS_NO_MEMORY;
1139 pad->smbpid = smbpid;
1141 DLIST_ADD(pd_list, pad);
1143 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1146 /****************************************************************************
1147 Reply to a session setup command.
1148 conn POINTER CAN BE NULL HERE !
1149 ****************************************************************************/
1151 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1156 fstring native_os, native_lanman, primary_domain;
1158 uint16 data_blob_len = SVAL(req->inbuf, smb_vwv7);
1159 enum remote_arch_types ra_type = get_remote_arch();
1160 int vuid = SVAL(req->inbuf,smb_uid);
1161 user_struct *vuser = NULL;
1162 NTSTATUS status = NT_STATUS_OK;
1163 uint16 smbpid = req->smbpid;
1164 uint16 smb_flag2 = req->flags2;
1166 DEBUG(3,("Doing spnego session setup\n"));
1168 if (global_client_caps == 0) {
1169 global_client_caps = IVAL(req->inbuf,smb_vwv10);
1171 if (!(global_client_caps & CAP_STATUS32)) {
1172 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1177 p = (uint8 *)smb_buf(req->inbuf);
1179 if (data_blob_len == 0) {
1180 /* an invalid request */
1181 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1185 bufrem = smb_bufrem(req->inbuf, p);
1186 /* pull the spnego blob */
1187 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1190 file_save("negotiate.dat", blob1.data, blob1.length);
1193 p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len;
1194 p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_os, p2,
1195 sizeof(native_os), STR_TERMINATE);
1196 p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_lanman, p2,
1197 sizeof(native_lanman), STR_TERMINATE);
1198 p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2,
1199 sizeof(primary_domain), STR_TERMINATE);
1200 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1201 native_os, native_lanman, primary_domain));
1203 if ( ra_type == RA_WIN2K ) {
1204 /* Vista sets neither the OS or lanman strings */
1206 if ( !strlen(native_os) && !strlen(native_lanman) )
1207 set_remote_arch(RA_VISTA);
1209 /* Windows 2003 doesn't set the native lanman string,
1210 but does set primary domain which is a bug I think */
1212 if ( !strlen(native_lanman) ) {
1213 ra_lanman_string( primary_domain );
1215 ra_lanman_string( native_lanman );
1219 /* Did we get a valid vuid ? */
1220 if (!is_partial_auth_vuid(vuid)) {
1221 /* No, then try and see if this is an intermediate sessionsetup
1222 * for a large SPNEGO packet. */
1223 struct pending_auth_data *pad = get_pending_auth_data(smbpid);
1225 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1226 "pending vuid %u\n",
1227 (unsigned int)pad->vuid ));
1232 /* Do we have a valid vuid now ? */
1233 if (!is_partial_auth_vuid(vuid)) {
1234 /* No, start a new authentication setup. */
1235 vuid = register_initial_vuid();
1236 if (vuid == UID_FIELD_INVALID) {
1237 data_blob_free(&blob1);
1238 reply_nterror(req, nt_status_squash(
1239 NT_STATUS_INVALID_PARAMETER));
1244 vuser = get_partial_auth_user_struct(vuid);
1245 /* This MUST be valid. */
1247 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1250 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1251 * sessionsetup requests as the Windows limit on the security blob
1252 * field is 4k. Bug #4400. JRA.
1255 status = check_spnego_blob_complete(smbpid, vuid, &blob1);
1256 if (!NT_STATUS_IS_OK(status)) {
1257 if (!NT_STATUS_EQUAL(status,
1258 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1259 /* Real error - kill the intermediate vuid */
1260 invalidate_vuid(vuid);
1262 data_blob_free(&blob1);
1263 reply_nterror(req, nt_status_squash(status));
1267 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1269 /* its a negTokenTarg packet */
1271 reply_spnego_negotiate(req, vuid, blob1,
1272 &vuser->auth_ntlmssp_state);
1273 data_blob_free(&blob1);
1277 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1279 /* its a auth packet */
1281 reply_spnego_auth(req, vuid, blob1,
1282 &vuser->auth_ntlmssp_state);
1283 data_blob_free(&blob1);
1287 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1290 if (!vuser->auth_ntlmssp_state) {
1291 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 /* Kill the intermediate vuid */
1294 invalidate_vuid(vuid);
1295 data_blob_free(&blob1);
1296 reply_nterror(req, nt_status_squash(status));
1301 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1304 data_blob_free(&blob1);
1306 reply_spnego_ntlmssp(req, vuid,
1307 &vuser->auth_ntlmssp_state,
1308 &chal, status, OID_NTLMSSP, false);
1309 data_blob_free(&chal);
1313 /* what sort of packet is this? */
1314 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1316 data_blob_free(&blob1);
1318 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1321 /****************************************************************************
1322 On new VC == 0, shutdown *all* old connections and users.
1323 It seems that only NT4.x does this. At W2K and above (XP etc.).
1324 a new session setup with VC==0 is ignored.
1325 ****************************************************************************/
1327 static int shutdown_other_smbds(struct db_record *rec,
1328 const struct connections_key *key,
1329 const struct connections_data *crec,
1332 const char *ip = (const char *)private_data;
1334 if (!process_exists(crec->pid)) {
1338 if (procid_is_me(&crec->pid)) {
1342 if (strcmp(ip, crec->addr) != 0) {
1346 messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN,
1351 static void setup_new_vc_session(void)
1353 char addr[INET6_ADDRSTRLEN];
1355 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1356 "compatible we would close all old resources.\n"));
1359 invalidate_all_vuids();
1361 if (lp_reset_on_zero_vc()) {
1362 connections_forall(shutdown_other_smbds,
1363 CONST_DISCARD(void *,
1364 client_addr(get_client_fd(),addr,sizeof(addr))));
1368 /****************************************************************************
1369 Reply to a session setup command.
1370 ****************************************************************************/
1372 void reply_sesssetup_and_X(struct smb_request *req)
1378 DATA_BLOB plaintext_password;
1380 fstring sub_user; /* Sainitised username for substituion */
1383 fstring native_lanman;
1384 fstring primary_domain;
1385 static bool done_sesssetup = False;
1386 auth_usersupplied_info *user_info = NULL;
1387 auth_serversupplied_info *server_info = NULL;
1388 uint16 smb_flag2 = req->flags2;
1392 bool doencrypt = global_encrypted_passwords_negotiated;
1394 DATA_BLOB session_key;
1396 START_PROFILE(SMBsesssetupX);
1398 ZERO_STRUCT(lm_resp);
1399 ZERO_STRUCT(nt_resp);
1400 ZERO_STRUCT(plaintext_password);
1402 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1404 /* a SPNEGO session setup has 12 command words, whereas a normal
1405 NT1 session setup has 13. See the cifs spec. */
1406 if (req->wct == 12 &&
1407 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1409 if (!global_spnego_negotiated) {
1410 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1411 "at SPNEGO session setup when it was not "
1413 reply_nterror(req, nt_status_squash(
1414 NT_STATUS_LOGON_FAILURE));
1415 END_PROFILE(SMBsesssetupX);
1419 if (SVAL(req->inbuf,smb_vwv4) == 0) {
1420 setup_new_vc_session();
1423 reply_sesssetup_and_X_spnego(req);
1424 END_PROFILE(SMBsesssetupX);
1428 smb_bufsize = SVAL(req->inbuf,smb_vwv2);
1430 if (Protocol < PROTOCOL_NT1) {
1431 uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
1433 /* Never do NT status codes with protocols before NT1 as we
1434 * don't get client caps. */
1435 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1437 if ((passlen1 > MAX_PASS_LEN)
1438 || (passlen1 > smb_bufrem(req->inbuf,
1439 smb_buf(req->inbuf)))) {
1440 reply_nterror(req, nt_status_squash(
1441 NT_STATUS_INVALID_PARAMETER));
1442 END_PROFILE(SMBsesssetupX);
1447 lm_resp = data_blob(smb_buf(req->inbuf), passlen1);
1449 plaintext_password = data_blob(smb_buf(req->inbuf),
1451 /* Ensure null termination */
1452 plaintext_password.data[passlen1] = 0;
1455 srvstr_pull_buf(req->inbuf, req->flags2, user,
1456 smb_buf(req->inbuf)+passlen1, sizeof(user),
1461 uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
1462 uint16 passlen2 = SVAL(req->inbuf,smb_vwv8);
1463 enum remote_arch_types ra_type = get_remote_arch();
1464 char *p = smb_buf(req->inbuf);
1465 char *save_p = smb_buf(req->inbuf);
1469 if(global_client_caps == 0) {
1470 global_client_caps = IVAL(req->inbuf,smb_vwv11);
1472 if (!(global_client_caps & CAP_STATUS32)) {
1473 remove_from_common_flags2(
1474 FLAGS2_32_BIT_ERROR_CODES);
1477 /* client_caps is used as final determination if
1478 * client is NT or Win95. This is needed to return
1479 * the correct error codes in some circumstances.
1482 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1483 ra_type == RA_WIN95) {
1484 if(!(global_client_caps & (CAP_NT_SMBS|
1486 set_remote_arch( RA_WIN95);
1492 /* both Win95 and WinNT stuff up the password
1493 * lengths for non-encrypting systems. Uggh.
1495 if passlen1==24 its a win95 system, and its setting
1496 the password length incorrectly. Luckily it still
1497 works with the default code because Win95 will null
1498 terminate the password anyway
1500 if passlen1>0 and passlen2>0 then maybe its a NT box
1501 and its setting passlen2 to some random value which
1502 really stuffs things up. we need to fix that one. */
1504 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1510 /* check for nasty tricks */
1511 if (passlen1 > MAX_PASS_LEN
1512 || passlen1 > smb_bufrem(req->inbuf, p)) {
1513 reply_nterror(req, nt_status_squash(
1514 NT_STATUS_INVALID_PARAMETER));
1515 END_PROFILE(SMBsesssetupX);
1519 if (passlen2 > MAX_PASS_LEN
1520 || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) {
1521 reply_nterror(req, nt_status_squash(
1522 NT_STATUS_INVALID_PARAMETER));
1523 END_PROFILE(SMBsesssetupX);
1527 /* Save the lanman2 password and the NT md4 password. */
1529 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1534 lm_resp = data_blob(p, passlen1);
1535 nt_resp = data_blob(p+passlen1, passlen2);
1536 } else if (lp_security() != SEC_SHARE) {
1538 * In share level we should ignore any passwords, so
1539 * only read them if we're not.
1542 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1544 if (unic && (passlen2 == 0) && passlen1) {
1545 /* Only a ascii plaintext password was sent. */
1546 (void)srvstr_pull_talloc(talloc_tos(),
1550 smb_buf(req->inbuf),
1552 STR_TERMINATE|STR_ASCII);
1554 (void)srvstr_pull_talloc(talloc_tos(),
1558 smb_buf(req->inbuf),
1559 unic ? passlen2 : passlen1,
1563 reply_nterror(req, nt_status_squash(
1564 NT_STATUS_INVALID_PARAMETER));
1565 END_PROFILE(SMBsesssetupX);
1568 plaintext_password = data_blob(pass, strlen(pass)+1);
1571 p += passlen1 + passlen2;
1572 p += srvstr_pull_buf(req->inbuf, req->flags2, user, p,
1573 sizeof(user), STR_TERMINATE);
1574 p += srvstr_pull_buf(req->inbuf, req->flags2, domain, p,
1575 sizeof(domain), STR_TERMINATE);
1576 p += srvstr_pull_buf(req->inbuf, req->flags2, native_os,
1577 p, sizeof(native_os), STR_TERMINATE);
1578 p += srvstr_pull_buf(req->inbuf, req->flags2,
1579 native_lanman, p, sizeof(native_lanman),
1582 /* not documented or decoded by Ethereal but there is one more
1583 * string in the extra bytes which is the same as the
1584 * PrimaryDomain when using extended security. Windows NT 4
1585 * and 2003 use this string to store the native lanman string.
1586 * Windows 9x does not include a string here at all so we have
1587 * to check if we have any extra bytes left */
1589 byte_count = SVAL(req->inbuf, smb_vwv13);
1590 if ( PTR_DIFF(p, save_p) < byte_count) {
1591 p += srvstr_pull_buf(req->inbuf, req->flags2,
1593 sizeof(primary_domain),
1596 fstrcpy( primary_domain, "null" );
1599 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1600 "PrimaryDomain=[%s]\n",
1601 domain, native_os, native_lanman, primary_domain));
1603 if ( ra_type == RA_WIN2K ) {
1604 if ( strlen(native_lanman) == 0 )
1605 ra_lanman_string( primary_domain );
1607 ra_lanman_string( native_lanman );
1612 if (SVAL(req->inbuf,smb_vwv4) == 0) {
1613 setup_new_vc_session();
1616 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1617 domain, user, get_remote_machine_name()));
1620 if (global_spnego_negotiated) {
1622 /* This has to be here, because this is a perfectly
1623 * valid behaviour for guest logons :-( */
1625 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1626 "at 'normal' session setup after "
1627 "negotiating spnego.\n"));
1628 reply_nterror(req, nt_status_squash(
1629 NT_STATUS_LOGON_FAILURE));
1630 END_PROFILE(SMBsesssetupX);
1633 fstrcpy(sub_user, user);
1635 fstrcpy(sub_user, lp_guestaccount());
1638 sub_set_smb_name(sub_user);
1640 reload_services(True);
1642 if (lp_security() == SEC_SHARE) {
1643 /* In share level we should ignore any passwords */
1645 data_blob_free(&lm_resp);
1646 data_blob_free(&nt_resp);
1647 data_blob_clear_free(&plaintext_password);
1649 map_username(sub_user);
1650 add_session_user(sub_user);
1651 add_session_workgroup(domain);
1652 /* Then force it to null for the benfit of the code below */
1658 nt_status = check_guest_password(&server_info);
1660 } else if (doencrypt) {
1661 if (!negprot_global_auth_context) {
1662 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1663 "session setup without negprot denied!\n"));
1664 reply_nterror(req, nt_status_squash(
1665 NT_STATUS_LOGON_FAILURE));
1666 END_PROFILE(SMBsesssetupX);
1669 nt_status = make_user_info_for_reply_enc(&user_info, user,
1672 if (NT_STATUS_IS_OK(nt_status)) {
1673 nt_status = negprot_global_auth_context->check_ntlm_password(
1674 negprot_global_auth_context,
1679 struct auth_context *plaintext_auth_context = NULL;
1682 nt_status = make_auth_context_subsystem(
1683 &plaintext_auth_context);
1685 if (NT_STATUS_IS_OK(nt_status)) {
1686 chal = plaintext_auth_context->get_ntlm_challenge(
1687 plaintext_auth_context);
1689 if (!make_user_info_for_reply(&user_info,
1691 plaintext_password)) {
1692 nt_status = NT_STATUS_NO_MEMORY;
1695 if (NT_STATUS_IS_OK(nt_status)) {
1696 nt_status = plaintext_auth_context->check_ntlm_password(
1697 plaintext_auth_context,
1701 (plaintext_auth_context->free)(
1702 &plaintext_auth_context);
1707 free_user_info(&user_info);
1709 if (!NT_STATUS_IS_OK(nt_status)) {
1710 nt_status = do_map_to_guest(nt_status, &server_info,
1714 if (!NT_STATUS_IS_OK(nt_status)) {
1715 data_blob_free(&nt_resp);
1716 data_blob_free(&lm_resp);
1717 data_blob_clear_free(&plaintext_password);
1718 reply_nterror(req, nt_status_squash(nt_status));
1719 END_PROFILE(SMBsesssetupX);
1723 /* Ensure we can't possible take a code path leading to a
1726 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1727 END_PROFILE(SMBsesssetupX);
1731 nt_status = create_local_token(server_info);
1732 if (!NT_STATUS_IS_OK(nt_status)) {
1733 DEBUG(10, ("create_local_token failed: %s\n",
1734 nt_errstr(nt_status)));
1735 data_blob_free(&nt_resp);
1736 data_blob_free(&lm_resp);
1737 data_blob_clear_free(&plaintext_password);
1738 reply_nterror(req, nt_status_squash(nt_status));
1739 END_PROFILE(SMBsesssetupX);
1743 if (server_info->user_session_key.data) {
1744 session_key = data_blob(server_info->user_session_key.data,
1745 server_info->user_session_key.length);
1747 session_key = data_blob_null;
1750 data_blob_clear_free(&plaintext_password);
1752 /* it's ok - setup a reply */
1753 reply_outbuf(req, 3, 0);
1754 if (Protocol >= PROTOCOL_NT1) {
1755 push_signature(&req->outbuf);
1756 /* perhaps grab OS version here?? */
1759 if (server_info->guest) {
1760 SSVAL(req->outbuf,smb_vwv2,1);
1763 /* register the name and uid as being validated, so further connections
1764 to a uid can get through without a password, on the same VC */
1766 if (lp_security() == SEC_SHARE) {
1767 sess_vuid = UID_FIELD_INVALID;
1768 data_blob_free(&session_key);
1769 TALLOC_FREE(server_info);
1771 /* Ignore the initial vuid. */
1772 sess_vuid = register_initial_vuid();
1773 if (sess_vuid == UID_FIELD_INVALID) {
1774 data_blob_free(&nt_resp);
1775 data_blob_free(&lm_resp);
1776 data_blob_free(&session_key);
1777 reply_nterror(req, nt_status_squash(
1778 NT_STATUS_LOGON_FAILURE));
1779 END_PROFILE(SMBsesssetupX);
1782 /* register_existing_vuid keeps the server info */
1783 sess_vuid = register_existing_vuid(sess_vuid,
1786 nt_resp.data ? nt_resp : lm_resp,
1788 if (sess_vuid == UID_FIELD_INVALID) {
1789 data_blob_free(&nt_resp);
1790 data_blob_free(&lm_resp);
1791 data_blob_free(&session_key);
1792 reply_nterror(req, nt_status_squash(
1793 NT_STATUS_LOGON_FAILURE));
1794 END_PROFILE(SMBsesssetupX);
1798 /* current_user_info is changed on new vuid */
1799 reload_services( True );
1801 sessionsetup_start_signing_engine(server_info, req->inbuf);
1804 data_blob_free(&nt_resp);
1805 data_blob_free(&lm_resp);
1807 SSVAL(req->outbuf,smb_uid,sess_vuid);
1808 SSVAL(req->inbuf,smb_uid,sess_vuid);
1810 if (!done_sesssetup)
1811 max_send = MIN(max_send,smb_bufsize);
1813 done_sesssetup = True;
1815 END_PROFILE(SMBsesssetupX);