Coverage Report

Created: 2025-07-23 07:04

/src/samba/source4/libcli/raw/clisession.c
Line
Count
Source (jump to first uncovered line)
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
0
#define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
29
0
  req = smbcli_request_setup_session(session, cmd, wct, buflen); \
30
0
  if (!req) return NULL; \
31
0
} while (0)
32
33
34
/****************************************************************************
35
 Initialize the session context
36
****************************************************************************/
37
struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport,
38
             TALLOC_CTX *parent_ctx, bool primary,
39
             struct smbcli_session_options options)
40
0
{
41
0
  struct smbcli_session *session;
42
0
  uint16_t flags2;
43
0
  uint32_t capabilities;
44
45
0
  session = talloc_zero(parent_ctx, struct smbcli_session);
46
0
  if (!session) {
47
0
    return NULL;
48
0
  }
49
50
0
  if (primary) {
51
0
    session->transport = talloc_steal(session, transport);
52
0
  } else {
53
0
    session->transport = talloc_reference(session, transport);
54
0
  }
55
0
  session->pid = (uint32_t)getpid();
56
0
  session->vuid = UID_FIELD_INVALID;
57
0
  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
0
  session->smbXcli = smbXcli_session_create(session, transport->conn);
66
0
  if (session->smbXcli == NULL) {
67
0
    talloc_free(session);
68
0
    return NULL;
69
0
  }
70
71
0
  capabilities = transport->negotiate.capabilities;
72
73
0
  flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
74
75
0
  if (capabilities & CAP_UNICODE) {
76
0
    flags2 |= FLAGS2_UNICODE_STRINGS;
77
0
  }
78
0
  if (capabilities & CAP_STATUS32) {
79
0
    flags2 |= FLAGS2_32_BIT_ERROR_CODES;
80
0
  }
81
0
  if (capabilities & CAP_EXTENDED_SECURITY) {
82
0
    flags2 |= FLAGS2_EXTENDED_SECURITY;
83
0
  }
84
0
  if (smb1cli_conn_signing_is_active(session->transport->conn)) {
85
0
    flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
86
0
  }
87
88
0
  session->flags2 = flags2;
89
90
0
  return session;
91
0
}
92
93
/****************************************************************************
94
 Perform a session setup (async send)
95
****************************************************************************/
96
struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session,
97
                union smb_sesssetup *parms)
98
0
{
99
0
  struct smbcli_request *req = NULL;
100
101
0
  switch (parms->old.level) {
102
0
  case RAW_SESSSETUP_OLD:
103
0
    SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
104
0
    SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
105
0
    SSVAL(req->out.vwv, VWV(1), 0);
106
0
    SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
107
0
    SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
108
0
    SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
109
0
    SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
110
0
    SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
111
0
    SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
112
0
    smbcli_req_append_blob(req, &parms->old.in.password);
113
0
    smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
114
0
    smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
115
0
    smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
116
0
    smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
117
0
    break;
118
119
0
  case RAW_SESSSETUP_NT1:
120
0
    SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
121
0
    SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
122
0
    SSVAL(req->out.vwv, VWV(1), 0);
123
0
    SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
124
0
    SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
125
0
    SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
126
0
    SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
127
0
    SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
128
0
    SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
129
0
    SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
130
0
    SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
131
0
    smbcli_req_append_blob(req, &parms->nt1.in.password1);
132
0
    smbcli_req_append_blob(req, &parms->nt1.in.password2);
133
0
    smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
134
0
    smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
135
0
    smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
136
0
    smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
137
0
    break;
138
139
0
  case RAW_SESSSETUP_SPNEGO:
140
0
    SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
141
0
    SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
142
0
    SSVAL(req->out.vwv, VWV(1), 0);
143
0
    SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
144
0
    SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
145
0
    SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
146
0
    SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
147
0
    SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
148
0
    SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
149
0
    SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
150
0
    smbcli_req_append_blob(req, &parms->spnego.in.secblob);
151
0
    smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
152
0
    smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
153
0
    smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
154
0
    break;
155
156
0
  case RAW_SESSSETUP_SMB2:
157
0
    return NULL;
158
0
  }
159
160
0
  if (!smbcli_request_send(req)) {
161
0
    smbcli_request_destroy(req);
162
0
    return NULL;
163
0
  }
164
165
0
  return req;
166
0
}
167
168
169
/****************************************************************************
170
 Perform a session setup (async recv)
171
****************************************************************************/
172
NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
173
        TALLOC_CTX *mem_ctx,
174
        union smb_sesssetup *parms)
175
0
{
176
0
  uint16_t len;
177
0
  uint8_t *p;
178
179
0
  if (!smbcli_request_receive(req)) {
180
0
    return smbcli_request_destroy(req);
181
0
  }
182
183
0
  if (!NT_STATUS_IS_OK(req->status) &&
184
0
      !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
185
0
    return smbcli_request_destroy(req);
186
0
  }
187
188
0
  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
0
    }
200
0
    break;
201
202
0
  case RAW_SESSSETUP_NT1:
203
0
    SMBCLI_CHECK_WCT(req, 3);
204
0
    ZERO_STRUCT(parms->nt1.out);
205
0
    parms->nt1.out.vuid   = SVAL(req->in.hdr, HDR_UID);
206
0
    parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
207
0
    p = req->in.data;
208
0
    if (p) {
209
0
      p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
210
0
      p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
211
0
      if (p < (req->in.data + req->in.data_size)) {
212
0
        smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
213
0
      }
214
0
    }
215
0
    break;
216
217
0
  case RAW_SESSSETUP_SPNEGO:
218
0
    SMBCLI_CHECK_WCT(req, 4);
219
0
    ZERO_STRUCT(parms->spnego.out);
220
0
    parms->spnego.out.vuid   = SVAL(req->in.hdr, HDR_UID);
221
0
    parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
222
0
    len                      = SVAL(req->in.vwv, VWV(3));
223
0
    p = req->in.data;
224
0
    if (!p) {
225
0
      break;
226
0
    }
227
228
0
    parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
229
0
    p += parms->spnego.out.secblob.length;
230
0
    p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
231
0
    p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
232
0
    smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
233
0
    break;
234
235
0
  case RAW_SESSSETUP_SMB2:
236
0
    req->status = NT_STATUS_INTERNAL_ERROR;
237
0
    break;
238
0
  }
239
240
0
failed:
241
0
  return smbcli_request_destroy(req);
242
0
}
243
244
245
/*
246
 Perform a session setup (sync interface)
247
*/
248
NTSTATUS smb_raw_sesssetup(struct smbcli_session *session,
249
         TALLOC_CTX *mem_ctx, union smb_sesssetup *parms)
250
0
{
251
0
  struct smbcli_request *req = smb_raw_sesssetup_send(session, parms);
252
0
  return smb_raw_sesssetup_recv(req, mem_ctx, parms);
253
0
}
254
255
256
/****************************************************************************
257
 Send a ulogoff (async send)
258
*****************************************************************************/
259
struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
260
0
{
261
0
  struct smbcli_request *req;
262
263
0
  SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);
264
265
0
  SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
266
0
  SSVAL(req->out.vwv, VWV(1), 0);
267
268
0
  if (!smbcli_request_send(req)) {
269
0
    smbcli_request_destroy(req);
270
0
    return NULL;
271
0
  }
272
273
0
  return req;
274
0
}
275
276
/****************************************************************************
277
 Send a ulogoff (sync interface)
278
*****************************************************************************/
279
NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
280
0
{
281
0
  struct smbcli_request *req = smb_raw_ulogoff_send(session);
282
0
  return smbcli_request_simple_recv(req);
283
0
}
284
285
286
/****************************************************************************
287
 Send a exit (async send)
288
*****************************************************************************/
289
struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
290
0
{
291
0
  struct smbcli_request *req;
292
293
0
  SETUP_REQUEST_SESSION(SMBexit, 0, 0);
294
295
0
  if (!smbcli_request_send(req)) {
296
0
    smbcli_request_destroy(req);
297
0
    return NULL;
298
0
  }
299
300
0
  return req;
301
0
}
302
303
/****************************************************************************
304
 Send a exit (sync interface)
305
*****************************************************************************/
306
_PUBLIC_ NTSTATUS smb_raw_exit(struct smbcli_session *session)
307
0
{
308
0
  struct smbcli_request *req = smb_raw_exit_send(session);
309
0
  return smbcli_request_simple_recv(req);
310
0
}