Skip to Content.
Sympa Menu

grouper-users - [grouper-users] Replicating peculiar functionality with psp

Subject: Grouper Users - Open Discussion List

List archive

[grouper-users] Replicating peculiar functionality with psp


Chronological Thread 
  • From: Colin Hudler <>
  • To: "" <>
  • Subject: [grouper-users] Replicating peculiar functionality with psp
  • Date: Wed, 04 Apr 2012 12:05:58 -0500

We have custom provisioner to LDAP. Users are allowed to add a Group Type and attribute value that the provisioner looks for to enable the synchronization to LDAP. One of the attributes allows the user to write the group into one or many pre-defined LDAP containers (e.g, ou=groups,ou=groups,ou=application,...). The attribute value is a string containing DNs separated by semicolon.

My approach so far is the goal of psp writing exactly the same static/dynamic groups as our custom sync. Success is measured by bulkCalc returning whatever is the equivalent of no-op. Alternatively, I can restructure how we use Types and Attributes. The immovable is our ability to direct static groups using Type/Attribute for one or more LDAP containers.

I have been successful in plucking the groups in GroupDataConnector, AllGroupNamesConnector, et al, by using GroupExactAttribute filters. However, I wonder about the feasibility of the dynamic user-specified static group DNs. Besides that I cannot currently conceive of the correct psp-resolver configuration, I think this might be opposed to the design (please let me know). Will it cause problems with the groupDn attribute? Our static groups may not have a canonical groupDn, and often not any static group at all. Attached is my attempt at a psp-resolver and psp.xml configuration just for POC. I think the log message during bulkCalc "PSO Identifier Definition 'groupDn' - Source attribute 'groupDn' does not exist" points at least at part of my problem.

As if that isn't enough, our custom AD synchronizer works similarly, except allows the user to also specify the DOMAIN where groups are stored (we do not always have them in the same domain as users). Perhaps I'll tackle this another time, but we also have user objects from a forest trust which are resolved by the provisioner (the group-member in AD must be a specially formatted foreign SID obtained from the other forest, not a vanilla local user object). WHAT A MESS!
<?xml version="1.0" encoding="utf-8"?>

<!-- Provisioning Service Provider (PSP) configuration. -->

<!-- A <pso /> is a Provisioning Service Object. The authoritative and allSourceIdentifiersRef attributes control the provisioning 
  of all source and target objects. If authoritative is "true", orphan objects will be deleted. Orphan objects exist on a target 
  without a corresponding source object. The allSourceIdentifiersRef attribute refers to an attribute resolver definition whose 
  values are all source identifiers applicable to this provisioned object. -->
<!-- <pso id="entityName" authoritative="[true|false]" allSourceIdentifiersRef="attributeDefinitionID" /> -->

<!-- The pso identifier refers to an attribute resolver definition. The targetId must match the id of a provisioning service 
  target in psp-services.xml. The containerId is the string id of the pso identifier containing these objects. -->
<!-- <identifier ref="attributeDefinitionID" targetId="targetId" containerId="containerId"/> -->

<!-- The identifying attribute has two purposes : (1) to determine the schema entity of target objects returned from a lookup 
  or search request and (2) to be converted to a query to search a target for all identifiers. If the identifying attribute 
  is not present, the pso will be ignored during bulk requests. -->
<!-- <identifyingAttribute name="attributeName" value="attributeValue" /> -->

<!-- The alternate identifier refers to an attribute resolver definition, and is the previous (old) identifier of an object 
  after it has been renamed. -->
<!-- <alternateIdentifier ref="attributeDefinitionID" /> -->

<!-- A provisioned attribute refers to an attribute resolver definition. -->
<!-- <attribute name="attributeName" ref="attributeDefinitionID" /> -->

<!-- References to the identifiers of other objects. -->
<!-- <references name="attributeName"> <reference ... /> </references> -->

<!-- A reference to the identifier of an object refers to an attribute resolver definition. -->
<!-- <reference ref="attributeDefinitionID" toObject="psoId" /> -->

<psp xmlns="http://grouper.internet2.edu/psp"; xmlns:psp="http://grouper.internet2.edu/psp"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://grouper.internet2.edu/psp classpath:/schema/psp.xsd">

  <!-- Provision a grouper group as an ldap group. -->
  <pso id="group" authoritative="true" allSourceIdentifiersRef="groupNames">
    <identifier ref="groupDn" targetId="ucmcdb" containerId="ou=groups,dc=uchicago,dc=edu" />
    <identifyingAttribute name="objectClass" value="groupOfNames" />
    <alternateIdentifier ref="groupDnAlternate" />
    <attribute name="objectClass" ref="groupObjectclass" />
    <attribute name="cn" />
    <attribute name="description" />
    <attribute name="hasMember" ref="hasMember" />
    <references name="uniquemember" emptyValue="">
      <reference ref="uniqueMember" toObject="member" />
    </references>
  </pso>

  <!-- Provision memberOf attributes for members which are ldap persons. -->
  <pso id="member" allSourceIdentifiersRef="memberSubjectIds">
    <identifier ref="memberDn" targetId="ucmcdb" containerId="ou=people,dc=uchicago,dc=edu" />
    <identifyingAttribute name="objectclass" value="eduMember" />
    <attribute name="objectClass" ref="memberObjectclass" retainAll="true" />
    <attribute name="ucisMemberOf" ref="ucisMemberOf" />
    <references name="ucismemberOf">
      <reference ref="ucisMemberOf" toObject="group" />
    </references>
  </pso>

</psp>
<?xml version="1.0" encoding="UTF-8"?>
<AttributeResolver
  xmlns="urn:mace:shibboleth:2.0:resolver"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
  xmlns:ad="urn:mace:shibboleth:2.0:resolver:ad"
  xmlns:dc="urn:mace:shibboleth:2.0:resolver:dc"
  xmlns:grouper="http://grouper.internet2.edu/shibboleth/2.0";
  xmlns:psp="http://grouper.internet2.edu/psp";
  xmlns:psp-grouper-ldap="http://grouper.internet2.edu/psp-grouper-ldap";
  xmlns:psp-grouper-source="http://grouper.internet2.edu/psp-grouper-source";
  xsi:schemaLocation="
   urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd
   urn:mace:shibboleth:2.0:resolver:dc classpath:/schema/shibboleth-2.0-attribute-resolver-dc.xsd
   urn:mace:shibboleth:2.0:resolver:ad classpath:/schema/shibboleth-2.0-attribute-resolver-ad.xsd
   http://grouper.internet2.edu/shibboleth/2.0 classpath:/schema/shibboleth-2.0-grouper.xsd
   http://grouper.internet2.edu/psp classpath:/schema/psp.xsd
   http://grouper.internet2.edu/psp-grouper-ldap classpath:/schema/psp-grouper-ldap.xsd
   http://grouper.internet2.edu/psp-grouper-source classpath:/schema/psp-grouper-source.xsd">

  <!-- Grouper data connectors. -->

    <resolver:DataConnector id="GroupDataConnector" xsi:type="grouper:GroupDataConnector">
       <grouper:Filter xsi:type="grouper:AND">
         <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Send To" value="ldap" />
         <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Type" value="LDAPSync" />
       </grouper:Filter>
       <grouper:Attribute id="members" />
       <grouper:Attribute id="groups" />
    </resolver:DataConnector>

  <resolver:DataConnector id="MemberDataConnector" xsi:type="grouper:MemberDataConnector">
    <grouper:Attribute id="entrydn" source="ucmcdb" />
    <grouper:Attribute id="groups" />
  </resolver:DataConnector>

  <resolver:DataConnector id="AllGroupNamesConnector" xsi:type="psp-grouper-source:AllGroupNamesDataConnector">
    <grouper:Filter xsi:type="grouper:AND">
      <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Send To" value="ldap" />
      <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Type" value="LDAPSync" />
    </grouper:Filter>
  </resolver:DataConnector>

  <resolver:AttributeDefinition id="groupNames" xsi:type="ad:Simple">
    <resolver:Dependency ref="AllGroupNamesConnector" />
  </resolver:AttributeDefinition>

  <resolver:DataConnector id="AllMemberSubjectIdsConnector" xsi:type="psp-grouper-source:AllMemberSubjectIdsDataConnector">
    <grouper:Filter xsi:type="grouper:MemberSource" sourceId="ucmcdb" />
  </resolver:DataConnector>

  <resolver:AttributeDefinition id="memberSubjectIds" xsi:type="ad:Simple">
    <resolver:Dependency ref="AllMemberSubjectIdsConnector" />
  </resolver:AttributeDefinition>

  <resolver:DataConnector id="StaticDataConnector" xsi:type="dc:Static">
    <dc:Attribute id="staticGroupObjectclass">
      <dc:Value>top</dc:Value>
      <dc:Value>groupOfNames</dc:Value>
      <dc:Value>eduMember</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="memberObjectclass">
      <dc:Value>eduMember</dc:Value>
    </dc:Attribute>
  </resolver:DataConnector>

  <!-- Group identifier and attributes. -->

  <!-- The LDAP DN of a group. For example, "cn=groupExtension,ou=stem,ou=groups,dc=example,dc=edu". -->
  <resolver:AttributeDefinition id="groupDn" xsi:type="psp-grouper-ldap:LdapDnFromGrouperNamePSOIdentifier" structure="flat" sourceAttributeID="groupNameInStem" rdnAttributeName="cn" baseDn="ou=groups,dc=uchicago,dc=edu">
    <resolver:Dependency ref="groupNameInStem" />
  </resolver:AttributeDefinition>

  <!-- The value of the "groupNameInStem" attribute is the name of the group of a change log entry. The name of the group is returned only if the group filter also matches. -->
  <resolver:AttributeDefinition id="groupNameInStem" xsi:type="grouper:FilteredName" sourceAttributeID="name">
    <resolver:Dependency ref="GroupDataConnector" />
    <grouper:Filter xsi:type="grouper:AND">
       <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Send To" value="ldap" />
       <grouper:Filter xsi:type="grouper:GroupExactAttribute" name="Type" value="LDAPSync" />
    </grouper:Filter>
  </resolver:AttributeDefinition>

  <!-- The alternate LDAP DN of a group. For example, the DN of a group before it is renamed. -->
  <resolver:AttributeDefinition id="groupDnAlternate" xsi:type="psp-grouper-ldap:LdapDnFromGrouperNamePSOIdentifier" structure="flat" sourceAttributeID="alternateName" rdnAttributeName="cn" baseDn="ou=groups,dc=uchicago,dc=edu">
    <resolver:Dependency ref="GroupDataConnector" />
  </resolver:AttributeDefinition>

  <!-- The group objectclass attribute. If a change log entry is resolved, do not return dependencies from the static data connector unless the change log entry is a membership change. -->
  <resolver:AttributeDefinition id="groupObjectclass" xsi:type="ad:Script">
    <resolver:Dependency ref="StaticDataConnector" />
    <ad:Script><![CDATA[
        // Import Shibboleth attribute provider.
        importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);
        
        // Create the attribute to be returned.
        groupObjectclass = new BasicAttribute("groupObjectclass");
        
        // Include values from 'staticGroupObjectClass' if the change log category is 'membership'.
        if (typeof changeLogCategory != "undefined" && changeLogCategory != null) {
            if (changeLogCategory.getValues().contains("membership")) {          
                groupObjectclass.getValues().addAll(staticGroupObjectclass.getValues());
            }
        // Include values from 'staticGroupObjectClass' if a change log entry is not being processed.
        } else {
            groupObjectclass.getValues().addAll(staticGroupObjectclass.getValues());
        }                       
    ]]></ad:Script>
  </resolver:AttributeDefinition>

  <!-- The value of the group "cn" attribute is the group name. -->
  <resolver:AttributeDefinition id="cn" xsi:type="ad:Simple" sourceAttributeID="name">
    <resolver:Dependency ref="GroupDataConnector" />
  </resolver:AttributeDefinition>

  <!-- The value of the group "description" attribute is the group description. -->
  <resolver:AttributeDefinition id="description" xsi:type="ad:Simple">
    <resolver:Dependency ref="GroupDataConnector" />
  </resolver:AttributeDefinition>

  <!-- The values of the group "hasMember" attribute is either the names of the groups or the uids of the subjects which are members of the group. -->
  <resolver:AttributeDefinition id="hasMember" xsi:type="grouper:Member" sourceAttributeID="members">
    <resolver:Dependency ref="GroupDataConnector" />
    <grouper:Attribute id="uid" source="ucmcdb" />
    <grouper:Attribute id="name" source="g:gsa" />
  </resolver:AttributeDefinition>

  <!-- The values of the group "uniqueMember" attribute is the dns of the subjects which are members of the group. -->
  <resolver:AttributeDefinition id="uniqueMember" xsi:type="grouper:Member" sourceAttributeID="members">
    <resolver:Dependency ref="GroupDataConnector" />
    <grouper:Attribute id="entrydn" source="ucmcdb" />
  </resolver:AttributeDefinition>

  <!-- Member identifier. -->

  <!-- The LDAP DN of a member. The value of this attribute is the entrydn of subjects whose source id is ucmcdb. -->
  <resolver:AttributeDefinition id="memberDn" xsi:type="psp:PSOIdentifier" sourceAttributeID="entrydn">
    <resolver:Dependency ref="MemberDataConnector" />
  </resolver:AttributeDefinition>

  <!-- The member objectclass attribute. -->
  <resolver:AttributeDefinition id="memberObjectclass" xsi:type="ad:Simple">
    <resolver:Dependency ref="StaticDataConnector" />
  </resolver:AttributeDefinition>

  <!-- The values of the member ucisMemberOf attribute are the names of the groups that the member is a member of. -->
  <resolver:AttributeDefinition id="ucisMemberOf" xsi:type="grouper:Group" sourceAttributeID="groups">
    <resolver:Dependency ref="MemberDataConnector" />
    <grouper:Attribute id="name" />
  </resolver:AttributeDefinition>

</AttributeResolver>



Archive powered by MHonArc 2.6.16.

Top of Page