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"
27 #include "../libcli/smb/smbXcli_base.h"
29 #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \
30 req = smbcli_request_setup(tree, cmd, wct, buflen); \
31 if (!req) return NULL; \
34 /****************************************************************************
35 Initialize the tree context
36 ****************************************************************************/
37 _PUBLIC_
struct smbcli_tree
*smbcli_tree_init(struct smbcli_session
*session
,
38 TALLOC_CTX
*parent_ctx
, bool primary
)
40 struct smbcli_tree
*tree
;
42 tree
= talloc_zero(parent_ctx
, struct smbcli_tree
);
48 tree
->session
= talloc_steal(tree
, session
);
50 tree
->session
= talloc_reference(tree
, session
);
53 tree
->smbXcli
= smbXcli_tcon_create(tree
);
54 if (tree
->smbXcli
== NULL
) {
62 /****************************************************************************
63 Send a tconX (async send)
64 ****************************************************************************/
65 struct smbcli_request
*smb_raw_tcon_send(struct smbcli_tree
*tree
,
66 union smb_tcon
*parms
)
68 struct smbcli_request
*req
= NULL
;
70 switch (parms
->tcon
.level
) {
72 SETUP_REQUEST_TREE(SMBtcon
, 0, 0);
73 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.service
, STR_ASCII
);
74 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.password
,STR_ASCII
);
75 smbcli_req_append_ascii4(req
, parms
->tcon
.in
.dev
, STR_ASCII
);
79 SETUP_REQUEST_TREE(SMBtconX
, 4, 0);
80 SSVAL(req
->out
.vwv
, VWV(0), 0xFF);
81 SSVAL(req
->out
.vwv
, VWV(1), 0);
82 SSVAL(req
->out
.vwv
, VWV(2), parms
->tconx
.in
.flags
);
83 SSVAL(req
->out
.vwv
, VWV(3), parms
->tconx
.in
.password
.length
);
84 smbcli_req_append_blob(req
, &parms
->tconx
.in
.password
);
85 smbcli_req_append_string(req
, parms
->tconx
.in
.path
, STR_TERMINATE
| STR_UPPER
);
86 smbcli_req_append_string(req
, parms
->tconx
.in
.device
, STR_TERMINATE
| STR_ASCII
);
93 if (!smbcli_request_send(req
)) {
94 smbcli_request_destroy(req
);
101 /****************************************************************************
102 Send a tconX (async recv)
103 ****************************************************************************/
104 NTSTATUS
smb_raw_tcon_recv(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
,
105 union smb_tcon
*parms
)
109 if (!smbcli_request_receive(req
) ||
110 smbcli_request_is_error(req
)) {
114 switch (parms
->tcon
.level
) {
116 SMBCLI_CHECK_WCT(req
, 2);
117 parms
->tcon
.out
.max_xmit
= SVAL(req
->in
.vwv
, VWV(0));
118 parms
->tcon
.out
.tid
= SVAL(req
->in
.vwv
, VWV(1));
122 ZERO_STRUCT(parms
->tconx
.out
);
123 parms
->tconx
.out
.tid
= SVAL(req
->in
.hdr
, HDR_TID
);
124 if (req
->in
.wct
>= 3) {
125 parms
->tconx
.out
.options
= SVAL(req
->in
.vwv
, VWV(2));
127 if (req
->in
.wct
>= 7) {
128 parms
->tconx
.out
.max_access
= IVAL(req
->in
.vwv
, VWV(3));
129 parms
->tconx
.out
.guest_max_access
= IVAL(req
->in
.vwv
, VWV(5));
132 /* output is actual service name */
136 p
+= smbcli_req_pull_string(&req
->in
.bufinfo
, mem_ctx
, &parms
->tconx
.out
.dev_type
,
137 p
, -1, STR_ASCII
| STR_TERMINATE
);
138 p
+= smbcli_req_pull_string(&req
->in
.bufinfo
, mem_ctx
, &parms
->tconx
.out
.fs_type
,
139 p
, -1, STR_TERMINATE
);
143 req
->status
= NT_STATUS_INTERNAL_ERROR
;
148 return smbcli_request_destroy(req
);
151 /****************************************************************************
152 Send a tconX (sync interface)
153 ****************************************************************************/
154 _PUBLIC_ NTSTATUS
smb_raw_tcon(struct smbcli_tree
*tree
, TALLOC_CTX
*mem_ctx
,
155 union smb_tcon
*parms
)
157 struct smbcli_request
*req
= smb_raw_tcon_send(tree
, parms
);
158 return smb_raw_tcon_recv(req
, mem_ctx
, parms
);
162 /****************************************************************************
163 Send a tree disconnect.
164 ****************************************************************************/
165 _PUBLIC_ NTSTATUS
smb_tree_disconnect(struct smbcli_tree
*tree
)
167 struct smbcli_request
*req
;
169 if (!tree
) return NT_STATUS_OK
;
170 req
= smbcli_request_setup(tree
, SMBtdis
, 0, 0);
172 if (smbcli_request_send(req
)) {
173 (void) smbcli_request_receive(req
);
175 return smbcli_request_destroy(req
);
180 a convenient function to establish a smbcli_tree from scratch
182 NTSTATUS
smbcli_tree_full_connection(TALLOC_CTX
*parent_ctx
,
183 struct smbcli_tree
**ret_tree
,
184 const char *dest_host
, const char **dest_ports
,
185 const char *service
, const char *service_type
,
186 const char *socket_options
,
187 struct cli_credentials
*credentials
,
188 struct resolve_context
*resolve_ctx
,
189 struct tevent_context
*ev
,
190 struct smbcli_options
*options
,
191 struct smbcli_session_options
*session_options
,
192 struct gensec_settings
*gensec_settings
)
194 struct smb_composite_connect io
;
196 TALLOC_CTX
*tmp_ctx
= talloc_new(parent_ctx
);
198 return NT_STATUS_NO_MEMORY
;
201 io
.in
.dest_host
= dest_host
;
202 io
.in
.dest_ports
= dest_ports
;
203 io
.in
.socket_options
= socket_options
;
204 io
.in
.called_name
= strupper_talloc(tmp_ctx
, dest_host
);
205 io
.in
.service
= service
;
206 io
.in
.service_type
= service_type
;
207 io
.in
.credentials
= credentials
;
208 io
.in
.gensec_settings
= gensec_settings
;
209 io
.in
.fallback_to_anonymous
= false;
211 /* This workgroup gets sent out by the SPNEGO session setup.
212 * I don't know of any servers that look at it, so we
213 * hardcode it to "". */
214 io
.in
.workgroup
= "";
215 io
.in
.options
= *options
;
216 io
.in
.session_options
= *session_options
;
218 status
= smb_composite_connect(&io
, parent_ctx
, resolve_ctx
, ev
);
219 if (NT_STATUS_IS_OK(status
)) {
220 *ret_tree
= io
.out
.tree
;
222 talloc_free(tmp_ctx
);