Asked by:
Having trouble with Active Directory Code when used from within CRM 2013

Question
-
Hello. I am working on code to create Active Directory users programmatically, and I'm running in to a strange issue. The code works correctly when run directly on the AD box, but when run from within CRM 2013 the UserPrincipalName doesn't work. My first issue is that when I use email addresses whose domains are already registered on our UDN, the UPN I'm trying to create doesn't map to the pre-existing udn entry but instead creates a duplicate entry on our UDN list. See http://i.imgur.com/Cif5aed.png for what I'm talking about. The second issue is that the users I create with the code below can't log in using the UPN, only the samAccountName. I've spent a few weeks trying to figure this issue out with no luck. Any help here would be appreciated.
try { string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath var adminUsername = ConfigurationHelper.GetConfigSettingByName(orgservice, "ADPasswordReset.AdminUsername", unsecureConfig, secureConfig); var adminPassword = ConfigurationHelper.GetConfigSettingByName(orgservice, "ADPasswordReset.AdminPassword", unsecureConfig, secureConfig); if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true) { throw new Exception("A User with that name already exists."); } DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUsername, adminPassword, AuthenticationTypes.Secure); DirectoryEntry newUser; string cn = firstName + " " + lastName; newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list. newUser.Properties["displayName"].Value = cn; newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName);//userName; newUser.Properties["userPrincipalName"].Value = checkUserName(userName); newUser.Properties["givenName"].Value = firstName; //Firstname newUser.Properties["sn"].Value = lastName; //Lastname? -Surname newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account. newUser.CommitChanges(); oGUID = newUser.Guid.ToString(); //Must be handled after the previous stuff. Unsure why. newUser.Invoke("SetPassword", new object[] { userPassword }); newUser.CommitChanges(); //For some reason, can't be handled before the password is set? newUser.Properties["userAccountControl"].Value = 0x0200; //0x0200 newUser.CommitChanges(); dirEntry.Close(); newUser.Close(); } public static string checkUserName(string userName) { if (!userName.Contains("@")) { return userName + "@example.local"; } return userName; } public static string getSAMNameFromUserName(string domainUserName) { int stop; string s = domainUserName; if (s.Contains("@")) { stop = s.IndexOf("@"); return (stop > -1) ? s.Substring(0, stop) : string.Empty; } return domainUserName;// string.Empty; }
Thursday, July 16, 2015 8:59 PM
All replies
-
I forgot to attach the error logs I've been getting:
Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 15 |Category: Application |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: d3d98a7e-c760-4113-81b0-e4d1588b939b | ActiveDirectoryUtility.FindUser ilOffset = 0x230
>Unable to find user bsmalcorn@example.com under the AD root path
[2015-07-13 10:40:03.072] Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 15 |Category: Application |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 34d92be8-52cc-4eb6-a091-b22f7e361e7e | ActiveDirectoryUtility.GetDomainPath ilOffset = 0x0
>Unable to get DNS name of domain xxxxxxxxxx: System.Net.Sockets.SocketException (0x80004005): No such host is known
> at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)
> at System.Net.Dns.GetHostEntry(String hostNameOrAddress)
> at Microsoft.Crm.Application.Utility.ActiveDirectoryUtility.GetDomainPath(String netBiosName)
[2015-07-13 10:43:17.228] Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 15 |Category: Application |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 3f5a3b51-375a-4b49-9b2f-885aeaed64f2 | ActiveDirectoryUtility.FindUser ilOffset = 0x230
>Unable to find user bsmalcorn@example.com under the AD root path
[2015-07-13 10:43:17.524] Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 53 |Category: Exception |User: 7560f48b-a8da-4d0c-bb01-33bd2db4023c |Level: Error |ReqId: 47405ce9-c790-4d60-a06f-c4a2d7b4280a | CrmException..ctor ilOffset = 0x0
at CrmException..ctor(String message, Exception innerException, Int32 errorCode, Boolean isFlowControlException) ilOffset = 0x0
at CrmException..ctor(String message, Int32 errorCode) ilOffset = 0x0
at SecurityUtils.GetSidFromAccount(String accountName) ilOffset = 0x34
at SecurityUtils.GetUserId(String domainName, Boolean limitGlobalCatalogSearches) ilOffset = 0x2C
at UserManagementFactory.GetActiveDirectoryInformation(String domainName, Boolean limitGlobalCatalogSearches) ilOffset = 0x1C
at UserManagementFactory.CheckForActiveDirectoryUser(String uniqueName, UserValidationParameters userValidationParameters, ExecutionContext context, Boolean limitGlobalCatalogSearches) ilOffset = 0x20
at UserManagementFactory.ValidateFederationUser(String domainName, ExecutionContext context) ilOffset = 0x66
at UserManagementFactory.UpdateDomainName(IBusinessEntity systemUser, BusinessProcessObject systemUserService, Guid oldActiveDirectoryId, Boolean usersAlreadyInConfigDatabase, Boolean provisioning, ExecutionContext context) ilOffset = 0xC7
at UserManagementFactory.UpdateUser(IBusinessEntity systemUser, IBusinessEntity newSystemUser, BusinessProcessObject systemUserService, Boolean usersAlreadyInConfigDB, Boolean provisioning, ExecutionContext context) ilOffset = 0x191
at SystemUserServiceInternal`1.HandleAccessModeChangePreUpdate(IBusinessEntity systemUser, Boolean usersAlreadyInConfigDB, BusinessEntity retrieveUser, Int32 accessMode, Int32 newAccessMode, ExecutionContext context, Boolean isStubUserRename) ilOffset = 0x1B9
at SystemUserServiceInternal`1.UpdateInternal(IBusinessEntity systemUser, Boolean usersAlreadyInConfigDB, ExecutionContext context, Boolean isStubUserRename) ilOffset = 0x332
at SystemUserServiceInternal`1.Update(IBusinessEntity systemUser, Boolean usersAlreadyInConfigDB, ExecutionContext context) ilOffset = 0x0
at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) ilOffset = 0xFFFFFFFF
at RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) ilOffset = 0x25
at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) ilOffset = 0x84
at LogicalMethodInfo.Invoke(Object target, Object[] values) ilOffset = 0x4F
at InternalOperationPlugin.Execute(IServiceProvider serviceProvider) ilOffset = 0x57
at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context) ilOffset = 0x200
at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) ilOffset = 0x65
at Pipeline.Execute(PipelineExecutionContext context) ilOffset = 0x65
at MessageProcessor.Execute(PipelineExecutionContext context) ilOffset = 0x1C5
at InternalMessageDispatcher.Execute(PipelineExecutionContext context) ilOffset = 0xE4
at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion) ilOffset = 0x16E
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode) ilOffset = 0x1F1
at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode) ilOffset = 0x23
at OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode) ilOffset = 0x26
at InprocessServiceProxy.ExecuteCore(OrganizationRequest request) ilOffset = 0x34
at PlatformCommand.XrmExecuteInternal() ilOffset = 0xF6
at UpdateCommand.Execute() ilOffset = 0x7
at DataSource.Update(EntityProxy entity, Boolean performDuplicateCheck, Guid auditingTransactionId, IOrganizationContext context) ilOffset = 0x10
at EntityProxy.Update(Boolean performDuplicateCheck, Guid auditingTransactionId) ilOffset = 0x0
at EntityProxy.Update(Boolean performDuplicateCheck) ilOffset = 0x0
at EntityProxy.UpdateAndRetrieve(String[] columnSet, Boolean performDuplicateCheck) ilOffset = 0x0
at CommandBase.UpdateEntity(Entity entity, Boolean retrieve) ilOffset = 0xD1
at SaveCommand.ExecuteCommand(String commandXml) ilOffset = 0x116
at CommandBase.Execute(String commandXml) ilOffset = 0x13
at InlineEditWebService.Execute(Int32 command, String commandXml) ilOffset = 0xD0
at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) ilOffset = 0xFFFFFFFF
at RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) ilOffset = 0x25
at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) ilOffset = 0x84
at LogicalMethodInfo.Invoke(Object target, Object[] values) ilOffset = 0x4F
at WebServiceHandler.Invoke() ilOffset = 0xC3
at WebServiceHandler.CoreProcessRequest() ilOffset = 0x13E
at SyncSessionlessHandler.ProcessRequest(HttpContext context) ilOffset = 0x39
at HandlerWrapper.ProcessRequest(HttpContext context) ilOffset = 0x0
at CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() ilOffset = 0x18D
at HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) ilOffset = 0x15
at ApplicationStepManager.ResumeSteps(Exception error) ilOffset = 0x10A
at HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) ilOffset = 0x5C
at HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) ilOffset = 0x16A
at ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType) ilOffset = 0x4B
>Crm Exception: Message: LookupAccountNameW failed with error, ErrorCode: -2147214038
[2015-07-13 10:43:17.540] Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 53 |Category: ADUtility |User: 7560f48b-a8da-4d0c-bb01-33bd2db4023c |Level: Error |ReqId: 47405ce9-c790-4d60-a06f-c4a2d7b4280a | SecurityUtils.GetSidFromAccount ilOffset = 0x35
>Error while retrieving SID from account bsmalcorn@example.com. Exception: Microsoft.Crm.CrmSecurityException: LookupAccountNameW failed with error
at Microsoft.Crm.SecurityUtils.GetSidFromAccount(String accountName)
[2015-07-13 10:43:17.540] Process: w3wp |Organization:32164c37-b869-e411-93f3-00155d543a19 |Thread: 53 |Category: ADUtility |User: 7560f48b-a8da-4d0c-bb01-33bd2db4023c |Level: Error |ReqId: 47405ce9-c790-4d60-a06f-c4a2d7b4280a | SecurityUtils.GetUserId ilOffset = 0x2C
>Error while retrieving userId. Exception: Microsoft.Crm.CrmSecurityException: LookupAccountNameW failed with error
at Microsoft.Crm.SecurityUtils.GetSidFromAccount(String accountName)
at Microsoft.Crm.SecurityUtils.GetUserId(String domainName, Boolean limitGlobalCatalogSearches)
Thursday, July 16, 2015 9:01 PM -
Good afternoon. I've tried some additional things and none of them seemed to help so I'm hoping somebody whose read this may have some ideas? Thank you.Monday, July 20, 2015 8:34 PM
-
For anybody who comes across this thread in the future, the problem was that something during the AD creation was appending whitespace to my username and domain. So instead of "example.com" it was saving the domain as "example.com " (notice the whitespace at the end?). I .Trim()'d everything and it appears to be working just fine. :)Tuesday, July 21, 2015 9:03 PM