Skip to content

MDEV-8628 Expand current_user In binlog For GRANT/REVOKE/RENAME/DROPU…#5162

Draft
LukeYL026 wants to merge 1 commit into
MariaDB:mainfrom
LukeYL026:mdev-8628-current-user-binlog
Draft

MDEV-8628 Expand current_user In binlog For GRANT/REVOKE/RENAME/DROPU…#5162
LukeYL026 wants to merge 1 commit into
MariaDB:mainfrom
LukeYL026:mdev-8628-current-user-binlog

Conversation

@LukeYL026
Copy link
Copy Markdown

@LukeYL026 LukeYL026 commented Jun 1, 2026

Description

In MariaDB, non-deterministic DDL statements involving CURRENT_USER() or CURRENT_USER are only expanded for SET PASSWORD when stored into the binlog event body as statement. Other commands like GRANT remain non-deterministic, with unexpanded CURRENT_USER.

While replication remains unaffected — the slave can resolve CURRENT_USER using metadata in event headers — binlog statements should still be deterministic. When the binlog is replayed via mysqlbinlog | mysql, only the raw SQL statement is returned and metadata is lost, leaving an unresolved, and hence non-deterministic current_user in the statement.

SET PASSWORD is already correct — it constructs a new query string via sprintf with a rigid format SET PASSWORD FOR 'user'@'host' = 'hash'. The remaining commands can have CURRENT_USER appearing at arbitrary positions, making full query reconstruction impractical. String replacement is the pragmatic approach.

This patch introduces rewrite_query_expanding_current_user() in sql/sql_acl.cc — a helper that performs a case-insensitive replacement of standalone current_user (with optional parentheses) with the quoted 'user'@'host' from the session's security context. The helper is invoked before each affected write_bin_log() call site only when the statement's user list contains CURRENT_USER.

Affected statements:

  • GRANT
  • REVOKE
  • RENAME USER
  • DROP USER
  • ALTER USER
  • CREATE FUNCTION
  • CREATE PROCEDURE
  • CREATE TRIGGER
  • CREATE EVENT
  • CREATE VIEW
  • ALTER EVENT
  • ALTER VIEW

Release Notes

Binlog replay via mysqlbinlog | mysql now correctly handles all listed statements that reference CURRENT_USER. Previously these statements retained an unresolvable current_user in raw SQL.

How can this PR be tested?

New MTR test binlog.binlog_mdev8628 covers the following cases to confirm that CURRENT_USER in the binlog event body is resolved to the actual 'user'@'host' value:

  • Lowercase current_user without parentheses
  • Uppercase CURRENT_USER() with parentheses
  • Mixed case cUrReNt_UsEr
  • ALTER USER with CURRENT_USER
  • CURRENT_USER in a multi-user GRANT list
  • RENAME USER with CURRENT_USER on both sides
  • REVOKE ALL PRIVILEGES with CURRENT_USER
  • GRANT/REVOKE role with CURRENT_USER (mysql_grant_role path)
  • GRANT/REVOKE on a procedure with CURRENT_USER (mysql_routine_grant path)
  • SET PASSWORD with CURRENT_USER (regression guard — was already correct before this fix)
  • Host-specific user ('u1'@'127.0.0.1') to confirm the host is also expanded correctly
  • All existing MTR tests pass, confirming no regressions.

Basing the PR against the correct MariaDB version

This fix targets the binlog writing path in sql/sql_acl.cc and applies to all supported versions where the bug is present.

Copyright

All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses MDEV-8628 by expanding the literal CURRENT_USER keyword to the actual 'user'@'host' in the binlog for statements like GRANT, REVOKE, RENAME USER, DROP USER, and ALTER USER. The review feedback identifies two critical issues in the query rewriting logic: a potential out-of-bounds read when a backslash is at the end of a quoted string, and a recommendation to use the existing append_user helper to safely format the user and host strings while avoiding null pointer dereferences.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread sql/sql_acl.cc Outdated
Comment thread sql/sql_acl.cc Outdated
@LukeYL026 LukeYL026 marked this pull request as draft June 1, 2026 22:17
@LukeYL026 LukeYL026 force-pushed the mdev-8628-current-user-binlog branch from 57a9d62 to 147b001 Compare June 1, 2026 22:28
…SER/ALTERUSER

When GRANT, REVOKE, RENAME USER, DROP USER, or ALTER USER reference
CURRENT_USER, the binlog stores the raw SQL with the literal keyword
rather than the resolved 'user'@'host' value. Live replication works
because the slave SQL thread reads Q_INVOKER metadata from the binary
event to resolve CURRENT_USER correctly. However, when the binlog is
replayed via mysqlbinlog | mysql, the metadata is lost and CURRENT_USER
resolves to whoever runs the replay client, producing wrong results.

Fix by replacing CURRENT_USER with the expanded 'user'@'host' in the
SQL text before writing to the binlog. Unlike SET PASSWORD which has a
rigid fixed format (SET PASSWORD FOR 'user'@'host' = 'hash') and can
reconstruct the entire query via sprintf, statements like GRANT and
REVOKE have variable syntax with CURRENT_USER appearing at arbitrary
positions in multi-user lists, optional clauses, and different grant
targets. A text replacement helper is needed to handle this without
reconstructing the full query for each statement type.

The helper scans the query string, skips quoted literals, and performs
a case-insensitive replacement of standalone current_user (with
optional parentheses). It is called at each affected write_bin_log()
call site only when the statement's user list contains CURRENT_USER,
adding zero overhead to the common case.

All new code of the whole pull request, including one or several files that are
either new files or modified ones, are contributed under the BSD-new license. I
am contributing on behalf of my employer Amazon Web Services, Inc.
@LukeYL026 LukeYL026 force-pushed the mdev-8628-current-user-binlog branch from 147b001 to 9ca9b2e Compare June 1, 2026 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants