I am trying to create a separate set of privileges for a database that contains both "read only" tables and "read write" tables. To be more specific, the database contains 10 tables that I want the user to only read from (i.e. select only). It also contains around 30 tables which the user is free to read and write to and from. Lastly, I would also like the user to be able to create/drop/alter tables created by him thus granting him full access to his own tables under the same database.
Is something like this possible? I have tried to think of the ways I can use GRANT but my head is getting stuck.
Thanks
What you want is possible except I'm not sure about the last sentence. I don't think mySQL tables have "owners" as such, but you can limit access to tables with certain prefixes. Maybe that is a way to go.
Obligatory manual reference: 12.4.1.3. GRANT Syntax
I recommend using a GUI like HeidiSQL (for Windows) to point-and-click the required privilege rules. It produces proper SQL to look at and learn from as well. Here is a screen shot of its excellent user manager.
Related
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/
Is there a way to create a user in MySQL that have login access but no databases, but it allows the user to create a new database to a limit of 5 or what ever I decide.
So basically what I want is to give a user access to create his own databases, but I dont want him to see other databases, also he should be limited to create only 5 databases
There is no notion of "Database Owner" or "Database Creator" in MySQL, therefore there is no way to limit the number of databases created by a user.
Note: it is possible to put some restrictions at account-level, but not the ones you are looking for. You will need a third-party management tool for this.
I'm working on some data project with a few other collaborators. Most are fairly new to SQL so have inquired if I can make the 'raw' data tables read-only so they aren't accidentally altered, how would I go about doing that? Currently all users have GRANT SELECT ON mydb.* TO 'user'#'%' permissions, but I need to be a little more open.
There's a question about making a single table read-only, but it seems like it would deny users the ability to make other tables; or if they did, they couldn't do anything with them. There doesn't seem to be (or I can't find) a 'deny' setting like in NTFS that overrides allow/GRANT; from what I read REVOKE is only the opposite of a prior GRANT, you can't "nest" them.
I was considering making a separate 'raw' database that would be SELECT-only so users could copy it into the 'workspace' database, but that seems a bit hacky and will eat up some semi-significant amount of space on my budget cloud server. What's the proper solution?
GRANT SELECT ON example.* to 'someuser'#'somehost';
Give read only privilege.
GRANT CREATE ON example TO 'someuser'#'somehost';
Give create table privilege.
You can make a single MyISAM table read only by compressing the table. Use myisampack on the command line to pack the table.
More info can be found in the MySQL Manual: http://dev.mysql.com/doc/refman/5.0/en/myisampack.html
I have a database with many many tables.
I want to block any users, except one, from accessing this table. All the users will also need to be able to access any future tables created in such database, and naturally it is not possible for me to add/remove access to those tables as some are temporary tables created just scripting purpose.
Something like:
GRANT ALL PRIV ON *.* TO user123 ...
REVOKE ALL PRIV ON mydb.table FROM user123
If some tables are temporary, why not just create them as TEMPORARY tables? Then they will only be accessible by the session which created them.
You can easily grant permissions on tables and then revoke for an individual table, but there's no way to easily maintain that going forward.
Another option is to simply put the table which needs different permissions in a separate database. Of course it managing permissions for two databases, so it could be messy, but it's somewhat closer to the goal.
There's a good reference guide to table privileges here. Think it has what you need. Other privileges are mentioned earlier in the same guide if you need those too.
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';