[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Fri Apr 15 14:12:02 MDT 2011
The branch, master has been updated
via e49893c Use handle based xattr set if available.
via 525ccd5 Ensure vfs_chown_fsp() is safe against races.
from e4c4dcf s3-waf: only LIBNMB needs to linked against -lresolv.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit e49893c68ef29f71ac6301f3955a7404e9c6daba
Author: Jeremy Allison <jra at samba.org>
Date: Fri Apr 15 10:49:34 2011 -0700
Use handle based xattr set if available.
Autobuild-User: Jeremy Allison <jra at samba.org>
Autobuild-Date: Fri Apr 15 22:11:12 CEST 2011 on sn-devel-104
commit 525ccd589ede79e97e83699629a1d98538855803
Author: Jeremy Allison <jra at samba.org>
Date: Fri Apr 15 12:21:39 2011 -0700
Ensure vfs_chown_fsp() is safe against races.
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/dosmode.c | 9 +++--
source3/smbd/open.c | 2 +-
source3/smbd/proto.h | 2 +
source3/smbd/vfs.c | 76 ++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 79 insertions(+), 10 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 1ea4c68..a9b6dfe 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -348,8 +348,6 @@ static bool set_ea_dos_attribute(connection_struct *conn,
struct xattr_DOSATTRIB dosattrib;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
- files_struct *fsp = NULL;
- bool ret = false;
if (!lp_store_dos_attributes(SNUM(conn))) {
return False;
@@ -387,6 +385,9 @@ static bool set_ea_dos_attribute(connection_struct *conn,
if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
0) == -1) {
+ bool ret = false;
+ files_struct *fsp = NULL;
+
if((errno != EPERM) && (errno != EACCES)) {
if (errno == ENOSYS
#if defined(ENOTSUP)
@@ -419,9 +420,9 @@ static bool set_ea_dos_attribute(connection_struct *conn,
if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname,
&fsp)))
- return ret;
+ return false;
become_root();
- if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+ if (SMB_VFS_FSETXATTR(fsp,
SAMBA_XATTR_DOS_ATTRIB, blob.data,
blob.length, 0) == 0) {
ret = true;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b7c8540..14e6bf9 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2563,7 +2563,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
Ensure we didn't get symlink raced on opening a directory.
****************************************************************************/
-static bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
+bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
const SMB_STRUCT_STAT *sbuf2)
{
if (sbuf1->st_ex_uid != sbuf2->st_ex_uid ||
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c097202..36eea5e 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -567,6 +567,8 @@ void remove_deferred_open_entry(struct file_id id, uint64_t mid,
NTSTATUS open_file_fchmod(connection_struct *conn,
struct smb_filename *smb_fname,
files_struct **result);
+bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
+ const SMB_STRUCT_STAT *sbuf2);
NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
struct smb_filename *smb_dname);
void msg_file_was_renamed(struct messaging_context *msg,
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index d8c57a6..0438f79 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1455,6 +1455,11 @@ int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
{
int ret;
+ bool as_root = false;
+ const char *path;
+ char *saved_dir = NULL;
+ char *parent_dir = NULL;
+ NTSTATUS status;
if (fsp->fh->fd != -1) {
/* Try fchown. */
@@ -1467,19 +1472,80 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
}
}
- if (fsp->posix_open) {
+ as_root = (geteuid() == 0);
+
+ if (as_root) {
+ /*
+ * We are being asked to chown as root. Make
+ * sure we chdir() into the path to pin it,
+ * and always act using lchown to ensure we
+ * don't deref any symbolic links.
+ */
+ const char *final_component = NULL;
+ struct smb_filename local_fname;
+
+ saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
+ if (!saved_dir) {
+ status = map_nt_error_from_unix(errno);
+ DEBUG(0,("vfs_chown_fsp: failed to get "
+ "current working directory. Error was %s\n",
+ strerror(errno)));
+ return status;
+ }
+
+ if (!parent_dirname(talloc_tos(),
+ fsp->fsp_name->base_name,
+ &parent_dir,
+ &final_component)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* cd into the parent dir to pin it. */
+ ret = SMB_VFS_CHDIR(fsp->conn, parent_dir);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ ZERO_STRUCT(local_fname);
+ local_fname.base_name = CONST_DISCARD(char *,final_component);
+
+ /* Must use lstat here. */
+ ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ /* Ensure it matches the fsp stat. */
+ if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ path = final_component;
+ } else {
+ path = fsp->fsp_name->base_name;
+ }
+
+ if (fsp->posix_open || as_root) {
ret = SMB_VFS_LCHOWN(fsp->conn,
- fsp->fsp_name->base_name,
+ path,
uid, gid);
} else {
ret = SMB_VFS_CHOWN(fsp->conn,
- fsp->fsp_name->base_name,
+ path,
uid, gid);
}
+
if (ret == 0) {
- return NT_STATUS_OK;
+ status = NT_STATUS_OK;
+ } else {
+ status = map_nt_error_from_unix(errno);
+ }
+
+ if (as_root) {
+ vfs_ChDir(fsp->conn,saved_dir);
+ TALLOC_FREE(saved_dir);
+ TALLOC_FREE(parent_dir);
}
- return map_nt_error_from_unix(errno);
+ return status;
}
int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
--
Samba Shared Repository
More information about the samba-cvs
mailing list