LCOV - code coverage report
Current view: top level - source3/smbd - sesssetup.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 342 542 63.1 %
Date: 2021-08-25 13:27:56 Functions: 4 7 57.1 %

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

Generated by: LCOV version 1.13