From 410762eb5596ab73b49d45fd9635a9204ad7f0b1 Mon Sep 17 00:00:00 2001 From: Albert Louis Rossi Date: Fri, 25 Aug 2023 09:40:11 -0500 Subject: [PATCH] common,gplazma-multimap,dcache-qos: authorize qos transition based on role Motivation: Implement authorization of user-initiated QoS transitions based on roles, as agreed upon. Modification: Create a new base principal, `UidRolePrincipal`, and subclass it with `QoSRolePrincipal` (where the uid is specified) and `QoSPlaceholderRolePrincipal` (where the uid must be derived from the user's `UidPrincipal`). Also add an `AdminRolePrincipal`. Map these new principals to the `multimap` plugin's `MappedPrincipals`. The admin role is specified as `admin:`, the qos role with and without a specified uid as `qos:` and `qos:`, respectively. The code is written to logical-OR these in case it may be useful to specify more than one `qos:` capability. The permissions utility in QoS has been rewritten to do this. The permission check in the `QoSAdjuster` has been removed as it was redundant. Result: It is now possible to authorize users to have QoS transition capabilities based on the `multimap` plugin. Target: master Patch: https://rb.dcache.org/r/14070/ Requires-notes: yes Acked-by: Lea --- .../org/dcache/auth/AbstractUidPrincipal.java | 115 ++++++++++++++++++ .../org/dcache/auth/AdminRolePrincipal.java | 74 +++++++++++ .../auth/QoSPlaceholderRolePrincipal.java | 89 ++++++++++++++ .../org/dcache/auth/QoSRolePrincipal.java | 79 ++++++++++++ .../java/org/dcache/auth/UidPrincipal.java | 49 +------- .../org/dcache/auth/UidRolePrincipal.java | 81 ++++++++++++ .../services/bulk/BulkServiceCommands.java | 5 +- .../adjuster/adjusters/QoSAdjuster.java | 21 ---- .../dcache/qos/util/QoSPermissionUtils.java | 44 ++++++- .../gplazma/plugins/GplazmaMultiMapFile.java | 13 +- 10 files changed, 497 insertions(+), 73 deletions(-) create mode 100644 modules/common/src/main/java/org/dcache/auth/AbstractUidPrincipal.java create mode 100644 modules/common/src/main/java/org/dcache/auth/AdminRolePrincipal.java create mode 100644 modules/common/src/main/java/org/dcache/auth/QoSPlaceholderRolePrincipal.java create mode 100644 modules/common/src/main/java/org/dcache/auth/QoSRolePrincipal.java create mode 100644 modules/common/src/main/java/org/dcache/auth/UidRolePrincipal.java diff --git a/modules/common/src/main/java/org/dcache/auth/AbstractUidPrincipal.java b/modules/common/src/main/java/org/dcache/auth/AbstractUidPrincipal.java new file mode 100644 index 00000000000..33a7279de98 --- /dev/null +++ b/modules/common/src/main/java/org/dcache/auth/AbstractUidPrincipal.java @@ -0,0 +1,115 @@ +/* +COPYRIGHT STATUS: +Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and +software are sponsored by the U.S. Department of Energy under Contract No. +DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide +non-exclusive, royalty-free license to publish or reproduce these documents +and software for U.S. Government purposes. All documents and software +available from this server are protected under the U.S. and Foreign +Copyright Laws, and FNAL reserves all rights. + +Distribution of the software available from this server is free of +charge subject to the user following the terms of the Fermitools +Software Legal Information. + +Redistribution and/or modification of the software shall be accompanied +by the Fermitools Software Legal Information (including the copyright +notice). + +The user is asked to feed back problems, benefits, and/or suggestions +about the software to the Fermilab Software Providers. + +Neither the name of Fermilab, the URA, nor the names of the contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +DISCLAIMER OF LIABILITY (BSD): + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB, +OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Liabilities of the Government: + +This software is provided by URA, independent from its Prime Contract +with the U.S. Department of Energy. URA is acting independently from +the Government and in its own private capacity and is not acting on +behalf of the U.S. Government, nor as its contractor nor its agent. +Correspondingly, it is understood and agreed that the U.S. Government +has no connection to this software and in no manner whatsoever shall +be liable for nor assume any responsibility or obligation for any claim, +cost, or damages arising out of or resulting from the use of the software +available from this server. + +Export Control: + +All documents and software available from this server are subject to U.S. +export control laws. Anyone downloading information from this server is +obligated to secure any necessary Government licenses before exporting +documents or software obtained from this server. + */ +package org.dcache.auth; + +import java.io.Serializable; +import java.security.Principal; + +/* + * Base class for both UidPrincipal and UidRolePrincipal. + */ +abstract class AbstractUidPrincipal implements Principal, Serializable { + + private static final long serialVersionUID = -8815120327854777479L; + + protected final long uid; + + protected AbstractUidPrincipal(long uid) { + if (uid < 0) { + throw new IllegalArgumentException("UID must be non-negative"); + } + this.uid = uid; + } + + protected AbstractUidPrincipal(String uid) { + this(Long.parseLong(uid)); + } + + public long getUid() { + return uid; + } + + @Override + public String getName() { + return String.valueOf(getUid()); + } + + @Override + public int hashCode() { + return (int) getUid(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(this.getClass().equals(other.getClass()))) { + return false; + } + AbstractUidPrincipal otherUid = (AbstractUidPrincipal) other; + return (otherUid.getUid() == getUid()); + } + + @Override + public String toString() { + return getClass().getSimpleName() + '[' + getName() + ']'; + } +} diff --git a/modules/common/src/main/java/org/dcache/auth/AdminRolePrincipal.java b/modules/common/src/main/java/org/dcache/auth/AdminRolePrincipal.java new file mode 100644 index 00000000000..251982a37bc --- /dev/null +++ b/modules/common/src/main/java/org/dcache/auth/AdminRolePrincipal.java @@ -0,0 +1,74 @@ +/* +COPYRIGHT STATUS: +Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and +software are sponsored by the U.S. Department of Energy under Contract No. +DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide +non-exclusive, royalty-free license to publish or reproduce these documents +and software for U.S. Government purposes. All documents and software +available from this server are protected under the U.S. and Foreign +Copyright Laws, and FNAL reserves all rights. + +Distribution of the software available from this server is free of +charge subject to the user following the terms of the Fermitools +Software Legal Information. + +Redistribution and/or modification of the software shall be accompanied +by the Fermitools Software Legal Information (including the copyright +notice). + +The user is asked to feed back problems, benefits, and/or suggestions +about the software to the Fermilab Software Providers. + +Neither the name of Fermilab, the URA, nor the names of the contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +DISCLAIMER OF LIABILITY (BSD): + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB, +OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Liabilities of the Government: + +This software is provided by URA, independent from its Prime Contract +with the U.S. Department of Energy. URA is acting independently from +the Government and in its own private capacity and is not acting on +behalf of the U.S. Government, nor as its contractor nor its agent. +Correspondingly, it is understood and agreed that the U.S. Government +has no connection to this software and in no manner whatsoever shall +be liable for nor assume any responsibility or obligation for any claim, +cost, or damages arising out of or resulting from the use of the software +available from this server. + +Export Control: + +All documents and software available from this server are subject to U.S. +export control laws. Anyone downloading information from this server is +obligated to secure any necessary Government licenses before exporting +documents or software obtained from this server. + */ +package org.dcache.auth; + +/** + * Authorizes the bearer to act as ROOT. + */ +@AuthenticationOutput +@AuthenticationInput +public class AdminRolePrincipal extends UidRolePrincipal { + + private static final long serialVersionUID = 2702995170926235855L; + + public AdminRolePrincipal() { + super(Subjects.getUid(Subjects.ROOT)); + } +} diff --git a/modules/common/src/main/java/org/dcache/auth/QoSPlaceholderRolePrincipal.java b/modules/common/src/main/java/org/dcache/auth/QoSPlaceholderRolePrincipal.java new file mode 100644 index 00000000000..9e20e998d55 --- /dev/null +++ b/modules/common/src/main/java/org/dcache/auth/QoSPlaceholderRolePrincipal.java @@ -0,0 +1,89 @@ +/* +COPYRIGHT STATUS: +Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and +software are sponsored by the U.S. Department of Energy under Contract No. +DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide +non-exclusive, royalty-free license to publish or reproduce these documents +and software for U.S. Government purposes. All documents and software +available from this server are protected under the U.S. and Foreign +Copyright Laws, and FNAL reserves all rights. + +Distribution of the software available from this server is free of +charge subject to the user following the terms of the Fermitools +Software Legal Information. + +Redistribution and/or modification of the software shall be accompanied +by the Fermitools Software Legal Information (including the copyright +notice). + +The user is asked to feed back problems, benefits, and/or suggestions +about the software to the Fermilab Software Providers. + +Neither the name of Fermilab, the URA, nor the names of the contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +DISCLAIMER OF LIABILITY (BSD): + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB, +OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Liabilities of the Government: + +This software is provided by URA, independent from its Prime Contract +with the U.S. Department of Energy. URA is acting independently from +the Government and in its own private capacity and is not acting on +behalf of the U.S. Government, nor as its contractor nor its agent. +Correspondingly, it is understood and agreed that the U.S. Government +has no connection to this software and in no manner whatsoever shall +be liable for nor assume any responsibility or obligation for any claim, +cost, or damages arising out of or resulting from the use of the software +available from this server. + +Export Control: + +All documents and software available from this server are subject to U.S. +export control laws. Anyone downloading information from this server is +obligated to secure any necessary Government licenses before exporting +documents or software obtained from this server. + */ +package org.dcache.auth; + +import java.util.UUID; + +/** + * Authorizes the user to execute QoS transitions on the files belonging to that user. + * The user's uid is not specified in the construction of the principal and must + * be derived from the user's actual Uid principal. The placeholder uid value + * is simply an attempt to give each object a unique random value for hashing purposes + * and should not be called in order to reference an actual uid. + */ +@AuthenticationOutput +@AuthenticationInput +public class QoSPlaceholderRolePrincipal extends UidRolePrincipal { + + private static final long serialVersionUID = 7355594681811638281L; + + private static final long PLACEHOLDER_FOR_USER_UID = Long.MAX_VALUE; + + private final long placeholderUid; + + public QoSPlaceholderRolePrincipal() { + super(PLACEHOLDER_FOR_USER_UID); + placeholderUid = UUID.randomUUID().getLeastSignificantBits(); + } + + public long getUid() { + return placeholderUid; + } +} diff --git a/modules/common/src/main/java/org/dcache/auth/QoSRolePrincipal.java b/modules/common/src/main/java/org/dcache/auth/QoSRolePrincipal.java new file mode 100644 index 00000000000..ace9495dc64 --- /dev/null +++ b/modules/common/src/main/java/org/dcache/auth/QoSRolePrincipal.java @@ -0,0 +1,79 @@ +/* +COPYRIGHT STATUS: +Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and +software are sponsored by the U.S. Department of Energy under Contract No. +DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide +non-exclusive, royalty-free license to publish or reproduce these documents +and software for U.S. Government purposes. All documents and software +available from this server are protected under the U.S. and Foreign +Copyright Laws, and FNAL reserves all rights. + +Distribution of the software available from this server is free of +charge subject to the user following the terms of the Fermitools +Software Legal Information. + +Redistribution and/or modification of the software shall be accompanied +by the Fermitools Software Legal Information (including the copyright +notice). + +The user is asked to feed back problems, benefits, and/or suggestions +about the software to the Fermilab Software Providers. + +Neither the name of Fermilab, the URA, nor the names of the contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +DISCLAIMER OF LIABILITY (BSD): + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB, +OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Liabilities of the Government: + +This software is provided by URA, independent from its Prime Contract +with the U.S. Department of Energy. URA is acting independently from +the Government and in its own private capacity and is not acting on +behalf of the U.S. Government, nor as its contractor nor its agent. +Correspondingly, it is understood and agreed that the U.S. Government +has no connection to this software and in no manner whatsoever shall +be liable for nor assume any responsibility or obligation for any claim, +cost, or damages arising out of or resulting from the use of the software +available from this server. + +Export Control: + +All documents and software available from this server are subject to U.S. +export control laws. Anyone downloading information from this server is +obligated to secure any necessary Government licenses before exporting +documents or software obtained from this server. + */ +package org.dcache.auth; + +/** + * Authorizes the bearer to execute QoS transitions on files whose owner + * is the given uid. + */ +@AuthenticationOutput +@AuthenticationInput +public class QoSRolePrincipal extends UidRolePrincipal { + + private static final long serialVersionUID = 3808303034807479246L; + + public QoSRolePrincipal(Long uid) { + super(uid); + } + + public QoSRolePrincipal(String uid) { + super(uid); + } +} diff --git a/modules/common/src/main/java/org/dcache/auth/UidPrincipal.java b/modules/common/src/main/java/org/dcache/auth/UidPrincipal.java index 95070aeba74..a7e5af7912f 100644 --- a/modules/common/src/main/java/org/dcache/auth/UidPrincipal.java +++ b/modules/common/src/main/java/org/dcache/auth/UidPrincipal.java @@ -1,8 +1,5 @@ package org.dcache.auth; -import java.io.Serializable; -import java.security.Principal; - /** * This Principal represents the UID of a person. In contrast to LoginUidPrincipal, UidPrincipal * represents an identity that the end-user is allowed to adopt. Therefore, it is safe to base @@ -13,51 +10,13 @@ */ @AuthenticationOutput @AuthenticationInput -public class UidPrincipal implements Principal, Serializable { - - private static final long serialVersionUID = 1489893133915358418L; +public class UidPrincipal extends AbstractUidPrincipal { - private final long _uid; + private static final long serialVersionUID = -6614351509379265417L; public UidPrincipal(long uid) { - if (uid < 0) { - throw new IllegalArgumentException("UID must be non-negative"); - } - _uid = uid; - } - - public UidPrincipal(String uid) { - this(Long.parseLong(uid)); + super(uid); } - public long getUid() { - return _uid; - } - - @Override - public String getName() { - return String.valueOf(_uid); - } - - @Override - public int hashCode() { - return (int) _uid; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof UidPrincipal)) { - return false; - } - UidPrincipal otherUid = (UidPrincipal) other; - return (otherUid.getUid() == getUid()); - } - - @Override - public String toString() { - return getClass().getSimpleName() + '[' + getName() + ']'; - } + public UidPrincipal(String uid) { super(uid); } } diff --git a/modules/common/src/main/java/org/dcache/auth/UidRolePrincipal.java b/modules/common/src/main/java/org/dcache/auth/UidRolePrincipal.java new file mode 100644 index 00000000000..8aee84eaa6f --- /dev/null +++ b/modules/common/src/main/java/org/dcache/auth/UidRolePrincipal.java @@ -0,0 +1,81 @@ +/* +COPYRIGHT STATUS: +Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and +software are sponsored by the U.S. Department of Energy under Contract No. +DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide +non-exclusive, royalty-free license to publish or reproduce these documents +and software for U.S. Government purposes. All documents and software +available from this server are protected under the U.S. and Foreign +Copyright Laws, and FNAL reserves all rights. + +Distribution of the software available from this server is free of +charge subject to the user following the terms of the Fermitools +Software Legal Information. + +Redistribution and/or modification of the software shall be accompanied +by the Fermitools Software Legal Information (including the copyright +notice). + +The user is asked to feed back problems, benefits, and/or suggestions +about the software to the Fermilab Software Providers. + +Neither the name of Fermilab, the URA, nor the names of the contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +DISCLAIMER OF LIABILITY (BSD): + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB, +OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Liabilities of the Government: + +This software is provided by URA, independent from its Prime Contract +with the U.S. Department of Energy. URA is acting independently from +the Government and in its own private capacity and is not acting on +behalf of the U.S. Government, nor as its contractor nor its agent. +Correspondingly, it is understood and agreed that the U.S. Government +has no connection to this software and in no manner whatsoever shall +be liable for nor assume any responsibility or obligation for any claim, +cost, or damages arising out of or resulting from the use of the software +available from this server. + +Export Control: + +All documents and software available from this server are subject to U.S. +export control laws. Anyone downloading information from this server is +obligated to secure any necessary Government licenses before exporting +documents or software obtained from this server. + */ +package org.dcache.auth; + +/** + * A Principal which assigns a role-based authorization with respect to a uid. + * While this code replicates the UidPrincipal, it needs to be independent so + * that its presence does not violate the requirement of only one Uid principal + * per user. + */ +@AuthenticationOutput +@AuthenticationInput +abstract class UidRolePrincipal extends AbstractUidPrincipal { + + private static final long serialVersionUID = 3405254609909807921L; + + protected UidRolePrincipal(long uid) { + super(uid); + } + + protected UidRolePrincipal(String uid) { + super(uid); + } +} diff --git a/modules/dcache-bulk/src/main/java/org/dcache/services/bulk/BulkServiceCommands.java b/modules/dcache-bulk/src/main/java/org/dcache/services/bulk/BulkServiceCommands.java index f2cac427a53..73180c97ea8 100644 --- a/modules/dcache-bulk/src/main/java/org/dcache/services/bulk/BulkServiceCommands.java +++ b/modules/dcache-bulk/src/main/java/org/dcache/services/bulk/BulkServiceCommands.java @@ -95,6 +95,7 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javax.security.auth.Subject; +import org.dcache.auth.AdminRolePrincipal; import org.dcache.auth.Subjects; import org.dcache.auth.attributes.Restriction; import org.dcache.auth.attributes.Restrictions; @@ -1101,7 +1102,9 @@ class RequestSubmit implements Callable { @Override public String call() { - Subject subject = Subjects.ROOT; + Subject subject = new Subject(); + Subjects.ROOT.getPrincipals().forEach(subject.getPrincipals()::add); + subject.getPrincipals().add(new AdminRolePrincipal()); Restriction restriction = Restrictions.none(); BulkRequest request = new BulkRequest(); request.setUrlPrefix("ssh://admin"); diff --git a/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/QoSAdjuster.java b/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/QoSAdjuster.java index 42d6b3e8164..53481eb24ae 100644 --- a/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/QoSAdjuster.java +++ b/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/QoSAdjuster.java @@ -59,12 +59,8 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ package org.dcache.qos.services.adjuster.adjusters; -import static org.dcache.qos.util.QoSPermissionUtils.canModifyQos; - import com.google.common.collect.ImmutableList; -import diskCacheV111.util.PermissionDeniedCacheException; import diskCacheV111.util.PnfsId; -import java.util.Optional; import javax.security.auth.Subject; import org.dcache.pool.classic.Cancellable; import org.dcache.pool.repository.StickyRecord; @@ -99,16 +95,6 @@ public void adjustQoS(QoSAdjusterTask task) { attributes = task.getAttributes(); subject = task.getSubject(); - try { - checkPermissions(); - } catch (PermissionDeniedCacheException e) { - /* - * handler is injected by factory build - */ - completionHandler.taskFailed(pnfsId, Optional.empty(), e); - return; - } - /* * Generate the SESSION ID. This is used by the QoS status endpoint * (requirements listener or QoS engine) to exclude location updates @@ -121,11 +107,4 @@ public void adjustQoS(QoSAdjusterTask task) { } protected abstract void runAdjuster(QoSAdjusterTask task); - - private void checkPermissions() throws PermissionDeniedCacheException { - if (!canModifyQos(subject, attributes)) { - throw new PermissionDeniedCacheException(String.format("subject does not have " - + "permission for %s on %s.", action, pnfsId)); - } - } } diff --git a/modules/dcache-qos/src/main/java/org/dcache/qos/util/QoSPermissionUtils.java b/modules/dcache-qos/src/main/java/org/dcache/qos/util/QoSPermissionUtils.java index daa4f19c1ad..6c173a0070e 100644 --- a/modules/dcache-qos/src/main/java/org/dcache/qos/util/QoSPermissionUtils.java +++ b/modules/dcache-qos/src/main/java/org/dcache/qos/util/QoSPermissionUtils.java @@ -59,8 +59,13 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ package org.dcache.qos.util; +import java.security.Principal; +import java.util.Iterator; +import java.util.Set; import javax.security.auth.Subject; - +import org.dcache.auth.AdminRolePrincipal; +import org.dcache.auth.QoSPlaceholderRolePrincipal; +import org.dcache.auth.QoSRolePrincipal; import org.dcache.auth.Subjects; import org.dcache.vehicles.FileAttributes; @@ -68,10 +73,13 @@ public class QoSPermissionUtils { /** * Determines if the user is allowed to modify qos. - * Currently the user must either be the owner of the file or be ROOT. * - * @param subject - * @param attributes + * This is a user-facing check done up front by the engine. Verifications and + * adjustments initiated by the QoS service itself are done as ROOT and + * do not need checking. + * + * @param subject of the message received. + * @param attributes with OWNER defined. */ public static boolean canModifyQos(Subject subject, FileAttributes attributes) { if (subject == null) { @@ -86,7 +94,33 @@ public static boolean canModifyQos(Subject subject, FileAttributes attributes) { */ return false; } - return Subjects.isRoot(subject) || Subjects.getUid(subject) == attributes.getOwner(); + + long owner = attributes.getOwner(); + + Set principals = subject.getPrincipals(); + + for (Iterator i = principals.iterator(); i.hasNext();) { + Principal next = i.next(); + + if (next instanceof AdminRolePrincipal) { + return true; + } + + /* + * This may not be something we have immediate need for, but the OR logic here + * allows for there being multiple specifications of qos permissions + * on different uids. + */ + if (next instanceof QoSPlaceholderRolePrincipal && Subjects.getUid(subject) == owner) { + return true; + } + + if (next instanceof QoSRolePrincipal && ((QoSRolePrincipal) next).getUid() == owner) { + return true; + } + } + + return false; } private QoSPermissionUtils() { diff --git a/modules/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapFile.java b/modules/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapFile.java index 69baf5add3b..cb42ddb5ed6 100644 --- a/modules/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapFile.java +++ b/modules/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapFile.java @@ -3,6 +3,7 @@ import static org.dcache.gplazma.plugins.exceptions.GplazmaParseMapFileException.checkFormat; import com.google.common.base.Splitter; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -21,6 +22,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import javax.security.auth.kerberos.KerberosPrincipal; +import org.dcache.auth.AdminRolePrincipal; import org.dcache.auth.EmailAddressPrincipal; import org.dcache.auth.EntitlementPrincipal; import org.dcache.auth.FQANPrincipal; @@ -30,6 +32,8 @@ import org.dcache.auth.OAuthProviderPrincipal; import org.dcache.auth.OidcSubjectPrincipal; import org.dcache.auth.OpenIdGroupPrincipal; +import org.dcache.auth.QoSPlaceholderRolePrincipal; +import org.dcache.auth.QoSRolePrincipal; import org.dcache.auth.UidPrincipal; import org.dcache.auth.UserNamePrincipal; import org.dcache.gplazma.AuthenticationException; @@ -115,7 +119,9 @@ public PrincipalMatcher buildMatcher(String value) UID("uid", UidPrincipal.class), USER_NAME("username", UserNamePrincipal.class), ENTITLEMENT("entitlement", EntitlementPrincipal.class), - OP("op", OAuthProviderPrincipal.class); + OP("op", OAuthProviderPrincipal.class), + ADMIN_ROLE("admin", AdminRolePrincipal.class), + QOS_ROLE("qos", QoSRolePrincipal.class); private final String label; private final Class groupType; @@ -139,6 +145,11 @@ public Principal buildPrincipal(String value) parts.size() == 2 ? Boolean.parseBoolean(parts.get(1)) : false; return groupType.getConstructor(String.class, Boolean.TYPE) .newInstance(parts.get(0), isPrimary); + } else if (QoSRolePrincipal.class.isAssignableFrom(groupType) + && Strings.emptyToNull(value) == null) { + return QoSPlaceholderRolePrincipal.class.getConstructor().newInstance(); + } else if (AdminRolePrincipal.class.isAssignableFrom(groupType)) { + return AdminRolePrincipal.class.getConstructor().newInstance(); } else { return groupType.getConstructor(String.class).newInstance(value); }