2005-11-11 07:45:38 +03:00
/*
Unix SMB / CIFS implementation .
SMB2 client library header
Copyright ( C ) Andrew Tridgell 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-11-11 07:45:38 +03:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-11-11 07:45:38 +03:00
*/
2008-05-16 09:03:58 +04:00
# ifndef __LIBCLI_SMB2_SMB2_H__
# define __LIBCLI_SMB2_SMB2_H__
2008-02-14 02:12:33 +03:00
# include "libcli/raw/request.h"
2008-05-30 11:03:54 +04:00
# include "libcli/raw/libcliraw.h"
2008-02-14 02:12:33 +03:00
2008-04-19 00:27:24 +04:00
struct smb2_handle ;
2009-03-31 02:57:57 +04:00
struct smb2_lease_break ;
2008-04-19 00:27:24 +04:00
2009-06-08 18:24:27 +04:00
struct smb2_request_buffer {
/* the raw SMB2 buffer, including the 4 byte length header */
uint8_t * buffer ;
/* the size of the raw buffer, including 4 byte header */
size_t size ;
/* how much has been allocated - on reply the buffer is over-allocated to
prevent too many realloc ( ) calls
*/
size_t allocated ;
/* the start of the SMB2 header - this is always buffer+4 */
uint8_t * hdr ;
/* the packet body */
uint8_t * body ;
size_t body_fixed ;
size_t body_size ;
/* this point to the next dynamic byte that can be used
* this will be moved when some dynamic data is pushed
*/
uint8_t * dynamic ;
/* this is used to range check and align strings and buffers */
struct request_bufinfo bufinfo ;
} ;
2005-11-11 07:45:38 +03:00
/* this is the context for the smb2 transport layer */
struct smb2_transport {
2011-09-20 22:59:45 +04:00
struct tevent_context * ev ; /* TODO: remove this !!! */
struct smbXcli_conn * conn ;
2005-11-11 07:45:38 +03:00
2009-06-08 18:24:27 +04:00
/* the details for coumpounded requests */
struct {
bool related ;
2011-09-20 22:59:45 +04:00
struct tevent_req * * reqs ;
2009-06-08 18:24:27 +04:00
} compound ;
2006-07-17 11:45:23 +04:00
/* an idle function - if this is defined then it will be
called once every period microseconds while we are waiting
for a packet */
struct {
void ( * func ) ( struct smb2_transport * , void * ) ;
2009-02-02 11:56:47 +03:00
void * private_data ;
2010-01-05 20:42:54 +03:00
unsigned int period ;
2011-11-22 13:10:30 +04:00
struct tevent_timer * te ;
2006-07-17 11:45:23 +04:00
} idle ;
2008-04-19 00:27:24 +04:00
struct {
/* a oplock break request handler */
bool ( * handler ) ( struct smb2_transport * transport ,
const struct smb2_handle * handle ,
uint8_t level , void * private_data ) ;
/* private data passed to the oplock handler */
void * private_data ;
} oplock ;
2008-05-30 11:03:54 +04:00
2009-03-31 02:57:57 +04:00
struct {
/* a lease break request handler */
bool ( * handler ) ( struct smb2_transport * transport ,
const struct smb2_lease_break * lease_break ,
void * private_data ) ;
/* private data passed to the oplock handler */
void * private_data ;
} lease ;
2011-09-20 22:59:45 +04:00
struct tevent_req * break_subreq ;
2009-03-31 02:57:57 +04:00
2008-05-30 11:03:54 +04:00
struct smbcli_options options ;
2005-11-11 07:45:38 +03:00
} ;
2019-12-21 00:10:49 +03:00
/*
SMB2 LSA state
*/
struct smb2lsa_state {
struct dcerpc_binding_handle * binding_handle ;
struct smb2_tree * ipc_tree ;
struct policy_handle handle ;
} ;
2005-11-11 12:11:51 +03:00
/*
SMB2 tree context
*/
struct smb2_tree {
struct smb2_session * session ;
2012-07-24 00:11:19 +04:00
struct smbXcli_tcon * smbXcli ;
2019-12-21 00:10:49 +03:00
struct smb2lsa_state * lsa ;
2005-11-11 12:11:51 +03:00
} ;
2005-11-11 08:53:54 +03:00
/*
SMB2 session context
*/
struct smb2_session {
struct smb2_transport * transport ;
2005-11-11 09:26:42 +03:00
struct gensec_security * gensec ;
2011-09-20 22:59:45 +04:00
struct smbXcli_session * smbXcli ;
2014-06-24 02:22:30 +04:00
bool needs_bind ;
2005-11-11 08:53:54 +03:00
} ;
2005-11-11 12:11:51 +03:00
2005-11-11 07:45:38 +03:00
/*
a client request moves between the following 4 states .
*/
enum smb2_request_state { SMB2_REQUEST_INIT , /* we are creating the request */
SMB2_REQUEST_RECV , /* we are waiting for a matching reply */
SMB2_REQUEST_DONE , /* the request is finished */
SMB2_REQUEST_ERROR } ; /* a packet or transport level error has occurred */
/* the context for a single SMB2 request */
struct smb2_request {
/* each request is in one of 3 possible states */
enum smb2_request_state state ;
2010-09-23 00:23:49 +04:00
2011-09-20 22:59:45 +04:00
struct tevent_req * subreq ;
2005-11-11 07:45:38 +03:00
struct smb2_transport * transport ;
2005-11-12 04:08:43 +03:00
struct smb2_session * session ;
struct smb2_tree * tree ;
2005-11-11 07:45:38 +03:00
2006-07-17 13:36:52 +04:00
struct {
2007-08-27 22:10:19 +04:00
bool can_cancel ;
2006-07-17 13:36:52 +04:00
} cancel ;
2005-11-11 07:45:38 +03:00
/* the NT status for this request. Set by packet receive code
or code detecting error . */
NTSTATUS status ;
2010-09-23 00:23:49 +04:00
2005-11-11 07:45:38 +03:00
struct smb2_request_buffer in ;
struct smb2_request_buffer out ;
2011-09-20 22:59:45 +04:00
struct iovec * recv_iov ;
uint16_t credit_charge ;
2005-11-11 07:45:38 +03:00
/* information on what to do with a reply when it is received
2023-08-03 15:34:51 +03:00
asynchronously . If this is not setup when a reply is received then
2005-11-11 07:45:38 +03:00
the reply is discarded
The private pointer is private to the caller of the client
library ( the application ) , not private to the library
*/
struct {
void ( * fn ) ( struct smb2_request * ) ;
2008-05-16 09:03:58 +04:00
void * private_data ;
2005-11-11 07:45:38 +03:00
} async ;
} ;
2005-11-17 03:48:24 +03:00
# define SMB2_MIN_SIZE 0x42
2008-09-25 05:58:38 +04:00
# define SMB2_MIN_SIZE_NO_BODY 0x40
2005-11-11 07:45:38 +03:00
2005-11-12 02:27:47 +03:00
/*
2005-11-16 14:01:15 +03:00
check that a body has the expected size
2005-11-12 02:27:47 +03:00
*/
2005-11-16 14:01:15 +03:00
# define SMB2_CHECK_PACKET_RECV(req, size, dynamic) do { \
2006-04-24 13:36:09 +04:00
size_t is_size = req - > in . body_size ; \
2005-11-16 14:01:15 +03:00
uint16_t field_size = SVAL ( req - > in . body , 0 ) ; \
uint16_t want_size = ( ( dynamic ) ? ( size ) + 1 : ( size ) ) ; \
if ( is_size < ( size ) ) { \
DEBUG ( 0 , ( " %s: buffer too small 0x%x. Expected 0x%x \n " , \
2006-09-09 14:05:58 +04:00
__location__ , ( unsigned ) is_size , ( unsigned ) want_size ) ) ; \
2005-11-16 14:01:15 +03:00
return NT_STATUS_BUFFER_TOO_SMALL ; \
} \
if ( field_size ! = want_size ) { \
DEBUG ( 0 , ( " %s: unexpected fixed body size 0x%x. Expected 0x%x \n " , \
2006-09-09 14:05:58 +04:00
__location__ , ( unsigned ) field_size , ( unsigned ) want_size ) ) ; \
2005-11-12 02:27:47 +03:00
return NT_STATUS_INVALID_PARAMETER ; \
} \
} while ( 0 )
2008-05-16 09:03:58 +04:00
# endif