#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/vfs.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/uaccess.h>
#include <linux/uuid.h>
#include <linux/pagemap.h>
#include <linux/xattr.h>
#include <linux/netfs.h>
#include <trace/events/netfs.h>
#include "cifsglob.h"
#include "cifsacl.h"
#include "cifsproto.h"
#include "smb2proto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "ntlmssp.h"
#include "smb2status.h"
#include "smb2glob.h"
#include "cifspdu.h"
#include "cifs_spnego.h"
#include "smbdirect.h"
#include "trace.h"
#ifdef CONFIG_CIFS_DFS_UPCALL
#include "dfs_cache.h"
#endif
#include "cached_dir.h"
static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = …;
int smb3_encryption_required(const struct cifs_tcon *tcon)
{ … }
static void
smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd,
const struct cifs_tcon *tcon,
struct TCP_Server_Info *server)
{ … }
static int
cifs_chan_skip_or_disable(struct cifs_ses *ses,
struct TCP_Server_Info *server,
bool from_reconnect)
{ … }
static int
smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
struct TCP_Server_Info *server, bool from_reconnect)
{ … }
static void
fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
void *buf,
unsigned int *total_len)
{ … }
static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
void **request_buf, unsigned int *total_len)
{ … }
static int smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
void **request_buf, unsigned int *total_len)
{ … }
static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
void **request_buf, unsigned int *total_len)
{ … }
static void
build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
{ … }
static void
build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
{ … }
static unsigned int
build_signing_ctxt(struct smb2_signing_capabilities *pneg_ctxt)
{ … }
static void
build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
{ … }
static unsigned int
build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname)
{ … }
static void
build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
{ … }
static void
assemble_neg_contexts(struct smb2_negotiate_req *req,
struct TCP_Server_Info *server, unsigned int *total_len)
{ … }
static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt)
{ … }
static void decode_compress_ctx(struct TCP_Server_Info *server,
struct smb2_compression_capabilities_context *ctxt)
{ … }
static int decode_encrypt_ctx(struct TCP_Server_Info *server,
struct smb2_encryption_neg_context *ctxt)
{ … }
static void decode_signing_ctx(struct TCP_Server_Info *server,
struct smb2_signing_capabilities *pctxt)
{ … }
static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
struct TCP_Server_Info *server,
unsigned int len_of_smb)
{ … }
static struct create_posix *
create_posix_buf(umode_t mode)
{ … }
static int
add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
{ … }
int
SMB2_negotiate(const unsigned int xid,
struct cifs_ses *ses,
struct TCP_Server_Info *server)
{ … }
int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
{ … }
enum securityEnum
smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
{ … }
struct SMB2_sess_data { … };
static int
SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
{ … }
static void
SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data)
{ … }
static int
SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
{ … }
static int
SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
{ … }
#ifdef CONFIG_CIFS_UPCALL
static void
SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
{ … }
#else
static void
SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
{
cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
sess_data->result = -EOPNOTSUPP;
sess_data->func = NULL;
}
#endif
static void
SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data);
static void
SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
{ … }
static void
SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
{ … }
static int
SMB2_select_sec(struct SMB2_sess_data *sess_data)
{ … }
int
SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server,
const struct nls_table *nls_cp)
{ … }
int
SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
{ … }
static inline void cifs_stats_fail_inc(struct cifs_tcon *tcon, uint16_t code)
{ … }
#define MAX_SHARENAME_LENGTH …
static inline void init_copy_chunk_defaults(struct cifs_tcon *tcon)
{ … }
int
SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
struct cifs_tcon *tcon, const struct nls_table *cp)
{ … }
int
SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
{ … }
static struct create_durable *
create_durable_buf(void)
{ … }
static struct create_durable *
create_reconnect_durable_buf(struct cifs_fid *fid)
{ … }
static void
parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
{ … }
static void
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
struct create_posix_rsp *posix)
{ … }
int smb2_parse_contexts(struct TCP_Server_Info *server,
struct kvec *rsp_iov,
unsigned int *epoch,
char *lease_key, __u8 *oplock,
struct smb2_file_all_info *buf,
struct create_posix_rsp *posix)
{ … }
static int
add_lease_context(struct TCP_Server_Info *server,
struct smb2_create_req *req,
struct kvec *iov,
unsigned int *num_iovec, u8 *lease_key, __u8 *oplock)
{ … }
static struct create_durable_v2 *
create_durable_v2_buf(struct cifs_open_parms *oparms)
{ … }
static struct create_durable_handle_reconnect_v2 *
create_reconnect_durable_v2_buf(struct cifs_fid *fid)
{ … }
static int
add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec,
struct cifs_open_parms *oparms)
{ … }
static int
add_durable_reconnect_v2_context(struct kvec *iov, unsigned int *num_iovec,
struct cifs_open_parms *oparms)
{ … }
static int
add_durable_context(struct kvec *iov, unsigned int *num_iovec,
struct cifs_open_parms *oparms, bool use_persistent)
{ … }
static struct crt_twarp_ctxt *
create_twarp_buf(__u64 timewarp)
{ … }
static int
add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
{ … }
static void setup_owner_group_sids(char *buf)
{ … }
static struct crt_sd_ctxt *
create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
{ … }
static int
add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode, bool set_owner)
{ … }
static struct crt_query_id_ctxt *
create_query_id_buf(void)
{ … }
static int
add_query_id_context(struct kvec *iov, unsigned int *num_iovec)
{ … }
static void add_ea_context(struct cifs_open_parms *oparms,
struct kvec *rq_iov, unsigned int *num_iovs)
{ … }
static int
alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
const char *treename, const __le16 *path)
{ … }
int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
umode_t mode, struct cifs_tcon *tcon,
const char *full_path,
struct cifs_sb_info *cifs_sb)
{ … }
int
SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
struct smb_rqst *rqst, __u8 *oplock,
struct cifs_open_parms *oparms, __le16 *path)
{ … }
void
SMB2_open_free(struct smb_rqst *rqst)
{ … }
int
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
__u8 *oplock, struct smb2_file_all_info *buf,
struct create_posix_rsp *posix,
struct kvec *err_iov, int *buftype)
{ … }
int
SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, u32 opcode,
char *in_data, u32 indatalen,
__u32 max_response_size)
{ … }
void
SMB2_ioctl_free(struct smb_rqst *rqst)
{ … }
int
SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
u64 volatile_fid, u32 opcode, char *in_data, u32 indatalen,
u32 max_out_data_len, char **out_data,
u32 *plen )
{ … }
int
SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid)
{ … }
int
SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, bool query_attrs)
{ … }
void
SMB2_close_free(struct smb_rqst *rqst)
{ … }
int
__SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid,
struct smb2_file_network_open_info *pbuf)
{ … }
int
SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid)
{ … }
int
smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
struct kvec *iov, unsigned int min_buf_size)
{ … }
int
smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
struct kvec *iov, unsigned int minbufsize,
char *data)
{ … }
int
SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid,
u8 info_class, u8 info_type, u32 additional_info,
size_t output_len, size_t input_len, void *input)
{ … }
void
SMB2_query_info_free(struct smb_rqst *rqst)
{ … }
static int
query_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type,
u32 additional_info, size_t output_len, size_t min_len, void **data,
u32 *dlen)
{ … }
int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data)
{ … }
#if 0
int
SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen)
{
size_t output_len = sizeof(struct smb311_posix_qinfo *) +
(sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2);
*plen = 0;
return query_info(xid, tcon, persistent_fid, volatile_fid,
SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0,
output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen);
}
#endif
int
SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid,
void **data, u32 *plen, u32 extra_info)
{ … }
int
SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, __le64 *uniqueid)
{ … }
static int
SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
struct cifs_tcon *tcon, struct TCP_Server_Info *server,
u64 persistent_fid, u64 volatile_fid,
u32 completion_filter, bool watch_tree)
{ … }
int
SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, bool watch_tree,
u32 completion_filter, u32 max_out_data_len, char **out_data,
u32 *plen )
{ … }
static void
smb2_echo_callback(struct mid_q_entry *mid)
{ … }
void smb2_reconnect_server(struct work_struct *work)
{ … }
int
SMB2_echo(struct TCP_Server_Info *server)
{ … }
void
SMB2_flush_free(struct smb_rqst *rqst)
{ … }
int
SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
struct cifs_tcon *tcon, struct TCP_Server_Info *server,
u64 persistent_fid, u64 volatile_fid)
{ … }
int
SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
u64 volatile_fid)
{ … }
#ifdef CONFIG_CIFS_SMB_DIRECT
static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
{ … }
#endif
static int
smb2_new_read_req(void **buf, unsigned int *total_len,
struct cifs_io_parms *io_parms, struct cifs_io_subrequest *rdata,
unsigned int remaining_bytes, int request_type)
{ … }
static void smb2_readv_worker(struct work_struct *work)
{ … }
static void
smb2_readv_callback(struct mid_q_entry *mid)
{ … }
int
smb2_async_readv(struct cifs_io_subrequest *rdata)
{ … }
int
SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, char **buf, int *buf_type)
{ … }
static void
smb2_writev_callback(struct mid_q_entry *mid)
{ … }
void
smb2_async_writev(struct cifs_io_subrequest *wdata)
{ … }
int
SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, int n_vec)
{ … }
int posix_info_sid_size(const void *beg, const void *end)
{ … }
int posix_info_parse(const void *beg, const void *end,
struct smb2_posix_info_parsed *out)
{ … }
static int posix_info_extra_size(const void *beg, const void *end)
{ … }
static unsigned int
num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
size_t size)
{ … }
int SMB2_query_directory_init(const unsigned int xid,
struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid,
int index, int info_level)
{ … }
void SMB2_query_directory_free(struct smb_rqst *rqst)
{ … }
int
smb2_parse_query_directory(struct cifs_tcon *tcon,
struct kvec *rsp_iov,
int resp_buftype,
struct cifs_search_info *srch_inf)
{ … }
int
SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, int index,
struct cifs_search_info *srch_inf)
{ … }
int
SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, u32 pid,
u8 info_class, u8 info_type, u32 additional_info,
void **data, unsigned int *size)
{ … }
void
SMB2_set_info_free(struct smb_rqst *rqst)
{ … }
static int
send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class,
u8 info_type, u32 additional_info, unsigned int num,
void **data, unsigned int *size)
{ … }
int
SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
u64 volatile_fid, u32 pid, loff_t new_eof)
{ … }
int
SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid,
struct cifs_ntsd *pnntsd, int pacllen, int aclflag)
{ … }
int
SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid,
struct smb2_file_full_ea_info *buf, int len)
{ … }
int
SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
const u64 persistent_fid, const u64 volatile_fid,
__u8 oplock_level)
{ … }
void
smb2_copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
struct kstatfs *kst)
{ … }
static void
copy_posix_fs_info_to_kstatfs(FILE_SYSTEM_POSIX_INFO *response_data,
struct kstatfs *kst)
{ … }
static int
build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
int level, int outbuf_len, u64 persistent_fid,
u64 volatile_fid)
{ … }
static inline void free_qfs_info_req(struct kvec *iov)
{ … }
int
SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
{ … }
int
SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
{ … }
int
SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, int level)
{ … }
int
smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
const __u32 num_lock, struct smb2_lock_element *buf)
{ … }
int
SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
const __u64 length, const __u64 offset, const __u32 lock_flags,
const bool wait)
{ … }
int
SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
__u8 *lease_key, const __le32 lease_state)
{ … }