Sun Identity Manager 8.1 Resources Reference

Chapter 50 Adding Actions to Resources

This chapter describes how to create and implement actions for resource adapters. Refer to the documentation for each adapter to determine if the adapter supports actions.

What are Actions?

Actions are scripts that run within the context of a managed resource, if native support exists for scripted actions. For example, on a system with a UNIX operating system, actions are sequences of UNIX shell commands. In Microsoft Windows environments, actions are DOS-style console commands that can execute within the CMD console. Actions reside within Identity Manager repository as objects. In mainframe environments, actions are Javascript scripts that are capable of sending and receiving keystrokes and commands to and from the mainframe. For Oracle ERP, the actions are Javascript or Beanshell scripts, which use a JDBC connection to manage additional custom fields in the Oracle database. See Chapter 25, Oracle ERP for more information about this adapter.

Use actions to perform work that is not performed directly against the resource account object but is instead performed before or after that resource account is created, updated, or deleted. Resource actions support copying files to a new user’s directory, updating the SUDOers file on UNIX for the user after they have been created, or other native activities. You could perform this type of work by using a custom resource adapter. However, it is simpler to deploy a resource adapter with actions than to deploy a custom resource adapter.

Three types of results messages are associated with actions:

Supported Processes

The following processes support before and after actions:

Defining Actions

An action has the following structure:

<ResourceAction name=’Name’>
    <ResTypeAction restype=’ResourceType’ actionType=’Language’ timeout=’Milliseconds’>
       <act>
       ...
       </act>
    </ResTypeAction>
 </ResourceAction>

where:

The <act> element defines the action. It contains code that is executed on the resource. For example, the following XML defines an action for a Solaris resource:

<?xml version=’1.0’ encoding=’UTF-8’?>
<!DOCTYPE Waveset PUBLIC ’waveset.dtd’ ’waveset.dtd’>
<Waveset>
    <ResourceAction name=’after-create’>
       <ResTypeAction restype=’Solaris’ timeout=’60000’>
          <act>
          #!/bin/ksh
          echo "$WSUSER_accountId says Hello World!"
          # exit $DISPLAY_INFO_CODE if there is not a failure, but you want
          # the output to be propagated to the UI
          #exit 0
          exit $DISPLAY_INFO_CODE
          </act>
       </ResTypeAction>
    </ResourceAction>
</Waveset>

Note –

The code contained within the <act> elements is the same as seen in a UNIX script (ksh or sh) or a Windows batch script.


Using Environment Variables

Environment variables are exported and available to actions. These comprise any one of the schema-mapped attributes that have values on the user (defined in the resource schema map in the Identity System Resource Attribute column), prefixed by WSUSER_. For instance, the preceding example uses the environment variable WSUSER_AccountId, formed by preceding the AccountId attribute defined in the Solaris resource schema map by WSUSER_. These variables should be identified as environment variables within the respective shell, so that in Solaris, the variable name is preceded by $ (dollar sign).

Because OS/400 does not have variable substitution in its command language, the resource adapter looks for variable names, and carries out the substitution before transmitting the command line to the resource. To make recognition of variables possible, you must add a $ before and after a variable. Specifically, to use WSUSER_AccountId in an OS/400 script, enter the following text in the command line: $accountId$. Note the exclusion of “WSUSER”.

Example usage:

<ResTypeAction restype="OS/400" timeout="6000">
<act>
CRTOUTQ OUTQ(SYSTEME/$accountId$)
</act>
</ResTypeAction>

Implementing After Actions

Identity Manager only pushes changed attributes to a resource on an update. An action cannot access any attributes that have not changed. If you write an after action that requires an attribute that might be unchanged, consider the following workaround:

ProcedureAccessing Unchanged Attributes

  1. Add an extra attribute to the resource’s schema map that mimics the account attribute that you need to access. For example, if you need to access the fullname account attribute, you could create an attribute named shadow_fullname. In the Resource User Attribute column of the schema map, add the value IGNORE_ATTR. for this new attribute to prevent the adapter from trying to use it.

  2. Set the value in your user form so that the attribute is populated:


    <Field name=’accounts[ResourceName].shadow_fullname’>
        <Expansion>
           <ref>accounts[ResourceName].fullname</ref>
        </Expansion>
     </Field>
  3. Reference %WSUSER_shadow_fullname% in your action so that it can get the value.

    Identity Manager never retrieves an attribute that is set to IGNORE_ATTR. As a result, Identity Manager considers the contents of an attribute such as shadow_fullname as a new value. The attribute is always pushed to the adapter and is available to after actions.

Creating an Action File

Keep the following items in mind when creating an action file.

Loading the Action File into Identity Manager

Follow these steps to import the action into Identity Manager:

ProcedureImporting the Action File

  1. Log in to the Identity Manager Administrator Interface.

  2. From the menu bar, select Configure, then Import Exchange File.

  3. Enter or browse for the XML file containing the action, and then click Import.

Implementing Actions

After you have defined an action, follow these steps to implement it:

ProcedureHow to Implement Actions

  1. Define fields on the Identity Manager user form.

  2. Add entries to the schema map for the resources on which you want to invoke the action.

Step 1: Define Identity Manager User Form Fields

Create user form fields to assign an action that will run before or after a user operation:

In this example, the field defines an action named after-create that runs after a user create operation:

<Field name=’global.create after action’>
    <Expansion>
       <s>after-create</s>
    </Expansion>
</Field>

The field name is formatted as:

{create|update|delete} {before|after} action

For detailed information about working with forms in Identity Manager, refer to Deployment Reference.

Step 2: Add Schema Map Entries

Add an entry to the schema map for the resources on which you want the action to run. To do this:

ProcedureAdding an Entry to the Schema Map

  1. Click Resources on the Identity Manager menu bar, and then select a resource.

  2. On the Edit Resource page, click Edit Resource Schema.

  3. On the schema map, click Add Attribute to add a row to the schema map.

  4. In the Identity System User Attribute column, enter create after action.

  5. Enter IGNORE_ATTR in the Resource User Attribute column. The IGNORE_ATTR entry causes the attribute to be ignored during normal account attribute processing.

  6. Click Save.

Active Directory Examples

This section provides examples of actions that you can run on an Active Directory resource after a resource adapter performs the following operations:

Example 1: Action that Follows Creation of a User

This procedure shows how to include an action that will run after the creation of a new user on the Active Directory resource.

ProcedureIncluding an Action that Follows the Creation of a User

  1. Enter create after action in the Identity Manager User Attribute column of the resource’s schema map.

  2. In the Attribute Type column, select string.

  3. In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.

  4. Add the following code to the user form you are using to create or edit users:


    <Field name=’resourceAccounts.currentResourceAccounts[AD].attributes.
    create after action’>
        <Expansion>
           <s>AfterCreate</s>
        </Expansion>
     </Field>
  5. Create the following XML file and import it into Identity Manager. (Change the file paths according to your environment.)


    <?xml version=’1.0’ encoding=’UTF-8’?>
     <!DOCTYPE Waveset PUBLIC ’waveset.dtd’ ’waveset.dtd’>
     <Waveset>
        <ResourceAction name=’AfterCreate’>
           <ResTypeAction restype=’Windows Active Directory’ timeout=’6000’>
              <act>
              echo create >> C:\Temp\%WSUSER_accountId%.txt
              exit
              </act>
           </ResTypeAction>
        </ResourceAction>
     </Waveset>

Example 2: Action that Follows the Update or Edit of a User Account

This procedure shows how to include an action that will run after the update or edit of a user on an Active Directory resource.

ProcedureIncluding an Action that Follows the Update or Edit of a User

  1. Enter update after action in the Identity Manager User Attribute column of the Active Directory schema map.

  2. In the Attribute Type column, select string.

  3. In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.

  4. Add the following fields to the user form that you are using to create and edit users:


    <Field name=’resourceAccounts.currentResourceAccounts[AD].
    attributes.update after action’>
        <Expansion>
           <s>AfterUpdate</s>
        </Expansion>
     </Field>
  5. Create the following XML file and import it into Identity Manager. (Change file paths according to your environment.)


    <?xml version=’1.0’ encoding=’UTF-8’?>
     <!DOCTYPE Waveset PUBLIC ’waveset.dtd’ ’waveset.dtd’>
     <Waveset>
        <ResourceAction name=’AfterUpdate’>
           <ResTypeAction restype=’Windows Active Directory’ timeout=’6000’>
              <act>
              echo update >> C:\Temp\%WSUSER_accountId%.txt
              exit
              </act>
           </ResTypeAction>
        </ResourceAction>
     </Waveset>

Example 3: Action that Follows the Deletion of a User

This procedure shows how to include an action that will run after the deletion of a user on the Active Directory resource.

ProcedureIncluding an Action that Follows the Deletion of a User

  1. Enter delete after action in the Identity Manager User Attribute column of the resource’s schema map.

  2. In the Attribute Type column, select string.

  3. In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.

  4. Add this to the Deprovision Form user form after the </Include> tag:


    <Field name= ’resourceAccounts.currentResourceAccounts[AD].attributes.
    delete after action’>
        <Expansion>
           <s>AfterDelete</s>
        </Expansion>
     </Field>
  5. Create the following XML file and import into Identity Manager. (Change file paths according to your environment.)


    <?xml version=’1.0’ encoding=’UTF-8’?> <!DOCTYPE Waveset PUBLIC 
        ’waveset.dtd’ ’waveset.dtd’>
     <Waveset>
        <ResourceAction name=’AfterDelete’>
           <ResTypeAction restype=’Windows Active Directory’ timeout=’6000’>
              <act>
              echo delete >> C:\Temp\%WSUSER_accountId%.txt
              exit
              </act>
           </ResTypeAction>
        </ResourceAction>
     </Waveset>
  6. Edit the XML for the Active Directory resource and add information to the “delete after action” schema mapping. Here is an example of a complete schema mapping for this resource with the new additions. (You will be adding the views-related information.)


    <AccountAttributeType id=’12’ name=’delete after action’ syntax=’string’ 
             mapName=’IGNORE_ATTR’ mapType=’string’>
        <Views>
           <String>Delete</String>
        </Views>
     </AccountAttributeType>

Domino Examples

Domino resources support before and after actions.

There are currently two supported types of actions: LotusScript and cmd shell. Any operation action can have any number of actions that will be executed.

The following examples demonstrate the use of LotusScript and cmd shell resource actions.

LotusScript Example

<ResourceAction name=’iterateAttributes’ createDate=’1083868010032’>
   <ResTypeAction restype=’Domino Gateway’ actionType=’lotusscript’>
      <act>
         Sub Initialize
            Main
         End Sub
         Sub Main
            Dim session As New NotesSession
            Dim doc As NotesDocument
            Set doc = session.DocumentContext
            Forall i In doc.Items
               Dim attrVal As Variant
               attrVal = doc.GetItemValue(i.Name)
            End Forall
         End Sub
      </act>
   </ResTypeAction>
</ResourceAction>

cmd shell Example

<ResourceAction name=’getDirectoryContents’ createDate=’1083868010032’>
   <ResTypeAction restype=’Domino Gateway’>
      <act>dir</act>
   </ResTypeAction>
</ResourceAction>

Note –

A null actionType defaults to cmd script type.


Running LotusScript

On Domino, the execution of LotusScript is handled by an agent attached to a database. The Domino adapter will execute LotusScript in any one of the following ways:

Input  

Results  

agentName 

Runs the agent. 

agentName and script 

Updates the agent with the script and runs the agent. 

agentName, agentCreate, and script 

Creates an agent with the script and runs the agent. 

The following customized account attributes can be used with LotusScript. If any of these attributes are to be used, add the attribute on the Domino Gateway schema map. Specify IGNORE_ATTR as the value in the Resource User Attribute column.


Note –

If you specify agentCreate you must also specify LotusScript to be executed.


Arguments to LotusScript

Agents arguments will be given in a note handle to LotusScript in a special property from the back-end NotesSession class. It can be defined as follows:

NotesDocument = NotesSession.DocumentContext

The NotesDocument can be instantiated by the action script routine and its field values can be read in as parameters to the LotusScript subroutine.

The following is a Lotus script example that gets the name a value of any arguments defined in the document.

Dim session As New NotesSession
Dim doc As NotesDocument
Set doc = session.DocumentContext

Forall i In doc.Items
   Dim attrVal As Variant
   attrVal = doc.GetItemValue(i.Name)
   Print(" Attribute Name: " + i.Name + " Value: " + attrVal(0))
End Forall

All of the attributes defined during the action call will be put into the NotesDocument prefixed with WSUSER_, just as in the case of the NT actions.

Running cmd Shell

Actions are run using the Windows command interpreter cmd.exe with extensions enabled. Actions that run before a user operation must return a zero value. Otherwise, the operation is aborted.

Arguments to the cmd Shell

As with NT/ADSI cmd actions, the environment variables are exported and available to actions. These comprise any one of the schema-mapped attributes that have values on the user (defined in the resource schema map in the Identity Manager User Attribute column), prefixed by WSUSER_.

Multi-valued attributes consist of a pipe-separated list, as in:

WSUSER_groups=staff|admin|users

Mainframe Examples

The ACF2, RACF, and Top Secret adapters require login and logoff resource actions. The login action negotiates an authenticated session with the mainframe. The logoff action disconnects when that session is no longer required.

A thin client host access 3270 emulator is provided to the context of the resource action by the resource adapter to simplify execution of commands in the scripted session. The emulator is defined in the com.waveset.object.HostAccess class. Refer to the JavaDoc for the HostAccess class for details about the methods available on hostAccess object passed to the resource action.

Resource Action Context

Several global variables may be expected within the context of the scripted action.

Object

Description

hostAccess 

TN3270 emulator; an instance of com.waveset.adapter.HostAccess. It is used for sending and receiving keystrokes and commands to/from the mainframe.

hostAccessLogin 

Instance of a class that implements the com.waveset.adapter.HostAccessLogin interface. It is mainly provided because it implements the logoff() method that may be required in the event of a failure during the login process.

identity 

A string that contains the accountId for the user on the resource. 

user 

Contains the name of the administrative user that should be logged on. 

userAttrs 

An instance of java.util.Map containing values for each of the Resource User Attributes needed by the action

password 

Encrypted object which stores the password of the mainframe user; use password.decryptToString() to convert to plain text. 

system 

mainframe system name 

out 

Instance of java.io.PrintStream. If the Javascript writes to this stream (for example, out.print(“Hello”) ), the contents will be traced, and will be shown in the UI results displayed for resource actions.

err 

An instance of java.io.PrintStream. If the Javascript writes to this stream (for example, err.print(“Error”)), the contents will be traced, and will be shown in the UI results displayed for resource actions.

Mnemonic Keywords for the sendKeys Method

The following table describes the special functions that can be executed through the 3270 emulator to simulate keying the non-alphanumeric values.

Function

Mnemonic Keyword

Function

Mnemonic Keyword

Attention 

[attn] 

F1 

[pf1] 

Backspace 

[backspace] 

F2 

[pf2] 

Backtab 

[backtab] 

F3 

[pf3] 

Beginning of Field 

[bof] 

F4 

[pf4] 

Clear 

[clear] 

F5 

[pf5] 

Cursor Down 

[down] 

F6 

[pf6] 

Cursor Left 

[left] 

F7 

[pf7] 

Cursor Right 

[right] 

F8 

[pf8] 

Cursor Select 

[cursel] 

F9 

[pf9] 

Cursor Up 

[up] 

F10 

[pf10] 

Delete Character 

[delete] 

F11 

[pf11] 

DUP Field 

[dup] 

F12 

[pf12] 

Enter 

[enter] 

F13 

[pf13] 

End of Field 

[eof] 

F14 

[pf14] 

Erase EOF 

[eraseeof] 

F15 

[pf15] 

Erase Field 

[erasefld] 

F16 

[pf16] 

Erase Input 

[erinp] 

F17 

[pf17] 

Field Mark 

[fieldmark] 

F18 

[pf18] 

Home 

[home] 

F19 

[pf19] 

Insert 

[insert] 

F20 

[pf20] 

New Line 

[newline] 

F21 

[pf21] 

PA1 

[pa1] 

F22 

[pf22] 

PA2 

[pa2] 

F23 

[pf23] 

PA3 

[pa3] 

F24 

[pf24] 

Page Up 

[pageup] 

   

Page Down 

[pagedn] 

   

Reset 

[reset] 

   

System Request 

[sysreq] 

   

Tab Field 

[tab] 

   

Sample Resource Actions

The following code samples illustrate actions that are commonly performed on mainframe resources:

Login Action

The following code is a complete sample of login and logoff resource actions. The sample is tailored to a specific customer’s environment using a Top Secret resource. As such, the text of commands, prompt, and command sequences will most likely differ across deployments. Note that the resource actions wrap Javascript inside of XML.

<ResourceAction name=’ACME Login Action’>
   <ResTypeAction restype=’TopSecret’>
      <act>
         var TSO_MORE = " ***";
         var TSO_PROMPT = " READY";
          var TS_PROMPT = " ?";
         hostAccess.waitForString("ENTER YOUR APPLICATION NAME");
         hostAccess.sendKeys("tso[enter]");
          hostAccess.waitForString("ENTER USERID– ");
         hostAccess.sendKeys(user + "[enter]");
         hostAccess.waitForString("TSO/E LOGON");
         hostAccess.sendKeys(password);
         hostAccess.sendKeys("[enter]");
         var pos = hostAccess.searchText("  -Nomail", false);
         if (pos != 0) {
            hostAccess.setCursorPos(pos);
            hostAccess.sendKeys("S");
         }
         pos = hostAccess.searchText("  -Nonotice", false);
         if (pos != 0) {
            hostAccess.setCursorPos(pos);
            hostAccess.sendKeys("S");
         }
         hostAccess.sendKeys("[enter]");
         hostAccess.waitForStringAndInput(TSO_MORE);
         hostAccess.sendKeys("[enter]");
         hostAccess.waitForStringAndInput(TSO_MORE);
         hostAccess.sendKeys("[enter]");
         hostAccess.waitForStringAndInput("ISPF");
         hostAccess.sendKeys("=x[enter]");
         hostAccess.waitForString(TSO_PROMPT);
         var resp =hostAccess.doCmd("PROFILE NOPROMPT MSGID NOINTERCOM 
NOPAUSE NOWTPMSG PLANGUAGE(ENU) SLANGUAGE(ENU) NOPREFIX[enter]", 
TSO_PROMPT, TSO_MORE);
         hostAccess.waitForStringAndInput("ENTER LOGON:");
         hostAccess.sendKeys(system + "[enter]");
         hostAccess.waitForStringAndInput("USER-ID.....");
         hostAccess.sendKeys(user + "[tab]" + password);
         hostAccess.sendKeys("[enter]");
         var stringsToHide = new java.util.ArrayList();
         stringsToHide.add(password.decryptToString());
         hostAccess.waitForString("==>", stringsToHide);
         hostAccess.waitForInput();
         hostAccess.sendKeys("[pf6]");
         hostAccess.waitForInput();
      </act>
   </ResTypeAction>
</ResourceAction>

Logoff Action

<ResourceAction name=’ACME Logoff Action’>
   <ResTypeAction restype=’TopSecret’>
      <act>
         var TSO_PROMPT = " READY";
         hostAccess.sendKeys("[clear]end[enter]");
         hostAccess.waitForString(TSO_PROMPT);
         hostAccess.sendKeys("logoff[enter]");
       </act>
   </ResTypeAction>
</ResourceAction>

RACF Dataset Rule Action

If the Create and Delete DataSet Rules parameter on the RACF resource parameter page is selected, Identity Manager directly administers dataset rules. To configure your own dataset rules, define an action similar to the following.

<ResourceAction name=’create after action’>
   <ResTypeAction restype=’RACF’>
      <act>
         var TSO_PROMPT = " READY";
         var TSO_MORE = " ***";
         var cmd1 = "addsd ’"+identity+".test1.**’ owner(’"+identity+"’)[enter]";
         var result1 = hostAccess.doCmd(cmd1, TSO_PROMPT, TSO_MORE);
      </act>
   </ResTypeAction>
</ResourceAction>

Extending Views

You can add attributes to a view. All attributes must be registered.

The user attributes that are available to the different provisioning activities in Identity Manager are limited to those necessary to complete the action. For example, when editing a user, all possible user attributes are retrieved from the assigned resources and available for update. In contrast, the Change Password process needs only a subset of attributes to perform the request.

Attribute Registration

Attributes can be registered in one of two locations:

Location  

Register Attributes Here If ...  

AccountAttributeType definition in the resource

... the attributes you want to update are specific to a particular resource, rather than to all resources of that type. 

System Configuration object 

...you want to make global registrations for all resources of a particular type. These registrations must be done in XML format. 

You can register different attributes for different views. For example, you can register the lock attribute for the Password view and the firstname attribute for the Rename view or the resource action for the Enable, Disable, or Deprovision view.


Note –

In the case of before or after actions, you must extend the view for any process except the create or update user process. For information on extending a view, see Identity Manager Views.


Global Registration

To make global registrations, add an attribute in the System Configuration object with this path:

updatableAttributes.ViewName.ResourceTypeName

where ViewName is one of Password, Reset, Enable, Disable, Rename, or Delete, and ResourceTypeName is the name of the resource type. The type name all is reserved for registrations that apply to all resources.

The value of this attribute must be a List of <String>s. The strings are names of the attributes you want to update. The following example registers the attribute named delete before action in the Deprovision view for all resources.

<Attribute name=’updatableAttributes’>
    <Object>
       <Attribute name=’Delete’>
          <Object>
             <Attribute name=’all’>
                <List>
                   <String>delete before action</String>
                </List>
            </Attribute>
         </Object>
      </Attribute>
       <Attribute name=’Enable’>
          <Object>
             <Attribute name=’all’>
                <List>
                   <String>enable before action</String>
                </List>
            </Attribute>
          </Object>
       </Attribute>
    </Object>
</Attribute>

Resource-Specific Registration

To make resource-specific registrations, modify the resource object from the Identity Manager Debug page and insert a <Views> sub-element in the AccountAttributeType element. <Views> must contain a list of strings whose values are the names of the views in which this attribute can be updated.

<AccountAttributeType name=’lastname’ mapName=’sn’ mapType=’string’>
    <Views>
       <String>Rename</String>
    </Views>
</AccountAttributeType>

In the view, attributes you want to modify are placed within this object:

resourceAccounts.currentResourceAccounts[ResourceTypeName].attributes

Example:

<Field name= ’resourceAccounts.currentResourceAccounts[OS400ResourceName].
    attributes.delete before action’ hidden=’true’>
    <Expansion>
       <s>os400BeforeDeleteAction</s>
    </Expansion>
</Field>