sql server remote access machine ip - sql

I wanna learn remote machine's ip adressess which accessed my sql server. someone at my job(in local network) find my database password and making row updates. how could I find the access person's ip?

In SQL Server you can try this:
CREATE FUNCTION [dbo].[GetCurrentIP] ()
RETURNS varchar(280)
AS
BEGIN
DECLARE #IP_Address varchar(280);
SELECT #IP_Address = client_net_address
FROM sys.dm_exec_connections
WHERE Session_id = ##SPID;
Return #IP_Address;
END

Add a trigger to the table that adds the server variables like host name to a separate table. See trigger on update. Also select host_name.

Related

Get the IP address of the server from SQL in Teradata

I want to check the current connection to validate if the configuration is correct according to the environment. I mean, I have a ETL and I want to be sure the database configuration points to the right server (dev, QA or prod)
How can I get the IP address of the server or hostname from SQL in Teradata?
As a Teradata system might have multiple nodes there's a range of IP addresses assigned to a system. And the hostname is used in your connection string, thus it should be known in advance.
There's no builtin way to get that info from a system table, but it's easy to create a SQL-UDF:
FUNCTION syslib.#servername ()
RETURNS VARCHAR(30)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
RETURNS NULL ON NULL INPUT
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN 'dev';
GRANT EXECUTE FUNCTION ON syslib.#servername TO PUBLIC;
As it's stored in syslib it can be used without qualified name: select servername()

Get the IP address of a user in calling a stored procedure (SQL)

Is it possible, and if so how, to get a user's remote IP address executing the query, analogously as we can get user's name with: SUSER_SNAME()?
Update before bounty
I am looking for a solution which allows to grab the IP address of an ordinary mortal user, not a database owner. The ideas proposed by TheGameiswar or njc do not allow to capture a user's IP address who has been granted just a execute permission. However, they are excellent ideas to start with the problem. Here I list the essence of the ideas:
Please see the sequence I follow:
create procedure MyStoredProcedure as
select client_net_address
from sys.dm_exec_connections
where session_id = ##SPID
Now add a user and grant permission:
CREATE LOGIN [user_mortal_jack] WITH PASSWORD=N'LongYouLive!!!';
GRANT EXECUTE ON MyStoredProcedure TO [user_mortal_jack];
When I run the procedure with a query:
EXECUTE AS USER = 'user_mortal_jack'
exec MyStoredProcedure
REVERT
I get error message:
The module being executed is not trusted. Either the owner of the database of the module needs to be granted authenticate permission, or the module needs to be digitally signed.
I will get this message even if I grant an additional permission:
grant VIEW SERVER STATE to [user_mortal_jack];
If I change the beginning of the stored procedure to:
create procedure MyStoredProcedure
with execute as OWNER as
I end up with different sort of error:
Could not obtain information about Windows NT group/user 'blahblah\admin_user', error code 0x534.
Update after bounty
Bounty is granted to Hadi for this single line of code hidden in their answer:
CONNECTIONPROPERTY('client_net_address')
which let's capture the IP address of any mortal user without neither granting any additional rights to the user nor setting the database TRUSTWORTHY ON option nor even creating a procedure WITH EXECUTE AS OWNER clause.
General Info
There are two ways to get the current connection information
Getting information from Dynamic Management Views
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
Using CONNECTIONPROPERTY function (SQL Server 2008 and newer 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
Suggested Solutions
If you are looking to grant user for a specific IP address
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
Assuming that you have a table that contains the granted IP address (i.e. 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
END
If you are looking to grant a user (database user) to execute a stored procedure, you should use this command
GRANT EXECUTE ON MyStoredProcedure TO User;
There are many detailed article and answers talking about the issue you are facing, and many suggested solutions, such as Setting the Database in TRUSTWORTHY mode (before using it read the first Link below) and Trusting the Authenticator, and other methods. You can find them in the links below
SQL Server EXECUTE AS trouble
SQL Server execute procedure as user
Extending Database Impersonation by Using EXECUTE AS (Extending the Scope of Impersonation section)
EXECUTE AS (Transact-SQL)
Execute a stored procedure as another user premission
Note: You can check #SteveFord answer for using TRUSTWORTHY property
If you are looking to block connections except specific IP addresses then you should follow this answer
Restrict SQL Server connection to specific IP address
Also there are many scripts that can be used to get client or server IP addresses that can be found in the question below:
How to get a client IP address from an SQL Server database
References
MS SQL 2008: Client IP address on shared hosting
Finding client IP-Address
How to get a client IP address from an SQL Server database
Get Client IP Address in SQL Server
You can use connections DMV to accomplish that..
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 for client_net_address
Host address of the client connecting to this server. Is nullable.
Using the EXECUTE AS OWNER statement in a CREATE PROCEDURE Statement:
From MSDN
When a user executes a module that has been specified to run in a
context other than CALLER, the user's permission to execute the module
is checked, but additional permissions checks on objects that are
accessed by the module are performed against the user account
specified in the EXECUTE AS clause. The user executing the module is,
in effect, impersonating the specified user.
The context specified in the EXECUTE AS clause of the module is valid
only for the duration of the module execution. Context reverts to the
caller when the module execution is completed.
The following must be created by a user who has permissions to query the DMVs
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
Then you will need to give the users permissions to execute the stored procedure:
Update to create the right permissions
You will need to set your database to Trustworthy (see Set Database to Trustworthy:
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];
I have tested this and this now works as expected
In order to get any caller's IP address and user name without granting all of them special permissions, you could cheat the server and database a little bit. A couple of things are needed to achieve this:
ALTER DATABASE MyDataBase SET TRUSTWORTHY ON
Create a login (not [user_mortal_jack]) in my example [user_immortan_joe]
Create a user for [user_immortan_joe] in MyDataBase
In the context of master grant VIEW SERVER STATE to [user_immortan_joe];
In MyDataBase create a stored procedure (not MyStoredProcedure, in my example get_ip) that is receiving an int representing a specific session_id parameter will output (output, not return) the IP address or that session_id. Create it with execute as 'user_immortan_joe'.
Create MyStoredProcedure in a manner that with the help the get_ip and of SUSER_SNAME() returns the IP address and user name of its caller.
This way you get the IP address and user name of any caller of MyStoredProcedure respecting the principle of least privilege and avoiding the problems you've encountered while pursuing a solution.
Sample script:
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

SQL Server Query : Host name

I have the exact Query Text and the exact time & date the Query was executed,
how can I find the Host Name that executed this query?
I'm using SQL Server 2008.
Do you need ##SERVERNAME
SELECT ##SERVERNAME
will return the server name where the query was executed.
HOST_NAME will return the workstation name
SELECT HOST_NAME()
There is not any table with historical information about the host that executed a query - http://www.sqlservercentral.com/Forums/Topic1334479-146-1.aspx
You can check with HostName() as
SELECT HOST_NAME() AS HostName, SUSER_NAME() LoggedInUser
http://blog.sqlauthority.com/2009/05/26/sql-server-find-hostname-and-current-logged-in-user-name/
or
SELECT #IP_Address = client_net_address
FROM sys.dm_exec_connections
WHERE Session_id = ##SPID;
How to get the client IP address from SQL Server 2008 itself?
How to identify the caller of a Stored Procedure from within the Sproc
This is as close as you'll get, I believe:
select host_name()
As is mentioned in the docs: "The client application provides the workstation name and can provide inaccurate data. Do not rely upon HOST_NAME as a security feature."

Getting the logged in user name inside a stored procedure on a linked server

The standard in our company is to log the user name that inserts or updates a record at the time the record is inserted or updated. We inset and update the tables calling stored procedures from applications. We use SUSER_SNAME() in the stored procedures to get the name. Now we've added inserting records in a table on a linked server. The SUSER_SNAME function not is returning the same login name as it does on the native database. Instead it is returning the name of the account created to link with. I know I can pass the user name as another parameter to the query, but it would be easier if there is a built-in function that works both when connected to the server directly, and when connecting to a linked server. Is there a built-in function that does this?
Stored procedure
INSERT INTO Account (ForeignKey, AccountNumber, IsProcessed,
Origin, Updated, LoginName, Total)
VALUES (#ForeignKey, #AccountNumber, #IsProcessed,
GETDATE(), NULL, SUSER_SNAME(), #Total)
RETURN SCOPE_IDENTITY()
No, there's no function to do this. When you create a linked server, the linked server "opens a connection" to the 2nd server. You, the user, have a connection to the 1st server. So when you run suser_sname() on the 1st server, you get your username that you are connected with. When you run it on the 2nd server, you STILL get the user name that you are using to connect to the second server. The difference is that the connection to the 2nd server is controlled by the administrator that configured the Linked Server. In your case, it sounds like he created a special account that is used for a linked server connection. Another option is to map accounts from the current server to accounts on the 2nd server. (If your DBA had done that, you might be getting the results that you want right now and not had any issues.) There are different ways to configure a linked server, and security should generally be a priority when doing so.
So, if you want to execute a query on the 2nd server and use your user name from the 1st server, then you need to pass it to the 2nd server, because it has no way of knowing who you are on a different machine.

Is there a SQL query that returns client IP?

I'm wondering if there is a SQL query that would show the IP of the client that wrote the query. Like if I have people making changes to my database I already have a log table but I want to add IP address to it. So I am wondering if this this possible.
If the connection was made with TCP, the query below will return the client IP address. Note that VIEW SERVER STATE permissions are required with this method.
SELECT client_net_address
FROM sys.dm_exec_connections
WHERE
session_id = ##SPID
AND net_transport = 'TCP';