gopher/smb.h

492 lines
11 KiB
C

#ifndef __SMB_H__
#define __SMB_H__
#include <stdint.h>
#define SMB2_MAGIC 0x424d53fe
// commands
enum {
SMB2_NEGOTIATE = 0x0000,
SMB2_SESSION_SETUP = 0x0001,
SMB2_LOGOFF = 0x0002,
SMB2_TREE_CONNECT = 0x0003,
SMB2_TREE_DISCONNECT = 0x0004,
SMB2_CREATE = 0x0005,
SMB2_CLOSE = 0x0006,
SMB2_FLUSH = 0x0007,
SMB2_READ = 0x0008,
SMB2_WRITE = 0x0009,
SMB2_LOCK = 0x000A,
SMB2_IOCTL = 0x000B,
SMB2_CANCEL = 0x000C,
SMB2_ECHO = 0x000D,
SMB2_QUERY_DIRECTORY = 0x000E,
SMB2_CHANGE_NOTIFY = 0x000F,
SMB2_QUERY_INFO = 0x0010,
SMB2_SET_INFO = 0x0011,
SMB2_OPLOCK_BREAK = 0x0012
};
// flags
enum {
SMB2_FLAGS_SERVER_TO_REDIR = 0x00000001,
SMB2_FLAGS_ASYNC_COMMAND = 0x00000002,
SMB2_FLAGS_RELATED_OPERATIONS = 0x00000004,
SMB2_FLAGS_SIGNED = 0x00000008
// integer overflow
/*
SMB2_FLAGS_DFS_OPERATIONS = 0x10000000,
SMB2_FLAGS_REPLAY_OPERATION = 0x20000000
*/
};
#define SMB2_FLAGS_DFS_OPERATIONS 0x10000000
#define SMB2_FLAGS_REPLAY_OPERATION 0x20000000
// symlink error response flags.
enum {
SYMLINK_FLAG_RELATIVE = 0x00000001
};
// negotiate flags
enum {
SMB2_NEGOTIATE_SIGNING_ENABLED = 0x0001,
SMB2_NEGOTIATE_SIGNING_REQUIRED = 0x0002,
SMB2_GLOBAL_CAP_DFS = 0x00000001,
SMB2_GLOBAL_CAP_LEASING = 0x00000002,
SMB2_GLOBAL_CAP_LARGE_MTU = 0x00000004,
SMB2_GLOBAL_CAP_MULTI_CHANNEL = 0x00000008,
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES = 0x00000010,
SMB2_GLOBAL_CAP_DIRECTORY_LEASING = 0x00000020,
SMB2_GLOBAL_CAP_ENCRYPTION = 0x00000040
};
// session setup flags
enum {
SMB2_SESSION_FLAG_BINDING = 0x01
};
// session setup response flags
enum {
SMB2_SESSION_FLAG_IS_GUEST = 0x0001,
SMB2_SESSION_FLAG_IS_NULL = 0x0002,
SMB2_SESSION_FLAG_ENCRYPT_DATA = 0x0004
};
// tree connect flags
enum {
SMB2_SHARE_TYPE_DISK = 0x01,
SMB2_SHARE_TYPE_PIPE = 0x02,
SMB2_SHARE_TYPE_PRINT = 0x03
};
// tree connect share flags.
enum {
SMB2_SHAREFLAG_MANUAL_CACHING = 0x0000,
SMB2_SHAREFLAG_AUTO_CACHING = 0x0010,
SMB2_SHAREFLAG_VDO_CACHING = 0x0020,
SMB2_SHAREFLAG_NO_CACHING = 0x0030,
SMB2_SHAREFLAG_DFS = 0x0001,
SMB2_SHAREFLAG_DFS_ROOT = 0x0002,
SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS = 0x0100,
SMB2_SHAREFLAG_FORCE_SHARED_DELETE = 0x0200,
SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING = 0x0400,
SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM = 0x0800,
SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK = 0x1000,
SMB2_SHAREFLAG_ENABLE_HASH_V1 = 0x2000,
SMB2_SHAREFLAG_ENABLE_HASH_V2 = 0x4000,
SMB2_SHAREFLAG_ENCRYPT_DATA = 0x8000
};
// tree connect capabilities
enum {
SMB2_SHARE_CAP_DFS = 0x0008,
SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY = 0x0010,
SMB2_SHARE_CAP_SCALEOUT = 0x0020,
SMB2_SHARE_CAP_CLUSTER = 0x0040,
SMB2_SHARE_CAP_ASYMMETRIC = 0x0080
};
// create - oplock
enum {
SMB2_OPLOCK_LEVEL_NONE = 0x00,
SMB2_OPLOCK_LEVEL_II = 0x01,
SMB2_OPLOCK_LEVEL_EXCLUSIVE = 0x08,
SMB2_OPLOCK_LEVEL_BATCH = 0x09,
SMB2_OPLOCK_LEVEL_LEAVE = 0xff
};
// create - impersonation
enum {
IMPERSONATION_ANONYMOUS = 0x00,
IMPERSONATION_IDENTIFICATION = 0x01,
IMPERSONATION_IMPERSONATION = 0x02,
IMPERSONATION_DELEGATE = 0x03
};
// create - share access
enum {
FILE_SHARE_READ = 0x01,
FILE_SHARE_WRITE = 0x02,
FILE_SHARE_DELETE = 0x04
};
// create - disposition
enum {
FILE_SUPERSEDE = 0x0000,
FILE_OPEN = 0x0001,
FILE_CREATE = 0x0002,
FILE_OPEN_IF = 0x0003,
FILE_OVERWRITE = 0x0004,
FILE_OVERWRITE_IF = 0x0005
};
// create - options
enum {
FILE_DIRECTORY_FILE = 0x0001,
FILE_WRITE_THROUGH = 0x0002,
FILE_SEQUENTIAL_ONLY = 0x0004,
FILE_NO_INTERMEDIATE_BUFFERING = 0x0008,
FILE_NON_DIRECTORY_FILE = 0x0040,
FILE_NO_EA_KNOWLEDGE = 0x0200,
FILE_RANDOM_ACCESS = 0x0800,
FILE_DELETE_ON_CLOSE = 0x1000,
FILE_OPEN_FOR_BACKUP_INTENT = 0x4000,
FILE_NO_COMPRESSION = 0x8000
};
#define FILE_OPEN_REPARSE_POINT 0x00200000
#define FILE_OPEN_NO_RECALL 0x00400000
// create - access
// 2.2.13.1.1
enum {
FILE_READ_DATA = 0x0001,
FILE_WRITE_DATA = 0x0002,
FILE_APPEND_DATA = 0x0004,
FILE_READ_EA = 0x0008,
FILE_WRITE_EA = 0x0010,
FILE_DELETE_CHILD = 0x0040,
FILE_EXECUTE = 0x0020,
FILE_READ_ATTRIBUTES = 0x0080,
FILE_WRITE_ATTRIBUTES = 0x0100
};
#define DELETE 0x00010000
#define READ_CONTROL 0x00020000
#define WRITE_DAC 0x00040000
#define WRITE_OWNER 0x00080000
//#define SYNCHRONIZE 0x00100000 // not used.
#define ACCESS_SYSTEM_SECURITY 0x01000000
#define MAXIMUM_ALLOWED 0x02000000
#define GENERIC_ALL 0x10000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_READ 0x80000000
// 2.2.13.1.2
enum {
FILE_LIST_DIRECTORY = 0x0001,
FILE_ADD_FILE = 0x0002,
FILE_ADD_SUBDIRECTORY = 0x0004,
FILE_TRAVERSE = 0x0020
};
// create file attributes - MS-FSCC
enum {
FILE_ATTRIBUTE_ARCHIVE = 0x0020,
FILE_ATTRIBUTE_COMPRESSED = 0x0800,
FILE_ATTRIBUTE_DIRECTORY = 0x0010,
FILE_ATTRIBUTE_ENCRYPTED = 0x4000,
FILE_ATTRIBUTE_HIDDEN = 0x0002,
FILE_ATTRIBUTE_NORMAL = 0x0080,
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000,
FILE_ATTRIBUTE_OFFLINE = 0x1000,
FILE_ATTRIBUTE_READONLY = 0x0001,
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400,
FILE_ATTRIBUTE_SPARSE_FILE = 0x0200,
FILE_ATTRIBUTE_SYSTEM = 0x0004,
FILE_ATTRIBUTE_TEMPORARY = 0x0100,
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000
};
#define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
// create response - flags
enum {
SMB2_CREATE_FLAG_REPARSEPOINT = 0x01
};
// create response - action
enum {
FILE_SUPERSEDED = 0x0000,
FILE_OPENED = 0x0001,
FILE_CREATED = 0x0002,
FILE_OVERWRITTEN = 0x0003
};
// close flags.
enum {
SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB = 0x0001
};
// read/write flags
enum {
SMB2_READFLAG_READ_UNBUFFERED = 0x01,
SMB2_WRITEFLAG_WRITE_THROUGH = 0x01,
SMB2_WRITEFLAG_WRITE_UNBUFFERED = 0x02
};
enum {
SMB2_CHANNEL_NONE = 0x0000,
SMB2_CHANNEL_RDMA_V1 = 0x0001,
SMB2_CHANNEL_RDMA_V1_INVALIDATE = 0x0002
};
typedef struct smb2_header_sync {
uint32_t protocol_id;
uint16_t structure_size;
uint16_t credit_charge;
uint32_t status;
uint16_t command;
uint16_t credit; // _request / _response
uint32_t flags;
uint32_t next_command;
uint32_t message_id[2]; // uint64_t
uint32_t reserved;
uint32_t tree_id;
uint32_t session_id[2]; // uint64_t
uint8_t signature[16];
} smb2_header_sync;
typedef struct smb2_header_async {
uint32_t protocol_id;
uint16_t structure_size;
uint16_t credit_charge;
uint32_t status;
uint16_t command;
uint16_t credit; // _request / _response
uint32_t flags;
uint32_t next_command;
uint32_t message_id[2]; // uint64_t
uint32_t async_id[2];
uint32_t session_id[2]; // uint64_t
uint8_t signature[16];
} smb2_header_async;
typedef struct smb2_error_response {
uint16_t structure_size;
uint16_t reserved;
uint32_t bytecount;
//uint8_t error_data[1]; // variable.
} smb2_error_response;
typedef struct smb2_negotiate_request {
uint16_t structure_size;
uint16_t dialect_count;
uint16_t security_mode;
uint16_t reserved;
uint32_t capabilities;
uint8_t client_guid[16];
uint32_t client_start_time[2];
//uint16_t dialects[1]; // variable sized.
} smb2_negotiate_request;
typedef struct smb2_negotiate_response {
uint16_t structure_size;
uint16_t security_mode;
uint16_t dialect_revision;
uint16_t reserved;
uint8_t server_guid[16];
uint32_t capabilities;
uint32_t max_transact_size;
uint32_t max_read_size;
uint32_t max_write_size;
uint32_t system_time[2];
uint32_t server_start_time[2];
uint16_t security_buffer_offset;
uint16_t security_buffer_length;
uint32_t reserved2;
//uint8_t buffer[1]; // variable
} smb2_negotiate_response;
typedef struct smb2_session_setup_request {
uint16_t structure_size;
uint8_t flags;
uint8_t security_mode;
uint32_t capabilities;
uint32_t channel;
uint16_t security_buffer_offset;
uint16_t security_buffer_length;
uint32_t previous_session_id[2];
//uint8t_t buffer[1]; // variable
} smb2_session_setup_request;
typedef struct smb2_session_setup_response {
uint16_t structure_size;
uint16_t session_flags;
uint16_t security_buffer_offset;
uint16_t security_buffer_length;
//uint8t_t buffer[1]; // variable
} smb2_session_setup_response;
typedef struct smb2_tree_connect_request {
uint16_t structure_size;
uint16_t reserved;
uint16_t path_offset;
uint16_t path_length;
// uint8_t buffer[0];
} smb2_tree_connect_request;
typedef struct smb2_tree_connect_response {
uint16_t structure_size;
uint8_t share_type;
uint8_t reserved;
uint32_t share_flags;
uint32_t capabilities;
uint32_t maximal_access;
} smb2_tree_connect_response;
typedef struct smb2_tree_disconnect_request {
uint16_t structure_size;
uint16_t reserved;
} smb2_tree_disconnect_request;
typedef struct smb2_tree_disconnect_response {
uint16_t structure_size;
uint16_t reserved;
} smb2_tree_disconnect_response;
typedef struct smb2_logoff_request {
uint16_t structure_size;
uint16_t reserved;
} smb2_logoff_request;
typedef struct smb2_logoff_response {
uint16_t structure_size;
uint16_t reserved;
} smb2_logoff_response;
typedef struct smb2_create_request {
uint16_t structure_size;
uint8_t security_flags;
uint8_t request_oplock_level;
uint32_t impersonation_level;
uint32_t smb_create_flags[2];
uint32_t reserved[2];
uint32_t desired_access;
uint32_t file_attributes;
uint32_t share_access;
uint32_t create_disposition;
uint32_t create_options;
uint16_t name_offset;
uint16_t name_length;
uint32_t create_contexts_offset;
uint32_t create_contexts_length;
//uint8_t buffer[0];
} smb2_create_request;
typedef struct smb2_create_response {
uint16_t structure_size;
uint8_t oplock_level;
uint8_t flags;
uint32_t create_action;
uint32_t creation_time[2];
uint32_t last_access_time[2];
uint32_t last_write_time[2];
uint32_t change_time[2];
uint32_t allocation_size[2];
uint32_t end_of_file[2];
uint32_t file_attributes;
uint32_t reserved2;
uint32_t file_id[4];
uint32_t create_contexts_offset;
uint32_t create_contexts_length;
// uint8_t buffer[0];
} smb2_create_response;
typedef struct smb2_close_request {
uint16_t structure_size;
uint16_t flags;
uint32_t reserved;
uint32_t file_id[4];
} smb2_close_request;
typedef struct smb2_close_response {
uint16_t structure_size;
uint16_t flags;
uint32_t reserved;
uint32_t creation_time[2];
uint32_t last_access_time[2];
uint32_t last_write_time[2];
uint32_t change_time[2];
uint32_t allocation_size[2];
uint32_t end_of_file[2];
uint32_t file_attributes;
} smb2_close_response;
typedef struct smb2_flush_request {
uint16_t structure_size;
uint16_t reserved;
uint32_t reserved2;
uint32_t file_id[4];
} smb2_flush_request;
typedef struct smb2_flush_response {
uint16_t structure_size;
uint16_t reserved;
} smb2_flush_response;
typedef struct smb2_read_request {
uint16_t structure_size;
uint8_t padding;
uint8_t flags;
uint32_t length;
uint32_t offset[2];
uint32_t file_id[4];
uint32_t minimum_count;
uint32_t channel;
uint32_t remaining_bytes;
uint16_t read_channel_info_offset;
uint16_t read_channel_info_length;
// uint8_t buffer[0];
} smb2_read_request;
typedef struct smb2_read_response {
uint16_t structure_size;
uint8_t data_offset;
uint8_t reserved;
uint32_t data_length;
uint32_t data_remaining;
uint32_t reserved2;
// uint8_t buffer[0];
} smb2_read_response;
#endif