User on Mac can’t login to AD, but can login from Windows

For about a month, we’ve been struggling with a pesky problem which boils down to the above description. As the above description suggests, the password is known to the user and the account is functional.

Other details:

  • Many others could login from all the macs tried—just the one user was having problems
  • We ensured that different groups setup the macs to rule out some odd configuration decision
  • We tried a couple semi-obvious things, like changing the password and ensuring the length and use of special characters shouldn’t cause problems on a Mac
  • We also looked closely at the AD account itself to see if there was anything broken or odd about it
  • We also tried inspecting the Mac-side logs, but that didn’t lead anywhere—but admittedly, our Mac expertise may not have been deep enough.

None of these produced much of anything and we were starting to create very far-fetched theories, and approaching what we thought was an option of last resort—deleting and recreating the AD user (which we now know probably wouldn’t have worked).

Finally, via a fortunate circumstance, one of our team members discovered there was another account with a displayName value which matched the user’s samAccountName value. We manually changed the displayName value on that other account, and logons for the person from Macs now worked!

The connection between a displayName and what the Mac client calls the username may seem arbitrary, but there is a fairly straightforward explanation:

  • Apple’s Mac AD client takes the username field value supplied and does an AD query using what is called ‘ambiguous name resolution’ (or ANR). This is a query against a set of pre-defined set of naming attributes. It’s what Outlook uses when you do an Address Book query. The ANR set includes displayName. You can find the other AD attributes it includes via an internet search of ‘ambiguous name resolution’. That’s a little funny design decision, but given the broad set of circumstances Apple might find in various Active Directories, it’s pretty understandable.

We believe the following to be true but there is a little speculation on our part:

  • Apple’s Mac AD client then takes all results from that query and silently chooses one and tries to authenticate using that one. If it fails, it doesn’t try any others and raises an error. Assuming our speculation is correct, this is a really bad design decision on Apple’s part.

The takeaway is there is a known problem where if your samAccountName matches the displayName or sn of another UW NetID, you may have problems logging in from a Mac.

I have never heard anyone else share anything remotely like this, nor have I found anything on the internet which suggests someone else has previously traced this problem to this cause. So I thought I’d share.

WS2016 AD upgrade problem: TLS ciphers

We’ve been replacing all our WS2012R2 DCs with WS2016 DCs. A non-Windows platform application which performs LDAPS queries against AD had a breaking issue. That application leverages a JDK library to establish the TLS connection (for LDAPS) with a domain controller.

See https://docs.microsoft.com/en-us/windows-server/security/tls/tls-schannel-ssp-changes-in-windows-10-and-windows-server for Microsoft details on the newly added crypto ciphers. An interesting detail is that the preferred crypto cipher for WS2016 is still in draft status! Presumably it was chosen because it is significantly faster than the other new/strong ciphers.

The exact details of the known problem are still a bit sketchy, so I can’t share that level of detail definitively. The facts are that both WS2016 server and JDK client have ciphers in common, but a mutually supported cipher is not negotiated (whereas a WS2012R2 server with the same JDK client does negotiate successfully). The JDK team has an issue tracking this which they have resolved based on wire-level examination showing that the WS2016 server doesn’t properly do TLS cipher negotiation: https://bugs.openjdk.java.net/browse/JDK-8178429.

So we looked to find a solution. We are aware that the ‘bouncy castle’ provider (instead of JDK) has been used in similar situations. Our working hypothesis was that WS2016 is just overzealous in negotiation when the newer ciphers are enabled or suggested first.

Our testing showed that switching the order so that the cipher still in draft status is not first was enough to allow the JDK based client to negotiate, which seems to support that hypothesis.

We rolled an order switch out, and plan to keep that in place for 6 months when the dependent application will be retired.

Some related links:

Office ProPlus Device Based Activation

Microsoft has a special capability called Office ProPlus Device Based Activation, which is only offered to Office 365 for Education customers. It allows the click to run Office to be licensed on a device basis instead of on a user basis.

http://boards.microsoft.com/public/prism/80710?token=f55452094b has more info, including a video, brief guide (which is not a guide, but just a step-by-step to implementation), and a FAQ partly hidden a layer below.

This capability has a lot of upside, and I appreciate the solution. There are several aspects of the design that are under-documented and which deserve thought:

  • Most of the issues center on the “device users” which are created and leveraged to enable this capability. Undocumented by Microsoft, the Azure AD object type/class these “device users” are is simply just Azure AD users with _Device_ as a prefix.
  • How do these objects go away? This topic is not covered, and I presume that you must invent your own mechanism to remove them when unnecessary. How you’d effectively do that is pretty unclear.
  • Another issue is where the Office ProPlus licenses which get applied to these users come from.

I’ve got a longer analysis paper over at https://itconnect.uw.edu/wares/msinf/comm/analysis/office-proplus-device-based-activation-analysis/ which discusses the topic and our proposal to implement.

Azure AD Role Activation

I’ve been trying to start using one of the many directory roles which Microsoft has defined for Azure AD. See https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles for the primary documentation on Azure AD roles.

If you’ve looked at Azure AD directory roles, you know that there are some roles which are immediately usable and others for which you have to do something to “turn them on.” I got stuck at the point of turning one on, and I figured an information post about this would be useful to others.

Behind the scenes there are two AAD objects in play. There is the DirectoryRole—which are all the roles that are usable in your tenant. And then there is the DirectoryRoleTemplate—which are all the roles which might be usable in your tenant. You “activate” a template to create a role object, which is effectively “turning it on”. I wrote a detailed blog post about this several months ago at: https://blogs.uw.edu/barkills/2017/02/28/azure-ad-roles/ if you want to learn more, but for the purposes of this post, you don’t need to know what’s in that other post.

From what I’ve been able to determine, there are three ways to turn these things on (listed in order I think they were available):

  1. MSOnline PowerShell module, via Add-MsolRoleMember, https://docs.microsoft.com/en-us/powershell/module/msonline/Add-MsolRoleMember?view=azureadps-1.0
  2. Azure AD Graph API, via REST call documented at https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/directoryroles-operations#ActivateDirectoryRole
  3. AzureAD PowerShell module, via Enable-AzureADDirectoryRole cmdlet, documented https://docs.microsoft.com/en-us/powershell/module/azuread/enable-azureaddirectoryrole?view=azureadps-2.0.

I also suspect that there may be ways to silently activate a role via one of the GUI admin consoles, but I have not extensively explored this.

Speaking of silent activation, I think that’s what option #1 does—you don’t have to know anything about DirectoryRoles, DirectoryTemplates, or even be aware there is an activation. But since that module is “old”, I’ve been purposely avoiding it, and I have to believe that’s what at least some others are doing.

Option #2 is likely not an option that many try. But I happen to like the Azure AD Graph Explorer because I find I can get more low-level details from it than any other AAD tool, so this is an option I tried. However, the documentation referenced is pretty opaque to me, with a recommended call that didn’t even include the required parameter—which I have to guess is because the documentation is incomplete. I couldn’t find a way to make it work, even by adding in the required parameter and the objectId of the DirectoryRoleTemplate I wanted to activate. I’m left wondering what the right incantation is to get this option to work.

Option #3 is where I started because I’ve come to like the AzureAD module. And I followed the example in the documentation ending up with the error message:

Enable-AzureADDirectoryRole : A parameter cannot be found that matches parameter name 'DirectoryRole'.

This drove me batty for a while, especially since it is a required parameter.

Eventually, I realized that the example listed is for a prior version of the AzureAD module, and they made major changes to the parameters. This issue was masked by two things:

  • the example in the documentation is completely incorrect for the current version—it must be based on a prior version
  • the help for this cmdlet is also incorrect, and not just the example but all of the help is incorrect

Making major changes to the parameters, especially when you drop the only required parameter, and not updating the documentation is bad, and that’s what seems to have happened here.

The good news is that the steps required, which used to include instantiating a special object to pass into the cmdlet, are much less complicated. From a high-level, you grab the objectId of the DirectoryRoleTemplate you want to activate, then pass that into the cmdlet as a string. So the example *should* read this:

$InviterRole = Get-AzureADDirectoryRoleTemplate | Where-Object {$_.DisplayName -eq "Guest Inviter"}

$InviterRole

 

ObjectId                             DisplayName   Description

--------                             -----------   -----------

95e79109-95c0-4d8e-aee3-d01accf2d47b Guest Inviter Guest Inviter has access to invite guest users.

 

Enable-AzureADDirectoryRole -RoleTemplateId $InviterRole.ObjectId

 

ObjectId                             DisplayName   Description

--------                             -----------   -----------

03618579-3c16-4765-9539-86d9163ee3d9 Guest Inviter Guest Inviter has access to invite guest users.

I hope this helps save someone else time. And I hope Microsoft takes note of the mess here and the places they might improve the documentation to help others in the future.