private void EnforceSharingPolicy(MailboxSession mailboxSession, ICollection <MapiAclTableRestriction.ExternalUserPermission> externalUserPermissions)
        {
            Util.ThrowOnNullArgument(mailboxSession, "mailboxSession");
            if (externalUserPermissions == null || externalUserPermissions.Count == 0)
            {
                return;
            }
            List <RightsNotAllowedRecipient> list = new List <RightsNotAllowedRecipient>(externalUserPermissions.Count);
            SharingPolicy sharingPolicy           = null;

            foreach (MapiAclTableRestriction.ExternalUserPermission externalUserPermission in externalUserPermissions)
            {
                if (sharingPolicy == null)
                {
                    IMailboxInfo mailboxInfo = mailboxSession.MailboxOwner.MailboxInfo;
                    sharingPolicy = DirectoryHelper.ReadSharingPolicy(mailboxInfo.MailboxGuid, mailboxInfo.IsArchive, mailboxSession.GetADRecipientSession(true, ConsistencyMode.IgnoreInvalid));
                    if (sharingPolicy == null)
                    {
                        ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal>((long)this.GetHashCode(), "{0}: No policy assigned means no external sharing is allowed for this user.", mailboxSession.MailboxOwner);
                        throw new NotAllowedExternalSharingByPolicyException();
                    }
                }
                if (!sharingPolicy.Enabled)
                {
                    ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal>((long)this.GetHashCode(), "{0}: A disabled policy means no external sharing is allowed for this user.", mailboxSession.MailboxOwner);
                    throw new NotAllowedExternalSharingByPolicyException();
                }
                SharingPolicyAction sharingPolicyAction = externalUserPermission.Principal.ExternalUser.IsReachUser ? sharingPolicy.GetAllowedForAnonymousCalendarSharing() : sharingPolicy.GetAllowed(externalUserPermission.Principal.ExternalUser.SmtpAddress.Domain);
                if (sharingPolicyAction == (SharingPolicyAction)0)
                {
                    ExTraceGlobals.StorageTracer.TraceDebug <IExchangePrincipal, PermissionSecurityPrincipal>((long)this.GetHashCode(), "{0}: Policy does not allow granting permissions to {1}.", mailboxSession.MailboxOwner, externalUserPermission.Principal);
                    throw new PrincipalNotAllowedByPolicyException(externalUserPermission.Principal);
                }
                MemberRights allowed      = PolicyAllowedMemberRights.GetAllowed(sharingPolicyAction, this.FolderInfo.StoreObjectType);
                MemberRights memberRights = ~allowed & externalUserPermission.MemberRights;
                if (memberRights != MemberRights.None)
                {
                    ExTraceGlobals.StorageTracer.TraceDebug((long)this.GetHashCode(), "{0}: Policy does not allow granting permission {1} to {2} on {3} folder '{4}'.", new object[]
                    {
                        mailboxSession.MailboxOwner,
                        memberRights,
                        externalUserPermission.Principal,
                        this.FolderInfo.StoreObjectType,
                        this.FolderInfo.DisplayName
                    });
                    list.Add(new RightsNotAllowedRecipient(externalUserPermission.Principal, memberRights));
                }
            }
            if (list.Count > 0)
            {
                throw new RightsNotAllowedByPolicyException(list.ToArray(), this.FolderInfo.StoreObjectType, this.FolderInfo.DisplayName);
            }
        }
Exemplo n.º 2
0
        public EncryptionResults Encrypt(IExchangePrincipal mailboxOwner, IRecipientSession recipientSession, ExternalUserCollection externalUserCollection, ValidRecipient[] recipients, string sender, string containerClass, string folderId, IFrontEndLocator frontEndLocator)
        {
            SharingDataType sharingDataType = SharingDataType.FromContainerClass(containerClass);

            if (sharingDataType == null || !sharingDataType.IsExternallySharable)
            {
                throw new ArgumentOutOfRangeException("containerClass");
            }
            ADUser aduser = DirectoryHelper.ReadADRecipient(mailboxOwner.MailboxInfo.MailboxGuid, mailboxOwner.MailboxInfo.IsArchive, recipientSession) as ADUser;

            if (aduser == null)
            {
                SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, string>((long)this.GetHashCode(), "{0}: The Active Directory user was not found. Sender={1}.", this, sender);
                throw new ObjectNotFoundException(ServerStrings.ADUserNotFound);
            }
            ProxyAddress item = new SmtpProxyAddress(sender, false);

            if (!aduser.EmailAddresses.Contains(item))
            {
                SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, string>((long)this.GetHashCode(), "{0}: The SMTP address was not found in the user AD object for this mailbox. Sender={1}.", this, sender);
                throw new ObjectNotFoundException(ServerStrings.ADUserNotFound);
            }
            SharingPolicy sharingPolicy = DirectoryHelper.ReadSharingPolicy(mailboxOwner.MailboxInfo.MailboxGuid, mailboxOwner.MailboxInfo.IsArchive, recipientSession);

            SharedFolderDataEncryption.Tracer.TraceDebug <SharedFolderDataEncryption, object>((long)this.GetHashCode(), "{0}: Sharing policy to be applied to this user: {1}", this, (sharingPolicy == null) ? "<null>" : sharingPolicy.Id);
            SharingPolicyAction sharingPolicyActions = SharedFolderDataEncryption.GetSharingPolicyActions(sharingDataType.StoreObjectType);

            SharedFolderDataRecipient[] externalIdentities = SharedFolderDataEncryption.GetExternalIdentities(externalUserCollection, recipients);
            List <InvalidRecipient>     list = new List <InvalidRecipient>();
            Dictionary <TokenTarget, List <SharedFolderDataRecipient> > dictionary = new Dictionary <TokenTarget, List <SharedFolderDataRecipient> >(externalIdentities.Length, SharedFolderDataEncryption.TokenTargetComparer);

            for (int i = 0; i < recipients.Length; i++)
            {
                SharedFolderDataRecipient item2          = externalIdentities[i];
                ValidRecipient            validRecipient = recipients[i];
                SmtpAddress smtpAddress = new SmtpAddress(validRecipient.SmtpAddress);
                string      domain      = smtpAddress.Domain;
                if (sharingPolicy == null || !sharingPolicy.IsAllowedForAnySharing(domain, sharingPolicyActions))
                {
                    SharedFolderDataEncryption.Tracer.TraceDebug <string>((long)this.GetHashCode(), "Sharing policy does not allow user to share with domain {0}", domain);
                    list.Add(new InvalidRecipient(validRecipient.SmtpAddress, InvalidRecipientResponseCodeType.SystemPolicyBlocksSharingWithThisRecipient));
                }
                else
                {
                    SmtpAddress smtpAddress2 = new SmtpAddress(validRecipient.SmtpAddressForEncryption);
                    TokenTarget tokenTarget  = TargetUriResolver.Resolve(smtpAddress2.Domain, aduser.OrganizationId);
                    if (tokenTarget == null)
                    {
                        list.Add(new InvalidRecipient(validRecipient.SmtpAddress, InvalidRecipientResponseCodeType.RecipientOrganizationNotFederated));
                    }
                    else
                    {
                        List <SharedFolderDataRecipient> list2;
                        if (!dictionary.TryGetValue(tokenTarget, out list2))
                        {
                            list2 = new List <SharedFolderDataRecipient>(1);
                            dictionary.Add(tokenTarget, list2);
                        }
                        list2.Add(item2);
                    }
                }
            }
            List <EncryptedSharedFolderData> list3 = new List <EncryptedSharedFolderData>(dictionary.Count);
            SharedFolderData sharedFolderData      = new SharedFolderData();

            sharedFolderData.DataType          = sharingDataType.ExternalName;
            sharedFolderData.FolderId          = folderId;
            sharedFolderData.SharingUrl        = this.GetSharingUrl(aduser, frontEndLocator);
            sharedFolderData.FederationUri     = this.externalAuthentication.TokenValidator.TargetUri.ToString();
            sharedFolderData.SenderSmtpAddress = sender;
            DelegationTokenRequest delegationTokenRequest = new DelegationTokenRequest
            {
                FederatedIdentity = aduser.GetFederatedIdentity(),
                EmailAddress      = aduser.GetFederatedSmtpAddress(new SmtpAddress(sender)).ToString(),
                Offer             = Offer.SharingInviteMessage
            };
            SecurityTokenService securityTokenService = this.externalAuthentication.GetSecurityTokenService(aduser.OrganizationId);

            foreach (KeyValuePair <TokenTarget, List <SharedFolderDataRecipient> > keyValuePair in dictionary)
            {
                delegationTokenRequest.Target = keyValuePair.Key;
                sharedFolderData.Recipients   = keyValuePair.Value.ToArray();
                try
                {
                    RequestedToken requestedToken = securityTokenService.IssueToken(delegationTokenRequest);
                    list3.Add(this.Encrypt(requestedToken, sharedFolderData));
                }
                catch (WSTrustException ex)
                {
                    foreach (SharedFolderDataRecipient sharedFolderDataRecipient in sharedFolderData.Recipients)
                    {
                        list.Add(new InvalidRecipient(sharedFolderDataRecipient.SmtpAddress, SharedFolderDataEncryption.GetResponseCodeFromException(ex), ex.ToString()));
                    }
                }
            }
            return(new EncryptionResults(list3.ToArray(), list.ToArray()));
        }