Open jasoncmcg opened 2 years ago
Trying to come back to this one, I wanted to see what GPT-4 had to say about it. Ultimately, it tried to recommend Python... However, I will continue to stay with Go and try to solve the issue. (This all runs from a Linux machine.)
...this approach requires a good understanding of the security descriptor format and manual manipulation of the binary data. You will need a package to help you work with security descriptors.
Here's a high-level outline of the steps you should follow:
Please note that this approach is more complex and error-prone than using a package or library that supports the required interfaces (IADsSecurityDescriptor, IADsAccessControlList, IADsAccessControlEntry). If possible, I recommend using a package that supports these interfaces to reduce complexity and the risk of errors...
The definition: HRESULT SetUserCannotChangePassword(LPCWSTR pwszUserDN, LPCWSTR pwszUsername, LPCWSTR pwszPassword, BOOL fCannotChangePassword) on this page: https://learn.microsoft.com/en-us/windows/win32/adsi/modifying-user-cannot-change-password-ldap-provider?redirectedfrom=MSDN
I tried to convert this to a Go function, but it is apparently too complex of a process for a GPT-4 to be able to convert. The closest I could come to usable information was to use this package: https://pkg.go.dev/golang.org/x/sys/windows#pkg-overview
Meanwhile, it appears to not be possible within the constraints.
@jasoncmcg
This may not be exactly within the scope of what you were hoping to do, but I recently came across this issue while looking to see if parsing/modifying the SDDL string for ntSecurityDescriptor was possible using this library. After determining that it wasn't part of this library, I took the time to create a library that can parse and write the binary SDDL format, so that modifying ACLs should be possible using a library such as go-ldap.
The library is here: https://github.com/huner2/go-sddlparse
@jasoncmcg
This may not be exactly within the scope of what you were hoping to do, but I recently came across this issue while looking to see if parsing/modifying the SDDL string for ntSecurityDescriptor was possible using this library. After determining that it wasn't part of this library, I took the time to create a library that can parse and write the binary SDDL format, so that modifying ACLs should be possible using a library such as go-ldap.
The library is here: https://github.com/huner2/go-sddlparse
I somehow missed this and have come back because I need to use this for something else. I appreciate it and will take a look.
Any progress on this?
TL;DR
How do I update
PASSWD_CANT_CHANGE
in the security descriptor discretionary access control list to set theADS_ACETYPE_ACCESS_DENIED_OBJECT
ace type in theIADsAccessControlEntry
?My Best Guess
My best guess is that I can use the ldap control to do something, but I cannot find any reference for it.
controls := []ldap.Control{}
Details
When activating an account, the following will activate with
DONT_EXPIRE_PASSWORD
andNORMAL_ACCOUNT
. However, attempting to use0x0040
forPASSWD_CANT_CHANGE
has no effect.According to this page reference: Note You cannot assign this permission by directly modifying the UserAccountControl attribute. For information about how to set the permission programmatically, see the "Property flag descriptions" section.
The above redirection leads to this page, where it lists the following steps to update this option.
IADsSecurityDescriptor
object from thentSecurityDescriptor
property of the user object.IADsAccessControlList
interface for the security descriptor from theIADsSecurityDescriptor.DiscretionaryAcl
property.IADsAccessControlEntry
.Trustee property. 5.Modify theIADsAccessControlEntry.AceType
property of the ACEs that were found toADS_ACETYPE_ACCESS_DENIED_OBJECT
if the user cannot change their password orADS_ACETYPE_ACCESS_ALLOWED_OBJECT
if the user can change their password.IADsAccessControlEntry
object that contains the property values shown in the table below and add the new entry to the ACL with theIADsAccessControlList.AddAce
method.IADsAccessControlEntry
object with the same property values shown in the table below except the Trustee property contains the account name for SID "S-1-5-10" ("NT AUTHORITY\SELF"). Add the entry to the ACL with theIADsAccessControlList.AddAce
method.ntSecurityDescriptor
property of the object, call the IADs.Put method with the sameIADsSecurityDescriptor
obtained in Step 2.GetNamedSecurityInfo
function with the LDAP ADsPath of the object and then theSetNamedSecurityInfo
function with the same DACL. This reordering will occur automatically when the ACEs are added.More information here with examples on this setting for
ADS_ACETYPE_ACCESS_DENIED_OBJECT