/// <summary>
        /// Initializes static members of the <see cref="PrincipalList"/> class.
        /// </summary>
        static PrincipalList()
        {
#if DEBUG
            try
            {
#endif
            principals = new Dictionary <SecurityIdentifier, Principal>();
#if DEBUG
        }
        catch (Exception excep)
        {
            // TODO: i18n.
            ApplicationLog.WriteInformationEvent("error in PrincipalList constructor, creating Dictionary object.", EventID.DebugMessage);
            ApplicationLog.WriteInformationEvent(excep.Message, EventID.DebugMessage);
        }
#endif


            // TODO: Put this back, to remove SIDs that remain after a reboot?

            /*
             #if DEBUG
             * try
             * {
             #endif
             *
             *  // Retrieve the stored SID list from the settings.
             *  string[] storedSIDs = Settings.SIDs;
             *  if (storedSIDs != null)
             *  {
             *      for (int i = 0; i < storedSIDs.Length; i++)
             *      {
             *          PrincipalList.AddSID(storedSIDs[i], DateTime.Now.AddMinutes(Settings.AdminRightsTimeout * -1), null);
             *      }
             *  }
             *
             #if DEBUG
             * }
             * catch (Exception excep)
             * {
             *  ApplicationLog.WriteInformationEvent("error in PrincipalList.ReadSidsFromSettings(), getting SIDs from settings.", EventID.DebugMessage);
             *  ApplicationLog.WriteInformationEvent(excep.Message, EventID.DebugMessage);
             * }
             #endif
             */

            /*
             * try
             * {
             *  Settings.SIDs = null;
             * }
             * catch (Exception excep)
             * {
             *  ApplicationLog.WriteInformationEvent("clearing SIDs list in Settings", EventID.DebugMessage);
             *  ApplicationLog.WriteInformationEvent(excep.Message, EventID.DebugMessage);
             * }
             */
        }
        public static void RemovePrincipal(SecurityIdentifier userSid, RemovalReason reason)
        {
            // TODO: Only do this if the principal is a member of the group?

            if ((LocalAdminGroup != null) && (userSid != null))
            {
                SecurityIdentifier[] localAdminSids = GetLocalGroupMembers(null, LocalAdminGroup.SamAccountName);

                foreach (SecurityIdentifier sid in localAdminSids)
                {
                    if (sid == userSid)
                    /* if (string.Compare(sid.Value, principalSID, true) == 0) */
                    {
                        string accountName = GetAccountNameFromSID(userSid.Value);
                        int    result      = RemoveLocalGroupMembers(null, LocalAdminGroup.SamAccountName, userSid);
                        if (result == 0)
                        {
                            PrincipalList.RemoveSID(userSid);
                            Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>();
                            string reasonString = Properties.Resources.RemovalReasonUnknown;
                            switch (reason)
                            {
                            case RemovalReason.ServiceStopped:
                                reasonString = Properties.Resources.RemovalReasonServiceStopped;
                                break;

                            case RemovalReason.Timeout:
                                reasonString = Properties.Resources.RemovalReasonTimeout;
                                break;

                            case RemovalReason.UserLogoff:
                                reasonString = Properties.Resources.RemovalReasonUserLogoff;
                                break;

                            case RemovalReason.UserRequest:
                                reasonString = Properties.Resources.RemovalReasonUserRequest;
                                break;
                            }
                            // TODO: i18n.
                            string message = string.Format("Principal {0} ({1}) removed from the Administrators group. Reason: {2}.", userSid, accountName, reasonString);
                            ApplicationLog.WriteInformationEvent(message, EventID.UserRemovedFromAdminsSuccess);
                        }
                        else
                        {
                            // TODO: i18n.
                            ApplicationLog.WriteWarningEvent(string.Format("Removing principal {0} ({1}) from the Administrators group returned error code {1}.", userSid, accountName, result), EventID.UserRemovedFromAdminsFailure);
                        }
                    }
                }
            }
        }
        public static void AddPrincipal(WindowsIdentity userIdentity, DateTime?expirationTime, string remoteAddress)
        {
            // TODO: Only do this if the principal is not a member of the group?

            /*
             #if DEBUG
             * ApplicationLog.WriteInformationEvent(string.Format("User is a member of {0:N0} groups.", userIdentity.Groups.Count), EventID.DebugMessage);
             #endif
             *
             #if DEBUG
             * ApplicationLog.WriteInformationEvent("Checking local allowed/denied list.", EventID.DebugMessage);
             #endif
             */
            bool userIsAuthorized = Shared.UserIsAuthorized(userIdentity, Settings.LocalAllowedEntities, Settings.LocalDeniedEntities);

#if DEBUG
            ApplicationLog.WriteInformationEvent(string.Format("User is authorized: {0}", userIsAuthorized), EventID.DebugMessage);
#endif

            if (!string.IsNullOrEmpty(remoteAddress))
            { // Request is from a remote computer. Check the remote authorization list.
                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("Checking remote allowed/denied list.", EventID.DebugMessage);
                 #endif
                 */
                userIsAuthorized &= Shared.UserIsAuthorized(userIdentity, Settings.RemoteAllowedEntities, Settings.RemoteDeniedEntities);

                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent(string.Format("User is authorized: {0}", userIsAuthorized), EventID.DebugMessage);
                 #endif
                 */
            }

            if (
                (LocalAdminGroup != null) &&
                (userIdentity.User != null) &&
                (userIdentity.Groups != null) &&
                (userIsAuthorized)
                )
            {
                PrincipalList.AddSID(userIdentity, expirationTime, remoteAddress);
                AddPrincipalToAdministrators(userIdentity.User, /* expirationTime, */ remoteAddress);
            }
        }
        public void AddPrincipalToAdministratorsGroup()
        {
            string remoteAddress = null;

            WindowsIdentity userIdentity = null;

            if (ServiceSecurityContext.Current != null)
            {
                userIdentity = ServiceSecurityContext.Current.WindowsIdentity;
            }

#if DEBUG
            else
            {
                ApplicationLog.WriteWarningEvent("Current service security context is null.", EventID.DebugMessage);
            }
#endif


            if (OperationContext.Current != null)
            {
                if (OperationContext.Current.IncomingMessageProperties != null)
                {
                    if (OperationContext.Current.IncomingMessageProperties.ContainsKey(RemoteEndpointMessageProperty.Name))
                    {
                        remoteAddress = ((RemoteEndpointMessageProperty)OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name]).Address;
                    }
                }
            }


#if DEBUG
            if (remoteAddress != null)
            {
                string message = string.Format("Administrator rights request came from [{0}].", remoteAddress);
                ApplicationLog.WriteInformationEvent(message, EventID.DebugMessage);
            }
#endif

            if (userIdentity != null)
            {
                int      timeoutMinutes = Shared.GetTimeoutForUser(userIdentity);
                DateTime expirationTime = DateTime.Now.AddMinutes(timeoutMinutes);
                LocalAdministratorGroup.AddPrincipal(userIdentity, expirationTime, remoteAddress);
            }
        }
        /// <summary>
        /// Adds a principal's security ID (SID) to the collection.
        /// </summary>
        /// <param name="sid">
        /// The SID to be added to the collection, in SDDL form.
        /// </param>
        /// <param name="expirationTime">
        /// The date and time at which the principal's administrator rights expire.
        /// </param>
        public static void AddSID(WindowsIdentity userIdentity, DateTime?expirationTime, string remoteAddress)
        {
            if (principals.ContainsKey(userIdentity.User))
            {
                // Set the expiration time for the given SID to the maximum of
                // its current value or the specified expiration time.
#if DEBUG
                ApplicationLog.WriteInformationEvent(string.Format("Setting expiration for SID {0} to {1}.", userIdentity.User.Value, new[] { principals[userIdentity.User].ExpirationTime, expirationTime }.Max()), EventID.DebugMessage);
#endif

                /*
                 * principals[userIdentity.User].ExpirationTime = new[] { principals[userIdentity.User].ExpirationTime, expirationTime }.Max();
                 */
                principals[userIdentity.User].RemoteAddress = remoteAddress;

#if DEBUG
                ApplicationLog.WriteInformationEvent(string.Format("SID list contains {0:N0} items.", principals.Count), EventID.DebugMessage);
#endif
            }
            else
            {
#if DEBUG
                System.Text.StringBuilder message = new System.Text.StringBuilder("Adding SID ");
                message.Append(userIdentity.User.Value);
                message.Append(" to list with an expiration of ");
                if (expirationTime.HasValue)
                {
                    message.Append(expirationTime.Value);
                }
                else
                {
                    message.Append("never");
                }
                message.Append(".");
                ApplicationLog.WriteInformationEvent(message.ToString(), EventID.DebugMessage);
#endif

                principals.Add(userIdentity.User, new Principal(userIdentity, expirationTime, remoteAddress));
                Settings.SIDs = GetSIDs().Select(p => p.Value).ToArray <string>();
            }
        }
        private static void AddPrincipalToAdministrators(SecurityIdentifier userSid, string remoteAddress)
        {
            int result = AddLocalGroupMembers(null, LocalAdminGroup.SamAccountName, userSid);

            if (result == 0)
            {
                /* PrincipalList.AddSID(userSid, expirationTime, remoteAddress); */
                // TODO: i18n.
                ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) added to the Administrators group.", userSid, GetAccountNameFromSID(userSid.Value)), EventID.UserAddedToAdminsSuccess);
                if (remoteAddress != null)
                {
                    // TODO: i18n.
                    ApplicationLog.WriteInformationEvent(string.Format("Request was sent from host {0}.", remoteAddress), EventID.RemoteRequestInformation);
                }
                Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>();
            }
            else
            {
                // TODO: i18n.
                ApplicationLog.WriteWarningEvent(string.Format("Adding principal {0} ({1}) to the Administrators group returned error code {2}.", userSid, GetAccountNameFromSID(userSid.Value), result), EventID.UserAddedToAdminsFailure);
            }
        }
        private void RemovalTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            /*
             * string[] expiredSidStrings = PrincipalList.GetExpiredSIDs();
             * foreach (string sidString in expiredSidStrings)
             * {
             *  LocalAdministratorGroup.RemovePrincipal(new SecurityIdentifier(sidString), RemovalReason.Timeout);
             * }
             */

            Principal[] expiredPrincipals = PrincipalList.GetExpiredPrincipals();
            foreach (Principal prin in expiredPrincipals)
            {
#if DEBUG
                ApplicationLog.WriteInformationEvent(string.Format("Expired Principal: {0}", prin.PrincipalSid.Value), EventID.DebugMessage);
#endif
                LocalAdministratorGroup.RemovePrincipal(prin.PrincipalSid, RemovalReason.Timeout);

                if ((Settings.EndRemoteSessionsUponExpiration) && (!string.IsNullOrEmpty(prin.RemoteAddress)))
                {
                    string userName = prin.PrincipalName;
                    while (userName.LastIndexOf("\\") >= 0)
                    {
                        userName = userName.Substring(userName.LastIndexOf("\\") + 1);
                    }
#if DEBUG
                    ApplicationLog.WriteInformationEvent(string.Format("Ending session for \"{0}\" on \"{1}.\"", userName, prin.RemoteAddress), EventID.DebugMessage);
#endif

                    int returnCode = Shared.EndNetworkSession(string.Format(@"\\{0}", prin.RemoteAddress), userName);

#if DEBUG
                    ApplicationLog.WriteInformationEvent(string.Format("Ending session returned error code {0}.", returnCode), EventID.DebugMessage);
#endif
                }
            }

            LocalAdministratorGroup.ValidateAllAddedPrincipals();
        }
示例#8
0
        /*
         * public static bool UserIsAuthorized(IdentityReferenceCollection authorizationGroups, string[] allowedSidsList, string[] deniedSidsList)
         */
        public static bool UserIsAuthorized(WindowsIdentity userIdentity, string[] allowedSidsList, string[] deniedSidsList)
        {
            /*
             #if DEBUG
             * ApplicationLog.WriteInformationEvent("In Shared.Shared.UserIsAuthorized.", EventID.DebugMessage);
             * ApplicationLog.WriteInformationEvent(string.Format("Authorization group count: {0:N0}", userIdentity.Groups.Count), EventID.DebugMessage);
             #endif
             */

#if DEBUG
            // TODO: i18n.
            if (deniedSidsList != null)
            {
                ApplicationLog.WriteInformationEvent(string.Format("Denied list contains {0:N0} entries.", deniedSidsList.Length), EventID.DebugMessage);
            }
            // TODO: i18n.
            if (allowedSidsList != null)
            {
                ApplicationLog.WriteInformationEvent(string.Format("Allowed list contains {0:N0} entries.", allowedSidsList.Length), EventID.DebugMessage);
            }
#endif

            /*
             #if DEBUG
             * ApplicationLog.WriteInformationEvent("Checking security principal against allowed and denied list.", EventID.DebugMessage);
             #endif
             */

            if ((deniedSidsList != null) && (deniedSidsList.Length > 0))
            { // The denied list contains entries. Check the user against that list first.
              /*
               #if DEBUG
               * ApplicationLog.WriteInformationEvent("Denied list contains entries.", EventID.DebugMessage);
               #endif
               */

                // If the user's SID or name is in the denied list, the user is not authorized.
                if ((ArrayContainsString(deniedSidsList, userIdentity.User.Value)) || (ArrayContainsString(deniedSidsList, userIdentity.Name)))
                {
                    /*
                     #if DEBUG
                     * ApplicationLog.WriteInformationEvent("Principal's SID is in the denied list. Permission denied.", EventID.DebugMessage);
                     #endif
                     */
                    return(false);
                }

                // If any of the user's authorization groups are in the denied list, the user is not authorized.
                foreach (SecurityIdentifier sid in userIdentity.Groups)
                {
                    if (ArrayContainsString(deniedSidsList, sid.Value))
                    {
                        /*
                         #if DEBUG
                         * ApplicationLog.WriteInformationEvent("One of the principal's groups is in the denied list. Permission denied.", EventID.DebugMessage);
                         #endif
                         */
                        return(false);
                    }

                    if (sid.IsValidTargetType(typeof(NTAccount)))
                    {
                        NTAccount account = (NTAccount)sid.Translate(typeof(NTAccount));
                        if (ArrayContainsString(deniedSidsList, account.Value))
                        {
                            /*
                             #if DEBUG
                             * ApplicationLog.WriteInformationEvent("One of the principal's groups is in the denied list. Permission denied.", EventID.DebugMessage);
                             #endif
                             */
                            return(false);
                        }
                    }
                }
            }

            // The user hasn't been denied yet, so now we check the authorization list.

            if (allowedSidsList == null)
            { // The allowed list is null, meaning everyone is allowed administrator rights.
                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("Allowed list is null. Everyone is allowed to request administrator rights.", EventID.DebugMessage);
                 #endif
                 */
                return(true);
            }
            else if (allowedSidsList.Length == 0)
            { // The allowed list is empty, meaning no one is allowed administrator rights.
                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("Allowed list is empty, but not null. No one is allowed to request administrator rights.", EventID.DebugMessage);
                 #endif
                 */
                return(false);
            }
            else
            { // The allowed list has entries.
                // If the user's SID is in the allowed list, the user is authorized.
                if ((ArrayContainsString(allowedSidsList, userIdentity.User.Value)) || (ArrayContainsString(allowedSidsList, userIdentity.Name)))
                {
                    /*
                     #if DEBUG
                     * ApplicationLog.WriteInformationEvent("Principal's SID is in the allowed list. Permission granted.", EventID.DebugMessage);
                     #endif
                     */
                    return(true);
                }

                // If any of the user's authorization groups are in the allowed list, the user is authorized.
                foreach (SecurityIdentifier sid in userIdentity.Groups)
                {
                    if (ArrayContainsString(allowedSidsList, sid.Value))
                    {
                        /*
                         #if DEBUG
                         * ApplicationLog.WriteInformationEvent("One of the principal's groups is in the allowed list. Permission granted.", EventID.DebugMessage);
                         #endif
                         */
                        return(true);
                    }

                    if (sid.IsValidTargetType(typeof(NTAccount)))
                    {
                        NTAccount account = (NTAccount)sid.Translate(typeof(NTAccount));
                        if (ArrayContainsString(allowedSidsList, account.Value))
                        {
                            /*
                             #if DEBUG
                             * ApplicationLog.WriteInformationEvent("One of the principal's groups is in the allowed list. Permission granted.", EventID.DebugMessage);
                             #endif
                             */
                            return(true);
                        }
                    }
                }


                // The user was not found in the allowed list, so the user is not authorized.

                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("Principal was not found in the allowed list. Permission denied.", EventID.DebugMessage);
                 #endif
                 */
                return(false);
            }
        }
        public static void ValidateAllAddedPrincipals()
        {
            SecurityIdentifier[] localAdminSids = null;

            /* string[] addedSids = PrincipalList.GetSIDs(); */
            SecurityIdentifier[] addedSids = PrincipalList.GetSIDs();

            if ((addedSids.Length > 0) && (LocalAdminGroup != null))
            {
                localAdminSids = GetLocalGroupMembers(null, LocalAdminGroup.SamAccountName);
            }

            for (int i = 0; i < addedSids.Length; i++)
            {
                bool sidFoundInAdminsGroup = false;
                if ((addedSids[i] != null) && (localAdminSids != null))
                {
                    foreach (SecurityIdentifier sid in localAdminSids)
                    {
                        if (sid == addedSids[i])
                        {
                            sidFoundInAdminsGroup = true;
                            break;
                        }
                    }

                    if (sidFoundInAdminsGroup)
                    {         // Principal's SID was found in the local administrators group.
                        if (PrincipalList.GetExpirationTime(addedSids[i]).HasValue)
                        {     // The principal's rights expire at some point.
                            if (PrincipalList.GetExpirationTime(addedSids[i]).Value > DateTime.Now)
                            { // The principal's administrator rights expire in the future.
                              // Nothing to do here, since the principal is already in the administrators group.
                            }
                            else
                            { // The principal's administrator rights have expired.
#if DEBUG
                                string accountName = GetAccountNameFromSID(addedSids[i]);
                                ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.DebugMessage);
#endif
                                LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout);
                            }
                        }

                        // TODO: This should be put back in, but it needs to account for the fact that
                        // some principals may be added without expiration times.

                        /*
                         * else
                         * { // The principal's rights never expire. This should never happen.
                         * // Remove the principal from the administrator group.
                         #if DEBUG
                         *  string accountName = GetAccountNameFromSID(addedSids[i]);
                         *  ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.DebugMessage);
                         #endif
                         *  LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout);
                         *
                         *  if (
                         *      (Settings.AutomaticAddAllowed != null) &&
                         *      (Settings.AutomaticAddAllowed.Length > 0) &&
                         *      (Shared.UserIsAuthorized(userIdentity, Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied))
                         *     )
                         *  {
                         #if DEBUG
                         *      ApplicationLog.WriteInformationEvent("User is allowed to be automatically added!", EventID.DebugMessage);
                         #endif
                         *      LocalAdministratorGroup.AddPrincipal(userIdentity, null, null);
                         *  }
                         * }
                         */
                    }
                    else
                    {         // Principal's SID was not found in the local administrators group.
                        if (PrincipalList.GetExpirationTime(addedSids[i]).HasValue)
                        {     // The principal's rights expire at some point.
                            if (PrincipalList.GetExpirationTime(addedSids[i]).Value > DateTime.Now)
                            { // The principal's administrator rights expire in the future.
                                string accountName = GetAccountNameFromSID(addedSids[i]);
                                if (Settings.OverrideRemovalByOutsideProcess)
                                {
                                    // TODO: i18n.
                                    ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Adding the principal back to the Administrators group.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.PrincipalRemovedByExternalProcess);
                                    AddPrincipalToAdministrators(addedSids[i], null);
                                }
                                else
                                {
                                    // TODO: i18n.
                                    ApplicationLog.WriteInformationEvent(string.Format("Principal {0} ({1}) has been removed from the Administrators group by an outside process. Removing the principal from Make Me Admin's list.", addedSids[i], string.IsNullOrEmpty(accountName) ? "unknown account" : accountName), EventID.PrincipalRemovedByExternalProcess);
                                    PrincipalList.RemoveSID(addedSids[i]);
                                    Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>();
                                }
                            }
                            else
                            { // The principal's administrator rights have expired.
                              // No need to remove from the administrators group, as we already know the SID
                              // is not present in the group.
#if DEBUG
                                ApplicationLog.WriteInformationEvent(string.Format("Removing SID \"{0}\" from the principal list.", addedSids[i]), EventID.DebugMessage);
#endif
                                PrincipalList.RemoveSID(addedSids[i]);
                                Settings.SIDs = PrincipalList.GetSIDs().Select(p => p.Value).ToArray <string>();
                            }
                        }

                        /*
                         * Rights shouldn't need to be removed here, as we already know the SID is not
                         * a member of the local administrator group.
                         * else
                         * { // The principal's rights never expire. This should never happen.
                         * // Remove the principal from the administrator. group.
                         *  LocalAdministratorGroup.RemovePrincipal(addedSids[i], RemovalReason.Timeout);
                         * }
                         */
                    }
                }
            }
        }
        protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            switch (changeDescription.Reason)
            {
            // The user has logged off from a session, either locally or remotely.
            case SessionChangeReason.SessionLogoff:
#if DEBUG
                ApplicationLog.WriteInformationEvent(string.Format("Session {0} has logged off.", changeDescription.SessionId), EventID.DebugMessage);
#endif
                //if (Settings.RemoveAdminRightsOnLogout)
                //{
                System.Collections.Generic.List <SecurityIdentifier> sidsToRemove = new System.Collections.Generic.List <SecurityIdentifier>(PrincipalList.GetSIDs());

                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("SID to remove list has been retrieved.", EventID.DebugMessage);
                 * for (int i = 0; i < sidsToRemove.Count; i++)
                 * {
                 *  ApplicationLog.WriteInformationEvent(string.Format("SID to remove: {0}", sidsToRemove[i]), EventID.DebugMessage);
                 * }
                 #endif
                 */

                int[] sessionIds = LsaLogonSessions.LogonSessions.GetLoggedOnUserSessionIds();
                foreach (int id in sessionIds)
                {
                    SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(id);
                    if (sid != null)
                    {
                        if (sidsToRemove.Contains(sid))
                        {
                            sidsToRemove.Remove(sid);
                        }
                    }
                }

                /*
                 #if DEBUG
                 * ApplicationLog.WriteInformationEvent("SID to remove list has been updated.", EventID.DebugMessage);
                 * for (int i = 0; i < sidsToRemove.Count; i++)
                 * {
                 *  ApplicationLog.WriteInformationEvent(string.Format("SID to remove: {0}", sidsToRemove[i]), EventID.DebugMessage);
                 * }
                 #endif
                 */

                for (int i = 0; i < sidsToRemove.Count; i++)
                {
                    if (
                        (!(PrincipalList.ContainsSID(sidsToRemove[i]) && PrincipalList.IsRemote(sidsToRemove[i])))
                        &&
                        (Settings.RemoveAdminRightsOnLogout || !PrincipalList.GetExpirationTime(sidsToRemove[i]).HasValue)
                        )
                    {
                        LocalAdministratorGroup.RemovePrincipal(sidsToRemove[i], RemovalReason.UserLogoff);
                    }
                }

                /*
                 * In theory, this code should remove the user associated with the logoff, but it doesn't work.
                 * SecurityIdentifier sid = LsaLogonSessions.LogonSessions.GetSidForSessionId(changeDescription.SessionId);
                 * if (!(PrincipalList.ContainsSID(sid) && PrincipalList.IsRemote(sid)))
                 * {
                 *  LocalAdministratorGroup.RemovePrincipal(sid, RemovalReason.UserLogoff);
                 * }
                 */
                //}

                /*
                 * else
                 * {
                 #if DEBUG
                 *  ApplicationLog.WriteInformationEvent("Removing admin rights on log off is disabled.", EventID.DebugMessage);
                 #endif
                 * }
                 */

                break;

            // The user has logged on to a session, either locally or remotely.
            case SessionChangeReason.SessionLogon:
#if DEBUG
                // TODO: i18n.
                ApplicationLog.WriteInformationEvent(string.Format("Session logon. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent);
#endif

                WindowsIdentity userIdentity = LsaLogonSessions.LogonSessions.GetWindowsIdentityForSessionId(changeDescription.SessionId);

                if (userIdentity != null)
                {
                    /*
                     #if DEBUG
                     * ApplicationLog.WriteInformationEvent("User identity is not null.", EventID.DebugMessage);
                     * ApplicationLog.WriteInformationEvent(string.Format("user name: {0}", userIdentity.Name), EventID.DebugMessage);
                     * ApplicationLog.WriteInformationEvent(string.Format("user SID: {0}", userIdentity.User), EventID.DebugMessage);
                     #endif
                     */

                    if (
                        (Settings.AutomaticAddAllowed != null) &&
                        (Settings.AutomaticAddAllowed.Length > 0) &&
                        (Shared.UserIsAuthorized(userIdentity, Settings.AutomaticAddAllowed, Settings.AutomaticAddDenied))
                        )
                    {
#if DEBUG
                        ApplicationLog.WriteInformationEvent("User is allowed to be automatically added!", EventID.DebugMessage);
#endif
                        LocalAdministratorGroup.AddPrincipal(userIdentity, null, null);
                    }
                }
                else
                {
                    // TODO: i18n.
                    ApplicationLog.WriteWarningEvent("User identity is null.", EventID.DebugMessage);
                }

                break;

                /*
                 * // The user has reconnected or logged on to a remote session.
                 * case SessionChangeReason.RemoteConnect:
                 *  ApplicationLog.WriteInformationEvent(string.Format("Remote connect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent);
                 *  break;
                 */

                /*
                 * // The user has disconnected or logged off from a remote session.
                 * case SessionChangeReason.RemoteDisconnect:
                 *  ApplicationLog.WriteInformationEvent(string.Format("Remote disconnect. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent);
                 *  break;
                 */

                /*
                 * // The user has locked their session.
                 * case SessionChangeReason.SessionLock:
                 *  ApplicationLog.WriteInformationEvent(string.Format("Session lock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent);
                 *  break;
                 */

                /*
                 * // The user has unlocked their session.
                 * case SessionChangeReason.SessionUnlock:
                 *  ApplicationLog.WriteInformationEvent(string.Format("Session unlock. Session ID: {0}", changeDescription.SessionId), EventID.SessionChangeEvent);
                 *  break;
                 */
            }

            base.OnSessionChange(changeDescription);
        }
 private void ServiceHostFaulted(object sender, EventArgs e)
 {
     // TODO: i18n.
     ApplicationLog.WriteInformationEvent("Service host faulted.", EventID.DebugMessage);
 }