From 8890c203d902cc8e1df0e86c9b6fad349527ebf5 Mon Sep 17 00:00:00 2001 From: shuwenwei Date: Tue, 30 Dec 2025 14:53:30 +0800 Subject: [PATCH 1/3] The grant option check for path privileges was not correctly logged in the audit log --- .../security/TreeAccessCheckVisitor.java | 84 +++++++++++++------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java index e63b63f850e5..83a5c48849f8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java @@ -167,6 +167,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.StringJoiner; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -668,31 +669,12 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co auditObject)) { return RpcUtils.SUCCESS_STATUS; } - for (String s : statement.getPrivilegeList()) { - PrivilegeType privilegeType = PrivilegeType.valueOf(s.toUpperCase()); - if (privilegeType.isSystemPrivilege()) { - if (!checkHasGlobalAuth(context, privilegeType, auditObject, true)) { - return AuthorityChecker.getTSStatus( - false, - "Has no permission to execute " - + authorType - + ", please ensure you have these privileges and the grant option is TRUE when granted)"); - } - } else if (privilegeType.isPathPrivilege()) { - if (!AuthorityChecker.checkPathPermissionGrantOption( - context.getUsername(), privilegeType, statement.getNodeNameList())) { - return AuthorityChecker.getTSStatus( - false, - "Has no permission to execute " - + authorType - + ", please ensure you have these privileges and the grant option is TRUE when granted)"); - } - } else { - return AuthorityChecker.getTSStatus( - false, "Not support Relation statement in tree sql_dialect"); - } - } - return RpcUtils.SUCCESS_STATUS; + return checkPermissionsWithGrantOption( + context, + Arrays.stream(statement.getPrivilegeList()) + .map(PrivilegeType::valueOf) + .collect(Collectors.toList()), + statement.getNodeNameList()); default: throw new IllegalArgumentException("Unknown authorType: " + authorType); } @@ -1997,6 +1979,58 @@ protected boolean checkHasGlobalAuth( return result; } + protected TSStatus checkPermissionsWithGrantOption( + IAuditEntity auditEntity, List privilegeList, List paths) { + Supplier supplier = + () -> { + StringJoiner joiner = new StringJoiner(" "); + if (paths != null) { + paths.forEach(path -> joiner.add(path.getFullPath())); + } + return joiner.toString(); + }; + auditEntity.setPrivilegeTypes(privilegeList); + if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { + recordObjectAuthenticationAuditLog(auditEntity.setResult(true), supplier); + return SUCCEED; + } + TSStatus status = SUCCEED; + for (PrivilegeType privilegeType : privilegeList) { + if (privilegeType.isSystemPrivilege()) { + if (!AuthorityChecker.checkSystemPermissionGrantOption( + auditEntity.getUsername(), privilegeType)) { + status = + AuthorityChecker.getTSStatus( + false, + "Has no permission to execute " + + privilegeType + + ", please ensure you have these privileges and the grant option is TRUE when granted)"); + break; + } + } else if (privilegeType.isPathPrivilege()) { + if (!AuthorityChecker.checkPathPermissionGrantOption( + auditEntity.getUsername(), privilegeType, paths)) { + status = + AuthorityChecker.getTSStatus( + false, + "Has no permission to execute " + + privilegeType + + ", please ensure you have these privileges and the grant option is TRUE when granted)"); + break; + } + } else { + status = + AuthorityChecker.getTSStatus( + false, "Not support Relation statement in tree sql_dialect"); + break; + } + } + recordObjectAuthenticationAuditLog( + auditEntity.setResult(status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), + supplier); + return status; + } + protected TSStatus checkWriteOnReadOnlyPath(IAuditEntity auditEntity, PartialPath path) { if (includeByAuditTreeDB(path) && !AuthorityChecker.INTERNAL_AUDIT_USER.equals(path.getFullPath())) { From 70624d9cc643c4825eebd5a368dc8383c93e5982 Mon Sep 17 00:00:00 2001 From: shuwenwei Date: Tue, 30 Dec 2025 15:03:28 +0800 Subject: [PATCH 2/3] fix --- .../plan/relational/security/TreeAccessCheckVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java index 83a5c48849f8..b6bbc04d1f2c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java @@ -672,7 +672,7 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co return checkPermissionsWithGrantOption( context, Arrays.stream(statement.getPrivilegeList()) - .map(PrivilegeType::valueOf) + .map(s -> PrivilegeType.valueOf(s.toUpperCase())) .collect(Collectors.toList()), statement.getNodeNameList()); default: From 2ffd0cc99722cd13a62b1e2024ffcf88cb3c7e00 Mon Sep 17 00:00:00 2001 From: shuwenwei Date: Tue, 30 Dec 2025 15:05:31 +0800 Subject: [PATCH 3/3] fix spell --- .../plan/relational/security/TreeAccessCheckVisitor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java index b6bbc04d1f2c..4daa322d58ec 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java @@ -2004,7 +2004,7 @@ protected TSStatus checkPermissionsWithGrantOption( false, "Has no permission to execute " + privilegeType - + ", please ensure you have these privileges and the grant option is TRUE when granted)"); + + ", please ensure you have these privileges and the grant option is TRUE when granted"); break; } } else if (privilegeType.isPathPrivilege()) { @@ -2015,7 +2015,7 @@ protected TSStatus checkPermissionsWithGrantOption( false, "Has no permission to execute " + privilegeType - + ", please ensure you have these privileges and the grant option is TRUE when granted)"); + + ", please ensure you have these privileges and the grant option is TRUE when granted"); break; } } else {