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