Ejemplo n.º 1
0
        public void CreatePublicFolderMessage(MailRecipient recipient, DeliverableItem item)
        {
            PublicFolderSession publicFolderSession = (PublicFolderSession)this.storeSession;
            bool flag = false;

            try
            {
                this.context.BeginTrackLatency(LatencyComponent.StoreDriverDeliveryRpc);
                using (Folder folder = Folder.Bind(publicFolderSession, this.deliverToFolder, new PropertyDefinition[]
                {
                    FolderSchema.SecurityDescriptor
                }))
                {
                    switch (MailPublicFolderPermissionHandler.CheckAccessForEmailDelivery(this.context, folder))
                    {
                    case AccessCheckResult.NotAllowedAnonymous:
                        DeliveryItem.Diag.TraceError(0L, "Anonymous users are not permitted to add contents to mail enabled public folder.");
                        throw new SmtpResponseException(AckReason.NotAuthenticated, MessageAction.NDR);

                    case AccessCheckResult.NotAllowedAuthenticated:
                        DeliveryItem.Diag.TraceError <RoutingAddress>(0L, "User {0} is not permitted to add contents to mail enabled public folder.", this.context.MbxTransportMailItem.From);
                        throw new SmtpResponseException(AckReason.RecipientPermissionRestricted, MessageAction.NDR);

                    case AccessCheckResult.NotAllowedInternalSystemError:
                        DeliveryItem.Diag.TraceError(0L, "Exception occured when determining permission for sender on public folder");
                        throw new SmtpResponseException(AckReason.PublicFolderSenderValidationFailed, MessageAction.NDR);

                    default:
                        if (folder.IsContentAvailable())
                        {
                            this.messageItem = MessageItem.CreateForDelivery(publicFolderSession, folder.Id, this.context.ReplayItem.InternetMessageId, this.context.ReplayItem.GetValueAsNullable <ExDateTime>(ItemSchema.SentTime));
                            if (this.messageItem != null && this.messageItem.DisposeTracker != null)
                            {
                                this.messageItem.DisposeTracker.AddExtraDataWithStackTrace("DeliveryItem owns messageItem at:{0}{1}");
                            }
                            flag = true;
                        }
                        else
                        {
                            this.ReroutePublicFolderRecipient(publicFolderSession, folder, recipient);
                        }
                        break;
                    }
                }
            }
            finally
            {
                TimeSpan additionalLatency = this.context.EndTrackLatency(LatencyComponent.StoreDriverDeliveryRpc);
                this.context.AddRpcLatency(additionalLatency, "Open message");
            }
            if (flag)
            {
                ItemConversion.ReplayInboundContent(this.context.ReplayItem, this.messageItem);
            }
        }
        internal static AccessCheckResult CheckAccessForEmailDelivery(MailItemDeliver mailItemDeliver, Folder mailPublicFolder)
        {
            if (mailItemDeliver == null)
            {
                throw new ArgumentNullException("MailItemDeliver");
            }
            if (mailPublicFolder == null)
            {
                throw new ArgumentNullException("MailPublicFolder");
            }
            if (mailItemDeliver.ReplayItem == null)
            {
                MailPublicFolderPermissionHandler.Diag.TraceError(0L, "ReplayItem for the message appears to be null.");
                return(AccessCheckResult.NotAllowedInternalSystemError);
            }
            if (mailItemDeliver.ReplayItem.From == null)
            {
                MailPublicFolderPermissionHandler.Diag.TraceError(0L, "From attribute of the ReplayItem for the given message appears to be null.");
                return(AccessCheckResult.NotAllowedInternalSystemError);
            }
            AccessCheckResult     accessCheckResult = AccessCheckResult.NotAllowedAuthenticated;
            ClientSecurityContext context           = null;
            bool isAnonymous = false;
            ADRecipientCache <TransportMiniRecipient> recipientCache = mailItemDeliver.MbxTransportMailItem.ADRecipientCache;
            IRecipientSession recipientSession = (recipientCache != null) ? recipientCache.ADSession : null;

            if (recipientSession != null)
            {
                recipientSession = DirectorySessionFactory.Default.GetTenantOrRootOrgRecipientSession(ConsistencyMode.IgnoreInvalid, ADSessionSettings.FromOrganizationIdWithoutRbacScopesServiceOnly(recipientSession.SessionSettings.CurrentOrganizationId), 146, "CheckAccessForEmailDelivery", "f:\\15.00.1497\\sources\\dev\\MailboxTransport\\src\\MailboxTransportDelivery\\StoreDriver\\MailPublicFolderPermissionHandler.cs");
                try
                {
                    GrayException.MapAndReportGrayExceptions(delegate()
                    {
                        Participant from = mailItemDeliver.ReplayItem.From;
                        if (from.RoutingType != "EX")
                        {
                            MailPublicFolderPermissionHandler.Diag.TraceDebug(0L, "Determined the sent user as an anonymous entity");
                            isAnonymous = true;
                            context     = MailPublicFolderPermissionHandler.GetAnonymousClientSecurityContext();
                            MailPublicFolderPermissionHandler.Diag.TraceDebug(0L, "Constructed clientSecurityContext for anonymous user");
                        }
                        else
                        {
                            MailPublicFolderPermissionHandler.Diag.TraceDebug(0L, "Determined the sent user as an authorized entity");
                            byte[] valueOrDefault = from.GetValueOrDefault <byte[]>(ParticipantSchema.ParticipantSID);
                            SecurityIdentifier securityIdentifier = (valueOrDefault == null) ? null : new SecurityIdentifier(valueOrDefault, 0);
                            TransportMiniRecipient data           = recipientCache.FindAndCacheRecipient(ProxyAddress.Parse(mailItemDeliver.MbxTransportMailItem.From.ToString())).Data;
                            if (securityIdentifier == null)
                            {
                                context = MailPublicFolderPermissionHandler.GetUserClientSecurityContext(MailPublicFolderPermissionHandler.EveryoneSID, null);
                            }
                            else if (data == null)
                            {
                                context = MailPublicFolderPermissionHandler.GetUserClientSecurityContext(securityIdentifier, null);
                            }
                            else
                            {
                                context = MailPublicFolderPermissionHandler.GetUserClientSecurityContext(securityIdentifier, recipientSession.GetTokenSids((ADObjectId)data[ADObjectSchema.Id], AssignmentMethod.S4U));
                            }
                            MailPublicFolderPermissionHandler.Diag.TraceDebug(0L, "Constructed clientSecurityContext for user {0}.", new object[]
                            {
                                (data != null) ? data[ADRecipientSchema.PrimarySmtpAddress] : context.UserSid
                            });
                        }
                        if (MailPublicFolderPermissionHandler.CanPostItemsToPublicFolder(mailPublicFolder, context))
                        {
                            accessCheckResult = AccessCheckResult.Allowed;
                            return;
                        }
                        if (isAnonymous)
                        {
                            accessCheckResult = AccessCheckResult.NotAllowedAnonymous;
                        }
                    });
                }
                catch (GrayException ex)
                {
                    string arg = string.Empty;
                    if (ex.InnerException != null)
                    {
                        arg = ex.InnerException.Message;
                    }
                    accessCheckResult = AccessCheckResult.NotAllowedInternalSystemError;
                    MailPublicFolderPermissionHandler.Diag.TraceError <ClientSecurityContext, string>(0L, "Access check failed on ClientSecurityContext {0} with {1}.", context, arg);
                }
                finally
                {
                    if (context != null)
                    {
                        context.Dispose();
                        context = null;
                    }
                }
            }
            return(accessCheckResult);
        }