MariaDB - MySQL GRANT permissions to table names not matching pattern - mysql

I'm using MariaDB. I have a set of entity tables like order, inventory etc and other audit tables order_audit, inventory_audit to track any changes made to the original tables. I do not want to allow database user that is being used by the Java application to have DELETE or UPDATE permissions on audit tables.
I could assign permissions in following way
grant select,insert,update,delete on my_db_name.* to 'my_app_db_user';
But the above query grants update and delete permissions to audit tables as well. I did a quick search and figured its not possible to use patterns on table names in MySQL.
Most of the solutions suggest using a different database for such tables that require different permissions. But since my audit tables belong to original tables, I don't like them in a separate database. Is there any workaround ?

Related

How can I define a schema in MySQL as a subset of another schema

I have a MySQL schema with 20 tables, two applications are using it, the first one is using all the tables but the second only 10.
How can isolate the tables in such a way that the second app only "see" 10 tables?
I was thinking about using a second schema and synonyms to the tables of the first schema, but MySQL does not support synonyms.
It's all about documentation, it is not a security concern.
How can I proceed?
MySQL easily allows you to grant privileges on only some tables to one user, while granting privileges to all tables to another user.
So I recommend simply using ACL granularity to hide the unwanted tables from each application.

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, permissions for different users to access different tables

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

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