r16410: remove some warnings of talloc_steal() usage without target
[kai/samba.git] / source4 / smb_server / smb_server.h
1 /* 
2    Unix SMB/CIFS implementation.
3    
4    Copyright (C) Andrew Tridgell              2003
5    Copyright (C) James J Myers                2003 <myersjj@samba.org>
6    Copyright (C) Stefan Metzmacher            2004-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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "libcli/raw/request.h"
24 #include "libcli/raw/interfaces.h"
25 #include "lib/events/events.h"
26 #include "lib/socket/socket.h"
27
28 /*
29   this header declares the core context structures associated with smb
30   sockets, tree connects, requests etc
31
32   the idea is that we will eventually get rid of all our global
33   variables and instead store our state from structures hanging off
34   these basic elements
35 */
36
37 struct smbsrv_tcons_context {
38         /* an id tree used to allocate tids */
39         struct idr_context *idtree_tid;
40
41         /* this is the limit of vuid values for this connection */
42         uint32_t idtree_limit;
43
44         /* list of open tree connects */
45         struct smbsrv_tcon *list;
46 };
47
48 struct smbsrv_sessions_context {
49         /* an id tree used to allocate vuids */
50         /* this holds info on session vuids that are already
51          * validated for this VC */
52         struct idr_context *idtree_vuid;
53
54         /* this is the limit of vuid values for this connection */
55         uint64_t idtree_limit;
56
57         /* also kept as a link list so it can be enumerated by
58            the management code */
59         struct smbsrv_session *list;
60 };
61
62 struct smbsrv_handles_context {
63         /* an id tree used to allocate file handles */
64         struct idr_context *idtree_hid;
65
66         /* this is the limit of handle values for this context */
67         uint64_t idtree_limit;
68
69         /* also kept as a link list so it can be enumerated by
70            the management code */
71         struct smbsrv_handle *list;
72 };
73
74 /* the current user context for a request */
75 struct smbsrv_session {
76         struct smbsrv_session *prev, *next;
77
78         struct smbsrv_connection *smb_conn;
79
80         /*
81          * in SMB2 tcons belong to just one session
82          * and not to the whole connection
83          */
84         struct smbsrv_tcons_context smb2_tcons;
85
86         /*
87          * the open file handles for this session,
88          * used for SMBexit, SMBulogoff and SMB2 SessionLogoff
89          */
90         struct smbsrv_handle_session_item *handles;
91
92         /* 
93          * an index passed over the wire:
94          * - 16 bit for smb
95          * - 64 bit for smb2
96          */
97         uint64_t vuid;
98
99         struct gensec_security *gensec_ctx;
100
101         struct auth_session_info *session_info;
102
103         /* some statistics for the management tools */
104         struct {
105                 /* the time when the session setup started */
106                 struct timeval connect_time;
107                 /* the time when the session setup was finished */
108                 struct timeval auth_time;
109                 /* the time when the last request comes in */
110                 struct timeval last_request_time;
111         } statistics;
112 };
113
114 /* we need a forward declaration of the ntvfs_ops strucutre to prevent
115    include recursion */
116 struct ntvfs_context;
117
118 struct smbsrv_tcon {
119         struct smbsrv_tcon *next, *prev;
120
121         /* the server context that this was created on */
122         struct smbsrv_connection *smb_conn;
123
124         /* the open file handles on this tcon */
125         struct smbsrv_handles_context handles;
126
127         /* 
128          * an index passed over the wire:
129          * - 16 bit for smb
130          * - 32 bit for smb2
131          */
132         uint32_t tid; /* an index passed over the wire (the TID) */
133
134         /* the share name */
135         const char *share_name;
136
137         /* the NTVFS context - see source/ntvfs/ for details */
138         struct ntvfs_context *ntvfs;
139
140         /* some stuff to support share level security */
141         struct {
142                 /* in share level security we need to fake up a session */
143                 struct smbsrv_session *session;
144         } sec_share;
145
146         /* some stuff to support share level security */
147         struct {
148                 /* in SMB2 a tcon always belongs to one session */
149                 struct smbsrv_session *session;
150         } smb2;
151
152         /* some statistics for the management tools */
153         struct {
154                 /* the time when the tree connect started */
155                 struct timeval connect_time;
156                 /* the time when the last request comes in */
157                 struct timeval last_request_time;
158         } statistics;
159 };
160
161 struct smbsrv_handle {
162         struct smbsrv_handle *next, *prev;
163
164         /* the tcon the handle belongs to */
165         struct smbsrv_tcon *tcon;
166
167         /* the session the handle was opened on */
168         struct smbsrv_session *session;
169
170         /* the smbpid used on the open, used for SMBexit */
171         uint16_t smbpid;
172
173         /*
174          * this is for adding the handle into a linked list
175          * on the smbsrv_session, we can't use *next,*prev
176          * for this because they're used for the linked list on the 
177          * smbsrv_tcon
178          */
179         struct smbsrv_handle_session_item {
180                 struct smbsrv_handle_session_item *prev, *next;
181                 struct smbsrv_handle *handle;
182         } session_item;
183
184         /*
185          * the value passed over the wire
186          * - 16 bit for smb
187          * - 64 bit for smb2
188          *   Note: for SMB2 handles are 128 bit
189          *         we'll fill the 2nd 64 bit with:
190          *         - 32 bit TID
191          *         - 32 bit 0xFFFFFFFF
192          */
193         uint64_t hid;
194
195         /*
196          * the ntvfs handle passed to the ntvfs backend
197          */
198         struct ntvfs_handle *ntvfs;
199
200         /* some statistics for the management tools */
201         struct {
202                 /* the time when the tree connect started */
203                 struct timeval open_time;
204                 /* the time when the last request comes in */
205                 struct timeval last_use_time;
206         } statistics;
207 };
208
209 /* a set of flags to control handling of request structures */
210 #define SMBSRV_REQ_CONTROL_LARGE     (1<<1) /* allow replies larger than max_xmit */
211
212 /* the context for a single SMB request. This is passed to any request-context 
213    functions */
214 struct smbsrv_request {
215         /* the smbsrv_connection needs a list of requests queued for send */
216         struct smbsrv_request *next, *prev;
217
218         /* the server_context contains all context specific to this SMB socket */
219         struct smbsrv_connection *smb_conn;
220
221         /* conn is only set for operations that have a valid TID */
222         struct smbsrv_tcon *tcon;
223
224         /* the session context is derived from the vuid */
225         struct smbsrv_session *session;
226
227         /* a set of flags to control usage of the request. See SMBSRV_REQ_CONTROL_* */
228         uint32_t control_flags;
229
230         /* the system time when the request arrived */
231         struct timeval request_time;
232
233         /* a pointer to the per request union smb_* io structure */
234         void *io_ptr;
235
236         /* the ntvfs_request */
237         struct ntvfs_request *ntvfs;
238
239         /* Now the SMB specific stuff */
240
241         /* the flags from the SMB request, in raw form (host byte order) */
242         uint16_t flags2;
243
244         /* this can contain a fnum from an earlier part of a chained
245          * message (such as an SMBOpenX), or -1 */
246         int chained_fnum;
247
248         /* how far through the chain of SMB commands have we gone? */
249         unsigned chain_count;
250
251         /* the sequence number for signing */
252         uint64_t seq_num;
253
254         struct request_buffer in;
255         struct request_buffer out;
256 };
257
258 /* this contains variables that should be used in % substitutions for
259  * smb.conf parameters */
260 struct substitute_context {
261         char *remote_arch;
262
263         /* our local netbios name, as give to us by the client */
264         char *local_machine;
265
266         /* the remote netbios name, as give to us by the client */
267         char *remote_machine;
268
269         /* the select remote protocol */
270         char *remote_proto;     
271
272         /* the name of the client as should be displayed in
273          * smbstatus. Can be an IP or a netbios name */
274         char *client_name; 
275
276         /* the username for %U */
277         char *user_name;
278 };
279
280 /* Remote architectures we know about. */
281 enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_WINXP, RA_SAMBA};
282
283 enum security_types {SEC_SHARE,SEC_USER};
284
285 /* smb server context structure. This should contain all the state
286  * information associated with a SMB server connection 
287  */
288 struct smbsrv_connection {
289         /* context that has been negotiated between the client and server */
290         struct {
291                 /* have we already done the NBT session establishment? */
292                 BOOL done_nbt_session;
293         
294                 /* only one negprot per connection is allowed */
295                 BOOL done_negprot;
296         
297                 /* multiple session setups are allowed, but some parameters are
298                    ignored in any but the first */
299                 BOOL done_sesssetup;
300                 
301                 /* 
302                  * Size of data we can send to client. Set
303                  *  by the client for all protocols above CORE.
304                  *  Set by us for CORE protocol.
305                  */
306                 unsigned max_send; /* init to BUFFER_SIZE */
307         
308                 /*
309                  * Size of the data we can receive. Set by us.
310                  * Can be modified by the max xmit parameter.
311                  */
312                 unsigned max_recv; /* init to BUFFER_SIZE */
313         
314                 /* a guess at the remote architecture. Try not to rely on this - in almost
315                    all cases using these values is the wrong thing to do */
316                 enum remote_arch_types ra_type;
317         
318                 /* the negotiatiated protocol */
319                 enum protocol_types protocol;
320         
321                 /* authentication context for multi-part negprot */
322                 struct auth_context *auth_context;
323         
324                 /* reference to the kerberos keytab, or machine trust account */
325                 struct cli_credentials *server_credentials;
326         
327                 /* did we tell the client we support encrypted passwords? */
328                 BOOL encrypted_passwords;
329         
330                 /* Did we choose SPNEGO, or perhaps raw NTLMSSP, or even no extended security at all? */
331                 const char *oid;
332         
333                 /* client capabilities */
334                 uint32_t client_caps;
335         
336                 /* the timezone we sent to the client */
337                 int zone_offset;
338
339                 /* NBT names only set when done_nbt_session is true */
340                 struct nbt_name *called_name;
341                 struct nbt_name *calling_name;
342         } negotiate;
343
344         /* the context associated with open tree connects on a smb socket, not for SMB2 */
345         struct smbsrv_tcons_context smb_tcons;
346
347         /* context associated with currently valid session setups */
348         struct smbsrv_sessions_context sessions;
349
350         /* the server_context holds a linked list of pending requests,
351          * this is used for blocking locks and requests blocked due to oplock
352          * break requests */
353         struct _smbsrv_pending_request {
354                 struct _smbsrv_pending_request *next, *prev;
355         
356                 /* the request itself - needs to be freed */
357                 struct smbsrv_request *request;
358         } *requests;
359
360         struct smb_signing_context signing;
361
362         struct stream_connection *connection;
363
364         /* this holds a partially received request */
365         struct packet_context *packet;
366
367         /* a list of partially received transaction requests */
368         struct smbsrv_trans_partial {
369                 struct smbsrv_trans_partial *next, *prev;
370                 struct smbsrv_request *req;
371                 struct smb_trans2 *trans;
372                 uint8_t command;
373         } *trans_partial;
374
375         /* configuration parameters */
376         struct {
377                 enum security_types security;
378                 BOOL nt_status_support;
379         } config;
380
381         /* some statictics for the management tools */
382         struct {
383                 /* the time when the client connects */
384                 struct timeval connect_time;
385                 /* the time when the last request comes in */
386                 struct timeval last_request_time;
387         } statistics;
388 };
389
390 #include "smb_server/smb_server_proto.h"
391 #include "smb_server/smb/smb_proto.h"
392
393 /* useful way of catching wct errors with file and line number */
394 #define SMBSRV_CHECK_WCT(req, wcount) do { \
395         if ((req)->in.wct != (wcount)) { \
396                 DEBUG(1,("Unexpected WCT %d at %s(%d) - expected %d\n", \
397                          (req)->in.wct, __FILE__, __LINE__, wcount)); \
398                 smbsrv_send_error(req, NT_STATUS_DOS(ERRSRV, ERRerror)); \
399                 return; \
400         } \
401 } while (0)
402         
403 /* useful wrapper for talloc with NO_MEMORY reply */
404 #define SMBSRV_TALLOC_IO_PTR(ptr, type) do { \
405         ptr = talloc(req, type); \
406         if (!ptr) { \
407                 smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
408                 return; \
409         } \
410         req->io_ptr = ptr; \
411 } while (0)
412
413 #define SMBSRV_SETUP_NTVFS_REQUEST(send_fn, state) do { \
414         req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req, \
415                                           req->session->session_info,\
416                                           SVAL(req->in.hdr,HDR_PID), \
417                                           SVAL(req->in.hdr,HDR_MID), \
418                                           req->request_time, \
419                                           req, send_fn, state); \
420         if (!req->ntvfs) { \
421                 smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
422                 return; \
423         } \
424         (void)talloc_steal(req->tcon->ntvfs, req); \
425         req->ntvfs->frontend_data.private_data = req; \
426 } while (0)
427
428 #define SMBSRV_CHECK_FILE_HANDLE(handle) do { \
429         if (!handle) { \
430                 smbsrv_send_error(req, NT_STATUS_INVALID_HANDLE); \
431                 return; \
432         } \
433 } while (0)
434
435 #define SMBSRV_CHECK_FILE_HANDLE_ERROR(handle, _status) do { \
436         if (!handle) { \
437                 smbsrv_send_error(req, _status); \
438                 return; \
439         } \
440 } while (0)
441
442 #define SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(handle) do { \
443         if (!handle) { \
444                 return NT_STATUS_INVALID_HANDLE; \
445         } \
446 } while (0)
447
448 /* 
449    check if the backend wants to handle the request asynchronously.
450    if it wants it handled synchronously then call the send function
451    immediately
452 */
453 #define SMBSRV_CALL_NTVFS_BACKEND(cmd) do { \
454         req->ntvfs->async_states->status = cmd; \
455         if (!(req->ntvfs->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
456                 req->ntvfs->async_states->send_fn(req->ntvfs); \
457         } \
458 } while (0)
459
460 /* check req->ntvfs->async_states->status and if not OK then send an error reply */
461 #define SMBSRV_CHECK_ASYNC_STATUS_ERR_SIMPLE do { \
462         req = talloc_get_type(ntvfs->async_states->private_data, struct smbsrv_request); \
463         if (NT_STATUS_IS_ERR(ntvfs->async_states->status)) { \
464                 smbsrv_send_error(req, ntvfs->async_states->status); \
465                 return; \
466         } \
467 } while (0)
468 #define SMBSRV_CHECK_ASYNC_STATUS_ERR(ptr, type) do { \
469         SMBSRV_CHECK_ASYNC_STATUS_ERR_SIMPLE; \
470         ptr = talloc_get_type(req->io_ptr, type); \
471 } while (0)
472 #define SMBSRV_CHECK_ASYNC_STATUS_SIMPLE do { \
473         req = talloc_get_type(ntvfs->async_states->private_data, struct smbsrv_request); \
474         if (!NT_STATUS_IS_OK(ntvfs->async_states->status)) { \
475                 smbsrv_send_error(req, ntvfs->async_states->status); \
476                 return; \
477         } \
478 } while (0)
479 #define SMBSRV_CHECK_ASYNC_STATUS(ptr, type) do { \
480         SMBSRV_CHECK_ASYNC_STATUS_SIMPLE; \
481         ptr = talloc_get_type(req->io_ptr, type); \
482 } while (0)
483
484 /* zero out some reserved fields in a reply */
485 #define SMBSRV_VWV_RESERVED(start, count) memset(req->out.vwv + VWV(start), 0, (count)*2)