private bool DidWeAuthThisUser(SessionProperties properties, bool exclusiveOnly) { PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); if (!exclusiveOnly) { if (pluginInfo.GetAuthenticationPlugins().Contains(PluginUuid)) { return(pluginInfo.GetAuthenticationResult(PluginUuid).Success); } } else { if (!pluginInfo.GetAuthenticationPlugins().Contains(PluginUuid)) { return(false); } // We must be the only one foreach (Guid pluginId in pluginInfo.GetAuthenticationPlugins()) { if (pluginId != PluginUuid && pluginInfo.GetAuthenticationResult(pluginId).Success) { return(false); } } return(true); } return(false); }
private bool WeAuthedThisUser(PluginActivityInformation actInfo) { try { BooleanResult ldapResult = actInfo.GetAuthenticationResult(this.Uuid); return(ldapResult.Success); } catch (KeyNotFoundException) { // The plugin is not enabled for authentication return(false); } }
private bool DidPluginAuth(string uuid, SessionProperties properties) { try { Guid pluginUuid = new Guid(uuid); PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); return(pluginInfo.GetAuthenticationResult(pluginUuid).Success); } catch (Exception e) { m_logger.ErrorFormat("Unable to validate that {0} authenticated user: {1}", uuid, e); return(false); } }
private bool HasUserAuthenticatedYet(SessionProperties properties) { PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid uuid in pluginInfo.GetAuthenticationPlugins()) { if (pluginInfo.GetAuthenticationResult(uuid).Success) { return(true); } } return(false); }
private bool WeAuthedThisUser(SessionProperties properties) { PluginActivityInformation actInfo = properties.GetTrackedSingle <PluginActivityInformation>(); try { BooleanResult ldapResult = actInfo.GetAuthenticationResult(this.Uuid); return(ldapResult.Success); } catch (KeyNotFoundException) { // The plugin is not enabled for authentication return(false); } }
public void AuthzDenyAuth() { Settings.Store.AuthzRequireAuth = true; m_plugin.BeginChain(m_props); PluginActivityInformation actInfo = m_props.GetTrackedSingle <PluginActivityInformation>(); actInfo.AddAuthenticateResult(LdapPlugin.LdapUuid, new BooleanResult { Success = false }); BooleanResult result = m_plugin.AuthorizeUser(m_props); m_plugin.EndChain(m_props); Assert.That(!result.Success, result.Message); Assert.That(result.Message, Is.EqualTo("Deny because LDAP authentication failed, or did not execute.")); }
public BooleanResult AuthorizeUser(SessionProperties properties) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); Dictionary <string, List <notify> > settings = GetSettings(userInfo); List <notify> autho_sys = new List <notify>(); try { autho_sys = settings["autho_sys"]; } catch { } foreach (notify line in autho_sys) { if (!Run(userInfo.SessionID, line.script, userInfo, line.pwd, true, GetAuthenticationPluginResults(properties), GetAuthorizationResults(properties), "")) { return new BooleanResult { Success = false, Message = String.Format("failed to run:{0}", line.script) } } ; } // return false if no other plugin succeeded BooleanResult ret = new BooleanResult() { Success = false, Message = this.Name + " plugin can't authorize a user on its own" }; PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid uuid in pluginInfo.GetAuthorizationPlugins()) { if (pluginInfo.GetAuthorizationResult(uuid).Success) { return(new BooleanResult() { Success = true }); } else { ret.Message = pluginInfo.GetAuthorizationResult(uuid).Message; } } return(ret); }
public BooleanResult GatewayProcess() { PluginActivityInformation pluginInfo = m_properties.GetTrackedSingle <PluginActivityInformation>(); List <IPluginAuthenticationGateway> plugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthenticationGateway>(); m_logger.DebugFormat("Processing gateways for user {0}, {1} plugins available", m_properties.GetTrackedSingle <UserInformation>().Username, plugins.Count); foreach (IPluginAuthenticationGateway plugin in plugins) { m_logger.DebugFormat("Calling {0}", plugin.Uuid); BooleanResult pluginResult = new BooleanResult() { Message = null, Success = false }; try { pluginResult = plugin.AuthenticatedUserGateway(m_properties); pluginInfo.AddGatewayResult(plugin.Uuid, pluginResult); // All must succeed, fail = total fail if (!pluginResult.Success) { m_logger.ErrorFormat("{0} Failed to process gateway for {1} message: {2}", plugin.Uuid, m_properties.GetTrackedSingle <UserInformation>().Username, pluginResult.Message); return(pluginResult); } } catch (Exception e) { m_logger.ErrorFormat("{0} Threw an unexpected exception, treating this as failure: {1}", plugin.Uuid, e); Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), "", "", String.Format("pGina: Gateway plugin Exception {0}", Environment.MachineName), e.ToString()); return(new BooleanResult() { Message = e.Message, Success = false }); } } m_logger.InfoFormat("Successfully processed gateways for {0}", m_properties.GetTrackedSingle <UserInformation>().Username); return(new BooleanResult() { Success = true }); }
public BooleanResult GatewayProcess() { PluginActivityInformation pluginInfo = m_properties.GetTrackedSingle <PluginActivityInformation>(); List <IPluginAuthenticationGateway> plugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthenticationGateway>(); m_logger.DebugFormat("Processing gateways for user {0}, {1} plugins available", m_properties.GetTrackedSingle <UserInformation>().Username, plugins.Count); foreach (IPluginAuthenticationGateway plugin in plugins) { m_logger.DebugFormat("Calling {0}", plugin.Uuid); BooleanResult pluginResult = new BooleanResult() { Message = null, Success = false }; try { pluginResult = plugin.AuthenticatedUserGateway(m_properties); pluginInfo.AddGatewayResult(plugin.Uuid, pluginResult); // All must succeed, fail = total fail if (!pluginResult.Success) { m_logger.ErrorFormat("{0} Failed to process gateway for {1} message: {2}", plugin.Uuid, m_properties.GetTrackedSingle <UserInformation>().Username, pluginResult.Message); return(pluginResult); } } catch (Exception e) { m_logger.ErrorFormat("{0} Threw an unexpected exception, treating this as failure: {1}", plugin.Uuid, e); return(pluginResult); } } m_logger.InfoFormat("Successfully processed gateways for {0}", m_properties.GetTrackedSingle <UserInformation>().Username); return(new BooleanResult() { Success = true }); }
public void InitTest() { // Default test settings, reset for each test Settings.Store.LdapHost = host; Settings.Store.LdapPort = port; Settings.Store.LdapTimeout = 10; Settings.Store.EncryptionMethod = (int)encMethod; Settings.Store.RequireCert = validateCert; Settings.Store.SearchDN = searchDN; Settings.Store.SetEncryptedSetting("SearchPW", searchPW); Settings.Store.GroupDnPattern = "cn=%g,ou=Group,dc=example,dc=com"; Settings.Store.GroupMemberAttrib = "memberUid"; Settings.Store.UseAuthBindForAuthzAndGateway = false; // Authentication Settings.Store.AllowEmptyPasswords = false; Settings.Store.DnPattern = "uid=%u,ou=People,dc=example,dc=com"; Settings.Store.DoSearch = false; Settings.Store.SearchFilter = ""; Settings.Store.SearchContexts = new string[] { }; // Authorization Settings.Store.GroupAuthzRules = new string[] { (new GroupAuthzRule(true)).ToRegString() }; Settings.Store.AuthzRequireAuth = false; Settings.Store.AuthzAllowOnError = true; // Gateway Settings.Store.GroupGatewayRules = new string[] { }; // Set up session props m_props = new SessionProperties(BogusSessionId); UserInformation userInfo = new UserInformation(); m_props.AddTrackedSingle <UserInformation>(userInfo); userInfo.Username = "******"; userInfo.Password = "******"; PluginActivityInformation actInfo = new PluginActivityInformation(); m_props.AddTrackedSingle <PluginActivityInformation>(actInfo); }
public BooleanResult AuthenticatedUserGateway(SessionProperties properties) { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); Dictionary <string, Dictionary <bool, string> > settings = GetSettings(userInfo); Dictionary <bool, string> gateway_sys = settings["gateway_sys"]; foreach (KeyValuePair <bool, string> line in gateway_sys) { if (!Run(userInfo.SessionID, line.Value, userInfo, line.Key, true)) { return new BooleanResult { Success = false, Message = String.Format("failed to run:{0}", line.Value) } } ; } // return false if no other plugin succeeded BooleanResult ret = new BooleanResult() { Success = false }; PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid uuid in pluginInfo.GetAuthenticationPlugins()) { if (pluginInfo.GetAuthenticationResult(uuid).Success) { return(new BooleanResult() { Success = true }); } else { ret.Message = pluginInfo.GetAuthenticationResult(uuid).Message; } } return(ret); }
public PluginDriver() { m_logger = LogManager.GetLogger(string.Format("PluginDriver:{0}", m_sessionId)); m_properties = new SessionProperties(m_sessionId); // Add the user information object we'll be using for this session UserInformation userInfo = new UserInformation(); m_properties.AddTrackedSingle <UserInformation>(userInfo); // Add the plugin tracking object we'll be using for this session PluginActivityInformation pluginInfo = new PluginActivityInformation(); pluginInfo.LoadedAuthenticationGatewayPlugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthenticationGateway>(); pluginInfo.LoadedAuthenticationPlugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthentication>(); pluginInfo.LoadedAuthorizationPlugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthorization>(); m_properties.AddTrackedSingle <PluginActivityInformation>(pluginInfo); m_logger.DebugFormat("New PluginDriver created"); }
internal string GetGatewayResults(SessionProperties properties) { string gateway = ""; try { PluginActivityInformation pluginInfo = properties.GetTrackedSingle <PluginActivityInformation>(); foreach (Guid uuid in pluginInfo.GetGatewayPlugins()) { if (pluginInfo.GetGatewayResult(uuid).Success) { gateway += "{" + uuid + "}"; } } } catch (Exception ex) { m_logger.ErrorFormat("GetGatewayResults Exception:", ex); } return(gateway); }
public BooleanResult AuthorizeUser(SessionProperties properties) { m_logger.Debug("MySql Plugin Authorization"); bool requireAuth = Settings.Store.AuthzRequireMySqlAuth; // If we require authentication, and we failed to auth this user, then we // fail authorization. if (requireAuth) { PluginActivityInformation actInfo = properties.GetTrackedSingle <PluginActivityInformation>(); try { BooleanResult mySqlResult = actInfo.GetAuthenticationResult(this.Uuid); if (!mySqlResult.Success) { m_logger.InfoFormat("Deny because MySQL auth failed, and configured to require MySQL auth."); return(new BooleanResult() { Success = false, Message = "Deny because MySQL authentication failed." }); } } catch (KeyNotFoundException) { // The plugin is not enabled for authentication m_logger.ErrorFormat("MySQL is not enabled for authentication, and authz is configured to require auth."); return(new BooleanResult { Success = false, Message = "Deny because MySQL auth did not execute, and configured to require MySQL auth." }); } } // Get the authz rules from registry List <GroupAuthzRule> rules = GroupRuleLoader.GetAuthzRules(); if (rules.Count == 0) { throw new Exception("No authorization rules found."); } try { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); string user = userInfo.Username; using (MySqlUserDataSource dataSource = new MySqlUserDataSource()) { foreach (GroupAuthzRule rule in rules) { m_logger.DebugFormat("Checking rule: {0}", rule.ToString()); bool inGroup = false; if (rule.RuleCondition != GroupRule.Condition.ALWAYS) { inGroup = dataSource.IsMemberOfGroup(user, rule.Group); m_logger.DebugFormat("User '{0}' {1} a member of '{2}'", user, inGroup ? "is" : "is not", rule.Group); } if (rule.RuleMatch(inGroup)) { if (rule.AllowOnMatch) { return new BooleanResult { Success = true, Message = string.Format("Allow via rule '{0}'", rule.ToString()) } } ; else { return new BooleanResult { Success = false, Message = string.Format("Deny via rule '{0}'", rule.ToString()) } }; } } } // If we get this far, no rules matched. This should never happen since // the last rule should always match (the default). Throw. throw new Exception("Missing default authorization rule."); } catch (Exception e) { m_logger.ErrorFormat("Exception during authorization: {0}", e); throw; } }
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"); } } }
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 AuthorizeUser(SessionProperties properties) { ////m_logger.Debug("LDAP Plugin Authorization"); bool requireAuth = Settings.Store.AuthzRequireAuth; // Get the authz rules from registry List <GroupAuthzRule> rules = GroupRuleLoader.GetAuthzRules(); // Get the LDAP server object LdapServer serv = properties.GetTrackedSingle <LdapServer>(); // If LDAP server object is not found, then something went wrong in authentication. // We allow or deny based on setting if (serv == null) { ////m_logger.ErrorFormat("AuthorizeUser: Internal error, LdapServer object not available."); // LdapServer is not available, allow or deny based on settings. return(new BooleanResult() { Success = Settings.Store.AuthzAllowOnError, Message = "LDAP server unavailable." }); } // If we require authentication, and we failed to auth this user, then we // fail authorization. Note that we do this AFTER checking the LDAP server object // because we may want to succeed if the authentication failed due to server // being unavailable. PluginActivityInformation actInfo = properties.GetTrackedSingle <PluginActivityInformation>(); if (requireAuth && !WeAuthedThisUser(actInfo)) { ////m_logger.InfoFormat("Deny because LDAP auth failed, and configured to require LDAP auth."); return(new BooleanResult() { Success = false, Message = "Deny because LDAP authentication failed, or did not execute." }); } // Apply the authorization rules try { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); // Bind for searching if we have rules to process. If there's only one, it's the // default rule which doesn't require searching the LDAP tree. if (rules.Count > 0) { this.BindForAuthzOrGatewaySearch(serv); } foreach (GroupAuthzRule rule in rules) { bool inGroup = false; string path = rule.path.Replace("%u", userInfo.Username); string filter = rule.filter.Replace("%u", userInfo.Username); inGroup = serv.GetUserAttribValue(path, filter, rule.SearchScope, new string[] { "dn" }).Count > 0; ////m_logger.DebugFormat("User {0} {1} {2} {3}", userInfo.Username, inGroup ? "is" : "is not", filter, path); if (rule.RuleMatch(inGroup)) { if (rule.AllowOnMatch) { return new BooleanResult() { Success = true, Message = string.Format("Allow via rule: \"{0}\"", rule.ToString()) } } ; else { return new BooleanResult() { Success = false, Message = string.Format("Deny via rule: \"{0}\"", rule.ToString()) } }; } } // If there is no matching rule use default. allow or deny if ((bool)Settings.Store.AuthzDefault) { return new BooleanResult() { Success = true, Message = "" } } ; else { return new BooleanResult() { Success = false, Message = String.Format("You are not allowed to login! No matching rule found! Default rule:{0}", (bool)Settings.Store.AuthzDefault ? "Allow" : "Deny") } }; } catch (Exception e) { if (e is LdapException) { LdapException ldapEx = (e as LdapException); if (ldapEx.ErrorCode == 81) { // Server can't be contacted, set server object to null ////m_logger.ErrorFormat("Server unavailable: {0}, {1}", ldapEx.ServerErrorMessage, e.Message); serv.Close(); properties.AddTrackedSingle <LdapServer>(null); return(new BooleanResult { Success = Settings.Store.AuthzAllowOnError, Message = "Failed to contact LDAP server." }); } else if (ldapEx.ErrorCode == 49) { // This is invalid credentials, return false, but server object should remain connected ////m_logger.ErrorFormat("LDAP bind failed: invalid credentials."); return(new BooleanResult { Success = false, Message = "Authorization via LDAP failed. Invalid credentials." }); } } // Unexpected error, let the PluginDriver catch ////m_logger.ErrorFormat("Error during authorization: {0}", e); throw; } }
public BooleanResult AuthorizeUser(SessionProperties properties) { m_logger.Debug("LDAP Plugin Authorization"); bool requireAuth = Settings.Store.AuthzRequireAuth; // Get the authz rules from registry List <GroupAuthzRule> rules = GroupRuleLoader.GetAuthzRules(); if (rules.Count == 0) { throw new Exception("No authorizaition rules found."); } // Get the LDAP server object LdapServer serv = properties.GetTrackedSingle <LdapServer>(); // If LDAP server object is not found, then something went wrong in authentication. // We allow or deny based on setting if (serv == null) { m_logger.ErrorFormat("AuthorizeUser: Internal error, LdapServer object not available."); // LdapServer is not available, allow or deny based on settings. return(new BooleanResult() { Success = Settings.Store.AuthzAllowOnError, Message = "LDAP server unavailable." }); } // If we require authentication, and we failed to auth this user, then we // fail authorization. Note that we do this AFTER checking the LDAP server object // because we may want to succeed if the authentication failed due to server // being unavailable. if (requireAuth) { PluginActivityInformation actInfo = properties.GetTrackedSingle <PluginActivityInformation>(); try { BooleanResult ldapResult = actInfo.GetAuthenticationResult(this.Uuid); if (!ldapResult.Success) { m_logger.InfoFormat("Deny because LDAP auth failed, and configured to require LDAP auth."); return(new BooleanResult() { Success = false, Message = "Deny because LDAP authentication failed." }); } } catch (KeyNotFoundException) { // The plugin is not enabled for authentication m_logger.ErrorFormat("LDAP is not enabled for authentication, and authz is configured to require authentication."); return(new BooleanResult { Success = false, Message = "Deny because LDAP auth did not execute, and configured to require LDAP auth." }); } } // Apply the authorization rules try { UserInformation userInfo = properties.GetTrackedSingle <UserInformation>(); string user = userInfo.Username; // Bind for searching if we have rules to process. If there's only one, it's the // default rule which doesn't require searching the LDAP tree. if (rules.Count > 1) { serv.BindForSearch(); } foreach (GroupAuthzRule rule in rules) { bool inGroup = false; // Don't need to check membership if the condition is "always." This is the // case for the default rule only. which is the last rule in the list. if (rule.RuleCondition != GroupRule.Condition.ALWAYS) { inGroup = serv.MemberOfGroup(user, rule.Group); m_logger.DebugFormat("User {0} {1} member of group {2}", user, inGroup ? "is" : "is not", rule.Group); } if (rule.RuleMatch(inGroup)) { if (rule.AllowOnMatch) { return new BooleanResult() { Success = true, Message = string.Format("Allow via rule: \"{0}\"", rule.ToString()) } } ; else { return new BooleanResult() { Success = false, Message = string.Format("Deny via rule: \"{0}\"", rule.ToString()) } }; } } // We should never get this far because the last rule in the list should always be a match, // but if for some reason we do, return success. return(new BooleanResult() { Success = true, Message = "" }); } catch (Exception e) { if (e is LdapException) { LdapException ldapEx = (e as LdapException); if (ldapEx.ErrorCode == 81) { // Server can't be contacted, set server object to null m_logger.ErrorFormat("Server unavailable: {0}, {1}", ldapEx.ServerErrorMessage, e.Message); serv.Close(); properties.AddTrackedSingle <LdapServer>(null); return(new BooleanResult { Success = Settings.Store.AuthzAllowOnError, Message = "Failed to contact LDAP server." }); } else if (ldapEx.ErrorCode == 49) { // This is invalid credentials, return false, but server object should remain connected m_logger.ErrorFormat("LDAP bind failed: invalid credentials."); return(new BooleanResult { Success = false, Message = "Authorization via LDAP failed. Invalid credentials." }); } } // Unexpected error, let the PluginDriver catch m_logger.ErrorFormat("Error during authorization: {0}", e); throw; } }
//Processes accounting on logon/logoff public void SessionChange(System.ServiceProcess.SessionChangeDescription changeDescription, pGina.Shared.Types.SessionProperties properties) { m_logger.DebugFormat("SessionChange({0})", properties.Id.ToString()); string username = null; if ((bool)Settings.Store.UseModifiedName) { username = properties.GetTrackedSingle <UserInformation>().Username; } else { username = properties.GetTrackedSingle <UserInformation>().OriginalUsername; } if (changeDescription.Reason == System.ServiceProcess.SessionChangeReason.SessionLogon) { //Create a new unique id for this accounting session and store it String sessionId = Guid.NewGuid().ToString(); lock (sessionIDLock) { sessionIDs.Add(username, sessionId); } //Determine which plugin authenticated the user (if any) PluginActivityInformation pai = properties.GetTrackedSingle <PluginActivityInformation>(); Packet.Acct_AuthenticType authSource = Packet.Acct_AuthenticType.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_AuthenticType.RADIUS; } else if (guid == LocalMachinePluginGuid) { authSource = Packet.Acct_AuthenticType.Local; } else { authSource = Packet.Acct_AuthenticType.Remote; } break; } } try { RADIUSClient client = GetClient(sessionId); client.startAccounting(username, authSource); } catch (Exception e) { m_logger.Error("Error occurred while starting accounting.", e); } } else if (changeDescription.Reason == System.ServiceProcess.SessionChangeReason.SessionLogoff) { //Check if guid was stored from accounting start request (if not, no point in sending a stop request) string sessionId = null; lock (sessionIDLock) { sessionId = sessionIDs.ContainsKey(username) ? sessionIDs[username] : null; if (sessionId == null) { m_logger.ErrorFormat("Error sending accounting stop request. No guid available for {0}", username); return; } //Remove the session id since we're logging off sessionIDs.Remove(username); } try { RADIUSClient client = GetClient(sessionId); client.stopAccounting(username, Packet.Acct_Terminate_CauseType.User_Request); } catch (Exception e) { m_logger.Error("Error occurred while stopping accounting.", e); return; } } }
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) { Dictionary <string, string> settings = GetSettings(userInfo.Username, userInfo); 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); } Roaming ro = new Roaming(); if (!userInfo.Description.EndsWith(" tmp")) //its a tmp profile do not upload { BooleanResult RetBool = ro.put(settings, userInfo.Username, userInfo.Password, userInfo.LocalProfilePath, userInfo.SID); if (!RetBool.Success) { m_logger.ErrorFormat("unable to Logoff {0} Error:{1}", userInfo.Username, RetBool.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: unable to Logoff {0} from {1}", userInfo.Username, Environment.MachineName), RetBool.Message); } } m_logger.InfoFormat("{0} cleanup 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(); } }
//Processes accounting on logon/logoff public void SessionChange(System.ServiceProcess.SessionChangeDescription changeDescription, pGina.Shared.Types.SessionProperties properties) { if (changeDescription.Reason != System.ServiceProcess.SessionChangeReason.SessionLogon && changeDescription.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 (changeDescription.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 = changeDescription.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 (changeDescription.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); } } } }
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(); } } } }
public BooleanResult AuthenticateUser() { PluginActivityInformation pluginInfo = m_properties.GetTrackedSingle <PluginActivityInformation>(); List <IPluginAuthentication> plugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthentication>(); m_logger.DebugFormat("Authenticating user {0}, {1} plugins available", m_properties.GetTrackedSingle <UserInformation>().Username, plugins.Count); // At least one must succeed BooleanResult finalResult = new BooleanResult() { Success = false }; foreach (IPluginAuthentication plugin in plugins) { m_logger.DebugFormat("Calling {0}", plugin.Uuid); BooleanResult pluginResult = new BooleanResult() { Message = null, Success = false }; try { pluginResult = plugin.AuthenticateUser(m_properties); pluginInfo.AddAuthenticateResult(plugin.Uuid, pluginResult); if (pluginResult.Success) { m_logger.DebugFormat("{0} Succeeded", plugin.Uuid); finalResult.Success = true; } else { if (!string.IsNullOrEmpty(pluginResult.Message)) { m_logger.WarnFormat("{0} Failed with Message: {1}", plugin.Uuid, pluginResult.Message); finalResult.Message = pluginResult.Message; } else { m_logger.WarnFormat("{0} Failed without a message", plugin.Uuid); } } } catch (Exception e) { m_logger.ErrorFormat("{0} Threw an unexpected exception, assuming failure: {1}", plugin.Uuid, e); } } if (finalResult.Success) { // Clear any errors from plugins if we did succeed finalResult.Message = null; m_logger.InfoFormat("Successfully authenticated {0}", m_properties.GetTrackedSingle <UserInformation>().Username); } else { m_logger.ErrorFormat("Failed to authenticate {0}, Message: {1}", m_properties.GetTrackedSingle <UserInformation>().Username, finalResult.Message); } return(finalResult); }
public BooleanResult AuthorizeUser() { PluginActivityInformation pluginInfo = m_properties.GetTrackedSingle <PluginActivityInformation>(); List <IPluginAuthorization> plugins = PluginLoader.GetOrderedPluginsOfType <IPluginAuthorization>(); m_logger.DebugFormat("Authorizing user {0}, {1} plugins available", m_properties.GetTrackedSingle <UserInformation>().Username, plugins.Count); // At least one must succeed BooleanResult finalResult = new BooleanResult() { Message = null, Success = true }; foreach (IPluginAuthorization plugin in plugins) { m_logger.DebugFormat("Calling {0}", plugin.Uuid); BooleanResult pluginResult = new BooleanResult() { Message = null, Success = false }; try { pluginResult = plugin.AuthorizeUser(m_properties); pluginInfo.AddAuthorizationResult(plugin.Uuid, pluginResult); if (pluginResult.Success) { m_logger.DebugFormat("{0} Succeeded", plugin.Uuid); finalResult.Success = true; } else { finalResult.Success = false; if (!string.IsNullOrEmpty(pluginResult.Message)) { m_logger.WarnFormat("{0} Failed with Message: {1}", plugin.Uuid, pluginResult.Message); finalResult.Message = pluginResult.Message; } else { m_logger.WarnFormat("{0} Failed without a message", plugin.Uuid); } break; } } catch (Exception e) { m_logger.ErrorFormat("{0} Threw an unexpected exception, treating this as failure: {1}", plugin.Uuid, e); Abstractions.Windows.Networking.sendMail(pGina.Shared.Settings.pGinaDynamicSettings.GetSettings(pGina.Shared.Settings.pGinaDynamicSettings.pGinaRoot, new string[] { "notify_pass" }), "", "", String.Format("pGina: Authorize plugin Exception {0}", Environment.MachineName), e.ToString()); return(new BooleanResult() { Message = e.Message, Success = false }); } } if (finalResult.Success) { // Clear any errors from plugins if we did succeed finalResult.Message = null; m_logger.InfoFormat("Successfully authorized {0}", m_properties.GetTrackedSingle <UserInformation>().Username); } else { m_logger.ErrorFormat("Failed to authorized {0}, Message: {1}", m_properties.GetTrackedSingle <UserInformation>().Username, finalResult.Message); } return(finalResult); }