MYSQL Definer Issue - mysql

There is a very strange issue. I have one procedure with a definer named as admin.
There was a case where we had to remove the user "dbadlys". So in order to do so we updated the mysql.proc table with the new account "admin#%" before deletion of account dbadlys and did the flush privileges as well.
I also verified the definer name from information_schema.routines and I saw that new definer name is now admin#%.
Issue:
Even though the definer name was now updated to new name when the code was calling the procedure it was using the old definer name dbadlys and was giving the below error:
The user specified as a definer does not exist
Upon further investigation, I found out that when we reconnect the instance then there was no error, however if we change the definer name and try to execute the procedure again then it doesn't reflect it.
My questions:
Is there anything else which I need to do in this situation or am missing anything?
if there is nothing missing then is there a way that application should see the changes?
Should I restart the application server?

If you have dba privilege, try recreating the SP without definer.
Definers are optional, unless you have a very specific need you don't need to use them.

Related

can i generate a mysql trigger without a definer clause?

Question is dead simple. I want to add a trigger to my database, any simple one like:
CREATE TRIGGER before_user_update BEFORE UPDATE ON `users`
FOR EACH ROW
BEGIN
SET NEW.user_id = NEW.old_user_id_column;
END
Unfortunately when i do that i always get a DEFINER clause in the dump with host and username, which is very troublesome because i need to use this on different environments on which this definer will be completely different?
Is there any workaround?
I guess this question could be asked: how to use the same query trigger in multiple environments?
(im using rails)
I know i can just remove the definer part from the schema manually, but it will cause problems to my coworkers who are going to run a migration and still get the clause in their schema
No, you cannot create a trigger without the definer clause.
As mysql documentation on create trigger says:
If the DEFINER clause is omitted, the default definer is the user who executes the CREATE TRIGGER statement. This is the same as specifying DEFINER = CURRENT_USER explicitly.
So, even if you omit the definer, mysql will give you one. So, you either create the same mysql user across the different environments or you save the trigger code with DEFINER = CURRENT_USER. Unfortunately, when you run the create trigger code, mysql will substitute the current user's name into the definer clause.

Cursor in Mysql has other rights than user?

i have two databases, db1 and db2.
User man1 had all privileges to db1 but only executing provileges for all functions and procedures in db2.
Calling function db2.getValue from db1 is successful and returns correct values, also if call for db2.getValue is nested in a stored procedure.
Now i create a stored Procedure proc1 and within this procedure i use a cursor to fetch values (_val1, _val2,--) from a table in db1 and call db2.getValue(_val1).
Now somthing really strange happens:
The first loop from the cursor finish, but the value from db2.getValue is empty. At the end of this loop, the loop ends and stops.
Does anyone have a hint where the problem could be here? Calling db1.getValue(_val1) instead of db2.getValue(_val1) works fine.
Therefore my idea was that within the cursor, the privileges for db2 might be not the same?
Kind Regards Solick
Yes, by design, a cursor can behave differently than the same SELECT query might behave if it were executed by the user who called the procedure.
Stored programs and views are defined prior to use and, when referenced, execute within a security context that determines their privileges. These privileges are controlled by their DEFINER attribute, and, if there is one, their SQL SECURITY characteristic.
— http://dev.mysql.com/doc/refman/5.6/en/stored-programs-security.html
If you don't specify a DEFINER when you create a stored program (proc, function, trigger, or event) or a view, then the object, when accessed, runs with the privileges of the user who originally defined it, not the user who invoked it.
You have three options, here:
Verify or possibly modify the permissions of the current DEFINER user if appropriate; or,
Specify a different DEFINER user when defining the stored program or view... you can do this as long as you (the person creating the object) have the SUPER privilege, and users invoking (accessing) the object will temporarily have the rights of that DEFINER user instead; or,
Add SQL SECURITY INVOKER to the definition of procedures, functions, and views (though not triggers or events), causing the object to run with the privileges of the user who invoked it, instead of the definer, which is the default behavior.
To see the permissions the existing definer has, for example if you see DEFINER=`someguy`#`localhost`:
mysql> SHOW GRANTS FOR 'someguy'#'localhost';
You can find the current definer in the definition of the procedure, with SHOW CREATE PROCEDURE procedure_name;.

SUPER privilege(s) for this operation

I create my database and user navid in my shared server with cpanel (databases -> mySQL# Databases -> add new user),and then selected ALL PRIVILEGES for user navid.
I was importing mydatabase.sql when I was confronted with this error.
how do i fix the error? store procedure worked fine in localhost.
what is SUPER privilege?
Error
SQL query:
DELIMITER $$--
-- Procedures
--
CREATE DEFINER = `navid`#`%` PROCEDURE `d_answer` ( OUT `sp_out` INT( 11 ) , IN `sp_id` INT( 11 ) ) NO SQL BEGIN DELETE FROM `tblname` WHERE `a_id` = sp_id;
SET sp_out = ROW_COUNT( ) ;
END$$
MySQL said: Documentation
#1227 - Access denied; you need (at least one of) the SUPER privilege(s) for this operation
From the documentation (my emphasis):
The SUPER privilege enables an account to use CHANGE MASTER TO, KILL
or mysqladmin kill to kill threads belonging to other accounts (you
can always kill your own threads), PURGE BINARY LOGS, configuration
changes using SET GLOBAL to modify global system variables, the
mysqladmin debug command, enabling or disabling logging, performing
updates even if the read_only system variable is enabled, starting and
stopping replication on slave servers, specification of any account
in the DEFINER attribute of stored programs and views, and enables
you to connect (once) even if the connection limit controlled by the
max_connections system variable is reached.
Since you are already navid to the database, you do not need to set the DEFINER attribute in your stored procedure; adding this line is causing the error to show up. If you remove this statement, your procedure will be created and you won't get the permissions error.
You only need to set DEFINER if you are setting up the stored procedure for some other user, by default the stored procedure gets the same security context as the user that is creating it:
All stored programs (procedures, functions, and triggers) and views
can have a DEFINER attribute that names a MySQL account. If the
DEFINER attribute is omitted from a stored program or view definition,
the default account is the user who creates the object.
I got the problem too and fixed it thus in MySQL Workbench.
In my case it is because the "Send to SQL Editor > Create Statement" has extra stuff in there that prevents from being used without modification.
Something like this:
CREATE ALGORITHM=UNDEFINED DEFINER=schemax#localhost SQL
SECURITY DEFINER VIEW viewName AS SELECT ....
Change it to this:
CREATE VIEW viewName AS SELECT ....
Seems to work now, no need to update permissions.
**I am the only user of my database..
I had the same issue - on my local dev server it was fine but on my hosted server (through PHPMyAdmin) it gave me the above error.
Removing the definer attribute seemed to be the easiest way to fix the problem if you're happy with the definer being the current user.
just remove the DEFINER attribute and with it's value, example:
CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW ...
Don't rely on default values, if emptying the definer field in phpMyAdmin or other programs won't solve, check the definer, should not be username#localhost unless explicitly needed, but username#%.

Error 1449 in MySQL - Alternative Solutions?

Recently, I deleted a user account in MySQL assigned to my former boss. Then, some database functions like deleting records from tables he made weren't working, giving the following error:
#1449 - There is no '*username*'#'localhost' registered
Now, I added a new user with the same name (and diff. password) and it works fine with no errors. But, is there way to resolve this without an placeholder user account?
Try replacing the DEFINER of the function
First login to mysql as root#localhost
Then, substitute root#localhost as the DEFINER
UPDATE mysql.proc SET definer='root#localhost'
WHERE definer = '*username*#localhost';
In fact, you can look at all DEFINERs like this:
SELECT COUNT(1) DefinerCount,definer,type
FROM mysql.proc GROUP BY definer,type;
This will show you how many functions and procedures each user owns. If any other the reported DEFINERs no longer exist or are invalid, you can make root#localhost inherit them.
Give it a Try !!!
I had to remove and re-add the triggers for the affected tables. (I used phpMyAdmin to do this).

Mysql: How to set up properly a procedure call inside init_connect variable

I want to store the activity of each session user at very high level into a table.
I wrote a procedure "audit.login_trigger". I have created the schema needed(audit DB and Table). It is some thing like this.
CREATE PROCEDURE audit.login_trigger()
SQL SECURITY DEFINER
BEGIN
INSERT INTO audit.audit_connect (thread_id, user, login_ts)
VALUES (CONNECTION_ID(), USER(), NOW());
END;
I have place this inside "init_connect".
SET GLOBAL init_connect="CALL audit.login_trigger()";
I want this to be executed for every user connection. I gave EXECUTE privileges on this PROCEDURE to root user but when the root user logged in, it is not populating the audit schema as expected. What might went wrong here ?
Thanks in advance.
Since this user is named "root" I wonder if it has super privileges. If it does, then note that init_connect doesn't fire for super users.