Commit 797b9e5a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull CIFS updates from Steve French:
 "This patchset is the final section of the SMB2.1 support merge for
  cifs.ko.  It also includes improvements to the cifs socket handling
  from Jeff, and also fixes a few cifs bug fixes.  It adds SMB2 support
  for file and inode operations as well as moves some existing cifs code
  to use ops server struct of protocol specific callbacks.

  Most of this code is SMB2 specific.  When enabled SMB2.1 does pass
  various functional tests including most of the connectathon test
  suite, For SMB2.1, Connectathon test 4 and some related tests fail due
  to not updating mode bits remotely (cifsacl support where mode bits
  are approximated with the cifs acl is not enable for smb2), and test8
  (symlink) support is not completed for SMB2 yet (note that we will
  likely have a "Unix Extensions" eventually, at least for Samba, so in
  the long run posix locks won't have to be emulated when mounting Linux
  to Linux, but for most NAS and for Windows mounts posix lock emulation
  will still used for SMB2 in a similar fashion as we do for cifs).

  SMB2.1 dialect is supported.  Although additional fixes to enable smb2
  (the original smb2.02) dialect and to add various optional features of
  the smb3 dialect are expected to be added in the future as testing
  progresses, currently mounting with the "vers=2.1" is supported (in
  order to mount using SMB2.1 to servers like Samba 4, and Windows 7,
  Windows 2008R2)."

* 'for-linus' of git://git.samba.org/sfrench/cifs-2.6: (82 commits)
  [CIFS] Fix indentation of fs/cifs/Kconfig entries
  [CIFS] Fix SMB2 negotiation support to select only one dialect (based on vers=)
  cifs: obtain file access during backup intent lookup (resend)
  CIFS: Fix possible freed pointer dereference in CIFS_SessSetup
  CIFS: Fix possible freed pointer dereference in SMB2_sess_setup
  CIFS: Make ops->close return void
  cifs: change DOS/NT/POSIX mapping of ERRnoresource
  cifs: remove support for deprecated "forcedirectio" and "strictcache" mount options
  cifs: remove support for CIFS_IOC_CHECKUMOUNT ioctl
  CIFS: Fix possible memory leaks in SMB2 code
  CIFS: Fix endian conversion of IndexNumber
  Trivial endian fixes
  MARK SMB2 support EXPERIMENTAL
  Update cifs version number
  cifs: add FL_CLOSE to fl_flags mask in cifs_read_flock
  cifs: Mangle string used for unc in /proc/mounts
  cifs: cleanups for cifs_mkdir_qinfo
  CIFS: Fix fast lease break after open problem
  CIFS: Add SMB2.1 lease break support
  CIFS: Fix cache coherency for read oplock case
  ...
parents 9c0ece06 1d4ab907
...@@ -9,13 +9,14 @@ config CIFS ...@@ -9,13 +9,14 @@ config CIFS
select CRYPTO_ARC4 select CRYPTO_ARC4
select CRYPTO_ECB select CRYPTO_ECB
select CRYPTO_DES select CRYPTO_DES
select CRYPTO_SHA256
help help
This is the client VFS module for the Common Internet File System This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block (CIFS) protocol which is the successor to the Server Message Block
(SMB) protocol, the native file sharing mechanism for most early (SMB) protocol, the native file sharing mechanism for most early
PC operating systems. The CIFS protocol is fully supported by PC operating systems. The CIFS protocol is fully supported by
file servers such as Windows 2000 (including Windows 2003, NT 4 file servers such as Windows 2000 (including Windows 2003, Windows 2008,
and Windows XP) as well by Samba (which provides excellent CIFS NT 4 and Windows XP) as well by Samba (which provides excellent CIFS
server support for Linux and many other operating systems). Limited server support for Linux and many other operating systems). Limited
support for OS/2 and Windows ME and similar servers is provided as support for OS/2 and Windows ME and similar servers is provided as
well. well.
...@@ -114,6 +115,13 @@ config CIFS_POSIX ...@@ -114,6 +115,13 @@ config CIFS_POSIX
(such as Samba 3.10 and later) which can negotiate (such as Samba 3.10 and later) which can negotiate
CIFS POSIX ACL support. If unsure, say N. CIFS POSIX ACL support. If unsure, say N.
config CIFS_ACL
bool "Provide CIFS ACL support"
depends on CIFS_XATTR && KEYS
help
Allows fetching CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
config CIFS_DEBUG2 config CIFS_DEBUG2
bool "Enable additional CIFS debugging routines" bool "Enable additional CIFS debugging routines"
depends on CIFS depends on CIFS
...@@ -138,21 +146,6 @@ config CIFS_DFS_UPCALL ...@@ -138,21 +146,6 @@ config CIFS_DFS_UPCALL
IP addresses) which is needed for implicit mounts of DFS junction IP addresses) which is needed for implicit mounts of DFS junction
points. If unsure, say N. points. If unsure, say N.
config CIFS_FSCACHE
bool "Provide CIFS client caching support"
depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
help
Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
to be cached locally on disk through the general filesystem cache
manager. If unsure, say N.
config CIFS_ACL
bool "Provide CIFS ACL support"
depends on CIFS_XATTR && KEYS
help
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
config CIFS_NFSD_EXPORT config CIFS_NFSD_EXPORT
bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL && BROKEN depends on CIFS && EXPERIMENTAL && BROKEN
...@@ -161,7 +154,7 @@ config CIFS_NFSD_EXPORT ...@@ -161,7 +154,7 @@ config CIFS_NFSD_EXPORT
config CIFS_SMB2 config CIFS_SMB2
bool "SMB2 network file system support (EXPERIMENTAL)" bool "SMB2 network file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL && INET && BROKEN depends on CIFS && EXPERIMENTAL && INET
select NLS select NLS
select KEYS select KEYS
select FSCACHE select FSCACHE
...@@ -178,3 +171,12 @@ config CIFS_SMB2 ...@@ -178,3 +171,12 @@ config CIFS_SMB2
(compared to cifs) due to protocol improvements. (compared to cifs) due to protocol improvements.
Unless you are a developer or tester, say N. Unless you are a developer or tester, say N.
config CIFS_FSCACHE
bool "Provide CIFS client caching support"
depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
help
Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
to be cached locally on disk through the general filesystem cache
manager. If unsure, say N.
...@@ -17,4 +17,4 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o ...@@ -17,4 +17,4 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \ cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o smb2misc.o smb2pdu.o smb2inode.o smb2file.o
...@@ -1222,7 +1222,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, ...@@ -1222,7 +1222,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
if (!open_file) if (!open_file)
return get_cifs_acl_by_path(cifs_sb, path, pacllen); return get_cifs_acl_by_path(cifs_sb, path, pacllen);
pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen); pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
cifsFileInfo_put(open_file); cifsFileInfo_put(open_file);
return pntsd; return pntsd;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "ntlmssp.h" #include "ntlmssp.h"
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/highmem.h>
/* /*
* Calculate and return the CIFS signature based on the mac key and SMB PDU. * Calculate and return the CIFS signature based on the mac key and SMB PDU.
...@@ -37,11 +38,13 @@ ...@@ -37,11 +38,13 @@
* the sequence number before this function is called. Also, this function * the sequence number before this function is called. Also, this function
* should be called with the server->srv_mutex held. * should be called with the server->srv_mutex held.
*/ */
static int cifs_calc_signature(const struct kvec *iov, int n_vec, static int cifs_calc_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server, char *signature) struct TCP_Server_Info *server, char *signature)
{ {
int i; int i;
int rc; int rc;
struct kvec *iov = rqst->rq_iov;
int n_vec = rqst->rq_nvec;
if (iov == NULL || signature == NULL || server == NULL) if (iov == NULL || signature == NULL || server == NULL)
return -EINVAL; return -EINVAL;
...@@ -91,6 +94,16 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec, ...@@ -91,6 +94,16 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
} }
} }
/* now hash over the rq_pages array */
for (i = 0; i < rqst->rq_npages; i++) {
struct kvec p_iov;
cifs_rqst_page_to_kvec(rqst, i, &p_iov);
crypto_shash_update(&server->secmech.sdescmd5->shash,
p_iov.iov_base, p_iov.iov_len);
kunmap(rqst->rq_pages[i]);
}
rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
if (rc) if (rc)
cERROR(1, "%s: Could not generate md5 hash", __func__); cERROR(1, "%s: Could not generate md5 hash", __func__);
...@@ -99,12 +112,12 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec, ...@@ -99,12 +112,12 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
} }
/* must be called with server->srv_mutex held */ /* must be called with server->srv_mutex held */
int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number) __u32 *pexpected_response_sequence_number)
{ {
int rc = 0; int rc = 0;
char smb_signature[20]; char smb_signature[20];
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base; struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
if ((cifs_pdu == NULL) || (server == NULL)) if ((cifs_pdu == NULL) || (server == NULL))
return -EINVAL; return -EINVAL;
...@@ -125,7 +138,7 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, ...@@ -125,7 +138,7 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
*pexpected_response_sequence_number = server->sequence_number++; *pexpected_response_sequence_number = server->sequence_number++;
server->sequence_number++; server->sequence_number++;
rc = cifs_calc_signature(iov, n_vec, server, smb_signature); rc = cifs_calc_signature(rqst, server, smb_signature);
if (rc) if (rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8); memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
else else
...@@ -134,6 +147,15 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, ...@@ -134,6 +147,15 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
return rc; return rc;
} }
int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence)
{
struct smb_rqst rqst = { .rq_iov = iov,
.rq_nvec = n_vec };
return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
}
/* must be called with server->srv_mutex held */ /* must be called with server->srv_mutex held */
int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number) __u32 *pexpected_response_sequence_number)
...@@ -147,14 +169,14 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, ...@@ -147,14 +169,14 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
pexpected_response_sequence_number); pexpected_response_sequence_number);
} }
int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, int cifs_verify_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server, struct TCP_Server_Info *server,
__u32 expected_sequence_number) __u32 expected_sequence_number)
{ {
unsigned int rc; unsigned int rc;
char server_response_sig[8]; char server_response_sig[8];
char what_we_think_sig_should_be[20]; char what_we_think_sig_should_be[20];
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base; struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
if (cifs_pdu == NULL || server == NULL) if (cifs_pdu == NULL || server == NULL)
return -EINVAL; return -EINVAL;
...@@ -186,8 +208,7 @@ int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, ...@@ -186,8 +208,7 @@ int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
cifs_pdu->Signature.Sequence.Reserved = 0; cifs_pdu->Signature.Sequence.Reserved = 0;
mutex_lock(&server->srv_mutex); mutex_lock(&server->srv_mutex);
rc = cifs_calc_signature(iov, nr_iov, server, rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
what_we_think_sig_should_be);
mutex_unlock(&server->srv_mutex); mutex_unlock(&server->srv_mutex);
if (rc) if (rc)
...@@ -686,12 +707,17 @@ calc_seckey(struct cifs_ses *ses) ...@@ -686,12 +707,17 @@ calc_seckey(struct cifs_ses *ses)
void void
cifs_crypto_shash_release(struct TCP_Server_Info *server) cifs_crypto_shash_release(struct TCP_Server_Info *server)
{ {
if (server->secmech.hmacsha256)
crypto_free_shash(server->secmech.hmacsha256);
if (server->secmech.md5) if (server->secmech.md5)
crypto_free_shash(server->secmech.md5); crypto_free_shash(server->secmech.md5);
if (server->secmech.hmacmd5) if (server->secmech.hmacmd5)
crypto_free_shash(server->secmech.hmacmd5); crypto_free_shash(server->secmech.hmacmd5);
kfree(server->secmech.sdeschmacsha256);
kfree(server->secmech.sdeschmacmd5); kfree(server->secmech.sdeschmacmd5);
kfree(server->secmech.sdescmd5); kfree(server->secmech.sdescmd5);
...@@ -716,6 +742,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server) ...@@ -716,6 +742,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
goto crypto_allocate_md5_fail; goto crypto_allocate_md5_fail;
} }
server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
if (IS_ERR(server->secmech.hmacsha256)) {
cERROR(1, "could not allocate crypto hmacsha256\n");
rc = PTR_ERR(server->secmech.hmacsha256);
goto crypto_allocate_hmacsha256_fail;
}
size = sizeof(struct shash_desc) + size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.hmacmd5); crypto_shash_descsize(server->secmech.hmacmd5);
server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
...@@ -727,7 +760,6 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server) ...@@ -727,7 +760,6 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
server->secmech.sdeschmacmd5->shash.flags = 0x0; server->secmech.sdeschmacmd5->shash.flags = 0x0;
size = sizeof(struct shash_desc) + size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.md5); crypto_shash_descsize(server->secmech.md5);
server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
...@@ -739,12 +771,29 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server) ...@@ -739,12 +771,29 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
server->secmech.sdescmd5->shash.tfm = server->secmech.md5; server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
server->secmech.sdescmd5->shash.flags = 0x0; server->secmech.sdescmd5->shash.flags = 0x0;
size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.hmacsha256);
server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
if (!server->secmech.sdeschmacsha256) {
cERROR(1, "%s: Can't alloc hmacsha256\n", __func__);
rc = -ENOMEM;
goto crypto_allocate_hmacsha256_sdesc_fail;
}
server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
server->secmech.sdeschmacsha256->shash.flags = 0x0;
return 0; return 0;
crypto_allocate_hmacsha256_sdesc_fail:
kfree(server->secmech.sdescmd5);
crypto_allocate_md5_sdesc_fail: crypto_allocate_md5_sdesc_fail:
kfree(server->secmech.sdeschmacmd5); kfree(server->secmech.sdeschmacmd5);
crypto_allocate_hmacmd5_sdesc_fail: crypto_allocate_hmacmd5_sdesc_fail:
crypto_free_shash(server->secmech.hmacsha256);
crypto_allocate_hmacsha256_fail:
crypto_free_shash(server->secmech.md5); crypto_free_shash(server->secmech.md5);
crypto_allocate_md5_fail: crypto_allocate_md5_fail:
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/random.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include "cifsfs.h" #include "cifsfs.h"
#include "cifspdu.h" #include "cifspdu.h"
...@@ -51,7 +52,6 @@ ...@@ -51,7 +52,6 @@
#ifdef CONFIG_CIFS_SMB2 #ifdef CONFIG_CIFS_SMB2
#include "smb2pdu.h" #include "smb2pdu.h"
#endif #endif
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
int cifsFYI = 0; int cifsFYI = 0;
int cifsERROR = 1; int cifsERROR = 1;
...@@ -89,6 +89,10 @@ extern mempool_t *cifs_mid_poolp; ...@@ -89,6 +89,10 @@ extern mempool_t *cifs_mid_poolp;
struct workqueue_struct *cifsiod_wq; struct workqueue_struct *cifsiod_wq;
#ifdef CONFIG_CIFS_SMB2
__u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];
#endif
static int static int
cifs_read_super(struct super_block *sb) cifs_read_super(struct super_block *sb)
{ {
...@@ -160,13 +164,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -160,13 +164,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int rc = -EOPNOTSUPP; struct TCP_Server_Info *server = tcon->ses->server;
unsigned int xid; unsigned int xid;
int rc = 0;
xid = get_xid(); xid = get_xid();
buf->f_type = CIFS_MAGIC_NUMBER;
/* /*
* PATH_MAX may be too long - it would presumably be total path, * PATH_MAX may be too long - it would presumably be total path,
* but note that some servers (includinng Samba 3) have a shorter * but note that some servers (includinng Samba 3) have a shorter
...@@ -178,27 +181,8 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -178,27 +181,8 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_files = 0; /* undefined */ buf->f_files = 0; /* undefined */
buf->f_ffree = 0; /* unlimited */ buf->f_ffree = 0; /* unlimited */
/* if (server->ops->queryfs)
* We could add a second check for a QFS Unix capability bit rc = server->ops->queryfs(xid, tcon, buf);
*/
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
/*
* Only need to call the old QFSInfo if failed on newer one,
* e.g. by OS/2.
**/
if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
rc = CIFSSMBQFSInfo(xid, tcon, buf);
/*
* Some old Windows servers also do not support level 103, retry with
* older level one if old server failed the previous call or we
* bypassed it because we detected that this was an older LANMAN sess
*/
if (rc)
rc = SMBOldQFSInfo(xid, tcon, buf);
free_xid(xid); free_xid(xid);
return 0; return 0;
...@@ -239,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -239,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb)
return NULL; return NULL;
cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->cifsAttrs = 0x20; /* default */
cifs_inode->time = 0; cifs_inode->time = 0;
/* Until the file is open and we have gotten oplock /*
info back from the server, can not assume caching of * Until the file is open and we have gotten oplock info back from the
file data or metadata */ * server, can not assume caching of file data or metadata.
*/
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;
...@@ -249,11 +234,16 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -249,11 +234,16 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->server_eof = 0; cifs_inode->server_eof = 0;
cifs_inode->uniqueid = 0; cifs_inode->uniqueid = 0;
cifs_inode->createtime = 0; cifs_inode->createtime = 0;
#ifdef CONFIG_CIFS_SMB2
/* Can not set i_flags here - they get immediately overwritten get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE);
to zero by the VFS */ #endif
/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/ /*
* Can not set i_flags here - they get immediately overwritten to zero
* by the VFS.
*/
/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */
INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->openFileList);
INIT_LIST_HEAD(&cifs_inode->llist);
return &cifs_inode->vfs_inode; return &cifs_inode->vfs_inode;
} }
...@@ -360,7 +350,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) ...@@ -360,7 +350,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
cifs_show_security(s, tcon->ses->server); cifs_show_security(s, tcon->ses->server);
cifs_show_cache_flavor(s, cifs_sb); cifs_show_cache_flavor(s, cifs_sb);
seq_printf(s, ",unc=%s", tcon->treeName); seq_printf(s, ",unc=");
seq_escape(s, tcon->treeName, " \t\n\\");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
seq_printf(s, ",multiuser"); seq_printf(s, ",multiuser");
...@@ -957,7 +948,7 @@ cifs_init_once(void *inode) ...@@ -957,7 +948,7 @@ cifs_init_once(void *inode)
struct cifsInodeInfo *cifsi = inode; struct cifsInodeInfo *cifsi = inode;
inode_init_once(&cifsi->vfs_inode); inode_init_once(&cifsi->vfs_inode);
mutex_init(&cifsi->lock_mutex); init_rwsem(&cifsi->lock_sem);
} }
static int static int
...@@ -1127,6 +1118,10 @@ init_cifs(void) ...@@ -1127,6 +1118,10 @@ init_cifs(void)
spin_lock_init(&cifs_file_list_lock); spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock); spin_lock_init(&GlobalMid_Lock);
#ifdef CONFIG_CIFS_SMB2
get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
#endif
if (cifs_max_pending < 2) { if (cifs_max_pending < 2) {
cifs_max_pending = 2; cifs_max_pending = 2;
cFYI(1, "cifs_max_pending set to min of 2"); cFYI(1, "cifs_max_pending set to min of 2");
......
...@@ -128,5 +128,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); ...@@ -128,5 +128,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops; extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */ #endif /* CONFIG_CIFS_NFSD_EXPORT */
#define CIFS_VERSION "1.78" #define CIFS_VERSION "2.0"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
This diff is collapsed.
...@@ -2210,7 +2210,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */ ...@@ -2210,7 +2210,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */
__u8 DeletePending; __u8 DeletePending;
__u8 Directory; __u8 Directory;
__u16 Pad2; __u16 Pad2;
__u64 IndexNumber; __le64 IndexNumber;
__le32 EASize; __le32 EASize;
__le32 AccessFlags; __le32 AccessFlags;
__u64 IndexNumber1; __u64 IndexNumber1;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -160,17 +160,18 @@ check_name(struct dentry *direntry) ...@@ -160,17 +160,18 @@ check_name(struct dentry *direntry)
static int static int
cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
struct tcon_link *tlink, unsigned oflags, umode_t mode, struct tcon_link *tlink, unsigned oflags, umode_t mode,
__u32 *oplock, __u16 *fileHandle, int *created) __u32 *oplock, struct cifs_fid *fid, int *created)
{ {
int rc = -ENOENT; int rc = -ENOENT;
int create_options = CREATE_NOT_DIR; int create_options = CREATE_NOT_DIR;
int desiredAccess; int desired_access;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifs_tcon *tcon = tlink_tcon(tlink); struct cifs_tcon *tcon = tlink_tcon(tlink);
char *full_path = NULL; char *full_path = NULL;
FILE_ALL_INFO *buf = NULL; FILE_ALL_INFO *buf = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
int disposition; int disposition;
struct TCP_Server_Info *server = tcon->ses->server;
*oplock = 0; *oplock = 0;
if (tcon->ses->server->oplocks) if (tcon->ses->server->oplocks)
...@@ -185,8 +186,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -185,8 +186,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open && if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP & (CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) { le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = cifs_posix_open(full_path, &newinode, rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode,
inode->i_sb, mode, oflags, oplock, fileHandle, xid); oflags, oplock, &fid->netfid, xid);
switch (rc) { switch (rc) {
case 0: case 0:
if (newinode == NULL) { if (newinode == NULL) {
...@@ -202,7 +203,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -202,7 +203,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
* close it and proceed as if it were a normal * close it and proceed as if it were a normal
* lookup. * lookup.
*/ */
CIFSSMBClose(xid, tcon, *fileHandle); CIFSSMBClose(xid, tcon, fid->netfid);
goto cifs_create_get_file_info; goto cifs_create_get_file_info;
} }
/* success, no need to query */ /* success, no need to query */
...@@ -244,11 +245,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -244,11 +245,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
*/ */
} }
desiredAccess = 0; desired_access = 0;
if (OPEN_FMODE(oflags) & FMODE_READ) if (OPEN_FMODE(oflags) & FMODE_READ)
desiredAccess |= GENERIC_READ; /* is this too little? */ desired_access |= GENERIC_READ; /* is this too little? */
if (OPEN_FMODE(oflags) & FMODE_WRITE) if (OPEN_FMODE(oflags) & FMODE_WRITE)
desiredAccess |= GENERIC_WRITE; desired_access |= GENERIC_WRITE;
disposition = FILE_OVERWRITE_IF; disposition = FILE_OVERWRITE_IF;
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
...@@ -260,8 +261,15 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -260,8 +261,15 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
else else
cFYI(1, "Create flag not set in create function"); cFYI(1, "Create flag not set in create function");
/* BB add processing to set equivalent of mode - e.g. via CreateX with /*
ACLs */ * BB add processing to set equivalent of mode - e.g. via CreateX with
* ACLs
*/
if (!server->ops->open) {
rc = -ENOSYS;
goto out;
}
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (buf == NULL) { if (buf == NULL) {
...@@ -279,28 +287,18 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -279,28 +287,18 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
if (backup_cred(cifs_sb)) if (backup_cred(cifs_sb))
create_options |= CREATE_OPEN_BACKUP_INTENT; create_options |= CREATE_OPEN_BACKUP_INTENT;
if (tcon->ses->capabilities & CAP_NT_SMBS) rc = server->ops->open(xid, tcon, full_path, disposition,
rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desired_access, create_options, fid, oplock,
desiredAccess, create_options, buf, cifs_sb);
fileHandle, oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
else
rc = -EIO; /* no NT SMB support fall into legacy open below */
if (rc == -EIO) {
/* old server, retry the open legacy style */
rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
desiredAccess, create_options,
fileHandle, oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
}
if (rc) { if (rc) {
cFYI(1, "cifs_create returned 0x%x", rc); cFYI(1, "cifs_create returned 0x%x", rc);
goto out; goto out;
} }
/* If Open reported that we actually created a file /*
then we now have to set the mode if possible */ * If Open reported that we actually created a file then we now have to
* set the mode if possible.
*/
if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
struct cifs_unix_set_info_args args = { struct cifs_unix_set_info_args args = {
.mode = mode, .mode = mode,
...@@ -321,11 +319,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -321,11 +319,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
args.uid = NO_CHANGE_64; args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64; args.gid = NO_CHANGE_64;
} }
CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle, CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid,
current->tgid); current->tgid);
} else { } else {
/* BB implement mode setting via Windows security /*
descriptors e.g. */ * BB implement mode setting via Windows security
* descriptors e.g.
*/
/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
/* Could set r/o dos attribute if mode & 0222 == 0 */ /* Could set r/o dos attribute if mode & 0222 == 0 */
...@@ -334,12 +334,14 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -334,12 +334,14 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
cifs_create_get_file_info: cifs_create_get_file_info:
/* server might mask mode so we have to query for it */ /* server might mask mode so we have to query for it */
if (tcon->unix_ext) if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
inode->i_sb, xid); xid);
else { else {
rc = cifs_get_inode_info(&newinode, full_path, buf, rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
inode->i_sb, xid, fileHandle); xid, &fid->netfid);
if (newinode) { if (newinode) {
if (server->ops->set_lease_key)
server->ops->set_lease_key(newinode, fid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
newinode->i_mode = mode; newinode->i_mode = mode;
if ((*oplock & CIFS_CREATE_ACTION) && if ((*oplock & CIFS_CREATE_ACTION) &&
...@@ -356,7 +358,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ...@@ -356,7 +358,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
cifs_create_set_dentry: cifs_create_set_dentry:
if (rc != 0) { if (rc != 0) {
cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
CIFSSMBClose(xid, tcon, *fileHandle); if (server->ops->close)
server->ops->close(xid, tcon, fid);
goto out; goto out;
} }
d_drop(direntry); d_drop(direntry);
...@@ -377,11 +380,14 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, ...@@ -377,11 +380,14 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
unsigned int xid; unsigned int xid;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifs_tcon *tcon; struct cifs_tcon *tcon;
__u16 fileHandle; struct TCP_Server_Info *server;
struct cifs_fid fid;
struct cifs_pending_open open;
__u32 oplock; __u32 oplock;
struct cifsFileInfo *pfile_info; struct cifsFileInfo *file_info;
/* Posix open is only called (at lookup time) for file create now. For /*
* Posix open is only called (at lookup time) for file create now. For
* opens (rather than creates), because we do not know if it is a file * opens (rather than creates), because we do not know if it is a file
* or directory yet, and current Samba no longer allows us to do posix * or directory yet, and current Samba no longer allows us to do posix
* open on dirs, we could end up wasting an open call on what turns out * open on dirs, we could end up wasting an open call on what turns out
...@@ -413,22 +419,34 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, ...@@ -413,22 +419,34 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
goto out_free_xid; goto out_free_xid;
tcon = tlink_tcon(tlink); tcon = tlink_tcon(tlink);
server = tcon->ses->server;
if (server->ops->new_lease_key)
server->ops->new_lease_key(&fid);
cifs_add_pending_open(&fid, tlink, &open);
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
&oplock, &fileHandle, opened); &oplock, &fid, opened);
if (rc) if (rc) {
cifs_del_pending_open(&open);
goto out; goto out;
}
rc = finish_open(file, direntry, generic_file_open, opened); rc = finish_open(file, direntry, generic_file_open, opened);
if (rc) { if (rc) {
CIFSSMBClose(xid, tcon, fileHandle); if (server->ops->close)
server->ops->close(xid, tcon, &fid);
cifs_del_pending_open(&open);
goto out; goto out;
} }
pfile_info = cifs_new_fileinfo(fileHandle, file, tlink, oplock); file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
if (pfile_info == NULL) { if (file_info == NULL) {
CIFSSMBClose(xid, tcon, fileHandle); if (server->ops->close)
server->ops->close(xid, tcon, &fid);
cifs_del_pending_open(&open);
rc = -ENOMEM; rc = -ENOMEM;
} }
...@@ -453,7 +471,9 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, ...@@ -453,7 +471,9 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
*/ */
unsigned oflags = O_EXCL | O_CREAT | O_RDWR; unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
struct tcon_link *tlink; struct tcon_link *tlink;
__u16 fileHandle; struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
struct cifs_fid fid;
__u32 oplock; __u32 oplock;
int created = FILE_CREATED; int created = FILE_CREATED;
...@@ -465,10 +485,16 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, ...@@ -465,10 +485,16 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
if (IS_ERR(tlink)) if (IS_ERR(tlink))
goto out_free_xid; goto out_free_xid;
tcon = tlink_tcon(tlink);
server = tcon->ses->server;
if (server->ops->new_lease_key)
server->ops->new_lease_key(&fid);
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
&oplock, &fileHandle, &created); &oplock, &fid, &created);
if (!rc) if (!rc && server->ops->close)
CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle); server->ops->close(xid, tcon, &fid);
cifs_put_tlink(tlink); cifs_put_tlink(tlink);
out_free_xid: out_free_xid:
......
This diff is collapsed.
This diff is collapsed.
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
#include "cifs_debug.h" #include "cifs_debug.h"
#include "cifsfs.h" #include "cifsfs.h"
#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
{ {
struct inode *inode = filep->f_dentry->d_inode; struct inode *inode = filep->f_dentry->d_inode;
...@@ -51,23 +49,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) ...@@ -51,23 +49,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
switch (command) { switch (command) {
static bool warned = false;
case CIFS_IOC_CHECKUMOUNT:
if (!warned) {
warned = true;
cERROR(1, "the CIFS_IOC_CHECKMOUNT ioctl will "
"be deprecated in 3.7. Please "
"migrate away from the use of "
"umount.cifs");
}
cFYI(1, "User unmount attempted");
if (cifs_sb->mnt_uid == current_uid())
rc = 0;
else {
rc = -EACCES;
cFYI(1, "uids do not match");
}
break;
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
case FS_IOC_GETFLAGS: case FS_IOC_GETFLAGS:
if (pSMBFile == NULL) if (pSMBFile == NULL)
...@@ -75,8 +56,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) ...@@ -75,8 +56,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
tcon = tlink_tcon(pSMBFile->tlink); tcon = tlink_tcon(pSMBFile->tlink);
caps = le64_to_cpu(tcon->fsUnixInfo.Capability); caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
if (CIFS_UNIX_EXTATTR_CAP & caps) { if (CIFS_UNIX_EXTATTR_CAP & caps) {
rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, rc = CIFSGetExtAttr(xid, tcon,
&ExtAttrBits, &ExtAttrMask); pSMBFile->fid.netfid,
&ExtAttrBits, &ExtAttrMask);
if (rc == 0) if (rc == 0)
rc = put_user(ExtAttrBits & rc = put_user(ExtAttrBits &
FS_FL_USER_VISIBLE, FS_FL_USER_VISIBLE,
...@@ -94,8 +76,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) ...@@ -94,8 +76,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
rc = -EFAULT; rc = -EFAULT;
break; break;
} }
/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, /*
extAttrBits, &ExtAttrMask);*/ * rc = CIFSGetExtAttr(xid, tcon,
* pSMBFile->fid.netfid,
* extAttrBits,
* &ExtAttrMask);
*/
} }
cFYI(1, "set flags not implemented yet"); cFYI(1, "set flags not implemented yet");
break; break;
......
This diff is collapsed.
...@@ -466,7 +466,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) ...@@ -466,7 +466,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
list_for_each(tmp2, &tcon->openFileList) { list_for_each(tmp2, &tcon->openFileList) {
netfile = list_entry(tmp2, struct cifsFileInfo, netfile = list_entry(tmp2, struct cifsFileInfo,
tlist); tlist);
if (pSMB->Fid != netfile->netfid) if (pSMB->Fid != netfile->fid.netfid)
continue; continue;
cFYI(1, "file id match, oplock break"); cFYI(1, "file id match, oplock break");
...@@ -579,3 +579,33 @@ backup_cred(struct cifs_sb_info *cifs_sb) ...@@ -579,3 +579,33 @@ backup_cred(struct cifs_sb_info *cifs_sb)
return false; return false;
} }
void
cifs_del_pending_open(struct cifs_pending_open *open)
{
spin_lock(&cifs_file_list_lock);
list_del(&open->olist);
spin_unlock(&cifs_file_list_lock);
}
void
cifs_add_pending_open_locked(struct cifs_fid *fid, struct tcon_link *tlink,
struct cifs_pending_open *open)
{
#ifdef CONFIG_CIFS_SMB2
memcpy(open->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
#endif
open->oplock = CIFS_OPLOCK_NO_CHANGE;
open->tlink = tlink;
fid->pending_open = open;
list_add_tail(&open->olist, &tlink_tcon(tlink)->pending_opens);
}
void
cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink,
struct cifs_pending_open *open)
{
spin_lock(&cifs_file_list_lock);
cifs_add_pending_open_locked(fid, tlink, open);
spin_unlock(&cifs_file_list_lock);
}
...@@ -110,7 +110,7 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = { ...@@ -110,7 +110,7 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
{ERRnoroom, -ENOSPC}, {ERRnoroom, -ENOSPC},
{ERRrmuns, -EUSERS}, {ERRrmuns, -EUSERS},
{ERRtimeout, -ETIME}, {ERRtimeout, -ETIME},
{ERRnoresource, -ENOBUFS}, {ERRnoresource, -EREMOTEIO},
{ERRtoomanyuids, -EUSERS}, {ERRtoomanyuids, -EUSERS},
{ERRbaduid, -EACCES}, {ERRbaduid, -EACCES},
{ERRusempx, -EIO}, {ERRusempx, -EIO},
...@@ -412,7 +412,7 @@ static const struct { ...@@ -412,7 +412,7 @@ static const struct {
from NT_STATUS_INSUFFICIENT_RESOURCES to from NT_STATUS_INSUFFICIENT_RESOURCES to
NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */ NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */
{ {
ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, { ERRDOS, ERRnoresource, NT_STATUS_INSUFFICIENT_RESOURCES}, {
ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, { ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {
ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, { ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, {
ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, { ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, {
...@@ -682,7 +682,7 @@ static const struct { ...@@ -682,7 +682,7 @@ static const struct {
ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, { ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, {
ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, { ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, {
ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, { ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, {
ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, { ERRDOS, ERRnoresource, NT_STATUS_INSUFF_SERVER_RESOURCES}, {
ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, {
ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, {
ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, {
...@@ -913,8 +913,9 @@ map_smb_to_linux_error(char *buf, bool logErr) ...@@ -913,8 +913,9 @@ map_smb_to_linux_error(char *buf, bool logErr)
* portion, the number of word parameters and the data portion of the message * portion, the number of word parameters and the data portion of the message
*/ */
unsigned int unsigned int
smbCalcSize(struct smb_hdr *ptr) smbCalcSize(void *buf)
{ {
struct smb_hdr *ptr = (struct smb_hdr *)buf;
return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
2 /* size of the bcc field */ + get_bcc(ptr)); 2 /* size of the bcc field */ + get_bcc(ptr));
} }
......
This diff is collapsed.
...@@ -876,7 +876,8 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, ...@@ -876,7 +876,8 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
smb_buf = (struct smb_hdr *)iov[0].iov_base; smb_buf = (struct smb_hdr *)iov[0].iov_base;
if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError == if ((type == RawNTLMSSP) && (resp_buf_type != CIFS_NO_BUFFER) &&
(smb_buf->Status.CifsError ==
cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) { cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
if (phase != NtLmNegotiate) { if (phase != NtLmNegotiate) {
cERROR(1, "Unexpected more processing error"); cERROR(1, "Unexpected more processing error");
......
This diff is collapsed.
This diff is collapsed.
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#ifndef _SMB2_GLOB_H #ifndef _SMB2_GLOB_H
#define _SMB2_GLOB_H #define _SMB2_GLOB_H
#define SMB2_MAGIC_NUMBER 0xFE534D42
/* /*
***************************************************************** *****************************************************************
* Constants go here * Constants go here
...@@ -40,5 +42,17 @@ ...@@ -40,5 +42,17 @@
#define SMB2_OP_MKDIR 5 #define SMB2_OP_MKDIR 5
#define SMB2_OP_RENAME 6 #define SMB2_OP_RENAME 6
#define SMB2_OP_DELETE 7 #define SMB2_OP_DELETE 7
#define SMB2_OP_HARDLINK 8
#define SMB2_OP_SET_EOF 9
/* Used when constructing chained read requests. */
#define CHAINED_REQUEST 1
#define START_OF_CHAIN 2
#define END_OF_CHAIN 4
#define RELATED_REQUEST 8
#define SMB2_SIGNATURE_SIZE (16)
#define SMB2_NTLMV2_SESSKEY_SIZE (16)
#define SMB2_HMACSHA256_SIZE (32)
#endif /* _SMB2_GLOB_H */ #endif /* _SMB2_GLOB_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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