PermissionChecker.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:6k
源码类别:

网格计算

开发平台:

Java

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