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



The information in this article applies to:

  • Microsoft Site Server 3.0

This article was previously published under Q216209

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-inherited 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
				

Modification Type:MajorLast Reviewed:6/11/2002
Keywords:kbDSupport kbprb KB216209