s4-smbtorture: add ndr test for nbt_netlogon_packet to avoid future regressions.
[Samba/id10ts.git] / source4 / libcli / raw / clisession.c
blob41765bfb2b2fa036968d00fd3adb6642f46afc4c
1 /*
2 Unix SMB/CIFS implementation.
3 SMB client session context management functions
5 Copyright (C) Andrew Tridgell 1994-2005
6 Copyright (C) James Myers 2003 <myersjj@samba.org>
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.
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.
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/>.
22 #include "includes.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "system/filesys.h"
27 #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
28 req = smbcli_request_setup_session(session, cmd, wct, buflen); \
29 if (!req) return NULL; \
30 } while (0)
33 /****************************************************************************
34 Initialize the session context
35 ****************************************************************************/
36 struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport,
37 TALLOC_CTX *parent_ctx, bool primary,
38 struct smbcli_session_options options)
40 struct smbcli_session *session;
41 uint16_t flags2;
42 uint32_t capabilities;
44 session = talloc_zero(parent_ctx, struct smbcli_session);
45 if (!session) {
46 return NULL;
49 if (primary) {
50 session->transport = talloc_steal(session, transport);
51 } else {
52 session->transport = talloc_reference(session, transport);
54 session->pid = (uint16_t)getpid();
55 session->vuid = UID_FIELD_INVALID;
56 session->options = options;
58 capabilities = transport->negotiate.capabilities;
60 flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
62 if (capabilities & CAP_UNICODE) {
63 flags2 |= FLAGS2_UNICODE_STRINGS;
65 if (capabilities & CAP_STATUS32) {
66 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
68 if (capabilities & CAP_EXTENDED_SECURITY) {
69 flags2 |= FLAGS2_EXTENDED_SECURITY;
71 if (session->transport->negotiate.sign_info.doing_signing) {
72 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
75 session->flags2 = flags2;
77 return session;
80 /****************************************************************************
81 Perform a session setup (async send)
82 ****************************************************************************/
83 struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session,
84 union smb_sesssetup *parms)
86 struct smbcli_request *req = NULL;
88 switch (parms->old.level) {
89 case RAW_SESSSETUP_OLD:
90 SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
91 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
92 SSVAL(req->out.vwv, VWV(1), 0);
93 SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
94 SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
95 SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
96 SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
97 SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
98 SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
99 smbcli_req_append_blob(req, &parms->old.in.password);
100 smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
101 smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
102 smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
103 smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
104 break;
106 case RAW_SESSSETUP_NT1:
107 SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
108 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
109 SSVAL(req->out.vwv, VWV(1), 0);
110 SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
111 SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
112 SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
113 SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
114 SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
115 SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
116 SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
117 SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
118 smbcli_req_append_blob(req, &parms->nt1.in.password1);
119 smbcli_req_append_blob(req, &parms->nt1.in.password2);
120 smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
121 smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
122 smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
123 smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
124 break;
126 case RAW_SESSSETUP_SPNEGO:
127 SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
128 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
129 SSVAL(req->out.vwv, VWV(1), 0);
130 SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
131 SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
132 SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
133 SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
134 SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
135 SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
136 SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
137 smbcli_req_append_blob(req, &parms->spnego.in.secblob);
138 smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
139 smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
140 smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
141 break;
143 case RAW_SESSSETUP_SMB2:
144 return NULL;
147 if (!smbcli_request_send(req)) {
148 smbcli_request_destroy(req);
149 return NULL;
152 return req;
156 /****************************************************************************
157 Perform a session setup (async recv)
158 ****************************************************************************/
159 NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
160 TALLOC_CTX *mem_ctx,
161 union smb_sesssetup *parms)
163 uint16_t len;
164 uint8_t *p;
166 if (!smbcli_request_receive(req)) {
167 return smbcli_request_destroy(req);
170 if (!NT_STATUS_IS_OK(req->status) &&
171 !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
172 return smbcli_request_destroy(req);
175 switch (parms->old.level) {
176 case RAW_SESSSETUP_OLD:
177 SMBCLI_CHECK_WCT(req, 3);
178 ZERO_STRUCT(parms->old.out);
179 parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID);
180 parms->old.out.action = SVAL(req->in.vwv, VWV(2));
181 p = req->in.data;
182 if (p) {
183 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
184 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
185 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
187 break;
189 case RAW_SESSSETUP_NT1:
190 SMBCLI_CHECK_WCT(req, 3);
191 ZERO_STRUCT(parms->nt1.out);
192 parms->nt1.out.vuid = SVAL(req->in.hdr, HDR_UID);
193 parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
194 p = req->in.data;
195 if (p) {
196 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
197 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
198 if (p < (req->in.data + req->in.data_size)) {
199 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
202 break;
204 case RAW_SESSSETUP_SPNEGO:
205 SMBCLI_CHECK_WCT(req, 4);
206 ZERO_STRUCT(parms->spnego.out);
207 parms->spnego.out.vuid = SVAL(req->in.hdr, HDR_UID);
208 parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
209 len = SVAL(req->in.vwv, VWV(3));
210 p = req->in.data;
211 if (!p) {
212 break;
215 parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
216 p += parms->spnego.out.secblob.length;
217 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
218 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
219 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
220 break;
222 case RAW_SESSSETUP_SMB2:
223 req->status = NT_STATUS_INTERNAL_ERROR;
224 break;
227 failed:
228 return smbcli_request_destroy(req);
233 Perform a session setup (sync interface)
235 NTSTATUS smb_raw_sesssetup(struct smbcli_session *session,
236 TALLOC_CTX *mem_ctx, union smb_sesssetup *parms)
238 struct smbcli_request *req = smb_raw_sesssetup_send(session, parms);
239 return smb_raw_sesssetup_recv(req, mem_ctx, parms);
243 /****************************************************************************
244 Send a ulogoff (async send)
245 *****************************************************************************/
246 struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
248 struct smbcli_request *req;
250 SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);
252 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
253 SSVAL(req->out.vwv, VWV(1), 0);
255 if (!smbcli_request_send(req)) {
256 smbcli_request_destroy(req);
257 return NULL;
260 return req;
263 /****************************************************************************
264 Send a ulogoff (sync interface)
265 *****************************************************************************/
266 NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
268 struct smbcli_request *req = smb_raw_ulogoff_send(session);
269 return smbcli_request_simple_recv(req);
273 /****************************************************************************
274 Send a exit (async send)
275 *****************************************************************************/
276 struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
278 struct smbcli_request *req;
280 SETUP_REQUEST_SESSION(SMBexit, 0, 0);
282 if (!smbcli_request_send(req)) {
283 smbcli_request_destroy(req);
284 return NULL;
287 return req;
290 /****************************************************************************
291 Send a exit (sync interface)
292 *****************************************************************************/
293 _PUBLIC_ NTSTATUS smb_raw_exit(struct smbcli_session *session)
295 struct smbcli_request *req = smb_raw_exit_send(session);
296 return smbcli_request_simple_recv(req);