- A lock timeout or deadlock while detecting (e.g. during an AX table synchronisation) dropped the database from AX monitoring for an hour, so its findings resolved and reopened. The earlier detection is kept and retried within 5 minutes. A cancelled collection is no longer reported as "læsningen fejlede". - A lock timeout kept the earlier batch picture forever; now at most 15 minutes (MeasuredAt), so a job that has started is not reported late from an old picture. - revoke-dynamics-ax-read.sql revoked SELECT on same-named tables in every schema, also a DENY set by a DBA. It now finds the AX schema like the grant script and revokes only granted SELECT there. - SQLI-AX-006 skips blocked sequences (as -005/-008 do); forecasts under a day say "inden for et døgn" instead of "om ca. 0 dage". - Integration tests: the SQL Scripts run as-is in main's format, and the shared connection has the agent's session settings after the AX reads. - docs/dynamics-ax.md: history bounds, lock-timeout window, session settings, /detection-problems, API redaction. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
66 lines
3.1 KiB
Transact-SQL
66 lines
3.1 KiB
Transact-SQL
/*
|
|
SQLInsight Pro: fjern den valgfri læseadgang til Dynamics AX' systemtabeller
|
|
==============================================================================
|
|
|
|
Fjerner det, grant-dynamics-ax-read.sql gav, i én AX-database: SELECT på AX' batch-, nummerserie-, RecId- og
|
|
firmatabeller. Agentens database-bruger slettes ikke (den kan være oprettet af grant-least-privilege.sql). Bagefter
|
|
viser SQLInsight AX-datatjekkene som "ikke målbar" med den GRANT, der skal til for at slå dem til igen.
|
|
|
|
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;
|
|
|
|
DECLARE @Procedure nvarchar(300);
|
|
DECLARE @Sql nvarchar(max);
|
|
SET @Procedure = QUOTENAME(@DatabaseName) + N'.sys.sp_executesql';
|
|
SET @Sql = N'
|
|
SET NOCOUNT ON;
|
|
DECLARE @user sysname;
|
|
DECLARE @revoke nvarchar(max);
|
|
DECLARE @count int;
|
|
SELECT @user = name FROM sys.database_principals WHERE sid = SUSER_SID(@login);
|
|
IF @user IS NULL
|
|
BEGIN
|
|
PRINT N''Login''''et har ingen bruger i '' + DB_NAME() + N''. Intet at fjerne.'';
|
|
RETURN;
|
|
END;
|
|
|
|
/* Only the AX schema (where SQLDICTIONARY and DATAAREA are, as grant-dynamics-ax-read.sql finds it), and only a SELECT
|
|
that was granted: a DENY, or a grant on a same-named table in another schema set up for another reason, is left alone. */
|
|
DECLARE @schema sysname;
|
|
SELECT TOP 1 @schema = s.name
|
|
FROM sys.tables t
|
|
JOIN sys.schemas s ON s.schema_id = t.schema_id
|
|
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;
|
|
IF @schema IS NULL
|
|
BEGIN
|
|
PRINT DB_NAME() + N'' er ikke en Dynamics AX-database (SQLDICTIONARY og DATAAREA findes ikke i samme skema). Intet er ændret.'';
|
|
RETURN;
|
|
END;
|
|
|
|
SET @revoke = N'''';
|
|
SET @count = 0;
|
|
SELECT @revoke = @revoke + N''REVOKE SELECT ON '' + QUOTENAME(s.name) + N''.'' + QUOTENAME(t.name) + N'' FROM '' + 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 UPPER(t.name) IN (N''BATCH'', N''BATCHJOB'', N''BATCHJOBHISTORY'', N''NUMBERSEQUENCETABLE'', N''NUMBERSEQUENCESCOPE'',
|
|
N''NUMBERSEQUENCEREFERENCE'', N''SYSTEMSEQUENCES'', N''SQLDICTIONARY'', N''DATAAREA'')
|
|
AND EXISTS (SELECT 1 FROM sys.database_permissions p
|
|
WHERE p.class = 1 AND p.major_id = t.object_id AND p.minor_id = 0 AND p.grantee_principal_id = USER_ID(@user)
|
|
AND p.permission_name = N''SELECT'' AND p.state IN (''G'', ''W''));
|
|
IF @count > 0 EXEC (@revoke);
|
|
PRINT N''SELECT fjernet på '' + CAST(@count AS nvarchar(10)) + N'' AX-tabeller i '' + DB_NAME() + N'' for '' + @user + N''.'';';
|
|
EXEC @Procedure @Sql, N'@login sysname', @login = @LoginName;
|