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

Generated by: LCOV version 1.14