Commit 849c9caa 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:
  [CIFS] Update readme to reflect forceuid mount parms
  cifs: Read buffer overflow
  cifs: show noforceuid/noforcegid mount options (try #2)
  cifs: reinstate original behavior when uid=/gid= options are specified
  [CIFS] Updates fs/cifs/CHANGES
  cifs: fix error handling in mount-time DFS referral chasing code
parents a33a052f d098564f
Version 1.60
-------------
Fix memory leak in reconnect. Fix oops in DFS mount error path.
Set s_maxbytes to smaller (the max that vfs can handle) so that
sendfile will now work over cifs mounts again. Add noforcegid
and noforceuid mount parameters.
Version 1.59 Version 1.59
------------ ------------
Client uses server inode numbers (which are persistent) rather than Client uses server inode numbers (which are persistent) rather than
......
...@@ -262,11 +262,11 @@ A partial list of the supported mount options follows: ...@@ -262,11 +262,11 @@ A partial list of the supported mount options follows:
mount. mount.
domain Set the SMB/CIFS workgroup name prepended to the domain Set the SMB/CIFS workgroup name prepended to the
username during CIFS session establishment username during CIFS session establishment
forceuid Set the default uid for inodes based on the uid forceuid Set the default uid for inodes to the uid
passed in. For mounts to servers passed in on mount. For mounts to servers
which do support the CIFS Unix extensions, such as a which do support the CIFS Unix extensions, such as a
properly configured Samba server, the server provides properly configured Samba server, the server provides
the uid, gid and mode so this parameter should not be the uid, gid and mode so this parameter should not be
specified unless the server and clients uid and gid specified unless the server and clients uid and gid
numbering differ. If the server and client are in the numbering differ. If the server and client are in the
same domain (e.g. running winbind or nss_ldap) and same domain (e.g. running winbind or nss_ldap) and
...@@ -278,11 +278,7 @@ A partial list of the supported mount options follows: ...@@ -278,11 +278,7 @@ A partial list of the supported mount options follows:
of existing files will be the uid (gid) of the person of existing files will be the uid (gid) of the person
who executed the mount (root, except when mount.cifs who executed the mount (root, except when mount.cifs
is configured setuid for user mounts) unless the "uid=" is configured setuid for user mounts) unless the "uid="
(gid) mount option is specified. For the uid (gid) of newly (gid) mount option is specified. Also note that permission
created files and directories, ie files created since
the last mount of the server share, the expected uid
(gid) is cached as long as the inode remains in
memory on the client. Also note that permission
checks (authorization checks) on accesses to a file occur checks (authorization checks) on accesses to a file occur
at the server, but there are cases in which an administrator at the server, but there are cases in which an administrator
may want to restrict at the client as well. For those may want to restrict at the client as well. For those
...@@ -290,12 +286,15 @@ A partial list of the supported mount options follows: ...@@ -290,12 +286,15 @@ A partial list of the supported mount options follows:
(such as Windows), permissions can also be checked at the (such as Windows), permissions can also be checked at the
client, and a crude form of client side permission checking client, and a crude form of client side permission checking
can be enabled by specifying file_mode and dir_mode on can be enabled by specifying file_mode and dir_mode on
the client. Note that the mount.cifs helper must be the client. (default)
at version 1.10 or higher to support specifying the uid forcegid (similar to above but for the groupid instead of uid) (default)
(or gid) in non-numeric form. noforceuid Fill in file owner information (uid) by requesting it from
forcegid (similar to above but for the groupid instead of uid) the server if possible. With this option, the value given in
the uid= option (on mount) will only be used if the server
can not support returning uids on inodes.
noforcegid (similar to above but for the group owner, gid, instead of uid)
uid Set the default uid for inodes, and indicate to the uid Set the default uid for inodes, and indicate to the
cifs kernel driver which local user mounted . If the server cifs kernel driver which local user mounted. If the server
supports the unix extensions the default uid is supports the unix extensions the default uid is
not used to fill in the owner fields of inodes (files) not used to fill in the owner fields of inodes (files)
unless the "forceuid" parameter is specified. unless the "forceuid" parameter is specified.
......
...@@ -55,7 +55,7 @@ void cifs_dfs_release_automount_timer(void) ...@@ -55,7 +55,7 @@ void cifs_dfs_release_automount_timer(void)
* i.e. strips from UNC trailing path that is not part of share * i.e. strips from UNC trailing path that is not part of share
* name and fixup missing '\' in the begining of DFS node refferal * name and fixup missing '\' in the begining of DFS node refferal
* if neccessary. * if neccessary.
* Returns pointer to share name on success or NULL on error. * Returns pointer to share name on success or ERR_PTR on error.
* Caller is responsible for freeing returned string. * Caller is responsible for freeing returned string.
*/ */
static char *cifs_get_share_name(const char *node_name) static char *cifs_get_share_name(const char *node_name)
...@@ -68,7 +68,7 @@ static char *cifs_get_share_name(const char *node_name) ...@@ -68,7 +68,7 @@ static char *cifs_get_share_name(const char *node_name)
UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */, UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
GFP_KERNEL); GFP_KERNEL);
if (!UNC) if (!UNC)
return NULL; return ERR_PTR(-ENOMEM);
/* get share name and server name */ /* get share name and server name */
if (node_name[1] != '\\') { if (node_name[1] != '\\') {
...@@ -87,7 +87,7 @@ static char *cifs_get_share_name(const char *node_name) ...@@ -87,7 +87,7 @@ static char *cifs_get_share_name(const char *node_name)
cERROR(1, ("%s: no server name end in node name: %s", cERROR(1, ("%s: no server name end in node name: %s",
__func__, node_name)); __func__, node_name));
kfree(UNC); kfree(UNC);
return NULL; return ERR_PTR(-EINVAL);
} }
/* find sharename end */ /* find sharename end */
...@@ -133,6 +133,12 @@ char *cifs_compose_mount_options(const char *sb_mountdata, ...@@ -133,6 +133,12 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
*devname = cifs_get_share_name(ref->node_name); *devname = cifs_get_share_name(ref->node_name);
if (IS_ERR(*devname)) {
rc = PTR_ERR(*devname);
*devname = NULL;
goto compose_mount_options_err;
}
rc = dns_resolve_server_name_to_ip(*devname, &srvIP); rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
if (rc != 0) { if (rc != 0) {
cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d", cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
......
...@@ -44,7 +44,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes, ...@@ -44,7 +44,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
int maxwords = maxbytes / 2; int maxwords = maxbytes / 2;
char tmp[NLS_MAX_CHARSET_SIZE]; char tmp[NLS_MAX_CHARSET_SIZE];
for (i = 0; from[i] && i < maxwords; i++) { for (i = 0; i < maxwords && from[i]; i++) {
charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp, charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
NLS_MAX_CHARSET_SIZE); NLS_MAX_CHARSET_SIZE);
if (charlen > 0) if (charlen > 0)
......
...@@ -376,10 +376,14 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -376,10 +376,14 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
seq_printf(s, ",forceuid"); seq_printf(s, ",forceuid");
else
seq_printf(s, ",noforceuid");
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
seq_printf(s, ",forcegid"); seq_printf(s, ",forcegid");
else
seq_printf(s, ",noforcegid");
cifs_show_address(s, tcon->ses->server); cifs_show_address(s, tcon->ses->server);
......
...@@ -803,6 +803,10 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -803,6 +803,10 @@ cifs_parse_mount_options(char *options, const char *devname,
char *data; char *data;
unsigned int temp_len, i, j; unsigned int temp_len, i, j;
char separator[2]; char separator[2];
short int override_uid = -1;
short int override_gid = -1;
bool uid_specified = false;
bool gid_specified = false;
separator[0] = ','; separator[0] = ',';
separator[1] = 0; separator[1] = 0;
...@@ -1093,18 +1097,20 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1093,18 +1097,20 @@ cifs_parse_mount_options(char *options, const char *devname,
"too long.\n"); "too long.\n");
return 1; return 1;
} }
} else if (strnicmp(data, "uid", 3) == 0) { } else if (!strnicmp(data, "uid", 3) && value && *value) {
if (value && *value) vol->linux_uid = simple_strtoul(value, &value, 0);
vol->linux_uid = uid_specified = true;
simple_strtoul(value, &value, 0); } else if (!strnicmp(data, "forceuid", 8)) {
} else if (strnicmp(data, "forceuid", 8) == 0) { override_uid = 1;
vol->override_uid = 1; } else if (!strnicmp(data, "noforceuid", 10)) {
} else if (strnicmp(data, "gid", 3) == 0) { override_uid = 0;
if (value && *value) } else if (!strnicmp(data, "gid", 3) && value && *value) {
vol->linux_gid = vol->linux_gid = simple_strtoul(value, &value, 0);
simple_strtoul(value, &value, 0); gid_specified = true;
} else if (strnicmp(data, "forcegid", 8) == 0) { } else if (!strnicmp(data, "forcegid", 8)) {
vol->override_gid = 1; override_gid = 1;
} else if (!strnicmp(data, "noforcegid", 10)) {
override_gid = 0;
} else if (strnicmp(data, "file_mode", 4) == 0) { } else if (strnicmp(data, "file_mode", 4) == 0) {
if (value && *value) { if (value && *value) {
vol->file_mode = vol->file_mode =
...@@ -1355,6 +1361,18 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1355,6 +1361,18 @@ cifs_parse_mount_options(char *options, const char *devname,
if (vol->UNCip == NULL) if (vol->UNCip == NULL)
vol->UNCip = &vol->UNC[2]; vol->UNCip = &vol->UNC[2];
if (uid_specified)
vol->override_uid = override_uid;
else if (override_uid == 1)
printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
"specified with no uid= option.\n");
if (gid_specified)
vol->override_gid = override_gid;
else if (override_gid == 1)
printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
"specified with no gid= option.\n");
return 0; return 0;
} }
...@@ -2544,11 +2562,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2544,11 +2562,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (mount_data != mount_data_global) if (mount_data != mount_data_global)
kfree(mount_data); kfree(mount_data);
mount_data = cifs_compose_mount_options( mount_data = cifs_compose_mount_options(
cifs_sb->mountdata, full_path + 1, cifs_sb->mountdata, full_path + 1,
referrals, &fake_devname); referrals, &fake_devname);
kfree(fake_devname);
free_dfs_info_array(referrals, num_referrals); free_dfs_info_array(referrals, num_referrals);
kfree(fake_devname);
kfree(full_path);
if (IS_ERR(mount_data)) {
rc = PTR_ERR(mount_data);
mount_data = NULL;
goto mount_fail_check;
}
if (tcon) if (tcon)
cifs_put_tcon(tcon); cifs_put_tcon(tcon);
...@@ -2556,8 +2583,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2556,8 +2583,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_put_smb_ses(pSesInfo); cifs_put_smb_ses(pSesInfo);
cleanup_volume_info(&volume_info); cleanup_volume_info(&volume_info);
FreeXid(xid);
kfree(full_path);
referral_walks_count++; referral_walks_count++;
goto try_mount_again; goto try_mount_again;
} }
......
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