Remove unused include param/param.h.
[ira/wip.git] / source4 / libcli / cliconnect.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    client connect/disconnect routines
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) James Peach 2005
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/libcli.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/raw/raw_proto.h"
27 #include "libcli/auth/libcli_auth.h"
28 #include "libcli/smb_composite/smb_composite.h"
29
30 /*
31   wrapper around smbcli_sock_connect()
32 */
33 bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, 
34                            const char **ports, 
35                            struct event_context *ev_ctx,
36                            struct resolve_context *resolve_ctx,
37                            struct smbcli_options *options,
38                            struct smb_iconv_convenience *iconv_convenience)
39 {
40         struct smbcli_socket *sock;
41
42         sock = smbcli_sock_connect_byname(server, ports, NULL,
43                                           resolve_ctx, ev_ctx);
44
45         if (sock == NULL) return false;
46         
47         cli->transport = smbcli_transport_init(sock, cli, true, options, 
48                                                                                    iconv_convenience);
49         if (!cli->transport) {
50                 return false;
51         }
52
53         return true;
54 }
55
56 /* wrapper around smbcli_transport_connect() */
57 bool smbcli_transport_establish(struct smbcli_state *cli, 
58                                 struct nbt_name *calling,
59                                 struct nbt_name *called)
60 {
61         return smbcli_transport_connect(cli->transport, calling, called);
62 }
63
64 /* wrapper around smb_raw_negotiate() */
65 NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol)
66 {
67         return smb_raw_negotiate(cli->transport, unicode, maxprotocol);
68 }
69
70 /* wrapper around smb_raw_sesssetup() */
71 NTSTATUS smbcli_session_setup(struct smbcli_state *cli, 
72                               struct cli_credentials *credentials,
73                               const char *workgroup,
74                               struct smbcli_session_options options)
75 {
76         struct smb_composite_sesssetup setup;
77         NTSTATUS status;
78
79         cli->session = smbcli_session_init(cli->transport, cli, true,
80                                            options);
81         if (!cli->session) return NT_STATUS_UNSUCCESSFUL;
82
83         setup.in.sesskey = cli->transport->negotiate.sesskey;
84         setup.in.capabilities = cli->transport->negotiate.capabilities;
85         setup.in.credentials = credentials;
86         setup.in.workgroup = workgroup;
87
88         status = smb_composite_sesssetup(cli->session, &setup);
89
90         cli->session->vuid = setup.out.vuid;
91
92         return status;
93 }
94
95 /* wrapper around smb_raw_tcon() */
96 NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, 
97                       const char *devtype, const char *password)
98 {
99         union smb_tcon tcon;
100         TALLOC_CTX *mem_ctx;
101         NTSTATUS status;
102
103         cli->tree = smbcli_tree_init(cli->session, cli, true);
104         if (!cli->tree) return NT_STATUS_UNSUCCESSFUL;
105
106         mem_ctx = talloc_init("tcon");
107         if (!mem_ctx) {
108                 return NT_STATUS_NO_MEMORY;
109         }
110
111         /* setup a tree connect */
112         tcon.generic.level = RAW_TCON_TCONX;
113         tcon.tconx.in.flags = 0;
114         if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
115                 tcon.tconx.in.password = data_blob(NULL, 0);
116         } else if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
117                 tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 24);
118                 if (cli->transport->negotiate.secblob.length < 8) {
119                         return NT_STATUS_INVALID_PARAMETER;
120                 }
121                 SMBencrypt(password, cli->transport->negotiate.secblob.data, tcon.tconx.in.password.data);
122         } else {
123                 tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1);
124         }
125         tcon.tconx.in.path = sharename;
126         tcon.tconx.in.device = devtype;
127         
128         status = smb_raw_tcon(cli->tree, mem_ctx, &tcon);
129
130         cli->tree->tid = tcon.tconx.out.tid;
131
132         talloc_free(mem_ctx);
133
134         return status;
135 }
136
137
138 /*
139   easy way to get to a fully connected smbcli_state in one call
140 */
141 NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx,
142                                 struct smbcli_state **ret_cli, 
143                                 const char *host,
144                                 const char **ports,
145                                 const char *sharename,
146                                 const char *devtype,
147                                 struct cli_credentials *credentials,
148                                 struct resolve_context *resolve_ctx,
149                                 struct event_context *ev,
150                                 struct smbcli_options *options,
151                                 struct smbcli_session_options *session_options,
152                                 struct smb_iconv_convenience *iconv_convenience)
153 {
154         struct smbcli_tree *tree;
155         NTSTATUS status;
156
157         *ret_cli = NULL;
158
159         status = smbcli_tree_full_connection(parent_ctx,
160                                              &tree, host, ports, 
161                                              sharename, devtype,
162                                              credentials, resolve_ctx, ev,
163                                              options,
164                                              session_options,
165                                                  iconv_convenience);
166         if (!NT_STATUS_IS_OK(status)) {
167                 goto done;
168         }
169
170         (*ret_cli) = smbcli_state_init(parent_ctx);
171
172         (*ret_cli)->tree = tree;
173         (*ret_cli)->session = tree->session;
174         (*ret_cli)->transport = tree->session->transport;
175
176         talloc_steal(*ret_cli, tree);
177         
178 done:
179         return status;
180 }
181
182
183 /*
184   disconnect the tree
185 */
186 NTSTATUS smbcli_tdis(struct smbcli_state *cli)
187 {
188         return smb_tree_disconnect(cli->tree);
189 }
190
191 /****************************************************************************
192  Initialise a client state structure.
193 ****************************************************************************/
194 struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx)
195 {
196         return talloc_zero(mem_ctx, struct smbcli_state);
197 }
198
199 /* Insert a NULL at the first separator of the given path and return a pointer
200  * to the remainder of the string.
201  */
202 static char *
203 terminate_path_at_separator(char * path)
204 {
205         char * p;
206
207         if (!path) {
208                 return NULL;
209         }
210
211         if ((p = strchr_m(path, '/'))) {
212                 *p = '\0';
213                 return p + 1;
214         }
215
216         if ((p = strchr_m(path, '\\'))) {
217                 *p = '\0';
218                 return p + 1;
219         }
220         
221         /* No separator. */
222         return NULL;
223 }
224
225 /*
226   parse a //server/share type UNC name
227 */
228 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
229                       char **hostname, char **sharename)
230 {
231         char *p;
232
233         *hostname = *sharename = NULL;
234
235         if (strncmp(unc_name, "\\\\", 2) &&
236             strncmp(unc_name, "//", 2)) {
237                 return false;
238         }
239
240         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
241         p = terminate_path_at_separator(*hostname);
242
243         if (p != NULL && *p) {
244                 *sharename = talloc_strdup(mem_ctx, p);
245                 terminate_path_at_separator(*sharename);
246         }
247
248         if (*hostname && *sharename) {
249                 return true;
250         }
251
252         talloc_free(*hostname);
253         talloc_free(*sharename);
254         *hostname = *sharename = NULL;
255         return false;
256 }
257
258
259