/// <summary> /// Handles the Elapsed event for the rights removal timer. /// </summary> /// <param name="sender"> /// The timer whose Elapsed event is firing. /// </param> /// <param name="e"> /// Data related to the event. /// </param> private void RemovalTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); User[] expiredUsers = encryptedSettings.GetExpiredUsers(); if (expiredUsers != null) { foreach (User prin in expiredUsers) { LocalAdministratorGroup.RemoveUser(prin.Sid, RemovalReason.Timeout); if ((Settings.EndRemoteSessionsUponExpiration) && (!string.IsNullOrEmpty(prin.RemoteAddress))) { string userName = prin.Name; while (userName.LastIndexOf("\\") >= 0) { userName = userName.Substring(userName.LastIndexOf("\\") + 1); } int returnCode = 0; if (!string.IsNullOrEmpty(userName)) { returnCode = LocalAdministratorGroup.EndNetworkSession(string.Format(@"\\{0}", prin.RemoteAddress), userName); } } } } LocalAdministratorGroup.ValidateAllAddedUsers(); }
/// <summary> /// Determines whether the given array of SIDs/Identities contains the given target user identity. /// </summary> /// <param name="accountList"> /// An array to be searched for the target identity. /// </param> /// <param name="userIdentity"> /// The user identity to check to see if they or one of the groups they belong to are in the list of identities. /// </param> /// <returns> /// Returns true if the given target identity is present in the array of SIDs/Identities. /// If the array is null or empty, false is returned. /// </returns> private static bool AccountListContainsIdentity(string[] accountList, WindowsIdentity userIdentity) { if (accountList != null) { foreach (string account in accountList) { SecurityIdentifier sid = LocalAdministratorGroup.GetSIDFromAccountName(account); // If the user's SID or name is in the list, return true if (sid == userIdentity.User) { return(true); } // If any of the user's authorization groups are in the denied list, the user is not authorized. foreach (IdentityReference groupsid in userIdentity.Groups) { // Translate the NT Account (Domain\User) to SID if needed, and check the resulting values. if (sid == (SecurityIdentifier)groupsid.Translate(typeof(SecurityIdentifier))) { return(true); } } } } return(false); }
/// <summary> /// Adds a user to the local Administrators group. /// </summary> public void AddUserToAdministratorsGroup(DateTime expirationTime) { string remoteAddress = null; WindowsIdentity userIdentity = null; if (ServiceSecurityContext.Current != null) { userIdentity = ServiceSecurityContext.Current.WindowsIdentity; } if (OperationContext.Current != null) { if (OperationContext.Current.IncomingMessageProperties != null) { if (OperationContext.Current.IncomingMessageProperties.ContainsKey(RemoteEndpointMessageProperty.Name)) { remoteAddress = ((RemoteEndpointMessageProperty)OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name]).Address; if (remoteAddress != null) { ApplicationLog.WriteEvent(string.Format(Properties.Resources.RequestSentFromHost, remoteAddress), EventID.RemoteRequestInformation, System.Diagnostics.EventLogEntryType.Information); } } } } if (userIdentity != null) { int timeoutMinutes = GetTimeoutForUser(userIdentity); LocalAdministratorGroup.AddUser(userIdentity, expirationTime, remoteAddress); } }
/// <summary> /// Handles the stopping of the service. /// </summary> /// <remarks> /// Executes when a stop command is sent to the service by the Service Control Manager (SCM). /// </remarks> protected override void OnStop() { if ((this.namedPipeServiceHost != null) && (this.namedPipeServiceHost.State == CommunicationState.Opened)) { this.namedPipeServiceHost.Close(); } if ((this.tcpServiceHost != null) && (this.tcpServiceHost.State == CommunicationState.Opened)) { this.tcpServiceHost.Close(); } this.removalTimer.Stop(); EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); SecurityIdentifier[] sids = encryptedSettings.AddedUserSIDs; for (int i = 0; i < sids.Length; i++) { LocalAdministratorGroup.RemoveUser(sids[i], RemovalReason.ServiceStopped); } if (processWatchSession != null) { processWatchSession.Dispose(); } base.OnStop(); }
/// <summary> /// Removes a user from the local Administrators group. /// </summary> /// <param name="reason"> /// The reason that the rights are being removed. /// </param> public void RemoveUserFromAdministratorsGroup(RemovalReason reason) { WindowsIdentity userIdentity = null; if (ServiceSecurityContext.Current != null) { userIdentity = ServiceSecurityContext.Current.WindowsIdentity; } if (userIdentity != null) { LocalAdministratorGroup.RemoveUser(userIdentity.User, reason); } }
public void AddPrincipalToAdministratorsGroup() { string remoteAddress = null; WindowsIdentity userIdentity = null; if (ServiceSecurityContext.Current != null) { userIdentity = ServiceSecurityContext.Current.WindowsIdentity; } #if DEBUG else { ApplicationLog.WriteWarningEvent("Current service security context is null.", EventID.DebugMessage); } #endif if (OperationContext.Current != null) { if (OperationContext.Current.IncomingMessageProperties != null) { if (OperationContext.Current.IncomingMessageProperties.ContainsKey(RemoteEndpointMessageProperty.Name)) { remoteAddress = ((RemoteEndpointMessageProperty)OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name]).Address; } } } #if DEBUG if (remoteAddress != null) { string message = string.Format("Administrator rights request came from [{0}].", remoteAddress); ApplicationLog.WriteInformationEvent(message, EventID.DebugMessage); } #endif if (userIdentity != null) { int timeoutMinutes = Shared.GetTimeoutForUser(userIdentity); DateTime expirationTime = DateTime.Now.AddMinutes(timeoutMinutes); LocalAdministratorGroup.AddPrincipal(userIdentity, expirationTime, remoteAddress); } }
/// <summary> /// Handles the Elapsed event for the rights removal timer. /// </summary> /// <param name="sender"> /// The timer whose Elapsed event is firing. /// </param> /// <param name="e"> /// Data related to the event. /// </param> private void RemovalTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); User[] expiredUsers = encryptedSettings.GetExpiredUsers(); if (expiredUsers != null) { foreach (User prin in expiredUsers) { LocalAdministratorGroup.RemoveUser(prin.Sid, RemovalReason.Timeout); if ((Settings.EndRemoteSessionsUponExpiration) && (!string.IsNullOrEmpty(prin.RemoteAddress))) { string userName = prin.Name; while (userName.LastIndexOf("\\") >= 0) { userName = userName.Substring(userName.LastIndexOf("\\") + 1); } // TODO: Log this return code if it's not a success? int returnCode = 0; if (!string.IsNullOrEmpty(userName)) { returnCode = LocalAdministratorGroup.EndNetworkSession(string.Format(@"\\{0}", prin.RemoteAddress), userName); } } } } LocalAdministratorGroup.ValidateAllAddedUsers(); if (Settings.LogElevatedProcesses != ElevatedProcessLogging.Never) { if (this.processWatchSession == null) { StartTracing(); } if (this.processWatchSession != null) { LogProcesses(); } } }
private void RemovalTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { /* * string[] expiredSidStrings = PrincipalList.GetExpiredSIDs(); * foreach (string sidString in expiredSidStrings) * { * LocalAdministratorGroup.RemovePrincipal(new SecurityIdentifier(sidString), RemovalReason.Timeout); * } */ Principal[] expiredPrincipals = PrincipalList.GetExpiredPrincipals(); foreach (Principal prin in expiredPrincipals) { #if DEBUG ApplicationLog.WriteInformationEvent(string.Format("Expired Principal: {0}", prin.PrincipalSid.Value), EventID.DebugMessage); #endif LocalAdministratorGroup.RemovePrincipal(prin.PrincipalSid, RemovalReason.Timeout); if ((Settings.EndRemoteSessionsUponExpiration) && (!string.IsNullOrEmpty(prin.RemoteAddress))) { string userName = prin.PrincipalName; while (userName.LastIndexOf("\\") >= 0) { userName = userName.Substring(userName.LastIndexOf("\\") + 1); } #if DEBUG ApplicationLog.WriteInformationEvent(string.Format("Ending session for \"{0}\" on \"{1}.\"", userName, prin.RemoteAddress), EventID.DebugMessage); #endif int returnCode = Shared.EndNetworkSession(string.Format(@"\\{0}", prin.RemoteAddress), userName); #if DEBUG ApplicationLog.WriteInformationEvent(string.Format("Ending session returned error code {0}.", returnCode), EventID.DebugMessage); #endif } } LocalAdministratorGroup.ValidateAllAddedPrincipals(); }
protected override void OnStop() { if (this.namedPipeServiceHost.State == CommunicationState.Opened) { this.namedPipeServiceHost.Close(); } if ((this.tcpServiceHost != null) && (this.tcpServiceHost.State == CommunicationState.Opened)) { this.tcpServiceHost.Close(); } this.removalTimer.Stop(); SecurityIdentifier[] sids = PrincipalList.GetSIDs(); for (int i = 0; i < sids.Length; i++) { LocalAdministratorGroup.RemovePrincipal(sids[i], RemovalReason.ServiceStopped); } base.OnStop(); }
/// <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]); } } } } } }
/// <summary> /// Executes when a change event is received from a Terminal Server session. /// </summary> /// <param name="changeDescription"> /// Identifies the type of session change and the session to which it applies. /// </param> protected override void OnSessionChange(SessionChangeDescription changeDescription) { switch (changeDescription.Reason) { // The user has logged off from a session, either locally or remotely. case SessionChangeReason.SessionLogoff: EncryptedSettings encryptedSettings = new EncryptedSettings(EncryptedSettings.SettingsFilePath); System.Collections.Generic.List <SecurityIdentifier> sidsToRemove = new System.Collections.Generic.List <SecurityIdentifier>(encryptedSettings.AddedUserSIDs); int[] sessionIds = LsaLogonSessions.LogonSessions.GetLoggedOnUserSessionIds(); // For any user that is still logged on, remove their SID from the list of // SIDs to be removed from Administrators. That is, let the users who are still // logged on stay in the Administrators group. foreach (int id in sessionIds) { SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(id); if (sid != null) { if (sidsToRemove.Contains(sid)) { sidsToRemove.Remove(sid); } } } // Process the list of SIDs to be removed from Administrators. for (int i = 0; i < sidsToRemove.Count; i++) { if ( // If the user is not remote. (!(encryptedSettings.ContainsSID(sidsToRemove[i]) && encryptedSettings.IsRemote(sidsToRemove[i]))) && // If admin rights are to be removed on logoff, or the user's rights do not expire. (Settings.RemoveAdminRightsOnLogout || !encryptedSettings.GetExpirationTime(sidsToRemove[i]).HasValue) ) { LocalAdministratorGroup.RemoveUser(sidsToRemove[i], RemovalReason.UserLogoff); } } /* * In theory, this code should remove the user associated with the logoff, but it doesn't work. * SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(changeDescription.SessionId); * if (!(UserList.ContainsSID(sid) && UserList.IsRemote(sid))) * { * LocalAdministratorGroup.RemoveUser(sid, RemovalReason.UserLogoff); * } */ break; // The user has logged on to a session, either locally or remotely. case SessionChangeReason.SessionLogon: WindowsIdentity userIdentity = LsaLogonSessions.LogonSessions.GetWindowsIdentityForSessionId(changeDescription.SessionId); if (userIdentity != null) { NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport); ChannelFactory <IAdminGroup> namedPipeFactory = new ChannelFactory <IAdminGroup>(binding, Settings.NamedPipeServiceBaseAddress); IAdminGroup channel = namedPipeFactory.CreateChannel(); bool userIsAuthorizedForAutoAdd = channel.UserIsAuthorized(Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied); namedPipeFactory.Close(); // If the user is in the automatic add list, then add them to the Administrators group. if ( (Settings.AutomaticAddAllowed != null) && (Settings.AutomaticAddAllowed.Length > 0) && (userIsAuthorizedForAutoAdd /*UserIsAuthorized(userIdentity, Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied)*/) ) { LocalAdministratorGroup.AddUser(userIdentity, null, null); } } else { ApplicationLog.WriteEvent(Properties.Resources.UserIdentifyIsNull, EventID.DebugMessage, System.Diagnostics.EventLogEntryType.Warning); } break; /* * // The user has reconnected or logged on to a remote session. * case SessionChangeReason.RemoteConnect: * ApplicationLog.WriteInformationEvent(string.Format("Remote connect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has disconnected or logged off from a remote session. * case SessionChangeReason.RemoteDisconnect: * ApplicationLog.WriteInformationEvent(string.Format("Remote disconnect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has locked their session. * case SessionChangeReason.SessionLock: * ApplicationLog.WriteInformationEvent(string.Format("Session lock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has unlocked their session. * case SessionChangeReason.SessionUnlock: * ApplicationLog.WriteInformationEvent(string.Format("Session unlock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ } base.OnSessionChange(changeDescription); }
/// <summary> /// Determines whether the given user is authorized to obtain administrator rights. /// </summary> /// <param name="userIdentity"> /// An identity object representing the user whose authorization is to be checked. /// </param> /// <param name="allowedSidsList"> /// The list of allowed SIDs and principal names against which the user's identity is checked. /// </param> /// <param name="deniedSidsList"> /// The list of denied SIDs and principal names against which the user's identity is checked. /// </param> /// <returns> /// Returns true if the user is authorized to obtain administrator rights. /// </returns> public bool UserIsAuthorized(string[] allowedSidsList, string[] deniedSidsList) { WindowsIdentity userIdentity = null; if (ServiceSecurityContext.Current != null) { userIdentity = ServiceSecurityContext.Current.WindowsIdentity; } if (userIdentity == null) { return(false); } if ((deniedSidsList != null) && (deniedSidsList.Length > 0)) { // The denied list contains entries. Check the user against that list first. // If the user's SID or name is in the denied list, the user is not authorized. if ((ArrayContainsString(deniedSidsList, userIdentity.User.Value)) || (ArrayContainsString(deniedSidsList, userIdentity.Name))) { return(false); } // If any of the user's authorization groups are in the denied list, the user is not authorized. foreach (SecurityIdentifier sid in userIdentity.Groups) { // Check the SID values. if (ArrayContainsString(deniedSidsList, sid.Value)) { return(false); } // Translate the SID to an NT Account (Domain\User), and check the resulting values. if (ArrayContainsString(deniedSidsList, LocalAdministratorGroup.GetAccountNameFromSID(sid))) { return(false); } } } // The user hasn't been denied yet, so now we check for authorization. // Check the authorization list. if (allowedSidsList == null) { // The allowed list is null, meaning everyone is allowed administrator rights. return(true); } else if (allowedSidsList.Length == 0) { // The allowed list is empty, meaning no one is allowed administrator rights. return(false); } else { // The allowed list has entries. // If the user's SID is in the allowed list, the user is authorized. if ((ArrayContainsString(allowedSidsList, userIdentity.User.Value)) || (ArrayContainsString(allowedSidsList, userIdentity.Name))) { return(true); } // If any of the user's authorization groups are in the allowed list, the user is authorized. foreach (SecurityIdentifier sid in userIdentity.Groups) { // Check the SID values. if (ArrayContainsString(allowedSidsList, sid.Value)) { return(true); } // Translate the SID to an NT Account (Domain\User), and check the resulting values. if (ArrayContainsString(allowedSidsList, LocalAdministratorGroup.GetAccountNameFromSID(sid))) { return(true); } } // The user was not found in the allowed list, so the user is not authorized. return(false); } }
/// <summary> /// Updates the variables which store the user's administrator status. /// </summary> private void UpdateUserAdministratorStatus() { this.userIsAdmin = LocalAdministratorGroup.IsMemberOfAdministrators(WindowsIdentity.GetCurrent()); this.userIsDirectAdmin = LocalAdministratorGroup.IsMemberOfAdministratorsDirectly(WindowsIdentity.GetCurrent()); }
public static void ValidateAllAddedPrincipals() { SecurityIdentifier[] localAdminSids = null; /* string[] addedSids = PrincipalList.GetSIDs(); */ SecurityIdentifier[] addedSids = PrincipalList.GetSIDs(); if ((addedSids.Length > 0) && (LocalAdminGroup != null)) { localAdminSids = GetLocalGroupMembers(null, LocalAdminGroup.SamAccountName); } for (int i = 0; i < addedSids.Length; i++) { bool sidFoundInAdminsGroup = false; if ((addedSids[i] != null) && (localAdminSids != null)) { foreach (SecurityIdentifier sid in localAdminSids) { if (sid == addedSids[i]) { sidFoundInAdminsGroup = true; break; } } if (sidFoundInAdminsGroup) { // Principal's SID was found in the local administrators group. if (PrincipalList.GetExpirationTime(addedSids[i]).HasValue) { // The principal's rights expire at some point. if (PrincipalList.GetExpirationTime(addedSids[i]).Value > DateTime.Now) { // The principal's administrator rights expire in the future. // Nothing to do here, since the principal is already in the administrators group. } else { // The principal's administrator rights have expired. #if DEBUG string accountName = GetAccountNameFromSID(addedSids[i]); ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.DebugMessage); #endif LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout); } } // TODO: This should be put back in, but it needs to account for the fact that // some principals may be added without expiration times. /* * else * { // The principal's rights never expire. This should never happen. * // Remove the principal from the administrator group. #if DEBUG * string accountName = GetAccountNameFromSID(addedSids[i]); * ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.DebugMessage); #endif * LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout); * * if ( * (Settings.AutomaticAddAllowed != null) && * (Settings.AutomaticAddAllowed.Length > 0) && * (Shared.UserIsAuthorized(userIdentity, Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied)) * ) * { #if DEBUG * ApplicationLog.WriteInformationEvent("User is allowed to be automatically added!", EventID.DebugMessage); #endif * LocalAdministratorGroup.AddPrincipal(userIdentity, null, null); * } * } */ } else { // Principal's SID was not found in the local administrators group. if (PrincipalList.GetExpirationTime(addedSids[i]).HasValue) { // The principal's rights expire at some point. if (PrincipalList.GetExpirationTime(addedSids[i]).Value > DateTime.Now) { // The principal's administrator rights expire in the future. string accountName = GetAccountNameFromSID(addedSids[i]); if (Settings.OverrideRemovalByOutsideProcess) { // TODO: i18n. ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Adding the principal back to the Administrators group.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.PrincipalRemovedByExternalProcess); AddPrincipalToAdministrators(addedSids[i], null); } else { // TODO: i18n. ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.PrincipalRemovedByExternalProcess); PrincipalList.RemoveSID(addedSids[i]); Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>(); } } else { // The principal'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. #if DEBUG ApplicationLog.WriteInformationEvent(string.Format("Removing SID \"{0}\" from the principal list.", addedSids[i]), EventID.DebugMessage); #endif PrincipalList.RemoveSID(addedSids[i]); Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>(); } } /* * Rights shouldn't need to be removed here, as we already know the SID is not * a member of the local administrator group. * else * { // The principal's rights never expire. This should never happen. * // Remove the principal from the administrator. group. * LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout); * } */ } } } }
protected override void OnSessionChange(SessionChangeDescription changeDescription) { switch (changeDescription.Reason) { // The user has logged off from a session, either locally or remotely. case SessionChangeReason.SessionLogoff: #if DEBUG ApplicationLog.WriteInformationEvent(string.Format("Session {0} has logged off.", changeDescription.SessionId), EventID.DebugMessage); #endif //if (Settings.RemoveAdminRightsOnLogout) //{ System.Collections.Generic.List <SecurityIdentifier> sidsToRemove = new System.Collections.Generic.List <SecurityIdentifier>(PrincipalList.GetSIDs()); /* #if DEBUG * ApplicationLog.WriteInformationEvent("SID to remove list has been retrieved.", EventID.DebugMessage); * for (int i = 0; i < sidsToRemove.Count; i++) * { * ApplicationLog.WriteInformationEvent(string.Format("SID to remove: {0}", sidsToRemove[i]), EventID.DebugMessage); * } #endif */ int[] sessionIds = LsaLogonSessions.LogonSessions.GetLoggedOnUserSessionIds(); foreach (int id in sessionIds) { SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(id); if (sid != null) { if (sidsToRemove.Contains(sid)) { sidsToRemove.Remove(sid); } } } /* #if DEBUG * ApplicationLog.WriteInformationEvent("SID to remove list has been updated.", EventID.DebugMessage); * for (int i = 0; i < sidsToRemove.Count; i++) * { * ApplicationLog.WriteInformationEvent(string.Format("SID to remove: {0}", sidsToRemove[i]), EventID.DebugMessage); * } #endif */ for (int i = 0; i < sidsToRemove.Count; i++) { if ( (!(PrincipalList.ContainsSID(sidsToRemove[i]) && PrincipalList.IsRemote(sidsToRemove[i]))) && (Settings.RemoveAdminRightsOnLogout || !PrincipalList.GetExpirationTime(sidsToRemove[i]).HasValue) ) { LocalAdministratorGroup.RemovePrincipal(sidsToRemove[i], RemovalReason.UserLogoff); } } /* * In theory, this code should remove the user associated with the logoff, but it doesn't work. * SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(changeDescription.SessionId); * if (!(PrincipalList.ContainsSID(sid) && PrincipalList.IsRemote(sid))) * { * LocalAdministratorGroup.RemovePrincipal(sid, RemovalReason.UserLogoff); * } */ //} /* * else * { #if DEBUG * ApplicationLog.WriteInformationEvent("Removing admin rights on log off is disabled.", EventID.DebugMessage); #endif * } */ break; // The user has logged on to a session, either locally or remotely. case SessionChangeReason.SessionLogon: #if DEBUG // TODO: i18n. ApplicationLog.WriteInformationEvent(string.Format("Session logon. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); #endif WindowsIdentity userIdentity = LsaLogonSessions.LogonSessions.GetWindowsIdentityForSessionId(changeDescription.SessionId); if (userIdentity != null) { /* #if DEBUG * ApplicationLog.WriteInformationEvent("User identity is not null.", EventID.DebugMessage); * ApplicationLog.WriteInformationEvent(string.Format("user name: {0}", userIdentity.Name), EventID.DebugMessage); * ApplicationLog.WriteInformationEvent(string.Format("user SID: {0}", userIdentity.User), EventID.DebugMessage); #endif */ if ( (Settings.AutomaticAddAllowed != null) && (Settings.AutomaticAddAllowed.Length > 0) && (Shared.UserIsAuthorized(userIdentity, Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied)) ) { #if DEBUG ApplicationLog.WriteInformationEvent("User is allowed to be automatically added!", EventID.DebugMessage); #endif LocalAdministratorGroup.AddPrincipal(userIdentity, null, null); } } else { // TODO: i18n. ApplicationLog.WriteWarningEvent("User identity is null.", EventID.DebugMessage); } break; /* * // The user has reconnected or logged on to a remote session. * case SessionChangeReason.RemoteConnect: * ApplicationLog.WriteInformationEvent(string.Format("Remote connect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has disconnected or logged off from a remote session. * case SessionChangeReason.RemoteDisconnect: * ApplicationLog.WriteInformationEvent(string.Format("Remote disconnect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has locked their session. * case SessionChangeReason.SessionLock: * ApplicationLog.WriteInformationEvent(string.Format("Session lock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ /* * // The user has unlocked their session. * case SessionChangeReason.SessionUnlock: * ApplicationLog.WriteInformationEvent(string.Format("Session unlock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent); * break; */ } base.OnSessionChange(changeDescription); }