I(with root account) create some procedure myproc which has some part of code below:
declare cur_uname varchar(20);
select substring_index(current_user(),'#', 1) into cur_uname;
Then I create another account abc#localhost with GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'abc'#'localhost';.
When I execute myproc under account abc#localhost,cur_uname is root but not abc. What should I address this problem?
CURRENT_USER():
Within a stored program or view, CURRENT_USER() returns the account for the user who defined the object (as given by its DEFINER value) unless defined with the SQL SECURITY INVOKER characteristic. In the latter case, CURRENT_USER() returns the object's invoker.
USER():
Returns the current MySQL user name and host name as a string in the utf8 character set. [...] The value indicates the user name you specified when connecting to the server, and the client host from which you connected. The value can be different from that of CURRENT_USER().
So I guess it all depends on the definition of "correct" that you need.
Related
I have an issues in that when i try to execute a stored procedure through my web application, i am shown the following error
SQLSTATE[42000]: Syntax error or access violation: 1142 INSERT command denied to user 'elitecareers_admin'#'%' for table 'user'
Here is my stored procedure just for clarity
DELIMITER $$
CREATE PROCEDURE `sp_create_account`( username_param VARCHAR(40), email_param VARCHAR(60), pass_w VARCHAR(30), category_id TINYINT )
BEGIN
DECLARE salt VARCHAR(60);
DECLARE password_var VARCHAR(128);
SET salt = 'ELiCrs#4$^7EC%?';
SET salt = CONCAT( username_param, salt );
SET password_var = SHA2( CONCAT( pass_w, salt ), 0 );
INSERT INTO elite.user
( user_id, username, email, pass, active, date_joined, user_category_id )
VALUES
( DEFAULT, username_param, email_param, password_var, DEFAULT, DEFAULT, category_id );
END $$
DELIMITER ;
and here is how the stored procedure looks when i run the show command
Here is my server information too
Here are the privileges for the user 'elitecareers_admin'#'%' under which the web application is executing
What i don't understand if the user has all privileges on the database, then why does mysql/maria server keeping those errors?
"The SQL SECURITY characteristic can be DEFINER or INVOKER to specify the security context; that is, whether the routine executes using the privileges of the account named in the routine DEFINER clause or the user who invokes it. This account must have permission to access the database with which the routine is associated. The default value is DEFINER. The user who invokes the routine must have the EXECUTE privilege for it, as must the DEFINER account if the routine executes in definer security context. " -- https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
So, regardless of who runs the proc, the permissions for 'elitecareers_admin'#'%' will be used for things such as accessing the table elite.user. But that user seems to have privileges only to the database elitecareers\_elite.
Plan A: Recreate the proc with SQL SECURITY INVOKER if that is appropriate.
Plan B: Figure out the difference between databases elite and elitecareers\_elite.
Plan C: Add another GRANT to let that admin get to elite.
Plan D: (There are probably other solutions.)
Calling a stored procedure results in this exception:
SQLException1 java.sql.SQLException: User does not have access to
metadata required to determine stored procedure parameter types. If
rights can not be granted, configure connection with
"noAccessToProcedureBodies=true" to have driver generate parameters
that represent INOUT strings irregardless of actual parameter types.
To resolve this, I tried:
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306
/database?useInformationSchema=true&noAccessToProcedureBodies=true",
"user_name", "pasword");
But it still does not work.
I am using shared hosting.
I am using
Software version: 5.0.91-community-log - MySQL Community Edition (GPL)
Protocol version: 10
Java 1.6
mysql-connector-java-5.1.14-bin.jar
One of my stored procedures is:
DROP PROCEDURE IF EXISTS `share_message`
DELIMITER //
CREATE PROCEDURE share_message(in messageid1 int(200),in received_by1 int(20),
in sent_by1 int(20),in shared_of1 int(20),author1 int(20), OUT query_status1 TINYINT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- ERROR
SET query_status1 = -1;
rollback;
END;
DECLARE EXIT HANDLER FOR SQLWARNING
BEGIN
-- WARNING
SET query_status1 = -1;
rollback;
END;
START TRANSACTION;
SET query_status1 = 0;
INSERT INTO post_message_users(messageid,received_by,sent_by,shared_of,author)
VALUES(messageid1,received_by1,sent_by1,shared_of1,author1);
UPDATE post_messages SET total_share=total_share+1 WHERE messageid=messageid1;
SET query_status1 =1;
COMMIT;
END//
DELIMITER ;
This is working properly with my local database.
It seems that the stored procedure you are attempting to use needs access to MySQL's INFORMATION_SCHEMA. That's a (fake) database built in every MySQL server; it's used to fetch descriptions of tables, columns, indexes, and the like.
It looks like the user id you're using doesn't have access to the INFORMATION_SCHEMA. That's understandable on a hosting service.
Go on MyPhpAdmin and try a query like this to be sure about that.
SELECT table_schema, table_name
FROM information_schema.columns
WHERE column_name = 'something'
AND table_schema = 'your database name'
If you get some kind of error saying you don't have permission, this is definitely your problem.
You could try rewriting your stored proc, or you could ask your hosting service to grant you the appropriate priv.
TLDR; Change your Java code, make the CallableStatement reference parameters by index instead of name.
After having a similar problem I updated my JDBC driver mysql-connector-java-5.1.26-bin.jar.
The error then changed from
User does not have access to metadata required to determine stored
procedure parameter types. If rights can not be granted, configure
connection with "noAccessToProcedureBodies=true" to have driver
generate parameters that represent INOUT strings irregardless of
actual parameter types.
to
No access to parameters by name when connection has been configured not to access procedure bodies
I changed my Callable Statement to reference parameters by index instead of name, and hey presto it works.
Updating the driver may not be necessary, just knowing to use indexes instead of names when you don't have metadata access or routine body access.
Good Luck
I'm dipping my toe into using stored functions with MySQL and am having trouble.
Having created a function and tested it, I don't seem to be able to allow other users to execute it. From the documentation, it seems that I need to grant EXECUTE access to the other users, but that doesn't appear to be sufficient.
I've put together a couple of scripts that I believe demonstrate the problem:
# This script creates two databases with a stored function in each.
#
# On one database, tester in granted all privileges.
# On the other, tester only gets a few.
#
# We want to find the minimum privileges required to allow tester to execute the
# stored function.
#
# This script must be run by an administrative user, i.e. root
CREATE DATABASE test1;
DELIMITER $$
CREATE FUNCTION test1.foo () RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
RETURN ('garp');
END$$
DELIMITER ;
GRANT ALL PRIVILEGES ON test1.* TO 'tester'#'localhost';
#
CREATE DATABASE test2;
DELIMITER $$
CREATE FUNCTION test2.foo () RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
RETURN ('garp');
END$$
DELIMITER ;
GRANT EXECUTE ON PROCEDURE test2.foo TO 'tester'#'localhost';
and
# This script tests whether tester can access the stored functions
#
# It should be executed by tester
SELECT 'test1.foo(): ', test1.foo ();
SELECT 'test2.foo(): ', test2.foo ();
When I run execute the second script, I get an error:
$ mysql --user=tester --password=tester --skip-column-names < testScript2.sql
test1.foo(): garp
ERROR 1370 (42000) at line 6: execute command denied to user 'tester'#'localhost' for routine 'test2.foo'
I have no doubt that I'm missing something obvious, but I can't see what that is. I imagine that I've got something wrong in the GRANT EXECUTE... statement in the first script, and am deeply suspicious of my use of single quotes, but I recall trying most of the combinations of placement and inclusion of single quotes without success.
I'd be really grateful to anyone who can point out my error.
For reference, I'm running Server version: 5.1.67-0ubuntu0.10.04.1 (Ubuntu) (on Ubuntu!).
Thanks
test2.foo is a function not a procedure.
Try:
GRANT EXECUTE ON FUNCTION test2.foo TO 'tester'#'localhost';
(I was able to reproduce the problem locally and confirm that this change works.)
I tried finding an answer to this online, but could not find any clear explanation:
Does the # in a stored procedure serve some sort of special purpose/signify something in particular? I am a little confused as to when we use it, since examples seem to vary on its usage.
For instance in the following example # is used:
DELIMITER $
DROP PROCEDURE IF EXISTS emp_count_2;
CREATE PROCEDURE emp_count_2(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM Employee;
END
$
DELIMITER ;
/* To invoke this procedure use the mysql command statement
CALL emp_count_2(#empCount);
SELECT #empCount;
*/
Once again, does the # in this example serve some sort of special purpose, or can we remove the # and just use normal variable names?
**EDIT: I am using MySql
The #variable syntax in MySQL denotes a user-defined session variable. You can set these user variables outside a stored procedure, but you can also set them inside a stored procedure, and the effect is that the variable retains the value after your procedure call returns.
So in your example, the following would also do the same thing:
CREATE PROCEDURE emp_count_2()
BEGIN
SELECT COUNT(*) INTO #empCount FROM Employee;
END
CALL emp_count_2(); /* sets #empCount as a side-effect */
SELECT #empCount;
It's okay for multiple sessions to set the user variable in this way concurrently, because user variables are scoped to a single session, and concurrent sessions may have variables of the same name, but with different values.
The variable syntax with no # prefix is for variables local to the procedure, either procedure parameters, or else local variables declared with DECLARE within the procedure body.
This usage you have, passing a user variable as a parameter and assigning it in the body of the procedure, is useful if you want to call a procedure several times and store the result in separate user variables. Otherwise each call to the procedure would overwrite the previous value in the #empCount user variable for the current session.
I have created an AWS RDS instance, I have created my master user with master password, and it is working/connecting fine.
But when I am going to create a function on that instance, it shows me the following error:
ERROR 1418: This function has none of DETERMINISTIC, NO SQL,
or READS SQL DATA in its declaration and binary logging is enabled
(you might want to use the less safe log_bin_trust_function_creator variable).
In my instance the variable log_bin_trust_function_creators shows OFF, and if I try to change the variable using SET GLOBAL log_bin_trust_function_creators = 1;, it gives me another error "Error Code: 1227. Access denied; you need (at least one of) the SUPER privilege(s) for this operation"
Set log_bin_trust_function_creators = 1 for Parameter group of the RDS instance.
Note: Default Parameter-Group is not editable. Create a new Parameter-Group and assign it to the RDS instance by modifying it from UI (AWS Admin Console) OR maybe using commands
DELIMITER $$
CREATE DEFINER=`DB_USERNAME_HERE`#`%` FUNCTION `GetDistance`(coordinate1 VARCHAR(120), coordinate2 VARCHAR(120)) RETURNS decimal(12,8)
READS SQL DATA
BEGIN
DECLARE distance DECIMAL(12,8);
/*Business logic goes here for the function*/
RETURN distance;
END $$
DELIMITER ;
Here, you have to replace DB_USERNAME_HERE with you RDS database username and function names according to you need.
Important thing is: DEFINER=`DB_USERNAME_HERE`#`%`
This was the problem I was facing after setting log_bin_trust_function_creators = 1 in parameter group. And it worked like a charm.
A better way is to apply your own parameter group, with log_bin_trust_function_creators set to true. (its false by default)
This happens when you try to create a procedure/function/view with a DEFINER that is not the current user.
To solve this remove or update the DEFINER clause.