MK-2 Posted March 2, 2010 Posted March 2, 2010 (edited) I'm sure this is easy, I'm just having a bad day! I want a laptop, connected via wireless to our network, but not joined the domain, to be able to bring up a box that will ask for user/password and then authenticate that against our AD. I know it can be done with IsMember, but will it work with machines not joined to the domain, only picking up its DHCP etc. **edit - probably helps when i type the problem out right too!!** i want it to authenticate the user and check they are a member of a certain group, hence me mentioning ismember if anyone has any script i can use that will let me check a user aganist a certain group that would be great. ta Edited March 2, 2010 by MK-2 me not learning to type properly!
dayzd Posted March 2, 2010 Posted March 2, 2010 The following is something a colleague of mine left behind when he moved on to bigger and better things a couple of years ago. It's from a small web-app he built to change users' passwords, so you'll need to disassemble it a little bit, but it should get you moving in the right direction (hopefully). Function SelectUser(strUserName) 'This function takes no inputs. 'It returns the LDAP address of the user, their forename & surname & their home path in the form of a string ("LDAP|FNAME SNAME|HOMEPATH"). 'It returns false if the user cancels the function, or "Failed" if the user cannot be found. dim objUser, strLDAP, objConnection, objCommand, objRecordSet if strUserName = "" then strUserName = InputBox("Please enter the username to change the password on (e.g. 1234bloggs)." & vbCrLf & "It does not matter if you user upper or lower case." & vbCrLf & "Be warned that only the first result will be returned!","Enter User Name") end if if strUserName = "" then SelectUser = false: exit function 'Cancel pressed 'These next few lines connect to the AD and set up various query variables. Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Provider" Set objCommand.ActiveConnection = objConnection objCommand.Properties("Searchscope") = 2 'full AD Search 'Find the user objCommand.CommandText = "SELECT ADSPath, givenName, sn, homeDirectory FROM 'LDAP://dc=DOMAIN,dc=internal' WHERE objectCategory='user' AND Name='" & strUserName & "*'" Set objRecordSet = objCommand.Execute if objRecordSet.BOF and objRecordSet.EOF then 'Checks for no results. SelectUser = "Failed" else SelectUser = objRecordSet.Fields("ADSPath") & "|" & objRecordSet.Fields("givenName") & " " & objRecordSet.Fields("sn") & "|" & objRecordSet.Fields("homeDirectory") end if end function (Mike, if you're reading this, hope you don't mind me passing this on!)
MK-2 Posted March 2, 2010 Author Posted March 2, 2010 thanks for that. i'll have a read through in a minute. the only problem i can foresee is that the app will be run on machines not joined to the domain at all. so i need a way of it verifying against LDAP even though it isn't on the domain. so if you were to put in user "test" it would have to know to look at domain xxxx for user test. i think i might just leave it until tomorrow when i'll be a bit fresher!!
dayzd Posted March 2, 2010 Posted March 2, 2010 I've run PHP scripts on a non-domain webserver that behave properly when pointed to our DC. They did include the dns name, as well as the domain name, so you may need to change the one line with the search parameters a little bit: objCommand.CommandText = "SELECT ADSPath, givenName, sn, homeDirectory FROM 'LDAP://dc=SERVERNAME,dc=DOMAIN,dc=SUFFIX' WHERE objectCategory='user' AND Name='" & strUserName & "*'" This (ldap:// servername.domain.internal) has worked for me from PHP, so I'd say there's a fair chance it'll work for you. 1
MK-2 Posted March 3, 2010 Author Posted March 3, 2010 thanks to abullett the remote auth is working, its now just the group check thing. this is the code ive got that i cant tell if its working or not, or if i have it the wrong way around, etc. strUserPath = "LDAP://dc=server1,dc=derbyhigh,dc=internal" & objSysInfo.UserName Set objUser = GetObject(strUserPath) ' Test for membership in the group. Set objGroup = GetObject("LDAP://cn=Year13,ou=Main Site,ou=DHS,ou=Establishments,dc=derbyhigh,dc=internal") If (objGroup.IsMember(strUserPath) = True) Then WshNetwork.MapNetworkDrive "N:","\\dhs-sr-001\" & strUserName & "$" i want it to check if the username entered is a member of the Year13 security group, then process the mapnetworkdrive command if they are, or fail if not
srochford Posted March 3, 2010 Posted March 3, 2010 I might just be being stupid, but I can't see a check for password on any of the scripts so far - ie I say I'm user jbloggs and it just accepts that! The script below takes user, password and group on the command line (eg checkpassword.vbs /user:jbloggs /password:ReallyReallySecret /group:year13) and does stuff if username and password are correct and user is in the group. I've tried to add helpful comments but shout if it's not clear! sUser=wscript.arguments.named("user") sPassword=wscript.arguments.named("password") sGroup=wscript.arguments.named("group") Const ADS_NAME_INITTYPE_GC = 3 Const ADS_NAME_TYPE_1779 = 1 Const ADS_NAME_TYPE_NT4 = 3 set rootDSE=GetObject("LDAP://rootDSE") 'get the DNS name of the domain - eg dc=ic,dc=ac,dc=uk sDNS=rootdse.get("defaultNamingContext") 'now find the NETBIOS name of the domain so we can do \user later on Set oTrans = CreateObject("NameTranslate") oTrans.Init ADS_NAME_INITTYPE_GC, "" oTrans.Set ADS_NAME_TYPE_1779, sDNS sDomain = oTrans.Get(ADS_NAME_TYPE_NT4) 'find the distinguished name of this user 'function will query LDAP anonymously - quits if the user is not there sDN1=getdn(sUser,"", "",true) if sDN1="N/A" then wscript.echo "Can't find user" wscript.quit end if 'now we know the user exists; is the password they gave us valid? 'carry out the same query but this time connect to the domain using the password sDN2=getdn(sUser,sPassword,sDomain,false) if sDN1<>sDN2 then 'password is not valid wscript.echo "Wrong password" wscript.quit end if 'username and password are valid; is the user in the group 'bind to user object set oUser=getobject("LDAP://" & sDN2) 'assume user is not in group bInGroup=false for each oGroup in oUser.groups 'check for each group - make lcase just to avoid problems with case if lcase(oGroup.samaccountname)=lcase(sGroup) then bInGroup=True exit for end if next 'process appropriately for in/out of group if bInGroup then wscript.echo "In group, mapping drives" else wscript.echo "Not in group " & sGroup wscript.quit end if function getDN(sNTName,sPassword,sDomain,bAnon) 'kludgy but saves unwanted errors on error resume next sResult="N/A" sBase="" 'set up connection to Active Direcotry set oCommand=createobject("adodb.command") sAttributes = "distinguishedName" Set oConn = CreateObject("ADODB.Connection") oConn.Provider = "ADsDSOObject" 'are we doing anon bind? if not bAnon then oConn.Properties("User ID") = sDomain & sUser oConn.Properties("Password") = sPassword end if oConn.Open oCommand.ActiveConnection = oConn set oRS=createobject("adodb.recordset") sFilter = "(samaccountname=" & sNTName & ")" 'query built here has domain name; filter based on username; only attribute needed is distinguished name and subtree means search whole directory sQuery = sBase & ";" & sFilter & ";" & sAttributes & ";subtree" oCommand.CommandText = sQuery Set oRS = oCommand.Execute 'will be EOF if not found if ors.eof then sresult="N/A" else sResult=ors("distinguishedname") end if ors.close 'return either N/A for not found or error (eg bad password) and distinguished name otherwise getDN=sResult on error goto 0 end function
MK-2 Posted March 4, 2010 Author Posted March 4, 2010 (edited) Steve: Thanks for that, I'll take a look through later. Will it work on a machine off the domain? As in a laptop connected via wireless to the network, but not actually a member of the domain (such as students laptops). that is the major downfall im having, making it authenticate on a domain it is not part of. sorry if it already does! **edit** just tested and i get the error i have been getting with mine: the specified domain either does not exist or could not be contacted (line 9) Edited March 4, 2010 by MK-2
srochford Posted March 4, 2010 Posted March 4, 2010 OK; plan B :-) Original idea was to make the script universal so that nothing had to be changed, it would run on any network. Trouble is you can't do that easily (if at all!) - you can't find the current domain name if you're not a domain member (which is kind of obvious and I'd guess I just didn't have enough coffee yesterday). This script needs 3 changes in the lines at the beginning. The first is the name of your domain, the second is the Netbios name of the domain (the bit that shows in the drop down when you go to log on) and the third the name of a domain controller. sDNS="dc=ic,dc=ac,dc=uk" sDomain = "IC" sDC="ICADS2" sUser=wscript.arguments.named("user") sPassword=wscript.arguments.named("password") sGroup=wscript.arguments.named("group") const ADS_SECURE_AUTHENTICATION = 1 const ADS_SERVER_BIND= 512 'find the distinguished name of this user 'will return N/A for either no user or wrong password sDN=getdn(sUser,sPassword,sDomain) if sDN="N/A" then wscript.echo "Can't find user" wscript.quit end if 'username and password are valid; is the user in the group 'bind to user object set oLDAP=getobject("LDAP:") set oUser=oLDAP.opendsobject("LDAP://" & sDC & "/" & sDN,sDomain & "\" & sUser,sPassword, ADS_SECURE_AUTHENTICATION + ADS_SERVER_BIND) 'assume user is not in group bInGroup=false for each oGroup in oUser.groups 'check for each group - make lcase just to avoid problems with case if lcase(oGroup.samaccountname)=lcase(sGroup) then bInGroup=True exit for end if next 'process appropriately for in/out of group if bInGroup then wscript.echo "In group, mapping drives" else wscript.echo "Not in group " & sGroup wscript.quit end if function getDN(sNTName,sPassword,sDomain) 'kludgy but saves unwanted errors on error resume next sResult="N/A" sBase="" 'set up connection to Active Direcotry set oCommand=createobject("adodb.command") sAttributes = "distinguishedName" Set oConn = CreateObject("ADODB.Connection") oConn.Provider = "ADsDSOObject" oConn.Properties("User ID") = sDomain & "\" & sUser oConn.Properties("Password") = sPassword oConn.Open oCommand.ActiveConnection = oConn set oRS=createobject("adodb.recordset") sFilter = "(samaccountname=" & sNTName & ")" 'query built here has domain name; filter based on username; only attribute needed is distinguished name and subtree means search whole directory sQuery = sBase & ";" & sFilter & ";" & sAttributes & ";subtree" oCommand.CommandText = sQuery Set oRS = oCommand.Execute 'will be EOF if not found if ors.eof then sresult="N/A" else sResult=ors("distinguishedname") end if ors.close 'return either N/A for not found or error (eg bad password) and distinguished name otherwise getDN=sResult on error goto 0 end function
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now