|
@@ -122,6 +122,8 @@ class FSPermissionChecker {
|
|
* @param subAccess If path is a directory,
|
|
* @param subAccess If path is a directory,
|
|
* it is the access required of the path and all the sub-directories.
|
|
* it is the access required of the path and all the sub-directories.
|
|
* If path is not a directory, there is no effect.
|
|
* If path is not a directory, there is no effect.
|
|
|
|
+ * @param resolveLink whether to resolve the final path component if it is
|
|
|
|
+ * a symlink
|
|
* @throws AccessControlException
|
|
* @throws AccessControlException
|
|
* @throws UnresolvedLinkException
|
|
* @throws UnresolvedLinkException
|
|
*
|
|
*
|
|
@@ -130,7 +132,7 @@ class FSPermissionChecker {
|
|
*/
|
|
*/
|
|
void checkPermission(String path, INodeDirectory root, boolean doCheckOwner,
|
|
void checkPermission(String path, INodeDirectory root, boolean doCheckOwner,
|
|
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
|
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
|
- FsAction subAccess)
|
|
|
|
|
|
+ FsAction subAccess, boolean resolveLink)
|
|
throws AccessControlException, UnresolvedLinkException {
|
|
throws AccessControlException, UnresolvedLinkException {
|
|
if (LOG.isDebugEnabled()) {
|
|
if (LOG.isDebugEnabled()) {
|
|
LOG.debug("ACCESS CHECK: " + this
|
|
LOG.debug("ACCESS CHECK: " + this
|
|
@@ -138,38 +140,39 @@ class FSPermissionChecker {
|
|
+ ", ancestorAccess=" + ancestorAccess
|
|
+ ", ancestorAccess=" + ancestorAccess
|
|
+ ", parentAccess=" + parentAccess
|
|
+ ", parentAccess=" + parentAccess
|
|
+ ", access=" + access
|
|
+ ", access=" + access
|
|
- + ", subAccess=" + subAccess);
|
|
|
|
|
|
+ + ", subAccess=" + subAccess
|
|
|
|
+ + ", resolveLink=" + resolveLink);
|
|
}
|
|
}
|
|
// check if (parentAccess != null) && file exists, then check sb
|
|
// check if (parentAccess != null) && file exists, then check sb
|
|
- // Resolve symlinks, the check is performed on the link target.
|
|
|
|
- final INodesInPath inodesInPath = root.getINodesInPath(path, true);
|
|
|
|
- final Snapshot snapshot = inodesInPath.getPathSnapshot();
|
|
|
|
- final INode[] inodes = inodesInPath.getINodes();
|
|
|
|
- int ancestorIndex = inodes.length - 2;
|
|
|
|
- for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
|
|
|
|
- ancestorIndex--);
|
|
|
|
- checkTraverse(inodes, ancestorIndex, snapshot);
|
|
|
|
|
|
+ // If resolveLink, the check is performed on the link target.
|
|
|
|
+ final INodesInPath inodesInPath = root.getINodesInPath(path, resolveLink);
|
|
|
|
+ final Snapshot snapshot = inodesInPath.getPathSnapshot();
|
|
|
|
+ final INode[] inodes = inodesInPath.getINodes();
|
|
|
|
+ int ancestorIndex = inodes.length - 2;
|
|
|
|
+ for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
|
|
|
|
+ ancestorIndex--);
|
|
|
|
+ checkTraverse(inodes, ancestorIndex, snapshot);
|
|
|
|
|
|
- final INode last = inodes[inodes.length - 1];
|
|
|
|
- if (parentAccess != null && parentAccess.implies(FsAction.WRITE)
|
|
|
|
- && inodes.length > 1 && last != null) {
|
|
|
|
- checkStickyBit(inodes[inodes.length - 2], last, snapshot);
|
|
|
|
- }
|
|
|
|
- if (ancestorAccess != null && inodes.length > 1) {
|
|
|
|
- check(inodes, ancestorIndex, snapshot, ancestorAccess);
|
|
|
|
- }
|
|
|
|
- if (parentAccess != null && inodes.length > 1) {
|
|
|
|
- check(inodes, inodes.length - 2, snapshot, parentAccess);
|
|
|
|
- }
|
|
|
|
- if (access != null) {
|
|
|
|
- check(last, snapshot, access);
|
|
|
|
- }
|
|
|
|
- if (subAccess != null) {
|
|
|
|
- checkSubAccess(last, snapshot, subAccess);
|
|
|
|
- }
|
|
|
|
- if (doCheckOwner) {
|
|
|
|
- checkOwner(last, snapshot);
|
|
|
|
- }
|
|
|
|
|
|
+ final INode last = inodes[inodes.length - 1];
|
|
|
|
+ if (parentAccess != null && parentAccess.implies(FsAction.WRITE)
|
|
|
|
+ && inodes.length > 1 && last != null) {
|
|
|
|
+ checkStickyBit(inodes[inodes.length - 2], last, snapshot);
|
|
|
|
+ }
|
|
|
|
+ if (ancestorAccess != null && inodes.length > 1) {
|
|
|
|
+ check(inodes, ancestorIndex, snapshot, ancestorAccess);
|
|
|
|
+ }
|
|
|
|
+ if (parentAccess != null && inodes.length > 1) {
|
|
|
|
+ check(inodes, inodes.length - 2, snapshot, parentAccess);
|
|
|
|
+ }
|
|
|
|
+ if (access != null) {
|
|
|
|
+ check(last, snapshot, access);
|
|
|
|
+ }
|
|
|
|
+ if (subAccess != null) {
|
|
|
|
+ checkSubAccess(last, snapshot, subAccess);
|
|
|
|
+ }
|
|
|
|
+ if (doCheckOwner) {
|
|
|
|
+ checkOwner(last, snapshot);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/** Guarded by {@link FSNamesystem#readLock()} */
|
|
/** Guarded by {@link FSNamesystem#readLock()} */
|