Re: Checking "Reset Password" Extended Attribute in AD

From: Joe Richards [MVP] (humorexpress_at_hotmail.com)
Date: 10/16/04

  • Next message: Dave Mills: "Re: Checking "Reset Password" Extended Attribute in AD"
    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)
    > 
    

  • Next message: Dave Mills: "Re: Checking "Reset Password" Extended Attribute in AD"

    Relevant Pages

    • VirtualAllocEx returns a bad pointer in some processes
      ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
      (microsoft.public.vc.mfc)
    • Virtual memory C++ problem
      ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
      (microsoft.public.win32.programmer.kernel)
    • Re: MapiSendMail and web browser
      ... Public Shared Function SendMail(ByVal strAttachmentFileName As String, ... Dim winhandle As IntPtr = New IntPtr ... Public Class MapiMessage ...
      (microsoft.public.win32.programmer.messaging)
    • Re: FTP
      ... Dim dwFileAttributes As Integer ... Public cAlternate As String ... > public int dwHighDateTime; ... > public static extern IntPtr InternetConnect( ...
      (microsoft.public.dotnet.languages.vb)
    • Help with Marshaling an Array of Pointers from COM to Managed Objects
      ... Dim pDesktop As IntPtr ... Dim pidlRecyclebin As IntPtr ... ByRef pceltFetched As IntPtr) As UInt32 ... 'Requests a pointer to an interface that allows a client to enumerate ...
      (microsoft.public.dotnet.framework.interop)