I've got a little C# app that drops and re-created a database for my tests to run. This app is executed in TeamCity that runs under NT AUTHORITY\SYSTEM user.
Here is my application:
public void SetupDatabase()
{
var childConnectionString = "Server=.\sqlexpress;Database=MyDatabase;Uid=Tester;Pwd=Tester;Trusted_Connection=True;MultipleActiveResultSets=True;";
var masterConnectionString = "Server=.\sqlexpress;Database=master;Uid=Tester;Pwd=Tester;Trusted_Connection=True;MultipleActiveResultSets=True;";
Console.WriteLine("Using child connectionString: {0}", childConnectionString);
Console.WriteLine("Using Master connectionString: {0}", masterConnectionString);
Console.WriteLine("Connection for master using this user: {0}", GetUser(masterConnectionString)); // <- this one shows NT AUTHORITY\SYSTEM
Console.WriteLine("Connection for child using this user: {0}", GetUser(childConnectionString)); // <- this one fails saying
// Cannot open database "MyDatabase" requested by the login. The login failed.
// Login failed for user 'NT AUTHORITY\SYSTEM'.
}
private string GetUser(string connectionString)
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = new SqlCommand("select SYSTEM_USER", connection);
var reader = command.ExecuteReader();
while (reader.Read())
{
var user = reader.GetString(0);
return user;
}
}
return "";
}
I'm specifying SQL Server username/password in the connection string, why is Login failed for user 'NT AUTHORITY\SYSTEM'?? I'm not using Windows Authentication.
Fair enough, System account will fail to login to MyDatabase because it is not set up on that database.
Funny thing - when I execute the same application myself I get no exceptions and my username is printed
Connection for master using this user: MACHINENAME\trailmax
Connection for child using this user: MACHINENAME\trailmax
Why-oh-why is username/password from the connection string are ignored and trying to login as Windows-Auth.
p.s. the user Tester is set up on MyDatabase and when I go to SSMS and use credentials from the connection string, I can login and can execute all the commands I need. The problem appears when I run the same executable from TeamCity.
You set Trusted_Connection=True, which means use windows authentication. If you want SQL authentication, then set Trusted_Connection=False.
Get rid of trusted_connection=true from the connection string
Take Trusted_Connection=True; out of your connection string. This overrides any user name or password.
Then have a think about your security architecture - do you really want to be hard coding and compiling logins and passwords into your windows servce?
Remove trusted_connection=true from your connection string as that is gonna override the user name you have configured. In the case of Windows Services, it's gonna use NT AUTHORITY\SYSTEM.
Related
I have MySql Server with authentication_windows.dll plugin.
There I have windows account "test_win" and sql user "test_sql" with password "test".
Even if Integrated Security is set to false, as long as user id matches existing windows account, the connection is opened without any error.
I am trying on MySQL80 Enterprise with authentication_windows.dll plugin.
Example of my connection string:
server=localhost;user id=test_win;database=mydb;Integrated Security=False;password=incorrect
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
}
Actual result: connection is opened and validated
I would expect "Access denied for #test_win (using password: YES)"
How can I force account validation except for Integrated security = false ?
Additional information:
Tested same scenario on MsSql with expected result
Data Source=localhost;Initial Catalog=mydb;User ID=test_win;Password=incorrect
Exception: Login failed for user 'test_win'
using (var connection = new SqlConnection(connectionString)
{
connection.Open();
}
To begin with: It is not a particular statement that does not work. SELECT * FROM [TABLE]; does not work either. When I run it in SSMS as user A it works perfectly fine. When I use it in C# like this:
string sqlCommand = "SELECT * FROM [TABLE];"
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Name"].ToString()))
using (var command = new SqlCommand(sqlCommand, conn))
{
conn.Open();
using (var dataReader = command.ExecuteReader())
{
while (dataReader.Read())
{
// work with results
}
}
}
I log this code block with a try-catch and I get this error message: System.Data.SqlClient.SqlException (0x80131904): The SELECT permission was denied on the object 'TABLE', database 'MyDb', schema 'dbo'.
Even if I run the program on the server where the db is, I get the same error.
My connection string looks loke this:
Data Source=Server\Something;Initial Catalog=MyDb;User ID=DOMAIN\username;Password=verySecurePassword;Trusted_Connection=True;
User A has the datareader role on the entire db.
Do you have any idea why this might be? My db admins cannot help me either and it does not appear to be a network issue, as the connection seems to work.
When you have this in your connection string:
Trusted_Connection=True;
This part of the connection string is ignored:
User ID=DOMAIN\username;Password=verySecurePassword;
Trusted connections and integrated security mean you always connect to the server as the account running your program's process. You don't get to specify the password; instead, the program will pass the authentication token issued for the user running the process, and the database will validate against that token.
If you need to use a domain login, you must run your program as that user. If you need to use a username/password, you must use Sql authentication with a non-domain account defined in Sql Server.
I am making a simple c#.net winform application which will connect to sql server.
I wnat it to have 2 ways to connect- Windows Authentication and SQL server Authentication.
From what I found online I came up so far with:
public static void SetConnectionStringParams(string dbAddress, bool isWinAuth, string user, string password)
{
if (isWinAuth)
{
_connectionString =
string.Format(
"Data Source={0};Database = {1};Integrated Security=True;Max Pool Size=1000;MultipleActiveResultSets=True;Connection Timeout=60",
dbAddress, DefaultDBname);
}
else
{
_connectionString =
string.Format(
"Data Source={0};Database = {1};User ID={2};Password={3};Max Pool Size=1000;MultipleActiveResultSets=True;Connection Timeout=60",
dbAddress, DefaultDBname, user, password);
}
}
which works great, but I couldn't found how in case of Windows Auth I force require user and password instead of using the Integrated Security=True...
Is there an API that do that? if not, would appreciate guidance how to do it.
Thank you,
Give this a shot
Ask user to enter windows username and password
Impersonate this user manually as by Microsoft and fetch users Principal & Identity
Now fork new thread with this Principal/Identity to talk with database with integrated security
Flush user, identity and principal on job completion or on exception
I'm writing a Windows Forms application in C# in which users have to connect
to a SQL Server database. The potential users receive randomly built
passwords from the customer and the customers policy enforces that users are required to change the password (SQL Server - option MUST_CHANGE).
I'm having difficulties in providing a function which allows the users
to change the given password on their first attempt to login: every attempt
to connect to SQL Server with the provided credentials leads to
a SqlException with error number 18488 stating that the user has to change
the password - which is exactly what I'm trying to do.
I've tried to use:
an ALTER LOGIN statement as a SqlCommand
ALTER LOGIN 'someLogin' WITH PASSWORD = 'newPassword', OLD_PASSWORD = 'oldPassword'
a ServerConnection with a Server and Login object issuing a
ChangePassword(oldPassword, newPassword) request
var serverConnection = new ServerConnection(someSQlConnection);
serverConnection.Connect();
var server = new Server(serverConnection);
var login = new Login(server, 'someLogin') { LoginType =
LoginType.SqlLogin };
login.ChangePassword(oldPassword, newPassword);
The Problem is that already the attempt to connect to the SQL Server
fails, the password changing query doesn't even get executed.Anybody can provide a hint how to solve this issue ?
Use the static ChangePassword method to set the new password:
System.Data.SqlClient.SqlConnection.ChangePassword(someSQlConnection,
"new_password");
As per documentation:
This method opens its own connection to the server, requests the
password change, and closes the connection as soon as it has
completed.
protected DataTable GetData(string Query)
{
DataTable data = new DataTable();
try
{
strConnectionString = "data source=(local);Integrated Security=True;initial catalog=ps_erdb;";
string Query = "Select ErdbBuildNumbereMinor from DBVersion";
using (sqlConnection = new SqlConnection(strConnectionString))
{
sqlConnection.Open();
SqlCommand cmd = sqlConnection.CreateCommand();
cmd.CommandTimeout = intConnectionTimeout;
cmd.CommandText = Query;
data.Load(cmd.ExecuteReader());
sqlConnection.Close();
}
return data;
}
catch (Exception ex)
{
}
return data;
}
the above code returns a error
Cannot open database "ps_erdb" requested by the login. The login
failed. Login failed for user 'MIG3-ESVTB\HPSInstall'.
But when i manually open SQL Server Management Studio with above login ,i was able to connect to database and execute the query.
A few possibilities to look into:
What user were you logged in with on your local client? Your connection
string indicates you're using integrated security so the application will
present your current logged in credentials to SQL Server. To help diagnose,
make sure you enable login auditing for both failed & successful
logins. When you connect from SSMS and run SELECT suser_name(), what does it return?
Is the database set for multi_user mode (default) or single_user
mode? Someone may have changed it to single_user. This allows the
first and only one connection. All subsequent attempts will fail. If it's in single user mode, just run ALTER DATABASE ps_erdb SET MULTI_USER from SSMS
When you login via SSMS, were you able to query data from the
ps_erdb database? If not, make sure you have a database user mapped
to the 'MIG3-ESVTB\HPSInstall' login and the appropriate permissions granted to the user (not the login).