return NT_STATUS_OK;
}
- status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
+ status = SMB_VFS_GET_NT_ACL(conn, smb_fname,
(SECINFO_OWNER |
SECINFO_GROUP |
SECINFO_DACL), talloc_tos(), &sd);
char *parent_dir = NULL;
struct security_descriptor *parent_sd = NULL;
uint32_t access_granted = 0;
+ struct smb_filename *parent_smb_fname = NULL;
if (!parent_dirname(talloc_tos(),
smb_fname->base_name,
return NT_STATUS_NO_MEMORY;
}
+ parent_smb_fname = synthetic_smb_fname(talloc_tos(),
+ parent_dir,
+ NULL,
+ NULL);
+ if (parent_smb_fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
if (get_current_uid(conn) == (uid_t)0) {
/* I'm sorry sir, I didn't know you were root... */
DEBUG(10,("check_parent_access: root override "
}
status = SMB_VFS_GET_NT_ACL(conn,
- parent_dir,
+ parent_smb_fname,
SECINFO_DACL,
talloc_tos(),
&parent_sd);
}
become_root();
- ret = SMB_VFS_LCHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
- (gid_t)-1);
+ ret = SMB_VFS_LCHOWN(conn,
+ smb_fname_cwd,
+ smb_fname_parent->st.st_ex_uid,
+ (gid_t)-1);
unbecome_root();
if (ret == -1) {
status = map_nt_error_from_unix(errno);
return NT_STATUS_OK;
}
- status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
+ status = SMB_VFS_GET_NT_ACL(conn, smb_fname,
(SECINFO_OWNER |
SECINFO_GROUP |
SECINFO_DACL),
/* Delete streams if create_disposition requires it */
if (!new_file_created && clear_ads(create_disposition) &&
!is_ntfs_stream_smb_fname(smb_fname)) {
- status = delete_all_streams(conn, smb_fname->base_name);
+ status = delete_all_streams(conn, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
fd_close(fsp);
}
if (info != FILE_WAS_OPENED) {
- /* Files should be initially set as archive */
- if (lp_map_archive(SNUM(conn)) ||
+ /* Overwritten files should be initially set as archive */
+ if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
lp_store_dos_attributes(SNUM(conn))) {
if (!posix_open) {
if (file_set_dosmode(conn, smb_fname,
return status;
}
- if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
+ if (SMB_VFS_MKDIR(conn, smb_dname, mode) != 0) {
return map_nt_error_from_unix(errno);
}
*/
if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
(mode & ~smb_dname->st.st_ex_mode)) {
- SMB_VFS_CHMOD(conn, smb_dname->base_name,
+ SMB_VFS_CHMOD(conn, smb_dname,
(smb_dname->st.st_ex_mode |
(mode & ~smb_dname->st.st_ex_mode)));
need_re_stat = true;
return status;
}
- /* Ensure there was no race condition. */
- if (!check_same_stat(&smb_dname->st, &fsp->fsp_name->st)) {
+ if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
+ DEBUG(5,("open_directory: %s is not a directory !\n",
+ smb_fname_str_dbg(smb_dname)));
+ fd_close(fsp);
+ file_free(req, fsp);
+ return NT_STATUS_NOT_A_DIRECTORY;
+ }
+
+ /* Ensure there was no race condition. We need to check
+ * dev/inode but not permissions, as these can change
+ * legitimately */
+ if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
DEBUG(5,("open_directory: stat struct differs for "
"directory %s.\n",
smb_fname_str_dbg(smb_dname)));
* If that works, delete them all by setting the delete on close and close.
*/
-NTSTATUS open_streams_for_delete(connection_struct *conn,
- const char *fname)
+static NTSTATUS open_streams_for_delete(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
struct stream_struct *stream_info = NULL;
files_struct **streams = NULL;
TALLOC_CTX *frame = talloc_stackframe();
NTSTATUS status;
- status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
+ status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
&num_streams, &stream_info);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
}
for (i=0; i<num_streams; i++) {
- struct smb_filename *smb_fname;
+ struct smb_filename *smb_fname_cp;
if (strequal(stream_info[i].name, "::$DATA")) {
streams[i] = NULL;
continue;
}
- smb_fname = synthetic_smb_fname(
- talloc_tos(), fname, stream_info[i].name, NULL);
- if (smb_fname == NULL) {
+ smb_fname_cp = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ stream_info[i].name,
+ NULL);
+ if (smb_fname_cp == NULL) {
status = NT_STATUS_NO_MEMORY;
goto fail;
}
- if (SMB_VFS_STAT(conn, smb_fname) == -1) {
+ if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
DEBUG(10, ("Unable to stat stream: %s\n",
- smb_fname_str_dbg(smb_fname)));
+ smb_fname_str_dbg(smb_fname_cp)));
}
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
- smb_fname, /* fname */
+ smb_fname_cp, /* fname */
DELETE_ACCESS, /* access_mask */
(FILE_SHARE_READ | /* share_access */
FILE_SHARE_WRITE | FILE_SHARE_DELETE),
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("Could not open stream %s: %s\n",
- smb_fname_str_dbg(smb_fname),
+ smb_fname_str_dbg(smb_fname_cp),
nt_errstr(status)));
- TALLOC_FREE(smb_fname);
+ TALLOC_FREE(smb_fname_cp);
break;
}
- TALLOC_FREE(smb_fname);
+ TALLOC_FREE(smb_fname_cp);
}
/*
const struct dom_sid *SY_U_sid = NULL;
const struct dom_sid *SY_G_sid = NULL;
size_t size = 0;
+ struct smb_filename *parent_smb_fname = NULL;
if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
+ parent_smb_fname = synthetic_smb_fname(talloc_tos(),
+ parent_name,
+ NULL,
+ NULL);
+
+ if (parent_smb_fname == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
status = SMB_VFS_GET_NT_ACL(fsp->conn,
- parent_name,
+ parent_smb_fname,
(SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
frame,
&parent_desc);
* We can't open a file with DELETE access if any of the
* streams is open without FILE_SHARE_DELETE
*/
- status = open_streams_for_delete(conn, smb_fname->base_name);
+ status = open_streams_for_delete(conn, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
- if (allocation_size
- && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
+ if ((allocation_size > fsp->fsp_name->st.st_ex_size)
+ && !(fsp->is_directory))
+ {
fsp->initial_allocation_size = smb_roundup(
fsp->conn, allocation_size);
- if (fsp->is_directory) {
- /* Can't set allocation size on a directory. */
- status = NT_STATUS_ACCESS_DENIED;
- goto fail;
- }
if (vfs_allocate_file_space(
fsp, fsp->initial_allocation_size) == -1) {
status = NT_STATUS_DISK_FULL;