summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2013-08-21 12:20:48 -0700
committerJeremy Allison <jra@samba.org>2013-08-26 20:19:46 +0200
commitd1593a20f3a5ebf287477dfa8f5ab31dca3dd0c3 (patch)
tree9161ed5dac1d1adf8117d5357a7a732d68a1631f
parentf1ff97fc022adaacaa23b7da250be6f7d51c6ac7 (diff)
downloadsamba-d1593a20f3a5ebf287477dfa8f5ab31dca3dd0c3.tar.gz
samba-d1593a20f3a5ebf287477dfa8f5ab31dca3dd0c3.tar.bz2
samba-d1593a20f3a5ebf287477dfa8f5ab31dca3dd0c3.zip
Fix the UNIX extensions CHOWN calls to use FCHOWN if available, else LCHOWN.
UNIX extensions calls must never deref links. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Simo Sorce <idra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Mon Aug 26 20:19:46 CEST 2013 on sn-devel-104
-rw-r--r--source3/smbd/trans2.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 3cd21926b1..b6cb3cc349 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7155,12 +7155,15 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
(unsigned int)set_owner,
smb_fname_str_dbg(smb_fname)));
- if (S_ISLNK(sbuf.st_ex_mode)) {
+ if (fsp && fsp->fh->fd != -1) {
+ ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+ } else {
+ /*
+ * UNIX extensions calls must always operate
+ * on symlinks.
+ */
ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
set_owner, (gid_t)-1);
- } else {
- ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
- set_owner, (gid_t)-1);
}
if (ret != 0) {
@@ -7178,12 +7181,23 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
(sbuf.st_ex_gid != set_grp)) {
+ int ret;
+
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
"changing group %u for file %s\n",
(unsigned int)set_owner,
smb_fname_str_dbg(smb_fname)));
- if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
- set_grp) != 0) {
+ if (fsp && fsp->fh->fd != -1) {
+ ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+ } else {
+ /*
+ * UNIX extensions calls must always operate
+ * on symlinks.
+ */
+ ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, (uid_t)-1,
+ set_grp);
+ }
+ if (ret != 0) {
status = map_nt_error_from_unix(errno);
if (delete_on_fail) {
SMB_VFS_UNLINK(conn, smb_fname);