jdk/src/share/classes/sun/security/acl/AclImpl.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 7970 af1579474d16
child 24969 afa6934dd8e8
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 7970
diff changeset
     2
 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.acl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.Principal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.acl.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * An Access Control List (ACL) is encapsulated by this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * @author      Satish Dharmaraj
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
public class AclImpl extends OwnerImpl implements Acl {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
    // Maintain four tables. one each for positive and negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    // ACLs. One each depending on whether the entity is a group
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    // or principal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    private Hashtable<Principal, AclEntry> allowedUsersTable =
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
    44
                                        new Hashtable<>(23);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    private Hashtable<Principal, AclEntry> allowedGroupsTable =
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
    46
                                        new Hashtable<>(23);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private Hashtable<Principal, AclEntry> deniedUsersTable =
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
    48
                                        new Hashtable<>(23);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private Hashtable<Principal, AclEntry> deniedGroupsTable =
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
    50
                                        new Hashtable<>(23);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    private String aclName = null;
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
    52
    private Vector<Permission> zeroSet = new Vector<>(1,1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * Constructor for creating an empty ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    public AclImpl(Principal owner, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        super(owner);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
            setName(owner, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        } catch (Exception e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     * Sets the name of the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * @param caller the principal who is invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     * @param name the name of the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     * @exception NotOwnerException if the caller principal is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * not on the owners list of the Acl.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    public void setName(Principal caller, String name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
      throws NotOwnerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        if (!isOwner(caller))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            throw new NotOwnerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        aclName = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * Returns the name of the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * @return the name of the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    public String getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        return aclName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * Adds an ACL entry to this ACL. An entry associates a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * group or a principal with a set of permissions. Each
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * user or group can have one positive ACL entry and one
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * negative ACL entry. If there is one of the type (negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * or positive) already in the table, a false value is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * The caller principal must be a part of the owners list of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * the ACL in order to invoke this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * @param caller the principal who is invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * @param entry the ACL entry that must be added to the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * @return true on success, false if the entry is already present.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * @exception NotOwnerException if the caller principal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * is not on the owners list of the Acl.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    public synchronized boolean addEntry(Principal caller, AclEntry entry)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
      throws NotOwnerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        if (!isOwner(caller))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            throw new NotOwnerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        Hashtable<Principal, AclEntry> aclTable = findTable(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        Principal key = entry.getPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        if (aclTable.get(key) != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        aclTable.put(key, entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * Removes an ACL entry from this ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * The caller principal must be a part of the owners list of the ACL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * in order to invoke this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * @param caller the principal who is invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * @param entry the ACL entry that must be removed from the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * @return true on success, false if the entry is not part of the ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * @exception NotOwnerException if the caller principal is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * the owners list of the Acl.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public synchronized boolean removeEntry(Principal caller, AclEntry entry)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
      throws NotOwnerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        if (!isOwner(caller))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            throw new NotOwnerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        Hashtable<Principal, AclEntry> aclTable = findTable(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        Principal key = entry.getPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        AclEntry o = aclTable.remove(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        return (o != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * This method returns the set of allowed permissions for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * specified principal. This set of allowed permissions is calculated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * If there is no entry for a group or a principal an empty permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * set is assumed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * The group positive permission set is the union of all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * the positive permissions of each group that the individual belongs to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * The group negative permission set is the union of all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * the negative permissions of each group that the individual belongs to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * If there is a specific permission that occurs in both
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * the postive permission set and the negative permission set,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * it is removed from both. The group positive and negatoive permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * sets are calculated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * The individial positive permission set and the individual negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * permission set is then calculated. Again abscence of an entry means
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * the empty set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * The set of permissions granted to the principal is then calculated using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * the simple rule: Individual permissions always override the Group permissions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * Specifically, individual negative permission set (specific
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * denial of permissions) overrides the group positive permission set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * And the individual positive permission set override the group negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * permission set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * @param user the principal for which the ACL entry is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * @return The resulting permission set that the principal is allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    public synchronized Enumeration<Permission> getPermissions(Principal user) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        Enumeration<Permission> individualPositive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        Enumeration<Permission> individualNegative;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        Enumeration<Permission> groupPositive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        Enumeration<Permission> groupNegative;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        // canonicalize the sets. That is remove common permissions from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        // positive and negative sets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        groupPositive =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            subtract(getGroupPositive(user), getGroupNegative(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        groupNegative  =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            subtract(getGroupNegative(user), getGroupPositive(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        individualPositive =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            subtract(getIndividualPositive(user), getIndividualNegative(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        individualNegative =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            subtract(getIndividualNegative(user), getIndividualPositive(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        // net positive permissions is individual positive permissions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        // plus (group positive - individual negative).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        Enumeration<Permission> temp1 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            subtract(groupPositive, individualNegative);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        Enumeration<Permission> netPositive =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            union(individualPositive, temp1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        // recalculate the enumeration since we lost it in performing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        // subtraction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        individualPositive =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            subtract(getIndividualPositive(user), getIndividualNegative(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        individualNegative =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            subtract(getIndividualNegative(user), getIndividualPositive(user));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        // net negative permissions is individual negative permissions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        // plus (group negative - individual positive).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        temp1 = subtract(groupNegative, individualPositive);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        Enumeration<Permission> netNegative = union(individualNegative, temp1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        return subtract(netPositive, netNegative);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * This method checks whether or not the specified principal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     * has the required permission. If permission is denied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * permission false is returned, a true value is returned otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * This method does not authenticate the principal. It presumes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * the principal is a valid authenticated principal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * @param principal the name of the authenticated principal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * @param permission the permission that the principal must have.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * @return true of the principal has the permission desired, false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    public boolean checkPermission(Principal principal, Permission permission)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        Enumeration<Permission> permSet = getPermissions(principal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        while (permSet.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            Permission p = permSet.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            if (p.equals(permission))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
              return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * returns an enumeration of the entries in this ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    public synchronized Enumeration<AclEntry> entries() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        return new AclEnumerator(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                                 allowedUsersTable, allowedGroupsTable,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                                 deniedUsersTable, deniedGroupsTable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * return a stringified version of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * ACL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        StringBuffer sb = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        Enumeration<AclEntry> entries = entries();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        while (entries.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            AclEntry entry = entries.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            sb.append(entry.toString().trim());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            sb.append("\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    // Find the table that this entry belongs to. There are 4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    // tables that are maintained. One each for postive and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    // negative ACLs and one each for groups and users.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    // This method figures out which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    // table is the one that this AclEntry belongs to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    private Hashtable<Principal, AclEntry> findTable(AclEntry entry) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        Hashtable<Principal, AclEntry> aclTable = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        Principal p = entry.getPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (p instanceof Group) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            if (entry.isNegative())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                aclTable = deniedGroupsTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                aclTable = allowedGroupsTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            if (entry.isNegative())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                aclTable = deniedUsersTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                aclTable = allowedUsersTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        return aclTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    // returns the set e1 U e2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    private static Enumeration<Permission> union(Enumeration<Permission> e1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                Enumeration<Permission> e2) {
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
   297
        Vector<Permission> v = new Vector<>(20, 20);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        while (e1.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            v.addElement(e1.nextElement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        while (e2.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            Permission o = e2.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            if (!v.contains(o))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                v.addElement(o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        return v.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    // returns the set e1 - e2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    private Enumeration<Permission> subtract(Enumeration<Permission> e1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                Enumeration<Permission> e2) {
7970
af1579474d16 7008728: diamond conversion of basic security, permissions, authentication
smarks
parents: 5506
diff changeset
   316
        Vector<Permission> v = new Vector<>(20, 20);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        while (e1.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            v.addElement(e1.nextElement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        while (e2.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            Permission o = e2.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            if (v.contains(o))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                v.removeElement(o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        return v.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    private Enumeration<Permission> getGroupPositive(Principal user) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        Enumeration<Permission> groupPositive = zeroSet.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        Enumeration<Principal> e = allowedGroupsTable.keys();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        while (e.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            Group g = (Group)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            if (g.isMember(user)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                AclEntry ae = allowedGroupsTable.get(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                groupPositive = union(ae.permissions(), groupPositive);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        return groupPositive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    private Enumeration<Permission> getGroupNegative(Principal user) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        Enumeration<Permission> groupNegative = zeroSet.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        Enumeration<Principal> e = deniedGroupsTable.keys();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        while (e.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            Group g = (Group)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            if (g.isMember(user)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                AclEntry ae = deniedGroupsTable.get(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                groupNegative = union(ae.permissions(), groupNegative);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        return groupNegative;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    private Enumeration<Permission> getIndividualPositive(Principal user) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        Enumeration<Permission> individualPositive = zeroSet.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        AclEntry ae = allowedUsersTable.get(user);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        if (ae != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            individualPositive = ae.permissions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return individualPositive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    private Enumeration<Permission> getIndividualNegative(Principal user) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        Enumeration<Permission> individualNegative = zeroSet.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        AclEntry ae  = deniedUsersTable.get(user);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        if (ae != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            individualNegative = ae.permissions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        return individualNegative;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
final class AclEnumerator implements Enumeration<AclEntry> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    Acl acl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    Enumeration<AclEntry> u1, u2, g1, g2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    AclEnumerator(Acl acl, Hashtable<?,AclEntry> u1, Hashtable<?,AclEntry> g1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                  Hashtable<?,AclEntry> u2, Hashtable<?,AclEntry> g2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        this.acl = acl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        this.u1 = u1.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        this.u2 = u2.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        this.g1 = g1.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        this.g2 = g2.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    public boolean hasMoreElements() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return (u1.hasMoreElements() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                u2.hasMoreElements() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                g1.hasMoreElements() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                g2.hasMoreElements());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    public AclEntry nextElement()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        AclEntry o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        synchronized (acl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            if (u1.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                return u1.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            if (u2.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                return u2.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            if (g1.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                return g1.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            if (g2.hasMoreElements())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                return g2.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        throw new NoSuchElementException("Acl Enumerator");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
}