Example #1
0
        private static RowEntry ConvertToRowEntry(AclTableEntry.ModifyOperation aclModifyOperation)
        {
            switch (aclModifyOperation.Operation)
            {
            case ModifyTableOperationType.Add:
                return(RowEntry.Add(new PropValue[]
                {
                    new PropValue(PropTag.EntryId, aclModifyOperation.Entry.MemberEntryId),
                    new PropValue(PropTag.MemberRights, aclModifyOperation.Entry.MemberRights)
                }));

            case ModifyTableOperationType.Modify:
                return(RowEntry.Modify(new PropValue[]
                {
                    new PropValue(PropTag.MemberId, aclModifyOperation.Entry.MemberId),
                    new PropValue(PropTag.MemberRights, aclModifyOperation.Entry.MemberRights)
                }));

            case ModifyTableOperationType.Remove:
                return(RowEntry.Remove(new PropValue[]
                {
                    new PropValue(PropTag.MemberId, aclModifyOperation.Entry.MemberId)
                }));

            default:
                return(RowEntry.Empty());
            }
        }
 public void ApplyPendingChanges()
 {
     this.CheckDisposed(null);
     AclTableEntry.ModifyOperation[] array = (from op in this.pendingModifyOperations
                                              select AclTableEntry.ModifyOperation.FromModifyTableOperation(op)).ToArray <AclTableEntry.ModifyOperation>();
     using (IQueryResult queryResult = this.currentPermissionsTable.GetQueryResult(null, new PropertyDefinition[]
     {
         PermissionSchema.MemberId,
         PermissionSchema.MemberEntryId
     }))
     {
         bool       flag;
         object[][] rows = queryResult.GetRows(queryResult.EstimatedRowCount, out flag);
         for (int i = 0; i < array.Length; i++)
         {
             AclTableEntry.ModifyOperation modifyOperation = array[i];
             switch (modifyOperation.Operation)
             {
             case ModifyTableOperationType.Modify:
             case ModifyTableOperationType.Remove:
                 if (modifyOperation.Entry.MemberId != -1L && modifyOperation.Entry.MemberId != 0L)
                 {
                     array[i] = new AclTableEntry.ModifyOperation(array[i].Operation, new AclTableEntry(array[i].Entry.MemberId, PrimaryHierarchyAclModifyTable.GetMemberEntryId(modifyOperation.Entry.MemberId, rows), array[i].Entry.MemberName, array[i].Entry.MemberRights));
                 }
                 break;
             }
         }
     }
     this.primaryHierarchyProvider.ModifyPermissions(this.coreFolder.Id, array, this.options, this.replaceAllRows);
     this.replaceAllRows = false;
     this.pendingModifyOperations.Clear();
 }
Example #3
0
        public void ModifyPermissions(StoreId folderId, AclTableEntry.ModifyOperation[] modifyOperations, ModifyTableOptions options, bool replaceAllRows)
        {
            using (PublicFolderConnectionLimitsTracker.Instance.GetToken(this.PrimaryHierarchyMailboxPrincipal.MailboxInfo.Location.ServerFqdn))
            {
                StoreSession storeSession = null;
                object       thisObject   = null;
                bool         flag         = false;
                try
                {
                    if (storeSession != null)
                    {
                        storeSession.BeginMapiCall();
                        storeSession.BeginServerHealthCall();
                        flag = true;
                    }
                    if (StorageGlobals.MapiTestHookBeforeCall != null)
                    {
                        StorageGlobals.MapiTestHookBeforeCall(MethodBase.GetCurrentMethod());
                    }
                    using (MapiStore hierarchyStore = this.GetHierarchyStore())
                    {
                        using (MapiFolder mapiFolder = (MapiFolder)hierarchyStore.OpenEntry(this.GetDestinationSpecificEntryId(hierarchyStore, folderId)))
                        {
                            using (MapiModifyTable mapiModifyTable = (MapiModifyTable)mapiFolder.OpenProperty(PropTag.AclTable, InterfaceIds.IExchangeModifyTable, 0, OpenPropertyFlags.DeferredErrors))
                            {
                                GetTableFlags    getTableFlags    = GetTableFlags.None;
                                ModifyTableFlags modifyTableFlags = ModifyTableFlags.None;
                                if (options == ModifyTableOptions.FreeBusyAware)
                                {
                                    getTableFlags    |= GetTableFlags.FreeBusy;
                                    modifyTableFlags |= ModifyTableFlags.FreeBusy;
                                }
                                if (replaceAllRows)
                                {
                                    modifyTableFlags |= ModifyTableFlags.RowListReplace;
                                }
                                using (MapiTable table = mapiModifyTable.GetTable(getTableFlags))
                                {
                                    Dictionary <byte[], long> entryIdToMemberIdMap = RPCPrimaryHierarchyProvider.GetEntryIdToMemberIdMap(table.QueryAllRows(null, RPCPrimaryHierarchyProvider.MapiAclTableColumns));
                                    List <RowEntry>           list = new List <RowEntry>(modifyOperations.Length);
                                    foreach (AclTableEntry.ModifyOperation modifyOperation in modifyOperations)
                                    {
                                        switch (modifyOperation.Operation)
                                        {
                                        case ModifyTableOperationType.Add:
                                            list.Add(RPCPrimaryHierarchyProvider.ConvertToRowEntry(modifyOperation));
                                            break;

                                        case ModifyTableOperationType.Modify:
                                        case ModifyTableOperationType.Remove:
                                        {
                                            AclTableEntry.ModifyOperation modifyOperation2 = modifyOperation;
                                            if (modifyOperation.Entry.MemberId != -1L && modifyOperation.Entry.MemberId != 0L)
                                            {
                                                if (entryIdToMemberIdMap.ContainsKey(modifyOperation.Entry.MemberEntryId))
                                                {
                                                    modifyOperation2 = new AclTableEntry.ModifyOperation(modifyOperation.Operation, new AclTableEntry(entryIdToMemberIdMap[modifyOperation.Entry.MemberEntryId], null, null, modifyOperation.Entry.MemberRights));
                                                }
                                                else if (modifyOperation.Operation == ModifyTableOperationType.Modify)
                                                {
                                                    modifyOperation2 = new AclTableEntry.ModifyOperation(ModifyTableOperationType.Add, new AclTableEntry(0L, modifyOperation.Entry.MemberEntryId, null, modifyOperation.Entry.MemberRights));
                                                }
                                                else
                                                {
                                                    modifyOperation2 = null;
                                                }
                                            }
                                            if (modifyOperation2 != null)
                                            {
                                                list.Add(RPCPrimaryHierarchyProvider.ConvertToRowEntry(modifyOperation2));
                                            }
                                            break;
                                        }
                                        }
                                    }
                                    mapiModifyTable.ModifyTable(modifyTableFlags, list.ToArray());
                                }
                            }
                        }
                    }
                }
                catch (MapiPermanentException ex)
                {
                    throw StorageGlobals.TranslateMapiException(ServerStrings.ExWrappedStreamFailure, ex, storeSession, thisObject, "{0}. MapiException = {1}.", new object[]
                    {
                        string.Format("RPCPrimaryHierarchyProvider.WriteAclPropertyStream : folderId = {0}", folderId),
                        ex
                    });
                }
                catch (MapiRetryableException ex2)
                {
                    throw StorageGlobals.TranslateMapiException(ServerStrings.ExWrappedStreamFailure, ex2, storeSession, thisObject, "{0}. MapiException = {1}.", new object[]
                    {
                        string.Format("RPCPrimaryHierarchyProvider.WriteAclPropertyStream : folderId = {0}", folderId),
                        ex2
                    });
                }
                finally
                {
                    try
                    {
                        if (storeSession != null)
                        {
                            storeSession.EndMapiCall();
                            if (flag)
                            {
                                storeSession.EndServerHealthCall();
                            }
                        }
                    }
                    finally
                    {
                        if (StorageGlobals.MapiTestHookAfterCall != null)
                        {
                            StorageGlobals.MapiTestHookAfterCall(MethodBase.GetCurrentMethod());
                        }
                    }
                }
            }
        }
Example #4
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;
            }
        }