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