You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ra...@apache.org on 2026/08/11 06:43:28 UTC

(ranger) 01/01: RANGER-5736: Fix MariaDB grant failure during Ranger Admin DB setup

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 <ra...@cloudera.com>
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 <cu...@cursor.com>
---
 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))