From 4dbea1f298c99736b1e8f77669d10e4ab651da23 Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 5 Feb 2026 08:15:22 +0800 Subject: [PATCH] dll & fuse: Added "AddWriteEaPerm" mount option. --- src/dll/fuse/fuse.c | 3 +++ src/dll/fuse/fuse_intf.c | 39 ++++++++++++++++++++++++++++++++++++++- src/dll/fuse/library.h | 2 ++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index dae28a0f..2f63351a 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -119,6 +119,8 @@ static struct fuse_opt fsp_fuse_core_opts[] = FUSE_OPT_KEY("GroupName=", 'g'), FSP_FUSE_CORE_OPT("--GroupName=", set_gid, 1), FUSE_OPT_KEY("--GroupName=", 'g'), + + FSP_FUSE_CORE_OPT("AddWriteEaAccess", add_write_ea_access, 1), FUSE_OPT_END, }; @@ -902,6 +904,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, f->set_create_dir_umask = opt_data.set_create_dir_umask; f->create_dir_umask = opt_data.create_dir_umask; f->set_uid = opt_data.set_uid; f->uid = opt_data.uid; f->set_gid = opt_data.set_gid; f->gid = opt_data.gid; + f->add_write_ea_access = opt_data.add_write_ea_access; f->rellinks = opt_data.rellinks; f->dothidden = opt_data.dothidden; f->ThreadCount = opt_data.ThreadCount; diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 37acd0fa..73d60ce7 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -545,6 +545,39 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem, return STATUS_SUCCESS; } +static VOID fsp_fuse_intf_AddWriteEaAccess( + PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + BOOL DaclPresent, DaclDefaulted; + PACL Acl; + ACL_SIZE_INFORMATION AclSizeInfo; + PACE_HEADER Ace; + PACCESS_MASK AccessMask; + + if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Acl, &DaclDefaulted)) + return; + if (0 == Acl) + return; + if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation)) + return; + + for (DWORD I = 0; I < AclSizeInfo.AceCount; I++) + { + if (!GetAce(Acl, I, &Ace)) + return; + + if (Ace->AceType == ACCESS_ALLOWED_ACE_TYPE) + AccessMask = &((PACCESS_ALLOWED_ACE)Ace)->Mask; + else if (Ace->AceType == ACCESS_DENIED_ACE_TYPE) + AccessMask = &((PACCESS_DENIED_ACE)Ace)->Mask; + else + continue; + + if (*AccessMask & FILE_WRITE_DATA) + *AccessMask |= FILE_WRITE_EA; + } +} + static NTSTATUS fsp_fuse_intf_GetSecurityEx(FSP_FILE_SYSTEM *FileSystem, const char *PosixPath, struct fuse_file_info *fi, PUINT32 PFileAttributes, @@ -578,8 +611,12 @@ static NTSTATUS fsp_fuse_intf_GetSecurityEx(FSP_FILE_SYSTEM *FileSystem, } *PSecurityDescriptorSize = SecurityDescriptorSize; - if (0 != SecurityDescriptorBuf) + if (0 != SecurityDescriptorBuf) + { memcpy(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); + if (f->add_write_ea_access) + fsp_fuse_intf_AddWriteEaAccess(SecurityDescriptorBuf); + } } if (0 != PFileAttributes) diff --git a/src/dll/fuse/library.h b/src/dll/fuse/library.h index dc981225..d9185188 100644 --- a/src/dll/fuse/library.h +++ b/src/dll/fuse/library.h @@ -55,6 +55,7 @@ struct fuse int set_create_dir_umask, create_dir_umask; int set_uid, uid; int set_gid, gid; + int add_write_ea_access; int rellinks; int dothidden; unsigned ThreadCount; @@ -147,6 +148,7 @@ struct fsp_fuse_core_opt_data set_create_dir_umask, create_dir_umask, set_uid, uid, username_to_uid_result, set_gid, gid, + add_write_ea_access, set_uidmap, set_attr_timeout, attr_timeout, rellinks,