Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
etercifs
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
etercifs
Commits
9aa3ba91
Commit
9aa3ba91
authored
Aug 08, 2014
by
Pavel Shilovsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update 3.12 sources from stable (v3.12.26)
parent
184bd032
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
269 additions
and
27 deletions
+269
-27
cifs_unicode.c
sources/3.12/cifs_unicode.c
+4
-3
cifsfs.c
sources/3.12/cifsfs.c
+13
-9
cifsglob.h
sources/3.12/cifsglob.h
+10
-0
cifsproto.h
sources/3.12/cifsproto.h
+3
-0
connect.c
sources/3.12/connect.c
+3
-0
file.c
sources/3.12/file.c
+28
-3
misc.c
sources/3.12/misc.c
+72
-2
smb1ops.c
sources/3.12/smb1ops.c
+11
-0
smb2misc.c
sources/3.12/smb2misc.c
+15
-3
smb2ops.c
sources/3.12/smb2ops.c
+15
-0
smb2pdu.c
sources/3.12/smb2pdu.c
+84
-1
smb2pdu.h
sources/3.12/smb2pdu.h
+9
-5
smb2proto.h
sources/3.12/smb2proto.h
+1
-0
smbfsctl.h
sources/3.12/smbfsctl.h
+1
-1
No files found.
sources/3.12/cifs_unicode.c
View file @
9aa3ba91
...
...
@@ -290,7 +290,8 @@ int
cifsConvertToUTF16
(
__le16
*
target
,
const
char
*
source
,
int
srclen
,
const
struct
nls_table
*
cp
,
int
mapChars
)
{
int
i
,
j
,
charlen
;
int
i
,
charlen
;
int
j
=
0
;
char
src_char
;
__le16
dst_char
;
wchar_t
tmp
;
...
...
@@ -298,12 +299,11 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
if
(
!
mapChars
)
return
cifs_strtoUTF16
(
target
,
source
,
PATH_MAX
,
cp
);
for
(
i
=
0
,
j
=
0
;
i
<
srclen
;
j
++
)
{
for
(
i
=
0
;
i
<
srclen
;
j
++
)
{
src_char
=
source
[
i
];
charlen
=
1
;
switch
(
src_char
)
{
case
0
:
put_unaligned
(
0
,
&
target
[
j
]);
goto
ctoUTF16_out
;
case
':'
:
dst_char
=
cpu_to_le16
(
UNI_COLON
);
...
...
@@ -350,6 +350,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
}
ctoUTF16_out:
put_unaligned
(
0
,
&
target
[
j
]);
/* Null terminate target unicode string */
return
j
;
}
...
...
sources/3.12/cifsfs.c
View file @
9aa3ba91
...
...
@@ -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
...
...
@@ -253,6 +249,11 @@ cifs_alloc_inode(struct super_block *sb)
cifs_set_oplock_level
(
cifs_inode
,
0
);
cifs_inode
->
delete_pending
=
false
;
cifs_inode
->
invalid_mapping
=
false
;
clear_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cifs_inode
->
flags
);
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cifs_inode
->
flags
);
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cifs_inode
->
flags
);
spin_lock_init
(
&
cifs_inode
->
writers_lock
);
cifs_inode
->
writers
=
0
;
cifs_inode
->
vfs_inode
.
i_blkbits
=
14
;
/* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode
->
server_eof
=
0
;
cifs_inode
->
uniqueid
=
0
;
...
...
@@ -734,19 +735,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned
long
nr_segs
,
loff_t
pos
)
{
struct
inode
*
inode
=
file_inode
(
iocb
->
ki_filp
);
struct
cifsInodeInfo
*
cinode
=
CIFS_I
(
inode
);
ssize_t
written
;
int
rc
;
written
=
cifs_get_writer
(
cinode
);
if
(
written
)
return
written
;
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
if
(
CIFS_CACHE_WRITE
(
CIFS_I
(
inode
)))
return
written
;
goto
out
;
rc
=
filemap_fdatawrite
(
inode
->
i_mapping
);
if
(
rc
)
cifs_dbg
(
FYI
,
"cifs_file_aio_write: %d rc on %p inode
\n
"
,
rc
,
inode
);
out:
cifs_put_writer
(
cinode
);
return
written
;
}
...
...
@@ -1183,10 +1191,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
"
);
...
...
sources/3.12/cifsglob.h
View file @
9aa3ba91
...
...
@@ -228,6 +228,8 @@ struct smb_version_operations {
/* verify the message */
int
(
*
check_message
)(
char
*
,
unsigned
int
);
bool
(
*
is_oplock_break
)(
char
*
,
struct
TCP_Server_Info
*
);
void
(
*
downgrade_oplock
)(
struct
TCP_Server_Info
*
,
struct
cifsInodeInfo
*
,
bool
);
/* process transaction2 response */
bool
(
*
check_trans2
)(
struct
mid_q_entry
*
,
struct
TCP_Server_Info
*
,
char
*
,
int
);
...
...
@@ -389,6 +391,7 @@ struct smb_version_operations {
const
char
*
,
u32
*
);
int
(
*
set_acl
)(
struct
cifs_ntsd
*
,
__u32
,
struct
inode
*
,
const
char
*
,
int
);
int
(
*
validate_negotiate
)(
const
unsigned
int
,
struct
cifs_tcon
*
);
};
struct
smb_version_values
{
...
...
@@ -544,6 +547,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 */
...
...
@@ -1080,6 +1084,12 @@ struct cifsInodeInfo {
unsigned
int
epoch
;
/* used to track lease state changes */
bool
delete_pending
;
/* DELETE_ON_CLOSE is set */
bool
invalid_mapping
;
/* pagecache is invalid */
unsigned
long
flags
;
#define CIFS_INODE_PENDING_OPLOCK_BREAK (0)
/* oplock break in progress */
#define CIFS_INODE_PENDING_WRITERS (1)
/* Writes in progress */
#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2)
/* Downgrade oplock to L2 */
spinlock_t
writers_lock
;
unsigned
int
writers
;
/* Number of writers on this inode */
unsigned
long
time
;
/* jiffies of last update of inode */
u64
server_eof
;
/* current file size on server -- protected by i_lock */
u64
uniqueid
;
/* server inode number */
...
...
sources/3.12/cifsproto.h
View file @
9aa3ba91
...
...
@@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
extern
struct
timespec
cnvrtDosUnixTm
(
__le16
le_date
,
__le16
le_time
,
int
offset
);
extern
void
cifs_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
);
extern
int
cifs_get_writer
(
struct
cifsInodeInfo
*
cinode
);
extern
void
cifs_put_writer
(
struct
cifsInodeInfo
*
cinode
);
extern
void
cifs_done_oplock_break
(
struct
cifsInodeInfo
*
cinode
);
extern
int
cifs_unlock_range
(
struct
cifsFileInfo
*
cfile
,
struct
file_lock
*
flock
,
const
unsigned
int
xid
);
extern
int
cifs_push_mandatory_locks
(
struct
cifsFileInfo
*
cfile
);
...
...
sources/3.12/connect.c
View file @
9aa3ba91
...
...
@@ -2149,6 +2149,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
...
...
sources/3.12/file.c
View file @
9aa3ba91
...
...
@@ -2619,12 +2619,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
struct
cifs_tcon
*
tcon
=
tlink_tcon
(
cfile
->
tlink
);
ssize_t
written
;
written
=
cifs_get_writer
(
cinode
);
if
(
written
)
return
written
;
if
(
CIFS_CACHE_WRITE
(
cinode
))
{
if
(
cap_unix
(
tcon
->
ses
)
&&
(
CIFS_UNIX_FCNTL_CAP
&
le64_to_cpu
(
tcon
->
fsUnixInfo
.
Capability
))
&&
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOPOSIXBRL
)
==
0
))
return
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
return
cifs_writev
(
iocb
,
iov
,
nr_segs
,
pos
);
&&
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOPOSIXBRL
)
==
0
))
{
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
goto
out
;
}
written
=
cifs_writev
(
iocb
,
iov
,
nr_segs
,
pos
);
goto
out
;
}
/*
* For non-oplocked files in strict cache mode we need to write the data
...
...
@@ -2644,6 +2652,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
inode
);
cinode
->
oplock
=
0
;
}
out:
cifs_put_writer
(
cinode
);
return
written
;
}
...
...
@@ -3655,6 +3665,13 @@ static int cifs_launder_page(struct page *page)
return
rc
;
}
static
int
cifs_pending_writers_wait
(
void
*
unused
)
{
schedule
();
return
0
;
}
void
cifs_oplock_break
(
struct
work_struct
*
work
)
{
struct
cifsFileInfo
*
cfile
=
container_of
(
work
,
struct
cifsFileInfo
,
...
...
@@ -3662,8 +3679,15 @@ void cifs_oplock_break(struct work_struct *work)
struct
inode
*
inode
=
cfile
->
dentry
->
d_inode
;
struct
cifsInodeInfo
*
cinode
=
CIFS_I
(
inode
);
struct
cifs_tcon
*
tcon
=
tlink_tcon
(
cfile
->
tlink
);
struct
TCP_Server_Info
*
server
=
tcon
->
ses
->
server
;
int
rc
=
0
;
wait_on_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
,
cifs_pending_writers_wait
,
TASK_UNINTERRUPTIBLE
);
server
->
ops
->
downgrade_oplock
(
server
,
cinode
,
test_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
));
if
(
!
CIFS_CACHE_WRITE
(
cinode
)
&&
CIFS_CACHE_READ
(
cinode
)
&&
cifs_has_mand_locks
(
cinode
))
{
cifs_dbg
(
FYI
,
"Reset oplock to None for inode=%p due to mand locks
\n
"
,
...
...
@@ -3700,6 +3724,7 @@ void cifs_oplock_break(struct work_struct *work)
cinode
);
cifs_dbg
(
FYI
,
"Oplock release rc = %d
\n
"
,
rc
);
}
cifs_done_oplock_break
(
cinode
);
}
const
struct
address_space_operations
cifs_addr_ops
=
{
...
...
sources/3.12/misc.c
View file @
9aa3ba91
...
...
@@ -472,8 +472,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
cifs_dbg
(
FYI
,
"file id match, oplock break
\n
"
);
pCifsInode
=
CIFS_I
(
netfile
->
dentry
->
d_inode
);
cifs_set_oplock_level
(
pCifsInode
,
pSMB
->
OplockLevel
?
OPLOCK_READ
:
0
);
set_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
pCifsInode
->
flags
);
/*
* Set flag if the server downgrades the oplock
* to L2 else clear.
*/
if
(
pSMB
->
OplockLevel
)
set_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
pCifsInode
->
flags
);
else
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
pCifsInode
->
flags
);
queue_work
(
cifsiod_wq
,
&
netfile
->
oplock_break
);
netfile
->
oplock_break_cancelled
=
false
;
...
...
@@ -557,6 +571,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
cinode
->
oplock
=
0
;
}
static
int
cifs_oplock_break_wait
(
void
*
unused
)
{
schedule
();
return
signal_pending
(
current
)
?
-
ERESTARTSYS
:
0
;
}
/*
* We wait for oplock breaks to be processed before we attempt to perform
* writes.
*/
int
cifs_get_writer
(
struct
cifsInodeInfo
*
cinode
)
{
int
rc
;
start:
rc
=
wait_on_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_OPLOCK_BREAK
,
cifs_oplock_break_wait
,
TASK_KILLABLE
);
if
(
rc
)
return
rc
;
spin_lock
(
&
cinode
->
writers_lock
);
if
(
!
cinode
->
writers
)
set_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
cinode
->
writers
++
;
/* Check to see if we have started servicing an oplock break */
if
(
test_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
))
{
cinode
->
writers
--
;
if
(
cinode
->
writers
==
0
)
{
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
);
}
spin_unlock
(
&
cinode
->
writers_lock
);
goto
start
;
}
spin_unlock
(
&
cinode
->
writers_lock
);
return
0
;
}
void
cifs_put_writer
(
struct
cifsInodeInfo
*
cinode
)
{
spin_lock
(
&
cinode
->
writers_lock
);
cinode
->
writers
--
;
if
(
cinode
->
writers
==
0
)
{
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
);
}
spin_unlock
(
&
cinode
->
writers_lock
);
}
void
cifs_done_oplock_break
(
struct
cifsInodeInfo
*
cinode
)
{
clear_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_OPLOCK_BREAK
);
}
bool
backup_cred
(
struct
cifs_sb_info
*
cifs_sb
)
{
...
...
sources/3.12/smb1ops.c
View file @
9aa3ba91
...
...
@@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
return
0
;
}
static
void
cifs_downgrade_oplock
(
struct
TCP_Server_Info
*
server
,
struct
cifsInodeInfo
*
cinode
,
bool
set_level2
)
{
if
(
set_level2
)
cifs_set_oplock_level
(
cinode
,
OPLOCK_READ
);
else
cifs_set_oplock_level
(
cinode
,
0
);
}
static
bool
cifs_check_trans2
(
struct
mid_q_entry
*
mid
,
struct
TCP_Server_Info
*
server
,
char
*
buf
,
int
malformed
)
...
...
@@ -960,6 +970,7 @@ struct smb_version_operations smb1_operations = {
.
clear_stats
=
cifs_clear_stats
,
.
print_stats
=
cifs_print_stats
,
.
is_oplock_break
=
is_valid_oplock_break
,
.
downgrade_oplock
=
cifs_downgrade_oplock
,
.
check_trans2
=
cifs_check_trans2
,
.
need_neg
=
cifs_need_neg
,
.
negotiate
=
cifs_negotiate
,
...
...
sources/3.12/smb2misc.c
View file @
9aa3ba91
...
...
@@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
else
cfile
->
oplock_break_cancelled
=
false
;
server
->
ops
->
set_oplock_level
(
cinode
,
rsp
->
OplockLevel
?
SMB2_OPLOCK_LEVEL_II
:
0
,
0
,
NULL
);
set_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
);
/*
* Set flag if the server downgrades the oplock
* to L2 else clear.
*/
if
(
rsp
->
OplockLevel
)
set_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
);
else
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
);
queue_work
(
cifsiod_wq
,
&
cfile
->
oplock_break
);
...
...
sources/3.12/smb2ops.c
View file @
9aa3ba91
...
...
@@ -650,6 +650,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
}
static
void
smb2_downgrade_oplock
(
struct
TCP_Server_Info
*
server
,
struct
cifsInodeInfo
*
cinode
,
bool
set_level2
)
{
if
(
set_level2
)
server
->
ops
->
set_oplock_level
(
cinode
,
SMB2_OPLOCK_LEVEL_II
,
0
,
NULL
);
else
server
->
ops
->
set_oplock_level
(
cinode
,
0
,
0
,
NULL
);
}
static
void
smb2_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
,
unsigned
int
epoch
,
bool
*
purge_cache
)
{
...
...
@@ -855,6 +866,7 @@ struct smb_version_operations smb20_operations = {
.
clear_stats
=
smb2_clear_stats
,
.
print_stats
=
smb2_print_stats
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
@@ -926,6 +938,7 @@ struct smb_version_operations smb21_operations = {
.
clear_stats
=
smb2_clear_stats
,
.
print_stats
=
smb2_print_stats
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
@@ -998,6 +1011,7 @@ struct smb_version_operations smb30_operations = {
.
print_stats
=
smb2_print_stats
,
.
dump_share_caps
=
smb2_dump_share_caps
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
@@ -1049,6 +1063,7 @@ struct smb_version_operations smb30_operations = {
.
set_oplock_level
=
smb3_set_oplock_level
,
.
create_lease_buf
=
smb3_create_lease_buf
,
.
parse_lease_buf
=
smb3_parse_lease_buf
,
.
validate_negotiate
=
smb3_validate_negotiate
,
};
struct
smb_version_values
smb20_values
=
{
...
...
sources/3.12/smb2pdu.c
View file @
9aa3ba91
...
...
@@ -375,7 +375,12 @@ 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
);
/* ClientGUID must be zero for SMB2.02 dialect */
if
(
ses
->
server
->
vals
->
protocol_id
==
SMB20_PROT_ID
)
memset
(
req
->
ClientGUID
,
0
,
SMB2_CLIENT_GUID_SIZE
);
else
memcpy
(
req
->
ClientGUID
,
server
->
client_guid
,
SMB2_CLIENT_GUID_SIZE
);
iov
[
0
].
iov_base
=
(
char
*
)
req
;
/* 4 for rfc1002 length field */
...
...
@@ -456,6 +461,82 @@ neg_exit:
return
rc
;
}
int
smb3_validate_negotiate
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
)
{
int
rc
=
0
;
struct
validate_negotiate_info_req
vneg_inbuf
;
struct
validate_negotiate_info_rsp
*
pneg_rsp
;
u32
rsplen
;
cifs_dbg
(
FYI
,
"validate negotiate
\n
"
);
/*
* validation ioctl must be signed, so no point sending this if we
* can not sign it. We could eventually change this to selectively
* sign just this, the first and only signed request on a connection.
* This is good enough for now since a user who wants better security
* would also enable signing on the mount. Having validation of
* negotiate info for signed connections helps reduce attack vectors
*/
if
(
tcon
->
ses
->
server
->
sign
==
false
)
return
0
;
/* validation requires signing */
vneg_inbuf
.
Capabilities
=
cpu_to_le32
(
tcon
->
ses
->
server
->
vals
->
req_capabilities
);
memcpy
(
vneg_inbuf
.
Guid
,
tcon
->
ses
->
server
->
client_guid
,
SMB2_CLIENT_GUID_SIZE
);
if
(
tcon
->
ses
->
sign
)
vneg_inbuf
.
SecurityMode
=
cpu_to_le16
(
SMB2_NEGOTIATE_SIGNING_REQUIRED
);
else
if
(
global_secflags
&
CIFSSEC_MAY_SIGN
)
vneg_inbuf
.
SecurityMode
=
cpu_to_le16
(
SMB2_NEGOTIATE_SIGNING_ENABLED
);
else
vneg_inbuf
.
SecurityMode
=
0
;
vneg_inbuf
.
DialectCount
=
cpu_to_le16
(
1
);
vneg_inbuf
.
Dialects
[
0
]
=
cpu_to_le16
(
tcon
->
ses
->
server
->
vals
->
protocol_id
);
rc
=
SMB2_ioctl
(
xid
,
tcon
,
NO_FILE_ID
,
NO_FILE_ID
,
FSCTL_VALIDATE_NEGOTIATE_INFO
,
true
/* is_fsctl */
,
(
char
*
)
&
vneg_inbuf
,
sizeof
(
struct
validate_negotiate_info_req
),
(
char
**
)
&
pneg_rsp
,
&
rsplen
);
if
(
rc
!=
0
)
{
cifs_dbg
(
VFS
,
"validate protocol negotiate failed: %d
\n
"
,
rc
);
return
-
EIO
;
}
if
(
rsplen
!=
sizeof
(
struct
validate_negotiate_info_rsp
))
{
cifs_dbg
(
VFS
,
"invalid size of protocol negotiate response
\n
"
);
return
-
EIO
;
}
/* check validate negotiate info response matches what we got earlier */
if
(
pneg_rsp
->
Dialect
!=
cpu_to_le16
(
tcon
->
ses
->
server
->
vals
->
protocol_id
))
goto
vneg_out
;
if
(
pneg_rsp
->
SecurityMode
!=
cpu_to_le16
(
tcon
->
ses
->
server
->
sec_mode
))
goto
vneg_out
;
/* do not validate server guid because not saved at negprot time yet */
if
((
le32_to_cpu
(
pneg_rsp
->
Capabilities
)
|
SMB2_NT_FIND
|
SMB2_LARGE_FILES
)
!=
tcon
->
ses
->
server
->
capabilities
)
goto
vneg_out
;
/* validate negotiate successful */
cifs_dbg
(
FYI
,
"validate negotiate info successful
\n
"
);
return
0
;
vneg_out:
cifs_dbg
(
VFS
,
"protocol revalidation - security settings mismatch
\n
"
);
return
-
EIO
;
}
int
SMB2_sess_setup
(
const
unsigned
int
xid
,
struct
cifs_ses
*
ses
,
const
struct
nls_table
*
nls_cp
)
...
...
@@ -821,6 +902,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
((
tcon
->
share_flags
&
SHI1005_FLAGS_DFS
)
==
0
))
cifs_dbg
(
VFS
,
"DFS capability contradicts DFS flag
\n
"
);
if
(
tcon
->
ses
->
server
->
ops
->
validate_negotiate
)
rc
=
tcon
->
ses
->
server
->
ops
->
validate_negotiate
(
xid
,
tcon
);
tcon_exit:
free_rsp_buf
(
resp_buftype
,
rsp
);
kfree
(
unc_path
);
...
...
sources/3.12/smb2pdu.h
View file @
9aa3ba91
...
...
@@ -166,8 +166,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 */
...
...
@@ -546,13 +544,19 @@ struct copychunk_ioctl {
__u32
Reserved2
;
}
__packed
;
/* Response and Request are the same format */
struct
validate_negotiate_info
{
struct
validate_negotiate_info_req
{
__le32
Capabilities
;
__u8
Guid
[
SMB2_CLIENT_GUID_SIZE
];
__le16
SecurityMode
;
__le16
DialectCount
;
__le16
Dialect
[
1
];
__le16
Dialects
[
1
];
/* dialect (someday maybe list) client asked for */
}
__packed
;
struct
validate_negotiate_info_rsp
{
__le32
Capabilities
;
__u8
Guid
[
SMB2_CLIENT_GUID_SIZE
];
__le16
SecurityMode
;
__le16
Dialect
;
/* Dialect in use for the connection */
}
__packed
;
#define RSS_CAPABLE 0x00000001
...
...
sources/3.12/smb2proto.h
View file @
9aa3ba91
...
...
@@ -158,5 +158,6 @@ extern int smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
struct
smb2_lock_element
*
buf
);
extern
int
SMB2_lease_break
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
__u8
*
lease_key
,
const
__le32
lease_state
);
extern
int
smb3_validate_negotiate
(
const
unsigned
int
,
struct
cifs_tcon
*
);
#endif
/* _SMB2PROTO_H */
sources/3.12/smbfsctl.h
View file @
9aa3ba91
...
...
@@ -90,7 +90,7 @@
#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4
/* BB add struct */
#define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8
/* BB add struct */
#define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC
/* BB add struct */
#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
/* BB add struct */
#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
/* Perform server-side data movement */
#define FSCTL_SRV_COPYCHUNK 0x001440F2
#define FSCTL_SRV_COPYCHUNK_WRITE 0x001480F2
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment