/* check the acl against the required access mask */
status = se_access_check(sd, token, *access_mask, access_mask);
talloc_free(acl);
+
+ /* if we used a NT acl, then allow access override if the
+ share allows for posix permission override
+ */
+ if (NT_STATUS_IS_OK(status)) {
+ name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
+ }
+
done:
if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
/* on SMB, this bit is always granted, even if not
return status;
}
- return pvfs_access_check_simple(pvfs, req, parent, access_mask);
+ status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
+ if (NT_STATUS_IS_OK(status) && parent->allow_override) {
+ name->allow_override = true;
+ }
+ return status;
}
mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
- if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+ if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
return pvfs_map_errno(pvfs, errno);
}
/* setup an inherited acl from the parent */
status = pvfs_acl_inherit(pvfs, req, name, -1);
if (!NT_STATUS_IS_OK(status)) {
- pvfs_sys_rmdir(pvfs, name->full_name);
+ pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
return status;
}
md->t2mkdir.in.num_eas,
md->t2mkdir.in.eas);
if (!NT_STATUS_IS_OK(status)) {
- pvfs_sys_rmdir(pvfs, name->full_name);
+ pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
return status;
}
mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
- if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+ if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
return pvfs_map_errno(pvfs, errno);
}
/* setup an inherited acl from the parent */
status = pvfs_acl_inherit(pvfs, req, name, -1);
if (!NT_STATUS_IS_OK(status)) {
- pvfs_sys_rmdir(pvfs, name->full_name);
+ pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
return status;
}
return status;
}
- if (pvfs_sys_rmdir(pvfs, name->full_name) == -1) {
+ if (pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override) == -1) {
/* some olders systems don't return ENOTEMPTY to rmdir() */
if (errno == EEXIST) {
return NT_STATUS_DIRECTORY_NOT_EMPTY;
DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
delete_path, nt_errstr(status)));
}
- if (pvfs_sys_rmdir(h->pvfs, delete_path) != 0) {
+ if (pvfs_sys_rmdir(h->pvfs, delete_path, h->name->allow_override) != 0) {
DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n",
delete_path, strerror(errno)));
}
uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY;
mode_t mode = pvfs_fileperms(pvfs, attrib);
- if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+ if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
return pvfs_map_errno(pvfs,errno);
}
return NT_STATUS_OK;
cleanup_delete:
- pvfs_sys_rmdir(pvfs, name->full_name);
+ pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
return status;
}
DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
delete_path, nt_errstr(status)));
}
- if (pvfs_sys_unlink(h->pvfs, delete_path) != 0) {
+ if (pvfs_sys_unlink(h->pvfs, delete_path, h->name->allow_override) != 0) {
DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n",
delete_path, strerror(errno)));
} else {
mode = pvfs_fileperms(pvfs, attrib);
/* create the file */
- fd = pvfs_sys_open(pvfs, name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode);
+ fd = pvfs_sys_open(pvfs, name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode, name->allow_override);
if (fd == -1) {
return pvfs_map_errno(pvfs, errno);
}
cleanup_delete:
close(fd);
- pvfs_sys_unlink(pvfs, name->full_name);
+ pvfs_sys_unlink(pvfs, name->full_name, name->allow_override);
return status;
}
}
/* do the actual open */
- fd = pvfs_sys_open(pvfs, f->handle->name->full_name, flags | O_NONBLOCK, 0);
+ fd = pvfs_sys_open(pvfs, f->handle->name->full_name, flags | O_NONBLOCK, 0, name->allow_override);
if (fd == -1) {
status = pvfs_map_errno(f->pvfs, errno);
mode_t mode = pvfs_fileperms(pvfs, attrib);
if (f->handle->name->st.st_mode != mode &&
f->handle->name->dos.attrib != attrib &&
- pvfs_sys_fchmod(pvfs, fd, mode) == -1) {
+ pvfs_sys_fchmod(pvfs, fd, mode, name->allow_override) == -1) {
talloc_free(lck);
return pvfs_map_errno(pvfs, errno);
}
uint32_t mask;
NTSTATUS status;
- if (pvfs_sys_rename(pvfs, name1->full_name, name2) == -1) {
+ if (pvfs_sys_rename(pvfs, name1->full_name, name2,
+ name1->allow_override) == -1) {
return pvfs_map_errno(pvfs, errno);
}
case RENAME_FLAG_COPY:
status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE);
NT_STATUS_NOT_OK_RETURN(status);
- return pvfs_copy_file(pvfs, name1, name2);
+ return pvfs_copy_file(pvfs, name1, name2, name1->allow_override && name2->allow_override);
case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
DEBUG(3,(__location__ ": Invalid rename cluster for %s\n",
(*name)->exists = false;
(*name)->stream_exists = false;
+ (*name)->allow_override = false;
if (!(pvfs->fs_attribs & FS_ATTR_NAMED_STREAMS)) {
flags &= ~PVFS_RESOLVE_STREAMS;
(*name)->original_name = talloc_strdup(*name, fname);
(*name)->stream_name = NULL;
(*name)->stream_id = 0;
+ (*name)->allow_override = false;
status = pvfs_fill_dos_info(pvfs, *name, flags, -1);
}
(*name)->stream_name = NULL;
(*name)->stream_id = 0;
+ (*name)->allow_override = false;
status = pvfs_fill_dos_info(pvfs, *name, PVFS_RESOLVE_NO_OPENDB, -1);
}
mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
- if (pvfs_sys_fchmod(pvfs, h->fd, mode) == -1) {
+ if (pvfs_sys_fchmod(pvfs, h->fd, mode, h->name->allow_override) == -1) {
return pvfs_map_errno(pvfs, errno);
}
}
newstats.dos.attrib |= (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY);
if (newstats.dos.attrib != name->dos.attrib) {
mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
- if (pvfs_sys_chmod(pvfs, name->full_name, mode) == -1) {
+ if (pvfs_sys_chmod(pvfs, name->full_name, mode, name->allow_override) == -1) {
return pvfs_map_errno(pvfs, errno);
}
change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
/*
wrap open for system override
*/
-int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode_t mode)
+int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode_t mode, bool allow_override)
{
int fd, ret;
struct pvfs_sys_ctx *ctx;
fd = open(filename, flags, mode);
if (fd != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return fd;
}
/*
wrap unlink for system override
*/
-int pvfs_sys_unlink(struct pvfs_state *pvfs, const char *filename)
+int pvfs_sys_unlink(struct pvfs_state *pvfs, const char *filename, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = unlink(filename);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
/*
wrap rename for system override
*/
-int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name2)
+int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name2, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = rename(name1, name2);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
/*
wrap mkdir for system override
*/
-int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode)
+int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = mkdir(dirname, mode);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
/*
wrap rmdir for system override
*/
-int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname)
+int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = rmdir(dirname);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
/*
wrap fchmod for system override
*/
-int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode)
+int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = fchmod(fd, mode);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
/*
wrap chmod for system override
*/
-int pvfs_sys_chmod(struct pvfs_state *pvfs, const char *filename, mode_t mode)
+int pvfs_sys_chmod(struct pvfs_state *pvfs, const char *filename, mode_t mode, bool allow_override)
{
int ret;
struct pvfs_sys_ctx *ctx;
ret = chmod(filename, mode);
if (ret != -1 ||
- !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+ !allow_override ||
errno != EACCES) {
return ret;
}
}
/* finally try the actual unlink */
- if (pvfs_sys_unlink(pvfs, name->full_name) == -1) {
+ if (pvfs_sys_unlink(pvfs, name->full_name, name->allow_override) == -1) {
status = pvfs_map_errno(pvfs, errno);
}
*/
NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
struct pvfs_filename *name1,
- struct pvfs_filename *name2)
+ struct pvfs_filename *name2,
+ bool allow_override)
{
int fd1, fd2;
mode_t mode;
return NT_STATUS_NO_MEMORY;
}
- fd1 = pvfs_sys_open(pvfs, name1->full_name, O_RDONLY, 0);
+ fd1 = pvfs_sys_open(pvfs, name1->full_name, O_RDONLY, 0, allow_override);
if (fd1 == -1) {
talloc_free(buf);
return pvfs_map_errno(pvfs, errno);
}
- fd2 = pvfs_sys_open(pvfs, name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0);
+ fd2 = pvfs_sys_open(pvfs, name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0, allow_override);
if (fd2 == -1) {
close(fd1);
talloc_free(buf);
close(fd1);
close(fd2);
talloc_free(buf);
- pvfs_sys_unlink(pvfs, name2->full_name);
+ pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
if (ret2 == -1) {
return pvfs_map_errno(pvfs, errno);
}
close(fd1);
mode = pvfs_fileperms(pvfs, name1->dos.attrib);
- if (pvfs_sys_fchmod(pvfs, fd2, mode) == -1) {
+ if (pvfs_sys_fchmod(pvfs, fd2, mode, allow_override) == -1) {
status = pvfs_map_errno(pvfs, errno);
close(fd2);
- pvfs_sys_unlink(pvfs, name2->full_name);
+ pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
return status;
}
status = pvfs_dosattrib_save(pvfs, name2, fd2);
if (!NT_STATUS_IS_OK(status)) {
close(fd2);
- pvfs_sys_unlink(pvfs, name2->full_name);
+ pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
return status;
}
bool has_wildcard;
bool exists; /* true if the base filename exists */
bool stream_exists; /* true if the stream exists */
+ bool allow_override;
struct stat st;
struct pvfs_dos_fileinfo dos;
};