Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
b34227ce
Commit
b34227ce
authored
May 29, 2009
by
Kristofer Pettersson
Browse files
Options
Browse Files
Download
Plain Diff
Automerge
parents
b674d2c9
66e0ee66
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
221 additions
and
69 deletions
+221
-69
mysql-test/r/grant.result
mysql-test/r/grant.result
+55
-0
mysql-test/t/grant.test
mysql-test/t/grant.test
+54
-0
sql/sp.cc
sql/sp.cc
+15
-13
sql/sp.h
sql/sp.h
+2
-2
sql/sql_acl.cc
sql/sql_acl.cc
+42
-40
sql/sql_acl.h
sql/sql_acl.h
+2
-2
sql/sql_class.cc
sql/sql_class.cc
+19
-10
sql/sql_class.h
sql/sql_class.h
+29
-1
sql/sql_parse.cc
sql/sql_parse.cc
+3
-1
No files found.
mysql-test/r/grant.result
View file @
b34227ce
...
...
@@ -1358,3 +1358,58 @@ DROP USER 'userbug33464'@'localhost';
USE test;
DROP DATABASE dbbug33464;
SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
CREATE USER user1;
CREATE USER user2;
GRANT CREATE ON db1.* TO 'user1'@'localhost';
GRANT CREATE ROUTINE ON db1.* TO 'user1'@'localhost';
GRANT CREATE ON db1.* TO 'user2'@'%';
GRANT CREATE ROUTINE ON db1.* TO 'user2'@'%';
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'user1'@'localhost';
Grants for user1@localhost
GRANT USAGE ON *.* TO 'user1'@'localhost'
GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost'
** Connect as user1 and create a procedure.
** The creation will imply implicitly assigned
** EXECUTE and ALTER ROUTINE privileges to
** the current user user1@localhost.
SELECT @@GLOBAL.sql_mode;
@@GLOBAL.sql_mode
SELECT @@SESSION.sql_mode;
@@SESSION.sql_mode
CREATE DATABASE db1;
CREATE PROCEDURE db1.proc1(p1 INT)
BEGIN
SET @x = 0;
REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
END ;||
** Connect as user2 and create a procedure.
** Implicitly assignment of privileges will
** fail because the user2@localhost is an
** unknown user.
CREATE PROCEDURE db1.proc2(p1 INT)
BEGIN
SET @x = 0;
REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
END ;||
Warnings:
Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges
SHOW GRANTS FOR 'user1'@'localhost';
Grants for user1@localhost
GRANT USAGE ON *.* TO 'user1'@'localhost'
GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost'
GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `db1`.`proc1` TO 'user1'@'localhost'
SHOW GRANTS FOR 'user2';
Grants for user2@%
GRANT USAGE ON *.* TO 'user2'@'%'
GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user2'@'%'
DROP PROCEDURE db1.proc1;
DROP PROCEDURE db1.proc2;
REVOKE ALL ON db1.* FROM 'user1'@'localhost';
REVOKE ALL ON db1.* FROM 'user2'@'%';
DROP USER 'user1';
DROP USER 'user1'@'localhost';
DROP USER 'user2';
DROP DATABASE db1;
mysql-test/t/grant.test
View file @
b34227ce
...
...
@@ -1471,5 +1471,59 @@ DROP DATABASE dbbug33464;
SET
@@
global
.
log_bin_trust_function_creators
=
@
old_log_bin_trust_function_creators
;
#
# Bug#44658 Create procedure makes server crash when user does not have ALL privilege
#
CREATE
USER
user1
;
CREATE
USER
user2
;
GRANT
CREATE
ON
db1
.*
TO
'user1'
@
'localhost'
;
GRANT
CREATE
ROUTINE
ON
db1
.*
TO
'user1'
@
'localhost'
;
GRANT
CREATE
ON
db1
.*
TO
'user2'
@
'%'
;
GRANT
CREATE
ROUTINE
ON
db1
.*
TO
'user2'
@
'%'
;
FLUSH
PRIVILEGES
;
SHOW
GRANTS
FOR
'user1'
@
'localhost'
;
connect
(
con1
,
localhost
,
user1
,,);
--
echo
**
Connect
as
user1
and
create
a
procedure
.
--
echo
**
The
creation
will
imply
implicitly
assigned
--
echo
**
EXECUTE
and
ALTER
ROUTINE
privileges
to
--
echo
**
the
current
user
user1
@
localhost
.
SELECT
@@
GLOBAL
.
sql_mode
;
SELECT
@@
SESSION
.
sql_mode
;
CREATE
DATABASE
db1
;
DELIMITER
||
;
CREATE
PROCEDURE
db1
.
proc1
(
p1
INT
)
BEGIN
SET
@
x
=
0
;
REPEAT
SET
@
x
=
@
x
+
1
;
UNTIL
@
x
>
p1
END
REPEAT
;
END
;
||
DELIMITER
;
||
connect
(
con2
,
localhost
,
user2
,,);
--
echo
**
Connect
as
user2
and
create
a
procedure
.
--
echo
**
Implicitly
assignment
of
privileges
will
--
echo
**
fail
because
the
user2
@
localhost
is
an
--
echo
**
unknown
user
.
DELIMITER
||
;
CREATE
PROCEDURE
db1
.
proc2
(
p1
INT
)
BEGIN
SET
@
x
=
0
;
REPEAT
SET
@
x
=
@
x
+
1
;
UNTIL
@
x
>
p1
END
REPEAT
;
END
;
||
DELIMITER
;
||
connection
default
;
SHOW
GRANTS
FOR
'user1'
@
'localhost'
;
SHOW
GRANTS
FOR
'user2'
;
disconnect
con1
;
disconnect
con2
;
DROP
PROCEDURE
db1
.
proc1
;
DROP
PROCEDURE
db1
.
proc2
;
REVOKE
ALL
ON
db1
.*
FROM
'user1'
@
'localhost'
;
REVOKE
ALL
ON
db1
.*
FROM
'user2'
@
'%'
;
DROP
USER
'user1'
;
DROP
USER
'user1'
@
'localhost'
;
DROP
USER
'user2'
;
DROP
DATABASE
db1
;
# Wait till we reached the initial number of concurrent sessions
--
source
include
/
wait_until_count_sessions
.
inc
sql/sp.cc
View file @
b34227ce
...
...
@@ -1308,13 +1308,20 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
/**
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
the routines in 'routines'.
@param thd Thread handler
@param routines List of needles in the hay stack
@param any Any of the needles are good enough
@return
@retval FALSE Found.
@retval TRUE Not found
*/
int
sp_exist_routines
(
THD
*
thd
,
TABLE_LIST
*
routines
,
bool
any
,
bool
no_error
)
bool
sp_exist_routines
(
THD
*
thd
,
TABLE_LIST
*
routines
,
bool
any
)
{
TABLE_LIST
*
routine
;
bool
result
=
0
;
bool
sp_object_found
;
DBUG_ENTER
(
"sp_exists_routine"
);
for
(
routine
=
routines
;
routine
;
routine
=
routine
->
next_global
)
...
...
@@ -1336,21 +1343,16 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
if
(
sp_object_found
)
{
if
(
any
)
DBUG_RETURN
(
1
);
result
=
1
;
break
;
}
else
if
(
!
any
)
{
if
(
!
no_error
)
{
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION or PROCEDURE"
,
routine
->
table_name
);
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION or PROCEDURE"
,
routine
->
table_name
);
DBUG_RETURN
(
TRUE
);
}
}
DBUG_RETURN
(
result
);
DBUG_RETURN
(
FALSE
);
}
...
...
sql/sp.h
View file @
b34227ce
...
...
@@ -39,8 +39,8 @@ sp_head *
sp_find_routine
(
THD
*
thd
,
int
type
,
sp_name
*
name
,
sp_cache
**
cp
,
bool
cache_only
);
int
sp_exist_routines
(
THD
*
thd
,
TABLE_LIST
*
procs
,
bool
any
,
bool
no_error
);
bool
sp_exist_routines
(
THD
*
thd
,
TABLE_LIST
*
procs
,
bool
any
);
int
sp_routine_exists_in_table
(
THD
*
thd
,
int
type
,
sp_name
*
name
);
...
...
sql/sql_acl.cc
View file @
b34227ce
...
...
@@ -3198,26 +3198,24 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
/*
/*
*
Store routine level grants in the privilege tables
SYNOPSIS
mysql_routine_grant()
thd Thread handle
table_list List of routines to give grant
is_proc true indicates routine list are procedures
user_list List of users to give grant
rights Table level grant
revoke_grant Set to 1 if this is a REVOKE command
@param thd Thread handle
@param table_list List of routines to give grant
@param is_proc Is this a list of procedures?
@param user_list List of users to give grant
@param rights Table level grant
@param revoke_grant Is this is a REVOKE command?
RETURN
0 ok
1 error
@return
@retval FALSE Success.
@retval TRUE An error occurred.
*/
bool
mysql_routine_grant
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
bool
is_proc
,
List
<
LEX_USER
>
&
user_list
,
ulong
rights
,
bool
revoke_grant
,
bool
no_error
)
bool
revoke_grant
,
bool
write_to_binlog
)
{
List_iterator
<
LEX_USER
>
str_list
(
user_list
);
LEX_USER
*
Str
,
*
tmp_Str
;
...
...
@@ -3228,22 +3226,20 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if
(
!
initialized
)
{
if
(
!
no_error
)
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--skip-grant-tables"
);
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--skip-grant-tables"
);
DBUG_RETURN
(
TRUE
);
}
if
(
rights
&
~
PROC_ACLS
)
{
if
(
!
no_error
)
my_message
(
ER_ILLEGAL_GRANT_FOR_TABLE
,
ER
(
ER_ILLEGAL_GRANT_FOR_TABLE
),
MYF
(
0
));
my_message
(
ER_ILLEGAL_GRANT_FOR_TABLE
,
ER
(
ER_ILLEGAL_GRANT_FOR_TABLE
),
MYF
(
0
));
DBUG_RETURN
(
TRUE
);
}
if
(
!
revoke_grant
)
{
if
(
sp_exist_routines
(
thd
,
table_list
,
is_proc
,
no_error
)
<
0
)
if
(
sp_exist_routines
(
thd
,
table_list
,
is_proc
)
)
DBUG_RETURN
(
TRUE
);
}
...
...
@@ -3324,9 +3320,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
{
if
(
revoke_grant
)
{
if
(
!
no_error
)
my_error
(
ER_NONEXISTING_PROC_GRANT
,
MYF
(
0
),
Str
->
user
.
str
,
Str
->
host
.
str
,
table_name
);
my_error
(
ER_NONEXISTING_PROC_GRANT
,
MYF
(
0
),
Str
->
user
.
str
,
Str
->
host
.
str
,
table_name
);
result
=
TRUE
;
continue
;
}
...
...
@@ -3351,16 +3346,14 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
thd
->
mem_root
=
old_root
;
pthread_mutex_unlock
(
&
acl_cache
->
lock
);
if
(
!
result
&&
!
no_error
)
if
(
write_to_binlog
)
{
write_bin_log
(
thd
,
TRUE
,
thd
->
query
,
thd
->
query_length
);
}
rw_unlock
(
&
LOCK_grant
);
if
(
!
result
&&
!
no_error
)
my_ok
(
thd
);
/* Tables are automatically closed */
DBUG_RETURN
(
result
);
}
...
...
@@ -6157,21 +6150,20 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
}
/*
/*
*
Grant EXECUTE,ALTER privilege for a stored procedure
SYNOPSIS
sp_grant_privileges()
thd The current thread.
db DB of the stored procedure
name Name of the stored procedure
@param thd The current thread.
@param sp_db
@param sp_name
@param is_proc
RETURN
0 OK.
< 0 Error
. Error message not yet sent.
@return
@retval FALSE Success
@retval TRUE An error occured
. Error message not yet sent.
*/
int
sp_grant_privileges
(
THD
*
thd
,
const
char
*
sp_db
,
const
char
*
sp_name
,
bool
sp_grant_privileges
(
THD
*
thd
,
const
char
*
sp_db
,
const
char
*
sp_name
,
bool
is_proc
)
{
Security_context
*
sctx
=
thd
->
security_ctx
;
...
...
@@ -6181,6 +6173,7 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool
result
;
ACL_USER
*
au
;
char
passwd_buff
[
SCRAMBLED_PASSWORD_CHAR_LENGTH
+
1
];
Dummy_error_handler
error_handler
;
DBUG_ENTER
(
"sp_grant_privileges"
);
if
(
!
(
combo
=
(
LEX_USER
*
)
thd
->
alloc
(
sizeof
(
st_lex_user
))))
...
...
@@ -6231,8 +6224,11 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
}
else
{
my_error
(
ER_PASSWD_LENGTH
,
MYF
(
0
),
SCRAMBLED_PASSWORD_CHAR_LENGTH
);
return
-
1
;
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_PASSWD_LENGTH
,
ER
(
ER_PASSWD_LENGTH
),
SCRAMBLED_PASSWORD_CHAR_LENGTH
);
return
TRUE
;
}
combo
->
password
.
str
=
passwd_buff
;
}
...
...
@@ -6248,8 +6244,14 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
thd
->
lex
->
ssl_type
=
SSL_TYPE_NOT_SPECIFIED
;
bzero
((
char
*
)
&
thd
->
lex
->
mqh
,
sizeof
(
thd
->
lex
->
mqh
));
/*
Only care about whether the operation failed or succeeded
as all errors will be handled later.
*/
thd
->
push_internal_handler
(
&
error_handler
);
result
=
mysql_routine_grant
(
thd
,
tables
,
is_proc
,
user_list
,
DEFAULT_CREATE_PROC_ACLS
,
0
,
1
);
DEFAULT_CREATE_PROC_ACLS
,
FALSE
,
FALSE
);
thd
->
pop_internal_handler
();
DBUG_RETURN
(
result
);
}
...
...
sql/sql_acl.h
View file @
b34227ce
...
...
@@ -233,7 +233,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
bool
revoke
);
bool
mysql_routine_grant
(
THD
*
thd
,
TABLE_LIST
*
table
,
bool
is_proc
,
List
<
LEX_USER
>
&
user_list
,
ulong
rights
,
bool
revoke
,
bool
no_error
);
bool
revoke
,
bool
write_to_binlog
);
my_bool
grant_init
();
void
grant_free
(
void
);
my_bool
grant_reload
(
THD
*
thd
);
...
...
@@ -264,7 +264,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const
char
*
db
,
const
char
*
table
);
bool
sp_revoke_privileges
(
THD
*
thd
,
const
char
*
sp_db
,
const
char
*
sp_name
,
bool
is_proc
);
int
sp_grant_privileges
(
THD
*
thd
,
const
char
*
sp_db
,
const
char
*
sp_name
,
bool
sp_grant_privileges
(
THD
*
thd
,
const
char
*
sp_db
,
const
char
*
sp_name
,
bool
is_proc
);
bool
check_routine_level_acl
(
THD
*
thd
,
const
char
*
db
,
const
char
*
name
,
bool
is_proc
);
...
...
sql/sql_class.cc
View file @
b34227ce
...
...
@@ -674,31 +674,40 @@ THD::THD()
void
THD
::
push_internal_handler
(
Internal_error_handler
*
handler
)
{
/*
TODO: The current implementation is limited to 1 handler at a time only.
THD and sp_rcontext need to be modified to use a common handler stack.
*/
DBUG_ASSERT
(
m_internal_handler
==
NULL
);
m_internal_handler
=
handler
;
if
(
m_internal_handler
)
{
handler
->
m_prev_internal_handler
=
m_internal_handler
;
m_internal_handler
=
handler
;
}
else
{
m_internal_handler
=
handler
;
}
}
bool
THD
::
handle_error
(
uint
sql_errno
,
const
char
*
message
,
MYSQL_ERROR
::
enum_warning_level
level
)
{
if
(
m_internal_handler
)
if
(
!
m_internal_handler
)
return
FALSE
;
for
(
Internal_error_handler
*
error_handler
=
m_internal_handler
;
error_handler
;
error_handler
=
m_internal_handler
->
m_prev_internal_handler
)
{
return
m_internal_handler
->
handle_error
(
sql_errno
,
message
,
level
,
this
);
if
(
error_handler
->
handle_error
(
sql_errno
,
message
,
level
,
this
))
return
TRUE
;
}
return
FALSE
;
// 'FALSE', as per coding style
return
FALSE
;
}
void
THD
::
pop_internal_handler
()
{
DBUG_ASSERT
(
m_internal_handler
!=
NULL
);
m_internal_handler
=
NULL
;
m_internal_handler
=
m_internal_handler
->
m_prev_internal_handler
;
}
extern
"C"
...
...
sql/sql_class.h
View file @
b34227ce
...
...
@@ -1036,7 +1036,10 @@ show_system_thread(enum_thread_type thread)
class
Internal_error_handler
{
protected:
Internal_error_handler
()
{}
Internal_error_handler
()
:
m_prev_internal_handler
(
NULL
)
{}
virtual
~
Internal_error_handler
()
{}
public:
...
...
@@ -1069,6 +1072,28 @@ class Internal_error_handler
const
char
*
message
,
MYSQL_ERROR
::
enum_warning_level
level
,
THD
*
thd
)
=
0
;
private:
Internal_error_handler
*
m_prev_internal_handler
;
friend
class
THD
;
};
/**
Implements the trivial error handler which cancels all error states
and prevents an SQLSTATE to be set.
*/
class
Dummy_error_handler
:
public
Internal_error_handler
{
public:
bool
handle_error
(
uint
sql_errno
,
const
char
*
message
,
MYSQL_ERROR
::
enum_warning_level
level
,
THD
*
thd
)
{
/* Ignore error */
return
TRUE
;
}
};
...
...
@@ -2210,6 +2235,9 @@ class THD :public Statement,
thd_scheduler
scheduler
;
public
:
inline
Internal_error_handler
*
get_internal_handler
()
{
return
m_internal_handler
;
}
/**
Add an internal error handler to the thread execution context.
@param handler the exception handler to add
...
...
sql/sql_parse.cc
View file @
b34227ce
...
...
@@ -3880,7 +3880,9 @@ mysql_execute_command(THD *thd)
res
=
mysql_routine_grant
(
thd
,
all_tables
,
lex
->
type
==
TYPE_ENUM_PROCEDURE
,
lex
->
users_list
,
grants
,
lex
->
sql_command
==
SQLCOM_REVOKE
,
0
);
lex
->
sql_command
==
SQLCOM_REVOKE
,
TRUE
);
if
(
!
res
)
my_ok
(
thd
);
}
else
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment