I have a SQL server 2000 and an Access database mdb connected by Linked server on the other hand I have a program in c # that updates data in a SQL table (Users) based data base access.
When running my program returns the following error message:
OLE DB provider 'Microsoft.Jet.OLEDB.4.0' reported an error. Authentication failed.
[OLE / DB provider returned message: Can not start the application. Missing information file of the working group or is opened exclusively by another user.] OLE DB error trace [OLE / DB Provider 'Microsoft.Jet.OLEDB.4.0' IDBInitialize:: Initialize returned 0x80040E4D: Authentication failed.]´ .
Both the program, the sql server and database access are on a remote server.
On the local server the problem was solved by running the following:
"sp_addlinkedsrvlogin 'ActSC', 'false', NULL, 'admin', NULL".
Try on the remote server the next, without result:
"sp_addlinkedsrvlogin 'ActSC', true, null, 'user', 'pass'".
On the remote server and from the "Query Analyzer" sql update statements are working correctly.
Can you think of what may be the problem?
Thanks!
You can't access mdw file remotely? Specify remote mdw file location in provider string (Jet OLEDB:System Database=MySystem.mdw) and allow access to it from local server.
My guess is that this is related to user impersonation. Simply said: when you use Query Analyser you're using a different login than when you're accessing the server from your C# application. Try by setting the same username & password in your C# app.
You could solve this by configuring the linked server connection with a username and password, so that SQL server disregards any other password/current user credentials. Just use/check the last option/radio in this printscreen (disregard the login mappings list in the middle) and enter the username & password to use for ALL connections:
(source: msdn.com)
Related
I am trying to use Microsoft SQL Server with a Go program to connect to a database in SQL server and read some data from the database.
However when I use err=db.ping() it causes an error which says:
login failed for user 'sakhaloo'
I downloaded the zip file of the driver package from this directory: github.com/denisenkom/go-mssqldb then I copy the files within the zipped file and paste them in the following address : C:\Go\src\github.com\denisenkom\go-mssqldb
Another problem is when I try to open my SQL database with SQL Server 2014 Management Studio it doesn't accept my user name or password, actually it causes this error when I enter my username and password:
A connection was successfully established with the server, but then an
error occurred during the login process. (provider: Shared Memory
Provider, error: 0-no process is on the other end of the
pipe.)(Microsoft SQL Server, Error:233)
i don't know what is wrong with all this process.
This is my code:
package main
import (
//_ "code.google.com/p/odbc"
_ "github.com/denisenkom/go-mssqldb"
"database/sql"
"fmt"
"log"
//"github.com/astaxie/beedb"
// "github.com/weigj/go-odbc"
)
var (
uName, pass string
p *Person
)
type Person struct {
userName string
passWord string
Email string
}
func main() {
db, err := sql.Open("mssql", "server=SAKHALOO-PC;user id=sakhaloo;password=hoollehayerazi;database=webApp" )
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("Please enter your full name & password:")
fmt.Scanln(&uName, &pass)
row := db.QueryRow("SELECT username, password, email FROM user WHERE username=? and password=?", uName, pass)
fmt.Println(row)
p := new(Person)
err = row.Scan(&p.userName, &p.passWord, &p.Email)
fmt.Printf("%s , %s , %s \n", p.userName, p.passWord, p.Email)
fmt.Printf("Hi %s, your email address is : %s", uName, p.Email)
}
I want to share my experience working out a simple demo Go language database program using SQL Server Express 2008. I believe that the following lessons learned will apply to any SQL Server version from 2008 and later.
My SQL Server Express was previously installed with the default instance rather than a named instance. It was also installed to use Windows Authentication. Both of these settings were required by other development work that I do. The other work that I do uses SQL Server Express on the same PC as the application as a local database engine. I was expecting to be able to use Windows Authentication with SQL Server in my Go application.
Looking for a driver and a small sample program to use with a local SQL Server and Go, this question came up in my search. I thought to add a bit of additional information and a sample program to help others to get started and learn from my mistakes. I also found this article GoLang and MSSQL Databases: An Example helpful especially after making sufficient mistakes that I understood it better.
The final version of my test program is as follows:
package main
import (
"fmt"
"log"
"database/sql"
_ "github.com/denisenkom/go-mssqldb" // the underscore indicates the package is used
)
func main() {
fmt.Println("starting app")
// the user needs to be setup in SQL Server as an SQL Server user.
// see create login and the create user SQL commands as well as the
// SQL Server Management Studio documentation to turn on Hybrid Authentication
// which allows both Windows Authentication and SQL Server Authentication.
// also need to grant to the user the proper access permissions.
// also need to enable TCP protocol in SQL Server Configuration Manager.
//
// you could also use Windows Authentication if you specify the fully qualified
// user id which would specify the domain as well as the user id.
// for instance you could specify "user id=domain\\user;password=userpw;".
condb, errdb := sql.Open("mssql", "server=localhost;user id=gouser;password=g0us3r;")
if errdb != nil {
fmt.Println(" Error open db:", errdb.Error())
}
defer condb.Close()
errdb = condb.Ping()
if errdb != nil {
log.Fatal(errdb)
}
// drop the database if it is there so we can recreate it
// next we will recreate the database, put a table into it,
// and add a few rows.
_, errdb = condb.Exec("drop database mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: drop db - ", errdb.Error())
}
_, errdb = condb.Exec("create database mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: create db - ", errdb.Error())
}
_, errdb = condb.Exec("use mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: using db - ", errdb.Error())
}
_, errdb = condb.Exec("create table junky (one int, two int)")
if errdb != nil {
fmt.Println(" Error Exec db: create table - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (101, 201)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 1 - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (102, 202)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 2 - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (103, 203)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 3 - ", errdb.Error())
}
// Now that we have our database lets read some records and print them.
var (
one int
two int
)
// documentation about a simple query and results loop is at URL
// http://go-database-sql.org/retrieving.html
// we use Query() and not Exec() as we expect zero or more rows to
// be returned. only use Query() if rows may be returned.
fmt.Println (" Query our table for the three rows we inserted.")
rows, errdb := condb.Query ("select one, two from junky")
defer rows.Close()
for rows.Next() {
err:= rows.Scan (&one, &two)
if err != nil {
fmt.Println(" Error Query db: select - ", err.Error())
} else {
fmt.Printf(" - one %d and two %d\n", one, two)
}
}
rows.Close()
errdb = rows.Err()
if errdb != nil {
fmt.Println(" Error Query db: processing rows - ", errdb.Error())
}
fmt.Println("ending app")
}
The first time the above application is run once the necessary changes to SQL Server settings are made, it will generate the following output. Since the database does not exist the first time the program is run, you will see the error message printed. However subsequent times it is run the database will exist and the error message when the database is dropped exist will not be output.
starting app
Error Exec db: drop db - mssql: Cannot drop the database 'mydbthing', because it does not exist or you do not have permission.
Query our table for the three rows we inserted.
- one 101 and two 201
- one 102 and two 202
- one 103 and two 203
ending app
Installing the SQL Server Driver package
The first thing I had to do was to find a database driver package that would work with SQL Server. Several stackoverflow postings recommended github.com/denisenkom/go-mssqldb so that is what used.
In order to use the github.com/denisenkom/go-mssqldb package I had to first retrieve it from the github repository using go get github.com/denisenkom/go-mssqldb from the command shell window created by running Git Shell.
Git Shell is the github shell that is installed as part of installing Git. I found that I had to run the go get command in the Git Shell in order for the go command to find the git application and access the github repository. When I tried to run the go get command from a normal command shell I saw an error message indicating that the git command could not be found.
After installing the go-mssqldb package I was able to run my sample application and kept running into a runtime error from the Open(). The output from my application was the following:
starting app
Error Exec db: create db - Unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.
ending app
Enabling TCP connections for SQL Server
After some searching I found a number of different sites which all indicated that the error meant that my SQL Server instance was not configured for TCP/IP. The various postings indicated I needed to use the Sql Server Configuration Manager to enable TCP/IP.
What I discovered is that there are actually two places where TCP/IP needs to be enabled. One was Client Protocols and that was indeed already enabled. However the other was Protocols for MSSQLSERVER and in that one TCP/IP was disabled. So I enabled TCP/IP in the Protocols for MSSQLSERVER section, then restarted the SQL Server service using the Service utility of the Administrative Tools from the Control Panel.
However I was still having problems with any kind of a query after using sql.Open(). I was seeing application output that was some variation of the following. The error message was the same however when function calls had errors could change from one run to the next. I tried changing the connection string specified in the sql.Open() with no results other than different error messages.
starting app
Error Exec db: create db - driver: bad connection
Error Exec db: create table - driver: bad connection
ending app
Poking around further I found this note in the github repository:
Known Issues
SQL Server 2008 and 2008 R2 engine cannot handle login records when
SSL encryption is not disabled. To fix SQL Server 2008 R2 issue,
install SQL Server 2008 R2 Service Pack 2. To fix SQL Server 2008
issue, install Microsoft SQL Server 2008 Service Pack 3 and Cumulative
update package 3 for SQL Server 2008 SP3. More information:
http://support.microsoft.com/kb/2653857
So I downloaded the updates which I never actually installed. While waiting on the download, I poked around more and found the folder containing the actual SQL Server executable along with the Log folder containing a series of files ERRORLOG, ERRORLOG.1, etc.
SQL Server logs indicate SQL Server user required
Looking in the ERRORLOG file I found an error log of SQL Server with the following logs which provided the next piece of the puzzle:
2016-08-15 22:56:22.41 Server SQL Server is now ready for client connections. This is an informational message; no user action is required.
2016-08-15 23:55:47.51 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.51 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: 127.0.0.1]
2016-08-15 23:55:47.61 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.61 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: ::1]
2016-08-15 23:55:47.62 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.62 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: 127.0.0.1]
I then realized that the Go SQL Server driver was not using Windows Authentication but instead was using SQL Server Authentication. I had tried to use Windows Authentication by specifying an empty user id= however that did not seem to work. So using the sqlcmd utility, I created an SQL Server user.
1> create login gouser with password='g0us3r';
2> go
1> create user gouser for login gouser;
2> go
Next I downloaded and installed the Microsoft SQL Server Management Studio. This is a different utility from the SQL Server Configuration Manager. Using this I did two things: (1) turned on SQL Server Authentication as well as Windows Authentication and (2) provided the necessary permissions for my new SQL Server user gouser. This utility also provided a nice user interface to browse the SQL Server and its various databases.
Make sure that the SQL user you create has sufficient permissions so that it can be used to connect to SQL Server and create a database.
Some Considerations for Using Windows Authentication
After further research I found that I could actually use Windows Authentication however the completely qualified user id and its password must be provided. For an environment using Active Directory with a domain name of "AD" the fully qualified user id would be "AD\userid" and for the local host would be "\userid". I am still researching on being able to automatically use the credentials of the currently logged in user.
After still further research and find assistance from the Go driver developers, Windows Authentication with the current should be possible if the sql.Open() does not include the user information meaning "user id=;password=;" should not be specified.
However this form of automatic Windows Authentication against the current user is only allowed if the SQL Server instance is using Kerberos with a valid Service Principal Name (SPN). If you perform a restart on your instance of SQL Server and you see the following log in your ERRORLOG file, SQL Server was not able to initialize with Kerberos.
2016-08-23 18:32:16.77 Server The SQL Server Network Interface library
could not register the Service Principal Name (SPN) for the SQL Server
service. Error: 0x54b, state: 3. Failure to register an SPN may cause
integrated authentication to fall back to NTLM instead of Kerberos.
This is an informational message. Further action is only required if
Kerberos authentication is required by authentication policies.
See also How to make sure that you are using Kerberos authentication when you create a remote connection to an instance of SQL Server 2005 which provides some additional information as well using the setspn command to correct the problem.
See also The SQL Network Interface library was unable to register SPN.
About Trusted Windows Authentication (Updated as per request from #Richard by #xpt)
Windows Authentication is logging into SQL Server with Windows credential without specifying a user id and password. This is called trusted connection for sqlcmd or ODBC; or called Single-Sign-On for go-mssqldb Go driver package.
From go-mssqldb's readme in github,
"user id" - enter the SQL Server Authentication user id or the Windows
Authentication user id in the DOMAIN\User format. On Windows, if user
id is empty or missing Single-Sign-On is used.
So I tried the following two ways with my SQL Server 2008 R2 and both are just working fine:
condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=DONTCARE;")
condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=;")
Note that using server=localhost would fail, as it is important to have the correct host name, from that name the driver is building the SQL Server kerberos Service Principal Name (SPN) and that name must match SQL Server's. I used a proper Service Principal Name (SPN) with my test so it works.
I made a linked server with Microsoft OLE DB Provider for ODBC Drivers:
EXEC master.dbo.sp_addlinkedserver #server = N'TEST',
#srvproduct=N'Microsoft Visual FoxPro Driver',
#provider=N'MSDASQL',
#datasrc=N'TEST'
It worked fine still I used WIndows Authentication Mode, but when I created a login user and switch to SQL AUthentication it did not work.
What changes are needed to work with SQL Authentication?
In providers I have enabled:"Nested queries","Allow inpocess", Level zero only".
The error is:
OLE DB provider "MSDASQL" for linked server "TEST" returned message
"[Microsoft][ODBC Driver Manager] Invalid connection string
attribute". OLE DB provider "MSDASQL" for linked server "TEST"
returned message "[Microsoft][ODBC Driver Manager] Data source name
not found and no default driver specified". Msg 7303, Level 16, State
1, Line 1 Cannot initialize the data source object of OLE DB provider
"MSDASQL" for linked server "TEST".
If the connection to the linked server works fine using Windows Authentication, but it doesn't using a SQL Server Authentication, I would have a look at the properties of the linked server and make sure, choosing the tab "Security", that both the authentication modes are enabled:
This error message can occur because of one of these problems.
One of the initialization parameters specified in sp_addlinkedserver (data_source, location, provider_string, or catalog) is incorrect for this provider.
Verify that these parameters defined for the linked server, specified by executing
sp_addlinkedserver, are correct for the given provider.
Check Here also sp_addlinkedsrvlogin
Login and password sent to the provider is invalid.
Verify that there is a valid login and password configured for the linked server and the current SQL Server login through sp_addlinkedsrvlogin.
Go through this Article
UPDATE
During a linked server connection (for example, when it processes a distributed query), the sending server provides a login name and password to connect to the receiving server on its behalf. For this connection to work, you must create a login mapping between the linked servers by using SQL Server system stored procedures. --HERE and HERE
You need to create login mapping for linked server see security for Linked Server
Use sp_addlinkedsrvlogin
Creates or updates a mapping between a login on the local instance of SQL Server and a security account on a remote server.
sp_addlinkedsrvlogin [ #rmtsrvname= ] 'rmtsrvname'
[ , [ #useself= ] 'TRUE' | 'FALSE' | 'NULL']
[ , [ #locallogin= ] 'locallogin' ]
[ , [ #rmtuser= ] 'rmtuser' ]
[ , [ #rmtpassword= ] 'rmtpassword' ]
My server setup is a bit weird. One of my DB Admins added a Linked Server to my server. In the linked server properties, I see the following in the Security view:
Local server login to remote server login mappings:
Local Login Impersonate Remote User Remote Password
domain\myusername CHECKED
For a login not defined in the list above, connections will:
- Be made using the security context
Remote login: linkedserveruser
With password: **************
Therefore, when I created a stored procedure with the following:
SELECT *
INTO #TEMP
FROM LINKEDSERVERNAME.DBName.dbo.TableName
-- Update local table after processing #TEMP
And setup a SQL job, it was failing with the following message:
Message
Executed as user: NT AUTHORITY\NETWORK SERVICE. Login failed for user 'linkedserveruser'. [SQLSTATE 28000] (Error 18456). The step failed.
After, digging through documentation, I found a KB811031 article that explains this problem and suggested that I map the security context and run the job as osql.
I did not have to map the security context because (as you can see from the settings of the linked server above), it already was mapped. I changed the Type to Operating System Command as suggested. When I run the job now, I get the following message:
Executed as user: domain\MYMACHINENAME$. Msg 18456, Level 14, State 1, Server SOMEOTHERDATABASENAME, Line 1 Login failed for user 'linkedserveruser'. Process Exit Code 0. The step succeeded.
And the job quits reporting success when in fact it failed. Any suggestions on how I can get this type of stored procedure containing a query to a linked server to run as a SQL job?
I try to connect a PostgreSQL to SQL Server 2012 server as linked server
I found some advices on different forum and follow it. But I'm stuck with an authentication problem.
I explain:
On the SQL Server, I have install the ODBC driver for PostgreSQL (psqlodbc_09_02_0100-x64). I created a system DSN to a specific database on the PostgreSQL. This DSN work correctly.
Using SSMS, I run this command to add the linked server:
EXEC master.dbo.sp_addlinkedserver
#server = N'lnk_test',
#srvproduct=N'PostgreSQL Unicode(x64)',
#provider=N'MSDASQL',
#provstr=N'Driver=PostgreSQL Unicode(x64);uid=postgres;Server=test1;database=accueil;pwd=MyPassword;SSLmode=disable;PORT=5432'
EXEC master.dbo.sp_addlinkedsrvlogin
#rmtsrvname=N'lnk_test',
#useself=N'True',
#locallogin=NULL,
#rmtuser=NULL,
#rmtpassword=NULL
After running, I have a new Linked Server called "lnk_test". When I receive the following error message:
Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "pgTest1_accueil".
OLE DB provider "MSDASQL" for linked server "pgTest1_accueil" returned message "[Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr failed".
OLE DB provider "MSDASQL" for linked server "pgTest1_accueil" returned message "FATAL: authentification par mot de passe échouée pour l'utilisateur « postgres »". (Microsoft SQL Server, Error: 7303)
The error message is in french, the traduction is: "authentication by password failed for user "postgres". I find the same error message in the log of the PostgreSQL server.
Is someone have an idea for resolving this problem?
Thanks in advance.
Jerome
[Update 2/08/2013]
I complete this post with the result of a test I realize today.
WHen using a packet sniffer, I check the packets sended when testing the connection through the ODBS Data Source Administrator (64-bit) and through the Linked Server under SSMS.
The data are the same between the 2 system for:
Opening the connection to the PostgreSQL
Sending the connection string (all parameters are the same)
the response of PostgreSQL asking for password (only different is the salt value, but it's normal)
the password are sended in the same way (crypted with MD5)
But after, the response of the server differ:
For the ODBC Data Source, all works correctly. I receive the authentication and can send test query.
For SSMS, I receive an error message (as describe upper).
Ok, I found the solution.
In the pg_hba.conf file, I change the method for sending passwords from MD5 to trust. After reloading the server, my linked server connection works.
the entry is now:
Type Database User Address Method
host all all x.x.x.x/x trust
In hope that help others peoples.
I think I found the answer; I was still getting the error with a recent version of the ODBC driver and Postgres 10.x.
The connection will work when tested in the Windows ODBC diaglog, but will fail in SQL Server. When setting the password for the remote user, place the password in curly braces.
{password}
This will keep the ODBC connection string from getting screwed up if you have certain symbols in your user's password.
I have a Visual Studio C++ project (unmanaged C++) in which I try to connect to a SQL Server 2008 instance on another machine in the LAN. I use TCP/IP. My connection string is:
"DRIVER={SQL Server Native Client 10.0};Server=tcp:169.254.204.232,1433;Network Library=DBMSSOCN;Initial Catalog=myDB;User ID=myDBUser;Password=myPassword;"
Important fact: I am able to successfully connect remotely to that instance with user id myDBUser and password myPassword using SSMS -- using SQL Authentication mode (and specifying TCP/IP in the connection options)! Also, once logged in I can successfully navigate the database myDB.
So yes, I have enabled Mixed mode authentication on my server.
Also note that the same code was successfully connecting when my instance was local and I was using Windows Authentication. In other words, what changed since this whole thing last worked is that I moved my server to another machine, am now using SQL Authentication, and therefore changed my connection string -- the code has otherwise not changed at all.
Here is the error message I get in my SQL Server 2008 instance's Server Logs:
Login failed for user ". Reason: An attempt to login using SQL Authentication failed. Server is configured for Windows Authentication only.
Error: 18456, Severity: 14, State: 58.
Notice that the user being quoted in that error message is blank, even though in my connection string I specify a non-blank user ID.
Other connection strings I tried that give the same result:
"DRIVER={SQL Server Native Client 10.0};Server=MACHINE2;Database=myDB;User ID=myDBUser;Password=myPassword;" (where MACHINE2 is the windows name of the machine hosting the sql server instance.)
I do not specify an instance name in the above connection string because my instance is installed as the default instance, not a named instance.
Any ideas on how to solve this?
UPDATE: I solved this problem it seems. Are you ready to find out how silly and totally unrelated that error message was?
In the connection string, I just changed "User ID" to "uid" and "Password" to "pwd", and now it works.
I now see "Connected successfully" in my SQL Server logs...
Try running SELECT SERVERPROPERTY('IsIntegratedSecurityOnly'); if it returns 1 is Windows Authentication if 0 Mixed. If it returns 1 is definitely Windows Authentication and there must be something else wrong.
I think I solved this problem by doing this...
right click on servername on object explorer -> Properties -> Security -> Changed server authentication to SQL server and Windows authentication mode -> click OK.
after that open server on object explorer -> Expand security -> Expand Login -> right click on your login -> properties -> type new password -> confirm password -> OK.
then disconnect your SQL and restart your system. then login SQL server 2008 with changed password in sql authentication mode.
Thanks :)
The answer: In the connection string, I just changed "User ID" to "uid" and "Password" to "pwd", and now it works. I now see "Connected successfully" in my SQL Server logs...