001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hdfs.server.namenode; 019 020import org.apache.commons.lang.StringUtils; 021import org.apache.hadoop.classification.InterfaceAudience; 022import org.apache.hadoop.classification.InterfaceStability; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.fs.permission.FsAction; 025import org.apache.hadoop.hdfs.DFSUtil; 026import org.apache.hadoop.security.AccessControlException; 027import org.apache.hadoop.security.UserGroupInformation; 028 029@InterfaceAudience.Public 030@InterfaceStability.Unstable 031public abstract class INodeAttributeProvider { 032 033 /** 034 * The AccessControlEnforcer allows implementations to override the 035 * default File System permission checking logic enforced on a file system 036 * object 037 */ 038 public interface AccessControlEnforcer { 039 040 /** 041 * Checks permission on a file system object. Has to throw an Exception 042 * if the filesystem object is not accessessible by the calling Ugi. 043 * @param fsOwner Filesystem owner (The Namenode user) 044 * @param supergroup super user geoup 045 * @param callerUgi UserGroupInformation of the caller 046 * @param inodeAttrs Array of INode attributes for each path element in the 047 * the path 048 * @param inodes Array of INodes for each path element in the path 049 * @param pathByNameArr Array of byte arrays of the LocalName 050 * @param snapshotId the snapshotId of the requested path 051 * @param path Path String 052 * @param ancestorIndex Index of ancestor 053 * @param doCheckOwner perform ownership check 054 * @param ancestorAccess The access required by the ancestor of the path. 055 * @param parentAccess The access required by the parent of the path. 056 * @param access The access required by the path. 057 * @param subAccess If path is a directory, It is the access required of 058 * the path and all the sub-directories. If path is not a 059 * directory, there should ideally be no effect. 060 * @param ignoreEmptyDir Ignore permission checking for empty directory? 061 * @throws AccessControlException 062 */ 063 public abstract void checkPermission(String fsOwner, String supergroup, 064 UserGroupInformation callerUgi, INodeAttributes[] inodeAttrs, 065 INode[] inodes, byte[][] pathByNameArr, int snapshotId, String path, 066 int ancestorIndex, boolean doCheckOwner, FsAction ancestorAccess, 067 FsAction parentAccess, FsAction access, FsAction subAccess, 068 boolean ignoreEmptyDir) 069 throws AccessControlException; 070 071 } 072 /** 073 * Initialize the provider. This method is called at NameNode startup 074 * time. 075 */ 076 public abstract void start(); 077 078 /** 079 * Shutdown the provider. This method is called at NameNode shutdown time. 080 */ 081 public abstract void stop(); 082 083 @Deprecated 084 String[] getPathElements(String path) { 085 path = path.trim(); 086 if (path.charAt(0) != Path.SEPARATOR_CHAR) { 087 throw new IllegalArgumentException("It must be an absolute path: " + 088 path); 089 } 090 int numOfElements = StringUtils.countMatches(path, Path.SEPARATOR); 091 if (path.length() > 1 && path.endsWith(Path.SEPARATOR)) { 092 numOfElements--; 093 } 094 String[] pathElements = new String[numOfElements]; 095 int elementIdx = 0; 096 int idx = 0; 097 int found = path.indexOf(Path.SEPARATOR_CHAR, idx); 098 while (found > -1) { 099 if (found > idx) { 100 pathElements[elementIdx++] = path.substring(idx, found); 101 } 102 idx = found + 1; 103 found = path.indexOf(Path.SEPARATOR_CHAR, idx); 104 } 105 if (idx < path.length()) { 106 pathElements[elementIdx] = path.substring(idx); 107 } 108 return pathElements; 109 } 110 111 @Deprecated 112 public INodeAttributes getAttributes(String fullPath, INodeAttributes inode) { 113 return getAttributes(getPathElements(fullPath), inode); 114 } 115 116 public abstract INodeAttributes getAttributes(String[] pathElements, 117 INodeAttributes inode); 118 119 public INodeAttributes getAttributes(byte[][] components, 120 INodeAttributes inode) { 121 String[] elements = new String[components.length]; 122 for (int i = 0; i < elements.length; i++) { 123 elements[i] = DFSUtil.bytes2String(components[i]); 124 } 125 return getAttributes(elements, inode); 126 } 127 128 /** 129 * Can be over-ridden by implementations to provide a custom Access Control 130 * Enforcer that can provide an alternate implementation of the 131 * default permission checking logic. 132 * @param defaultEnforcer The Default AccessControlEnforcer 133 * @return The AccessControlEnforcer to use 134 */ 135 public AccessControlEnforcer getExternalAccessControlEnforcer( 136 AccessControlEnforcer defaultEnforcer) { 137 return defaultEnforcer; 138 } 139}