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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/raw/libcliraw.h"
25 #include "system/filesys.h"
26 #include "auth/auth.h"
28 #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
29 req = smbcli_request_setup_session(session, cmd, wct, buflen); \
30 if (!req) return NULL; \
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)
40 struct smbcli_session *session;
42 uint32_t capabilities;
44 session = talloc_zero(parent_ctx, struct smbcli_session);
50 session->transport = talloc_steal(session, transport);
52 session->transport = talloc_reference(session, transport);
54 session->pid = (uint16_t)getpid();
55 session->vuid = UID_FIELD_INVALID;
57 capabilities = transport->negotiate.capabilities;
59 flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
61 if (capabilities & CAP_UNICODE) {
62 flags2 |= FLAGS2_UNICODE_STRINGS;
64 if (capabilities & CAP_STATUS32) {
65 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
67 if (capabilities & CAP_EXTENDED_SECURITY) {
68 flags2 |= FLAGS2_EXTENDED_SECURITY;
70 if (session->transport->negotiate.sign_info.doing_signing) {
71 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
74 session->flags2 = flags2;
79 /****************************************************************************
80 Perform a session setup (async send)
81 ****************************************************************************/
82 struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session, union smb_sesssetup *parms)
84 struct smbcli_request *req = NULL;
86 switch (parms->old.level) {
87 case RAW_SESSSETUP_OLD:
88 SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
89 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
90 SSVAL(req->out.vwv, VWV(1), 0);
91 SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
92 SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
93 SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
94 SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
95 SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
96 SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
97 smbcli_req_append_blob(req, &parms->old.in.password);
98 smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
99 smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
100 smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
101 smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
104 case RAW_SESSSETUP_NT1:
105 SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
106 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
107 SSVAL(req->out.vwv, VWV(1), 0);
108 SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
109 SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
110 SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
111 SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
112 SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
113 SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
114 SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
115 SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
116 smbcli_req_append_blob(req, &parms->nt1.in.password1);
117 smbcli_req_append_blob(req, &parms->nt1.in.password2);
118 smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
119 smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
120 smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
121 smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
124 case RAW_SESSSETUP_SPNEGO:
125 SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
126 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
127 SSVAL(req->out.vwv, VWV(1), 0);
128 SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
129 SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
130 SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
131 SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
132 SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
133 SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
134 SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
135 smbcli_req_append_blob(req, &parms->spnego.in.secblob);
136 smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
137 smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
138 smbcli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE);
142 if (!smbcli_request_send(req)) {
143 smbcli_request_destroy(req);
151 /****************************************************************************
152 Perform a session setup (async recv)
153 ****************************************************************************/
154 NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req,
156 union smb_sesssetup *parms)
161 if (!smbcli_request_receive(req)) {
162 return smbcli_request_destroy(req);
165 if (!NT_STATUS_IS_OK(req->status) &&
166 !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
167 return smbcli_request_destroy(req);
170 switch (parms->old.level) {
171 case RAW_SESSSETUP_OLD:
172 SMBCLI_CHECK_WCT(req, 3);
173 ZERO_STRUCT(parms->old.out);
174 parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID);
175 parms->old.out.action = SVAL(req->in.vwv, VWV(2));
178 p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
179 p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
180 p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
184 case RAW_SESSSETUP_NT1:
185 SMBCLI_CHECK_WCT(req, 3);
186 ZERO_STRUCT(parms->nt1.out);
187 parms->nt1.out.vuid = SVAL(req->in.hdr, HDR_UID);
188 parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
191 p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
192 p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
193 if (p < (req->in.data + req->in.data_size)) {
194 p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
199 case RAW_SESSSETUP_SPNEGO:
200 SMBCLI_CHECK_WCT(req, 4);
201 ZERO_STRUCT(parms->spnego.out);
202 parms->spnego.out.vuid = SVAL(req->in.hdr, HDR_UID);
203 parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
204 len = SVAL(req->in.vwv, VWV(3));
210 parms->spnego.out.secblob = smbcli_req_pull_blob(req, mem_ctx, p, len);
211 p += parms->spnego.out.secblob.length;
212 p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
213 p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
214 p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE);
219 return smbcli_request_destroy(req);
224 Perform a session setup (sync interface)
226 NTSTATUS smb_raw_session_setup(struct smbcli_session *session, TALLOC_CTX *mem_ctx,
227 union smb_sesssetup *parms)
229 struct smbcli_request *req = smb_raw_session_setup_send(session, parms);
230 return smb_raw_session_setup_recv(req, mem_ctx, parms);
234 /****************************************************************************
235 Send a uloggoff (async send)
236 *****************************************************************************/
237 struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
239 struct smbcli_request *req;
241 SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);
243 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
244 SSVAL(req->out.vwv, VWV(1), 0);
246 if (!smbcli_request_send(req)) {
247 smbcli_request_destroy(req);
254 /****************************************************************************
255 Send a uloggoff (sync interface)
256 *****************************************************************************/
257 NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
259 struct smbcli_request *req = smb_raw_ulogoff_send(session);
260 return smbcli_request_simple_recv(req);
264 /****************************************************************************
265 Send a exit (async send)
266 *****************************************************************************/
267 struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
269 struct smbcli_request *req;
271 SETUP_REQUEST_SESSION(SMBexit, 0, 0);
273 if (!smbcli_request_send(req)) {
274 smbcli_request_destroy(req);
281 /****************************************************************************
282 Send a exit (sync interface)
283 *****************************************************************************/
284 NTSTATUS smb_raw_exit(struct smbcli_session *session)
286 struct smbcli_request *req = smb_raw_exit_send(session);
287 return smbcli_request_simple_recv(req);