locked
Having trouble with Active Directory Code when used from within CRM 2013 RRS feed

  • 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