title: Sitecore active directory problem with permissions and roles-in-roles
body: <h1>Question</h1>
  
  <p>I have written custom membership/role/profile providers to authenticate users against an Active Directory domain. I'm trying to use roles-in-roles to provide uers in the ADDOMAIN with sitecore permissions by adding their AD group as a member of the appropriate sitecore role. If I log in as an AD user, I don't seem to have the permissions of the sitecore role, however, if I log in as a sitecore user in the same sitecore role, I do get the permissions. Is there something that I'm missing in the membership/role providers that I need to include to make this work or is there something else at play here?</p>
  
  <p>We're using Sitecore version 6.4 if that makes any difference.</p>
  
  <p><strong>SOLUTION</strong>: The answer from @Yan completely solved the issue. The problem is language permissions are only explicitly granted to sitecore domain users (via sitecore\Everyone). When creating AD users, they are in a different domain and don't inherit those language permissions. The fix is to grant the read/write permissions specifically to the AD domain, or as I have done, create another sitecore role and assign the necessary permissions to that role and then assign my AD roles into that role. </p>
  
  <p>The permissions you need to set are lang:read and lang:write in the master database on the /System/Languages/[LANGUAGE: en in my case] item. If you can't see these permissions in the security editor, then click the columns button and choose those columns.</p>
  
  <h1>More details</h1>
  
  <p>My apologies in advance for the level of detail.</p>
  
  <p>I have written custom membership/role/profile providers to authenticate users against an  Active Directory domain. We're not using the AD module provided by sitecore as we only want our users to see particular groups and users instead of every user/group within the AD. I am also only trying to provide authentication and role membership services as I don't want the sitecore administrators to be able to modify AD users or roles.</p>
  
  <p>The role I'm testing is called <em>sitecore\Content Author</em> in that it has the permissions that I want my AD users to have. The AD users are part of the <em>ADDOMAIN\Web-Authors-Group</em> group within the AD and within sitecore, I have set this group up as belonging to <em>sitecore\Content Author</em>. User <em>ADDOMAIN\sitecoreauthor1</em> is a member of <em>ADDOMAIN\Web-Authors-Group</em> within the AD and I also have a sitecore user <em>sitecore\bcauthor</em> user who is a member of the <em>sitecore\Content Author</em> role. I have also set up a separate sitecore role called <em>sitecore\SecondAuthorRole</em> and the user <em>sitecore\secondAuthor</em> in that role to test that the roles-in-roles functionality works normally.</p>
  
  <p>In case that's confusing, here's a visual representation:  </p>
  
  <pre>
  Sitecore Roles
  
      sitecore\Content Author
        - sitecore\bcauthor
        - ADDOMAIN\Web-Authors-Group
        - sitecore\SecondAuthorRole
      sitecore\SecondAuthorRole
        - sitecore\secondAuthor
  
  ActiveDirectory Groups
  
      ADDOMAIN\Web-Authors-Group
        - ADDOMAIN\sitecoreauthor1
  </pre>
  
  <p>If I log in as <em>sitecore\bcauthor</em>, I can do everything that the <em>sitecore\Content Author</em> role can do. If I log in as <em>sitecore\secondAuthor</em>, I can also do everything that the <em>sitecore\Content Author</em> role can do. However, if I log in as the <em>ADDOMAIN\sitecoreauthor1</em> user, I don't seem to have any of the permissions of the <em>sitecore\Content Author</em> role. </p>
  
  <h1>Even more information</h1>
  
  <p>The permissions for the home item (which is the item I'm testing against) are:</p>
  
  <pre><code> ar|sitecore\Content Author|pe|+item:rename|+item:write|+item:delete|+item:create|pd|+item:rename|+item:write|+item:delete|+item:create
  </code></pre>
  
  <h2>Code</h2>
  
  <p>Here's the skeleton of the classes that implement the read-only providers for membership, roles and profile:</p>
  
  <h3>Membership Provider class</h3>
  
  <pre><code>public class DirectoryMembershipProvider : System.Web.Security.MembershipProvider
  {
      public override string ApplicationName { get; set; }
      public override bool EnablePasswordReset { get { return false; } }
      public override bool EnablePasswordRetrieval { get { return false; } }
      public override int MaxInvalidPasswordAttempts { get { return 100; } }
      public override int MinRequiredNonAlphanumericCharacters { get { return 0; } }
      public override int MinRequiredPasswordLength { get { return 1; } }
      public override MembershipPasswordFormat PasswordFormat { get { return MembershipPasswordFormat.Clear; } }
      public override string PasswordStrengthRegularExpression { get { return ""; } }
      public override bool RequiresQuestionAndAnswer { get { return false; } }
      public override bool RequiresUniqueEmail { get { return false; } }
  
      // Not implemented
      public override bool ChangePassword(string username, string oldPassword, string newPassword)
      public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
      public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
      protected override byte[] DecryptPassword(byte[] encodedPassword)
      public override bool DeleteUser(string username, bool deleteAllRelatedData)
      protected override byte[] EncryptPassword(byte[] password)
      protected override byte[] EncryptPassword(byte[] password, MembershipPasswordCompatibilityMode legacyPasswordCompatibilityMode)
      protected override void OnValidatingPassword(ValidatePasswordEventArgs e)
      public override string ResetPassword(string username, string answer)
      public override bool UnlockUser(string userName)
      public override void UpdateUser(MembershipUser user)
  
      // Implemented functions
      public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
      public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
      public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
      public override string GetPassword(string username, string answer)
      public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
      public override MembershipUser GetUser(string username, bool userIsOnline)
      public override string GetUserNameByEmail(string email)
      public override bool ValidateUser(string username, string password)
  }
  </code></pre>
  
  <h3>Role Provider</h3>
  
  <pre><code>public class DirectoryRoleProvider : System.Web.Security.RoleProvider
  {
      public override string ApplicationName { get; set; }
  
      // not implemented
      public override void AddUsersToRoles(string[] usernames, string[] roleNames)
      public override void CreateRole(string roleName)
      public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
      public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
  
      // implemented functions
      public override string[] FindUsersInRole(string roleName, string usernameToMatch)
      public override string[] GetAllRoles()
      public override string[] GetRolesForUser(string username)
      public override string[] GetUsersInRole(string roleName)
      public override bool IsUserInRole(string username, string roleName)
      public override bool RoleExists(string roleName)
  }
  </code></pre>
  
  <h3>Profile Provider</h3>
  
  <pre><code>public class DirectoryProfileProvider : System.Web.Profile.ProfileProvider
  {
      public override string ApplicationName { get; set; }
  
      public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { return 0; }
      public override int DeleteProfiles(ProfileInfoCollection profiles) { return 0; }
      public override int DeleteProfiles(string[] usernames) { return 0; }
  
      // not implemented
      public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
      public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
  
      // implemented functions
      public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
      public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
      public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
      public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
      public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
  }
  </code></pre>