Constraint Violation When Creating AD User Object with account management extension class attributes

10.4k views Asked by At

I'm creating a WCF service to retrieve and update/create AD Person objects, and have run into a snag. I created an extension class to manage extended attributes (delivered schema attributes, but not in the default account management class attribute set). I have no problem retrieving or updating these extended attributes, but when I try to create a new person object in AD, I receive a constraint violation

System.DirectoryServices.DirectoryServicesCOMException: A constraint violation occurred.

I'm currently testing this in debug mode in Visio 2013 on a Windows 8.1 desktop. Code below. Any hints or insight anyone can offer is most appreciated.

Hopefully the code below is documented well enough and makes sense. Thanks in advance!

Update: I should have been more clear. The reason I am pretty sure it is the extension attributes is when I comment out those lines in the calling code (now commented in code section below) that set those attributes it will create the object without errors.

This is my calling code:

....other code.....

PrincipalContext pc = null;

try {
    pc = new PrincipalContext(ContextType.Domain, MyProject.ADAccountService.Properties.Settings.Default.Domain, MyProject.ADAccountService.Properties.Settings.Default.PeopleDN, MyProject.ADAccountService.Properties.Settings.Default.AdminAcct, MyProject.ADAccountService.Properties.Settings.Default.AdminPW);
}
catch (Exception e) {
    defaultLogger.Warn(MyProject.ADAccountService.App_GlobalResources.Messages.PrincipalContextCreateFail, e);
    // Application.Exit();
}

....other code looking for whether ADObject already exists...

// Create the new UserPrincipal object
if (!newADPerson.personExists) {
    using (ADeXt userNew = new ADeXt(pc)) {

        string randomPassword = System.Web.Security.Membership.GeneratePassword(20, 4);
        if (newADPerson.officePhone != null && newADPerson.officePhone.Length > 0) { userNew.VoiceTelephoneNumber = newADPerson.officePhone; }
        if (newADPerson.department != null && newADPerson.department.Length > 0) { userNew.department = newADPerson.department; } //offending codeline
        if (newADPerson.title != null && newADPerson.title.Length > 0) { userNew.title = newADPerson.title; } //offending codeline
        if (newADPerson.faxNumber != null && newADPerson.faxNumber.Length > 0) { userNew.facsimileTelephoneNumber = newADPerson.faxNumber; } //offending codeline
        if (newADPerson.officeLocation != null && newADPerson.officeLocation.Length > 0) { userNew.physicalDeliveryOfficeName = newADPerson.officeLocation; } //offending codeline
        if (newADPerson.isEmployee) {
            //if an employee and (newADPerson.script == null) use default value from global project settings
            userNew.ScriptPath = newADPerson.script ?? MyProject.ADAccountService.Properties.Settings.Default.defaultScript;
        }

        if (newADPerson.lastName != null && newADPerson.lastName.Length > 0) { userNew.Surname = newADPerson.lastName; }
        if (newADPerson.firstName != null && newADPerson.firstName.Length > 0) { userNew.GivenName = newADPerson.firstName; }
        if (newADPerson.emplID != null) { userNew.EmployeeId = newADPerson.emplID; }
        if (newADPerson.displayName != null && newADPerson.displayName.Length > 0) { userNew.DisplayName = newADPerson.displayName; }

        userNew.SamAccountName = AccountID;
        userNew.Name = AccountID;
        userNew.UserPrincipalName = AccountID + MyProject.ADAccountService.Properties.Settings.Default.ExchangeAddress;

        try {
            userNew.Save();
            userNew.SetPassword(randomPassword);
        }
        catch (Exception e) {

            pc.Dispose();
        }
    }
}

Extension class code:

namespace MyProject.ADAccountService.Classes {
    [DirectoryObjectClass("user")]
    [DirectoryRdnPrefix("CN")]
    class ADeXt : UserPrincipal {
        public ADeXt(PrincipalContext context)
            : base(context) {
        }

        public ADeXt(
            PrincipalContext context,
string Container, //new constructor parameter added resolving issue
            string samAccountName,
            string password,
            bool enabled
            )
            : base(
               context,
               samAccountName,
               password,
               enabled
               ) {
        }

        public static new ADeXt FindByIdentity(PrincipalContext context, string identityValue) {

            return (ADeXt)FindByIdentityWithType(context, typeof(ADeXt), identityValue);
        }

        [DirectoryProperty("physicalDeliveryOfficeName")]
        public string physicalDeliveryOfficeName {
            get {
                object[] result = this.ExtensionGet("physicalDeliveryOfficeName");
                if (result != null) {
                    return (string)result[0];
                }
                else {
                    return null;
                }
            }
            set {
                this.ExtensionSet("physicalDeliveryOfficeName", value);
            }
        }

        [DirectoryProperty("department")]
        public string department {
            get {
                object[] result = this.ExtensionGet("department");
                if (result != null) {
                    return (string)result[0];
                }
                else {
                    return null;
                }
            }
            set {
                this.ExtensionSet("department", value);
            }
        }

        [DirectoryProperty("title")]
        public string title {
            get {
                object[] result = this.ExtensionGet("title");
                if (result != null) {
                    return (string)result[0];
                }
                else {
                    return null;
                }
            }
            set {
                this.ExtensionSet("title", value);
            }
        }

        [DirectoryProperty("facsimileTelephoneNumber")]
        public string facsimileTelephoneNumber {
            get {
                object[] result = this.ExtensionGet("facsimileTelephoneNumber");
                if (result != null) {
                    return (string)result[0];
                }
                else {
                    return null;
                }
            }
            set {
                this.ExtensionSet("facsimileTelephoneNumber", value);
            }
        }
    }
}    
2

There are 2 answers

0
Jeff On

Thanks Marc, that hint helped me solve. added new parameter for the container in the extension constructor and that did the trick.

Changed the constructor in the extension class to add the default container. New constructor now lists like this:

public ADeXt(
    PrincipalContext context,
    **string Container,**
    string samAccountName,
    string password,
    bool enabled
    )
    : base(
       context,
       samAccountName,
       password,
       enabled
       ) {
}
0
Bernard Moeskops On

For anyone looking into this error. It could mean a lot of things, the first Google results will show that it has something to do with the PDC Emulator or replicating.

In my case it was due to too many characters for the employeeID (16 max). Sometimes it is initials (6 max) or samAccountName (19 max). Just peel of fields until it works as a starting point.