Patch for rename user and audit log (#16535)
* Fix audit logger
* Fix rename user bugs
* Unify username parser
diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDBRegionReconstructForIoTV1IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDBRegionReconstructForIoTV1IT.java
index 777b1d2..42dee93 100644
--- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDBRegionReconstructForIoTV1IT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDBRegionReconstructForIoTV1IT.java
@@ -151,7 +151,7 @@
EnvFactory.getEnv()
.getConnection(
EnvFactory.getEnv().dataNodeIdToWrapper(dataNodeToBeReconstructed).get(),
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
BaseEnv.TREE_SQL_DIALECT);
Statement flushStatement = flushConn.createStatement()) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBUserRenameIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBUserRenameIT.java
index b17f778..b9c474e 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBUserRenameIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBUserRenameIT.java
@@ -68,6 +68,11 @@
Statement adminStmt = adminCon.createStatement()) {
adminStmt.execute("CREATE USER user1 'IoTDB@2021abc'");
adminStmt.execute("CREATE USER user2 'IoTDB@2023abc'");
+ if (BaseEnv.TABLE_SQL_DIALECT.equals(dialect)) {
+ adminStmt.execute("GRANT SECURITY TO USER user2");
+ } else {
+ adminStmt.execute("GRANT SECURITY ON root.** TO USER user2");
+ }
try (Connection userCon =
EnvFactory.getEnv().getConnection("user1", "IoTDB@2021abc", dialect);
Statement userStmt = userCon.createStatement()) {
@@ -77,20 +82,36 @@
// A normal user can only rename himself
userStmt.execute("ALTER USER user1 RENAME TO user3");
}
+ try (Connection userCon =
+ EnvFactory.getEnv().getConnection("user2", "IoTDB@2023abc", dialect);
+ Statement userStmt = userCon.createStatement()) {
+ // User with SECURITY privilege can rename other users
+ userStmt.execute("ALTER USER user3 RENAME TO user1");
+ // Nobody can rename superuser
+ Assert.assertThrows(
+ SQLException.class, () -> userStmt.execute("ALTER USER root RENAME TO admin"));
+ }
// Cannot rename an unexisting user
Assert.assertThrows(
SQLException.class, () -> adminStmt.execute("ALTER USER user4 RENAME TO user5"));
// Cannot rename to an already existed user
Assert.assertThrows(
- SQLException.class, () -> adminStmt.execute("ALTER USER user2 RENAME TO user3"));
- // The superuser can rename anyone
- adminStmt.execute("ALTER USER user3 RENAME TO user4");
+ SQLException.class, () -> adminStmt.execute("ALTER USER user2 RENAME TO user1"));
+ // Cannot rename to an illegal name
+ Assert.assertThrows(
+ SQLException.class, () -> adminStmt.execute("ALTER USER user2 RENAME TO p00"));
+ // Only the superuser can rename him/herself
adminStmt.execute("ALTER USER root RENAME TO admin");
}
- // Ensure every rename works
try (Connection adminCon = EnvFactory.getEnv().getConnection("admin", "root", dialect);
Statement adminStmt = adminCon.createStatement()) {
- final String ans = "0,admin,\n" + "10000,user4,\n" + "10001,user2,\n";
+ // We can rename other user to root
+ adminStmt.execute("ALTER USER user1 RENAME TO root");
+ adminStmt.execute("ALTER USER root RENAME TO user4");
+ // We can create another root
+ adminStmt.execute("CREATE USER root 'IoTDB@2025abc'");
+ // Ensure everything works
+ final String ans = "0,admin,\n" + "10000,user4,\n" + "10001,user2,\n" + "10002,root,\n";
ResultSet resultSet = adminStmt.executeQuery("LIST USER");
validateResultSet(resultSet, ans);
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBBitwiseFunctionTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBBitwiseFunctionTableIT.java
index 904aa8a..6a8b837 100644
--- a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBBitwiseFunctionTableIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBBitwiseFunctionTableIT.java
@@ -148,7 +148,7 @@
EnvFactory.getEnv(),
"select time,s2,s3,bit_count(9,64),bit_count(s2,64),bit_count(s2,s3) from bit_count_error_table",
"Argument exception, the scalar function num must be representable with the bits specified. 9 cannot be represented with 2 bits.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -159,7 +159,7 @@
EnvFactory.getEnv(),
"select time,s2,s3,bit_count(9,1),bit_count(s2,1),bit_count(s2,s3) from bit_count_error_table",
"Argument exception, the scalar function bit_count bits must be between 2 and 64.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -170,7 +170,7 @@
EnvFactory.getEnv(),
"select time, bit_count(s4) from bit_count_error_table",
"701: Scalar function bit_count only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -178,7 +178,7 @@
EnvFactory.getEnv(),
"select time, bit_count(s1,s4) from bit_count_error_table",
"701: Scalar function bit_count only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -204,7 +204,7 @@
EnvFactory.getEnv(),
"select time, bitwise_and(s4) from bitwise_and_table",
"701: Scalar function bitwise_and only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -212,7 +212,7 @@
EnvFactory.getEnv(),
"select time, bitwise_and(s1,s4) from bitwise_and_table",
"701: Scalar function bitwise_and only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -240,7 +240,7 @@
EnvFactory.getEnv(),
"select time, bitwise_not(s4) from bitwise_not_table",
"701: Scalar function bitwise_not only accepts one argument and it must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -248,7 +248,7 @@
EnvFactory.getEnv(),
"select time, bitwise_not(s1,s4) from bitwise_not_table",
"701: Scalar function bitwise_not only accepts one argument and it must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -274,7 +274,7 @@
EnvFactory.getEnv(),
"select time, bitwise_or(s4) from bitwise_or_table",
"701: Scalar function bitwise_or only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -282,7 +282,7 @@
EnvFactory.getEnv(),
"select time, bitwise_or(s1,s4) from bitwise_or_table",
"701: Scalar function bitwise_or only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -308,7 +308,7 @@
EnvFactory.getEnv(),
"select time, bitwise_xor(s4) from bitwise_xor_table",
"701: Scalar function bitwise_xor only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -316,7 +316,7 @@
EnvFactory.getEnv(),
"select time, bitwise_xor(s1,s4) from bitwise_xor_table",
"701: Scalar function bitwise_xor only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -347,7 +347,7 @@
EnvFactory.getEnv(),
"select time, bitwise_left_shift(s4) from bitwise_left_shift_table",
"701: Scalar function bitwise_left_shift only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -355,7 +355,7 @@
EnvFactory.getEnv(),
"select time, bitwise_left_shift(s1,s4) from bitwise_left_shift_table",
"701: Scalar function bitwise_left_shift only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -388,7 +388,7 @@
EnvFactory.getEnv(),
"select time, bitwise_right_shift(s4) from bitwise_right_shift_table",
"701: Scalar function bitwise_right_shift only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -396,7 +396,7 @@
EnvFactory.getEnv(),
"select time, bitwise_right_shift(s1,s4) from bitwise_right_shift_table",
"701: Scalar function bitwise_right_shift only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
@@ -423,7 +423,7 @@
EnvFactory.getEnv(),
"select time, bitwise_right_shift_arithmetic(s4) from bitwise_right_shift_arithmetic_table",
"701: Scalar function bitwise_right_shift_arithmetic only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
@@ -431,7 +431,7 @@
EnvFactory.getEnv(),
"select time, bitwise_right_shift_arithmetic(s1,s4) from bitwise_right_shift_arithmetic_table",
"701: Scalar function bitwise_right_shift_arithmetic only accepts two arguments and they must be Int32 or Int64 data type.",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
DATABASE_NAME);
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionCompressedIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionCompressedIT.java
index c82bdfc..f8cc5a7 100644
--- a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionCompressedIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionCompressedIT.java
@@ -63,7 +63,7 @@
ITableSession session1 =
new TableSessionBuilder()
.nodeUrls(nodeUrls)
- .username(CommonDescriptor.getInstance().getConfig().getAdminName())
+ .username(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.password(CommonDescriptor.getInstance().getConfig().getAdminPassword())
.enableCompression(true)
.enableRedirection(true)
@@ -83,7 +83,7 @@
ITableSession session2 =
new TableSessionBuilder()
.nodeUrls(nodeUrls)
- .username(CommonDescriptor.getInstance().getConfig().getAdminName())
+ .username(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.password(CommonDescriptor.getInstance().getConfig().getAdminPassword())
.enableCompression(true)
.enableRedirection(true)
@@ -103,7 +103,7 @@
ITableSession session3 =
new TableSessionBuilder()
.nodeUrls(nodeUrls)
- .username(CommonDescriptor.getInstance().getConfig().getAdminName())
+ .username(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.password(CommonDescriptor.getInstance().getConfig().getAdminPassword())
.enableCompression(true)
.enableRedirection(true)
@@ -123,7 +123,7 @@
ITableSession session4 =
new TableSessionBuilder()
.nodeUrls(nodeUrls)
- .username(CommonDescriptor.getInstance().getConfig().getAdminName())
+ .username(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.password(CommonDescriptor.getInstance().getConfig().getAdminPassword())
.enableCompression(true)
.enableRedirection(true)
@@ -143,7 +143,7 @@
ITableSession session5 =
new TableSessionBuilder()
.nodeUrls(nodeUrls)
- .username(CommonDescriptor.getInstance().getConfig().getAdminName())
+ .username(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.password(CommonDescriptor.getInstance().getConfig().getAdminPassword())
.enableCompression(false)
.enableRedirection(true)
diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 14a82e7..58f77da 100644
--- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -1046,7 +1046,7 @@
// Create User
createUser
- : CREATE USER userName=identifier password=STRING_LITERAL
+ : CREATE USER userName=usernameWithRoot password=STRING_LITERAL
;
// Create Role
@@ -1061,7 +1061,7 @@
// Rename user
renameUser
- : ALTER USER username=usernameWithRoot RENAME TO newUsername=identifier
+ : ALTER USER username=usernameWithRoot RENAME TO newUsername=usernameWithRoot
;
// ---- Alter User Account Unlock
@@ -1071,7 +1071,7 @@
// Grant User Privileges
grantUser
- : GRANT privileges ON prefixPath (COMMA prefixPath)* TO USER userName=identifier (grantOpt)?
+ : GRANT privileges ON prefixPath (COMMA prefixPath)* TO USER userName=usernameWithRoot (grantOpt)?
;
// Grant Role Privileges
@@ -1086,12 +1086,12 @@
// Grant User Role
grantRoleToUser
- : GRANT ROLE roleName=identifier TO userName=identifier
+ : GRANT ROLE roleName=identifier TO userName=usernameWithRoot
;
// Revoke User Privileges
revokeUser
- : REVOKE privileges ON prefixPath (COMMA prefixPath)* FROM USER userName=identifier
+ : REVOKE privileges ON prefixPath (COMMA prefixPath)* FROM USER userName=usernameWithRoot
;
// Revoke Role Privileges
@@ -1101,12 +1101,12 @@
// Revoke Role From User
revokeRoleFromUser
- : REVOKE ROLE roleName=identifier FROM userName=identifier
+ : REVOKE ROLE roleName=identifier FROM userName=usernameWithRoot
;
// Drop User
dropUser
- : DROP USER userName=identifier
+ : DROP USER userName=usernameWithRoot
;
// Drop Role
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
index 5379831..0e49b86 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
@@ -325,7 +325,7 @@
case CreateSchemaTemplate:
case CommitSetSchemaTemplate:
case PipeUnsetTemplate:
- return CommonDescriptor.getInstance().getConfig().getAdminName().equals(username)
+ return CommonDescriptor.getInstance().getConfig().getDefaultAdminName().equals(username)
? StatusUtils.OK
: new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
.setMessage("Only the admin user can perform this operation");
diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/consensuspipe/ConsensusPipeManager.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/consensuspipe/ConsensusPipeManager.java
index b460e69..525ee6b 100644
--- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/consensuspipe/ConsensusPipeManager.java
+++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/consensuspipe/ConsensusPipeManager.java
@@ -114,7 +114,8 @@
.put(EXTRACTOR_CAPTURE_TABLE_KEY, String.valueOf(true))
.put(EXTRACTOR_CAPTURE_TREE_KEY, String.valueOf(true))
.put(
- EXTRACTOR_IOTDB_USER_KEY, CommonDescriptor.getInstance().getConfig().getAdminName())
+ EXTRACTOR_IOTDB_USER_KEY,
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
.build(),
ImmutableMap.<String, String>builder()
.put(PROCESSOR_KEY, config.getProcessorPluginName())
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
index bbd9ada..495c317 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
@@ -77,7 +77,8 @@
public class AuthorityChecker {
public static int SUPER_USER_ID = 0;
- public static String SUPER_USER = CommonDescriptor.getInstance().getConfig().getAdminName();
+ public static String SUPER_USER =
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName();
public static String SUPER_USER_ID_IN_STR = "0";
public static final TSStatus SUCCEED = new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index ad09bc6..35eee66 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -2678,7 +2678,7 @@
"fakePipeName",
// TODO: currently use root to create topic
temporaryTopicMeta.generateExtractorAttributes(
- CommonDescriptor.getInstance().getConfig().getAdminName()),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName()),
temporaryTopicMeta.generateProcessorAttributes(),
temporaryTopicMeta.generateConnectorAttributes("fakeConsumerGroupId"));
} catch (final Exception e) {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
index 8c13ef5..1695faa 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
@@ -2488,12 +2488,22 @@
}
/** Data Control Language (DCL). */
+ private static String parseUsernameWithRoot(IoTDBSqlParser.UsernameWithRootContext ctx) {
+ String src = ctx.identifier() != null ? ctx.identifier().getText() : "root";
+ if (src.startsWith(TsFileConstant.BACK_QUOTE_STRING)
+ && src.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
+ src =
+ src.substring(1, src.length() - 1)
+ .replace(TsFileConstant.DOUBLE_BACK_QUOTE_STRING, TsFileConstant.BACK_QUOTE_STRING);
+ }
+ return src;
+ }
// Create User
@Override
public Statement visitCreateUser(IoTDBSqlParser.CreateUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.CREATE_USER);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
authorStatement.setPassWord(parseStringLiteral(ctx.password.getText()));
return authorStatement;
}
@@ -2510,7 +2520,7 @@
@Override
public Statement visitAlterUser(IoTDBSqlParser.AlterUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.UPDATE_USER);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
authorStatement.setNewPassword(parseStringLiteral(ctx.password.getText()));
return authorStatement;
}
@@ -2518,8 +2528,8 @@
@Override
public Statement visitRenameUser(IoTDBSqlParser.RenameUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.RENAME_USER);
- authorStatement.setUserName(parseIdentifier(ctx.username.getText()));
- authorStatement.setNewUsername(parseIdentifier(ctx.newUsername.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.username));
+ authorStatement.setNewUsername(parseUsernameWithRoot(ctx.newUsername));
return authorStatement;
}
@@ -2552,7 +2562,7 @@
String[] priviParsed = parsePrivilege(privileges);
AuthorStatement authorStatement = new AuthorStatement(AuthorType.GRANT_USER);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
authorStatement.setPrivilegeList(priviParsed);
authorStatement.setNodeNameList(nodeNameList);
if (!CommonDescriptor.getInstance().getConfig().getEnableGrantOption()
@@ -2597,7 +2607,7 @@
public Statement visitGrantRoleToUser(IoTDBSqlParser.GrantRoleToUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.GRANT_USER_ROLE);
authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
return authorStatement;
}
@@ -2615,7 +2625,7 @@
String[] priviParsed = parsePrivilege(privileges);
AuthorStatement authorStatement = new AuthorStatement(AuthorType.REVOKE_USER);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
authorStatement.setPrivilegeList(priviParsed);
authorStatement.setNodeNameList(nodeNameList);
return authorStatement;
@@ -2708,7 +2718,7 @@
public Statement visitRevokeRoleFromUser(IoTDBSqlParser.RevokeRoleFromUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.REVOKE_USER_ROLE);
authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
return authorStatement;
}
@@ -2717,7 +2727,7 @@
@Override
public Statement visitDropUser(IoTDBSqlParser.DropUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.DROP_USER);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
return authorStatement;
}
@@ -2747,7 +2757,7 @@
public Statement visitListRole(IoTDBSqlParser.ListRoleContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.LIST_ROLE);
if (ctx.userName != null) {
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
}
return authorStatement;
}
@@ -2757,7 +2767,7 @@
@Override
public Statement visitListPrivilegesUser(IoTDBSqlParser.ListPrivilegesUserContext ctx) {
AuthorStatement authorStatement = new AuthorStatement(AuthorType.LIST_USER_PRIVILEGE);
- authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+ authorStatement.setUserName(parseUsernameWithRoot(ctx.userName));
return authorStatement;
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
index ad5e748..d7a35f3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
@@ -264,10 +264,20 @@
case RENAME_USER:
case UPDATE_USER:
auditEntity.setAuditLogOperation(AuditLogOperation.DDL);
- // users can change the username and password of themselves
- // the superuser can affect anyone
- if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()
- || statement.getUserName().equals(userName)) {
+ if (statement.getUserName().equals(userName)) {
+ // users can change the username and password of themselves
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName);
+ return;
+ }
+ if (AuthorityChecker.SUPER_USER_ID
+ == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) {
+ // Only the superuser can alter him/herself
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setResult(false), statement::getUserName);
+ throw new AccessDeniedException("Only the superuser can alter him/herself.");
+ }
+ if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
+ // the superuser can alter anyone
ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName);
return;
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java
index 92262b6..29fc704 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java
@@ -487,6 +487,6 @@
auditEntity.getUsername(),
auditEntity.getUserId(),
auditObject.get(),
- true));
+ auditEntity.getResult()));
}
}
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 52303cc..cd6cbe3 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
@@ -519,11 +519,21 @@
case UPDATE_USER:
case RENAME_USER:
context.setAuditLogOperation(AuditLogOperation.DDL);
- // users can change the username and password of themselves
if (statement.getUserName().equals(context.getUsername())) {
+ // users can change the username and password of themselves
recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername);
return RpcUtils.SUCCESS_STATUS;
}
+ if (AuthorityChecker.SUPER_USER_ID
+ == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) {
+ // Only the superuser can alter him/herself
+ recordObjectAuthenticationAuditLog(context.setResult(false), context::getUsername);
+ return AuthorityChecker.getTSStatus(
+ false,
+ "Has no permission to execute "
+ + authorType
+ + ", because only the superuser can alter him/herself.");
+ }
context.setPrivilegeType(PrivilegeType.SECURITY);
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.DDL),
@@ -1093,6 +1103,7 @@
return SUCCEED;
}
setCanSeeAuditDB(statement, context);
+ context.setPrivilegeType(PrivilegeType.READ_DATA);
try {
statement.setAuthorityScope(
AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_DATA));
@@ -1894,6 +1905,6 @@
auditEntity.getUsername(),
auditEntity.getUserId(),
auditObject.get(),
- true));
+ auditEntity.getResult()));
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 1d29930..431ed9d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -265,6 +265,7 @@
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.tsfile.common.constant.TsFileConstant;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.utils.TimeDuration;
import org.apache.tsfile.write.schema.MeasurementSchema;
@@ -1704,10 +1705,22 @@
}
// ********************** author expressions ********************
+ private String parseUsernameWithRoot(RelationalSqlParser.UsernameWithRootContext ctx) {
+ String src =
+ ctx.identifier() != null ? ((Identifier) visit(ctx.identifier())).getValue() : "root";
+ if (src.startsWith(TsFileConstant.BACK_QUOTE_STRING)
+ && src.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
+ src =
+ src.substring(1, src.length() - 1)
+ .replace(TsFileConstant.DOUBLE_BACK_QUOTE_STRING, TsFileConstant.BACK_QUOTE_STRING);
+ }
+ return src;
+ }
+
@Override
public Node visitCreateUserStatement(RelationalSqlParser.CreateUserStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.CREATE_USER);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
String password = ((StringLiteral) visit(ctx.password)).getValue();
stmt.setPassword(password);
return stmt;
@@ -1723,7 +1736,7 @@
@Override
public Node visitDropUserStatement(RelationalSqlParser.DropUserStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.DROP_USER);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
return stmt;
}
@@ -1737,7 +1750,7 @@
@Override
public Node visitAlterUserStatement(RelationalSqlParser.AlterUserStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.UPDATE_USER);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
String password = ((StringLiteral) visit(ctx.password)).getValue();
stmt.setPassword(password);
return stmt;
@@ -1763,15 +1776,15 @@
@Override
public Node visitRenameUserStatement(RelationalSqlParser.RenameUserStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.RENAME_USER);
- stmt.setUserName(((Identifier) visit(ctx.username)).getValue());
- stmt.setNewUsername(((Identifier) visit(ctx.newUsername)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.username));
+ stmt.setNewUsername(parseUsernameWithRoot(ctx.newUsername));
return stmt;
}
@Override
public Node visitGrantUserRoleStatement(RelationalSqlParser.GrantUserRoleStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.GRANT_USER_ROLE);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
stmt.setRoleName(((Identifier) visit(ctx.roleName)).getValue());
return stmt;
}
@@ -1779,7 +1792,7 @@
@Override
public Node visitRevokeUserRoleStatement(RelationalSqlParser.RevokeUserRoleStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.REVOKE_USER_ROLE);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
stmt.setRoleName(((Identifier) visit(ctx.roleName)).getValue());
return stmt;
}
@@ -1788,7 +1801,7 @@
public Node visitListUserPrivilegeStatement(
RelationalSqlParser.ListUserPrivilegeStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.LIST_USER_PRIV);
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
return stmt;
}
@@ -1813,7 +1826,7 @@
public Node visitListRoleStatement(RelationalSqlParser.ListRoleStatementContext ctx) {
RelationalAuthorStatement stmt = new RelationalAuthorStatement(AuthorRType.LIST_ROLE);
if (ctx.OF() != null) {
- stmt.setUserName(((Identifier) visit(ctx.userName)).getValue());
+ stmt.setUserName(parseUsernameWithRoot(ctx.userName));
}
return stmt;
}
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
index 96a40d0..67c5de5 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/authorizer/LocalFileAuthorizerTest.java
@@ -250,7 +250,7 @@
IAuthorizer authorizer = BasicAuthorizer.getInstance();
List<String> userList = authorizer.listAllUsers();
assertEquals(1, userList.size());
- assertEquals(CommonDescriptor.getInstance().getConfig().getAdminName(), userList.get(0));
+ assertEquals(CommonDescriptor.getInstance().getConfig().getDefaultAdminName(), userList.get(0));
int userCnt = 10;
for (int i = 0; i < userCnt; i++) {
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/LocalFileAuthorizer.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/LocalFileAuthorizer.java
index 117871f..1e82f81 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/LocalFileAuthorizer.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/LocalFileAuthorizer.java
@@ -36,6 +36,6 @@
@Override
public boolean isAdmin(String username) {
- return config.getAdminName().equals(username);
+ return config.getDefaultAdminName().equals(username);
}
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
index f781df9..9ee82c0 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
@@ -40,6 +40,7 @@
import java.util.Map;
import static org.apache.iotdb.commons.auth.entity.User.INTERNAL_USER_END_ID;
+import static org.apache.iotdb.commons.conf.IoTDBConstant.SUPER_USER_ID;
/** This class stores information of each user. */
public abstract class BasicUserManager extends BasicRoleManager {
@@ -76,16 +77,16 @@
* @throws AuthException if an exception is raised when interacting with the lower storage.
*/
private void initAdmin() throws AuthException {
- User admin = this.getEntity(CommonDescriptor.getInstance().getConfig().getAdminName());
+ User admin = this.getEntity(SUPER_USER_ID);
if (admin == null) {
createUser(
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
CommonDescriptor.getInstance().getConfig().getAdminPassword(),
true,
true);
+ admin = this.getEntity(SUPER_USER_ID);
}
- admin = this.getEntity(CommonDescriptor.getInstance().getConfig().getAdminName());
try {
PartialPath rootPath = new PartialPath(IoTDBConstant.PATH_ROOT + ".**");
PathPrivilege pathPri = new PathPrivilege(rootPath);
@@ -106,11 +107,12 @@
} catch (IllegalPathException e) {
LOGGER.warn(
"Got a wrong path for {} to init",
- CommonDescriptor.getInstance().getConfig().getAdminName(),
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName(),
e);
}
LOGGER.info(
- "Internal user {} initialized", CommonDescriptor.getInstance().getConfig().getAdminName());
+ "Internal user {} initialized",
+ CommonDescriptor.getInstance().getConfig().getDefaultAdminName());
}
private void initUserId() {
@@ -152,8 +154,9 @@
lock.writeLock(username);
try {
long userid;
- if (username.equals(CommonDescriptor.getInstance().getConfig().getAdminName())) {
- userid = 0;
+ if (username.equals(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())
+ && this.getEntity(SUPER_USER_ID) == null) {
+ userid = SUPER_USER_ID;
} else {
userid = ++nextUserId;
}
@@ -191,7 +194,7 @@
private void validCheck(String username, String password, boolean enableEncrypt)
throws AuthException {
- if (!CommonDescriptor.getInstance().getConfig().getAdminName().equals(username)) {
+ if (!CommonDescriptor.getInstance().getConfig().getDefaultAdminName().equals(username)) {
if (username.equals(password)
&& CommonDescriptor.getInstance().getConfig().isEnforceStrongPassword()) {
throw new AuthException(
@@ -230,6 +233,7 @@
}
public void renameUser(String username, String newUsername) throws AuthException {
+ AuthUtils.validateName(newUsername);
User user = this.getEntity(username);
if (user == null) {
throw new AuthException(
@@ -295,8 +299,9 @@
try {
User user = (User) accessor.loadEntity(userId);
if (user.getUserId() == -1) {
- if (user.getName().equals(CommonDescriptor.getInstance().getConfig().getAdminName())) {
- user.setUserId(0);
+ if (user.getName()
+ .equals(CommonDescriptor.getInstance().getConfig().getDefaultAdminName())) {
+ user.setUserId(SUPER_USER_ID);
} else {
user.setUserId(++nextUserId);
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index 2c6912b..c735e8d 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -537,7 +537,7 @@
this.authorizerProvider = authorizerProvider;
}
- public String getAdminName() {
+ public String getDefaultAdminName() {
return adminName;
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/IoTDBConstant.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/IoTDBConstant.java
index 5c07cbf..4a54d77 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/IoTDBConstant.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/IoTDBConstant.java
@@ -372,4 +372,6 @@
// Class Name
public static final String STRING_2D_ARRAY_CLASS_NAME = String[][].class.getName();
public static final String STRING_ARRAY_CLASS_NAME = String[].class.getName();
+
+ public static final int SUPER_USER_ID = 0;
}
diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 087d3d8..a17932b 100644
--- a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -691,7 +691,7 @@
// ------------------------------------------- Authority Statement -----------------------------------------------------
createUserStatement
- : CREATE USER userName=identifier password=string
+ : CREATE USER userName=usernameWithRoot password=string
;
createRoleStatement
@@ -699,7 +699,7 @@
;
dropUserStatement
- : DROP USER userName=identifier
+ : DROP USER userName=usernameWithRoot
;
dropRoleStatement
@@ -707,7 +707,7 @@
;
alterUserStatement
- : ALTER USER userName=identifier SET PASSWORD password=string
+ : ALTER USER userName=usernameWithRoot SET PASSWORD password=string
;
alterUserAccountUnlockStatement
@@ -724,15 +724,15 @@
;
renameUserStatement
- : ALTER USER username=identifier RENAME TO newUsername=identifier
+ : ALTER USER username=usernameWithRoot RENAME TO newUsername=usernameWithRoot
;
grantUserRoleStatement
- : GRANT ROLE roleName=identifier TO userName=identifier
+ : GRANT ROLE roleName=identifier TO userName=usernameWithRoot
;
revokeUserRoleStatement
- : REVOKE ROLE roleName=identifier FROM userName=identifier
+ : REVOKE ROLE roleName=identifier FROM userName=usernameWithRoot
;
@@ -741,7 +741,7 @@
;
listUserPrivilegeStatement
- : LIST PRIVILEGES OF USER userName=identifier
+ : LIST PRIVILEGES OF USER userName=usernameWithRoot
;
listRolePrivilegeStatement
@@ -753,7 +753,7 @@
;
listRoleStatement
- : LIST ROLE (OF USER userName=identifier)?
+ : LIST ROLE (OF USER userName=usernameWithRoot)?
;
diff --git a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
index 1086b5b..ce2cbd0 100644
--- a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
+++ b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
@@ -267,6 +267,7 @@
struct TInvalidatePermissionCacheReq {
1: required string username
2: required string roleName
+ 3: optional bool needDisconnect
}
struct TDataNodeHeartbeatReq {