i was wondering if there is a way to limit the number of databases a user can create in mysql? I would like to give a user the right to create databases, but he should not be able to create an infinite number of databases.
Thanks,
Gerold
If your users only have granted permissions on their own databases, you can check information_schema.SCHEMA_PRIVILEGES prior to permitting creation how many databases they already have. However, for this to work, you would have to prohibit CREATE DATABASE by the users directly and instead create the databases in application code via another privileged database user then grant access to the users to their newly created databases.
SELECT
GRANTEE,
COUNT(DISTINCT TABLE_SCHEMA) AS NUM_DBS
FROM information_schema.SCHEMA_PRIVILEGES
GROUP BY GRANTEE
If NUM_DBS is greater than your limit, don't create a new database for them.
Note that if you are granting permissions to users for databases other than the ones they "own", you will need to account for that in your query by excluding those via something like
WHERE TABLE_SCHEMA NOT IN ('other','dbs','you','grant','access','on')
Related
I've found that it's possible to grant user access to only specific tables in a DB. The next part of the puzzle is restricting the scope of select queries.
Should my frontend server ever be compromised by someone able to script, they may attempt to use mysql credentials from the server to dump the database.
If everything is limited to only select, update, and insert queries via mysql privileges, the supposed malicious user could still select * on the tables the mysql user has access to. Perhaps I'm overly paranoid, but I'm wondering if anything can be done to restrict that too.
The assumption here is that if the server is compromised, the mysql user can be used via a script on the server to get a copy of everything in the DB. I'm trying to find the options to protect my (and my users' data).
By design, the frontend application that will use this mysql user will never need to return more than 20 rows (mostly due to hardcoded . I'm therefore happy to restrict the mysql user from ever getting more than 20 rows from a select query.
Can this be done using mysql privileges for that mysql user?
You could create view as select ... limit 20, remove select privilege from the table and grant it only for the view instead.
Let's say we have a public DNA database running on mysql. Database contains only complete data. In this scenario, some special users want to add experimental data to the database, which may not be complete or they don't want it to be visible to everyone. Instead they want the experimental data to only be visible to users with correct privileges. What approach would you take to achieve this?
Presumably these datasets are large, and performance is important. That means the privilege system should be as coarse as possible.
If I were doing this, I'd create a "public" database, and use the MySQL GRANT command to allow guest users to SELECT on that database.
For example:
CREATE USER 'guest'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'guest'#'%';
Then, for the nonpublic datasets, I'd put them into other databases, and be more selective about the users GRANTed privileges. For example, these GRANTs give two different users access to private information and the public information.
CREATE USER 'venter'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'venter'#'%';
GRANT SELECT ON celera.* TO 'venter'#'%';
CREATE USER 'collins'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'collins'#'%';
GRANT SELECT ON hgp.* TO 'collins'#'%';
A user who has SELECT privileges on, let us say, the public database and the celera database, can issue queries like this allowing seamless (if not optimally performing) merging of private and public data.
SELECT whatever
FROM public.AGCT
UNION ALL
SELECT whatever
FROM celera.AGCT
Of course, it has to make scientific sense to take the union of these datasets. That may or may not be the case.
Don't be alarmed at the idea of creating multiple databases. They really are nothing more complex than directories in a computer file system. A single server can deliver dozens of them without any problems.
MySQL is definitely up to this kinds of security. Hosting providers run multi-tenant servers routinely.
I would consider MariaDB (a MySQL-compatible database written by MySQL's founder) over MySQL, as it supports roles.
Neither of them support Row Security like Oracle does, but you can mimic it by adding an "owner" column with the name of the role that can select/update the row.
Add a WITH CHECK OPTION view that checks that the current_user is in the role specified in that column.
Add a trigger to set owner value properly.
update: If you can't alter the table but can add new ones, add a new one w same key as original, and add owner column, and join the tables in your view.
See
http://www.sqlmaestro.com/resources/all/row_level_security_mysql/
So I was creating an application that required user log in, with each user having some privilege. Now this model closely resembled that of mysql's database where there can be many user, with each user having their own privileges.
So currently, for each user of my application, i am running a create user query and then grant them required permission and its working perfectly fine as of now
My Question
How good is my current approach?
I know, I can create my own user table and privilege table and then write queries accordingly, but is there any problem with my current approach,(after all thats what mysql does behind the scene, right?)
There can be so many dis-advantages of this approach, few are below-
As user rights are managed in mysql in myisam tables, so if you will insert users very frequently then locking can be here.
Privileges will not be effective till you flush them, and flush command lock the tables and can block all you application queries for some time.
You can't save additional important information of user in these system tables, while in your own user table you can save user name, email, creation time, password update time etc.
Easy management as you can create limited profile in mysql user table and map a group of users with these predefined profiles.
By this you can allow a user to connect db but restrict to do some specific task in applicatioin as you can join this tables with active/inactive status in you queries.
I would like to understand how hard this is to implement.
In unix, there are unix groups where certain people with a group can access certain folders and files.
I would like to apply the same concept into MYSQL where people could only access, view certain tables or even same tables but different rows ...
How can I achieve this? Would I have to use a different database system?
Gordon
This is a very common and simple approach. You can create users and specify which databases/tables they can access and what type of operations they can execute. See the mysql documentation on this
For instance:
--create the user
CREATE USER 'gordon'#'localhost' IDENTIFIED BY 'yourpassword';
--specify table and specific operations for that user
GRANT SELECT,UPDATE,DELETE,INSERT ON database.table TO 'gordon'#'localhost';
Short version: How can I write an SQL procedure to list which of several tables in a MySQL database a particular user has access to?
Longer version:
I'm writing a multi-user app that accesses a database with data for several branches of a company. The database has a number of lookup tables that any user can access, and a table for each branch that only authorized users can access. My strategy is:
Write a stored procecure that returns a list of the relevant tables for which the user has SELECT privilege.
From the app, call the procedure. If there's only one table returned, use it, otherwise let the user select which branch they want to access (e.g. for managers).
I'm having trouble figuring out how to write such a stored procedure. SHOW GRANTS FOR CURRENT_USER is an obvious possibility, but parsing something like:
GRANT SELECT ON Company.BranchABC TO 'auser'#'%clientdomain.com'
in SQL to figure out what the tables are seems way too messy. Doing a SELECT from the actual tables that hold the permissions also seems problematic, because I'd have to duplicate MySQL's logic for combining the permissions from the various tables (user, db, host, etc.)
Any words of wisdom?
You can see what privileges on which tables a user has:
show grants for 'user'#'host';
For example, to see the privileges of user1 (all machines in the network 10.25), run:
show grants for 'user'#'10.25.%.%';
I have never granted per table permissions to MySQL users before, but to do this, you would check that the TABLE_PRIVILEGES table in the information_schema database.
That should point you in the right direction.
MySQL users list and its privilege can be check with the Query.
select * from mysql.user\G;
http://www.thedevheaven.com/2012/04/retrieve-mysql-users-list-and-its.html