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