/// <summary> /// Returns a list of groups of which the user is a member. It does so in a fashion that /// may seem strange since one can call UserPrincipal.GetGroups, but seems to be much faster /// in my tests. /// </summary> /// <param name="user"></param> /// <returns></returns> private static List <GroupPrincipal> GetGroups(UserPrincipal user) { List <GroupPrincipal> result = new List <GroupPrincipal>(); // Get all groups using a PrincipalSearcher and GroupPrincipal filter = new GroupPrincipal(m_machinePrincipal); using (PrincipalSearcher searcher = new PrincipalSearcher(filter)) { PrincipalSearchResult <Principal> sResult = searcher.FindAll(); foreach (Principal p in sResult) { if (p is GroupPrincipal) { GroupPrincipal gp = (GroupPrincipal)p; if (LocalAccount.IsUserInGroup(user, gp)) { result.Add(gp); } else { gp.Dispose(); } } else { p.Dispose(); } } } return(result); }
private UserPrincipal CreateOrGetUserPrincipal(UserInformation userInfo) { UserPrincipal user = null; if (!LocalAccount.UserExists(userInfo.Username)) { // See note about MS bug in CreateOrGetGroupPrincipal to understand the mix of DE/Principal here: using (user = new UserPrincipal(m_machinePrincipal)) { user.Name = userInfo.Username; user.SetPassword(userInfo.Password); user.Save(); // Sync via DE SyncUserPrincipalInfo(user, userInfo); // We have to re-fetch to get changes made via underlying DE return(GetUserPrincipal(user.Name)); } } user = GetUserPrincipal(userInfo.Username); if (user != null) { return(user); } else { throw new Exception( String.Format("Unable to get user principal for account that apparently exists: {0}", userInfo.Username)); } }
public void SyncToLocalUser() { m_logger.Debug("SyncToLocalUser()"); using (UserPrincipal user = CreateOrGetUserPrincipal(UserInfo)) { // Force password and fullname match (redundant if we just created, but oh well) SyncUserPrincipalInfo(user, UserInfo); try { List <SecurityIdentifier> ignoredSids = new List <SecurityIdentifier>(new SecurityIdentifier[] { new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), // "Authenticated Users" new SecurityIdentifier("S-1-1-0"), // "Everyone" }); // First remove from any local groups they aren't supposed to be in m_logger.Debug("Checking for groups to remove."); List <GroupPrincipal> localGroups = LocalAccount.GetGroups(user); foreach (GroupPrincipal group in localGroups) { m_logger.DebugFormat("Remove {0}?", group.Name); // Skip ignored sids if (!ignoredSids.Contains(group.Sid)) { GroupInformation gi = new GroupInformation() { Name = group.Name, SID = group.Sid, Description = group.Description }; if (!UserInfo.InGroup(gi)) { m_logger.DebugFormat("Removing user {0} from group {1}", user.Name, group.Name); RemoveUserFromGroup(user, group); } } group.Dispose(); } // Now add to any they aren't already in that they should be m_logger.Debug("Checking for groups to add"); foreach (GroupInformation groupInfo in UserInfo.Groups) { m_logger.DebugFormat("Add {0}?", groupInfo.Name); if (!IsUserInGroup(user, groupInfo)) { using (GroupPrincipal group = CreateOrGetGroupPrincipal(groupInfo)) { m_logger.DebugFormat("Adding user {0} to group {1}", user.Name, group.Name); AddUserToGroup(user, group); } } } } catch (Exception e) { throw new GroupSyncException(e); } } m_logger.Debug("End SyncToLocalUser()"); }
/// <summary> /// This is a faster technique for determining whether or not a user exists on the local /// machine. UserPrincipal.FindByIdentity tends to be quite slow in general, so if /// you only need to know whether or not the account exists, this method is much /// faster. /// </summary> /// <param name="strUserName">The user name</param> /// <returns>Whether or not the account with the given user name exists on the system</returns> public static bool UserExists(string strUserName) { try { using (DirectoryEntry userEntry = LocalAccount.GetUserDirectoryEntry(strUserName)) { return(userEntry != null); } } catch (Exception) { return(false); } }
// Load userInfo.Username's group list and populate userInfo.Groups accordingly public static void SyncLocalGroupsToUserInfo(UserInformation userInfo) { ILog logger = LogManager.GetLogger("LocalAccount.SyncLocalGroupsToUserInfo"); try { SecurityIdentifier EveryoneSid = new SecurityIdentifier("S-1-1-0"); SecurityIdentifier AuthenticatedUsersSid = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null); if (LocalAccount.UserExists(userInfo.Username)) { using (UserPrincipal user = LocalAccount.GetUserPrincipal(userInfo.Username)) { foreach (GroupPrincipal group in LocalAccount.GetGroups(user)) { // Skip "Authenticated Users" and "Everyone" as these are generated if (group.Sid == EveryoneSid || group.Sid == AuthenticatedUsersSid) { continue; } userInfo.AddGroup(new GroupInformation() { Name = group.Name, Description = group.Description, SID = group.Sid }); } } } } catch (Exception e) { logger.ErrorFormat("Unexpected error while syncing local groups, skipping rest: {0}", e); } }
public static void SyncUserInfoToLocalUser(UserInformation userInfo) { LocalAccount la = new LocalAccount(userInfo); la.SyncToLocalUser(); }