how to restrict user access: only connect and exec function - sql-server

Please advice how to restrict user access to mssql: just connect and execute only specific list of functions or stored procedures. The problem is that default 'public' role is giving more rights than needed - list databases, get user list etc.
How to close as much as possile (deny all) and after that open only what is allowed?
Real situation is the following: partner site asked not to get data through xml webservice but have direct connection to mssql and I am going to make a table function for them or stored procedure with parameters, but want to hide everything what is going on inside server.
Thanks.

You can deny them permissions they will not need. For instance, you can DENY VIEW ANY DATABASE so that they cannot see other databases on the server. There are lots of options available through the DENY facility (so many that they have separate pages for those that apply at the server level, and those that apply at the database level).
Just:
DENY VIEW ANY DATABASE to <user> --Run in master
and
DENY VIEW DEFINTION to <user> -- run in the database you've given them connect permission
should be sufficient that they cannot see anything, or select from any tables. Then you just need to explicitly grant them the permissions you want them to have.

Related

Locking the stored procedure and view

How to lock the view and stored procedure in SQL Server to avoid being scripted out by any user? Only SA account should able to delete it. No other permission should be there for SA also.
I am asking this to avoid the table information getting exposed to any user. But only data should able to read from the view that I create.
You cannot limit the permissions of the sysadmin role - by definition it MUST have full permissions to do anything with the instance and databases.
To prevent other users from scripting it out then DENY VIEW DEFINITION to the users on those objects

SQL Server 2008 - give user access to certain tables and views only

I need to allow certain user access to only specific views and tables. I have tried following so far
Created a user ex_user
Created a role rviewonly
deny view definition to rviewonly;
Then I executed this sql
GRANT SELECT ON vwBI_PEOPLE TO rviewonly
It seems to work, and this ex_user can do a select command on it however I do not see this vwBI_PEOPLE in list of views in Management Studio. There are about 50 views that I have to give this user access to along with about 40 different tables - I want the user to be able to see the available views and tables in Management Studio's Object Explorer
Because you have denied view definition at the database level (no object specified) to the role/user, this trumps any grant view definition on ... that you may make on an individual object. Grant select on ... will also allow view definition on that object without having to specify grant view definition.
I recommend revoking view definition at the database level:
revoke view definition to rviewonly;
And simply let your grant select on statements do the work for you. You shouldn't have to rerun them again after running the above revoke. view definiton by itself would be good for giving a user/role access to metadata, but not data.
Note that any deny will always trump a grant including the cases where you deny a role access but grant the user access or vice-versa.
I just verified this on a SQL Server 2008 R2 dev box. I'm not sure if any settings exist that might alter this behavior for your instance.
I had the same question before. I, instead of using a role, just granted select on the user itself. This is something handy for multiple table permission granting:
SELECT 'GRANT SELECT ON '+name+' TO ex_user;'
from sysobjects
where name in (
'[Enter table]',
'[names here]',
'[in a list]',
'[to grant permissions]'
)
Then copy all the results, throw it in a query, and run it. Especially handy if all the tables you want to grant access to are prefixed with the same grouping of letters.
Example: You can just change the above query's where clause to be where name like 'TST_%', if all the tables/views you're granting start with "TST_".
You need to add ex_user to rviewonly role sp_addrolemember:
EXEC sp_addrolemember rviewonly, [ex_user];
Then use revoke instead of deny view definition to the role:
revoke view definition to rviewonly;

PostgreSQL - Securing DB and hide structure

I am deploying a database in postgreSQL and I created a user that just will be able to execute certain functions.
I revoked all privileges from the user i just created and granted connect privileges executing:
REVOKE ALL PRIVILEGES ON DATABASE <database> FROM my_user;
REVOKE ALL PRIVILEGES ON SCHEMA public TO my_user;
GRANT CONNECT ON DATABASE <database> TO my_user;
But when i connect to the database with this user, i am able to read all table structures and all function source codes. Is there a way to hide it from this user?
I take the chance to make another question: I want to just execute functions (which may include select, insert or update on database tables) with this user, but I don't want to grant privileges on select, update or delete on tables.
I am using "SECURITY DEFINER" and then I grant execution, but I think it may be a little insecure. Am I right? is there any other way to do it?
Thanks in Advance.
Lamis
There's no way to hide the system catalogues from a user in PostgreSQL. If a user can't access the catalogues then they can't locate any other database objects.
If you really can't afford to let them see the structure of the db, you'll need to prevent them connecting. Build some sort of middle layer with a simple API that calls the db.
SECURITY DEFINER is the standard way to provide limited access at a higher privilege level. You have to be careful with any function arguments that can end up in a dynamic query though. That's the same "bobby tables" issue as with any dynamic sql building though.
How about
REVOKE SELECT ON pg_namespace FROM my_user;
REVOKE SELECT ON pg_catalog.pg_database FROM my_user;
You won't be able to see anything, but you'll be able to make queries if you know the namespace and table name.

How to disable SQL Server Management Studio for a user

Is there a way to prevent users from getting into SQL Server Management Studio so that they can't just edit table rows manually? They still need to access the tables by running my application.
You can use the DENY VIEW ANY DATABASE command for the particular user(s). This is a new feature available in SQL Server 2008.
It prevents the user from seeing the system catalog (sys.databases, sys.sysdatabases, etc.) and therefore makes the DB invisible to them in SQL Management Studio (SSMS).
Run this command from the Master Database:
DENY VIEW ANY DATABASE TO 'loginName'
The user is still able to access the database through your application. However, if they log in through SSMS, your database will not show up in the list of databases and if they open a query window, your database will not appear in the dropdown.
However, this is not fool-proof. If the user is smart enough to run the Query Command:
USE <YourDatabaseName>
Then they will see the database in the Query Analyzer.
Since this solution is taking you 90% there, I would give the database some obscure name not let the users know the name of the database.
You DO NOT need to worry about them having access to the tool. Simply make sure they do not know any of the SQL logins for the specific Databases that have read/write permissions, if they do, change the password. If they have access to the DB via Windows Authentication, make sure that they are in a datareader role. You can use roles to manage what the users can do in SQL.
You can use a trigger.
CREATE TRIGGER [TR_LOGON_APP]
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE #program_name nvarchar(128)
DECLARE #host_name nvarchar(128)
SELECT #program_name = program_name,
#host_name = host_name
FROM sys.dm_exec_sessions AS c
WHERE c.session_id = ##spid
IF ORIGINAL_LOGIN() IN('YOUR_APP_LOGIN_NAME')
AND #program_name LIKE '%Management%Studio%'
BEGIN
RAISERROR('This login is for application use only.',16,1)
ROLLBACK;
END
END;
https://www.sqlservercentral.com/Forums/1236514/How-to-prevent-user-login-to-SQL-Management-Studio-#bm1236562
I would suggest you lock down the database and give appropriate read-only (or other) rights to the user. That way the user can still use management studio to run select queries and such.
If you don't want the user to have any rights at all then you could do that as well.
If your application is running as a service/user account then only that account requires access to the database. The individual users' account do not require any access to the database and therefore they won't even have read access. Your app will be the gateway to the data.
If the users are running the application under their user accounts then grant them read-only permission. You can simply add them to the db_datareader role.
Hope this helps!
You can deny 'Users' access rights to the ssms.exe executable file, while granting the relevant users/administrators rights to it.
If your application only used stored procedures to modify the data, you could give the end users access to run the stored procs, but deny them access to modify the tables.
Don't let them know what the database login is.
If you can't restrict the login, use stored procedures exclusively for updates and disable any CREATE,DELETE,INSERT, or UPDATE permissions for that user.
An Application Role will allow you to secure database objects to your application instead of the logged on user.
I agree with Jon Erickson as a general rule
do not allow any users access to the tables, but only allow access through stored procs
do not allow general user accounts access to stored procs, but only the account your app runs under (whether it's an integrated login or SQL login)
Make well usage of Database Roles, if Users should only have SELECT (read) access assign them the db_datareader Role. Even if they login using SSMS they will can execute only SELECT statements.

Let a user view all info of sys.databaseprincipals

I have a database and I want let to some role the permission to query all info from the sys.databaseprincipals and see other user names. How can I do this?
Thanks.
Wrap the call in a stored proc or table valued function and use EXECUTE AS OWNER (assuming dbo.nameofcodeobject).
Otherwise, you have to switch off MetaData Visibility protection for the entire server
You can't use EXECUTE AS for views which would be useful here...
Edit, based on comment.
From sys.database_principals:
In SQL Server 2005 and later versions,
the visibility of the metadata in
catalog views is limited to securables
that a user either owns or on which
the user has been granted some
permission. For more information, see
Metadata Visibility Configuration.
dbo owns everything so sees everything
Permissions can not be granted because there is no "GRANT VIEW SECURITY"
Maybee its just me and my servers setup but I am able to query the sys.database_principals so long as I have the connect permission. I am also able to see the user name.
You can grant Connect by doing:
GRANT CONNECT TO [USER]

Resources