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
3ae3d4d5
Commit
3ae3d4d5
authored
May 13, 2003
by
Steve French
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix readlink of dfs junctions
parent
1f9ccaab
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
147 additions
and
23 deletions
+147
-23
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+1
-0
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+4
-2
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+76
-3
fs/cifs/connect.c
fs/cifs/connect.c
+26
-6
fs/cifs/inode.c
fs/cifs/inode.c
+0
-9
fs/cifs/link.c
fs/cifs/link.c
+40
-3
No files found.
fs/cifs/cifspdu.h
View file @
3ae3d4d5
...
...
@@ -1263,6 +1263,7 @@ typedef struct dfs_referral_level_3 {
__u16
ServerType
;
/* 0x0001 = CIFS server */
__u16
ReferralFlags
;
/* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */
__u16
TimeToLive
;
__u16
Proximity
;
__u16
DfsPathOffset
;
__u16
DfsAlternatePathOffset
;
__u16
NetworkAddressOffset
;
...
...
fs/cifs/cifsproto.h
View file @
3ae3d4d5
...
...
@@ -127,13 +127,15 @@ extern int CIFSSMBUnixQPathInfo(const int xid,
extern
int
CIFSGetDFSRefer
(
const
int
xid
,
struct
cifsSesInfo
*
ses
,
const
unsigned
char
*
searchName
,
unsigned
char
**
targetUNCs
,
int
*
number_of_UNC_in_array
,
unsigned
int
*
number_of_UNC_in_array
,
const
struct
nls_table
*
nls_codepage
);
extern
int
connect_to_dfs_path
(
int
xid
,
struct
cifsSesInfo
*
pSesInfo
,
const
char
*
old_path
,
const
struct
nls_table
*
nls_codepage
);
extern
int
get_dfs_path
(
int
xid
,
struct
cifsSesInfo
*
pSesInfo
,
const
char
*
old_path
,
const
struct
nls_table
*
nls_codepage
,
unsigned
int
*
pnum_referrals
,
unsigned
char
**
preferrals
);
extern
int
CIFSSMBQFSInfo
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
struct
statfs
*
FSData
,
const
struct
nls_table
*
nls_codepage
);
...
...
fs/cifs/cifssmb.c
View file @
3ae3d4d5
...
...
@@ -1625,15 +1625,18 @@ int
CIFSGetDFSRefer
(
const
int
xid
,
struct
cifsSesInfo
*
ses
,
const
unsigned
char
*
searchName
,
unsigned
char
**
targetUNCs
,
int
*
number_of_UNC_in_array
,
unsigned
int
*
number_of_UNC_in_array
,
const
struct
nls_table
*
nls_codepage
)
{
/* TRANS2_GET_DFS_REFERRAL */
TRANSACTION2_GET_DFS_REFER_REQ
*
pSMB
=
NULL
;
TRANSACTION2_GET_DFS_REFER_RSP
*
pSMBr
=
NULL
;
struct
dfs_referral_level_3
*
referrals
=
NULL
;
int
rc
=
0
;
int
bytes_returned
;
int
name_len
;
unsigned
int
i
;
char
*
temp
;
*
number_of_UNC_in_array
=
0
;
*
targetUNCs
=
NULL
;
...
...
@@ -1701,6 +1704,76 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
cFYI
(
1
,
(
"Send error in GetDFSRefer = %d"
,
rc
));
}
else
{
/* decode response */
/* BB Add logic to parse referrals here */
pSMBr
->
DataOffset
=
le16_to_cpu
(
pSMBr
->
DataOffset
);
pSMBr
->
DataCount
=
le16_to_cpu
(
pSMBr
->
DataCount
);
cFYI
(
1
,
(
"Decoding GetDFSRefer response. BCC: %d Offset %d"
,
pSMBr
->
ByteCount
,
pSMBr
->
DataOffset
));
if
((
pSMBr
->
ByteCount
<
17
)
||
(
pSMBr
->
DataOffset
>
512
))
/* BB also check enough total bytes returned */
rc
=
-
EIO
;
/* bad smb */
else
{
referrals
=
(
struct
dfs_referral_level_3
*
)
(
8
/* sizeof start of data block */
+
pSMBr
->
DataOffset
+
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
);
cFYI
(
1
,(
"num_referrals: %d dfs flags: 0x%x ...
\n
for referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x"
,
pSMBr
->
NumberOfReferrals
,
pSMBr
->
DFSFlags
,
referrals
->
ReferralSize
,
referrals
->
ServerType
,
referrals
->
ReferralFlags
,
referrals
->
TimeToLive
));
/* BB This field is actually two bytes in from start of
data block so we could do safety check that DataBlock
begins at address of pSMBr->NumberOfReferrals */
*
number_of_UNC_in_array
=
le16_to_cpu
(
pSMBr
->
NumberOfReferrals
);
/* BB Fix below so can return more than one referral */
if
(
*
number_of_UNC_in_array
>
1
)
*
number_of_UNC_in_array
=
1
;
/* get the length of the strings describing refs */
name_len
=
0
;
for
(
i
=
0
;
i
<*
number_of_UNC_in_array
;
i
++
)
{
/* make sure that DfsPathOffset not past end */
referrals
->
DfsPathOffset
=
le16_to_cpu
(
referrals
->
DfsPathOffset
);
if
(
referrals
->
DfsPathOffset
>
pSMBr
->
DataCount
)
{
/* if invalid referral, stop here and do
not try to copy any more */
*
number_of_UNC_in_array
=
i
;
break
;
}
temp
=
((
char
*
)
referrals
)
+
referrals
->
DfsPathOffset
;
if
(
pSMBr
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
name_len
+=
UniStrnlen
((
wchar_t
*
)
temp
,
pSMBr
->
DataCount
);
}
else
{
name_len
+=
strnlen
(
temp
,
pSMBr
->
DataCount
);
}
referrals
++
;
/* BB add check that referral pointer does not fall off end PDU */
}
/* BB add check for name_len bigger than bcc */
*
targetUNCs
=
kmalloc
(
name_len
+
1
+
(
*
number_of_UNC_in_array
),
GFP_KERNEL
);
/* copy the ref strings */
referrals
=
(
struct
dfs_referral_level_3
*
)
(
8
/* sizeof data hdr */
+
pSMBr
->
DataOffset
+
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
);
for
(
i
=
0
;
i
<*
number_of_UNC_in_array
;
i
++
)
{
temp
=
((
char
*
)
referrals
)
+
referrals
->
DfsPathOffset
;
if
(
pSMBr
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
cifs_strfromUCS_le
(
*
targetUNCs
,
(
wchar_t
*
)
temp
,
name_len
,
nls_codepage
);
}
else
{
strncpy
(
*
targetUNCs
,
temp
,
name_len
);
}
/* BB update target_uncs pointers */
referrals
++
;
}
temp
=
*
targetUNCs
;
temp
[
name_len
]
=
0
;
}
}
if
(
pSMB
)
buf_release
(
pSMB
);
...
...
fs/cifs/connect.c
View file @
3ae3d4d5
...
...
@@ -571,11 +571,32 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
int
connect_to_dfs_path
(
int
xid
,
struct
cifsSesInfo
*
pSesInfo
,
const
char
*
old_path
,
const
struct
nls_table
*
nls_codepage
)
{
unsigned
char
*
referrals
=
NULL
;
unsigned
int
num_referrals
;
int
rc
=
0
;
rc
=
get_dfs_path
(
xid
,
pSesInfo
,
old_path
,
nls_codepage
,
&
num_referrals
,
&
referrals
);
/* BB Add in code to: if valid refrl, if not ip address contact
the helper that resolves tcp names, mount to it, try to
tcon to it unmount it if fail */
/* BB free memory for referrals string BB */
return
rc
;
}
int
get_dfs_path
(
int
xid
,
struct
cifsSesInfo
*
pSesInfo
,
const
char
*
old_path
,
const
struct
nls_table
*
nls_codepage
,
unsigned
int
*
pnum_referrals
,
unsigned
char
**
preferrals
)
{
char
*
temp_unc
;
int
rc
=
0
;
int
num_referrals
=
0
;
unsigned
char
*
referrals
=
NULL
;
*
pnum_referrals
=
0
;
if
(
pSesInfo
->
ipc_tid
==
0
)
{
temp_unc
=
kmalloc
(
2
/* for slashes */
+
...
...
@@ -594,11 +615,10 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
kfree
(
temp_unc
);
}
if
(
rc
==
0
)
rc
=
CIFSGetDFSRefer
(
xid
,
pSesInfo
,
old_path
,
&
referrals
,
&
num_referrals
,
nls_codepage
);
return
-
ENODEV
;
/* BB remove and add return code processing */
rc
=
CIFSGetDFSRefer
(
xid
,
pSesInfo
,
old_path
,
preferrals
,
pnum_referrals
,
nls_codepage
);
return
rc
;
}
int
setup_session
(
unsigned
int
xid
,
struct
cifsSesInfo
*
pSesInfo
,
struct
nls_table
*
nls_info
)
...
...
fs/cifs/inode.c
View file @
3ae3d4d5
...
...
@@ -53,10 +53,6 @@ cifs_get_inode_info_unix(struct inode **pinode,
/* dump_mem("\nUnixQPathInfo return data", &findData, sizeof(findData)); */
if
(
rc
)
{
if
(
rc
==
-
EREMOTE
)
{
/* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
&referrals,
&num_referrals,
cifs_sb->local_nls); */
tmp_path
=
kmalloc
(
strnlen
(
pTcon
->
treeName
,
...
...
@@ -180,11 +176,6 @@ cifs_get_inode_info(struct inode **pinode,
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if
(
rc
)
{
if
(
rc
==
-
EREMOTE
)
{
/* BB add call to new func rc = GetDFSReferral(); */
/* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
&referrals,
&num_referrals,
cifs_sb->local_nls); */
tmp_path
=
kmalloc
(
strnlen
(
pTcon
->
treeName
,
...
...
fs/cifs/link.c
View file @
3ae3d4d5
...
...
@@ -113,6 +113,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
/* BB Should we be using page symlink ops here? */
if
(
rc
==
0
)
{
/* BB Add special case check for Samba DFS symlinks */
target_path
[
PATH_MAX
-
1
]
=
0
;
rc
=
vfs_follow_link
(
nd
,
target_path
);
}
...
...
@@ -186,7 +189,10 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
char
*
full_path
=
NULL
;
char
*
tmp_path
=
NULL
;
char
*
tmpbuffer
;
unsigned
char
*
referrals
=
NULL
;
int
num_referrals
=
0
;
int
len
;
__u16
fid
;
...
...
@@ -206,6 +212,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
FreeXid
(
xid
);
return
-
ENOMEM
;
}
/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
if
(
cifs_sb
->
tcon
->
ses
->
capabilities
&
CAP_UNIX
)
rc
=
CIFSSMBUnixQuerySymLink
(
xid
,
pTcon
,
full_path
,
...
...
@@ -224,8 +231,36 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
if
(
CIFSSMBClose
(
xid
,
pTcon
,
fid
))
{
cFYI
(
1
,(
"Error closing junction point (open for ioctl)"
));
}
if
(
rc
==
-
EIO
)
{
/* Query if DFS Junction */
tmp_path
=
kmalloc
(
MAX_TREE_SIZE
+
MAX_PATHCONF
+
1
,
GFP_KERNEL
);
if
(
tmp_path
)
{
strncpy
(
tmp_path
,
pTcon
->
treeName
,
MAX_TREE_SIZE
);
strncat
(
tmp_path
,
full_path
,
MAX_PATHCONF
);
rc
=
get_dfs_path
(
xid
,
pTcon
->
ses
,
tmp_path
,
cifs_sb
->
local_nls
,
&
num_referrals
,
&
referrals
);
cFYI
(
1
,(
"Get DFS for %s rc = %d "
,
tmp_path
,
rc
));
if
((
num_referrals
==
0
)
&&
(
rc
==
0
))
rc
=
-
EACCES
;
else
{
cFYI
(
1
,(
"num referral: %d"
,
num_referrals
));
if
(
referrals
)
{
cFYI
(
1
,(
"referral string: %s "
,
referrals
));
strncpy
(
tmpbuffer
,
referrals
,
len
-
1
);
}
}
kfree
(
tmp_path
);
if
(
referrals
)
{
kfree
(
referrals
);
}
}
/* BB add code like else decode referrals then memcpy to
tmpbuffer and free referrals string array BB */
}
}
}
/* BB Anything else to do to handle recursive links? */
/* BB Should we be using page ops here? */
...
...
@@ -238,10 +273,12 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
rc
));
}
if
(
tmpbuffer
)
if
(
tmpbuffer
)
{
kfree
(
tmpbuffer
);
if
(
full_path
)
}
if
(
full_path
)
{
kfree
(
full_path
);
}
FreeXid
(
xid
);
return
rc
;
}
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