Only revoke GRANT OPTION when user actually has it
When revoking privileges from a user, the GRANT OPTION is always revoked, even if the user doesn't have it. If the user exists, this doesn't give an error, but if the user doesn't exist, it does: mysql> GRANT ALL ON test.* TO 'test'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> REVOKE GRANT OPTION ON test.* FROM 'test'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> REVOKE GRANT OPTION ON test.* FROM 'test'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> REVOKE ALL ON test.* FROM 'test'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> REVOKE GRANT OPTION ON test.* FROM 'test'@'localhost'; ERROR 1141 (42000): There is no such grant defined for user 'test' on host 'localhost' Additionally, in MySQL 5.6 this breaks replication because of http://bugs.mysql.com/bug.php?id=68892. Rather than revoking the GRANT OPTION and catching the error, check if the user actually has it and only revoke it when he does.
This commit is contained in:
parent
d1effecb2e
commit
9d0fc0fd67
1 changed files with 10 additions and 11 deletions
|
@ -144,6 +144,7 @@ def user_add(cursor, user, host, password, new_priv):
|
||||||
|
|
||||||
def user_mod(cursor, user, host, password, new_priv):
|
def user_mod(cursor, user, host, password, new_priv):
|
||||||
changed = False
|
changed = False
|
||||||
|
grant_option = False
|
||||||
|
|
||||||
# Handle passwords.
|
# Handle passwords.
|
||||||
if password is not None:
|
if password is not None:
|
||||||
|
@ -162,9 +163,12 @@ def user_mod(cursor, user, host, password, new_priv):
|
||||||
# If the user has privileges on a db.table that doesn't appear at all in
|
# If the user has privileges on a db.table that doesn't appear at all in
|
||||||
# the new specification, then revoke all privileges on it.
|
# the new specification, then revoke all privileges on it.
|
||||||
for db_table, priv in curr_priv.iteritems():
|
for db_table, priv in curr_priv.iteritems():
|
||||||
|
# If the user has the GRANT OPTION on a db.table, revoke it first.
|
||||||
|
if "GRANT" in priv:
|
||||||
|
grant_option = True
|
||||||
if db_table not in new_priv:
|
if db_table not in new_priv:
|
||||||
if user != "root" and "PROXY" not in priv:
|
if user != "root" and "PROXY" not in priv:
|
||||||
privileges_revoke(cursor, user,host,db_table)
|
privileges_revoke(cursor, user,host,db_table,grant_option)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
# If the user doesn't currently have any privileges on a db.table, then
|
# If the user doesn't currently have any privileges on a db.table, then
|
||||||
|
@ -180,7 +184,7 @@ def user_mod(cursor, user, host, password, new_priv):
|
||||||
for db_table in db_table_intersect:
|
for db_table in db_table_intersect:
|
||||||
priv_diff = set(new_priv[db_table]) ^ set(curr_priv[db_table])
|
priv_diff = set(new_priv[db_table]) ^ set(curr_priv[db_table])
|
||||||
if (len(priv_diff) > 0):
|
if (len(priv_diff) > 0):
|
||||||
privileges_revoke(cursor, user,host,db_table)
|
privileges_revoke(cursor, user,host,db_table,grant_option)
|
||||||
privileges_grant(cursor, user,host,db_table,new_priv[db_table])
|
privileges_grant(cursor, user,host,db_table,new_priv[db_table])
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
@ -243,17 +247,12 @@ def privileges_unpack(priv):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def privileges_revoke(cursor, user,host,db_table):
|
def privileges_revoke(cursor, user,host,db_table,grant_option):
|
||||||
|
if grant_option:
|
||||||
|
query = "REVOKE GRANT OPTION ON %s FROM '%s'@'%s'" % (db_table,user,host)
|
||||||
|
cursor.execute(query)
|
||||||
query = "REVOKE ALL PRIVILEGES ON %s FROM '%s'@'%s'" % (db_table,user,host)
|
query = "REVOKE ALL PRIVILEGES ON %s FROM '%s'@'%s'" % (db_table,user,host)
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
query = "REVOKE GRANT OPTION ON %s FROM '%s'@'%s'" % (db_table,user,host)
|
|
||||||
try:
|
|
||||||
cursor.execute(query)
|
|
||||||
except MySQLdb.OperationalError, e:
|
|
||||||
# 1141 -> There is no such grant defined for user ... on host ...
|
|
||||||
# If this exception is raised, there is no need to revoke the GRANT privilege
|
|
||||||
if e.args[0] != 1141 or not e.args[1].startswith("There is no such grant defined for user"):
|
|
||||||
raise e
|
|
||||||
|
|
||||||
def privileges_grant(cursor, user,host,db_table,priv):
|
def privileges_grant(cursor, user,host,db_table,priv):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue