diff options
Diffstat (limited to 'source4/ntvfs/posix/pvfs_setfileinfo.c')
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 31db6ce630..10eb082183 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -27,6 +27,38 @@ /* + determine what access bits are needed for a call +*/ +static uint32_t pvfs_setfileinfo_access(enum smb_setfileinfo_level level) +{ + uint32_t needed; + + switch (level) { + case RAW_SFILEINFO_EA_SET: + needed = SEC_FILE_WRITE_EA; + break; + + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + needed = SEC_STD_DELETE; + break; + + case RAW_SFILEINFO_END_OF_FILE_INFO: + needed = SEC_FILE_WRITE_DATA; + break; + + case RAW_SFILEINFO_POSITION_INFORMATION: + needed = 0; + break; + + default: + needed = SEC_FILE_WRITE_ATTRIBUTE; + break; + } + return needed; +} + +/* rename_information level */ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, @@ -100,6 +132,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } } + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (rename(name->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } @@ -202,6 +239,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, uint32_t create_options; struct pvfs_filename newstats; NTSTATUS status; + uint32_t access_needed; f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { @@ -210,6 +248,11 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, h = f->handle; + access_needed = pvfs_setfileinfo_access(info->generic.level); + if (!(f->access_mask & access_needed)) { + return NT_STATUS_ACCESS_DENIED; + } + /* update the file information */ status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); if (!NT_STATUS_IS_OK(status)) { @@ -272,9 +315,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - if (!(f->access_mask & SEC_STD_DELETE)) { - return NT_STATUS_ACCESS_DENIED; - } create_options = h->create_options; if (info->disposition_info.in.delete_on_close) { create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; @@ -389,6 +429,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct pvfs_filename newstats; NTSTATUS status; struct utimbuf unix_times; + uint32_t access_needed; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, @@ -401,6 +442,11 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + access_needed = pvfs_setfileinfo_access(info->generic.level); + status = pvfs_access_check_simple(pvfs, req, name, access_needed); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* we take a copy of the current file stats, then update newstats in each of the elements below. At the end we |