LCOV - code coverage report
Current view: top level - source3/smbd - smb1_sesssetup.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 383 572 67.0 %
Date: 2024-05-31 13:13:24 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    handle SMBsessionsetup
       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
      10             : 
      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.
      15             : 
      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.
      20             : 
      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/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "../lib/tsocket/tsocket.h"
      27             : #include "lib/util/server_id.h"
      28             : #include "smbd/smbd.h"
      29             : #include "smbd/globals.h"
      30             : #include "source3/smbd/smbXsrv_session.h"
      31             : #include "auth.h"
      32             : #include "messages.h"
      33             : #include "smbprofile.h"
      34             : #include "../libcli/security/security.h"
      35             : #include "auth/gensec/gensec.h"
      36             : #include "../libcli/smb/smb_signing.h"
      37             : #include "lib/util/string_wrappers.h"
      38             : #include "source3/lib/substitute.h"
      39             : 
      40             : /****************************************************************************
      41             :  Add the standard 'Samba' signature to the end of the session setup.
      42             : ****************************************************************************/
      43             : 
      44       12026 : static int push_signature(uint8_t **outbuf)
      45             : {
      46         133 :         char *lanman;
      47         133 :         int result, tmp;
      48         133 :         fstring native_os;
      49             : 
      50       12026 :         result = 0;
      51             : 
      52       12026 :         fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
      53             :                 SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
      54             : 
      55       12026 :         tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
      56             : 
      57       12026 :         if (tmp == -1) return -1;
      58       12026 :         result += tmp;
      59             : 
      60       12026 :         if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
      61       12026 :                 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
      62       12026 :                 SAFE_FREE(lanman);
      63             :         }
      64             :         else {
      65           0 :                 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
      66             :         }
      67             : 
      68       12026 :         if (tmp == -1) return -1;
      69       12026 :         result += tmp;
      70             : 
      71       12026 :         tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
      72             : 
      73       12026 :         if (tmp == -1) return -1;
      74       12026 :         result += tmp;
      75             : 
      76       12026 :         return result;
      77             : }
      78             : 
      79             : /****************************************************************************
      80             :  Reply to a session setup command.
      81             :  conn POINTER CAN BE NULL HERE !
      82             : ****************************************************************************/
      83             : 
      84       13280 : static void reply_sesssetup_and_X_spnego(struct smb_request *req)
      85             : {
      86         133 :         const uint8_t *p;
      87         133 :         DATA_BLOB in_blob;
      88       13280 :         DATA_BLOB out_blob = data_blob_null;
      89         133 :         size_t bufrem;
      90       13280 :         char *tmp = NULL;
      91         133 :         const char *native_os;
      92         133 :         const char *native_lanman;
      93         133 :         const char *primary_domain;
      94       13280 :         uint16_t data_blob_len = SVAL(req->vwv+7, 0);
      95       13280 :         enum remote_arch_types ra_type = get_remote_arch();
      96       13280 :         uint64_t vuid = req->vuid;
      97       13280 :         NTSTATUS status = NT_STATUS_OK;
      98       13280 :         struct smbXsrv_connection *xconn = req->xconn;
      99       13280 :         struct smbd_server_connection *sconn = req->sconn;
     100       13280 :         uint16_t action = 0;
     101       13280 :         bool is_authenticated = false;
     102       13280 :         NTTIME now = timeval_to_nttime(&req->request_time);
     103       13280 :         struct smbXsrv_session *session = NULL;
     104       13280 :         uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
     105       13280 :         uint32_t client_caps = IVAL(req->vwv+10, 0);
     106         133 :         struct smbXsrv_session_auth0 *auth;
     107             : 
     108       13280 :         DEBUG(3,("Doing spnego session setup\n"));
     109             : 
     110       13280 :         if (!xconn->smb1.sessions.done_sesssetup) {
     111       10614 :                 global_client_caps = client_caps;
     112             : 
     113       10614 :                 if (!(global_client_caps & CAP_STATUS32)) {
     114           0 :                         remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
     115             :                 }
     116             :         }
     117             : 
     118       13280 :         p = req->buf;
     119             : 
     120       13280 :         if (data_blob_len == 0) {
     121             :                 /* an invalid request */
     122           0 :                 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
     123           0 :                 return;
     124             :         }
     125             : 
     126       13280 :         bufrem = smbreq_bufrem(req, p);
     127             :         /* pull the spnego blob */
     128       13280 :         in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
     129             : 
     130             : #if 0
     131             :         file_save("negotiate.dat", in_blob.data, in_blob.length);
     132             : #endif
     133             : 
     134       13280 :         p = req->buf + in_blob.length;
     135             : 
     136       13280 :         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     137             :                                      STR_TERMINATE);
     138       13280 :         native_os = tmp ? tmp : "";
     139             : 
     140       13280 :         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     141             :                                      STR_TERMINATE);
     142       13280 :         native_lanman = tmp ? tmp : "";
     143             : 
     144       13280 :         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     145             :                                      STR_TERMINATE);
     146       13280 :         primary_domain = tmp ? tmp : "";
     147             : 
     148       13280 :         DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
     149             :                 native_os, native_lanman, primary_domain));
     150             : 
     151       13280 :         if ( ra_type == RA_WIN2K ) {
     152             :                 /* Vista sets neither the OS or lanman strings */
     153             : 
     154           0 :                 if ( !strlen(native_os) && !strlen(native_lanman) )
     155           0 :                         set_remote_arch(RA_VISTA);
     156             : 
     157             :                 /* Windows 2003 doesn't set the native lanman string,
     158             :                    but does set primary domain which is a bug I think */
     159             : 
     160           0 :                 if ( !strlen(native_lanman) ) {
     161           0 :                         ra_lanman_string( primary_domain );
     162             :                 } else {
     163           0 :                         ra_lanman_string( native_lanman );
     164             :                 }
     165       13280 :         } else if ( ra_type == RA_VISTA ) {
     166           0 :                 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
     167           0 :                         set_remote_arch(RA_OSX);
     168             :                 }
     169             :         }
     170             : 
     171       13280 :         if (vuid != 0) {
     172        6300 :                 status = smb1srv_session_lookup(xconn,
     173             :                                                 vuid, now,
     174             :                                                 &session);
     175        6300 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
     176           0 :                         reply_force_doserror(req, ERRSRV, ERRbaduid);
     177           0 :                         return;
     178             :                 }
     179        6300 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
     180           4 :                         status = NT_STATUS_OK;
     181             :                 }
     182        6300 :                 if (NT_STATUS_IS_OK(status)) {
     183          36 :                         session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     184          36 :                         status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     185          36 :                         TALLOC_FREE(session->pending_auth);
     186             :                 }
     187        6300 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     188           0 :                         reply_nterror(req, nt_status_squash(status));
     189           0 :                         return;
     190             :                 }
     191             :         }
     192             : 
     193       13280 :         if (session == NULL) {
     194             :                 /* create a new session */
     195        6980 :                 status = smbXsrv_session_create(xconn,
     196             :                                                 now, &session);
     197        6980 :                 if (!NT_STATUS_IS_OK(status)) {
     198           0 :                         reply_nterror(req, nt_status_squash(status));
     199           0 :                         return;
     200             :                 }
     201             :         }
     202             : 
     203       13280 :         status = smbXsrv_session_find_auth(session, xconn, now, &auth);
     204       13280 :         if (!NT_STATUS_IS_OK(status)) {
     205        7016 :                 status = smbXsrv_session_create_auth(session, xconn, now,
     206             :                                                      0, /* flags */
     207             :                                                      0, /* security */
     208             :                                                      &auth);
     209        7016 :                 if (!NT_STATUS_IS_OK(status)) {
     210           0 :                         reply_nterror(req, nt_status_squash(status));
     211           0 :                         return;
     212             :                 }
     213             :         }
     214             : 
     215       13280 :         if (auth->gensec == NULL) {
     216        7016 :                 status = auth_generic_prepare(session,
     217             :                                               xconn->remote_address,
     218             :                                               xconn->local_address,
     219             :                                               "SMB",
     220        6883 :                                               &auth->gensec);
     221        7016 :                 if (!NT_STATUS_IS_OK(status)) {
     222           0 :                         TALLOC_FREE(session);
     223           0 :                         reply_nterror(req, nt_status_squash(status));
     224           0 :                         return;
     225             :                 }
     226             : 
     227        7016 :                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
     228        7016 :                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
     229        7016 :                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
     230             : 
     231        7016 :                 status = gensec_start_mech_by_oid(auth->gensec,
     232             :                                                   GENSEC_OID_SPNEGO);
     233        7016 :                 if (!NT_STATUS_IS_OK(status)) {
     234           0 :                         DEBUG(0, ("Failed to start SPNEGO handler!\n"));
     235           0 :                         TALLOC_FREE(session);;
     236           0 :                         reply_nterror(req, nt_status_squash(status));
     237           0 :                         return;
     238             :                 }
     239             :         }
     240             : 
     241       13280 :         become_root();
     242       13280 :         status = gensec_update(auth->gensec,
     243             :                                talloc_tos(),
     244             :                                in_blob, &out_blob);
     245       13280 :         unbecome_root();
     246       13280 :         if (!NT_STATUS_IS_OK(status) &&
     247        7581 :             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     248        1316 :                 TALLOC_FREE(session);
     249        1316 :                 reply_nterror(req, nt_status_squash(status));
     250        1316 :                 return;
     251             :         }
     252             : 
     253       17617 :         if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
     254        5663 :                 struct auth_session_info *session_info = NULL;
     255             : 
     256        5663 :                 status = gensec_session_info(auth->gensec,
     257             :                                              session,
     258             :                                              &session_info);
     259        5663 :                 if (!NT_STATUS_IS_OK(status)) {
     260          10 :                         DEBUG(1,("Failed to generate session_info "
     261             :                                  "(user and group token) for session setup: %s\n",
     262             :                                  nt_errstr(status)));
     263          10 :                         data_blob_free(&out_blob);
     264          10 :                         TALLOC_FREE(session);
     265          10 :                         reply_nterror(req, nt_status_squash(status));
     266          10 :                         return;
     267             :                 }
     268             : 
     269        5653 :                 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
     270           4 :                         action |= SMB_SETUP_GUEST;
     271             :                 }
     272             : 
     273        5653 :                 session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
     274        5653 :                 session->global->encryption_cipher = 0;
     275        5653 :                 session->global->channels[0].signing_algo =
     276        5520 :                                 session->global->signing_algo;
     277        5653 :                 session->global->channels[0].encryption_cipher =
     278        5520 :                                 session->global->encryption_cipher;
     279             : 
     280        5653 :                 if (session_info->session_key.length > 0) {
     281        5649 :                         struct smbXsrv_session *x = session;
     282             : 
     283        5782 :                         status = smb2_signing_key_sign_create(x->global,
     284        5516 :                                                 x->global->signing_algo,
     285        5649 :                                                 &session_info->session_key,
     286             :                                                 NULL, /* no derivation */
     287        5516 :                                                 &x->global->signing_key);
     288        5649 :                         if (!NT_STATUS_IS_OK(status)) {
     289           0 :                                 data_blob_free(&out_blob);
     290           0 :                                 TALLOC_FREE(session);
     291           0 :                                 reply_nterror(req, status);
     292           0 :                                 return;
     293             :                         }
     294        5649 :                         x->global->signing_key_blob = x->global->signing_key->blob;
     295             : 
     296             :                         /*
     297             :                          * clear the session key
     298             :                          * the first tcon will add setup the application key
     299             :                          */
     300        5649 :                         data_blob_clear_free(&session_info->session_key);
     301             :                 }
     302             : 
     303        5653 :                 sconn->num_users++;
     304             : 
     305        5653 :                 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
     306        5598 :                         is_authenticated = true;
     307        5731 :                         session->homes_snum =
     308        5598 :                                 register_homes_share(session_info->unix_info->unix_name);
     309             :                 }
     310             : 
     311        5653 :                 if (smb1_srv_is_signing_negotiated(xconn) &&
     312        1054 :                     is_authenticated &&
     313        1054 :                     smb2_signing_key_valid(session->global->signing_key))
     314             :                 {
     315             :                         /*
     316             :                          * Try and turn on server signing on the first non-guest
     317             :                          * sessionsetup.
     318             :                          */
     319        1054 :                         smb1_srv_set_signing(xconn,
     320        1054 :                                 session->global->signing_key->blob,
     321             :                                 data_blob_null);
     322             :                 }
     323             : 
     324        5653 :                 set_current_user_info(session_info->unix_info->sanitized_username,
     325        5653 :                                       session_info->unix_info->unix_name,
     326        5653 :                                       session_info->info->domain_name);
     327             : 
     328        5653 :                 session->status = NT_STATUS_OK;
     329        5653 :                 session->global->auth_session_info = talloc_move(session->global,
     330             :                                                                  &session_info);
     331        5653 :                 session->global->auth_session_info_seqnum += 1;
     332        5653 :                 session->global->channels[0].auth_session_info_seqnum =
     333        5520 :                         session->global->auth_session_info_seqnum;
     334        5653 :                 session->global->auth_time = now;
     335        5653 :                 if (client_caps & CAP_DYNAMIC_REAUTH) {
     336           0 :                         session->global->expiration_time =
     337           0 :                                 gensec_expire_time(auth->gensec);
     338             :                 } else {
     339        5653 :                         session->global->expiration_time =
     340             :                                 GENSEC_EXPIRE_TIME_INFINITY;
     341             :                 }
     342             : 
     343        5653 :                 if (!session_claim(session)) {
     344           0 :                         DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
     345             :                                   (unsigned long long)session->global->session_wire_id));
     346           0 :                         data_blob_free(&out_blob);
     347           0 :                         TALLOC_FREE(session);
     348           0 :                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
     349           0 :                         return;
     350             :                 }
     351             : 
     352        5653 :                 status = smbXsrv_session_update(session);
     353        5653 :                 if (!NT_STATUS_IS_OK(status)) {
     354           0 :                         DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
     355             :                                   (unsigned long long)session->global->session_wire_id,
     356             :                                   nt_errstr(status)));
     357           0 :                         data_blob_free(&out_blob);
     358           0 :                         TALLOC_FREE(session);
     359           0 :                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
     360           0 :                         return;
     361             :                 }
     362             : 
     363        5653 :                 if (!xconn->smb1.sessions.done_sesssetup) {
     364        5633 :                         if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
     365           0 :                                 reply_force_doserror(req, ERRSRV, ERRerror);
     366           0 :                                 return;
     367             :                         }
     368        5633 :                         xconn->smb1.sessions.max_send = smb_bufsize;
     369        5633 :                         xconn->smb1.sessions.done_sesssetup = true;
     370             :                 }
     371             : 
     372             :                 /* current_user_info is changed on new vuid */
     373        5653 :                 reload_services(sconn, conn_snum_used, true);
     374        6301 :         } else if (NT_STATUS_IS_OK(status)) {
     375          36 :                 struct auth_session_info *session_info = NULL;
     376             : 
     377          36 :                 status = gensec_session_info(auth->gensec,
     378             :                                              session,
     379             :                                              &session_info);
     380          36 :                 if (!NT_STATUS_IS_OK(status)) {
     381           0 :                         DEBUG(1,("Failed to generate session_info "
     382             :                                  "(user and group token) for session setup: %s\n",
     383             :                                  nt_errstr(status)));
     384           0 :                         data_blob_free(&out_blob);
     385           0 :                         TALLOC_FREE(session);
     386           0 :                         reply_nterror(req, nt_status_squash(status));
     387           0 :                         return;
     388             :                 }
     389             : 
     390          36 :                 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
     391           0 :                         action |= SMB_SETUP_GUEST;
     392             :                 }
     393             : 
     394             :                 /*
     395             :                  * Keep the application key
     396             :                  */
     397          36 :                 data_blob_clear_free(&session_info->session_key);
     398          36 :                 session_info->session_key =
     399          36 :                         session->global->auth_session_info->session_key;
     400          36 :                 talloc_steal(session_info, session_info->session_key.data);
     401          36 :                 TALLOC_FREE(session->global->auth_session_info);
     402             : 
     403          36 :                 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
     404          22 :                         session->homes_snum =
     405          22 :                                 register_homes_share(session_info->unix_info->unix_name);
     406             :                 }
     407             : 
     408          36 :                 set_current_user_info(session_info->unix_info->sanitized_username,
     409          36 :                                       session_info->unix_info->unix_name,
     410          36 :                                       session_info->info->domain_name);
     411             : 
     412          36 :                 session->status = NT_STATUS_OK;
     413          36 :                 session->global->auth_session_info = talloc_move(session->global,
     414             :                                                                  &session_info);
     415          36 :                 session->global->auth_session_info_seqnum += 1;
     416          36 :                 session->global->channels[0].auth_session_info_seqnum =
     417          36 :                         session->global->auth_session_info_seqnum;
     418          36 :                 session->global->auth_time = now;
     419          36 :                 if (client_caps & CAP_DYNAMIC_REAUTH) {
     420           6 :                         session->global->expiration_time =
     421           6 :                                 gensec_expire_time(auth->gensec);
     422             :                 } else {
     423          30 :                         session->global->expiration_time =
     424             :                                 GENSEC_EXPIRE_TIME_INFINITY;
     425             :                 }
     426             : 
     427          36 :                 status = smbXsrv_session_update(session);
     428          36 :                 if (!NT_STATUS_IS_OK(status)) {
     429           0 :                         DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
     430             :                                   (unsigned long long)session->global->session_wire_id,
     431             :                                   nt_errstr(status)));
     432           0 :                         data_blob_free(&out_blob);
     433           0 :                         TALLOC_FREE(session);
     434           0 :                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
     435           0 :                         return;
     436             :                 }
     437             : 
     438          36 :                 conn_clear_vuid_caches(sconn, session->global->session_wire_id);
     439             : 
     440             :                 /* current_user_info is changed on new vuid */
     441          36 :                 reload_services(sconn, conn_snum_used, true);
     442             :         }
     443             : 
     444       11954 :         vuid = session->global->session_wire_id;
     445             : 
     446       11954 :         reply_smb1_outbuf(req, 4, 0);
     447             : 
     448       11954 :         SSVAL(req->outbuf, smb_uid, vuid);
     449       11954 :         SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
     450       11954 :         SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
     451       11954 :         SSVAL(req->outbuf, smb_vwv2, action);
     452       11954 :         SSVAL(req->outbuf, smb_vwv3, out_blob.length);
     453             : 
     454       11954 :         if (message_push_blob(&req->outbuf, out_blob) == -1) {
     455           0 :                 data_blob_free(&out_blob);
     456           0 :                 TALLOC_FREE(session);
     457           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     458           0 :                 return;
     459             :         }
     460       11954 :         data_blob_free(&out_blob);
     461             : 
     462       11954 :         if (push_signature(&req->outbuf) == -1) {
     463           0 :                 TALLOC_FREE(session);
     464           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     465           0 :                 return;
     466             :         }
     467             : }
     468             : 
     469             : /****************************************************************************
     470             :  On new VC == 0, shutdown *all* old connections and users.
     471             :  It seems that only NT4.x does this. At W2K and above (XP etc.).
     472             :  a new session setup with VC==0 is ignored.
     473             : ****************************************************************************/
     474             : 
     475             : struct shutdown_state {
     476             :         const char *ip;
     477             :         size_t ip_length;
     478             :         struct messaging_context *msg_ctx;
     479             : };
     480             : 
     481           0 : static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
     482             :                                 void *private_data)
     483             : {
     484           0 :         struct shutdown_state *state = (struct shutdown_state *)private_data;
     485           0 :         struct server_id self_pid = messaging_server_id(state->msg_ctx);
     486           0 :         struct server_id pid = session->channels[0].server_id;
     487           0 :         const char *addr = session->channels[0].remote_address;
     488           0 :         const char *port_colon;
     489           0 :         size_t addr_len;
     490           0 :         struct server_id_buf tmp;
     491             : 
     492           0 :         DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
     493             :                    server_id_str_buf(pid, &tmp), addr));
     494             : 
     495           0 :         if (!process_exists(pid)) {
     496           0 :                 DEBUG(10, ("process does not exist\n"));
     497           0 :                 return 0;
     498             :         }
     499             : 
     500           0 :         if (server_id_equal(&pid, &self_pid)) {
     501           0 :                 DEBUG(10, ("It's me\n"));
     502           0 :                 return 0;
     503             :         }
     504             : 
     505           0 :         port_colon = strrchr(addr, ':');
     506           0 :         if (port_colon == NULL) {
     507           0 :                 DBG_DEBUG("addr %s in contains no port\n", addr);
     508           0 :                 return 0;
     509             :         }
     510           0 :         addr_len = port_colon - addr;
     511             : 
     512           0 :         if ((addr_len != state->ip_length) ||
     513           0 :             (strncmp(addr, state->ip, state->ip_length) != 0)) {
     514           0 :                 DEBUG(10, ("%s (%zu) does not match %s (%zu)\n",
     515             :                            state->ip, state->ip_length, addr, addr_len));
     516           0 :                 return 0;
     517             :         }
     518             : 
     519           0 :         DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
     520             :                   "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
     521             :                   state->ip));
     522             : 
     523           0 :         messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
     524             :                        &data_blob_null);
     525           0 :         return 0;
     526             : }
     527             : 
     528           0 : static void setup_new_vc_session(struct smbd_server_connection *sconn)
     529             : {
     530           0 :         DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
     531             :                 "compatible we would close all old resources.\n"));
     532             : 
     533           0 :         if (lp_reset_on_zero_vc()) {
     534           0 :                 char *addr;
     535           0 :                 const char *port_colon;
     536           0 :                 struct shutdown_state state;
     537             : 
     538           0 :                 addr = tsocket_address_string(
     539             :                         sconn->remote_address, talloc_tos());
     540           0 :                 if (addr == NULL) {
     541           0 :                         return;
     542             :                 }
     543           0 :                 state.ip = addr;
     544             : 
     545           0 :                 port_colon = strrchr(addr, ':');
     546           0 :                 if (port_colon == NULL) {
     547           0 :                         return;
     548             :                 }
     549           0 :                 state.ip_length = port_colon - addr;
     550           0 :                 state.msg_ctx = sconn->msg_ctx;
     551           0 :                 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
     552           0 :                 TALLOC_FREE(addr);
     553             :         }
     554             : }
     555             : 
     556             : /****************************************************************************
     557             :  Reply to a session setup command.
     558             : ****************************************************************************/
     559             : 
     560             : struct reply_sesssetup_and_X_state {
     561             :         struct smb_request *req;
     562             :         struct auth4_context *auth_context;
     563             :         struct auth_usersupplied_info *user_info;
     564             :         const char *user;
     565             :         const char *domain;
     566             :         DATA_BLOB lm_resp;
     567             :         DATA_BLOB nt_resp;
     568             :         DATA_BLOB plaintext_password;
     569             : };
     570             : 
     571       13380 : static int reply_sesssetup_and_X_state_destructor(
     572             :                 struct reply_sesssetup_and_X_state *state)
     573             : {
     574       13380 :         data_blob_clear_free(&state->nt_resp);
     575       13380 :         data_blob_clear_free(&state->lm_resp);
     576       13380 :         data_blob_clear_free(&state->plaintext_password);
     577       13380 :         return 0;
     578             : }
     579             : 
     580       13380 : void reply_sesssetup_and_X(struct smb_request *req)
     581             : {
     582       13380 :         struct reply_sesssetup_and_X_state *state = NULL;
     583         133 :         uint64_t sess_vuid;
     584         133 :         uint16_t smb_bufsize;
     585       13380 :         char *tmp = NULL;
     586         133 :         fstring sub_user; /* Sanitised username for substitution */
     587         133 :         const char *native_os;
     588         133 :         const char *native_lanman;
     589         133 :         const char *primary_domain;
     590       13380 :         struct auth_session_info *session_info = NULL;
     591       13380 :         uint16_t smb_flag2 = req->flags2;
     592       13380 :         uint16_t action = 0;
     593       13380 :         bool is_authenticated = false;
     594       13380 :         NTTIME now = timeval_to_nttime(&req->request_time);
     595       13380 :         struct smbXsrv_session *session = NULL;
     596         133 :         NTSTATUS nt_status;
     597       13380 :         struct smbXsrv_connection *xconn = req->xconn;
     598       13380 :         struct smbd_server_connection *sconn = req->sconn;
     599       13380 :         bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
     600       13380 :         bool signing_allowed = false;
     601       13380 :         bool signing_mandatory = smb1_signing_is_mandatory(
     602             :                 xconn->smb1.signing_state);
     603             : 
     604       13380 :         START_PROFILE(SMBsesssetupX);
     605             : 
     606       13380 :         DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
     607             : 
     608       13380 :         state = talloc_zero(req, struct reply_sesssetup_and_X_state);
     609       13380 :         if (state == NULL) {
     610           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     611           0 :                 END_PROFILE(SMBsesssetupX);
     612           0 :                 return;
     613             :         }
     614       13380 :         state->req = req;
     615       13380 :         talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
     616             : 
     617       13380 :         if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
     618        1126 :                 signing_allowed = true;
     619             :         }
     620       13380 :         if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
     621         580 :                 signing_mandatory = true;
     622             :         }
     623             : 
     624             :         /*
     625             :          * We can call smb1_srv_set_signing_negotiated() each time.
     626             :          * It finds out when it needs to turn into a noop
     627             :          * itself.
     628             :          */
     629       13380 :         smb1_srv_set_signing_negotiated(xconn,
     630             :                                    signing_allowed,
     631             :                                    signing_mandatory);
     632             : 
     633             :         /* a SPNEGO session setup has 12 command words, whereas a normal
     634             :            NT1 session setup has 13. See the cifs spec. */
     635       13380 :         if (req->wct == 12 &&
     636       13280 :             (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
     637             : 
     638       13280 :                 if (!xconn->smb1.negprot.spnego) {
     639           0 :                         DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt "
     640             :                                  "at SPNEGO session setup when it was not "
     641             :                                  "negotiated.\n"));
     642           0 :                         reply_nterror(req, nt_status_squash(
     643             :                                               NT_STATUS_LOGON_FAILURE));
     644           0 :                         END_PROFILE(SMBsesssetupX);
     645           0 :                         return;
     646             :                 }
     647             : 
     648       13280 :                 if (SVAL(req->vwv+4, 0) == 0) {
     649           0 :                         setup_new_vc_session(req->sconn);
     650             :                 }
     651             : 
     652       13280 :                 reply_sesssetup_and_X_spnego(req);
     653       13280 :                 END_PROFILE(SMBsesssetupX);
     654       13280 :                 return;
     655             :         }
     656             : 
     657         100 :         smb_bufsize = SVAL(req->vwv+2, 0);
     658             : 
     659         100 :         if (xconn->protocol < PROTOCOL_NT1) {
     660          24 :                 uint16_t passlen1 = SVAL(req->vwv+7, 0);
     661             : 
     662             :                 /* Never do NT status codes with protocols before NT1 as we
     663             :                  * don't get client caps. */
     664          24 :                 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
     665             : 
     666          24 :                 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
     667           0 :                         reply_nterror(req, nt_status_squash(
     668             :                                               NT_STATUS_INVALID_PARAMETER));
     669           0 :                         END_PROFILE(SMBsesssetupX);
     670           0 :                         return;
     671             :                 }
     672             : 
     673          24 :                 if (doencrypt) {
     674          24 :                         state->lm_resp = data_blob_talloc(state,
     675             :                                                           req->buf,
     676             :                                                           passlen1);
     677             :                 } else {
     678           0 :                         state->plaintext_password = data_blob_talloc(state,
     679             :                                                                 req->buf,
     680             :                                                                 passlen1+1);
     681             :                         /* Ensure null termination */
     682           0 :                         state->plaintext_password.data[passlen1] = 0;
     683             :                 }
     684             : 
     685          24 :                 srvstr_pull_req_talloc(state, req, &tmp,
     686          24 :                                        req->buf + passlen1, STR_TERMINATE);
     687          24 :                 state->user = tmp ? tmp : "";
     688             : 
     689          24 :                 state->domain = "";
     690             : 
     691             :         } else {
     692          76 :                 uint16_t passlen1 = SVAL(req->vwv+7, 0);
     693          76 :                 uint16_t passlen2 = SVAL(req->vwv+8, 0);
     694          76 :                 enum remote_arch_types ra_type = get_remote_arch();
     695          76 :                 const uint8_t *p = req->buf;
     696          76 :                 const uint8_t *save_p = req->buf;
     697           0 :                 uint16_t byte_count;
     698             : 
     699          76 :                 if (!xconn->smb1.sessions.done_sesssetup) {
     700          76 :                         global_client_caps = IVAL(req->vwv+11, 0);
     701             : 
     702          76 :                         if (!(global_client_caps & CAP_STATUS32)) {
     703           8 :                                 remove_from_common_flags2(
     704             :                                                 FLAGS2_32_BIT_ERROR_CODES);
     705             :                         }
     706             : 
     707             :                         /* client_caps is used as final determination if
     708             :                          * client is NT or Win95. This is needed to return
     709             :                          * the correct error codes in some circumstances.
     710             :                         */
     711             : 
     712          76 :                         if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
     713             :                                         ra_type == RA_WIN95) {
     714           0 :                                 if(!(global_client_caps & (CAP_NT_SMBS|
     715             :                                                         CAP_STATUS32))) {
     716           0 :                                         set_remote_arch( RA_WIN95);
     717             :                                 }
     718             :                         }
     719             :                 }
     720             : 
     721          76 :                 if (!doencrypt) {
     722             :                         /* both Win95 and WinNT stuff up the password
     723             :                          * lengths for non-encrypting systems. Uggh.
     724             : 
     725             :                            if passlen1==24 its a win95 system, and its setting
     726             :                            the password length incorrectly. Luckily it still
     727             :                            works with the default code because Win95 will null
     728             :                            terminate the password anyway
     729             : 
     730             :                            if passlen1>0 and passlen2>0 then maybe its a NT box
     731             :                            and its setting passlen2 to some random value which
     732             :                            really stuffs things up. we need to fix that one.  */
     733             : 
     734           0 :                         if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
     735           0 :                                         passlen2 != 1) {
     736           0 :                                 passlen2 = 0;
     737             :                         }
     738             :                 }
     739             : 
     740             :                 /* check for nasty tricks */
     741          76 :                 if (passlen1 > MAX_PASS_LEN
     742          76 :                     || passlen1 > smbreq_bufrem(req, p)) {
     743           0 :                         reply_nterror(req, nt_status_squash(
     744             :                                               NT_STATUS_INVALID_PARAMETER));
     745           0 :                         END_PROFILE(SMBsesssetupX);
     746           0 :                         return;
     747             :                 }
     748             : 
     749          76 :                 if (passlen2 > MAX_PASS_LEN
     750          76 :                     || passlen2 > smbreq_bufrem(req, p+passlen1)) {
     751           0 :                         reply_nterror(req, nt_status_squash(
     752             :                                               NT_STATUS_INVALID_PARAMETER));
     753           0 :                         END_PROFILE(SMBsesssetupX);
     754           0 :                         return;
     755             :                 }
     756             : 
     757             :                 /* Save the lanman2 password and the NT md4 password. */
     758             : 
     759          76 :                 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
     760           2 :                         doencrypt = False;
     761             :                 }
     762             : 
     763          76 :                 if (doencrypt) {
     764          74 :                         state->lm_resp = data_blob_talloc(state, p, passlen1);
     765          74 :                         state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
     766             :                 } else {
     767           2 :                         char *pass = NULL;
     768           2 :                         bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
     769             : 
     770           2 :                         if (unic && (passlen2 == 0) && passlen1) {
     771             :                                 /* Only a ascii plaintext password was sent. */
     772           0 :                                 (void)srvstr_pull_talloc(state,
     773             :                                                         req->inbuf,
     774             :                                                         req->flags2,
     775             :                                                         &pass,
     776             :                                                         req->buf,
     777             :                                                         passlen1,
     778             :                                                         STR_TERMINATE|STR_ASCII);
     779             :                         } else {
     780           2 :                                 (void)srvstr_pull_talloc(state,
     781             :                                                         req->inbuf,
     782             :                                                         req->flags2,
     783             :                                                         &pass,
     784             :                                                         req->buf,
     785             :                                                         unic ? passlen2 : passlen1,
     786             :                                                         STR_TERMINATE);
     787             :                         }
     788           2 :                         if (!pass) {
     789           0 :                                 reply_nterror(req, nt_status_squash(
     790             :                                               NT_STATUS_INVALID_PARAMETER));
     791           0 :                                 END_PROFILE(SMBsesssetupX);
     792           0 :                                 return;
     793             :                         }
     794           2 :                         state->plaintext_password = data_blob_talloc(state,
     795             :                                                                 pass,
     796             :                                                                 strlen(pass)+1);
     797             :                 }
     798             : 
     799          76 :                 p += passlen1 + passlen2;
     800             : 
     801          76 :                 p += srvstr_pull_req_talloc(state, req, &tmp, p,
     802             :                                             STR_TERMINATE);
     803          76 :                 state->user = tmp ? tmp : "";
     804             : 
     805          76 :                 p += srvstr_pull_req_talloc(state, req, &tmp, p,
     806             :                                             STR_TERMINATE);
     807          76 :                 state->domain = tmp ? tmp : "";
     808             : 
     809          76 :                 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     810             :                                             STR_TERMINATE);
     811          76 :                 native_os = tmp ? tmp : "";
     812             : 
     813          76 :                 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     814             :                                             STR_TERMINATE);
     815          76 :                 native_lanman = tmp ? tmp : "";
     816             : 
     817             :                 /* not documented or decoded by Ethereal but there is one more
     818             :                  * string in the extra bytes which is the same as the
     819             :                  * PrimaryDomain when using extended security.  Windows NT 4
     820             :                  * and 2003 use this string to store the native lanman string.
     821             :                  * Windows 9x does not include a string here at all so we have
     822             :                  * to check if we have any extra bytes left */
     823             : 
     824          76 :                 byte_count = SVAL(req->vwv+13, 0);
     825          76 :                 if ( PTR_DIFF(p, save_p) < byte_count) {
     826           0 :                         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
     827             :                                                     STR_TERMINATE);
     828           0 :                         primary_domain = tmp ? tmp : "";
     829             :                 } else {
     830          76 :                         primary_domain = talloc_strdup(talloc_tos(), "null");
     831             :                 }
     832             : 
     833          76 :                 DEBUG(3,("Domain=[%s]  NativeOS=[%s] NativeLanMan=[%s] "
     834             :                         "PrimaryDomain=[%s]\n",
     835             :                         state->domain, native_os, native_lanman, primary_domain));
     836             : 
     837          76 :                 if ( ra_type == RA_WIN2K ) {
     838           0 :                         if ( strlen(native_lanman) == 0 )
     839           0 :                                 ra_lanman_string( primary_domain );
     840             :                         else
     841           0 :                                 ra_lanman_string( native_lanman );
     842             :                 }
     843             : 
     844             :         }
     845             : 
     846         100 :         if (SVAL(req->vwv+4, 0) == 0) {
     847           0 :                 setup_new_vc_session(req->sconn);
     848             :         }
     849             : 
     850         100 :         DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
     851             :                  state->domain, state->user, get_remote_machine_name()));
     852             : 
     853         100 :         if (*state->user) {
     854          63 :                 if (xconn->smb1.negprot.spnego) {
     855             : 
     856             :                         /* This has to be here, because this is a perfectly
     857             :                          * valid behaviour for guest logons :-( */
     858             : 
     859           0 :                         DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt "
     860             :                                 "at 'normal' session setup after "
     861             :                                 "negotiating spnego.\n"));
     862           0 :                         reply_nterror(req, nt_status_squash(
     863             :                                               NT_STATUS_LOGON_FAILURE));
     864           0 :                         END_PROFILE(SMBsesssetupX);
     865           0 :                         return;
     866             :                 }
     867          63 :                 fstrcpy(sub_user, state->user);
     868             :         } else {
     869          37 :                 fstrcpy(sub_user, "");
     870             :         }
     871             : 
     872         100 :         if (!*state->user) {
     873          37 :                 DEBUG(3,("Got anonymous request\n"));
     874             : 
     875          37 :                 nt_status = make_auth4_context(state, &state->auth_context);
     876          37 :                 if (NT_STATUS_IS_OK(nt_status)) {
     877           0 :                         uint8_t chal[8];
     878             : 
     879          37 :                         state->auth_context->get_ntlm_challenge(
     880             :                                         state->auth_context, chal);
     881             : 
     882          37 :                         if (!make_user_info_guest(state,
     883             :                                                   sconn->remote_address,
     884             :                                                   sconn->local_address,
     885             :                                                   "SMB", &state->user_info)) {
     886           0 :                                 nt_status =  NT_STATUS_NO_MEMORY;
     887             :                         }
     888             : 
     889          37 :                         if (NT_STATUS_IS_OK(nt_status)) {
     890          37 :                                 state->user_info->auth_description = "guest";
     891             :                         }
     892             :                 }
     893          63 :         } else if (doencrypt) {
     894          63 :                 state->auth_context = xconn->smb1.negprot.auth_context;
     895          63 :                 if (state->auth_context == NULL) {
     896           0 :                         DEBUG(0, ("reply_sesssetup_and_X:  Attempted encrypted "
     897             :                                 "session setup without negprot denied!\n"));
     898           0 :                         reply_nterror(req, nt_status_squash(
     899             :                                               NT_STATUS_LOGON_FAILURE));
     900           0 :                         END_PROFILE(SMBsesssetupX);
     901           0 :                         return;
     902             :                 }
     903          63 :                 nt_status = make_user_info_for_reply_enc(state,
     904             :                                                          &state->user_info,
     905             :                                                          state->user,
     906             :                                                          state->domain,
     907             :                                                          sconn->remote_address,
     908             :                                                          sconn->local_address,
     909             :                                                          "SMB",
     910             :                                                          state->lm_resp,
     911             :                                                          state->nt_resp);
     912             : 
     913          63 :                 if (NT_STATUS_IS_OK(nt_status)) {
     914          61 :                         state->user_info->auth_description = "bare-NTLM";
     915             :                 }
     916             :         } else {
     917           0 :                 nt_status = make_auth4_context(state, &state->auth_context);
     918           0 :                 if (NT_STATUS_IS_OK(nt_status)) {
     919           0 :                         uint8_t chal[8];
     920             : 
     921           0 :                         state->auth_context->get_ntlm_challenge(
     922             :                                         state->auth_context, chal);
     923             : 
     924           0 :                         if (!make_user_info_for_reply(state,
     925             :                                                       &state->user_info,
     926             :                                                       state->user,
     927             :                                                       state->domain,
     928             :                                                       sconn->remote_address,
     929             :                                                       sconn->local_address,
     930             :                                                       "SMB",
     931             :                                                       chal,
     932             :                                                       state->plaintext_password)) {
     933           0 :                                 nt_status = NT_STATUS_NO_MEMORY;
     934             :                         }
     935             : 
     936           0 :                         if (NT_STATUS_IS_OK(nt_status)) {
     937           0 :                                 state->user_info->auth_description = "plaintext";
     938             :                         }
     939             :                 }
     940             :         }
     941             : 
     942         100 :         if (!NT_STATUS_IS_OK(nt_status)) {
     943           2 :                 reply_nterror(req, nt_status_squash(nt_status));
     944           2 :                 END_PROFILE(SMBsesssetupX);
     945           2 :                 return;
     946             :         }
     947             : 
     948          98 :         nt_status = auth_check_password_session_info(state->auth_context,
     949             :                                                      req, state->user_info,
     950             :                                                      &session_info);
     951          98 :         TALLOC_FREE(state->user_info);
     952          98 :         if (!NT_STATUS_IS_OK(nt_status)) {
     953           2 :                 reply_nterror(req, nt_status_squash(nt_status));
     954           2 :                 END_PROFILE(SMBsesssetupX);
     955           2 :                 return;
     956             :         }
     957             : 
     958             :         /* it's ok - setup a reply */
     959          96 :         reply_smb1_outbuf(req, 3, 0);
     960          96 :         SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
     961          96 :         SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
     962             : 
     963          96 :         if (xconn->protocol >= PROTOCOL_NT1) {
     964          72 :                 push_signature(&req->outbuf);
     965             :                 /* perhaps grab OS version here?? */
     966             :         }
     967             : 
     968          96 :         if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
     969           1 :                 action |= SMB_SETUP_GUEST;
     970             :         }
     971             : 
     972             :         /* register the name and uid as being validated, so further connections
     973             :            to a uid can get through without a password, on the same VC */
     974             : 
     975          96 :         nt_status = smbXsrv_session_create(xconn,
     976             :                                            now, &session);
     977          96 :         if (!NT_STATUS_IS_OK(nt_status)) {
     978           0 :                 reply_nterror(req, nt_status_squash(nt_status));
     979           0 :                 END_PROFILE(SMBsesssetupX);
     980           0 :                 return;
     981             :         }
     982             : 
     983          96 :         session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
     984          96 :         session->global->encryption_cipher = 0;
     985          96 :         session->global->channels[0].signing_algo =
     986          96 :                         session->global->signing_algo;
     987          96 :         session->global->channels[0].encryption_cipher =
     988          96 :                         session->global->encryption_cipher;
     989             : 
     990          96 :         if (session_info->session_key.length > 0) {
     991          47 :                 struct smbXsrv_session *x = session;
     992           0 :                 uint8_t session_key[16];
     993           0 :                 NTSTATUS status;
     994             : 
     995          47 :                 status = smb2_signing_key_sign_create(x->global,
     996          47 :                                         x->global->signing_algo,
     997          47 :                                         &session_info->session_key,
     998             :                                         NULL, /* no derivation */
     999          47 :                                         &x->global->signing_key);
    1000          47 :                 if (!NT_STATUS_IS_OK(status)) {
    1001           0 :                         TALLOC_FREE(session);
    1002           0 :                         reply_nterror(req, status);
    1003           0 :                         END_PROFILE(SMBsesssetupX);
    1004           0 :                         return;
    1005             :                 }
    1006          47 :                 x->global->signing_key_blob = x->global->signing_key->blob;
    1007             : 
    1008             :                 /*
    1009             :                  * The application key is truncated/padded to 16 bytes
    1010             :                  */
    1011          47 :                 ZERO_STRUCT(session_key);
    1012          47 :                 memcpy(session_key, session->global->signing_key_blob.data,
    1013          47 :                        MIN(session->global->signing_key_blob.length,
    1014             :                            sizeof(session_key)));
    1015          47 :                 session->global->application_key_blob =
    1016          47 :                         data_blob_talloc(session->global,
    1017             :                                          session_key,
    1018             :                                          sizeof(session_key));
    1019          47 :                 ZERO_STRUCT(session_key);
    1020          47 :                 if (session->global->application_key_blob.data == NULL) {
    1021           0 :                         TALLOC_FREE(session);
    1022           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1023           0 :                         END_PROFILE(SMBsesssetupX);
    1024           0 :                         return;
    1025             :                 }
    1026          47 :                 talloc_keep_secret(session->global->application_key_blob.data);
    1027             : 
    1028             :                 /*
    1029             :                  * Place the application key into the session_info
    1030             :                  */
    1031          47 :                 data_blob_clear_free(&session_info->session_key);
    1032          47 :                 session_info->session_key = data_blob_dup_talloc(session_info,
    1033             :                                                 session->global->application_key_blob);
    1034          47 :                 if (session_info->session_key.data == NULL) {
    1035           0 :                         TALLOC_FREE(session);
    1036           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1037           0 :                         END_PROFILE(SMBsesssetupX);
    1038           0 :                         return;
    1039             :                 }
    1040          47 :                 talloc_keep_secret(session_info->session_key.data);
    1041             :         }
    1042             : 
    1043          96 :         sconn->num_users++;
    1044             : 
    1045          96 :         if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
    1046          58 :                 is_authenticated = true;
    1047          58 :                 session->homes_snum =
    1048          58 :                         register_homes_share(session_info->unix_info->unix_name);
    1049             :         }
    1050             : 
    1051          96 :         if (smb1_srv_is_signing_negotiated(xconn) &&
    1052           9 :             is_authenticated &&
    1053           9 :             smb2_signing_key_valid(session->global->signing_key))
    1054             :         {
    1055             :                 /*
    1056             :                  * Try and turn on server signing on the first non-guest
    1057             :                  * sessionsetup.
    1058             :                  */
    1059           9 :                 smb1_srv_set_signing(xconn,
    1060           9 :                         session->global->signing_key->blob,
    1061           9 :                         state->nt_resp.data ? state->nt_resp : state->lm_resp);
    1062             :         }
    1063             : 
    1064          96 :         set_current_user_info(session_info->unix_info->sanitized_username,
    1065          96 :                               session_info->unix_info->unix_name,
    1066          96 :                               session_info->info->domain_name);
    1067             : 
    1068          96 :         session->status = NT_STATUS_OK;
    1069          96 :         session->global->auth_session_info = talloc_move(session->global,
    1070             :                                                          &session_info);
    1071          96 :         session->global->auth_session_info_seqnum += 1;
    1072          96 :         session->global->channels[0].auth_session_info_seqnum =
    1073          96 :                 session->global->auth_session_info_seqnum;
    1074          96 :         session->global->auth_time = now;
    1075          96 :         session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
    1076             : 
    1077          96 :         nt_status = smbXsrv_session_update(session);
    1078          96 :         if (!NT_STATUS_IS_OK(nt_status)) {
    1079           0 :                 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
    1080             :                           (unsigned long long)session->global->session_wire_id,
    1081             :                           nt_errstr(nt_status)));
    1082           0 :                 TALLOC_FREE(session);
    1083           0 :                 reply_nterror(req, nt_status_squash(nt_status));
    1084           0 :                 END_PROFILE(SMBsesssetupX);
    1085           0 :                 return;
    1086             :         }
    1087             : 
    1088          96 :         if (!session_claim(session)) {
    1089           0 :                 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
    1090             :                           (unsigned long long)session->global->session_wire_id));
    1091           0 :                 TALLOC_FREE(session);
    1092           0 :                 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
    1093           0 :                 END_PROFILE(SMBsesssetupX);
    1094           0 :                 return;
    1095             :         }
    1096             : 
    1097             :         /* current_user_info is changed on new vuid */
    1098          96 :         reload_services(sconn, conn_snum_used, true);
    1099             : 
    1100          96 :         sess_vuid = session->global->session_wire_id;
    1101             : 
    1102          96 :         SSVAL(req->outbuf,smb_vwv2,action);
    1103          96 :         SSVAL(req->outbuf,smb_uid,sess_vuid);
    1104          96 :         SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
    1105          96 :         req->vuid = sess_vuid;
    1106             : 
    1107          96 :         if (!xconn->smb1.sessions.done_sesssetup) {
    1108          96 :                 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
    1109           0 :                         reply_force_doserror(req, ERRSRV, ERRerror);
    1110           0 :                         END_PROFILE(SMBsesssetupX);
    1111           0 :                         return;
    1112             :                 }
    1113          96 :                 xconn->smb1.sessions.max_send = smb_bufsize;
    1114          96 :                 xconn->smb1.sessions.done_sesssetup = true;
    1115             :         }
    1116             : 
    1117          96 :         TALLOC_FREE(state);
    1118          96 :         END_PROFILE(SMBsesssetupX);
    1119             : }

Generated by: LCOV version 1.14