views:

293

answers:

4

I am using a WCF service to expose certain Active Directory management functions to our help desk staff without giving them the group membership required to manipulate AD directly. Adding users to and removing users from groups is working like a champ with existing users, but every time I create a new user it throws back this fun code:

The server is unwilling to process the request. (Exception from HRESULT: 0x80072035)

The code I use to add the user to the group is

    public bool AddGroupToUser(string userDn, string groupDn)
    {
        try
        {
            DirectoryEntry groupEntry = LdapTools.GetDirectoryEntry(groupDn);
            groupEntry.Properties["member"].Add(userDn);
            groupEntry.CommitChanges();
            groupEntry.Close();
            return true;
        }
        catch (DirectoryServicesCOMException)
        {
            return false;
        }
    }

Everything I've read on the subject is rather vague and I can't seem to find out WHY the exception is being triggered. Any ideas?

UPDATE

This is the code I use to create the user in AD:

        try
        {
            DirectoryEntry container = GetDirectoryEntry(storageOu);
            DirectoryEntry newUser = container.Children.Add("CN=" + employee.FullName, "user");
            newUser.Properties["sAMAccountName"].Value = employee.Username;
            newUser.Properties["displayName"].Value = employee.FullName;
            newUser.Properties["givenName"].Value = employee.FirstName;
            newUser.Properties["sn"].Value = employee.LastName;
            newUser.Properties["department"].Value = departmentName;
            newUser.Properties["userPrincipalName"].Value = employee.Username + "@APEX.Local";
            newUser.CommitChanges();

            newUser.Invoke("SetPassword", new object[] { employee.Password });
            newUser.CommitChanges();

            AdsUserFlags userSettings = AdsUserFlags.NormalAccount;
            newUser.Properties["userAccountControl"].Value = userSettings;
            newUser.CommitChanges();

            ldapPath = newUser.Path;

            newUser.Close();
            container.Close();
        }
        catch (DirectoryServicesCOMException e)
        {
            // Something went wrong... what???
        }
        catch (Exception e)
        {
            // Something else went wrong
        }

The new user can login, and can be manipulated using the standard MS tools.

A: 

Try:

 public bool  AddUserToGroup(string userName, string groupName)

        {

            bool done = false;

            GroupPrincipal group = GroupPrincipal.FindByIdentity(context, groupName);

            if (group == null)

            {

                group = new GroupPrincipal(context, groupName);

            }

            UserPrincipal user = UserPrincipal.FindByIdentity(context, userName);

            if (user != null & group != null)

            {

                group.Members.Add(user);

                group.Save();

                done = (user.IsMemberOf(group));

            }

            return done;

        }

Reference:
http://www.c-sharpcorner.com/UploadFile/dhananjaycoder/activedirectoryoperations11132009113015AM/activedirectoryoperations.aspx

JeremySpouken
of course, this only works on .NET 3.5 and up.
marc_s
A: 

As it mentioned in here, can you tell us that you set the password of the newly created users? In the reference, it says that you should SetPassword of the user before doing anything with it.

Melih Öztürk
You can also check out the accepted soluiton in http://www.experts-exchange.com/Programming/Misc/Q_21962620.html
Melih Öztürk
Check out the code update I added to the question, I added my user creation code to it.
thaBadDawg
I use the same code on my company except that my user's userAccountControl property has also "Password Does not expire" value. (ActiveDs.ADS_USER_FLAG.ADS_UF_DONT_EXPIRE_PASSWD) Can you try to set this value too?
Melih Öztürk
+1  A: 

Apparently, unless I'm missing an important step here, the issue is time. When forcing the system to sleep for 8 seconds before attempting to add groups to the new user the process works. If I do it any sooner than the 8 second mark it fails.

I'm marking this answer as correct unless anybody can provide me a better solution.

thaBadDawg
I don't think the DirectoryEntry primitives are guaranteed to use the same AD binding internally, so it's entirely possible you manipulate the group on a different domain controller than the one you added the user to (AD uses a multimaster replication model). The amount of time it takes for replication to complete will depend on the number of domain controllers, the setting which determines how long to wait before notifying peers of a change and the volume of AD transactions. In a large domain I have seen AD take upwards of 5 minutes to fully replicate an SPN, so be careful with 8 seconds.
Alex Peck
I've written a wrapper around DirectoryEntry aimed at solving the problem of not knowing what domain controller I'm connecting to. I connect to the same DC every time now and it still doesn't recognize the DirectoryEntry on subsequent calls before the 8 second time period has passed. Luckily, for now at least, I only have to worry about two DCs. Heaven help me if we ever start adding a DC per location.Do you know of a way to find out when the SPN has been fully replicated?
thaBadDawg
A: 

Time issue could occur from a Active Directory replication issue.

Once, I gave a product to my customer which creates user over Active Directory, which has over 10.000 records in it, with the given informations on a SharePoint form and then program adds the user to a SharePoint group. The problem was, SharePoint throws an error about the newly created user, it says user does not exist in AD.

So, one of out system engineer told us about the replication opearation on the Active Directory that it could be the source of the problem and it was true.

For the solution, program tries to do the job for 10 times with 1 second sleeps. No problem occurred so far. So as a solution, I would suggest you to check out the AD for the existence of replication method.

P.S: When I asked questions to my customers system engineers about the replication operation, they all rejected the existence of AD replication operation and told me that the program has the problem. They believed me when we created a new user in AD from a computer, we couldn't see the user for 5 seconds on an another computer.

Melih Öztürk