VB6 and Sql server 2016 Express connection string - vb6

In one of our old vb6 app connection string is as follows:
nk = "Provider=SQLOLEDB;"
nk = nk + "Integrated Security=SSPI;"
nk = nk + "Persist Security Info=False;"
nk = nk + "User ID=sa;"
nk = nk + "Password=******;"
nk = nk + "Initial Catalog=" & db & ";"
nk = nk + "Data Source=" & hn
kon.ConnectionString = nk
kon.Open
If I try to connect with these options it wont work, so I'm interested why these two options:
nk = nk + "Integrated Security=SSPI;"
nk = nk + "Persist Security Info=False;"
are not ignored?
Just to mention that application is connecting to Sql Server 2016 Express on Windows Server 2016 Standard over local network.

your issue is with
Integrated Security=SSPI
It should be set to false (or removed altogether) as you are not using current Windows user Authentication but a standard SQL user-password login.
Out of MSDN documentation:
When false, User ID and Password are specified in the connection. When
true, the current Windows account credentials are used for
authentication. Recognized values are true, false, yes, no, and sspi
(strongly recommended), which is equivalent to true. If User ID and
Password are specified and Integrated Security is set to true, the
User ID and Password will be ignored and Integrated Security will be
used.

Related

VBA Query using ADODB returning different results on different computers

In VBA macro in Excel I have an issue where the exact same query with the exact same database credentials are returning different results depending on what computer the script is being executed. Some pull all of the correct results, others have results missing.
If we execute the query using Toad or any other tool that can execute oracle it has worked correctly on every machine tested.
So far we have found out that the following things are not causing the issue:
Oracle Driver version (instant client vs full both tested no correlation found)
Excel versions (everyone at my company has the same build of excel)
VBA project references are the same.
Confirmed all machines are pointing to the correct database.
ODBC Settings are the same
All machines tested are running Excel 2010 on windows 7, The Database is Oracle 11,
Here is the script
Dim cn
Set cn = CreateObject("ADODB.Connection")
Dim rs
Set rs = CreateObject("ADODB.Recordset")
cn.ConnectionString = "DSN=#####;UID=####;PWD=#####;DBQ=######;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=O;MLD=0;ODA=F"`
`cn.Open`
`Set rs = cn.Execute(SQLfinal)`
Dim iCol As Integer
Dim iRow As Integer
fldCount = rs.Fields.Count
For iCol = 1 To fldCount
Sheets("8. Data").Cells(12, iCol).Value = rs.Fields(iCol - 1).Name
Next
Sheets("8. ####").Cells(13, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
cn.Close
Rows("12:12").Select
Selection.AutoFilter
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With

ASP Retrieving a trigger-populated field value - worked with earlier version of Oracle

The below sample ASP classic code that I have modified so it can be run via cscript or wscript, communicating with Oracle 8i and using Oracle ODBC Driver 8.01.07.00 running on Windows 2000, returns a valid shipper_id. This primary key field is populated via a before insert or update trigger (I can include it if necessary, but I have confirmed it works).
However, with Oracle 11, Oracle ODBC driver 11.02.00.03, and Windows Server 2012, only a blank value is returned - why?
Any help that can be provided would be appreciated. Note that I would rather not have to switch to OO4O or use the Oracle Provider for OLE DB unless there is no other option.
Dim strCnxn, cnxn, rs
strCnxn = "DSN=OUR_DSN;uid=OUR_UID;pwd=OUR_PWD"
Set cnxn = Wscript.CreateObject("ADODB.Connection")
cnxn.Open strCnxn
Set rs = Wscript.CreateObject("ADODB.Recordset")
rs.Open "SHIPPER", cnxn, 1, 3, &H0002 'adOpenKeyset, adLockOptimistic, adCmdTable
rs.AddNew
rs("CARRIER_ID") = "13263"
rs("NAME") = "test-shipper"
rs.Update
Wscript.Echo("Shipper ID: " & rs("SHIPPER_ID"))
Wscript.Echo("Carrier ID: " & rs("CARRIER_ID"))
Wscript.Echo("Name: " & rs("NAME"))
rs.Close
Set rs = Nothing
Set cnxn = Nothing

Managing remote DACLs on fileshares: Win32_ACE to Win32_Share

Goal: Add a local user account share-level Read/Write permissions to an existing file share.
I'm hitting a roadblock in developing this. Apparently Microsoft wants you to add your user's ACE to the DACL and then back into the security descriptor of the share. (1). (No, NET SHARE /ADD is not available for existing shares, I was surprised.)
In theory that should be simple enough, but my main fear is doing it wrong and losing the existing share permissions (lots of network users, specific groups). This solution needs to scale to a few thousand shares. I'm developing the solution to output data about the existing DACL in case I need to back out. I should write code to interpret that log and be prepared to add them back en-masse should anything go wrong.
At the moment I'm using VBscript-- I feel PowerShell might be a bit stronger of an approach but VBscript/WMI is a known quantity.
Research:
(1) http://blogs.msdn.com/b/helloworld/archive/2008/07/22/editing-share-permission.aspx
Copy the existing ACEs to an array:
rc = shareSec.GetSecurityDescriptor(sd)
ReDim acl(UBound(sd.DACL)+1) '+1 for the new ACL we're going to add
For i = 0 To UBound(sd.DACL)
Set acl(i) = sd.DACL(i)
Next
Add the new ACE to that array:
Set acl(UBound(acl)) = NewACE(NewTrustee(username, domain), 2032127)
The functions NewTrustee() and NewACE() encapsulate the instructions for creating the trustee and the ACE. The number is the access mask for Full Control.
Create a new security descriptor and assign it to the share:
Set sd = wmi.Get("Win32_SecurityDescriptor").SpawnInstance_
sd.ControlFlags = flags
sd.DACL = acl
rc = shareSec.SetSecurityDescriptor(sd)
Check this page for a lot more detail information about security descriptors, trustees, ACLs and ACEs.
Full script:
Const FullControl = 2032127
' modify these variables according to your requirements:
computer = "."
share = "..."
username = "..."
domain = CreateObject("WScript.Network").UserDomain
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" _
& computer & "/root/cimv2")
Set shareSec = GetObject("winmgmts:Win32_LogicalShareSecuritySetting.Name='" _
& share & "'")
Function NewTrustee(name, domain)
Dim trustee, account
Set trustee = wmi.Get("Win32_Trustee").SpawnInstance_
trustee.Name = name
trustee.Domain = domain
Set account = wmi.Get("Win32_UserAccount.Domain='" & domain & "',Name='" _
& name & "'")
trustee.Properties_.Item("SID") = wmi.Get("Win32_SID.SID='" & account.SID _
& "'").BinaryRepresentation
Set NewTrustee = trustee
End Function
Function NewACE(trustee, permissions)
Dim ace : Set ace = wmi.Get("Win32_Ace").SpawnInstance_
ace.Properties_.Item("AccessMask") = permissions
ace.Properties_.Item("AceFlags") = 3
ace.Properties_.Item("AceType") = 0
ace.Properties_.Item("Trustee") = trustee
Set NewACE = ace
End Function
' copy existing ACEs
rc = shareSec.GetSecurityDescriptor(sd)
flags = sd.ControlFlags
ReDim acl(UBound(sd.DACL)+1) '+1 for the new ACL we're going to add
For i = 0 To UBound(sd.DACL)
Set acl(i) = sd.DACL(i)
Next
Set sd = Nothing
' add new ACE
Set acl(UBound(acl)) = NewACE(NewTrustee(username, domain), FullControl)
' prepare new security descriptor
Set sd = wmi.Get("Win32_SecurityDescriptor").SpawnInstance_
sd.ControlFlags = flags
sd.DACL = acl
' assign new security descriptor
rc = shareSec.SetSecurityDescriptor(sd)

Secure LDAP object manipulation with VBscript using alternate credentials

I'm aware of using ADsDSOobject with explicit credentials to connect to an AD object to read attributes, list members, etc. And the GetObject("LDAP//...") method for manipulating those objects (adding group members, changing properties, etc.), but is there a way to manipulate attributes and memberships with explicit credentials?
The first method I'm referring to is something like...
Set conn = Server.CreateObject("ADODB.Connection")
Set cmd = Server.CreateObject("ADODB.Command")
conn.Provider = "ADsDSOobject"
conn.Properties("User ID") = AD_Username
conn.Properties("Password") = AD_Password
conn.Properties("Encrypt Password") = True
conn.Open "Active Directory Provider"
Set cmd.ActiveConnection = conn
But none of the script examples that perform tasks like adding a user to a domain group can use this approach as far as I know. Is there a way to do that somehow?
In VBScript, very often, you are using ADSI to add user to group. Here is a sample code to add a user to a domain group
Set objUser = GetObject("LDAP://CN=jeffsmith,DC=fabrikam,DC=com")
Set objGroup = GetObject("LDAP://CN=group1,DC=fabrikam,DC=com")
objGroup.add(objUser.ADsPath)
It works fine but it's always using your current user credentails. It's because GetObject doesn't allow you to specify alternate credentials.
To specify another credentails, you need to replace GetObject by OpenDSObject
Const ADS_SECURE_AUTHENTICATION = 1
Set openDS = GetObject("LDAP:")
Set objUser = openDS.OpenDSObject("LDAP://CN=jeffsmith,DC=fabrikam,DC=com",
"username",
"password",
ADS_SECURE_AUTHENTICATION)
Set objGroup = openDS.OpenDSObject("LDAP://CN=group1,DC=fabrikam,DC=com",
"username",
"password",
ADS_SECURE_AUTHENTICATION)
objGroup.add(objUser.ADsPath)

How to connect to LDAP store with VB6

I’ve got a problem with Visual Basic (6) in combination with LDAP. When I try to connect to an LDAP store, I always get errors like ‘Bad Pathname’ or ‘Table does not exist’ (depending on what the code looks like).
This is the part of the code I wrote to connect:
path = "LDAP://xx.xxx.xxx.xxx:xxx/"
Logging.WriteToLogFile "Test1", logINFO
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADsDSOObject"
conn.Properties("User ID") = "USER_ID"
conn.Properties("Password") = "PASSWORD"
conn.Properties("Encrypt Password") = True
conn.Properties("ADSI Flag") = 34
Logging.WriteToLogFile "Test2", logINFO
conn.Open "Active Directory Provider"
Logging.WriteToLogFile "Test3", logINFO
Set rs = conn.Execute("<" & path & "ou=Some,ou=Kindof,o=Searchbase>;(objectclass=*);name;subtree")
Logging.WriteToLogFile "Test4", logINFO
The logfile shows “Test1” , “Test2”, “Test3” and then “Table does not exist”, so it’s the line “Set rs = conn.Execute(…)” where things go wrong (pretty obvious…).
In my code, I try to connect in a secure way. I found out it has nothing to do with SSL/certificates though, because it’s also not possible to establish an anonymous unsecured connection. Funny thing is: I wrote a small test app in .NET in five minutes. With that app I was able to connect (anonymously) and read results from the LDAP store, no problems at all.
Does anyone have any experience with the combination LDAP and VB6 and maybe know what could be the problem? I googled and saw some example code snippets, but unfortunately none of them worked (same error messages as result). Thanks in advance!
I'm not sure how much help this will be, but I use this code to access Active Directory objects.
Set oinfo = New ADSystemInfo
sDomain = Split(oinfo.DomainDNSName, ".")
'-- Get Datasets from the Active Directory
'-- Connect to Active Directory in logged in domain
con.Open "Provider=ADsDSOObject;Encrypt Password=False;Integrated Security=SSPI;Data Source=ADSDSOObject;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648"
'-- Query all serviceConnectionPoints in the Active Directory
'-- that contain the keyword "urn://tavis.net/TM/Database"
'-- and return the full path to the object
Set rst = con.Execute("<LDAP://DC=" & sDomain(0) & ",DC=" & sDomain(1) & ">;(&(objectCategory=serviceConnectionPoint)(keywords=urn://tavis.net/TM/Database));Name, AdsPath;subTree")
2 things:
The Open() method call takes additional parameters, server/username/password
The LDAP query you passed to Execute() should be:
"<" & path & "ou=Some/ou=Kindof/o=Searchbase>;(objectclass=*);name;subtree"

Resources