aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <cifs.adm@hostme.bitkeeper.com>2004-07-18 06:18:24 -0700
committerSteve French <cifs.adm@hostme.bitkeeper.com>2004-07-18 06:18:24 -0700
commitffa50ea5500b7caf47d773e69f1a38b7c5299db1 (patch)
tree1f5894ebdcb1f8aef06ecbd81e37a85941c7f52b /fs
parent1bb0fa189c6ae75cbf440244ae77a8ede9912df1 (diff)
parent69da8a3fbc62f0febefcb17915241606e1fd9284 (diff)
downloadhistory-ffa50ea5500b7caf47d773e69f1a38b7c5299db1.tar.gz
Merge bk://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README28
-rw-r--r--fs/cifs/cifs_fs_sb.h4
-rw-r--r--fs/cifs/cifsfs.c10
-rw-r--r--fs/cifs/connect.c16
-rw-r--r--fs/cifs/dir.c23
-rw-r--r--fs/cifs/inode.c20
7 files changed, 96 insertions, 18 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3f1663754388bd..3ed47af501548b 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,16 @@
+Version 1.21
+------------
+Add new mount parm to control whether mode check (vfs_permission) is done on
+the client. If Unix extensions are enabled and the uids on the client
+and server do not match, client permission checks are meaningless on
+server uids that do not exist on the client (this does not affect the
+normal ACL check which occurs on the server). Fix default uid
+on mknod to match create and mkdir. Add optional mount parm to allow
+override of the default uid behavior (in which the server sets the uid
+and gid of newly created files). Normally for network filesystem mounts
+user want the server to set the uid/gid on newly created files (rather than
+using uid of the client processes you would in a local filesystem).
+
Version 1.20
------------
Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps
diff --git a/fs/cifs/README b/fs/cifs/README
index 59a00eea0b35f3..799530255b283e 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -255,7 +255,33 @@ A partial list of the supported mount options follows:
mount helper will not prompt the user for a password
if guest is specified on the mount options. If no
password is specified a null password will be used.
-
+ perm Client does permission checks (vfs_permission check of uid
+ and gid of the file against the mode and desired operation),
+ Note that this is in addition to the normal ACL check on the
+ target machine done by the server software.
+ Client permission checking is enabled by default.
+ noperm Client does not do permission checks. This can expose
+ files on this mount to access by other users on the local
+ client system. It is typically only needed when the server
+ supports the CIFS Unix Extensions but the UIDs/GIDs on the
+ client and server system do not match closely enough to allow
+ access by the user doing the mount.
+ Note that this does not affect the normal ACL check on the
+ target machine done by the server software (of the server
+ ACL against the user name provided at mount time).
+ setuids If the CIFS Unix extensions are negotiated with the server
+ the client will attempt to set the effective uid and gid of
+ the local process on newly created files, directories, and
+ devices (create, mkdir, mknod).
+ nosetuids The client will not attempt to set the uid and gid on
+ on newly created files, directories, and devices (create,
+ mkdir, mknod) which will result in the server setting the
+ uid and gid to the default (usually the server uid of the
+ usern who mounted the share). Letting the server (rather than
+ the client) set the uid and gid is the default. This
+ parameter has no effect if the CIFS Unix Extensions are not
+ negotiated.
+
The mount.cifs mount helper also accepts a few mount options before -o
including:
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 8007c2e925f5dd..592af83bcb9ca7 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -18,6 +18,9 @@
#ifndef _CIFS_FS_SB_H
#define _CIFS_FS_SB_H
+#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
+#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
+
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
struct list_head nested_tcon_q;
@@ -28,5 +31,6 @@ struct cifs_sb_info {
gid_t mnt_gid;
mode_t mnt_file_mode;
mode_t mnt_dir_mode;
+ int mnt_cifs_flags;
};
#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0170ad6bcd03a7..ad20e058abb196 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -192,15 +192,11 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
{
- struct cifs_sb_info *cifs_sb;
+ struct cifs_sb_info *cifs_sb;
- cifs_sb = CIFS_SB(inode->i_sb);
+ cifs_sb = CIFS_SB(inode->i_sb);
- if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
- /* the server supports the Unix-like mode bits and does its
- own permission checks, and therefore we do not allow the file
- mode to be overriden on these mounts - so do not do perm
- check on client side */
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
return 0;
} else /* file mode might have been restricted at mount time
on the client (above and beyond ACL on servers) for
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5c84f9b869933c..e93f69075c08e2 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -64,6 +64,8 @@ struct smb_vol {
int rw:1;
int retry:1;
int intr:1;
+ int setuids:1;
+ int noperm:1;
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
@@ -740,6 +742,14 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
vol->retry = 1;
} else if (strnicmp(data, "soft", 4) == 0) {
vol->retry = 0;
+ } else if (strnicmp(data, "perm", 4) == 0) {
+ vol->noperm = 0;
+ } else if (strnicmp(data, "noperm", 6) == 0) {
+ vol->noperm = 1;
+ } else if (strnicmp(data, "setuids", 7) == 0) {
+ vol->setuids = 1;
+ } else if (strnicmp(data, "nosetuids", 9) == 0) {
+ vol->setuids = 0;
} else if (strnicmp(data, "nohard", 6) == 0) {
vol->retry = 0;
} else if (strnicmp(data, "nosoft", 6) == 0) {
@@ -1314,6 +1324,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
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));
+
+ if(volume_info.noperm)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
+ if(volume_info.setuids)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+
tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
volume_info.username);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 95d68da2aaff28..91567f61d6ddd9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -243,11 +243,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
then we now have to set the mode if possible */
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
(oplock & CIFS_CREATE_ACTION))
- CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
+ (__u64)current->euid,
+ (__u64)current->egid,
+ 0 /* dev */,
+ cifs_sb->local_nls);
+ } else {
+ CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1,
(__u64)-1,
0 /* dev */,
cifs_sb->local_nls);
+ }
else {
/* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
@@ -348,9 +356,16 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
rc = -ENOMEM;
if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
- rc = CIFSSMBUnixSetPerms(xid, pTcon,
- full_path, mode, current->euid, current->egid,
- device_number, cifs_sb->local_nls);
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
+ mode,(__u64)current->euid,(__u64)current->egid,
+ device_number, cifs_sb->local_nls);
+ } else {
+ rc = CIFSSMBUnixSetPerms(xid, pTcon,
+ full_path, mode, (__u64)-1, (__u64)-1,
+ device_number, cifs_sb->local_nls);
+ }
+
if(!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8434166488b2db..a2965cfd355964 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -480,12 +480,20 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
d_instantiate(direntry, newinode);
if(direntry->d_inode)
direntry->d_inode->i_nlink = 2;
- if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
- CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
- (__u64)-1,
- (__u64)-1,
- 0 /* dev_t */,
- cifs_sb->local_nls);
+ if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
+ (__u64)current->euid,
+ (__u64)current->egid,
+ 0 /* dev_t */,
+ cifs_sb->local_nls);
+ } else {
+ CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
+ (__u64)-1,
+ (__u64)-1,
+ 0 /* dev_t */,
+ cifs_sb->local_nls);
+ }
else { /* BB to be implemented via Windows secrty descriptors*/
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
}