Insert values into table B based on column from table A? - sql

I have 2 tables, a Users table and a User_permissions table. A user can have many permissions and each permission can be assigned to many different users, although this relationship has not been configured into the database (not my decision!).
Let's say 2 new permissions are created - an admin permission and a superadmin permission. Furthermore, every user in the Users table need to be given this permission by inserting the username and permission name into the User_permissions table.
Obviously this could be done manually by INSERT INTO User_permissions VALUES (userA, admin) and so on but given that I have a list of over 1,000 users, is there an easier way of doing this? I was thinking of writing a quick script in Java, but is there an easier way using only SQL?

Use insert . . . select:
INSERT INTO User_permissions(user, permission)
SELECT user, 'admin'
FROM users u;

Related

Registration process with a user_role table pattern

More of a sanity check question.
I'm using a DB relation similar to this, which seems a popular pattern:
Such schema makes a registration and login process quite sophisticated. Say I want to register a user and give them a 'USER' role by default.
For registration:
Create a user and insert to the users table
Get the ID of the USER role from the roles table
Insert newly created user's ID and the fetched ID of the USER role to the users_roles table
For login (I want to fetch the user with their roles):
Authenticate user and get the user ID from users table
Get Role IDs for that user from the user_roles table (user may have more than one)
Get role names from the roles table
I'm guessing that you could probably do some clever JOINs and nested SELECTs to avoid multiple statements (I'm using an SDK though, with no raw SQL option - and that means three separate DB calls) but is there a better way to do this while preserving such DB design?

How to give access to columns to new user when current user does not see the tables?

Using SYSTEM user I create a new user. After that I try to give this user access to specific columns only in 1 table, but get the error that this table does not exist. Meaning that SYSTEM user does not have access to this table. Unfortunately, the user that has access to the normal production tables cannot manage user privileges and access. What are my options?
CREATE USER test1 IDENTIFIED BY 123456;
GRANT UPDATE (extinvno, invoiceno) ON invoice TO test1;
Edit: Solution
Created 3 views that I needed. GRANT-ed the new user SELECT and UPDATE on 2 of the views and SELET on the 3rd. For the new user I had to use the chema to refer to the views: chema.view
If SYSTEM doesn't own the table then you need to specify who does; for example if the table was in the HR schema you would do:
GRANT UPDATE (extinvno, invoiceno) ON HR.invoice TO test1;
... using the real owning schema name, of course.
It isn't that SYSTEM doesn't have access to the table; it's that by default it's looking for SYSTEM.invoice, which doesn't exist.
The table owner could also grant the update privilege to test1.

How to limit permissions of certain Informix users

I have multiple users on my Informix 12.10 server. I want to limit certain users delete permission in Informix so that particular users cannot delete any tables in Informix.
Do you mean "delete tables" as in "DROP TABLE", or delete (from) tables?
If you want to limit the ability to drop (non-temporary) tables, then you should know that only users with RESOURCE or DBA privilege can drop tables; only users with DBA privilege can drop tables they don't own. The cure to this problem is to limit the people who have either RESOURCE or DBA privilege.
If you don't want people to delete from specific tables, revoke delete privilege from PUBLIC (because anyone can do what PUBLIC can do) on each of those tables, and also from each user otherwise granted DELETE permission. That tends to get a bit verbose, but is doable with a shell script to generate the DDL:
for table in "$#"
do
echo "REVOKE DELETE ON $table FROM PUBLIC;"
for user in user1 user2 user3 user4
do echo "REVOKE DELETE ON $table FROM $user;"
done
done
Save the output in a .sql file and run it with DB-Access. You can get much fancier with how you generate the list of users. You could also generate a comma-separated list of user names and run a single REVOKE statement. You pays your money and takes your pick. For a given table ('elements' in this example), this SELECT statement lists the users from whom DELETE permission must be revoked:
SELECT a.grantee, t.owner, t.tabname, t.tabid
FROM "informix".SysTabAuth AS a
JOIN "informix".SysTables AS t ON a.tabid = t.tabid
WHERE a.tabauth[5] = 'd'
AND t.tabname = 'elements';
That generates more information than you need — the grantee column is sufficient — but the extra might help you during debugging. Note that if 'user1' grants delete permission to 'user2', and 'user3' tries to run the REVOKE statement REVOKE DELETE ON tablename FROM user2 will not change the permissions. However, a DBA could run REVOKE DELETE ON tablename FROM user2 AS user1. In other words, the grantor matters, as well as the grantee.
You might want to make use of the NODEFDAC environment variable (it's short for 'no default DAC', where DAC is 'discretionary access control') when creating tables to deny PUBLIC default permissions on created tables.
However, that's of limited help and simply setting it does not apply the new rules retroactively.

Letting users "GRANT SELECT" without making them admins or giving them CONTROL permission

Background info:
I administrate a database in SSMS. I am the only administrator. I have users creating tables, and then they want to grant select permissions on those tables, to other users. But they are not allowed to do it because they are not administrators or have CONTROL permission on the schema.
Question:
How can I as an SSMS database administrator let users grant SELECT on tables they create to other users, without making them admins or giving them CONTROL permissions?
I would simply get users to create a table in their own schema along the lines of (SSMS syntax may be different, this is just meant to be illustrative):
create table select_access (
table_name varchar[50],
user_name varchar[50],
is_active varchar
)
Then have an admin job run periodically (every five or ten minutes, for example) and, for every applicable user, examine the entries in that table.
If there's an entry for a table not currently having the permission (with is_active set to Y), grant the permission. If there's an entry for a table currently having the permission (with is_active set to N), remove the permission.
That way, they have full control over select permissions on their tables without getting you involved.
To share a table, they just create it, add entries to select_access for each user they want to share it with, then wait for your job to run.
To disable, they just set the is_active field to N for the users they want to revoke access for and, again, wait for your job to run.
The use of is_active is just to make your life easier, as your only necessary source of information is just that table.
You could make it smarter by just letting them delete the row for the given user/table but then you'd have to process the table and all their tables that may have access granted but no longer have an entry in select_access.
Just make sure any table they grant permissions to is a table in their schema, not one of the system tables :-)

SQL permissions based on record value (if column X = Y for user1 allow Inserts/Updates etc.)

I need to run queries as a "user" which is a record in a table, with permissions based on a record value of that user.
I have a database with a tUsers Table, such as:
ID Username Email Role
1 Pieman mail.com Admin
2 Cakedude mail.co.uk Receptionist
3 Muffin gh.com Other
I need to have it so only "users"/records with "Role" of "Admin" can view and edit the table, and "Receptionist" view it etc.
I know of and use GRANT for permissions, but don't know how to run a query as a user based on a table record and to have the permission only GRANTED if that users' role is "Admin"
So if I have:
USE DB1;
GRANT SELECT ON OBJECT::tUsers TO Admins;
GO
SELECT * FROM tUsers
How do I make that run as say tUser with ID 1, and the GRANT if the users' role = "Admin"
I'm sure I've seen this done before.
I'm fairly new and still learning the correct terminology, so if this is a duplicate question, or is essentially just describing an sql Function sorry.
I don't think you can grant or revoke permissions to users in your own user table. However you can of course restrict queries based on your own user table.
One solution is to do it in your application. Verifier permissions before you do anything for him/her.
Another solution is to use stored procedures which take user id as parameter and do the checking for you in a central place.
The third one is to user parameterized views where you filter out entries one user can't access.
There are other solutions but the basic idea is you need somehow check permissions instead asking dBm server to do it for you.