I am using a VBScript to do an authentication between my application with OID(Oracle Identity Directory) using an LDAP script. I am successfull in doing authentication. The next step involved is fetching all the groups that user is belonging to and map with the groups in my application. For some reasons I am not able to fetch the group information from the LDAP server. I know the attribute I should query is "groupmembership". But I am not able to get any values from this attribute. Any help on this is required. Here is a code snippet of what I have -
'ldapauth.vbs
'Version: 1.0
'Use: c:\cscript ldapauth.vbs <userName> [<password>]
'Ex - Anonymous: c:\>cscript ldapauth.vbs svc_testconsona
'Ex - Authenticated: c:\>cscript ldapauth.vbs svc_testconsona wipro#123
Dim oUser 'LDAP object holding user info
Dim oDSP 'Directory Service Provider
Dim oArgs 'Command line arguments
Dim sCN 'search parameter - LDAP attribute: CN
Dim sPWD 'CN's password parameter
Dim sRoot 'Holds the root of the LDAP object
Dim sDN 'Distinguished Name of authenticating account
Dim sLDAPsrv 'LDAP server
Dim sLDAPsb 'LDAP search base
Dim bAuthQuery 'Query Type - True=Authenticated, False=Anonymous
CONST ADS_SECURE_AUTHENTICATION = &H0001
CONST ADS_USE_ENCRYPTION = &H0002
CONST ADS_USE_SSL = &H0002
CONST ADS_READONLY_SERVER = &H0004
CONST ADS_NO_AUTHENTICATION = &H0010
CONST ADS_FAST_BIND = &H0020
CONST ADS_USE_SIGNING = &H0040
CONST ADS_USE_SEALING = &H0080
CONST ADS_USE_DELEGATION = &H0100
CONST ADS_SERVER_BIND = &H0200
Const ADS_PROPERTY_NOT_FOUND = &h8000500D
sLDAPsrv = "myserver.domain.com:389"
sLDAPsb = "ou=Active,o=CMI"
'Get the command line args
set oArgs=WScript.Arguments
'Check command line args
On Error Resume Next
sCN = oArgs.item(0) 'username
If Err.Number <> 0 Then
Echo ""
Echo "**** ERROR: No username supplied."
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <userName> [<password>]"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
sRoot = "LDAP://" & sLDAPsrv & "/cn=" & sCN & "," & sLDAPsb
sDN = "cn=" & sCN & "," & sLDAPsb
wscript.echo "the query is:"
wscript.echo sRoot
On Error Resume Next
sPWD = oArgs.item(1) 'password
If Err.Number <> 0 Then 'This will be a non-authenticated query
bAuthQuery = False
Echo ""
Echo "Performing anonymous LDAP query..."
Echo ""
Else 'This will be an authenticated query
bAuthQuery = True
Echo ""
Echo "Performing authenticated LDAP query..."
Echo ""
End If
'Done checking command line args
'Set directory service provider
Set oDSP = GetObject("LDAP:")
'Perform requested type of query - anonymous or authenticated
If bAuthQuery Then 'authenticated query requested
'Set the LDAP object query
On Error Resume Next
Set oUser = oDSP.OpenDSObject(sRoot,sDN,sPWD,ADS_SERVER_BIND)
If Err.Number <> 0 Then
If Err.Number = "-2147023570" Then
Echo "**** ERROR: Authentication failed. Check username, password and search base."
ElseIf Err.Number = "-2147016646" Then
Echo "**** ERROR: LDAP server not found."
Else
Echo "**** ERROR: Unable to bind to LDAP server. " & Err.Number
End If
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <username> <password>"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
Else 'anonymous query requested
'Set the LDAP object query
On Error Resume Next
Set oUser = oDSP.OpenDSObject(sRoot,vbNullString,vbNullString,ADS_SERVER_BIND AND ADS_NO_AUTHENTICATION)
If Err.Number <> 0 Then
If Err.Number = "-2147016656" Then
Echo "**** ERROR: Username not found."
ElseIf Err.Number = "-2147016646" Then
Echo "**** ERROR: LDAP server not found."
Else
Echo "**** ERROR: Unable to bind to LDAP server. " & Err.Number
End If
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <username [<password>]"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
End If
'Populate the user property cache
oUser.GetInfo
'Iterate through available user attributes
For count = 0 to (oUser.PropertyCount-1)
sAttribName = oUser.Item(CInt(count)).Name
-'This line fetches the attribute name poroperly. But values from groupmembership is not getting it.
if sAttribName = "groupmembership" then
sAttribVal = oUser.GetInfoEx(sAttribName)
else
sAttribVal = oUser.Get(sAttribName)
end if
If IsArray(sAttribVal) Then
For Each sMultiVal in oUser.GetEx(sAttribName)
sAttribList = sAttribList & sAttribName & Space(16-Len(sAttribName)) & ":: " & sMultiVal & vbCRLF
Next
Else
sAttribList = sAttribList & sAttribName & Space(16-Len(sAttribName)) & ": " & sAttribVal & vbCRLF
End If
sAttribName = ""
sAttribVal = ""
if err.number <> 0 then
err.Clear
end if
Next
Echo sAttribList
'Clean up
set oDSP=Nothing
set oUser=Nothing
wscript.Quit
Sub Echo(byref message)
WScript.Echo message
End Sub
OID doesn't normally have an attribute on a user called groupmembership (unless you added one yourself).
If you are trying to find the groups that a user is a member of, you have to do a second ldap search for the groups.
Groups in OID have either groupOfNames or groupOfUniqueNames as their object class. Each of these object classes has a multivalued attribute for storing the names of group members. When a user is assigned to a group, their DN is added to the respective multivalued attribute. In the groupOfNames object class, this multivalued attribute is member, and, in the groupOfUniqueNames object class, it is uniqueMember.
Related
I want help to create a registry path which will use a variable for logged in user SID. The path is like - HKEY_USERS\'%UserSID%'\Software\Microsoft\Office\16.0\Outlook
User SID should be picked for whoever user is currently logged in on the system.
I don't know how to create this variable?
I want to use this variable in my script array.
KEY_PATHS = Array("HKEY_USERS\S-1-5-21-4054882774-118064744-2143271696-500\Software\Microsoft\Office\16.0\Outlook", _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-2660683129-3636505375-3381148637-65620")
DEBUG_PRINTING = False
MASTER_EXECUTION
Sub MASTER_EXECUTION()
' WMI Class Management
MAINTAIN_WMI_CLASS()
' Registry Key Storage
For Each KEY_PATH In KEY_PATHS
STORE_KEYS(KEY_PATH)
Next
If Err.Number <> 0 Then
EVENT_WRITER "ERROR","Storing Registry Keys Failed " & Err.Number & " | " & Err.Description
Else
EVENT_WRITER "INFO", "Storing Registry Keys Completed Successfully"
End If
End Sub
Function CONVERT_HIVE(HIVE)
' Check and return a system name based on a friendly name
If UCase(HIVE) = "HKEY_LOCAL_MACHINE" Then
CONVERT_HIVE = &H80000002
ElseIf UCase(HIVE) = "HKEY_USERS" Then
CONVERT_HIVE = &H80000002
ElseIf UCase(HIVE) = "HKEY_CURRENT_CONFIG" Then
CONVERT_HIVE = &H80000005
Else
EVENT_WRITER "ERROR","Converting Hive " & HIVE & " failed - " & Err.Number & " | " & Err.Description
WScript.Quit
End If
End Function
I got my answer in one of Microsoft thread:
Below VB code will fetch logged in user sid and and we can use that variable for our purpose:
vbs code in image
'And the variable path i was looking for will be like
KEY_PATHS = Array("HKEY_USERS\" & Sid & "\Software\Microsoft\Office\16.0\Outlook\PST")
Trying to read domain admin group members through VBScript, but unable to read. Throwing error on user server.
object not a collection
But it's working in my local test Windows Server 2012.
User Running it from member server. User is having domain admin rights.
How to check LDAP issue in server or is their anything else?
Option Explicit
'Get all member of a group INCLUDING members from ALL NESTED groups.
'Simply call the script with the samAccountName of the group.
'If the group name contains spaces it should be ENCLOSED IN QUOTES,
'IE scriptName.vbs "DOMAIN ADMINS"
Dim objGroup
'verify a group name was passed
If WScript.Arguments.Count <> 1 Then
WScript.Echo "NO GROUP PASSED"
WScript.Echo "Usage: scriptName <groupSamAccountName>"
WScript.Quit
End If
'bind to the gorup
Set objGroup = getGroup(WScript.Arguments(0))
'enumerate the groups members
enumMembers objGroup, ""
Function getGroup(strGroupName)
Dim objConn, objRecSet, strQueryString, objRootDSE, strQueryFrom
Const adsOpenStatic = 3
Set objRootDSE = GetObject("LDAP://RootDSE")
strQueryFrom = "LDAP://" & objRootDSE.Get("defaultNamingContext")
Set objConn = WScript.CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open
strQueryString = "SELECT AdsPath FROM '" & strQueryFrom & "' " & _
"WHERE samAccountName = '" & strGroupName & "'"
Set objRecSet = WScript.CreateObject("ADODB.Recordset")
objRecSet.Open strQueryString, objConn, adsOpenStatic
If objRecSet.RecordCount = 1 Then
Set getGroup = GetObject(objRecSet("AdsPath"))
Else
WScript.Echo UCase(strGroupName) & " was not found in the domain.(" & objRootDSE.Get("defaultNamingContext") & ")"
WScript.Quit
End If
End Function
Sub enumMembers(ByRef objGroup, strInheritedFrom)
Dim objMember
For Each objMember In objGroup.Members '<---throwing error by saying "object not a collection"
If LCase(objMember.class) = "group" Then
WScript.Echo objMember.SamAccountName
End If
Next
End Sub
I'm writing a VBScript that will simply check each user in AD if their password has been changed within a given number of days. When I was trying to get it working for a single user, I came up with the following working code:
Option Explicit
Dim objUser, strLDAPConnection, intPwdExpLimit
strLDAPConnection = "CN=Test User,OU=Test,OU=Employees,DC=domain,DC=com"
intPwdExpLimit = 90
Set objUser = GetObject("LDAP://" + strLDAPConnection)
WScript.Echo DaysSincePwdChange(objUser)
Function DaysSincePwdChange(objUserAccount)
DaysSincePwdChange = dateDiff("d", objUserAccount.PasswordLastChanged, Now)
End Function
So then I tried to get it to work by looping through all users in a Test OU with the following code:
Option Explicit
Const strOffice = "Test"
Dim objEmployeesOU, objUser, intPwdExpLimit
intPwdExpLimit = 90
Set objEmployeesOU = GetObject("LDAP://OU=" & strOffice & _
",OU=Employees,DC=domain,DC=com")
For Each objUser In objEmployeesOU
If objUser.class = "user" Then
If ((DaysSincePwdChange(objUser)) >= intPwdExpLimit) Then
MsgBox(objUser & ": Password Expired.")
Else
MsgBox(objUser & ": Password Current.")
End If
End If
Next
Function DaysSincePwdChange(objUserAccount)
DaysSincePwdChange = dateDiff("d", objUserAccount.PasswordLastChanged, Now)
End Function
The above code produces a 0x8000500D error and googling the error says that it can't find the property in the cache (referring to the PasswordLastSet property, see error description link here).
Any ideas why the first block of code works fine but the second has a problem accessing that property?
Error code 0x8000500d means E_ADS_PROPERTY_NOT_FOUND. The password of the user has never been changed, so the property is not set. You could handle the condition like this:
Function DaysSincePwdChange(objUserAccount)
On Error Resume Next
DaysSincePwdChange = dateDiff("d", objUserAccount.PasswordLastChanged, Now)
If Err Then
If Err.Number = &h8000500d Then
DaysSincePwdChange = -1
Else
WScript.Echo "Unexpected Error (0x" & Hex(Err.Number) & "): " & _
Err.Description
WScript.Quit 1
End If
End If
End Function
and modify the check like this:
passwordAge = DaysSincePwdChange(objUser)
If passwordAge >= intPwdExpLimit) Then
MsgBox(objUser & ": Password Expired.")
ElseIf passwordAge = -1 Then
MsgBox(objUser & ": Password never changed.")
Else
MsgBox(objUser & ": Password Current.")
End If
Context: Windows7 64bit, ActiveDirectory, Windows Server 2003
I'm trying to get the code given by Microsoft on their page GetSecurityDescriptor method of the Win32_Printer Class (Windows) to work. I'm a bit curious to know how the double instantiation of winmgmts works out, viz (from their code)
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate, (Security)}!\\" & strComputer & "\root\cimv2")
Set objWMIService = GetObject("winmgmts:")
I would have thought that the second instance would clobber the first. This would seem to be borne out by the fact that no matter what server name I put in strComputer, I still get a list of the printers on my computer.
Has anyone had any joy getting the DACL of a server-connected printer using VBScript?
you are right and there is more than one thing wrong with that script, here is a working version
SE_DACL_PRESENT = &h4
ACCESS_ALLOWED_ACE_TYPE = &h0
ACCESS_DENIED_ACE_TYPE = &h1
strComputer = "xxxxxxxxxx"
strUser = "xxxxxxxxxxxx"
strPassword = "xxxxxxx"
strDomain = "xxx"
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, _
"root\cimv2", _
strUser, _
strPassword, _
"MS_409", _
"ntlmdomain:" + strDomain)
Set colInstalledPrinters = objSWbemServices.ExecQuery ("Select * from Win32_Printer")
On error resume next
For Each objPrinter in colInstalledPrinters
Wscript.Echo "Name: " & objPrinter.Name
Return = objPrinter.GetSecurityDescriptor( objSD )
If ( return = 2 ) Then
WScript.Echo "Could not get security descriptor: " & Return
Elseif ( return = 8 ) Then
WScript.Echo "Unknown failure: " & Return
Elseif ( return = 9 ) Then
WScript.Echo "The user does not have adequate privileges to execute the method: " & Return
Elseif ( return = 21) Then
WScript.Echo "A parameter specified in the method call is not valid: " & Return
Elseif ( return = 0 ) Then
intControlFlags = objSD.ControlFlags
If intControlFlags AND SE_DACL_PRESENT Then
arrACEs = objSD.DACL
For Each objACE in arrACEs
WScript.Echo objACE.Trustee.Domain & "\" & objACE.Trustee.Name
If objACE.AceType = ACCESS_ALLOWED_ACE_TYPE Then
WScript.Echo vbTab & "User has access to printer"
ElseIf objACE.AceType = ACCESS_DENIED_ACE_TYPE Then
WScript.Echo vbTab & "User does not have access to the printer"
End If
Next
Else
WScript.Echo "No DACL found in security descriptor"
end if
Else
WScript.Echo "Could not get security descriptor: " & Return
End If
Next
=>> on my domain this gives the ACL twice per user, could be caused by the way security is given
Name: printer1
\CREATOR OWNER
User has access to printer
\CREATOR OWNER
User has access to printer
MCM\DomainUsers
User has access to printer
MCM\DomainUsers
User has access to printer
MCM\DomainUsers
User has access to printer
MCM\admin
User has access to printer
MCM\admin
User has access to printer
BUILTIN\Administrators
User has access to printer
BUILTIN\Administrators
User has access to printer
I already made security login that if failed 3 times the program will be terminated. However, I want to make a security login that will lock the system and the admin will be required to login instead.
Here's my code:
Dim nCnt As Integer
Dim nCnt2 As String
Private Sub cmdOk_Click()
nUsername = "username ='" & txtUsername.Text & "'"
npassword = txtPassword.Text
If nCnt < 2 Then
With adoLog.Recordset
.MoveFirst
.Find nUsername
If .EOF Then
MsgBox "Access Denied" & vbCrLf & "Please try again." & vbCrLf & vbCrLf & "Warning: You only have " & nCnt2 & " attempt.", vbCritical, "Terror"""
nCnt = nCnt + 1
nCnt2 = nCnt2 - 1
Label7.Caption = nCnt2
txtUsername.Text = ""
txtPassword.Text = ""
txtUsername.SetFocus
Else
If adoLog.Recordset.Fields("password").Value = npassword And adoLog.Recordset.Fields("flag").Value = 1 Then
Call Change_Flag
MsgBox "Access Granted"
cUser = adoLog.Recordset.Fields("name").Value
cPosition = adoLog.Recordset.Fields("position").Value
With adoHistory_Login.Recordset
.AddNew
.Fields("name").Value = cUser
.Fields("position").Value = cPosition
.Fields("time_login").Value = Time()
.Fields("date_login").Value = Date
.Fields("date_logout").Value = Date
.Update
Me.Refresh
frmMain.Show
frmMain.SetFocus
End With
Unload Me
txtUsername.Text = ""
txtPassword.Text = ""
Else
MsgBox "Access Denied" & vbCrLf & "Please try again." & vbCrLf & vbCrLf & "Warning: You only have " & nCnt2 & " attempt.", vbCritical, "Terror"""
nCnt = nCnt + 1
nCnt2 = nCnt2 - 1
Label7.Caption = nCnt2
txtUsername.Text = ""
txtPassword.Text = ""
txtUsername.SetFocus
End If
End If
End With
Else
Call block
End
End If
End Sub
Private Sub Change_Flag()
With adoLog.Recordset
.Fields("flag").Value = 0
End With
End Sub
Private Sub block()
MsgBox "You already used all attempt." & vbCrLf & "This will terminate the application.", vbCritical, "Terror"
End Sub
Private Sub Form_Initialize()
cmdOK.Enabled = False
txtPassword.Enabled = False
cmdRegister.Visible = False
If adoLog.Recordset.RecordCount <> 0 Then
cmdOK.Enabled = False
txtPassword.Enabled = False
txtUsername.Enabled = True
Else
cmdRegister.Visible = True
txtUsername.Enabled = False
End If
End Sub
Private Sub Form_Load()
nCnt2 = 2
Label7.Caption = nCnt2
End Sub
You will need to store an additional flag somewhere to indicate that login is denied and then check this flag before attempting the login. You will also need to store the account type and check to see if the account is allowed to log in even if this flag is set.
Are you wanting to lock out the full PC or the username that is being used?
Add a new column to the recordset for IsLocked and have it get set to true after the 3 logins (Make sure you provide some way for the admin to clear it back out though).
As soon as the username is used check IsLocked first before the password and kick it out immediately with the appropriate message.
Also, make sure you prevent the IsLocked from ever being set on the admin username.