Access Master DB Tables from User Database in SQL AZURE - sql

I am trying to access sys.SQL_Logins on Master DB from a User Database so that I could join sys.sql_logins with sys.sysusers.
UserDatabase
SELECT DP.NAME, DP.sid, SU.sid
FROM sys.sql_logins DP
INNER JOIN SYS.sysusers SU
ON DP.name=SU.name
In Azure I am not able to do this, since I am not able to call master DB from UserDatbase. My objective was to compare SID of sys.sql_logins with sys.sqlusers from User Database.
Is there any way I could join these two tables in Azure.

You can only execute queries against a single database. However, you can set up an external table to point to the master database views. This code should get you there:
CREATE MASTER KEY; -- if your DB doesn't already have one
GO
CREATE DATABASE SCOPED CREDENTIAL AccessToMaster
WITH IDENTITY = 'yourmasterlogin', SECRET = 'yourpassword'; --TODO set a login name and password that can access the master database
GO
CREATE EXTERNAL DATA SOURCE MasterDatabase
WITH
(
TYPE = RDBMS,
LOCATION = N'yourserver.database.windows.net', --TODO replace your server name
DATABASE_NAME = N'master',
CREDENTIAL = AccessToMaster
);
GO
CREATE SCHEMA MasterDB AUTHORIZATION dbo;
GO
CREATE EXTERNAL TABLE MasterDB.sql_logins
(
[name] sysname,
principal_id int,
[sid] varbinary(85),
[is_disabled] bit
)
WITH
(
DATA_SOURCE = MasterDatabase,
SCHEMA_NAME = 'sys',
OBJECT_NAME = 'sql_logins'
);
GO
SELECT * FROM MasterDB.sql_logins;
GO

Related

Cross Database Trigger with EXECUTE AS not working - permission problem

I have 2 Databases. Database A belongs to an ERP System and Database B is my own database.
I've created an AFTER INSERT DML Trigger in a table which belongs to Database A.
Every single ERP User is associated with a DB User.
At the moment I copy all the users from Database A to Database B to grant permission for my tables.
It was the only solution I could find to make it work but it's bad because a new ERP User will get an Error Message when there's no user in Database B.
So now I tried it once again to use WITH EXECUTE AS .... I tried OWNER and different DB users but nothing works and I have absolutely no idea what's wrong.
I even granted all permissions for the user on the tables I use in the trigger.
Let's say I have a user called "triggerUser" when I do WITH EXECUTE AS 'triggerUser' it doesn't work but when I remove the EXECUTE AS .... and use the triggerUser for the ERP Login it works so the user got the permissions to write my tables.
Here's my trigger. Maybe you have an idea what I'm missing.
CREATE TRIGGER [dbo].[TR_manAddAutomatikQueueForLager_AfterInsert]
ON [SL_MWAWI].[dbo].[LAGERPROTOKOLL]
WITH EXECUTE AS 'moep'
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE #Mandant int
SET #Mandant = (SELECT MANDANT_ID FROM SL_Daten.dbo.MANDANT WHERE Datenbankname = 'SL_MWAWI')
-- insert
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
INSERT INTO maniacSellerGen2.dbo.manAutomatikQueue
SELECT #Mandant, ISNULL(wsa.WebShopId, wsav.WebShopId), ISNULL(wsav.VaterArtikelnummer, wsa.Artikelnummer), 'Lager', GETDATE()
FROM inserted
LEFT JOIN maniacSellerGen2.dbo.manWebShopArtikel wsa
ON wsa.Artikelnummer COLLATE DATABASE_DEFAULT = inserted.Artikelnummer COLLATE DATABASE_DEFAULT
AND #Mandant = wsa.Mandant
LEFT JOIN maniacSellerGen2.dbo.manWebShopArtikelVarianten wsav
ON wsav.Artikelnummer COLLATE DATABASE_DEFAULT = inserted.Artikelnummer COLLATE DATABASE_DEFAULT
AND #Mandant = wsav.Mandant
WHERE ((wsa.Artikelnummer IS NULL AND wsav.Artikelnummer IS NOT NULL)
OR (wsa.Artikelnummer IS NOT NULL AND wsav.Artikelnummer IS NULL))
END
END
Here's a screenshot from the permissions for the user in every database it has db_datareader and db_datawriter.
Permissions
I also did tried this:
GRANT INSERT ON dbo.manAutomatikQueue TO moep
GRANT DELETE ON dbo.manAutomatikQueue TO moep
GRANT UPDATE ON dbo.manAutomatikQueue TO moep
GRANT SELECT ON dbo.manAutomatikQueue TO moep
Thanks a lot!

Identify Schema for table depending on User Access

I have a scenario where there are two database
schemas: Schema1 and Schema2 and a table: Table1.
Same Table1 exisits in both the schemas like Schema1.Table1 and Schema2.Table1.
Now we have some stored procedures which will be in another Schema say Schema3.
CREATE PROCEDURE SCHEMA3.GETDETAILS (
#AS_CODE_TYPE VARCHAR(1) ,
#AS_OUT_FIELD1 VARCHAR(50) OUT ,
#AS_RETURN_VAL INTEGER OUT
)
AS
BEGIN
SELECT #AS_OUT_FIELD1 = [EXTERNALREFKEY] FROM TABLE1 WHERE CODE_TYPE = #AS_CODE_TYPE
IF #AS_OUT_FIELD1 <> ' '
BEGIN
SET #AS_RETURN_VAL = 1 ;
END
ELSE
BEGIN
SET #AS_RETURN_VAL = - 1 ;
END
END
Now My question:
How do i get the schema details for a given user .
Do i need to modify the SP to dynamically append the schema to table depending on the user access to a specific schema.
Please help
When creating a user, if you don't specify it's schema, it will has the default schema 'dbo'.
You can get the user schema by running the bellow query in master DB:
USE master;
SELECT s.name user, s.default_schema_name user_schema FROM sys.database_principals s
WHERE s.name='user'
GO
For example:
You also can alter the user schema if you have the permission.
For more details, Changing the default schema of a user:
ALTER USER Mary51 WITH DEFAULT_SCHEMA = Purchasing;
GO
Hope this helps

SQL Azure database : Query SQL server Azure data warehouse data

Is there any option to query the Azure SQL Data warehouse (Cloud) from the Azure SQL Server database (Cloud)?
We have a central warehouse hosted in cloud with all the domains needed for the Application. It would be great if we can use those tables as external tables using the approach described at https://azure.microsoft.com/en-us/blog/querying-remote-databases-in-azure-sql-db.
Querying Data Warehouse from SQL DB is currently unsupported.
You can access Azure SQL Data Warehouse from Azure SQL using external tables
Here's the article: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-external-table-transact-sql
Example:
CREATE MASTER KEY
CREATE DATABASE SCOPED CREDENTIAL dwcredential WITH IDENTITY = '<username>',
SECRET = '<password>';
CREATE EXTERNAL DATA SOURCE sqldw WITH
(
TYPE = RDBMS,
LOCATION = N'<dwserver>.database.windows.net',
DATABASE_NAME = N'<dwdatabasename>',
CREDENTIAL = dwcredential
)
GO
CREATE EXTERNAL TABLE [<azuresqltablename>](
[col1] [int] NOT NULL,
[col2] [int] NOT NULL
)
WITH
(
DATA_SOURCE = sqldw,
SCHEMA_NAME = 'dbo', --schema name of remote table
OBJECT_NAME = '<dwtablename>' --table name of remote table
);

Find all databases where particular user exists and its role

I have a huge instance containing 1000+ databases. I need to find a way to query entire instance and find databases that contain particular user and what role this user has. I am not interested whether the user is orphanded. I just want to know which databases have this user and which do not.
Lets say that my user is called TestUser. Databases that do not contain this user should return NULL.
I would like the results in the following format:
Column1 - Database Name
Column2 - UserName (if exists or else NULL)
Column3 - UserRole (if exists or else NULL)
Under the assumption that you are not looking for issuing 1000+ selects, one (extremely ugly) solution would be:
SELECT 'DB_1' , UserName , UserRole
FROM DB_1.UsersTable
WHERE Username = 'TestUser'
UNION
SELECT 'DB_2' , UserName , UserRole
FROM DB_2.UsersTable
WHERE Username = 'TestUser'
:
:
Another solution is to use DYNAMIC SQL:
Collect the list of all the DBs that you to check,
Build a string hosting a select statement like the one above,
Execute the statement.
Again, both methods are shameful.
create table #temp
(
dbname sysname,
dbrole sysname,
dbuser sysname
)
Exec sp_msforeachdb '
if db_id()>4
Begin
insert into #temp
select db_name(), rp.name as database_role, mp.name as database_user
from sys.database_role_members drm
join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)
End
'
The Roles Part is referenced from here:
Get list of all database users with specified role

List the User mapped to a Login on one particular database

I'm back here with a SQL User/Login problem.
First off all i'm working on SQL server 2008 and i'm not the master on that server.
On that SQL server i have different Login and these Login are mapped to a USER to my database 'DB_MyDataBase'.
Indeed, i have 10 different Login mapped to 10 different User on my database 'DB_MyDataBase'.
For i.e., when i'm connecting to the SQL server with a Login 'Laurent', That SQL Login 'Laurent' is the USER 'Laurel' on my database 'DB_MyDataBase'. For the moment, no problem.
But now for that 10 different Login and want to know their respective USER for my database 'DB_MyDataBase'.
After some research i've found a request that can do "the job"
sp_msloginmappings 'Laurent', 1
Normally, that show mapping user account info in current databases context for login account 'Laurent'
But when i tried it, i had a error message.
Nom d'objet 'dbo.syslogins' non valide.
Error message is : Object name 'dbo.syslogins' is not valid for non French users.
I've found another request which is working "a bit".
SET NOCOUNT ON
CREATE TABLE #temp
(
SERVER_name SYSNAME NULL ,
Database_name SYSNAME NULL ,
UserName SYSNAME ,
GroupName SYSNAME ,
LoginName SYSNAME NULL ,
DefDBName SYSNAME NULL ,
DefSchemaName SYSNAME NULL ,
UserID INT ,
[SID] VARBINARY(85)
)
DECLARE #command VARCHAR(MAX)
--this will contain all the databases (and their sizes!)
--on a server
DECLARE #databases TABLE
(
Database_name VARCHAR(128) ,
Database_size INT ,
remarks VARCHAR(255)
)
INSERT INTO #databases--stock the table with the list of databases
EXEC sp_databases
SELECT #command = COALESCE(#command, '') + '
USE ' + database_name + '
insert into #temp (UserName,GroupName, LoginName,
DefDBName, DefSchemaName,UserID,[SID])
Execute sp_helpuser
UPDATE #TEMP SET database_name=DB_NAME(),
server_name=##ServerName
where database_name is null
'
FROM #databases
EXECUTE ( #command )
SELECT loginname ,
UserName ,
Database_name
FROM #temp
WHERE LoginName = 'Laurent'
So that one is working it's listing all User mapped to that Login on every database BUT (there is always a "but"...) it's only working with the Login i use to connect.
For i.e. When i connect to the SQL server with Login 'Laurent' the previous request is working because i request for the same Login that i used to connect to the SQL server but when i connect with Login 'Laurent' and do the previous request with a different Login (so not 'Laurent' but another one which have a user mapped to my database 'DB_MyDataBase'.) I don't see anything, it returns me blank column....
Maybe it's because i'm not master on that SQL server.
So how i can list User mapped to a Login different from the one i'm connected?
I hope my question is clear enough (sorry for long text) and thanks for your future answer. Don't hesitate to ask me if you need further info to answer me.
What you can see will depend on the permissions of the user you are logged in as. This query against two of the security catalog views should give you what you want provided you have the necessary permission.
select
dp.name as UserName,
sp.name as LoginName
from
sys.database_principals dp
left join sys.server_principals sp on sp.sid = dp.sid
where
dp.type in ('S', 'U')