Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3979877e
Commit
3979877e
authored
May 31, 2006
by
Steve French
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CIFS] Support for setting up SMB sessions to legacy lanman servers
parent
26a21b98
Changes
20
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
837 additions
and
76 deletions
+837
-76
fs/Kconfig
fs/Kconfig
+38
-2
fs/cifs/CHANGES
fs/cifs/CHANGES
+5
-0
fs/cifs/Makefile
fs/cifs/Makefile
+1
-1
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.c
+71
-13
fs/cifs/cifs_debug.h
fs/cifs/cifs_debug.h
+4
-0
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.c
+1
-0
fs/cifs/cifsencrypt.c
fs/cifs/cifsencrypt.c
+2
-0
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+2
-2
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+37
-14
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+31
-6
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+1
-1
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+85
-10
fs/cifs/connect.c
fs/cifs/connect.c
+26
-13
fs/cifs/dir.c
fs/cifs/dir.c
+1
-1
fs/cifs/fcntl.c
fs/cifs/fcntl.c
+2
-2
fs/cifs/inode.c
fs/cifs/inode.c
+2
-1
fs/cifs/misc.c
fs/cifs/misc.c
+6
-4
fs/cifs/readdir.c
fs/cifs/readdir.c
+10
-6
fs/cifs/sess.c
fs/cifs/sess.c
+511
-0
fs/cifs/smbencrypt.c
fs/cifs/smbencrypt.c
+1
-0
No files found.
fs/Kconfig
View file @
3979877e
...
...
@@ -1663,7 +1663,7 @@ config CIFS_STATS
mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
config CIFS_STATS2
bool "
CIFS e
xtended statistics"
bool "
E
xtended statistics"
depends on CIFS_STATS
help
Enabling this option will allow more detailed statistics on SMB
...
...
@@ -1676,6 +1676,32 @@ config CIFS_STATS2
Unless you are a developer or are doing network performance analysis
or tuning, say N.
config CIFS_WEAK_PW_HASH
bool "Support legacy servers which use weaker LANMAN security"
depends on CIFS
help
Modern CIFS servers including Samba and most Windows versions
(since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
security mechanisms. These hash the password more securely
than the mechanisms used in the older LANMAN version of the
SMB protocol needed to establish sessions with old SMB servers.
Enabling this option allows the cifs module to mount to older
LANMAN based servers such as OS/2 and Windows 95, but such
mounts may be less secure than mounts using NTLM or more recent
security mechanisms if you are on a public network. Unless you
have a need to access old SMB servers (and are on a private
network) you probably want to say N. Even if this support
is enabled in the kernel build, they will not be used
automatically. At runtime LANMAN mounts are disabled but
can be set to required (or optional) either in
/proc/fs/cifs (see fs/cifs/README for more detail) or via an
option on the mount command. This support is disabled by
default in order to reduce the possibility of a downgrade
attack.
If unsure, say N.
config CIFS_XATTR
bool "CIFS extended attributes"
depends on CIFS
...
...
@@ -1704,6 +1730,16 @@ config CIFS_POSIX
(such as Samba 3.10 and later) which can negotiate
CIFS POSIX ACL support. If unsure, say N.
config CIFS_DEBUG2
bool "Enable additional CIFS debugging routines
help
Enabling this option adds a few more debugging routines
to the cifs code which slightly increases the size of
the cifs module and can cause additional logging of debug
messages in some error paths, slowing performance. This
option can be turned off unless you are debugging
cifs problems. If unsure, say N.
config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
...
...
@@ -1719,7 +1755,7 @@ config CIFS_EXPERIMENTAL
If unsure, say N.
config CIFS_UPCALL
bool "
CIFS
Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
depends on CIFS_EXPERIMENTAL
select CONNECTOR
help
...
...
fs/cifs/CHANGES
View file @
3979877e
Version 1.44
------------
Rewritten sessionsetup support, including support for legacy SMB
session setup needed for OS/2 and older servers such as Windows 95 and 98.
Version 1.43
------------
POSIX locking to servers which support CIFS POSIX Extensions
...
...
fs/cifs/Makefile
View file @
3979877e
...
...
@@ -3,4 +3,4 @@
#
obj-$(CONFIG_CIFS)
+=
cifs.o
cifs-objs
:=
cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o
ntlmssp
.o
cifs-objs
:=
cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o
sess
.o
fs/cifs/cifs_debug.c
View file @
3979877e
...
...
@@ -39,7 +39,7 @@ cifs_dump_mem(char *label, void *data, int length)
char
*
charptr
=
data
;
char
buf
[
10
],
line
[
80
];
printk
(
KERN_DEBUG
"%s: dump of %d bytes of data at 0x%p
\n
\n
"
,
printk
(
KERN_DEBUG
"%s: dump of %d bytes of data at 0x%p
\n
"
,
label
,
length
,
data
);
for
(
i
=
0
;
i
<
length
;
i
+=
16
)
{
line
[
0
]
=
0
;
...
...
@@ -57,6 +57,57 @@ cifs_dump_mem(char *label, void *data, int length)
}
}
#ifdef CONFIG_CIFS_DEBUG2
void
cifs_dump_detail
(
struct
smb_hdr
*
smb
)
{
cERROR
(
1
,(
"Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d"
,
smb
->
Command
,
smb
->
Status
.
CifsError
,
smb
->
Flags
,
smb
->
Flags2
,
smb
->
Mid
,
smb
->
Pid
));
cERROR
(
1
,(
"smb buf %p len %d"
,
smb
,
smbCalcSize_LE
(
smb
)));
}
void
cifs_dump_mids
(
struct
TCP_Server_Info
*
server
)
{
struct
list_head
*
tmp
;
struct
mid_q_entry
*
mid_entry
;
if
(
server
==
NULL
)
return
;
cERROR
(
1
,(
"Dump pending requests:"
));
spin_lock
(
&
GlobalMid_Lock
);
list_for_each
(
tmp
,
&
server
->
pending_mid_q
)
{
mid_entry
=
list_entry
(
tmp
,
struct
mid_q_entry
,
qhead
);
if
(
mid_entry
)
{
cERROR
(
1
,(
"State: %d Cmd: %d Pid: %d Tsk: %p Mid %d"
,
mid_entry
->
midState
,
(
int
)
mid_entry
->
command
,
mid_entry
->
pid
,
mid_entry
->
tsk
,
mid_entry
->
mid
));
#ifdef CONFIG_CIFS_STATS2
cERROR
(
1
,(
"IsLarge: %d buf: %p time rcv: %ld now: %ld"
,
mid_entry
->
largeBuf
,
mid_entry
->
resp_buf
,
mid_entry
->
when_received
,
jiffies
));
#endif
/* STATS2 */
cERROR
(
1
,(
"IsMult: %d IsEnd: %d"
,
mid_entry
->
multiRsp
,
mid_entry
->
multiEnd
));
if
(
mid_entry
->
resp_buf
)
{
cifs_dump_detail
(
mid_entry
->
resp_buf
);
cifs_dump_mem
(
"existing buf: "
,
mid_entry
->
resp_buf
,
62
/* fixme */
);
}
}
}
spin_unlock
(
&
GlobalMid_Lock
);
}
#endif
/* CONFIG_CIFS_DEBUG2 */
#ifdef CONFIG_PROC_FS
static
int
cifs_debug_data_read
(
char
*
buf
,
char
**
beginBuffer
,
off_t
offset
,
...
...
@@ -73,7 +124,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
*
beginBuffer
=
buf
+
offset
;
length
=
sprintf
(
buf
,
"Display Internal CIFS Data Structures for Debugging
\n
"
...
...
@@ -397,10 +447,10 @@ static read_proc_t multiuser_mount_read;
static
write_proc_t
multiuser_mount_write
;
static
read_proc_t
extended_security_read
;
static
write_proc_t
extended_security_write
;
static
read_proc_t
ntlmv2_enabled_read
;
/*
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 write_proc_t packet_signing_enabled_write;
*/
static
read_proc_t
experimEnabled_read
;
static
write_proc_t
experimEnabled_write
;
static
read_proc_t
linuxExtensionsEnabled_read
;
...
...
@@ -469,7 +519,7 @@ cifs_proc_init(void)
if
(
pde
)
pde
->
write_proc
=
lookupFlag_write
;
pde
=
/*
pde =
create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
ntlmv2_enabled_read, NULL);
if (pde)
...
...
@@ -479,7 +529,7 @@ cifs_proc_init(void)
create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
packet_signing_enabled_read, NULL);
if (pde)
pde
->
write_proc
=
packet_signing_enabled_write
;
pde->write_proc = packet_signing_enabled_write;
*/
}
void
...
...
@@ -496,9 +546,9 @@ cifs_proc_clean(void)
#endif
remove_proc_entry
(
"MultiuserMount"
,
proc_fs_cifs
);
remove_proc_entry
(
"OplockEnabled"
,
proc_fs_cifs
);
remove_proc_entry
(
"NTLMV2Enabled"
,
proc_fs_cifs
);
/* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */
remove_proc_entry
(
"ExtendedSecurity"
,
proc_fs_cifs
);
remove_proc_entry
(
"PacketSigningEnabled"
,
proc_fs_cifs
);
/* remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); */
remove_proc_entry
(
"LinuxExtensionsEnabled"
,
proc_fs_cifs
);
remove_proc_entry
(
"Experimental"
,
proc_fs_cifs
);
remove_proc_entry
(
"LookupCacheEnabled"
,
proc_fs_cifs
);
...
...
@@ -787,7 +837,7 @@ extended_security_read(char *page, char **start, off_t off,
{
int
len
;
len
=
sprintf
(
page
,
"
%d
\n
"
,
extended_security
);
len
=
sprintf
(
page
,
"
0x%x
\n
"
,
extended_security
);
len
-=
off
;
*
start
=
page
+
off
;
...
...
@@ -808,19 +858,25 @@ extended_security_write(struct file *file, const char __user *buffer,
{
char
c
;
int
rc
;
cERROR
(
1
,(
"size %ld"
,
count
));
/* BB removeme BB */
if
((
count
<
2
)
||
(
count
>
8
))
return
-
EINVAL
;
rc
=
get_user
(
c
,
buffer
);
/* BB fixme need to parse more characters in order to handle CIFSSEC flags */
if
(
rc
)
return
rc
;
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
extended_security
=
0
;
extended_security
=
CIFSSEC_DEF
;
/* default */
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
extended_security
=
1
;
extended_security
=
CIFSSEC_MAX
;
return
count
;
}
static
int
/*
static int
ntlmv2_enabled_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
...
...
@@ -855,6 +911,8 @@ ntlmv2_enabled_write(struct file *file, const char __user *buffer,
ntlmv2_support = 0;
else if (c == '1' || c == 'y' || c == 'Y')
ntlmv2_support = 1;
else if (c == '2')
ntlmv2_support = 2;
return count;
}
...
...
@@ -898,7 +956,7 @@ packet_signing_enabled_write(struct file *file, const char __user *buffer,
sign_CIFS_PDUs = 2;
return count;
}
}
*/
#endif
fs/cifs/cifs_debug.h
View file @
3979877e
...
...
@@ -24,6 +24,10 @@
#define _H_CIFS_DEBUG
void
cifs_dump_mem
(
char
*
label
,
void
*
data
,
int
length
);
#ifdef CONFIG_CIFS_DEBUG2
void
cifs_dump_detail
(
struct
smb_hdr
*
);
void
cifs_dump_mids
(
struct
TCP_Server_Info
*
);
#endif
extern
int
traceSMB
;
/* flag which enables the function below */
void
dump_smb
(
struct
smb_hdr
*
,
int
);
#define CIFS_INFO 0x01
...
...
fs/cifs/cifs_unicode.c
View file @
3979877e
...
...
@@ -22,6 +22,7 @@
#include "cifs_unicode.h"
#include "cifs_uniupr.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
/*
...
...
fs/cifs/cifsencrypt.c
View file @
3979877e
...
...
@@ -225,6 +225,8 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
user_name_len
=
strlen
(
ses
->
userName
);
if
(
user_name_len
>
MAX_USERNAME_SIZE
)
return
-
EINVAL
;
if
(
ses
->
domainName
==
NULL
)
return
-
EINVAL
;
/* BB should we use CIFS_LINUX_DOM */
dom_name_len
=
strlen
(
ses
->
domainName
);
if
(
dom_name_len
>
MAX_USERNAME_SIZE
)
return
-
EINVAL
;
...
...
fs/cifs/cifsfs.c
View file @
3979877e
...
...
@@ -56,8 +56,8 @@ unsigned int experimEnabled = 0;
unsigned
int
linuxExtEnabled
=
1
;
unsigned
int
lookupCacheEnabled
=
1
;
unsigned
int
multiuser_mount
=
0
;
unsigned
int
extended_security
=
0
;
unsigned
int
ntlmv2_support
=
0
;
unsigned
int
extended_security
=
CIFSSEC_DEF
;
/* unsigned int ntlmv2_support = 0; */
unsigned
int
sign_CIFS_PDUs
=
1
;
extern
struct
task_struct
*
oplockThread
;
/* remove sparse warning */
struct
task_struct
*
oplockThread
=
NULL
;
...
...
fs/cifs/cifsglob.h
View file @
3979877e
...
...
@@ -88,7 +88,8 @@ enum statusEnum {
};
enum
securityEnum
{
NTLM
=
0
,
/* Legacy NTLM012 auth with NTLM hash */
LANMAN
=
0
,
/* Legacy LANMAN auth */
NTLM
,
/* Legacy NTLM012 auth with NTLM hash */
NTLMv2
,
/* Legacy NTLM auth with NTLMv2 hash */
RawNTLMSSP
,
/* NTLMSSP without SPNEGO */
NTLMSSP
,
/* NTLMSSP via SPNEGO */
...
...
@@ -179,7 +180,9 @@ struct cifsUidInfo {
struct
cifsSesInfo
{
struct
list_head
cifsSessionList
;
struct
semaphore
sesSem
;
#if 0
struct cifsUidInfo *uidInfo; /* pointer to user info */
#endif
struct
TCP_Server_Info
*
server
;
/* pointer to server info */
atomic_t
inUse
;
/* # of mounts (tree connections) on this ses */
enum
statusEnum
status
;
...
...
@@ -194,7 +197,7 @@ struct cifsSesInfo {
char
serverName
[
SERVER_NAME_LEN_WITH_NULL
*
2
];
/* BB make bigger for
TCP names - will ipv6 and sctp addresses fit? */
char
userName
[
MAX_USERNAME_SIZE
+
1
];
char
domainName
[
MAX_USERNAME_SIZE
+
1
]
;
char
*
domainName
;
char
*
password
;
};
/* session flags */
...
...
@@ -391,9 +394,9 @@ struct mid_q_entry {
struct
smb_hdr
*
resp_buf
;
/* response buffer */
int
midState
;
/* wish this were enum but can not pass to wait_event */
__u8
command
;
/* smb command code */
unsigned
multiPart
:
1
;
/* multiple responses to one SMB request */
unsigned
largeBuf
:
1
;
/* if valid response, is pointer to large buf */
unsigned
multiResp
:
1
;
/* multiple trans2 responses for one request */
unsigned
multiRsp
:
1
;
/* multiple trans2 responses for one request */
unsigned
multiEnd
:
1
;
/* both received */
};
struct
oplock_q_entry
{
...
...
@@ -430,15 +433,35 @@ struct dir_notify_req {
#define CIFS_LARGE_BUFFER 2
#define CIFS_IOVEC 4
/* array of response buffers */
/* Type of session setup needed */
#define CIFS_PLAINTEXT 0
#define CIFS_LANMAN 1
#define CIFS_NTLM 2
#define CIFS_NTLMSSP_NEG 3
#define CIFS_NTLMSSP_AUTH 4
#define CIFS_SPNEGO_INIT 5
#define CIFS_SPNEGO_TARG 6
/* Security Flags: indicate type of session setup needed */
#define CIFSSEC_MAY_SIGN 0x00001
#define CIFSSEC_MAY_NTLM 0x00002
#define CIFSSEC_MAY_NTLMV2 0x00004
#define CIFSSEC_MAY_KRB5 0x00008
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MAY_LANMAN 0x00010
#define CIFSSEC_MAY_PLNTXT 0x00020
#endif
/* weak passwords */
#define CIFSSEC_MAY_SEAL 0x00040
/* not supported yet */
#define CIFSSEC_MUST_SIGN 0x01001
/* note that only one of the following can be set so the
result of setting MUST flags more than once will be to
require use of the stronger protocol */
#define CIFSSEC_MUST_NTLM 0x02002
#define CIFSSEC_MUST_NTLMV2 0x04004
#define CIFSSEC_MUST_KRB5 0x08008
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MUST_LANMAN 0x10010
#define CIFSSEC_MUST_PLNTXT 0x20020
#define CIFSSEC_MASK 0x37037
/* current flags supported if weak */
#else
#define CIFSSEC_MASK 0x07007
/* flags supported if no weak config */
#endif
/* WEAK_PW_HASH */
#define CIFSSEC_MUST_SEAL 0x40040
/* not supported yet */
#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2
#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2
/*
*****************************************************************
* All constants go here
...
...
@@ -540,8 +563,8 @@ GLOBAL_EXTERN unsigned int experimEnabled;
GLOBAL_EXTERN
unsigned
int
lookupCacheEnabled
;
GLOBAL_EXTERN
unsigned
int
extended_security
;
/* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
GLOBAL_EXTERN
unsigned
int
ntlmv2_support
;
/* better optional password hash */
GLOBAL_EXTERN
unsigned
int
sign_CIFS_PDUs
;
/* enable smb packet signing */
GLOBAL_EXTERN
unsigned
int
secFlags
;
GLOBAL_EXTERN
unsigned
int
linuxExtEnabled
;
/*enable Linux/Unix CIFS extensions*/
GLOBAL_EXTERN
unsigned
int
CIFSMaxBufSize
;
/* max size not including hdr */
GLOBAL_EXTERN
unsigned
int
cifs_min_rcv
;
/* min size of big ntwrk buf pool */
...
...
fs/cifs/cifspdu.h
View file @
3979877e
...
...
@@ -24,8 +24,14 @@
#include <net/sock.h>
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define LANMAN_PROT 0
#define CIFS_PROT 1
#else
#define CIFS_PROT 0
#define BAD_PROT CIFS_PROT+1
#endif
#define POSIX_PROT CIFS_PROT+1
#define BAD_PROT 0xFFFF
/* SMB command codes */
/* Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
...
...
@@ -400,6 +406,25 @@ typedef struct negotiate_req {
unsigned
char
DialectsArray
[
1
];
}
__attribute__
((
packed
))
NEGOTIATE_REQ
;
/* Dialect index is 13 for LANMAN */
typedef
struct
lanman_neg_rsp
{
struct
smb_hdr
hdr
;
/* wct = 13 */
__le16
DialectIndex
;
__le16
SecurityMode
;
__le16
MaxBufSize
;
__le16
MaxMpxCount
;
__le16
MaxNumberVcs
;
__le16
RawMode
;
__le32
SessionKey
;
__le32
ServerTime
;
__le16
ServerTimeZone
;
__le16
EncryptionKeyLength
;
__le16
Reserved
;
__u16
ByteCount
;
unsigned
char
EncryptionKey
[
1
];
}
__attribute__
((
packed
))
LANMAN_NEG_RSP
;
typedef
struct
negotiate_rsp
{
struct
smb_hdr
hdr
;
/* wct = 17 */
__le16
DialectIndex
;
...
...
@@ -520,8 +545,8 @@ typedef union smb_com_session_setup_andx {
__le16
MaxMpxCount
;
__le16
VcNumber
;
__u32
SessionKey
;
__le16
Pass
s
wordLength
;
__u32
Reserved
;
__le16
PasswordLength
;
__u32
Reserved
;
/* encrypt key len and offset */
__le16
ByteCount
;
unsigned
char
AccountPassword
[
1
];
/* followed by */
/* STRING AccountName */
...
...
@@ -1844,13 +1869,13 @@ typedef struct {
typedef
struct
{
__le32
DeviceType
;
__le32
DeviceCharacteristics
;
}
__attribute__
((
packed
))
FILE_SYSTEM_DEVICE_INFO
;
/* device info,
level 0x104 */
}
__attribute__
((
packed
))
FILE_SYSTEM_DEVICE_INFO
;
/* device info
level 0x104 */
typedef
struct
{
__le32
Attributes
;
__le32
MaxPathNameComponentLength
;
__le32
FileSystemNameLen
;
char
FileSystemName
[
52
];
/* do not
really need to save this - so potentially get only subset of name
*/
char
FileSystemName
[
52
];
/* do not
have to save this - get subset?
*/
}
__attribute__
((
packed
))
FILE_SYSTEM_ATTRIBUTE_INFO
;
/******************************************************************************/
...
...
fs/cifs/cifsproto.h
View file @
3979877e
...
...
@@ -69,7 +69,7 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
struct
cifsSesInfo
*
ses
,
void
**
request_buf
);
extern
int
CIFS_SessSetup
(
unsigned
int
xid
,
struct
cifsSesInfo
*
ses
,
const
int
stage
,
int
*
pNTLMv2_flg
,
const
int
stage
,
const
struct
nls_table
*
nls_cp
);
#endif
extern
__u16
GetNextMid
(
struct
TCP_Server_Info
*
server
);
...
...
fs/cifs/cifssmb.c
View file @
3979877e
...
...
@@ -44,8 +44,11 @@ static struct {
int
index
;
char
*
name
;
}
protocols
[]
=
{
#ifdef CONFIG_CIFS_WEAK_PW_HASH
{
LANMAN_PROT
,
"
\2
LM1.2X002"
},
#endif
/* weak password hashing for legacy clients */
{
CIFS_PROT
,
"
\2
NT LM 0.12"
},
{
CIFS
_PROT
,
"
\2
POSIX 2"
},
{
POSIX
_PROT
,
"
\2
POSIX 2"
},
{
BAD_PROT
,
"
\2
"
}
};
#else
...
...
@@ -53,11 +56,29 @@ static struct {
int
index
;
char
*
name
;
}
protocols
[]
=
{
#ifdef CONFIG_CIFS_WEAK_PW_HASH
{
LANMAN_PROT
,
"
\2
LM1.2X002"
},
#endif
/* weak password hashing for legacy clients */
{
CIFS_PROT
,
"
\2
NT LM 0.12"
},
{
BAD_PROT
,
"
\2
"
}
};
#endif
/* define the number of elements in the cifs dialect array */
#ifdef CONFIG_CIFS_POSIX
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFS_NUM_PROT 3
#else
#define CIFS_NUM_PROT 2
#endif
/* CIFS_WEAK_PW_HASH */
#else
/* not posix */
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFS_NUM_PROT 2
#else
#define CIFS_NUM_PROT 1
#endif
/* CONFIG_CIFS_WEAK_PW_HASH */
#endif
/* CIFS_POSIX */
/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
...
...
@@ -322,6 +343,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
/* potential retries of smb operations it turns out we can determine */
/* from the mid flags when the request buffer can be resent without */
/* having to use a second distinct buffer for the response */
if
(
response_buf
)
*
response_buf
=
*
request_buf
;
header_assemble
((
struct
smb_hdr
*
)
*
request_buf
,
smb_command
,
tcon
,
...
...
@@ -373,6 +395,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
NEGOTIATE_RSP
*
pSMBr
;
int
rc
=
0
;
int
bytes_returned
;
int
i
;
struct
TCP_Server_Info
*
server
;
u16
count
;
...
...
@@ -388,19 +411,71 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
return
rc
;
pSMB
->
hdr
.
Mid
=
GetNextMid
(
server
);
pSMB
->
hdr
.
Flags2
|=
SMBFLG2_UNICODE
;
if
(
extended_security
)
pSMB
->
hdr
.
Flags2
|=
SMBFLG2_EXT_SEC
;
count
=
strlen
(
protocols
[
0
].
name
)
+
1
;
strncpy
(
pSMB
->
DialectsArray
,
protocols
[
0
].
name
,
30
);
/* null guaranteed to be at end of source and target buffers anyway */
/* if (extended_security)
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;*/
count
=
0
;
for
(
i
=
0
;
i
<
CIFS_NUM_PROT
;
i
++
)
{
strncpy
(
pSMB
->
DialectsArray
+
count
,
protocols
[
i
].
name
,
16
);
count
+=
strlen
(
protocols
[
i
].
name
)
+
1
;
/* null at end of source and target buffers anyway */
}
pSMB
->
hdr
.
smb_buf_length
+=
count
;
pSMB
->
ByteCount
=
cpu_to_le16
(
count
);
rc
=
SendReceive
(
xid
,
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
if
(
rc
==
0
)
{
cFYI
(
1
,(
"Dialect: %d"
,
pSMBr
->
DialectIndex
));
/* Check wct = 1 error case */
if
((
pSMBr
->
hdr
.
WordCount
<
13
)
||
(
pSMBr
->
DialectIndex
==
BAD_PROT
))
{
/* core returns wct = 1, but we do not ask for
core - otherwise it just comes when dialect
index is -1 indicating we could not negotiate
a common dialect */
rc
=
-
EOPNOTSUPP
;
goto
neg_err_exit
;
}
else
if
((
pSMBr
->
hdr
.
WordCount
==
13
)
&&
(
pSMBr
->
DialectIndex
==
LANMAN_PROT
))
{
struct
lanman_neg_rsp
*
rsp
=
(
struct
lanman_neg_rsp
*
)
pSMBr
;
/* BB Mark ses struct as negotiated lanman level BB */
server
->
secType
=
LANMAN
;
server
->
secMode
=
(
__u8
)
le16_to_cpu
(
rsp
->
SecurityMode
);
server
->
maxReq
=
le16_to_cpu
(
rsp
->
MaxMpxCount
);
server
->
maxBuf
=
min
((
__u32
)
le16_to_cpu
(
rsp
->
MaxBufSize
),
(
__u32
)
CIFSMaxBufSize
+
MAX_CIFS_HDR_SIZE
);
/* BB what do we do with raw mode? BB */
server
->
timeZone
=
le16_to_cpu
(
rsp
->
ServerTimeZone
);
/* Do we have to set signing flags? no signing
was available LANMAN - default should be ok */
/* BB FIXME set default dummy capabilities since
they are not returned by the server in this dialect */
/* get server time for time conversions and add
code to use it and timezone since this is not UTC */
if
(
rsp
->
EncryptionKeyLength
==
CIFS_CRYPTO_KEY_SIZE
)
{
memcpy
(
server
->
cryptKey
,
rsp
->
EncryptionKey
,
CIFS_CRYPTO_KEY_SIZE
);
}
else
{
rc
=
-
EIO
;
goto
neg_err_exit
;
}
cFYI
(
1
,(
"LANMAN negotiated"
));
/* BB removeme BB */
goto
neg_err_exit
;
}
else
if
(
pSMBr
->
hdr
.
WordCount
!=
17
)
{
/* unknown wct */
rc
=
-
EOPNOTSUPP
;
goto
neg_err_exit
;
}
server
->
secMode
=
pSMBr
->
SecurityMode
;
if
((
server
->
secMode
&
SECMODE_USER
)
==
0
)
cFYI
(
1
,(
"share mode security"
));
...
...
@@ -479,7 +554,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
}
}
neg_err_exit:
cifs_buf_release
(
pSMB
);
return
rc
;
}
...
...
fs/cifs/connect.c
View file @
3979877e
...
...
@@ -49,8 +49,6 @@
static
DECLARE_COMPLETION
(
cifsd_complete
);
extern
void
SMBencrypt
(
unsigned
char
*
passwd
,
unsigned
char
*
c8
,
unsigned
char
*
p24
);
extern
void
SMBNTencrypt
(
unsigned
char
*
passwd
,
unsigned
char
*
c8
,
unsigned
char
*
p24
);
...
...
@@ -585,9 +583,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* merge response - fix up 1st*/
if
(
coalesce_t2
(
smb_buffer
,
mid_entry
->
resp_buf
))
{
mid_entry
->
multiRsp
=
1
;
break
;
}
else
{
/* all parts received */
mid_entry
->
multiEnd
=
1
;
goto
multi_t2_fnd
;
}
}
else
{
...
...
@@ -632,9 +632,14 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up_process
(
task_to_wake
);
}
else
if
((
is_valid_oplock_break
(
smb_buffer
,
server
)
==
FALSE
)
&&
(
isMultiRsp
==
FALSE
))
{
cERROR
(
1
,
(
"No task to wake, unknown frame rcvd!
"
));
cERROR
(
1
,
(
"No task to wake, unknown frame rcvd!
NumMids %d"
,
midCount
.
counter
));
cifs_dump_mem
(
"Received Data is: "
,(
char
*
)
smb_buffer
,
sizeof
(
struct
smb_hdr
));
#ifdef CONFIG_CIFS_DEBUG2
cifs_dump_detail
(
smb_buffer
);
cifs_dump_mids
(
server
);
#endif
/* CIFS_DEBUG2 */
}
}
/* end while !EXITING */
...
...
@@ -976,7 +981,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
}
/* BB are there cases in which a comma can be valid in
a domain name and need special handling? */
if
(
strnlen
(
value
,
65
)
<
65
)
{
if
(
strnlen
(
value
,
256
)
<
256
)
{
vol
->
domainname
=
value
;
cFYI
(
1
,
(
"Domain name set"
));
}
else
{
...
...
@@ -1762,9 +1767,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if
(
volume_info
.
username
)
strncpy
(
pSesInfo
->
userName
,
volume_info
.
username
,
MAX_USERNAME_SIZE
);
if
(
volume_info
.
domainname
)
strncpy
(
pSesInfo
->
domainName
,
volume_info
.
domainname
,
MAX_USERNAME_SIZE
);
if
(
volume_info
.
domainname
)
{
int
len
=
strlen
(
volume_info
.
domainname
);
pSesInfo
->
domainName
=
kmalloc
(
len
+
1
,
GFP_KERNEL
);
if
(
pSesInfo
->
domainName
)
strcpy
(
pSesInfo
->
domainName
,
volume_info
.
domainname
);
}
pSesInfo
->
linux_uid
=
volume_info
.
linux_uid
;
down
(
&
pSesInfo
->
sesSem
);
rc
=
cifs_setup_session
(
xid
,
pSesInfo
,
cifs_sb
->
local_nls
);
...
...
@@ -2054,7 +2064,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr
++
;
}
if
(
user
==
NULL
)
bytes_returned
=
0
;
/* ski
ll
null user */
bytes_returned
=
0
;
/* ski
p
null user */
else
bytes_returned
=
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
user
,
100
,
...
...
@@ -2635,8 +2645,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
/* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */
NTLMSSP_NEGOTIATE_128
;
if
(
sign_CIFS_PDUs
)
negotiate_flags
|=
NTLMSSP_NEGOTIATE_SIGN
;
if
(
ntlmv2_support
)
negotiate_flags
|=
NTLMSSP_NEGOTIATE_NTLMV2
;
/*
if(ntlmv2_support)
negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
*/
/* setup pointers to domain name and workstation name */
bcc_ptr
+=
SecurityBlobLength
;
...
...
@@ -3429,7 +3439,10 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
}
/* else do not bother copying these informational fields */
}
if
(
smb_buffer_response
->
WordCount
==
3
)
tcon
->
Flags
=
le16_to_cpu
(
pSMBr
->
OptionalSupport
);
else
tcon
->
Flags
=
0
;
cFYI
(
1
,
(
"Tcon flags: 0x%x "
,
tcon
->
Flags
));
}
else
if
((
rc
==
0
)
&&
tcon
==
NULL
)
{
/* all we need to save for IPC$ connection */
...
...
@@ -3528,8 +3541,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
pSesInfo
->
server
->
timeZone
));
#ifdef CONFIG_CIFS_EXPERIMENTAL
if
(
experimEnabled
>
1
)
rc
=
CIFS_SessSetup
(
xid
,
pSesInfo
,
CIFS_NTLM
/* type */
,
&
ntlmv2_flag
,
nls_info
);
rc
=
CIFS_SessSetup
(
xid
,
pSesInfo
,
first_time
,
nls_info
);
else
#endif
if
(
extended_security
...
...
fs/cifs/dir.c
View file @
3979877e
...
...
@@ -113,7 +113,7 @@ build_path_from_dentry(struct dentry *direntry)
full_path[namelen+2] = 0;
BB remove above eight lines BB */
/* Inode operations in similar order to how they appear in
the
Linux file fs.h */
/* Inode operations in similar order to how they appear in Linux file fs.h */
int
cifs_create
(
struct
inode
*
inode
,
struct
dentry
*
direntry
,
int
mode
,
...
...
fs/cifs/fcntl.c
View file @
3979877e
...
...
@@ -91,14 +91,14 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
if
(
full_path
==
NULL
)
{
rc
=
-
ENOMEM
;
}
else
{
c
ERROR
(
1
,(
"cifs dir notify on file %s with arg 0x%lx"
,
full_path
,
arg
));
/* BB removeme BB */
c
FYI
(
1
,(
"dir notify on file %s Arg 0x%lx"
,
full_path
,
arg
));
rc
=
CIFSSMBOpen
(
xid
,
pTcon
,
full_path
,
FILE_OPEN
,
GENERIC_READ
|
SYNCHRONIZE
,
0
/* create options */
,
&
netfid
,
&
oplock
,
NULL
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
/* BB fixme - add this handle to a notify handle list */
if
(
rc
)
{
c
ERROR
(
1
,(
"Could not open directory for notify"
));
/* BB remove BB */
c
FYI
(
1
,(
"Could not open directory for notify"
));
}
else
{
filter
=
convert_to_cifs_notify_flags
(
arg
);
if
(
filter
!=
0
)
{
...
...
fs/cifs/inode.c
View file @
3979877e
...
...
@@ -1121,7 +1121,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
xid
=
GetXid
();
cFYI
(
1
,
(
"
In cifs_setattr, name =
%s attrs->iavalid 0x%x"
,
cFYI
(
1
,
(
"
setattr on file
%s attrs->iavalid 0x%x"
,
direntry
->
d_name
.
name
,
attrs
->
ia_valid
));
cifs_sb
=
CIFS_SB
(
direntry
->
d_inode
->
i_sb
);
...
...
@@ -1157,6 +1157,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
when the local oplock break takes longer to flush
writebehind data than the SMB timeout for the SetPathInfo
request would allow */
open_file
=
find_writable_file
(
cifsInode
);
if
(
open_file
)
{
__u16
nfid
=
open_file
->
netfid
;
...
...
fs/cifs/misc.c
View file @
3979877e
...
...
@@ -101,6 +101,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
kfree
(
buf_to_free
->
serverDomain
);
kfree
(
buf_to_free
->
serverNOS
);
kfree
(
buf_to_free
->
password
);
kfree
(
buf_to_free
->
domainName
);
kfree
(
buf_to_free
);
}
...
...
@@ -499,11 +500,12 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
if
(
pSMBr
->
ByteCount
>
sizeof
(
struct
file_notify_information
))
{
data_offset
=
le32_to_cpu
(
pSMBr
->
DataOffset
);
pnotify
=
(
struct
file_notify_information
*
)
((
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
data_offset
);
cFYI
(
1
,(
"dnotify on %s
with a
ction: 0x%x"
,
pnotify
->
FileName
,
pnotify
=
(
struct
file_notify_information
*
)
((
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
data_offset
);
cFYI
(
1
,(
"dnotify on %s
A
ction: 0x%x"
,
pnotify
->
FileName
,
pnotify
->
Action
));
/* BB removeme BB */
/* cifs_dump_mem("Received notify Data is: ",buf,sizeof(struct smb_hdr)+60); */
/* cifs_dump_mem("Rcvd notify Data: ",buf,
sizeof(struct smb_hdr)+60); */
return
TRUE
;
}
if
(
pSMBr
->
hdr
.
Status
.
CifsError
)
{
...
...
fs/cifs/readdir.c
View file @
3979877e
...
...
@@ -31,8 +31,8 @@
#include "cifs_fs_sb.h"
#include "cifsfs.h"
/* BB fixme - add debug wrappers around this function to disable it fixme BB */
/*
static void dump_cifs_file_struct(struct file *file, char *label)
#ifdef CONFIG_CIFS_DEBUG2
static
void
dump_cifs_file_struct
(
struct
file
*
file
,
char
*
label
)
{
struct
cifsFileInfo
*
cf
;
...
...
@@ -53,7 +53,8 @@
}
}
} */
}
#endif
/* DEBUG2 */
/* Returns one if new inode created (which therefore needs to be hashed) */
/* Might check in the future if inode number changed so we can rehash inode */
...
...
@@ -597,7 +598,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
. and .. for the root of a drive and for those we need
to start two entries earlier */
/* dump_cifs_file_struct(file, "In fce ");*/
#ifdef CONFIG_CIFS_DEBUG2
dump_cifs_file_struct
(
file
,
"In fce "
);
#endif
if
(((
index_to_find
<
cifsFile
->
srch_inf
.
index_of_last_entry
)
&&
is_dir_changed
(
file
))
||
(
index_to_find
<
first_entry_in_buffer
))
{
...
...
@@ -980,9 +983,10 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
rc
=
cifs_filldir
(
current_entry
,
file
,
filldir
,
direntry
,
tmp_buf
);
file
->
f_pos
++
;
if
(
file
->
f_pos
==
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
if
(
file
->
f_pos
==
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
cFYI
(
1
,(
"last entry in buf at pos %lld %s"
,
file
->
f_pos
,
tmp_buf
));
/* BB removeme BB */
file
->
f_pos
,
tmp_buf
));
cifs_save_resume_key
(
current_entry
,
cifsFile
);
break
;
}
else
...
...
fs/cifs/sess.c
0 → 100644
View file @
3979877e
This diff is collapsed.
Click to expand it.
fs/cifs/smbencrypt.c
View file @
3979877e
...
...
@@ -30,6 +30,7 @@
#include <linux/random.h>
#include "cifs_unicode.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "md5.h"
#include "cifs_debug.h"
#include "cifsencrypt.h"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment