public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (properties == null) { return; } m_logger.DebugFormat("SessionChange({0}) - ID: {1}", Reason.ToString(), SessionId); //If SessionMode is enabled, send event to it. if ((bool)Settings.Store.SessionMode) { ILoggerMode mode = LoggerModeFactory.getLoggerMode(LoggerMode.SESSION); mode.Log(SessionId, Reason, properties); } //If EventMode is enabled, send event to it. if ((bool)Settings.Store.EventMode) { ILoggerMode mode = LoggerModeFactory.getLoggerMode(LoggerMode.EVENT); mode.Log(SessionId, Reason, properties); } //Close the connection if it's still open LoggerModeFactory.closeConnection(); }
public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (properties == null) { return; } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (userInfo.Description.Contains("pGina created")) { Dictionary <string, Dictionary <bool, string> > settings = GetSettings(userInfo); Dictionary <bool, string> notification_sys = settings["notification_sys"]; Dictionary <bool, string> notification_usr = settings["notification_usr"]; foreach (KeyValuePair <bool, string> line in notification_sys) { if (!Run(userInfo.SessionID, line.Value, userInfo, line.Key, true)) { m_logger.InfoFormat("failed to run:{0}", line.Value); } } foreach (KeyValuePair <bool, string> line in notification_usr) { if (!Run(userInfo.SessionID, line.Value, userInfo, line.Key, false)) { m_logger.InfoFormat("failed to run:{0}", line.Value); } } } } }
//Logs the event if it's an event we track according to the registry. public bool Log(int SessionId, System.ServiceProcess.SessionChangeReason Reason, pGina.Shared.Types.SessionProperties properties) { //Get the logging message for this event. string msg = null; switch (Reason) { case System.ServiceProcess.SessionChangeReason.SessionLogon: msg = LogonEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.SessionLogoff: msg = LogoffEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.SessionLock: msg = SessionLockEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.SessionUnlock: msg = SessionUnlockEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.SessionRemoteControl: msg = SesionRemoteControlEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.ConsoleConnect: msg = ConsoleConnectEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.ConsoleDisconnect: msg = ConsoleDisconnectEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.RemoteConnect: msg = RemoteConnectEvent(SessionId, properties); break; case System.ServiceProcess.SessionChangeReason.RemoteDisconnect: msg = RemoteDisconnectEvent(SessionId, properties); break; } m_logger.DebugFormat("SessionChange({0}) - Message: {1}", Reason.ToString(), msg); //Check if there is a message to log if (!string.IsNullOrEmpty(msg)) { if (m_conn == null) { throw new InvalidOperationException("No MySQL Connection present."); } //Send it to the server logToServer(msg); } return(true); //No msg to log }
public void HandleSessionChange(System.ServiceProcess.SessionChangeReason changeargs) { lock (statelock) { if (running) { state.HandleConsoleChanged(changeargs); } } }
public void HandleSessionChange(System.ServiceProcess.SessionChangeReason changeargs, uint sessionId) { lock (statelock) { if (running && (sessionId == Win32Impl.WTSGetActiveConsoleSessionId())) { state.HandleConsoleChanged(changeargs); } } }
public void HandleConsoleChanged(System.ServiceProcess.SessionChangeReason reason) { try { if ((reason == System.ServiceProcess.SessionChangeReason.ConsoleConnect) || (reason == System.ServiceProcess.SessionChangeReason.SessionLogon)) { handleConsoleChanged(); } } catch (Exception ex) { exceptionhandler.HandleException("Clipboard Changed", ex); } }
public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { // Only applies to pGina sessions! if (properties != null) { switch (Reason) { case System.ServiceProcess.SessionChangeReason.SessionLogon: LogonEvent(SessionId); break; case System.ServiceProcess.SessionChangeReason.SessionLogoff: LogoffEvent(SessionId); break; } } }
public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (properties == null) { return; } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { UserInformation uInfo = properties.GetTrackedSingle <UserInformation>(); m_logger.DebugFormat("{1} SessionChange SessionLogoff for ID:{0}", SessionId, uInfo.Username); m_logger.InfoFormat("{3} {0} {1} {2}", uInfo.Description.Contains("pGina created"), uInfo.HasSID, properties.CREDUI, uInfo.Username); if (uInfo.Description.Contains("pGina created") && uInfo.HasSID && !properties.CREDUI) { try { Locker.TryEnterWriteLock(-1); RunningTasks.Add(uInfo.Username.ToLower(), true); } finally { Locker.ExitWriteLock(); } // add this plugin into PluginActivityInformation m_logger.DebugFormat("{1} properties.id:{0}", properties.Id, uInfo.Username); PluginActivityInformation notification = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, uInfo.Username); } m_logger.DebugFormat("{1} PluginActivityInformation add guid:{0}", PluginUuid, uInfo.Username); notification.AddNotificationResult(PluginUuid, new BooleanResult { Message = "", Success = false }); properties.AddTrackedSingle <PluginActivityInformation>(notification); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, uInfo.Username); } Thread rem_local = new Thread(() => cleanup(uInfo, SessionId, properties)); rem_local.Start(); } else { m_logger.InfoFormat("{0} {1}. I'm not executing Notification stage", uInfo.Username, (properties.CREDUI) ? "has a program running in his context" : "is'nt a pGina created user"); } } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (!userInfo.HasSID) { m_logger.InfoFormat("{1} SessionLogon Event denied for ID:{0}", SessionId, userInfo.Username); return; } m_logger.DebugFormat("{1} SessionChange SessionLogon for ID:{0}", SessionId, userInfo.Username); if (userInfo.Description.Contains("pGina created")) { if (!userInfo.Description.Contains("pgSMB")) { if (!String.IsNullOrEmpty(userInfo.LoginScript)) { if (!Abstractions.WindowsApi.pInvokes.StartUserProcessInSession(SessionId, userInfo.LoginScript)) { m_logger.ErrorFormat("Can't run application {0}", userInfo.LoginScript); Abstractions.WindowsApi.pInvokes.SendMessageToUser(SessionId, "Can't run application", String.Format("I'm unable to run your LoginScript\n{0}", userInfo.LoginScript)); } } if (!Abstractions.Windows.User.QueryQuota(Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_USERS, userInfo.SID.ToString()) && Convert.ToUInt32(userInfo.usri4_max_storage) > 0) { m_logger.InfoFormat("{1} no quota GPO settings for user {0}", userInfo.SID.ToString(), userInfo.Username); if (!Abstractions.Windows.User.SetQuota(Abstractions.WindowsApi.pInvokes.structenums.RegistryLocation.HKEY_USERS, userInfo.SID.ToString(), Convert.ToUInt32(userInfo.usri4_max_storage))) { m_logger.InfoFormat("{1} failed to set quota GPO for user {0}", userInfo.SID.ToString(), userInfo.Username); } else { m_logger.InfoFormat("{1} done quota GPO settings for user {0}", userInfo.SID.ToString(), userInfo.Username); try { Abstractions.WindowsApi.pInvokes.StartUserProcessInSession(SessionId, "proquota.exe"); } catch (Exception ex) { m_logger.ErrorFormat("{2} Can't run application {0} because {1}", "proquota.exe", ex.ToString(), userInfo.Username); } } } IntPtr hToken = Abstractions.WindowsApi.pInvokes.GetUserToken(userInfo.Username, null, userInfo.Password); if (hToken != IntPtr.Zero) { string uprofile = Abstractions.WindowsApi.pInvokes.GetUserProfilePath(hToken); if (String.IsNullOrEmpty(uprofile)) { uprofile = Abstractions.WindowsApi.pInvokes.GetUserProfileDir(hToken); } Abstractions.WindowsApi.pInvokes.CloseHandle(hToken); m_logger.InfoFormat("add LocalProfilePath:[{0}]", uprofile); // the profile realy exists there, instead of assuming it will be created or changed during a login (temp profile[win error reading profile]) userInfo.LocalProfilePath = uprofile; properties.AddTrackedSingle <UserInformation>(userInfo); if ((uprofile.Contains(@"\TEMP") && !userInfo.Username.StartsWith("temp", StringComparison.CurrentCultureIgnoreCase)) || Abstractions.Windows.User.IsProfileTemp(userInfo.SID.ToString()) == true) { Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), userInfo.Username, userInfo.Password, String.Format("pGina: Windows tmp Login {0} from {1}", userInfo.Username, Environment.MachineName), "Windows was unable to load the profile"); } } } if (userInfo.PasswordEXPcntr.Ticks > 0) { Abstractions.WindowsApi.pInvokes.SendMessageToUser(SessionId, "Password expiration warning", String.Format("Your password will expire in {0} days {1} hours {2} minutes", userInfo.PasswordEXPcntr.Days, userInfo.PasswordEXPcntr.Hours, userInfo.PasswordEXPcntr.Minutes)); } } else { m_logger.InfoFormat("{0} {1}. I'm not executing Notification stage", userInfo.Username, (userInfo.Description.Contains("pgSMB")) ? "was created by pgSMB" : "is'nt a pGina created user"); } } }
public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (properties == null) { return; } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); m_logger.DebugFormat("{1} SessionChange SessionLogoff for ID:{0}", SessionId, userInfo.Username); m_logger.InfoFormat("{3} {0} {1} {2}", userInfo.Description.Contains("pGina created pgSMB2"), userInfo.HasSID, properties.CREDUI, userInfo.Username); if (userInfo.Description.Contains("pGina created pgSMB2") && userInfo.HasSID && !properties.CREDUI) { try { Locker.TryEnterWriteLock(-1); RunningTasks.Add(userInfo.Username.ToLower(), true); } finally { Locker.ExitWriteLock(); } // add this plugin into PluginActivityInformation m_logger.DebugFormat("{1} properties.id:{0}", properties.Id, userInfo.Username); PluginActivityInformation notification = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, userInfo.Username); } m_logger.DebugFormat("{1} PluginActivityInformation add guid:{0}", PluginUuid, userInfo.Username); notification.AddNotificationResult(PluginUuid, new BooleanResult { Message = "", Success = false }); properties.AddTrackedSingle <PluginActivityInformation>(notification); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, userInfo.Username); } Thread rem_smb = new Thread(() => cleanup(userInfo, SessionId, properties)); rem_smb.Start(); } else { m_logger.InfoFormat("{0} {1}. I'm not executing Notification stage", userInfo.Username, (properties.CREDUI) ? "has a program running in his context" : "is'nt a pGina created pgSMB2 user"); } } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (!userInfo.HasSID) { m_logger.InfoFormat("{1} SessionLogon Event denied for ID:{0}", SessionId, userInfo.Username); return; } m_logger.DebugFormat("{1} SessionChange SessionLogon for ID:{0}", SessionId, userInfo.Username); if (userInfo.Description.Contains("pGina created pgSMB2")) { Dictionary <string, string> settings = GetSettings(userInfo.Username, userInfo); if (!String.IsNullOrEmpty(settings["ScriptPath"])) { if (!Abstractions.WindowsApi.pInvokes.StartUserProcessInSession(SessionId, settings["ScriptPath"])) { m_logger.ErrorFormat("Can't run application {0}", settings["ScriptPath"]); Abstractions.WindowsApi.pInvokes.SendMessageToUser(SessionId, "Can't run application", String.Format("I'm unable to run your LoginScript\n{0}", settings["ScriptPath"])); } } IntPtr hToken = Abstractions.WindowsApi.pInvokes.GetUserToken(userInfo.Username, null, userInfo.Password); if (hToken != IntPtr.Zero) { string uprofile = Abstractions.WindowsApi.pInvokes.GetUserProfilePath(hToken); if (String.IsNullOrEmpty(uprofile)) { uprofile = Abstractions.WindowsApi.pInvokes.GetUserProfileDir(hToken); } Abstractions.WindowsApi.pInvokes.CloseHandle(hToken); m_logger.InfoFormat("add LocalProfilePath:[{0}]", uprofile); // the profile realy exists there, instead of assuming it will be created or changed during a login (temp profile[win error reading profile]) userInfo.LocalProfilePath = uprofile; properties.AddTrackedSingle <UserInformation>(userInfo); if ((uprofile.Contains(@"\TEMP") && !userInfo.Username.StartsWith("temp", StringComparison.CurrentCultureIgnoreCase)) || Abstractions.Windows.User.IsProfileTemp(userInfo.SID.ToString()) == true) { m_logger.InfoFormat("TEMP profile detected"); string userInfo_old_Description = userInfo.Description; userInfo.Description = "pGina created pgSMB2 tmp"; properties.AddTrackedSingle <UserInformation>(userInfo); pInvokes.structenums.USER_INFO_4 userinfo4 = new pInvokes.structenums.USER_INFO_4(); if (pInvokes.UserGet(userInfo.Username, ref userinfo4)) { userinfo4.logon_hours = IntPtr.Zero; userinfo4.comment = userInfo.Description; if (!pInvokes.UserMod(userInfo.Username, userinfo4)) { m_logger.ErrorFormat("Can't modify userinformation {0}", userInfo.Username); } } else { m_logger.ErrorFormat("Can't get userinformation {0}", userInfo.Username); } if (userInfo_old_Description.EndsWith("pGina created pgSMB2")) { Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), userInfo.Username, userInfo.Password, String.Format("pGina: Windows tmp Login {0} from {1}", userInfo.Username, Environment.MachineName), "Windows was unable to load the profile"); } } } if (userInfo.Description.EndsWith("pGina created pgSMB2")) { try { if (!EventLog.SourceExists("proquota")) { EventLog.CreateEventSource("proquota", "Application"); } } catch { EventLog.CreateEventSource("proquota", "Application"); } Abstractions.Windows.User.SetQuota(pInvokes.structenums.RegistryLocation.HKEY_USERS, userInfo.SID.ToString(), 0); string proquotaPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "proquota.exe"); try { using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows Defender\Exclusions\Processes", true)) { if (key != null) { bool proquota_exclude_found = false; foreach (string ValueName in key.GetValueNames()) { if (ValueName.Equals(proquotaPath, StringComparison.CurrentCultureIgnoreCase)) { proquota_exclude_found = true; } } if (!proquota_exclude_found) { key.SetValue(proquotaPath, 0, Microsoft.Win32.RegistryValueKind.DWord); } } } } catch { } m_logger.InfoFormat("start session:{0} prog:{1}", SessionId, proquotaPath); if (!Abstractions.WindowsApi.pInvokes.StartUserProcessInSession(SessionId, proquotaPath + " \"" + userInfo.LocalProfilePath + "\" " + settings["MaxStore"])) { m_logger.ErrorFormat("{0} Can't run application {1}", userInfo.Username, "proquota.exe"); } } } else { m_logger.InfoFormat("{0} is'nt a pGina pgSMB2 plugin created user. I'm not executing Notification stage", userInfo.Username); } } }
private void cleanup(UserInformation userInfo, int sessionID, SessionProperties properties, List <notify> notification_sys, List <notify> notification_usr, System.ServiceProcess.SessionChangeReason Reason, string authentication, string authorization, string gateway) { try { 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); } foreach (notify line in notification_sys) { if (line.logoff) { if (!Run(userInfo.SessionID, line.script, userInfo, line.pwd, true, authentication, authorization, gateway)) { m_logger.InfoFormat("failed to run:{0}", line.script); } } } foreach (notify line in notification_usr) { if (line.logoff) { if (!Run(userInfo.SessionID, line.script, userInfo, line.pwd, null, authentication, authorization, gateway)) { m_logger.InfoFormat("failed to run:{0}", line.script); } } } m_logger.InfoFormat("{0} scripting done", userInfo.Username); } catch (Exception ex) { m_logger.FatalFormat("{0} Error during Logoff of {1}", userInfo.Username, ex.Message); Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), userInfo.Username, userInfo.Password, String.Format("pGina: Logoff Exception {0} from {1}", userInfo.Username, Environment.MachineName), "Logoff Exception\n" + ex.Message); } 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 void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (properties == null) { return; } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (userInfo.Description.Contains("pGina created") && userInfo.HasSID && !properties.CREDUI) { try { Locker.TryEnterWriteLock(-1); RunningTasks.Add(userInfo.Username.ToLower(), true); } finally { Locker.ExitWriteLock(); } // add this plugin into PluginActivityInformation m_logger.DebugFormat("{1} properties.id:{0}", properties.Id, userInfo.Username); PluginActivityInformation notification = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, userInfo.Username); } m_logger.DebugFormat("{1} PluginActivityInformation add guid:{0}", PluginUuid, userInfo.Username); notification.AddNotificationResult(PluginUuid, new BooleanResult { Message = "", Success = false }); properties.AddTrackedSingle <PluginActivityInformation>(notification); foreach (Guid gui in notification.GetNotificationPlugins()) { m_logger.DebugFormat("{1} PluginActivityInformation Guid:{0}", gui, userInfo.Username); } } } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon || Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); if (userInfo.Description.Contains("pGina created")) { Dictionary <string, List <notify> > settings = GetSettings(userInfo); List <notify> notification_sys = new List <notify>(); try { notification_sys = settings["notification_sys"]; } catch { } List <notify> notification_usr = new List <notify>(); try { notification_usr = settings["notification_usr"]; } catch { } string authe = GetAuthenticationPluginResults(properties); string autho = GetAuthorizationResults(properties); string gateway = GetGatewayResults(properties); foreach (notify line in notification_sys) { if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon && line.logon) { if (!Run(userInfo.SessionID, line.script, userInfo, line.pwd, true, authe, autho, gateway)) { m_logger.InfoFormat("failed to run:{0}", line.script); } } } foreach (notify line in notification_usr) { if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon && line.logon) { if (!Run(userInfo.SessionID, line.script, userInfo, line.pwd, false, authe, autho, gateway)) { m_logger.InfoFormat("failed to run:{0}", line.script); } } } if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { Thread rem_smb = new Thread(() => cleanup(userInfo, SessionId, properties, notification_sys, notification_usr, Reason, authe, autho, gateway)); rem_smb.Start(); } } } }
//Processes accounting on logon/logoff public void SessionChange(int SessionId, System.ServiceProcess.SessionChangeReason Reason, SessionProperties properties) { if (Reason != System.ServiceProcess.SessionChangeReason.SessionLogon && Reason != System.ServiceProcess.SessionChangeReason.SessionLogoff) { //m_logger.DebugFormat("Not logging on or off for this session change call ({0})... exiting.", changeDescription.Reason); return; } if (properties == null) { //m_logger.DebugFormat("No session properties available. This account does not appear to be managed by pGina. Exiting SessionChange()"); return; } if (!(bool)Settings.Store.EnableAcct) { m_logger.Debug("Session Change stage set on RADIUS plugin but accounting is not enabled in plugin settings."); return; } //Determine username (may change depending on value of UseModifiedName setting) string username = null; UserInformation ui = properties.GetTrackedSingle <UserInformation>(); if (ui == null) { //m_logger.DebugFormat("No userinformation for this session logoff... exiting..."); return; } if ((bool)Settings.Store.UseModifiedName) { username = ui.Username; } else { username = ui.OriginalUsername; } Session session = null; //User is logging on if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogon) { lock (m_sessionManager) { //Check if session information is already available for this id if (!m_sessionManager.Keys.Contains(properties.Id)) { //No session info - must have authed with something other than RADIUS. //m_logger.DebugFormat("RADIUS Accounting Logon: Unable to find session for {0} with GUID {1}", username, properties.Id); if (!(bool)Settings.Store.AcctingForAllUsers) { //m_logger.Debug("Accounting for non-RADIUS users is disabled. Exiting."); return; } RADIUSClient client = GetClient(); session = new Session(properties.Id, username, client); m_sessionManager.Add(properties.Id, session); //Check forced interim-update setting if ((bool)Settings.Store.SendInterimUpdates && (bool)Settings.Store.ForceInterimUpdates) { int interval = (int)Settings.Store.InterimUpdateTime; session.SetInterimUpdate(interval, InterimUpdatesCallback); } } else { session = m_sessionManager[properties.Id]; } } //Determine which plugin authenticated the user (if any) PluginActivityInformation pai = properties.GetTrackedSingle <PluginActivityInformation>(); Packet.Acct_Authentic authSource = Packet.Acct_Authentic.Not_Specified; IEnumerable <Guid> authPlugins = pai.GetAuthenticationPlugins(); Guid LocalMachinePluginGuid = new Guid("{12FA152D-A2E3-4C8D-9535-5DCD49DFCB6D}"); foreach (Guid guid in authPlugins) { if (pai.GetAuthenticationResult(guid).Success) { if (guid == SimpleUuid) { authSource = Packet.Acct_Authentic.RADIUS; } else if (guid == LocalMachinePluginGuid) { authSource = Packet.Acct_Authentic.Local; } else //Not RADIUS, not Local, must be some other auth plugin { authSource = Packet.Acct_Authentic.Remote; } break; } } //We can finally start the accounting process try { lock (session) { session.windowsSessionId = SessionId; //Grab session ID now that we're authenticated session.username = username; //Accting username may have changed depending on 'Use Modified username for accounting option' session.client.startAccounting(username, authSource); //m_logger.DebugFormat("Successfully completed accounting start process..."); } } catch (Exception e) { m_logger.Error("Error occurred while starting accounting.", e); } } //User is logging off else if (Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { lock (m_sessionManager) { if (m_sessionManager.Keys.Contains(properties.Id)) { session = m_sessionManager[properties.Id]; } else { //m_logger.DebugFormat("Users {0} is logging off, but no RADIUS session information is available for session ID {1}.", username, properties.Id); return; } //Remove the session from the session manager m_sessionManager.Remove(properties.Id); } lock (session) { //Disbale any active callbacks for this session session.disableCallbacks(); session.active = false; //Assume normal logout if no other terminate reason is listed. if (session.terminate_cause == null) { session.terminate_cause = Packet.Acct_Terminate_Cause.User_Request; } try { //m_logger.DebugFormat("About to send accounting stop packet. Session has been active {0} seconds.", (DateTime.Now - session.client.accountingStartTime).TotalSeconds); session.client.stopAccounting(session.username, session.terminate_cause); } catch (RADIUSException re) { m_logger.DebugFormat("Unable to send accounting stop message for user {0} with ID {1}. Message: {2}", session.username, session.id, re.Message); } } } }