/// <summary> /// Removes the given security identifier (SID) from the local Administrators group. /// </summary> /// <param name="userSid"> /// The security identifier (SID) to be removed from the local Administrators group. /// </param> /// <param name="reason"> /// The reason for the removal. /// </param> public static void RemoveUser(SecurityIdentifier userSid, RemovalReason reason) { // TODO: Only do this if the user is a member of the group? if ((LocalAdminGroup != null) && (userSid != null)) { SecurityIdentifier[] localAdminSids = GetLocalGroupMembers(LocalAdminGroup.SamAccountName); foreach (SecurityIdentifier sid in localAdminSids) { if (sid == userSid) { string accountName = GetAccountNameFromSID(userSid); int result = RemoveLocalGroupMembers(LocalAdminGroup.SamAccountName, userSid); if (result == 0) { EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); encryptedSettings.RemoveUser(userSid); string reasonString = Properties.Resources.RemovalReasonUnknown; switch (reason) { case RemovalReason.ServiceStopped: reasonString = Properties.Resources.RemovalReasonServiceStopped; break; case RemovalReason.Timeout: reasonString = Properties.Resources.RemovalReasonTimeout; break; case RemovalReason.UserLogoff: reasonString = Properties.Resources.RemovalReasonUserLogoff; break; case RemovalReason.UserRequest: reasonString = Properties.Resources.RemovalReasonUserRequest; break; } string message = string.Format(Properties.Resources.UserRemoved, userSid, accountName, reasonString); ApplicationLog.WriteEvent(message, EventID.UserRemovedFromAdminsSuccess, System.Diagnostics.EventLogEntryType.Information); } else { ApplicationLog.WriteEvent(string.Format(Properties.Resources.RemovingUserReturnedError, userSid, accountName, result), EventID.UserRemovedFromAdminsFailure, System.Diagnostics.EventLogEntryType.Warning); } } } } }
/// <summary> /// Validates that all of the users stored in the on-disk user list /// are in the local Adminstrators group if they're supposed to be, and vice-vera. /// </summary> public static void ValidateAllAddedUsers() { // Get a list of the users stored in the on-disk list. EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); SecurityIdentifier[] addedUserList = encryptedSettings.AddedUserSIDs; // Get a list of the current members of the Administrators group. SecurityIdentifier[] localAdminSids = null; if ((addedUserList.Length > 0) && (LocalAdminGroup != null)) { localAdminSids = GetLocalGroupMembers(LocalAdminGroup.SamAccountName); } for (int i = 0; i < addedUserList.Length; i++) { bool sidFoundInAdminsGroup = false; if ((addedUserList[i] != null) && (localAdminSids != null)) { foreach (SecurityIdentifier sid in localAdminSids) { if (sid == addedUserList[i]) { sidFoundInAdminsGroup = true; break; } } AdminGroupManipulator adminGroup = new AdminGroupManipulator(); if (sidFoundInAdminsGroup) { // User's SID was found in the local administrators group. DateTime?expirationTime = encryptedSettings.GetExpirationTime(addedUserList[i]); if (expirationTime.HasValue) { // The user's rights expire at some point. if (expirationTime.Value > DateTime.Now) { // The user's administrator rights expire in the future. // Nothing to do here, since the user is already in the administrators group. } else { // The user's administrator rights have expired. LocalAdministratorGroup.RemoveUser(addedUserList[i], RemovalReason.Timeout); } } else { // The user's rights never expire. // Get a WindowsIdentity object for the user matching the added user SID. WindowsIdentity sessionIdentity = null; WindowsIdentity userIdentity = null; int[] loggedOnSessionIDs = LsaLogonSessions.LogonSessions.GetLoggedOnUserSessionIds(); foreach (int sessionId in loggedOnSessionIDs) { sessionIdentity = LsaLogonSessions.LogonSessions.GetWindowsIdentityForSessionId(sessionId); if ((sessionIdentity != null) && (sessionIdentity.User == addedUserList[i])) { userIdentity = sessionIdentity; break; } } if ( (Settings.AutomaticAddAllowed != null) && (Settings.AutomaticAddAllowed.Length > 0) && (adminGroup.UserIsAuthorized(Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied)) ) { // The user is an automatically-added user. // Nothing to do here. The user is an automatically-added one, and their rights don't expire. } else { // The user is not an automatically-added user. // Users who are not automatically added should not have non-expiring rights. Remove this user. LocalAdministratorGroup.RemoveUser(addedUserList[i], RemovalReason.Timeout); } } } else { // User's SID was not found in the local administrators group. DateTime?expirationTime = encryptedSettings.GetExpirationTime(addedUserList[i]); if (expirationTime.HasValue) { // The user's rights expire at some point. if (expirationTime.Value > DateTime.Now) { // The user's administrator rights expire in the future. string accountName = GetAccountNameFromSID(addedUserList[i]); if (Settings.OverrideRemovalByOutsideProcess) { ApplicationLog.WriteEvent(string.Format(Properties.Resources.UserRemovedByOutsideProcess + " " + Properties.Resources.AddingUserBackToAdministrators, addedUserList[i], string.IsNullOrEmpty(accountName) ? Properties.Resources.UnknownAccount : accountName), EventID.UserRemovedByExternalProcess, System.Diagnostics.EventLogEntryType.Information); AddUserToAdministrators(addedUserList[i]); } else { ApplicationLog.WriteEvent(string.Format(Properties.Resources.UserRemovedByOutsideProcess + " " + Properties.Resources.RemovingUserFromList, addedUserList[i], string.IsNullOrEmpty(accountName) ? Properties.Resources.UnknownAccount : accountName), EventID.UserRemovedByExternalProcess, System.Diagnostics.EventLogEntryType.Information); encryptedSettings.RemoveUser(addedUserList[i]); } } else { // The user's administrator rights have expired. // No need to remove from the administrators group, as we already know the SID // is not present in the group. encryptedSettings.RemoveUser(addedUserList[i]); } } else { // The user's rights never expire. // Get a WindowsIdentity object for the user matching the added user SID. WindowsIdentity sessionIdentity = null; WindowsIdentity userIdentity = null; int[] loggedOnSessionIDs = LsaLogonSessions.LogonSessions.GetLoggedOnUserSessionIds(); foreach (int sessionId in loggedOnSessionIDs) { sessionIdentity = LsaLogonSessions.LogonSessions.GetWindowsIdentityForSessionId(sessionId); if ((sessionIdentity != null) && (sessionIdentity.User == addedUserList[i])) { userIdentity = sessionIdentity; break; } } if ( (Settings.AutomaticAddAllowed != null) && (Settings.AutomaticAddAllowed.Length > 0) && (adminGroup.UserIsAuthorized(Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied)) ) { // The user is an automatically-added user. // The users rights do not expire, but they are an automatically-added user and are missing // from the Administrators group. Add the user back in. AddUserToAdministrators(addedUserList[i]); } else { // The user is not an automatically-added user. // The user is not in the Administrators group now, but they are // listed as having non-expiring rights, even though they are not // automatically added. This should never really happen, but // just in case, we'll remove them from the on-disk user list. encryptedSettings.RemoveUser(addedUserList[i]); } } } } } }