Tag Archives: Exchange

SharePoint 2016 SMTP Authentication

Edit: It appears that this has been fixed in KB 3191880 :

SharePoint outbound email messages incorrectly try to authenticate to SMTP servers that support Generic Security Service Application Program Interface (GSSAPI), Kerberos, or NTLM authentication. This may prevent email messages from being sent. After you install this update, SharePoint sends email messages anonymously without authentication.


Recently I encountered an issue where SharePoint designer workflow’s emails not being delivered.

Additional inspection revealed that the messages in question were addressed to an Exchange Distribution group with “Permitted Senders.”  This designation meant that messages sent to this distribution group must be received from an authenticated sender (which SharePoint does not support by default: SHAREPOINT 2016 OUTBOUND SMTP FAILURES).

Old Solution

One solution I’ve used in the past is to setup Microsoft’s SMTP server on one of the SharePoint servers, and use that to relay (authenticated) messages to the Exchange server.   This has generally worked fine in the past, but  has always felt a little kludgey.

Seriously, Microsoft?  You’re recommending that we install IIS6 tools on a modern server?

The Problem

Anyway, the above solution breaks down with SharePoint 2016 in certain scenarios:  When sharing documents in SP2016, the “invitation” is sent as the user who initiated the invitation!!!

By default, Exchange only allows authenticated users to send as the account who’s credentials were supplied.

This presents a “Catch 22:”

  • Enable IIS6.0 SMTP relay to send Authenticated messages to Exchange and be able to relay to groups (and external domains)
    —————————-OR—————————————–
  • Configure SharePoint to send through an unauthenticated receive connector, and be allowed to send as any user, but not able to relay otuside the domain, or to groups which require authentication.

I went down a few different solution paths trying to solve this:

Failed Attempt 1: Grant Send-As Permission to SharePoint

Attempt to grant the  SharePoint SMTP service account (since I was already sending authenticated mail) “send-as” permissions on all mailboxes in the domain.

This just felt kludgey, and I was ultimately not able to get it to work.

I may have not waited the recommended 2 hours for the Mailbox Cache Idle Limit to expire:  https://technet.microsoft.com/en-us/library/aa996988(EXCHG.80).aspx

 

Successful Attempt: Configure Externally Secured Exchange Connector

The solution for me was to create a new “Externally Secured” Exchange Receive connector: https://technet.microsoft.com/en-us/library/mt668454(v=exchg.160).aspx

Essentially, this allows the hosts defined in the receive connector’s scope to deliver “unauthenticated” SMTP traffic as if it were authenticated.  

This fulfills my SharePoint requirements:

  •  To “send-as” on behalf of users in a document sharing scenario.
  • To send email as SharePoint to distribution groups which require the sender to be authenticated
  • To send email to users outside of my domain.

I hope this helps someone (even if it’s me in the future).

ADFS 4.0 on Server 2016 <-> Outlook Web App 2013

I recently enabled SAML authentication on Outlook Web App 2013, following the TechNet Documentation here: https://technet.microsoft.com/en-us/library/dn635116(v=exchg.150).aspx

It seemed to work fine; however, I would occasionally (about 1/8 attempts) receive an error message saying: “WrongAudienceUriOrBadSigningCert”

I had already added my ADFS token signing certificate to the Exchange server’s trusted root store as  suggested here:  https://flamingkeys.com/exchange-2013-with-ad-fs-login-fails-with-wrongaudienceuriorbadsigningcert/

The truly troubling thing was, that the issue could not be reproduced reliably.  It affected both internal and external devices (both the primary ADFS and the ADFS Web Application Proxy servers)

I watched a fiddler trace as I attempted to access OWA, and the only difference between successful and failed attempts was a  “/” at the end of the URL.

This can be observed in the POST body of the 302 to owa:


<saml:AudienceRestrictionCondition>
<saml:Audience>https://mail.corp.org/owa/</saml:Audience>
</saml:AudienceRestrictionCondition>

<saml:AudienceRestrictionCondition>
<saml:Audience>https://mail.corp.org/owa</saml:Audience>
</saml:AudienceRestrictionCondition>

This is the token issued to me by my ADFS4 Server!  It would seem that the tokens issued by the IdP do not contain a consistent Audience tag.

The TechNet documentation states very clearly that

The inclusion of the trailing slash / in the URL examples shown below is intentional. It’s important to ensure that both the AD FS relying party trusts and Exchange Audience URI’s are identical. This means the AD FS relying party trusts and Exchange Audience URI’s should both have or both emit the trailing slashes in their URLs. The examples in this section contain the trailing /’s after any url ending with “owa” ( /owa/) or “ecp” (/ecp/).

Ignoring this advise, I added all 4 urls to my Exchange farm configuration


$uris = @("https://mail.corp.org/owa/","https://mail.corp.org/ecp/","https://mail.corp.org/owa","https://mail.corp.org/ecp")

Set-OrganizationConfig -AdfsIssuer "https://adfs.corp.org/adfs/ls/" -AdfsAudienceUris $uris -AdfsSignCertificateThumbprint "<thhumb>"

Having 4 audience URIs resulted in a 100% success rate while attempting to open OWA from a successful ADFS authentication.

I hope this helps someone, as I couldn’t seem to find this issue anywhere else online.

SharePoint 2016 Outbound SMTP Failures

Recently I was configuring a SharePoint 2016 farm, and encountered some peculiar issues with outbound email.

SharePoint 2016 is the first version of SharePoint to include built-in support for TLS. In any previous version of SharePoint, TLS requirements were fulfilled by setting up a SMTP relay capable of authenticating to the desired target SMTP server.

Interestingly, It seems that SharePoint 2016 also responds to SMTP authentication challenges despite not having an explicit configuration option in Central Administration for which credentials to use for SMTP.

The issue I recently experienced is as follows:

  • List / Library “initial” alert subscription messages are delivered to the appropriate address
  • Actual alerts from a list / library are not delivered
  • Workflow Task emails are not delivered

Digging into the ULS logs of the SharePoint server, I noticed the following:

  • Messages send by w3wp (running under the web app pool service account) were delivered
  • Messages sent by OWSTIMER (running under the farm account) were not delivered.  The timer job in question is “job-immediate-alerts.”

So, despite having outbound email configured in Central Administration, it seems that SharePoint is not treating different classes of outbound email equally.

I tried many of the “well known fixes” to no avail:

  • Re-starting the server
  • Re-starting the timer service
  • Manually starting the job-immediate-alerts timer job with PowerShell
  • Altering the alerts properties of the site with stsadm

I finally broke out WireShark on my SharePoint server to observe the SMTP traffic.  What I found was interesting:

  • Messages sent by w3wp.exe had these characteristics:
    • SharePoint sends the message immediately upon request from the browser to subscribe to alerts on a library
    • SharePoint opens a SMTP session to the configured server
    • The Exchange 2013 server responds with an SMTP ntlm authentication challenge
    • The SharePoint server provides the credentials of the web app service account!
    • Exchange returns with smtp 5.7.1 client was not authenticated. 
    • SharePoint ignores the 5.7.1 error message, and delivers the message anyway
  • Message sent by OWSTIMER.exe had these characteristics:
    • SharePoint attempts to send the message with each execution of the job-immediate-alerts timer job.
    • SharePoint opens a SMTP session to the configured server
    • The Exchange 2013 server responds with an SMTP ntlm authentication challenge
    • The SharePoint server provides the credentials of the farm service account!
    • Exchange returns with smtp 5.7.1 client was not authenticated. 
    • SharePoint stops attempting to deliver the message because of the error!

In both of these scenarios, neither the farm service account, nor the web app service account are configured with Exchange mailboxes, so the authentication fails.

The receive connector in Exchange is configured to allow TLS, Exchange Authentication, and Anonymous authentication.

The unexpected behavior is this: SharePoint reacts to an SMTP 5.7.1. unauthenticated message differently depending on the context from which the SMTP session was initiated.  SMTP sessions initiated directly in the web app context succeed, but SMTP sessions initiated from timer jobs fail.

My temporary solution was to create a separate receive connector in Exchange on a separate port scoped so to only the SharePoint server’s IP that allows only anonymous authentication (it seems that by having Exchange Authentication checked, SharePoint fails).  This causes the Exchange server to never prompt the SharePoint server for STMP authentication, and therefore messages are delivered.

I’ll update this post as I discover more.

Exchange Dynamic Distribution Group Delivery Problems

Consider the following:

An Exchange Dynamic Distribution Group has a valid recipient filter, and the filter generates the desired resultant set of recipients with the following PowerShell command:

Get-Recipient - RecipientPreviewFilter $(Get-DynamicDistributionGroup "name").RecipientFilter

However, when a user sends a message to the group, no messages are delivered, and the sender does not receive an NDR.

One possible cause of this issue is a property of the dynamic distribution group called RecipientContainer.  This is similar to the SearchBase attribute of the Get-ADUser cmdlet: it specifies the container in which to apply the RecipientFilter.  Therefore, the RecipientContainer must be the OU (Or a parent of) in which the desired users are stored.

More info here: https://www.corelan.be/index.php/2008/11/05/dynamic-distribution-lists-not-working-as-expected-0-recipients-during-mail-routing/

Pushing Calendar Events with the EWS API

We’ve had a need to populate users’ calendars with data from an internal FileMaker Database, so I dug around in the EWS API, and came up with a script that uses the FileMaker ODBC Connection, and the EWS API to accomplish the task:

First things first, we need to install the EWS Managed API on the machine that will run the script.

After the EWS Managed API is installed, we need to reference it in our PowerShell script:

Add-Type -Path “C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll”

Next, we need to set up a System.Net.NetworkCredential object for the account we’ll use to push these events.  This account must have at least modify permission on the target users’ calendar.

$Credentials = new-object system.net.NetworkCredential(“CalendarAccessAccount”,”SuperStrongPa$$w0Rd!”,”litware”)

Next, we need to Create anMicrosoft.Exchange.WebServices.Data.ExchangeService object:

$version = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService($version)

We don’t want to use the default credentials, Instead we want to authenticate using the service account specified earlier:

$service.UseDefaultCredentials = $false
$service.Credentials=$Credentials

And, presuming AutoDiscover is set up correctly in our domain, we want to let EWS figure out the server address, port, etc:

$service.AutodiscoverUrl(“TargetMailbox@litware.com”)

Next, we need to reference the user’s calendar (it’s really just a folder as far as the API is concerned):

$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar, “TargetMailbox@litware.com”)

And finally, we build the appointment object:

$Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $Service
$appointment.Subject = “Test111”
$appointment.Body = “Test111”
$appointment.Start = $(Get-Date).AddHours(6)
$appointment.End =$(Get-Date).AddHours(9)

Don’t forget to save it:

$appointment.Save($folderid)

 

All in all, we can wrap this up as a function:

Function CreateAppointment($User,$Credentials)
{
$mailboxName=$User
$version = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService($version)
$service.UseDefaultCredentials = $false
$service.Credentials=$Credentials
$service.AutodiscoverUrl($mailboxName)

$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar, $mailboxName)

$Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $Service
$appointment.Subject = “Test Subject”
$appointment.Body = “Test Body”
$appointment.Start = $(Get-Date).AddHours(6)
$appointment.End =$(Get-Date).AddHours(9)

$appointment.Save($folderid)

}

Now we can call the function from, say, with a loop so as to iterate through each user in a CSV:

$users = Import-CSV “Users.csv”

$Credentials = new-object system.net.NetworkCredential(“CalendarAccessAccount”,”SuperStrongPa$$w0Rd!”,”litware”)

Foreach ($User in $Users)

{

CreateAppointment $User $Credentials

}

 

More to come later on the FileMaker ODBC Connection…