SQL Server - Difference between errors 18456, 4064 and 4060 - c#

I have a windows application written in vb.net. It interacts with SQL Server and we can create users from it on the server. From the application I disabled some users (it runs DROP USER (loginName) command behind the scenes). There was some strange behavior observed while handling SqlException in this case. While trying to login into SQL server (both through code and SQL server management studio) with disabled users, for some users it was giving a 4064 error code whereas for others it was giving 18456.
Here are some more details:
SQL Server version - 2016 SP1. Mixed mode authentication.
There are a couple of DBs other than master.
On SQL Server in sys.syslogins table - For users for whom I got a 4064 error, the default DB was
master. For those who's default DB was not master, I got 18456 error.
In code - For some reason, while catching SqlException in code, for
users getting 4064 error while logging on SQL, I get 4060 error. For
users with 18456 code, it works fine and I get the same error code in
Exception.
Entries are in sys.syslogins, sys.sysusers table (as far as sys
tables go).
As per the official description given:
MSSQLSERVER_4064:
The SQL Server login was unable to connect because of a problem with its
default database. Either the database itself is invalid or the login lacks
CONNECT permission on the database.
and
MSSQLSERVER_18456:
When a connection attempt is rejected because of an authentication failure that involves a bad password or user name, a message similar to the following is returned to the client: "Login failed for user ''. (Microsoft SQL Server, Error: 18456)".
Could not find an official detailed description for 4060 except this:
Cannot open database "%.*ls" requested by the login. The login failed.
Several forums say its related to login failure. I tried looking for some data on difference between nature of the failures for these 3 codes, but couldn't find one.
What are the scenarios in which we can get 4064 or 4060 codes? Are there any overlapping fail cases where we can get either of these (like for 18456 and 4060)?
EDIT: Here is the code for creating the connection:
connection = new SqlConnection()
Dim builder As New SqlConnectionStringBuilder
builder.DataSource = "localhost"
builder.InitialCatalog = "DatabaseA"
builder.ConnectTimeout = 120
builder.UserID = username
builder.Password = Encrypt(password)
connection.ConnectionString = builder.ConnectionString

Related

Can't initialize local SQL Server database with EFCore commandline tools

I've been trying to follow several different tutorials with EFCore and .net core and I've been totally blocked at the point where I try and create a local database.
I've used both the powershell tools and the commandline tools to try and create an initial migration (or do anything, really).
I consistently get the error:
System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - No process is on the other end of the pipe.)
The database does not currently exist on the system, though local SQL Server appears to be up and running.
Here is the c# code for adding the context:
services.AddDbContextPool<TestDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("TestDb")
)
);
This is the connection string code:
"TestDb": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=TestDb"
I get similar errors whether I run add-migration, dotnet ef migration add, or dotnet ef dbcontext info. (note: with the dotnet calls I am using the -s ..\{webproject}\{webproject}.csproj property
I've also messed with the connection string by adding various combinations of Trusted_Connection=True; MultipleActiveResultSets=True;, and Integrated Security=true.
I've gone into SSMS and ensured the Server authentication is SQL Server and Windows Authentication Mode and that Maximum Connections is set to 0 (unlimited). I've also gone to logins and tried adding the user to pretty much all the server roles.
So, yeah, I'm pretty confused. I've worked with EF for years, though this is my first experience with EFCore and I'm definitely more of a developer than a SQL Admin. This is also my first time trying to use the local db on this particular computer.
Edit: Looking at error.log in AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\mssqllocaldb I see this error:
2020-01-28 10:15:03.50 Logon Error: 18456, Severity: 14, State: 38.
2020-01-28 10:15:03.50 Logon Login failed for user 'LAPTOP-NC6HQ4TB\ripli'. Reason: Failed to open the explicitly specified database 'TestDb'. [CLIENT: <named pipe>]
Which is confusing. Of course I can't open the specified database. The entire point is I want to create a DB that doesn't yet exist.
Found the answer. Sorry to everyone who tried to help, as you wouldn't have had enough information to solve it.
In the DbContext I had tried to add some code to the constructor to try and populate some data to the database as part of a test. This caused several problems. If the Database hadn't yet been created it tried to connect to the DB before it had been created, which caused the problems I described.
Furthermore, if I had created the db manually it would try to access the DbSets (which had not yet been created), and then complain that the set name was invalid (which, at this point it was.
This all might have been fine if the DB had been created in advance, but since I was using the DbContext to construct the database, it understandably caused problems.
And all of this headache would have been avoided had I not violated SRP and not tried to (even temporarily) hijack a context constructor to hack in some test data.
The takeaway here? Don't pollute your constructors with unrelated hacks. Bleh.

Unable to connect to SQL Server Express 2014 when signed in with local account

Installed SQL Server Express 2014 & can connect/query with SSMS. I'm using Visual Studio 2015 (C#) and EF 6 to programatically connect to the server. In all the following scenarios I'm using the same connection string + am using the "sa" account with the correct password in the connection string.
When I sign in to the computer with a Windows domain account (ex: domain\username) then run the code it works fine.
When I sign in to the computer using a local account (ex: computername\username) account then run the code it fails with the following error: The underlying provider failed on Open. Note that I can launch and use SSMS w/out problems.
Here's my connection string.
metadata=res://*/[efName].csdl|res://*/[efName].ssdl|res://*/[efName].msl;provider=System.Data.SqlClient;provider connection string=\'Data Source=.\SQLExpress;Initial Catalog=db-name;Integrated Security=True;User ID=sa;Password=[psw];MultipleActiveResultSets=True;Application Name=EntityFramework;User Instance=False\'
I've tried with Integrated Security on or off (same result). Tried Data Source as ".\SQLExpress" or "[machineName]\SQLExpress" (same result).
After digging a bit I found the following entry in the Windows Event Viewer.
Level: Information
Source: MSQL$SQLEXPRESS
Task Category: Logon
Message: Login failed for user 'computername\username'. Reason: Failed to open the explicitly specified database 'db-name'. [CLIENT: ]
Looks to me like SQL Server windows service is using some kind of network auth prior to allowing a connection to SQL Server.
It's probably no surprise that the error message returned by EF/SQL didn't help at all. It has nothing to do with the underlying provider...
After some trial/error I've whittled it down to this. It's required that you set IntegratedSecurity=false when providing specific userName/Password credentials in the connection string. That's it.

Cannot generate a consistant token ASP.NET C# server-side Oauth2.0

I am having troubles trying to autogenerate a token that all client-side users can use. Am using Oauth 2.0.
I can perfectly generate a token localhost, using Account controller /api/Account/Register, but when I publish the web api I cannot access with that token, and I also can't generate the token like I did localhost.
Is there any way to generate a token server-side like I do localhost?, it should be consistent in the way that when I republish the app that token should still be the same.
I am using Postman to test it. When I call /api/Account/Register with this json:
{
"Email": "da#a.com",
"Password": "sample striAng 21|",
"ConfirmPassword": "sample striAng 21|"
}
it returns me an error in like this:
{
"Message": "An error has occurred."
}
I am copying exactly what I did localhost, but on server doesn't work.
The problem is that you're connecting to a SQL Express Database on your local machine, but in most of the cases Servers don't use SQL Express (Nor have the same credentials when login to it) you MUST set up your web.config and sql connection.
A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or
was not accessible. Verify that the instance name is correct and that
SQL Server is configured to allow remote connections. (provider: SQL
Network Interfaces, error: 52 - Unable to locate a Local Database
Runtime installation. Verify that SQL Server Express is properly
installed and that the Local Database Runtime feature is enabled.)"
On your Web.config change/comment out your current connectionStrings and replace it with the one of your server
<connectionStrings>
<add name="YourDataBaseContextName" connectionString="Data Source=TheConnection;Initial Catalog=YourDataBaseName;User Id=TheUserOfDatabase;Password=YourHopeNotSoEasyPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
What i don't understand here is why I have a sql problem, being that Account controller never uses any database?
They do use it, after all you must save the register data on somewhere, right?
More specifically this lines register and save to database the model that you send:
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
it looks like 500 internal server error.
Any other endpoint is working all everything dosn't work?
You shold check connection string on server, and check if db exist and have proper tables.
Make sure that any envirement specyfic setting has valid value.

Can't connect to local SQL Server 2014 from C# using OleDbConnection

I see several answers to problems similar to mine, but I don't know enough to adapt those answers to my problem. So, with apologies for what is probably a duplicate question, here goes:
I'm trying to connect to a Microsoft SQL 2014 database on my local machine from a ASP.NET application. The code is:
oCN = new OleDbConnection(connectionString);
With a connectionString of:
Provider=SQLNCLI11; Server=FLIPPY\SQLEXPRESS; Trusted_Connection=yes;
Database=FingerTipDisplay; User Id=<my user id>; Password=<my password>
oCN is as follows after the call to new OleDbConnection():
- oCN {System.Data.OleDb.OleDbConnection} System.Data.OleDb.OleDbConnection
CanRaiseEvents true bool
ConnectionString "Provider=SQLNCLI11; Server=FLIPPY\\SQLEXPRESS; Trusted_Connection=yes; Database=FingerTipDisplay; User Id=<my user id>; Password=<my password>" string
ConnectionTimeout 15 int
Container null System.ComponentModel.IContainer
DataSource "" string
Database "" string
DbProviderFactory null System.Data.Common.DbProviderFactory
DesignMode false bool
+ Events {System.ComponentModel.EventHandlerList} System.ComponentModel.EventHandlerList
Provider "SQLNCLI11" string
+ ServerVersion 'oCN.ServerVersion' threw an exception of type 'System.InvalidOperationException' string {System.InvalidOperationException}
Site null System.ComponentModel.ISite
State Closed System.Data.ConnectionState
+ Static members
+ Non-Public members
I believe my SQL server is running correctly:
I can't get SQL Server Agent to start, and am not sure if that's causing my problem or not. From other replies I've ensured TCP/IP is enabled:
This is my database structure:
and I think that the user name and password I'm connecting has the right permissions from the dbo schema:
I've checked the SQL Server logs and don't see anything that looks like a failed login attempt, and I don't know where to look in the OleDbConnection object for feedback on why the connection failed. I'm working on someone else's code, so I'm reluctant to use SqlConnection() since I don't know the implications for the rest of the app.
I'm guessing that the problem is in the connection string, but I don't know what to use for that. I've tried SQLOLEDB as the provider, and I've tried using Initial Catalog instead of Database.
Thanks in advance for your help.
Update:
Thanks for all the help so far. oCN.Open() was throwing an OleDbException immediately, and it was:
"Login failed for user 'riehlj2002#gmail.com'."
I made some changes to the connection string based on the advice below...this is what it looks like right now:
Provider=SQLNCLI11; server=localhost; DataSource=localhost\SQLEXPRESS; Database=FingerTipDisplay; user id=<my user id>; password=<my password>
Now it doesn't throw the exception right away, but it still throws it. This is the exception I get:
{"Login timeout expired\r\nA network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.\r\nNamed Pipes Provider: Could not open a connection to SQL Server [2]. \r\nInvalid connection string attribute"}
A few things I notice.
First, if I change server to localhost\SQLEXPRESS I get an immediate exception telling me that I have an invalid connection string attribute, so the advice in this link doesn't work for me.
Second, it doesn't seem to matter whether I use localhost or my machine name...it does the same thing.
Third, I was surprised to see something in there about the named pipes protocol. I went into the SQL Server Configuration Manager and enabled that protocol...it didn't make a difference.
Fourth, it doesn't make a difference whether I specify DataSource or not in terms of the exception, but intuitively it seems like I have to specify the server instance somewhere so I've left it in.
Fifth, if I change the provider to SQLOLEDB I get a different exception: {"[DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied.\r\nInvalid connection string attribute"}, so I think I'm on the right track with SQLNCLI11.
Sixth, in the OleDbConnection object the DataSource and Database properties are both empty strings despite their being specified in the connection string.
Finally, the very last part of the exception I'm getting now talks about an invalid connection string attribute, but I removed each one in turn and either got the same exception or got another one that I've already described.
Again, thanks for the help.
You are using Trusted_Connection=yes but specifying a username and password. It's either one or the other, I don't think you can do both in the same connection string (not sure if that'd raise any errors, but the supplied user and password would be at least ignored, for sure).
In your case, since you are using a user and a password, you'd need to set Trusted_Connection to no (or false), or just not set it (it should be false by default)
OK, I found the problem. My original connection string wasn't finding the database, so I got no additional information in the server logs. I changed the connection string to:
Provider=SQLNCLI11; server=localhost\SQLEXPRESS; Database=FingerTipDisplay; user id=<my user id>; password=<my user id>
And then I found in the server log that it was configured to use Windows authentication only. I used this link to allow SQL server authentication, and all is now well. Your answers got me going in the right direction...thanks.

Sys.WebForms.PageRequestManagerServerErrorException: Login failed for user

I get the above error when trying to run my .net app as it attempts to connect to a SQL database on another server.
The SQL connection string is using a trusted connection.
IIS has anonymous access switched off, and integrated windows authentication switched on.
The user the error relates to is "DOMAINNAME\IISSERVERNAME$"
Do I need to add user "DOMAINNAME\IISSERVERNAME$" as a login on the SQL server machine?
I expected my username to be passed around - i.e. if I have access to the SQL server then the application would run fine?
Thanks in advance.
EDIT: Should point out that I know it's authenticating OK from an IIS point of view... if I switch to anonymous access it fails my own security as an "Unknown User"... which is what I'm after
Try this as connection string
Data Source=localhost;Initial Catalog=dbname;Integrated Security=True;
Sorted it.
Had to add the user DOMAINNAME\IISSERVERNAME$ as a SQL login on that server.
As a side issue, then had to add execute permissions for that login to the schema.
Thanks for your help.

Categories

Resources