Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
0f36b018
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0f36b018
编写于
1月 18, 2006
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6
上级
648bf4fb
47c886b3
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
729 addition
and
183 deletion
+729
-183
fs/cifs/CHANGES
fs/cifs/CHANGES
+10
-0
fs/cifs/README
fs/cifs/README
+11
-1
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.c
+31
-20
fs/cifs/cifs_fs_sb.h
fs/cifs/cifs_fs_sb.h
+3
-2
fs/cifs/cifsacl.h
fs/cifs/cifsacl.h
+38
-0
fs/cifs/cifsencrypt.c
fs/cifs/cifsencrypt.c
+54
-1
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+24
-4
fs/cifs/cifsfs.h
fs/cifs/cifsfs.h
+1
-1
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+15
-3
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+84
-13
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+14
-9
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+247
-47
fs/cifs/connect.c
fs/cifs/connect.c
+76
-13
fs/cifs/dir.c
fs/cifs/dir.c
+4
-4
fs/cifs/file.c
fs/cifs/file.c
+46
-27
fs/cifs/inode.c
fs/cifs/inode.c
+5
-4
fs/cifs/misc.c
fs/cifs/misc.c
+12
-5
fs/cifs/readdir.c
fs/cifs/readdir.c
+11
-6
fs/cifs/rfc1002pdu.h
fs/cifs/rfc1002pdu.h
+2
-2
fs/cifs/transport.c
fs/cifs/transport.c
+21
-19
fs/cifs/xattr.c
fs/cifs/xattr.c
+20
-2
未找到文件。
fs/cifs/CHANGES
浏览文件 @
0f36b018
Version 1.40
------------
Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
of readpages by eliminating one extra memcpy. Allow update of file size
from remote server even if file is open for write as long as mount is
directio. Recognize share mode security and send NTLM encrypted password
on tree connect if share mode negotiated.
Version 1.39
------------
Defer close of a file handle slightly if pending writes depend on that handle
...
...
@@ -7,6 +15,8 @@ Fix SFU style symlinks and mknod needed for servers which do not support the
CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative
dentries so files that the client sees as deleted but that later get created
on the server will be recognized. Add client side permission check on setattr.
Timeout stuck requests better (where server has never responded or sent corrupt
responses)
Version 1.38
------------
...
...
fs/cifs/README
浏览文件 @
0f36b018
...
...
@@ -436,7 +436,17 @@ A partial list of the supported mount options follows:
SFU does). In the future the bottom 9 bits of the mode
mode also will be emulated using queries of the security
descriptor (ACL).
sec Security mode. Allowed values are:
none attempt to connection as a null user (no name)
krb5 Use Kerberos version 5 authentication
krb5i Use Kerberos authentication and packet signing
ntlm Use NTLM password hashing (default)
ntlmi Use NTLM password hashing with signing (if
/proc/fs/cifs/PacketSigningEnabled on or if
server requires signing also can be the default)
ntlmv2 Use NTLMv2 password hashing
ntlmv2i Use NTLMv2 password hashing with packet signing
The mount.cifs mount helper also accepts a few mount options before -o
including:
...
...
fs/cifs/cifs_debug.c
浏览文件 @
0f36b018
...
...
@@ -219,6 +219,10 @@ cifs_stats_write(struct file *file, const char __user *buffer,
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
||
c
==
'0'
)
{
read_lock
(
&
GlobalSMBSeslock
);
#ifdef CONFIG_CIFS_STATS2
atomic_set
(
&
totBufAllocCount
,
0
);
atomic_set
(
&
totSmBufAllocCount
,
0
);
#endif
/* CONFIG_CIFS_STATS2 */
list_for_each
(
tmp
,
&
GlobalTreeConnectionList
)
{
tcon
=
list_entry
(
tmp
,
struct
cifsTconInfo
,
cifsConnectionList
);
...
...
@@ -276,6 +280,14 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
smBufAllocCount
.
counter
,
cifs_min_small
);
length
+=
item_length
;
buf
+=
item_length
;
#ifdef CONFIG_CIFS_STATS2
item_length
=
sprintf
(
buf
,
"Total Large %d Small %d Allocations
\n
"
,
atomic_read
(
&
totBufAllocCount
),
atomic_read
(
&
totSmBufAllocCount
));
length
+=
item_length
;
buf
+=
item_length
;
#endif
/* CONFIG_CIFS_STATS2 */
item_length
=
sprintf
(
buf
,
"Operations (MIDs): %d
\n
"
,
midCount
.
counter
);
...
...
@@ -389,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
static
write_proc_t
ntlmv2_enabled_write
;
static
read_proc_t
packet_signing_enabled_read
;
static
write_proc_t
packet_signing_enabled_write
;
static
read_proc_t
quota
Enabled_read
;
static
write_proc_t
quota
Enabled_write
;
static
read_proc_t
experim
Enabled_read
;
static
write_proc_t
experim
Enabled_write
;
static
read_proc_t
linuxExtensionsEnabled_read
;
static
write_proc_t
linuxExtensionsEnabled_write
;
...
...
@@ -430,9 +442,9 @@ cifs_proc_init(void)
pde
->
write_proc
=
oplockEnabled_write
;
pde
=
create_proc_read_entry
(
"Experimental"
,
0
,
proc_fs_cifs
,
quota
Enabled_read
,
NULL
);
experim
Enabled_read
,
NULL
);
if
(
pde
)
pde
->
write_proc
=
quota
Enabled_write
;
pde
->
write_proc
=
experim
Enabled_write
;
pde
=
create_proc_read_entry
(
"LinuxExtensionsEnabled"
,
0
,
proc_fs_cifs
,
linuxExtensionsEnabled_read
,
NULL
);
...
...
@@ -574,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
}
static
int
quota
Enabled_read
(
char
*
page
,
char
**
start
,
off_t
off
,
experim
Enabled_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
int
len
;
len
=
sprintf
(
page
,
"%d
\n
"
,
experimEnabled
);
/* could also check if quotas are enabled in kernel
as a whole first */
len
-=
off
;
*
start
=
page
+
off
;
...
...
@@ -596,21 +607,23 @@ quotaEnabled_read(char *page, char **start, off_t off,
return
len
;
}
static
int
quota
Enabled_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
experim
Enabled_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
char
c
;
int
rc
;
char
c
;
int
rc
;
rc
=
get_user
(
c
,
buffer
);
if
(
rc
)
return
rc
;
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
experimEnabled
=
0
;
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
experimEnabled
=
1
;
rc
=
get_user
(
c
,
buffer
);
if
(
rc
)
return
rc
;
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
experimEnabled
=
0
;
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
experimEnabled
=
1
;
else
if
(
c
==
'2'
)
experimEnabled
=
2
;
return
count
;
return
count
;
}
static
int
...
...
@@ -620,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
int
len
;
len
=
sprintf
(
page
,
"%d
\n
"
,
linuxExtEnabled
);
/* could also check if quotas are enabled in kernel
as a whole first */
len
-=
off
;
*
start
=
page
+
off
;
...
...
fs/cifs/cifs_fs_sb.h
浏览文件 @
0f36b018
...
...
@@ -24,9 +24,10 @@
#define CIFS_MOUNT_DIRECT_IO 8
/* do not write nor read through page cache */
#define CIFS_MOUNT_NO_XATTR 0x10
/* if set - disable xattr support */
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20
/* remap illegal chars in filenames */
#define CIFS_MOUNT_POSIX_PATHS
0x40
/* Negotiate posix pathnames if possible. */
#define CIFS_MOUNT_UNX_EMUL
0x80
/* Network compat with SFUnix emulation */
#define CIFS_MOUNT_POSIX_PATHS
0x40
/* Negotiate posix pathnames if possible. */
#define CIFS_MOUNT_UNX_EMUL
0x80
/* Network compat with SFUnix emulation */
#define CIFS_MOUNT_NO_BRL 0x100
/* No sending byte range locks to srv */
#define CIFS_MOUNT_CIFS_ACL 0x200
/* send ACL requests to non-POSIX srv */
struct
cifs_sb_info
{
struct
cifsTconInfo
*
tcon
;
/* primary mount */
...
...
fs/cifs/cifsacl.h
0 → 100644
浏览文件 @
0f36b018
/*
* fs/cifs/cifsacl.h
*
* Copyright (c) International Business Machines Corp., 2005
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CIFSACL_H
#define _CIFSACL_H
struct
cifs_sid
{
__u8
revision
;
/* revision level */
__u8
num_subauths
;
__u8
authority
[
6
];
__u32
sub_auth
[
4
];
/* next sub_auth if any ... */
}
__attribute__
((
packed
));
/* everyone */
extern
const
struct
cifs_sid
sid_everyone
;
/* group users */
extern
const
struct
cifs_sid
sid_user
;
#endif
/* _CIFSACL_H */
fs/cifs/cifsencrypt.c
浏览文件 @
0f36b018
/*
* fs/cifs/cifsencrypt.c
*
* Copyright (C) International Business Machines Corp., 200
3
* Copyright (C) International Business Machines Corp., 200
5
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
...
...
@@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
return
rc
;
}
static
int
cifs_calc_signature2
(
const
struct
kvec
*
iov
,
int
n_vec
,
const
char
*
key
,
char
*
signature
)
{
struct
MD5Context
context
;
if
((
iov
==
NULL
)
||
(
signature
==
NULL
))
return
-
EINVAL
;
MD5Init
(
&
context
);
MD5Update
(
&
context
,
key
,
CIFS_SESSION_KEY_SIZE
+
16
);
/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */
/* BB FIXME BB */
MD5Final
(
signature
,
&
context
);
return
-
EOPNOTSUPP
;
/* return 0; */
}
int
cifs_sign_smb2
(
struct
kvec
*
iov
,
int
n_vec
,
struct
TCP_Server_Info
*
server
,
__u32
*
pexpected_response_sequence_number
)
{
int
rc
=
0
;
char
smb_signature
[
20
];
struct
smb_hdr
*
cifs_pdu
=
iov
[
0
].
iov_base
;
if
((
cifs_pdu
==
NULL
)
||
(
server
==
NULL
))
return
-
EINVAL
;
if
((
cifs_pdu
->
Flags2
&
SMBFLG2_SECURITY_SIGNATURE
)
==
0
)
return
rc
;
spin_lock
(
&
GlobalMid_Lock
);
cifs_pdu
->
Signature
.
Sequence
.
SequenceNumber
=
cpu_to_le32
(
server
->
sequence_number
);
cifs_pdu
->
Signature
.
Sequence
.
Reserved
=
0
;
*
pexpected_response_sequence_number
=
server
->
sequence_number
++
;
server
->
sequence_number
++
;
spin_unlock
(
&
GlobalMid_Lock
);
rc
=
cifs_calc_signature2
(
iov
,
n_vec
,
server
->
mac_signing_key
,
smb_signature
);
if
(
rc
)
memset
(
cifs_pdu
->
Signature
.
SecuritySignature
,
0
,
8
);
else
memcpy
(
cifs_pdu
->
Signature
.
SecuritySignature
,
smb_signature
,
8
);
return
rc
;
}
int
cifs_verify_signature
(
struct
smb_hdr
*
cifs_pdu
,
const
char
*
mac_key
,
__u32
expected_sequence_number
)
{
...
...
fs/cifs/cifsfs.c
浏览文件 @
0f36b018
...
...
@@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
return
written
;
}
static
loff_t
cifs_llseek
(
struct
file
*
file
,
loff_t
offset
,
int
origin
)
{
/* origin == SEEK_END => we must revalidate the cached file length */
if
(
origin
==
2
)
{
int
retval
=
cifs_revalidate
(
file
->
f_dentry
);
if
(
retval
<
0
)
return
(
loff_t
)
retval
;
}
return
remote_llseek
(
file
,
offset
,
origin
);
}
static
struct
file_system_type
cifs_fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"cifs"
,
...
...
@@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = {
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_mmap
,
.
sendfile
=
generic_file_sendfile
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
...
...
@@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_ops = {
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
...
...
@@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_ops = {
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_mmap
,
.
sendfile
=
generic_file_sendfile
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
...
...
@@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_nobrl_ops = {
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
...
...
@@ -733,7 +746,7 @@ cifs_init_request_bufs(void)
kmem_cache_destroy
(
cifs_req_cachep
);
return
-
ENOMEM
;
}
/*
256 (MAX_CIFS_HD
R_SIZE bytes is enough for most SMB responses and
/*
MAX_CIFS_SMALL_BUFFE
R_SIZE bytes is enough for most SMB responses and
almost all handle based requests (but not write response, nor is it
sufficient for path based requests). A smaller size would have
been more efficient (compacting multiple slab items on one 4k page)
...
...
@@ -742,7 +755,8 @@ cifs_init_request_bufs(void)
efficient to alloc 1 per page off the slab compared to 17K (5page)
alloc of large cifs buffers even when page debugging is on */
cifs_sm_req_cachep
=
kmem_cache_create
(
"cifs_small_rq"
,
MAX_CIFS_HDR_SIZE
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
MAX_CIFS_SMALL_BUFFER_SIZE
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
cifs_sm_req_cachep
==
NULL
)
{
mempool_destroy
(
cifs_req_poolp
);
kmem_cache_destroy
(
cifs_req_cachep
);
...
...
@@ -954,6 +968,12 @@ init_cifs(void)
atomic_set
(
&
tconInfoReconnectCount
,
0
);
atomic_set
(
&
bufAllocCount
,
0
);
atomic_set
(
&
smBufAllocCount
,
0
);
#ifdef CONFIG_CIFS_STATS2
atomic_set
(
&
totBufAllocCount
,
0
);
atomic_set
(
&
totSmBufAllocCount
,
0
);
#endif
/* CONFIG_CIFS_STATS2 */
atomic_set
(
&
midCount
,
0
);
GlobalCurrentXid
=
0
;
GlobalTotalActiveXid
=
0
;
...
...
fs/cifs/cifsfs.h
浏览文件 @
0f36b018
...
...
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern
ssize_t
cifs_listxattr
(
struct
dentry
*
,
char
*
,
size_t
);
extern
int
cifs_ioctl
(
struct
inode
*
inode
,
struct
file
*
filep
,
unsigned
int
command
,
unsigned
long
arg
);
#define CIFS_VERSION "1.
39
"
#define CIFS_VERSION "1.
40
"
#endif
/* _CIFSFS_H */
fs/cifs/cifsglob.h
浏览文件 @
0f36b018
...
...
@@ -233,6 +233,8 @@ struct cifsTconInfo {
atomic_t
num_hardlinks
;
atomic_t
num_symlinks
;
atomic_t
num_locks
;
atomic_t
num_acl_get
;
atomic_t
num_acl_set
;
#ifdef CONFIG_CIFS_STATS2
unsigned
long
long
time_writes
;
unsigned
long
long
time_reads
;
...
...
@@ -285,6 +287,7 @@ struct cifs_search_info {
unsigned
endOfSearch
:
1
;
unsigned
emptyDir
:
1
;
unsigned
unicode
:
1
;
unsigned
smallBuf
:
1
;
/* so we know which buf_release function to call */
};
struct
cifsFileInfo
{
...
...
@@ -420,7 +423,12 @@ struct dir_notify_req {
#define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8
/* session closed while this request out */
#define MID_NO_RESP_NEEDED 0x10
#define MID_SMALL_BUFFER 0x20
/* 112 byte response buffer instead of 4K */
/* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0
/* Response buffer not returned */
#define CIFS_SMALL_BUFFER 1
#define CIFS_LARGE_BUFFER 2
#define CIFS_IOVEC 4
/* array of response buffers */
/*
*****************************************************************
...
...
@@ -505,8 +513,12 @@ GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
GLOBAL_EXTERN
atomic_t
tconInfoReconnectCount
;
/* Various Debug counters to remove someday (BB) */
GLOBAL_EXTERN
atomic_t
bufAllocCount
;
GLOBAL_EXTERN
atomic_t
smBufAllocCount
;
GLOBAL_EXTERN
atomic_t
bufAllocCount
;
/* current number allocated */
#ifdef CONFIG_CIFS_STATS2
GLOBAL_EXTERN
atomic_t
totBufAllocCount
;
/* total allocated over all time */
GLOBAL_EXTERN
atomic_t
totSmBufAllocCount
;
#endif
GLOBAL_EXTERN
atomic_t
smBufAllocCount
;
GLOBAL_EXTERN
atomic_t
midCount
;
/* Misc globals */
...
...
fs/cifs/cifspdu.h
浏览文件 @
0f36b018
/*
* fs/cifs/cifspdu.h
*
* Copyright (c) International Business Machines Corp., 2002
* Copyright (c) International Business Machines Corp., 2002
,2005
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
...
...
@@ -80,7 +80,11 @@
#define NT_TRANSACT_GET_USER_QUOTA 0x07
#define NT_TRANSACT_SET_USER_QUOTA 0x08
#define MAX_CIFS_HDR_SIZE 256
/* is future chained NTCreateXReadX bigger? */
#define MAX_CIFS_SMALL_BUFFER_SIZE 448
/* big enough for most */
/* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
/* among the requests (NTCreateX response is bigger with wct of 34) */
#define MAX_CIFS_HDR_SIZE 0x58
/* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
#define CIFS_SMALL_PATH 120
/* allows for (448-88)/3 */
/* internal cifs vfs structures */
/*****************************************************************
...
...
@@ -524,7 +528,7 @@ typedef union smb_com_session_setup_andx {
/* STRING PrimaryDomain */
/* STRING NativeOS */
/* STRING NativeLanMan */
}
__attribute__
((
packed
))
old_req
;
/* pre-NTLM (LANMAN2.1) request
format */
}
__attribute__
((
packed
))
old_req
;
/* pre-NTLM (LANMAN2.1) req
format */
struct
{
/* default (NTLM) response format */
struct
smb_hdr
hdr
;
/* wct = 3 */
...
...
@@ -536,7 +540,7 @@ typedef union smb_com_session_setup_andx {
unsigned
char
NativeOS
[
1
];
/* followed by */
/* unsigned char * NativeLanMan; */
/* unsigned char * PrimaryDomain; */
}
__attribute__
((
packed
))
old_resp
;
/* pre-NTLM (LANMAN2.1) response format
*/
}
__attribute__
((
packed
))
old_resp
;
/* pre-NTLM (LANMAN2.1) response
*/
}
__attribute__
((
packed
))
SESSION_SETUP_ANDX
;
#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
...
...
@@ -1003,10 +1007,49 @@ typedef struct smb_com_setattr_rsp {
/* empty wct response to setattr */
/***************************************************/
/* NT Transact structure defintions follow */
/* Currently only ioctl and notify are implemented */
/***************************************************/
/*******************************************************/
/* NT Transact structure defintions follow */
/* Currently only ioctl, acl (get security descriptor) */
/* and notify are implemented */
/*******************************************************/
typedef
struct
smb_com_ntransact_req
{
struct
smb_hdr
hdr
;
/* wct >= 19 */
__u8
MaxSetupCount
;
__u16
Reserved
;
__le32
TotalParameterCount
;
__le32
TotalDataCount
;
__le32
MaxParameterCount
;
__le32
MaxDataCount
;
__le32
ParameterCount
;
__le32
ParameterOffset
;
__le32
DataCount
;
__le32
DataOffset
;
__u8
SetupCount
;
/* four setup words follow subcommand */
/* SNIA spec incorrectly included spurious pad here */
__le16
SubCommand
;
/* 2 = IOCTL/FSCTL */
/* SetupCount words follow then */
__le16
ByteCount
;
__u8
Pad
[
3
];
__u8
Parms
[
0
];
}
__attribute__
((
packed
))
NTRANSACT_REQ
;
typedef
struct
smb_com_ntransact_rsp
{
struct
smb_hdr
hdr
;
/* wct = 18 */
__u8
Reserved
[
3
];
__le32
TotalParameterCount
;
__le32
TotalDataCount
;
__le32
ParameterCount
;
__le32
ParameterOffset
;
__le32
ParameterDisplacement
;
__le32
DataCount
;
__le32
DataOffset
;
__le32
DataDisplacement
;
__u8
SetupCount
;
/* 0 */
__u16
ByteCount
;
/* __u8 Pad[3]; */
/* parms and data follow */
}
__attribute__
((
packed
))
NTRANSACT_RSP
;
typedef
struct
smb_com_transaction_ioctl_req
{
struct
smb_hdr
hdr
;
/* wct = 23 */
__u8
MaxSetupCount
;
...
...
@@ -1021,11 +1064,11 @@ typedef struct smb_com_transaction_ioctl_req {
__le32
DataOffset
;
__u8
SetupCount
;
/* four setup words follow subcommand */
/* SNIA spec incorrectly included spurious pad here */
__le16
SubCommand
;
/* 2 = IOCTL/FSCTL */
__le16
SubCommand
;
/* 2 = IOCTL/FSCTL */
__le32
FunctionCode
;
__u16
Fid
;
__u8
IsFsctl
;
/* 1 = File System Control, 0 = device control (IOCTL)
*/
__u8
IsRootFlag
;
/* 1 = apply command to root of share (must be DFS
share)
*/
__u8
IsFsctl
;
/* 1 = File System Control 0 = device control (IOCTL)
*/
__u8
IsRootFlag
;
/* 1 = apply command to root of share (must be DFS
)
*/
__le16
ByteCount
;
__u8
Pad
[
3
];
__u8
Data
[
1
];
...
...
@@ -1045,9 +1088,35 @@ typedef struct smb_com_transaction_ioctl_rsp {
__u8
SetupCount
;
/* 1 */
__le16
ReturnedDataLen
;
__u16
ByteCount
;
__u8
Pad
[
3
];
}
__attribute__
((
packed
))
TRANSACT_IOCTL_RSP
;
#define CIFS_ACL_OWNER 1
#define CIFS_ACL_GROUP 2
#define CIFS_ACL_DACL 4
#define CIFS_ACL_SACL 8
typedef
struct
smb_com_transaction_qsec_req
{
struct
smb_hdr
hdr
;
/* wct = 19 */
__u8
MaxSetupCount
;
__u16
Reserved
;
__le32
TotalParameterCount
;
__le32
TotalDataCount
;
__le32
MaxParameterCount
;
__le32
MaxDataCount
;
__le32
ParameterCount
;
__le32
ParameterOffset
;
__le32
DataCount
;
__le32
DataOffset
;
__u8
SetupCount
;
/* no setup words follow subcommand */
/* SNIA spec incorrectly included spurious pad here */
__le16
SubCommand
;
/* 6 = QUERY_SECURITY_DESC */
__le16
ByteCount
;
/* bcc = 3 + 8 */
__u8
Pad
[
3
];
__u16
Fid
;
__u16
Reserved2
;
__le32
AclFlags
;
}
__attribute__
((
packed
))
QUERY_SEC_DESC_REQ
;
typedef
struct
smb_com_transaction_change_notify_req
{
struct
smb_hdr
hdr
;
/* wct = 23 */
__u8
MaxSetupCount
;
...
...
@@ -1068,10 +1137,12 @@ typedef struct smb_com_transaction_change_notify_req {
__u8
WatchTree
;
/* 1 = Monitor subdirectories */
__u8
Reserved2
;
__le16
ByteCount
;
/* __u8 Pad[3];*/
/*
__u8 Pad[3];*/
/* __u8 Data[1];*/
}
__attribute__
((
packed
))
TRANSACT_CHANGE_NOTIFY_REQ
;
/* BB eventually change to use generic ntransact rsp struct
and validation routine */
typedef
struct
smb_com_transaction_change_notify_rsp
{
struct
smb_hdr
hdr
;
/* wct = 18 */
__u8
Reserved
[
3
];
...
...
fs/cifs/cifsproto.h
浏览文件 @
0f36b018
...
...
@@ -48,8 +48,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
struct
smb_hdr
*
/* out */
,
int
*
/* bytes returned */
,
const
int
long_op
);
extern
int
SendReceive2
(
const
unsigned
int
/* xid */
,
struct
cifsSesInfo
*
,
struct
kvec
*
,
int
/* nvec
*/
,
int
*
/*
bytes
returned */
,
const
int
long_op
);
struct
kvec
*
,
int
/* nvec
to send */
,
int
*
/*
type of buf
returned */
,
const
int
long_op
);
extern
int
checkSMBhdr
(
struct
smb_hdr
*
smb
,
__u16
mid
);
extern
int
checkSMB
(
struct
smb_hdr
*
smb
,
__u16
mid
,
int
length
);
extern
int
is_valid_oplock_break
(
struct
smb_hdr
*
smb
);
...
...
@@ -93,11 +93,12 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const
struct
nls_table
*
);
extern
int
CIFSFindFirst
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
__u16
*
searchHandle
,
struct
cifs_search_info
*
psrch_inf
,
int
map
,
const
char
dirsep
);
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
__u16
*
searchHandle
,
struct
cifs_search_info
*
psrch_inf
,
int
map
,
const
char
dirsep
);
extern
int
CIFSFindNext
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
__u16
searchHandle
,
struct
cifs_search_info
*
psrch_inf
);
__u16
searchHandle
,
struct
cifs_search_info
*
psrch_inf
);
extern
int
CIFSFindClose
(
const
int
,
struct
cifsTconInfo
*
tcon
,
const
__u16
search_handle
);
...
...
@@ -230,19 +231,18 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const
int
smb_file_id
);
extern
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
);
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
,
int
*
return_buf_type
);
extern
int
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
const
char
*
buf
,
const
char
__user
*
ubuf
,
const
int
long_op
);
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern
int
CIFSSMBWrite2
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
offset
,
unsigned
int
*
nbytes
,
struct
kvec
*
iov
,
const
int
nvec
,
const
int
long_op
);
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
extern
int
CIFSGetSrvInodeNumber
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
unsigned
char
*
searchName
,
__u64
*
inode_number
,
const
struct
nls_table
*
nls_codepage
,
...
...
@@ -269,6 +269,8 @@ extern void tconInfoFree(struct cifsTconInfo *);
extern
int
cifs_reconnect
(
struct
TCP_Server_Info
*
server
);
extern
int
cifs_sign_smb
(
struct
smb_hdr
*
,
struct
TCP_Server_Info
*
,
__u32
*
);
extern
int
cifs_sign_smb2
(
struct
kvec
*
iov
,
int
n_vec
,
struct
TCP_Server_Info
*
,
__u32
*
);
extern
int
cifs_verify_signature
(
struct
smb_hdr
*
,
const
char
*
mac_key
,
__u32
expected_sequence_number
);
extern
int
cifs_calculate_mac_key
(
char
*
key
,
const
char
*
rn
,
const
char
*
pass
);
...
...
@@ -297,6 +299,9 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
const
char
*
fileName
,
const
char
*
ea_name
,
const
void
*
ea_value
,
const
__u16
ea_value_len
,
const
struct
nls_table
*
nls_codepage
,
int
remap_special_chars
);
extern
int
CIFSSMBGetCIFSACL
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
__u16
fid
,
char
*
acl_inf
,
const
int
buflen
,
const
int
acl_type
/* ACCESS vs. DEFAULT */
);
extern
int
CIFSSMBGetPosixACL
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
unsigned
char
*
searchName
,
char
*
acl_inf
,
const
int
buflen
,
const
int
acl_type
,
...
...
fs/cifs/cifssmb.c
浏览文件 @
0f36b018
...
...
@@ -37,6 +37,7 @@
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "cifsacl.h"
#ifdef CONFIG_CIFS_POSIX
static
struct
{
...
...
@@ -372,8 +373,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
rc
=
SendReceive
(
xid
,
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
if
(
rc
==
0
)
{
server
->
secMode
=
pSMBr
->
SecurityMode
;
server
->
secType
=
NTLM
;
/* BB override default for
server
->
secMode
=
pSMBr
->
SecurityMode
;
if
((
server
->
secMode
&
SECMODE_USER
)
==
0
)
cFYI
(
1
,(
"share mode security"
));
server
->
secType
=
NTLM
;
/* BB override default for
NTLMv2 or kerberos v5 */
/* one byte - no need to convert this or EncryptionKeyLen
from little endian */
...
...
@@ -383,7 +386,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
min
(
le32_to_cpu
(
pSMBr
->
MaxBufferSize
),
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
server
->
maxRw
=
le32_to_cpu
(
pSMBr
->
MaxRawSize
);
cFYI
(
0
,
(
"Max buf = %d
"
,
ses
->
server
->
maxBuf
));
cFYI
(
0
,
(
"Max buf = %d"
,
ses
->
server
->
maxBuf
));
GETU32
(
ses
->
server
->
sessid
)
=
le32_to_cpu
(
pSMBr
->
SessionKey
);
server
->
capabilities
=
le32_to_cpu
(
pSMBr
->
Capabilities
);
server
->
timeZone
=
le16_to_cpu
(
pSMBr
->
ServerTimeZone
);
...
...
@@ -411,8 +414,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
(
server
->
server_GUID
,
pSMBr
->
u
.
extended_response
.
GUID
,
16
)
!=
0
)
{
cFYI
(
1
,
(
"UID of server does not match previous connection to same ip address"
));
cFYI
(
1
,
(
"server UID changed"
));
memcpy
(
server
->
server_GUID
,
pSMBr
->
u
.
...
...
@@ -958,21 +960,19 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
/* If no buffer passed in, then caller wants to do the copy
as in the case of readpages so the SMB buffer must be
freed by the caller */
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
)
const
int
netfid
,
const
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
,
int
*
pbuf_type
)
{
int
rc
=
-
EACCES
;
READ_REQ
*
pSMB
=
NULL
;
READ_RSP
*
pSMBr
=
NULL
;
char
*
pReadData
=
NULL
;
int
bytes_returned
;
int
wct
;
int
resp_buf_type
=
0
;
struct
kvec
iov
[
1
];
cFYI
(
1
,(
"Reading %d bytes on fid %d"
,
count
,
netfid
));
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
...
...
@@ -981,8 +981,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
wct
=
10
;
/* old style read */
*
nbytes
=
0
;
rc
=
smb_init
(
SMB_COM_READ_ANDX
,
wct
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
rc
=
small_smb_init
(
SMB_COM_READ_ANDX
,
wct
,
tcon
,
(
void
**
)
&
pSMB
);
if
(
rc
)
return
rc
;
...
...
@@ -990,13 +989,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
if
(
tcon
->
ses
->
server
==
NULL
)
return
-
ECONNABORTED
;
pSMB
->
AndXCommand
=
0xFF
;
/* none */
pSMB
->
AndXCommand
=
0xFF
;
/* none */
pSMB
->
Fid
=
netfid
;
pSMB
->
OffsetLow
=
cpu_to_le32
(
lseek
&
0xFFFFFFFF
);
if
(
wct
==
12
)
pSMB
->
OffsetHigh
=
cpu_to_le32
(
lseek
>>
32
);
else
if
((
lseek
>>
32
)
>
0
)
/* can not handle this big offset for old */
return
-
EIO
;
else
if
((
lseek
>>
32
)
>
0
)
/* can not handle this big offset for old */
return
-
EIO
;
pSMB
->
Remaining
=
0
;
pSMB
->
MaxCount
=
cpu_to_le16
(
count
&
0xFFFF
);
...
...
@@ -1005,14 +1004,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
pSMB
->
ByteCount
=
0
;
/* no need to do le conversion since 0 */
else
{
/* old style read */
struct
smb_com_readx_req
*
pSMBW
=
struct
smb_com_readx_req
*
pSMBW
=
(
struct
smb_com_readx_req
*
)
pSMB
;
pSMBW
->
ByteCount
=
0
;
pSMBW
->
ByteCount
=
0
;
}
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
iov
[
0
].
iov_base
=
(
char
*
)
pSMB
;
iov
[
0
].
iov_len
=
pSMB
->
hdr
.
smb_buf_length
+
4
;
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
1
/* num iovecs */
,
&
resp_buf_type
,
0
);
cifs_stats_inc
(
&
tcon
->
num_reads
);
pSMBr
=
(
READ_RSP
*
)
iov
[
0
].
iov_base
;
if
(
rc
)
{
cERROR
(
1
,
(
"Send error in read = %d"
,
rc
));
}
else
{
...
...
@@ -1022,33 +1025,43 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
*
nbytes
=
data_length
;
/*check that DataLength would not go beyond end of SMB */
if
((
data_length
>
CIFSMaxBufSize
)
if
((
data_length
>
CIFSMaxBufSize
)
||
(
data_length
>
count
))
{
cFYI
(
1
,(
"bad length %d for count %d"
,
data_length
,
count
));
rc
=
-
EIO
;
*
nbytes
=
0
;
}
else
{
pReadData
=
(
char
*
)
(
&
pSMBr
->
hdr
.
Protocol
)
+
pReadData
=
(
char
*
)
(
&
pSMBr
->
hdr
.
Protocol
)
+
le16_to_cpu
(
pSMBr
->
DataOffset
);
/*
if(rc = copy_to_user(buf, pReadData, data_length)) {
cERROR(1,("Faulting on read rc = %d",rc));
rc = -EFAULT;
}*/
/* can not use copy_to_user when using page cache*/
/*
if(rc = copy_to_user(buf, pReadData, data_length)) {
cERROR(1,("Faulting on read rc = %d",rc));
rc = -EFAULT;
}*/
/* can not use copy_to_user when using page cache*/
if
(
*
buf
)
memcpy
(
*
buf
,
pReadData
,
data_length
);
memcpy
(
*
buf
,
pReadData
,
data_length
);
}
}
if
(
*
buf
)
cifs_buf_release
(
pSMB
);
else
*
buf
=
(
char
*
)
pSMB
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
cifs_small_buf_release
(
pSMB
);
if
(
*
buf
)
{
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
iov
[
0
].
iov_base
);
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
iov
[
0
].
iov_base
);
}
else
/* return buffer to caller to free */
/* BB FIXME how do we tell caller if it is not a large buffer */
{
*
buf
=
iov
[
0
].
iov_base
;
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
*
pbuf_type
=
CIFS_SMALL_BUFFER
;
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
*
pbuf_type
=
CIFS_LARGE_BUFFER
;
}
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
int
CIFSSMBWrite
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
...
...
@@ -1155,7 +1168,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
int
CIFSSMBWrite2
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
const
unsigned
int
count
,
...
...
@@ -1164,10 +1176,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
{
int
rc
=
-
EACCES
;
WRITE_REQ
*
pSMB
=
NULL
;
int
bytes_returned
,
wct
;
int
wct
;
int
smb_hdr_len
;
int
resp_buf_type
=
0
;
/* BB removeme BB */
cFYI
(
1
,(
"write2 at %lld %d bytes"
,
(
long
long
)
offset
,
count
));
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
...
...
@@ -1210,22 +1222,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
pSMBW
->
ByteCount
=
cpu_to_le16
(
count
+
5
);
}
iov
[
0
].
iov_base
=
pSMB
;
iov
[
0
].
iov_len
=
smb_hdr_len
+
4
;
if
(
wct
==
14
)
iov
[
0
].
iov_len
=
smb_hdr_len
+
4
;
else
/* wct == 12 pad bigger by four bytes */
iov
[
0
].
iov_len
=
smb_hdr_len
+
8
;
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
n_vec
+
1
,
&
bytes_returned
,
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
n_vec
+
1
,
&
resp_buf_type
,
long_op
);
cifs_stats_inc
(
&
tcon
->
num_writes
);
if
(
rc
)
{
cFYI
(
1
,
(
"Send error Write2 = %d"
,
rc
));
*
nbytes
=
0
;
}
else
if
(
resp_buf_type
==
0
)
{
/* presumably this can not happen, but best to be safe */
rc
=
-
EIO
;
*
nbytes
=
0
;
}
else
{
WRITE_RSP
*
pSMBr
=
(
WRITE_RSP
*
)
pSMB
;
WRITE_RSP
*
pSMBr
=
(
WRITE_RSP
*
)
iov
[
0
].
iov_base
;
*
nbytes
=
le16_to_cpu
(
pSMBr
->
CountHigh
);
*
nbytes
=
(
*
nbytes
)
<<
16
;
*
nbytes
+=
le16_to_cpu
(
pSMBr
->
Count
);
}
}
cifs_small_buf_release
(
pSMB
);
if
(
resp_buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
iov
[
0
].
iov_base
);
else
if
(
resp_buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
iov
[
0
].
iov_base
);
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
...
...
@@ -1234,8 +1258,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
}
#endif
/* CIFS_EXPERIMENTAL */
int
CIFSSMBLock
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
__u16
smb_file_id
,
const
__u64
len
,
...
...
@@ -1906,6 +1928,90 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
/* Initialize NT TRANSACT SMB into small smb request buffer.
This assumes that all NT TRANSACTS that we init here have
total parm and data under about 400 bytes (to fit in small cifs
buffer size), which is the case so far, it easily fits. NB:
Setup words themselves and ByteCount
MaxSetupCount (size of returned setup area) and
MaxParameterCount (returned parms size) must be set by caller */
static
int
smb_init_ntransact
(
const
__u16
sub_command
,
const
int
setup_count
,
const
int
parm_len
,
struct
cifsTconInfo
*
tcon
,
void
**
ret_buf
)
{
int
rc
;
__u32
temp_offset
;
struct
smb_com_ntransact_req
*
pSMB
;
rc
=
small_smb_init
(
SMB_COM_NT_TRANSACT
,
19
+
setup_count
,
tcon
,
(
void
**
)
&
pSMB
);
if
(
rc
)
return
rc
;
*
ret_buf
=
(
void
*
)
pSMB
;
pSMB
->
Reserved
=
0
;
pSMB
->
TotalParameterCount
=
cpu_to_le32
(
parm_len
);
pSMB
->
TotalDataCount
=
0
;
pSMB
->
MaxDataCount
=
cpu_to_le32
((
tcon
->
ses
->
server
->
maxBuf
-
MAX_CIFS_HDR_SIZE
)
&
0xFFFFFF00
);
pSMB
->
ParameterCount
=
pSMB
->
TotalParameterCount
;
pSMB
->
DataCount
=
pSMB
->
TotalDataCount
;
temp_offset
=
offsetof
(
struct
smb_com_ntransact_req
,
Parms
)
+
(
setup_count
*
2
)
-
4
/* for rfc1001 length itself */
;
pSMB
->
ParameterOffset
=
cpu_to_le32
(
temp_offset
);
pSMB
->
DataOffset
=
cpu_to_le32
(
temp_offset
+
parm_len
);
pSMB
->
SetupCount
=
setup_count
;
/* no need to le convert byte fields */
pSMB
->
SubCommand
=
cpu_to_le16
(
sub_command
);
return
0
;
}
static
int
validate_ntransact
(
char
*
buf
,
char
**
ppparm
,
char
**
ppdata
,
int
*
pdatalen
,
int
*
pparmlen
)
{
char
*
end_of_smb
;
__u32
data_count
,
data_offset
,
parm_count
,
parm_offset
;
struct
smb_com_ntransact_rsp
*
pSMBr
;
if
(
buf
==
NULL
)
return
-
EINVAL
;
pSMBr
=
(
struct
smb_com_ntransact_rsp
*
)
buf
;
/* ByteCount was converted from little endian in SendReceive */
end_of_smb
=
2
/* sizeof byte count */
+
pSMBr
->
ByteCount
+
(
char
*
)
&
pSMBr
->
ByteCount
;
data_offset
=
le32_to_cpu
(
pSMBr
->
DataOffset
);
data_count
=
le32_to_cpu
(
pSMBr
->
DataCount
);
parm_offset
=
le32_to_cpu
(
pSMBr
->
ParameterOffset
);
parm_count
=
le32_to_cpu
(
pSMBr
->
ParameterCount
);
*
ppparm
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
parm_offset
;
*
ppdata
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
data_offset
;
/* should we also check that parm and data areas do not overlap? */
if
(
*
ppparm
>
end_of_smb
)
{
cFYI
(
1
,(
"parms start after end of smb"
));
return
-
EINVAL
;
}
else
if
(
parm_count
+
*
ppparm
>
end_of_smb
)
{
cFYI
(
1
,(
"parm end after end of smb"
));
return
-
EINVAL
;
}
else
if
(
*
ppdata
>
end_of_smb
)
{
cFYI
(
1
,(
"data starts after end of smb"
));
return
-
EINVAL
;
}
else
if
(
data_count
+
*
ppdata
>
end_of_smb
)
{
cFYI
(
1
,(
"data %p + count %d (%p) ends after end of smb %p start %p"
,
*
ppdata
,
data_count
,
(
data_count
+
*
ppdata
),
end_of_smb
,
pSMBr
));
/* BB FIXME */
return
-
EINVAL
;
}
else
if
(
parm_count
+
data_count
>
pSMBr
->
ByteCount
)
{
cFYI
(
1
,(
"parm count and data count larger than SMB"
));
return
-
EINVAL
;
}
return
0
;
}
int
CIFSSMBQueryReparseLinkInfo
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
unsigned
char
*
searchName
,
...
...
@@ -1928,7 +2034,8 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
pSMB
->
TotalDataCount
=
0
;
pSMB
->
MaxParameterCount
=
cpu_to_le32
(
2
);
/* BB find exact data count max from sess structure BB */
pSMB
->
MaxDataCount
=
cpu_to_le32
(
4000
);
pSMB
->
MaxDataCount
=
cpu_to_le32
((
tcon
->
ses
->
server
->
maxBuf
-
MAX_CIFS_HDR_SIZE
)
&
0xFFFFFF00
);
pSMB
->
MaxSetupCount
=
4
;
pSMB
->
Reserved
=
0
;
pSMB
->
ParameterOffset
=
0
;
...
...
@@ -1955,7 +2062,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
rc
=
-
EIO
;
/* bad smb */
else
{
if
(
data_count
&&
(
data_count
<
2048
))
{
char
*
end_of_smb
=
pSMBr
->
ByteCount
+
(
char
*
)
&
pSMBr
->
ByteCount
;
char
*
end_of_smb
=
2
/* sizeof byte count */
+
pSMBr
->
ByteCount
+
(
char
*
)
&
pSMBr
->
ByteCount
;
struct
reparse_data
*
reparse_buf
=
(
struct
reparse_data
*
)
((
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
data_offset
);
...
...
@@ -2199,6 +2308,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
cifs_stats_inc
(
&
tcon
->
num_acl_get
);
if
(
rc
)
{
cFYI
(
1
,
(
"Send error in Query POSIX ACL = %d"
,
rc
));
}
else
{
...
...
@@ -2386,6 +2496,92 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
#endif
/* CONFIG_POSIX */
/* security id for everyone */
const
struct
cifs_sid
sid_everyone
=
{
1
,
1
,
{
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
}};
/* group users */
const
struct
cifs_sid
sid_user
=
{
1
,
2
,
{
0
,
0
,
0
,
0
,
0
,
5
},
{
32
,
545
,
0
,
0
}};
/* Convert CIFS ACL to POSIX form */
static
int
parse_sec_desc
(
struct
cifs_sid
*
psec_desc
,
int
acl_len
)
{
return
0
;
}
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
__u16
fid
,
/* BB fix up return info */
char
*
acl_inf
,
const
int
buflen
,
const
int
acl_type
/* ACCESS/DEFAULT not sure implication */
)
{
int
rc
=
0
;
int
buf_type
=
0
;
QUERY_SEC_DESC_REQ
*
pSMB
;
struct
kvec
iov
[
1
];
cFYI
(
1
,
(
"GetCifsACL"
));
rc
=
smb_init_ntransact
(
NT_TRANSACT_QUERY_SECURITY_DESC
,
0
,
8
/* parm len */
,
tcon
,
(
void
**
)
&
pSMB
);
if
(
rc
)
return
rc
;
pSMB
->
MaxParameterCount
=
cpu_to_le32
(
4
);
/* BB TEST with big acls that might need to be e.g. larger than 16K */
pSMB
->
MaxSetupCount
=
0
;
pSMB
->
Fid
=
fid
;
/* file handle always le */
pSMB
->
AclFlags
=
cpu_to_le32
(
CIFS_ACL_OWNER
|
CIFS_ACL_GROUP
|
CIFS_ACL_DACL
);
pSMB
->
ByteCount
=
cpu_to_le16
(
11
);
/* 3 bytes pad + 8 bytes parm */
pSMB
->
hdr
.
smb_buf_length
+=
11
;
iov
[
0
].
iov_base
=
(
char
*
)
pSMB
;
iov
[
0
].
iov_len
=
pSMB
->
hdr
.
smb_buf_length
+
4
;
rc
=
SendReceive2
(
xid
,
tcon
->
ses
,
iov
,
1
/* num iovec */
,
&
buf_type
,
0
);
cifs_stats_inc
(
&
tcon
->
num_acl_get
);
if
(
rc
)
{
cFYI
(
1
,
(
"Send error in QuerySecDesc = %d"
,
rc
));
}
else
{
/* decode response */
struct
cifs_sid
*
psec_desc
;
__le32
*
parm
;
int
parm_len
;
int
data_len
;
int
acl_len
;
struct
smb_com_ntransact_rsp
*
pSMBr
;
/* validate_nttransact */
rc
=
validate_ntransact
(
iov
[
0
].
iov_base
,
(
char
**
)
&
parm
,
(
char
**
)
&
psec_desc
,
&
parm_len
,
&
data_len
);
if
(
rc
)
goto
qsec_out
;
pSMBr
=
(
struct
smb_com_ntransact_rsp
*
)
iov
[
0
].
iov_base
;
cERROR
(
1
,(
"smb %p parm %p data %p"
,
pSMBr
,
parm
,
psec_desc
));
/* BB removeme BB */
if
(
le32_to_cpu
(
pSMBr
->
ParameterCount
)
!=
4
)
{
rc
=
-
EIO
;
/* bad smb */
goto
qsec_out
;
}
/* BB check that data area is minimum length and as big as acl_len */
acl_len
=
le32_to_cpu
(
*
(
__le32
*
)
parm
);
/* BB check if(acl_len > bufsize) */
parse_sec_desc
(
psec_desc
,
acl_len
);
}
qsec_out:
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
iov
[
0
].
iov_base
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
iov
[
0
].
iov_base
);
cifs_small_buf_release
(
pSMB
);
return
rc
;
}
/* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */
int
SMBQueryInformation
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
...
...
@@ -4284,7 +4480,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
{
int
rc
=
0
;
struct
smb_com_transaction_change_notify_req
*
pSMB
=
NULL
;
struct
smb_com_transaction_change_notify_rsp
*
pSMBr
=
NULL
;
struct
smb_com_
n
transaction_change_notify_rsp
*
pSMBr
=
NULL
;
struct
dir_notify_req
*
dnotify_req
;
int
bytes_returned
;
...
...
@@ -4299,6 +4495,10 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
pSMB
->
MaxParameterCount
=
cpu_to_le32
(
2
);
/* BB find exact data count max from sess structure BB */
pSMB
->
MaxDataCount
=
0
;
/* same in little endian or be */
/* BB VERIFY verify which is correct for above BB */
pSMB
->
MaxDataCount
=
cpu_to_le32
((
tcon
->
ses
->
server
->
maxBuf
-
MAX_CIFS_HDR_SIZE
)
&
0xFFFFFF00
);
pSMB
->
MaxSetupCount
=
4
;
pSMB
->
Reserved
=
0
;
pSMB
->
ParameterOffset
=
0
;
...
...
fs/cifs/connect.c
浏览文件 @
0f36b018
...
...
@@ -76,12 +76,19 @@ struct smb_vol {
unsigned
setuids
:
1
;
unsigned
noperm
:
1
;
unsigned
no_psx_acl
:
1
;
/* set if posix acl support should be disabled */
unsigned
cifs_acl
:
1
;
unsigned
no_xattr
:
1
;
/* set if xattr (EA) support should be disabled*/
unsigned
server_ino
:
1
;
/* use inode numbers from server ie UniqueId */
unsigned
direct_io
:
1
;
unsigned
remap
:
1
;
/* set to remap seven reserved chars in filenames */
unsigned
posix_paths
:
1
;
/* unset to not ask for posix pathnames. */
unsigned
sfu_emul
:
1
;
unsigned
krb5
:
1
;
unsigned
ntlm
:
1
;
unsigned
ntlmv2
:
1
;
unsigned
nullauth
:
1
;
/* attempt to authenticate with null user */
unsigned
sign
:
1
;
unsigned
seal
:
1
;
/* encrypt */
unsigned
nocase
;
/* request case insensitive filenames */
unsigned
nobrl
;
/* disable sending byte range locks to srv */
unsigned
int
rsize
;
...
...
@@ -508,7 +515,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* else length ok */
reconnect
=
0
;
if
(
pdu_length
>
MAX_CIFS_
HD
R_SIZE
-
4
)
{
if
(
pdu_length
>
MAX_CIFS_
SMALL_BUFFE
R_SIZE
-
4
)
{
isLargeBuf
=
TRUE
;
memcpy
(
bigbuf
,
smallbuf
,
4
);
smb_buffer
=
bigbuf
;
...
...
@@ -777,7 +784,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
vol
->
rw
=
TRUE
;
vol
->
ntlm
=
TRUE
;
/* default is always to request posix paths. */
vol
->
posix_paths
=
1
;
...
...
@@ -903,6 +910,39 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
printk
(
KERN_WARNING
"CIFS: ip address too long
\n
"
);
return
1
;
}
}
else
if
(
strnicmp
(
data
,
"sec"
,
3
)
==
0
)
{
if
(
!
value
||
!*
value
)
{
cERROR
(
1
,(
"no security value specified"
));
continue
;
}
else
if
(
strnicmp
(
value
,
"krb5i"
,
5
)
==
0
)
{
vol
->
sign
=
1
;
vol
->
krb5
=
1
;
}
else
if
(
strnicmp
(
value
,
"krb5p"
,
5
)
==
0
)
{
/* vol->seal = 1;
vol->krb5 = 1; */
cERROR
(
1
,(
"Krb5 cifs privacy not supported"
));
return
1
;
}
else
if
(
strnicmp
(
value
,
"krb5"
,
4
)
==
0
)
{
vol
->
krb5
=
1
;
}
else
if
(
strnicmp
(
value
,
"ntlmv2i"
,
7
)
==
0
)
{
vol
->
ntlmv2
=
1
;
vol
->
sign
=
1
;
}
else
if
(
strnicmp
(
value
,
"ntlmv2"
,
6
)
==
0
)
{
vol
->
ntlmv2
=
1
;
}
else
if
(
strnicmp
(
value
,
"ntlmi"
,
5
)
==
0
)
{
vol
->
ntlm
=
1
;
vol
->
sign
=
1
;
}
else
if
(
strnicmp
(
value
,
"ntlm"
,
4
)
==
0
)
{
/* ntlm is default so can be turned off too */
vol
->
ntlm
=
1
;
}
else
if
(
strnicmp
(
value
,
"nontlm"
,
6
)
==
0
)
{
vol
->
ntlm
=
0
;
}
else
if
(
strnicmp
(
value
,
"none"
,
4
)
==
0
)
{
vol
->
nullauth
=
1
;
}
else
{
cERROR
(
1
,(
"bad security option: %s"
,
value
));
return
1
;
}
}
else
if
((
strnicmp
(
data
,
"unc"
,
3
)
==
0
)
||
(
strnicmp
(
data
,
"target"
,
6
)
==
0
)
||
(
strnicmp
(
data
,
"path"
,
4
)
==
0
))
{
...
...
@@ -1120,6 +1160,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
vol
->
server_ino
=
1
;
}
else
if
(
strnicmp
(
data
,
"noserverino"
,
9
)
==
0
)
{
vol
->
server_ino
=
0
;
}
else
if
(
strnicmp
(
data
,
"cifsacl"
,
7
)
==
0
)
{
vol
->
cifs_acl
=
1
;
}
else
if
(
strnicmp
(
data
,
"nocifsacl"
,
9
)
==
0
)
{
vol
->
cifs_acl
=
0
;
}
else
if
(
strnicmp
(
data
,
"acl"
,
3
)
==
0
)
{
vol
->
no_psx_acl
=
0
;
}
else
if
(
strnicmp
(
data
,
"noacl"
,
5
)
==
0
)
{
...
...
@@ -1546,7 +1590,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cFYI
(
1
,
(
"Username: %s "
,
volume_info
.
username
));
}
else
{
cifserror
(
"No username specified
"
);
cifserror
(
"No username specified"
);
/* In userspace mount helper we can get user name from alternate
locations such as env variables and files on disk */
kfree
(
volume_info
.
UNC
);
...
...
@@ -1587,7 +1631,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
return
-
EINVAL
;
}
else
/* which servers DFS root would we conect to */
{
cERROR
(
1
,
(
"CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified
"
));
(
"CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"
));
kfree
(
volume_info
.
UNC
);
kfree
(
volume_info
.
password
);
FreeXid
(
xid
);
...
...
@@ -1626,7 +1670,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if
(
srvTcp
)
{
cFYI
(
1
,
(
"Existing tcp session with server found
"
));
cFYI
(
1
,
(
"Existing tcp session with server found"
));
}
else
{
/* create socket */
if
(
volume_info
.
port
)
sin_server
.
sin_port
=
htons
(
volume_info
.
port
);
...
...
@@ -1689,11 +1733,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if
(
existingCifsSes
)
{
pSesInfo
=
existingCifsSes
;
cFYI
(
1
,
(
"Existing smb sess found
"
));
cFYI
(
1
,
(
"Existing smb sess found"
));
kfree
(
volume_info
.
password
);
/* volume_info.UNC freed at end of function */
}
else
if
(
!
rc
)
{
cFYI
(
1
,
(
"Existing smb sess not found
"
));
cFYI
(
1
,
(
"Existing smb sess not found"
));
pSesInfo
=
sesInfoAlloc
();
if
(
pSesInfo
==
NULL
)
rc
=
-
ENOMEM
;
...
...
@@ -1751,7 +1795,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb
->
mnt_gid
=
volume_info
.
linux_gid
;
cifs_sb
->
mnt_file_mode
=
volume_info
.
file_mode
;
cifs_sb
->
mnt_dir_mode
=
volume_info
.
dir_mode
;
cFYI
(
1
,(
"file mode: 0x%x dir mode: 0x%x"
,
cifs_sb
->
mnt_file_mode
,
cifs_sb
->
mnt_dir_mode
));
cFYI
(
1
,(
"file mode: 0x%x dir mode: 0x%x"
,
cifs_sb
->
mnt_file_mode
,
cifs_sb
->
mnt_dir_mode
));
if
(
volume_info
.
noperm
)
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_NO_PERM
;
...
...
@@ -1767,6 +1812,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_UNX_EMUL
;
if
(
volume_info
.
nobrl
)
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_NO_BRL
;
if
(
volume_info
.
cifs_acl
)
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_CIFS_ACL
;
if
(
volume_info
.
direct_io
)
{
cFYI
(
1
,(
"mounting share using direct i/o"
));
...
...
@@ -1777,7 +1824,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
find_unc
(
sin_server
.
sin_addr
.
s_addr
,
volume_info
.
UNC
,
volume_info
.
username
);
if
(
tcon
)
{
cFYI
(
1
,
(
"Found match on UNC path
"
));
cFYI
(
1
,
(
"Found match on UNC path"
));
/* we can have only one retry value for a connection
to a share so for resources mounted more than once
to the same server share the last value passed in
...
...
@@ -1926,7 +1973,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
__u32
capabilities
;
__u16
count
;
cFYI
(
1
,
(
"In sesssetup
"
));
cFYI
(
1
,
(
"In sesssetup"
));
if
(
ses
==
NULL
)
return
-
EINVAL
;
user
=
ses
->
userName
;
...
...
@@ -3202,9 +3249,26 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
pSMB
->
AndXCommand
=
0xFF
;
pSMB
->
Flags
=
cpu_to_le16
(
TCON_EXTENDED_SECINFO
);
pSMB
->
PasswordLength
=
cpu_to_le16
(
1
);
/* minimum */
bcc_ptr
=
&
pSMB
->
Password
[
0
];
bcc_ptr
++
;
/* skip password */
if
((
ses
->
server
->
secMode
)
&
SECMODE_USER
)
{
pSMB
->
PasswordLength
=
cpu_to_le16
(
1
);
/* minimum */
bcc_ptr
++
;
/* skip password */
}
else
{
pSMB
->
PasswordLength
=
cpu_to_le16
(
CIFS_SESSION_KEY_SIZE
);
/* BB FIXME add code to fail this if NTLMv2 or Kerberos
specified as required (when that support is added to
the vfs in the future) as only NTLM or the much
weaker LANMAN (which we do not send) is accepted
by Samba (not sure whether other servers allow
NTLMv2 password here) */
SMBNTencrypt
(
ses
->
password
,
ses
->
server
->
cryptKey
,
bcc_ptr
);
bcc_ptr
+=
CIFS_SESSION_KEY_SIZE
;
*
bcc_ptr
=
0
;
bcc_ptr
++
;
/* align */
}
if
(
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
))
smb_buffer
->
Flags2
|=
SMBFLG2_SECURITY_SIGNATURE
;
...
...
@@ -3222,7 +3286,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr
+=
2
*
length
;
/* convert num of 16 bit words to bytes */
bcc_ptr
+=
2
;
/* skip trailing null */
}
else
{
/* ASCII */
strcpy
(
bcc_ptr
,
tree
);
bcc_ptr
+=
strlen
(
tree
)
+
1
;
}
...
...
fs/cifs/dir.c
浏览文件 @
0f36b018
...
...
@@ -3,7 +3,7 @@
*
* vfs operations that deal with dentries
*
* Copyright (C) International Business Machines Corp., 2002,200
3
* Copyright (C) International Business Machines Corp., 2002,200
5
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
...
...
@@ -200,8 +200,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
(
oplock
&
CIFS_CREATE_ACTION
))
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_SET_UID
)
{
CIFSSMBUnixSetPerms
(
xid
,
pTcon
,
full_path
,
mode
,
(
__u64
)
current
->
e
uid
,
(
__u64
)
current
->
e
gid
,
(
__u64
)
current
->
fs
uid
,
(
__u64
)
current
->
fs
gid
,
0
/* dev */
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
...
...
@@ -325,7 +325,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
else
if
(
pTcon
->
ses
->
capabilities
&
CAP_UNIX
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_SET_UID
)
{
rc
=
CIFSSMBUnixSetPerms
(
xid
,
pTcon
,
full_path
,
mode
,(
__u64
)
current
->
euid
,(
__u64
)
current
->
e
gid
,
mode
,(
__u64
)
current
->
fsuid
,(
__u64
)
current
->
fs
gid
,
device_number
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
...
...
fs/cifs/file.c
浏览文件 @
0f36b018
...
...
@@ -553,13 +553,13 @@ int cifs_closedir(struct inode *inode, struct file *file)
}
ptmp
=
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
;
if
(
ptmp
)
{
/* BB removeme BB */
cFYI
(
1
,
(
"freeing smb buf in srch struct in closedir
"
));
cFYI
(
1
,
(
"closedir free smb buf in srch struct
"
));
pCFileStruct
->
srch_inf
.
ntwrk_buf_start
=
NULL
;
cifs_buf_release
(
ptmp
);
}
ptmp
=
pCFileStruct
->
search_resume_name
;
if
(
ptmp
)
{
/* BB removeme BB */
cFYI
(
1
,
(
"freeing resume name in closedir
"
));
cFYI
(
1
,
(
"closedir free resume name
"
));
pCFileStruct
->
search_resume_name
=
NULL
;
kfree
(
ptmp
);
}
...
...
@@ -868,10 +868,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
if
(
rc
!=
0
)
break
;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* BB FIXME We can not sign across two buffers yet */
if
((
experimEnabled
)
&&
((
pTcon
->
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
))
==
0
)
)
{
if
((
pTcon
->
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
))
==
0
)
{
struct
kvec
iov
[
2
];
unsigned
int
len
;
...
...
@@ -887,7 +886,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
iov
,
1
,
long_op
);
}
else
/* BB FIXME fixup indentation of line below */
#endif
rc
=
CIFSSMBWrite
(
xid
,
pTcon
,
open_file
->
netfid
,
min_t
(
const
int
,
cifs_sb
->
wsize
,
...
...
@@ -1024,7 +1022,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
return
rc
;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
static
int
cifs_writepages
(
struct
address_space
*
mapping
,
struct
writeback_control
*
wbc
)
{
...
...
@@ -1227,7 +1224,6 @@ static int cifs_writepages(struct address_space *mapping,
return
rc
;
}
#endif
static
int
cifs_writepage
(
struct
page
*
page
,
struct
writeback_control
*
wbc
)
{
...
...
@@ -1426,6 +1422,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
rc
=
-
EAGAIN
;
smb_read_data
=
NULL
;
while
(
rc
==
-
EAGAIN
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
if
((
open_file
->
invalidHandle
)
&&
(
!
open_file
->
closePend
))
{
rc
=
cifs_reopen_file
(
file
->
f_dentry
->
d_inode
,
...
...
@@ -1434,20 +1431,22 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
break
;
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
);
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
,
&
buf_type
);
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
if
(
copy_to_user
(
current_offset
,
smb_read_data
+
4
/* RFC1001 hdr */
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
bytes_read
))
{
rc
=
-
EFAULT
;
FreeXid
(
xid
);
return
rc
;
}
}
if
(
smb_read_data
)
{
cifs_buf_release
(
smb_read_data
);
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
}
}
...
...
@@ -1480,6 +1479,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
int
xid
;
char
*
current_offset
;
struct
cifsFileInfo
*
open_file
;
int
buf_type
=
CIFS_NO_BUFFER
;
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
file
->
f_dentry
->
d_sb
);
...
...
@@ -1516,9 +1516,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
break
;
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
current_offset
);
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
current_offset
,
&
buf_type
);
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
...
...
@@ -1616,6 +1617,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct
smb_com_read_rsp
*
pSMBr
;
struct
pagevec
lru_pvec
;
struct
cifsFileInfo
*
open_file
;
int
buf_type
=
CIFS_NO_BUFFER
;
xid
=
GetXid
();
if
(
file
->
private_data
==
NULL
)
{
...
...
@@ -1672,14 +1674,17 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
read_size
,
offset
,
&
bytes_read
,
&
smb_read_data
);
open_file
->
netfid
,
read_size
,
offset
,
&
bytes_read
,
&
smb_read_data
,
&
buf_type
);
/* BB more RC checks ? */
if
(
rc
==
-
EAGAIN
)
{
if
(
smb_read_data
)
{
cifs_buf_release
(
smb_read_data
);
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
}
}
...
...
@@ -1736,7 +1741,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
break
;
}
if
(
smb_read_data
)
{
cifs_buf_release
(
smb_read_data
);
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
}
bytes_read
=
0
;
...
...
@@ -1746,7 +1754,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
/* need to free smb_read_data buf before exit */
if
(
smb_read_data
)
{
cifs_buf_release
(
smb_read_data
);
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
smb_read_data
=
NULL
;
}
...
...
@@ -1825,10 +1836,20 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
open_file
=
find_writable_file
(
cifsInode
);
if
(
open_file
)
{
struct
cifs_sb_info
*
cifs_sb
;
/* there is not actually a write pending so let
this handle go free and allow it to
be closable if needed */
atomic_dec
(
&
open_file
->
wrtPending
);
cifs_sb
=
CIFS_SB
(
cifsInode
->
vfs_inode
.
i_sb
);
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
{
/* since no page cache to corrupt on directio
we can change size safely */
return
1
;
}
return
0
;
}
else
return
1
;
...
...
@@ -1873,9 +1894,7 @@ struct address_space_operations cifs_addr_ops = {
.
readpage
=
cifs_readpage
,
.
readpages
=
cifs_readpages
,
.
writepage
=
cifs_writepage
,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
writepages
=
cifs_writepages
,
#endif
.
prepare_write
=
cifs_prepare_write
,
.
commit_write
=
cifs_commit_write
,
.
set_page_dirty
=
__set_page_dirty_nobuffers
,
...
...
fs/cifs/inode.c
浏览文件 @
0f36b018
...
...
@@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
==
0
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
/* Read header */
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
netfid
,
24
/* length */
,
0
/* offset */
,
&
bytes_read
,
&
pbuf
);
&
bytes_read
,
&
pbuf
,
&
buf_type
);
if
((
rc
==
0
)
&&
(
bytes_read
>=
8
))
{
if
(
memcmp
(
"IntxBLK"
,
pbuf
,
8
)
==
0
)
{
cFYI
(
1
,(
"Block device"
));
...
...
@@ -267,7 +268,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
}
else
{
inode
->
i_mode
|=
S_IFREG
;
/* then it is a file */
rc
=
-
EOPNOTSUPP
;
/* or some unknown SFU type */
}
}
CIFSSMBClose
(
xid
,
pTcon
,
netfid
);
}
return
rc
;
...
...
@@ -750,8 +751,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_SET_UID
)
{
CIFSSMBUnixSetPerms
(
xid
,
pTcon
,
full_path
,
mode
,
(
__u64
)
current
->
e
uid
,
(
__u64
)
current
->
e
gid
,
(
__u64
)
current
->
fs
uid
,
(
__u64
)
current
->
fs
gid
,
0
/* dev_t */
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
...
...
fs/cifs/misc.c
浏览文件 @
0f36b018
/*
* fs/cifs/misc.c
*
* Copyright (C) International Business Machines Corp., 2002,200
4
* Copyright (C) International Business Machines Corp., 2002,200
5
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
...
...
@@ -161,6 +161,9 @@ cifs_buf_get(void)
if
(
ret_buf
)
{
memset
(
ret_buf
,
0
,
sizeof
(
struct
smb_hdr
)
+
3
);
atomic_inc
(
&
bufAllocCount
);
#ifdef CONFIG_CIFS_STATS2
atomic_inc
(
&
totBufAllocCount
);
#endif
/* CONFIG_CIFS_STATS2 */
}
return
ret_buf
;
...
...
@@ -195,6 +198,10 @@ cifs_small_buf_get(void)
/* No need to clear memory here, cleared in header assemble */
/* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
atomic_inc
(
&
smBufAllocCount
);
#ifdef CONFIG_CIFS_STATS2
atomic_inc
(
&
totSmBufAllocCount
);
#endif
/* CONFIG_CIFS_STATS2 */
}
return
ret_buf
;
}
...
...
@@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
struct
cifsSesInfo
*
ses
;
char
*
temp
=
(
char
*
)
buffer
;
memset
(
temp
,
0
,
MAX_CIFS_HDR_SIZE
);
memset
(
temp
,
0
,
256
);
/* bigger than MAX_CIFS_HDR_SIZE */
buffer
->
smb_buf_length
=
(
2
*
word_count
)
+
sizeof
(
struct
smb_hdr
)
-
...
...
@@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
/* BB Add support for establishing new tCon and SMB Session */
/* with userid/password pairs found on the smb session */
/* for other target tcp/ip addresses BB */
if
(
current
->
uid
!=
treeCon
->
ses
->
linux_uid
)
{
cFYI
(
1
,(
"Multiuser mode and UID did not match tcon uid
"
));
if
(
current
->
fs
uid
!=
treeCon
->
ses
->
linux_uid
)
{
cFYI
(
1
,(
"Multiuser mode and UID did not match tcon uid"
));
read_lock
(
&
GlobalSMBSeslock
);
list_for_each
(
temp_item
,
&
GlobalSMBSessionList
)
{
ses
=
list_entry
(
temp_item
,
struct
cifsSesInfo
,
cifsSessionList
);
if
(
ses
->
linux_uid
==
current
->
uid
)
{
if
(
ses
->
linux_uid
==
current
->
fs
uid
)
{
if
(
ses
->
server
==
treeCon
->
ses
->
server
)
{
cFYI
(
1
,(
"found matching uid substitute right smb_uid"
));
buffer
->
Uid
=
ses
->
Suid
;
...
...
fs/cifs/readdir.c
浏览文件 @
0f36b018
...
...
@@ -214,8 +214,7 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
tmp_inode
->
i_fop
=
&
cifs_file_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
->
lock
=
NULL
;
tmp_inode
->
i_data
.
a_ops
=
&
cifs_addr_ops
;
if
((
cifs_sb
->
tcon
)
&&
(
cifs_sb
->
tcon
->
ses
)
&&
(
cifs_sb
->
tcon
->
ses
->
server
->
maxBuf
<
...
...
@@ -327,12 +326,18 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
if
(
S_ISREG
(
tmp_inode
->
i_mode
))
{
cFYI
(
1
,
(
"File inode"
));
tmp_inode
->
i_op
=
&
cifs_file_inode_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
tmp_inode
->
i_fop
=
&
cifs_file_direct_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
tmp_inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
tmp_inode
->
i_fop
=
&
cifs_file_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
->
lock
=
NULL
;
tmp_inode
->
i_data
.
a_ops
=
&
cifs_addr_ops
;
if
((
cifs_sb
->
tcon
)
&&
(
cifs_sb
->
tcon
->
ses
)
&&
(
cifs_sb
->
tcon
->
ses
->
server
->
maxBuf
<
...
...
fs/cifs/rfc1002pdu.h
浏览文件 @
0f36b018
...
...
@@ -24,11 +24,11 @@
/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
/* RFC 1002 session packet types */
#define RFC1002_SESSION_MES
A
SAGE 0x00
#define RFC1002_SESSION_MESSAGE 0x00
#define RFC1002_SESSION_REQUEST 0x81
#define RFC1002_POSITIVE_SESSION_RESPONSE 0x82
#define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83
#define RFC1002_RETARGET_SESSION_RESPONSE 0x8
3
#define RFC1002_RETARGET_SESSION_RESPONSE 0x8
4
#define RFC1002_SESSION_KEEP_ALIVE 0x85
/* RFC 1002 flags (only one defined */
...
...
fs/cifs/transport.c
浏览文件 @
0f36b018
...
...
@@ -206,7 +206,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
return
rc
;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
static
int
smb_send2
(
struct
socket
*
ssocket
,
struct
kvec
*
iov
,
int
n_vec
,
struct
sockaddr
*
sin
)
...
...
@@ -299,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
int
SendReceive2
(
const
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
,
struct
kvec
*
iov
,
int
n_vec
,
int
*
pbytes_returned
,
struct
kvec
*
iov
,
int
n_vec
,
int
*
pRespBufType
/* ret */
,
const
int
long_op
)
{
int
rc
=
0
;
...
...
@@ -307,6 +306,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
unsigned
long
timeout
;
struct
mid_q_entry
*
midQ
;
struct
smb_hdr
*
in_buf
=
iov
[
0
].
iov_base
;
*
pRespBufType
=
CIFS_NO_BUFFER
;
/* no response buf yet */
if
(
ses
==
NULL
)
{
cERROR
(
1
,(
"Null smb session"
));
...
...
@@ -392,8 +393,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
return
-
ENOMEM
;
}
/* BB FIXME */
/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
rc
=
cifs_sign_smb2
(
iov
,
n_vec
,
ses
->
server
,
&
midQ
->
sequence_number
);
midQ
->
midState
=
MID_REQUEST_SUBMITTED
;
#ifdef CONFIG_CIFS_STATS2
...
...
@@ -489,21 +489,23 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
receive_len
,
xid
));
rc
=
-
EIO
;
}
else
{
/* rcvd frame is ok */
if
(
midQ
->
resp_buf
&&
(
midQ
->
midState
==
MID_RESPONSE_RECEIVED
))
{
in_buf
->
smb_buf_length
=
receive_len
;
/* BB verify that length would not overrun small buf */
memcpy
((
char
*
)
in_buf
+
4
,
(
char
*
)
midQ
->
resp_buf
+
4
,
receive_len
);
dump_smb
(
in_buf
,
80
);
iov
[
0
].
iov_base
=
(
char
*
)
midQ
->
resp_buf
;
if
(
midQ
->
largeBuf
)
*
pRespBufType
=
CIFS_LARGE_BUFFER
;
else
*
pRespBufType
=
CIFS_SMALL_BUFFER
;
iov
[
0
].
iov_len
=
receive_len
+
4
;
iov
[
1
].
iov_len
=
0
;
dump_smb
(
midQ
->
resp_buf
,
80
);
/* convert the length into a more usable form */
if
((
receive_len
>
24
)
&&
(
ses
->
server
->
secMode
&
(
SECMODE_SIGN_REQUIRED
|
SECMODE_SIGN_ENABLED
)))
{
rc
=
cifs_verify_signature
(
in
_buf
,
rc
=
cifs_verify_signature
(
midQ
->
resp
_buf
,
ses
->
server
->
mac_signing_key
,
midQ
->
sequence_number
+
1
);
if
(
rc
)
{
...
...
@@ -512,18 +514,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
}
}
*
pbytes_returned
=
in_buf
->
smb_buf_length
;
/* BB special case reconnect tid and uid here? */
/* BB special case Errbadpassword and pwdexpired here */
rc
=
map_smb_to_linux_error
(
in
_buf
);
rc
=
map_smb_to_linux_error
(
midQ
->
resp
_buf
);
/* convert ByteCount if necessary */
if
(
receive_len
>=
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
in_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
in_buf
)
=
le16_to_cpu
(
BCC_LE
(
in_buf
));
(
2
*
midQ
->
resp_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
midQ
->
resp_buf
)
=
le16_to_cpu
(
BCC_LE
(
midQ
->
resp_buf
));
midQ
->
resp_buf
=
NULL
;
/* mark it so will not be freed
by DeleteMidQEntry */
}
else
{
rc
=
-
EIO
;
cFYI
(
1
,(
"Bad MID state?"
));
...
...
@@ -549,7 +552,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
return
rc
;
}
#endif
/* CIFS_EXPERIMENTAL */
int
SendReceive
(
const
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
,
...
...
@@ -790,7 +792,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC_LE
(
out_buf
));
}
else
{
rc
=
-
EIO
;
cERROR
(
1
,(
"Bad MID state?
"
));
cERROR
(
1
,(
"Bad MID state?"
));
}
}
cifs_no_response_exit:
...
...
fs/cifs/xattr.c
浏览文件 @
0f36b018
...
...
@@ -254,7 +254,8 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
rc
=
CIFSSMBQueryEA
(
xid
,
pTcon
,
full_path
,
ea_name
,
ea_value
,
buf_size
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
}
else
if
(
strncmp
(
ea_name
,
POSIX_ACL_XATTR_ACCESS
,
strlen
(
POSIX_ACL_XATTR_ACCESS
))
==
0
)
{
}
else
if
(
strncmp
(
ea_name
,
POSIX_ACL_XATTR_ACCESS
,
strlen
(
POSIX_ACL_XATTR_ACCESS
))
==
0
)
{
#ifdef CONFIG_CIFS_POSIX
if
(
sb
->
s_flags
&
MS_POSIXACL
)
rc
=
CIFSSMBGetPosixACL
(
xid
,
pTcon
,
full_path
,
...
...
@@ -262,10 +263,27 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
__u16 fid;
int oplock = FALSE;
rc = CIFSSMBOpen(xid, pTcon, full_path,
FILE_OPEN, GENERIC_READ, 0, &fid,
&oplock, NULL, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if(rc == 0) {
rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
ea_value, buf_size,
ACL_TYPE_ACCESS);
CIFSSMBClose(xid, pTcon, fid)
}
} */
/* BB enable after fixing up return data */
#else
cFYI
(
1
,(
"query POSIX ACL not supported yet"
));
#endif
/* CONFIG_CIFS_POSIX */
}
else
if
(
strncmp
(
ea_name
,
POSIX_ACL_XATTR_DEFAULT
,
strlen
(
POSIX_ACL_XATTR_DEFAULT
))
==
0
)
{
}
else
if
(
strncmp
(
ea_name
,
POSIX_ACL_XATTR_DEFAULT
,
strlen
(
POSIX_ACL_XATTR_DEFAULT
))
==
0
)
{
#ifdef CONFIG_CIFS_POSIX
if
(
sb
->
s_flags
&
MS_POSIXACL
)
rc
=
CIFSSMBGetPosixACL
(
xid
,
pTcon
,
full_path
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录