From: Ralph Boehme Date: Mon, 14 Dec 2020 10:20:46 +0000 (+0100) Subject: smbd: use pathref fsp in change_dir_owner_to_parent() X-Git-Tag: samba-4.14.0rc1~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24a46b9db9561c49996a2e77320228a7d22de08a;p=thirdparty%2Fsamba.git smbd: use pathref fsp in change_dir_owner_to_parent() Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index fdbcb7c206c..20f39ee2414 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1023,117 +1023,50 @@ static NTSTATUS change_dir_owner_to_parent(connection_struct *conn, struct smb_filename *smb_dname, SMB_STRUCT_STAT *psbuf) { - struct smb_filename *smb_fname_cwd = NULL; - struct smb_filename *saved_dir_fname = NULL; - TALLOC_CTX *ctx = talloc_tos(); - NTSTATUS status = NT_STATUS_OK; int ret; ret = SMB_VFS_STAT(conn, smb_fname_parent); if (ret == -1) { - status = map_nt_error_from_unix(errno); DEBUG(0,("change_dir_owner_to_parent: failed to stat parent " "directory %s. Error was %s\n", smb_fname_str_dbg(smb_fname_parent), strerror(errno))); - goto out; - } - - /* We've already done an lstat into psbuf, and we know it's a - directory. If we can cd into the directory and the dev/ino - are the same then we can safely chown without races as - we're locking the directory in place by being in it. This - should work on any UNIX (thanks tridge :-). JRA. - */ - - saved_dir_fname = vfs_GetWd(ctx,conn); - if (!saved_dir_fname) { - status = map_nt_error_from_unix(errno); - DEBUG(0,("change_dir_owner_to_parent: failed to get " - "current working directory. Error was %s\n", - strerror(errno))); - goto out; - } - - /* Chdir into the new path. */ - if (vfs_ChDir(conn, smb_dname) == -1) { - status = map_nt_error_from_unix(errno); - DEBUG(0,("change_dir_owner_to_parent: failed to change " - "current working directory to %s. Error " - "was %s\n", smb_dname->base_name, strerror(errno) )); - goto chdir; - } - - smb_fname_cwd = synthetic_smb_fname(ctx, - ".", - NULL, - NULL, - smb_dname->twrp, - 0); - if (smb_fname_cwd == NULL) { - status = NT_STATUS_NO_MEMORY; - goto chdir; - } - - ret = SMB_VFS_STAT(conn, smb_fname_cwd); - if (ret == -1) { - status = map_nt_error_from_unix(errno); - DEBUG(0,("change_dir_owner_to_parent: failed to stat " - "directory '.' (%s) Error was %s\n", - smb_dname->base_name, strerror(errno))); - goto chdir; - } - - /* Ensure we're pointing at the same place. */ - if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev || - smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) { - DEBUG(0,("change_dir_owner_to_parent: " - "device/inode on directory %s changed. " - "Refusing to chown !\n", - smb_dname->base_name )); - status = NT_STATUS_ACCESS_DENIED; - goto chdir; + return map_nt_error_from_unix(errno); } - if (smb_fname_parent->st.st_ex_uid == smb_fname_cwd->st.st_ex_uid) { + if (smb_fname_parent->st.st_ex_uid == smb_dname->st.st_ex_uid) { /* Already this uid - no need to change. */ DEBUG(10,("change_dir_owner_to_parent: directory %s " "is already owned by uid %d\n", smb_dname->base_name, - (int)smb_fname_cwd->st.st_ex_uid )); - status = NT_STATUS_OK; - goto chdir; + (int)smb_dname->st.st_ex_uid )); + return NT_STATUS_OK; } become_root(); - ret = SMB_VFS_LCHOWN(conn, - smb_fname_cwd, - smb_fname_parent->st.st_ex_uid, - (gid_t)-1); + ret = SMB_VFS_FCHOWN(smb_dname->fsp, + smb_fname_parent->st.st_ex_uid, + (gid_t)-1); unbecome_root(); if (ret == -1) { - status = map_nt_error_from_unix(errno); DEBUG(10,("change_dir_owner_to_parent: failed to chown " "directory %s to parent directory uid %u. " "Error was %s\n", smb_dname->base_name, (unsigned int)smb_fname_parent->st.st_ex_uid, strerror(errno) )); - } else { - DEBUG(10,("change_dir_owner_to_parent: changed ownership of new " - "directory %s to parent directory uid %u.\n", - smb_dname->base_name, - (unsigned int)smb_fname_parent->st.st_ex_uid )); - /* Ensure the uid entry is updated. */ - psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid; + return map_nt_error_from_unix(errno); } - chdir: - vfs_ChDir(conn, saved_dir_fname); - out: - TALLOC_FREE(saved_dir_fname); - TALLOC_FREE(smb_fname_cwd); - return status; + DBG_DEBUG("changed ownership of new " + "directory %s to parent directory uid %u.\n", + smb_dname->base_name, + (unsigned int)smb_fname_parent->st.st_ex_uid); + + /* Ensure the uid entry is updated. */ + psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid; + + return NT_STATUS_OK; } /****************************************************************************