[CIFS] UID/GID override on CIFS mounts to Samba
When CIFS Unix Extensions are negotiated we get the Unix uid and gid owners of the file from the server (on the Unix Query Path Info levels), but if the server's uids don't match the client uid's users were having to disable the Unix Extensions (which turned off features they still wanted). The changeset patch allows users to override uid and/or gid for file/directory owner with a default uid and/or gid specified at mount (as is often done when mounting from Linux cifs client to Windows server). This changeset also displays the uid and gid used by default in /proc/mounts (if applicable). Also cleans up code by adding some of the missing spaces after "if" keywords per-kernel style guidelines (as suggested by Randy Dunlap when he reviewed the patch). Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
@@ -2,7 +2,11 @@ Version 1.49
|
||||
------------
|
||||
IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
|
||||
address after the "ip=" mount option, at least until mount.cifs is fixed to
|
||||
handle DNS host to ipv6 name translation).
|
||||
handle DNS host to ipv6 name translation). Accept override of uid or gid
|
||||
on mount even when Unix Extensions are negotiated (it used to be ignored
|
||||
when Unix Extensions were ignored). This allows users to override the
|
||||
default uid and gid for files when they are certain that the uids or
|
||||
gids on the server do not match those of the client.
|
||||
|
||||
Version 1.48
|
||||
------------
|
||||
|
@@ -257,13 +257,19 @@ A partial list of the supported mount options follows:
|
||||
mount.
|
||||
domain Set the SMB/CIFS workgroup name prepended to the
|
||||
username during CIFS session establishment
|
||||
uid If CIFS Unix extensions are not supported by the server
|
||||
this overrides the default uid for inodes. For mounts to
|
||||
servers which do support the CIFS Unix extensions, such
|
||||
as a properly configured Samba server, the server provides
|
||||
the uid, gid and mode. For servers which do not support
|
||||
the Unix extensions, the default uid (and gid) returned on
|
||||
lookup of existing files is the uid (gid) of the person
|
||||
uid Set the default uid for inodes. For mounts to servers
|
||||
which do support the CIFS Unix extensions, such as a
|
||||
properly configured Samba server, the server provides
|
||||
the uid, gid and mode so this parameter should not be
|
||||
specified unless the server and clients uid and gid
|
||||
numbering differ. If the server and client are in the
|
||||
same domain (e.g. running winbind or nss_ldap) and
|
||||
the server supports the Unix Extensions then the uid
|
||||
and gid can be retrieved from the server (and uid
|
||||
and gid would not have to be specifed on the mount.
|
||||
For servers which do not support the CIFS Unix
|
||||
extensions, the default uid (and gid) returned on lookup
|
||||
of existing files will be the uid (gid) of the person
|
||||
who executed the mount (root, except when mount.cifs
|
||||
is configured setuid for user mounts) unless the "uid="
|
||||
(gid) mount option is specified. For the uid (gid) of newly
|
||||
@@ -281,8 +287,7 @@ A partial list of the supported mount options follows:
|
||||
the client. Note that the mount.cifs helper must be
|
||||
at version 1.10 or higher to support specifying the uid
|
||||
(or gid) in non-numberic form.
|
||||
gid If CIFS Unix extensions are not supported by the server
|
||||
this overrides the default gid for inodes.
|
||||
gid Set the default gid for inodes (similar to above).
|
||||
file_mode If CIFS Unix extensions are not supported by the server
|
||||
this overrides the default mode for file inodes.
|
||||
dir_mode If CIFS Unix extensions are not supported by the server
|
||||
|
@@ -80,7 +80,7 @@ need to add ability to set time to server (utimes command)
|
||||
|
||||
u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)
|
||||
|
||||
v) mount check for unmatched uids - and uid override
|
||||
v) mount check for unmatched uids
|
||||
|
||||
w) Add mount option for Linux extension disable per mount, and partial
|
||||
disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?)
|
||||
|
@@ -24,10 +24,12 @@
|
||||
#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_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 */
|
||||
#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
|
||||
#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
|
||||
|
||||
struct cifs_sb_info {
|
||||
struct cifsTconInfo *tcon; /* primary mount */
|
||||
|
@@ -306,6 +306,14 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
||||
cifs_sb->tcon->ses->domainName);
|
||||
}
|
||||
}
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_printf(s, ",posixpaths");
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
|
||||
!(cifs_sb->tcon->ses->capabilities & CAP_UNIX))
|
||||
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
|
||||
!(cifs_sb->tcon->ses->capabilities & CAP_UNIX))
|
||||
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
|
||||
seq_printf(s, ",rsize=%d",cifs_sb->rsize);
|
||||
seq_printf(s, ",wsize=%d",cifs_sb->wsize);
|
||||
}
|
||||
|
@@ -75,6 +75,8 @@ struct smb_vol {
|
||||
unsigned retry:1;
|
||||
unsigned intr:1;
|
||||
unsigned setuids:1;
|
||||
unsigned override_uid:1;
|
||||
unsigned override_gid:1;
|
||||
unsigned noperm:1;
|
||||
unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
|
||||
unsigned cifs_acl:1;
|
||||
@@ -1042,11 +1044,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
|
||||
if (value && *value) {
|
||||
vol->linux_uid =
|
||||
simple_strtoul(value, &value, 0);
|
||||
vol->override_uid = 1;
|
||||
}
|
||||
} else if (strnicmp(data, "gid", 3) == 0) {
|
||||
if (value && *value) {
|
||||
vol->linux_gid =
|
||||
simple_strtoul(value, &value, 0);
|
||||
vol->override_gid = 1;
|
||||
}
|
||||
} else if (strnicmp(data, "file_mode", 4) == 0) {
|
||||
if (value && *value) {
|
||||
@@ -1989,7 +1993,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
||||
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.override_uid)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
|
||||
if (volume_info.override_gid)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
|
||||
if (volume_info.direct_io) {
|
||||
cFYI(1,("mounting share using direct i/o"));
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
|
||||
|
@@ -139,8 +139,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
|
||||
inode->i_mode |= S_IFREG;
|
||||
cFYI(1,("unknown type %d",type));
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
inode->i_uid = cifs_sb->mnt_uid;
|
||||
else
|
||||
inode->i_uid = le64_to_cpu(findData.Uid);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
inode->i_gid = cifs_sb->mnt_gid;
|
||||
else
|
||||
inode->i_gid = le64_to_cpu(findData.Gid);
|
||||
|
||||
inode->i_nlink = le64_to_cpu(findData.Nlinks);
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
@@ -523,6 +532,8 @@ int cifs_get_inode_info(struct inode **pinode,
|
||||
or retrieve from NTFS stream extended attribute */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
/* fill in uid, gid, mode from server ACL */
|
||||
/* BB FIXME this should also take into account the
|
||||
* default uid specified on mount if present */
|
||||
get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
|
||||
} else if (atomic_read(&cifsInfo->inUse) == 0) {
|
||||
inode->i_uid = cifs_sb->mnt_uid;
|
||||
|
@@ -357,7 +357,13 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
|
||||
cFYI(1,("unknown inode type %d",type));
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
tmp_inode->i_uid = cifs_sb->mnt_uid;
|
||||
else
|
||||
tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
tmp_inode->i_gid = cifs_sb->mnt_gid;
|
||||
else
|
||||
tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
|
||||
tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
|
||||
|
||||
@@ -382,7 +388,6 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
|
||||
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
|
||||
|
Reference in New Issue
Block a user