public RemoveUserAndProfile ( string user, int sessionID ) : void | ||
user | string | |
sessionID | int | |
return | void |
public void RemoveUserAndProfile(string user, int sessionID)
{
// First we have to work out where the users profile is on disk.
try
{
if (!String.IsNullOrEmpty(UserInfo.LocalProfilePath))
{
// instead of while (true)
if (File.Exists(UserInfo.LocalProfilePath + "\\NTUSER.DAT"))
{
bool inuse = true;
for (int x = 0; x < 60; x++)
{
try
{
using (FileStream isunloaded = File.Open(UserInfo.LocalProfilePath + "\\NTUSER.DAT", FileMode.Open, FileAccess.Read))
{
inuse = false;
break;
}
}
catch (Exception ex)
{
m_logger.DebugFormat("loop{1}:{0}", ex.Message, x);
Thread.Sleep(1000);
}
}
if (inuse)
{
return;
}
}
m_logger.DebugFormat("User {0} has profile in {1}, giving myself delete permission", user, UserInfo.LocalProfilePath);
try { Directory.Delete(UserInfo.LocalProfilePath, true); }
catch { }
RecurseDelete(UserInfo.LocalProfilePath);
}
// Now remove it from the registry as well
Abstractions.WindowsApi.pInvokes.DeleteProfile(UserInfo.SID);
Abstractions.Windows.User.DelProfileList(UserInfo.SID.ToString());
}
catch (KeyNotFoundException)
{
m_logger.DebugFormat("User {0} has no disk profile, just removing principal", user);
}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\SessionData\" + sessionID.ToString() + "'");
try{Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\SessionData\" + sessionID.ToString(), false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\NetCache\PurgeAtNextLogoff\" + UserInfo.SID + "'");
try{Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\NetCache\PurgeAtNextLogoff\", true).DeleteValue(UserInfo.SID.ToString(), false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Status\" + UserInfo.SID + "'");
try{Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Status\" + UserInfo.SID, false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\" + UserInfo.SID + "'");
try{Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\" + UserInfo.SID, false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\" + UserInfo.SID + "'");
try{Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\" + UserInfo.SID, false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\Windows\CurrentVersion\GameUX\" + UserInfo.SID + "'");
try {Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentVersion\GameUX\" + UserInfo.SID, false);}
catch {}
m_logger.Debug(@"removing SessionData 'SOFTWARE\Microsoft\IdentityStore\Cache\" + UserInfo.SID + "'");
try {Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\IdentityStore\Cache\" + UserInfo.SID, false);}
catch {}
using (UserPrincipal userPrincipal = GetUserPrincipal(user))
{
try
{
userPrincipal.Delete();
}
catch (Exception ex)
{
m_logger.ErrorFormat("userPrincipal.Delete error:{0}", ex.Message);
}
}
}
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); } } } }