About Jon Bryan

Posts by Jon Bryan:

An Alternative To Using The Generic Array From File Function

While looking to improve on my method of getting exceptions or a long list of mail suffixes into an array, to be checked during code execution, I came across this: https://msdn.microsoft.com/en-us/library/windows/desktop/ms696048(v=vs.85).aspx

This seemed to me to be a really nice solution, just defining all exceptions and suffixes within one file, read it in on code execution, then check for existence or whatever in the code.

So, given the following xml file:

Add the System.Xml Import and declare the variables, so they are global:

Add the code to read the xml file into the Initialize Sub:

Then, when you wish to look for those values within those variables – just like in the last post:

An Update on my Generic Array From File post

In this post: https://blog.oholics.net/a-generic-array-from-file-function-to-cope-with-inevitable-exceptions/, I documented a method of generating an array of values from a text file.

While I was happy that this method worked, I was not entirely happy with the fact that I still had some hard coded values in the code. However, the way that the function operated meant that if I took my collection of mail suffixes (20+) and added them all to the text file, then the array would be built for each and every user that passed through the dll, not too efficient!

So, I was looking for something a little more elegant. I was happy for the array to simply be defined when the dll was loaded.

Here is my solution:

At the beginning of my AD MA, I declare my dates and logging levels etc, then generate those arrays using the function. These arrays are now static and are good for processing all users without being regenerated.

When I wish to look into the array to validate a valid email suffix for example, I go from this (as in the last post):

To this:

Much cleaner – plus all suffixes can now just reside in a text file.

Note that updates to the text file will only be realised if the dll is reloaded and the array is regenerated. I believe that this is after 5 minutes of inactivity and seems to hold true from testing.

SharePoint Foundation 2013 – Setup is Unable to Proceed due to following error, requires .Net Framework 4.5

I have been setting up a MIM PAM lab at home. Following the guide here: https://technet.microsoft.com/en-us/library/mt488766.aspx

I’m installing onto Server 2012 R2, with SharePoint Foundation 2013 SP1

After installing the SharePoint Foundation 2013 Prerequisites, using the Service Pack 1 release, all installs just fine. Then I run the setup.exe, very quickly I’m prompted with the message “Setup is Unable to Proceed due to following error, requires .Net Framework 4.5“. The prerequisite installation log (C:\Users\<MyUserAccount>\AppData\Local\Temp\) shows:

2016-01-29 22:39:36 – Check whether the following prerequisite is installed:
2016-01-29 22:39:36 – Microsoft .NET Framework 4.5
2016-01-29 22:39:36 – Reading the following DWORD value/name…
2016-01-29 22:39:36 – Install
2016-01-29 22:39:36 – from the following registry location…
2016-01-29 22:39:36 – SOFTWARE\Microsoft\Net Framework Setup\NDP\V4\full
2016-01-29 22:39:36 – The value is (1)
2016-01-29 22:39:36 – Reading the following string value/name…
2016-01-29 22:39:36 – Version
2016-01-29 22:39:36 – from the following registry location…
2016-01-29 22:39:36 – SOFTWARE\Microsoft\Net Framework Setup\NDP\V4\full
2016-01-29 22:39:36 – The value is…
2016-01-29 22:39:36 – 4.6.01055
2016-01-29 22:39:36 – A post release .NET 4.5 is installed

However, the SharePoint Foundation installation log shows:

2016/01/30 19:27:00:389::[3788] Catalyst .Net version check failed. Setup requires .Net Framework version 4.5.50501 to install this product

4.6.01055 is installed but the installer wants the older version – 4.5.50501.

So, after a bit of googling, I find this: https://social.technet.microsoft.com/Forums/sharepoint/en-US/bbed58e1-4a80-4dde-91fd-c6fc95bf85ac/sharepoint-2013-installation-with-net-framework-4550501-and-4550709?forum=sharepointadmin

In that post, Rick just sets all of the registry entries. However, the one that seems to be the ‘looked up’ value (at least based on my testing today), which is contrary to the prerequisite log, is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client.

Detailed method:

Right click the Client key, choose Permissions…

DefaultPerms

Note that the Administrators group has Read access by default.

Click Advanced, note at the top of the window, the owner is shown as TrustedInstaller:

DefaultAdvancedPermissions

Click the Change link beside the owner label.

Change the scope (“From this location”), to the local machine, choose <localmachine>\administrators group:

SetOwner

Click OK, then OK again until we are back at the initial Permissions window, tick Full Control for the Administrators group:

AmendedPerms

OK, then go set the Version number to 4.5.50501

Install SharePoint Foundation 2013.

Once complete, put things back to how they were before – of course this is optional….. just depends on how lazy you feel and whether you want to be caught out by the fact that you changed this sometime in the future, then can’t figure out why something else doesn’t work. Making the change back is so straightforward and quick, I believe that it is worth doing 🙂

After installation, flip version back to 4.6.01055. Then, right click the Client key, remove full control from the Administrators group, apply. Then, click Advanced, go and change the Owner again –  as before but using NT SERVICE\TrustedInstaller as the owner:

ResetOwner

Click OK, until you are back to Square 1. Easy!

Process To Email The Manager Of A Service Account When Their End Date Is Approaching

A long term goal of mine, has been to get “account requestors” to take ownership of their Service Accounts.

Attempts have been made by my predecessors to record an owner of a service account, but it has simply been done as a string attribute of the AD object. Thus, when the person leaves and the account is deleted, the service account becomes orphaned, with an reference to a long forgotten ID.

So thinking of a way to carry this out….. I am already using the email address of the owner of an administrative account to make decisions about whether the administrative account should be enabled or disabled – based on the end date of the owner – discovered by looking up the email address in the MV.

I figured that I could do something similar for those Service Accounts. I’ll be creating service accounts via the portal, the owner of the account will be assigned to the manager attribute. So, how can I get the email address of the manager into the MV as a thing that I can lookup??? I can’t do an advanced flow rule on the FIMMA, and even if I could, Manager is a reference attribute, so I can’t do it anyway… I found an article about dereferencing another attribute, that get me going down this path….. The solution is simple. Create a new attribute and binding in the portal – “ManagerEmailAddress”, then setup a workflow as follows:

GetManagerEmailAddressWF

When the account falls into scope, the managers email address is set into that new attribute – in the sync engine create a direct flow to put that into the MV (I’m using “serialNumber” – for one reason or another, that I wont go into :)).

I have on the import from AD, some code to set an MV boolean flag – “functionalID” – if the DN of the person object contains the strings found in the Service Account OU’s, thenfunctionalID = True. This attribute is pushed into the portal and is used in set definitions.

So, I’m getting there. Now I need something to set another flag in the MV that will go to the portal. this one defines if the owner of the Service Account is approaching their end date (30 days prior):It is defined on the Import from AD and populates the MV attribute “functionalID-owner-expiring”

Of course after initial code definition, I found another of those inevitable exceptions, so added the generateArrayFromFile function, with a reference (in txt file) to the email address that should be ignored.

Create attribute and binding in the portal for FunctionalID-owner-expiring

Setup an Export in the FIMMA for the new attribute

Create a set: FunctionalID = True and FunctionalID-owner-expiring = True.

Create notification workflow and mail template: notification to [//Target/Manager], then the set transition MPR.

I think I have it, just need to do a little testing to see that it works as expected.

I’m still a long way from the stated goal, as I still need to find “owners” for all of those accounts that have been created in the past.

A Generic Array From File Function To Cope With Inevitable Exceptions

In the last few days, I have had a few more exceptions to cope with in my FIM Config.

  1. Another new mail suffix
  2. A user who is employed by one tenant, who has that tenants email address suffix; but who is on secondment to another tenant, who have a different mail suffix. The users attributes have been changed in the HR system, so that they gain access to the stuff in the other tenant, which is controlled by automatic groups, based on attribute data!

So, I’d been thinking for a while about having a method to add exceptions without having to add them to the code directly and thus forcing a rebuild followed by full syncs. I found a nice function to read a text file to an array, this is added to the top of the dll after the lines:

Public Class MAExtensionObject_YourMA
Implements IMASynchronization

So, to put this use – take my previous port regarding generating validating email addresses: https://blog.oholics.net/defining-a-unique-email-address-and-validating-mail-suffix/, at line 97 I ask “Does the suffix match?” This chunk is now as follows:

So, the referenced file simply has the email address of the user that I don’t want to be alerted about. If the email address does not match the expected value, look in the array generated from the text file; if it in not in there either raise an error to get this fixed or investigated.

Regarding the valid mail suffixes – I posted about this already: https://blog.oholics.net/emailaddresspresent-flag-setting-and-checking-email-suffix-validity/.

I have a hardcoded list of those that are already in use in the dll, if the suffix is not found in that array, it does a lookup of the array generated from the “suffixes” text file, if it is not in there it raises an error:

Console App for enumerating userAccountControl integer values

When trying something new out with FIM Development, I often see how to do it in a console app beforehand. Then once I have the process/ method worked out, I translate it into FIM code. Usually this is a very clean process and is quicker than editing the FIM code directly, then doing sync’s on individual accounts.

When I was initially looking at exporting userAccountControl values to AD, I used Jorge’s code snippet: https://jorgequestforknowledge.wordpress.com/2010/07/29/managing-the-useraccountcontrol-attribute-in-ad-by-fim/ as the basis for my code. Initially, I had some difficulty understanding the differences between the “Or’s and And’s”, so used a console app to understand what integer values the different combinations made. The list of flags can be found here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa772300(v=vs.85).aspx

My userAccountControl Export code became a bit of a monster, due to the number of rules needed to match the existing configuration.

The console app is super simple – fiddle with the different flags and operators to see the different results:

Note, that you need to add the reference to “Active DS Type Library”, else you will get squiggles under “ADS_USER_FLAG”:

AddDSRef

Amending/ Changing IE Proxy Settings, Continued

After sorting through the data that I obtained from the collection script, removing duplicates, etc. The result set was slightly messier than I expected, quite a few manually added entries and incorrect ones.

Anyway, to get the bulk of the changes implemented, I’m just targeting the large expected set – those with VPN settings labelled SITE1 PPTP and SITE1 VPN (anonymised…). Those with SITE2 PPTP have the settings, that were previously enforced by another script, have them enforced here too. This script will take the place of the existing one.

New machines, who do not have the settings already have them defined. Anyway here it is:

Yubikey Neo

So this is not directly relevant to FIM per se, but it falls under the kind of IdM/ Authentication umbrella, so I thought it belonged here….

In December 2014, I bought a Yubikey Neo. I wanted to see how it could be used to harden access to some sensitive “stuff”.

These are really cool devices; they are relatively inexpensive (~£36), yet provide a bunch of functionality all on one device, some of which I have not used.

The components that I did use were:

  • Yubico OTP – the One Time Passcode functionality that is present OOB – used to sign into the Yubico Forums
  • U2F – I use this for 2FA for my Google accounts and this blog – it is very simple to set up this 2FA method across multiple services. Look here for more information: https://www.yubico.com/applications/fido/
  • SmartCard (PIV) – this was the part that I was really interested in for securing stuff within the enterprise. I had recently installed a Windows PKI Infrastructure, so used that to generate trusted SmartCard Logon Certificates to install onto the devices. Look here for configuration docs: https://developers.yubico.com/yubico-piv-tool/

As with most of these things the documentation was initially difficult to read, there were various command line tools to manage different aspects of the Yubikeys, some of them had bugs at the time.

Anyway, long story short, back then I got it configured just how I wanted and used it daily ever since. However, just before Christmas, the SmartCard certificate that I had generated the previous year expired. Thus, the SmartCard functionality of the Yubikey became invalid.

I generated myself a new certificate from my CA, then came to try to remove the old certificate from one of my Yubikeys. I could not because I needed to authenticate against the device to carry out this action. The authentication string (aka password) is called the Management Key, that is (should be) changed from the default value when configuring the device. I went on the scrounge trying to find the key for this particular device, I found my old notes (command line dumps) from the previous year, there were a few management Keys within but not one for this particular device.

So, I might as well reset it, back to the docs: https://developers.yubico.com/yubico-piv-tool/YubiKey_PIV_introduction.html, in order to be able to reset the device, I first need to lock the device, by providing bad PIN and PUK values:

OK, so now I need a new management key….. The docs use dd to generate the key:

At the time, I didn’t have easy access to a Unix system to do this, but more importantly I wanted to find a way to achieve the same result in Windows, using PowerShell. This would allow me to script the whole process. Here is the script to create the management key (For info about what “{0:X2}” means, look here: http://www.powershellmagazine.com/2012/10/12/pstip-converting-numbers-to-hex/)

I have now re-written a script that I put together last year to add initialise a new or reset Yubikey (with PIV support) and add a user SmartCard certificate from a Windows CA:

U2F Login for WordPress – OPENSSL_VERSION_NUMBER Undefined

While looking to get this working: https://github.com/shield-9/u2f-login/, I was seeing errors in the http logs referring to OPENSSL_VERSION_TEXT. These were being generated by the following lines in the u2f.php file:

After running a few more tests, it seemed that this PHP Constant should have been defined, but was not. Goggling didn’t provide any quick answers, but I soon worked it out for myself.

In the php.ini file (under arch in /etc/php/), uncomment the line: “extension=openssl.so” and restart httpd. Once the extension is enabled, the Constant is then available.

In the end I did not use this plugin, I was unable to register my Yubikeys. The plugin seems to have been superseded by this one: http://github.com/georgestephanis/two-factor/. In order to have the ability to use U2F login using this plugin, the openssl.so extension has to be enabled; otherwise, the U2F login option is not available.

Hiding Portal Buttons from Normal Users

Recently, one of my co-workers was assigned to work with me to learn some FIM and to help, where possible, with some configuration.

One of the things on my list of “things to do” was to find a way of hiding certain portal buttons from a normal users view – after all they are not (currently) going to be allowed to use the portal for any self service task yet – that might come later….

So, I sent my co-worker off to find and implement the solution in the test environment, thinking “It can’t be that hard…”

I had already implemented the following solution to hide New and Delete User buttons:http://blogs.msdn.com/b/connector_space/archive/2014/10/02/5-minute-fim-hacks-hiding-the-quot-new-quot-and-quot-delete-quot-user-buttons.aspx

A week later we met to see how much progress had been made, he had found the following information (http://social.technet.microsoft.com/wiki/contents/articles/2139.how-to-remove-new-delete-and-other-buttons-from-fim-portal-pages.aspx), but didn’t really understand what it meant. So, we went through it together. I must admit, when I first read it through, it didn’t make a lot of sense to me either, but after a few re-reads it clicked into place.

This was done around 1 month ago and already I’m forgetting the actions that were carried out, so I’m going to document the steps in a more verbose fashion here for future reference.

Create new search scopes, using the original Search Scopes’ values as the basis. The resource type shold be “Resource”.

SearchScopes

I had already setup a new Usage Keyword “PrivilegedUsers”, that I was using to control the things that the helpdesk users would see to do their admin tasks. So, in the original search scopes this keyword needs to be added and the BasicUI and GlobalSearchResult keywords should be removed. Then in the (new) copies of the search scopes, BasicUI and GlobalSearchResultshould be present.

Original and New Search Scope Usage Keywords:

Do an IIS reset….

Now on the home page, choose one of those new search scopes and do a “blank” search. Copy the URL that this search went to – note that the UI of this search presents only the details button.

Do the same thing for each of the new search scopes, copying the URL’s for later….

Now we need to make those URL’s available via the portal UI. We need to do this for both the Navigation Bar and Home Page, so create new resources, using the information within the originals as the basis. The only change that I made was to remove the reference to (DGs) and (SGs) for the top level items and to add a description “User Read Only view” for those new items with the same name (so that I could tell the difference):

NavBarResources

Use the URL’s that were obtained from the search scopes to define the behaviour of the Resource:Behaviour

Do an IIS reset….

If you copied the Parent Order and Order values of the original Resources, the result is a little messy from the Administrators POV, as all of those items are crammed together. Unfortunately, I know of no way to hide an item from the admin, so I just rearranged the order of the layout. It displays as follows after re-arranging both the Nav Bar and Home Page Resource orders:

HomePage_Admin

A normal user looking at the portal sees this, the links go to the URL’s in those Search Scopes defined earlier:

HomePage_User

And when looking at for example “Distribution Groups”, sees that Details button only:

HomePage_User_Result

The PrivilegedUsers view, looks like this:HomePage_PU

And if a member of PrivilegedUsers uses the Distribution Groups (DGs) link, they see this – note all of the buttons are available:

DIst_PU_View

If I remember missing something or something not being quite right, I’ll be back to correct…