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 } }
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 }); } }