OpenICF Windows Local Accounts Connector
The OpenICF Windows Local Accounts connector is implemented as a C#-based OpenICF .NET connector embedded and started by an OpenICF .NET connector server. The OpenICF .NET connector server receives requests from the DirX Identity OpenICF connector, which is a Java-based connector that conforms to the DirX Identity Java Connector Integration Framework and which sends the requests to the OpenICF connector server using an internal OpenICF protocol.
For a description of the Java-based DirX Identity OpenICF connector, see the chapter "OpenICF Connector" in this reference. This chapter also describes how to secure the connection from the Java-based OpenICF connector to the OpenICF connector server with SSL.
Overview
The OpenICF Windows Local Accounts connector is deployed as an OpenICF connector bundle to a .NET-based OpenICF connector server running on any Windows server.
On one side, it implements the OpenICF SPI operations Schema(), Create(), Update(), Delete(), CreateFilterTranslator() and ExecuteQuery() called by the OpenICF connector server that receives the corresponding SPML Add, Modify, Delete and Search requests by the Java-based OpenICF connector.
On the other side, it implements the System.DirectoryServices.AccountManagement API for accessing a Windows local accounts and groups database. The Account Management API is a .NET framework DirectoryServices namespace that provides uniform access and manipulation of user, computer and group security principals for three directory platforms: the Active Directory Domain Services, the local Security Account Manager (SAM) database on every Windows computer and the Active Directory Lightweight Directory Services (AD LDS).
The connector manages user and group objects of a SAM database located on any computer in the Windows network.
The Account Management API can only use the Windows NT LAN Manager (NTLM) protocol for authentication when accessing a SAM database. If user name and password are not provided for authentication, the security context of the calling thread (the account under which the connector server runs) is used for binding. The Account Management API also supports Kerberos or SSL authentication for accessing Active Directory.
The Account Management API does not provide any encryption protocol for the subsequent data transfer when accessing a SAM database. Hence the attributes and values of a create or modify request are not completely encrypted - as could be done by choosing Kerberos when accessing Active Directory. If a password is submitted in such a request it is always encrypted as stated by Microsoft:
When changing or setting a user’s password on a remote SAM DB with the AccountManagement API methods UserPrincipal::ChangePassword(oldPassword, newPassword) or UserPrincipal::SetPassword(newPassword) the function SamrUnicodeChangePasswordUser2 is called behind the scene, which encrypts the new password with a key from the hash of the old password or, in the latter case when no old password is provided, with an internal temporary key.
Moreover there is the possibility to secure the complete RPC/TCP connection, which is the underlying protocol used by the Account Management API by configuring IPSec. IPSec is a computer-wide setting that secures all IP traffic. It is not specific to an individual application like SSL, but it is transparent to applications.
Prerequisites
The OpenICF .NET connector server in the OpenICF Windows Local Accounts connector configuration has the following prerequisites:
-
The connector server must be OpenICF .NET connector server version 1.4.0.0 or newer.
-
The machine on which the connector server is installed must be running Windows Server 2008, Windows Server 2012, Windows 7 or Windows 8 and must have at least 20 MB of free disk space and 200 MB of available RAM.
-
The .NET framework version 4.0 or newer must be installed on the machine where the connector server is installed.
To install the OpenICF .NET connector server:
-
Download an OpenICF .NET connector server version 1.4.0.0 or newer from the Internet as a ConnectorServer*.msi* installation file; for example, openicf-1.4.0.0-SNAPSHOT-dotnet.msi.
-
Run the ConnectorServer*.msi* installation file and then follow the wizard’s instructions. When it completes, the connector server is now installed as the Windows service ConnectorServerService. The default installation location is C:\Program Files\Identity Connectors\Connector Server.
To configure the OpenICF .NET connector server:
-
Set the key (shared secret key) for the connector server: navigate to the directory where the connector server is installed and then execute the following command in the MS/DOS shell:
ConnectorServer /setkey newkey
where newkey is the value for the connector server key. The same key (= password) must be configured in the OpenICF Windows Local Accounts connector configuration file in the password property of the connection section of type OpenIcfServer (see the configuration snippet given in the next step). -
Update the connector server configuration file ConnectorServer.exe.Config. This file is located in the connector server installation directory and is an XML-formatted file. The most common items to change in this configuration file are the port number or the trace settings. For the trace settings, you can specify a log file name and a trace level (for example, All) in the <trace> section and then find the related logging of all OpenICF connector bundles deployed into the connector server in that log file, for example:
<trace autoflush="true" indentsize="4">
<listeners>
<remove name="Default" />
<!--add name="console" /-->
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\Program Files (x86)\Identity Connectors\Connector Server\connectorserver.log" traceOutputOptions="DateTime">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="All"/>
</add>
</listeners>
</trace>
The OpenICF Windows Local Accounts connector has the following prerequisites:
-
The WindowsLocalAccounts.Connector-1.4.0.0.zip bundle, which is installed to the DirX Identity subfolder install_path*\connectors\OpenICF\bundles\dotnet*, must be deployed (that is, unzipped) to the installation folder of the OpenICF .NET connector server. Restarting the OpenICF .NET connector server activates the new bundle..
-
On the target Windows machines with the SAM databases to be managed, the Open ICF Windows Local Accounts connector can only access the SAM databases of the target Windows machines if they satisfy the following prerequisites:
-
Windows Server 2012 R2 system - the Remote Registry Service must be started. This action is performed by default on this Windows version.
-
Windows Server 2008 R2 system - the Remote Registry Service must be started (performed by default).
-
Windows 7 Professional Client system - the Remote Registry Service must be started, (not performed by default) and the following Inbound Rules of the Windows Firewall configuration settings must be enabled: Remote Service Management (NP-In) for the Profile type Domain.
-
Windows Server 2003 system - the Remote Registry Service must be started (performed by default) and the File and Printer Sharing services must be selected in the Exceptions tab of the Windows Firewall configuration settings.
There may be other Inbound Rules to be enabled or Firewall Exceptions to be set to allow SAM database access in addition to or instead of those described here if they cover the relevant port ranges required for the RPC traffic.
The installation of a .NET Framework is not necessary on a target machine.
If the Remote Registry Service is not started on a target machine, the Windows Local Accounts connector receives the error message "The network path was not found" when trying to perform add, modify, delete or search operations.
Limitations
The following limitations apply:
-
Between the machine where the connector service runs and each remote target machine with a local SAM database to be managed, only one RPC connection for each target machine is valid. An additional RPC connection with different credentials than an existing RPC connection to the same target machine may fail due to the well-known Microsoft RPC limitation described under KB106211, KB173199, KB183366, KB824198. As a result, the connections to the target machines should not be built up with changing credentials.
-
Due to the preceding limitation, the .NET connector server service must be started under an account with appropriate access rights to the remote target machine’s SAM database (it must be a member of the target machine’s Administrator group). As a result, no user and password must be specified for the Windows Local Accounts connector. If they are specified, they are passed to the Account Management API authentication method. However, they may not take effect because different credentials for a pre-existing connection to the same machine may already be in effect. If a user name beginning with dummy (case insensitive) is specified, the connector does not pass any credentials to the authentication method.
-
For search requests only, the EqualityMatch filter for all attributes and the StartsWith filter for the naming attribute, which is the SamAccountName, are supported. The "SearchRequest" section provides an example.
Deployment
This section describes the following deployment scenarios:
-
One .NET connector server for all Windows systems in one Windows domain
-
One .NET connector server on each Windows target machine
-
One .NET connector server for several Windows domains
One .NET Connector Server/One Windows Domain
To manage several Windows local systems joined to the same domain, only one .NET connector server needs to be installed on a Windows machine in the domain (see the Windows system requirements for the .NET connector server described in "Prerequisites"). It must be configured so that the .NET connector server service runs under a specific domain account which is added to the Administrator group of each targeted Windows machine in that domain.
On DirX Identity side, one Identity target system relates to one Windows local target system. All Identity target systems in this scenario bind to the same .NET connector server (specified in the Windows Local Accounts Connector <connection> section of type OpenIcfServer), which itself then addresses the request to that Windows target machine that is specified in the Windows Local Accounts Connector <connection> section of type OpenIcfConnector (see the example given in the "Configuration" section).
One .NET Connector Server per Windows Target Machine
If the Windows target machine is not joined to a domain or for performance or network connectivity reasons, a .NET connector server can also be installed on a Windows target machine itself.
One .NET Connector Server/Several Windows Domains
If the domain account under which a .NET connector server service runs is known in other domains through trust relationships and can be added to the Administrator groups of target machines in other domains, those target machines can also be managed by a .NET connector server running in a different domain.
Request and Response Handling
This section describes the SPML requests processed by the Java-based DirX Identity OpenICF connector and the attributes supported by the C#-based OpenICF Windows Local Accounts connector.
Attribute names in uppercase characters with leading and trailing underscore () characters are predefined or operational attributes of the OpenICF connector framework. If there are also native attribute names for these attributes - for example, SamAccountName for NAME or Members for ACCOUNTS or Enabled for ENABLE__ - both names are supported by the connector and can therefore be used.
In all requests, the operational attribute objType with the allowed values user or group (default = user) specifies whether the operation is performed for users or for groups.
AddRequest
The identifier in an add request for a user or a group is mandatory and will become the SamAccountName attribute.
Here is an example add request for a user:
<spml:addRequest xmlns="urn:oasis:names:tc:SPML:1:0"
xmlns:spml="urn:oasis:names:tc:SPML:1:0"
xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core"
requestID="add-01"
<spml:identifier type="urn:oasis:names:tc:SPML:1:0#DN">
<spml:id>MHummels</spml:id>
</spml:identifier>
<spml:operationalAttributes>
<dsml:attr name="objType">
<dsml:value>user</dsml:value>
</dsml:attr>
</spml:operationalAttributes>
<spml:attributes>
<spml:attr name="Enabled" xmlns="urn:oasis:names:tc:DSML:2:0:core">
<dsml:value>false</dsml:value>
</spml:attr>
<spml:attr name="__PASSWORD__">
<dsml:value type="string">Dirx123#</dsml:value>
</spml:attr>
<spml:attr name="DisplayName" xmlns="urn:oasis:names:tc:DSML:2:0:core">
<dsml:value>Mats Hummels</dsml:value>
</spml:attr>
</spml:attributes>
</spml:addRequest>
Here is an example add request for a group:
<spml:addRequest xmlns="urn:oasis:names:tc:SPML:1:0"
xmlns:spml="urn:oasis:names:tc:SPML:1:0"
xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core"
requestID="add-01"
>
<spml:identifier type="urn:oasis:names:tc:SPML:1:0#DN">
<spml:id>TestGroup2</spml:id>
</spml:identifier>
<spml:operationalAttributes>
<dsml:attr name="objType">
<dsml:value>group</dsml:value>
</dsml:attr>
</spml:operationalAttributes>
<spml:attributes>
<spml:attr name="Description" xmlns="urn:oasis:names:tc:DSML:2:0:core">
<dsml:value>Created with OpenICF</dsml:value>
</spml:attr>
<spml:attr name="Members" xmlns="urn:oasis:names:tc:DSML:2:0:core">
<dsml:value>agerbe66</dsml:value>
</spml:attr>
</spml:attributes>
</spml:addRequest>
ModifyRequest
In a modify request, the identifier is also mandatory and must be set to the SamAccountName value returned in the SPML AddResponse for the object.
Here is an example modify request for a user:
<spml:modifyRequest requestID="mod-1: set some attributes">
<spml:identifier
type = "urn:oasis:names:tc:SPML:1:0#DN">
<spml:id>MHummels</spml:id>
</spml:identifier>
<spml:modifications>
<spml:modification name="__GROUPS__" operation="replace">
<dsml:value>TestGroup1</dsml:value>
</spml:modification>
<spml:modification name="DisplayName" operation="replace">
<dsml:value>Mats Hummels</dsml:value>
</spml:modification>
<spml:modification name="Description" operation="replace">
<dsml:value>Test account for OpenICF Windows Local Accounts Connector</dsml:value>
</spml:modification>
<spml:modification name="Enabled" operation="replace">
<dsml:value>True</dsml:value>
</spml:modification>
<spml:modification name="__CURRENT_PASSWORD__" operation="replace">
<dsml:value>Dirx123#</dsml:value>
</spml:modification>
<spml:modification name="__PASSWORD__" operation="replace">
<dsml:value>Dirx456#</dsml:value>
</spml:modification>
<spml:modification name="PasswordNeverExpires" operation="replace">
<dsml:value>True</dsml:value>
</spml:modification>
<spml:modification name="HomeDirectory" operation="replace">
<dsml:value>d:\MyTemp</dsml:value>
</spml:modification>
</spml:modifications>
</spml:modifyRequest>
Here is an example modify request for a group:
<spml:modifyRequest requestID="mod-1: add and delete members">
<spml:identifier
type = "urn:oasis:names:tc:SPML:1:0#DN">
<spml:id>TestGroup2</spml:id>
</spml:identifier>
<spml:operationalAttributes>
<dsml:attr name="objType">
<dsml:value>group</dsml:value>
</dsml:attr>
</spml:operationalAttributes>
<spml:modifications>
<spml:modification name="Description" operation="replace">
<dsml:value>Renamed</dsml:value>
</spml:modification>
<spml:modification name="Members" operation="add">
<dsml:value>MHummels</dsml:value>
<dsml:value>PwlTestUser</dsml:value>
</spml:modification>
<spml:modification name="Members" operation="delete">
<dsml:value>agerbe66</dsml:value>
</spml:modification>
</spml:modifications>
</spml:modifyRequest>
DeleteRequest
In a delete request, the identifier is also mandatory. It must be the SamAccountName of the user or group object. The delete request does not require additional attributes.
SearchRequest
In an SPML search request, the OpenICF Windows Local Accounts connector supports the standard element filter, which can be of type EqualityMatch applicable on most attributes or of type Substring Initial applicable only on the naming attribute NAME (=SamAccountName). An example of each filter type is shown here. Regarding the attributes section, either all attributes, if none are specified, or the ones specified are retrieved.
Here is an example request that searches for all enabled users with the requested attributes. Note that with the attribute GROUPS, you can also retrieve the list of groups of which the user is a member.
<spml:searchRequest xmlns="urn:oasis:names:tc:SPML:1:0"
xmlns:spml="urn:oasis:names:tc:SPML:1:0"
xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core"
requestID="search-user-1">
<spml:operationalAttributes>
<dsml:attr name="objType">
<dsml:value>user</dsml:value>
</dsml:attr>
</spml:operationalAttributes>
<filter>
<dsml:equalityMatch name="__ENABLE__">
<dsml:value type="string">true</dsml:value>
</dsml:equalityMatch>
</filter>
<dsml:attributes>
<dsml:attribute name="__NAME__"/>
<dsml:attribute name="SamAccountName"/>
<dsml:attribute name="DisplayName"/>
<dsml:attribute name="__ENABLE__"/>
<dsml:attribute name="__LOCK_OUT__"/>
<dsml:attribute name="__DESCRIPTION__"/>
<dsml:attribute name="PasswordNeverExpires"/>
<dsml:attribute name="HomeDirectory"/>
<dsml:attribute name="__GROUPS__"/>
</dsml:attributes>
</spml:searchRequest>
Here is an example request that searches for all groups with SamAccountName beginning with “Test”:
<spml:searchRequest xmlns="urn:oasis:names:tc:SPML:1:0"
xmlns:spml="urn:oasis:names:tc:SPML:1:0"
xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core"
requestID="search-groups-1">
<spml:operationalAttributes>
<dsml:attr name="objType">
<dsml:value>group</dsml:value>
</dsml:attr>
</spml:operationalAttributes>
<filter>
<dsml:substrings name="__NAME__">
<dsml:initial>Test</dsml:initial>
</dsml:substrings>
</filter>
<dsml:attributes>
<dsml:attribute name="__NAME__"/>
<dsml:attribute name="SamAccountName"/>
<dsml:attribute name="Description"/>
<dsml:attribute name="Members"/>
</dsml:attributes>
</spml:searchRequest>
Configuration
Here is a sample configuration snippet for the OpenICF Windows Local Accounts connector:
<connector
role="connector"
className="net.atos.dirx.dxi.connector.openicf.OpenIcfConnector"
name="ts" version="1.00">
<connection type="OpenIcfServer"
server="WindowsServer01"
port="8759"
password="pwd for connector server"
>
<property name="bundleName" value="WindowsLocalAccounts.Connector"/>
<property name="bundleVersion" value="1.4.0.0"/>
<property name="implementationClassName" value="Org.IdentityConnectors.WindowsLocalAccounts.WindowsLocalAccountsConnector"/>
</connection>
<!-- Windows LA Connector specific properties -->
<connection type="OpenIcfConnector">
<property name="user" value="AdminIcfConnector"/>
<property name="password" value="pwd local computer admin"/>
<property name="host" value="TargetSAM01"/>
</connection>
</connector>
The following properties of the OpenICF .NET connector server <connection> section can be specified:
-
port - the port number of the connector server.
-
server - the server name or IP address of the connector server.
-
password - the key value for binding to the connector server. It is the key string value that was applied when running the command ConnectorServer /setkey keyvalue in the connector server installation folder before starting the server for the first time.
-
bundleName - the name of the connector bundle running in the connector server.
-
bundleVersion - the version number of the connector bundle.
-
implementationClassName - the connector class name where the OpenICF SPI methods are implemented.
The following properties can be specified in the <connection> section of the OpenICF Windows Local Accounts connector:
-
user - the administrator name of the Windows Local Accounts (SAM) database.
-
password - the password of the administrator.
-
host - the name of the computer whose SAM database is to be managed.