Monday, October 10, 2016

AD LDS for Cisco CMS - Local users and userProxy setup

Need an LDAP server, but can’t use your Active Directory for various reasons, and you don’t want to install a linux OpenLDAP setup?  If you have a Microsoft Windows Server available, you can install the Active Directory Lightweight Services (AD LDS) feature as a simple stand-alone LDAP server or as a proxy to your Active Directory you can augment with your own needs.  Using AD LDS you can create your own users and groups using local passwords you control, or you can also add proxied users where you use the passwords from your enterprise directory.  This guide will go through two setups: 1) setting up the minimum needed to have a stand-alone LDAP you will not sync with Active Directory and 2) Expand upon that basic setup to add importing and proxying of users from Active Directory.

This guide is written assuming Windows 2012, but should apply equally to Windows 2008.  

Chapter 1: Stand-Alone LDAP using AD LDS
A Windows Server 2012 server you have administrative rights to (Note covered, but should apply to Windows 2008/R2 servers as well)

While CMS has been tested by Cisco Sales to interoperate with Active Directory Lightweight Services (AD LDS), Cisco TAC can not provide support/guidance on operating your AD LDS instance.  It is recommended you work with your internal Microsoft resources or partner if you need assistance with maintaining or troubleshooting your AD LDS instance.  This configuration requires significant interaction with Active Directory as a LDAP server.  This document serves as a guide of a example configuration that has been validated to work, but is not intended to be all encompassing documentation for Microsoft’s AD LDS.  This configuration was documented and tested with Windows Server 2012 and CMS v2.0.4

Install AD LDS Service

Use the Server Manager, from the Manage Menu, select to add a New Role.  Use the Wizard to Add the Active Directory Lightweight Directory Services role to the local server - you can just click through the Role Wizard with the defaults.  Once the wizard completes, it will provide a clickable link to launch the configuration wizard for the service.  Click and start the configuration wizard

Proceed through the configuration wizard using the following guidance
  • when prompted for what type of instance to use, select A unique instance
  • when prompted for a name for the instance, use a label of your choice.  Note this label is what the service will be identified as when looking at the Windows Services Control Panel
  • leave the default port numbers of 389 and 636
  • when prompted for specifying if you want to create an application directory partition, select Yes, create an application partition, and specify the ldap root DN you want for this directory.  Example:  dc=cms,dc=lab
  • when prompted for installation path, leave the default or set to a path of your choice
  • when prompted for what service user to use, leave the default which is to use the Network Service account
  • when prompted for for assigning administrators to the service, leave the default choice of adding the current logged in user
  • when prompted for which LDFs to import, mark the checkboxes for import for MS-AdamSyncMetaData, MS-InetOrgPerson.ldf, MS-User.ldf, MS-UserProxy.ldf, MS-UserProxyFull.ldf
  • Complete the rest of wizard and finish

Add a service user for CMS
You will create a user in the AD LDS directory to use as the service user to allow CMS to connect to the directory.  This account only needs reader access to the directory for CMS to function.

  • From the Windows Start menu, type ‘ADSI Edit’ and open the utility from the search results.  Once opened, right click on the item in console tree, select to Connect to.  Set the Computer value to localhost:389  .  Select the option for Connection Point to Distinguished Name and enter the ldap DN you set in the installer.  Ex:  dc=cms,dc=lab  and click Ok

  • Once connected, expand the tree on the left.  Right-click on the root level folder (dc=cms,dc=lab) and select New->Object..  Select type user, click Next.  Set the Common Name you want for the new service user account (Example: cmsuser).   Click Next and Finish
  • Right click on the entry created for the user and select Reset Password.  Enter a password for the user and click Ok to save
  • Right click on the entry for the user and select Properties.  Scroll in the list until you find msDS-UserAccountDisable.  Double-click and set the value to False.  Click ok. 

  • Double click the entry for msDS-DontExpirePassword and set to True then click Ok. Click Ok again to close the Properties window for the user 
  • Expand the folder tree and click-on the folder CN=Roles.  In the list, right-click on CN=Readers and select Properties
  • Find the property named member in the list and double-click

  • Click the Add DN button and add the full DN of the user you created in the previous steps for the service user.  Example: cn=cmsuser,dc=cms,dc=lab  .  Click Ok, and Ok again to close the properties windows.

You now have an ‘empty’ LDAP server you can connect to via LDAP bind

Test the service user
You will use the built-in Windows ldp.exe LDAP utility to test connecting to the server using the newly created service account
  • From the Windows Start menu, type ‘ldp’ and open the utility from the search results.  Once opened, under the Connection Menu, select Connect.  In the server field, enter localhost and set port to 389.  The two checkboxes should be unchecked.  Click Ok.  A large amount of text will go by in the console, but it should not report errors
  • Under the Connection Menu, select Bind
  • Set Bind type to Simple bind
  • For username, put the full LDAP DN of the user you created
    • Ex: cn=cmsuser,dc=cms,dc=lab  
  • Enter the password you set on the account and click Ok to connect
  • If successful, the console will say ‘Authenticated as: ‘CN=…’ 
  • From the View menu, you can select Tree and in the drop down, select your top level DN (Ex: dc=cms,dc=lab) and click Ok.  The directory structure is then browsable in the client
This confirms your LDAP user details for use by CMS.  This test was from localhost, before attempting to connect from a CMS server, ensure LDAP 389 is allowed through the local Windows Firewall on the server if it is use

Enable SSL for LDAP server
The LDS Instance can use LDAP over SSL but must have access to a Certificate and Private key to function.  Without SSL, the LDAP user passwords will be in the clear on the network, so configuring SSL is recommended.

The LDS service can use a certificate from the service account’s Certificate Store, or the Computer’s Certificate Store.  This guide will outline using the Computer account as the Certificate Tools are limited when using the Service User accounts.  The default service user for AD LDS (Network Service) will not have permissions to a private key loaded in this certificate store by default so permissions must be granted.

  • Securing a certificate through a CSR, or enrollment from an Enterprise CA will not be covered in this guide but follows standard Window’s certificate tasks.  Import a certificate to the Computer’s Certificate Store using the Certificates Snap-In for Microsoft Management Console (mmc). 
  • Once a certificate is loaded in the Personal Store, right click the certificate, select All Tasks and Manage Private Keys.  If Network Service is not listed in the user list, click the ‘Add’ button, search for Network Service and add it to the list of users.  It will default to have Read and Full Control permissions.  Click Ok to save the changes and the Certificates Snap-in can be closed.  Restart the LDS windows service, or just restart the server
  • SSL can be verified using the ldp.exe tool to connect to the server as was previously, but when specifying the server values in the Connect screen, you must enter the hostname that matches the name on the certificate, set port to 636 and mark the SSL checkbox.  If you connect without errors, SSL is functioning properly. 
  • - If not, check
    • your firewall configuration for TCP port 636
    • your certificate's attributes for CN or SAN names and that it matches the hostname used in the ldp client
    • that the certificate is stored in the computer account
    • that the service user running LDS has read permissions to the private key
Extend the default schema
The default AD LDS schema is very lightweight and does not include common attributes you may see when trying to mimmic an Active Directory example.  Extending it to the Windows2008 functional level will open more opportunities and should be done to avoid later issues with incomplete schemas.

  • Open a command prompt on the server hosting LDS, and change to the adam directory under your Windows directory.  Ex:  c:\windows\adam
  • Issue the following command to import the Windows 2008 Forest Schema
ldifde -i -u -f ms-adamschemaw2k8.ldf -s localhost:389 -c "cn=Configuration,dc=X" #configurationNamingContext
  • The command should show progress and then report Command completed successfully

Adding a user to the LDAP for a CMA user
The LDS directory functions just as any other LDAP or Active Directory where you can create users, groups, and place them in containers or OUs of your choice to organize them.  These items can be created using virtually any LDAP tool or ldif imports.  Since this guide is covering a bare essentials setup, we will outline how to create a user using Microsoft’s ADSI Editor.  To be an account that can be authenticated locally by the LDS instance, you will need to create a user object, set a password, and have the msDS-UserAccountDisabled attribute set to False.  You should configure any attribute you will use with your CMS LDAP mappings.

NOTE:  sAMAccountName is a common attribute used by CMS LDAP mappings (and used in most documentation examples).  This attribute is not present in the default schema, but was added when the schema was extended to the Windows2008 functional level.  However, this attribute is not editable using the ADSI Editor GUI utility.  If you are only using a stand-alone LDAP and wish to use the ADSI GUI tool, you may wish to substitute another attribute to use in sAMAccountName ’s place, such as employeeID which can be edited in ADSI Editor.  Alternatively, you can create ldif files and make adds/changes using those files.

Using ASDI Edit to add a locally authenticated user
  • From the start menu, type ‘ADSI Edit’ and open utility from the search results.  Once opened, right click on the item in console tree, select to ‘Connect to’.  
    • Set the Computer value to localhost:389
    • Select the option for Connection Point to Distinguished Name and enter the ldap DN you set in the installer.  Ex:  dc=cms,dc=lab  and click Ok
  • Optional - You can create an OU to organize your users.  Right-click on the folder level to add the folder, select New -> Object, select organizationalUnit and give it a name.  Best practice is to organize users into OUs for easier filtering/searching
  • Expand the tree on the left.  Right-click on the OU or folder where you want to create the user and select New->Object..  Select type user, click Next.  Set the common name for the user Ex: 'John Doe’ and click Next and then click Finish
  • Right click on the new entry for the user and select Reset Password.  Enter a password for the user and click Ok to save
  • Right click on the user and select Properties. In the Attribute Editor, you will set the values for this user.  At the minimum you must add all the attributes you plan on using in your ldapMapping properties with CMS.  Because for this example this is a stand-alone LDAP that is not replicated from an enterprise directory, you can use whatever values you desire as long as the users have unique DNs, userPrincipalName attributes, and your resulting ldapMappings will result in unique usernames and space URIs.  Recommendation for the minimum fields include
     msDS-UserDontExpirePassword = true
     msDS-UserAccountDisabled = false
     userPrincipalName    (if using CAC cards)

For each attribute to set, double-click the attribute from the list, set the value desired, and click Ok.  Click Ok when done editing the user.

*NOTE - sAMAccount is a common attribute in CMS documentation, but is not editable in ADSI Edit.  If you prefer to use ADSI edit, you may want to substitute using another attribute such as employeeID and not use sAMAccountName.  This example is shown using employeeID

TIP: The Filter button in the ADSI Editor attribute page may be filtering out options you are looking for.  Click the button and ensure the Show only attributes that have values is unchecked to see all possible attributes.

Using ASDI Edit to add a user group
  • From the start menu, type ‘ADSI Edit’ and open utility from the search results.  Once opened, right click on the item in console tree, select to Connect to.  
    • Set the Computer value to localhost:389
    • Select the option for Connection Point to Distinguished Name and enter the ldap DN you set in the installer.  Ex:  dc=cms,dc=lab  and click Ok
  • Expand the tree on the left.  Right-click on the OU or folder where you want to create the group and select New->Object..  Select type group, click Next.  Set the common name for the user Ex: ‘Video Admins’ and click Next and then click Finish
  • Right click on the user and select Properties. In the Attribute Editor, find the member attribute and double-click.  The member attribute is a list of all users who are a member of this group
    • Click the Add DN button and enter the LDAP DN of the user you wish to add to the group (Ex:  cn=Jane Doe,dc=cms,dc=lab).  Click Ok, and repeat the process to add additional accounts.  Click Ok when complete.

TIP: Groups can have both users and other groups as members.  You can reference groups in your CMS LDAP filter as a way to select which users to import.  The following LDAP filter recursively selects members of the group cn=video admins,dc=cms,dc=lab  :  Example  memberOf:1.2.840.113556.1.4.1941:=cn=video admins,dc=cms,dc=lab

Adding a locally authenticated user using ldif
ldif files are simple text files fed into a ldif utility that will make the instructed changes to objects in the LDAP directory.  The text files must be customized to the change intended and syntax is critical.  Unfortunately the error messages from the server and ldif utilities are usually very cryptic and difficult to interpret.  AD LDS uses standard LDIF files and syntaxes.  Examples are given here to assist. 

To process a ldfi file against your LDS instance.
  • While logged in to the server hosting LDS as the user you added as an administrator when installing LDS, Open a command prompt
  • For simple ldif files that include full DN references (example:  enlisted.ldf.txt) , use the following command:   ldifde -i -f enlisted.ldf.txt -s localhost:389
  • A successful import will look like this

A failed command may report syntax errors or schema violations for the changes submitted

The following examples provide starting templates for common tasks.  To use, copy the example text to a text file in a program like Notepad.exe  Edit the dn field to the DN of the object you are trying to manipulate, and edit the attributes and values to match your intended change.  These examples are given as starting points.  You may use general LDAP and ldif command references for additional help.

To add a locally authenticated user via ldif
The file must include the DN to where you want the user to be located, and edit the attribute list to match the intended values.  Take special note of the password handling steps provided after the example.  The account can not have the msDS-UserAccountDisable attribute set until after the user has a valid password.  

Example user add.  Adds ‘Bob Smith’ to the existing ‘Local users’ folder
-------- CUT HERE ----------
dn: cn=Bob Smith,ou=Local Users,dc=cms,dc=lab
changetype: add
objectClass: user
displayName: Bob Smith
givenName: Bob
sn: Smith
telephoneNumber: 7035551211
employeeID: bob.smith
sAMAccountName: bob.smith

-------- CUT HERE ----------

NOTE: Passwords can not be set via plain-text or non-SSL connections.  Setting the password is possible using base64 encoding - See but can easily be done after the user is already in the directory using the ADSI Editor and selecting Reset Password.  So to complete the task of adding a new user, import the user via ldif, then set their password and the msDS-userAccountDisable attribute using following steps in ADSI Edit:
  • Right click on the entry created for the user and select Reset Password.  Enter a password for the user and click Ok to save
  • Right click on the entry for the user and select Properties.  Scroll in the list until you find msDS-UserAccountDisable.  Double-click and set the value to False.  Click ok. 
  • Double click the entry for msDS-DontExpirePassword and set to True then click Ok.  Click Ok again to close the Properties window.
Modify an existing user’s attribute via ldif
To add a new attribute or complete replace an existing value.  This example adds or replaces the sAMAccountName value for user cn=Bob Smith,ou=Local Users,dc=cms, dc=lab
Example user modify
-------- CUT HERE ----------
dn: cn=Bob Smith,ou=Local Users,dc=cms,dc=lab
changetype: modify
replace: sAMAccountName
sAMAccountName: bobby.smith
-------- CUT HERE ----------

Configure CMS for the LDS LDAP server
There are no special considerations needed to make the CMS LDAP import work with the AD LDS instance.  The server connection settings are done the same as when connecting to Active Directory, but it is recommended you use port 636 and secure connection option as LDAP bind alone does not protect passwords being transmitted over the wire.  Make sure any attributes you use for your LDAP filter and LDAP mappings are attributes that are defined in your LDS objects.  (Ex: do not try to filter on a attribute that is not populated in your LDS users).

Configure your server connection settings with the service user you created in earlier steps.  NOTE: unlike ActiveDirectory, authenticated users do not have read access to the LDS directory by default.  Only users added to the Reader or Administrator roles in LDS will be suitable for the service user for CMS LDAP settings.  This guide instructed you to create a local LDS user object to use as the service user, and that should be the user configured in CMS

Complete the LDAP base DN, filter, and mapping settings as you normally would.  Remember you can only use attributes you have populated in the LDS server.  

TIP: Make sure all users included in your ldap filter have all the attributes necessary for your ldap mappings.  The service user created may not have these and may cause ldap sync to fail.  If that is the case, exclude the user from the import using your LDAP filter, or add the necessary attributes to the user using ADSI Edit or ldif import.

Chapter 2: Configure LDS with proxied authentication
The prior chapter outlined configuring LDS to operate as a stand-alone LDAP server where you would create users and groups that can be used with your CMS installation.  The negative to this setup is you need to manage the passwords in this LDAP and create all the users and groups yourself.  What if you wanted to use the users and groups from Active Directory, but just needed the ability to add some of your own extra stuff, but can not do it in Active Directory itself?  

LDS can be configured to import your Active Directory into your LDS instance, and allow users to connect to your directory, but still be authenticated by the true Active Directory.  This is achieved with ‘userProxy’ objects in LDS.  A version of the user’s LDAP attributes are copied into your directory as a ‘userProxy’ object, which includes a link back to the original user record in ActiveDirectory.  When a user tries to bind to your LDS, the authentication portion is proxied back to Active Directory, while the rest of the contents come from your LDS instance.  This allows you create shadow copies of your Active Directory entries and mix them with entries of your own.  Have user accounts in AD, but not the security groups you desire?  Using LDS, you can import the enterprise users into LDS, create your own security group in LDS, and have CMS use the LDS security group to filter users by.. but when users authenticate, its done by the enterprise Active Directory!  This gives you the best of both worlds, but is a directory that the administrator would have to maintain.

Disclaimer:  While CMS has been tested by Cisco Sales to interoperate with Active Directory Lightweight Services (AD LDS), Cisco TAC can not provide support/guidance on operating your AD LDS instance.  It is recommended you work with your internal Microsoft resources or partner if you need assistance with maintaining or troubleshooting your AD LDS instance.  This configuration requires significant interaction with Active Directory as a LDAP server.  This document serves as a guide of a example configuration that has been validated to work, but is not intended to be all encompassing documentation for Microsoft’s AD LDS.  This configuration was documented and tested with Windows Server 2012 and CMS v2.0.4

Functional explanation
In the previous chapter, we setup LDS with ‘user’ objects with passwords.  These objects are defined in LDS and allow a client to do a simple LDAP bind using the password stored in the ‘user’ object’s attributes.  Now, we will use a utility named adamSync to read user objects from your enterprise Active Directory and create a matching object in LDS, with a subset of the attributes from the user’s definition in Active Directory.  But instead of creating ‘user’ objects as we did before for users, adamSync will create ‘userProxy’ objects.  This ‘userProxy’ object differs from ‘user’ objects by having an AuxillaryClass associated with it, that when seen, LDS knows if someone tries to bind with that object’s DN, to authenticate the user not with a local password, but by passing the password to the underlying Windows subsystems.  When adamSync creates the ‘userProxy’ object, it includes the Security ID (SID) of the user it copied from in Active Directory and that, along with the password supplied in the login/bind request, is what is tested by Windows to grant the request or not.

CMS can sync it’s local users with any type of object in the directory, so it can create users from both ‘user’ and ‘userProxy’ objects in the LDS directory.  The difference is simply when CMS tries to bind to LDAP to test a user’s login, users imported from ‘user’ objects in LDS will have their password checked locally by LDS, users linked to ‘userProxy’ objects will have the password verified by Active Directory.  The ‘user’ and ‘userProxy’ objects should include the attributes that you are interested in using in your LDAP Mappings (mail, telephoneNumber, etc).  Additional objects such as groups can also be synchronized into your LDS so they can be used by the filter settings when configuring your CMS ldap settings for filters, containers, etc.

Pre-requisites for proxied authentication
  • A Windows Server 2012 server you have administrative rights to (Note covered, but should apply to Windows 2008/R2 servers as well)
  • The Windows Server must be a member of the AD domain to authenticate users.  Other domains can be included as well if there is a trust between the computer’s domain and the other domains
  • You must have an existing Active Directory you will be importing users from

Install LDS Service
The installation of the AD LDS service and initial configuration is the same as the prior chapter.  You can add onto an existing LDS configuration setup as covered in the prior section, or if starting from scratch, complete the following sections from the prior chapter:
  1. Install AD LDS Service
  2. Add a service user for CMS
  3. Test service user
  4. Enable SSL for LDAP server
  5. Extend the default schema
Note, while using SSL was recommended in the previous section, it is required when using proxied authentication and the userProxy objects.  This can be disabled in the AD LDS configuration, but is not recommended since you will be sending Active Directory credentials in the clear if you do so.

Define Sync settings
  • Open Notepad.exe on the server hosting the LDS instance, and copy the following text to a new file.  Save the file in the adam folder in your windows directory and name it domainSync.xml
-------- CUT HERE ----------
<?xml version="1.0"?>
  <description>Cisco CMS Directory Sync</description>       
      <include>member</include>   <!-- Do not add this attribute to userProxy object -->

-------- CUT HERE ----------

  • Edit the file you just created and configure the following properties to match your environment
    • <source-ad-name></source-ad-name>  - Should be the FQDN of the Domain controller you wish to import from (the source)
    • <source-ad-partition>dc=company,dc=com</source-ad-partition> - The DN of the Active Directory Domain you are importing from
    • <source-ad-account>administrator</source-ad-account> - The AD Username of the user to connect to the source Active Directory.  This user must have read access to all the containers you intend to read from
    • <account-domain></account-domain> - Must be the Fully qualified DNS name of the Active Directory Domain you are importing from 
    • <target-dn>dc=cms,dc=lab</target-dn> - Set to the DN you configured for the LDS application partition during setup
    • <base-dn>dc=company,dc=com</base-dn> - Set to the top level of the Domain you wish to import from.  Recommend to set to the top level of the domain so you can handle any user moves.  Alternatively, you can set to a specific container if you have a very focused import
    • <object-filter>(&#124;(&amp;(sAMAccountType=805306368)(!(cn=Administrator))(!(cn=guest))(!(cn=krbtgt))(sAMAccountName=*))(objectClass=group)(objectCategory=OrganizationUnit))</object-filter>   - Controls which LDAP objects in and below the target-dn that will be synchronized.  This value will import users, OUs, and groups which should be sufficent for most needs.  If you wish to customize this LDAP filter, note the | and & characters should be encoded as follows: 
      • | (logical OR) substitute as &#124;
      • &(logical AND) substitute as &amp;
    • List of Attributes - these are all the attributes that the sync will read and sync over to your LDS directory.  This will limit what LDAP attributes from your AD that are available for your LDAP mappings in CMS.  If you need additional attributes from the user records, you can add them here following the existing syntax, but any user attributes you add *must* also add the attribute to the userProxy class using the AD Schema Editor (next steps).  Errors here will break the sync entirely
  • Save your changes, but keep the file open for reference. 
userProxy Schema
The default LDS userProxy object does not contain the common attributes that would normally be significant for a CMS installation, so we will use the Schema Editor to expand the list of valid attributes a userProxy can have.

Register the Schema snap-in
You only have to do this one time, it is not necessary each time you use the snap-in.

  • Log into the Windows server where LDS is installed with the user who has administrative rights to LDS
  • Open a command prompt and enter the command  regsvr32 schmmgmt.dll    You should get a pop-up saying DLL was registered successfully
Extend userProxy schema

  • From the Windows Start menu, enter ‘mmc' to search for the Microsoft Management Console and click to open
  • From the File Menu, select Add/Remove Snap-in and double-click the Active Directory Schema item to add it to the list of selected snap-ins.  Then click Ok
  • Active Directory Schema should appear in the Tree under Console Root.  Right-click on it and select Change Active Directory Domain Controller..  
  • In the dialog that opens, click in the table where it says to Type a directory name..  enter  localhost:389   and then select that row and click Ok.  You will get a long message about changing the domain you are managing and click Yes to acknowledge.
  • Expand the resulting tree structure, under Classes, scroll till you locate the userProxy object.  Right-click on it and select Properties
  • Select the attributes tab
  • In the optional box, you will see a single attribute userPrincipalName shown.  You must now add each of the attributes listed that were listed in the sync file created in the previous step.  Add an attribute by clicking the Add button, finding the name in the list, and clicking Ok.  Repeat this step until all the attributes in the sync file (except ‘member’ - this is not a user attribute so it should not be added to userProxy) are displaying in the Optional box.  Click Ok when completed.  You can close the Schema Editor/MMC window.  When prompted if you wish to save your console settings, you can select No.
ADAMsync is a command line program that executes the actual sync that is scoped by the domainsync.xml file created in the previous steps.  The configuration xml file is loaded into the LDS directory, and the sync is triggered by executing the ADAMsync program with the /sync or /fs parameters.

This guide will outline how to execute this manually, but you can extend this functionality by having adamsync ran automatically using Windows Task Manager.  Any future changes (except passwords) will not replicate to your LDS directory from the enterprise AD until ADAMsync is re-ran.  Depending on the size of your directory and scope, this task may cause load on a domain controller.  Please consult with your Directory Administrators regarding automating your syncs.

Load the Sync XML file

  • Your command prompt should still be open in the adam directory below the Windows directory.  If not, open a new command prompt and switch to that directory
  • Enter the following command    adamsync.exe /install localhost:389 domainsync.xml   System should respond with ‘Done’.  If you are using an account for source-ad-account other than the user who will be logged in when performing the sync, add /passPrompt to the command when issuing the adamsync.exec /install command
  • Anytime you make any changes to the domainsync.xml file, the above command must be repeated to reload the configuration into the service.
Triggering the ADAMSync
The sync must be triggered using the command below.  Change dc=cms,dc=lab to the DN of your LDS partition (same value you set in the target-dn value in the sync xml file and set during install)
adamsync.exe /sync localhost:389 “dc=cms,dc=lab” /log out.txt

Open the out.txt file and check for errors.  The log will generate a lot of information, but jump directly to the bottom for the critical results.  You should not see any errors and you should see a line containing Updating the configuration file DirSync cookie with a new value.  near the end of the file which confirms the run was completed without error.  If there are errors, confirm the contents of the sync xml file and confirm all attributes listed in the sync file have been successfully added to the userProxy object.

Confirm Sync Success

  • From the start menu, type ‘ADSI Edit’ and open utility from the search results.  Once opened, right click on the item in console tree, select to Connect to.  
    • Set the Computer value to localhost:389
    • Select the option for Connection Point to Distinguished Name and enter the ldap DN you set in the installer.  Ex:  dc=cms,dc=lab  and click Ok
  • Expand the tree and confirm the containers from your Active Directory are now seen in your LDS instance.  Confirm that you see items for your AD users, but the type column should show ‘userProxy’ instead of ‘user’.

TIP: If your LDS gets to a state you are uncertain of, running the adamSync with the parameter /sync replaced with /fs will perform a full sync which will overwrite any conflicting information in LDS with info from your Active Directory

Adding localized users and groups
With ADAMsync you will create objects in your directory based on the XML settings file.  You may want to augment your directory with entries that only exist in LDS for use cases like the following:

  • I need a CMA user account for a user that is not part of my Active Directory, such as an consultant, partner, or associate - You can add a user into LDS using the steps in the earlier chapter to add local users, along side automatically created users.  Both can co-exist in the same LDS directory
  • I need to group my Active Directory users for importing into CMS, but do not have an appropriate group in AD - You can add a group object in LDS using the steps in the earlier chapter, and then add the userProxy objects that were imported via ADAMsync as members of that group.  You can then use the memberOf attribute when importing users in CMS to automatically select users you have added to that group, while they still authenticate using the password from Active Directory
Adding these additional users and groups are done the same way as outlined in the previous chapter and can be done via ADSI Edit or ldif files.

Configure CMS for proxied authentication
Configuring CMS with this directory follows the same principles as configuring with Active Directory but with the following items of note

  • Unlike ActiveDirectory, authenticated users do not have read access to the LDS directory by default.  Only users added to the Reader or Administrator roles in LDS will be suitable for the service user for CMS LDAP settings.  This guide instructed you to create a local LDS user object to use as the service user, and that should be the user configured in CMS
  • The LDAP server settings must be configured to use port 636 when using proxied authentication - the LDS server will not authenticate users if not using SSL
  • Remember that your CMS user import must be sync’d for updates in LDS to propogate to CMS.  So when considering your change management and synchronization, changes should be made in AD, then LDS, and then have CMS sync.  Password changes do not require syncs.
  • The root of user’s DN’s will be the root of your LDS domain (dc=cms,dc=lab in this example), not your original Active Directory domain.  Remember this when constructing LDAP filters and LDAP mappings.  So if your LDS server with DN equals dc=cms,dc=lab is importing the user CN=Bob Smith,CN=Users,DC=company,DC=com  the user will be represented with a different DN, CN=Bob Smith,CN=Users,DC=cms,DC=lab in the LDS directory that CMS will be querying.  NOTE: This will not change the names users log in with, because the user logs in with their XMPP ID, not their DN, but be aware when writing your LDAP import settings.
  • When designing LDAP filters for CMS, you will be targeting classes user and userProxy.  Make sure your filter captures the ldap objects you intend.  For instance, beware objectClass=person does NOT include userProxy objects.

Validate total solution

  • Pick a user from your Active Directory to test with that you know the user account’s password.
  • Confirm the user is listed in the User List in the CMS webAdmin page and note the user’s XMPP ID
  • Using either the CMA client, or the webbridge, log in using the user’s XMPP ID and Active Directory password.  User should authenticate and login

Monday, September 21, 2015

Booting VMWare Fusion from USB

Need to boot a VMWare Fusion guest OS from a physical USB drive?  Don't want to cheat by simply moving the image from the USB to a disk image?

The limitation is the VMWare BIOS does not support boot from USB - so the simplest workaround is to leverage a great simple utility called Plop Bootmanager.  It's a image you can boot via floppy (which VMWare does support) which allows you to boot from USB!

1) Get Plop Bootmanager from
2) Ensure your guest machine has a floppy drive in its supported hardware, if not add it.  Link the drive to the plpbt.img and ensure the drive is set to be connected to the guest OS
3) Boot the machine, you'll get the cool starfield boot menu after it boots from the floppy drive.  If it doesn't work, use the startup device setting in VMWare to ensure the floppy is the boot device
4) Connect your USB drive, and in the VMWare interface connect the USB drive to the guest OS
5) In the guest machine, select USB from the menu.. and watch the magic!
6) Ensure you disconnect the floppy drive in the VMWare settings to avoid booting to it on next boot

Monday, June 22, 2015

LED Lighting DIY for Ikea Detolf Cabinets


I knew right from the start I wanted to LED light my detolf cabinets after seeing so many impressive setups on the tfw2005 forums.  I also knew I wanted to do it cheap, and that doing it via a DIY path was viable for me.  Looking at other people's installs, the devil is in the details and often people would skimp a bit on the tidy side of the wiring, and people also weren't very specific in their descriptions of their builds!  So I had the idea, but no build details.. so here is my write-up of my install for future buyers :)

LED Source

This is driven by personal choices and availability more than anything.. but there are some basics.  
  • Single color vs RGB - This is a cabinet display, so I knew I didn't need the ability to change colors except for 'just because I could'.  Single color is also only 2 wire, where RGB is 4 wire.  2 wire was going to be much easier to install and smaller to hide cables... so Single Color it is!
  • Warm White vs Cool White? - You can find a natural color 'warm white' if you desire.. but since we are playing with toys here, I want the higher tech looking cool white
  • 3628 vs 5050 - The numbers refer to the actual LED size 3.6mmX2.8mm vs 5mmX5mm.  Again because we are going for tidy... I wanted the smaller LEDs.. so 3628 it is.  3628 strips are 8mm wide.  5050 can be brighter, but also take more power and larger.
  • High Density? - The strips normally come in 300 LEDs per meter or 600 LEDs per meter (high density).  In theory more LEDs = more light.. but it depends on the actual components used.  Try to look for luminance specs when comparing products.  In my samples, I actually preferred the light output of my 300 LED strip over the 600!  The other advantage of high density is the points where the strip can be cut and joined are more prevalent.  In my samples, the 300 strip could be cut every 3 inches, the 600 was every 1 inch. In my install, the trimming was not a showstopper.  
My conclusion was to use a 3628 cool white strip with 300 LEDs per meter.  Source - Amazon -  $8 with prime shipping.
Note this strip is a 'waterproof' strip.  Waterproof obviously isn't needed, but I didn't notice it when initially ordering, but now that I have it, it was ok and I didn't mind it.  In some sense, it helped support the strip making it easier to work with and diffuses the light some.

NOTE:  These kinds of products can change components and be slightly different from different sources.  The strip I purchased had wide angle LEDs, and when purchased again from a different seller, the LEDs were different.  So be careful if buying at different times.  I bought the item sold by Amazon directly and I was happy with that set (twice).

Power Supply

You can use any 12V power supply with enough power to drive your load.  The load is specific to your wiring layout and LED choice.  Amps = Watts / 12V 
I wanted to run everything from a single power supply so it could be controlled from a single controller.  I calculated the theoretical load for my wiring and LEDs as 1 Amp @ 12V per cabinet.  Since I was doing two, and wanted plenty of head room, I got a 5A supply.  A single cabinet could be done by a 2A or 3A supply easily.  My 5A supply - $17 from Amazon Prime -  5A power supply with 2.1mm plug


Approximately ~20ft of 20 or 22 awg stranded single conductor wire per cabinet is needed. Here you can go multiple ways depending on what you have available.  Ironically this was the hardest part to source!  You want smaller wire to make it easier to hide.. any 20 to 24 awg stranded should be fine for this load.  Home Depot/Lowes won't have it, but Train Hobby Stores will and call it 'Layout Wire'.  My preference was black wire for the jumpers (you'll need about 2ft per cabinet) and white for the cabinet wiring.  Worse case you can use 18" speaker wire, but it's a lot more bulky and hard to hide/bend.  You may also find red/black speaker wire in smaller sizes, but will be harder to hide.  Once you find the correct cable, you should be able to get a spool of 50 or 100ft for ~$8-12

Other Misc parts needed:

Wireless LED Controller - I didn't have a switched outlet handy, so I wanted a remote power switch.  This fit the bill and has other features like dimming!  This is the version with 2.1mm plugs already attached - $6 from Amazon Prime - 
Clear/White Wire Ties - Get a bag of the smallest tie size you can.. Usually about 4"  ~$4 from your home improvement store
Wire Shrink Wrap - ~10 inches of 1/8" heat shrink colored to match your cabinet wiring.  I just bought a big box of everything from Amazon Prime to replace the leftovers I was using - $12 from Amazon Prime - 

The following components could be made redundant if you hardwired everything, but I opt'd using these so it could be plugged/unplugged in pieces.

Power Plug Adapter - These make the wiring easy and are useful for quick testing too. The build needs one per cabinet.. A set of 10 is only $3 -
Power Splitter - Since I was doing two cabinets.. this splits the power supply to two 2.1mm male jacks.  You can get higher #s of spliters if you need to do more cabinets and your power supply is strong enough. - 1 to 2 splitter $4 with Amazon Prime - 
Single color LED Wiring Connectors - In the spirit of pluggable, I ordered these as well, tho in hindsight it might be advisable to skip these.  I'll cover that at the end.  This guide is written assuming you are using them.  Pack of 10 $7 from Amazon Prime - 


  • Soldering Iron + solder
  • Razor Blade
  • Wire Cutter and Wire Stripper that can strip 20-24 awg wire
  • Electrical tape
  • Scissors
  • Small Precision screwdriver
  • Small needle nose plyers
  • Diagonal cutters or similar nub cutters
  • Hair Dryer, lighter, or torch to shrink heat shrink
  • Scrap cardboard.  One piece for cutting with the razor blade, another roughly 2'x2' for making a template


The driving factors in my design was 1) sufficient, even light  2) clean look - hide wiring as much as possible 3) Serviceable if need to deal with failures/dis-assembly.  
In researching other people's installs I found where the lights were installed varied, but taping directly to the glass shelf was more common than I expected.  I originally thought I would connect to the shelf bars, but I abandoned that once considering how to keep them aligned, stuck, and still look tidy.  In what order, lengths, etc where the LEDs connected was a topic not well covered in other people's pictures.  

In the interest of minimal cabling I went for a 'common bus' design.  One set of wires runs the full length of the cabinet, and each shelf has a string of LEDs that taps into the common bus.  This design puts a series set of LEDs per shelf, in parallel with the other shelves.  

Each shelf has three LED strips wired together to go around the edge of the shelf, and the set is connected to the common bus wires running the length of the cabinet.  The bus wires are terminated with a 2.1mm adapter for easy plug/unplug, which is connected to a 2.1mm splitter so multiple cabinets can be fed from the same power supply.  The power supply is connected to the LED controller, which is in turn connected to the splitter.


Each shelf in the cabinet is the same, so my design uses the same setup on each shelf, including the cabinet top, to ease the build.  The LEDs go along each side and the front of the shelf.  Make note of where your LEDs can be cut - there will be small pads and lines to show where you can cut the LED strips.  The LEDs can be cut with simple household scissors - make sure you cut in the middle so the pads left on each edge are as large as possible. 
Layout the LEDs on one of the shelves and cut three strips to mock up how they would lay out on the shelf if attached to the underside of the shelf.  For the LED strips I used, this resulted in a 11.75" strip for the front, and 9.75" strips for the sides. In my layout, the strips are about 3/8 of a inch inside the shelf supports, and about 0.5" from the front of the shelf.

Make note of which side of your cabinet you want the common bus wires and connects to be.  I chose to run them on the inside edge of my cabinets to try to make it harder to see.  Measure the glass shelves' length and width dimensions.  Note where the inside edge of the bar supports are relative to the shelf edge.

Use some scrap cardboard as a cutting board, take your three cut LED strips, and using a razor blade, trim the waterproofing off the end of the strips.  Cut the vinyl material back to a point near the first component on the strip.  Slice through the vinyl portion being careful not to cut the strip itself, and pull the waterproofing off.  Make a cut, bend back, repeat, etc.  You can try to get under the edge and separate it, but I found just making a vertical cut, then bending and working the cut till you get separation and you can tear the piece off

Because all shelves are the same - it makes sense to use a template to ease your build.  I just used the bottom of the Amazon box my stuff came in!  Transfer the dimensions of the measured shelf to the cardboard and draw out your shelf.  

Next, layout your trimmed LED strips as you will want them to be on the shelf.  Lay them out with their backing down, LED facing up.  This is the layout if you were looking the shelf from the bottom.  If your bus wires will be on the right side of your cabinet, they will be on the LEFT REAR side of your template because you are looking at it upside down.

If you will be using the wiring connectors, they need about 1/4" clearance on the strip to connect to the strip.  On the LED strips I used, a diode near the edge of one side of the LED cutting points meant only one side of trimming point had enough clearance to use a connector so you had to orient the strips a specific direction.  If the power is on the LEFT side of your template, orient the LED strips so the + pad of each strip is to the middle of the shelf.  This should put the edge WITHOUT the diode near the left rear of your template.  If your power is on the RIGHT side of your template, orient the strips with the - pad to the middle.  Again, this should result in the LED end with the most space being the end near your power corner.  Each LED strip should be laid out so the + and - pads are on the same side of two adjacent strips.  

With the shelf marked out on the template, arrange the LED strips as you would have them on the shelf.  Use strips of electrical tape right over the top of the strip to help you make the layout.  In my setup, I arranged the three strips so the side strips ended slightly before the inside edge of the center strip, and the entire assembly would align so the wire connector on the power side would be right inside the edge of the shelf.  This resulted in a layout where the center strip was approx 1/2" from the front edge centered left to right, and the side strips were oriented approximately 3/8" inside the shelf supports.  You should be able to make L shape lines between the like +/- pads on adjacent LED strips.  Use one of the wire connectors to help you gauge where the power side should end so the connector is still 'on' the shelf.

Corners arranged

Connector staged to place the strip at the correct location

Once you have the layout as you want it, use a pen and mark on your template the + and - symbols near each edge to help remind you, and mark around the edge of the strips near the joints so you can easily align the next set of LED strips.

Template notes to help arrangement - Note, + or - locations will depend on which side the power connector is wired - don't follow this example blindly :)
The photo below is an example template with power connector on the RIGHT, so - is to the inside.  Note each LED end has lines around it, the - and + symbols to help, and the electrical tape holding things in place.

Using the soldering iron, load up each strips' pads with solder.  Do NOT put solder on the ends connecting to the wire connectors, only the joints between the center and side strips.  Just place the iron on the pad, and touch some solder to the point and create a small ball.  Don't worry about sloppy here, just don't short the pads together or have huge spikes of solder poking out.  

Next you will have to connect the + pad of the center strip to the + pad of the adjacent strip using a small jumper wire.  Do the same for the - pads, and then repeat for the other side of the center strip.    Start with the inside pad, and then repeat for the outside pad.  

To make the jumper wires, cut a small portion of your layout wire, shape it into the L shape needed to fit between the pads.  I recommend cutting the piece about 1.5" long, then trim about 1/4 of the insulation off one end with your wire strippers.  Twist the exposed wire to tighten the strands, then trim the exposed wire to about 1/16" long.  Lay it on the template, and bend the wire to layout between the LED strips.  Trim the wire long, strip the insulation back about 1/4", twist the wires, and again laying the piece on the template, trim to final size needed.  Keep it a little long and trim as needed.  Repeat this till you have a jumper that lays between the pads well.

Hold the jumper with a pair of needle nose pliers, melt the solder on the pad, and solder the wire to the pad.  You won't get beautiful joints because of the pads, but it will hold very strong.  Just try to keep the wire from spreading out or shorting to the adjacent pad.  The wire should have good contact with the pad and the pad should move in unison with the wire when moved.  Then repeat for the other side of the wire.  Install all four jumpers needed to connect the three LED strips.

These photos show white jumpers - I experimented with both white and black and found black to be preferable as it tended to draw less attention to them once installed.

Here is a view of black jumpers, installed in the cabinet

Next you will need to test the strip.  If your strip has the power on the left side of the template, grab a wire connector and find the end where clasp opens on the red wire side (if power is on the right, use the side with clasp on the black side - you want the clasp opening on the 'inside' of the shelf).  Measure back 3" from the connector and cut the the other end of the connector off.  Split the wires, and strip the insulation back approx 1/8".  Use one of the female plug 2.1mm adaptors and screw the adaptor onto the connector.  Use this connector+adaptor as your test plug to test each shelf unit as you build them.

On the LED strip where your wire connector will attach, pull back the adhesive tape cover on the bottom of the strip where the weather proofing has been removed and trim it.  Only remove the cover where the wire connector will be.  Open the clasp of the connector, insert the strip so the prongs make contact with the exposed pads on the strip, then close the clasp.  Plug the strip into your power supply and it should all light!

If no strips light, ensure the wires at the power adapter are secure and in the correct slot.  Check the wiring connector and ensure it's making good contacts with the pad.  If one strip doesn't light, first double check the + goes to + and - to - between each strip.  Press and/or move the strips around to see if you have a flaky joint.  Unplug the strip before making any corrections by re-soldering the jumpers in question.  Ensure all three strips light reliably and then take the set to your cabinet and lay out the set on the top side of a shelf, LED down and ensure it lays out as you want.  Try to avoid stressing the jumper connections when possible.  If you are not happy with the layout, make any adjustments to your template needed to guide your next sets.  You can remove the wire connector from the strip and use it again when testing other sets.

If you are happy with your first set, then using your template, make three more sets of the LED shelf sets.  The lines and +/- symbols you drew on the template will speed up the additional builds and ensure consistency.

Stage the Wire Connectors

The wire connectors provide a way to disconnect the shelf sets from the common wiring if need be for adjustments/fixes.  If you bought the back to back ones linked above, you only use one side of the connector for each shelf.  But which side you use matters.  You want to use the side where the clasp will open from side AWAY from the side of your cabinet so you can reach it.  Using your template as a guide, determine which side of the connector you will use so it matches the desired clasp direction and LED + / - pads.  If you can't get the pads to line up, red to +, black to -, don't worry about it you can ignore color as long as you are consistent when you wire everything up.

When connecting to the common bus, we will stagger the joints to minimize bulk.  In my design, for the wires coming from the connector, I left 0.5" to account for the bend, put the first joint 1" down, and the second joint 2" down from the connector.

Make a simple template.  On your scrap cardboard, draw a line marking 0, 1.5", 1.75", 2.5", and 2.75" lengths.  Grab a connector with the end you will use, lay it on the template it so the back end of the connector where the wire starts lies at the 0 mark, and cut the wires at the 2.75" mark.  Using your razor blade, split the black and red wires and pull them apart.  Pick one color to be the long wire - you will use this same scheme for all your shelves in this cabinet, so be consistent.  Using your template, strip 1/4" of the end of the long wire, and twist the strands.  Trim the other wire to the 1.75" mark, and then strip 1/4" of the wire and twist the strands.  You should have a connector with a 2.5" of covered wire with an extra 1/4" of bare wire, and the other lead 1.5" of covered wire with an extra 1/4" of bare wire.  

Repeat the process and make three more connectors.  Be sure to be consistent with which way the clasp opens, and which color wire is the long and short wire.  Check things against a LED set on your template if you need to double check stuff.. remember.. the cardboard is the BOTTOM of your shelf, so the clasp should open upwards and from the middle when sitting on the template.

The bus wires

The bus wire needs to be >65" to run the length of the cabinet.  I recommend starting with a longer wire, you can always trim shorter.  Cut a piece of wire approximately 85" long.  Trim 1/4" of the end of the wire.  Cut a piece of heat shrink about 5/8" long and slide onto the wire.  Take one of your wire connectors, with the long wire, and shape the bare wire into a hook shape (wrapping around the shaft of a small screwdriver is a quick trick!).  Do the same with the bus wire, then loop the two wire hooks together, then twist them tight.

The joint should support itself.  Solder the joint securely and allow it to cool.  Then slide the heat shrink over the joint and shrink using a hair dryer, lighter, or torch.  Be careful not to burn the wires if using an open flame.  This will be the joint for the top of the cabinet.

Each shelf is 15.5" apart, and it's 15 1/8" from the top of the cabinet to the bottom of the top shelf.  Each joint will be 15.5" apart, and the first joint will be 15 1/8" from the start.  Because the of the lead on the wire connectors, the joints will be 1" and 2" below the shelf itself.

On your long bus wire, measure 15 1/8" along the wire from the solder joint and using your wire strippers, split the wire insulation and pull the insulation back to create a bare spot in the wire WITHOUT cutting the wire.  If you use wire strippers with the correct size for your wire, this is trivial.  Just cut and then tug on the wire to create a gap.

Take one of the staged wire connectors, lay the LONG wire along the bus wire with the bare end pointing away from the previous joint you just made.  Take the bare wire of the LONG lead and wrap tightly around the bare spot created on the bus wire.

Solder the wires, and allow to cool.  then cut a piece of heat shrink about 1/2" long, slide over the end of the bus wire and up over this joint, including where the wires lay parallel to each other.  Shrink with heat.

Repeat the steps for two more connectors.  Measure 15.5" down the bus wire from the solder joint (not from where the heat shrink ends - from the joint!), and repeat the process.  Split the insulation, lay out the LONG lead of a staged connector, wrap it, solder it, then cover with heat shrink.

Cut a second wire approx 86" long to act as the second bus wire.   Cut a piece of heat shrink about 5/8" long and slide onto the wire.  Strip 1/4" from the end of the wire.  Shape the bare wire into a hook shape.  Take the remaining short lead from the top most wire connector, form the bare wire into a hook, loop the two wire hooks together, then twist them tight.  Solder, and then shrink the heat shrink over the joint.  

The trick with the second wire is ensuring the wire connectors and bus wires are not twisted or crossing so they lay nicely when installed in the cabinet.  When connecting the wires of a connector, we need to lay the cables and connectors out tidy to ensure we don't introduce twists between it and the previous connector.  Grap the top most connector, lay it so the clasp is facing up, then layout the bus wire to the right until you get to the second wire connector.  Orient the second connector so it lays to the left along the bus wire, pointing at the previous connector, clasp up,  and the leads not crossing/twisted.  Now take your second bus wire, stretch it out and lay it along side the first bus wire so it lays flat and does not cross the first wire.  At the next connector, the goal is to have the connector pointing to the left, laying flat on the bus wires, clasp up, and no crossing of the leads.  

It should look like this diagram

With the connector and wires laid out, mark where the bare wire of the first unattached short lead crosses the second bus wire.  Using your wire stripper, split the insulation and expose a small gap.  Twist the bare lead of the connector onto the wire and solder the joint.  Cut a piece of heat shrink about 1/2" long, slide over the end of the bus wire up over the joint and shrink with heat.  Repeat this process for each of the connectors.  You do not need to measure distances as long as you layout the wires flat and oriented correctly.

An example of a completed wire connector joint

Now connect a LED shelf set to each of the wire connectors.  Pull back and trim the 1/2" or so of tape backing cover on the LED strip where the connector will attach.  This will make the set easier to install in the cabinet.  Open the clasp on the connector, slide in the strip making sure the pads make good contact with the prongs, and then close the clasp..  Once all are connected, strip 1/4" of the end of the bus wires and connect a 2.1mm female adapter.  Connect to the power supply and check that all LED strips light reliably.  Adjust any wire connectors or jumpers as needed to get the full set to light reliably.  This is also a convenient time to test your LED controller!

Install into cabinet

Empty out your cabinets to give yourself room and to avoid risking dropping anything!  With the full set complete, run the set of wires down the back of the cabinet by dropping them behind the shelves.  Starting at the top of the cabinet, test fit where you want the LED strips to be to mounted to the top of the cabinet trying to be uniform in layout and positioning so the wire connector aligns near the shelf supports and along the back edge of the shelves.  Starting at the wood top, remove the backing from the LED strip one at a time, and press the strip into place.  Repeat for all three strips and press firmly into place.  Make sure you don't create any binding in the corners.  You may need a short piece of electrical tape to hold the wire connector to the top temporarily to help keep it from pulling the rest of the strip down while doing the initial install.

Once the strips are attached, run the bus wires down behind the wire posts of the cabinet, using wire ties to organize the wire as you move down to the next shelf.  Avoid twists, and don't tighten the ties until you have mounted the next lower set of LEDs so you can shift the ties as needed.  I used 3-5 ties in-between each shelf.  I also used ties right under the wire connector to help support it's bend.

A look at the wire ties (final install)

Continue moving top to bottom, aligning the bus wires, then attaching the next shelf of LEDs, and repeat.  Once a shelf is installed, it helps to tidy up the wires above it and tighten the wire ties.

Once you get to the bottom shelf, you will need to run the bus wires out of the cabinet.  In my case, I chose to simply drill through the the bottom shelf and run the wires out the back.  I have the plastic feet on my cabinet, and they take up >1" in radius around the post supports, so you can not drill directly near the wire posts.  Instead, I moved approx 2" to the inside from the wire post, and drilled a 1/4" hole through the bottom of the cabinet.  The minimum size how you need will depend on your choice of wire.  Vacuum out the dust created.  I also painted the hole with semi-gloss black paint to help make it disappear.  While you have the paint out, it is useful to paint the front edge of the cabinet where the crappy laminate doesn't cover the wood on the seams very well.  Brush on the seam generously, then a quick wipe with your finger will remove the excess leaving a perfect look.

Pass the bus wires through the new hole, and use your wire ties to get the wire as in conspicuous as possible.  Trim the wires to the length desired depending on where you want your 2.1mm plug to be.  Strip the ends of the wire, and attach a 2.1mm female power adaptor.  Connect to the wire splitter if needed, then into the LED remote, and then the power supply.  Light it up, and tidy up the wiring to your taste!  If the lights don't work, try flipping the bus wires in the 2.1mm adapter.

Here is the white wire through the bottom of the cabinet up close

Finish up your job by clipping all the wire ties close and adjusting the locations and rotation to hide your bus wires as best you can and cleaning up the glass anywhere you put your finger prints on :)
Some final views

Retrospective and Improvements

What would I change in hindsight?  First, while the wire connectors were chosen for serviceability, I don't think they are worth the trade-off in reliability.  They can be a source of unreliable connections making a shelf flicker, and aren't as easy to attach while in the cabinet as I would have hoped for.  I would suggest substituting the connectors with simple hardwired leads between the LED strips and the bus wires.  Instead of a 2.75" and 1.75" wire leads on the connectors, add another 1/2" of length to a wire and attach the LED strips via these jumpers to the bus wires the same as you connected the wire connectors.

Wire?  I found the black wire better to be better for the jumpers between the strips, but was mainly indifferent when it came to the bus wires.  Black or white would do.   20 awg was more than large enough, if I could find smaller wire, I would have used it.

Bus Design?  Worked like a champ and would highly recommend it as a wiring setup for these cabinets.

I actually used laytex gloves when installing into the cabinet to minimize how many fingerprint/etc I got on the glass I had to clean up.  When vacuuming the dust from drilling is also a good time to vacuum any dust from the cabinet as well :)

Power choices?  Using the 2.1mm adapters and splitters was a great choice and having the box of adapters made testing things SOOO much easier.  The LED controller did not work with the first power transformer I had, but worked fine with the one I bought.  No idea why.. but having it all working via remote and easy 2.1mm adapters is very much recommended!

Total Cost for two cabinets?
$8 x 2 for LED reels
$10 for Spool of Wire
$17 for Power supply
$3 for 2.1mm adapters
$6 for LED controller
$4 for 2.1mm spliter
$7 for Wire Connectors
$12 for shrink wrap
$4 for wire ties

= $79 / 2 = $39 cabinet.  It would only cost about $12 more to add a third cabinet.  And could be as cheap as ~$15 /cabinet if you had wire/shrink wrap handy and hardwired things.