Sind "Benutzer erstellen" und "Verbindung gewähren" funktional gleichwertig?

8

Ich habe per se kein Problem, aber ich habe festgestellt, dass, wenn ich einem Principal, der nicht in der Datenbank vorhanden ist, eine Datenbankberechtigung erteile, die Berechtigung in sys.database_permissions angezeigt wird, der Benutzer jedoch keine Verbindung zu herstellen kann Datenbank (wie erwartet). Wenn ich dann grant connectzum Benutzer, ist alles in Ordnung. Was mich fragte, ob create userund grant connectfunktionell gleichwertig. Das heißt, gibt es noch etwas, create userdas grant connectdas nicht tut?

Ben Thul
quelle

Antworten:

9

Sie können Server-Principals keine Datenbankberechtigungen erteilen: Sie müssen zuerst einen Datenbank-Principal erstellen, was Sie wahrscheinlich bereits getan haben.

Sie beziehen sich auf das Fehlen von CONNECT-Berechtigungen für den GUEST-Principal, das wahrscheinlich von einem weisen DBA widerrufen wurde. Wenn einem Datenbankprinzipal keine expliziten CONNECT-Berechtigungen erteilt werden, erbt er die Berechtigung vom Gastbenutzer.

Hier ist ein Repro-Skript, das Ihnen helfen kann, die Funktionsweise zu verstehen:

-- create a test database
CREATE DATABASE testPermissions;
GO

USE testPermissions;
GO

-- revoke CONNECT permissions from users that 
-- are not granted CONNECT explicitly or
-- do not inherit the permission from server
-- or database roles.
-- this is considered a security best practice
REVOKE CONNECT FROM GUEST;
GO

-- create a test table
CREATE TABLE someTable (
    someColumn int
);
GO

-- insert some values
INSERT INTO someTable VALUES (1);
GO

-- create a login, AKA server principal
-- this login has NO PERMISSIONS on the database
CREATE LOGIN testlogin WITH PASSWORD=N'aVeryLongPasswordNobodyWillEverGuess', CHECK_POLICY = OFF
GO


-- if you try to grant database permissions 
-- to a login you get an error
GRANT SELECT TO testlogin;
GO

-- Msg 15151, Level 16, State 1, Line 1
-- Cannot find the user 'testlogin', because it does not exist or you do not have permission.

-- if you create a database user you are creating
-- a link between a database principal and
-- a server principal with the "FOR LOGIN" clause
CREATE USER testUser FOR LOGIN testLogin;
GO

-- now if you grant some permissions to the 
-- database principal you won't get any errors
GRANT SELECT TO testUser;
GO

-- you can now see that the database principal
-- has been granted some permissions
SELECT pe.class_desc
    ,OBJECT_NAME(pe.major_id) AS target_object_name
    ,pe.permission_name
    ,pr.name AS grantee
    ,pr.type_desc
FROM sys.database_permissions AS pe
LEFT JOIN sys.database_principals AS pr
    ON pe.grantee_principal_id = pr.principal_id
WHERE pr.name = 'testUser';
GO


-- class_desc  target_object_name  permission_name  grantee   type_desc
-- ----------- ------------------- ---------------- --------- ----------
-- DATABASE    NULL                SELECT           testUser  SQL_USER


-- If you try to connect as the "testUser" database principal
-- you will get an error, as it doesn't have CONNECT privileges
EXECUTE AS USER = 'testUser';
GO

-- Msg 916, Level 14, State 1, Line 1
-- The server principal "testlogin" is not able to access the database "testPermissions" under the current security context.

-- Now grant the CONNECT privilege
GRANT CONNECT TO testUser;
GO

-- If you try to connect as testUser things
-- will now work as expected
EXECUTE AS USER = 'testUser';
GO

USE testPermissions
GO

-- the select permissions are already granted:
-- the query works
SELECT *
FROM someTable;

REVERT;
GO
spaghettidba
quelle