Commit 6facac1a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French:
 "This includes a set of misc.  cifs fixes (most importantly some byte
  range lock related write fixes from Pavel, and some ACL and idmap
  related fixes from Jeff) but also includes the SMB2.02 dialect
  enablement, and a key fix for SMB3 mounts.

  Default authentication upgraded to ntlmv2 for cifs (it was already
  ntlmv2 for smb2)"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6: (43 commits)
  CIFS: Fix write after setting a read lock for read oplock files
  cifs: parse the device name into UNC and prepath
  cifs: fix up handling of prefixpath= option
  cifs: clean up handling of unc= option
  cifs: fix SID binary to string conversion
  fix "disabling echoes and oplocks" on SMB2 mounts
  Do not send SMB2 signatures for SMB3 frames
  cifs: deal with id_to_sid embedded sid reply corner case
  cifs: fix hardcoded default security descriptor length
  cifs: extra sanity checking for cifs.idmap keys
  cifs: avoid extra allocation for small cifs.idmap keys
  cifs: simplify id_to_sid and sid_to_id mapping code
  CIFS: Fix possible data coherency problem after oplock break to None
  CIFS: Do not permit write to a range mandatory locked with a read lock
  cifs: rename cifs_readdir_lookup to cifs_prime_dcache and make it void return
  cifs: Add CONFIG_CIFS_DEBUG and rename use of CIFS_DEBUG
  cifs: Make CIFS_DEBUG possible to undefine
  SMB3 mounts fail with access denied to some servers
  cifs: Remove unused cEVENT macro
  cifs: always zero out smb_vol before parsing options
  ...
parents 3f1c64f4 c299dd0e
...@@ -122,9 +122,17 @@ config CIFS_ACL ...@@ -122,9 +122,17 @@ config CIFS_ACL
Allows fetching CIFS/NTFS ACL from the server. The DACL blob Allows fetching CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller. is handed over to the application/caller.
config CIFS_DEBUG
bool "Enable CIFS debugging routines"
default y
depends on CIFS
help
Enabling this option adds helpful debugging messages to
the cifs code which increases the size of the cifs module.
If unsure, say Y.
config CIFS_DEBUG2 config CIFS_DEBUG2
bool "Enable additional CIFS debugging routines" bool "Enable additional CIFS debugging routines"
depends on CIFS depends on CIFS_DEBUG
help help
Enabling this option adds a few more debugging routines Enabling this option adds a few more debugging routines
to the cifs code which slightly increases the size of to the cifs code which slightly increases the size of
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
#define CIFS_DEBUG /* BB temporary */
#ifndef _H_CIFS_DEBUG #ifndef _H_CIFS_DEBUG
#define _H_CIFS_DEBUG #define _H_CIFS_DEBUG
...@@ -37,49 +36,43 @@ void dump_smb(void *, int); ...@@ -37,49 +36,43 @@ void dump_smb(void *, int);
#define CIFS_RC 0x02 #define CIFS_RC 0x02
#define CIFS_TIMER 0x04 #define CIFS_TIMER 0x04
extern int cifsFYI;
extern int cifsERROR;
/* /*
* debug ON * debug ON
* -------- * --------
*/ */
#ifdef CIFS_DEBUG #ifdef CONFIG_CIFS_DEBUG
/* information message: e.g., configuration, major event */ /* information message: e.g., configuration, major event */
extern int cifsFYI; #define cifsfyi(fmt, ...) \
#define cifsfyi(fmt, arg...) \
do { \ do { \
if (cifsFYI & CIFS_INFO) \ if (cifsFYI & CIFS_INFO) \
printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg); \ printk(KERN_DEBUG "%s: " fmt "\n", \
__FILE__, ##__VA_ARGS__); \
} while (0) } while (0)
#define cFYI(set, fmt, arg...) \ #define cFYI(set, fmt, ...) \
do { \ do { \
if (set) \ if (set) \
cifsfyi(fmt, ##arg); \ cifsfyi(fmt, ##__VA_ARGS__); \
} while (0) } while (0)
#define cifswarn(fmt, arg...) \ #define cifswarn(fmt, ...) \
printk(KERN_WARNING fmt "\n", ##arg) printk(KERN_WARNING fmt "\n", ##__VA_ARGS__)
/* debug event message: */ /* error event message: e.g., i/o error */
extern int cifsERROR; #define cifserror(fmt, ...) \
#define cEVENT(fmt, arg...) \
do { \ do { \
if (cifsERROR) \ if (cifsERROR) \
printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg); \ printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
} while (0)
/* error event message: e.g., i/o error */
#define cifserror(fmt, arg...) \
do { \
if (cifsERROR) \
printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg); \
} while (0) } while (0)
#define cERROR(set, fmt, arg...) \ #define cERROR(set, fmt, ...) \
do { \ do { \
if (set) \ if (set) \
cifserror(fmt, ##arg); \ cifserror(fmt, ##__VA_ARGS__); \
} while (0) } while (0)
/* /*
...@@ -87,10 +80,27 @@ do { \ ...@@ -87,10 +80,27 @@ do { \
* --------- * ---------
*/ */
#else /* _CIFS_DEBUG */ #else /* _CIFS_DEBUG */
#define cERROR(set, fmt, arg...) #define cifsfyi(fmt, ...) \
#define cEVENT(fmt, arg...) do { \
#define cFYI(set, fmt, arg...) if (0) \
#define cifserror(fmt, arg...) printk(KERN_DEBUG "%s: " fmt "\n", \
__FILE__, ##__VA_ARGS__); \
} while (0)
#define cFYI(set, fmt, ...) \
do { \
if (0 && set) \
cifsfyi(fmt, ##__VA_ARGS__); \
} while (0)
#define cifserror(fmt, ...) \
do { \
if (0) \
printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
} while (0)
#define cERROR(set, fmt, ...) \
do { \
if (0 && set) \
cifserror(fmt, ##__VA_ARGS__); \
} while (0)
#endif /* _CIFS_DEBUG */ #endif /* _CIFS_DEBUG */
#endif /* _H_CIFS_DEBUG */ #endif /* _H_CIFS_DEBUG */
This diff is collapsed.
...@@ -23,11 +23,8 @@ ...@@ -23,11 +23,8 @@
#define _CIFSACL_H #define _CIFSACL_H
#define NUM_AUTHS 6 /* number of authority fields */ #define NUM_AUTHS (6) /* number of authority fields */
#define NUM_SUBAUTHS 5 /* number of sub authority fields */ #define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */
#define NUM_WK_SIDS 7 /* number of well known sids */
#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
#define DEFSECDESCLEN 192 /* sec desc len contaiting a dacl with three aces */
#define READ_BIT 0x4 #define READ_BIT 0x4
#define WRITE_BIT 0x2 #define WRITE_BIT 0x2
...@@ -41,12 +38,32 @@ ...@@ -41,12 +38,32 @@
#define SIDOWNER 1 #define SIDOWNER 1
#define SIDGROUP 2 #define SIDGROUP 2
#define SIDLEN 150 /* S- 1 revision- 6 authorities- max 5 sub authorities */
#define SID_ID_MAPPED 0 /*
#define SID_ID_PENDING 1 * Security Descriptor length containing DACL with 3 ACEs (one each for
#define SID_MAP_EXPIRE (3600 * HZ) /* map entry expires after one hour */ * owner, group and world).
#define SID_MAP_RETRY (300 * HZ) /* wait 5 minutes for next attempt to map */ */
#define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \
sizeof(struct cifs_acl) + \
(sizeof(struct cifs_ace) * 3))
/*
* Maximum size of a string representation of a SID:
*
* The fields are unsigned values in decimal. So:
*
* u8: max 3 bytes in decimal
* u32: max 10 bytes in decimal
*
* "S-" + 3 bytes for version field + 15 for authority field + NULL terminator
*
* For authority field, max is when all 6 values are non-zero and it must be
* represented in hex. So "-0x" + 12 hex digits.
*
* Add 11 bytes for each subauthority field (10 bytes each + 1 for '-')
*/
#define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1)
#define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */
struct cifs_ntsd { struct cifs_ntsd {
__le16 revision; /* revision level */ __le16 revision; /* revision level */
...@@ -60,10 +77,13 @@ struct cifs_ntsd { ...@@ -60,10 +77,13 @@ struct cifs_ntsd {
struct cifs_sid { struct cifs_sid {
__u8 revision; /* revision level */ __u8 revision; /* revision level */
__u8 num_subauth; __u8 num_subauth;
__u8 authority[6]; __u8 authority[NUM_AUTHS];
__le32 sub_auth[5]; /* sub_auth[num_subauth] */ __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */
} __attribute__((packed)); } __attribute__((packed));
/* size of a struct cifs_sid, sans sub_auth array */
#define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS)
struct cifs_acl { struct cifs_acl {
__le16 revision; /* revision level */ __le16 revision; /* revision level */
__le16 size; __le16 size;
...@@ -78,26 +98,4 @@ struct cifs_ace { ...@@ -78,26 +98,4 @@ struct cifs_ace {
struct cifs_sid sid; /* ie UUID of user or group who gets these perms */ struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
} __attribute__((packed)); } __attribute__((packed));
struct cifs_wksid {
struct cifs_sid cifssid;
char sidname[SIDNAMELENGTH];
} __attribute__((packed));
struct cifs_sid_id {
unsigned int refcount; /* increment with spinlock, decrement without */
unsigned long id;
unsigned long time;
unsigned long state;
char *sidstr;
struct rb_node rbnode;
struct cifs_sid sid;
};
#ifdef __KERNEL__
extern struct key_type cifs_idmap_key_type;
extern const struct cred *root_cred;
#endif /* KERNEL */
extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
#endif /* _CIFSACL_H */ #endif /* _CIFSACL_H */
...@@ -64,24 +64,23 @@ unsigned int global_secflags = CIFSSEC_DEF; ...@@ -64,24 +64,23 @@ unsigned int global_secflags = CIFSSEC_DEF;
unsigned int sign_CIFS_PDUs = 1; unsigned int sign_CIFS_PDUs = 1;
static const struct super_operations cifs_super_ops; static const struct super_operations cifs_super_ops;
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
module_param(CIFSMaxBufSize, int, 0); module_param(CIFSMaxBufSize, uint, 0);
MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). " MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
"Default: 16384 Range: 8192 to 130048"); "Default: 16384 Range: 8192 to 130048");
unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
module_param(cifs_min_rcv, int, 0); module_param(cifs_min_rcv, uint, 0);
MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: " MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
"1 to 64"); "1 to 64");
unsigned int cifs_min_small = 30; unsigned int cifs_min_small = 30;
module_param(cifs_min_small, int, 0); module_param(cifs_min_small, uint, 0);
MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 " MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
"Range: 2 to 256"); "Range: 2 to 256");
unsigned int cifs_max_pending = CIFS_MAX_REQ; unsigned int cifs_max_pending = CIFS_MAX_REQ;
module_param(cifs_max_pending, int, 0444); module_param(cifs_max_pending, uint, 0444);
MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
"Default: 32767 Range: 2 to 32767."); "Default: 32767 Range: 2 to 32767.");
module_param(enable_oplocks, bool, 0644); module_param(enable_oplocks, bool, 0644);
MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks (bool). Default:" MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1");
"y/Y/1");
extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_req_poolp;
...@@ -230,6 +229,7 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -230,6 +229,7 @@ cifs_alloc_inode(struct super_block *sb)
cifs_set_oplock_level(cifs_inode, 0); cifs_set_oplock_level(cifs_inode, 0);
cifs_inode->delete_pending = false; cifs_inode->delete_pending = false;
cifs_inode->invalid_mapping = false; cifs_inode->invalid_mapping = false;
cifs_inode->leave_pages_clean = false;
cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode->server_eof = 0; cifs_inode->server_eof = 0;
cifs_inode->uniqueid = 0; cifs_inode->uniqueid = 0;
...@@ -540,8 +540,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) ...@@ -540,8 +540,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
char *s, *p; char *s, *p;
char sep; char sep;
full_path = build_path_to_root(vol, cifs_sb, full_path = cifs_build_path_to_root(vol, cifs_sb,
cifs_sb_master_tcon(cifs_sb)); cifs_sb_master_tcon(cifs_sb));
if (full_path == NULL) if (full_path == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -1205,7 +1205,6 @@ exit_cifs(void) ...@@ -1205,7 +1205,6 @@ exit_cifs(void)
unregister_filesystem(&cifs_fs_type); unregister_filesystem(&cifs_fs_type);
cifs_dfs_release_automount_timer(); cifs_dfs_release_automount_timer();
#ifdef CONFIG_CIFS_ACL #ifdef CONFIG_CIFS_ACL
cifs_destroy_idmaptrees();
exit_cifs_idmap(); exit_cifs_idmap();
#endif #endif
#ifdef CONFIG_CIFS_UPCALL #ifdef CONFIG_CIFS_UPCALL
......
...@@ -178,6 +178,7 @@ struct smb_rqst { ...@@ -178,6 +178,7 @@ struct smb_rqst {
enum smb_version { enum smb_version {
Smb_1 = 1, Smb_1 = 1,
Smb_20,
Smb_21, Smb_21,
Smb_30, Smb_30,
}; };
...@@ -280,9 +281,6 @@ struct smb_version_operations { ...@@ -280,9 +281,6 @@ struct smb_version_operations {
/* set attributes */ /* set attributes */
int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *, int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *,
const unsigned int); const unsigned int);
/* build a full path to the root of the mount */
char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
struct cifs_tcon *);
/* check if we can send an echo or nor */ /* check if we can send an echo or nor */
bool (*can_echo)(struct TCP_Server_Info *); bool (*can_echo)(struct TCP_Server_Info *);
/* send echo request */ /* send echo request */
...@@ -369,6 +367,8 @@ struct smb_version_operations { ...@@ -369,6 +367,8 @@ struct smb_version_operations {
void (*set_lease_key)(struct inode *, struct cifs_fid *fid); void (*set_lease_key)(struct inode *, struct cifs_fid *fid);
/* generate new lease key */ /* generate new lease key */
void (*new_lease_key)(struct cifs_fid *fid); void (*new_lease_key)(struct cifs_fid *fid);
int (*calc_signature)(struct smb_rqst *rqst,
struct TCP_Server_Info *server);
}; };
struct smb_version_values { struct smb_version_values {
...@@ -396,7 +396,6 @@ struct smb_vol { ...@@ -396,7 +396,6 @@ struct smb_vol {
char *password; char *password;
char *domainname; char *domainname;
char *UNC; char *UNC;
char *UNCip;
char *iocharset; /* local code page for mapping to and from Unicode */ char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
...@@ -444,11 +443,11 @@ struct smb_vol { ...@@ -444,11 +443,11 @@ struct smb_vol {
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
bool sockopt_tcp_nodelay:1; bool sockopt_tcp_nodelay:1;
unsigned short int port;
unsigned long actimeo; /* attribute cache timeout (jiffies) */ unsigned long actimeo; /* attribute cache timeout (jiffies) */
struct smb_version_operations *ops; struct smb_version_operations *ops;
struct smb_version_values *vals; struct smb_version_values *vals;
char *prepath; char *prepath;
struct sockaddr_storage dstaddr; /* destination address */
struct sockaddr_storage srcaddr; /* allow binding to a local IP */ struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls; struct nls_table *local_nls;
}; };
...@@ -1031,6 +1030,7 @@ struct cifsInodeInfo { ...@@ -1031,6 +1030,7 @@ struct cifsInodeInfo {
bool clientCanCacheAll; /* read and writebehind oplock */ bool clientCanCacheAll; /* read and writebehind oplock */
bool delete_pending; /* DELETE_ON_CLOSE is set */ bool delete_pending; /* DELETE_ON_CLOSE is set */
bool invalid_mapping; /* pagecache is invalid */ bool invalid_mapping; /* pagecache is invalid */
bool leave_pages_clean; /* protected by i_mutex, not set pages dirty */
unsigned long time; /* jiffies of last update of inode */ unsigned long time; /* jiffies of last update of inode */
u64 server_eof; /* current file size on server -- protected by i_lock */ u64 server_eof; /* current file size on server -- protected by i_lock */
u64 uniqueid; /* server inode number */ u64 uniqueid; /* server inode number */
...@@ -1067,30 +1067,16 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) ...@@ -1067,30 +1067,16 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
static inline void static inline void
convert_delimiter(char *path, char delim) convert_delimiter(char *path, char delim)
{ {
int i; char old_delim, *pos;
char old_delim;
if (path == NULL)
return;
if (delim == '/') if (delim == '/')
old_delim = '\\'; old_delim = '\\';
else else
old_delim = '/'; old_delim = '/';
for (i = 0; path[i] != '\0'; i++) { pos = path;
if (path[i] == old_delim) while ((pos = strchr(pos, old_delim)))
path[i] = delim; *pos = delim;
}
}
static inline char *
build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
if (!vol->ops->build_path_to_root)
return NULL;
return vol->ops->build_path_to_root(vol, cifs_sb, tcon);
} }
#ifdef CONFIG_CIFS_STATS #ifdef CONFIG_CIFS_STATS
...@@ -1362,7 +1348,7 @@ require use of the stronger protocol */ ...@@ -1362,7 +1348,7 @@ require use of the stronger protocol */
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */ #define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP) #define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMSSP)
#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2) #define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP) #define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
/* /*
...@@ -1506,6 +1492,6 @@ extern struct smb_version_values smb20_values; ...@@ -1506,6 +1492,6 @@ extern struct smb_version_values smb20_values;
extern struct smb_version_operations smb21_operations; extern struct smb_version_operations smb21_operations;
extern struct smb_version_values smb21_values; extern struct smb_version_values smb21_values;
#define SMB30_VERSION_STRING "3.0" #define SMB30_VERSION_STRING "3.0"
/*extern struct smb_version_operations smb30_operations; */ /* not needed yet */ extern struct smb_version_operations smb30_operations;
extern struct smb_version_values smb30_values; extern struct smb_version_values smb30_values;
#endif /* _CIFS_GLOB_H */ #endif /* _CIFS_GLOB_H */
...@@ -58,8 +58,10 @@ do { \ ...@@ -58,8 +58,10 @@ do { \
} while (0) } while (0)
extern int init_cifs_idmap(void); extern int init_cifs_idmap(void);
extern void exit_cifs_idmap(void); extern void exit_cifs_idmap(void);
extern void cifs_destroy_idmaptrees(void);
extern char *build_path_from_dentry(struct dentry *); extern char *build_path_from_dentry(struct dentry *);
extern char *cifs_build_path_to_root(struct smb_vol *vol,
struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern char *cifs_compose_mount_options(const char *sb_mountdata, extern char *cifs_compose_mount_options(const char *sb_mountdata,
const char *fullpath, const struct dfs_info3_param *ref, const char *fullpath, const struct dfs_info3_param *ref,
...@@ -107,9 +109,7 @@ extern unsigned int smbCalcSize(void *buf); ...@@ -107,9 +109,7 @@ extern unsigned int smbCalcSize(void *buf);
extern int decode_negTokenInit(unsigned char *security_blob, int length, extern int decode_negTokenInit(unsigned char *security_blob, int length,
struct TCP_Server_Info *server); struct TCP_Server_Info *server);
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
const unsigned short int port);
extern int map_smb_to_linux_error(char *buf, bool logErr); extern int map_smb_to_linux_error(char *buf, bool logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ , extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifs_tcon *, int /* length of const struct cifs_tcon *, int /* length of
...@@ -185,7 +185,7 @@ extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon); ...@@ -185,7 +185,7 @@ extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
__u64 length, __u8 type, __u64 length, __u8 type,
struct cifsLockInfo **conf_lock, struct cifsLockInfo **conf_lock,
bool rw_check); int rw_check);
extern void cifs_add_pending_open(struct cifs_fid *fid, extern void cifs_add_pending_open(struct cifs_fid *fid,
struct tcon_link *tlink, struct tcon_link *tlink,
struct cifs_pending_open *open); struct cifs_pending_open *open);
......
This diff is collapsed.
...@@ -44,6 +44,38 @@ renew_parental_timestamps(struct dentry *direntry) ...@@ -44,6 +44,38 @@ renew_parental_timestamps(struct dentry *direntry)
} while (!IS_ROOT(direntry)); } while (!IS_ROOT(direntry));
} }
char *
cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
int dfsplen;
char *full_path = NULL;
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
full_path = kzalloc(1, GFP_KERNEL);
return full_path;
}
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
if (full_path == NULL)
return full_path;
if (dfsplen)
strncpy(full_path, tcon->treeName, dfsplen);
full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path;
}
/* Note: caller must free return buffer */ /* Note: caller must free return buffer */
char * char *
build_path_from_dentry(struct dentry *direntry) build_path_from_dentry(struct dentry *direntry)
......
This diff is collapsed.
...@@ -1791,11 +1791,12 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, ...@@ -1791,11 +1791,12 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
stat->ino = CIFS_I(inode)->uniqueid; stat->ino = CIFS_I(inode)->uniqueid;
/* /*
* If on a multiuser mount without unix extensions, and the admin hasn't * If on a multiuser mount without unix extensions or cifsacl being
* overridden them, set the ownership to the fsuid/fsgid of the current * enabled, and the admin hasn't overridden them, set the ownership
* process. * to the fsuid/fsgid of the current process.
*/ */
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
!tcon->unix_ext) { !tcon->unix_ext) {
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
stat->uid = current_fsuid(); stat->uid = current_fsuid();
......
...@@ -204,7 +204,7 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len) ...@@ -204,7 +204,7 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len)
return rc; return rc;
} }
int void
cifs_set_port(struct sockaddr *addr, const unsigned short int port) cifs_set_port(struct sockaddr *addr, const unsigned short int port)
{ {
switch (addr->sa_family) { switch (addr->sa_family) {
...@@ -214,19 +214,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port) ...@@ -214,19 +214,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port)
case AF_INET6: case AF_INET6:
((struct sockaddr_in6 *)addr)->sin6_port = htons(port); ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
break; break;
default:
return 0;
} }
return 1;
}
int
cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
const unsigned short int port)
{
if (!cifs_convert_address(dst, src, len))
return 0;
return cifs_set_port(dst, port);
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -66,18 +66,20 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) ...@@ -66,18 +66,20 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
#endif /* DEBUG2 */ #endif /* DEBUG2 */
/* /*
* Attempt to preload the dcache with the results from the FIND_FIRST/NEXT
*
* Find the dentry that matches "name". If there isn't one, create one. If it's * Find the dentry that matches "name". If there isn't one, create one. If it's
* a negative dentry or the uniqueid changed, then drop it and recreate it. * a negative dentry or the uniqueid changed, then drop it and recreate it.
*/ */
static struct dentry * static void
cifs_readdir_lookup(struct dentry *parent, struct qstr *name, cifs_prime_dcache(struct dentry *parent, struct qstr *name,
struct cifs_fattr *fattr) struct cifs_fattr *fattr)
{ {
struct dentry *dentry, *alias; struct dentry *dentry, *alias;
struct inode *inode; struct inode *inode;
struct super_block *sb = parent->d_inode->i_sb; struct super_block *sb = parent->d_inode->i_sb;
cFYI(1, "For %s", name->name); cFYI(1, "%s: for %s", __func__, name->name);
if (parent->d_op && parent->d_op->d_hash) if (parent->d_op && parent->d_op->d_hash)
parent->d_op->d_hash(parent, parent->d_inode, name); parent->d_op->d_hash(parent, parent->d_inode, name);
...@@ -87,37 +89,32 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, ...@@ -87,37 +89,32 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
dentry = d_lookup(parent, name); dentry = d_lookup(parent, name);
if (dentry) { if (dentry) {
int err; int err;
inode = dentry->d_inode; inode = dentry->d_inode;
/* update inode in place if i_ino didn't change */ /* update inode in place if i_ino didn't change */
if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
cifs_fattr_to_inode(inode, fattr); cifs_fattr_to_inode(inode, fattr);
return dentry; goto out;
} }
err = d_invalidate(dentry); err = d_invalidate(dentry);
dput(dentry); dput(dentry);
if (err) if (err)
return NULL; return;
} }
dentry = d_alloc(parent, name); dentry = d_alloc(parent, name);
if (dentry == NULL) if (!dentry)
return NULL; return;
inode = cifs_iget(sb, fattr); inode = cifs_iget(sb, fattr);
if (!inode) { if (!inode)
dput(dentry); goto out;
return NULL;
}
alias = d_materialise_unique(dentry, inode); alias = d_materialise_unique(dentry, inode);
if (alias != NULL) { if (alias && !IS_ERR(alias))
dput(dentry); dput(alias);
if (IS_ERR(alias)) out:
return NULL; dput(dentry);
dentry = alias;
}
return dentry;
} }
static void static void
...@@ -137,6 +134,16 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) ...@@ -137,6 +134,16 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
if (fattr->cf_cifsattrs & ATTR_READONLY) if (fattr->cf_cifsattrs & ATTR_READONLY)
fattr->cf_mode &= ~S_IWUGO; fattr->cf_mode &= ~S_IWUGO;
/*
* We of course don't get ACL info in FIND_FIRST/NEXT results, so
* mark it for revalidation so that "ls -l" will look right. It might
* be super-slow, but if we don't do this then the ownership of files
* may look wrong since the inodes may not have timed out by the time
* "ls" does a stat() call on them.
*/
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
fattr->cf_cifsattrs & ATTR_SYSTEM) { fattr->cf_cifsattrs & ATTR_SYSTEM) {
if (fattr->cf_eof == 0) { if (fattr->cf_eof == 0) {
...@@ -652,7 +659,6 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir, ...@@ -652,7 +659,6 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_dirent de = { NULL, }; struct cifs_dirent de = { NULL, };
struct cifs_fattr fattr; struct cifs_fattr fattr;
struct dentry *dentry;
struct qstr name; struct qstr name;
int rc = 0; int rc = 0;
ino_t ino; ino_t ino;
...@@ -723,13 +729,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir, ...@@ -723,13 +729,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
*/ */
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); cifs_prime_dcache(file->f_dentry, &name, &fattr);
dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
rc = filldir(dirent, name.name, name.len, file->f_pos, ino, rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
fattr.cf_dtype); fattr.cf_dtype);
dput(dentry);
return rc; return rc;
} }
......
...@@ -575,37 +575,6 @@ cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -575,37 +575,6 @@ cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data); return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
} }
static char *
cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
int dfsplen;
char *full_path = NULL;
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
full_path = kzalloc(1, GFP_KERNEL);
return full_path;
}
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
if (full_path == NULL)
return full_path;
if (dfsplen)
strncpy(full_path, tcon->treeName, dfsplen);
strncpy(full_path + dfsplen, vol->prepath, pplen);
convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path;
}
static void static void
cifs_clear_stats(struct cifs_tcon *tcon) cifs_clear_stats(struct cifs_tcon *tcon)
{ {
...@@ -943,7 +912,6 @@ struct smb_version_operations smb1_operations = { ...@@ -943,7 +912,6 @@ struct smb_version_operations smb1_operations = {
.set_path_size = CIFSSMBSetEOF, .set_path_size = CIFSSMBSetEOF,
.set_file_size = CIFSSMBSetFileSize, .set_file_size = CIFSSMBSetFileSize,
.set_file_info = smb_set_file_info, .set_file_info = smb_set_file_info,
.build_path_to_root = cifs_build_path_to_root,
.echo = CIFSSMBEcho, .echo = CIFSSMBEcho,
.mkdir = CIFSSMBMkDir, .mkdir = CIFSSMBMkDir,
.mkdir_setinfo = cifs_mkdir_setinfo, .mkdir_setinfo = cifs_mkdir_setinfo,
......
...@@ -260,13 +260,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) ...@@ -260,13 +260,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
struct cifs_fid_locks *fdlocks; struct cifs_fid_locks *fdlocks;
xid = get_xid(); xid = get_xid();
/* we are going to update can_cache_brlcks here - need a write access */
down_write(&cinode->lock_sem);
if (!cinode->can_cache_brlcks) {
up_write(&cinode->lock_sem);
free_xid(xid);
return rc;
}
/* /*
* Accessing maxBuf is racy with cifs_reconnect - need to store value * Accessing maxBuf is racy with cifs_reconnect - need to store value
...@@ -274,7 +267,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) ...@@ -274,7 +267,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
*/ */
max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
if (!max_buf) { if (!max_buf) {
up_write(&cinode->lock_sem);
free_xid(xid); free_xid(xid);
return -EINVAL; return -EINVAL;
} }
...@@ -282,7 +274,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) ...@@ -282,7 +274,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
max_num = max_buf / sizeof(struct smb2_lock_element); max_num = max_buf / sizeof(struct smb2_lock_element);
buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL);
if (!buf) { if (!buf) {
up_write(&cinode->lock_sem);
free_xid(xid); free_xid(xid);
return -ENOMEM; return -ENOMEM;
} }
...@@ -293,10 +284,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) ...@@ -293,10 +284,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
rc = stored_rc; rc = stored_rc;
} }
cinode->can_cache_brlcks = false;
kfree(buf); kfree(buf);
up_write(&cinode->lock_sem);
free_xid(xid); free_xid(xid);
return rc; return rc;
} }
...@@ -262,23 +262,6 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -262,23 +262,6 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
return rc; return rc;
} }
static char *
smb2_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
char *full_path = NULL;
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
full_path = kzalloc(2, GFP_KERNEL);
return full_path;
}
cERROR(1, "prefixpath is not supported for SMB2 now");
return NULL;
}
static bool static bool
smb2_can_echo(struct TCP_Server_Info *server) smb2_can_echo(struct TCP_Server_Info *server)
{ {
...@@ -613,7 +596,6 @@ struct smb_version_operations smb21_operations = { ...@@ -613,7 +596,6 @@ struct smb_version_operations smb21_operations = {
.set_path_size = smb2_set_path_size, .set_path_size = smb2_set_path_size,
.set_file_size = smb2_set_file_size, .set_file_size = smb2_set_file_size,
.set_file_info = smb2_set_file_info, .set_file_info = smb2_set_file_info,
.build_path_to_root = smb2_build_path_to_root,
.mkdir = smb2_mkdir, .mkdir = smb2_mkdir,
.mkdir_setinfo = smb2_mkdir_setinfo, .mkdir_setinfo = smb2_mkdir_setinfo,
.rmdir = smb2_rmdir, .rmdir = smb2_rmdir,
...@@ -641,6 +623,91 @@ struct smb_version_operations smb21_operations = { ...@@ -641,6 +623,91 @@ struct smb_version_operations smb21_operations = {
.get_lease_key = smb2_get_lease_key, .get_lease_key = smb2_get_lease_key,
.set_lease_key = smb2_set_lease_key, .set_lease_key = smb2_set_lease_key,
.new_lease_key = smb2_new_lease_key, .new_lease_key = smb2_new_lease_key,
.calc_signature = smb2_calc_signature,
};
struct smb_version_operations smb30_operations = {
.compare_fids = smb2_compare_fids,
.setup_request = smb2_setup_request,
.setup_async_request = smb2_setup_async_request,
.check_receive = smb2_check_receive,
.add_credits = smb2_add_credits,
.set_credits = smb2_set_credits,
.get_credits_field = smb2_get_credits_field,
.get_credits = smb2_get_credits,
.get_next_mid = smb2_get_next_mid,
.read_data_offset = smb2_read_data_offset,
.read_data_length = smb2_read_data_length,
.map_error = map_smb2_to_linux_error,
.find_mid = smb2_find_mid,
.check_message = smb2_check_message,
.dump_detail = smb2_dump_detail,
.clear_stats = smb2_clear_stats,
.print_stats = smb2_print_stats,
.is_oplock_break = smb2_is_valid_oplock_break,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
.negotiate_rsize = smb2_negotiate_rsize,
.sess_setup = SMB2_sess_setup,
.logoff = SMB2_logoff,
.tree_connect = SMB2_tcon,
.tree_disconnect = SMB2_tdis,
.is_path_accessible = smb2_is_path_accessible,
.can_echo = smb2_can_echo,
.echo = SMB2_echo,
.query_path_info = smb2_query_path_info,
.get_srv_inum = smb2_get_srv_inum,
.query_file_info = smb2_query_file_info,
.set_path_size = smb2_set_path_size,
.set_file_size = smb2_set_file_size,
.set_file_info = smb2_set_file_info,
.mkdir = smb2_mkdir,
.mkdir_setinfo = smb2_mkdir_setinfo,
.rmdir = smb2_rmdir,
.unlink = smb2_unlink,
.rename = smb2_rename_path,
.create_hardlink = smb2_create_hardlink,
.open = smb2_open_file,
.set_fid = smb2_set_fid,
.close = smb2_close_file,
.flush = smb2_flush_file,
.async_readv = smb2_async_readv,
.async_writev = smb2_async_writev,
.sync_read = smb2_sync_read,
.sync_write = smb2_sync_write,
.query_dir_first = smb2_query_dir_first,
.query_dir_next = smb2_query_dir_next,
.close_dir = smb2_close_dir,
.calc_smb_size = smb2_calc_size,
.is_status_pending = smb2_is_status_pending,
.oplock_response = smb2_oplock_response,
.queryfs = smb2_queryfs,
.mand_lock = smb2_mand_lock,
.mand_unlock_range = smb2_unlock_range,
.push_mand_locks = smb2_push_mandatory_locks,
.get_lease_key = smb2_get_lease_key,
.set_lease_key = smb2_set_lease_key,
.new_lease_key = smb2_new_lease_key,
.calc_signature = smb3_calc_signature,
};
struct smb_version_values smb20_values = {
.version_string = SMB20_VERSION_STRING,
.protocol_id = SMB20_PROT_ID,
.req_capabilities = 0, /* MBZ */
.large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr),
.max_header_size = MAX_SMB2_HDR_SIZE,
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
.lock_cmd = SMB2_LOCK,
.cap_unix = 0,
.cap_nt_find = SMB2_NT_FIND,
.cap_large_files = SMB2_LARGE_FILES,
}; };
struct smb_version_values smb21_values = { struct smb_version_values smb21_values = {
......
...@@ -425,7 +425,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) ...@@ -425,7 +425,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
} }
cFYI(1, "sec_flags 0x%x", sec_flags); cFYI(1, "sec_flags 0x%x", sec_flags);
if (sec_flags & CIFSSEC_MUST_SIGN) { if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
cFYI(1, "Signing required"); cFYI(1, "Signing required");
if (!(server->sec_mode & (SMB2_NEGOTIATE_SIGNING_REQUIRED | if (!(server->sec_mode & (SMB2_NEGOTIATE_SIGNING_REQUIRED |
SMB2_NEGOTIATE_SIGNING_ENABLED))) { SMB2_NEGOTIATE_SIGNING_ENABLED))) {
...@@ -612,7 +612,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, ...@@ -612,7 +612,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
/* BB add code to build os and lm fields */ /* BB add code to build os and lm fields */
rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, CIFS_LOG_ERROR); rc = SendReceive2(xid, ses, iov, 2, &resp_buftype,
CIFS_LOG_ERROR | CIFS_NEG_OP);
kfree(security_blob); kfree(security_blob);
rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base; rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base;
......
...@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, ...@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
struct smb_rqst *rqst); struct smb_rqst *rqst);
extern struct mid_q_entry *smb2_setup_async_request( extern struct mid_q_entry *smb2_setup_async_request(
struct TCP_Server_Info *server, struct smb_rqst *rqst); struct TCP_Server_Info *server, struct smb_rqst *rqst);
extern int smb2_calc_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server);
extern int smb3_calc_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server);
extern void smb2_echo_request(struct work_struct *work); extern void smb2_echo_request(struct work_struct *work);
extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode); extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode);
extern __u8 smb2_map_lease_to_oplock(__le32 lease_state); extern __u8 smb2_map_lease_to_oplock(__le32 lease_state);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "smb2status.h" #include "smb2status.h"
#include "smb2glob.h" #include "smb2glob.h"
static int int
smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
{ {
int i, rc; int i, rc;
...@@ -116,6 +116,13 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -116,6 +116,13 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
return rc; return rc;
} }
int
smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
{
cFYI(1, "smb3 signatures not supported yet");
return -EOPNOTSUPP;
}
/* must be called with server->srv_mutex held */ /* must be called with server->srv_mutex held */
static int static int
smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
...@@ -132,7 +139,7 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -132,7 +139,7 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
return rc; return rc;
} }
rc = smb2_calc_signature(rqst, server); rc = server->ops->calc_signature(rqst, server);
return rc; return rc;
} }
...@@ -168,7 +175,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -168,7 +175,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE); memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
mutex_lock(&server->srv_mutex); mutex_lock(&server->srv_mutex);
rc = smb2_calc_signature(rqst, server); rc = server->ops->calc_signature(rqst, server);
mutex_unlock(&server->srv_mutex); mutex_unlock(&server->srv_mutex);
if (rc) if (rc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment