From 055e08e07c4b589dd49ae06eda605e4a92ef8ad8 Mon Sep 17 00:00:00 2001 From: Tigran Mkrtchyan Date: Tue, 30 Sep 2025 15:24:21 +0200 Subject: [PATCH] gplazma: enforce RolePrincipal if Role attribute is set Motivation: some parts of dCache use Subject to identify users role, thus require RolePrincipal, others use solo Role attributes. In case of only Role attribute is set the role enforcement doesn't work. Modification: Update GPlazma to set RolePrincipal if Role attribute is set. Result: More consistent role behaviour. Acked-by: Karen Hoyos Target: master, 11.1, 11.0, 10.2 Require-book: no Require-notes: yes (cherry picked from commit c49820e4418a5e790ce1f1eed41c2431050cda01) Signed-off-by: Tigran Mkrtchyan --- .../main/java/org/dcache/gplazma/GPlazma.java | 10 ++++++++++ .../gplazma/AddHomeRootSessionPlugin.java | 6 ++++++ .../java/org/dcache/gplazma/GPlazmaTests.java | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/modules/gplazma2/src/main/java/org/dcache/gplazma/GPlazma.java b/modules/gplazma2/src/main/java/org/dcache/gplazma/GPlazma.java index d01ede32fe4..05339caccfb 100644 --- a/modules/gplazma2/src/main/java/org/dcache/gplazma/GPlazma.java +++ b/modules/gplazma2/src/main/java/org/dcache/gplazma/GPlazma.java @@ -203,6 +203,16 @@ public LoginReply buildReply(LoginMonitor monitor, Subject originalSubject, Subject subject = new Subject(false, principals, publicCredentials, privateCredentials); + + // REVISIT: some parts of dCache use Subject to identify the users role, thus require RolePrincipal, + // others use solo Role attributes. For now, enforce RolePrincipal if Role attribute is set. + for (Object attribute : attributes) { + if (attribute instanceof org.dcache.auth.attributes.Role) { + String roleName = ((org.dcache.auth.attributes.Role) attribute).getRole(); + subject.getPrincipals().add(new org.dcache.auth.RolePrincipal(roleName)); + } + } + reply.setSubject(subject); reply.setSessionAttributes(attributes); diff --git a/modules/gplazma2/src/test/java/org/dcache/gplazma/AddHomeRootSessionPlugin.java b/modules/gplazma2/src/test/java/org/dcache/gplazma/AddHomeRootSessionPlugin.java index deb98b26296..ca937797d69 100644 --- a/modules/gplazma2/src/test/java/org/dcache/gplazma/AddHomeRootSessionPlugin.java +++ b/modules/gplazma2/src/test/java/org/dcache/gplazma/AddHomeRootSessionPlugin.java @@ -5,10 +5,13 @@ import java.security.Principal; import java.util.Properties; import java.util.Set; + +import org.dcache.auth.DesiredRole; import org.dcache.auth.UserNamePrincipal; import org.dcache.auth.attributes.HomeDirectory; import org.dcache.auth.attributes.Restriction; import org.dcache.auth.attributes.Restrictions; +import org.dcache.auth.attributes.Role; import org.dcache.auth.attributes.RootDirectory; import org.dcache.gplazma.plugins.GPlazmaSessionPlugin; @@ -55,6 +58,9 @@ public void session(Set authorizedPrincipals, if (restriction != null) { attrib.add(restriction); } + authorizedPrincipals.stream().filter(p -> p instanceof DesiredRole) + .map(DesiredRole.class::cast).map(DesiredRole::getName) + .forEach(r -> attrib.add(new Role(r))); return; } } diff --git a/modules/gplazma2/src/test/java/org/dcache/gplazma/GPlazmaTests.java b/modules/gplazma2/src/test/java/org/dcache/gplazma/GPlazmaTests.java index c72d6f9c188..49e8dff291f 100644 --- a/modules/gplazma2/src/test/java/org/dcache/gplazma/GPlazmaTests.java +++ b/modules/gplazma2/src/test/java/org/dcache/gplazma/GPlazmaTests.java @@ -18,7 +18,11 @@ import java.util.Properties; import java.util.Set; import javax.security.auth.Subject; + +import org.dcache.auth.DesiredRole; import org.dcache.auth.GidPrincipal; +import org.dcache.auth.RolePrincipal; +import org.dcache.auth.Subjects; import org.dcache.auth.UidPrincipal; import org.dcache.auth.UserNamePrincipal; import org.dcache.auth.attributes.HomeDirectory; @@ -352,6 +356,20 @@ public void testLoginWithoutAuthentication() throws AuthenticationException { Assert.assertNotNull(result); } + + @Test + public void testRolePropagation() throws AuthenticationException { + Configuration config = newConfiguration( + AUTH_CONFIG_ITEM, + MAPPING_CONFIG_ITEM, + ACCOUNT_CONFIG_ITEM, + SESSION_CONFIG_ITEM); + + _inputSubject.getPrincipals().add(new DesiredRole("qos-user")); + LoginReply result = new GPlazma(newLoadStrategy(config), EMPTY_PROPERTIES).login(_inputSubject); + assertTrue("Missing qos-user role", Subjects.hasRole(result.getSubject(), RolePrincipal.Role.QOS_USER)); + } + private static Configuration newConfiguration(ConfigurationItem... items) { return new Configuration( Arrays.asList(items));