/// <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.Description = "pGina created"; userInfo.Description = user.Description; if (userInfo.PasswordEXP) { user.ExpirePasswordNow(); } user.Save(); // Sync via DE SyncUserPrincipalInfo(userInfo); // We have to re-fetch to get changes made via underlying DE return(GetUserPrincipal(user.Name)); } } user = GetUserPrincipal(userInfo.Username); if (user == null) { m_logger.ErrorFormat("Unable to get user principal for account that apparently exists: {0}", userInfo.Username); } return(user); }
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 BooleanResult ChangePassword(ChangePasswordInfo cpInfo, ChangePasswordPluginActivityInfo pluginInfo) { m_logger.Debug("ChangePassword()"); // Verify the old password if (Abstractions.WindowsApi.pInvokes.ValidateCredentials(cpInfo.Username, cpInfo.OldPassword)) { m_logger.DebugFormat("Authenticated via old password: {0}", cpInfo.Username); } else { return(new BooleanResult { Success = false, Message = "Current password or username is not valid." }); } using (UserPrincipal user = LocalAccount.GetUserPrincipal(cpInfo.Username)) { if (user != null) { m_logger.DebugFormat("Found principal, changing password for {0}", cpInfo.Username); user.SetPassword(cpInfo.NewPassword); } else { return(new BooleanResult { Success = false, Message = "Local machine plugin internal error: directory entry not found." }); } } return(new BooleanResult { Success = true, Message = "Local password successfully changed." }); }
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()"); }
public BooleanResult AuthenticateUser(SessionProperties properties) { try { bool alwaysAuth = Settings.Store.AlwaysAuthenticate; m_logger.DebugFormat("AuthenticateUser({0})", properties.Id.ToString()); // Get user info UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); m_logger.DebugFormat("Found username: {0}", userInfo.Username); // Should we authenticate? Only if user has not yet authenticated, or we are not in fallback mode if (alwaysAuth || !HasUserAuthenticatedYet(properties)) { if (LocalAccount.UserExists(userInfo.Username)) { // We use a pInvoke here instead of using PrincipalContext.ValidateCredentials // due to the fact that the latter will throw an exception when the network is disconnected. if (Abstractions.WindowsApi.pInvokes.ValidateCredentials(userInfo.Username, userInfo.Password)) { m_logger.InfoFormat("Authenticated user: {0}", userInfo.Username); userInfo.Domain = Environment.MachineName; m_logger.Debug("AuthenticateUser: Mirroring group membership from SAM"); LocalAccount.SyncLocalGroupsToUserInfo(userInfo); // Return success return(new BooleanResult() { Success = true }); } } else { m_logger.InfoFormat("User {0} does not exist on this machine.", userInfo.Username); } } m_logger.ErrorFormat("Failed to authenticate user: {0}", userInfo.Username); // Note that we don't include a message. We are a last chance auth, and want previous/failed plugins // to have the honor of explaining why. return(new BooleanResult() { Success = false, Message = null }); } catch (Exception e) { m_logger.ErrorFormat("AuthenticateUser exception: {0}", e); throw; // Allow pGina service to catch and handle exception } }
/// <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); } }
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(); } }
public BooleanResult AuthorizeUser(SessionProperties properties) { // Some things we always do, bool mirrorGroups = Settings.Store.MirrorGroupsForAuthdUsers; // Should we load users groups from SAM? We always do if we auth'd only if (mirrorGroups && !DidWeAuthThisUser(properties, false)) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (LocalAccount.UserExists(userInfo.Username)) { m_logger.DebugFormat("AuthorizeUser: Mirroring users group membership from SAM"); LocalAccount.SyncLocalGroupsToUserInfo(userInfo); } } // Do we need to do authorization? if (DoesAuthzApply(properties)) { bool limitToLocalAdmins = Settings.Store.AuthzLocalAdminsOnly; bool limitToLocalGroups = Settings.Store.AuthzLocalGroupsOnly; string[] limitToGroupList = Settings.Store.AuthzLocalGroups; bool restrictionsApply = limitToLocalAdmins || limitToLocalGroups; PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); if (!restrictionsApply) { return(new BooleanResult() { Success = true }); } else if (!pluginInfo.LoadedAuthenticationGatewayPlugins.Contains(this)) { return(new BooleanResult() { Success = false, Message = string.Format("Plugin configured to authorize users based on group membership, but not in the gateway list to ensure membership is enforced, denying access") }); } // The user must have the local administrator group in his group list, and // we must be in the Gateway list of plugins (as we'll be the ones ensuring // this group membership is enforced). if (limitToLocalAdmins) { SecurityIdentifier adminSid = Abstractions.Windows.Security.GetWellknownSID(WellKnownSidType.BuiltinAdministratorsSid); string adminName = Abstractions.Windows.Security.GetNameFromSID(adminSid); if (!ListedInGroup(adminName, adminSid, properties)) { return(new BooleanResult() { Success = false, Message = string.Format("Users group list does not include the admin group ({0}), denying access", adminName) }); } } // The user must have one of the groups listed (by name) in their group list // and we must be in the Gateway list of plugins (as we'll be the ones ensuring // this group membership is enforced). if (limitToLocalGroups) { if (limitToGroupList.Length > 0) { foreach (string group in limitToGroupList) { SecurityIdentifier sid = null; try { sid = new SecurityIdentifier(group); } catch { } if (ListedInGroup(group, sid, properties)) { return(new BooleanResult() { Success = true }); } } } return(new BooleanResult() { Success = false, Message = "User is not a member of one of the required groups, denying access" }); } return(new BooleanResult() { Success = true }); } else { // We elect to not do any authorization, let the user pass for us return(new BooleanResult() { Success = true }); } }
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>(); // is this a pgina user? Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4(); if (Abstractions.WindowsApi.pInvokes.UserGet(userInfo.Username, ref userinfo4)) //true if user exists { if (!userinfo4.comment.Contains("pGina created")) { m_logger.InfoFormat("User {0} is'nt a pGina created user. I'm not executing Gateway stage", userInfo.Username); return(new BooleanResult() { Success = true }); } } // Add user to all mandatory groups if (MandatoryGroups.Length > 0) { foreach (string group in MandatoryGroups) { string group_string = group; m_logger.DebugFormat("Is there a Group with SID/Name:{0}", group); using (GroupPrincipal groupconf = LocalAccount.GetGroupPrincipal(group)) { if (groupconf != null) { m_logger.DebugFormat("Groupname: \"{0}\"", groupconf.Name); group_string = groupconf.Name; } else { m_logger.ErrorFormat("Group: \"{0}\" not found", group); m_logger.Error("Failsave add user to group Users"); using (GroupPrincipal groupfail = LocalAccount.GetGroupPrincipal(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null).ToString())) { if (groupfail != null) { group_string = groupfail.Name; } else { m_logger.Debug("no BuiltinUsers. I'm out of options"); group_string = null; } } } } if (group_string != null) { userInfo.AddGroup(new GroupInformation() { Name = group_string }); } } } try { m_logger.DebugFormat("AuthenticatedUserGateway({0}) for user: {1}", properties.Id.ToString(), userInfo.Username); LocalAccount.SyncUserInfoToLocalUser(userInfo); using (UserPrincipal user = LocalAccount.GetUserPrincipal(userInfo.Username)) { userInfo.SID = user.Sid; userInfo.Description = user.Description; } properties.AddTrackedSingle <UserInformation>(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) { if (e.Message.ToLower().Contains("0x800708c5")) { return(new BooleanResult() { Success = false, Message = string.Format("This Worstation is denying the password of {0}.\nMost likely the password does not meet complexity requirements\n\n{1}", userInfo.Username, e) }); } return(new BooleanResult() { Success = false, Message = string.Format("Unexpected error while syncing user's info: {0}", e) }); } return(new BooleanResult() { Success = true }); }
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); } } } }
public static void SyncUserInfoToLocalUser(UserInformation userInfo) { LocalAccount la = new LocalAccount(userInfo); la.SyncToLocalUser(); }
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(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); } } //set ntuser.dat permissions if (!String.IsNullOrEmpty(UserInfo.usri4_profile) && !UserInfo.Description.Contains("pgSMB")) { Abstractions.WindowsApi.pInvokes.structenums.OSVERSIONINFOW verinfo = Abstractions.WindowsApi.pInvokes.VersionsInfo(); if (verinfo.dwMajorVersion == 0) { m_logger.WarnFormat("SyncToLocalUser: VersionsInfo() failed. I'm unable to detect OS beyond Windows 8.0"); verinfo.dwBuildNumber = Environment.OSVersion.Version.Build; verinfo.dwMajorVersion = Environment.OSVersion.Version.Major; verinfo.dwMinorVersion = Environment.OSVersion.Version.Minor; verinfo.dwPlatformId = Environment.OSVersion.Version.Build; } string ProfileExtension = (Environment.OSVersion.Version.Major == 6) ? (verinfo.dwMinorVersion > 3) /*greater than 8.1*/ ? ".V5" : ".V2" : ""; if (Connect2share(UserInfo.usri4_profile + ProfileExtension, UserInfo.Username, UserInfo.Password, 3, false)) { if (File.Exists(UserInfo.usri4_profile + ProfileExtension + "\\NTUSER.DAT")) { SetACL(UserInfo, ProfileExtension); Connect2share(UserInfo.usri4_profile + ProfileExtension, null, null, 0, true); } else { Connect2share(UserInfo.usri4_profile + ProfileExtension, null, null, 0, true); } } } m_logger.Debug("End SyncToLocalUser()"); }
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(); } }