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 : }
|