1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.fs.permission;
19 
20 import java.util.Iterator;
21 import java.util.List;
22 
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.classification.InterfaceStability;
25 
26 import com.google.common.collect.Lists;
27 
28 /**
29  * AclUtil contains utility methods for manipulating ACLs.
30  */
31 @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
32 @InterfaceStability.Unstable
33 public final class AclUtil {
34 
35   /**
36    * Given permissions and extended ACL entries, returns the full logical ACL.
37    *
38    * @param perm FsPermission containing permissions
39    * @param entries List<AclEntry> containing extended ACL entries
40    * @return List<AclEntry> containing full logical ACL
41    */
getAclFromPermAndEntries(FsPermission perm, List<AclEntry> entries)42   public static List<AclEntry> getAclFromPermAndEntries(FsPermission perm,
43       List<AclEntry> entries) {
44     List<AclEntry> acl = Lists.newArrayListWithCapacity(entries.size() + 3);
45 
46     // Owner entry implied by owner permission bits.
47     acl.add(new AclEntry.Builder()
48       .setScope(AclEntryScope.ACCESS)
49       .setType(AclEntryType.USER)
50       .setPermission(perm.getUserAction())
51       .build());
52 
53     // All extended access ACL entries.
54     boolean hasAccessAcl = false;
55     Iterator<AclEntry> entryIter = entries.iterator();
56     AclEntry curEntry = null;
57     while (entryIter.hasNext()) {
58       curEntry = entryIter.next();
59       if (curEntry.getScope() == AclEntryScope.DEFAULT) {
60         break;
61       }
62       hasAccessAcl = true;
63       acl.add(curEntry);
64     }
65 
66     // Mask entry implied by group permission bits, or group entry if there is
67     // no access ACL (only default ACL).
68     acl.add(new AclEntry.Builder()
69       .setScope(AclEntryScope.ACCESS)
70       .setType(hasAccessAcl ? AclEntryType.MASK : AclEntryType.GROUP)
71       .setPermission(perm.getGroupAction())
72       .build());
73 
74     // Other entry implied by other bits.
75     acl.add(new AclEntry.Builder()
76       .setScope(AclEntryScope.ACCESS)
77       .setType(AclEntryType.OTHER)
78       .setPermission(perm.getOtherAction())
79       .build());
80 
81     // Default ACL entries.
82     if (curEntry != null && curEntry.getScope() == AclEntryScope.DEFAULT) {
83       acl.add(curEntry);
84       while (entryIter.hasNext()) {
85         acl.add(entryIter.next());
86       }
87     }
88 
89     return acl;
90   }
91 
92   /**
93    * Translates the given permission bits to the equivalent minimal ACL.
94    *
95    * @param perm FsPermission to translate
96    * @return List<AclEntry> containing exactly 3 entries representing the owner,
97    *   group and other permissions
98    */
getMinimalAcl(FsPermission perm)99   public static List<AclEntry> getMinimalAcl(FsPermission perm) {
100     return Lists.newArrayList(
101       new AclEntry.Builder()
102         .setScope(AclEntryScope.ACCESS)
103         .setType(AclEntryType.USER)
104         .setPermission(perm.getUserAction())
105         .build(),
106       new AclEntry.Builder()
107         .setScope(AclEntryScope.ACCESS)
108         .setType(AclEntryType.GROUP)
109         .setPermission(perm.getGroupAction())
110         .build(),
111       new AclEntry.Builder()
112         .setScope(AclEntryScope.ACCESS)
113         .setType(AclEntryType.OTHER)
114         .setPermission(perm.getOtherAction())
115         .build());
116   }
117 
118   /**
119    * Checks if the given entries represent a minimal ACL (contains exactly 3
120    * entries).
121    *
122    * @param entries List<AclEntry> entries to check
123    * @return boolean true if the entries represent a minimal ACL
124    */
isMinimalAcl(List<AclEntry> entries)125   public static boolean isMinimalAcl(List<AclEntry> entries) {
126     return entries.size() == 3;
127   }
128 
129   /**
130    * There is no reason to instantiate this class.
131    */
AclUtil()132   private AclUtil() {
133   }
134 }
135