wodzu
wodzu

Reputation: 3172

Moving user entry to another container entry in Active Directory: "there is a naming violation"

I'm having trouble moving a user entry from one container entry to another

using (var newParent = GetEntry(destination, Configuration.ServerAddress, Configuration.UserName, Configuration.Password))
{
    _entry.MoveTo(newParent);
}

...

public static DirectoryEntry GetEntry(Guid guid, string serverAddress, string userName, string password)
{
    try
    {
        var id = guid.ToString().Replace("}", "").Replace("{", "");
        return new DirectoryEntry(String.Format("{0}<GUID={1}>", serverAddress, id), userName, password);
    }

    catch (Exception e)
    {
        if (e.HResult != Searcher.ENTRY_NOT_FOUND)
            throw new DirectoryServiceException(e);
    }
    return null;
}

The _entry ('user@****.com') has to be moved to its destination 'container@****.com'. Since I'm using the System.DirectoryServices namespace, both are of type DirectoryEntry.

enter image description here

But on calling the MoveTo() method there occurs a DirectoryServicesCOMException, which contains following information:

Message: There is a naming violation.
ExtendedErrorMessage: 00000057: LdapErr: DSID-0C090A8E, comment: Error in attribute conversion operation, data 0, v1db1
HResult -2147016649

Anyone any idea on what could cause this exception?

Upvotes: 0

Views: 2074

Answers (2)

wodzu
wodzu

Reputation: 3172

Turned out, that the Path property must not contain the entry's GUID. Since I used the GUID to retreive the entry from AD it looked like:

LDAP://<domain>/<GUID=9908d4c1-0438-4d23-8828-f5876166c84f>

To make it work, you have make sure, the path looks like this:

LDAP://<domain>/[email protected],CN=UnitTestContainer,DC=<domain>

I don't know why it behaves like that. Probably the path is needed for some internal processing... If anyone knows a way to make it work with GUIDs, please let me know.

Upvotes: 3

Justin C
Justin C

Reputation: 777

I know this is an older thread, but thought I'd add my recent experience here as I just ran into this limitation.

Wodzu's assumption about "Probably the path is needed for some internal processing" is correct.

The following article mentions a hint:

Using objectGUID to Bind to an Object

Per the above link: "The following IADsContainer methods are not supported by objects obtained by binding using the object GUID:". This includes "MoveHere". The code example here is C++ so it may not be obvious "why" this is until we consider how System.DirectoryServices works.

This hint combined with an excellent directory services programming guide (cited below) gives us a better picture - this book mentions IADsContainer.MoveHere is used "under the hood" by MoveTo().

You can see this for yourself by viewing the source code for .NET. Here's an example path of where to look if you clone the repo (any 4.x version will be very similar here):

corefx-master\src\System.DirectoryServices\src\System\DirectoryServices\DirectoryEntry.cs

enter image description here

Book: Kaplan, Joe; Dunn, Ryan. The .NET Develper's Guide to Directory Services Programming (Kindle Location 1719). Pearson Education. Kindle Edition.

Upvotes: 2

Related Questions