[midPoint] AD Connector on v3.0

Tim Tompkins trench4g63 at gmail.com
Wed Jun 4 23:34:02 CEST 2014


Hi,

After too much time searching back and forth between sources and the
HOWTOs; and a lot of trial and error, I finally managed to get AD to sync
with group membership entitlements working.
I have been able to create roles that have "inducements" that create an
active directory account that includes group membership. Removing
membership from the group in AD will show as removed under the AD account
in midPoint. (I did set the Default AD GPO to no restrictions on passwords
and have not tested anything to do with passwords at this point.)

Below I am including the XML in the hope that it will save someone else
some time, if anyone finds any bugs or improvements please let me know.

Cheers,

Tim T.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2010-2013 Evolveum
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->


<!--

This file is an example of Resource definition. It defines an AD resource
using an Identity Connector Framework AD connector and Connector Server.

This resource definition contains only the very basic definitions for
midPoint to work.

-->

<objects
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
    xmlns:icfc="
http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3
"
    xmlns:icfs="
http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3
"
xmlns:func="http://midpoint.evolveum.com/xml/ns/public/function/basic-3"
xmlns:my="http://myself.me/schemas/whatever"
    xsi:schemaLocation="
http://midpoint.evolveum.com/xml/ns/public/common/common-3
../../infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd">

<resource oid="ef2bc95b-76e0-48e2-86d6-3d4f02d3eaef">

<!-- Resource name. It will be displayed in GUI.  -->
<name>Active Directory Advanced Sync</name>

<!-- Reference to the ICF AD connector. OID is "virtual" for now. -->
<connectorRef type="ConnectorType">
<filter>
<q:equal>
<q:path>c:connectorType</q:path>
<q:value>Org.IdentityConnectors.ActiveDirectory.ActiveDirectoryConnector</q:value>
</q:equal>
</filter>
</connectorRef>

<!-- Configuration section contains configuration of the connector,
             such as hostnames and passwords -->
<connectorConfiguration>

<!-- Configuration specific for the Active Directory connector -->
<icfc:configurationProperties
                xmlns:icfcad="
http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/ActiveDirectory.Connector/Org.IdentityConnectors.ActiveDirectory.ActiveDirectoryConnector
">
<icfcad:DirectoryAdminName>ADMINISTRATOR</icfcad:DirectoryAdminName>
<icfcad:DirectoryAdminPassword><clearValue>PASSWORD</clearValue></icfcad:DirectoryAdminPassword>
<icfcad:ObjectClass>User</icfcad:ObjectClass>
<icfcad:Container>ou=accounts,dc=test,dc=local</icfcad:Container>
<icfcad:CreateHomeDirectory>true</icfcad:CreateHomeDirectory>
<icfcad:LDAPHostName>HOSTNAME</icfcad:LDAPHostName><!-- This is the
hostname of AD server as seen from the ConnectorServer instance! -->
<icfcad:SearchChildDomains>false</icfcad:SearchChildDomains>
<icfcad:DomainName>test.local</icfcad:DomainName>
<icfcad:SyncGlobalCatalogServer>HOSTNAME</icfcad:SyncGlobalCatalogServer><!--
hostname of DC to look up for changes when synchronizing -->
<icfcad:SyncDomainController>HOSTNAME</icfcad:SyncDomainController><!--
hostname of DC to look up for changes when synchronizing -->
</icfc:configurationProperties>

<icfc:resultsHandlerConfiguration>  <!-- currently this requires latest
Evolveum version of .net connector server -->
<icfc:enableCaseInsensitiveFilter>true</icfc:enableCaseInsensitiveFilter>
</icfc:resultsHandlerConfiguration>


</connectorConfiguration>

<!-- Resource schema definition.
             It defines all the object classes that are available to
midPoint
             (accounts, groups, ...).

             This should be direct mapping of ICF schema (and therefore also
             LDAP schema). This is not supposed to be customized during
deployment.

 The <schema> element is missing. That tells midPoint to generate it from
 the resource on the first use of this resource definition.
 -->

<!-- Resource Schema Handling definition.
             This part defines how the schema defined above will be used by
             midPoint. It defines expressions and limitations for individual
             schema attributes.

             The expressions that describe both inbound and outbound flow of
             the attributes are defined in this section.

             This is the part where most of the customization takes place.

        -->

<schemaHandling>
 <objectType> <kind>account</kind> <displayName>Default
Account</displayName>
<default>true</default>
<objectClass>ri:AccountObjectClass</objectClass>

<attribute>
<ref>ri:givenName</ref>
<!-- required attribute on AD -->
<displayName>Given Name</displayName>
<outbound>
<strength>weak</strength>
<source>
<path>$user/givenName</path>
</source>
</outbound>
<inbound>
<target>
<path>$user/givenName</path>
</target>
</inbound>
</attribute>
<attribute>
<ref>ri:sn</ref>
<displayName>Surname</displayName>
<outbound>
<strength>weak</strength>
<source>
<path>$user/familyName</path>
</source>
</outbound>
<inbound>
<target>
<path>$user/familyName</path>
</target>
</inbound>
</attribute>
<attribute>
<ref>ri:sAMAccountName</ref>
<!-- required attribute on AD -->
<displayName>Login name</displayName>
<outbound>
<strength>weak</strength>
<source>
<path>$user/name</path>
</source>
</outbound>
<inbound>
<target>
<path>$user/name</path>
</target>
</inbound>
</attribute>

<attribute>
<ref>ri:mail</ref>
<outbound>
<source>
<path>$user/emailAddress</path>
</source>
</outbound>
<inbound>
<target>
<path>$user/emailAddress</path>
</target>
</inbound>
</attribute>
<attribute><!-- This attribute must be set to
other than "false". We will set it to "true" to expire the password
immediately (after create). Note there is no "initial" attribute, because
the
current implementation of forms would set the __PASSWORD_EXPIRED__ = false
by
default, which is not what we want. But it works, because it is set to
"true"
on the create, and on the update of other attributes, this attribute is not
changed, so this outbound will not be processed.
Please note that AD itself does not support changing the _PASSWORD_EXPIRED__
to "false". The only way of resetting the flag is to change user's password.
-->
<ref>icfs:passwordExpired</ref>
<outbound>
<expression>
<value>true</value>
</expression>
</outbound>
</attribute>

<attribute>
<ref>icfs:name</ref>
<displayName>Distinguished Name</displayName>

<limitations>
<minOccurs>0</minOccurs>
<access>
                            <read>true</read>
<add>true</add>
</access>
</limitations>

<outbound>
<source>
<path>$user/givenName</path>
</source>
<source>
<path>$user/familyName</path>
</source>
<expression>
<script>
<code>
'cn='+givenName+'
'+familyName+iterationToken+',ou=accounts,dc=test,dc=local'
</code>
</script>
</expression>
</outbound>
</attribute>
<iteration>
<maxIterations>5</maxIterations>
</iteration>
<protected>
<icfs:name>cn=Administrator,cn=Users,dc=test,dc=local</icfs:name>
</protected>
<activation>
<administrativeStatus>
<outbound/>
</administrativeStatus>
</activation>
<credentials>
<password>
<outbound/>
</password>
</credentials>
<association>
<ref>ri:group</ref>
<displayName>AD Group Membership</displayName>
<kind>entitlement</kind>
<intent>group</intent>
<direction>objectToSubject</direction>
<associationAttribute>ri:member</associationAttribute>
<valueAttribute>icfs:name</valueAttribute>
</association>
</objectType>
 <objectType> <kind>entitlement</kind> <displayName>AD Group</displayName>
 <intent>group</intent>
<objectClass>ri:CustomGroupObjectClass</objectClass>

<attribute>
<ref>icfs:name</ref>
<matchingRule>mr:stringIgnoreCase</matchingRule>
<outbound>
<!-- Name cannot be weak. Changes in name trigger object rename. -->
<source>
<path>$focus/name</path>
</source>
</outbound>
</attribute>
<attribute>
<ref>ri:cn</ref>
<matchingRule>mr:stringIgnoreCase</matchingRule>
<outbound>
<!-- This MUST be weak in case of OpenDJ. If DN (name) is changed then the
uid will be changed
 as a side-effect as it is a naming attribute. -->
<strength>weak</strength>
<source>
<path>$focus/name</path>
</source>
</outbound>
<inbound>
<strength>weak</strength>
<target>
<path>$focus/name</path>
</target>
</inbound>
</attribute>
<attribute>
<ref>ri:description</ref>
<outbound>
<strength>strong</strength>
<source>
<path>description</path>
</source>
</outbound>
<inbound>
<strength>weak</strength>
<target>
<path>$focus/description</path>
</target>
</inbound>
</attribute>
        </objectType>
<objectType>
        <kind>generic</kind>
            <intent>ou</intent>
            <displayName>Organizational Unit</displayName>

<objectClass>ri:CustomorganizationalUnitObjectClass</objectClass>
            <attribute>
                <ref>icfs:name</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger
object rename. -->
<source>
<path>$focus/name</path>
</source>
<source>
<path>$focus/extension/ext:orgpath</path>
</source>
                    <expression>
                    <script>
                        <code>
                         import javax.naming.ldap.Rdn
                         import javax.naming.ldap.LdapName

                         dn = new LdapName('dc=test,dc=local')
                        orgpath.tokenize('/').reverse().each { ouname ->
dn.add(new Rdn('ou',ouname)) }
                         return dn.toString()
                        </code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:ou</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                <!-- This MUST be weak in case of OpenDJ. If DN (name) is
changed then the uid will be changed
                     as a side-effect as it is a naming attribute. -->
                <strength>weak</strength>
                <source>
                <path>$focus/name</path>
                </source>
                </outbound>
                <inbound>
                <strength>weak</strength>
                <target>
                <path>$focus/name</path>
                </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                <source>
                <path>description</path>
                </source>
                </outbound>
            </attribute>
        </objectType>
 </schemaHandling>
<!--
                <capabilities xmlns:cap="
http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
                    <cap:credentials>
                        <cap:password/>
                    </cap:credentials>
                    <cap:liveSync/>
                    <cap:testConnection/>
                </capabilities>
        -->
<scripts>
<script>
<host>resource</host>
<language>Shell</language>
<argument>
<value>jbond</value>
<name>HOMEDIR</name>
</argument>
<code>
                    echo "after modify," >> C:\a.txt
                    exit
</code>
<operation>modify</operation>
<order>after</order>
</script>
<!--
           <script>
           <operation>modify</operation>
           <order>before</order>
   <language>Shell</language>
   <host>resource</host>
           <argument>
               <value>jbond</value>
               <name>HOMEDIR</name>
           </argument>
           <code>
   echo "before modify," >> C:\a.txt
   exit
           </code>
           </script>

           <script>
           <operation>add</operation>
           <order>after</order>
   <language>Shell</language>
   <host>resource</host>
           <argument>
               <value>jbond</value>
               <name>HOMEDIR</name>
           </argument>
           <code>
   echo "after create," >> C:\a.txt
   exit
           </code>
           </script>

           <script>
           <operation>add</operation>
           <order>before</order>
   <language>Shell</language>
   <host>resource</host>
           <argument>
               <value>jbond</value>
               <name>HOMEDIR</name>
           </argument>
   <code>
   echo "before create," >> C:\a.txt
   exit
           </code>
           </script>-->
</scripts>
<!--
            Synchronization section describes the synchronization policy,
timing,
            reactions and similar synchronization settings.
        -->
<synchronization>
<objectSynchronization> <!-- USER SYNC -->
<!--
The synchronization for this resource is enabled.
It means that the synchronization will react to changes detected by
the system (live sync task, discovery or reconciliation) -->
<enabled>true</enabled>

<correlation>
<q:description>
Correlation expression is a search query.
Following search queury will look for users that have "name"
equal to the "sAMAccountName" attribute of the account. Simply speaking,
it will look for match in usernames in the IDM and the resource.
The correlation rule always looks for users, so it will not match
any other object type.
</q:description>
<q:equal>
<q:path>c:name</q:path>
<expression>
<script>
<language>http://www.w3.org/TR/xpath/</language>
<code>
$c:account/c:attributes/ri:sAMAccountName
</code>
</script>
</expression>
</q:equal>
</correlation>

<!-- Confirmation rule may be here, but as the search above will
 always return at most one match, the confirmation rule is not needed. -->

<!-- Following section describes reactions to a situations.
 The setting here assumes that this resource is authoritative,
 therefore all accounts created on the resource should be
 reflected as new users in IDM.
 See http://wiki.evolveum.com/display/midPoint/Synchronization+Situations
 -->
<reaction>
<situation>linked</situation>
<action ref="
http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser"/>
</reaction>
<reaction>
<situation>deleted</situation>
<action ref="
http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount"/>
</reaction>
<reaction>
<situation>unlinked</situation>
<action ref="
http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount"/>
</reaction>
<reaction>
<situation>unmatched</situation>
<!-- Reference to the User Template is here. If the user would be
 created as a result of this action, it will be created according
 to this template. -->
<objectTemplateRef oid="c0c010c0-d34d-b33f-f00d-777222222222"/>
<action ref="
http://midpoint.evolveum.com/xml/ns/public/model/action-3#addUser"/>
<!--                <action ref="
http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount"/>-->
</reaction>
</objectSynchronization>

<objectSynchronization> <name>group sync</name>
<objectClass>ri:CustomGroupObjectClass</objectClass>

<kind>entitlement</kind>
<intent>group</intent>
<focusType>c:RoleType</focusType>
<enabled>true</enabled>
<correlation>
<q:equal>
<q:path>c:name</q:path>
<expression>
<path>
declare namespace ri="
http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
$shadow/attributes/ri:sAMAccountName
</path>
</expression>
</q:equal>
</correlation>

<reaction>
<situation>linked</situation>
<synchronize>true</synchronize>
</reaction>
<reaction>
<situation>deleted</situation>
<synchronize>true</synchronize>
<action>
<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink
</handlerUri>
</action>
</reaction>
<reaction>
<situation>unlinked</situation>
<synchronize>true</synchronize>
<action>
<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link
</handlerUri>
</action>
</reaction>
<reaction>
<situation>unmatched</situation>
<synchronize>true</synchronize>
<action>
<handlerUri>
http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus
</handlerUri>
</action>
</reaction>
</objectSynchronization>
 </synchronization>
</resource>
<objectTemplate oid="c0c010c0-d34d-b33f-f00d-777222222222">
<name>Default User Template2</name>

<description>
            Alternative User Template Object.
            This object is used when creating a new account, to set it up
as needed.
</description>

<mapping>
<description>
                Property mapping.
                Defines how properties of user object are set up.
                This specific definition sets a full name as a concatenation
                of givenName and familyName.
</description>
<strength>weak</strength>
<source>
<path>$user/givenName</path>
</source>
<source>
<path>$user/familyName</path>
</source>
<expression>
<script>
<language>
http://midpoint.evolveum.com/xml/ns/public/expression/language#Groovy
</language>
<code>
givenName + ' ' + familyName
</code>
</script>
</expression>
<target>
<path>fullName</path>
</target>
</mapping>

</objectTemplate>

<task oid="91919191-76e0-59e2-86d6-444f02d3ffff"> <name>Synchronization:
Active Directory</name>
<description>
Definition of a live synchronization task. It will poll changelog and pull
in changes
</description>
<taskIdentifier>91919191-76e0-59e2-86d6-444f02d3ffff</taskIdentifier>
<!--ownerRef oid="00000000-0000-0000-0000-000000000002"/-->
<ownerRef oid="00000000-0000-0000-0000-000000000002"/>
<executionStatus>runnable</executionStatus>
<handlerUri>
http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/live-sync/handler-3
</handlerUri>
<objectRef oid="ef2bc95b-76e0-48e2-86d6-3d4f02d3eaef"
type="c:ResourceType"/>
<recurrence>recurring</recurrence>
<binding>tight</binding>
<schedule>
<interval>5</interval>
</schedule>
</task>
</objects>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.evolveum.com/pipermail/midpoint/attachments/20140604/b3f1d632/attachment.htm>


More information about the midPoint mailing list