Jump to content

Active Directory UDF


water
 Share

Recommended Posts

  • 2 weeks later...

Apologies if this isn't the right place for it - but I think it's the right place to ask questions about how things work (wiki didn't seem appropriate).

I'm using the AD UDF (stable) for a VPN login/drive mapping GUI/script that runs on both domain PCs as well as home PCs (love it btw, does an AWESOME job) - and we had a strange error which I've just finally managed to track down, and I wanted to bring it to your attention. The problem we were having is some of our home users would immediately get locked accounts when they tried to run our script. It was consistent for each user, they either had the issue or did not. It ended up being that their home PC username exactly matched their work username (e.g. at home they're jsmith, at work they're jsmith).

In breaking down and digging into it, I found that even if you specify the first 5 parameters (user, pass, domain, host, config), _AD_Open still attempts to 'test' certain things without the user parameter. This was compounded (for us) by the fact that we use some role accounts to do things like check password age, expiration, and whether a username is valid. and always close the connection and open a new one each time. In short, _AD_Open was being called 3 times (and doing LDAP binds without the specified credentials, using ObjGet() ), and this locked their account before the script was finished.

I've fixed it for our scenario, by simply commenting out the chunk where the RootDSE's are attempted, and explicitly re-setting the $sAD_DNSDomain / $sAD_HostServer / $sAD_Configuration to their parameter values afterwards, but I wanted to pass it on back both as feedback and a heads up to anyone running into a similar problem. Also, I hate butchering even my own local copy of such a useful UDF, and wouldn't want to be removing anything important for other functions I might use down the road.

If a non-domain machine uses this library, and the account name of the local user running it exactly match an account name on your domain, they will cause a failed login attempt every time _AD_Open is called. I don't know what the behavior would be if you had a domain machine in another domain w/ a similar account name match, as I haven't dug through the nested IF statements, but that might be worth poking at as well.

I'm of course available for any more information, details, etc.

Cheers,

-Martin

Link to comment
Share on other sites

Martin,

thank you very much for this heads up! This thread is the perfect place to discuss the UDFs functionality!

The _AD_Open function is one of the most complex of the UDF. What you see now is the result of a very, very long discussion about how to connect to AD. The RooDSE's are the result of the latest change. This change was necessary because the previous version didn't use the bind cache and therefore started a new connection for every LDAP command which lead to undesired results (even to the server rejecting connection attempts).

I have to admit that I'm not very familiar with all this connection stuff and very few information can be found by Google. It's more of a trial & error thing.

I'm always willing to improve the UDF but changes in this area need thorough testing.

Unfortunately I have no test AD available and the production AD environment is read only for me. So the testing has to be done by the AutoIt community.

If you can provide your changed _AD_Open function I will be happy to check it and do some testing here as far as possible.

Thanks a lot for taking the time to track the error and to let me know about it!

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

My modified one wasn't useful for the general populous, as I was just skipping the If/ElseIf/Else block of ObjGet("LDAP://" RootDSE pieces. I spent some time yesterday trying to look at it ways to make those calls use the provided credentials, but there doesn't seem to be a way to do it without switching to OpenDSObject - I couldn't find a way to force it to bind anonymously nor with specific credentials. I know it does bind anonymously after the initial failed attempt (all rolled into the single ObjGet call, handled by the COM object), but I don't know how to force it to not try to bind with the current user.. It looks like the oAD_RootDSE object is used in other places, so seeing as I don't use those pieces, I didn't want to cram in my potential solution on top of the existing code without understanding things more fully.

So - the best solution to this would be to have a way to force the provided credentials into the RootDSE query. The documentation I find on Microsofts site says that the RootDSE by default is the only component that will allow an anonymous bind, and indeed the anonymous bind does work after it fails with the local user bind. Can you point me at any documentation you came across for the COM object that's being called by ObjGet("LDAP://RootDSE") so I can see if there isn't a way to override things there? The OpenDSObject has bindflags which we could force an anonymous bind on, I need to find an equivalent for the ObjGet, if such a thing exists.

If it doesn't, I don't know that a general purpose solution for this corner case (non-domain machines, and possibly any machines querying a foreign domain, w/ matched account names) will be able to be made without rewriting all the pieces that rely on RootDSE (and then the simplest case of _AD_Open - ObjGet("LDAP://RootDSE") and populating DNSDomain/HostServer/Configuration would have to be complicated by doing that and then creating the DSObject which other parts of hte code would be relying on.

Anyway, I fear I'm rambling so I'll finish up - I wasn't able to find anything for anonymous binds in the LDAP RFC's / URL scheme other than 'bindname', which is an optional component, and attempts to tack it on just threw errors (though, admittedly, I was mostly shooting in the dark). If there is more useful documentation on the COM object that ObjGet creates, I can determine whether it's possible to get this issue corrected for my less common instance, without a messy massive performance hit for the trivial cases.

The pieces I'm testing only require read access, but to track/replicate the error you'd need a non-domain machine (or, again, possibly an off-domain machine) w/ a matched user login name on both systems. The trickier bit, though, is you would also require the ability to see login failures and/or unlock accounts. If you have only readonly locally, then even if you were able to bring a non-domain machine on-network, you'd still be subject to your lockout/timeout period for testing any fix, which would likely drive you insane long before they came near a solution. You'd be able to test a final solution if/when I arrive at one, but it wouldn't be practical for you to try fixing it.

Link to comment
Share on other sites

I see you have put some time in investigating this problem :)

I have to admint that I'm not very familiar with the stuff that happens in _AD_Open (most of the code has been taken from the original UDF written by Jonathan Clelland). What I would try is to replace "ObjGet" with __AD_ObjGet and give it a try.

This function uses the credentials if provided.

If it works for you we would have to test for any negative results for other users. If it works fine for everyone it could become a part of the next version of the UDF.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

do _AD_UnJoinDomain and _AD_JoinDomain work in win7? i have been trying to get it working but no luck. keep getting error 0

_AD_Open()

        If Not @error Then
            ConsoleWrite("leaving..." & @CRLF)
            $leave = _AD_UnJoinDomain(@ComputerName, "WORKGROUP", @ComputerName & "administrator", "password")
        EndIf

        _AD_Close()

        If $leave <> @error Then
            $prompt = MsgBox($msg_prompt, $script_name, "Domain has been unjoined." & @CRLF & _
                    @CRLF & _
                    "Restart?")

            If $prompt = 6 Then
                Shutdown(2, "Domain Unjoin")
            EndIf
        Else
            MsgBox(0, "", @error)
        EndIf
Link to comment
Share on other sites

The error checking needs to be changed:

_AD_Open()

If Not @error Then
    ConsoleWrite("leaving..." & @CRLF)
    $leave = _AD_UnJoinDomain(@ComputerName, "WORKGROUP", @ComputerName & "administrator", "password")
    $iError = @error
EndIf

_AD_Close()

If $iError = 0 Then
    $prompt = MsgBox($msg_prompt, $script_name, "Domain has been unjoined." & @CRLF & @CRLF & Restart?")
    If $prompt = 6 Then
        Shutdown(2, "Domain Unjoin")
     EndIf
Else
    MsgBox(0, "", @error)
EndIf

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

  • 1 month later...

Experimental Version 1.2.2.0 has been released.

For testing purpose only!

Needs 3.3.9.2 beta for the new way the UDF handles COM errors!

For download please see my signature.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

  • 2 weeks later...

Hi water. Thanks for this UDF. I have been making good use of it.

I do have a qustion though. Does it have the ability to poll the ACL?

I noticed that a few years back you had asked a I am trying to automate our annual security audits (I lost count of how many trees and how many hours I wastfully killed this year), and need to list all users that have access to any particular share/folder, and list what group, if any, is giving them that access. I can code the shell to recurse through shares/folders on each server easily enough, but getting the ACL data is what I am missing. Are there functions for this in your UDF, or did you ever find a solution for yourself?

Thanks in advance for your help.

Link to comment
Share on other sites

Unfortunately there is no direct connection between AD and the ACLs set on a fileserver. AD only gives you the groups and the accounts being members of this group.

I have written a to combine the output of DumpSec/DumpACL and the Active Directory.

But unfortunately this tool uses the old ADfunctions UDF and - I have to admit - is poorly written.

Maybe it is a starting point for what you need.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Link to comment
Share on other sites

I hope the script works for you or is at least a good starting point. It's quite old and I would write a better script today!

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Minor tweaks to make it run with the current version of AI, but it will give me a launching point. I'll post the utility in a new thread for everyone once I get it working.

We bought an auditing tool last year, but it still required WAY too much manual effort to get the reports we wanted.

Thanks again for the help.

Link to comment
Share on other sites

I'm glad this ugly beast was useful to you! I really hate to look at code I have written only a few years ago.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Func _Adupdate()
GUISetState(@SW_HIDE, $MainGUI)
_AD_Open()
Local $newOU = $newTOU ; =======> Change this when moving domains OU=?, OU=?, DC=?, DC=?
Local $sTitle = "Active Directory Update"
#Region ### START Koda GUI section ### Form=
Local $hMain = GUICreate("sTitle", 413, 619, -1, -1)
GUICtrlCreateLabel("Move Computer To Selected OU And Auto Update Description In AD", 8, 2, 559, 21)
GUICtrlSetFont(-1, 9, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
Local $IObject = GUICtrlCreateInput(_AD_SamAccountNameToFQDN(@ComputerName & "$"), 8, 30, 559, 21)
GUICtrlSetState($IObject, $GUI_HIDE)
GUICtrlCreateLabel("Name Of Computer Being Moved And Updated:", 8, 99, 231, 21)
Local $ComputerToMove = GUICtrlCreateLabel(@ComputerName, 250, 99, 116, 21)
GUICtrlSetFont(-1, 9, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlCreateLabel("Move The Above Computer To The Below Selected Organizational", 8, 132, 343, 21)
Local $Group1 = GUICtrlCreateGroup("Select Your Theatre Of Operation", 8, 24, 393, 65)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
Local $USARadio = GUICtrlCreateRadio("USA", 16, 56, 81, 17)
Local $AfricaRadio = GUICtrlCreateRadio("Africa", 246, 56, 65, 17)
Local $hTree = GUICtrlCreateTreeView(6, 154, 400, 300, -1, $WS_EX_CLIENTEDGE)
GUICtrlSetTip(-1, "Ensure you select the correct OU")
Local $bExit = GUICtrlCreateButton("Close", 5, 534, 400, 64)
GUICtrlSetImage(-1, "shell32.dll", 28)
Local $BOK = GUICtrlCreateButton("Move And Update", 5, 464, 400, 64)
GUICtrlSetTip(-1, "Once pressed, the computer will be moved to the selected OU" & @CRLF & _
"and the computer description auto populated into Active Directory.", "", 0, 1)
GUICtrlSetImage(-1, "shell32.dll", -89)
GUICtrlSetColor(-1, 0xC0C0C0)
GUICtrlCreateGroup("", -99, -99, 1, 1)
;Local $aTreeView = _AD_GetOUTreeView($newOU, $hTree)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

If BitAND(GUICtrlRead($USARadio), $GUI_CHECKED) Then
$newTOU = ("OU=USA,DC=Domain,DC=com")
EndIf
If BitAND(GUICtrlRead($AfricaRadio), $GUI_CHECKED) Then
$newTOU = ("OU=Africa,DC=Domain,DC=com")
EndIf
Local $aTreeView = _AD_GetOUTreeView($newOU, $hTree)

Hi Water

I'm trying to restrict what is visable in the OU tree by using radio button in my GUI

Depending on which radio is selected depends on which OU's are visable for selection.

If I insert Local $newOU = ("OU=USA,DC=Domain,DC=com")

it works, so it must be my attempt at getting it to read the info somewhere or I'm totally way off.

Days have now past with no forward motion. hence this post.

Any assistance will be most welcome.

Edited by Iceman682
Link to comment
Share on other sites

I am on vacation right now and will answer your question when I return by the end of september.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

I defenitely will! I'm sitting in Casablanca right now and will enjoy Marocco for 11 more days!

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

  • 2 weeks later...

I'm trying to use _AD_MoveObject , but I have no idea what you mean by FQDN for the OU. I've dried the Canonical Name: domain.invalid/Test/OU as well as the Distinguished name: OU=OU,OU=Test,DC=domain,DC=invalid but it seems both methods throw an error of 1... How do I specify the OU I want to move my Object to?

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...