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