it-swarm.com.de

Abrufen der IP-Adresse eines Benutzers beim Aufrufen einer gespeicherten Prozedur (SQL)

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.

17

Allgemeine Information

Es gibt zwei Möglichkeiten, die aktuellen Verbindungsinformationen abzurufen

  1. 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
    
  2. 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
    

Lösungsvorschläge

  1. 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
    
  2. 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

  3. 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.

  4. 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

14
Hadi

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

4
Steve Ford

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.

4
TheGameiswar

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:

  1. ALTER DATABASE MyDataBase SET TRUSTWORTHY ON
  2. Erstellen Sie in meinem Beispiel ein Login (nicht [user_mortal_jack]) [user_immortan_joe]
  3. Erstellen Sie einen Benutzer für [user_immortan_joe] In MyDataBase
  4. Im Kontext von mastergrant VIEW SERVER STATE to [user_immortan_joe];
  5. Erstellen Sie in 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'.
  6. Erstellen Sie MyStoredProcedure so, dass mit der Hilfe von 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