Ist es möglich und wenn ja, wie kann die entfernte IP-Adresse eines Benutzers die Abfrage ausführen, so wie wir den Benutzernamen mit: SUSER_SNAME()
erhalten können?
Update vor Kopfgeld
Ich suche nach einer Lösung, die es ermöglicht, die IP-Adresse eines normalen sterblichen Benutzers und nicht eines Datenbankinhabers zu ermitteln. Die von TheGameiswar oder njc vorgeschlagenen Ideen erlauben es nicht, die IP-Adresse eines Benutzers zu erfassen, der nur eine execute
-Berechtigung erteilt wurde. Sie sind jedoch hervorragende Ideen, um mit dem Problem zu beginnen. Hier liste ich das Wesentliche der Ideen auf:
Bitte sehen Sie sich die Reihenfolge an, die ich befolge:
create procedure MyStoredProcedure as
select client_net_address
from sys.dm_exec_connections
where session_id = @@SPID
Fügen Sie nun einen Benutzer hinzu und erteilen Sie die Berechtigung:
CREATE LOGIN [user_mortal_jack] WITH PASSWORD=N'LongYouLive!!!';
GRANT EXECUTE ON MyStoredProcedure TO [user_mortal_jack];
Wenn ich die Prozedur mit einer Abfrage ausführe:
EXECUTE AS USER = 'user_mortal_jack'
exec MyStoredProcedure
REVERT
Ich bekomme eine Fehlermeldung:
Das ausgeführte Modul ist nicht vertrauenswürdig. Entweder muss dem Besitzer der Datenbank des Moduls die Berechtigung zum Authentifizieren erteilt werden, oder das Modul muss digital signiert sein.
Ich werde diese Nachricht auch erhalten, wenn ich eine zusätzliche Erlaubnis erteile:
grant VIEW SERVER STATE to [user_mortal_jack];
Wenn ich den Anfang der gespeicherten Prozedur ändere:
create procedure MyStoredProcedure
with execute as OWNER as
Ich ende mit einer anderen Art von Fehler:
Informationen zu Windows NT-Gruppe/Benutzer 'blahblah\admin_user', Fehlercode 0x534, konnten nicht abgerufen werden.
Update nach Kopfgeld
Für diese einzige Codezeile, die in ihrer Antwort verborgen ist, wird Hadi eine Kopfprämie gewährt:
CONNECTIONPROPERTY('client_net_address')
dabei erfassen wir die IP-Adresse eines sterblichen Benutzers, ohne dem Benutzer zusätzliche Rechte zu erteilen, die Option TRUSTWORTHY ON der Datenbank einzustellen oder sogar eine Prozedur WITH EXECUTE AS OWNER
-Klausel zu erstellen.
Es gibt zwei Möglichkeiten, die aktuellen Verbindungsinformationen abzurufen
Informationen aus Dynamic Management Views abrufen
SELECT
conn.session_ID as SPID,
conn.client_net_address as IPAddress,
sess.Host_name as MachineName,
sess.program_name as ApplicationName,
login_name as LoginName
FROM sys.dm_exec_connections conn
inner join sys.dm_exec_sessions sess
on conn.session_ID=sess.session_ID
Verwenden von CONNECTIONPROPERTY function (SQL Server 2008 und neuere Version):
select
CONNECTIONPROPERTY('net_transport') AS net_transport,
CONNECTIONPROPERTY('protocol_type') AS protocol_type,
CONNECTIONPROPERTY('auth_scheme') AS auth_scheme,
CONNECTIONPROPERTY('local_net_address') AS local_net_address,
CONNECTIONPROPERTY('local_tcp_port') AS local_tcp_port,
CONNECTIONPROPERTY('client_net_address') AS client_net_address
Wenn Sie dem Benutzer eine bestimmte IP-Adresse zuweisen möchten
CREATE PROCEDURE MyStoredProcedure AS
BEGIN
DECLARE @IP_Address varchar(255);
SELECT @IP_Address = CAST(CONNECTIONPROPERTY('client_net_address') as varchar(200))
IF @IP_Address = 'XXX.XXX.XXX.XXX'
SELECT TOP 1 FROM tb
END
Angenommen, Sie haben eine Tabelle, die die gewährte IP-Adresse enthält (d. H. TBL_IP
)
CREATE PROCEDURE MyStoredProcedure AS BEGIN DECLARE @IP_Address varchar (255);
SELECT @IP_Address = CAST(CONNECTIONPROPERTY('client_net_address') as varchar(200))
IF EXISTS (SELECT 1 FROM TBL_IP WHERE [IP] = @IP_Address )
SELECT TOP 1 FROM tb
ENDE
Wenn Sie einem Benutzer (Datenbankbenutzer) die Ausführung einer gespeicherten Prozedur erteilen möchten, sollten Sie diesen Befehl verwenden
AUSFÜHREN AUF MyStoredProcedure AN Benutzer;
Es gibt viele ausführliche Artikel und Antworten, die sich auf das Problem beziehen, mit dem Sie konfrontiert sind, und viele Lösungsvorschläge, z. B. Einstellung der Datenbank in den Modus TRUSTWORTHY
(bevor Sie sie verwenden, lesen Sie den ersten Link unten) und Trusting the Authenticator und andere Methoden. Sie finden sie in den Links unten
Hinweis: Sie können die @SteveFord-Antwort zur Verwendung der TRUSTWORTHY
-Eigenschaft überprüfen.
Wenn Sie Verbindungen mit Ausnahme bestimmter IP-Adressen blockieren möchten, sollten Sie dieser Antwort folgen
Es gibt auch viele Skripte, die verwendet werden können, um Client- oder Server-IP-Adressen zu erhalten, die in der folgenden Frage enthalten sind:
Verweise
Verwenden der EXECUTE AS OWNER
-Anweisung in einer CREATE PROCEDURE
-Anweisung:
Von _ MSDN
Wenn ein Benutzer ein Modul ausführt, das für die Ausführung in einer .__ angegeben wurde. Kontext anders als CALLER, die Berechtigung des Benutzers zur Ausführung des Moduls wird markiert, aber zusätzliche Berechtigungen werden für Objekte geprüft, die .__ sind. Der Zugriff durch das Modul erfolgt für das Benutzerkonto in der EXECUTE AS-Klausel angegeben. Der Benutzer, der das Modul ausführt, ist in der Tat, den angegebenen Benutzer imitieren.
Der in der EXECUTE AS-Klausel des Moduls angegebene Kontext ist gültig nur für die Dauer der Modulausführung. Der Kontext wird auf .__ zurückgesetzt. Aufrufer, wenn die Modulausführung abgeschlossen ist.
Das Folgende muss von einem Benutzer erstellt werden, der über Berechtigungen zum Abfragen der DMVs verfügt
CREATE PROCEDURE MyStoredProcedure
WITH EXECUTE AS OWNER
AS
BEGIN
SET NOCOUNT ON
SELECT TOP 1
FROM tb
INNER JOIN sys.dm_exec_connections cn
ON tb.client_net_address = cn.client_net_address
WHERE cn.Session_Id = @@SPID
END
Dann müssen Sie den Benutzern Berechtigungen zum Ausführen der gespeicherten Prozedur erteilen:
Aktualisieren Sie, um die richtigen Berechtigungen zu erstellen
Sie müssen Ihre Datenbank auf "Vertrauenswürdig" setzen (siehe Setzen Sie die Datenbank auf "Vertrauenswürdig" :
ALTER DATABASE MyDataBase SET TRUSTWORTHY ON
CREATE LOGIN [user_mortal_jack] WITH PASSWORD=N'LongYouLive!!!';
CREATE USER [user_mortal_jack] FOR LOGIN [user_mortal_jack] WITH DEFAULT_SCHEMA=[dbo]
GO
GRANT EXECUTE ON MyStoredProcedure TO [user_mortal_jack];
Ich habe das getestet und funktioniert jetzt wie erwartet
Sie können Verbindungen DMV verwenden, um das zu erreichen.
select ec.client_net_address,* from sys.dm_exec_connections ec
join
sys.dm_exec_requests rq
on rq.connection_id=ec.connection_id
cross apply
sys.dm_exec_sql_text(rq.sql_handle) txt
where txt.text like '%your stored proc%'
MSDN für client_net_address
Hostadresse des Clients, der eine Verbindung zu diesem Server herstellt. Ist nullfähig.
Um die IP-Adresse und den Benutzernamen eines beliebigen Anrufers abzurufen, ohne ihm alle besonderen Berechtigungen zu erteilen, können Sie den Server und die Datenbank ein wenig betrügen . Um dies zu erreichen, sind ein paar Dinge erforderlich:
ALTER DATABASE MyDataBase SET TRUSTWORTHY ON
[user_mortal_jack]
) [user_immortan_joe]
[user_immortan_joe]
In MyDataBasemaster
grant VIEW SERVER STATE to [user_immortan_joe];
MyDataBase
eine gespeicherte Prozedur (nicht MyStoredProcedure
, in meinem Beispiel get_ip
), Die ein int empfängt, das einen bestimmten session_id
- Parameter darstellt, wird output
(Ausgabe, nicht Rückgabe) die IP-Adresse oder das session_id
. Erstellen Sie es with execute as 'user_immortan_joe'
.get_ip
Und von SUSER_SNAME()
die IP-Adresse und der Benutzername des Anrufers zurückgegeben werden.Auf diese Weise erhalten Sie die IP-Adresse und den Benutzernamen eines Anrufers von MyStoredProcedure
, der das Prinzip des geringsten Privilegs respektiert und die Probleme vermeidet, auf die Sie bei der Suche nach einer Lösung gestoßen sind.
Beispielskript:
use MyDataBase
go
alter database MyDataBase set trustworthy on;
go
CREATE LOGIN [user_mortal_jack] WITH PASSWORD=N'LongYouLive!!!';
go
create user [user_mortal_jack];
go
CREATE LOGIN [user_immortan_joe] WITH PASSWORD=N'ToTheGatesOfValhalla!!!';
go
create user [user_immortan_joe];
go
use master
go
grant VIEW SERVER STATE to [user_immortan_joe];
use MyDataBase
go
create PROCEDURE get_ip
@spid int, @ip varchar(50) output
with execute as 'user_immortan_joe'
as
begin
select @ip = client_net_address
from sys.dm_exec_connections
where session_id = @spid
end;
go
create procedure MyStoredProcedure
as
begin
declare @spid int = @@spid, @ip varchar(50);
exec dbo.get_ip @spid,@ip output;
select @ip as ipAddress ,SUSER_SNAME() as userName
end
go
GRANT EXECUTE ON MyStoredProcedure TO [user_mortal_jack];
go
EXECUTE AS USER = 'user_mortal_jack'
exec MyStoredProcedure
REVERT