Credential Persistence / Azure AD SSO Synchronization Customization

The company I work for has our Exchange service hosted with Intermedia, which at the time of the transition from an on-premise solution seemed great. Why deal with the headache of an Exchange server when you can make someone else do it for you? Fast forward three years and Microsoft’s Exchange Online service has become both ubiquitous and quite stable, but for Reasons we aren’t in the market to move our e-mail servers again.

That being said, we’re happy to be leveraging Microsoft’s other Office 365 offerings (because we don’t have a choice in the matter. Thanks Microsoft). This has created a pretty interesting dilemma that should be applicable any time you have your Exchange service hosted outside Office 365, and are also looking to leverage Office 365. Intermedia provides Active Directory synchronization via their proprietary HostPilot software, and Microsoft provides Acive Directory synchronization via Azure AD Sync. Intermedia and Azure both look to our UPN for our e-mails (and more importantly, our usernames), which it turns out is a problem!

Local Computer Credential Persistence

For some reason, if the “username” e-mail address used for your Exchange mailbox is the same as your UPN, your computer will save the credentials for that account with “Local Computer” persistence. This means that the credentials will not persist through sessions. If you log out, then log back in, you will need to re-enter your password. You can check this in the Credential Manager. What you want is “Enterprise” persistence.

Okay, so what did we do? Well, we thought we were being pretty clever by changing our UPN to include a subdomain. Instead of [email protected], we changed everyone’s UPN to be [email protected]. We were then able to synchronize that UPN to Office 365, and ensure all of our users continued to be able to have their mailbox credential persist between sessions. The theory was that users would only need to use their @sub.domain.com account once, when activating Office licensing, and one of our technicians would be doing that anyways, so the impact would be minimal.

SAML Single Sign On

Fast forward another year, and we have a new dilemma. We have an on-prem application that previously did not have SSO enabled, but a security audit brought up doing so to ensure that user accounts are disabled in a timely fashion. Reasonable. When weighing our options, we considered setting up AD FS on-premise, but my boss brought up the idea of using Azure AD. We’re already synchronizing everything up to Azure, why not continue to leverage it.

Great idea, except we ran into the issue of minimal impact. We had assumed that we would only ever use the Azure AD accounts for Office activation, and users would never need to remember when to use sub.domain.com instead of domain.com. But here we are, hoisted upon our own pitard.

This got me thinking about how the Azure AD Synchronization works. The AD Sync Service Manager uses a bunch of rules to match the data in your local user object with the data in your cloud user object. For all intents and purposes, you have two identical Active Directory forests that are synchronized byt this service. That means that the service needs to know what attributes to synchronize with what attributes, and more importantly, the rules for how it does that is exposed to us. We can set each user’s extensionAttribute1 attribute to be their [email protected] e-mail address and retain [email protected] as their UPN, continuing to bypass the previous issue of credential persistence. There are a number of reasons I went with the extensionAttribute1 attribute and not, say, proxyAddresses and mail, but I’ll talk about that later.

The broad strokes for the process were aped from evotech at the link below, but I ran into a few differences that are worth noting. https://evotec.xyz/azure-ad-connect-synchronizing-mail-field-with-userprincipalname-in-azure/

Open the Synchronization Rules editor and find the two rules shown in the screenshot.

When editing the rules, you’re prompted to clone and disable the default rule. I highly recommend you do this, as this is a very simple failsafe. Make sure to rename the clone, and make sure to change the priority. Default rules all have priorities over 100, so choose something below 100.

Navigate to the “Transformations” tab on the left, and find the line for userPrincipalName. The userPrincipalName is, you guessed it, the attribute that is used as your as “username” for Azure AD, so we’ll need to change this expression. Do this for both rules above.

Here is what the default is, followed by what I changed it to be.

Default:
IIF(IsPresent([userPrincipalName]),[userPrincipalName], IIF(IsPresent([sAMAccountName]),([sAMAccountName]&"@"&%Domain.FQDN%),Error("AccountName is not present")))
Modified:
IIF(IsPresent([extensionAttribute1]),[extensionAttribute1], IIF(IsPresent([userPrincipalName]),[userPrincipalName], IIF(IsPresent([sAMAccountName]),([sAMAccountName]&"@"&%Domain.FQDN%),Error("AccountName is not present"))))

If you take a minute to break it down, it makes a lot of sense. The default checks if there is a userPrincipalName for the object, and if it does it users that. Otherwise, it will check for a sAMAccountName and use that plus the domain from your FQDN, and finally error if none of those are around. What we want, though, is to add the extensionAttribute1 attribute as the first thing it checks, and have it use that. I liked keeping the UPN as a fallback so that worst comes to worst, I can direct a user to use that if I can’t immediately fix the problem.

However, that’s not the end. It turns out that when Azure AD Sync Service pulls the user object, it does not pull all attributes on the object, but rather a subset of them. You’ll need to find the pictured rule below and clone and edit that as well.

This is the rule that queries local AD and pulls what it needs. Go to the Join Rules tab on the left and add what’s highlighted in red. Now, it will pull in the extensionAttribute1 value and give the previous rules something to work with.

Once you’re done, open up Powershell and run the following to start a sync to match the value in your local user object’s extensionAttribute1 attribute with the UPN for your Azure AD user object.

 Start-ADSyncSyncCycle –PolicyType Initial 

Considerations

I said earlier there were reasons we didn’t sync with certain attributes, so below are the attributes I thought about syncing with and why that didn’t work.

mail – Our mailboxes are set up funny-like with Intermedia, and so they all have to synchronize using another e-mail address, which turns out to be in the mail field. This is something I may try to untangle later, but it may also be that we had run into credential persistence issue during the migration.

proxyaddresses – Azure AD Sync really did not like using the proxyaddresses field. The UPN value accepts strings, and while the proxyaddresses field is stated to be a string, I’m not sure it’s string enough to be accepted. Also, our previous on-prem Exchange server meant that a lot of older user accounts still had a lot of X500 data in that attribute, so it was better to just avoid it.

otherMailbox – I had thought about using this earlier on, and probably could have, but in troubleshooting why the sync wasn’t working, I decided to use the extensionAttribute1 field instead. In hindsight, it probably didn’t work because of needing to add the join rule. If you’ve got a bee in your bonnet to use this attribute, it’s probably fine.

Conclusion

This was a real long post, and a culmination of about two months total of beating my head against a wall, mostly with regards to the credential persistence. That’s what I get for opening a support ticket with Microsoft. If this helped you, let me know. If there’s anything that isn’t technically correct or just straight up wrong, let me know as well. All in all, it was pretty cool bending Azure AD to my will.

LDAPS Logging

In March 2020, Microsoft will require all LDAP traffic to occur over LDAPS. Here’s how to set up logging in Event Viewer to see what kind of traffic is not occurring over LDAPS, and where that traffic is coming from. 

In Event Viewer, set up a custom view checking for logging events 2886, 2887, 2888, 2889 in the Directory Service logs.

Before your events return the source of the traffic, you’ll need to enable LDAP Interface events at logging level 2. Go into the registry on each of your DCs and enter the following:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics 
(DWORD32) 16 LDAP Interface Events - 2

And here it is in Powershell:

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics" -Name "16 LDAP Interface Events" -Value "2"

Installing Click-to-Run Office Suite

With Office 365, installation and products are tied to user’s accounts, making it difficult to set up a computer with an Office install before giving it to the user. Click-to-Run Deployment will allow you to have Office fully installed on the computer, then the first time the user runs any of the Office programs (i.e. Word, Excel, etc) they will be asked to log in with their Office 365 account credentials, thus licensing the product. Below are instructions on how to download, configure, and install the Click-to-Run Office suite. 

 The Quick and Dirty

If you want to just download and go, and not read any of my lovely documentation, here’s everything below packed up in a nice ZIP file. Does not include the Office download, so you’ll still need to run setup.exe /download download.xml

https://github.com/Omnialias/OfficeInstaller

Step-by-step guide

  • Go to either here for Office 2013 and here for Office 2016 to download the Deployment Tool.
     
  • Run the installer that you get, which will extract two files to the location you specify: setup.exe and configuration.xml.
     
  • The setup.exe file can be used with three switches, which can be found by using the /? switch, which yields the below statement:
    setup.exe /?
    Usage:
    SETUP mode [path to configuration file]
    SETUP /download [path to configuration file]
    SETUP /configure [path to configuration file]
    SETUP /packager [path to configuration file] [output path]
    SETUP /help [path to configuration file]
    /download Downloads files to create an Office15 installation source
    /configure Adds, removes, or configures an Office15 installation
    /packager Produces an Office App-V package from an Office installation source
    /help - Prints this message
    We are concerned with the first two switches, /download and /configure. 
    • /Download will download the Office version described in the configuration file provided, but in CAB files and not an executable.
    • /Configuration will install Office using the downloaded CAB files.
       
  •  The contents of the configuration file is listed below:
    <Configuration>
    <!--  <Add SourcePath="\\Server\Share\" OfficeClientEdition="32" >
    <Product ID="O365ProPlusRetail">
    <Language ID="en-us" />
    </Product>
    <Product ID="VisioProRetail">
    <Language ID="en-us" />
    </Product>
    </Add>  --> 

    <!--  <Updates Enabled="TRUE" UpdatePath="\\Server\Share\" /> -->
    <!--  <Display Level="None" AcceptEULA="TRUE" />  -->
    <!--  <Logging Path="%temp%" />  -->
    <!--  <Property Name="AUTOACTIVATE" Value="1" />  --></Configuration>

    Using this as a framework, we will create two .xml files: download.xml to be used with the /download switch to download the version of Office we want to install, and install.xml to be used with the /configuration switch to install what we’ve downloaded. Both of these files should be saved to the same location that setup.exe and configuration.xml are. For this example, we’ll call this ~\OfficeInstall\
     
  • For the download.xml file, what works for me is listed below. 
    <Configuration> 
    <Add OfficeClientEdition="32" >
    <Product ID="O365ProPlusRetail">
    <Language ID="en-us" />
    </Product>
    </Add> 
    <Updates Enabled="FALSE" />
    <Display Level="None" AcceptEULA="TRUE" />
    <Logging Path="C:\Office Log" />
    <Property Name="AUTOACTIVATE" Value="1" /> 
    </Configuration>

    For the Product ID, that value needs to match the version of Office that you plan to install. Follow the guide here. In my example, the majority of my users own Office 365 Enterprise E3, so I have O365ProPlusRetail as the Product ID. Make sure to change that as necessary. The CAB files will be downloaded to ~\OfficeInstall\Office\Data\.
     
  • For the install.xml file, what works for me is listed below:
    <Configuration> 
    <Add OfficeClientEdition="32" >
    <Product ID="O365ProPlusRetail">
    <Language ID="en-us" />
    </Product>
    </Add> 
    <Updates Enabled="FALSE" />
    <Display Level="None" AcceptEULA="TRUE" />
    <Logging Path="C:\Office Log" />
    <Property Name="AUTOACTIVATE" Value="1" /> 
    </Configuration>

    A couple of notes here. I’ve removed the Source Path and disabled the Updates because those two are unnecessary. The Source Path is asking for the location of the CAB files, but those will just be in the same location as the rest of your files. This is here in case you want to put the CAB files on a network share, but it doesn’t look like doing it this way has yielded great results for people. Instead, everyone suggest leaving the CAB files local. Again, note the Product ID here is set to the version of Office we are installing. Finally, there are logs being written to at the location of the logging path. Feel free to change that to what you would like. 
     
  • Now that we have those two files created and saved to the location of setup.exe and configuration.xml, we need one last thing. Some way to start the setup. You can use the command line to do it, but here’s a nice, double-clickable cmd file. This can come in handy if you are deploying through MDT. Also gives you some sort of visual to tell you if the installer has finished. 
    @echo
    offpushd
    %~dp0
    echo Installing Office 365 Pro Plus Retail x86setup.exe /CONFIGURE install.xml
  • After all of that, it’s time to do some work. Go to the command line and navigate to ~\OfficeInstall. Then type in: setup.exe /download download.xmlThis will download the specified version of Office’s CAB files to ~\OfficeInstall\Office\Data\.
     
  • Now you’re ready to go. Go to your command line, navigate back to ~\OfficeInstall and typeinstall.cmdThat will run the installer, the command line should say” Installing Office 365 Pro Plus Retail” and when it’s done, should send you back to the command line. 
     
  • Office should now be installed. The first time you open Word or Excel, you should be prompted to enter your Office 365 credentials. 

Map to OneDrive as a Mapped Drive

1. First, please refer to the troubleshooting tips in the following article before you begin to map the network drive:
• Upgrade your IE to the latest version.
• Add your SharePoint Online sites to the trusted sites
http://support.microsoft.com/kb/2616712 
2. Select the Keep me signed in check box when you sign in to your Office 365 accounthttp://portal.office.com .
3. After signing to Office 365, get to your OneDrive for Business, and copy the OneDrive for Business URL like https://contoso-my.sharepoint.com/personal/user_domain_com/documents/
4. Right-click the Computer icon from the desktop, and then click Map Network Drive.
5. Select a Drive and then paste the URL of the library you copied before in the Folder input box.
6. Make sure the check boxes of Reconnect at sign-in and Connect using different credentials are selected, and then click Finish.
7. Enter the username and password of your Office 365 when you are prompted to enter the credentials> Click OK.

Configure iPhone/IMAP Access to a Shared Mailbox – Office 365

These instructions are specifically for setting up access to a Office 365 shared mailbox on an iPhone but the settings could possibly be used to configure any IMAP mail client.

  • Settings app → Mail → Accounts → Add Account → Other → Add Mail Account
  • The settings at this screen don’t matter much. We’ll put the correct ones in the next screen. Fill it out and tap Next
    • Name:  User’s name
    • Email:  Email address of the shared mailbox
    • Password:  Password associated with the user’s primary mailbox
    • Description:  This is how the mailbox will be labeled in the Mail app
  • At the next screen, we need to get a lot of settings right.
    • Name:  User’s name of shared mailbox name. This will be what a recipient sees for the “From” display name in their mail client when they receive a message from the shared mailbox
    • Email:  Email address of the shared mailbox
    • Description:  This is how the mailbox will be labeled in the Mail app

      Incoming Mail Server
    • Host Name: outlook.office365.com
    • Username:  [email protected]\alias_of_shared_mailbox
      (The alias of the shared mailbox can be found in through Exchange Admin Center → Recipients → Shared → Double-click on the shared mailbox and its in the General tab. Note that the alias is often the first part of the email address but isn’t always! You need to check.)
    • Password:  Password associated with the user’s primary mailbox

      Outgoing Mail Server
    • Host Name:  smtp.office365.com
    • Username: [email protected]
      (Note that this is different than incoming mail server settings!)
    • Password:  Password associated with the user’s primary mailbox.
  • Next. Should be self-explanatory from here. Check with the end-user that they can open the Inbox of the shared account in the Mail app.

Raspbian Login Loop with No Prompt

If you’ve confirmed the username and password definitely work, but login is looping.

SSH to the computer.

Run ls -lah.

If in the output the line you get:

-rw-------  1 root root   53 Nov 29 10:19 .Xauthority

then you need to do sudo chown username:username .Xauthority and try logging in.

Java Error 1603

I really hope I don’t ever need this again…

GUI Solution

Go to C:\program files\java\bin\javacpl.exe, go to the Security tab, and uncheck “Enable Java content in the browser”. Close out of the Java Control Panel and try the update/installation again and it should work.

Afterwards, go in to javacpl.exe and re-enable “Enable Java content in the browser” or else the user will be unable to use any in-browser Java applets.

If Java has already been uninstalled and javacpl.exe no longer exists, then refer to the command line solution instead.

Command Line Solution

Download the offline Java installer and run it from the command line with WEB_JAVA=0 after the installer path.

Afterwards, go in to javacpl.exe and re-enable “Enable Java content in the browser” or else the user will be unable to use any in-browser Java applets.

iDRAC Commands

The following commands can be issued from inside the Windows OS to control the iDRAC. OpenManage must be installed on the server.

Get Network Config

racadm getniccfg

Change Network Config

racadm config -g cfgLanNetworking -o cfgNicEnable 1
racadm config -g cfgLanNetworking -o cfgNicIpAddress x.x.x.x
racadm config -g cfgLanNetworking -o cfgNicNetmask 255.255.255.0
racadm config -g cfgLanNetworking -o cfgNicGateway x.x.x.x
racadm config -g cfgLanNetworking -o cfgNicUseDHCP 0
racadm config -g cfgLanNetworking -o cfgDNSServersFromDHCP 0
racadm config -g cfgLanNetworking -o cfgDNSServer1 y.y.y.y
racadm config -g cfgLanNetworking -o cfgDNSServer2 y.y.y.y

Soft reset iDRAC

racadm racreset

Change DRAC to or from Dedicated NIC and Shared NIC

racadm config -g cfgLAnNetworking -o cfgNicSelection 0 or 1 (0 for shared, 1 for dedicated)

Changing root password

racadm config -g cfgUserAdmin -o cfgUserAdminPassword -i 2 newpassword

Enabling Device Owner Mode using Android Debug Brdige (ADB)

  • With a new (or factory reset) Lollipop Android device, go through the setup wizard WITHOUT adding a Google account. If you accidentally added an account, simply remove the account from the Settings app once you finish the setup wizard.
     
  • Once the setup wizard is done and you’re on your device’s home screen
    • Go to Settings
    • Go to “About device” (Might be named slightly different)
    • Click the “Build number” field 7 times. This will turn on “Developer options”
    • Go back to Settings
    • Go to “Developer options”
    • Scroll down and enable “USB debugging”
       
  • Plug the device into computer
    • Your device might prompt you with a trust dialog. Click accept.
       
  • On the computer, run the following command to install the latest Android SM app you downloaded onto your device:
    • adb install AndroidSM.apk
       
  • Once installed, run the following command to set Systems Manager as the device owner of the device: