Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : SMB client tree context management functions
5 :
6 : Copyright (C) Andrew Tridgell 1994-2005
7 : Copyright (C) James Myers 2003 <myersjj@samba.org>
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "libcli/raw/libcliraw.h"
25 : #include "libcli/raw/raw_proto.h"
26 : #include "libcli/smb_composite/smb_composite.h"
27 : #include "../libcli/smb/smbXcli_base.h"
28 :
29 : #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \
30 : req = smbcli_request_setup(tree, cmd, wct, buflen); \
31 : if (!req) return NULL; \
32 : } while (0)
33 :
34 : /****************************************************************************
35 : Initialize the tree context
36 : ****************************************************************************/
37 2943 : _PUBLIC_ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session,
38 : TALLOC_CTX *parent_ctx, bool primary)
39 : {
40 144 : struct smbcli_tree *tree;
41 :
42 2943 : tree = talloc_zero(parent_ctx, struct smbcli_tree);
43 2943 : if (!tree) {
44 0 : return NULL;
45 : }
46 :
47 2943 : if (primary) {
48 2826 : tree->session = talloc_steal(tree, session);
49 : } else {
50 117 : tree->session = talloc_reference(tree, session);
51 : }
52 :
53 2943 : tree->smbXcli = smbXcli_tcon_create(tree);
54 2943 : if (tree->smbXcli == NULL) {
55 0 : talloc_free(tree);
56 0 : return NULL;
57 : }
58 :
59 2799 : return tree;
60 : }
61 :
62 : /****************************************************************************
63 : Send a tconX (async send)
64 : ****************************************************************************/
65 2935 : struct smbcli_request *smb_raw_tcon_send(struct smbcli_tree *tree,
66 : union smb_tcon *parms)
67 : {
68 2935 : struct smbcli_request *req = NULL;
69 :
70 2935 : switch (parms->tcon.level) {
71 0 : case RAW_TCON_TCON:
72 0 : SETUP_REQUEST_TREE(SMBtcon, 0, 0);
73 0 : smbcli_req_append_ascii4(req, parms->tcon.in.service, STR_ASCII);
74 0 : smbcli_req_append_ascii4(req, parms->tcon.in.password,STR_ASCII);
75 0 : smbcli_req_append_ascii4(req, parms->tcon.in.dev, STR_ASCII);
76 0 : break;
77 :
78 2935 : case RAW_TCON_TCONX:
79 2935 : SETUP_REQUEST_TREE(SMBtconX, 4, 0);
80 2935 : SSVAL(req->out.vwv, VWV(0), 0xFF);
81 2935 : SSVAL(req->out.vwv, VWV(1), 0);
82 2935 : SSVAL(req->out.vwv, VWV(2), parms->tconx.in.flags);
83 2935 : SSVAL(req->out.vwv, VWV(3), parms->tconx.in.password.length);
84 2935 : smbcli_req_append_blob(req, &parms->tconx.in.password);
85 2935 : smbcli_req_append_string(req, parms->tconx.in.path, STR_TERMINATE | STR_UPPER);
86 2935 : smbcli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII);
87 2935 : break;
88 :
89 0 : case RAW_TCON_SMB2:
90 0 : return NULL;
91 : }
92 :
93 2935 : if (!smbcli_request_send(req)) {
94 0 : smbcli_request_destroy(req);
95 0 : return NULL;
96 : }
97 :
98 2791 : return req;
99 : }
100 :
101 : /****************************************************************************
102 : Send a tconX (async recv)
103 : ****************************************************************************/
104 2935 : NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
105 : union smb_tcon *parms)
106 : {
107 144 : uint8_t *p;
108 :
109 5870 : if (!smbcli_request_receive(req) ||
110 2935 : smbcli_request_is_error(req)) {
111 49 : goto failed;
112 : }
113 :
114 2886 : switch (parms->tcon.level) {
115 0 : case RAW_TCON_TCON:
116 0 : SMBCLI_CHECK_WCT(req, 2);
117 0 : parms->tcon.out.max_xmit = SVAL(req->in.vwv, VWV(0));
118 0 : parms->tcon.out.tid = SVAL(req->in.vwv, VWV(1));
119 2748 : break;
120 :
121 2886 : case RAW_TCON_TCONX:
122 2886 : ZERO_STRUCT(parms->tconx.out);
123 2886 : parms->tconx.out.tid = SVAL(req->in.hdr, HDR_TID);
124 2886 : if (req->in.wct >= 3) {
125 2886 : parms->tconx.out.options = SVAL(req->in.vwv, VWV(2));
126 : }
127 2886 : if (req->in.wct >= 7) {
128 2018 : parms->tconx.out.max_access = IVAL(req->in.vwv, VWV(3));
129 2018 : parms->tconx.out.guest_max_access = IVAL(req->in.vwv, VWV(5));
130 : }
131 :
132 : /* output is actual service name */
133 2886 : p = req->in.data;
134 2886 : if (!p) break;
135 :
136 2886 : p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type,
137 : p, -1, STR_ASCII | STR_TERMINATE);
138 2886 : smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.fs_type,
139 : p, -1, STR_TERMINATE);
140 2886 : break;
141 :
142 0 : case RAW_TCON_SMB2:
143 0 : req->status = NT_STATUS_INTERNAL_ERROR;
144 0 : break;
145 : }
146 :
147 2935 : failed:
148 2935 : return smbcli_request_destroy(req);
149 : }
150 :
151 : /****************************************************************************
152 : Send a tconX (sync interface)
153 : ****************************************************************************/
154 194 : _PUBLIC_ NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx,
155 : union smb_tcon *parms)
156 : {
157 194 : struct smbcli_request *req = smb_raw_tcon_send(tree, parms);
158 194 : return smb_raw_tcon_recv(req, mem_ctx, parms);
159 : }
160 :
161 :
162 : /****************************************************************************
163 : Send a tree disconnect.
164 : ****************************************************************************/
165 222 : _PUBLIC_ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree)
166 : {
167 16 : struct smbcli_request *req;
168 :
169 222 : if (!tree) return NT_STATUS_OK;
170 210 : req = smbcli_request_setup(tree, SMBtdis, 0, 0);
171 210 : if (req == NULL) {
172 0 : return NT_STATUS_NO_MEMORY;
173 : }
174 :
175 210 : if (smbcli_request_send(req)) {
176 210 : (void) smbcli_request_receive(req);
177 : }
178 210 : return smbcli_request_destroy(req);
179 : }
180 :
181 :
182 : /*
183 : a convenient function to establish a smbcli_tree from scratch
184 : */
185 2575 : NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
186 : struct smbcli_tree **ret_tree,
187 : const char *dest_host, const char **dest_ports,
188 : const char *service, const char *service_type,
189 : const char *socket_options,
190 : struct cli_credentials *credentials,
191 : struct resolve_context *resolve_ctx,
192 : struct tevent_context *ev,
193 : struct smbcli_options *options,
194 : struct smbcli_session_options *session_options,
195 : struct gensec_settings *gensec_settings)
196 : {
197 141 : struct smb_composite_connect io;
198 141 : NTSTATUS status;
199 2575 : TALLOC_CTX *tmp_ctx = talloc_new(parent_ctx);
200 2575 : if (!tmp_ctx) {
201 0 : return NT_STATUS_NO_MEMORY;
202 : }
203 :
204 2575 : io.in.dest_host = dest_host;
205 2575 : io.in.dest_ports = dest_ports;
206 2575 : io.in.socket_options = socket_options;
207 2575 : io.in.called_name = strupper_talloc(tmp_ctx, dest_host);
208 2575 : io.in.service = service;
209 2575 : io.in.service_type = service_type;
210 2575 : io.in.existing_conn = NULL;
211 2575 : io.in.credentials = credentials;
212 2575 : io.in.gensec_settings = gensec_settings;
213 2575 : io.in.fallback_to_anonymous = false;
214 :
215 : /* This workgroup gets sent out by the SPNEGO session setup.
216 : * I don't know of any servers that look at it, so we
217 : * hardcode it to "". */
218 2575 : io.in.workgroup = "";
219 2575 : io.in.options = *options;
220 2575 : io.in.session_options = *session_options;
221 :
222 2575 : status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev);
223 2575 : if (NT_STATUS_IS_OK(status)) {
224 2463 : *ret_tree = io.out.tree;
225 : }
226 2575 : talloc_free(tmp_ctx);
227 2575 : return status;
228 : }
|