Force MS Access ODBC Connection to use SQL Server Authentication - sql-server

I'm using the following code that is run from my Autoexec macro to make the ODBC connection.
'Name : CreateDSNConnection
'Purpose : Create a DSN to link tables to SQL Server
'Parameters
' sServer: Name of SQL Server that you are linking to
' sDatabase: Name of the SQL Server database that you are linking to
' sUsername: Name of the SQL Server user who can connect to SQL Server, leave blank to use a Trusted Connection
' sPassword: SQL Server user password
Public Function CreateDSNConnection(sServer As String, sDatabase As String, sUsername As String, sPassword As String) As Boolean
Dim sConnect As String
On Error GoTo CreateDSNConnection_Err
If Len(sUsername) = 0 Then
'//Use trusted authentication if stUsername is not supplied.
sConnect = "Description=DBTraining" & vbCr & "SERVER=" & sServer & vbCr & "DATABASE=" & sDatabase & vbCr & "Trusted_Connection=Yes"
Else
sConnect = "Description=DBTraining" & vbCr & "SERVER=" & sServer & vbCr & "DATABASE=" & sDatabase
End If
DBEngine.RegisterDatabase "DBTraining", "SQL Server", True, sConnect
'Add error checking.
CreateDSNConnection = True
Debug.Print "Connection made"
Exit Function
CreateDSNConnection_Err:
CreateDSNConnection = False
MsgBox "CreateDSNConnection encountered an unexpected error: " & Err.Description, vbCritical, "Unexpected Error!"
End Function
Pretty standard stuff...but it seems that the ODBC connection is always setup as using Windows auth and I need it setup to use SQL Server auth. I've tried dropping in the UID= and PWD=, but it still tries to use Windows.

Here is a trusted connection from Access to SQL Server:
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"Trusted_Connection=yes"
Or for SQL Server Authentication:
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"User Id=,myUID>;Password=<MyPWD>"

What ended up working for me was starting it over from scratch.
I blew out the existing UserDSN from the ODBC connection.
Then opened my DB and ran the CreateDSNConnection code
That put the UserDSN back in, and was set to use SQL Server Authentication, but was using my Windows login
Deleted all linked tables and views
Recreated the links for tables and views using the Generic SQL login account and checked the Save password option
Compacted & Repaired
Sent to a user to test...it worked
I had tried every one of these steps multiple times...except for the first one. I'm guessing that there was something corrupted in the UserDSN file??? I have no idea. But deleting it and starting over completely resolved the issue.

Dim CurConn As ADODB.Connection
Set CurConn = New ADODB.Connection
CurConn.Open "Provider=myProvider;" & _
"Server=myServer;" & _
"Database=myDatabase;" & _
"Trusted_Connection=no;" & _
"User Id=myUsername;" & _
"Password=myPassword;"
This, how I do it in Access VBA.

Related

Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication Access vba

I am trying to connect to SQL Server on the internet using VBA TCP/IP. First thing that I did was to attach tables using DSN Less connection:
stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDatabase & ";UID=" & stUsername & ";PWD=" & stPassword
Set td = CurrentDb.CreateTableDef(stLocalTableName, 0, stRemoteTableName, stConnect)
This is working perfectly fine and I can now use Access linked tables to view my table contents.
But when I try to create an ADODB connection:
Set cn = New ADODB.Connection
cn.ConnectionTimeout = 60
cn.CommandTimeout = 90
cn.Open "Provider=Microsoft.Access.OLEDB.10.0;Persist Security Info=False;Data Source=" & stServer & ";Integrated Security=SSPI;Initial Catalog=" & stDatabase & ";UID=" & stUsername & ";PWD=" & stPassword & ";Data Provider=SQLOLEDB.1"
With the variables parsed the above connection string looks something like this:
Provider=Microsoft.Access.OLEDB.10.0;Persist Security Info=False;Data Source=42.133.12.12,1433;Integrated Security=SSPI;Initial Catalog=MYDB;UID=MYDB_USER;PWD=MYDB_PASSWORD;Data Provider=SQLOLEDB.1
I get the error:
Login failed. The login is from an untrusted domain and cannot be used
with Integrated authentication.
I have looked at various places online but have not found any solutions.
Remove 'Integraged Security=SSPI' from your connection string. You are specifying to use integrated security in addition to a username and password in the connection.

Login failed for user (SQL Server) via VBA (Excel) Macro

I'm creating a macro in an Excel spreadsheet that will connect to an instance of SQL server using SQL Server Authentication. This is a recycled function I've written previously that I know works. I suspect it's either the way I've constructed the connection string for the SQL authentication, or the way the user is configured (although I have successfully logged into the server through SSMS with the user account so I know the account works).
Public Function GetConnection(ServerLocation As String, db As String) As ADODB.Connection
Dim ServerName As String, cn As ADODB.Connection, un As String, pw As String
un = "MyUser"
pw = "MyPassword"
ServerName = "MyServer"
If cn Is Nothing Then
Set cn = New ADODB.Connection
cn.ConnectionString = "Driver={SQL Server};Server=" & ServerName & ";Database=" & db & ";UID='" & un & "';Pwd=" & pw & ";"
cn.CursorLocation = adUseClient
cn.Open
When I run the macro I get
Login Failed for user "MyUser"
at the cn.Open line.
I've checked that remote logins are allowed, and both SQL Server and Windows Authentication modes are enabled. I've also recreated the user account just in case.
Is there an issue with the connection string or am I missing something on the server?
Many thanks!
I found the solution: the single quotes around the UID are not required. I spotted these after viewing the Log and noticing the way the user name was formatted. Without the additional single quotes the connection is successful and my procedure executes successfully.
My final connection string looks like this:
cn.ConnectionString = "Driver={SQL Server};Server=" & ServerName & ";Database=" & db & ";UID=" & un & ";Pwd=" & pw & ";"

Connection to a Microsoft SQL Database via VBA (ADODB) with the lowest risk to harm the database

im currently looking for a way to connect to a Microsoft SQL Server Database via VBA (ADODB) with the focus on a minimal risk in harming, block and change the structure of the database. Therefor the access is readonly.
My attemp is the following:
Set DBConn = New ADODB.Connection
Set TmpRecset = New Recordset
DBConn.ConnectionString = pConnStr
DBConn.Open
On Error GoTo TermConnection
With TmpRecset
.ActiveConnection = DBConn
.Source = pQuery
.LockType = adLockReadOnly
.CursorType = adOpenForwardOnly
.CursorLocation = adUseClient
.Open
End With
On Error GoTo TermRecordset
//Doing something useful with TmpRecset
On Error GoTo 0
TermRecordset:
TmpRecset.Close
Set TmpRecset.ActiveConnection = Nothing
TermConnection:
DBConn.Close
Set DBConn = Nothing
End Sub
And I'm using the following connection string:
"Provider=SQLOLEDB;Data Source=IP\Database;Initial Catalog=Databasename;Trusted_connection=yes;"
I used the manual error handling to ensure, that the recordset and the database is closed whatever happens. Via the parameters of the recordset I define the readonly access.
Are there some other mechanisms to make sure, that the integrity of the Database will be ensured?
Best regards
In my opinion there is no reasonable security in Excel. All security should reside on the server. If you want to prevent accidental or malicious changes to the database then the database on the server should be read-only or all users should have read-only access to the SQL server. Furthermore, you can implement traces on the server, SQL audit C2, or make use of extended properties. Yet, all of this is on the side of the SQL server. The things you can do on the "client" side (such as Excel in this case) are only support functions. And so the question is (to me) what kind of support functions can I implement in Excel to ensure SQL server safety. Here are some of the things I do:
(1) Make the connection string dynamic using global variables or storing the string on a hidden sheet. Then you can automatically switch between development server and production server. Example:
Dim conRCServer As ADODB.Connection
Dim rstResult As ADODB.Recordset
Dim strSQL As String
Set conRCServer = New ADODB.Connection
conRCServer.ConnectionString = "PROVIDER=SQLOLEDB; " _
& "DATA SOURCE=" & Ref.Range("C2").Value2 & ";" _
& "INITIAL CATALOG=" & Ref.Range("C4").Value & ";" _
& "Integrated Security=SSPI "
On Error GoTo SQL_ConnectionError
conRCServer.Open
On Error GoTo 0
(2) Have a seperate error handler for connecting to the server and handling SQL syntax errors. Example:
Set rstResult = New ADODB.Recordset
strSQL = "set nocount on; "
strSQL = strSQL & "/* #" & ActiveWorkbook.Path & "/" & ActiveWorkbook.Name & "{" & WorksheetUsers.Name & "}btnDownloadUserDataFromServer */"
strSQL = strSQL & "select v.LastName, "
strSQL = strSQL & " v.FirstName "
strSQL = strSQL & "from vUsers as v "
strSQL = strSQL & "order by v.LastName, v.FirstName "
rstResult.ActiveConnection = conRCServer
On Error GoTo SQL_StatementError
rstResult.Open strSQL
On Error GoTo 0
Here is an error handler for the SQL syntax and in the above example is a seperate handler for the possible SQL connection error.
(3) Incorporate self-identification within the SQL syntax. As you can see in the above example I am also letting the server know which file, which sheet (within the file) and which function within the sheet the user called to execute this statement. If you capture this data on the server with a trace then you can see who is writing their own queries, who is using your standard files and which functions are used (and their respective impact).
(4) If an error occurs you might want to consider writing automated error emails. Example:
SQL_ConnectionError:
Y = MsgBox("Cannot connect to the server. Please make sure that you have a working internet connection. " & _
"Also ensure that are connected to the corporate network and are allowed to access the server. " & _
"Do you want me to prepare an error-email?", 52, "Problems connecting to Server...")
If Y = 6 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = Ref.Range("C7").Value2
.CC = Ref.Range("C8").Value2
.Subject = "Problems connecting to database '" & Ref.Range("C4").Value & "' on server '" & Ref.Range("C2").Value & "'"
.HTMLBody = "<span style=""font-size:10px"">---Automatically generated Error-Email---" & _
"</span><br><br>Error report from the file '" & _
"<span style=""color:blue"">" & ActiveWorkbook.Name & _
"</span>' located and saved on '<span style=""color:blue"">" & _
ActiveWorkbook.Path & "</span>'.<br>" & _
"Excel is not able to establish a connection to the server. Technical data to follow." & "<br><br>" & _
"Computer Name: <span style=""color:green;"">" & Environ("COMPUTERNAME") & "</span><br>" & _
"Logged in as: <span style=""color:green;"">" & Environ("USERDOMAIN") & "/" & Environ("USERNAME") & "</span><br>" & _
"Domain Server: <span style=""color:green;"">" & Environ("LOGONSERVER") & "</span><br>" & _
"User DNS Domain: <span style=""color:green;"">" & Environ("USERDNSDOMAIN") & "</span><br>" & _
"Operating System: <span style=""color:green;"">" & Environ("OS") & "</span><br>" & _
"Excel Version: <span style=""color:green;"">" & Application.Version & "</span><br>" & _
"<br><span style=""font-size:10px""><br>" & _
"Possible reasons for this error include: (1) no Internet connection, (2) no working VPN connection to the corporate network, " & _
"(3) the server is currently offline, (4) DNS authentication problems, (5) ... other reasons ..., " & _
"(6) the user does not have the required permission to connect to the underlying database on the server." & _
"<br><br>---Automatically generated Error-Email---"
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End If
Exit Sub
I also looked into your approach of changing the connection parameters. But in most corporate environments I have worked for these connection parameters have been overridden (for example ADODB.Connection.CommandTimeout is overridden by the server's SQL timeout per user or Windows corporate presets if they exist). So, they did not work for me. But the above worked rather well for me and the companies I worked for over the last couple of years.
Let me know if this is the kind of answer you've been looking for.

Change SQL Server Password through MS Access VBA Front-End

I have been working on developing a MS Access application that will allow some coworkers to easily interact with data on our SQL Server. The program is about done, but one little thing remains- allowing a user to change their SQL Server password through the MS Access front-end. I have been googling my little heart out, but after a while everything starts to look the same (even if the answer is right in front of me!).
I found a couple links that are helpful, but I can't quite make the leap on how to apply it to my VBA program.
Change expired password without "Password Expired dialog box"
How can I change SQL Server login account password on first login via C#?
http://www.utteraccess.com/forum/Users-Change-SQL-Pass-t2006545.html&pid=2378998
My current connection string looks like this
Dim cn As ADODB.Connection
Dim strCS As String
Set cn = New ADODB.Connection
strCS = "Provider=SQLOLEDB;" _
& "Server=IP ADDRESS GOES HERE;" _
& "Database=" + DBselect.Value + ";" _
& "User ID=" + Uname.Value + ";" _
& "Password=" + pWord.Value + ";" _
& "MARS Connection=True;"
cn.ConnectionString = strCS
cn.Open
This connection string works perfectly fine as long as the user's password hasn't expired.
How would I modify this connection string to change a users password? Any help is really appreciated!
Thanks!
Looks to me, from that 1st link, that this will work:
1) Create a new stored procedure in SQL Server called spChangeLogin. It should look like this:
CREATE procedure [dbo].[spChangeLogin]
#UserName VarChar (50),
#OldPass VarChar (20),
#NewPass VarChar (20)
AS
BEGIN
ALTER LOGIN #UserName WITH
PASSWORD = #NewPass
OLD_PASSWORD = #OldPass
END
;
GO
2) Add this to your Access DB:
Dim cnComments As New ADODB.Connection
Dim strCS As String
Dim P As String
Dim Rsx As ADODB.Recordset
'Set up the connection string
strCS = "Provider=SQLOLEDB;" _
& "Server=IP ADDRESS GOES HERE;" _
& "Database=" + DBselect.Value + ";" _
& "User ID=" + Uname.Value + ";" _
& "Password=" + pWord.Value + ";" _
& "MARS Connection=True;"
cnComments.Open strCS
P = "spChangeLogin '" & Me.UserName & "', '" & Me.OldPass & "', '" & Me.NewPass & "'"
Set Rsx = cnComments.Execute(P)
3) Put 3 fields on your form; UserName, OldPass and NewPass
Requires ALTER ANY LOGIN permission.
NOTE:
My connection string looks like this:
strConn = "PROVIDER=SQLOLEDB;DATA SOURCE=MyServerName;INITIAL CATALOG=MyDatabaseName;UID=GlobalUserID;PWD=GlobalPassword;"
You may need to adjust accordingly.

Database fail to connect

I try to connect ms access database files named ShopTranfer.accdb but I got error "not a valid account name or password"
here is my connection string
Dim BD As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
con & ";Jet OLEDB:Database Password=" & pass &
";Jet OLEDB:System Database=" & dir & ";"
BD actual value is
Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=c:\users\ahsan.gulahmed\desktop\shoptransfer.accdb;Jet
OLEDB:Database Password=a;Jet OLEDB:System
Database=C:\inetpub\wwwroot\HMIS\Shop.mdw;
use this url to get example of all contents..
http://www.mybringback.com/tutorial-series/828/thenewboston-sample-projects/
this is an good example for android api demos for all things......................

Resources