Merge pull request #3634 from stintel/mysql-revoke-grant-option

Only revoke GRANT OPTION when user actually has it
This commit is contained in:
Michael DeHaan 2013-08-01 17:04:54 -07:00
commit 5fbb82fd15

View file

@ -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):