Novell Home

Idmnxdrvdevkit

From Developer Community

Identity Manager Linux and UNIX Driver 3.1 Developer Kit

Contents

Overview

This Kit is to provide help in the following scenarios:

  • Using the Scriptable Framework to develop IDM Drivers to New Applications
  • Provide detailed understanding of the Scriptable Framework used by the Linux and Unix Driver for Files, NIS and NIS+, so administrators can extend the driver to accomplish new and greater things.

It is best to have a good working knowledge of the following items before proceeding:

  • Novell's Identity Manager Product:

http://www.novell.com/products/identitymanager/

  • The Linux and UNIX (nxdrv not nisdrv) Bidirectional Driver.
  • Familiarity with any scripting language you would like to develop with for this connector.
  • The API's, Exits and/or commands of the application you are integrating with.
  • Novell's iManager IDM Driver import Process, if you wish to extend or modify the default Custom Import xml.

The latest installment of the Linux and Unix driver has been developed so it can easily be extended to support any application that has API's, commands or scriptable interfaces for User and/or password management, which can include applications that are PAM aware for password synchronization.

Identity Manager has two channels for synchronizing data. The publisher is responsible for publishing things to the Identity Vault and the Subscriber is responsible for subscribing to events from the Identity Vault. The Scriptable Framework also has components that are used Cross Channel.

Built into the Scriptable Framework are the following components that resolve the corosponding issues so you don't have to worry about those things.

  • Embedded Remote Loader
    • With full SSL support and an installer to easily configure the certificates
    • Web based access to debugging information from the Embedded Remote Loader
  • Built in Encrypted ChangeLog, this allows changes to queue up from the application to the Identity Vault in case there is a communication problem.
  • Built in Loopback Detection system to prevent subscribed events from being published back to eDirectory.
  • Shared Memory Helper Programs that allow for large variable passing to and from the scripts.
  • Easily extendable platform schema file for use with any application.
  • Platform based include exclude for simplified testing and deployment in the hands of the platform administrator.
  • Designed to be easily extensible to support eventing systems such as applications that have exits or callouts as well as systems that must be polled for changes or a combination of both.

Depending on the type of integration you would like to perform the following scenarios might help:

  • If you wish to only push information into the application they you will probably only be concerned with the Subscriber Scripts and the Schema File. You can take any type of information and use your Directory as a clearing house for information and access control. It is a very common notion to take an application and push the logic of access control (who has access to change what) to the directory and then provision the result of the change to the applicatoin. This framework will allow you to integrate applications faster.
  • If you wish to only push information from an application to the Directory or Identity Vault you will only be concerned with the Publisher. With this there are two methods of handling the gathering of information to be sent...
    • First you can use any existing exits or call-outs that are provided by the application and use the Schema File to let Identity Manager know how to map the information to eDir and then use the change log helper command to take the call-out or exit data and place it onto the change log.
    • Secondly you can use a diffing method, such as keeping a snapshot file of a file or table and diffing the snapshot on the polling interval using the Poll Script (which is called on the polling interval, the Scriptable Framework makes sure the last polling interval is complete before it processes another) in combination with the Change Log Helper program.
  • If you wish to provide centralized auditing for an application that has not been directly enabled for Novell Audit (http://www.novell.com/products/audit/), you can use the publisher channel to publish changes to the local system logs as status documents that can get sent to Novell Audit.

Once you have an idea of how you want to use this framework, the following documentation in conjunction with the Custom Scripts, can help you achieve your development goals quickly and efficiently.

Driver Shim Components and Framework

  • The following sections describe each of the components of the driver shim and scriptable framework.

Cross Channel (Utilities and Subsystems used by both the Publisher and Subscriber)

  • Include Exclude
    • Local (Platform) Users, Groups, etc, can be included or excluded based on association or other attribute values such as group membership. All events related to excluded users or groups will be filtered out by the driver before it is processed by the engine.
  • Schema
    • The Schema specifies the class and attribute definitions from the external application. It defines the available classes and attributes in the external database. This is reported to the IDM Engine through a schema-def document.
  • Association Script
    • The purpose of the association script is to allow the developer to decide how an association is derived in the target application. Here is an example of an association script. Notice how the value is returned from the scripts through standard output:
     if [ "$OPERATION" = "-create" ]; then
       if [ "$CLASS_NAME" = "User" ]; then
         echo ${loginName}"User"
       fi
     elif [ "$OPERATION" = "-extract" ]; then
       if [ "$ATTRIBUTE" = "loginName" ]; then
         loginName=`echo $ASSOCIATION | sed -e 's/User$//g'`
         echo $loginName
       elif [ "$ATTRIBUTE" = "CLASS_NAME" ]; then
         CLASS_NAME=`echo $ASSOCIATION | grep "User$"`
         if [ -n "$CLASS_NAME" ]; then
           echo "User"
         fi
       fi
     fi

Publisher (Publish into the Identity Vault)

  • As previously noted, the Publisher has two methods available to publish events back into the Identity Vault. You can choose either of these or a mix of both. If you choose both, keep in mind the ordering of events- you may need to submit some events on hold and release after diffing, or vice versa.
  • Poll Script (diffing based event submitting)
    • Example:
     TIMESTAMP=`ls -l /etc/passwd`
     PASSWD_TIMESTAMP=`cat $PASSWD_TIMESTAMP_FILE`

     # check if the timestamp has changed
     if [ "$TIMESTAMP" != "$PASSWD_TIMESTAMP" ]
     then
       # check_passwd_changes will handle all the “comm? logic
       check_passwd_changes

       # finally, update timestamp and map file
       echo "$TIMESTAMP" > $PASSWD_TIMESTAMP_FILE
       cp $PASSWD_NEW $PASSWD_OLD
     fi
  • Change Log Tool (Event Submitting) -- /usr/local/nxdrv/bin/nxclh
    • This is a helper routine that is called with key values, which must match up to the schema file, to add items to the change log. The command uses command-line parameters as well as standard input for creating the event. Using standard input from scripts involves the use of hereis-documents or here documents.
    • The command offers the following command line options:
  • -? [--help] help menu
  • -t [--type] event type (add,delete,modify,modify-password,rename,move,modify-association)
  • -c [--class-name] name of the base class name of the object as defined in the schema file
  • -e [--event-id] identifier used to tag this event
  • -a [--association] association for this event which is determined by the Identity Manager Policy and attribute matching rules on a publish and the associate.
  • -s [--src-dn] distinguished name of the source object
  • -o [--old-src-dn] old distinguished name of the source object
  • -p [--password] new password for this object
  • -w [--old-password] current password for this object
  • -n [--new-name] new name for this object
  • -r [--remove-old-name] remove old name on rename
  • -y [--old-association] old association on modify-association
  • -z [--new-association] new association on modify-association
  • -1 [--hold] hold event
  • -2 [--release] release events from hold
  • NOTE: Both hold and release are designed to be used with hybrid event and polling systems such as PAM eventing and etc/passwd polling where you want to make sure you have things like creates processed before password changes.

Subscriber (Subscribe from the Identity Vault)

  • Query
    • The query enables policy or scripts to query the local application for information needed to make a decision. For example a matching rule will query for any attributes that match what is given in policy.
    • Query Script Called from policy or subscriber
    • A “query-search? is a query with a scope of "subtree". This is used to decide whether an object exists in the target application matching the criteria set by the search attributes.
    • A “query-read? is a query with a scope of "entry". This is used to retrieve the current information of a user in the target application who has already been associated with the IDM engine.
    • Query Script Variables:
      • SEARCH_CLASSES : Specifies the search filter for object classes. If the query contains no SEARCH_CLASSES elements, all entries matching the scope and the SEARCH_ATTR_ elements are returned.
      • SEARCH_ATTRS : Contains a list of the SEARCH_ATTR_ attribute names.
      • SEARCH_ATTR_ : Specifies the search filter for attribute values. If more than one SEARCH_ATTR_ element is specified, the entry must match all attributes to be returned.
      • READ_ATTRS : Specifies which attribute values are returned with entries that match the search filters.
      • ALL_READ_ATTRS : Specifies that all readable attributes should be returned.
      • NO_READ_ATTRS : Specifies that no attributes are to be returned.
    • Query Script Responses
      • Using IDMSETVAR functions for as many "instances" that are returned by the query

Name/Value Pair interface

  • Subscriber events come into the scripts in Name/Value pairs and the publisher submits events to the Identity Vault in Name/Value pairs. These are mapped to XDS event types, which are XML documents understood by the engine. Details on this mapping are described in the technical details section.
  • Referential Values
    • An attribute is referential if it refers to another object in the Identity Vault. The Name/Value pairs require all referential attribute values to have a value and a referential value in that respective order. The referential value is the association for the referencing object. The value may be anything useful, such as the CN.

Getting Started

What to Get

  • Skeleton Scripts
    • The skeleton scripts are a skeleton model where you can insert the appropriate commands to update the application you are developing to. By default the Skeleton Scripts return not implemented.
  • IDM Skeleton Import
    • The skeleton import by default allows you to only specify which directory the scripts will be called out of. You can customize the import to set up policy, GCV's as well as default matching rules or schema mapping....
  • Perl Scripting will be facilitated by using the perl helper libraries.

The latest developer files will be stored in subversion assocaited with this project.

Requirements Gathering

  • Schema
    • Decide what sort information exists in the target application that is desirable to read or update and represent this data in the form of an Object/Attribute Schema definition. The schema definition should contain a list of object types, or Classes and each Class will contain information fields, or Attributes.
    • For example, the Files driver (/etc/passwd and /etc/group) represent two classes: User and Group. The User class maintains attributes such as loginName, uidNumbser, loginShell and homeDirectory. The Group class maintains attributes such as gidNumber and memberUid.
    • This list should conform to the format of /usr/local/nxdrv/schema/schema.def, which contains the actual list used by the engine during event processing.
  • Dataflow (one-way or bidirectional synchronization)
    • Decide whether publishing information from the target application to the Identity Manager engine is possible. Are there "hooks" that can notify your driver of modifications or can you dump information as needed and scan for changes on configured polling intervals?
    • Polling for changes makes use of the "poll.sh" script, which gives the driver opportunity to scan for changes and submit them to the changelog.
    • Hooks allows exit points to submit changes to the changelog whenever they arrive using the ChangeLog command-line tool or library API.
  • Associations
    • How are objects uniquely identified in the target application? Are names unique enough? If so, are they unique across all object types? Does the application use a global unique ID, or GUID to identify an object?
    • Logic to create these associations or resolve information from an association may be useful for some applications to have in a single script, "association.sh"
  • Query Processor
    • Can the target application be queried for information from a specific object or even searched on with search criteria?
    • Query scripts, query-search- and query-read- are used to accomplish these tasks.

Where and What to Modify

  • The schema definition, /usr/local/nxdrv/schema/schema.def
    • This file defines the schema for your target application. See "Technical Details" for more information on this file.
  • The Unix scripts under /usr/local/nxdrv/scripts/
    • Logic that can only be done on the platform, or makes more sense to perform on the platform should be placed in these scripts.
    • The driver shim directly calls three of these scripts:
      • subscriber.sh - This script is called on all subscriber events. The main purpose of this script is to decide what script to call based on the command that was issued (add, modify, delete, etc.). In addition, it executes the globals.sh script which exports globally-accesible information that can be used throughout all the scripts.
      • poll.sh - This script is called when the polling interval expires and it's time to scan for application changes. This script may or may not need to do anything depending on whether your application is able to publish or already has a mechanism, or "hook" for publishing modifications.
      • heartbeat.sh - This script is used only as a way to submit status information for the IDM engine to alert it whether the driver is running or not and generate Audit events, if configured to do so.

Technical Details

  • Scripts
    • The globals.sh script is not directly called by the shim, but it is called by the subscriber.sh and simply contains a set of variables which are exported to the shell for quickly configuring options used by the scripts.
    • The idmlib.sh script is not directly called by the shim, but is simply a library of functions that aid the other scripts in retrieving and manipulating data as well as performing some common Unix system tasks. The following are these functions:
      • STATUS_SUCCESS returns a success status document
      • STATUS_ERROR returns a error status document
      • STATUS_WARNING returns a warning status document
      • STATUS_FATAL returns a fatal status document
      • STATUS_RETRY returns a retry status document
      • IDMGETVAR gets a variable from shared memroy
      • IDMSETVAR returns a variable (through standard output)
      • IDMGETQVAR returns a variable from the previous query
      • IDMQUERY performs a query
      • LOGGER logs a message to the local system log
      • MKTEMP makes a temporary filename
      • TRACE sends a trace message to the driver shim trace file
      • EXEC executes a command, checks return status, logs results in system log and trace file, returns appropriate status document
      • EXEC_WITHOUT_STATUS same as EXEC but with no status document generated
    • Helper Example:
        # perform query back into Identity Manager
        IDMQUERY “User? “bobUser? “loginName,gecos,loginShell,homeDirectory?
        loginName=`IDMGETQVAR “loginName?`
        gecos=`IDMGETQVAR “gecos?`
        loginShell=`IDMGETQVAR “loginShell?`
        homeDirectory=`IDMGETQVAR “homeDirectory?`

The XDS Command Set

  • The query Command
    • Reserved Keywords: SCOPE, DEST_DN, CLASS_NAME, EVENT_ID, ASSOCIATION, SEARCH_CLASSES, SEARCH_ATTR_, READ_ATTRS, ALL_READ_ATTRS, NO_READ_ATTRS, READ_PARENT
    <query class-name="User" event-id="1234" scope="subtree">
      <search-class class-name="User"/>
      <search-attr attr-name="Surname">
        <value type="string">Jones</value>
      </search-attr>
      <read-attr/>
      <read-parent/>
    </query>

  This will call the "query" script with the following variables and their values:
  
      CLASS_NAME=User
      EVENT_ID=1234
      SCOPE=subtree
      SEARCH_CLASSES=User
      SEARCH_ATTR_SURNAME=Jones
      ALL_READ_ATTRS=true
      READ_PARENT=true

  The script will report back to the subscriber shim with the following variables and their values:
 
      COMMAND=INSTANCE
      CLASS_NAME=User
      SRC_DN=src_dn1
      ASSOCIATION=association1
      PARENT=parent
      ADD_attr1=value1
      ADD_attr2=value2
      ADD_attr3=value3a,value3b,value3c
   
      COMMAND=INSTANCE
      CLASS_NAME=User
      SRC_DN=src_dn2
      ASSOCIATION=association2
      PARENT=parent    
      ADD_attr1=value1
      ADD_attr2=value2
      COMMAND=STATUS
      EVENT_ID=<event-id>
      STATUS_LEVEL=<success, warning, error, retry, or fatal>
      STATUS_MESSAGE=<optional message>
  • The add Command
    • Reserved Keywords: CLASS_NAME, SRC_DN, SRC_ENTRY_ID, TEMPLATE_DN, EVENT_ID, ADD_, PASSWORD, ASSOCIATION, DEST_DN, DEST_ENTRY_ID, STATUS_LEVEL, STATUS_MESSAGE
     <add class-name="User" src-dn="\Sam" template-dn="\Template" event-id="1234">
       <add-attr attr-name="cn">
         <value>Sam</value>
       </add-attr>
       <add-attr attr-name="Group Membership">
         <value association-ref="1000">Group1</value>
         <value association-ref="1001">Group2</value>
       </add-attr>
       <password>blarg</password>
     </add>
   This will call the "add" script with the following variables and their values:
  
     CLASS_NAME=User
     SRC_DN=\Sam
     TEMPLATE_DN=\Template
     EVENT_ID=1234
     ADD_CN=Sam
     ADD_Group_Membership=Group1
     ADD_REF_Group_Membership=1000
     ADD_Group_Membership=Group2
     ADD_REF_Group_Membership=1001
     PASSWORD=blarg    
   The script will report back to the subscriber shim with the following variables and their values:
 
     COMMAND=ADD_ASSOCIATION
     ASSOCIATION=<association>
     DEST_DN=<dest_dn>
     DEST_ENTRY_ID=<dest_entry_id>
     EVENT_ID=<event_id>
     COMMAND=status
     EVENT_ID=<event_id>
     STATUS_LEVEL=<success, warning, error, retry, or fatal>
     STATUS_MESSAGE=<optional message>
  • The modify Command
    • Reserved Keywords: SRC_DN, CLASS_NAME, EVENT_ID, ASSOCIATION, ADD_, REMOVE_, REMOVE_ALL_, STATUS_LEVEL, STATUS_MESSAGE
       <modify class-name="User" event-id="1234" src-dn="\Sam">
         <attr attr-name="cn">
           <association>1012</association>
           <modify-attr attr-name="Given Name">
             <remove-all-values/>
             <add-value>
               <value>Samuel</value>
             </add-value>
           </modify-attr>
           <modify-attr attr-name="Given Name">
             <remove-value>
               <value>555-1212</value>
             </remove-value>
             <add-value>
               <value>555-1764</value>
               <value>555-1765</value>
             </add-value>
           </modify-attr>
       </modify>

   This will call the modify script with the following variables and their values:
 
      CLASS_NAME=User
       SRC_DN=\Sam
       EVENT_ID=1234
       REMOVE_ALL_Given_Name=true
       ADD_Given_Name=Samuel
       REMOVE_Telephone_Number=555-1212
       ADD_Telephone_Number=555-1764,555-1765
   
   The script will report back to the subscriber shim with the following variables and their values:
       COMMAND=status
       EVENT_ID=<event_id>
       STATUS_LEVEL=<success, warning, error, retry, or fatal>
       STATUS_MESSAGE=<optional message>
  • The modify-password Command
    • Reserved Keywords: CLASS_NAME, SRC_DN, DEST_DN, EVENT_ID, OLD_PASSWORD, PASSWORD, ASSOCIATION, STATUS_LEVEL, STATUS_MESSAGE
       <modify-password src-dn="\Sam" event-id="1234">
         <association>1012</association>
         <old-password>S4m</old-password>
         <password>S4mu31</password>
       </modify-password>

    This will call the modify-password script with the following variables and their values:
 
       CLASS_NAME=User
       SRC_DN=\Sam
       EVENT_ID=1234
       ASSOCIATION=1012
       OLD_PASSWORD=S4m
       PASSWORD=S4mu31
    
    The script will report back to the subscriber shim with the following variables and their values:
 
       COMMAND=status
       EVENT_ID=<event_id>  
       STATUS_LEVEL=<success, warning, error, retry, or fatal>
       STATUS_MESSAGE=<optional message>
  • The delete Command
    • Reserved Keywords: CLASS_NAME, SRC_DN, DEST_DN, DEST_ENTRY_ID, EVENT_ID, ASSOCIATION, STATUS_LEVEL, STATUS_MESSAGE
       <delete class-name="User" src-dn="\Sam" event-id="1234">
         <association>1012</association>
       </delete>

    This will call the delete script with the following variables and their values:
       CLASS_NAME=User
       SRC_DN=\Sam
       EVENT_ID=1234
       ASSOCIATION=1012
    
    The script will report back to the subscriber shim with the following variables and their values:
       COMMAND=status
       EVENT_ID=<event_id>  
       STATUS_LEVEL=<success, warning, error, retry, or fatal>
       STATUS_MESSAGE=<optional message>
  • The rename Command
    • Reserved Keywords: CLASS_NAME, SRC_DN, OLD_SRC_DN, REMOVE_OLD_NAME, EVENT_ID, ASSOCIATION, NEW_NAME, STATUS_LEVEL, STATUS_MESSAGE
       <rename class-name="User" src-dn="\Samuel" old-src-dn="\Sam" event-id="1234" remove-old-name="false">
         <association>1012</association>
         <new-name>Samuel</new-name>
       </rename>

    This will call the rename script with the following variables and their values:
       CLASS_NAME=User
       SRC_DN=\Samuel
       OLD_SRC_DN=\Sam
       REMOVE_OLD_NAME=false
       ASSOCIATION=1012
       NEW_NAME=Samuel

    The script will report back to the subscriber shim with the following variables and their values:
       COMMAND=status
       EVENT_ID=<event_id>  
       STATUS_LEVEL=<success, warning, error, retry, or fatal>
       STATUS_MESSAGE=<optional message>
  • The move Command
    • Reserved Keywords: CLASS_NAME, SRC_DN, OLD_SRC_DN, EVENT_ID, ASSOCIATION, PARENT, STATUS_LEVEL, STATUS_MESSAGE
       <move class-name="User" src-dn="\Users\Samuel" old-src-dn="\Samuel" event-id="1234">
         <association>1012</association>
         <parent src-dn="\Users\">
           <association>1013</association>
         </parent>
       </move>
 
    This will call the move script with the following variables and their values:
  
     CLASS_NAME=User
        SRC_DN=\Users\Samuel
        OLD_SRC_DN=\Samuel
        EVENT_ID=1234
        ASSOCIATION=1012
        PARENT_SRC_DN=\Users\
        PARENT_ASSOCIATION=1013
  
    The script will report back to the subscriber shim with the following variables and their values: 
    
        COMMAND=status
        EVENT_ID=<event_id>
        STATUS_LEVEL=<success, warning, error, retry, or fatal>
        STATUS_MESSAGE=<optional message>

Schema Definition

  o The schema determines the names of the objects and attributes of the local application. These names are the names used in the subscriber and publisher scripts to identify items to be synchronized by Identity Manager.
  o In order to provide a customizable schema definition for our external scripting applications, the schema is read in from an external file in an easy-to-edit format:
  
  • Rules
    • Each line represents an element
    • Lines with comments will begin with a '#' character.
    • The line must begin with the element name, SCHEMA, CLASS or ATTRIBUTE
    • Elements must be in order to associate the correct attribute with the correct class
    • class-def and attr-def elements must contain their actual name as the second argument
    • Boolean keywords will simply be specified or not specified for "true" or "false" values
    • Type keywords will be enumerated as a list of keyword options (STRING, INTEGER, BOOLEAN, DN, etc..)
  • example:
       SCHEMA HIERARCHICAL
         CLASS "Organiztion" CONTAINER
           ATTRIBUTE "Name" CASESENSITIVE MULTIVALUED NAMING READONLY REQUIRED STRING
           ATTRIBUTE "Object Path" MULTIVALUED READONLY STRING
           ATTRIBUTE "Unique Id" REQUIRED INTEGER
         CLASS "User"
           ATTRIBUTE "cn" NAMING REQUIRED
           ATTRIBUTE "Group Membership" MULTIVALUED DN
         CLASS "Group"
           ATTRIBUTE "cn" NAMING REQUIRED
           ATTRIBUTE "Group Members" MULTIVALUED DN

File Releases

File listings are not available for this project.

Project Members

NamePosition
Billycook 
Jeffbate 

Novell® Making IT Work As One

© 2009 Novell, Inc. All Rights Reserved.