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.
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:
Success. Displays an Identity Manager success message.
Success with action output. Displays an Identity Manager success message along with standard error and output information.
Failure. Displays an Identity Manager failure message, along with standard error and output information.
The following processes support before and after actions:
create
update
delete
enable
disable
login and logoff (mainframe adapters only)
An action has the following structure:
<ResourceAction name=’Name’> <ResTypeAction restype=’ResourceType’ actionType=’Language’ timeout=’Milliseconds’> <act> ... </act> </ResTypeAction> </ResourceAction>
where:
Name is the name of the resource action.
ResourceType is the type of resource (such as AIX or HP-UX).
Milliseconds (optional) is the amount of time to wait for the action to complete.
Language (optional) is the language of the script. This parameter is required for the Oracle ERP adapter. The Oracle ERP adapter supports actionType values of Javascript and Beanshell.
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>
The code contained within the <act> elements is the same as seen in a UNIX script (ksh or sh) or a Windows batch script.
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>
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:
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.
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> |
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.
Keep the following items in mind when creating an action file.
If you change any variable names in the Identity Manager Resource Attribute column on the schema map, you must change the names in this object as well.
Because the actions are included in an XML expression, some characters must be escaped. Escape these characters as follows:
& (ampersand): &
< (less than): <
On UNIX resources, spaces in attribute names are replaced with _ (underscore). On Windows resources, spaces are maintained.
Multi-valued attributes consist of a comma-separated list, as in:
WSUSER_groups=staff,admin,users
Gateway-based adapters use a pipe-delimited list for multi-valued attributes. For example:
WSUSER_NotesGroups=group1|group2|group3
On Active Directory resources, 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.
A Javascript is assumed to have completed successfully unless it throws an exception.
Follow these steps to import the action into Identity Manager:
Log in to the Identity Manager Administrator Interface.
From the menu bar, select Configure, then Import Exchange File.
Enter or browse for the XML file containing the action, and then click Import.
After you have defined an action, follow these steps to implement it:
Define fields on the Identity Manager user form.
Add entries to the schema map for the resources on which you want to invoke the action.
Create user form fields to assign an action that will run before or after a user operation:
Field name. Indicates when the action will run and for which operation
Field value. Contains the action name
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.
Add an entry to the schema map for the resources on which you want the action to run. To do this:
Click Resources on the Identity Manager menu bar, and then select a resource.
On the Edit Resource page, click Edit Resource Schema.
On the schema map, click Add Attribute to add a row to the schema map.
In the Identity System User Attribute column, enter create after action.
Enter IGNORE_ATTR in the Resource User Attribute column. The IGNORE_ATTR entry causes the attribute to be ignored during normal account attribute processing.
Click Save.
This section provides examples of actions that you can run on an Active Directory resource after a resource adapter performs the following operations:
Creation of a user
Update or edit of a user account
Deletion 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.
Enter create after action in the Identity Manager User Attribute column of the resource’s schema map.
In the Attribute Type column, select string.
In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.
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> |
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> |
This procedure shows how to include an action that will run after the update or edit of a user on an Active Directory resource.
Enter update after action in the Identity Manager User Attribute column of the Active Directory schema map.
In the Attribute Type column, select string.
In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.
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> |
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> |
This procedure shows how to include an action that will run after the deletion of a user on the Active Directory resource.
Enter delete after action in the Identity Manager User Attribute column of the resource’s schema map.
In the Attribute Type column, select string.
In the Resource User Attribute column, enter IGNORE_ATTR. Leave the Required, Audit, Read Only, and Write Only columns unchecked.
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> |
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> |
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 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.
<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>
<ResourceAction name=’getDirectoryContents’ createDate=’1083868010032’> <ResTypeAction restype=’Domino Gateway’> <act>dir</act> </ResTypeAction> </ResourceAction>
A null actionType defaults to cmd script type.
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.
agentName. Identifies the name of the agent to execute. This attribute must be specified, or an error will be returned.
agentServer. Specifies the location of the database where the agent has been installed, and where to run the agent. This attribute defaults to the value specified in the Registration Server Machine resource parameter (REG_SERVER) if not present.
agentDBName. Specifies the database name where the agent can be found. This attribute defaults to the value specified in the Names Database resource parameter (NAB) on the resource.
agentCreate. Specifies the flag that indicates whether the adapter should create a new agent, if the named agent is not found. This attribute defaults to false. A non-NULL value enables this flag.
If you specify agentCreate you must also specify LotusScript to be executed.
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.
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.
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
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.
Several global variables may be expected within the context of the scripted action.
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] |
The following code samples illustrate actions that are commonly performed on mainframe resources:
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>
<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>
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>
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.
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.
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.
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>
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>