PRB: ADSI / MoveHere Cannot Move CNs Across Value Partitions on Membership Server

ID: Q216209


The information in this article applies to:


SYMPTOMS

The MoveHere ADSI call fails when it is used to move (rename) a CN in a membership directory. A network sniff of the LDAP traffic between the client and LDAP server shows the LDAP server returning the following error:

LDAP_UNWILLING_TO_PERFORM


CAUSE

MoveHere cannot move objects from one value partition to another unless it is from the ou=AnonymousUsers to the ou=Members container.


RESOLUTION

To work around this problem, it is necessary to create a new user, copy over the old user attributes, and delete the old user. The following code can be used for this purpose. It is important to note, however, that this code does not take non-inherited Access Control Entries (ACEs) and group membership into account. So you must apply your own code to migrate group membership and non-inhertied ACEs to the newly created object.


Private Sub MoveAUser()
    On Error GoTo errorHandler
    
    Dim oDS
    Dim oADsContainer
    Dim oADsNewUser
    Dim oADsOldUser
    Dim oADsOldUserSchema
    Dim oGuidGen
    Dim strGuid
    Dim strLdapPath
    Dim strFromUserCn
    Dim strToUserCn


    'The path to the ou=Members container
    strLdapPath = "LDAP://myserver:389/ou=Members,o=Microsoft"
    'The old user
    strFromUserCn = "cn=NewTest3"
    'The new user
    strToUserCn = "cn=NewTest4"
    
    'Bind to the container in which the Member will be created
    Set ds = GetObject("LDAP:")
    Set oADsContainer = ds.OpenDSObject(strLdapPath, _
        "cn=Administrator,ou=Members,o=Microsoft", "password", 0)
    
    'Bind to the old user and schema
    Set oADsOldUser = oADsContainer.GetObject("member", strFromUserCn)
    Set oADsOldUserSchema = GetObject(oADsOldUser.Schema)
    
    'Create the new user object, note that the Create() method
    'returns an interface pointer
    
    Set oADsNewUser = oADsContainer.Create("member", strToUserCn)
    
    On Error GoTo 0 ' in case an attribute is not set
    
    For Each UserProp In oADsOldUserSchema.MandatoryProperties
    ' ingnore cn and objectclass
        If ((UserProp <> "cn") And UserProp <> "objectClass") Then
            oADsNewUser.Put UserProp, oADsOldUser.Get(UserProp)
        End If
    Next
    
    For Each UserProp In oADsOldUserSchema.OptionalProperties
        oADsNewUser.Put UserProp, oADsOldUser.Get(UserProp)
    Next
    
    On Error GoTo errorHandler
    
    oADsNewUser.SetInfo
    
    'Destroy the old user and schema
    Set oADsOldUserSchema = Nothing
    Set oADsOldUser = Nothing
    oADsContainer.Delete "member", fromUser
    
    'Destroy the objects
    Set oDS = Nothing
    Set oGuidGen = Nothing
    Set oADsNewUser = Nothing
    Set oADsContainer = Nothing
    
    Exit Sub
    
errorHandler:
    MsgBox "Error is " & Err.Description
End Sub 


STATUS

This behavior is by design.


MORE INFORMATION

Steps to Reproduce Behavior

To reproduce this behavior, call MoveHere to rename a member in a value partitioned database:

    Dim oADs
    Dim strLdapPath
    Dim strFromUserDn
    Dim strToUserDn
    
    strLdapPath = "LDAP://myserver:389/o=Microsoft/ou=Members"
    strFromUserDn = _
        "LDAP://myserver:389/cn=TestUser1,ou=Members,o=Microsoft"
    strToUserDn = "cn=Testuser2"
    
    Set oADs = GetObject("LDAP:")
    Set oADs = oADs.OpenDSObject(strLdapPath, _
        "cn=Administrator,ou=Members,o=Microsoft", "password", 0)
    
    oADs.MoveHere strFromUserDn, strToUserDn 

Additional query words:


Keywords          : 
Version           : winnt:3.0
Platform          : winnt 
Issue type        : kbprb 

Last Reviewed: February 19, 1999