$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
Previously I discussed IDirectoryObject, today I will show how to change a user’s password with IDirectoryObject.
I didn’t find any documentation except a kb article describing how to use pure ldap to do it. Of course I could have used IADsUser::SetPassword but I decided not to because of the following reasons:
All example code I found was .NET based using the .NET wrappers for Active Directory and seemed to be meant for use in Adam rather than full Active Directory (it set port number to 389 and password mode to cleartext).
In the end it’s not very difficult but nonetheless it took me a while before I got it right.
We can write to the unicodePwd attribute which wants the password as a double quoted unicode string. If you look at this attribute with AdsiEdit you’ll see that the type is Octet String and that it can be written only.
I was tricked with Delphi’s QuotedStr function for a while because it doesn’t return a double but single quoted string 😉
Below a small snippet from the upcoming JwsclActiveDirectory that shows how to use it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | procedure TJwAdUser.SetPassword(const Value: TJwString); var AdValue: ADSVALUE; AdAttrInfo: ADS_ATTR_INFO; TempPwd: TJwString; DirObjIntf: IDirectoryObject; Count: DWORD; hr: HRESULT; begin { To set the password we need a secure bind to the Domain Controller, this is possible from win2000 sp5 and higher } hr := ADsOpenObject(PWideChar(FPathName), nil, nil, ADS_USE_SIGNING or ADS_USE_SEALING or ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, Pointer(DirObjIntf)); if failed(hr) then raise EJwsclAdNoInterfaceException.CreateFmtEx( 'Interface %s not obtained', 'SetPassword', ClassName, 'JwsclActiveDirectory', 0, hr, ['IID_IDirectoryObject']); { we can set the password through the unicodePwd attribute. } AdAttrInfo.pszAttrName := 'unicodePwd'; AdAttrInfo.dwControlCode := ADS_ATTR_UPDATE; AdAttrInfo.pADsValues := @AdValue; AdAttrInfo.dwNumValues := 1; { the password needs to be within a double quoted string } TempPwd := AnsiQuotedStr(Value, '"'); { unicodePwd is of type Octet String } AdValue.dwType := ADSTYPE_OCTET_STRING; AdValue.OctetString.dwLength := Length(TempPwd) * sizeof(TempPwd[1]); AdValue.OctetString.lpValue := @TempPwd[1]; { set the password } hr := DirObjIntf.SetObjectAttributes(@AdAttrInfo, 1, Count); { don't keep the password in memory... } SecureZeroMemory(@TempPwd[1], Length(TempPwd) * sizeof(TempPwd[1])); DirObjIntf := nil; if failed(hr) then raise EJwsclAdSetPropertyException.CreateFmtEx( 'SetObjectAttributes failed to set %s', 'SetPassword', ClassName, 'JwsclActiveDirectory', 0, hr, [AdAttrInfo.pszAttrName]); end; |
2 Responses for "Random Active Directory Notes #4"
Hi Remko,
I was just wondering how JwsclActiveDirectory is going? I’m keen to use it in a program I’m writing to dynamically add/remove users to groups, based on which computer they use to log into the Terminal Server.
Cheers,
Alex
I too am keen to use this, but i can’t get it to compile.
There seems to be lots of dependencies missing. I am new to JEDI. Is there a step by step guide on where all the files should be placed?
I have added \WIN32API folder to my search path, but then i notice that it needs \WIN32API\jwaWindows folder as well. So i added this, then it complains that it cant find JwaWinDLLNames.pas… and it goes on.
Leave a reply