What is the difference between SYSTEM_USER and USER in SQL server? - sql-server

I am very new to databases and confused between the keywords SYSTEM_USER and USER in MSSQL. The definitions say that they return the username in the current context. but the instance I have running returns 'dbo' for USER and 'sa' for system user.
Can somebody highlight the exact difference between the two?

SYSTEM_USER: returns Server Login name that was used to login to the instance (either SQL Server login or AD/Domain/Windows user-name).
USER, CURRENT_USER, USER_NAME(), or SESSION_USER: these all return Database User principal, which is (by default) dbo if you are db-owner or logged in as a sysadmin or sa (not to be confused with the dbo schema or the DB_Owner of current database in use).
Examples:
SELECT SYSTEM_USER --> myDomain\user.name
----------------------------------------------
SELECT USER --> dbo
SELECT CURRENT_USER --> dbo
SELECT USER_NAME() --> dbo
SELECT SESSION_USER --> dbo
----------------------------------------------
Note: USER_NAME([user_id]) can additionally take an int-user-id, default arg is 1, i.e.: USER_NAME(1) would be same as USER_NAME().

SYSTEM_USER to return the current system user name.
USER to return the database user name.

According to difference between SYSTEM_USER and USER:
If the current user is logged in to Microsoft® SQL ServerT using
Windows Authentication, SYSTEM_USER returns the Windows 2000 or
Windows NT 4.0 login identification name
for example, DOMAIN\user_login_name.
However, if the current user is logged in to SQL Server using SQL
Server Authentication, SYSTEM_USER returns the SQL Server login
identification name,
for example, sa for a user logged in as sa

Related

How do I determine the user when my SQL Server Login is a AD group?

Consider this example:
If I have a security group on Active Directory (let's call it MyGroup) which has 5 users in it (MYDOMAIN\User1 - MYDOMAIN\User5)
If I create a SQL Server Login and User for my database like this:
CREATE LOGIN [MYDOMAIN\MyGroup] FROM WINDOWS;
CREATE USER [MyGroup] FOR LOGIN [MYDOMAIN\MyGroup];
If MYDOMAIN\User4 connects to the database, is there a SQL query I can use to tell which user of MyGroup has connected to the database?
The function SUSER_SNAME will return the current login, when called without a parameter.
Example
SELECT
SUSER_SNAME()
;

How to understand that a user gets database access in SQL Server

I have been tasked with auditing security on my SQL Server. But, when I look at a login in SQL Server Management Studio, I don't see a checkbox beside the master db for that login. How can I determine what databases a login has access to?
ther is a useful system store procedure to list all mapping user of SQL login account.
Syntax:
sp_msloginmappings #Loginname , #Flags
#loginname: the login account name, If loginname is not specified, results are returned for the login account(current login name)
#Flags: value can be 0 and 1, by default 0. 0 means show mapping user in all databases. 1 indicates how mapping user in current
database context.
e.g
here is sample:
sp_msloginmappings 'sa'
show mapping user account info in all databases for login account 'sa'
sp_msloginmappings 'sa', 1
show mapping user account info in current databases context for login account 'sa'
If you see a login match up to a user in this manner, then the login has access to the database.
SELECT sp.name AS 'Login', dp.name AS 'User'
FROM sys.database_principals dp
JOIN sys.server_principals sp
ON dp.sid = sp.sid
ORDER BY sp.name, dp.name;
you can do it in SQL Server 2005/2008

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

SQL USER_NAME() windows authentication

When I logged in sql management studio with windows authentication and I run
SELECT USER_NAME()
I see the result as dbo.
I would of thought that it would showed my user ....
I more looking at the explaination to as why it returns dbo
Use this instead
SELECT SUSER_NAME()
USER_NAME: Returns a database user name from a specified identification number.
SUSER_NAME: Returns the login identification name of the user.
Try:
SELECT SUSER_SNAME()
i had similar problem, the problem is due to the way user id is created.
choose the login id under security -> right click properties -> Server Roles. Ensure you click only "Public" no "sysadmin"

Sql Server 2005 how to change dbo login name

I have a database with user 'dbo' that has a login name "domain\xzy". How do I change it from "domain\xzy" to "domain\abc".
I figured it out. Within SQL Management Studio you have to right-click on the database -> Properties -> Files -> Owner field. Change this field to the login name/account that you want associated with the "dbo" username for that database. Please keep in mind that the login name/account you choose must already be setup in the sql server under Security -> Logins
If you are trying to remap a login to a db user you can use sp_change_user_login
exec sp_change_user_login 'Update_One', 'user', 'login'
PhantomTypist gives a good answer using the GUI. For achieving the same result with TSQL, you can use this code:
USE [My_Database_Name]
GO
EXEC dbo.sp_changedbowner #loginame = N'domain\abc', #map = false
GO
This is a Windows login, not a SQL Server login, so you cannot 'change' the login name since it is linked to the user account in Active Directory.
Create a new Server Login (Windows) mapped to the new windows user (and remove the old one if necessary). Then in login's Security > User Mapping, permission that login to the appropriate database as user 'dbo' (or assign to the db_owner role)

Resources