Creating mysql user vs a custom table with user data - 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.

Related

List of specific database tables that a user has access

I am beginner in mysql management, so I need help in writing query for listing specific database tables that a user has access.
This is a strange wish...
Normally users should not be interested in tables. Tables are a technical aspect of the data model, something that should not be visible to the user. The user is interested in storing and retrieving data. But he usually is and should not be aware of how that data is stored.
Anyways: there is no such function AFAIK. you will have to create some hack yourself. You can query the list of tables inside a database. Then you'd have to iterate over that list and test for access rights one by one.
Have a look at mysql information_schema tables.
19.14 The INFORMATION_SCHEMA TABLE_PRIVILEGES Table
The TABLE_PRIVILEGES table provides information about table
privileges. This information comes from the mysql.tables_priv grant
table.
http://dev.mysql.com/doc/refman/5.0/en/table-privileges-table.html
and
6.2.2 Privilege System Grant Tables
Normally, you manipulate the contents of the grant tables in the mysql
database indirectly by using statements such as GRANT and REVOKE to
set up accounts and control the privileges available to each one. See
Section 13.7.1, “Account Management Statements”. The discussion here
describes the underlying structure of the grant tables and how the
server uses their contents when interacting with clients.
http://dev.mysql.com/doc/refman/5.1/en/grant-table-structure.html

Is it possible to make certain data available to certain users on a public mysql database?

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/

MySQL: How to avoid a user from even seeing I have other DB's and grant select access to one view on one DB?

I have several DB's in my server, and I need to allow one user to select records from a view in one of the DB's. But I need for this user to not even see that there are other DB's nor see that there are other tables in the DB where the view belongs. Is this possible?
I had an account with a hosting company, a shared hosting account, and I could only see my DB when I accessed it through phpmyadmin. This is similar to what I need. Thank you for your help.
I've found the overview contained in this article even more helpful than the actual MySQL documentation for describing the big picture of how MySQL privileges are granted or denied.
The gist of the overview article is that privileges are controlled by a series of increasingly finer-grained permissions tables in the mysql database: mysql.user, mysql.db, mysql.host, mysql.tables_priv, mysql.columns_priv, mysql.procs_priv. The general rule is that a "Y" value for a privilege in a more fine-grained table overrules a "N" value in a more coarse-grained table. So the recommended strategy is to start by denying most privileges in the user table (which gives the coarsest control), and then make only the specific overrides that you want in the more fine-grained tables.
In particular, there is a privilege called SHOW_DATABASES which is determined by the Show_db_priv column in the mysql.user table; you'll want to set this to "N" for the user in question (and as described above, you may want to set most other permissions in the user table to "N" as well) and then grant only the privileges that the user actually needs in the mysql.db or mysql.tables_priv table or whatever would be appropriate for your particular case.
You have to add a user to a database using grant privileges.
Create new databases and simply don't add the user to it then the user won't be able to see it.
The only way the user will be able to find the database is if they try to access it and guess the database name. So basically a user/hacker would have to attempt to connect to a bunch of random database names in order to find one that says "access denied"

Max number of databases per user in mysql

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')

List of tables that a user has SELECT privilege for in MySQL

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