We have many domains in the same forest (i.e. sw.main.company.com, nw.main.company.com, main.company.com) and I have control of an OU in sw.main.company.com where I have set up a Universal Active Directory Group.
I have no difficulty pragmatically (c#) adding "sw" domain users to the group using System.DirectoryServices.AccountManagement .NET 4.5 etc. on the default AD port, but when it comes to adding users from the other domains (nw, mw, etc.), I get "HResult=-2147016651 Message=The server is unwilling to process the request" and "Operation not allowed through GC port, data 0, v1db1" when setting the new PrincipalContext(ContextType.Domain "sw.main.company.com:3268", "DC=main,DC=company,DC=com").
All of the Domain Controllers are also Global Catalog servers and invoking port 3268 allows the users from the other domains to resolve correctly, but I cannot commit the additions using the GlobalPrincipal.Save() command without throwing the error.
I have included the relevant code below as well as the detailed error stack. I need help with this.
public void SyncADUsers()
{
AddUserToGroup("MW\\abc123user", "Universal_Group_1");
}
public void AddUserToGroup(string userId, string groupName)
{
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "sw.main.company.com:3268", "DC=main,DC=company,DC=com"))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName);
group.Members.Add(pc, IdentityType.SamAccountName, userId);
group.Save();
}
}
catch (System.DirectoryServices.DirectoryServicesCOMException E)
{
//doSomething with E.Message.ToString();
}
}
System.InvalidOperationException was unhandled HResult=-2146233079 Message=The server is unwilling to process the request. Source=System.DirectoryServices.AccountManagement StackTrace: at System.DirectoryServices.AccountManagement.ADStoreCtx.UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes) at System.DirectoryServices.AccountManagement.SDSUtils.ApplyChangesToDirectory(Principal p, StoreCtx storeCtx, GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes) at System.DirectoryServices.AccountManagement.ADStoreCtx.Update(Principal p) at System.DirectoryServices.AccountManagement.Principal.Save() at ExampleUsers.SyncAD.AddUserToGroup(String userId, String groupName) in c:\SourceControl\ExampleUsers\ExampleUsers\SyncAD.cs:line 33 at ExampleUsers.SyncAD.SyncADUsers() in c:\SourceControl\ExampleUsers\ExampleUsers\SyncAD.cs:line 18 at ExampleUsers.Program.Main(String[] args) in c:\SourceControl\ExampleUsers\ExampleUsers\Program.cs:line 62 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: System.DirectoryServices.DirectoryServicesCOMException HResult=-2147016651 Message=The server is unwilling to process the request. Source=System.DirectoryServices ErrorCode=-2147016651 ExtendedError=8245 ExtendedErrorMessage=00002035: LdapErr: DSID-0C090B3E, comment: Operation not allowed through GC port, data 0, v1db1 StackTrace: at System.DirectoryServices.DirectoryEntry.CommitChanges() at System.DirectoryServices.AccountManagement.ADStoreCtx.UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes) InnerException:
In reference to BaldPate's response, if the Global Catalog is read only, we need to read and resolve users in different domains using the 3268 port and then SAVE the users using the 389 port all in the same context. This can be accomplished with the following code (note the separate calls to the 3268 and default 389 ports) and thanks to BaldPate for making this clear: