Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,13 @@ public String getErasureCodingPolicyName(INode inode) {
void checkPermission(INodeDirectory inode, int snapshotId, FsAction access)
throws AccessControlException {
if (dir != null && dir.isPermissionEnabled()
&& pc != null && !pc.isSuperUser()) {
pc.checkPermission(inode, snapshotId, access);
&& pc != null) {
if (pc.isSuperUser()) {
// call external enforcer for audit
pc.checkSuperuserPrivilege(inode.getFullPathName());
} else {
pc.checkPermission(inode, snapshotId, access);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,25 @@ static FileStatus setOwner(
try {
iip = fsd.resolvePath(pc, src, DirOp.WRITE);
fsd.checkOwner(pc, iip);
if (!pc.isSuperUser()) {
if (username != null && !pc.getUser().equals(username)) {
throw new AccessControlException("User " + pc.getUser()
+ " is not a super user (non-super user cannot change owner).");
}
if (group != null && !pc.isMemberOfGroup(group)) {
throw new AccessControlException(
"User " + pc.getUser() + " does not belong to " + group);
// At this point, the user must be either owner or super user.
// superuser: can change owner to a different user,
// change owner group to any group
// owner: can't change owner to a different user but can change owner
// group to different group that the user belongs to.
if ((username != null && !pc.getUser().equals(username)) ||
(group != null && !pc.isMemberOfGroup(group))) {
try {
// check if the user is superuser
pc.checkSuperuserPrivilege(iip.getPath());
} catch (AccessControlException e) {
if (username != null && !pc.getUser().equals(username)) {
throw new AccessControlException("User " + pc.getUser()
+ " is not a super user (non-super user cannot change owner).");
}
if (group != null && !pc.isMemberOfGroup(group)) {
throw new AccessControlException(
"User " + pc.getUser() + " does not belong to " + group);
}
}
}
changed = unprotectedSetOwner(fsd, iip, username, group);
Expand Down Expand Up @@ -238,10 +249,12 @@ static void setQuota(FSDirectory fsd, FSPermissionChecker pc, String src,
fsd.writeLock();
try {
INodesInPath iip = fsd.resolvePath(pc, src, DirOp.WRITE);
// Here, the assumption is that the caller of this method has
// already checked for super user privilege
if (fsd.isPermissionEnabled() && !pc.isSuperUser() && allowOwner) {
INodeDirectory parentDir= iip.getLastINode().getParent();
if (parentDir == null ||
!parentDir.getUserName().equals(pc.getUser())) {
try {
fsd.checkOwner(pc, iip.getParentINodesInPath());
} catch(AccessControlException ace) {
throw new AccessControlException(
"Access denied for user " + pc.getUser() +
". Superuser or owner of parent folder privilege is required");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ static HdfsFileStatus getFileInfo(FSDirectory fsd, FSPermissionChecker pc,
// superuser to receive null instead.
try {
iip = fsd.resolvePath(pc, srcArg, dirOp);
pc.checkSuperuserPrivilege(iip.getPath());
} catch (AccessControlException ace) {
return null;
}
Expand Down Expand Up @@ -151,12 +152,14 @@ static GetBlockLocationsResult getBlockLocations(
BlockManager bm = fsd.getBlockManager();
fsd.readLock();
try {
final INodesInPath iip = fsd.resolvePath(pc, src, DirOp.READ);
// Just get INodesInPath without access checks, since we check for path
// access later
final INodesInPath iip = fsd.resolvePath(null, src, DirOp.READ);
src = iip.getPath();
final INodeFile inode = INodeFile.valueOf(iip.getLastINode(), src);
if (fsd.isPermissionEnabled()) {
fsd.checkPathAccess(pc, iip, FsAction.READ);
fsd.checkUnreadableBySuperuser(pc, iip);
fsd.checkPathAccess(pc, iip, FsAction.READ);
}

final long fileSize = iip.isSnapshot()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,10 @@ private static void checkXAttrChangeAccess(
if (inode != null &&
inode.isDirectory() &&
inode.getFsPermission().getStickyBit()) {
if (!pc.isSuperUser()) {
if (pc.isSuperUser()) {
// call external enforcer for audit
pc.checkSuperuserPrivilege(iip.getPath());
} else {
fsd.checkOwner(pc, iip);
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,18 +717,18 @@ public INodesInPath resolvePath(FSPermissionChecker pc, String src,

byte[][] components = INode.getPathComponents(src);
boolean isRaw = isReservedRawName(components);
components = resolveComponents(components, this);
INodesInPath iip = INodesInPath.resolve(rootDir, components, isRaw);
if (isPermissionEnabled && pc != null && isRaw) {
switch(dirOp) {
case READ_LINK:
case READ:
break;
default:
pc.checkSuperuserPrivilege();
break;
case READ_LINK:
case READ:
break;
default:
pc.checkSuperuserPrivilege(iip.getPath());
break;
}
}
components = resolveComponents(components, this);
INodesInPath iip = INodesInPath.resolve(rootDir, components, isRaw);
// verify all ancestors are dirs and traversable. note that only
// methods that create new namespace items have the signature to throw
// PNDE
Expand Down Expand Up @@ -1942,7 +1942,10 @@ void checkPermission(FSPermissionChecker pc, INodesInPath iip,
boolean doCheckOwner, FsAction ancestorAccess, FsAction parentAccess,
FsAction access, FsAction subAccess, boolean ignoreEmptyDir)
throws AccessControlException {
if (!pc.isSuperUser()) {
if (pc.isSuperUser()) {
// call the external enforcer for audit
pc.checkSuperuserPrivilege(iip.getPath());
} else {
readLock();
try {
pc.checkPermission(iip, doCheckOwner, ancestorAccess,
Expand All @@ -1958,9 +1961,12 @@ void checkUnreadableBySuperuser(FSPermissionChecker pc, INodesInPath iip)
if (pc.isSuperUser()) {
if (FSDirXAttrOp.getXAttrByPrefixedName(this, iip,
SECURITY_XATTR_UNREADABLE_BY_SUPERUSER) != null) {
throw new AccessControlException(
"Access is denied for " + pc.getUser() + " since the superuser "
+ "is not allowed to perform this operation.");
String errorMessage = "Access is denied for " + pc.getUser()
+ " since the superuser is not allowed to perform this operation.";
pc.denyUserAccess(iip.getPath(), errorMessage);
} else {
// call the external enforcer for audit.
pc.checkSuperuserPrivilege(iip.getPath());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ BatchedListEntries<OpenFileEntry> listOpenFiles(long prevId,
EnumSet<OpenFilesType> openFilesTypes, String path) throws IOException {
INode.checkAbsolutePath(path);
final String operationName = "listOpenFiles";
checkSuperuserPrivilege();
checkSuperuserPrivilege(operationName, path);
checkOperation(OperationCategory.READ);
BatchedListEntries<OpenFileEntry> batchedListEntries;
String normalizedPath = new Path(path).toString(); // normalize path.
Expand Down Expand Up @@ -2289,6 +2289,7 @@ boolean truncate(String src, long newLength, String clientName,
final String operationName = "truncate";
requireEffectiveLayoutVersionForFeature(Feature.TRUNCATE);
FSDirTruncateOp.TruncateResult r = null;
FileStatus status;
try {
NameNode.stateChangeLog.info(
"DIR* NameSystem.truncate: src={} newLength={}", src, newLength);
Expand All @@ -2307,7 +2308,7 @@ boolean truncate(String src, long newLength, String clientName,
r = FSDirTruncateOp.truncate(this, src, newLength, clientName,
clientMachine, mtime, toRemoveBlocks, pc);
} finally {
FileStatus status = r != null ? r.getFileStatus() : null;
status = r != null ? r.getFileStatus() : null;
writeUnlock(operationName,
getLockReportInfoSupplier(src, null, status));
}
Expand All @@ -2316,11 +2317,12 @@ boolean truncate(String src, long newLength, String clientName,
removeBlocks(toRemoveBlocks);
toRemoveBlocks.clear();
}
logAuditEvent(true, operationName, src, null, r.getFileStatus());
logAuditEvent(true, operationName, src, null, status);
} catch (AccessControlException e) {
logAuditEvent(false, operationName, src);
throw e;
}
assert(r != null);
return r.getResult();
}

Expand Down Expand Up @@ -3582,7 +3584,7 @@ void setQuota(String src, long nsQuota, long ssQuota, StorageType type)
FSPermissionChecker.setOperationType(operationName);
try {
if(!allowOwnerSetQuota) {
checkSuperuserPrivilege(pc);
checkSuperuserPrivilege(operationName, src);
}
writeLock();
try {
Expand Down Expand Up @@ -5222,18 +5224,22 @@ PermissionStatus createFsOwnerPermissions(FsPermission permission) {
return new PermissionStatus(fsOwner.getShortUserName(), supergroup, permission);
}

/**
* This method is retained for backward compatibility.
* Please use {@link #checkSuperuserPrivilege(String)} instead.
*
* @throws AccessControlException if user is not a super user.
*/
void checkSuperuserPrivilege() throws AccessControlException {
if (isPermissionEnabled) {
FSPermissionChecker pc = getPermissionChecker();
pc.checkSuperuserPrivilege();
pc.checkSuperuserPrivilege(null);
}
}

void checkSuperuserPrivilege(FSPermissionChecker pc)
throws AccessControlException {
if (isPermissionEnabled) {
pc.checkSuperuserPrivilege();
}
void checkSuperuserPrivilege(String operationName)
throws IOException {
checkSuperuserPrivilege(operationName, null);
}

/**
Expand Down Expand Up @@ -6011,7 +6017,8 @@ public String toString() {
*/
Collection<CorruptFileBlockInfo> listCorruptFileBlocks(String path,
String[] cookieTab) throws IOException {
checkSuperuserPrivilege();
final String operationName = "listCorruptFileBlocks";
checkSuperuserPrivilege(operationName, path);
checkOperation(OperationCategory.READ);

int count = 0;
Expand Down Expand Up @@ -6939,7 +6946,7 @@ public SnapshotManager getSnapshotManager() {
void allowSnapshot(String path) throws IOException {
checkOperation(OperationCategory.WRITE);
final String operationName = "allowSnapshot";
checkSuperuserPrivilege(operationName);
checkSuperuserPrivilege(operationName, path);
writeLock();
try {
checkOperation(OperationCategory.WRITE);
Expand All @@ -6956,7 +6963,7 @@ void allowSnapshot(String path) throws IOException {
void disallowSnapshot(String path) throws IOException {
checkOperation(OperationCategory.WRITE);
final String operationName = "disallowSnapshot";
checkSuperuserPrivilege(operationName);
checkSuperuserPrivilege(operationName, path);
writeLock();
try {
checkOperation(OperationCategory.WRITE);
Expand Down Expand Up @@ -7666,13 +7673,14 @@ void addCachePool(CachePoolInfo req, boolean logRetryCache)
final String operationName = "addCachePool";
checkOperation(OperationCategory.WRITE);
String poolInfoStr = null;
String poolName = req == null ? null : req.getPoolName();
try {
checkSuperuserPrivilege();
checkSuperuserPrivilege(operationName, poolName);
writeLock();
try {
checkOperation(OperationCategory.WRITE);
checkNameNodeSafeMode("Cannot add cache pool"
+ (req == null ? null : req.getPoolName()));
+ poolName);
CachePoolInfo info = FSNDNCacheOp.addCachePool(this, cacheManager, req,
logRetryCache);
poolInfoStr = info.toString();
Expand All @@ -7694,7 +7702,7 @@ void modifyCachePool(CachePoolInfo req, boolean logRetryCache)
String poolNameStr = "{poolName: " +
(req == null ? null : req.getPoolName()) + "}";
try {
checkSuperuserPrivilege();
checkSuperuserPrivilege(operationName, poolNameStr);
writeLock();
try {
checkOperation(OperationCategory.WRITE);
Expand All @@ -7721,7 +7729,7 @@ void removeCachePool(String cachePoolName, boolean logRetryCache)
checkOperation(OperationCategory.WRITE);
String poolNameStr = "{poolName: " + cachePoolName + "}";
try {
checkSuperuserPrivilege();
checkSuperuserPrivilege(operationName, poolNameStr);
writeLock();
try {
checkOperation(OperationCategory.WRITE);
Expand Down Expand Up @@ -7926,8 +7934,7 @@ void createEncryptionZone(final String src, final String keyName,
Metadata metadata = FSDirEncryptionZoneOp.ensureKeyIsInitialized(dir,
keyName, src);
final FSPermissionChecker pc = getPermissionChecker();
FSPermissionChecker.setOperationType(operationName);
checkSuperuserPrivilege(pc);
checkSuperuserPrivilege(operationName, src);
checkOperation(OperationCategory.WRITE);
writeLock();
try {
Expand Down Expand Up @@ -7988,9 +7995,7 @@ BatchedListEntries<EncryptionZone> listEncryptionZones(long prevId)
final String operationName = "listEncryptionZones";
boolean success = false;
checkOperation(OperationCategory.READ);
final FSPermissionChecker pc = getPermissionChecker();
FSPermissionChecker.setOperationType(operationName);
checkSuperuserPrivilege(pc);
checkSuperuserPrivilege(operationName, dir.rootDir.getFullPathName());
readLock();
try {
checkOperation(OperationCategory.READ);
Expand All @@ -8006,12 +8011,13 @@ BatchedListEntries<EncryptionZone> listEncryptionZones(long prevId)

void reencryptEncryptionZone(final String zone, final ReencryptAction action,
final boolean logRetryCache) throws IOException {
final String operationName = "reencryptEncryptionZone";
boolean success = false;
try {
Preconditions.checkNotNull(zone, "zone is null.");
checkOperation(OperationCategory.WRITE);
final FSPermissionChecker pc = dir.getPermissionChecker();
checkSuperuserPrivilege(pc);
checkSuperuserPrivilege(operationName, zone);
checkNameNodeSafeMode("NameNode in safemode, cannot " + action
+ " re-encryption on zone " + zone);
reencryptEncryptionZoneInt(pc, zone, action, logRetryCache);
Expand All @@ -8026,9 +8032,7 @@ BatchedListEntries<ZoneReencryptionStatus> listReencryptionStatus(
final String operationName = "listReencryptionStatus";
boolean success = false;
checkOperation(OperationCategory.READ);
final FSPermissionChecker pc = getPermissionChecker();
FSPermissionChecker.setOperationType(operationName);
checkSuperuserPrivilege(pc);
checkSuperuserPrivilege(operationName, dir.rootDir.getFullPathName());
readLock();
try {
checkOperation(OperationCategory.READ);
Expand Down Expand Up @@ -8871,15 +8875,19 @@ private ECTopologyVerifierResult getEcTopologyVerifierResultForEnabledPolicies()
Arrays.asList(enabledEcPolicies));
}

// This method logs operatoinName without super user privilege.
// This method logs operationName without super user privilege.
// It should be called without holding FSN lock.
void checkSuperuserPrivilege(String operationName)
void checkSuperuserPrivilege(String operationName, String path)
throws IOException {
try {
checkSuperuserPrivilege();
} catch (AccessControlException ace) {
logAuditEvent(false, operationName, null);
throw ace;
if (isPermissionEnabled) {
try {
FSPermissionChecker.setOperationType(operationName);
FSPermissionChecker pc = getPermissionChecker();
pc.checkSuperuserPrivilege(path);
} catch(AccessControlException ace){
logAuditEvent(false, operationName, path);
throw ace;
}
}
}

Expand Down
Loading