dll: fuse: FSP_FUSE_CAP_DELETE_ACCESS

This commit is contained in:
Bill Zissimopoulos 2021-10-26 13:21:57 +01:00
parent 73359d682b
commit 52dd6f7478
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
4 changed files with 62 additions and 30 deletions

View File

@ -79,7 +79,7 @@ struct fuse_operations
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
/* S */ void *(*init)(struct fuse_conn_info *conn);
/* S */ void (*destroy)(void *data);
/* _ */ int (*access)(const char *path, int mask);
/* S */ int (*access)(const char *path, int mask);
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);

View File

@ -54,6 +54,7 @@ extern "C" {
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
#define FSP_FUSE_CAP_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
#define FUSE_IOCTL_COMPAT (1 << 0)
@ -79,6 +80,9 @@ extern "C" {
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
#endif
/* delete access */
#define FSP_FUSE_DELETE_OK 0x40000000
/* notify extension */
#define FSP_FUSE_NOTIFY_MKDIR 0x0001
#define FSP_FUSE_NOTIFY_RMDIR 0x0002

View File

@ -991,6 +991,19 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
int err;
NTSTATUS Result;
if (0 != (CreateOptions & FILE_DELETE_ON_CLOSE) &&
0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
{
err = f->ops.access(contexthdr->PosixPath, FSP_FUSE_DELETE_OK);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
{
if (STATUS_ACCESS_DENIED == Result)
Result = STATUS_CANNOT_DELETE;
goto exit;
}
}
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, 0,
&Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result))
@ -1583,22 +1596,37 @@ static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
static NTSTATUS fsp_fuse_intf_Delete(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, PWSTR FileName, ULONG Flags)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
int err;
NTSTATUS Result;
switch (Flags)
{
case FILE_DISPOSITION_DO_NOT_DELETE:
return STATUS_SUCCESS;
case FILE_DISPOSITION_DELETE:
return fsp_fuse_intf_CanDelete(FileSystem, FileDesc, FileName);
Result = STATUS_SUCCESS;
if (0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
{
err = f->ops.access(filedesc->PosixPath, FSP_FUSE_DELETE_OK);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (STATUS_INVALID_DEVICE_REQUEST == Result)
Result = STATUS_SUCCESS;
}
if (NT_SUCCESS(Result))
Result = fsp_fuse_intf_CanDelete(FileSystem, FileDesc, FileName);
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
if (STATUS_ACCESS_DENIED == Result)
Result = STATUS_CANNOT_DELETE;
return Result;
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
case -1:
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
int err;
NTSTATUS Result = STATUS_SUCCESS;
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
{
if (0 != f->ops.rmdir)
@ -1625,7 +1653,6 @@ static NTSTATUS fsp_fuse_intf_Delete(FSP_FILE_SYSTEM *FileSystem,
Result = STATUS_CANNOT_DELETE;
return Result;
}
default:
return STATUS_INVALID_PARAMETER;

View File

@ -88,6 +88,7 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f)
FSP_FUSE_CAP_READDIR_PLUS |
FSP_FUSE_CAP_READ_ONLY |
FSP_FUSE_CAP_STAT_EX |
FSP_FUSE_CAP_DELETE_ACCESS |
FSP_FUSE_CAP_CASE_INSENSITIVE;
if (0 != f->ops.init)
{