LCOV - code coverage report
Current view: top level - libcli/smb - smb1cli_session.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 217 357 60.8 %
Date: 2024-06-13 04:01:37 Functions: 6 9 66.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    client connect/disconnect routines
       4             :    Copyright (C) Andrew Tridgell 1994-1998
       5             :    Copyright (C) Andrew Bartlett 2001-2003
       6             :    Copyright (C) Volker Lendecke 2011
       7             :    Copyright (C) Jeremy Allison 2011
       8             :    Copyright (C) Stefan Metzmacher 2016
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "system/network.h"
      26             : #include "../lib/util/tevent_ntstatus.h"
      27             : #include "../libcli/smb/smb_common.h"
      28             : #include "../libcli/smb/smbXcli_base.h"
      29             : 
      30             : 
      31             : struct smb1cli_session_setup_lm21_state {
      32             :         struct smbXcli_session *session;
      33             :         uint16_t vwv[10];
      34             :         struct iovec *recv_iov;
      35             :         uint16_t out_session_id;
      36             :         uint16_t out_action;
      37             :         char *out_native_os;
      38             :         char *out_native_lm;
      39             : };
      40             : 
      41             : static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq);
      42             : 
      43           0 : struct tevent_req *smb1cli_session_setup_lm21_send(TALLOC_CTX *mem_ctx,
      44             :                                 struct tevent_context *ev,
      45             :                                 struct smbXcli_conn *conn,
      46             :                                 uint32_t timeout_msec,
      47             :                                 uint32_t pid,
      48             :                                 struct smbXcli_session *session,
      49             :                                 uint16_t in_buf_size,
      50             :                                 uint16_t in_mpx_max,
      51             :                                 uint16_t in_vc_num,
      52             :                                 uint32_t in_sess_key,
      53             :                                 const char *in_user,
      54             :                                 const char *in_domain,
      55             :                                 const DATA_BLOB in_apassword,
      56             :                                 const char *in_native_os,
      57             :                                 const char *in_native_lm)
      58             : {
      59           0 :         struct tevent_req *req = NULL;
      60           0 :         struct smb1cli_session_setup_lm21_state *state = NULL;
      61           0 :         struct tevent_req *subreq = NULL;
      62           0 :         uint16_t *vwv = NULL;
      63           0 :         uint8_t *bytes = NULL;
      64             : 
      65           0 :         req = tevent_req_create(mem_ctx, &state,
      66             :                                 struct smb1cli_session_setup_lm21_state);
      67           0 :         if (req == NULL) {
      68           0 :                 return NULL;
      69             :         }
      70           0 :         state->session = session;
      71           0 :         vwv = state->vwv;
      72             : 
      73           0 :         if (in_user == NULL) {
      74           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
      75           0 :                 return tevent_req_post(req, ev);
      76             :         }
      77             : 
      78           0 :         if (in_domain == NULL) {
      79           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
      80           0 :                 return tevent_req_post(req, ev);
      81             :         }
      82             : 
      83           0 :         if (in_apassword.length > UINT16_MAX) {
      84           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
      85           0 :                 return tevent_req_post(req, ev);
      86             :         }
      87             : 
      88           0 :         if (in_native_os == NULL && in_native_lm != NULL) {
      89           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
      90           0 :                 return tevent_req_post(req, ev);
      91             :         }
      92             : 
      93           0 :         SCVAL(vwv+0, 0, 0xff);
      94           0 :         SCVAL(vwv+0, 1, 0);
      95           0 :         SSVAL(vwv+1, 0, 0);
      96           0 :         SSVAL(vwv+2, 0, in_buf_size);
      97           0 :         SSVAL(vwv+3, 0, in_mpx_max);
      98           0 :         SSVAL(vwv+4, 0, in_vc_num);
      99           0 :         SIVAL(vwv+5, 0, in_sess_key);
     100           0 :         SSVAL(vwv+7, 0, in_apassword.length);
     101           0 :         SSVAL(vwv+8, 0, 0); /* reserved */
     102           0 :         SSVAL(vwv+9, 0, 0); /* reserved */
     103             : 
     104           0 :         bytes = talloc_array(state, uint8_t,
     105             :                              in_apassword.length);
     106           0 :         if (tevent_req_nomem(bytes, req)) {
     107           0 :                 return tevent_req_post(req, ev);
     108             :         }
     109           0 :         if (in_apassword.length != 0) {
     110           0 :                 memcpy(bytes,
     111           0 :                        in_apassword.data,
     112           0 :                        in_apassword.length);
     113             :         }
     114             : 
     115           0 :         bytes = smb_bytes_push_str(bytes,
     116           0 :                                    smbXcli_conn_use_unicode(conn),
     117           0 :                                    in_user, strlen(in_user)+1,
     118             :                                    NULL);
     119           0 :         bytes = smb_bytes_push_str(bytes,
     120           0 :                                    smbXcli_conn_use_unicode(conn),
     121           0 :                                    in_domain, strlen(in_domain)+1,
     122             :                                    NULL);
     123           0 :         if (in_native_os != NULL) {
     124           0 :                 bytes = smb_bytes_push_str(bytes,
     125           0 :                                            smbXcli_conn_use_unicode(conn),
     126           0 :                                            in_native_os, strlen(in_native_os)+1,
     127             :                                            NULL);
     128             :         }
     129           0 :         if (in_native_lm != NULL) {
     130           0 :                 bytes = smb_bytes_push_str(bytes,
     131           0 :                                            smbXcli_conn_use_unicode(conn),
     132           0 :                                            in_native_lm, strlen(in_native_lm)+1,
     133             :                                            NULL);
     134             :         }
     135           0 :         if (tevent_req_nomem(bytes, req)) {
     136           0 :                 return tevent_req_post(req, ev);
     137             :         }
     138             : 
     139           0 :         subreq = smb1cli_req_send(state, ev, conn,
     140             :                                   SMBsesssetupX,
     141             :                                   0, /*  additional_flags */
     142             :                                   0, /*  clear_flags */
     143             :                                   0, /*  additional_flags2 */
     144             :                                   0, /*  clear_flags2 */
     145             :                                   timeout_msec,
     146             :                                   pid,
     147             :                                   NULL, /* tcon */
     148             :                                   session,
     149             :                                   10, /* wct */
     150             :                                   vwv,
     151           0 :                                   talloc_get_size(bytes),
     152             :                                   bytes);
     153           0 :         if (tevent_req_nomem(subreq, req)) {
     154           0 :                 return tevent_req_post(req, ev);
     155             :         }
     156           0 :         tevent_req_set_callback(subreq, smb1cli_session_setup_lm21_done, req);
     157             : 
     158           0 :         return req;
     159             : }
     160             : 
     161           0 : static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq)
     162             : {
     163           0 :         struct tevent_req *req =
     164           0 :                 tevent_req_callback_data(subreq,
     165             :                 struct tevent_req);
     166           0 :         struct smb1cli_session_setup_lm21_state *state =
     167           0 :                 tevent_req_data(req,
     168             :                 struct smb1cli_session_setup_lm21_state);
     169             :         NTSTATUS status;
     170           0 :         uint8_t *inhdr = NULL;
     171             :         uint8_t wct;
     172           0 :         uint16_t *vwv = NULL;
     173             :         uint32_t num_bytes;
     174           0 :         uint8_t *bytes = NULL;
     175           0 :         const uint8_t *p = NULL;
     176           0 :         size_t ret = 0;
     177             :         uint16_t flags2;
     178           0 :         bool use_unicode = false;
     179           0 :         struct smb1cli_req_expected_response expected[] = {
     180             :         {
     181             :                 .status = NT_STATUS_OK,
     182             :                 .wct    = 3,
     183             :         },
     184             :         };
     185             : 
     186           0 :         status = smb1cli_req_recv(subreq, state,
     187             :                                   &state->recv_iov,
     188             :                                   &inhdr,
     189             :                                   &wct,
     190             :                                   &vwv,
     191             :                                   NULL, /* pvwv_offset */
     192             :                                   &num_bytes,
     193             :                                   &bytes,
     194             :                                   NULL, /* pbytes_offset */
     195             :                                   NULL, /* pinbuf */
     196             :                                   expected, ARRAY_SIZE(expected));
     197           0 :         TALLOC_FREE(subreq);
     198           0 :         if (tevent_req_nterror(req, status)) {
     199           0 :                 return;
     200             :         }
     201             : 
     202           0 :         flags2 = SVAL(inhdr, HDR_FLG2);
     203           0 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     204           0 :                 use_unicode = true;
     205             :         }
     206             : 
     207           0 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     208           0 :         state->out_action = SVAL(vwv+2, 0);
     209             : 
     210           0 :         p = bytes;
     211             : 
     212           0 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     213             :                                     use_unicode, bytes, num_bytes,
     214             :                                     p, &ret);
     215           0 :         if (tevent_req_nterror(req, status)) {
     216           0 :                 return;
     217             :         }
     218           0 :         p += ret;
     219             : 
     220           0 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     221             :                                     use_unicode, bytes, num_bytes,
     222             :                                     p, &ret);
     223           0 :         if (tevent_req_nterror(req, status)) {
     224           0 :                 return;
     225             :         }
     226             : 
     227           0 :         smb1cli_session_set_id(state->session, state->out_session_id);
     228           0 :         smb1cli_session_set_action(state->session, state->out_action);
     229             : 
     230           0 :         tevent_req_done(req);
     231             : }
     232             : 
     233           0 : NTSTATUS smb1cli_session_setup_lm21_recv(struct tevent_req *req,
     234             :                                          TALLOC_CTX *mem_ctx,
     235             :                                          char **out_native_os,
     236             :                                          char **out_native_lm)
     237             : {
     238           0 :         struct smb1cli_session_setup_lm21_state *state =
     239           0 :                 tevent_req_data(req,
     240             :                 struct smb1cli_session_setup_lm21_state);
     241             :         NTSTATUS status;
     242             : 
     243           0 :         if (tevent_req_is_nterror(req, &status)) {
     244           0 :                 tevent_req_received(req);
     245           0 :                 return status;
     246             :         }
     247             : 
     248           0 :         if (out_native_os != NULL) {
     249           0 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     250             :         }
     251             : 
     252           0 :         if (out_native_lm != NULL) {
     253           0 :                 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
     254             :         }
     255             : 
     256           0 :         tevent_req_received(req);
     257           0 :         return NT_STATUS_OK;
     258             : }
     259             : 
     260             : struct smb1cli_session_setup_nt1_state {
     261             :         struct smbXcli_session *session;
     262             :         uint16_t vwv[13];
     263             :         struct iovec *recv_iov;
     264             :         uint8_t *inbuf;
     265             :         uint16_t out_session_id;
     266             :         uint16_t out_action;
     267             :         char *out_native_os;
     268             :         char *out_native_lm;
     269             :         char *out_primary_domain;
     270             : };
     271             : 
     272             : static void smb1cli_session_setup_nt1_done(struct tevent_req *subreq);
     273             : 
     274           9 : struct tevent_req *smb1cli_session_setup_nt1_send(TALLOC_CTX *mem_ctx,
     275             :                                 struct tevent_context *ev,
     276             :                                 struct smbXcli_conn *conn,
     277             :                                 uint32_t timeout_msec,
     278             :                                 uint32_t pid,
     279             :                                 struct smbXcli_session *session,
     280             :                                 uint16_t in_buf_size,
     281             :                                 uint16_t in_mpx_max,
     282             :                                 uint16_t in_vc_num,
     283             :                                 uint32_t in_sess_key,
     284             :                                 const char *in_user,
     285             :                                 const char *in_domain,
     286             :                                 const DATA_BLOB in_apassword,
     287             :                                 const DATA_BLOB in_upassword,
     288             :                                 uint32_t in_capabilities,
     289             :                                 const char *in_native_os,
     290             :                                 const char *in_native_lm)
     291             : {
     292           9 :         struct tevent_req *req = NULL;
     293           9 :         struct smb1cli_session_setup_nt1_state *state = NULL;
     294           9 :         struct tevent_req *subreq = NULL;
     295           9 :         uint16_t *vwv = NULL;
     296           9 :         uint8_t *bytes = NULL;
     297           9 :         size_t align_upassword = 0;
     298           9 :         size_t apassword_ofs = 0;
     299           9 :         size_t upassword_ofs = 0;
     300             : 
     301           9 :         req = tevent_req_create(mem_ctx, &state,
     302             :                                 struct smb1cli_session_setup_nt1_state);
     303           9 :         if (req == NULL) {
     304           0 :                 return NULL;
     305             :         }
     306           9 :         state->session = session;
     307           9 :         vwv = state->vwv;
     308             : 
     309           9 :         if (in_user == NULL) {
     310           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     311           0 :                 return tevent_req_post(req, ev);
     312             :         }
     313             : 
     314           9 :         if (in_domain == NULL) {
     315           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     316           0 :                 return tevent_req_post(req, ev);
     317             :         }
     318             : 
     319           9 :         if (in_apassword.length > UINT16_MAX) {
     320           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     321           0 :                 return tevent_req_post(req, ev);
     322             :         }
     323             : 
     324           9 :         if (in_upassword.length > UINT16_MAX) {
     325           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     326           0 :                 return tevent_req_post(req, ev);
     327             :         }
     328             : 
     329           9 :         if (in_native_os == NULL && in_native_lm != NULL) {
     330           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     331           0 :                 return tevent_req_post(req, ev);
     332             :         }
     333             : 
     334           9 :         SCVAL(vwv+0,  0, 0xff);
     335           9 :         SCVAL(vwv+0,  1, 0);
     336           9 :         SSVAL(vwv+1,  0, 0);
     337           9 :         SSVAL(vwv+2,  0, in_buf_size);
     338           9 :         SSVAL(vwv+3,  0, in_mpx_max);
     339           9 :         SSVAL(vwv+4,  0, in_vc_num);
     340           9 :         SIVAL(vwv+5,  0, in_sess_key);
     341           9 :         SSVAL(vwv+7,  0, in_apassword.length);
     342           9 :         SSVAL(vwv+8,  0, in_upassword.length);
     343           9 :         SSVAL(vwv+9,  0, 0); /* reserved */
     344           9 :         SSVAL(vwv+10, 0, 0); /* reserved */
     345           9 :         SIVAL(vwv+11, 0, in_capabilities);
     346             : 
     347           9 :         if (in_apassword.length == 0 && in_upassword.length > 0) {
     348             :                 /*
     349             :                  * This is plaintext auth with a unicode password,
     350             :                  * we need to align the buffer.
     351             :                  *
     352             :                  * This is what smbclient and Windows XP send as
     353             :                  * a client. And what smbd expects.
     354             :                  *
     355             :                  * But it doesn't follow [MS-CIFS] (v20160714)
     356             :                  * 2.2.4.53.1 SMB_COM_SESSION_SETUP_ANDX Request:
     357             :                  *
     358             :                  * ...
     359             :                  *
     360             :                  *  If SMB_FLAGS2_UNICODE is set (1), the value of OEMPasswordLen
     361             :                  *  MUST be 0x0000 and the password MUST be encoded using
     362             :                  *  UTF-16LE Unicode. Padding MUST NOT be added to
     363             :                  *  align this plaintext Unicode string to a word boundary.
     364             :                  *
     365             :                  * ...
     366             :                  */
     367           0 :                 uint16_t security_mode = smb1cli_conn_server_security_mode(conn);
     368             : 
     369           0 :                 if (!(security_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) {
     370           0 :                         align_upassword = 1;
     371             :                 }
     372             :         }
     373             : 
     374           9 :         bytes = talloc_array(state, uint8_t,
     375             :                              in_apassword.length +
     376             :                              align_upassword +
     377             :                              in_upassword.length);
     378           9 :         if (tevent_req_nomem(bytes, req)) {
     379           0 :                 return tevent_req_post(req, ev);
     380             :         }
     381           9 :         if (in_apassword.length != 0) {
     382          11 :                 memcpy(bytes + apassword_ofs,
     383           6 :                        in_apassword.data,
     384           1 :                        in_apassword.length);
     385           6 :                 upassword_ofs += in_apassword.length;
     386             :         }
     387           9 :         if (align_upassword != 0) {
     388           0 :                 memset(bytes + upassword_ofs, 0, align_upassword);
     389           0 :                 upassword_ofs += align_upassword;
     390             :         }
     391           9 :         if (in_upassword.length != 0) {
     392          11 :                 memcpy(bytes + upassword_ofs,
     393           6 :                        in_upassword.data,
     394           1 :                        in_upassword.length);
     395             :         }
     396             : 
     397          16 :         bytes = smb_bytes_push_str(bytes,
     398           9 :                                    smbXcli_conn_use_unicode(conn),
     399           9 :                                    in_user, strlen(in_user)+1,
     400             :                                    NULL);
     401          16 :         bytes = smb_bytes_push_str(bytes,
     402           9 :                                    smbXcli_conn_use_unicode(conn),
     403           9 :                                    in_domain, strlen(in_domain)+1,
     404             :                                    NULL);
     405           9 :         if (in_native_os != NULL) {
     406          16 :                 bytes = smb_bytes_push_str(bytes,
     407           9 :                                            smbXcli_conn_use_unicode(conn),
     408           9 :                                            in_native_os, strlen(in_native_os)+1,
     409             :                                            NULL);
     410             :         }
     411           9 :         if (in_native_lm != NULL) {
     412          16 :                 bytes = smb_bytes_push_str(bytes,
     413           9 :                                            smbXcli_conn_use_unicode(conn),
     414           9 :                                            in_native_lm, strlen(in_native_lm)+1,
     415             :                                            NULL);
     416             :         }
     417           9 :         if (tevent_req_nomem(bytes, req)) {
     418           0 :                 return tevent_req_post(req, ev);
     419             :         }
     420             : 
     421           9 :         subreq = smb1cli_req_send(state, ev, conn,
     422             :                                   SMBsesssetupX,
     423             :                                   0, /*  additional_flags */
     424             :                                   0, /*  clear_flags */
     425             :                                   0, /*  additional_flags2 */
     426             :                                   0, /*  clear_flags2 */
     427             :                                   timeout_msec,
     428             :                                   pid,
     429             :                                   NULL, /* tcon */
     430             :                                   session,
     431             :                                   13, /* wct */
     432             :                                   vwv,
     433           9 :                                   talloc_get_size(bytes),
     434             :                                   bytes);
     435           9 :         if (tevent_req_nomem(subreq, req)) {
     436           0 :                 return tevent_req_post(req, ev);
     437             :         }
     438           9 :         tevent_req_set_callback(subreq, smb1cli_session_setup_nt1_done, req);
     439             : 
     440           9 :         return req;
     441             : }
     442             : 
     443           9 : static void smb1cli_session_setup_nt1_done(struct tevent_req *subreq)
     444             : {
     445           7 :         struct tevent_req *req =
     446           9 :                 tevent_req_callback_data(subreq,
     447             :                 struct tevent_req);
     448           7 :         struct smb1cli_session_setup_nt1_state *state =
     449           9 :                 tevent_req_data(req,
     450             :                 struct smb1cli_session_setup_nt1_state);
     451             :         NTSTATUS status;
     452           9 :         uint8_t *inhdr = NULL;
     453             :         uint8_t wct;
     454           9 :         uint16_t *vwv = NULL;
     455             :         uint32_t num_bytes;
     456           9 :         uint8_t *bytes = NULL;
     457           9 :         const uint8_t *p = NULL;
     458           9 :         size_t ret = 0;
     459             :         uint16_t flags2;
     460           9 :         bool use_unicode = false;
     461           9 :         struct smb1cli_req_expected_response expected[] = {
     462             :         {
     463             :                 .status = NT_STATUS_OK,
     464             :                 .wct    = 3,
     465             :         },
     466             :         };
     467             : 
     468           9 :         status = smb1cli_req_recv(subreq, state,
     469             :                                   &state->recv_iov,
     470             :                                   &inhdr,
     471             :                                   &wct,
     472             :                                   &vwv,
     473             :                                   NULL, /* pvwv_offset */
     474             :                                   &num_bytes,
     475             :                                   &bytes,
     476             :                                   NULL, /* pbytes_offset */
     477             :                                   &state->inbuf,
     478             :                                   expected, ARRAY_SIZE(expected));
     479           9 :         TALLOC_FREE(subreq);
     480           9 :         if (tevent_req_nterror(req, status)) {
     481           4 :                 return;
     482             :         }
     483             : 
     484           7 :         flags2 = SVAL(inhdr, HDR_FLG2);
     485           7 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     486           7 :                 use_unicode = true;
     487             :         }
     488             : 
     489           7 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     490           7 :         state->out_action = SVAL(vwv+2, 0);
     491             : 
     492           7 :         p = bytes;
     493             : 
     494           7 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     495             :                                     use_unicode, bytes, num_bytes,
     496             :                                     p, &ret);
     497           7 :         if (tevent_req_nterror(req, status)) {
     498           0 :                 return;
     499             :         }
     500           7 :         p += ret;
     501             : 
     502           7 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     503             :                                     use_unicode, bytes, num_bytes,
     504             :                                     p, &ret);
     505           7 :         if (tevent_req_nterror(req, status)) {
     506           0 :                 return;
     507             :         }
     508           7 :         p += ret;
     509             : 
     510           7 :         status = smb_bytes_pull_str(state, &state->out_primary_domain,
     511             :                                     use_unicode, bytes, num_bytes,
     512             :                                     p, &ret);
     513           7 :         if (tevent_req_nterror(req, status)) {
     514           0 :                 return;
     515             :         }
     516             : 
     517           7 :         smb1cli_session_set_id(state->session, state->out_session_id);
     518           7 :         smb1cli_session_set_action(state->session, state->out_action);
     519             : 
     520           7 :         tevent_req_done(req);
     521             : }
     522             : 
     523           9 : NTSTATUS smb1cli_session_setup_nt1_recv(struct tevent_req *req,
     524             :                                         TALLOC_CTX *mem_ctx,
     525             :                                         struct iovec **precv_iov,
     526             :                                         const uint8_t **precv_inbuf,
     527             :                                         char **out_native_os,
     528             :                                         char **out_native_lm,
     529             :                                         char **out_primary_domain)
     530             : {
     531           7 :         struct smb1cli_session_setup_nt1_state *state =
     532           9 :                 tevent_req_data(req,
     533             :                 struct smb1cli_session_setup_nt1_state);
     534             :         NTSTATUS status;
     535           9 :         struct iovec *recv_iov = NULL;
     536             : 
     537           9 :         if (tevent_req_is_nterror(req, &status)) {
     538           2 :                 tevent_req_received(req);
     539           2 :                 return status;
     540             :         }
     541             : 
     542           7 :         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
     543           7 :         if (precv_iov != NULL) {
     544           7 :                 *precv_iov = recv_iov;
     545             :         }
     546           7 :         if (precv_inbuf != NULL) {
     547           7 :                 *precv_inbuf = state->inbuf;
     548             :         }
     549             : 
     550           7 :         if (out_native_os != NULL) {
     551           7 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     552             :         }
     553             : 
     554           7 :         if (out_native_lm != NULL) {
     555           7 :                 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
     556             :         }
     557             : 
     558           7 :         if (out_primary_domain != NULL) {
     559           7 :                 *out_primary_domain = talloc_move(mem_ctx,
     560             :                                                   &state->out_primary_domain);
     561             :         }
     562             : 
     563           7 :         tevent_req_received(req);
     564           7 :         return NT_STATUS_OK;
     565             : }
     566             : 
     567             : struct smb1cli_session_setup_ext_state {
     568             :         struct smbXcli_session *session;
     569             :         uint16_t vwv[12];
     570             :         struct iovec *recv_iov;
     571             :         uint8_t *inbuf;
     572             :         NTSTATUS status;
     573             :         uint16_t out_session_id;
     574             :         uint16_t out_action;
     575             :         DATA_BLOB out_security_blob;
     576             :         char *out_native_os;
     577             :         char *out_native_lm;
     578             : };
     579             : 
     580             : static void smb1cli_session_setup_ext_done(struct tevent_req *subreq);
     581             : 
     582         167 : struct tevent_req *smb1cli_session_setup_ext_send(TALLOC_CTX *mem_ctx,
     583             :                                 struct tevent_context *ev,
     584             :                                 struct smbXcli_conn *conn,
     585             :                                 uint32_t timeout_msec,
     586             :                                 uint32_t pid,
     587             :                                 struct smbXcli_session *session,
     588             :                                 uint16_t in_buf_size,
     589             :                                 uint16_t in_mpx_max,
     590             :                                 uint16_t in_vc_num,
     591             :                                 uint32_t in_sess_key,
     592             :                                 const DATA_BLOB in_security_blob,
     593             :                                 uint32_t in_capabilities,
     594             :                                 const char *in_native_os,
     595             :                                 const char *in_native_lm)
     596             : {
     597         167 :         struct tevent_req *req = NULL;
     598         167 :         struct smb1cli_session_setup_ext_state *state = NULL;
     599         167 :         struct tevent_req *subreq = NULL;
     600         167 :         uint16_t *vwv = NULL;
     601         167 :         uint8_t *bytes = NULL;
     602             : 
     603         167 :         req = tevent_req_create(mem_ctx, &state,
     604             :                                 struct smb1cli_session_setup_ext_state);
     605         167 :         if (req == NULL) {
     606           0 :                 return NULL;
     607             :         }
     608         167 :         state->session = session;
     609         167 :         vwv = state->vwv;
     610             : 
     611         167 :         if (in_security_blob.length > UINT16_MAX) {
     612           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     613           0 :                 return tevent_req_post(req, ev);
     614             :         }
     615             : 
     616         167 :         if (in_native_os == NULL && in_native_lm != NULL) {
     617           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     618           0 :                 return tevent_req_post(req, ev);
     619             :         }
     620             : 
     621         167 :         SCVAL(vwv+0,  0, 0xff);
     622         167 :         SCVAL(vwv+0,  1, 0);
     623         167 :         SSVAL(vwv+1,  0, 0);
     624         167 :         SSVAL(vwv+2,  0, in_buf_size);
     625         167 :         SSVAL(vwv+3,  0, in_mpx_max);
     626         167 :         SSVAL(vwv+4,  0, in_vc_num);
     627         167 :         SIVAL(vwv+5,  0, in_sess_key);
     628         167 :         SSVAL(vwv+7,  0, in_security_blob.length);
     629         167 :         SSVAL(vwv+8,  0, 0); /* reserved */
     630         167 :         SSVAL(vwv+9,  0, 0); /* reserved */
     631         167 :         SIVAL(vwv+10, 0, in_capabilities);
     632             : 
     633         167 :         bytes = talloc_array(state, uint8_t,
     634             :                              in_security_blob.length);
     635         167 :         if (tevent_req_nomem(bytes, req)) {
     636           0 :                 return tevent_req_post(req, ev);
     637             :         }
     638         167 :         if (in_security_blob.length != 0) {
     639         315 :                 memcpy(bytes,
     640         167 :                        in_security_blob.data,
     641          19 :                        in_security_blob.length);
     642             :         }
     643             : 
     644         167 :         if (in_native_os != NULL) {
     645         315 :                 bytes = smb_bytes_push_str(bytes,
     646         167 :                                            smbXcli_conn_use_unicode(conn),
     647         167 :                                            in_native_os, strlen(in_native_os)+1,
     648             :                                            NULL);
     649             :         }
     650         167 :         if (in_native_lm != NULL) {
     651         315 :                 bytes = smb_bytes_push_str(bytes,
     652         167 :                                            smbXcli_conn_use_unicode(conn),
     653         167 :                                            in_native_lm, strlen(in_native_lm)+1,
     654             :                                            NULL);
     655             :         }
     656         167 :         if (tevent_req_nomem(bytes, req)) {
     657           0 :                 return tevent_req_post(req, ev);
     658             :         }
     659             : 
     660         167 :         subreq = smb1cli_req_send(state, ev, conn,
     661             :                                   SMBsesssetupX,
     662             :                                   0, /*  additional_flags */
     663             :                                   0, /*  clear_flags */
     664             :                                   0, /*  additional_flags2 */
     665             :                                   0, /*  clear_flags2 */
     666             :                                   timeout_msec,
     667             :                                   pid,
     668             :                                   NULL, /* tcon */
     669             :                                   session,
     670             :                                   12, /* wct */
     671             :                                   vwv,
     672         167 :                                   talloc_get_size(bytes),
     673             :                                   bytes);
     674         167 :         if (tevent_req_nomem(subreq, req)) {
     675           0 :                 return tevent_req_post(req, ev);
     676             :         }
     677         167 :         tevent_req_set_callback(subreq, smb1cli_session_setup_ext_done, req);
     678             : 
     679         167 :         return req;
     680             : }
     681             : 
     682         167 : static void smb1cli_session_setup_ext_done(struct tevent_req *subreq)
     683             : {
     684         148 :         struct tevent_req *req =
     685         167 :                 tevent_req_callback_data(subreq,
     686             :                 struct tevent_req);
     687         148 :         struct smb1cli_session_setup_ext_state *state =
     688         167 :                 tevent_req_data(req,
     689             :                 struct smb1cli_session_setup_ext_state);
     690             :         NTSTATUS status;
     691         167 :         uint8_t *inhdr = NULL;
     692             :         uint8_t wct;
     693         167 :         uint16_t *vwv = NULL;
     694             :         uint32_t num_bytes;
     695         167 :         uint8_t *bytes = NULL;
     696         167 :         const uint8_t *p = NULL;
     697         167 :         size_t ret = 0;
     698             :         uint16_t flags2;
     699         167 :         uint16_t out_security_blob_length = 0;
     700         167 :         bool use_unicode = false;
     701         167 :         struct smb1cli_req_expected_response expected[] = {
     702             :         {
     703             :                 .status = NT_STATUS_OK,
     704             :                 .wct    = 4,
     705             :         },
     706             :         {
     707             :                 .status = NT_STATUS_MORE_PROCESSING_REQUIRED,
     708             :                 .wct    = 4,
     709             :         },
     710             :         };
     711             : 
     712         167 :         status = smb1cli_req_recv(subreq, state,
     713             :                                   &state->recv_iov,
     714             :                                   &inhdr,
     715             :                                   &wct,
     716             :                                   &vwv,
     717             :                                   NULL, /* pvwv_offset */
     718             :                                   &num_bytes,
     719             :                                   &bytes,
     720             :                                   NULL, /* pbytes_offset */
     721             :                                   &state->inbuf,
     722             :                                   expected, ARRAY_SIZE(expected));
     723         167 :         TALLOC_FREE(subreq);
     724         167 :         state->status = status;
     725         167 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     726          76 :                 status = NT_STATUS_OK;
     727             :         }
     728         167 :         if (tevent_req_nterror(req, status)) {
     729          22 :                 return;
     730             :         }
     731             : 
     732         153 :         flags2 = SVAL(inhdr, HDR_FLG2);
     733         153 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     734         153 :                 use_unicode = true;
     735             :         }
     736             : 
     737         153 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     738         153 :         state->out_action = SVAL(vwv+2, 0);
     739         153 :         out_security_blob_length = SVAL(vwv+3, 0);
     740             : 
     741         153 :         if (out_security_blob_length > num_bytes) {
     742           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     743           0 :                 return;
     744             :         }
     745             : 
     746         153 :         p = bytes;
     747             : 
     748             :         /*
     749             :          * Note: this points into state->recv_iov!
     750             :          */
     751         153 :         state->out_security_blob = data_blob_const(p, out_security_blob_length);
     752         153 :         p += out_security_blob_length;
     753             : 
     754         153 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     755             :                                     use_unicode, bytes, num_bytes,
     756             :                                     p, &ret);
     757         153 :         if (tevent_req_nterror(req, status)) {
     758           0 :                 return;
     759             :         }
     760         153 :         p += ret;
     761             : 
     762         153 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     763             :                                     use_unicode, bytes, num_bytes,
     764             :                                     p, &ret);
     765         153 :         if (tevent_req_nterror(req, status)) {
     766           0 :                 return;
     767             :         }
     768             :         /* p += ret; */
     769             : 
     770         153 :         smb1cli_session_set_id(state->session, state->out_session_id);
     771         153 :         smb1cli_session_set_action(state->session, state->out_action);
     772             : 
     773         153 :         tevent_req_done(req);
     774             : }
     775             : 
     776         167 : NTSTATUS smb1cli_session_setup_ext_recv(struct tevent_req *req,
     777             :                                         TALLOC_CTX *mem_ctx,
     778             :                                         struct iovec **precv_iov,
     779             :                                         const uint8_t **precv_inbuf,
     780             :                                         DATA_BLOB *out_security_blob,
     781             :                                         char **out_native_os,
     782             :                                         char **out_native_lm)
     783             : {
     784         148 :         struct smb1cli_session_setup_ext_state *state =
     785         167 :                 tevent_req_data(req,
     786             :                 struct smb1cli_session_setup_ext_state);
     787             :         NTSTATUS status;
     788         167 :         struct iovec *recv_iov = NULL;
     789             : 
     790         167 :         if (tevent_req_is_nterror(req, &status)) {
     791          14 :                 tevent_req_received(req);
     792          14 :                 return status;
     793             :         }
     794             : 
     795         153 :         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
     796         153 :         if (precv_iov != NULL) {
     797         153 :                 *precv_iov = recv_iov;
     798             :         }
     799         153 :         if (precv_inbuf != NULL) {
     800         153 :                 *precv_inbuf = state->inbuf;
     801             :         }
     802             : 
     803         153 :         *out_security_blob = state->out_security_blob;
     804             : 
     805         153 :         if (out_native_os != NULL) {
     806         153 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     807             :         }
     808             : 
     809         153 :         if (out_native_lm != NULL) {
     810         153 :                 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
     811             :         }
     812             : 
     813             :         /*
     814             :          * Return the status from the server:
     815             :          * NT_STATUS_MORE_PROCESSING_REQUIRED or
     816             :          * NT_STATUS_OK.
     817             :          */
     818         153 :         status = state->status;
     819         153 :         tevent_req_received(req);
     820         153 :         return status;
     821             : }

Generated by: LCOV version 1.13