Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Various small cifs/smb3 fixes, include some for stable, and some from the recent SMB3 test event" * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: File names with trailing period or space need special case conversion Fix reconnect to not defer smb3 session reconnect long after socket reconnect cifs: check hash calculating succeeded cifs: dynamic allocation of ntlmssp blob cifs: use CIFS_MAX_DOMAINNAME_LEN when converting the domain name cifs: stuff the fl_owner into "pid" field in the lock request
This commit is contained in:
commit
fbe601f7a3
|
@ -101,6 +101,12 @@ convert_sfm_char(const __u16 src_char, char *target)
|
||||||
case SFM_SLASH:
|
case SFM_SLASH:
|
||||||
*target = '\\';
|
*target = '\\';
|
||||||
break;
|
break;
|
||||||
|
case SFM_SPACE:
|
||||||
|
*target = ' ';
|
||||||
|
break;
|
||||||
|
case SFM_PERIOD:
|
||||||
|
*target = '.';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +410,7 @@ static __le16 convert_to_sfu_char(char src_char)
|
||||||
return dest_char;
|
return dest_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __le16 convert_to_sfm_char(char src_char)
|
static __le16 convert_to_sfm_char(char src_char, bool end_of_string)
|
||||||
{
|
{
|
||||||
__le16 dest_char;
|
__le16 dest_char;
|
||||||
|
|
||||||
|
@ -427,6 +433,18 @@ static __le16 convert_to_sfm_char(char src_char)
|
||||||
case '|':
|
case '|':
|
||||||
dest_char = cpu_to_le16(SFM_PIPE);
|
dest_char = cpu_to_le16(SFM_PIPE);
|
||||||
break;
|
break;
|
||||||
|
case '.':
|
||||||
|
if (end_of_string)
|
||||||
|
dest_char = cpu_to_le16(SFM_PERIOD);
|
||||||
|
else
|
||||||
|
dest_char = 0;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if (end_of_string)
|
||||||
|
dest_char = cpu_to_le16(SFM_SPACE);
|
||||||
|
else
|
||||||
|
dest_char = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dest_char = 0;
|
dest_char = 0;
|
||||||
}
|
}
|
||||||
|
@ -469,9 +487,16 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
|
||||||
/* see if we must remap this char */
|
/* see if we must remap this char */
|
||||||
if (map_chars == SFU_MAP_UNI_RSVD)
|
if (map_chars == SFU_MAP_UNI_RSVD)
|
||||||
dst_char = convert_to_sfu_char(src_char);
|
dst_char = convert_to_sfu_char(src_char);
|
||||||
else if (map_chars == SFM_MAP_UNI_RSVD)
|
else if (map_chars == SFM_MAP_UNI_RSVD) {
|
||||||
dst_char = convert_to_sfm_char(src_char);
|
bool end_of_string;
|
||||||
else
|
|
||||||
|
if (i == srclen - 1)
|
||||||
|
end_of_string = true;
|
||||||
|
else
|
||||||
|
end_of_string = false;
|
||||||
|
|
||||||
|
dst_char = convert_to_sfm_char(src_char, end_of_string);
|
||||||
|
} else
|
||||||
dst_char = 0;
|
dst_char = 0;
|
||||||
/*
|
/*
|
||||||
* FIXME: We can not handle remapping backslash (UNI_SLASH)
|
* FIXME: We can not handle remapping backslash (UNI_SLASH)
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
#define SFM_LESSTHAN ((__u16) 0xF023)
|
#define SFM_LESSTHAN ((__u16) 0xF023)
|
||||||
#define SFM_PIPE ((__u16) 0xF027)
|
#define SFM_PIPE ((__u16) 0xF027)
|
||||||
#define SFM_SLASH ((__u16) 0xF026)
|
#define SFM_SLASH ((__u16) 0xF026)
|
||||||
|
#define SFM_PERIOD ((__u16) 0xF028)
|
||||||
|
#define SFM_SPACE ((__u16) 0xF029)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mapping mechanism to use when one of the seven reserved characters is
|
* Mapping mechanism to use when one of the seven reserved characters is
|
||||||
|
|
|
@ -87,6 +87,7 @@ extern mempool_t *cifs_req_poolp;
|
||||||
extern mempool_t *cifs_mid_poolp;
|
extern mempool_t *cifs_mid_poolp;
|
||||||
|
|
||||||
struct workqueue_struct *cifsiod_wq;
|
struct workqueue_struct *cifsiod_wq;
|
||||||
|
__u32 cifs_lock_secret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bumps refcount for cifs super block.
|
* Bumps refcount for cifs super block.
|
||||||
|
@ -1266,6 +1267,8 @@ 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);
|
||||||
|
|
||||||
|
get_random_bytes(&cifs_lock_secret, sizeof(cifs_lock_secret));
|
||||||
|
|
||||||
if (cifs_max_pending < 2) {
|
if (cifs_max_pending < 2) {
|
||||||
cifs_max_pending = 2;
|
cifs_max_pending = 2;
|
||||||
cifs_dbg(FYI, "cifs_max_pending set to min of 2\n");
|
cifs_dbg(FYI, "cifs_max_pending set to min of 2\n");
|
||||||
|
|
|
@ -1619,6 +1619,7 @@ void cifs_oplock_break(struct work_struct *work);
|
||||||
|
|
||||||
extern const struct slow_work_ops cifs_oplock_break_ops;
|
extern const struct slow_work_ops cifs_oplock_break_ops;
|
||||||
extern struct workqueue_struct *cifsiod_wq;
|
extern struct workqueue_struct *cifsiod_wq;
|
||||||
|
extern __u32 cifs_lock_secret;
|
||||||
|
|
||||||
extern mempool_t *cifs_mid_poolp;
|
extern mempool_t *cifs_mid_poolp;
|
||||||
|
|
||||||
|
|
|
@ -428,7 +428,9 @@ cifs_echo_request(struct work_struct *work)
|
||||||
* server->ops->need_neg() == true. Also, no need to ping if
|
* server->ops->need_neg() == true. Also, no need to ping if
|
||||||
* we got a response recently.
|
* we got a response recently.
|
||||||
*/
|
*/
|
||||||
if (!server->ops->need_neg || server->ops->need_neg(server) ||
|
|
||||||
|
if (server->tcpStatus == CifsNeedReconnect ||
|
||||||
|
server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
|
||||||
(server->ops->can_echo && !server->ops->can_echo(server)) ||
|
(server->ops->can_echo && !server->ops->can_echo(server)) ||
|
||||||
time_before(jiffies, server->lstrp + echo_interval - HZ))
|
time_before(jiffies, server->lstrp + echo_interval - HZ))
|
||||||
goto requeue_echo;
|
goto requeue_echo;
|
||||||
|
|
|
@ -1112,6 +1112,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __u32
|
||||||
|
hash_lockowner(fl_owner_t owner)
|
||||||
|
{
|
||||||
|
return cifs_lock_secret ^ hash32_ptr((const void *)owner);
|
||||||
|
}
|
||||||
|
|
||||||
struct lock_to_push {
|
struct lock_to_push {
|
||||||
struct list_head llist;
|
struct list_head llist;
|
||||||
__u64 offset;
|
__u64 offset;
|
||||||
|
@ -1178,7 +1184,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
|
||||||
else
|
else
|
||||||
type = CIFS_WRLCK;
|
type = CIFS_WRLCK;
|
||||||
lck = list_entry(el, struct lock_to_push, llist);
|
lck = list_entry(el, struct lock_to_push, llist);
|
||||||
lck->pid = flock->fl_pid;
|
lck->pid = hash_lockowner(flock->fl_owner);
|
||||||
lck->netfid = cfile->fid.netfid;
|
lck->netfid = cfile->fid.netfid;
|
||||||
lck->length = length;
|
lck->length = length;
|
||||||
lck->type = type;
|
lck->type = type;
|
||||||
|
@ -1305,7 +1311,8 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
|
||||||
posix_lock_type = CIFS_RDLCK;
|
posix_lock_type = CIFS_RDLCK;
|
||||||
else
|
else
|
||||||
posix_lock_type = CIFS_WRLCK;
|
posix_lock_type = CIFS_WRLCK;
|
||||||
rc = CIFSSMBPosixLock(xid, tcon, netfid, current->tgid,
|
rc = CIFSSMBPosixLock(xid, tcon, netfid,
|
||||||
|
hash_lockowner(flock->fl_owner),
|
||||||
flock->fl_start, length, flock,
|
flock->fl_start, length, flock,
|
||||||
posix_lock_type, wait_flag);
|
posix_lock_type, wait_flag);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -1505,7 +1512,8 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
|
||||||
posix_lock_type = CIFS_UNLCK;
|
posix_lock_type = CIFS_UNLCK;
|
||||||
|
|
||||||
rc = CIFSSMBPosixLock(xid, tcon, cfile->fid.netfid,
|
rc = CIFSSMBPosixLock(xid, tcon, cfile->fid.netfid,
|
||||||
current->tgid, flock->fl_start, length,
|
hash_lockowner(flock->fl_owner),
|
||||||
|
flock->fl_start, length,
|
||||||
NULL, posix_lock_type, wait_flag);
|
NULL, posix_lock_type, wait_flag);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,6 @@ typedef struct _AUTHENTICATE_MESSAGE {
|
||||||
|
|
||||||
int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
|
int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
|
||||||
void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
|
void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
|
||||||
int build_ntlmssp_auth_blob(unsigned char *pbuffer, u16 *buflen,
|
int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
|
||||||
struct cifs_ses *ses,
|
struct cifs_ses *ses,
|
||||||
const struct nls_table *nls_cp);
|
const struct nls_table *nls_cp);
|
||||||
|
|
|
@ -364,19 +364,43 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
||||||
sec_blob->DomainName.MaximumLength = 0;
|
sec_blob->DomainName.MaximumLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do not malloc the blob, it is passed in pbuffer, because its
|
static int size_of_ntlmssp_blob(struct cifs_ses *ses)
|
||||||
maximum possible size is fixed and small, making this approach cleaner.
|
{
|
||||||
This function returns the length of the data in the blob */
|
int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
|
||||||
int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
- CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
|
||||||
|
|
||||||
|
if (ses->domainName)
|
||||||
|
sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
||||||
|
else
|
||||||
|
sz += 2;
|
||||||
|
|
||||||
|
if (ses->user_name)
|
||||||
|
sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
|
||||||
|
else
|
||||||
|
sz += 2;
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_ntlmssp_auth_blob(unsigned char **pbuffer,
|
||||||
u16 *buflen,
|
u16 *buflen,
|
||||||
struct cifs_ses *ses,
|
struct cifs_ses *ses,
|
||||||
const struct nls_table *nls_cp)
|
const struct nls_table *nls_cp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
|
AUTHENTICATE_MESSAGE *sec_blob;
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
unsigned char *tmp;
|
unsigned char *tmp;
|
||||||
|
|
||||||
|
rc = setup_ntlmv2_rsp(ses, nls_cp);
|
||||||
|
if (rc) {
|
||||||
|
cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
|
||||||
|
*buflen = 0;
|
||||||
|
goto setup_ntlmv2_ret;
|
||||||
|
}
|
||||||
|
*pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
|
||||||
|
sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
|
||||||
|
|
||||||
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
|
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
|
||||||
sec_blob->MessageType = NtLmAuthenticate;
|
sec_blob->MessageType = NtLmAuthenticate;
|
||||||
|
|
||||||
|
@ -391,7 +415,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||||
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
||||||
sec_blob->NegotiateFlags = cpu_to_le32(flags);
|
sec_blob->NegotiateFlags = cpu_to_le32(flags);
|
||||||
|
|
||||||
sec_blob->LmChallengeResponse.BufferOffset =
|
sec_blob->LmChallengeResponse.BufferOffset =
|
||||||
|
@ -399,13 +423,9 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||||
sec_blob->LmChallengeResponse.Length = 0;
|
sec_blob->LmChallengeResponse.Length = 0;
|
||||||
sec_blob->LmChallengeResponse.MaximumLength = 0;
|
sec_blob->LmChallengeResponse.MaximumLength = 0;
|
||||||
|
|
||||||
sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->NtChallengeResponse.BufferOffset =
|
||||||
|
cpu_to_le32(tmp - *pbuffer);
|
||||||
if (ses->user_name != NULL) {
|
if (ses->user_name != NULL) {
|
||||||
rc = setup_ntlmv2_rsp(ses, nls_cp);
|
|
||||||
if (rc) {
|
|
||||||
cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
|
|
||||||
goto setup_ntlmv2_ret;
|
|
||||||
}
|
|
||||||
memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
|
memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
|
||||||
ses->auth_key.len - CIFS_SESS_KEY_SIZE);
|
ses->auth_key.len - CIFS_SESS_KEY_SIZE);
|
||||||
tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
|
tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
|
||||||
|
@ -423,23 +443,23 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ses->domainName == NULL) {
|
if (ses->domainName == NULL) {
|
||||||
sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->DomainName.Length = 0;
|
sec_blob->DomainName.Length = 0;
|
||||||
sec_blob->DomainName.MaximumLength = 0;
|
sec_blob->DomainName.MaximumLength = 0;
|
||||||
tmp += 2;
|
tmp += 2;
|
||||||
} else {
|
} else {
|
||||||
int len;
|
int len;
|
||||||
len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
|
len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
|
||||||
CIFS_MAX_USERNAME_LEN, nls_cp);
|
CIFS_MAX_DOMAINNAME_LEN, nls_cp);
|
||||||
len *= 2; /* unicode is 2 bytes each */
|
len *= 2; /* unicode is 2 bytes each */
|
||||||
sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->DomainName.Length = cpu_to_le16(len);
|
sec_blob->DomainName.Length = cpu_to_le16(len);
|
||||||
sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
|
sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
|
||||||
tmp += len;
|
tmp += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ses->user_name == NULL) {
|
if (ses->user_name == NULL) {
|
||||||
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->UserName.Length = 0;
|
sec_blob->UserName.Length = 0;
|
||||||
sec_blob->UserName.MaximumLength = 0;
|
sec_blob->UserName.MaximumLength = 0;
|
||||||
tmp += 2;
|
tmp += 2;
|
||||||
|
@ -448,13 +468,13 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||||
len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
|
len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
|
||||||
CIFS_MAX_USERNAME_LEN, nls_cp);
|
CIFS_MAX_USERNAME_LEN, nls_cp);
|
||||||
len *= 2; /* unicode is 2 bytes each */
|
len *= 2; /* unicode is 2 bytes each */
|
||||||
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->UserName.Length = cpu_to_le16(len);
|
sec_blob->UserName.Length = cpu_to_le16(len);
|
||||||
sec_blob->UserName.MaximumLength = cpu_to_le16(len);
|
sec_blob->UserName.MaximumLength = cpu_to_le16(len);
|
||||||
tmp += len;
|
tmp += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->WorkstationName.Length = 0;
|
sec_blob->WorkstationName.Length = 0;
|
||||||
sec_blob->WorkstationName.MaximumLength = 0;
|
sec_blob->WorkstationName.MaximumLength = 0;
|
||||||
tmp += 2;
|
tmp += 2;
|
||||||
|
@ -463,19 +483,19 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||||
(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
||||||
&& !calc_seckey(ses)) {
|
&& !calc_seckey(ses)) {
|
||||||
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
|
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
|
||||||
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
|
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
|
||||||
sec_blob->SessionKey.MaximumLength =
|
sec_blob->SessionKey.MaximumLength =
|
||||||
cpu_to_le16(CIFS_CPHTXT_SIZE);
|
cpu_to_le16(CIFS_CPHTXT_SIZE);
|
||||||
tmp += CIFS_CPHTXT_SIZE;
|
tmp += CIFS_CPHTXT_SIZE;
|
||||||
} else {
|
} else {
|
||||||
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
||||||
sec_blob->SessionKey.Length = 0;
|
sec_blob->SessionKey.Length = 0;
|
||||||
sec_blob->SessionKey.MaximumLength = 0;
|
sec_blob->SessionKey.MaximumLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*buflen = tmp - *pbuffer;
|
||||||
setup_ntlmv2_ret:
|
setup_ntlmv2_ret:
|
||||||
*buflen = tmp - pbuffer;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,6 +710,8 @@ sess_auth_lanman(struct sess_data *sess_data)
|
||||||
rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
|
rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
|
||||||
ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
|
ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
|
||||||
true : false, lnm_session_key);
|
true : false, lnm_session_key);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
|
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
|
||||||
bcc_ptr += CIFS_AUTH_RESP_SIZE;
|
bcc_ptr += CIFS_AUTH_RESP_SIZE;
|
||||||
|
@ -1266,7 +1288,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
|
||||||
struct cifs_ses *ses = sess_data->ses;
|
struct cifs_ses *ses = sess_data->ses;
|
||||||
__u16 bytes_remaining;
|
__u16 bytes_remaining;
|
||||||
char *bcc_ptr;
|
char *bcc_ptr;
|
||||||
char *ntlmsspblob = NULL;
|
unsigned char *ntlmsspblob = NULL;
|
||||||
u16 blob_len;
|
u16 blob_len;
|
||||||
|
|
||||||
cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
|
cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
|
||||||
|
@ -1279,19 +1301,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
|
||||||
/* Build security blob before we assemble the request */
|
/* Build security blob before we assemble the request */
|
||||||
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
|
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
|
||||||
smb_buf = (struct smb_hdr *)pSMB;
|
smb_buf = (struct smb_hdr *)pSMB;
|
||||||
/*
|
rc = build_ntlmssp_auth_blob(&ntlmsspblob,
|
||||||
* 5 is an empirical value, large enough to hold
|
|
||||||
* authenticate message plus max 10 of av paris,
|
|
||||||
* domain, user, workstation names, flags, etc.
|
|
||||||
*/
|
|
||||||
ntlmsspblob = kzalloc(5*sizeof(struct _AUTHENTICATE_MESSAGE),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!ntlmsspblob) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = build_ntlmssp_auth_blob(ntlmsspblob,
|
|
||||||
&blob_len, ses, sess_data->nls_cp);
|
&blob_len, ses, sess_data->nls_cp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free_ntlmsspblob;
|
goto out_free_ntlmsspblob;
|
||||||
|
|
|
@ -588,7 +588,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
|
||||||
u16 blob_length = 0;
|
u16 blob_length = 0;
|
||||||
struct key *spnego_key = NULL;
|
struct key *spnego_key = NULL;
|
||||||
char *security_blob = NULL;
|
char *security_blob = NULL;
|
||||||
char *ntlmssp_blob = NULL;
|
unsigned char *ntlmssp_blob = NULL;
|
||||||
bool use_spnego = false; /* else use raw ntlmssp */
|
bool use_spnego = false; /* else use raw ntlmssp */
|
||||||
|
|
||||||
cifs_dbg(FYI, "Session Setup\n");
|
cifs_dbg(FYI, "Session Setup\n");
|
||||||
|
@ -713,13 +713,7 @@ ssetup_ntlmssp_authenticate:
|
||||||
iov[1].iov_len = blob_length;
|
iov[1].iov_len = blob_length;
|
||||||
} else if (phase == NtLmAuthenticate) {
|
} else if (phase == NtLmAuthenticate) {
|
||||||
req->hdr.SessionId = ses->Suid;
|
req->hdr.SessionId = ses->Suid;
|
||||||
ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
|
rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
|
||||||
GFP_KERNEL);
|
|
||||||
if (ntlmssp_blob == NULL) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto ssetup_exit;
|
|
||||||
}
|
|
||||||
rc = build_ntlmssp_auth_blob(ntlmssp_blob, &blob_length, ses,
|
|
||||||
nls_cp);
|
nls_cp);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n",
|
cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n",
|
||||||
|
@ -1818,6 +1812,33 @@ SMB2_echo(struct TCP_Server_Info *server)
|
||||||
|
|
||||||
cifs_dbg(FYI, "In echo request\n");
|
cifs_dbg(FYI, "In echo request\n");
|
||||||
|
|
||||||
|
if (server->tcpStatus == CifsNeedNegotiate) {
|
||||||
|
struct list_head *tmp, *tmp2;
|
||||||
|
struct cifs_ses *ses;
|
||||||
|
struct cifs_tcon *tcon;
|
||||||
|
|
||||||
|
cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
|
||||||
|
spin_lock(&cifs_tcp_ses_lock);
|
||||||
|
list_for_each(tmp, &server->smb_ses_list) {
|
||||||
|
ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
|
||||||
|
list_for_each(tmp2, &ses->tcon_list) {
|
||||||
|
tcon = list_entry(tmp2, struct cifs_tcon,
|
||||||
|
tcon_list);
|
||||||
|
/* add check for persistent handle reconnect */
|
||||||
|
if (tcon && tcon->need_reconnect) {
|
||||||
|
spin_unlock(&cifs_tcp_ses_lock);
|
||||||
|
rc = smb2_reconnect(SMB2_ECHO, tcon);
|
||||||
|
spin_lock(&cifs_tcp_ses_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&cifs_tcp_ses_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no session, renegotiate failed above */
|
||||||
|
if (server->tcpStatus == CifsNeedNegotiate)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
|
rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue