2 Unix SMB/CIFS implementation.
4 SMB client tree context management functions
6 Copyright (C) Andrew Tridgell 1994-2005
7 Copyright (C) James Myers 2003 <myersjj@samba.org>
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.
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.
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/>.
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/raw/raw_proto.h"
26 #include "libcli/smb_composite/smb_composite.h"
28 #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \
29 req = smbcli_request_setup(tree, cmd, wct, buflen); \
30 if (!req) return NULL; \
33 /****************************************************************************
34 Initialize the tree context
35 ****************************************************************************/
36 _PUBLIC_
struct smbcli_tree
*smbcli_tree_init(struct smbcli_session
*session
,
37 TALLOC_CTX
*parent_ctx
, bool primary
)
39 struct smbcli_tree
*tree
;
41 tree
= talloc_zero(parent_ctx
, struct smbcli_tree
);
47 tree
->session
= talloc_steal(tree
, session
);
49 tree
->session
= talloc_reference(tree
, session
);
56 /****************************************************************************
57 Send a tconX (async send)
58 ****************************************************************************/
59 struct smbcli_request
*smb_raw_tcon_send(struct smbcli_tree
*tree
,
60 union smb_tcon
*parms
)
62 struct smbcli_request
*req
= NULL
;
64 switch (parms
->tcon
.level
) {
66 SETUP_REQUEST_TREE(SMBtcon
, 0, 0);
67 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.service
, STR_ASCII
);
68 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.password
,STR_ASCII
);
69 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.dev
, STR_ASCII
);
73 SETUP_REQUEST_TREE(SMBtconX
, 4, 0);
74 SSVAL(req
->out
.vwv
, VWV(0), 0xFF);
75 SSVAL(req
->out
.vwv
, VWV(1), 0);
76 SSVAL(req
->out
.vwv
, VWV(2), parms
->tconx
.in
.flags
);
77 SSVAL(req
->out
.vwv
, VWV(3), parms
->tconx
.in
.password
.length
);
78 smbcli_req_append_blob(req
, &parms
->tconx
.in
.password
);
79 smbcli_req_append_string(req
, parms
->tconx
.in
.path
, STR_TERMINATE
| STR_UPPER
);
80 smbcli_req_append_string(req
, parms
->tconx
.in
.device
, STR_TERMINATE
| STR_ASCII
);
87 if (!smbcli_request_send(req
)) {
88 smbcli_request_destroy(req
);
95 /****************************************************************************
96 Send a tconX (async recv)
97 ****************************************************************************/
98 NTSTATUS
smb_raw_tcon_recv(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
,
99 union smb_tcon
*parms
)
103 if (!smbcli_request_receive(req
) ||
104 smbcli_request_is_error(req
)) {
108 switch (parms
->tcon
.level
) {
110 SMBCLI_CHECK_WCT(req
, 2);
111 parms
->tcon
.out
.max_xmit
= SVAL(req
->in
.vwv
, VWV(0));
112 parms
->tcon
.out
.tid
= SVAL(req
->in
.vwv
, VWV(1));
116 ZERO_STRUCT(parms
->tconx
.out
);
117 parms
->tconx
.out
.tid
= SVAL(req
->in
.hdr
, HDR_TID
);
118 if (req
->in
.wct
>= 4) {
119 parms
->tconx
.out
.options
= SVAL(req
->in
.vwv
, VWV(3));
122 /* output is actual service name */
126 p
+= smbcli_req_pull_string(&req
->in
.bufinfo
, mem_ctx
, &parms
->tconx
.out
.dev_type
,
127 p
, -1, STR_ASCII
| STR_TERMINATE
);
128 p
+= smbcli_req_pull_string(&req
->in
.bufinfo
, mem_ctx
, &parms
->tconx
.out
.fs_type
,
129 p
, -1, STR_TERMINATE
);
133 req
->status
= NT_STATUS_INTERNAL_ERROR
;
138 return smbcli_request_destroy(req
);
141 /****************************************************************************
142 Send a tconX (sync interface)
143 ****************************************************************************/
144 _PUBLIC_ NTSTATUS
smb_raw_tcon(struct smbcli_tree
*tree
, TALLOC_CTX
*mem_ctx
,
145 union smb_tcon
*parms
)
147 struct smbcli_request
*req
= smb_raw_tcon_send(tree
, parms
);
148 return smb_raw_tcon_recv(req
, mem_ctx
, parms
);
152 /****************************************************************************
153 Send a tree disconnect.
154 ****************************************************************************/
155 _PUBLIC_ NTSTATUS
smb_tree_disconnect(struct smbcli_tree
*tree
)
157 struct smbcli_request
*req
;
159 if (!tree
) return NT_STATUS_OK
;
160 req
= smbcli_request_setup(tree
, SMBtdis
, 0, 0);
162 if (smbcli_request_send(req
)) {
163 (void) smbcli_request_receive(req
);
165 return smbcli_request_destroy(req
);
170 a convenient function to establish a smbcli_tree from scratch
172 NTSTATUS
smbcli_tree_full_connection(TALLOC_CTX
*parent_ctx
,
173 struct smbcli_tree
**ret_tree
,
174 const char *dest_host
, const char **dest_ports
,
175 const char *service
, const char *service_type
,
176 const char *socket_options
,
177 struct cli_credentials
*credentials
,
178 struct resolve_context
*resolve_ctx
,
179 struct tevent_context
*ev
,
180 struct smbcli_options
*options
,
181 struct smbcli_session_options
*session_options
,
182 struct gensec_settings
*gensec_settings
)
184 struct smb_composite_connect io
;
186 TALLOC_CTX
*tmp_ctx
= talloc_new(parent_ctx
);
188 return NT_STATUS_NO_MEMORY
;
191 io
.in
.dest_host
= dest_host
;
192 io
.in
.dest_ports
= dest_ports
;
193 io
.in
.socket_options
= socket_options
;
194 io
.in
.called_name
= strupper_talloc(tmp_ctx
, dest_host
);
195 io
.in
.service
= service
;
196 io
.in
.service_type
= service_type
;
197 io
.in
.credentials
= credentials
;
198 io
.in
.gensec_settings
= gensec_settings
;
199 io
.in
.fallback_to_anonymous
= false;
201 /* This workgroup gets sent out by the SPNEGO session setup.
202 * I don't know of any servers that look at it, so we
203 * hardcode it to "". */
204 io
.in
.workgroup
= "";
205 io
.in
.options
= *options
;
206 io
.in
.session_options
= *session_options
;
208 status
= smb_composite_connect(&io
, parent_ctx
, resolve_ctx
, ev
);
209 if (NT_STATUS_IS_OK(status
)) {
210 *ret_tree
= io
.out
.tree
;
212 talloc_free(tmp_ctx
);