diff --git a/modules/dcache-chimera/src/main/java/org/dcache/chimera/namespace/ChimeraNameSpaceProvider.java b/modules/dcache-chimera/src/main/java/org/dcache/chimera/namespace/ChimeraNameSpaceProvider.java index 49a56a30783..68e892ef3b3 100644 --- a/modules/dcache-chimera/src/main/java/org/dcache/chimera/namespace/ChimeraNameSpaceProvider.java +++ b/modules/dcache-chimera/src/main/java/org/dcache/chimera/namespace/ChimeraNameSpaceProvider.java @@ -369,7 +369,8 @@ public FileAttributes createFile(Subject subject, String path, if (assignAttributes.getDefinedAttributes().isEmpty()) { fileAttributes = getFileAttributes(inode, requestedAttributes); } else { - fileAttributes = setFileAttributes(subject, inode.getPnfsId(), + // skip permission check on create by using ROOT subject. + fileAttributes = setFileAttributes(Subjects.ROOT, inode.getPnfsId(), assignAttributes, requestedAttributes); } diff --git a/modules/dcache-chimera/src/test/java/diskCacheV111/namespace/PnfsManagerTest.java b/modules/dcache-chimera/src/test/java/diskCacheV111/namespace/PnfsManagerTest.java index 872c7107773..c253d0c6ca7 100644 --- a/modules/dcache-chimera/src/test/java/diskCacheV111/namespace/PnfsManagerTest.java +++ b/modules/dcache-chimera/src/test/java/diskCacheV111/namespace/PnfsManagerTest.java @@ -55,6 +55,11 @@ import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; import liquibase.resource.ClassLoaderResourceAccessor; +import org.dcache.acl.ACE; +import org.dcache.acl.enums.AccessMask; +import org.dcache.acl.enums.AceFlags; +import org.dcache.acl.enums.AceType; +import org.dcache.acl.enums.Who; import org.dcache.auth.Subjects; import org.dcache.auth.attributes.Restrictions; import org.dcache.chimera.ChimeraFsException; @@ -66,8 +71,11 @@ import org.dcache.chimera.namespace.ChimeraNameSpaceProvider; import org.dcache.chimera.namespace.ChimeraOsmStorageInfoExtractor; import org.dcache.chimera.posix.Stat; +import org.dcache.namespace.ACLPermissionHandler; +import org.dcache.namespace.ChainedPermissionHandler; import org.dcache.namespace.CreateOption; import org.dcache.namespace.FileAttribute; +import org.dcache.namespace.PermissionHandler; import org.dcache.namespace.PosixPermissionHandler; import org.dcache.util.Checksum; import org.dcache.util.ChecksumType; @@ -775,6 +783,49 @@ public void testNoAtimeUpdateOnGetFileAttributesNegativeGap() throws ChimeraFsEx stat_after.getATime() == stat_before.getATime()); } + @Test + public void testCreateFileWithXattrAndInheritedACLs() throws ChimeraFsException { + + var permissionHandler = new ChainedPermissionHandler( + new ACLPermissionHandler(), + new PosixPermissionHandler() + ); + + _pnfsManager.setPermissionHandler(permissionHandler); + ((ChimeraNameSpaceProvider) _pnfsManager.getNameSpaceProvider()).setPermissionHandler(permissionHandler); + ((ChimeraNameSpaceProvider) _pnfsManager.getNameSpaceProvider()).setAclEnabled(true); + + var rootInode = _fs.path2inode("/"); + FsInode dir = _fs.mkdir(rootInode, "dir", 1, 2, 0755); + + var acl = List.of( + new ACE(AceType.ACCESS_DENIED_ACE_TYPE, + AceFlags.INHERIT_ONLY_ACE.getValue() | AceFlags.FILE_INHERIT_ACE.getValue(), + AccessMask.WRITE_ATTRIBUTES.getValue(), + Who.EVERYONE, -1), + + new ACE(AceType.ACCESS_DENIED_ACE_TYPE, + AceFlags.INHERIT_ONLY_ACE.getValue() | AceFlags.FILE_INHERIT_ACE.getValue(), + AccessMask.WRITE_DATA.getValue(), + Who.EVERYONE, -1) + ); + + _fs.setACL(dir, acl); + + var pnfsCreateEntryMessage = new PnfsCreateEntryMessage("/dir/file1", + FileAttributes.of() + .fileType(REGULAR) + .mode(0600) + .uid(1) + .gid(2) + .xattr("foo", "bar") + .build()); + + pnfsCreateEntryMessage.setSubject(Subjects.of(1, 2, new int[]{1})); + _pnfsManager.createEntry(pnfsCreateEntryMessage); + assertThat(pnfsCreateEntryMessage.getReturnCode(), is(0)); + } + private void assertNotExists(String path) throws ChimeraFsException { try { _fs.path2inode(path);