One place recognises AX (version 3.0/4.0/2009/2012/2012 R2/F&O, schema owner, model store) from metadata only. Per-version adapters hold all table/column knowledge, check every column in sys.columns before use and degrade to 'ikke målbar' with the exact column or the exact GRANT text. Only AX 3.0 is verified against a real customer schema; 2009/2012 are written from Microsoft's documented schema (docs/dynamics-ax/*.documented.tsv, replaced by a real export when one is dropped in). grant-dynamics-ax-read.sql is version- and schema-aware (bmssa) and covers exactly the adapters' tables. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
101 lines
5 KiB
Transact-SQL
101 lines
5 KiB
Transact-SQL
/*
|
||
SQLInsight Pro: valgfri læseadgang til Dynamics AX' systemtabeller
|
||
=====================================================================
|
||
|
||
TILVALG. Agenten læser normalt kun metadata (grant-least-privilege.sql). Med dette script må den desuden læse de
|
||
få AX-systemtabeller, som AX-tjekkene bruger, i ÉN navngiven AX-database, så SQLInsight kan advare om batchjob i
|
||
fejl, forsinkede eller hængende batchjob, nummerserier og RecId'er der er ved at løbe tør:
|
||
|
||
Axapta 3.0 og AX 4.0: BATCH, NUMBERSEQUENCETABLE, NUMBERSEQUENCEREFERENCE, SYSTEMSEQUENCES, SQLDICTIONARY, DATAAREA
|
||
AX 2009: BATCHJOB, BATCHJOBHISTORY, NUMBERSEQUENCETABLE, NUMBERSEQUENCEREFERENCE, SYSTEMSEQUENCES,
|
||
SQLDICTIONARY, DATAAREA
|
||
AX 2012 og F&O: BATCHJOB, BATCHJOBHISTORY, NUMBERSEQUENCETABLE, NUMBERSEQUENCESCOPE, NUMBERSEQUENCEREFERENCE,
|
||
SYSTEMSEQUENCES, SQLDICTIONARY, DATAAREA
|
||
|
||
Kun SELECT, kun disse tabeller: ingen kundedata (debitorer, ordrer, posteringer), ingen skriverettigheder. Scriptet
|
||
finder selv AX-versionen og skemaet, tabellerne ligger i (bmssa i Axapta 3.0, dbo senere). Tabeller, der ikke findes
|
||
i databasen, springes over. Scriptet kan køres igen uden skade. Fjern adgangen igen med revoke-dynamics-ax-read.sql.
|
||
|
||
SQLInsight Web viser det samme som færdige GRANT-sætninger for hver AX-database (Dynamics AX → AX-databaser).
|
||
AX 2009, 2012 og F&O er baseret på Microsofts dokumenterede skema – ikke verificeret mod kundedata.
|
||
|
||
Understøtter SQL Server 2005 og nyere. Kør som sysadmin eller som db_owner/db_securityadmin i AX-databasen.
|
||
*/
|
||
SET NOCOUNT ON;
|
||
|
||
DECLARE @DatabaseName sysname;
|
||
DECLARE @LoginName sysname;
|
||
SET @DatabaseName = N'AXDB'; -- <== ret til AX-databasen
|
||
SET @LoginName = N'DOMÆNE\svc-sqlinsight$'; -- <== ret til agentens login
|
||
|
||
IF DB_ID(@DatabaseName) IS NULL
|
||
BEGIN
|
||
RAISERROR(N'Databasen %s findes ikke.', 16, 1, @DatabaseName);
|
||
RETURN;
|
||
END;
|
||
|
||
IF SUSER_SID(@LoginName) IS NULL
|
||
BEGIN
|
||
RAISERROR(N'Login %s findes ikke. Kør grant-least-privilege.sql først.', 16, 1, @LoginName);
|
||
RETURN;
|
||
END;
|
||
|
||
DECLARE @Procedure nvarchar(300);
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Procedure = QUOTENAME(@DatabaseName) + N'.sys.sp_executesql';
|
||
SET @Sql = N'
|
||
SET NOCOUNT ON;
|
||
DECLARE @schema sysname;
|
||
DECLARE @precision int;
|
||
DECLARE @version nvarchar(10);
|
||
DECLARE @tables nvarchar(400);
|
||
DECLARE @user sysname;
|
||
DECLARE @grant nvarchar(max);
|
||
DECLARE @count int;
|
||
|
||
SELECT TOP 1 @schema = s.name, @precision = c.precision
|
||
FROM sys.tables t
|
||
JOIN sys.schemas s ON s.schema_id = t.schema_id
|
||
LEFT JOIN sys.columns c ON c.object_id = t.object_id AND UPPER(c.name) = N''RECID''
|
||
WHERE UPPER(t.name) = N''SQLDICTIONARY'' AND OBJECT_ID(QUOTENAME(s.name) + N''.DATAAREA'', N''U'') IS NOT NULL
|
||
ORDER BY CASE WHEN s.name = N''dbo'' THEN 0 ELSE 1 END, s.name;
|
||
|
||
IF @schema IS NULL
|
||
BEGIN
|
||
DECLARE @database sysname;
|
||
SET @database = DB_NAME();
|
||
RAISERROR(N''%s er ikke en Dynamics AX-database (SQLDICTIONARY og DATAAREA findes ikke i samme skema). Intet er ændret.'', 16, 1, @database);
|
||
RETURN;
|
||
END;
|
||
|
||
/* The same version rules as SQLInsight''s detection (Core/DynamicsAx/AxDetection.cs). */
|
||
IF @precision <= 10 SET @version = N''3.0'';
|
||
ELSE IF OBJECT_ID(QUOTENAME(@schema) + N''.BATCHJOB'', N''U'') IS NULL SET @version = N''4.0'';
|
||
ELSE IF OBJECT_ID(QUOTENAME(@schema) + N''.NUMBERSEQUENCESCOPE'', N''U'') IS NULL SET @version = N''2009'';
|
||
ELSE SET @version = N''2012'';
|
||
|
||
/* The tables per version: the same lists as the version adapters'' ReadTables (Core/DynamicsAx/AxSchemaAdapter.cs). */
|
||
SET @tables = CASE
|
||
WHEN @version IN (N''3.0'', N''4.0'') THEN N''|BATCH|NUMBERSEQUENCETABLE|NUMBERSEQUENCEREFERENCE|SYSTEMSEQUENCES|SQLDICTIONARY|DATAAREA|''
|
||
WHEN @version = N''2009'' THEN N''|BATCHJOB|BATCHJOBHISTORY|NUMBERSEQUENCETABLE|NUMBERSEQUENCEREFERENCE|SYSTEMSEQUENCES|SQLDICTIONARY|DATAAREA|''
|
||
ELSE N''|BATCHJOB|BATCHJOBHISTORY|NUMBERSEQUENCETABLE|NUMBERSEQUENCESCOPE|NUMBERSEQUENCEREFERENCE|SYSTEMSEQUENCES|SQLDICTIONARY|DATAAREA|''
|
||
END;
|
||
|
||
SELECT @user = name FROM sys.database_principals WHERE sid = SUSER_SID(@login);
|
||
IF @user IS NULL
|
||
BEGIN
|
||
SET @user = @login;
|
||
SET @grant = N''CREATE USER '' + QUOTENAME(@user) + N'' FOR LOGIN '' + QUOTENAME(@login) + N'';'';
|
||
EXEC (@grant);
|
||
PRINT N''Bruger oprettet uden rettigheder: '' + @user;
|
||
END;
|
||
|
||
SET @grant = N'''';
|
||
SET @count = 0;
|
||
SELECT @grant = @grant + N''GRANT SELECT ON '' + QUOTENAME(s.name) + N''.'' + QUOTENAME(t.name) + N'' TO '' + QUOTENAME(@user) + N''; '', @count = @count + 1
|
||
FROM sys.tables t
|
||
JOIN sys.schemas s ON s.schema_id = t.schema_id
|
||
WHERE s.name = @schema AND CHARINDEX(N''|'' + UPPER(t.name) + N''|'', @tables) > 0;
|
||
IF @count > 0 EXEC (@grant);
|
||
PRINT N''Dynamics AX '' + @version + N'' i skemaet '' + @schema + N'': SELECT givet på '' + CAST(@count AS nvarchar(10)) + N'' tabeller i '' + DB_NAME() + N'' til '' + @user + N''.'';';
|
||
EXEC @Procedure @Sql, N'@login sysname', @login = @LoginName;
|