private List <AclTableEntry> ParseTableEntries(ArraySegment <byte> tableSegment)
        {
            List <AclTableEntry> result;

            using (BinaryDeserializer binaryDeserializer = new BinaryDeserializer(tableSegment))
            {
                List <AclTableEntry> list    = FolderSecurity.AclTableEntry.ParseTableEntries <AclTableEntry>(binaryDeserializer.Reader, new Func <BinaryReader, AclTableEntry>(AclTableEntry.Parse));
                HashSet <string>     hashSet = null;
                if (list != null)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        AclTableEntry aclTableEntry = list[i];
                        if (aclTableEntry.MemberEntryId != null && aclTableEntry.MemberEntryId.Length != 0)
                        {
                            if (hashSet == null)
                            {
                                hashSet = new HashSet <string>();
                            }
                            string text = AclHelper.LegacyDnFromEntryId(aclTableEntry.MemberEntryId);
                            if (!hashSet.Add(text.ToLower()))
                            {
                                return(null);
                            }
                        }
                        if (aclTableEntry.MemberId != 0L && aclTableEntry.MemberId != -1L)
                        {
                            aclTableEntry.SetMemberId(AclModifyTable.GetIdForSecurityIdentifier(aclTableEntry.SecurityIdentifier, null, this.coreFolder.AclTableIdMap));
                        }
                    }
                }
                result = list;
            }
            return(result);
        }
 private void FixRightsIfNeeded(AclTableEntry tableEntry)
 {
     if ((tableEntry.MemberRights & MemberRights.FreeBusyDetailed) == MemberRights.FreeBusyDetailed)
     {
         tableEntry.MemberRights |= MemberRights.FreeBusySimple;
     }
     if ((this.options & ModifyTableOptions.FreeBusyAware) != ModifyTableOptions.FreeBusyAware)
     {
         if (tableEntry.MemberId == -1L)
         {
             tableEntry.MemberRights &= ~(MemberRights.FreeBusySimple | MemberRights.FreeBusyDetailed);
         }
         else
         {
             tableEntry.MemberRights |= MemberRights.FreeBusySimple;
             if ((tableEntry.MemberRights & MemberRights.ReadAny) == MemberRights.ReadAny)
             {
                 tableEntry.MemberRights |= MemberRights.FreeBusyDetailed;
             }
         }
     }
     if ((tableEntry.MemberRights & (MemberRights.ReadAny | MemberRights.Owner)) != MemberRights.None)
     {
         tableEntry.MemberRights |= MemberRights.Visible;
     }
     if ((tableEntry.MemberRights & MemberRights.DeleteAny) != MemberRights.None)
     {
         tableEntry.MemberRights |= MemberRights.DeleteOwned;
     }
     if ((tableEntry.MemberRights & MemberRights.EditAny) != MemberRights.None)
     {
         tableEntry.MemberRights |= MemberRights.EditOwned;
     }
 }
        private static AclTableEntry BuildAnonymousDefaultEntry()
        {
            AclTableEntry aclTableEntry = new AclTableEntry(-1L, Array <byte> .Empty, "Anonymous", MemberRights.None);

            aclTableEntry.SetSecurityIdentifier(new SecurityIdentifier(WellKnownSidType.AnonymousSid, null), false);
            return(aclTableEntry);
        }
        private static AclTableEntry BuildEveryoneDefaultEntry(MemberRights rights)
        {
            AclTableEntry aclTableEntry = new AclTableEntry(0L, Array <byte> .Empty, string.Empty, rights);

            aclTableEntry.SetSecurityIdentifier(new SecurityIdentifier(WellKnownSidType.WorldSid, null), false);
            return(aclTableEntry);
        }
        private MapiAclTableRestriction.ExternalUserPermission TryGetExternalUserPermission(AclTableEntry aclTableEntry, MapiAclTableAdapter mapiAclTableAdapter, ref ExternalUserCollection externalUsers)
        {
            Util.ThrowOnNullArgument(aclTableEntry, "aclTableEntry");
            Util.ThrowOnNullArgument(mapiAclTableAdapter, "mapiAclTableAdapter");
            MailboxSession mailboxSession = this.session as MailboxSession;

            if (mailboxSession == null)
            {
                return(null);
            }
            byte[]       memberEntryId = aclTableEntry.MemberEntryId;
            MemberRights memberRights  = aclTableEntry.MemberRights;
            long         memberId      = aclTableEntry.MemberId;

            if (memberEntryId == null || memberEntryId.Length == 0)
            {
                if (memberId <= 0L)
                {
                    return(null);
                }
                ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal, long>((long)this.GetHashCode(), "{0}: Getting memberEntryId from current ACL table for MemberId {1}.", mailboxSession.MailboxOwner, memberId);
                AclTableEntry byMemberId = mapiAclTableAdapter.GetByMemberId(memberId);
                if (byMemberId == null || byMemberId.MemberEntryId == null)
                {
                    ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal, long>((long)this.GetHashCode(), "{0}: Not found memberEntryId from current ACL table for MemberId {1}. Skipped.", mailboxSession.MailboxOwner, memberId);
                    return(null);
                }
                memberEntryId = byMemberId.MemberEntryId;
            }
            if (mapiAclTableAdapter.TryGetParticipantEntryId(memberEntryId) != null)
            {
                ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal>((long)this.GetHashCode(), "{0}: MemberEntryId indicates internal user. Skipped.", mailboxSession.MailboxOwner);
                return(null);
            }
            ExternalUser externalUser = mapiAclTableAdapter.TryGetExternalUser(memberEntryId, ref externalUsers);

            if (externalUser == null)
            {
                ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal>((long)this.GetHashCode(), "{0}: MemberEntryId is not external user. Skipped.", mailboxSession.MailboxOwner);
                return(null);
            }
            return(new MapiAclTableRestriction.ExternalUserPermission(externalUser, memberRights));
        }
            public static AclTableEntry.ModifyOperation FromModifyTableOperation(ModifyTableOperation modifyTableOperation)
            {
                long?num = null;

                byte[]       array        = null;
                MemberRights?memberRights = null;
                string       text         = null;

                byte[] array2 = null;
                bool?  flag   = null;

                foreach (PropValue propValue in modifyTableOperation.Properties)
                {
                    if (propValue.Property == PermissionSchema.MemberId)
                    {
                        num = new long?((long)propValue.Value);
                    }
                    else if (propValue.Property == PermissionSchema.MemberEntryId)
                    {
                        array = (byte[])propValue.Value;
                    }
                    else if (propValue.Property == PermissionSchema.MemberRights)
                    {
                        memberRights = new MemberRights?((MemberRights)((int)propValue.Value));
                    }
                    else if (propValue.Property == PermissionSchema.MemberName)
                    {
                        text = (string)propValue.Value;
                    }
                    else if (propValue.Property == PermissionSchema.MemberSecurityIdentifier)
                    {
                        array2 = (byte[])propValue.Value;
                    }
                    else
                    {
                        if (propValue.Property != PermissionSchema.MemberIsGroup)
                        {
                            throw new InvalidParamException(new LocalizedString("Unexpected property in modification entry"));
                        }
                        flag = new bool?((bool)propValue.Value);
                    }
                }
                AclTableEntry aclTableEntry = null;

                switch (modifyTableOperation.Operation)
                {
                case ModifyTableOperationType.Add:
                    if (array == null || memberRights == null || num != null || (text != null && (array2 == null || flag == null)))
                    {
                        throw new InvalidParamException(new LocalizedString("Invalid modification(add) entry"));
                    }
                    aclTableEntry = new AclTableEntry(0L, array, string.Empty, memberRights.Value);
                    break;

                case ModifyTableOperationType.Modify:
                    if (num == null || memberRights == null || array != null || text != null)
                    {
                        throw new InvalidParamException(new LocalizedString("Invalid modification(modify) entry"));
                    }
                    aclTableEntry = new AclTableEntry(num.Value, null, string.Empty, memberRights.Value);
                    break;

                case ModifyTableOperationType.Remove:
                    if (num == null || memberRights != null || array != null || text != null)
                    {
                        throw new InvalidParamException(new LocalizedString("Invalid modification(remove) entry"));
                    }
                    aclTableEntry = new AclTableEntry(num.Value, null, string.Empty, MemberRights.None);
                    break;
                }
                return(new AclTableEntry.ModifyOperation(modifyTableOperation.Operation, aclTableEntry));
            }
 internal ModifyOperation(ModifyTableOperationType operation, AclTableEntry tableEntry)
 {
     this.operation  = operation;
     this.tableEntry = tableEntry;
 }
        private static List <AclTableEntry> BuildAclTableFromSecurityDescriptor(RawSecurityDescriptor securityDescriptor, RawSecurityDescriptor freeBusySecurityDescriptor, LazilyInitialized <ExternalUserCollection> lazilyInitializedExternalUserCollection, IRecipientSession recipientSession, AclTableIdMap aclTableIdMap, out bool isCanonical, out string canonicalErrorInformation)
        {
            FolderSecurity.AnnotatedAceList annotatedAceList = new FolderSecurity.AnnotatedAceList(securityDescriptor, freeBusySecurityDescriptor, (SecurityIdentifier securityIdentifier) => AclModifyTable.GetSecurityIdentifierType(recipientSession, securityIdentifier));
            isCanonical = annotatedAceList.IsCanonical(out canonicalErrorInformation);
            IList <FolderSecurity.SecurityIdentifierAndFolderRights> list;

            if (isCanonical)
            {
                list = annotatedAceList.GetSecurityIdentifierAndRightsList();
            }
            else
            {
                ExTraceGlobals.StorageTracer.TraceWarning <string, string>(0L, "Got non canonical SD: {0}, ErrorInfo: ", securityDescriptor.GetSddlForm(AccessControlSections.All), canonicalErrorInformation);
                list = Array <FolderSecurity.SecurityIdentifierAndFolderRights> .Empty;
            }
            List <AclTableEntry> list2 = new List <AclTableEntry>(list.Count + 1);

            foreach (FolderSecurity.SecurityIdentifierAndFolderRights securityIdentifierAndFolderRights in list)
            {
                MemberRights memberRights = (MemberRights)(securityIdentifierAndFolderRights.AllowRights & ~(MemberRights)securityIdentifierAndFolderRights.DenyRights);
                bool         flag         = false;
                bool         flag2        = false;
                byte[]       entryId;
                string       text;
                List <SecurityIdentifier> list3;
                SecurityIdentifier        securityIdentifier;
                if (securityIdentifierAndFolderRights.SecurityIdentifier.IsWellKnown(WellKnownSidType.WorldSid))
                {
                    entryId = Array <byte> .Empty;
                    text    = string.Empty;
                    string legacyDN = string.Empty;
                    securityIdentifier = securityIdentifierAndFolderRights.SecurityIdentifier;
                    list3 = null;
                    flag2 = true;
                }
                else if (securityIdentifierAndFolderRights.SecurityIdentifier.IsWellKnown(WellKnownSidType.AnonymousSid))
                {
                    entryId            = Array <byte> .Empty;
                    text               = "Anonymous";
                    securityIdentifier = securityIdentifierAndFolderRights.SecurityIdentifier;
                    list3              = null;
                }
                else if (ExternalUser.IsExternalUserSid(securityIdentifierAndFolderRights.SecurityIdentifier))
                {
                    ExternalUser externalUser = AclHelper.TryGetExternalUser(securityIdentifierAndFolderRights.SecurityIdentifier, lazilyInitializedExternalUserCollection);
                    if (externalUser == null)
                    {
                        ExTraceGlobals.StorageTracer.TraceWarning <SecurityIdentifier>(0L, "Cannot find external user with SID {0}, build entry from information we have", securityIdentifierAndFolderRights.SecurityIdentifier);
                        string text2 = AclHelper.CreateLocalUserStrignRepresentation(securityIdentifierAndFolderRights.SecurityIdentifier);
                        text = text2;
                    }
                    else
                    {
                        text = externalUser.Name;
                        string legacyDN = externalUser.LegacyDn;
                    }
                    entryId            = AddressBookEntryId.MakeAddressBookEntryIDFromLocalDirectorySid(securityIdentifierAndFolderRights.SecurityIdentifier);
                    securityIdentifier = securityIdentifierAndFolderRights.SecurityIdentifier;
                    list3 = null;
                }
                else
                {
                    MiniRecipient miniRecipient = recipientSession.FindMiniRecipientBySid <MiniRecipient>(securityIdentifierAndFolderRights.SecurityIdentifier, Array <PropertyDefinition> .Empty);
                    string        legacyDN;
                    if (miniRecipient == null)
                    {
                        ExTraceGlobals.StorageTracer.TraceWarning <SecurityIdentifier>(0L, "Cannot find recipient with SID {0}, build entry from the information we have", securityIdentifierAndFolderRights.SecurityIdentifier);
                        flag = (securityIdentifierAndFolderRights.SecurityIdentifierType == FolderSecurity.SecurityIdentifierType.Group);
                        string text3 = AclHelper.CreateNTUserStrignRepresentation(securityIdentifierAndFolderRights.SecurityIdentifier);
                        text               = text3;
                        legacyDN           = text3;
                        securityIdentifier = securityIdentifierAndFolderRights.SecurityIdentifier;
                        list3              = null;
                    }
                    else
                    {
                        flag = AclHelper.IsGroupRecipientType(miniRecipient.RecipientType);
                        if (string.IsNullOrEmpty(miniRecipient.DisplayName))
                        {
                            text = AclHelper.CreateNTUserStrignRepresentation(securityIdentifierAndFolderRights.SecurityIdentifier);
                        }
                        else
                        {
                            text = miniRecipient.DisplayName;
                        }
                        if (string.IsNullOrEmpty(miniRecipient.LegacyExchangeDN))
                        {
                            legacyDN = text;
                        }
                        else
                        {
                            legacyDN = miniRecipient.LegacyExchangeDN;
                        }
                        SecurityIdentifier masterAccountSid = miniRecipient.MasterAccountSid;
                        if (masterAccountSid != null && !masterAccountSid.IsWellKnown(WellKnownSidType.SelfSid))
                        {
                            securityIdentifier = masterAccountSid;
                            list3 = null;
                        }
                        else
                        {
                            securityIdentifier = miniRecipient.Sid;
                            MultiValuedProperty <SecurityIdentifier> sidHistory = miniRecipient.SidHistory;
                            if (sidHistory != null && sidHistory.Count != 0)
                            {
                                list3 = new List <SecurityIdentifier>(sidHistory);
                            }
                            else
                            {
                                list3 = null;
                            }
                        }
                    }
                    entryId = AddressBookEntryId.MakeAddressBookEntryID(legacyDN, flag);
                }
                AclTableEntry aclTableEntry = list2.Find((AclTableEntry entry) => entry.SecurityIdentifier == securityIdentifier);
                if (aclTableEntry == null && list3 != null)
                {
                    using (List <SecurityIdentifier> .Enumerator enumerator2 = list3.GetEnumerator())
                    {
                        while (enumerator2.MoveNext())
                        {
                            SecurityIdentifier sid = enumerator2.Current;
                            aclTableEntry = list2.Find((AclTableEntry entry) => entry.SecurityIdentifier == sid);
                            if (aclTableEntry != null)
                            {
                                break;
                            }
                        }
                    }
                }
                if (aclTableEntry == null)
                {
                    aclTableEntry = new AclTableEntry(AclModifyTable.GetIdForSecurityIdentifier(securityIdentifier, list3, aclTableIdMap), entryId, text, memberRights);
                    aclTableEntry.SetSecurityIdentifier(securityIdentifier, flag);
                    if (flag2)
                    {
                        list2.Insert(0, aclTableEntry);
                    }
                    else
                    {
                        list2.Add(aclTableEntry);
                    }
                }
                else
                {
                    aclTableEntry.MemberRights &= memberRights;
                    if (aclTableEntry.IsGroup != flag)
                    {
                        throw new NonCanonicalACLException(annotatedAceList.CreateErrorInformation((LID)35788U, new int[0]));
                    }
                    aclTableEntry.SetSecurityIdentifier(securityIdentifier, flag);
                }
            }
            return(list2);
        }
        public void ApplyPendingChanges()
        {
            this.CheckDisposed(null);
            bool flag = (this.options & ModifyTableOptions.ExtendedPermissionInformation) == ModifyTableOptions.ExtendedPermissionInformation;
            IRecipientSession recipientSession = this.recipientSession;

            if (flag)
            {
                this.recipientSession = null;
            }
            try
            {
                if (!this.propertyTableRestrictionSuppressed && this.modifyTableRestriction != null)
                {
                    this.modifyTableRestriction.Enforce(this, this.pendingModifyOperations);
                }
                if (this.replaceAllRows)
                {
                    this.tableEntries.Clear();
                }
                List <long> list = new List <long>(1);
                AclTableEntry.ModifyOperation[] array = (from op in this.pendingModifyOperations
                                                         select AclTableEntry.ModifyOperation.FromModifyTableOperation(op)).ToArray <AclTableEntry.ModifyOperation>();
                for (int i = 0; i < array.Length; i++)
                {
                    AclTableEntry.ModifyOperation aclModifyOperation = array[i];
                    if ((aclModifyOperation.Entry.MemberRights & (MemberRights.FreeBusySimple | MemberRights.FreeBusyDetailed)) != MemberRights.None && (this.options & ModifyTableOptions.FreeBusyAware) != ModifyTableOptions.FreeBusyAware)
                    {
                        throw new InvalidParamException(new LocalizedString("F/B unaware clients sent F/B rights"));
                    }
                    switch (aclModifyOperation.Operation)
                    {
                    case ModifyTableOperationType.Add:
                    {
                        SecurityIdentifier        securityIdentifier = null;
                        List <SecurityIdentifier> sidHistory         = null;
                        bool   flag2      = false;
                        string memberName = null;
                        string arg;
                        if (flag)
                        {
                            arg = AclHelper.LegacyDnFromEntryId(aclModifyOperation.Entry.MemberEntryId);
                            bool flag3 = false;
                            bool flag4 = false;
                            bool flag5 = false;
                            foreach (PropValue propValue in this.pendingModifyOperations[i].Properties)
                            {
                                if (propValue.Property == PermissionSchema.MemberIsGroup)
                                {
                                    flag3 = true;
                                    flag2 = (bool)propValue.Value;
                                }
                                else if (propValue.Property == PermissionSchema.MemberSecurityIdentifier)
                                {
                                    flag5 = true;
                                    securityIdentifier = new SecurityIdentifier((byte[])propValue.Value, 0);
                                }
                                else if (propValue.Property == PermissionSchema.MemberName)
                                {
                                    flag4      = true;
                                    memberName = (string)propValue.Value;
                                }
                            }
                            if (!flag3 || !flag4 || !flag5)
                            {
                                throw new InvalidOperationException(string.Format("Required property is missing. IsGroupFound={0}, DisplayNameFound={1}, SecurityIdentifierFound={2}", flag3, flag4, flag5));
                            }
                        }
                        else if (!AclHelper.TryGetUserFromEntryId(aclModifyOperation.Entry.MemberEntryId, this.Session, this.recipientSession, new LazilyInitialized <ExternalUserCollection>(() => this.GetExternalUsers(this.Session)), out arg, out securityIdentifier, out sidHistory, out flag2, out memberName))
                        {
                            ExTraceGlobals.StorageTracer.TraceWarning <string>(0L, "Cannot find recipient for LegDN {0}, skip this entry", arg);
                            break;
                        }
                        aclModifyOperation.Entry.SetSecurityIdentifier(securityIdentifier, flag2);
                        aclModifyOperation.Entry.SetMemberId(AclModifyTable.GetIdForSecurityIdentifier(securityIdentifier, sidHistory, this.coreFolder.AclTableIdMap));
                        aclModifyOperation.Entry.SetMemberName(memberName);
                        int num = this.tableEntries.FindIndex((AclTableEntry aclTableEntry) => aclTableEntry.MemberId == aclModifyOperation.Entry.MemberId);
                        if (num != -1)
                        {
                            this.tableEntries.RemoveAt(num);
                        }
                        this.FixRightsIfNeeded(aclModifyOperation.Entry);
                        if (flag2)
                        {
                            this.tableEntries.Add(aclModifyOperation.Entry);
                        }
                        else if (this.tableEntries.Count == 0 || this.tableEntries[0].MemberId != 0L)
                        {
                            this.tableEntries.Insert(0, aclModifyOperation.Entry);
                        }
                        else
                        {
                            this.tableEntries.Insert(1, aclModifyOperation.Entry);
                        }
                        break;
                    }

                    case ModifyTableOperationType.Modify:
                    {
                        if (this.replaceAllRows && aclModifyOperation.Entry.MemberId != -1L && aclModifyOperation.Entry.MemberId != 0L)
                        {
                            throw new InvalidParamException(new LocalizedString("Modify with ReplaceAllRows"));
                        }
                        AclTableEntry aclTableEntry2 = this.tableEntries.Find((AclTableEntry aclTableEntry) => aclTableEntry.MemberId == aclModifyOperation.Entry.MemberId);
                        if (aclTableEntry2 == null)
                        {
                            if (aclModifyOperation.Entry.MemberId == -1L)
                            {
                                aclTableEntry2 = AclModifyTable.BuildAnonymousDefaultEntry();
                                this.tableEntries.Add(aclTableEntry2);
                            }
                            else
                            {
                                if (aclModifyOperation.Entry.MemberId != 0L)
                                {
                                    throw new ObjectNotFoundException(new LocalizedString("AclTableEntry not found"));
                                }
                                aclTableEntry2 = AclModifyTable.BuildEveryoneDefaultEntry(MemberRights.FreeBusySimple);
                                this.tableEntries.Add(aclTableEntry2);
                            }
                        }
                        this.FixRightsIfNeeded(aclModifyOperation.Entry);
                        aclTableEntry2.MemberRights = aclModifyOperation.Entry.MemberRights;
                        break;
                    }

                    case ModifyTableOperationType.Remove:
                    {
                        if (this.replaceAllRows)
                        {
                            throw new InvalidParamException(new LocalizedString("Remove with ReplaceAllRows"));
                        }
                        bool flag6 = false;
                        for (int k = i + 1; k < array.Length; k++)
                        {
                            if (array[k].Operation == ModifyTableOperationType.Modify && aclModifyOperation.Entry.MemberId == array[k].Entry.MemberId)
                            {
                                flag6 = true;
                            }
                        }
                        if (!flag6)
                        {
                            int num2 = this.tableEntries.FindIndex((AclTableEntry aclTableEntry) => aclTableEntry.MemberId == aclModifyOperation.Entry.MemberId);
                            if (num2 == -1)
                            {
                                if (!list.Contains(aclModifyOperation.Entry.MemberId))
                                {
                                    throw new ObjectNotFoundException(new LocalizedString("AclTableEntry not found"));
                                }
                            }
                            else
                            {
                                list.Add(aclModifyOperation.Entry.MemberId);
                                this.tableEntries.RemoveAt(num2);
                            }
                        }
                        break;
                    }
                    }
                }
                this.replaceAllRows = false;
                this.pendingModifyOperations.Clear();
                this.Save();
            }
            finally
            {
                this.recipientSession = recipientSession;
            }
        }