Writing a PSLang script
PSLang scripts are broken down into functions. Each function must include a name, function parameters (if applicable), and a sequence of statements to execute:
function <FunctionName>( <p1>, <p2>, … ) { <statement> <statement> … }
The scripts can contain a mix of user-defined functions and built-in functions which are used to pass information to the agent.
Warning
Remember to remove all debugging statements and to review all statements that will create logs before using the script in a production environment. Ensure that no sensitive information is being captured in the logs.
User-defined functions
In order for agtdos
, agttelnet
, or agtssh
to perform an agent operation, you must implement the corresponding function in your script. Write these functions to provide interaction details between Bravura Security Fabric and the target.
The agents use the following functions:
list( const $wantGroups, const $wantAttributes)
Lists accounts on the target system, and the attributes for each account.The parameters passed to the function are as follows:
$wantGroups
– determines if this function should retrieve group membership.If the value of
$wantGroups
is a non-zero value, write your function to retrieve the group(s) to which each account belongs while listing accounts.$wantAttributes
– determines if this function should retrieve attributes for each account.If the value of $wantAttributes is a non-zero value, write your function to list the attributes for each account.
If both
$wantGroups
and$wantAttributes
are 0 , write your function to list accounts on the target system only.See
listmembermethod
below for more information about listing group membership.listgroups( const $wantMembers)
Lists groups.The parameters passed to the function are as follows:
$wantMembers
– determines if this function should retrieve group membership.If the value of
$wantMembers
is non-zero, write your function to retrieve the account(s) that belong to each group while listing groups.If this value of
$wantMembers
is0
, write your function to list groups only.
See
listmembermethod
below for more information about listing group membership.listresource( const $resourceType)
Lists resources for Bravura Privilege ’s infrastructure auto discovery feature. The parameters passed to the function are as follows:$resourceType
defines which type of resource to list.Depending on target system configuration, listresource() will be called multiple times each with a different resourceType value. The values that resourceType can take on are:
ls_compsvr
– list server computer objects.ls_admmember
– list members of administrative groups.ls_taskacct
– list scheduled task accounts.ls_comacct
– list COM object accounts.ls_iisacct
– list IIS virtual directory accounts.ls_scmacct
– list Service Control Manager accounts.
movecontext( const $info )
Moves an account to a new context or location on a context-sensitive target. Supported in Bravura Identity and Bravura Privilege .isenabled( const $info )
Checks if an account is enabled. Supported in Bravura Pass and Bravura Privilege .islocked( const $info )
Checks if an account is locked. Supported in Bravura Pass and Bravura Privilege .ispwexpired( const $info )
Checks if an account’s password is expired. Supported in Bravura Pass and Bravura Privilege .isacctexpired( const $info )
Checks if an account is expired. Supported in Bravura Pass and Bravura Privilege .disable( const $info )
Disables an account. Supported in Bravura Identity and Bravura Privilege .Most systems differentiate between disabled and intruder-locked accounts.
enable( const $info )
Enables an account. Supported in Bravura Identity and Bravura Privilege .lock( const $info )
Locks an account (sets the intruder lockout). Supported in Bravura Pass and Bravura Privilege .Most system differentiate between intruder-locked and disabled accounts.
unlock( const $info )
Unlocks an account (clears the intruder lockout). Supported in Bravura Pass and Bravura Privilege .expirepw( const $info )
Expires an account’s password. Supported in Bravura Pass and Bravura Privilege .unexpirepw( const $info )
Unexpires an account’s password. Supported in Bravura Pass and Bravura Privilege .expireacct( const $info )
Expires an account. Supported in Bravura Pass and Bravura Privilege .unexpireacct( const $info )
Unexpires an account. Supported in Bravura Pass and Bravura Privilege .create( const $info )
Creates a new account on the target system. This operation creates the account (possibly using a template for some attribute values), then sets other attribute values – including the password for the new account. Supported in Bravura Identity and Bravura Privilege .This function should make use of the target system administrator credentials.
delete( const $info )
Deletes an existing account on the target system. The typical behavior is to first ensure that the account being deleted exists. Supported in Bravura Identity and Bravura Privilege .You may also wish to include instructions to delete any files or objects associated with the account.
verify( const $info )
Checks if a given password is the correct, current password for an account. If the application supports the concept of intruder lockout and the verification fails, the intruder lockout counter is incremented. Supported in Bravura Identity and Bravura Privilege .admin_verify( const $info )
Checks if a given password is the correct, current password for an account without triggering an intruder lockout if the password is not correct. Supported in Bravura Pass and Bravura Privilege .verifyreset( const $info )
Verifies if the account’s password matches the new password, and if the verification fails, administratively sets it to the new password. If the verification succeeds, then the reset is not necessary, and the operation returns success. Supported in Bravura Pass and Bravura Privilege .reset( const $info )
Administratively resets an account’s password to a new value. If the application supports the concept of intruder lockout, then the intruder lockout counter is cleared and the account unlocked. If the application supports the concept of password expiry, then the expiry date is set according to the expiry policy of the application. Disabled accounts will remain disabled. Supported in Bravura Pass and Bravura Privilege .change( const $info )
Changes the password for an account, from a known current value to a desired new value. If the application supports the concept of intruder lockout, then the intruder lockout counter is cleared and the account unlocked. If the application supports the concept of password expiry, then the expiry date is set according to the expiry policy of the application. Supported in Bravura Pass and Bravura Privilege .resetexpirepw( const $info )
Administratively resets an account’s password to a new value and expires the account’s new password, so that the user is forced to change his password the next time he logs in. Supported in Bravura Pass and Bravura Privilege .groupuseradd( const $info )
Adds an account to a group. Supported in Bravura Identity and Bravura Privilege .groupuserdelete( const $info )
Removes an account from a group. Supported in Bravura Identity and Bravura Privilege .groupgroupadd( const $info )
Adds a group to a group. Supported in Bravura Identity and Bravura Privilege .groupgroupdelete( const $info )
Removes a group from a group. Supported in Bravura Identity and Bravura Privilege .update( const $info )
Updates attributes for an existing account. Supported in Bravura Identity and Bravura Privilege .userattributes( const $info )
Lists attributes for a specified account. Supported in Bravura Identity and Bravura Privilege .
All functions are optional. To indicate success your function must return 0
. To indicate failure, your function must return 1
.
Warning
Functions which reset or verify passwords in scripts used by Bravura Privilege for password randomization must always report the result of the reset or verification accurately. Inaccurate status information may result in checked out passwords not working; additionally, if the credential used to manage the target system is being randomized, Bravura Privilege may invalidate its own managed system credential when an erroneous status is returned. Do not assume scripted password changes are always successful; always check return codes.
If your target does not support a particular operation (for example, if there is no intruder lockout mechanism), then omit the corresponding function from the script. If the agent cannot find a particular function in the script, the agent returns a message saying "Function [<operation>] not found in script".
The following additional functions (optional) do not represent actual agent operations, however they are also called directly by the agent:
connecttarget( const $cinfo )
called before the first operation is performed.This function must return 0 on success, or 1 on failure.
disconnecttarget( const $cinfo )
called after the last operation is performed.This function must return 0 on success, or 1 on failure.
listmembermethod()
used to determine the supported method for listing group membership on the target system.If both methods are supported, select the method that is the most efficient. This function must return:
0
- if the script cannot list group membership1
- if the script list accounts in a group while listing groups2
- if the script lists groups while listing accounts
The calling program uses the result of
listmembermethod
, along with your target-configuration settings, to determine the value of$wantGroups
and$wantMembers
.For example, if the calling program is executed with the option to list group membership, and the result of listmembermethod is 1, the calling program executes the function:
listgroups(1)
addressattrs ()
used to extend the address wizard by adding additional address line elements. It is only possible to add new address line elements, not remove or change existing ones. This is useful when creating a scripted target system with a scripted platform definition file.If not defined, the address wizard behaves as normal.
From within this function the addAddressElement callback function adds a single address line element. The callback function can be called multiple times and takes the following form:
addAddressElement(name, type, defaultValue, isRequired,restrictedValuesList, description, advanced);
Where:
name: is the string name of the of the address line component.
type: is one of ($AddressTypeInt $AddressTypeString $AddressTypeBoolean $AddressTypeKvgroup $AddressTypeRestricted $AddressTypeScript $AddressTypeDir $AddressTypeFile).
defaultValue: string default value or empty if no default value.
isRequired: boolean, where 1=required and 0=optional.
restrictedValuesList: array of display/actual values for each restricted value.
description: Textual description of the element.
advanced: boolean, 1=display attribute in advanced section and 0=default
An example is included in the sample
agttelnet-racf.psl
.
The following function is available to agtssh
:
credentialoverride(inout $cinfo )
called before all other functions and used to override the adminid and adminpw credentials on the connection to the SSH target.The function is optional, and is not called if it is not defined.
The function is called before all other functions.
The adminid, adminpw, host, and address elements are readable in the function.
The adminid and adminpw elements are settable within the credentialoverride function to other values. The return value for the function does not affect the commitment of the override values -
agtssh
always uses the returned values for adminid and adminpw for the connection.The host, address, sysid, and syspw elements do not commit overridden values.
The adminid and adminpw elements are accessible via a transitional variable to other functions.
The variable
$COMMON_SHELL
can be set in the function to specify a custom shell.
Input parameters ($cinfo and $info)
The connecttarget()
and disconnecttarget()
functions each take one parameter, an associative array ($cinfo
). Each element is a string. Elements of the array are:
address the target address.
adminid the target system administrator’s ID.
adminpw the target system administrator’s password.
sysid the target system administrator’s ID if the Is this an additional system password? checkbox is selected.
syspw the target system administrator’s password if the Is this an additional system password? checkbox is selected.
Most of the functions that relate to Bravura Security Fabric operations (for example, create()
, enable()
,reset()
, change()
) also take one parameter, an associative array ($info
). Each element is a string unless otherwise indicated. Elements of the array are:
userid the profile ID of the user.
shortid the short ID of the user.
fullname the full name of the user.
acctid the ID for the account that the user has on this system.
newpw the new password (for password reset and create operations).
oldpw the old password (for verify operations).
modeluid the template ID (for create operations).
groupid the group ID (for group* operations).
groupname the group description (for group* operations).
attributes a KVGroup containing information about attributes to set (for create and update operations)
The general format of the KVGroup is as follows:
"attributes" "" = { "DEFAULT-ACTION" = "COPY" "attribute" "givenName" = { "SEQUENCE" = "0" "GROUP" = "0" "ACTION" = "VALUE" "VALUE" = "John" } "attribute" "sn" = { "SEQUENCE" = "0" "GROUP" = "0" "ACTION" = "VALUE" "VALUE" = "Doe" } }
ConnectionCredential a KVGroup containing information about target administrator credentials and system credentials (for reset operations).
The general format of the KVGroup is as follows:
"ConnectionCredential" "" = { "AdminCredential" "" = { "admin1" = "{AES}@KK|dE]=GqX=zqJyTIgqL]XCyECV?AsAJ[O?vBJGpAaEGgfK" "admin2" = "{AES}e[LkiHEv?=iAGTD|ZA^cKCYJCb?[tByFDp_=e]EhWDkgHzmD" } "SysCredential" "" = { "sysadm1" = "{AES}fN=>rLOB?^gDICJfc@fYLB@@COGlv=H@IFc@EW?XBJTwFEXB" } }
Return codes
The return codes for user-defined functions (with the exception of listmembermethod()
) for agtdos
, agttelnet
, and agtssh
are as follows:
Code | Value | Description |
---|---|---|
ACSuccess | 0 | The operation was successful. |
ACUnknownError | 1 | The operation failed with an unknown error. |
ACOperationNotSupported | 2 | The operation is not supported by the target system. |
ACNotConnected | 3 | Can be used in the connecttarget() function if a connection could not be established. |
ACAlreadyConnected | 4 | Can be used in the connecttarget() function if an attempt is made to connect to a target that already has a connection. |
ACInvalidServer | 5 | Can be used in the connecttarget() function if the target address is invalid. |
ACObjectAlreadyExists | 6 | The object to create (for example, user or group) already exists. |
ACInvalidUser | 7 | The user account is invalid or does not exist. |
ACInvalidModelUser | 8 | The template account is invalid or does not exist. |
ACUserNotInGroup | 9 | The user is not in the specified group. |
ACTimeout | 10 | The operation timed out. |
ACAccessDenied | 11 | The target system administrator could not logon due to a bad ID/password pair, account restrictions, and so on. |
ACInvalidGroup | 12 | The group is invalid or does not exist. |
ACUserAlreadyGroupMember | 13 | The user is already a member of the specified group. |
ACVerifyFailed | 14 | The password could not be verified. Use this code ONLY when the specified password is not correct. |
ACInitFailed | 15 | The operation failed to initialize. |
ACLockFailed | 16 | The operation failed to get a lock on a file while reading or writing. |
ACScriptError | 17 | The operation encountered an error in the script. |
ACNotLicensed | 18 | The operation is not licensed. |
ACLogFileFailure | 19 | Failed to write to the log file. |
ACImplementerFailure | 20 | The implementor failed to perform the operation. |
ACAdminLocked | 21 | The target system administrator account is locked. |
ACInvalidPasswd | 22 | The password is invalid. |
ACDelayLoadError | 23 | The operation encountered an error loading a dll or function point. |
ACReadOnlyResource | 24 | The operation could not write to a resource because it was read only. |
ACPluginAborted | 25 | The plugin failed. |
ACPasswordLocked | 26 | The password is locked. |
ACPasswordExpired | 27 | The password has expired. |
ACAccountExpired | 28 | The account has expired. |
ACAccountDisabled | 29 | The account is disabled. |
ACOperationRolledback | 30 | The operation was rolled back. |
ACOperationAborted | 31 | The operation was aborted. |
ACOperationRollbackFailed | 32 | The rollback operation has failed. |
ACEndOfFile | 33 | The operation has reached the end of file. |
ACGroupAlreadyGroupMember | 34 | The group is already a group member. |
ACGroupNotInGroup | 35 | Group is not a member of group. |
ACNull | 0xffff | A null code. |
Built-in Functions
Apart from the standard PSLang built-in functions, there are several built-in agent functions available to the agents.
You call the following built-ins from within functions representing agent operations in order to communicate the results of the operation back to the agent:
agentError
reports an error message.agentWarning
reports a warning message.agentInfo
reports an information message.agentListUser
is called once for each user during the list operation.agentListGroup
(oragentListGroupSID
) is called once for each group during the list operation.agentListAttribute
is called once for each attribute during the list attribute, create, and update operations.agentListResourceComputer
is called once for each computer object during the list resource operation.agentListResourceAccount
is called once for each account object during the list resource operation.agentIsEnabled
tells the agent whether or not the given user is enabled.agentIsLocked
tells the agent whether or not the given user is locked out.agentIsPassExpired
tells the agent whether or not the given user’s password has expired.agentIsAcctExpired
tells the agent whether or not the given user’s account has expired.agentLongId
provides the long ID of the user during create, update, rename, or move context operations.agentShortID
provides the short ID of the user during create, update, rename, or move context operations.agentGroups
provides the list of groups to which a user belongs.agentOutput
can return IP information on reset using agentOutput. The keys are ip-address and dns-host-name. This information is used by Bravura Privilege to load current information when the reset occurs. This is included in the agtssh-simple.psl sample. By default it is disabled. It can be enabled with the $emit_info at the top of the script by setting it to non-zero.
See the PSLang Reference Manual (pslang.pdf) for more information about these built-in functions.
Global variables
In any agent script, input passed to the agent is stored in the $_inVars
"hidden" global variable. You can declare and define additional global variables for use throughout the script.
Following is an example of the contents of the $_inVars
KVGroup when performing a list operation:
"" "" = { "address" = "agtdos.psl" "adminid" = "null" "adminpw" = "<encrypted password value>" "hostid" = "DOS" "listdbfilename" = "C:\\Program Files\\Hitachi ID\\IDM Suite\\default\\psconfig\\AGTDOS.db" "operation" = "listobj" "platformname" = "Win32 Console Script" "timeout" = "-1" "listattributes" "" = { } }
Built-in variables
The following built-in variables are available for use with PSLang scripts:
$KeyAccounts
Value: "accounts" Description: List of accounts.
$KeyAcctID
Value: "acctid" Description: Name of the target account to operate on.
$KeyAction
Value: "ACTION" Description: Action to do to the attribute.
$KeyActionCopy
Value: "COPY" Description: Action to do to the attribute.
$KeyActionIgnore
Value: "IGNORE" Description: Action to do to the attribute.
$KeyActionReplace
Value: "REPLACE" Description: Action to do to the attribute.
$KeyActionValue
Value: "VALUE" Description: Value of the attribute.
$KeyAddress
Value: "address" Description: The address line to use to connect to the target.
$KeyAddrComps
Value: "addresscomponents" Description: Key to the sub-array containing the address elements already split.
$KeyAdminID
Value: "adminid" Description: Name of the account to connect to target as.
$KeyAdminPW
Value: "adminpw" Description: Password of the account to connect to the target with.
$KeyAttribute
Value: "attribute" Description: Single account attribute details.
$KeyAttributes
Value: "attributes" Description: List of account details.
$KeyAuthKey
Value: "authkey" Description: SSH Authentication key attribute.
$KeyBoolean
Value: "boolean" Description: true/false address attribute type
$KeyCAPath
Value: "CApath" Description: Path to certificate file.
$KeyCAFile
Value: "CAfile" Description: Certificate file name.
$KeyChildGroupID
Value: "childgroupid"
$KeyCheckCert
Value: "checkCert" Description: Should the agent check the SSL certificate.
$KeyCommand
Value: "command" Description: Command to run during runcommand() operation.
$KeyCommandFile
Value: "commandfilename" Description: File where the output from runcommand() operation is written to.
$KeyCompression
Value: "compression" Description: SSH address attribute to compress the data transmitted.
$KeyFalse
Value: "false" Description: String used for boolean address and account attributes.
$KeyFullName
Value: "fullname" Description: Description attribute of an account.
$KeyGroup
Value: "group" Description: Single sub KV of a group on the target.
$KeyGroupID
Value: "groupid" Description: Identifier for the group.
$KeyGroupName
Value: "groupname" Description: Name of the group.
$KeyGroups
Value: "groups" Description: List of groups.
$KeyHostID
Value: "hostid" Description:
$KeyHostKeysDenyUnmatched
Value: "DenyUnmatch" Description: Tells the SSH library to connect ONLY if the host key matches an existing one.
$KeyHostKeysUpdate
Value: "AllowUpdate" Description: Allows the SSH connection to update the host key if one already exists (unsafe).
$KeyHostKeysAppend
Value: "AllowAppend" Description: Tells the SSH libary to add the host key if it is missing, but refuse if it does not match.
$KeyInteger
Value: "integer" Description: Integral address attribute type.
$KeyKvgroup
Value: "kvgroup" Description: Address attribute type.
$KeyManagedGroup
Value: "managedGroup"
$KeyModelUID
Value: "modeluid" Description: Account to use as a template when creating a new user.
$KeyNewPW
Value: "newpw" Description: Password for the new account or the new password when resetting an existing account.
$KeyNoPTY
Value: "nopty"
$KeyOldPW
Value: "oldpw" Description: Current password for an account.
$KeyOperation
Value: "operation" Description: The action that is currently underway.
$KeyPort
Value: "port" Description: IP port to connect to on the target.
$KeyPosition
Value: "position" Description:
$KeyReadOnly
Value: "readonly" Description: Address attribute that is not modifiable by the user.
$KeyResource
Value: "resource" Description:
$KeyResourceAddress
Value: "resourceaddress" Description:
$KeyResourceType
Value: "resourcetype" Description:
$KeyRestricted
Value: "restricted" Description: Address attribute type of restricted values.
$KeyRestrictedValue
Value: "restrictedvalue" Description: Key for the chosen restricted address attribute value.
$KeyRestrictedValueText
Value: "restrictedvaluetext" Description: Display value for a restricted address attribute value.
$KeyRestart
Value: "restart" Description:
$KeyRevision
Value: "rev" Description:
$KeyScript
Value: "script" Description: Address attribute type.
$KeyFile
Value: "file" Description: Address attribute type.
$KeyDir
Value: "dir" Description: Address attribute type.
$KeyPath
Value: "path" Description: Address attribute type.
$KeyServer
Value: "server" Description: Address attribute containing the target to connect to.
$KeyServerInfo
Value: "serverinfo" Description: Operation to query the target for version and status information.
$KeySettings
Value: "settings" Description:
$KeyShortID
Value: "shortid" Description: User’s ID
$KeySSL
Value: "SSL" Description: Address attribute determining if encrypted telnet should be used.
$KeyString
Value: "string" Description:
$KeySysID
Value: "sysID" Description: Username for secondary login to the target (e.g. sudo).
$KeySysPassword
Value: "syspassword" Description: Password for the secondary login to the target.
$KeyTerm
Value: "terminal" Description: Address attribute determining the terminal type for the telnet connection.
$KeyTimeout
Value: "timeout" Description: Address attribute defining how long the agent should wait for connection to complete.
$KeyTrue
Value: "true" Description: String used for boolean address and account attributes.
$KeyWriteOption
Value: "writeoption" Description: Address attribute determining the terminal type for the telnet connection.
Live debugging
You can use the termdebug
KVGroup to interactively monitor what is sent and received by agent scripts over raw TCP connections, SSL raw connections (not http/https), telnet and SSH connections. To do this, add a supplemental termdebug
KVGroup to the agent input. For example:
# KVGROUP-V1.0 "" "" = { "address" = "telnet_unix.psl" "adminid" = "root" "adminpw" = "<encrypted password value>" "hostid" = "SSH1" "listfilename" = "C:\\listing-test.txt" "instance" = "globoco" "listresource" "" = { } "operation" = "list" "timeout" = "30" "termdebug" "" = { ## mandatory configurations "address" = "127.0.0.1" #String representation of the #address of the interface to listen to. "port" = "3210" #string representation of the TCP port to listen to. #agtssh listens to this port on IDM Suite server "command" = "c:\\windows\\system32\\telnet.exe localhost 3210" #Command line to run with full executable path and parameters #Quotes and backslashes need to be escaped with \. #See below for more info. ## optional configurations "interactive" = "1" #0=no 1=yes #If 1, shows a dialog box with the string to # be sent, and waits for OK before it is sent. "waitforjointimeout" = "10000" #Timeout, in milliseconds, of the agent waiting # for a client connection. "sendtimeout" = "1000" #Timeout, in milliseconds, of sending data back to the # client. } }
Warning
Data seen on the debug port is raw decrypted data.
Command options
The command value can take Cygwin telnet.exe, or nc.exe, or a tn3270/tn5250 client as required, for example:
"command" = "c:\\cywgin\\bin\\bash -c \"/bin/telnet.exe localhost 3210 | tee /tmp/log1; sleep 3600\""
To prevent the window closing after the debug port closes, include cmd.exe /k telnet ...
for telnet, or sleep
for Cygwin telnet.exe or nc.exe.
For non-interactive debugging, the command can be something like:
"command" = "c:\\windows\\system32\\cmd.exe /c telnet localhost 3210 >> c:\\debuglog.txt 2>&1"
Interactivity options
When interactivity is turned on ("interactive" = "1" ) the script waits for one of the following inputs before proceeding:
ok = next step
cancel = skip next questions, run all steps automatically without any more prompting
If the original agent script or the target itself has very strict timeouts, it is recommended that you do not use the interactive option, or cancel it before the section with critical timing.
Adding the termdebug KVGroup to input
You can add the termdebug KVGroup to the agent input by:
Capturing agent input using the pstee program, then manually adding the inner KVGroup.
Wrapping the actual agent in an
agtdos
script as described in the PSLang Reference Manual (pslang.pdf) .The script should:
Read $_inVars
Replace its address ( "address" = "doswrapper.psl" ) with the telnet or ssh address line, then add the termdebug KVGroup
Call the original agent with this group (converted to string) as input. It could also log the new modified agent input for debugging the PSLang wrapper script.
This method is more complicated, but has the advantage of working for every agent call and not replaying operations. See the PSLang Reference Manual (pslang.pdf) for more information about KVGroup functions, and system() calls.