Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
34f598ca
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
34f598ca
编写于
1月 18, 2012
作者:
S
Steve French
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git+ssh://git.samba.org/data/git/sfrench/cifs-2.6
上级
dcd169b7
789b4588
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
312 addition
and
63 deletion
+312
-63
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.c
+10
-1
fs/cifs/cifs_spnego.c
fs/cifs/cifs_spnego.c
+7
-3
fs/cifs/cifsencrypt.c
fs/cifs/cifsencrypt.c
+8
-3
fs/cifs/connect.c
fs/cifs/connect.c
+246
-55
include/keys/user-type.h
include/keys/user-type.h
+2
-1
security/keys/internal.h
security/keys/internal.h
+1
-0
security/keys/key.c
security/keys/key.c
+1
-0
security/keys/user_defined.c
security/keys/user_defined.c
+37
-0
未找到文件。
fs/cifs/cifs_debug.c
浏览文件 @
34f598ca
...
@@ -676,14 +676,23 @@ static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
...
@@ -676,14 +676,23 @@ static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
{
{
char
c
;
char
c
;
int
rc
;
int
rc
;
static
bool
warned
;
rc
=
get_user
(
c
,
buffer
);
rc
=
get_user
(
c
,
buffer
);
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
multiuser_mount
=
0
;
multiuser_mount
=
0
;
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
{
multiuser_mount
=
1
;
multiuser_mount
=
1
;
if
(
!
warned
)
{
warned
=
true
;
printk
(
KERN_WARNING
"CIFS VFS: The legacy multiuser "
"mount code is scheduled to be deprecated in "
"3.5. Please switch to using the multiuser "
"mount option."
);
}
}
return
count
;
return
count
;
}
}
...
...
fs/cifs/cifs_spnego.c
浏览文件 @
34f598ca
...
@@ -113,9 +113,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
...
@@ -113,9 +113,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
MAX_MECH_STR_LEN
+
MAX_MECH_STR_LEN
+
UID_KEY_LEN
+
(
sizeof
(
uid_t
)
*
2
)
+
UID_KEY_LEN
+
(
sizeof
(
uid_t
)
*
2
)
+
CREDUID_KEY_LEN
+
(
sizeof
(
uid_t
)
*
2
)
+
CREDUID_KEY_LEN
+
(
sizeof
(
uid_t
)
*
2
)
+
USER_KEY_LEN
+
strlen
(
sesInfo
->
user_name
)
+
PID_KEY_LEN
+
(
sizeof
(
pid_t
)
*
2
)
+
1
;
PID_KEY_LEN
+
(
sizeof
(
pid_t
)
*
2
)
+
1
;
if
(
sesInfo
->
user_name
)
desc_len
+=
USER_KEY_LEN
+
strlen
(
sesInfo
->
user_name
);
spnego_key
=
ERR_PTR
(
-
ENOMEM
);
spnego_key
=
ERR_PTR
(
-
ENOMEM
);
description
=
kzalloc
(
desc_len
,
GFP_KERNEL
);
description
=
kzalloc
(
desc_len
,
GFP_KERNEL
);
if
(
description
==
NULL
)
if
(
description
==
NULL
)
...
@@ -152,8 +154,10 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
...
@@ -152,8 +154,10 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
dp
=
description
+
strlen
(
description
);
dp
=
description
+
strlen
(
description
);
sprintf
(
dp
,
";creduid=0x%x"
,
sesInfo
->
cred_uid
);
sprintf
(
dp
,
";creduid=0x%x"
,
sesInfo
->
cred_uid
);
dp
=
description
+
strlen
(
description
);
if
(
sesInfo
->
user_name
)
{
sprintf
(
dp
,
";user=%s"
,
sesInfo
->
user_name
);
dp
=
description
+
strlen
(
description
);
sprintf
(
dp
,
";user=%s"
,
sesInfo
->
user_name
);
}
dp
=
description
+
strlen
(
description
);
dp
=
description
+
strlen
(
description
);
sprintf
(
dp
,
";pid=0x%x"
,
current
->
pid
);
sprintf
(
dp
,
";pid=0x%x"
,
current
->
pid
);
...
...
fs/cifs/cifsencrypt.c
浏览文件 @
34f598ca
...
@@ -420,15 +420,20 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
...
@@ -420,15 +420,20 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
}
}
/* convert ses->user_name to unicode and uppercase */
/* convert ses->user_name to unicode and uppercase */
len
=
s
trlen
(
ses
->
user_name
)
;
len
=
s
es
->
user_name
?
strlen
(
ses
->
user_name
)
:
0
;
user
=
kmalloc
(
2
+
(
len
*
2
),
GFP_KERNEL
);
user
=
kmalloc
(
2
+
(
len
*
2
),
GFP_KERNEL
);
if
(
user
==
NULL
)
{
if
(
user
==
NULL
)
{
cERROR
(
1
,
"calc_ntlmv2_hash: user mem alloc failure
\n
"
);
cERROR
(
1
,
"calc_ntlmv2_hash: user mem alloc failure
\n
"
);
rc
=
-
ENOMEM
;
rc
=
-
ENOMEM
;
return
rc
;
return
rc
;
}
}
len
=
cifs_strtoUCS
((
__le16
*
)
user
,
ses
->
user_name
,
len
,
nls_cp
);
UniStrupr
(
user
);
if
(
len
)
{
len
=
cifs_strtoUCS
((
__le16
*
)
user
,
ses
->
user_name
,
len
,
nls_cp
);
UniStrupr
(
user
);
}
else
{
memset
(
user
,
'\0'
,
2
);
}
rc
=
crypto_shash_update
(
&
ses
->
server
->
secmech
.
sdeschmacmd5
->
shash
,
rc
=
crypto_shash_update
(
&
ses
->
server
->
secmech
.
sdeschmacmd5
->
shash
,
(
char
*
)
user
,
2
*
len
);
(
char
*
)
user
,
2
*
len
);
...
...
fs/cifs/connect.c
浏览文件 @
34f598ca
...
@@ -38,6 +38,7 @@
...
@@ -38,6 +38,7 @@
#include <asm/processor.h>
#include <asm/processor.h>
#include <linux/inet.h>
#include <linux/inet.h>
#include <linux/module.h>
#include <linux/module.h>
#include <keys/user-type.h>
#include <net/ipv6.h>
#include <net/ipv6.h>
#include "cifspdu.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsglob.h"
...
@@ -225,74 +226,90 @@ static int check2ndT2(struct smb_hdr *pSMB)
...
@@ -225,74 +226,90 @@ static int check2ndT2(struct smb_hdr *pSMB)
static
int
coalesce_t2
(
struct
smb_hdr
*
psecond
,
struct
smb_hdr
*
pTargetSMB
)
static
int
coalesce_t2
(
struct
smb_hdr
*
psecond
,
struct
smb_hdr
*
pTargetSMB
)
{
{
struct
smb_t2_rsp
*
pSMB
2
=
(
struct
smb_t2_rsp
*
)
psecond
;
struct
smb_t2_rsp
*
pSMB
s
=
(
struct
smb_t2_rsp
*
)
psecond
;
struct
smb_t2_rsp
*
pSMBt
=
(
struct
smb_t2_rsp
*
)
pTargetSMB
;
struct
smb_t2_rsp
*
pSMBt
=
(
struct
smb_t2_rsp
*
)
pTargetSMB
;
char
*
data_area_of_t
arge
t
;
char
*
data_area_of_t
g
t
;
char
*
data_area_of_
buf2
;
char
*
data_area_of_
src
;
int
remaining
;
int
remaining
;
unsigned
int
byte_count
,
total_in_
buf
;
unsigned
int
byte_count
,
total_in_
tgt
;
__u16
t
otal_data_size
,
total_in_buf2
;
__u16
t
gt_total_cnt
,
src_total_cnt
,
total_in_src
;
total_data_size
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
TotalDataCount
);
src_total_cnt
=
get_unaligned_le16
(
&
pSMBs
->
t2_rsp
.
TotalDataCount
);
tgt_total_cnt
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
TotalDataCount
);
if
(
t
otal_data_size
!=
if
(
t
gt_total_cnt
!=
src_total_cnt
)
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
TotalDataCount
))
cFYI
(
1
,
"total data count of primary and secondary t2 differ "
cFYI
(
1
,
"total data size of primary and secondary t2 differ"
);
"source=%hu target=%hu"
,
src_total_cnt
,
tgt_total_cnt
);
total_in_
buf
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataCount
);
total_in_
tgt
=
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataCount
);
remaining
=
t
otal_data_size
-
total_in_buf
;
remaining
=
t
gt_total_cnt
-
total_in_tgt
;
if
(
remaining
<
0
)
if
(
remaining
<
0
)
{
cFYI
(
1
,
"Server sent too much data. tgt_total_cnt=%hu "
"total_in_tgt=%hu"
,
tgt_total_cnt
,
total_in_tgt
);
return
-
EPROTO
;
return
-
EPROTO
;
}
if
(
remaining
==
0
)
/* nothing to do, ignore */
if
(
remaining
==
0
)
{
/* nothing to do, ignore */
cFYI
(
1
,
"no more data remains"
);
return
0
;
return
0
;
}
total_in_
buf2
=
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
DataCount
);
total_in_
src
=
get_unaligned_le16
(
&
pSMBs
->
t2_rsp
.
DataCount
);
if
(
remaining
<
total_in_
buf2
)
{
if
(
remaining
<
total_in_
src
)
cFYI
(
1
,
"transact2 2nd response contains too much data"
);
cFYI
(
1
,
"transact2 2nd response contains too much data"
);
}
/* find end of first SMB data area */
/* find end of first SMB data area */
data_area_of_t
arge
t
=
(
char
*
)
&
pSMBt
->
hdr
.
Protocol
+
data_area_of_t
g
t
=
(
char
*
)
&
pSMBt
->
hdr
.
Protocol
+
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataOffset
);
get_unaligned_le16
(
&
pSMBt
->
t2_rsp
.
DataOffset
);
/* validate target area */
data_area_of_buf2
=
(
char
*
)
&
pSMB2
->
hdr
.
Protocol
+
/* validate target area */
get_unaligned_le16
(
&
pSMB2
->
t2_rsp
.
DataOffset
);
data_area_of_src
=
(
char
*
)
&
pSMBs
->
hdr
.
Protocol
+
get_unaligned_le16
(
&
pSMBs
->
t2_rsp
.
DataOffset
);
data_area_of_t
arget
+=
total_in_buf
;
data_area_of_t
gt
+=
total_in_tgt
;
/* copy second buffer into end of first buffer */
total_in_tgt
+=
total_in_src
;
total_in_buf
+=
total_in_buf2
;
/* is the result too big for the field? */
/* is the result too big for the field? */
if
(
total_in_buf
>
USHRT_MAX
)
if
(
total_in_tgt
>
USHRT_MAX
)
{
cFYI
(
1
,
"coalesced DataCount too large (%u)"
,
total_in_tgt
);
return
-
EPROTO
;
return
-
EPROTO
;
put_unaligned_le16
(
total_in_buf
,
&
pSMBt
->
t2_rsp
.
DataCount
);
}
put_unaligned_le16
(
total_in_tgt
,
&
pSMBt
->
t2_rsp
.
DataCount
);
/* fix up the BCC */
/* fix up the BCC */
byte_count
=
get_bcc
(
pTargetSMB
);
byte_count
=
get_bcc
(
pTargetSMB
);
byte_count
+=
total_in_
buf2
;
byte_count
+=
total_in_
src
;
/* is the result too big for the field? */
/* is the result too big for the field? */
if
(
byte_count
>
USHRT_MAX
)
if
(
byte_count
>
USHRT_MAX
)
{
cFYI
(
1
,
"coalesced BCC too large (%u)"
,
byte_count
);
return
-
EPROTO
;
return
-
EPROTO
;
}
put_bcc
(
byte_count
,
pTargetSMB
);
put_bcc
(
byte_count
,
pTargetSMB
);
byte_count
=
be32_to_cpu
(
pTargetSMB
->
smb_buf_length
);
byte_count
=
be32_to_cpu
(
pTargetSMB
->
smb_buf_length
);
byte_count
+=
total_in_
buf2
;
byte_count
+=
total_in_
src
;
/* don't allow buffer to overflow */
/* don't allow buffer to overflow */
if
(
byte_count
>
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
-
4
)
if
(
byte_count
>
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
-
4
)
{
cFYI
(
1
,
"coalesced BCC exceeds buffer size (%u)"
,
byte_count
);
return
-
ENOBUFS
;
return
-
ENOBUFS
;
}
pTargetSMB
->
smb_buf_length
=
cpu_to_be32
(
byte_count
);
pTargetSMB
->
smb_buf_length
=
cpu_to_be32
(
byte_count
);
memcpy
(
data_area_of_target
,
data_area_of_buf2
,
total_in_buf2
);
/* copy second buffer into end of first buffer */
memcpy
(
data_area_of_tgt
,
data_area_of_src
,
total_in_src
);
if
(
remaining
==
total_in_buf2
)
{
if
(
remaining
!=
total_in_src
)
{
cFYI
(
1
,
"found the last secondary response"
);
/* more responses to go */
return
0
;
/* we are done */
cFYI
(
1
,
"waiting for more secondary responses"
);
}
else
/* more responses to go */
return
1
;
return
1
;
}
/* we are done */
cFYI
(
1
,
"found the last secondary response"
);
return
0
;
}
}
static
void
static
void
...
@@ -1578,11 +1595,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
...
@@ -1578,11 +1595,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
}
}
}
}
if
(
vol
->
multiuser
&&
!
(
vol
->
secFlg
&
CIFSSEC_MAY_KRB5
))
{
#ifndef CONFIG_KEYS
cERROR
(
1
,
"Multiuser mounts currently require krb5 "
/* Muliuser mounts require CONFIG_KEYS support */
"authentication!"
);
if
(
vol
->
multiuser
)
{
cERROR
(
1
,
"Multiuser mounts require kernels with "
"CONFIG_KEYS enabled."
);
goto
cifs_parse_mount_err
;
goto
cifs_parse_mount_err
;
}
}
#endif
if
(
vol
->
UNCip
==
NULL
)
if
(
vol
->
UNCip
==
NULL
)
vol
->
UNCip
=
&
vol
->
UNC
[
2
];
vol
->
UNCip
=
&
vol
->
UNC
[
2
];
...
@@ -1981,10 +2001,16 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
...
@@ -1981,10 +2001,16 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
return
0
;
return
0
;
break
;
break
;
default:
default:
/* NULL username means anonymous session */
if
(
ses
->
user_name
==
NULL
)
{
if
(
!
vol
->
nullauth
)
return
0
;
break
;
}
/* anything else takes username/password */
/* anything else takes username/password */
if
(
ses
->
user_name
==
NULL
)
if
(
strncmp
(
ses
->
user_name
,
return
0
;
vol
->
username
?
vol
->
username
:
""
,
if
(
strncmp
(
ses
->
user_name
,
vol
->
username
,
MAX_USERNAME_SIZE
))
MAX_USERNAME_SIZE
))
return
0
;
return
0
;
if
(
strlen
(
vol
->
username
)
!=
0
&&
if
(
strlen
(
vol
->
username
)
!=
0
&&
...
@@ -2039,6 +2065,132 @@ cifs_put_smb_ses(struct cifs_ses *ses)
...
@@ -2039,6 +2065,132 @@ cifs_put_smb_ses(struct cifs_ses *ses)
cifs_put_tcp_session
(
server
);
cifs_put_tcp_session
(
server
);
}
}
#ifdef CONFIG_KEYS
/* strlen("cifs:a:") + INET6_ADDRSTRLEN + 1 */
#define CIFSCREDS_DESC_SIZE (7 + INET6_ADDRSTRLEN + 1)
/* Populate username and pw fields from keyring if possible */
static
int
cifs_set_cifscreds
(
struct
smb_vol
*
vol
,
struct
cifs_ses
*
ses
)
{
int
rc
=
0
;
char
*
desc
,
*
delim
,
*
payload
;
ssize_t
len
;
struct
key
*
key
;
struct
TCP_Server_Info
*
server
=
ses
->
server
;
struct
sockaddr_in
*
sa
;
struct
sockaddr_in6
*
sa6
;
struct
user_key_payload
*
upayload
;
desc
=
kmalloc
(
CIFSCREDS_DESC_SIZE
,
GFP_KERNEL
);
if
(
!
desc
)
return
-
ENOMEM
;
/* try to find an address key first */
switch
(
server
->
dstaddr
.
ss_family
)
{
case
AF_INET
:
sa
=
(
struct
sockaddr_in
*
)
&
server
->
dstaddr
;
sprintf
(
desc
,
"cifs:a:%pI4"
,
&
sa
->
sin_addr
.
s_addr
);
break
;
case
AF_INET6
:
sa6
=
(
struct
sockaddr_in6
*
)
&
server
->
dstaddr
;
sprintf
(
desc
,
"cifs:a:%pI6c"
,
&
sa6
->
sin6_addr
.
s6_addr
);
break
;
default:
cFYI
(
1
,
"Bad ss_family (%hu)"
,
server
->
dstaddr
.
ss_family
);
rc
=
-
EINVAL
;
goto
out_err
;
}
cFYI
(
1
,
"%s: desc=%s"
,
__func__
,
desc
);
key
=
request_key
(
&
key_type_logon
,
desc
,
""
);
if
(
IS_ERR
(
key
))
{
if
(
!
ses
->
domainName
)
{
cFYI
(
1
,
"domainName is NULL"
);
rc
=
PTR_ERR
(
key
);
goto
out_err
;
}
/* didn't work, try to find a domain key */
sprintf
(
desc
,
"cifs:d:%s"
,
ses
->
domainName
);
cFYI
(
1
,
"%s: desc=%s"
,
__func__
,
desc
);
key
=
request_key
(
&
key_type_logon
,
desc
,
""
);
if
(
IS_ERR
(
key
))
{
rc
=
PTR_ERR
(
key
);
goto
out_err
;
}
}
down_read
(
&
key
->
sem
);
upayload
=
key
->
payload
.
data
;
if
(
IS_ERR_OR_NULL
(
upayload
))
{
rc
=
PTR_ERR
(
key
);
goto
out_key_put
;
}
/* find first : in payload */
payload
=
(
char
*
)
upayload
->
data
;
delim
=
strnchr
(
payload
,
upayload
->
datalen
,
':'
);
cFYI
(
1
,
"payload=%s"
,
payload
);
if
(
!
delim
)
{
cFYI
(
1
,
"Unable to find ':' in payload (datalen=%d)"
,
upayload
->
datalen
);
rc
=
-
EINVAL
;
goto
out_key_put
;
}
len
=
delim
-
payload
;
if
(
len
>
MAX_USERNAME_SIZE
||
len
<=
0
)
{
cFYI
(
1
,
"Bad value from username search (len=%ld)"
,
len
);
rc
=
-
EINVAL
;
goto
out_key_put
;
}
vol
->
username
=
kstrndup
(
payload
,
len
,
GFP_KERNEL
);
if
(
!
vol
->
username
)
{
cFYI
(
1
,
"Unable to allocate %ld bytes for username"
,
len
);
rc
=
-
ENOMEM
;
goto
out_key_put
;
}
cFYI
(
1
,
"%s: username=%s"
,
__func__
,
vol
->
username
);
len
=
key
->
datalen
-
(
len
+
1
);
if
(
len
>
MAX_PASSWORD_SIZE
||
len
<=
0
)
{
cFYI
(
1
,
"Bad len for password search (len=%ld)"
,
len
);
rc
=
-
EINVAL
;
kfree
(
vol
->
username
);
vol
->
username
=
NULL
;
goto
out_key_put
;
}
++
delim
;
vol
->
password
=
kstrndup
(
delim
,
len
,
GFP_KERNEL
);
if
(
!
vol
->
password
)
{
cFYI
(
1
,
"Unable to allocate %ld bytes for password"
,
len
);
rc
=
-
ENOMEM
;
kfree
(
vol
->
username
);
vol
->
username
=
NULL
;
goto
out_key_put
;
}
out_key_put:
up_read
(
&
key
->
sem
);
key_put
(
key
);
out_err:
kfree
(
desc
);
cFYI
(
1
,
"%s: returning %d"
,
__func__
,
rc
);
return
rc
;
}
#else
/* ! CONFIG_KEYS */
static
inline
int
cifs_set_cifscreds
(
struct
smb_vol
*
vol
__attribute__
((
unused
)),
struct
cifs_ses
*
ses
__attribute__
((
unused
)))
{
return
-
ENOSYS
;
}
#endif
/* CONFIG_KEYS */
static
bool
warned_on_ntlm
;
/* globals init to false automatically */
static
bool
warned_on_ntlm
;
/* globals init to false automatically */
static
struct
cifs_ses
*
static
struct
cifs_ses
*
...
@@ -2914,18 +3066,33 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
...
@@ -2914,18 +3066,33 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
/*
/*
* Windows only supports a max of 60k reads. Default to that when posix
* Windows only supports a max of 60kb reads and 65535 byte writes. Default to
* extensions aren't in force.
* those values when posix extensions aren't in force. In actuality here, we
* use 65536 to allow for a write that is a multiple of 4k. Most servers seem
* to be ok with the extra byte even though Windows doesn't send writes that
* are that large.
*
* Citation:
*
* http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx
*/
*/
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
static
unsigned
int
static
unsigned
int
cifs_negotiate_wsize
(
struct
cifs_tcon
*
tcon
,
struct
smb_vol
*
pvolume_info
)
cifs_negotiate_wsize
(
struct
cifs_tcon
*
tcon
,
struct
smb_vol
*
pvolume_info
)
{
{
__u64
unix_cap
=
le64_to_cpu
(
tcon
->
fsUnixInfo
.
Capability
);
__u64
unix_cap
=
le64_to_cpu
(
tcon
->
fsUnixInfo
.
Capability
);
struct
TCP_Server_Info
*
server
=
tcon
->
ses
->
server
;
struct
TCP_Server_Info
*
server
=
tcon
->
ses
->
server
;
unsigned
int
wsize
=
pvolume_info
->
wsize
?
pvolume_info
->
wsize
:
unsigned
int
wsize
;
CIFS_DEFAULT_IOSIZE
;
/* start with specified wsize, or default */
if
(
pvolume_info
->
wsize
)
wsize
=
pvolume_info
->
wsize
;
else
if
(
tcon
->
unix_ext
&&
(
unix_cap
&
CIFS_UNIX_LARGE_WRITE_CAP
))
wsize
=
CIFS_DEFAULT_IOSIZE
;
else
wsize
=
CIFS_DEFAULT_NON_POSIX_WSIZE
;
/* can server support 24-bit write sizes? (via UNIX extensions) */
/* can server support 24-bit write sizes? (via UNIX extensions) */
if
(
!
tcon
->
unix_ext
||
!
(
unix_cap
&
CIFS_UNIX_LARGE_WRITE_CAP
))
if
(
!
tcon
->
unix_ext
||
!
(
unix_cap
&
CIFS_UNIX_LARGE_WRITE_CAP
))
...
@@ -3136,10 +3303,9 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
...
@@ -3136,10 +3303,9 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
return
-
EINVAL
;
return
-
EINVAL
;
if
(
volume_info
->
nullauth
)
{
if
(
volume_info
->
nullauth
)
{
cFYI
(
1
,
"null user"
);
cFYI
(
1
,
"Anonymous login"
);
volume_info
->
username
=
kzalloc
(
1
,
GFP_KERNEL
);
kfree
(
volume_info
->
username
);
if
(
volume_info
->
username
==
NULL
)
volume_info
->
username
=
NULL
;
return
-
ENOMEM
;
}
else
if
(
volume_info
->
username
)
{
}
else
if
(
volume_info
->
username
)
{
/* BB fixme parse for domain name here */
/* BB fixme parse for domain name here */
cFYI
(
1
,
"Username: %s"
,
volume_info
->
username
);
cFYI
(
1
,
"Username: %s"
,
volume_info
->
username
);
...
@@ -3657,16 +3823,38 @@ int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
...
@@ -3657,16 +3823,38 @@ int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
return
rc
;
return
rc
;
}
}
static
int
cifs_set_vol_auth
(
struct
smb_vol
*
vol
,
struct
cifs_ses
*
ses
)
{
switch
(
ses
->
server
->
secType
)
{
case
Kerberos
:
vol
->
secFlg
=
CIFSSEC_MUST_KRB5
;
return
0
;
case
NTLMv2
:
vol
->
secFlg
=
CIFSSEC_MUST_NTLMV2
;
break
;
case
NTLM
:
vol
->
secFlg
=
CIFSSEC_MUST_NTLM
;
break
;
case
RawNTLMSSP
:
vol
->
secFlg
=
CIFSSEC_MUST_NTLMSSP
;
break
;
case
LANMAN
:
vol
->
secFlg
=
CIFSSEC_MUST_LANMAN
;
break
;
}
return
cifs_set_cifscreds
(
vol
,
ses
);
}
static
struct
cifs_tcon
*
static
struct
cifs_tcon
*
cifs_construct_tcon
(
struct
cifs_sb_info
*
cifs_sb
,
uid_t
fsuid
)
cifs_construct_tcon
(
struct
cifs_sb_info
*
cifs_sb
,
uid_t
fsuid
)
{
{
int
rc
;
struct
cifs_tcon
*
master_tcon
=
cifs_sb_master_tcon
(
cifs_sb
);
struct
cifs_tcon
*
master_tcon
=
cifs_sb_master_tcon
(
cifs_sb
);
struct
cifs_ses
*
ses
;
struct
cifs_ses
*
ses
;
struct
cifs_tcon
*
tcon
=
NULL
;
struct
cifs_tcon
*
tcon
=
NULL
;
struct
smb_vol
*
vol_info
;
struct
smb_vol
*
vol_info
;
char
username
[
28
];
/* big enough for "krb50x" + hex of ULONG_MAX 6+16 */
/* We used to have this as MAX_USERNAME which is */
/* way too big now (256 instead of 32) */
vol_info
=
kzalloc
(
sizeof
(
*
vol_info
),
GFP_KERNEL
);
vol_info
=
kzalloc
(
sizeof
(
*
vol_info
),
GFP_KERNEL
);
if
(
vol_info
==
NULL
)
{
if
(
vol_info
==
NULL
)
{
...
@@ -3674,8 +3862,6 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
...
@@ -3674,8 +3862,6 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
goto
out
;
goto
out
;
}
}
snprintf
(
username
,
sizeof
(
username
),
"krb50x%x"
,
fsuid
);
vol_info
->
username
=
username
;
vol_info
->
local_nls
=
cifs_sb
->
local_nls
;
vol_info
->
local_nls
=
cifs_sb
->
local_nls
;
vol_info
->
linux_uid
=
fsuid
;
vol_info
->
linux_uid
=
fsuid
;
vol_info
->
cred_uid
=
fsuid
;
vol_info
->
cred_uid
=
fsuid
;
...
@@ -3685,8 +3871,11 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
...
@@ -3685,8 +3871,11 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
vol_info
->
local_lease
=
master_tcon
->
local_lease
;
vol_info
->
local_lease
=
master_tcon
->
local_lease
;
vol_info
->
no_linux_ext
=
!
master_tcon
->
unix_ext
;
vol_info
->
no_linux_ext
=
!
master_tcon
->
unix_ext
;
/* FIXME: allow for other secFlg settings */
rc
=
cifs_set_vol_auth
(
vol_info
,
master_tcon
->
ses
);
vol_info
->
secFlg
=
CIFSSEC_MUST_KRB5
;
if
(
rc
)
{
tcon
=
ERR_PTR
(
rc
);
goto
out
;
}
/* get a reference for the same TCP session */
/* get a reference for the same TCP session */
spin_lock
(
&
cifs_tcp_ses_lock
);
spin_lock
(
&
cifs_tcp_ses_lock
);
...
@@ -3709,6 +3898,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
...
@@ -3709,6 +3898,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
if
(
ses
->
capabilities
&
CAP_UNIX
)
if
(
ses
->
capabilities
&
CAP_UNIX
)
reset_cifs_unix_caps
(
0
,
tcon
,
NULL
,
vol_info
);
reset_cifs_unix_caps
(
0
,
tcon
,
NULL
,
vol_info
);
out:
out:
kfree
(
vol_info
->
username
);
kfree
(
vol_info
->
password
);
kfree
(
vol_info
);
kfree
(
vol_info
);
return
tcon
;
return
tcon
;
...
...
include/keys/user-type.h
浏览文件 @
34f598ca
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
/*****************************************************************************/
/*****************************************************************************/
/*
/*
* the payload for a key of type "user"
* the payload for a key of type "user"
or "logon"
* - once filled in and attached to a key:
* - once filled in and attached to a key:
* - the payload struct is invariant may not be changed, only replaced
* - the payload struct is invariant may not be changed, only replaced
* - the payload must be read with RCU procedures or with the key semaphore
* - the payload must be read with RCU procedures or with the key semaphore
...
@@ -33,6 +33,7 @@ struct user_key_payload {
...
@@ -33,6 +33,7 @@ struct user_key_payload {
};
};
extern
struct
key_type
key_type_user
;
extern
struct
key_type
key_type_user
;
extern
struct
key_type
key_type_logon
;
extern
int
user_instantiate
(
struct
key
*
key
,
const
void
*
data
,
size_t
datalen
);
extern
int
user_instantiate
(
struct
key
*
key
,
const
void
*
data
,
size_t
datalen
);
extern
int
user_update
(
struct
key
*
key
,
const
void
*
data
,
size_t
datalen
);
extern
int
user_update
(
struct
key
*
key
,
const
void
*
data
,
size_t
datalen
);
...
...
security/keys/internal.h
浏览文件 @
34f598ca
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
extern
struct
key_type
key_type_dead
;
extern
struct
key_type
key_type_dead
;
extern
struct
key_type
key_type_user
;
extern
struct
key_type
key_type_user
;
extern
struct
key_type
key_type_logon
;
/*****************************************************************************/
/*****************************************************************************/
/*
/*
...
...
security/keys/key.c
浏览文件 @
34f598ca
...
@@ -999,6 +999,7 @@ void __init key_init(void)
...
@@ -999,6 +999,7 @@ void __init key_init(void)
list_add_tail
(
&
key_type_keyring
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_keyring
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_dead
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_dead
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_user
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_user
.
link
,
&
key_types_list
);
list_add_tail
(
&
key_type_logon
.
link
,
&
key_types_list
);
/* record the root user tracking */
/* record the root user tracking */
rb_link_node
(
&
root_key_user
.
node
,
rb_link_node
(
&
root_key_user
.
node
,
...
...
security/keys/user_defined.c
浏览文件 @
34f598ca
...
@@ -18,6 +18,8 @@
...
@@ -18,6 +18,8 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include "internal.h"
#include "internal.h"
static
int
logon_vet_description
(
const
char
*
desc
);
/*
/*
* user defined keys take an arbitrary string as the description and an
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
* arbitrary blob of data as the payload
...
@@ -35,6 +37,24 @@ struct key_type key_type_user = {
...
@@ -35,6 +37,24 @@ struct key_type key_type_user = {
EXPORT_SYMBOL_GPL
(
key_type_user
);
EXPORT_SYMBOL_GPL
(
key_type_user
);
/*
* This key type is essentially the same as key_type_user, but it does
* not define a .read op. This is suitable for storing username and
* password pairs in the keyring that you do not want to be readable
* from userspace.
*/
struct
key_type
key_type_logon
=
{
.
name
=
"logon"
,
.
instantiate
=
user_instantiate
,
.
update
=
user_update
,
.
match
=
user_match
,
.
revoke
=
user_revoke
,
.
destroy
=
user_destroy
,
.
describe
=
user_describe
,
.
vet_description
=
logon_vet_description
,
};
EXPORT_SYMBOL_GPL
(
key_type_logon
);
/*
/*
* instantiate a user defined key
* instantiate a user defined key
*/
*/
...
@@ -189,3 +209,20 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
...
@@ -189,3 +209,20 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
}
}
EXPORT_SYMBOL_GPL
(
user_read
);
EXPORT_SYMBOL_GPL
(
user_read
);
/* Vet the description for a "logon" key */
static
int
logon_vet_description
(
const
char
*
desc
)
{
char
*
p
;
/* require a "qualified" description string */
p
=
strchr
(
desc
,
':'
);
if
(
!
p
)
return
-
EINVAL
;
/* also reject description with ':' as first char */
if
(
p
==
desc
)
return
-
EINVAL
;
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录