libcli: move some common SMB and SMB2 stuff into libcli/smb/
[obnox/samba/samba-obnox.git] / source4 / libcli / smb2 / smb2.h
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 client library header
5
6    Copyright (C) Andrew Tridgell 2005
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 #ifndef __LIBCLI_SMB2_SMB2_H__
23 #define __LIBCLI_SMB2_SMB2_H__
24
25 #include "libcli/raw/request.h"
26 #include "libcli/raw/libcliraw.h"
27
28 struct smb2_handle;
29 struct smb2_lease_break;
30
31 /*
32   information returned from the negotiate process
33 */
34 struct smb2_negotiate {
35         DATA_BLOB secblob;
36         NTTIME system_time;
37         NTTIME server_start_time;
38         uint16_t security_mode;
39         uint16_t dialect_revision;
40 };
41
42 struct smb2_request_buffer {
43         /* the raw SMB2 buffer, including the 4 byte length header */
44         uint8_t *buffer;
45
46         /* the size of the raw buffer, including 4 byte header */
47         size_t size;
48
49         /* how much has been allocated - on reply the buffer is over-allocated to
50            prevent too many realloc() calls
51         */
52         size_t allocated;
53
54         /* the start of the SMB2 header - this is always buffer+4 */
55         uint8_t *hdr;
56
57         /* the packet body */
58         uint8_t *body;
59         size_t body_fixed;
60         size_t body_size;
61
62         /* this point to the next dynamic byte that can be used
63          * this will be moved when some dynamic data is pushed
64          */
65         uint8_t *dynamic;
66
67         /* this is used to range check and align strings and buffers */
68         struct request_bufinfo bufinfo;
69 };
70
71 /* this is the context for the smb2 transport layer */
72 struct smb2_transport {
73         /* socket level info */
74         struct smbcli_socket *socket;
75
76         struct smb2_negotiate negotiate;
77
78         /* next seqnum to allocate */
79         uint64_t seqnum;
80
81         /* the details for coumpounded requests */
82         struct {
83                 uint32_t missing;
84                 bool related;
85                 struct smb2_request_buffer buffer;
86         } compound;
87
88         struct {
89                 uint16_t charge;
90                 uint16_t ask_num;
91         } credits;
92
93         /* a list of requests that are pending for receive on this
94            connection */
95         struct smb2_request *pending_recv;
96
97         /* context of the stream -> packet parser */
98         struct packet_context *packet;
99
100         /* an idle function - if this is defined then it will be
101            called once every period microseconds while we are waiting
102            for a packet */
103         struct {
104                 void (*func)(struct smb2_transport *, void *);
105                 void *private_data;
106                 uint_t period;
107         } idle;
108
109         struct {
110                 /* a oplock break request handler */
111                 bool (*handler)(struct smb2_transport *transport,
112                                 const struct smb2_handle *handle,
113                                 uint8_t level, void *private_data);
114                 /* private data passed to the oplock handler */
115                 void *private_data;
116         } oplock;
117
118         struct {
119                 /* a lease break request handler */
120                 bool (*handler)(struct smb2_transport *transport,
121                                 const struct smb2_lease_break *lease_break,
122                                 void *private_data);
123                 /* private data passed to the oplock handler */
124                 void *private_data;
125         } lease;
126
127         struct smbcli_options options;
128
129         bool signing_required;
130 };
131
132
133 /*
134   SMB2 tree context
135 */
136 struct smb2_tree {
137         struct smb2_session *session;
138         uint32_t tid;
139 };
140
141 /*
142   SMB2 session context
143 */
144 struct smb2_session {
145         struct smb2_transport *transport;
146         struct gensec_security *gensec;
147         uint64_t uid;
148         DATA_BLOB session_key;
149         bool signing_active;
150 };
151
152
153
154 /*
155   a client request moves between the following 4 states.
156 */
157 enum smb2_request_state {SMB2_REQUEST_INIT, /* we are creating the request */
158                         SMB2_REQUEST_RECV, /* we are waiting for a matching reply */
159                         SMB2_REQUEST_DONE, /* the request is finished */
160                         SMB2_REQUEST_ERROR}; /* a packet or transport level error has occurred */
161
162 /* the context for a single SMB2 request */
163 struct smb2_request {
164         /* allow a request to be part of a list of requests */
165         struct smb2_request *next, *prev;
166
167         /* each request is in one of 3 possible states */
168         enum smb2_request_state state;
169         
170         struct smb2_transport *transport;
171         struct smb2_session   *session;
172         struct smb2_tree      *tree;
173
174         uint64_t seqnum;
175
176         struct {
177                 bool do_cancel;
178                 bool can_cancel;
179                 uint32_t pending_id;
180         } cancel;
181
182         /* the NT status for this request. Set by packet receive code
183            or code detecting error. */
184         NTSTATUS status;
185         
186         struct smb2_request_buffer in;
187         struct smb2_request_buffer out;
188
189         /* information on what to do with a reply when it is received
190            asyncronously. If this is not setup when a reply is received then
191            the reply is discarded
192
193            The private pointer is private to the caller of the client
194            library (the application), not private to the library
195         */
196         struct {
197                 void (*fn)(struct smb2_request *);
198                 void *private_data;
199         } async;
200 };
201
202
203 #define SMB2_MIN_SIZE 0x42
204 #define SMB2_MIN_SIZE_NO_BODY 0x40
205
206 /*
207   check that a body has the expected size
208 */
209 #define SMB2_CHECK_PACKET_RECV(req, size, dynamic) do { \
210         size_t is_size = req->in.body_size; \
211         uint16_t field_size = SVAL(req->in.body, 0); \
212         uint16_t want_size = ((dynamic)?(size)+1:(size)); \
213         if (is_size < (size)) { \
214                 DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \
215                          __location__, (unsigned)is_size, (unsigned)want_size)); \
216                 return NT_STATUS_BUFFER_TOO_SMALL; \
217         }\
218         if (field_size != want_size) { \
219                 DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \
220                          __location__, (unsigned)field_size, (unsigned)want_size)); \
221                 return NT_STATUS_INVALID_PARAMETER; \
222         } \
223 } while (0)
224
225 #endif