Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled) - odbc

I have a problem when trying to connect to MySQL database using Windows OBDC driver. There are plenty of search hits regarding the obvious... people are using old versions, however, I'm not.
mysqld is on CentOS 6.4 32bit
./usr/libexec/mysqld Ver 5.1.69 for redhat-linux-gnu on i386 (Source distribution)
So I'm at a loss to understand where any pre 4.1.1 protocol is coming from. Any ideas?

I guess that if you ask the right question its easier to find the answer.
In this case "my" problem relates to how the passwords are hashed and stored in the database. Legacy passwords were stored with a shorter hash that's now deprecated.
A few important points:
mysql_upgrade cannot and does not upgrade passwords, nor does it warn about it in some versions, see: http://bugs.mysql.com/bug.php?id=65461.
Even it you have mostly the latest server and clients, all it takes is one legacy client somewhere to create a legacy password and then you'll have trouble with that account no matter what client tries to use it.
Different versions have treated the situation differently so you can be sitting on some legacy passwords in your database and then suddenly, for no apparent reason, some accounts stop working... this is because of how different versions chose to handle the situation.
You cannot upgrade passwords. You must know what they are and you must change them.
EDIT: To be more clear, you must change the password that is stored with the shorter hash using a new client that uses longer hashes. By doing so you will be writing that accounts password with the longer hash, at which point nothing should be flagging attempts to access the account any more. If the problem is recurrent you should be looking for the older clients at your site which are still writing passwords with the deprecated hash length.

MySQL Workbench 6.08 in the Manage Server Connections, Connection tab, Advanced sub-tab you must check the box 'Use the old authentication protocol.'

Try installing old version driver 3.51.30: http://dev.mysql.com/downloads/connector/odbc/5.1.html#downloads
It works on my Mysql Ver 5.0.24a-community

I ran into this while using the ODBC Connector for Windows to connect to a Percona 5.5 server. which has secure_auth disabled.
From what I found the ODBC connector, unlike MySql Workbench, does not support an option to authenticate logins which use the old 16-byte hashed passwords. There is a bug report regarding this, but it appears the assignee is/was confused about the feature request (See bug #71234).
I was able to update the mysql login to use the new 41-byte hash using these commands:
set old_passwords=0;
set password=password('yourpasswordhere');
As I mentioned our server has secure_auth disabled, which appears to cause password() to return old_password() results. Running set old_passwords=0; will enable the password() method to generate the new 41-byte hashes (for the duration of your session).

I had a similar error message when remotely trying to access my MySQL database. Using Directadmin I easily changed the MySql database password as suggested above. This automatically generated the password using the newer hash method. This solved the remote connection problem instantly.

I found another solution in case anyone hits this - very weird -
Install the 5.1 64 bit ODBC driver - verify an ODBC connection by itself works, if you can connect then you should be able to after doing #2
Click on Linked Servers - Providers - right click on MSDASQL, click on Properties
uncheck "Allow inprocess" - which is a good thing to do unless you need to insert TEXT and NTEXT fields.
Create your linked server connection or test the one you have been fighting with - lol
When I had "Allow inprocess" checked I still got the error even though the ODBC system DSN worked fine. I'm assuming because I had a mixture of 5.2 (with servers that worked fine) and 5.1 for the servers that didn't, SQL was sharing the processes because the 5.1 driver does not give that error.

If you can't change your server, perhaps you can change your client: http://bugs.mysql.com/bug.php?id=75425

Related

ODBC 18 vs ODBC 17 in Windows Data Source Manager

I have a microsoft access front end connecting to a SQL database for the backend. I have been using this setup for the last 4 years and I have recently run into issues with new associates not being able to use the tool due to our company retiring ODBC driver 17 from our internal systems. I don't understand what is the difference between ODBC Driver 17 and 18 that would cause version 18 to fail.
How the driver is used:
in ODBC Data source manager a manual link to our database is created. The associate enters a specific name for the link "Our_link" and in the Driver name it states "ODBC Driver 17 for SQL Server"
Then inside of our access front end we link to that driver like so:
Const ConStrSQL As String = "DRIVER={ODBC Driver 17 for SQLServer};Server=OurServer;Database=Our_DB;UID=User();Trusted_Connection=Yes;"
The issue I am having is when I try to create the ODBC connection in the data source administrator using ODBC driver 18 I get an error that states:
[![`"Connection Failed: The certificate chain was issued by an authority that is not trusted"`]
Not sure if this extra information would help but I also see the following:
SQLState: 08001
SQL Server Error -2146893019
Client unable to establish connection
Is this something I need to reach out to our database admin group and ask if they installed driver 18 on the server side?
I'm guessing it has to do with the changes to the encryption behavior with version 18, specifically that encryption is required by default. The recommended fix is to install a trusted certificate on your server[1], but if you don't want to deal with the DB Admins you might be able to still connect by specifying No (or optional) to Encrypt in your connection string.[2]
There is a chance that won't work the server is set to Force Encryption, but it sounds like the change is all on the client end. Ideally you would want the encryption working all the time, so if you are using a self-signed certificate add the public key from the SQL server to trusted certificates on the client machines.
[1]: https://techcommunity.microsoft.com/t5/sql-server-blog/odbc-driver-18-0-for-sql-server-released/ba-p/3169228)
[2]: https://learn.microsoft.com/en-us/sql/connect/odbc/dsn-connection-string-attribute?view=sql-server-ver16#encrypt
The 'fix' that was found with the help of one of my database admins is as follows:
In the data source manager there is an option to select that states "Trust Server Certificate"
Once that option is selected I was able to complete the rest of my DSM connection. One thing to note is I was receiving the previous error when trying to change the DEFAULT DATABASE option. The checkbox to "trust server certificate" is on the screen after that.. so I had to skip choosing my default database, check the box, then go back and select my default database for everything to work.
I haven't completed all my testing in Access to make sure everything works 100%, but my quick testing is very promising.

How to avoid storing userid/password in the .odbc.ini file on Linux?

I am connecting to a Teradata database through ODBC with Stata on an Ubuntu server (12.04 LTS). Everything works fine, except that I have my TD userid and password stored in the .odbc.ini file, which seems like a terrible idea. The alternative is to enter them in Stata, which seems even worse and is awkward. Is there a way to do this more securely? The login info that I use to ssh into the server is synced with the TD database. It seems that it should be possible to pass that information along.
In ODBC terms you do not need to store usernames / passwords in any of your ODBC ini files. Both the ODBC SQLConnect and SQLDriverConnect support the passing in of username / password at the time they are called.
SQLDriverConnect would need something in your InConnectionString like "DSN=YourDataSourceName;UID=username;PWD=password".
You could go one step further and pass in the whole DSN as a command line argument thus meaning that you would not need an ODBC data source in an ini file. I'm sure one of the forum readers can post a sample for you from Teradata.
As for passing in the user name and password from your SSH loging. Your application would need to capture that and pass it to ODBC.
If you want to establish a finer grain of security around your odbc.ini file or other files on your Ubuntu server that may contain user credentials I would strongly suggest the use of Access Control Lists (ACLs). Beyond the typical Owner::Group::World permissions you can specify permissions down to the specific user on whether they are allowed or denied an explicit permission for a given file.
Other options regarding security on Teradata include the use of LDAP authentication if your environment supports it. Configuring LDAP on Teradata is beyond the scope of SO and in many cases a billable, professional services engagement with Teradata's Information Security CoE.

what's the issue with AttachDbFilename

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?
Thanks for your explanation.
Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.
This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):
Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.
Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).
Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."
Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.
Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.
EDIT: I've blogged about this here:
Bad Habits : Using AttachDBFileName
In case someone had the problem.
When attaching the database with a connection string containing AttachDBFile
with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.
In order to assure the connection to be shareable with other processes
instead use DataBase to specify the database name in your connection string
Example or connection string :
Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30
,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.
By connecting to the data base with AttachDBFile giving the path to the .mdf file
(namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

Database Connectivity ASP.NET - PostgreSQL

Am trying to run a C# application which fetches data from PostgreSQL database(8.4) and am using the PostgreSQL OLE DB Provider
This is my connection string
string connString =
#"Provider=PostgreSQL OLE DB
Provider;Data
Source=localhost;location=;User
ID=;password=;timeout=1000";
The error am getting is
The 'PostgreSQL OLE DB Provider'
provider is not registered on the
local machine
Can anyone point out me where should I correct so as to get the connect to the database. By the way am using PGOLEDBLib.
I have seen a few different "pgoledb" libraries. None appear to actually be named "pgoledblib", so this info may or may not apply to you.
The most recently active PGOLEDB has documented their connection string attributes here; it appears they use a different Provider value -- "PGNP.1".
Another provider, which seems to have been languishing since 2006, has connection strings here; these are in line with the earlier suggestions from OrbMan.
Of course, you may find that paying nothing for such a provider leads to paying much in installation, configuration, and utilization headaches. Towards easing such headaches, I offer a link to my employer's options supporting ODBC, JDBC, and ADO.NET clients on many platforms.
Any particular reason you're using the OLE DB provider? I believe the general idea is that you get better performance, and I think also functionality, if you use a native .net provider - e.g. http://npgsql.projects.postgresql.org/
Try using "PostgreSQL" or "PostgreSQL.1" for the Provider attribute.. If that does not work, you will probably need to re-install the driver.
I found the solution.
Step 1: Down load & install
https://www.pgoledb.com/index.php/component/filecabinet/?task=download&cid[0]=15
Step 2: Restart PC.
Step 3: Set the connection string as below
Provider=PGNP.1;Data Source=localhost;Persist Security Info=True;Initial Catalog=myDatabase;User ID=yyy;password=xxx
It should work as your expected

Pull Sybase data into SQL Server

I have an ASP.NET app that uses a SQL Server database. I now need to pull data from Sybase ASE into that SQL Server database for my app to consume, and I'm not having any success with my ideas.
Has anyone done this? Any ideas/suggestions/tips?
You can configure a linked server from SQL Server to Sybase. It should be fairly vanilla using the Sybase provider on the MS side.
Okay, I've finally (through lame trial and error) found out how to link my Sybase ASE (12.5) server to my SQL Server (2008) which will allow the integration I want. Here's roughly how I did it:
Logged in to Sybase ASE OLE DB Configuration Manager (this is like the Sybase version of Windows' ODBC Data Sources) and added an OLE DB data source. I believe you must be an admin on the PC to do this.
In SQL Server 2008 Management Studio, went to Server Objects > Linked Servers. Right click and select "New Linked Server".
In the Linked Server Properties, I set the following properties:
General:
--Linked server: the name of your linked server as you want it to appear in your linked server list
--Provider: Select Sybase ASE OLE DB Provider from the dropdown list.
--Product name: The exact name of the OLD DB data source you just created in Sybase ASE OLE DB Configuration Manager.
--Data source: Same as Product name.
--Provider string: I left this blank
--Location: I left this blank
--Catalog: The default database (master or whatever) to log on to.
Security:
--You need to map a valid SQL Server logon to a valid Sybase logon. I did not use impersonation (which does a credentials pass-thru).
--I chose my connection Be made without using a security context.
Server Options:
--All the defaults worked for me.
Throughout, the standard SQL Server help worked fairly well as a guide. Though not always true, F1 was my friend here.
I can now do distributed queries, DTS or SSIS packages, and use SSRS. This takes a lot of the suck out of Sybase ASE.
Of course the above can be done via the command line using sp_linkserver, but the GUI is more comfortable for a lowly dev like me.
Use Management Studio or Enterprise Manager to import the data using the data importation wizard. That should be it, just make sure you pick the right data provider in the wizard and you should be good to go.
If you want this to be a live feed create a small windows service to manage the exchange of information. It should be relatively simple to do, just a little bit of leg work on your end. If you are adverse to that there are plenty of off the shelf solutions that can do this for you.
The question is a little vague on specifics:
Is this a one time conversion or part of a repeated process.
Is the source machine "reachable" from your destination machine (can you connect the two or do you need to read in files)
With most conversions there are two parts:
Physically getting data from the source into the destination.
Mapping data from the source to the destination tables.
It is hard to make any recommendations without more info. What would be fine for a one time conversion would not work if you need to read in data all day every day. Also, if the source database can not be connected to and you have to pass files, they methods change.

Resources