This is an automated email from the ASF dual-hosted git repository. ramackri pushed a commit to branch RANGER-5736-patch in repository https://gitbox.apache.org/repos/asf/ranger.git
commit 6f5e78b6805e225bcf599bef31209ce26f9dc503 Author: ramk <[email protected]> AuthorDate: Tue Aug 11 12:13:16 2026 +0530 RANGER-5736: Fix MariaDB grant failure during Ranger Admin DB setup MariaDB returns error 1133 when dba_script.py grants privileges to a host-specific user after wildcard grants with FLUSH PRIVILEGES. Detect MariaDB at runtime and adjust grant order, flush timing, and retry logic without changing behavior for Oracle MySQL or other DB flavors. Co-authored-by: Cursor <[email protected]> --- security-admin/scripts/dba_script.py | 154 ++++++++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 39 deletions(-) diff --git a/security-admin/scripts/dba_script.py b/security-admin/scripts/dba_script.py index 739418566..fb8252de5 100644 --- a/security-admin/scripts/dba_script.py +++ b/security-admin/scripts/dba_script.py @@ -176,6 +176,23 @@ def __init__(self, host,SQL_CONNECTOR_JAR,JAVA_BIN,db_ssl_enabled,db_ssl_require self.javax_net_ssl_keyStorePassword=javax_net_ssl_keyStorePassword self.javax_net_ssl_trustStore=javax_net_ssl_trustStore self.javax_net_ssl_trustStorePassword=javax_net_ssl_trustStorePassword + self.is_mariadb = None + + def detect_server_type(self, get_cmd, db_root_password): + if self.is_mariadb is not None: + return self.is_mariadb + if is_unix: + query = get_cmd + " -query \"SELECT version();\"" + elif os_name == "WINDOWS": + query = get_cmd + " -query \"SELECT version();\" -c ;" + jisql_log(query, db_root_password) + output = check_output(query).lower() + self.is_mariadb = "mariadb" in output + if self.is_mariadb: + log("[I] Detected MariaDB server", "info") + else: + log("[I] Detected MySQL-compatible server (non-MariaDB)", "info") + return self.is_mariadb def get_jisql_cmd(self, user, password ,db_name): #TODO: User array for forming command @@ -199,6 +216,87 @@ def get_jisql_cmd(self, user, password ,db_name): jisql_cmd = "%s %s -cp %s;%s\\jisql\\lib\\* org.apache.util.sql.Jisql -driver mysqlconj -cstring jdbc:mysql://%s/%s%s -u %s -p \"%s\" -noheader -trim" %(self.JAVA_BIN, db_ssl_cert_param,self.SQL_CONNECTOR_JAR, path, self.host, db_name,db_ssl_param,user, password) return jisql_cmd + def mysql_user_hosts(self): + if self.host == "localhost": + return ["%", "localhost"] + if self.is_mariadb is True: + # Grant db_host before FLUSH from wildcard/localhost grants (MariaDB docker init issue). + return [self.host, "%", "localhost"] + return ["%", "localhost", self.host] + + def recreate_mysql_user(self, root_user, db_root_password, db_user, db_password, host, get_cmd, dryMode): + if dryMode == False: + log("[I] Recreating MySQL user " + db_user + " for host " + host, "info") + if is_unix: + query = get_cmd + " -query \"drop user if exists '%s'@'%s';\"" %(db_user, host) + jisql_log(query, db_root_password) + subprocessCallWithRetry(shlex.split(query)) + if db_password == "": + query = get_cmd + " -query \"create user '%s'@'%s';\"" %(db_user, host) + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(shlex.split(query)) + else: + query = get_cmd + " -query \"create user '%s'@'%s' identified by '%s';\"" %(db_user, host, db_password) + query_with_masked_pwd = get_cmd + " -query \"create user '%s'@'%s' identified by '%s';\"" %(db_user, host, masked_pwd_string) + jisql_log(query_with_masked_pwd, db_root_password) + ret = subprocessCallWithRetry(shlex.split(query)) + elif os_name == "WINDOWS": + query = get_cmd + " -query \"drop user if exists '%s'@'%s';\" -c ;" %(db_user, host) + jisql_log(query, db_root_password) + subprocessCallWithRetry(query) + if db_password == "": + query = get_cmd + " -query \"create user '%s'@'%s';\" -c ;" %(db_user, host) + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(query) + else: + query = get_cmd + " -query \"create user '%s'@'%s' identified by '%s';\" -c ;" %(db_user, host, db_password) + query_with_masked_pwd = get_cmd + " -query \"create user '%s'@'%s' identified by '%s';\" -c ;" %(db_user, host, masked_pwd_string) + jisql_log(query_with_masked_pwd, db_root_password) + ret = subprocessCallWithRetry(query) + if ret != 0: + return False + return self.verify_user(root_user, db_root_password, host, db_user, get_cmd, dryMode) + + def grant_mysql_user_on_db(self, get_cmd, db_root_password, db_name, db_user, db_password, host, root_user, dryMode, retry_on_failure): + if dryMode == False: + log("[I] ---------- Granting privileges TO user '"+db_user+"'@'"+host+"' on db '"+db_name+"'----------" , "info") + if is_unix: + query = get_cmd + " -query \"grant all privileges on %s.* to '%s'@'%s' with grant option;\"" %(db_name,db_user, host) + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(shlex.split(query)) + elif os_name == "WINDOWS": + query = get_cmd + " -query \"grant all privileges on %s.* to '%s'@'%s' with grant option;\" -c ;" %(db_name,db_user, host) + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(query) + if ret != 0 and retry_on_failure: + log("[I] Grant failed for '" + db_user + "'@'" + host + "', recreating user and retrying", "info") + if not self.recreate_mysql_user(root_user, db_root_password, db_user, db_password, host, get_cmd, dryMode): + return False + if is_unix: + ret = subprocessCallWithRetry(shlex.split(query)) + elif os_name == "WINDOWS": + ret = subprocessCallWithRetry(query) + if ret != 0: + return False + log("[I] Privileges granted to '" + db_user + "' on '"+db_name+"'", "info") + else: + logFile("grant all privileges on %s.* to '%s'@'%s' with grant option;" %(db_name,db_user, host)) + return True + + def flush_mysql_privileges(self, get_cmd, db_root_password, db_user, db_name): + log("[I] ---------- FLUSH PRIVILEGES ----------" , "info") + if is_unix: + query = get_cmd + " -query \"FLUSH PRIVILEGES;\"" + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(shlex.split(query)) + elif os_name == "WINDOWS": + query = get_cmd + " -query \"FLUSH PRIVILEGES;\" -c ;" + jisql_log(query, db_root_password) + ret = subprocessCallWithRetry(query) + if ret != 0: + log("[E] Granting privileges to '" +db_user+"' failed on '"+db_name+"'", "error") + sys.exit(1) + def verify_user(self, root_user, db_root_password, host, db_user, get_cmd,dryMode): if dryMode == False: log("[I] Verifying user " + db_user+ " for Host "+ host, "info") @@ -222,8 +320,9 @@ def check_connection(self, db_name, db_user, db_password): query = get_cmd + " -query \"SELECT version();\" -c ;" jisql_log(query, db_password) output = check_output(query) - if output.strip('Production |'): - #log("[I] Checking connection passed.", "info") + if output.strip('Production |') or output.strip(): + if self.is_mariadb is None: + self.is_mariadb = "mariadb" in output.lower() return True else: log("[E] Can't establish db connection.. Exiting.." ,"error") @@ -231,8 +330,7 @@ def check_connection(self, db_name, db_user, db_password): def create_rangerdb_user(self, root_user, db_user, db_password, db_root_password,dryMode): if self.check_connection('mysql', root_user, db_root_password): - hosts_arr =["%", "localhost"] - if not self.host == "localhost": hosts_arr.append(self.host) + hosts_arr = self.mysql_user_hosts() for host in hosts_arr: get_cmd = self.get_jisql_cmd(root_user, db_root_password, 'mysql') if self.verify_user(root_user, db_root_password, host, db_user, get_cmd,dryMode): @@ -329,40 +427,19 @@ def create_db(self, root_user, db_root_password, db_name, db_user, db_password,d def grant_xa_db_user(self, root_user, db_name, db_user, db_password, db_root_password, is_revoke,dryMode): - hosts_arr =["%", "localhost"] - if not self.host == "localhost": hosts_arr.append(self.host) + get_cmd = self.get_jisql_cmd(root_user, db_root_password, 'mysql') + if dryMode == False: + self.detect_server_type(get_cmd, db_root_password) + hosts_arr = self.mysql_user_hosts() + retry_on_failure = self.is_mariadb is True for host in hosts_arr: - if dryMode == False: - log("[I] ---------- Granting privileges TO user '"+db_user+"'@'"+host+"' on db '"+db_name+"'----------" , "info") - get_cmd = self.get_jisql_cmd(root_user, db_root_password, 'mysql') - if is_unix: - query = get_cmd + " -query \"grant all privileges on %s.* to '%s'@'%s' with grant option;\"" %(db_name,db_user, host) - jisql_log(query, db_root_password) - ret = subprocessCallWithRetry(shlex.split(query)) - elif os_name == "WINDOWS": - query = get_cmd + " -query \"grant all privileges on %s.* to '%s'@'%s' with grant option;\" -c ;" %(db_name,db_user, host) - jisql_log(query, db_root_password) - ret = subprocessCallWithRetry(query) - if ret == 0: - log("[I] ---------- FLUSH PRIVILEGES ----------" , "info") - if is_unix: - query = get_cmd + " -query \"FLUSH PRIVILEGES;\"" - jisql_log(query, db_root_password) - ret = subprocessCallWithRetry(shlex.split(query)) - elif os_name == "WINDOWS": - query = get_cmd + " -query \"FLUSH PRIVILEGES;\" -c ;" - jisql_log(query, db_root_password) - ret = subprocessCallWithRetry(query) - if ret == 0: - log("[I] Privileges granted to '" + db_user + "' on '"+db_name+"'", "info") - else: - log("[E] Granting privileges to '" +db_user+"' failed on '"+db_name+"'", "error") - sys.exit(1) - else: - log("[E] Granting privileges to '" +db_user+"' failed on '"+db_name+"'", "error") - sys.exit(1) - else: - logFile("grant all privileges on %s.* to '%s'@'%s' with grant option;" %(db_name,db_user, host)) + if not self.grant_mysql_user_on_db(get_cmd, db_root_password, db_name, db_user, db_password, host, root_user, dryMode, retry_on_failure): + log("[E] Granting privileges to '" +db_user+"' failed on '"+db_name+"'", "error") + sys.exit(1) + if dryMode == False and self.is_mariadb is not True: + self.flush_mysql_privileges(get_cmd, db_root_password, db_user, db_name) + if dryMode == False and self.is_mariadb is True: + self.flush_mysql_privileges(get_cmd, db_root_password, db_user, db_name) def create_auditdb_user(self, xa_db_host, audit_db_host, db_name, audit_db_name, xa_db_root_user, audit_db_root_user, db_user, audit_db_user, xa_db_root_password, audit_db_root_password, db_password, audit_db_password, DBA_MODE,dryMode): is_revoke=False @@ -375,8 +452,7 @@ def create_auditdb_user(self, xa_db_host, audit_db_host, db_name, audit_db_name, def writeDrymodeCmd(self, xa_db_host, audit_db_host, xa_db_root_user, xa_db_root_password, db_user, db_password, db_name, audit_db_root_user, audit_db_root_password, audit_db_user, audit_db_password, audit_db_name): logFile("# Login to MySQL Server from a MySQL dba user(i.e 'root') to execute below sql statements.") - hosts_arr =["%", "localhost"] - if not self.host == "localhost": hosts_arr.append(self.host) + hosts_arr = self.mysql_user_hosts() for host in hosts_arr: logFile("create user '%s'@'%s' identified by '%s';" %(db_user, host, db_password)) logFile("create database %s;"%(db_name))
