sqlinsight-pro/src/SQLInsight.Core/Configuration/GrantScript.cs
Søren Eggert Lundsteen Olsen 8776faefb3 Instance configuration core: database selection, sealed credentials, agent request contracts
DatabaseSelection decides which databases the database-specific checks run in
(system databases always), and which may send Dynamics AX findings to the hub
(default none). CredentialEnvelope seals a SQL login password with the agent's
RSA public key (RSA-OAEP-SHA256 + AES-256-GCM), bound to server and login, so only
the agent can open it. Shared contracts for connection tests and discovery, server
address validation, the service account login rule, and the least-privilege GRANT
script filled in for one login.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 13:21:59 +02:00

49 lines
2.4 KiB
C#

using System.Text;
using System.Text.RegularExpressions;
namespace SQLInsight.Core.Configuration;
/// <summary>
/// db/permissions/grant-least-privilege.sql, ready to run for one login: what SQLInsight Web shows for a newly added
/// server. SQLInsight never runs it on the customer's server itself; a sysadmin runs it.
/// </summary>
public static partial class GrantScript
{
/// <summary>The script with <paramref name="login"/> filled in. For a Windows login it starts by creating the login if it is missing.</summary>
public static string For(string login, bool windowsLogin)
{
ArgumentException.ThrowIfNullOrWhiteSpace(login);
var literal = "N'" + login.Trim().Replace("'", "''", StringComparison.Ordinal) + "'";
var script = LoginPlaceholder().Replace(Template(), _ => "SET @LoginName = " + literal + ";", 1);
var header = new StringBuilder();
header.Append("/* Kør som sysadmin på instansen. Giver SQLInsight-agentens login ").Append(InComment(login.Trim())).Append(" de rettigheder, den skal bruge. */\r\n");
if (windowsLogin)
{
header.Append("IF SUSER_ID(").Append(literal).Append(") IS NULL\r\n CREATE LOGIN ")
.Append(Quote(login.Trim())).Append(" FROM WINDOWS;\r\nGO\r\n");
}
else
{
header.Append("/* SQL-login: opret det først, hvis det mangler, fx\r\n CREATE LOGIN ").Append(InComment(Quote(login.Trim())))
.Append(" WITH PASSWORD = N'…', CHECK_POLICY = ON; */\r\n");
}
return header.Append(script).ToString();
}
/// <summary>The script as shipped, with the placeholder login.</summary>
public static string Template()
{
using var stream = typeof(GrantScript).Assembly.GetManifestResourceStream("SQLInsight.Core.grant-least-privilege.sql")
?? throw new InvalidOperationException("grant-least-privilege.sql mangler i programmet.");
using var reader = new StreamReader(stream);
return reader.ReadToEnd();
}
private static string InComment(string text) => text.Replace("*/", "* /", StringComparison.Ordinal).Replace("/*", "/ *", StringComparison.Ordinal);
private static string Quote(string name) => "[" + name.Replace("]", "]]", StringComparison.Ordinal) + "]";
[GeneratedRegex(@"SET @LoginName = N'[^']*';[^\r\n]*")]
private static partial Regex LoginPlaceholder();
}