Thursday, February 3, 2011

Some or all identity references could not be translated

Sometimes working with Active Directory can be a real pain in the butt. In the on demand virtual desktop solution I’m working on, a user sign-up action results in an AD user object and a user profile folder created on a file server with folder permissions customized to work with that user. The sign-up process takes place through a web interface, which in turn communicates with a web service that performs the necessary AD and file system operations. The problem I was running into was that after I created the AD user object and started in on the user profile directory setup, I would get an IdentityNotMappedException. The code went something like this:
   1: DirectorySecurity dirSec = Directory.GetAccessControl("user directory here");
   2: NTAccount ntAccount = new NTAccount("domain username here");
   3: dirSec.SetOwner(ntAccount);

The exception occurs at line 3. So, upon further investigation, we concluded that because the web server might be talking to a different AD controller than the file server, replication might not be happening fast enough. So to fix the problem, I started using the SID of the newly created user. Here’s a snippet:

   1: using (PrincipalContext principalContext = new PrincipalContext(/* Domain info here */))
   2: {
   3:     string username = "some username";
   4:  
   5:     // Create the new user
   6:     UserPrincipal userPrincipal = new UserPrincipal(principalContext);
   7:     userPrincipal.DisplayName = "First Last";
   8:     userPrincipal.GivenName = "First"
   9:     userPrincipal.Surname = "Last"
  10:     userPrincipal.EmailAddress = "Email"
  11:     userPrincipal.Enabled = true;
  12:     userPrincipal.Name = username;
  13:     // sAMAccountName can only be at most 19 characters
  14:     userPrincipal.SamAccountName = "username";
  15:     userPrincipal.UserPrincipalName = "upn";
  16:     userPrincipal.HomeDirectory = "path to file server user directory";
  17:     userPrincipal.HomeDrive = "drive letter here";
  18:     userPrincipal.Save();
  19:  
  20:     ((DirectoryEntry)userPrincipal.GetUnderlyingObject()).InvokeSet("TerminalServicesProfilePath", new object[] { @"C:\Profiles\Mandy.man" });
  21:     ((DirectoryEntry)userPrincipal.GetUnderlyingObject()).CommitChanges();
  22:  
  23:     // Explicitly create user directory if it doesn't exist
  24:     if (!Directory.Exists(userPrincipal.HomeDirectory))
  25:     {
  26:         Directory.CreateDirectory(userPrincipal.HomeDirectory);
  27:         DirectorySecurity dirSec = Directory.GetAccessControl(userPrincipal.HomeDirectory);
  28:  
  29:         dirSec.SetOwner(userPrincipal.Sid);
  30:  
  31:         FileSystemAccessRule accessRule = new FileSystemAccessRule(userPrincipal.Sid,
  32:             FileSystemRights.FullControl,
  33:             InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
  34:             PropagationFlags.None,
  35:             AccessControlType.Allow);
  36:         dirSec.AddAccessRule(accessRule);
  37:  
  38:         Directory.SetAccessControl(userPrincipal.HomeDirectory, dirSec);
  39:     }
  40: }

No comments:

Post a Comment