SQL and Active Directory groups, Schema permissions - sql-server

I have the following problem, we assign perms in SQL 2014 using ad groups. we have the following
l_sql-db-demodb-dbo: this is a local group where we assign the actual permission (dbowner against 'demodb')
g_sql-db-demodb-dbo: global group that is a member of the above
user: user is added to global group giving permissions for dbo to demodb.
This all works fine... mostly. User tries to run SQL profiler 2014 and run a trace and output trace to demodb. User can select the database, cannot select a schema.
If I assign the same exact permission set against the user account itself, it works as expected. for some reason the groups (or the nesting of groups) are killing this ability.
Note that this is SQL 2014 SP1. SP2 has not been approved for rollout, so I'm not sure if this is a bug..

Related

IS_ROLEMEMBER erroneously returns 0 for database role members?

Running a local instance of SQL Server 2012.
I have created a custom role:
CREATE ROLE [my_user] AUTHORIZATION [dbo]
For all my users (local Windows users and SQL users), I have specified this role for my database (under the User Mappings setting). Thus, the following query should return 1:
SELECT IS_ROLEMEMBER('my_user')
For my Windows-authenticated users it does indeed return 1, but as soon as I'm logged on as an SQL user, it returns 0. I have triple-checked that the SQL user does indeed have this role. What am I missing here?
Update
Performed some more testing. This certainly is weird behavior. I performed these steps:
On my local SQL Server I created a database test with user sa. Role my_user added.
Logged on as sa in the Management Studio and added MYDOMAIN\MyUser to this role.
Re-logged on with Windows Authentication and executed IS_ROLEMEMBER('my_user'). Returns 0.
Tried the query using both sa (specifying the username) and the Windows user. Same problem.
Tried restarting the SQL Server, just in case.
This makes no sense! If I right-click the role I can see that my Windows user is indeed a member of it. The IS_ROLEMEMBER function is flawed! When I run the following query, it shows that my user is indeed a member of the database role:
SELECT
USER_NAME(memberuid), USER_NAME(groupuid)
FROM
sys.sysmembers
WHERE
USER_NAME(groupuid) = 'my_user'
This also shows my membership:
select r.name as role_name, m.name as member_name from sys.database_role_members rm
inner join sys.database_principals r on rm.role_principal_id = r.principal_id
inner join sys.database_principals m on rm.member_principal_id = m.principal_id
Some additional information:
I'm on a domain, but currently disconnected. I have seen this problem when connected too though.
Running Windows 8.1 64-bit.
Update 2
If I explicitly specify the principal as some have suggested, I get this error (executing as sa):
SELECT IS_ROLEMEMBER('my_user', 'MYDOMAIN\UserX')
Msg 15404, Level 16, State 19, Line 1
Could not obtain information about Windows NT group/user 'MYDOMAIN\UserX',
error code 0x54b.
Could it be that IS_ROLEMEMBER experiences the same problem, but does not print the error?
I just had this same issue... I found that the user in question had server roles also assigned to them. When I removed all server roles except 'public', suddenly the is_rolemember query started correctly reporting a 1 instead of the zero..... I tested this back and forth a few times to confirm.
Also had this issue. Turns out I had to remove sysadmin server role, then it worked.
This is taken from: https://learn.microsoft.com/en-us/sql/t-sql/functions/is-member-transact-sql
Members of the sysadmin fixed server role enter every database as the dbo user. Checking permission for member of the sysadmin fixed server role, checks permissions for dbo, not the original login. Since dbo can't be added to a database role and doesn’t exist in Windows groups, dbo will always return 0 (or NULL if the role doesn't exist).
Try specifying the principal explicitly.
SELECT IS_ROLEMEMBER('my_user', 'SqlLogin')
I tested this and it returned 1.
CREATE DATABASE TestDatabase;
GO
USE TestDatabase;
GO
CREATE ROLE TestRole AUTHORIZATION dbo;
GO
CREATE USER TestUser WITHOUT LOGIN;
GO
EXEC sp_addrolemember 'TestRole', 'TestUser';
GO
SELECT IS_ROLEMEMBER('TestRole', 'TestUser');
GO

Windows NT user or group 'DOMAIN\USER' not found?

I am trying to create users on a SQL server from an Active Directory group as an application I am working with does not natively support Windows authentication and relies upon individual logins being created on the SQL server, as application level permissions are managed in the application rather than using SQL roles. Due to this, each user that is to access the application needs their own user creating against the SQL instance that the applications database is on, so that the user can then be assigned individual permissions within the application.
I am reading the list of users from the Active Directory group we have designated using the following;
exec master..xp_logininfo 'domain\groupname', 'members'
This returns output similar to the following;
account name type privilege mapped login name permission path
DOMAIN\USER user user DOMAIN\USER DOMAIN\GROUPNAME
For the most part, the users returned in this list can be created on the SQL instance without any drama. I am creating the users as SQL accounts using sp_grantlogin in the first instance, before moving on to allow each new login access to the application database. However, a handful of users are being reported as not existing. I get the following error as a result of running sp_grantlogin;
Msg 15401, Level 11, State 1, Procedure sp_grantlogin, Line 49
Windows NT user or group 'DOMAIN\USER' not found. Check the name again.
Obviously in the above error message, I have removed the actual username. Why would xp_logininfo return a user that cannot be created with sp_grantlogin? Is there anything obvious that I am missing?
This just means that the user is not in the Administrator group. If your problem is like mine where your Active Directory in on a different Virtual Machine, and your SQL Server on another. And you have joined Active Directory Domain to your SQL Server Virtual Machine, then you have to do the following on your SQL Server Virtual MAchine.
Navigate to Tools --> Computer Management.
The windows opens, Expand System Tools --> Local Users and Groups.
Click on Groups and you should see a list of groups to the right
column of the window.
Double click Administrator, a new window opens and you will notice that the linked User is not under there.
Click Add, new window opens. Here, under location, you may chose to change
location of your domain.
Click Advanced, a log in prompt opens, simply log in with you administrator Virtual Machine account.
Click Find Now with all fields as is. From a list of users presented, double click the user imported from Active Directory and click Ok.
Do you change the case of the login name before using sp_grantlogin?
If you have a case sensitive server collation, then the case of the AD user nneds to be specified in exactly the right case.
You can find the server collation by doing:
select serverproperty('collation')
If you do have a case sensitive server collation, and you don't mess with the case, there is probably a mismatch with what xp_logininfo is returning and the actual case in AD. In which case, try creating the user with variations on the case.
If none of this applies, look into the account. Is it disabled, can you log in with it, etc.. If suser_sid() returns null, then there must be some kind of problem with it.
I can give you my advice from doing this in Windows 7 although it may not be relevant.
The problem I had was that I had renamed the user account in the Windows UI. The name appeared correctly in Windows, and I used the new name to log on. But behind the scenes it was still using the old name which was what SQL Server was looking for.
I struggled with this for HOURS before I finally worked it out!!
I have also faced this error for users, who was:
created in AD
granted some SQL permissions
renamed in AD
Then I try to add this new, renamed user account name to the same server/database, error Msg 15401, Level 11, State 1, Procedure sp_grantlogin, Line 49 appears.
I have followed steps in http://support.microsoft.com/kb/324321/en-us and this command returned old user account name befor rename:
SELECT name FROM syslogins WHERE sid = SUSER_SID ('YourDomain\YourLogin')
it returned
YourDomain\OldLogin
after executing
exec sp_revokelogin 'YourDomain\OldLogin'
problem was fixed, sp_grantlogin now works ok.
PS as another test method I suggest running sp_grantlogin remotely, from another server. It may succeed to.
I had a very similar case, the same error code 15401, but in this case what I was doing was adding users from the Domain, into a group in the server where I had SQL; so then just add the group to SQL engine with the same ROLE.
USE [master]
GO
CREATE LOGIN [localhost\Administrators] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
Msg 15401, Level 16, State 1, Line 3
Windows NT user or group 'localhost\Administrators' not found. Check the name again.
Then in the link PRB: Use BUILTIN\Group to Grant Access to Predefined Windows NT Groups
I found the issue, so the solution was:
USE [master]
GO
CREATE LOGIN [BUILTIN\Administrators] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
GO
ALTER SERVER ROLE [sysadmin] ADD MEMBER [BUILTIN\Administrators]
GO
Command(s) completed successfully.
I believe this is great to diminish the number of login accounts, and have a more manageable number of users assigned to the roles in the SQL server.
If you're using a non-English language, or have been using one on your machine, you might have to localize the user details you're trying to use.
E.g. [NT AUTHORITY\Network Service] on a Swedish machine is [NT INSTANS\Nätverkstjänst].
Spent hours trying to figure out why BUILTIN\, NT AUTHORITY\, <MachineName>\ etc. didn't work.
My issue was the length of the login. In Domain\User syntax, Windows uses the so called pre-Windows 2000 syntax. That syntax limits the length of the username to 20 characters. You have to truncate the username to the first 20 characters and then it should work, like so:
Domain\Abcdefghijklmnopqrstuvwxyz
Becomes
Domain\Abcdefghijklmnopqrst

Finding out the windows group by virtue of which a user is able to access a database in sql server?

There is a SQL Server 2005 database with mixed-mode authentication.
Among others, we have the following logins on the server: our-domain\developers-group-1, and our-domain\developers-group-2 which are AD groups.
The our-domain\developer-group-2 is added to the sysadmin role on the server, by virture of which all domain users of that group can access any database as SQL Server implictly maps the sysadmin role to the dbo user in each database.
There are two users our-domain\good-user and our-domain\bad-user
The issue is the following: Both the good-user and the bad-user have the exact same AD group memberships. They are both members of our-domain\developers-group-1 and our-domain\developers-group-2. The good-user is able to access all the databases, and the bad-user is not. The bad-user is able to login, but he is unable access any databases. By the way, I am the good-user.
How do I go about finding out why?
Here's what I tried so far:
When I do print current_user, I get dbo
When I do print system_user, I get my-domain\good-user
When I do select * from fn_my_permissions(NULL, 'SERVER'), I see permissions.
But if do execute as user='my-domain\good-user'; select * from fn_my_permissions(NULL, 'SERVER'), I dont see any permisisons.
And When I do, execute as user='my-domain\bad-user'; select * from fn_my_permissions(NULL, 'SERVER'), I dont see any permisisons.
Also, I was wondering if there is a sql command that will tell me, "hey! the current database user is able to access this database because he is a member such-and-such ad-group, which is a login that is mapped to such-and-such user in this database".
If you have the relevant permissions within Management Studio, this shouldn't take too long to work out. It sounds like the bad-user AD group has limited permissions within SQL Server.
You need to check the settings in Security in the GUI, and check the mappings for each of these AD groups - clicking on the databases to see what permissions they have on each database.
Is it possible that you simply have implicit permissions as the creator/owner of the objects, yet no explicit permissions have been granted on the AD groups/roles or to your user individually?

When is IS_MEMBER set in Sql Server?

I am trying to get IS_MEMBER working in a UDF in Sql Server 2005.
I have a windows group "Domain\TestGroup".
I allocate my Login "Domain\Kieran" to it.
select SUSER_NAME();
gives "Domain\Kieran"
but
select IS_MEMBER('Domain\TestGroup');
returns NULL.
The NULL answer from IS_MEMBER means that SQL Server does not recognise the Windows group.
It looks at the login token from your connection. It does not query Active Directory.
From the BOL link:
IS_MEMBER determines Windows group
membership by examining an access
token that is created by Windows. The
access token does not reflect changes
in group membership that are made
after a user connects to an instance
of SQL Server.
So, even though doamin\kieran is in the group you'll probably need to log out and back in so your login token is updated with the group membership.
It should all work in your UDF (unless you have EXECUTE AS USER or OWNER in the UDF)
Ah. I think I see the problem.
My login is in builtin\Administrators which is a member of the server fixed role sysadmin.
Therefore I'm a member of sysadmin, which means I'm dbo and won't see any role or group information.
Check your ERRORLOG and see if there is any error indicating that the SQL Server service cannot connect to the 'domain' Active Directory.

How do I prevent SQL Server sysadmin users write access?

I have created a test user that has sysadmin right in SQL Server 2005 (sysadmin, because i want to profile with this user name also).But i want to restrict that test users access rights to production database.
It is under "logins" and also db name selected under the "User Mapping" tab of its properties with "db_denydatareader" default schema. But it is still can run select statements.
Sorry but once you give SysAdmin access, you've given away the farm. You'll have to create a different role for the test user and then grant access only to the databases you want.

Resources