morrySnow commented on code in PR #40932:
URL: https://github.com/apache/doris/pull/40932#discussion_r1766288814


##########
fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java:
##########
@@ -249,6 +271,110 @@ private void handleFieldList() throws ConnectionException 
{
         handleFieldList(tableName);
     }
 
+    private void handleChangeUser() throws IOException {
+        // Random bytes generated when creating connection.
+        byte[] authPluginData = getConnectContext().getAuthPluginData();
+        String userName = new 
String(MysqlProto.readNulTerminateString(packetBuf));
+        int passwordLen = MysqlProto.readInt1(packetBuf);
+        byte[] password = MysqlProto.readFixedString(packetBuf, passwordLen);
+        String db = new String(MysqlProto.readNulTerminateString(packetBuf));
+        // Read the character set.
+        MysqlProto.readInt2(packetBuf);
+        String authPluginName = new 
String(MysqlProto.readNulTerminateString(packetBuf));
+
+        // Send Protocol::AuthSwitchRequest to client if auth plugin name is 
not mysql_native_password
+        if (!MysqlHandshakePacket.AUTH_PLUGIN_NAME.equals(authPluginName)) {
+            MysqlChannel channel = ctx.mysqlChannel;
+            MysqlSerializer serializer = MysqlSerializer.newInstance();
+            serializer.writeInt1((byte) 0xfe);
+            
serializer.writeNulTerminateString(MysqlHandshakePacket.AUTH_PLUGIN_NAME);
+            serializer.writeBytes(authPluginData);
+            serializer.writeInt1(0);
+            channel.sendAndFlush(serializer.toByteBuffer());
+            // Server receive auth switch response packet from client.
+            ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+            int length = authSwitchResponse.limit();
+            password = new byte[length];
+            System.arraycopy(authSwitchResponse.array(), 0, password, 0, 
length);
+        }
+
+        // For safety, not allowed to change to root or admin.
+        if (Auth.ROOT_USER.equals(userName) || 
Auth.ADMIN_USER.equals(userName)) {
+            ctx.getState().setError(ErrorCode.ERR_ACCESS_DENIED_ERROR, "Change 
to root or admin is forbidden");
+            return;
+        }
+
+        // Check password.
+        List<UserIdentity> currentUserIdentity = Lists.newArrayList();
+        try {
+            Env.getCurrentEnv().getAuth()
+                .checkPassword(userName, ctx.remoteIP, password, 
authPluginData, currentUserIdentity);
+        } catch (AuthenticationException e) {
+            ctx.getState().setError(ErrorCode.ERR_ACCESS_DENIED_ERROR, 
"Authentication failed.");
+            return;
+        }
+        ctx.setCurrentUserIdentity(currentUserIdentity.get(0));
+        ctx.setQualifiedUser(userName);
+
+        // Change default db if set.
+        if (Strings.isNullOrEmpty(db)) {
+            ctx.changeDefaultCatalog(InternalCatalog.INTERNAL_CATALOG_NAME);
+        } else {
+            String catalogName = null;
+            String dbName = null;
+            String[] dbNames = db.split("\\.");

Review Comment:
   could `db` like
   ```
   `123.456`.`789.012`
   ```
   ? 
   do we need parse it with `NereidsParser.visitMultipartIdentifier`?



##########
fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java:
##########
@@ -249,6 +271,110 @@ private void handleFieldList() throws ConnectionException 
{
         handleFieldList(tableName);
     }
 
+    private void handleChangeUser() throws IOException {
+        // Random bytes generated when creating connection.
+        byte[] authPluginData = getConnectContext().getAuthPluginData();
+        String userName = new 
String(MysqlProto.readNulTerminateString(packetBuf));
+        int passwordLen = MysqlProto.readInt1(packetBuf);
+        byte[] password = MysqlProto.readFixedString(packetBuf, passwordLen);
+        String db = new String(MysqlProto.readNulTerminateString(packetBuf));
+        // Read the character set.
+        MysqlProto.readInt2(packetBuf);
+        String authPluginName = new 
String(MysqlProto.readNulTerminateString(packetBuf));
+
+        // Send Protocol::AuthSwitchRequest to client if auth plugin name is 
not mysql_native_password
+        if (!MysqlHandshakePacket.AUTH_PLUGIN_NAME.equals(authPluginName)) {
+            MysqlChannel channel = ctx.mysqlChannel;
+            MysqlSerializer serializer = MysqlSerializer.newInstance();
+            serializer.writeInt1((byte) 0xfe);
+            
serializer.writeNulTerminateString(MysqlHandshakePacket.AUTH_PLUGIN_NAME);
+            serializer.writeBytes(authPluginData);

Review Comment:
   authPluginData could be null, should we handle it before write?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to