Re: Checking "Reset Password" Extended Attribute in AD
From: Joe Richards [MVP] (humorexpress_at_hotmail.com)
Date: 10/16/04
- Previous message: Craig: "Re: Cert Stores"
- In reply to: Dave Mills: "Checking "Reset Password" Extended Attribute in AD"
- Next in thread: Dave Mills: "Re: Checking "Reset Password" Extended Attribute in AD"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Sat, 16 Oct 2004 11:02:45 -0400
I haven't ever used this function so I am just guessing. BTW, I looked through
the MSDN docs, they pretty much suck for these functions, they need some
examples. Oh, I also don't do NET but tried to work through what you are doing
anyway...
First off
> Dim gUSER As New Guid("bf967aba-0de6-11d0-a285-00aa00000000")
> '00aa003049e2
>
I expect so, but do you know that GUID isn't correct, the part you remmed out
top replace with 0's is correct.
dn:CN=User,CN=Schema,CN=Configuration,DC=joe,DC=com
>schemaIDGUID: {BF967ABA-0DE6-11D0-A285-00AA003049E2}
Other than that what I would try in your shoes is to not put the Reset Password
GUID into the property level of OBJECT_TYPE_LIST, I would put it into the
property set level. It isn't a property, it is a special CA access right which
is closer to being a property set than a property. In fact it is maintained in
with the property sets.
Now I am going to see if I contact someone on how "light" those docs are on MSDN.
joe
--
Joe Richards Microsoft MVP Windows Server Directory Services
www.joeware.net
Dave Mills wrote:
> I'm writing a web page which certain users will be able to use to reset
> student passwords, without needing the "Users and Computers" MMC page.
>
> I need to be able to check if the user which IIS is currently
> impersonating has the right to reset a given user's password - my
> instinct told me to go with the "AccessCheckByType" API function - I
> have managed to get the impersonated user's token, and the security
> descriptor from the User in active directory - I call AccessCheckByType
> and it returns success however it is not returning the correct results
> in status.
>
> Am I even correct in thinking AccessCheckByType is the correct function
> to use??
>
> Cheers
>
> Dave
>
> Code below:
>
> Dim result As Integer 'for return codes!!#
> Dim lasterror As Integer
>
> Dim deCurriculum As New
> DirectoryServices.DirectoryEntry("LDAP://student.spacollege.ac.uk",
> "student\Administrator", "monkey") 'where you want to look for the
> account
> Dim obj As Object = deCurriculum.NativeObject
> Dim dsSrch As New DirectorySearcher(deCurriculum)
> Dim strUsername As String = txtUsername.Text
> dsSrch.Filter = "(&(objectClass=user)(sAMAccountName=" & strUsername &
> "))"
>
> Dim srUser As SearchResult = dsSrch.FindOne()
> If srUser Is Nothing Then Throw New Exception("UserNotFound")
> Dim deUser As DirectoryEntry = srUser.GetDirectoryEntry()
>
> 'get some user details
> lblUsername.Text = CType(deUser.Properties("sAMAccountName").Value,
> String)
> lblFirstName.Text = CType(deUser.Properties("givenName").Value, String)
> lblSurname.Text = CType(deUser.Properties("sn").Value, String)
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'Setup SID
>
> 'Get SID from DirectoryEntry
> Dim bytearraySID() As Byte = deUser.Properties("objectSid").Value()
> Dim pSID As IntPtr = Marshal.AllocHGlobal(bytearraySID.Length)
> Marshal.Copy(bytearraySID, 0, pSID, bytearraySID.Length)
> result = IsValidSid(pSID) 'check SID is valid (sanity check!)
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'Get the binary security descriptor from deUser
>
> 'force the property into the property cache
> Dim aProperties() = {"NTSecurityDescriptor"}
> deUser.Invoke("GetInfoEx", New Object() {aProperties, 0})
>
> Dim pv2SecDesc As ActiveDs.IADsPropertyValue2 =
> deUser.Invoke("GetPropertyItem", New Object() {"NTSecurityDescriptor",
> 26}).Values(0)
> Dim bytearraySecDesc() As Byte = pv2SecDesc.GetObjectProperty(8) '8 = as
> byte array
> 'Dim sdSecDesc As ActiveDs.IADsSecurityDescriptor =
> pv2SecDesc.GetObjectProperty(26)
> Dim pSelfRelativeSecDesc As IntPtr =
> Marshal.AllocHGlobal(bytearraySecDesc.Length)
> 'copy security descriptor to memory location
> Marshal.Copy(bytearraySecDesc, 0, pSelfRelativeSecDesc,
> bytearraySecDesc.Length)
>
> 'setup some variables for conversion from self-relative to absolute
> format
> Dim AbsoluteSecDesc As SECURITY_DESCRIPTOR
> Dim dwAbsoluteSecDescSize As Integer
> Dim pDacl As IntPtr
> Dim dwDaclSize As Integer
> Dim pSacl As IntPtr
> Dim dwSaclSize As Integer
> Dim pOwner As IntPtr
> Dim dwOwnerSize As Integer
> Dim pPrimaryGroup As IntPtr
> Dim dwPrimaryGroupSize As Integer
>
> dwAbsoluteSecDescSize = Marshal.SizeOf(AbsoluteSecDesc)
> 'find out the sizes of the memory to allocate
> MakeAbsoluteSD(pSelfRelativeSecDesc, AbsoluteSecDesc,
> dwAbsoluteSecDescSize, pDacl, dwDaclSize, pSacl, dwSaclSize, _
> pOwner, dwOwnerSize, pPrimaryGroup, dwPrimaryGroupSize)
> pDacl = Marshal.AllocHGlobal(dwDaclSize)
> pSacl = Marshal.AllocHGlobal(dwSaclSize)
> pOwner = Marshal.AllocHGlobal(dwOwnerSize)
> pPrimaryGroup = Marshal.AllocHGlobal(dwPrimaryGroupSize)
> 'convert self-relative security descriptor to absolute format
> MakeAbsoluteSD(pSelfRelativeSecDesc, AbsoluteSecDesc,
> dwAbsoluteSecDescSize, pDacl, dwDaclSize, pSacl, dwSaclSize, _
> pOwner, dwOwnerSize, pPrimaryGroup, dwPrimaryGroupSize)
> 'deallocate as not needed any more
> Marshal.FreeHGlobal(pSelfRelativeSecDesc)
>
> result = IsValidSecurityDescriptor(AbsoluteSecDesc) 'check absolute
> security descriptor is valid (sanity check!)
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'Get Impersonated User's token
>
> 'ImpersonateSelf(SecurityImpersonation) 'not needed as IIS is already
> impersonating authenticated user
>
> Dim strImpersonatedUser As String =
> System.Threading.Thread.CurrentPrincipal.Identity.Name 'just out of
> interest!!
>
> Dim token As Integer
> result = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, False, token)
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'Setup OBJECT_TYPE_LIST array
>
> 'Setup GUIDs
> Dim gRESETPASSWORD As New Guid("00299570-246d-11d0-a768-00aa006e0529")
> Dim pResetPasswordGuid As IntPtr =
> Marshal.AllocHGlobal(gRESETPASSWORD.ToByteArray().Length)
> Marshal.Copy(gRESETPASSWORD.ToByteArray(), 0, pResetPasswordGuid,
> gRESETPASSWORD.ToByteArray().Length)
>
> Dim gUSER As New Guid("bf967aba-0de6-11d0-a285-00aa00000000")
> '00aa003049e2
> Dim pUserGuid As IntPtr =
> Marshal.AllocHGlobal(gUSER.ToByteArray().Length)
> Marshal.Copy(gUSER.ToByteArray(), 0, pUserGuid,
> gUSER.ToByteArray().Length)
>
> Dim gNULL As New Guid
> Dim pNullGuid As IntPtr =
> Marshal.AllocHGlobal(gNULL.ToByteArray().Length)
> Marshal.Copy(gNULL.ToByteArray(), 0, pNullGuid,
> gNULL.ToByteArray().Length)
>
> Dim ObjectTypeList(0) As OBJECT_TYPE_LIST
> Dim ObjectTypeListLength As Integer = 0
>
> ObjectTypeList(0).Level = 0
> ObjectTypeList(0).Sbz = 0
> ObjectTypeList(0).ObjectType = pUserGuid
>
> 'ObjectTypeList(1).Level = 1
> 'ObjectTypeList(1).Sbz = 0
> 'ObjectTypeList(1).ObjectType = pNullGuid
>
> 'ObjectTypeList(2).Level = 2
> 'ObjectTypeList(2).Sbz = 0
> 'ObjectTypeList(2).ObjectType = pResetPasswordGuid
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'Check extended right
>
> Dim DesiredAccess As Integer = ADS_RIGHT_DS_CONTROL_ACCESS
>
> Dim GenMap As GENERIC_MAPPING
> GenMap.GenericRead = 0
> GenMap.GenericWrite = 0
> GenMap.GenericExecute = 0
> GenMap.GenericAll = 0
> MapGenericMask(DesiredAccess, GenMap)
>
> Dim pPrivilegeSet As IntPtr = IntPtr.Zero
> Dim PrivilegeSetLength As Integer = 0
>
> Dim GrantedAccess As Integer
> Dim Status As Integer
>
> 'calculate size of PriviledgeSet
> result = AccessCheckByType(AbsoluteSecDesc, pSID, token, DesiredAccess,
> ObjectTypeList, ObjectTypeListLength, _
> GenMap, pPrivilegeSet, PrivilegeSetLength, GrantedAccess, Status)
> pPrivilegeSet = Marshal.AllocHGlobal(PrivilegeSetLength)
> 'Check Access
> result = AccessCheckByType(AbsoluteSecDesc, pSID, token, DesiredAccess,
> ObjectTypeList, ObjectTypeListLength, _
> GenMap, pPrivilegeSet, PrivilegeSetLength, GrantedAccess, Status)
> lasterror = Err.LastDllError
>
> '---------------------------------------------------------------------------------------------------------------------------------'
> 'DeAllocate memory - todo integrate with exception handling
>
> Marshal.FreeHGlobal(pDacl)
> Marshal.FreeHGlobal(pSacl)
> Marshal.FreeHGlobal(pOwner)
> Marshal.FreeHGlobal(pPrimaryGroup)
>
> Marshal.FreeHGlobal(pSID)
>
> Marshal.FreeHGlobal(pResetPasswordGuid)
> Marshal.FreeHGlobal(pUserGuid)
> Marshal.FreeHGlobal(pNullGuid)
>
> Marshal.FreeHGlobal(pPrivilegeSet)
>
- Previous message: Craig: "Re: Cert Stores"
- In reply to: Dave Mills: "Checking "Reset Password" Extended Attribute in AD"
- Next in thread: Dave Mills: "Re: Checking "Reset Password" Extended Attribute in AD"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|