source: proiecte/HadoopJUnit/hadoop-0.20.1/src/hdfs/org/apache/hadoop/hdfs/server/namenode/PermissionChecker.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 6.2 KB
Line 
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 */
18package org.apache.hadoop.hdfs.server.namenode;
19
20import java.util.*;
21
22import org.apache.commons.logging.Log;
23import org.apache.commons.logging.LogFactory;
24import org.apache.hadoop.fs.permission.*;
25import org.apache.hadoop.ipc.Server;
26import org.apache.hadoop.security.AccessControlException;
27import org.apache.hadoop.security.UserGroupInformation;
28
29/** Perform permission checking in {@link FSNamesystem}. */
30class PermissionChecker {
31  static final Log LOG = LogFactory.getLog(UserGroupInformation.class);
32
33  final String user;
34  private final Set<String> groups = new HashSet<String>();
35  final boolean isSuper;
36
37  PermissionChecker(String fsOwner, String supergroup
38      ) throws AccessControlException{
39    UserGroupInformation ugi = UserGroupInformation.getCurrentUGI();
40    if (LOG.isDebugEnabled()) {
41      LOG.debug("ugi=" + ugi);
42    }
43
44    if (ugi != null) {
45      user = ugi.getUserName();
46      groups.addAll(Arrays.asList(ugi.getGroupNames()));
47      isSuper = user.equals(fsOwner) || groups.contains(supergroup);
48    }
49    else {
50      throw new AccessControlException("ugi = null");
51    }
52  }
53
54  boolean containsGroup(String group) {return groups.contains(group);}
55
56  /**
57   * Check whether current user have permissions to access the path.
58   * Traverse is always checked.
59   *
60   * Parent path means the parent directory for the path.
61   * Ancestor path means the last (the closest) existing ancestor directory
62   * of the path.
63   * Note that if the parent path exists,
64   * then the parent path and the ancestor path are the same.
65   *
66   * For example, suppose the path is "/foo/bar/baz".
67   * No matter baz is a file or a directory,
68   * the parent path is "/foo/bar".
69   * If bar exists, then the ancestor path is also "/foo/bar".
70   * If bar does not exist and foo exists,
71   * then the ancestor path is "/foo".
72   * Further, if both foo and bar do not exist,
73   * then the ancestor path is "/".
74   *
75   * @param doCheckOwner Require user to be the owner of the path?
76   * @param ancestorAccess The access required by the ancestor of the path.
77   * @param parentAccess The access required by the parent of the path.
78   * @param access The access required by the path.
79   * @param subAccess If path is a directory,
80   * it is the access required of the path and all the sub-directories.
81   * If path is not a directory, there is no effect.
82   * @return a PermissionChecker object which caches data for later use.
83   * @throws AccessControlException
84   */
85  void checkPermission(String path, INodeDirectory root, boolean doCheckOwner,
86      FsAction ancestorAccess, FsAction parentAccess, FsAction access,
87      FsAction subAccess) throws AccessControlException {
88    if (LOG.isDebugEnabled()) {
89      LOG.debug("ACCESS CHECK: " + this
90          + ", doCheckOwner=" + doCheckOwner
91          + ", ancestorAccess=" + ancestorAccess
92          + ", parentAccess=" + parentAccess
93          + ", access=" + access
94          + ", subAccess=" + subAccess);
95    }
96
97    synchronized(root) {
98      INode[] inodes = root.getExistingPathINodes(path);
99      int ancestorIndex = inodes.length - 2;
100      for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
101          ancestorIndex--);
102      checkTraverse(inodes, ancestorIndex);
103
104      if (ancestorAccess != null && inodes.length > 1) {
105        check(inodes, ancestorIndex, ancestorAccess);
106      }
107      if (parentAccess != null && inodes.length > 1) {
108        check(inodes, inodes.length - 2, parentAccess);
109      }
110      if (access != null) {
111        check(inodes[inodes.length - 1], access);
112      }
113      if (subAccess != null) {
114        checkSubAccess(inodes[inodes.length - 1], subAccess);
115      }
116      if (doCheckOwner) {
117        checkOwner(inodes[inodes.length - 1]);
118      }
119    }
120  }
121
122  private void checkOwner(INode inode) throws AccessControlException {
123    if (inode != null && user.equals(inode.getUserName())) {
124      return;
125    }
126    throw new AccessControlException("Permission denied");
127  }
128
129  private void checkTraverse(INode[] inodes, int last
130      ) throws AccessControlException {
131    for(int j = 0; j <= last; j++) {
132      check(inodes[j], FsAction.EXECUTE);
133    }
134  }
135
136  private void checkSubAccess(INode inode, FsAction access
137      ) throws AccessControlException {
138    if (inode == null || !inode.isDirectory()) {
139      return;
140    }
141
142    Stack<INodeDirectory> directories = new Stack<INodeDirectory>();
143    for(directories.push((INodeDirectory)inode); !directories.isEmpty(); ) {
144      INodeDirectory d = directories.pop();
145      check(d, access);
146
147      for(INode child : d.getChildren()) {
148        if (child.isDirectory()) {
149          directories.push((INodeDirectory)child);
150        }
151      }
152    }
153  }
154
155  private void check(INode[] inodes, int i, FsAction access
156      ) throws AccessControlException {
157    check(i >= 0? inodes[i]: null, access);
158  }
159
160  private void check(INode inode, FsAction access
161      ) throws AccessControlException {
162    if (inode == null) {
163      return;
164    }
165    FsPermission mode = inode.getFsPermission();
166
167    if (user.equals(inode.getUserName())) { //user class
168      if (mode.getUserAction().implies(access)) { return; }
169    }
170    else if (groups.contains(inode.getGroupName())) { //group class
171      if (mode.getGroupAction().implies(access)) { return; }
172    }
173    else { //other class
174      if (mode.getOtherAction().implies(access)) { return; }
175    }
176    throw new AccessControlException("Permission denied: user=" + user
177        + ", access=" + access + ", inode=" + inode);
178  }
179}
Note: See TracBrowser for help on using the repository browser.