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