Let a user view all info of sys.databaseprincipals - sql-server

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]

Related

After creating a new user in a SQL Server database, the user is able to create and drop tables. Why?

I have a huge problem with rights of new users of my SQL Server database. The new user cannot see any tables but is still able to drop them or create new tables.
Code to create the user:
--Code Start
--This is how I instantiate the new user:
CREATE LOGIN userName WITH PASSWORD 'password';
CREATE USER userName FOR LOGIN userName;
--Furthermore, the user get some roles. So that the user can do at least something:
CREATE ROLE roleExample;
GRANT DELETE, INSERT, SELECT, UPDATE ON dbo.exampleTable TO roleExample;
SP_ADDROLEMEMBER roleExample, userName;
--Code End
In my opinion, the new User should only be able to operate on the exampleTable now. But as I said, the user is also able to create and drop tables.
That's why, I added some constraints to the role, the new user gets:
DENY CREATE TABLE TO roleExample AS dbo;
This did not help either. The User is still able to create tables in dbo.
This problem is btw. not related to a specific schema. The new user can create and drop tables in any schema.
I guess that new users are allowed to create or drop tables by default. Sadly, I do not know how to change it.
I hope you guys can help me.
Attached is an example, where you can see that the user does not know the schema, where a new table should be created. Nevertheless, the schema exists and after executing this statement, the table is created. The error-message just says that this table is already created, because I executed this statement twice. Still, the user is not able to see its own created table in SQL Server Management Studio.
User does not know schema, but still can create tables in it
OK, so there's several things that it might be, but by far the most likely is that someone has granted some database permission(s) to the public role or to some AD group that your users are all in. (Also possible, but less likely is that something similar has been done to the server permissions).
To check for database permissions open SSMS (SQL Server Management Studio), right-click on your database in the Object Explorer pane and select "Properties". Then in the Database Properties window click the "Permissions" page from the list on the upper-left.
If there are any database permissions granted to any Users or Roles, they should appear in the upper listbox. If Public is in there click it to see if has been granted any database-wide permissions. All users have the Public role, so anything granted here is automatically granted to all users.
If that isn't it, then check any other roles listed in the upper listbox. Also check any users that look like they might be AD Groups because these work like DB roles except that SQL Server cannot administer them, nor tell who's in a specific group from these interfaces.
If you don't find anything here, then repeat this for the Server Permissions also.

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;

The EXECUTE permission was denied on the object 'xxxxxxx', database 'zzzzzzz', schema 'dbo'

I'm having problems executing a function.
Here's what I did:
Create a function using SQL Server Management Studio. It was successfully created.
I then tried executing the newly created function and here's what I get:
The EXECUTE permission was denied on
the object 'xxxxxxx', database
'zzzzzzz', schema 'dbo'.
Sounds like you need to grant the execute permission to the user (or a group that they a part of) for the stored procedure in question.
For example, you could grant access thus:
USE zzzzzzz;
GRANT EXEC ON dbo.xxxxxxx TO PUBLIC
Best solution that i found is create a new database role i.e.
CREATE ROLE db_executor;
and then grant that role exec permission.
GRANT EXECUTE TO db_executor;
Now when you go to the properties of the user and go to User Mapping and select the database where you have added new role,now new role will be visible in the Database role membership for: section
For more detail read full article
In SQL Server Management Studio, go to security->schema->dbo:
Double-click dbo, select the Permissions page, then click the "View database permissions" link in blue:
Select the user for whom you want to change permissions, and look for the "Execute" permission under the "explicit" tab:
Choose the appropriate permission by checking the appropriate box.
you need to run something like this
GRANT Execute ON [dbo].fnc_whatEver TO [domain\user]
This will work if you are trying to Grant permission to Users or roles.
Using Microsoft SQL Server Management Studio:
Go to: Databases
Right click on dbo.my_database
Choose: Properties
On the left side panel, click on: Permissions
Select the User or Role and in the Name Panel
Find Execute in in permissions and checkmark: Grant,With Grant, or Deny
Giving such permission can be dangerous, especially if your web application uses that same username.
Now the web user (and the whole world wide web) also has the permission to create and drop objects within your database. Think SQL Injection!
I recommend granting Execute privileges only to the specific user on the given object as follows:
grant execute on storedProcedureNameNoquotes to myusernameNoquotes
Now the user myusernameNoquotes can execute procedure storedProcedureNameNoquotes without other unnecessary permissions to your valuable data.
You don't have the right to execute it, although you have enough permissions to create it.
For more information, see GRANT Object Permissions (Transact-SQL)
If you have issues like the question ask above regarding the exception thrown when the solution is executed, the problem is permission, not properly granted to the users of that group to access the database/stored procedure. All you need do is to do something like what i have below, replacing mine with your database name, stored procedures (function)and the type of permission or role or who you are granting the access to.
USE [StableEmployee]
GO
GRANT EXEC ON dbo.GetAllEmployees TO PUBLIC
/****** Object: StoredProcedure [dbo].[GetAllEmployees] Script Date: 01/27/2016 16:27:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[GetAllEmployees]
as
Begin
Select EmployeeId, Name, Gender, City, DepartmentId
From tblEmployee
End
here is how to give permission for one user not public,
Direct Query:
Use MyDatabase
Grant execute on [dbo].[My-procedures-name] to [IIS APPPOOL\my-iis-pool]
Go
You can give everybody execute permission:
GRANT Execute on [dbo].your_object to [public]
"Public" is the default database role that all users are a member of.
If you make this user especial for a specific database, then maybe you do not set it as db_owner in "user mapping" of properties
I have faced the same problem and I solved as give db_owner permission too to the Database user.
The general answer is to grant execute permission as explained above. But that doesn't work if the schema owner of SP is different to underlying objects.
Check schema owners by:
select name, USER_NAME(s.principal_id) AS Schema_Owner from sys.schemas s
To change the owner of an schema you can:
ALTER AUTHORIZATION ON SCHEMA::YOUR_SCHEMA TO YOUR_USER;
Examples:
ALTER AUTHORIZATION ON SCHEMA::Claim TO dbo
ALTER AUTHORIZATION ON SCHEMA::datix TO user1;
Finally if within your SP you are truncating a table or changing structure you may want to add WITH EXECUTE AS OWNER in your SP:
ALTER procedure [myProcedure]
WITH EXECUTE AS OWNER
as
truncate table etl.temp
If you only need to grant a single function then (only db admin can do it):
Open Management studio
Find function/procedure you want to grant in Object Eplorer (dbname-Programmability-[Functions/Stored Procedures]-...)
Right click on function or procedure name and open Properties
In Properties select Permissions, add user (or schema) you want and Grant him Execute permission.
I believe this is most secure way how to do it because you only grant to user execution of this function. Nothing else!
I think you have to select the object you want to grant access to, then right-click, and select properties. Select permission on the modal window that will be displayed then click on Search, on the newly revealed window, select browse, select the user you want to grant access and click on ok. it will display for you a list of permission and the grant status, and then you can choose to grant or deny
This shows that you don't have access to perform any action on the specified database table. To enable this, Go to Security -> Schema and check.
you'd better off modifying server roles, which was designed for security privileges. add sysadmin server role to your user. for better security you may have your custom server roles. but this approach will give you what you want for now.
Object Explorer -> Server -> Security -> Logins
Right click on your desired user
Go to Server Roles on left hand side
Make sure sysadmin is checked
Hit OK and restart your SQL server
Good luck

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.

Resources