private void IterateCleanupUsers() { lock (this) { List <CleanupTask> tasks = CleanupTasks.GetEligibleTasks(); List <string> loggedOnUsers = null; try { loggedOnUsers = LoggedOnLocalUsers(); } catch (System.ComponentModel.Win32Exception e) { m_logger.ErrorFormat("Error (ignored) LoggedOnLocalUsers {0}", e); return; } m_logger.DebugFormat("IterateCleanupUsers Eligible users: {0}", string.Join(",", tasks)); m_logger.DebugFormat("IterateCleanupUsers loggedOnUsers: {0}", string.Join(",", loggedOnUsers)); foreach (CleanupTask task in tasks) { try { using (UserPrincipal userPrincipal = LocalAccount.GetUserPrincipal(task.UserName)) { // Make sure the user exists if (userPrincipal == null) { // This dude doesn't exist! m_logger.DebugFormat("User {0} doesn't exist, not cleaning up.", task.UserName); CleanupTasks.RemoveTaskForUser(task.UserName); continue; } // Is she logged in still? if (loggedOnUsers.Contains(task.UserName, StringComparer.CurrentCultureIgnoreCase)) { continue; } m_logger.InfoFormat("Cleaning up: {0} -> {1}", task.UserName, task.Action); try { switch (task.Action) { case CleanupAction.SCRAMBLE_PASSWORD: LocalAccount.ScrambleUsersPassword(task.UserName); break; case CleanupAction.DELETE_PROFILE: LocalAccount.RemoveUserAndProfile(task.UserName); break; default: m_logger.ErrorFormat("Unrecognized action: {0}, skipping user {1}", task.Action, task.UserName); throw new Exception(); } } catch (Exception e) { m_logger.WarnFormat("Cleanup for {0} failed, will retry next time around. Error: {1}", task.UserName, e); continue; } // All done! No more cleanup for this user needed CleanupTasks.RemoveTaskForUser(task.UserName); } } catch (Exception e) { // If something goes wrong, we log the exception and ignore. m_logger.ErrorFormat("Caught (ignoring) Exception {0}", e); } } } }
private void cleanup(UserInformation userInfo, int sessionID, SessionProperties properties) { bool scramble = Settings.Store.ScramblePasswords; bool remove = Settings.Store.RemoveProfiles; while (true) { // logoff detection is quite a problem under NT6 // a disconnectEvent is only triggered during a logoff // but not during a shutdown/reboot // and the SessionLogoffEvent is only saying that the user is logging of // So, there is no event that is fired during a user-logoff/reboot/shutdown // that indicates that the user has logged of if (Abstractions.WindowsApi.pInvokes.IsSessionLoggedOFF(sessionID) || IsShuttingDown) { break; } else { Thread.Sleep(1000); } } while (true) { // if no other notification plugin is working on this user // if the first entry from GetNotificationPlugins is equal to this plugin UID IEnumerable <Guid> guids = properties.GetTrackedSingle <PluginActivityInformation>().GetNotificationPlugins(); /*foreach(Guid gui in guids) * { * m_logger.DebugFormat("{1} PluginActivityInformation guid:{0}", gui, userInfo.Username); * }*/ if (guids.DefaultIfEmpty(Guid.Empty).FirstOrDefault().Equals(PluginUuid) || guids.ToList().Count == 0) { break; } Thread.Sleep(1000); } m_logger.DebugFormat("{0} start cleanup with Description \"{1}\"", userInfo.Username, userInfo.Description); if (LocalAccount.UserExists(userInfo.Username)) { lock (logoff_locker) { LocalAccount lo = new LocalAccount(userInfo); if (remove) { m_logger.DebugFormat("{0} remove profile", userInfo.Username); lo.RemoveUserAndProfile(userInfo.Username, sessionID); } else { m_logger.DebugFormat("{0} not removing profile", userInfo.Username); } if (scramble && !remove) { m_logger.DebugFormat("{0} scramble password", userInfo.Username); lo.ScrambleUsersPassword(userInfo.Username); } else { m_logger.DebugFormat("{0} not scramble password", userInfo.Username); } m_logger.DebugFormat("{0} cleanup done", userInfo.Username); } } else { m_logger.DebugFormat("{0} doesnt exist", userInfo.Username); } try { Locker.TryEnterWriteLock(-1); RunningTasks.Remove(userInfo.Username.ToLower()); PluginActivityInformation notification = properties.GetTrackedSingle <PluginActivityInformation>(); notification.DelNotificationResult(PluginUuid); m_logger.InfoFormat("{1} PluginActivityInformation del Guid:{0}", PluginUuid, userInfo.Username); properties.AddTrackedSingle <PluginActivityInformation>(notification); foreach (Guid guid in properties.GetTrackedSingle <PluginActivityInformation>().GetNotificationPlugins()) { m_logger.InfoFormat("{1} PluginActivityInformation Guid:{0}", guid, userInfo.Username); } } finally { Locker.ExitWriteLock(); } }
private void cleanup(UserInformation userInfo, int sessionID, SessionProperties properties) { bool scramble = Settings.Store.ScramblePasswords; bool remove = Settings.Store.RemoveProfiles; while (true) { // logoff detection is quite a problem under NT6 // a disconnectEvent is only triggered during a logoff // but not during a shutdown/reboot // and the SessionLogoffEvent is only saying that the user is logging of // So, there is no event that is fired during a user-logoff/reboot/shutdown // that indicates that the user has logged of if (Abstractions.WindowsApi.pInvokes.IsSessionLoggedOFF(sessionID) || IsShuttingDown) { break; } else { Thread.Sleep(1000); } } while (true) { // if no other notification plugin is working on this user // if the first entry from GetNotificationPlugins is equal to this plugin UID IEnumerable<Guid> guids = properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins(); /*foreach(Guid gui in guids) { m_logger.DebugFormat("{1} PluginActivityInformation guid:{0}", gui, userInfo.Username); }*/ if (guids.DefaultIfEmpty(Guid.Empty).FirstOrDefault().Equals(PluginUuid) || guids.ToList().Count == 0) { break; } Thread.Sleep(1000); } m_logger.DebugFormat("{0} start cleanup with Description \"{1}\"", userInfo.Username, userInfo.Description); if (LocalAccount.UserExists(userInfo.Username)) { lock (logoff_locker) { LocalAccount lo = new LocalAccount(userInfo); if (remove) { m_logger.DebugFormat("{0} remove profile", userInfo.Username); lo.RemoveUserAndProfile(userInfo.Username, sessionID); } else { m_logger.DebugFormat("{0} not removing profile", userInfo.Username); } if (scramble && !remove) { m_logger.DebugFormat("{0} scramble password", userInfo.Username); lo.ScrambleUsersPassword(userInfo.Username); } else { m_logger.DebugFormat("{0} not scramble password", userInfo.Username); } m_logger.DebugFormat("{0} cleanup done", userInfo.Username); } } else { m_logger.DebugFormat("{0} doesnt exist", userInfo.Username); } try { Locker.TryEnterWriteLock(-1); RunningTasks.Remove(userInfo.Username.ToLower()); PluginActivityInformation notification = properties.GetTrackedSingle<PluginActivityInformation>(); notification.DelNotificationResult(PluginUuid); m_logger.InfoFormat("{1} PluginActivityInformation del Guid:{0}", PluginUuid, userInfo.Username); properties.AddTrackedSingle<PluginActivityInformation>(notification); foreach (Guid guid in properties.GetTrackedSingle<PluginActivityInformation>().GetNotificationPlugins()) { m_logger.InfoFormat("{1} PluginActivityInformation Guid:{0}", guid, userInfo.Username); } } finally { Locker.ExitWriteLock(); } }