public static void AddTask(CleanupTask newTask) { lock (s_lock) { Dictionary <string, CleanupTask> tasks = CleanupTasks.LoadTasks(); if (tasks.ContainsKey(newTask.UserName)) { // We already have a task for this user... get it. CleanupTask currentTask = tasks[newTask.UserName]; // We only need to change the action if it is not "DELETE_PROFILE" because if // it is "DELETE_PROFILE" then we want to do both actions (delete and scramble), // in which case it is pointless to do the scramble. if (currentTask.Action != CleanupAction.DELETE_PROFILE) { // Current task action must be SCRAMBLE, so we only change if the new // task is not SCRAMBLE (i.e. delete). if (currentTask.Action != newTask.Action) { tasks[newTask.UserName] = newTask; } } } else { tasks.Add(newTask.UserName, newTask); } CleanupTasks.SaveTasks(tasks); } }
public static void RemoveTaskForUser(string user) { lock (s_lock) { Dictionary <string, CleanupTask> tasks = CleanupTasks.LoadTasks(); // Upper-case the user name to remain case insensitive (see CleanupTask constructor) user = user.ToUpper(); if (tasks.ContainsKey(user)) { tasks.Remove(user); CleanupTasks.SaveTasks(tasks); } } }
/// <summary> /// Get the list of tasks that have time stamps that are at least 30 /// seconds in the past. /// </summary> /// <returns></returns> public static List <CleanupTask> GetEligibleTasks() { lock (s_lock) { Dictionary <string, CleanupTask> tasks = CleanupTasks.LoadTasks(); List <CleanupTask> result = new List <CleanupTask>(); foreach (KeyValuePair <string, CleanupTask> pair in tasks) { if ((DateTime.Now - pair.Value.TimeStamp) > TimeSpan.FromSeconds(30)) { result.Add(pair.Value); } } return(result); } }
public BooleanResult AuthenticatedUserGateway(SessionProperties properties) { // Our job, if we've been elected to do gateway, is to ensure that an // authenticated user: // // 1. Has a local account // 2. That account's password is set to the one they used to authenticate // 3. That account is a member of all groups listed, and not a member of any others // Is failure at #3 a total fail? bool failIfGroupSyncFails = Settings.Store.GroupCreateFailIsFail; // Groups everyone is added to string[] MandatoryGroups = Settings.Store.MandatoryGroups; // user info UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); // Add user to all mandatory groups if (MandatoryGroups.Length > 0) { foreach (string group in MandatoryGroups) { userInfo.AddGroup(new GroupInformation() { Name = group }); } } try { bool scramble = Settings.Store.ScramblePasswords; bool remove = Settings.Store.RemoveProfiles; if (remove) { // If this user doesn't already exist, and we are supposed to clean up after ourselves, // make note of the username! if (!LocalAccount.UserExists(userInfo.Username)) { m_logger.DebugFormat("Marking for deletion: {0}", userInfo.Username); CleanupTasks.AddTask(new CleanupTask(userInfo.Username, CleanupAction.DELETE_PROFILE)); } } // If we are configured to scramble passwords if (scramble) { // Scramble the password only if the user is not in the list // of exceptions. string[] exceptions = Settings.Store.ScramblePasswordsExceptions; if (!exceptions.Contains(userInfo.Username, StringComparer.CurrentCultureIgnoreCase)) { // If configured to do so, we check to see if this plugin failed // to auth this user, and only scramble in that case bool scrambleWhenLMFail = Settings.Store.ScramblePasswordsWhenLMAuthFails; if (scrambleWhenLMFail) { // Scramble the password only if we did not authenticate this user if (!DidWeAuthThisUser(properties, false)) { m_logger.DebugFormat("LM did not authenticate this user, marking user for scramble: {0}", userInfo.Username); CleanupTasks.AddTask(new CleanupTask(userInfo.Username, CleanupAction.SCRAMBLE_PASSWORD)); } } else { m_logger.DebugFormat("Marking user for scramble: {0}", userInfo.Username); CleanupTasks.AddTask(new CleanupTask(userInfo.Username, CleanupAction.SCRAMBLE_PASSWORD)); } } } m_logger.DebugFormat("AuthenticatedUserGateway({0}) for user: {1}", properties.Id.ToString(), userInfo.Username); LocalAccount.SyncUserInfoToLocalUser(userInfo); } catch (LocalAccount.GroupSyncException e) { if (failIfGroupSyncFails) { return new BooleanResult() { Success = false, Message = string.Format("Unable to sync users local group membership: {0}", e.RootException) } } ; } catch (Exception e) { return(new BooleanResult() { Success = false, Message = string.Format("Unexpected error while syncing user's info: {0}", e) }); } return(new BooleanResult() { Success = true }); }
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); } } } }