Commit 5cf11daf authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (21 commits)
  [CIFS] Remove debug statement
  Fix possible access to undefined memory region.
  [CIFS] Enable DFS support for Windows query path info
  [CIFS] Enable DFS support for Unix query path info
  [CIFS] add missing seq_printf to cifs_show_options for hard mount option
  [CIFS] add more complete mount options to cifs_show_options
  [CIFS] Add missing defines for DFS
  CIFSGetDFSRefer cleanup + dfs_referral_level_3 fixed to conform REFERRAL_V3 the MS-DFSC spec.
  Fixed DFS code to work with new 'build_path_from_dentry', that returns full path if share in the dfs, now.
  [CIFS] enable parsing for transport encryption mount parm
  [CIFS] Finishup DFS code
  [CIFS] BKL-removal: convert CIFS over to unlocked_ioctl
  [CIFS] suppress duplicate warning
  [CIFS] Fix paths when share is in DFS to include proper prefix
  add function to convert access flags to legacy open mode
  clarify return value of cifs_convert_flags()
  [CIFS] don't explicitly do a FindClose on rewind when directory search has ended
  [CIFS] cleanup old checkpatch warnings
  [CIFS] CIFSSMBPosixLock should return -EINVAL on error
  fix memory leak in CIFSFindNext
  ...
parents d40ace0c 397d71dd
...@@ -36,6 +36,7 @@ Miklos Szeredi ...@@ -36,6 +36,7 @@ Miklos Szeredi
Kazeon team for various fixes especially for 2.4 version. Kazeon team for various fixes especially for 2.4 version.
Asser Ferno (Change Notify support) Asser Ferno (Change Notify support)
Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
Igor Mammedov (DFS support)
Test case and Bug Report contributors Test case and Bug Report contributors
------------------------------------- -------------------------------------
......
Version 1.53 Version 1.53
------------ ------------
DFS support added (Microsoft Distributed File System client support needed
for referrals which enable a hierarchical name space among servers).
Version 1.52 Version 1.52
------------ ------------
...@@ -12,7 +14,8 @@ Add ability to modify cifs acls for handling chmod (when mounted with ...@@ -12,7 +14,8 @@ Add ability to modify cifs acls for handling chmod (when mounted with
cifsacl flag). Fix prefixpath path separator so we can handle mounts cifsacl flag). Fix prefixpath path separator so we can handle mounts
with prefixpaths longer than one directory (one path component) when with prefixpaths longer than one directory (one path component) when
mounted to Windows servers. Fix slow file open when cifsacl mounted to Windows servers. Fix slow file open when cifsacl
enabled. enabled. Fix memory leak in FindNext when the SMB call returns -EBADF.
Version 1.51 Version 1.51
------------ ------------
......
...@@ -483,6 +483,11 @@ A partial list of the supported mount options follows: ...@@ -483,6 +483,11 @@ A partial list of the supported mount options follows:
sign Must use packet signing (helps avoid unwanted data modification sign Must use packet signing (helps avoid unwanted data modification
by intermediate systems in the route). Note that signing by intermediate systems in the route). Note that signing
does not work with lanman or plaintext authentication. does not work with lanman or plaintext authentication.
seal Must seal (encrypt) all data on this mounted share before
sending on the network. Requires support for Unix Extensions.
Note that this differs from the sign mount option in that it
causes encryption of data sent over this mounted share but other
shares mounted to the same server are unaffected.
sec Security mode. Allowed values are: sec Security mode. Allowed values are:
none attempt to connection as a null user (no name) none attempt to connection as a null user (no name)
krb5 Use Kerberos version 5 authentication krb5 Use Kerberos version 5 authentication
......
Version 1.52 January 3, 2008 Version 1.53 May 20, 2008
A Partial List of Missing Features A Partial List of Missing Features
================================== ==================================
...@@ -20,20 +20,21 @@ d) Cleanup now unneeded SessSetup code in ...@@ -20,20 +20,21 @@ d) Cleanup now unneeded SessSetup code in
fs/cifs/connect.c and add back in NTLMSSP code if any servers fs/cifs/connect.c and add back in NTLMSSP code if any servers
need it need it
e) ms-dfs and ms-dfs host name resolution cleanup e) fix NTLMv2 signing when two mounts with different users to same
f) fix NTLMv2 signing when two mounts with different users to same
server. server.
g) Directory entry caching relies on a 1 second timer, rather than f) Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started) using FindNotify or equivalent. - (started)
h) quota support (needs minor kernel change since quota calls g) quota support (needs minor kernel change since quota calls
to make it to network filesystems or deviceless filesystems) to make it to network filesystems or deviceless filesystems)
i) investigate sync behavior (including syncpage) and check h) investigate sync behavior (including syncpage) and check
for proper behavior of intr/nointr for proper behavior of intr/nointr
i) improve support for very old servers (OS/2 and Win9x for example)
Including support for changing the time remotely (utimes command).
j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
extra copy in/out of the socket buffers in some cases. extra copy in/out of the socket buffers in some cases.
......
...@@ -219,53 +219,6 @@ static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent, ...@@ -219,53 +219,6 @@ static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent,
} }
static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
{
char *full_path = NULL;
char *search_path;
char *tmp_path;
size_t l_max_len;
struct cifs_sb_info *cifs_sb;
if (dentry->d_inode == NULL)
return NULL;
cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
if (cifs_sb->tcon == NULL)
return NULL;
search_path = build_path_from_dentry(dentry);
if (search_path == NULL)
return NULL;
if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
int i;
/* we should use full path name for correct working with DFS */
l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
strnlen(search_path, MAX_PATHCONF) + 1;
tmp_path = kmalloc(l_max_len, GFP_KERNEL);
if (tmp_path == NULL) {
kfree(search_path);
return NULL;
}
strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
tmp_path[l_max_len-1] = 0;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
for (i = 0; i < l_max_len; i++) {
if (tmp_path[i] == '\\')
tmp_path[i] = '/';
}
strncat(tmp_path, search_path, l_max_len - strlen(tmp_path));
full_path = tmp_path;
kfree(search_path);
} else {
full_path = search_path;
}
return full_path;
}
static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd, static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
struct list_head *mntlist) struct list_head *mntlist)
{ {
...@@ -333,7 +286,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) ...@@ -333,7 +286,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
goto out_err; goto out_err;
} }
full_path = build_full_dfs_path_from_dentry(dentry); full_path = build_path_from_dentry(dentry);
if (full_path == NULL) { if (full_path == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto out_err; goto out_err;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
struct cifs_sb_info { struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */ struct cifsTconInfo *tcon; /* primary mount */
......
/* /*
* fs/cifs/cifsfs.c * fs/cifs/cifsfs.c
* *
* Copyright (C) International Business Machines Corp., 2002,2007 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* Common Internet FileSystem (CIFS) client * Common Internet FileSystem (CIFS) client
...@@ -353,9 +353,41 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -353,9 +353,41 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
!(cifs_sb->tcon->unix_ext)) !(cifs_sb->tcon->unix_ext))
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
if (!cifs_sb->tcon->unix_ext) {
seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
cifs_sb->mnt_file_mode,
cifs_sb->mnt_dir_mode);
}
if (cifs_sb->tcon->seal)
seq_printf(s, ",seal");
if (cifs_sb->tcon->nocase)
seq_printf(s, ",nocase");
if (cifs_sb->tcon->retry)
seq_printf(s, ",hard");
} }
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths"); seq_printf(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
seq_printf(s, ",setuids");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
seq_printf(s, ",serverino");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
seq_printf(s, ",directio");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
seq_printf(s, ",nouser_xattr");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
seq_printf(s, ",mapchars");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
seq_printf(s, ",sfu");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
seq_printf(s, ",nobrl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
seq_printf(s, ",cifsacl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
seq_printf(s, ",dynperm");
if (m->mnt_sb->s_flags & MS_POSIXACL)
seq_printf(s, ",acl");
seq_printf(s, ",rsize=%d", cifs_sb->rsize); seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize); seq_printf(s, ",wsize=%d", cifs_sb->wsize);
} }
...@@ -657,7 +689,7 @@ const struct file_operations cifs_file_ops = { ...@@ -657,7 +689,7 @@ const struct file_operations cifs_file_ops = {
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
.llseek = cifs_llseek, .llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl, .unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
...@@ -677,7 +709,7 @@ const struct file_operations cifs_file_direct_ops = { ...@@ -677,7 +709,7 @@ const struct file_operations cifs_file_direct_ops = {
.flush = cifs_flush, .flush = cifs_flush,
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl, .unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
.llseek = cifs_llseek, .llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
...@@ -697,7 +729,7 @@ const struct file_operations cifs_file_nobrl_ops = { ...@@ -697,7 +729,7 @@ const struct file_operations cifs_file_nobrl_ops = {
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
.llseek = cifs_llseek, .llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl, .unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
...@@ -716,7 +748,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { ...@@ -716,7 +748,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
.flush = cifs_flush, .flush = cifs_flush,
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl, .unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
.llseek = cifs_llseek, .llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
...@@ -731,7 +763,7 @@ const struct file_operations cifs_dir_ops = { ...@@ -731,7 +763,7 @@ const struct file_operations cifs_dir_ops = {
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify, .dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */ #endif /* CONFIG_CIFS_EXPERIMENTAL */
.ioctl = cifs_ioctl, .unlocked_ioctl = cifs_ioctl,
}; };
static void static void
......
...@@ -95,8 +95,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *, ...@@ -95,8 +95,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
size_t, int); size_t, int);
extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern int cifs_ioctl(struct inode *inode, struct file *filep, extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
unsigned int command, unsigned long arg);
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
extern const struct export_operations cifs_export_ops; extern const struct export_operations cifs_export_ops;
......
...@@ -281,6 +281,7 @@ struct cifsTconInfo { ...@@ -281,6 +281,7 @@ struct cifsTconInfo {
bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
bool retry:1; bool retry:1;
bool nocase:1; bool nocase:1;
bool seal:1; /* transport encryption for this mounted share */
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
for this mount even if server would support */ for this mount even if server would support */
/* BB add field for back pointer to sb struct(s)? */ /* BB add field for back pointer to sb struct(s)? */
......
...@@ -1904,19 +1904,26 @@ typedef struct smb_com_transaction2_get_dfs_refer_req { ...@@ -1904,19 +1904,26 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
char RequestFileName[1]; char RequestFileName[1];
} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ; } __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
#define DFS_VERSION cpu_to_le16(0x0003)
/* DFS server target type */
#define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */
#define DFS_TYPE_ROOT 0x0001
/* Referral Entry Flags */
#define DFS_NAME_LIST_REF 0x0200
typedef struct dfs_referral_level_3 { typedef struct dfs_referral_level_3 {
__le16 VersionNumber; __le16 VersionNumber;
__le16 ReferralSize; __le16 Size;
__le16 ServerType; /* 0x0001 = CIFS server */ __le16 ServerType; /* 0x0001 = root targets; 0x0000 = link targets */
__le16 ReferralFlags; /* or proximity - not clear which since it is __le16 ReferralEntryFlags; /* 0x0200 bit set only for domain
always set to zero - SNIA spec says 0x01 or DC referral responce */
means strip off PathConsumed chars before __le32 TimeToLive;
submitting RequestFileName to remote node */
__le16 TimeToLive;
__le16 Proximity;
__le16 DfsPathOffset; __le16 DfsPathOffset;
__le16 DfsAlternatePathOffset; __le16 DfsAlternatePathOffset;
__le16 NetworkAddressOffset; __le16 NetworkAddressOffset; /* offset of the link target */
__le16 ServiceSiteGuid;
} __attribute__((packed)) REFERRAL3; } __attribute__((packed)) REFERRAL3;
typedef struct smb_com_transaction_get_dfs_refer_rsp { typedef struct smb_com_transaction_get_dfs_refer_rsp {
......
...@@ -93,7 +93,7 @@ extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); ...@@ -93,7 +93,7 @@ extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
extern int cifs_get_inode_info(struct inode **pinode, extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
FILE_ALL_INFO * pfile_info, FILE_ALL_INFO *pfile_info,
struct super_block *sb, int xid, const __u16 *pfid); struct super_block *sb, int xid, const __u16 *pfid);
extern int cifs_get_inode_info_unix(struct inode **pinode, extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
...@@ -130,7 +130,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, ...@@ -130,7 +130,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO * findData, FILE_ALL_INFO *findData,
int legacy /* whether to use old info level */, int legacy /* whether to use old info level */,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
...@@ -141,18 +141,15 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, ...@@ -141,18 +141,15 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBUnixQPathInfo(const int xid, extern int CIFSSMBUnixQPathInfo(const int xid,
struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_UNIX_BASIC_INFO * pFindData, FILE_UNIX_BASIC_INFO *pFindData,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
const unsigned char *searchName, const unsigned char *searchName,
unsigned char **targetUNCs, struct dfs_info3_param **target_nodes,
unsigned int *number_of_UNC_in_array, unsigned int *number_of_nodes_in_array,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path,
const struct nls_table *nls_codepage, int remap);
extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path, const char *old_path,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
......
This diff is collapsed.
...@@ -60,7 +60,7 @@ struct smb_vol { ...@@ -60,7 +60,7 @@ struct smb_vol {
char *domainname; char *domainname;
char *UNC; char *UNC;
char *UNCip; char *UNCip;
char *in6_addr; /* ipv6 address as human readable form of in6_addr */ char *in6_addr; /* ipv6 address as human readable form of in6_addr */
char *iocharset; /* local code page for mapping to and from Unicode */ char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[16]; /* netbios name of client */ char source_rfc1001_name[16]; /* netbios name of client */
char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
...@@ -75,19 +75,21 @@ struct smb_vol { ...@@ -75,19 +75,21 @@ struct smb_vol {
bool setuids:1; bool setuids:1;
bool override_uid:1; bool override_uid:1;
bool override_gid:1; bool override_gid:1;
bool dynperm:1;
bool noperm:1; bool noperm:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */ bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1; bool cifs_acl:1;
bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
bool server_ino:1; /* use inode numbers from server ie UniqueId */ bool server_ino:1; /* use inode numbers from server ie UniqueId */
bool direct_io:1; bool direct_io:1;
bool remap:1; /* set to remap seven reserved chars in filenames */ bool remap:1; /* set to remap seven reserved chars in filenames */
bool posix_paths:1; /* unset to not ask for posix pathnames. */ bool posix_paths:1; /* unset to not ask for posix pathnames. */
bool no_linux_ext:1; bool no_linux_ext:1;
bool sfu_emul:1; bool sfu_emul:1;
bool nullauth:1; /* attempt to authenticate with null user */ bool nullauth:1; /* attempt to authenticate with null user */
unsigned nocase; /* request case insensitive filenames */ bool nocase:1; /* request case insensitive filenames */
unsigned nobrl; /* disable sending byte range locks to srv */ bool nobrl:1; /* disable sending byte range locks to srv */
bool seal:1; /* request transport encryption on share */
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
unsigned int sockopt; unsigned int sockopt;
...@@ -1246,6 +1248,10 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1246,6 +1248,10 @@ cifs_parse_mount_options(char *options, const char *devname,
vol->setuids = 1; vol->setuids = 1;
} else if (strnicmp(data, "nosetuids", 9) == 0) { } else if (strnicmp(data, "nosetuids", 9) == 0) {
vol->setuids = 0; vol->setuids = 0;
} else if (strnicmp(data, "dynperm", 7) == 0) {
vol->dynperm = true;
} else if (strnicmp(data, "nodynperm", 9) == 0) {
vol->dynperm = false;
} else if (strnicmp(data, "nohard", 6) == 0) { } else if (strnicmp(data, "nohard", 6) == 0) {
vol->retry = 0; vol->retry = 0;
} else if (strnicmp(data, "nosoft", 6) == 0) { } else if (strnicmp(data, "nosoft", 6) == 0) {
...@@ -1268,8 +1274,12 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1268,8 +1274,12 @@ cifs_parse_mount_options(char *options, const char *devname,
vol->no_psx_acl = 1; vol->no_psx_acl = 1;
} else if (strnicmp(data, "sign", 4) == 0) { } else if (strnicmp(data, "sign", 4) == 0) {
vol->secFlg |= CIFSSEC_MUST_SIGN; vol->secFlg |= CIFSSEC_MUST_SIGN;
/* } else if (strnicmp(data, "seal",4) == 0) { } else if (strnicmp(data, "seal", 4) == 0) {
vol->secFlg |= CIFSSEC_MUST_SEAL; */ /* we do not do the following in secFlags because seal
is a per tree connection (mount) not a per socket
or per-smb connection option in the protocol */
/* vol->secFlg |= CIFSSEC_MUST_SEAL; */
vol->seal = 1;
} else if (strnicmp(data, "direct", 6) == 0) { } else if (strnicmp(data, "direct", 6) == 0) {
vol->direct_io = 1; vol->direct_io = 1;
} else if (strnicmp(data, "forcedirectio", 13) == 0) { } else if (strnicmp(data, "forcedirectio", 13) == 0) {
...@@ -1413,27 +1423,6 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) ...@@ -1413,27 +1423,6 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
return NULL; return NULL;
} }
int
connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path, const struct nls_table *nls_codepage,
int remap)
{
struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals;
int rc = 0;
rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
&num_referrals, &referrals, remap);
/* 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 */
kfree(referrals);
return rc;
}
int int
get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
const struct nls_table *nls_codepage, unsigned int *pnum_referrals, const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
...@@ -1441,7 +1430,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, ...@@ -1441,7 +1430,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
{ {
char *temp_unc; char *temp_unc;
int rc = 0; int rc = 0;
unsigned char *targetUNCs;
*pnum_referrals = 0; *pnum_referrals = 0;
*preferrals = NULL; *preferrals = NULL;
...@@ -1464,7 +1452,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, ...@@ -1464,7 +1452,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
kfree(temp_unc); kfree(temp_unc);
} }
if (rc == 0) if (rc == 0)
rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
pnum_referrals, nls_codepage, remap); pnum_referrals, nls_codepage, remap);
/* BB map targetUNCs to dfs_info3 structures, here or /* BB map targetUNCs to dfs_info3 structures, here or
in CIFSGetDFSRefer BB */ in CIFSGetDFSRefer BB */
...@@ -1815,7 +1803,7 @@ convert_delimiter(char *path, char delim) ...@@ -1815,7 +1803,7 @@ convert_delimiter(char *path, char delim)
if (path == NULL) if (path == NULL)
return; return;
if (delim == '/') if (delim == '/')
old_delim = '\\'; old_delim = '\\';
else else
old_delim = '/'; old_delim = '/';
...@@ -2125,6 +2113,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2125,6 +2113,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
if (volume_info.override_gid) if (volume_info.override_gid)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
if (volume_info.dynperm)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
if (volume_info.direct_io) { if (volume_info.direct_io) {
cFYI(1, ("mounting share using direct i/o")); cFYI(1, ("mounting share using direct i/o"));
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
...@@ -2141,6 +2131,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2141,6 +2131,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
for the retry flag is used */ for the retry flag is used */
tcon->retry = volume_info.retry; tcon->retry = volume_info.retry;
tcon->nocase = volume_info.nocase; tcon->nocase = volume_info.nocase;
if (tcon->seal != volume_info.seal)
cERROR(1, ("transport encryption setting "
"conflicts with existing tid"));
} else { } else {
tcon = tconInfoAlloc(); tcon = tconInfoAlloc();
if (tcon == NULL) if (tcon == NULL)
...@@ -2154,10 +2147,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2154,10 +2147,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if ((strchr(volume_info.UNC + 3, '\\') == NULL) if ((strchr(volume_info.UNC + 3, '\\') == NULL)
&& (strchr(volume_info.UNC + 3, '/') == && (strchr(volume_info.UNC + 3, '/') ==
NULL)) { NULL)) {
rc = connect_to_dfs_path(xid, pSesInfo, /* rc = connect_to_dfs_path(xid, pSesInfo,
"", cifs_sb->local_nls, "", cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);*/
cFYI(1, ("DFS root not supported"));
rc = -ENODEV; rc = -ENODEV;
goto out; goto out;
} else { } else {
...@@ -2173,6 +2167,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2173,6 +2167,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
atomic_inc(&pSesInfo->inUse); atomic_inc(&pSesInfo->inUse);
tcon->retry = volume_info.retry; tcon->retry = volume_info.retry;
tcon->nocase = volume_info.nocase; tcon->nocase = volume_info.nocase;
tcon->seal = volume_info.seal;
} }
} }
} }
...@@ -2314,9 +2309,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2314,9 +2309,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
user = ses->userName; user = ses->userName;
domain = ses->domainName; domain = ses->domainName;
smb_buffer = cifs_buf_get(); smb_buffer = cifs_buf_get();
if (smb_buffer == NULL) {
if (smb_buffer == NULL)
return -ENOMEM; return -ENOMEM;
}
smb_buffer_response = smb_buffer; smb_buffer_response = smb_buffer;
pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer; pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
......
...@@ -49,18 +49,25 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -49,18 +49,25 @@ build_path_from_dentry(struct dentry *direntry)
struct dentry *temp; struct dentry *temp;
int namelen; int namelen;
int pplen; int pplen;
int dfsplen;
char *full_path; char *full_path;
char dirsep; char dirsep;
struct cifs_sb_info *cifs_sb;
if (direntry == NULL) if (direntry == NULL)
return NULL; /* not much we can do if dentry is freed and return NULL; /* not much we can do if dentry is freed and
we need to reopen the file after it was closed implicitly we need to reopen the file after it was closed implicitly
when the server crashed */ when the server crashed */
dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); cifs_sb = CIFS_SB(direntry->d_sb);
pplen = CIFS_SB(direntry->d_sb)->prepathlen; dirsep = CIFS_DIR_SEP(cifs_sb);
pplen = cifs_sb->prepathlen;
if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
cifs_bp_rename_retry: cifs_bp_rename_retry:
namelen = pplen; namelen = pplen + dfsplen;
for (temp = direntry; !IS_ROOT(temp);) { for (temp = direntry; !IS_ROOT(temp);) {
namelen += (1 + temp->d_name.len); namelen += (1 + temp->d_name.len);
temp = temp->d_parent; temp = temp->d_parent;
...@@ -91,7 +98,7 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -91,7 +98,7 @@ build_path_from_dentry(struct dentry *direntry)
return NULL; return NULL;
} }
} }
if (namelen != pplen) { if (namelen != pplen + dfsplen) {
cERROR(1, cERROR(1,
("did not end path lookup where expected namelen is %d", ("did not end path lookup where expected namelen is %d",
namelen)); namelen));
...@@ -107,7 +114,18 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -107,7 +114,18 @@ build_path_from_dentry(struct dentry *direntry)
since the '\' is a valid posix character so we can not switch since the '\' is a valid posix character so we can not switch
those safely to '/' if any are found in the middle of the prepath */ those safely to '/' if any are found in the middle of the prepath */
/* BB test paths to Windows with '/' in the midst of prepath */ /* BB test paths to Windows with '/' in the midst of prepath */
strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen);
if (dfsplen) {
strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
int i;
for (i = 0; i < dfsplen; i++) {
if (full_path[i] == '\\')
full_path[i] = '/';
}
}
}
strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
return full_path; return full_path;
} }
...@@ -590,7 +608,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, ...@@ -590,7 +608,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
* case take precedence. If a is not a negative dentry, this * case take precedence. If a is not a negative dentry, this
* should have no side effects * should have no side effects
*/ */
memcpy(a->name, b->name, a->len); memcpy((void *)a->name, b->name, a->len);
return 0; return 0;
} }
return 1; return 1;
......
...@@ -134,10 +134,6 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -134,10 +134,6 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
rkey = request_key(&key_type_dns_resolver, name, ""); rkey = request_key(&key_type_dns_resolver, name, "");
if (!IS_ERR(rkey)) { if (!IS_ERR(rkey)) {
data = rkey->payload.data; data = rkey->payload.data;
cFYI(1, ("%s: resolved: %s to %s", __func__,
rkey->description,
*ip_addr
));
} else { } else {
cERROR(1, ("%s: unable to resolve: %s", __func__, name)); cERROR(1, ("%s: unable to resolve: %s", __func__, name));
goto out; goto out;
...@@ -150,6 +146,11 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -150,6 +146,11 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
if (*ip_addr) { if (*ip_addr) {
memcpy(*ip_addr, data, len); memcpy(*ip_addr, data, len);
(*ip_addr)[len] = '\0'; (*ip_addr)[len] = '\0';
if (!IS_ERR(rkey))
cFYI(1, ("%s: resolved: %s to %s", __func__,
name,
*ip_addr
));
rc = 0; rc = 0;
} else { } else {
rc = -ENOMEM; rc = -ENOMEM;
......
...@@ -75,7 +75,11 @@ static inline int cifs_convert_flags(unsigned int flags) ...@@ -75,7 +75,11 @@ static inline int cifs_convert_flags(unsigned int flags)
return (GENERIC_READ | GENERIC_WRITE); return (GENERIC_READ | GENERIC_WRITE);
} }
return 0x20197; return (READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA |
FILE_READ_DATA);
} }
static inline int cifs_get_disposition(unsigned int flags) static inline int cifs_get_disposition(unsigned int flags)
......
This diff is collapsed.
...@@ -30,9 +30,9 @@ ...@@ -30,9 +30,9 @@
#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
int cifs_ioctl(struct inode *inode, struct file *filep, long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
unsigned int command, unsigned long arg)
{ {
struct inode *inode = filep->f_dentry->d_inode;
int rc = -ENOTTY; /* strange error - but the precedent */ int rc = -ENOTTY; /* strange error - but the precedent */
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
......
...@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) ...@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
char *full_path = NULL; char *full_path = NULL;
char *tmp_path = NULL;
char *tmpbuffer; char *tmpbuffer;
int len; int len;
__u16 fid; __u16 fid;
...@@ -295,45 +294,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) ...@@ -295,45 +294,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
cFYI(1, ("Error closing junction point " cFYI(1, ("Error closing junction point "
"(open for ioctl)")); "(open for ioctl)"));
} }
/* BB unwind this long, nested function, or remove BB */ /* If it is a DFS junction earlier we would have gotten
if (rc == -EIO) { PATH_NOT_COVERED returned from server so we do
/* Query if DFS Junction */ not need to request the DFS info here */
unsigned int num_referrals = 0;
struct dfs_info3_param *refs = NULL;
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, &refs,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
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 (refs && refs->path_name) {
strncpy(tmpbuffer,
refs->path_name,
len-1);
}
}
kfree(refs);
kfree(tmp_path);
}
/* 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 Anything else to do to handle recursive links? */
......
...@@ -141,11 +141,11 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst) ...@@ -141,11 +141,11 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
int ret = 0; int ret = 0;
/* calculate length by finding first slash or NULL */ /* calculate length by finding first slash or NULL */
if (address_family == AF_INET) { if (address_family == AF_INET)
ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
} else if (address_family == AF_INET6) { else if (address_family == AF_INET6)
ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
}
cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); cFYI(DBG2, ("address conversion returned %d for %s", ret, cp));
if (ret > 0) if (ret > 0)
ret = 1; ret = 1;
......
...@@ -64,7 +64,7 @@ typedef struct _SECURITY_BUFFER { ...@@ -64,7 +64,7 @@ typedef struct _SECURITY_BUFFER {
} __attribute__((packed)) SECURITY_BUFFER; } __attribute__((packed)) SECURITY_BUFFER;
typedef struct _NEGOTIATE_MESSAGE { typedef struct _NEGOTIATE_MESSAGE {
__u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
__le32 MessageType; /* 1 */ __le32 MessageType; /* 1 */
__le32 NegotiateFlags; __le32 NegotiateFlags;
SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */ SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
...@@ -74,7 +74,7 @@ typedef struct _NEGOTIATE_MESSAGE { ...@@ -74,7 +74,7 @@ typedef struct _NEGOTIATE_MESSAGE {
} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; } __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
typedef struct _CHALLENGE_MESSAGE { typedef struct _CHALLENGE_MESSAGE {
__u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
__le32 MessageType; /* 2 */ __le32 MessageType; /* 2 */
SECURITY_BUFFER TargetName; SECURITY_BUFFER TargetName;
__le32 NegotiateFlags; __le32 NegotiateFlags;
......
...@@ -670,8 +670,11 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, ...@@ -670,8 +670,11 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
(index_to_find < first_entry_in_buffer)) { (index_to_find < first_entry_in_buffer)) {
/* close and restart search */ /* close and restart search */
cFYI(1, ("search backing up - close and restart search")); cFYI(1, ("search backing up - close and restart search"));
cifsFile->invalidHandle = true; if (!cifsFile->srch_inf.endOfSearch &&
CIFSFindClose(xid, pTcon, cifsFile->netfid); !cifsFile->invalidHandle) {
cifsFile->invalidHandle = true;
CIFSFindClose(xid, pTcon, cifsFile->netfid);
}
kfree(cifsFile->search_resume_name); kfree(cifsFile->search_resume_name);
cifsFile->search_resume_name = NULL; cifsFile->search_resume_name = NULL;
if (cifsFile->srch_inf.ntwrk_buf_start) { if (cifsFile->srch_inf.ntwrk_buf_start) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment