LCOV - code coverage report
Current view: top level - source4/libcli/raw - clisession.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 137 166 82.5 %
Date: 2024-04-21 15:09:00 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB client session context management functions
       4             : 
       5             :    Copyright (C) Andrew Tridgell 1994-2005
       6             :    Copyright (C) James Myers 2003 <myersjj@samba.org>
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/raw/libcliraw.h"
      24             : #include "libcli/raw/raw_proto.h"
      25             : #include "system/filesys.h"
      26             : #include "../libcli/smb/smbXcli_base.h"
      27             : 
      28             : #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
      29             :         req = smbcli_request_setup_session(session, cmd, wct, buflen); \
      30             :         if (!req) return NULL; \
      31             : } while (0)
      32             : 
      33             : 
      34             : /****************************************************************************
      35             :  Initialize the session context
      36             : ****************************************************************************/
      37        4052 : struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport,
      38             :                                            TALLOC_CTX *parent_ctx, bool primary,
      39             :                                            struct smbcli_session_options options)
      40             : {
      41         133 :         struct smbcli_session *session;
      42         133 :         uint16_t flags2;
      43         133 :         uint32_t capabilities;
      44             : 
      45        4052 :         session = talloc_zero(parent_ctx, struct smbcli_session);
      46        4052 :         if (!session) {
      47           0 :                 return NULL;
      48             :         }
      49             : 
      50        4052 :         if (primary) {
      51        2749 :                 session->transport = talloc_steal(session, transport);
      52             :         } else {
      53        1303 :                 session->transport = talloc_reference(session, transport);
      54             :         }
      55        4052 :         session->pid = (uint32_t)getpid();
      56        4052 :         session->vuid = UID_FIELD_INVALID;
      57        4052 :         session->options = options;
      58             : 
      59             :         /*
      60             :          * for now session->vuid is still used by the callers, but we call:
      61             :          * smb1cli_session_set_id(session->smbXcli, session->vuid);
      62             :          * before using session->smbXcli, in future we should remove
      63             :          * session->vuid.
      64             :          */
      65        4052 :         session->smbXcli = smbXcli_session_create(session, transport->conn);
      66        4052 :         if (session->smbXcli == NULL) {
      67           0 :                 talloc_free(session);
      68           0 :                 return NULL;
      69             :         }
      70             : 
      71        4052 :         capabilities = transport->negotiate.capabilities;
      72             : 
      73        4052 :         flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
      74             : 
      75        4052 :         if (capabilities & CAP_UNICODE) {
      76        4048 :                 flags2 |= FLAGS2_UNICODE_STRINGS;
      77             :         }
      78        4052 :         if (capabilities & CAP_STATUS32) {
      79        4040 :                 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
      80             :         }
      81        4052 :         if (capabilities & CAP_EXTENDED_SECURITY) {
      82        4032 :                 flags2 |= FLAGS2_EXTENDED_SECURITY;
      83             :         }
      84        4052 :         if (smb1cli_conn_signing_is_active(session->transport->conn)) {
      85         434 :                 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
      86             :         }
      87             : 
      88        4052 :         session->flags2 = flags2;
      89             : 
      90        4052 :         return session;
      91             : }
      92             : 
      93             : /****************************************************************************
      94             :  Perform a session setup (async send)
      95             : ****************************************************************************/
      96        6669 : struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session,
      97             :                                               union smb_sesssetup *parms)
      98             : {
      99        6669 :         struct smbcli_request *req = NULL;
     100             : 
     101        6669 :         switch (parms->old.level) {
     102           4 :         case RAW_SESSSETUP_OLD:
     103           4 :                 SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
     104           4 :                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
     105           4 :                 SSVAL(req->out.vwv, VWV(1), 0);
     106           4 :                 SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
     107           4 :                 SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
     108           4 :                 SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
     109           4 :                 SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
     110           4 :                 SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
     111           4 :                 SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
     112           4 :                 smbcli_req_append_blob(req, &parms->old.in.password);
     113           4 :                 smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
     114           4 :                 smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
     115           4 :                 smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
     116           4 :                 smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
     117           4 :                 break;
     118             : 
     119          17 :         case RAW_SESSSETUP_NT1:
     120          17 :                 SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
     121          17 :                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
     122          17 :                 SSVAL(req->out.vwv, VWV(1), 0);
     123          17 :                 SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
     124          17 :                 SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
     125          17 :                 SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
     126          17 :                 SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
     127          17 :                 SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
     128          17 :                 SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
     129          17 :                 SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
     130          17 :                 SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
     131          17 :                 smbcli_req_append_blob(req, &parms->nt1.in.password1);
     132          17 :                 smbcli_req_append_blob(req, &parms->nt1.in.password2);
     133          17 :                 smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
     134          17 :                 smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
     135          17 :                 smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
     136          17 :                 smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
     137          17 :                 break;
     138             : 
     139        6648 :         case RAW_SESSSETUP_SPNEGO:
     140        6648 :                 SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
     141        6648 :                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
     142        6648 :                 SSVAL(req->out.vwv, VWV(1), 0);
     143        6648 :                 SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
     144        6648 :                 SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
     145        6648 :                 SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
     146        6648 :                 SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
     147        6648 :                 SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
     148        6648 :                 SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
     149        6648 :                 SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
     150        6648 :                 smbcli_req_append_blob(req, &parms->spnego.in.secblob);
     151        6648 :                 smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
     152        6648 :                 smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
     153        6648 :                 smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
     154        6648 :                 break;
     155             : 
     156           0 :         case RAW_SESSSETUP_SMB2:
     157           0 :                 return NULL;
     158             :         }
     159             : 
     160        6669 :         if (!smbcli_request_send(req)) {
     161           0 :                 smbcli_request_destroy(req);
     162           0 :                 return NULL;
     163             :         }
     164             : 
     165        6536 :         return req;
     166             : }
     167             : 
     168             : 
     169             : /****************************************************************************
     170             :  Perform a session setup (async recv)
     171             : ****************************************************************************/
     172        6669 : NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
     173             :                                 TALLOC_CTX *mem_ctx,
     174             :                                 union smb_sesssetup *parms)
     175             : {
     176         133 :         uint16_t len;
     177         133 :         uint8_t *p;
     178             : 
     179        6669 :         if (!smbcli_request_receive(req)) {
     180           2 :                 return smbcli_request_destroy(req);
     181             :         }
     182             : 
     183        6667 :         if (!NT_STATUS_IS_OK(req->status) &&
     184        3845 :             !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     185        1263 :                 return smbcli_request_destroy(req);
     186             :         }
     187             : 
     188        5404 :         switch (parms->old.level) {
     189           0 :         case RAW_SESSSETUP_OLD:
     190           0 :                 SMBCLI_CHECK_WCT(req, 3);
     191           0 :                 ZERO_STRUCT(parms->old.out);
     192           0 :                 parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID);
     193           0 :                 parms->old.out.action = SVAL(req->in.vwv, VWV(2));
     194           0 :                 p = req->in.data;
     195           0 :                 if (p) {
     196           0 :                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
     197           0 :                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
     198           0 :                         smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
     199             :                 }
     200        5271 :                 break;
     201             : 
     202          15 :         case RAW_SESSSETUP_NT1:
     203          15 :                 SMBCLI_CHECK_WCT(req, 3);
     204          15 :                 ZERO_STRUCT(parms->nt1.out);
     205          15 :                 parms->nt1.out.vuid   = SVAL(req->in.hdr, HDR_UID);
     206          15 :                 parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
     207          15 :                 p = req->in.data;
     208          15 :                 if (p) {
     209          15 :                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
     210          15 :                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
     211          15 :                         if (p < (req->in.data + req->in.data_size)) {
     212          15 :                                 smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
     213             :                         }
     214             :                 }
     215          15 :                 break;
     216             : 
     217        5389 :         case RAW_SESSSETUP_SPNEGO:
     218        5389 :                 SMBCLI_CHECK_WCT(req, 4);
     219        5389 :                 ZERO_STRUCT(parms->spnego.out);
     220        5389 :                 parms->spnego.out.vuid   = SVAL(req->in.hdr, HDR_UID);
     221        5389 :                 parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
     222        5389 :                 len                      = SVAL(req->in.vwv, VWV(3));
     223        5389 :                 p = req->in.data;
     224        5389 :                 if (!p) {
     225           0 :                         break;
     226             :                 }
     227             : 
     228        5389 :                 parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
     229        5389 :                 p += parms->spnego.out.secblob.length;
     230        5389 :                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
     231        5389 :                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
     232        5389 :                 smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
     233        5389 :                 break;
     234             : 
     235           0 :         case RAW_SESSSETUP_SMB2:
     236           0 :                 req->status = NT_STATUS_INTERNAL_ERROR;
     237           0 :                 break;
     238             :         }
     239             : 
     240        5404 : failed:
     241        5404 :         return smbcli_request_destroy(req);
     242             : }
     243             : 
     244             : 
     245             : /*
     246             :  Perform a session setup (sync interface)
     247             : */
     248           0 : NTSTATUS smb_raw_sesssetup(struct smbcli_session *session,
     249             :                            TALLOC_CTX *mem_ctx, union smb_sesssetup *parms)
     250             : {
     251           0 :         struct smbcli_request *req = smb_raw_sesssetup_send(session, parms);
     252           0 :         return smb_raw_sesssetup_recv(req, mem_ctx, parms);
     253             : }
     254             : 
     255             : 
     256             : /****************************************************************************
     257             :  Send a ulogoff (async send)
     258             : *****************************************************************************/
     259          28 : struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
     260             : {
     261           0 :         struct smbcli_request *req;
     262             : 
     263          28 :         SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);
     264             : 
     265          28 :         SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
     266          28 :         SSVAL(req->out.vwv, VWV(1), 0);
     267             : 
     268          28 :         if (!smbcli_request_send(req)) {
     269           0 :                 smbcli_request_destroy(req);
     270           0 :                 return NULL;
     271             :         }
     272             : 
     273          28 :         return req;
     274             : }
     275             : 
     276             : /****************************************************************************
     277             :  Send a ulogoff (sync interface)
     278             : *****************************************************************************/
     279          28 : NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
     280             : {
     281          28 :         struct smbcli_request *req = smb_raw_ulogoff_send(session);
     282          28 :         return smbcli_request_simple_recv(req);
     283             : }
     284             : 
     285             : 
     286             : /****************************************************************************
     287             :  Send a exit (async send)
     288             : *****************************************************************************/
     289        2410 : struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
     290             : {
     291         129 :         struct smbcli_request *req;
     292             : 
     293        2410 :         SETUP_REQUEST_SESSION(SMBexit, 0, 0);
     294             : 
     295        2410 :         if (!smbcli_request_send(req)) {
     296           0 :                 smbcli_request_destroy(req);
     297           0 :                 return NULL;
     298             :         }
     299             : 
     300        2281 :         return req;
     301             : }
     302             : 
     303             : /****************************************************************************
     304             :  Send a exit (sync interface)
     305             : *****************************************************************************/
     306        2410 : _PUBLIC_ NTSTATUS smb_raw_exit(struct smbcli_session *session)
     307             : {
     308        2410 :         struct smbcli_request *req = smb_raw_exit_send(session);
     309        2410 :         return smbcli_request_simple_recv(req);
     310             : }

Generated by: LCOV version 1.14