Skip to content

Commit

Permalink
cifs: Set client guid on per connection basis
Browse files Browse the repository at this point in the history
When mounting from a Windows 2012R2 server, we hit the following
problem:
1) Mount with any of the following versions - 2.0, 2.1 or 3.0
2) unmount
3) Attempt a mount again using a different SMB version >= 2.0.

You end up with the following failure:
Status code returned 0xc0000203 STATUS_USER_SESSION_DELETED
CIFS VFS: Send error in SessSetup = -5
CIFS VFS: cifs_mount failed w/return code = -5

I cannot reproduce this issue using a Windows 2008 R2 server.

This appears to be caused because we use the same client guid for the
connection on first mount which we then disconnect and attempt to mount
again using a different protocol version. By generating a new guid each
time a new connection is Negotiated, we avoid hitting this problem.

Signed-off-by: Sachin Prabhu <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
spuiuk authored and smfrench committed May 21, 2014
1 parent 179d618 commit 39552ea
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 12 deletions.
8 changes: 0 additions & 8 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ extern mempool_t *cifs_mid_poolp;

struct workqueue_struct *cifsiod_wq;

#ifdef CONFIG_CIFS_SMB2
__u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];
#endif

/*
* Bumps refcount for cifs super block.
* Note that it should be only called if a referece to VFS super block is
Expand Down Expand Up @@ -1188,10 +1184,6 @@ init_cifs(void)
spin_lock_init(&cifs_file_list_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) {
cifs_max_pending = 2;
cifs_dbg(FYI, "cifs_max_pending set to min of 2\n");
Expand Down
1 change: 1 addition & 0 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ struct TCP_Server_Info {
int echo_credits; /* echo reserved slots */
int oplock_credits; /* oplock break reserved slots */
bool echoes:1; /* enable echoes */
__u8 client_guid[SMB2_CLIENT_GUID_SIZE]; /* Client GUID */
#endif
u16 dialect; /* dialect index that server chose */
bool oplocks:1; /* enable oplocks */
Expand Down
3 changes: 3 additions & 0 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
sizeof(tcp_ses->srcaddr));
memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
sizeof(tcp_ses->dstaddr));
#ifdef CONFIG_CIFS_SMB2
get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
#endif
/*
* at this point we are the only ones with the pointer
* to the struct since the kernel thread not created yet
Expand Down
5 changes: 3 additions & 2 deletions fs/cifs/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)

req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities);

memcpy(req->ClientGUID, cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
memcpy(req->ClientGUID, server->client_guid, SMB2_CLIENT_GUID_SIZE);

iov[0].iov_base = (char *)req;
/* 4 for rfc1002 length field */
Expand Down Expand Up @@ -478,7 +478,8 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)

vneg_inbuf.Capabilities =
cpu_to_le32(tcon->ses->server->vals->req_capabilities);
memcpy(vneg_inbuf.Guid, cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid,
SMB2_CLIENT_GUID_SIZE);

if (tcon->ses->sign)
vneg_inbuf.SecurityMode =
Expand Down
2 changes: 0 additions & 2 deletions fs/cifs/smb2pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ struct smb2_symlink_err_rsp {

#define SMB2_CLIENT_GUID_SIZE 16

extern __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];

struct smb2_negotiate_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
Expand Down

0 comments on commit 39552ea

Please sign in to comment.