Пример #1
0
        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);
        }
Пример #2
0
 public static bool TryGetUserFromEntryId(byte[] memberEntryId, StoreSession session, IRecipientSession recipientSession, LazilyInitialized <ExternalUserCollection> externalUsers, out string legacyDN, out SecurityIdentifier securityIdentifier, out List <SecurityIdentifier> sidHistory, out bool isGroup, out string displayName)
 {
     legacyDN = AclHelper.LegacyDnFromEntryId(memberEntryId);
     if (AddressBookEntryId.IsLocalDirctoryAddressBookEntryId(memberEntryId))
     {
         sidHistory = null;
         return(AclHelper.ResolveLocalDirectoryUserFromAddressBookEntryId(memberEntryId, externalUsers, out securityIdentifier, out isGroup, out displayName));
     }
     return(AclHelper.ResolveRecipientParametersFromLegacyDN(legacyDN, session, recipientSession, out securityIdentifier, out sidHistory, out isGroup, out displayName));
 }
Пример #3
0
        private static bool ResolveRecipientParametersFromLegacyDN(string legacyDN, StoreSession session, IRecipientSession recipientSession, out SecurityIdentifier securityIdentifier, out List <SecurityIdentifier> sidHistory, out bool isGroup, out string displayName)
        {
            securityIdentifier = null;
            sidHistory         = null;
            isGroup            = false;
            displayName        = string.Empty;
            if (legacyDN == string.Empty)
            {
                securityIdentifier = AclHelper.everyoneSecurityIdentifier;
                return(true);
            }
            if (string.Compare(legacyDN, "Anonymous", StringComparison.OrdinalIgnoreCase) == 0)
            {
                securityIdentifier = AclHelper.anonymousSecurityIdentifier;
                displayName        = "Anonymous";
                return(true);
            }
            MiniRecipient[] array = recipientSession.FindMiniRecipient(null, QueryScope.SubTree, new ComparisonFilter(ComparisonOperator.Equal, MiniRecipientSchema.LegacyExchangeDN, legacyDN), null, 2, Array <PropertyDefinition> .Empty);
            if (array == null || array.Length == 0)
            {
                return(false);
            }
            if (array.Length > 1)
            {
                throw new NonUniqueLegacyExchangeDNException(ServerStrings.ErrorNonUniqueLegacyDN(legacyDN));
            }
            SecurityIdentifier masterAccountSid = array[0].MasterAccountSid;

            if (masterAccountSid != null && !masterAccountSid.IsWellKnown(WellKnownSidType.SelfSid))
            {
                securityIdentifier = masterAccountSid;
            }
            else
            {
                securityIdentifier = array[0].Sid;
                MultiValuedProperty <SecurityIdentifier> sidHistory2 = array[0].SidHistory;
                if (sidHistory2 != null && sidHistory2.Count != 0)
                {
                    sidHistory = new List <SecurityIdentifier>(sidHistory2);
                }
            }
            if (securityIdentifier == null)
            {
                throw new CorruptDataException(ServerStrings.UserSidNotFound(legacyDN));
            }
            isGroup = AclHelper.IsGroupRecipientType(array[0].RecipientType);
            if (!AclHelper.IsNTUserLegacyDN(legacyDN, session.InternalPreferedCulture, securityIdentifier, out displayName))
            {
                displayName = array[0].DisplayName;
            }
            return(true);
        }
Пример #4
0
        private static bool ResolveLocalDirectoryUserFromAddressBookEntryId(byte[] entryId, LazilyInitialized <ExternalUserCollection> externalUsers, out SecurityIdentifier securityIdentifier, out bool isGroup, out string displayName)
        {
            securityIdentifier = null;
            isGroup            = false;
            displayName        = string.Empty;
            securityIdentifier = AddressBookEntryId.MakeSidFromLocalDirctoryAddressBookEntryId(entryId);
            ExternalUser externalUser = AclHelper.TryGetExternalUser(securityIdentifier, externalUsers);

            if (externalUser == null)
            {
                throw new ExternalUserNotFoundException(securityIdentifier);
            }
            displayName = externalUser.Name;
            return(true);
        }
Пример #5
0
        private static FolderSecurity.SecurityIdentifierType GetSecurityIdentifierType(IRecipientSession recipientSession, SecurityIdentifier securityIdentifier)
        {
            if (ExternalUser.IsExternalUserSid(securityIdentifier))
            {
                return(FolderSecurity.SecurityIdentifierType.User);
            }
            ADRecipient adrecipient = recipientSession.FindBySid(securityIdentifier);

            if (adrecipient == null)
            {
                return(FolderSecurity.SecurityIdentifierType.Unknown);
            }
            if (!AclHelper.IsGroupRecipientType(adrecipient.RecipientType))
            {
                return(FolderSecurity.SecurityIdentifierType.User);
            }
            return(FolderSecurity.SecurityIdentifierType.Group);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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;
            }
        }
Пример #8
0
 public static bool TryGetUserFromEntryId(byte[] memberEntryId, StoreSession session, IRecipientSession recipientSession, ExternalUserCollection externalUsers, out string legacyDN, out SecurityIdentifier securityIdentifier, out List <SecurityIdentifier> sidHistory, out bool isGroup, out string displayName)
 {
     return(AclHelper.TryGetUserFromEntryId(memberEntryId, session, recipientSession, new LazilyInitialized <ExternalUserCollection>(() => externalUsers), out legacyDN, out securityIdentifier, out sidHistory, out isGroup, out displayName));
 }