LCOV - code coverage report
Current view: top level - libcli/smb - smb1cli_session.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 296 372 79.6 %
Date: 2024-04-21 15:09:00 Functions: 9 9 100.0 %

          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          24 : 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          24 :         struct tevent_req *req = NULL;
      60          24 :         struct smb1cli_session_setup_lm21_state *state = NULL;
      61          24 :         struct tevent_req *subreq = NULL;
      62          24 :         uint16_t *vwv = NULL;
      63          24 :         uint8_t *bytes = NULL;
      64             : 
      65          24 :         req = tevent_req_create(mem_ctx, &state,
      66             :                                 struct smb1cli_session_setup_lm21_state);
      67          24 :         if (req == NULL) {
      68           0 :                 return NULL;
      69             :         }
      70          24 :         state->session = session;
      71          24 :         vwv = state->vwv;
      72             : 
      73          24 :         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          24 :         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          24 :         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          24 :         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          24 :         SCVAL(vwv+0, 0, 0xff);
      94          24 :         SCVAL(vwv+0, 1, 0);
      95          24 :         SSVAL(vwv+1, 0, 0);
      96          24 :         SSVAL(vwv+2, 0, in_buf_size);
      97          24 :         SSVAL(vwv+3, 0, in_mpx_max);
      98          24 :         SSVAL(vwv+4, 0, in_vc_num);
      99          24 :         SIVAL(vwv+5, 0, in_sess_key);
     100          24 :         SSVAL(vwv+7, 0, in_apassword.length);
     101          24 :         SSVAL(vwv+8, 0, 0); /* reserved */
     102          24 :         SSVAL(vwv+9, 0, 0); /* reserved */
     103             : 
     104          24 :         bytes = talloc_array(state, uint8_t,
     105             :                              in_apassword.length);
     106          24 :         if (tevent_req_nomem(bytes, req)) {
     107           0 :                 return tevent_req_post(req, ev);
     108             :         }
     109          24 :         if (in_apassword.length != 0) {
     110          14 :                 memcpy(bytes,
     111          14 :                        in_apassword.data,
     112          14 :                        in_apassword.length);
     113             :         }
     114             : 
     115          24 :         bytes = smb_bytes_push_str(bytes,
     116          24 :                                    smbXcli_conn_use_unicode(conn),
     117          24 :                                    in_user, strlen(in_user)+1,
     118             :                                    NULL);
     119          24 :         bytes = smb_bytes_push_str(bytes,
     120          24 :                                    smbXcli_conn_use_unicode(conn),
     121          24 :                                    in_domain, strlen(in_domain)+1,
     122             :                                    NULL);
     123          24 :         if (in_native_os != NULL) {
     124          24 :                 bytes = smb_bytes_push_str(bytes,
     125          24 :                                            smbXcli_conn_use_unicode(conn),
     126          24 :                                            in_native_os, strlen(in_native_os)+1,
     127             :                                            NULL);
     128             :         }
     129          24 :         if (in_native_lm != NULL) {
     130          24 :                 bytes = smb_bytes_push_str(bytes,
     131          24 :                                            smbXcli_conn_use_unicode(conn),
     132          24 :                                            in_native_lm, strlen(in_native_lm)+1,
     133             :                                            NULL);
     134             :         }
     135          24 :         if (tevent_req_nomem(bytes, req)) {
     136           0 :                 return tevent_req_post(req, ev);
     137             :         }
     138             : 
     139          24 :         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          24 :                                   talloc_get_size(bytes),
     152             :                                   bytes);
     153          24 :         if (tevent_req_nomem(subreq, req)) {
     154           0 :                 return tevent_req_post(req, ev);
     155             :         }
     156          24 :         tevent_req_set_callback(subreq, smb1cli_session_setup_lm21_done, req);
     157             : 
     158          24 :         return req;
     159             : }
     160             : 
     161          24 : static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq)
     162             : {
     163           0 :         struct tevent_req *req =
     164          24 :                 tevent_req_callback_data(subreq,
     165             :                 struct tevent_req);
     166           0 :         struct smb1cli_session_setup_lm21_state *state =
     167          24 :                 tevent_req_data(req,
     168             :                 struct smb1cli_session_setup_lm21_state);
     169           0 :         NTSTATUS status;
     170          24 :         uint8_t *inhdr = NULL;
     171           0 :         uint8_t wct;
     172          24 :         uint16_t *vwv = NULL;
     173           0 :         uint32_t num_bytes;
     174          24 :         uint8_t *bytes = NULL;
     175          24 :         const uint8_t *p = NULL;
     176          24 :         size_t ret = 0;
     177           0 :         uint16_t flags2;
     178          24 :         bool use_unicode = false;
     179          24 :         struct smb1cli_req_expected_response expected[] = {
     180             :         {
     181             :                 .status = NT_STATUS_OK,
     182             :                 .wct    = 3,
     183             :         },
     184             :         };
     185             : 
     186          24 :         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          24 :         TALLOC_FREE(subreq);
     198          24 :         if (tevent_req_nterror(req, status)) {
     199           0 :                 return;
     200             :         }
     201             : 
     202          24 :         flags2 = SVAL(inhdr, HDR_FLG2);
     203          24 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     204           0 :                 use_unicode = true;
     205             :         }
     206             : 
     207          24 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     208          24 :         state->out_action = SVAL(vwv+2, 0);
     209             : 
     210          24 :         p = bytes;
     211             : 
     212          24 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     213             :                                     use_unicode, bytes, num_bytes,
     214             :                                     p, &ret);
     215          24 :         if (tevent_req_nterror(req, status)) {
     216           0 :                 return;
     217             :         }
     218          24 :         p += ret;
     219             : 
     220          24 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     221             :                                     use_unicode, bytes, num_bytes,
     222             :                                     p, &ret);
     223          24 :         if (tevent_req_nterror(req, status)) {
     224           0 :                 return;
     225             :         }
     226             : 
     227          24 :         smb1cli_session_set_id(state->session, state->out_session_id);
     228          24 :         smb1cli_session_set_action(state->session, state->out_action);
     229             : 
     230          24 :         tevent_req_done(req);
     231             : }
     232             : 
     233          24 : 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          24 :                 tevent_req_data(req,
     240             :                 struct smb1cli_session_setup_lm21_state);
     241           0 :         NTSTATUS status;
     242             : 
     243          24 :         if (tevent_req_is_nterror(req, &status)) {
     244           0 :                 tevent_req_received(req);
     245           0 :                 return status;
     246             :         }
     247             : 
     248          24 :         if (out_native_os != NULL) {
     249          24 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     250             :         }
     251             : 
     252          24 :         if (out_native_lm != NULL) {
     253          24 :                 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
     254             :         }
     255             : 
     256          24 :         tevent_req_received(req);
     257          24 :         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          65 : 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          65 :         struct tevent_req *req = NULL;
     293          65 :         struct smb1cli_session_setup_nt1_state *state = NULL;
     294          65 :         struct tevent_req *subreq = NULL;
     295          65 :         uint16_t *vwv = NULL;
     296          65 :         uint8_t *bytes = NULL;
     297          65 :         size_t align_upassword = 0;
     298          65 :         size_t apassword_ofs = 0;
     299          65 :         size_t upassword_ofs = 0;
     300             : 
     301          65 :         req = tevent_req_create(mem_ctx, &state,
     302             :                                 struct smb1cli_session_setup_nt1_state);
     303          65 :         if (req == NULL) {
     304           0 :                 return NULL;
     305             :         }
     306          65 :         state->session = session;
     307          65 :         vwv = state->vwv;
     308             : 
     309          65 :         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          65 :         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          65 :         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          65 :         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          65 :         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          65 :         SCVAL(vwv+0,  0, 0xff);
     335          65 :         SCVAL(vwv+0,  1, 0);
     336          65 :         SSVAL(vwv+1,  0, 0);
     337          65 :         SSVAL(vwv+2,  0, in_buf_size);
     338          65 :         SSVAL(vwv+3,  0, in_mpx_max);
     339          65 :         SSVAL(vwv+4,  0, in_vc_num);
     340          65 :         SIVAL(vwv+5,  0, in_sess_key);
     341          65 :         SSVAL(vwv+7,  0, in_apassword.length);
     342          65 :         SSVAL(vwv+8,  0, in_upassword.length);
     343          65 :         SSVAL(vwv+9,  0, 0); /* reserved */
     344          65 :         SSVAL(vwv+10, 0, 0); /* reserved */
     345          65 :         SIVAL(vwv+11, 0, in_capabilities);
     346             : 
     347          65 :         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          65 :         bytes = talloc_array(state, uint8_t,
     375             :                              in_apassword.length +
     376             :                              align_upassword +
     377             :                              in_upassword.length);
     378          65 :         if (tevent_req_nomem(bytes, req)) {
     379           0 :                 return tevent_req_post(req, ev);
     380             :         }
     381          65 :         if (in_apassword.length != 0) {
     382          42 :                 memcpy(bytes + apassword_ofs,
     383          42 :                        in_apassword.data,
     384          42 :                        in_apassword.length);
     385          42 :                 upassword_ofs += in_apassword.length;
     386             :         }
     387          65 :         if (align_upassword != 0) {
     388           0 :                 memset(bytes + upassword_ofs, 0, align_upassword);
     389           0 :                 upassword_ofs += align_upassword;
     390             :         }
     391          65 :         if (in_upassword.length != 0) {
     392          42 :                 memcpy(bytes + upassword_ofs,
     393          42 :                        in_upassword.data,
     394          42 :                        in_upassword.length);
     395             :         }
     396             : 
     397          65 :         bytes = smb_bytes_push_str(bytes,
     398          65 :                                    smbXcli_conn_use_unicode(conn),
     399          65 :                                    in_user, strlen(in_user)+1,
     400             :                                    NULL);
     401          65 :         bytes = smb_bytes_push_str(bytes,
     402          65 :                                    smbXcli_conn_use_unicode(conn),
     403          65 :                                    in_domain, strlen(in_domain)+1,
     404             :                                    NULL);
     405          65 :         if (in_native_os != NULL) {
     406          65 :                 bytes = smb_bytes_push_str(bytes,
     407          65 :                                            smbXcli_conn_use_unicode(conn),
     408          65 :                                            in_native_os, strlen(in_native_os)+1,
     409             :                                            NULL);
     410             :         }
     411          65 :         if (in_native_lm != NULL) {
     412          65 :                 bytes = smb_bytes_push_str(bytes,
     413          65 :                                            smbXcli_conn_use_unicode(conn),
     414          65 :                                            in_native_lm, strlen(in_native_lm)+1,
     415             :                                            NULL);
     416             :         }
     417          65 :         if (tevent_req_nomem(bytes, req)) {
     418           0 :                 return tevent_req_post(req, ev);
     419             :         }
     420             : 
     421          65 :         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          65 :                                   talloc_get_size(bytes),
     434             :                                   bytes);
     435          65 :         if (tevent_req_nomem(subreq, req)) {
     436           0 :                 return tevent_req_post(req, ev);
     437             :         }
     438          65 :         tevent_req_set_callback(subreq, smb1cli_session_setup_nt1_done, req);
     439             : 
     440          65 :         return req;
     441             : }
     442             : 
     443          65 : static void smb1cli_session_setup_nt1_done(struct tevent_req *subreq)
     444             : {
     445           0 :         struct tevent_req *req =
     446          65 :                 tevent_req_callback_data(subreq,
     447             :                 struct tevent_req);
     448           0 :         struct smb1cli_session_setup_nt1_state *state =
     449          65 :                 tevent_req_data(req,
     450             :                 struct smb1cli_session_setup_nt1_state);
     451           0 :         NTSTATUS status;
     452          65 :         uint8_t *inhdr = NULL;
     453           0 :         uint8_t wct;
     454          65 :         uint16_t *vwv = NULL;
     455           0 :         uint32_t num_bytes;
     456          65 :         uint8_t *bytes = NULL;
     457          65 :         const uint8_t *p = NULL;
     458          65 :         size_t ret = 0;
     459           0 :         uint16_t flags2;
     460          65 :         bool use_unicode = false;
     461          65 :         struct smb1cli_req_expected_response expected[] = {
     462             :         {
     463             :                 .status = NT_STATUS_OK,
     464             :                 .wct    = 3,
     465             :         },
     466             :         };
     467             : 
     468          65 :         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          65 :         TALLOC_FREE(subreq);
     480          65 :         if (tevent_req_nterror(req, status)) {
     481           4 :                 return;
     482             :         }
     483             : 
     484          61 :         flags2 = SVAL(inhdr, HDR_FLG2);
     485          61 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     486          61 :                 use_unicode = true;
     487             :         }
     488             : 
     489          61 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     490          61 :         state->out_action = SVAL(vwv+2, 0);
     491             : 
     492          61 :         p = bytes;
     493             : 
     494          61 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     495             :                                     use_unicode, bytes, num_bytes,
     496             :                                     p, &ret);
     497          61 :         if (tevent_req_nterror(req, status)) {
     498           0 :                 return;
     499             :         }
     500          61 :         p += ret;
     501             : 
     502          61 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     503             :                                     use_unicode, bytes, num_bytes,
     504             :                                     p, &ret);
     505          61 :         if (tevent_req_nterror(req, status)) {
     506           0 :                 return;
     507             :         }
     508          61 :         p += ret;
     509             : 
     510          61 :         status = smb_bytes_pull_str(state, &state->out_primary_domain,
     511             :                                     use_unicode, bytes, num_bytes,
     512             :                                     p, &ret);
     513          61 :         if (tevent_req_nterror(req, status)) {
     514           0 :                 return;
     515             :         }
     516             : 
     517          61 :         smb1cli_session_set_id(state->session, state->out_session_id);
     518          61 :         smb1cli_session_set_action(state->session, state->out_action);
     519             : 
     520          61 :         tevent_req_done(req);
     521             : }
     522             : 
     523          65 : 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           0 :         struct smb1cli_session_setup_nt1_state *state =
     532          65 :                 tevent_req_data(req,
     533             :                 struct smb1cli_session_setup_nt1_state);
     534           0 :         NTSTATUS status;
     535          65 :         struct iovec *recv_iov = NULL;
     536             : 
     537          65 :         if (tevent_req_is_nterror(req, &status)) {
     538           4 :                 tevent_req_received(req);
     539           4 :                 return status;
     540             :         }
     541             : 
     542          61 :         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
     543          61 :         if (precv_iov != NULL) {
     544          61 :                 *precv_iov = recv_iov;
     545             :         }
     546          61 :         if (precv_inbuf != NULL) {
     547          61 :                 *precv_inbuf = state->inbuf;
     548             :         }
     549             : 
     550          61 :         if (out_native_os != NULL) {
     551          61 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     552             :         }
     553             : 
     554          61 :         if (out_native_lm != NULL) {
     555          61 :                 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
     556             :         }
     557             : 
     558          61 :         if (out_primary_domain != NULL) {
     559          61 :                 *out_primary_domain = talloc_move(mem_ctx,
     560             :                                                   &state->out_primary_domain);
     561             :         }
     562             : 
     563          61 :         tevent_req_received(req);
     564          61 :         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        7624 : 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        7624 :         struct tevent_req *req = NULL;
     598        7624 :         struct smb1cli_session_setup_ext_state *state = NULL;
     599        7624 :         struct tevent_req *subreq = NULL;
     600        7624 :         uint16_t *vwv = NULL;
     601        7624 :         uint8_t *bytes = NULL;
     602             : 
     603        7624 :         req = tevent_req_create(mem_ctx, &state,
     604             :                                 struct smb1cli_session_setup_ext_state);
     605        7624 :         if (req == NULL) {
     606           0 :                 return NULL;
     607             :         }
     608        7624 :         state->session = session;
     609        7624 :         vwv = state->vwv;
     610             : 
     611        7624 :         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        7624 :         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        7624 :         SCVAL(vwv+0,  0, 0xff);
     622        7624 :         SCVAL(vwv+0,  1, 0);
     623        7624 :         SSVAL(vwv+1,  0, 0);
     624        7624 :         SSVAL(vwv+2,  0, in_buf_size);
     625        7624 :         SSVAL(vwv+3,  0, in_mpx_max);
     626        7624 :         SSVAL(vwv+4,  0, in_vc_num);
     627        7624 :         SIVAL(vwv+5,  0, in_sess_key);
     628        7624 :         SSVAL(vwv+7,  0, in_security_blob.length);
     629        7624 :         SSVAL(vwv+8,  0, 0); /* reserved */
     630        7624 :         SSVAL(vwv+9,  0, 0); /* reserved */
     631        7624 :         SIVAL(vwv+10, 0, in_capabilities);
     632             : 
     633        7624 :         bytes = talloc_array(state, uint8_t,
     634             :                              in_security_blob.length);
     635        7624 :         if (tevent_req_nomem(bytes, req)) {
     636           0 :                 return tevent_req_post(req, ev);
     637             :         }
     638        7624 :         if (in_security_blob.length != 0) {
     639        7624 :                 memcpy(bytes,
     640        7624 :                        in_security_blob.data,
     641        7624 :                        in_security_blob.length);
     642             :         }
     643             : 
     644        7624 :         if (in_native_os != NULL) {
     645        7624 :                 bytes = smb_bytes_push_str(bytes,
     646        7624 :                                            smbXcli_conn_use_unicode(conn),
     647        7624 :                                            in_native_os, strlen(in_native_os)+1,
     648             :                                            NULL);
     649             :         }
     650        7624 :         if (in_native_lm != NULL) {
     651        7624 :                 bytes = smb_bytes_push_str(bytes,
     652        7624 :                                            smbXcli_conn_use_unicode(conn),
     653        7624 :                                            in_native_lm, strlen(in_native_lm)+1,
     654             :                                            NULL);
     655             :         }
     656        7624 :         if (tevent_req_nomem(bytes, req)) {
     657           0 :                 return tevent_req_post(req, ev);
     658             :         }
     659             : 
     660        7624 :         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        7624 :                                   talloc_get_size(bytes),
     673             :                                   bytes);
     674        7624 :         if (tevent_req_nomem(subreq, req)) {
     675           0 :                 return tevent_req_post(req, ev);
     676             :         }
     677        7624 :         tevent_req_set_callback(subreq, smb1cli_session_setup_ext_done, req);
     678             : 
     679        7624 :         return req;
     680             : }
     681             : 
     682        7624 : static void smb1cli_session_setup_ext_done(struct tevent_req *subreq)
     683             : {
     684           0 :         struct tevent_req *req =
     685        7624 :                 tevent_req_callback_data(subreq,
     686             :                 struct tevent_req);
     687           0 :         struct smb1cli_session_setup_ext_state *state =
     688        7624 :                 tevent_req_data(req,
     689             :                 struct smb1cli_session_setup_ext_state);
     690           0 :         NTSTATUS status;
     691        7624 :         uint8_t *inhdr = NULL;
     692           0 :         uint8_t wct;
     693        7624 :         uint16_t *vwv = NULL;
     694           0 :         uint32_t num_bytes;
     695        7624 :         uint8_t *bytes = NULL;
     696        7624 :         const uint8_t *p = NULL;
     697        7624 :         size_t ret = 0;
     698           0 :         uint16_t flags2;
     699        7624 :         uint16_t out_security_blob_length = 0;
     700        7624 :         bool use_unicode = false;
     701        7624 :         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        7624 :         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        7624 :         TALLOC_FREE(subreq);
     724        7624 :         state->status = status;
     725        7624 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     726        3801 :                 status = NT_STATUS_OK;
     727             :         }
     728        7624 :         if (tevent_req_nterror(req, status)) {
     729          44 :                 return;
     730             :         }
     731             : 
     732        7580 :         flags2 = SVAL(inhdr, HDR_FLG2);
     733        7580 :         if (flags2 & FLAGS2_UNICODE_STRINGS) {
     734        7580 :                 use_unicode = true;
     735             :         }
     736             : 
     737        7580 :         state->out_session_id = SVAL(inhdr, HDR_UID);
     738        7580 :         state->out_action = SVAL(vwv+2, 0);
     739        7580 :         out_security_blob_length = SVAL(vwv+3, 0);
     740             : 
     741        7580 :         if (out_security_blob_length > num_bytes) {
     742           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     743           0 :                 return;
     744             :         }
     745             : 
     746        7580 :         p = bytes;
     747             : 
     748             :         /*
     749             :          * Note: this points into state->recv_iov!
     750             :          */
     751        7580 :         state->out_security_blob = data_blob_const(p, out_security_blob_length);
     752        7580 :         p += out_security_blob_length;
     753             : 
     754        7580 :         status = smb_bytes_pull_str(state, &state->out_native_os,
     755             :                                     use_unicode, bytes, num_bytes,
     756             :                                     p, &ret);
     757        7580 :         if (tevent_req_nterror(req, status)) {
     758           0 :                 return;
     759             :         }
     760        7580 :         p += ret;
     761             : 
     762        7580 :         status = smb_bytes_pull_str(state, &state->out_native_lm,
     763             :                                     use_unicode, bytes, num_bytes,
     764             :                                     p, &ret);
     765        7580 :         if (tevent_req_nterror(req, status)) {
     766           0 :                 return;
     767             :         }
     768             :         /* p += ret; */
     769             : 
     770        7580 :         smb1cli_session_set_id(state->session, state->out_session_id);
     771        7580 :         smb1cli_session_set_action(state->session, state->out_action);
     772             : 
     773        7580 :         tevent_req_done(req);
     774             : }
     775             : 
     776        7624 : 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           0 :         struct smb1cli_session_setup_ext_state *state =
     785        7624 :                 tevent_req_data(req,
     786             :                 struct smb1cli_session_setup_ext_state);
     787           0 :         NTSTATUS status;
     788        7624 :         struct iovec *recv_iov = NULL;
     789             : 
     790        7624 :         if (tevent_req_is_nterror(req, &status)) {
     791          44 :                 tevent_req_received(req);
     792          44 :                 return status;
     793             :         }
     794             : 
     795        7580 :         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
     796        7580 :         if (precv_iov != NULL) {
     797        7580 :                 *precv_iov = recv_iov;
     798             :         }
     799        7580 :         if (precv_inbuf != NULL) {
     800        7580 :                 *precv_inbuf = state->inbuf;
     801             :         }
     802             : 
     803        7580 :         *out_security_blob = state->out_security_blob;
     804             : 
     805        7580 :         if (out_native_os != NULL) {
     806        7580 :                 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
     807             :         }
     808             : 
     809        7580 :         if (out_native_lm != NULL) {
     810        7580 :                 *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        7580 :         status = state->status;
     819        7580 :         tevent_req_received(req);
     820        7580 :         return status;
     821             : }

Generated by: LCOV version 1.14