Application accounts
The runwithpass program allows you to securely download large credential files, as well as retrieve privileged passwords from the Bravura Privilege vault and use them to execute scripts and command-line programs.
The pamutil shared library is a library that provides the same functionality but is intended to be invoked from locally compiled programs; that is, it allows a program to fetch a password on demand.
To use the program or library, you must:
Configure product administrator access.
Copy the program or library, and configuration files, to the system on which you will run scripts or commands.
Edit the configuration file.
Configuring access
To use this program, your OTP API user needs to have permissions to view the password:
Create a new product administrator (Manage the system > Security > Access to product features) with the "OTP IDAPI caller" privilege.
Create a privileged access user group (Manage the system > Security > Privileged access to systems).
On the Membership Criteria tab, create a user class, or use an existing one, that contains the administrator you created in Step 1.
Give the user group the permission "Pre-approve check-out of managed accounts" on the policy that the password is managed under.
See Using a plugin to define access to passwords for details on managing large numbers of OTP API callers with limited permissions.
Using a plugin to define access to passwords
You can define a plugin that can be used to determine user access controls when viewing passwords using pamutil . This plugin is configured from Manage the system > Privileged access > Options > General > Account access request > RES PWD ACL PLUGIN .
This plugin only applies to KMKeyGetByAccount and RecoverKeyByAccount API functions and is intended to simplify management of large numbers of OTP API callers with limited permissions. It determines whether users will be able to retrieve the passwords of accounts directly.
The plugin point will receive a KVGroup in the following format:
"" "" = {
"userid" = "<ID of user calling the API function>";
"managedaccount" = "<ID of managed account of the password being viewed>";
"managedsystem" = "<ID of managed system of the managed account>";
}It must return a KVGroup in the following format:
"output" "plugin_passwordacl" = {
"acl" "" = {
"view" = "<permission>"
}
"retval" = "0"
}Where "<permission>" can be either "allow" or "deny".
If "view"="allow" , the user will be granted access to view the password for this API call only, bypassing all other access control checks. Likewise, if "view"="deny" , the user will be denied access, bypassing all other access control checks.
It is acceptable to return a KVGroup with no view pair. In this case processing will continue as though the plugin had not been called at all, and the user’s permissions will be determined based on their user group memberships as usual.
Installing files
Copy the appropriate program or library, and configuration files, to the system on which you will run scripts or commands.
Windows systems
For deployment on Windows systems, the program, library and configuration files are located in zip files in the util and utilx64 directories. Use the package appropriate for your system and needs:
pamutil(-x64).zipwhich includes common files for deployment on Windows systemspamutil-devkit(x64).zipwhich includes additional files for developers writing programs that link against pamutil
Unix/Linux systems
For deployment on Unix/Linux systems, use the distribution’s package manager to install the hid-common, hid-idapi and hid-pamutil packages found in the Unix/Linux *tar.gz archives in the <instance>\addon\idmunix directory. Once the packages have been installed the program, library and configuration files are typically located in the /usr/local/psunix/ directory.
Bravura Security Fabric includes binaries and library files for a variety of Unix and Linux variants. Contact support@bravurasecurity.com for additional variants.
Install the following shared object libraries first, which are required by pamutil.
openssl – available from http://www.openssl.org/
Version 1.1.x with Connector Pack 4.6 or earlier, or 3.0.x with Connector Pack 4.7 or later, has been verified on supported platforms.
libcurl – available from http://curl.haxx.se/libcurl/
Version 7.26.0 has been tested on supported platforms.
It is not recommended to deploy runwithpass without SSL.
Configuration and credentials files
Both the program and library use the following files:
The configuration file, supplied as
config.ini,which defines configuration parameters.The credentials file, which is specified in the configuration file, holds encrypted passwords.
The large credentials configuration file, supplied as
lcinfo.ini, which contains information about large credential files.
These file can be renamed and can be placed anywhere on the filesystem.
Configuration file
The configuration file, typically called config.ini, specifies the following parameters, in simple ’key=value’ format:
Options marked with a
are required.
apiurl=https://<server>/<instancename>/idapi2The URL to the Bravura Privilege API web service. Edit the value to suit your environment. An empty URL means do a local connection.proxy=A proxy to use when accessing the API SOAP Service (idapisoap) endpoint. If omitted, uses the default proxy from environment variables on Unix/Linux system or the proxy settings in user registry on Windows. If empty, disables all proxy use.capath=For Unix/Linux systems only: The CA directory or file holding the certificates to trust.cert=The certification file in PEM format for client authentication.Warning
This is not recommended for use without supervision from Bravura Security staff.
ignorebadservercert=0Whether to ignore problems with server certificate and identity validation. Default is 0 (do not ignore) if not specified. Valid values are 0 (false) or 1 (true).timeout=30The API SOAP Service (idapisoap) call timeout in seconds. Default is 300 if not specified. Valid values are between 0 and 3600 inclusive.
lockfile=/tmp/.pam-lockThe filesystem path where a lock will be placed while calling the web service, to ensure that two processes do not simultaneously access the same one-time password (OTP), which could lead to an invalid OTP being retained locally.locktries=200The number of tries to lock the file. Default is10 if not specified. Valid values are between 0 and 200 inclusive.locksleep=0.1The delay between attempts to lock the file, in seconds. Default is 2 seconds if not specified. Valid values are between 0 and 100 inclusive. It supports fractional values, like 1.5.
credsfile=creds.iniThe filesystem path where credentials will be stored
lcinfofile=lcinfo.iniThe filesystem path where large credential file information will be storedcacheseconds=60The lifetime of cached credentials. Default is 60 if not specified. Valid values are between 0 and 86400 (24 hours) inclusive.usemachinekey=1Whether to include MAC address, IP address and host name in the encryption key. Default is 1 (do include). Valid values are 0 (false) or 1 (true).Note
Data is encrypted whether this setting is enabled or not. See Credentials file encryption.
useargskey=1Whether to include the command line details to the encryption key. Default is 0 if not specified. Valid values are 0 (false) or 1 (true).filekey=./config.iniCan appear multiple times to use multiple files as keys.filekey=/usr/local/lib/libidapi.soThe files to include into the encryption key.synchronouswriteis deprecated and ignored if present. A warning will exist in the log.
Credentials file
The credentials file, specified in the configuration file (config.ini), holds two types of passwords:
A one-time password, used by
runwithpassand/orpamutilshared object to authenticate to the Bravura Privilege web service.Cached copies of the passwords fetched from the Bravura Privilege web service.
The file has one line of text per system/account/password. For example:
system=__OTP__|user=ID|password=PW|expires=0
Where:
ID is the ID of the product administrator (OTP), proxy user, or managed account ID.
PW is the password for this ID
The file will be created upon initializing the one-time password user, as detailed in One-time passwords .
Credentials file encryption
The usemachinekey setting (Fingerprinting) in pamutil incorporates machine-specific information (MAC address, IP, hostname) into the encryption key used for credential files, preventing unauthorized access from other machines. When disabled (changed from 1 to 0 in the configuration file) using runwithpass causes existing credentials to become undecryptable because the key no longer includes machine-specific information, so it requires reinitialization with the -initial command.
After using the -initial option with runwithpass, the creds.ini file is reset and will contain only the essential predefined credentials. Specifically, it will contain one record for the __OTP__ credential (which stores the API user and password), and if a proxy is configured in config.ini, it will also contain a __PROXY__ credential record. All previously cached account credentials are removed during this reinitialization process.
After changing usemachinekey to 0 and reinitializing with the -initial option, PAMUtil will still encrypt the credential data in the creds.ini file. The difference is that the encryption key will no longer include machine-specific information. The credentials remain encrypted for security, but they're now encrypted with a key that doesn't depend on the machine's hardware identifiers, making the credential file portable across different machines.
Large credentials configuration file
The lcinfo.ini configuration file contains information about large credential files. This file is created upon the first download of a large credential file using pamutil . Each time a new large credential file gets downloaded, its information gets recorded into this configuration file.
The location of lcinfo.ini is configured in config.ini .
Installation and setup of Bravura Privilege Pattern is required in order to upload vaulted files.
The file has one line of text per large credential file. For example:
system=TESTSYS|user=sampleCredFile|attrkey=LC_FILE|filename=sampleCredFile.zip|lchash=zkYU108lTR10b8EGgxLDvQ==
Where:
system is the ID of the vault system or team vault the file is associated to
user is the ID of the vaulted file
attrkey is the attribute key the file is added to (typically LC_FILE)
filename is the name of the file
lchash is the hash of the file contents
This configuration file does not store password information.
One-time passwords
The Bravura Privilege API can eliminate static, plaintext passwords embedded in scripts and configuration files. This is done by creating one user ID per application per server; that is, an application running on 10 servers requires 10 user IDs. These IDs are Bravura Privilege product administrator IDs with the "OTP IDAPI caller" privilege, and granted access to just the passwords they need to retrieve, randomize, or override.
OTP IDAPI account IDs are subject to two extra authentication constraints, as compared to human Bravura Privilege users:
They must authenticate to the Bravura Privilege web services API with a one time password; whenever an OTP IDAPI ID successfully signs into the API, it uses the previous passwords but receives a new password, to be used next time.
They must authenticate from a previously defined IP subnet; that is, they must be connecting from a well known application server.
This means that any user of the API has to be initialized with an application ID’s password and must track changes to that password on every call to the API. In turn, this means that API access should be serialized, to avoid a race condition where two processes call the API using the same application ID from the same machine at the same time, and it’s not clear which new password is the most current one.
The runwithpass program and the pamutil library shared object take care of recording changes to the OTP and serializing API access via a lock file.
One-time passwords and cached passwords are both stored in the creds.ini credentials file. The file name may vary, as specified in the configuration file. The ID and password must be initialized before it can be used by this program to connect to the Bravura Privilege web services.
To initialize the creds.ini credential file with an ID and password use the following command:
runwithpass -initial
Enter the ID and password as prompted.
Alternatively, the pamutil API function SetInitialPasswords can also be used.
Note
If the useargskey option is enabled in the config.ini all other arguments that would be normally used need to be specified. See Using useargskey to tie API account, managed account, and command together for more information.
In the scenario where the OTP passwords needs to be reset the previously mentioned command can be used to reset the creds.ini credential file.
Each time an OTP IDAPI account signs into the API, its password gets randomized. You can set how often the password gets randomized, in hour intervals. The option, Number of hours between password randomizations , is available for Bravura Privilege product administrator IDs with the "OTP IDAPI caller" privilege, located in Manage the system > Security > Access to product features > Individual administrators.
By default, passwords that OTP IDAPI accounts use to sign into the API are immediately discarded. However, you can set a limit of how many passwords previously used by an OTP account that will be considered valid when authenticating to the API. These passwords will be stored in a password history, and the oldest password will be removed each time the OTP account signs in again. This option is configured from Manage the system > Security > Options > OTP MAXIMUM.
Caching
Imagine that there are 1,000 servers, each of which holds an application that needs a password from the Bravura Privilege vault 1,000 times per second. In total, then, the Bravura Privilege web service would have to provide 1,000,000 passwords per second. This would require a lot of resources and create a single point of failure for the entire infrastructure.
To reduce the workload on the Bravura Privilege service, improve the performance of applications that require credentials from the vault and provide for resiliency in the event that Bravura Privilege is unreachable, credentials fetched from the vault are cached locally, in the creds.ini file.
For large credential files, if the file has previously been downloaded, and it has not been modified based on a file content hash check, the Bravura Privilege service will not attempt to contact the instance to download the file again. If the file does not exist, or does exist but has been modified (fails the hash check), the file will be downloaded again.
Key management
The credentials file, creds.ini, contains both cached passwords fetched via the Bravura Privilege API and the current value of the one-time password. This file needs to be protected, which in practice means encrypted.
The question then is how to synthesize an encryption key to use when encrypting passwords in this file? A plaintext key is clearly not desirable, since the whole point of the API is to eliminate plaintext passwords (keys and passwords are essentially interchangeable).
The only realistic option is to have the API wrapper synthesize a key from characteristics of the runtime environment. This way, if the credentials file is moved to another machine or if an attacker gains partial access to the server or its filesystem, the key generation process would yield a new key and so cached credentials and the OTP will become unavailable.
The runwithpass program and the pamutil library support a number of inputs into the key generation process:
Characteristics of the machine running the software; that is, IP address, MAC addresses, hostname, and so on.
A cryptographic hash of one or more files on the filesystem.
A cryptographic hash of the entire command line being executed by the program.
Command-line options for runwithpass
The following are the command-line options for runwithpass:
runwithpass.exe [ -conf <file> ] -res <resource ID> -acct <account ID> [ -expirecache ][ -keyword <string> ][ -replace <inputfile> <outputfile> ][ -v ][ -initial ][ -randomize ][ -override <password> ] [ -downloadfile <attributekey> ][ -downloaddir <directory> ] [ -downloadfilepassword ][-- <client cmd> ]
Argument | Description |
|---|---|
-conf <filename> | Specify a configuration file. The default is config.ini. |
-res <resource ID> | The ID of the system from which the password will be fetched. |
-acct <account ID> | The ID of the account for which the password will be fetched. |
-expirecache | Treat cached credential as expired. See Section 1.10 for more information. |
-keyword <string> | String to replace with password in client command arguments or input file. |
-replace <inputfile> <outputfile> | Search/replace on the given input/output files. <inputfile> may be - meaning stdin. <outputfile> may be - meaning stdout. |
-v | Attempts to obtain more detailed error information when available. |
-initial | Set the initial passwords as encrypted. Using this argument will prompt for the following:
|
-override <password> | Set the account’s password to the specified value. |
-randomize | Set the account’s password to a random value. |
-downloadfile <attributekey> | Download the large credential file using this attribute key. |
-downloaddir <directory> | Download the large credential file to a specific directory. By default, the current directory will be used. |
-downloadfilepassword | Fetch the password associated with the large credential file, if one exists. Must be used in conjunction with -downloadfile. |
-- | Client command line and arguments to run follow the --. If the client command is omitted and no replacement is specified, the password is sent to stdout. |
The command line, including the password if it was substituted, executed by runwithpass may be visible to other users of the system. Using -replace to pass the password to the program’s standard input is recommended.
It is recommended that you use full path names in all arguments.
Examples
To fetch the password for psadmin on target system SSH:
runwithpass.exe -conf config.ini -res SSH -acct psadmin
To replace PWD in template.txt with the password for account APISVCACCT on system PAMSYSID01:
runwithpass -conf config.ini -keyword PWD -res PAMSYSID01 -acct APISVCACCT -replace template.txt - -- /bin/cat
To pass a password on the command-line to /usr/local/bin/somecommand:
runwithpass -conf config.ini -keyword PASSWORD -res PAMSYSID01 -acct APISVCACCT -- /usr/local/bin/somecommand -u APISVCACCT@myserver -p PASSWORD
Note that running ’ps -ef’ will display the password unless /usr/local/bin/somecommand removes it from its process space.
There is no portable way for processes to hide their own command-line arguments and none at all for a parent process to rewrite command-line arguments after passing them to a child process.
To initialize the credential passwords with useargskey encryption:
runwithpass -res AD -acct Administrator -initial
To set the password of an account to a specified value:
runwithpass -res AD -acct Administrator -override newPassword
To randomize the password of an account:
runwithpass -res AD -acct Administrator -randomize
To download a large credential file to the current directory:
runwithpass -res TESTSYS -acct vaultfile -downloadfile LC_FILE
To download a large credential file to a specified directory:
runwithpass -res TESTSYS -acct vaultfile -downloadfile LC_FILE -downloaddir /home/psadmin
To download a large credential file that is associated with a password:
runwithpass -res TESTSYS -acct vaultfile -downloadfile LC_FILE -downloadfilepassword
pamutil API
You can write programs that link against the pamutil library. This section describes functions that are provided in the relevant .h header files. All functions return 0 on success, and non-zero on failure.
Return codes
The pamutil library returns a 32-bit signed integer type. Strictly speaking, this type is only guaranteed to be 16 bits long, but it was retained for backwards compatibility purposes. If your compiler emits 16-bit integers, please contact support@bravurasecurity.com for a replacement that uses the long type.
The pamutil library return codes are split into five fields to indicate problems encountered during execution, as shown below:
Bit | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
Field | CB | RESERVED | SPECIFIC | |||||||||
Bit | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Field | GENERAL | IDAPI | ||||||||||||||||||
Field | Description |
|---|---|
CB | Set when a password was returned from the cache instead of the Bravura Privilege server. If set, a password was returned. If unset, a password may or may not have been returned. |
RESERVED | Reserved. You may assume this field will always be 0. |
SPECIFIC | The error code in this field indicates a specific error, such as "Cannot open file for reading." |
GENERAL | The error code in this field indicates a general error, such as "Error loading creds file." |
IDAPI | The error code in this field indicates the error returned by the API Service ( |
You can use the GetErrorMessage function in the shared object, or the -v flag in runwithpass to obtain error messages corresponding to error codes returned by pamutil .
Error codes
# | Code | Meaning |
|---|---|---|
1 | ERR_LOADING_CONFIG_FILE | Error loading config file |
2 | ERR_LOADING_CREDS_FILE | Error loading creds file |
3 | ERR_GENERATING_MACHINE_KEY | Error generating machine key |
4 | ERR_GENERATING_FILE_KEY | Error generating file key |
5 | ERR_GENERATING_ENCRYPTION_KEY | Error generating encryption key |
6 | ERR_DECRYPTING_CREDS_FILE | Error decrypting creds file |
7 | ERR_LOCKING | Error obtaining file lock |
8 | ERR_CALLING_SOAP | Error calling IDAPI service |
9 | ERR_ENCRYPTING_CREDS | Error encrypting creds file |
10 | ERR_WRITING_CREDS_FILE | Error writing to creds file |
11 | ERR_WRITING_CONFIG_FILE | Error writing to config file |
12 | ERR_UNLOCKING | Error unlocking file lock |
13 | ERR_BUILDING_COMMAND_LINE | Error building command line |
14 | ERR_RUNNING_COMMAND | Error running command |
15 | ERR_REPLACING_INPUT_FILE | Error in replace input/output file |
16 | ERR_PARSING_ARGUMENTS | Invalid arguments supplied |
17 | ERR_CREATING_ERRMSG | Error creating an error message |
18 | UNKNOWN | Unknown |
# | Code | Meaning |
|---|---|---|
1 | NON_NUMERIC_INPUT_IGNOREBADSERVERCERT | Non-numeric value specified for 'ignorebadservercert' |
2 | NON_NUMERIC_INPUT_TIMEOUT | Non-numeric value specified for 'timeout' |
3 | NON_NUMERIC_INPUT_LOCKTRIES | Non-numeric value specified for 'locktries' |
4 | NON_NUMERIC_INPUT_LOCKSLEEP | Non-numeric value specified for 'locksleep' |
5 | NON_NUMERIC_INPUT_CACHESECONDS | Non-numeric value specified for 'cacheseconds' |
6 | NON_NUMERIC_INPUT_USEMACHINEKEY | Non-numeric value specified for 'usemachinekey' |
7 | NON_NUMERIC_INPUT_USEARGSKEY | Non-numeric value specified for 'useargskey' |
8 | CANNOT_OPEN_FILE_READING | Cannot open file for reading |
9 | CANNOT_OPEN_FILE_WRITING | Cannot open file for writing |
10 | CANNOT_READ_FROM_FILE | Cannot read from open file |
11 | CANNOT_CREATE_FILE | Failed to create file |
12 | CANNOT_LOCK_FILE | Failed to lock file |
13 | CANNOT_UNLOCK_FILE | Failed to unlock file |
14 | CANNOT_OPEN_DLL | Failed to load libidapi |
15 | CANNOT_LOCATE_FUNCPTR_DLL | Failed to load libidapi |
16 | MISSING_REQUIRED_KEYWORD | A required keyword was missing |
17 | INVALID_KEYWORD_ENCOUNTERED | An invalid keyword was encountered |
18 | VALUE_OUT_OF_RANGE | A numeric input value was out of range |
19 | LOCKTRIES_VALUE_OUT_OF_RANGE | The 'locktries' value was out of the acceptable range [0,200] |
20 | LOCKSLEEP_VALUE_OUT_OF_RANGE | The 'locksleep' value was out of the acceptable range [0,100000] |
21 | CACHESECONDS_VALUE_OUT_OF_RANGE | The 'cacheseconds' value was out of the acceptable range [0,86400] |
22 | TIMEOUT_VALUE_OUT_OF_RANGE | The 'timeout' value was out of the acceptable range [0,3600] |
23 | IGNOREBADSERVERCERT_VALUE_OUT_OF_RANGE | The 'ignorebadservercert' value was out of the acceptable range |
24 | USEARGSKEY_VALUE_OUT_OF_RANGE | The 'useargskey' value was out of the acceptable range |
25 | USEMACHINEKEY_VALUE_OUT_OF_RANGE | The 'usemachinekey' value was out of the acceptable range |
26 | BLANK_SYSTEM | The 'system' entry can not be blank |
27 | DUPLICATE_SYSTEM | A duplicate 'system' entry was encountered |
28 | DUPLICATE_USER | A duplicate 'user' entry was encountered |
29 | DUPLICATE_PASSWORD | A duplicate 'password' entry was encountered |
30 | DUPLICATE_PLAINTEXT | A duplicate 'plaintext' entry was encountered |
31 | DUPLICATE_EXPIRES | A duplicate 'expires' entry was encountered |
32 | DECRYPTION_FAILURE | Failed to decrypt |
33 | FAILED_IOCTL | Call to ioctl() failed |
34 | FAILED_CREATE_SOCKET | Failed to create socket |
35 | FAILED_MALLOC | Memory allocation failed |
36 | FAILED_GETKERNINFO | Call to getkerninfo() failed |
37 | FAILED_FCNTL | Call to fcntl() failed |
38 | RETRY_LIMIT_EXCEEDED | Lockfile retry limit exceeded |
39 | IMPROPER_ARGC_ARGV | Improper use of argc/argv; either null argv with positive argc or negative argc |
40 | CONFIGFILE_PATH_REQUIRED | A path to a config file is required |
41 | CREDSFILE_PATH_REQUIRED | A path to a creds file is required |
42 | LOCKFILE_PATH_REQUIRED | A path to a lock file is required |
43 | APIURL_REQUIRED | An API URL is required |
44 | NO_BYTES | An input or output buffer had no data when it was expected to contain data |
45 | UNALIGNED_CIPHERTEXT | Unaligned ciphertext |
46 | BAD_CIPHERTEXT_ENCODING | Bad ciphertext encoding |
47 | LOGIN_FAILED | Login failed |
48 | KMKEYGETBYACCOUNT_FAILED | KMKeyGetByAccount failed |
49 | NO_VALID_IFACE | No valid interface found |
50 | INCORRECT_FORMAT_DELIMETER | Delimeter expected when parsing |
51 | INCORRECT_FORMAT_KEY_VALUE | Incorrect input format, missing '=' |
52 | BUFFER_OVERRUN | A buffer was not large enough to hold the output data |
53 | SOURCE_FILE_REQUIRED | A source file must be specified |
54 | DESTINATION_FILE_REQUIRED | A destination file must be specified |
55 | SOURCE_DESTINATION_SAME | Source and destination may not be the same |
56 | SOAP_CLIENT_EXCEPTION | A SOAP client exception occurred |
57 | SOAP_CLIENT_PARSERROR_MISSING_FIELDS (deprecated: SOAP_CLIENT_INSUFFICIENT_MEMORY) | Required fields were missing from the server's response |
58 | SOAP_CLIENT_PARSERROR (deprecated: SOAP_CLIENT_INSUFFICIENT_BUFFER) | The SOAP client failed to parse the server's response |
59 | SOAP_CLIENT_FAILED_TO_SEND_REQUEST | The SOAP client failed to send the request |
60 | SPECIFIC_OUT_OF_RANGE | The specific error code was either negative or larger than the largest known code. |
61 | GENERAL_OUT_OF_RANGE | The general error code was either negative or larger than the largest known code. |
62 | UNKNOWN | Unknown/OS error; consult logs for more information |
63 | ENCRYPTION_FAILURE | Failed to encrypt |
64 | FAILED_GET_SEMAPHORE | Failed acquiring semaphore |
65 | FAILED_RELEASE_SEMAPHORE | Failed releasing semaphore |
66 | USER_EMPTY | The user field was empty |
67 | PASSWORD_EMPTY | The password field was empty |
68 | MANAGEDACCOUNTRANDOMIZEPASSWORD_FAILED | ManagedAccountRandomizePassword failed |
69 | MANAGEDACCOUNTOVERRIDEPASSWORD_FAILED | ManagedAccountOverridePassword failed |
70 | MANAGEDACCOUNTRANDOMIZEPASSWORD_MULTIPLE_RES | ManagedAccountRandomizePassword returned multiple results |
71 | MANAGEDACCOUNTOVERRIDEPASSWORD_MULTIPLE_RES | ManagedAccountOverridePassword returned multiple results |
72 | NON_NUMERIC_INPUT_SYNCHRONOUSWRITE | Non-numeric value specified for 'synchronouswrite' |
73 | LARGECREDENTIALGET_FAILED | LargeCredentialGet failed |
74 | LCINFOFILE_PATH_REQUIRED | A path to a large creds info file is required |
75 | DUPLICATE_ATTRKEY | A duplicate 'attrkey' entry was encountered |
76 | DUPLICATE_FILENAME | A duplicate 'filename' entry was encountered |
77 | DUPLICATE_LCHASH | A duplicate 'lchash' entry was encountered |
Common return values
Below are some error codes of note, either because they are commonly encountered or should be handled by scripts:
Code | Meaning | Notes |
|---|---|---|
0 | No errors. A fresh password was retrieved from the Bravura Privilege server. | |
-2147483648 | No errors. A password was retrieved from the cache. | Since the password was retrieved from the cache, there is a chance that it is now incorrect. Be prepared to retry any operations involving this password. Do not proceed on this error code if your application cannot tolerate incorrect passwords. In such cases, you should use the expirecache argument to prevent usage of the cache. |
-2097119174 | Error calling KMKeyGetByAccount on the API Service. The API Service returned 58 (ERR_PASSWORD_CHANGE_IMMINENT). A cached password was retrieved. | The Bravura Privilege server is currently in the process of changing the requested password and the cache is likely to be stale now or in the very near future. Your application should wait and retry. Do not use the cached password unless it is critical that execution proceed. |
50364474 | Error calling KMKeyGetByAccount on the API Service. The API Service returned 58 (ERR_PASSWORD_CHANGE_IMMINENT). A cached password was not retrieved. | The Bravura Privilege server is currently in the process of changing the requested password and the cache has expired. Your application must wait and retry. |
61898752 | Error calling the API Service. There was an error attempting to send the SOAP request. A cached password was not retrieved. | Typically this error is caused by a network problem; for example, if |
33579008 | Failed to decrypt a password in the creds file. A cached password was not retrieved. | This error can be caused by changes in the composite key, or tampering of the creds file. |
-2098167805 | Error logging in to the API Service. The API Service returned error code 3 (ERR_NOT_LOGGED_IN). A cached password was retrieved. | The API user credentials were successfully decrypted (or were not encrypted) but were rejected by the API Service. If the password in the creds file has not recently changed, immediate action should be taken. This error may mean that your API account has been compromised. |
49315843 | Error logging in to the API Service. The API Service returned error code 3 (ERR_NOT_LOGGED_IN). A cached password was not retrieved. | The API user credentials were successfully decrypted (or were not encrypted) but were rejected by the API Service. If this instance of |
39874560 | Retry limit exceeded when trying to lock the lock file. A cached password was not retrieved. | This error may occur when multiple |
-2107609088 | Retry limit exceeded when trying to lock the lock file. A cached password was retrieved. | Same as above. |
72384698 | Error calling ManagedAccountOverridePassword on the IDAPI service. The API Service returned 186 (ERR_PASSWORD_FAILED_STRENGTH_CHECK) | The password the user specified did not meet the complexity requirements for this account and was rejected. |
Functions
GetPamUtilConfig
To obtain information from the configuration file.
int GetPamUtilConfig( const char* cfgFilePath,
struct PamUtilConfig** config
);where:
cfgFilePath [in]: File name to open and read configuration settings from
config [out]: Pointer to a pointer that will point to the allocated PamUtilConfig struct
This function parses the configuration file and returns its content in a PamUtilConfig struct. The struct is allocated so you must call FreePamUtilConfig when you have finished with struct.
FreePamUtilConfig
Clear the struct allocated by GetPamUtilConfig.
int FreePamUtilConfig( struct PamUtilConfig* config);
where:
config [in]: Pointer that was allocated by GetPamUtilConfig
GetPassword
To obtain a password from the cache and/or web service, with full locking, caching and OTP management semantics:
int GetPassword( const char* cfgFilePath,
char* errmsg,
unsigned int errmsg_bufsz,
int expirecache,
const char* resourceId,
const char* accountId,
int argc,
char** argv,
const char* userkey,
char* password,
unsigned int password_bufsz
);where:
cfgFilePath [in]: File name to open and read configuration settings from
errmsg [out]: Pointer to a buffer to place an error message in
errmsg_bufsz [in]: Size of the errmsg buffer
expirecache [in]: Whether to treat the cache as expired and force a fetch of the password
resourceId [in]: Name of the managed system to retrieve a password for
accountId [in]: Name of the account to retrieve a password for
argc [in]: The number of elements in argv. Ignored if useargskey=0
argv [in]: An array of null-terminated strings which will be incorporated into the encryption key. Ignored if useargskey=0
userkey [in]: An unencrypted null-terminated string to add to the encryption key
password [out]: Pointer to a buffer to place the retrieved password in
password_bufsz [in]: Size of the password buffer
Bravura Security recommends that you always place command-line arguments for programs using the pamutil shared library in the argc and argv parameters, even if you don’t intend to use them. If useargskey is unset in config.ini, the library will ignore these parameters. You can subsequently enable the useargskey option without needing to recompile the program.
RandomizePassword
To set the password of an account to a random value.
int RandomizePassword( const char* cfgFilePath,
char* errmsg,
unsigned int errmsg_size,
const char* resourceId,
const char* accountId,
int argc,
char** argv,
const char* userkey
);where:
cfgFilePath [in]: File name to open and read configuration settings from
errmsg [out]: Pointer to a buffer to place an error message in
errmsg_bufsz [in]: Size of the errmsg buffer
resourceId [in]: Name of the managed system to retrieve a password for
accountId [in]: Name of the account to retrieve a password for
argc [in]: The number of elements in argv. Ignored if useargskey=0
argv [in]: An array of null-terminated strings which will be incorporated into the encryption key. Ignored if useargskey=0
userkey [in]: An unencrypted null-terminated string to add to the encryption key
Bravura Security recommends that you always place command-line arguments for programs using the pamutil shared library in the argc and argv parameters, even if you don’t intend to use them. If useargskey is unset in config.ini, the library will ignore these parameters. You can subsequently enable the useargskey option without needing to recompile the program.
OverridePassword
To set the password of an account to a specified value.
int OverridePassword( const char* cfgFilePath,
char* errmsg,
unsigned int errmsg_size,
const char* resourceId,
const char* accountId,
const char* overridenPassword,
int argc,
char** argv,
const char* userkey
);where:
cfgFilePath [in]: File name to open and read configuration settings from
errmsg [out]: Pointer to a buffer to place an error message in
errmsg_bufsz [in]: Size of the errmsg buffer
resourceId [in]: Name of the managed system to retrieve a password for
accountId [in]: Name of the account to retrieve a password for
overridenPassword [in]: The specified value to set the password as
argc [in]: The number of elements in argv. Ignored if useargskey=0
argv [in]: An array of null-terminated strings which will be incorporated into the encryption key. Ignored if useargskey=0
userkey [in]: An unencrypted null-terminated string to add to the encryption key
Bravura Security recommends that you always place command-line arguments for programs using the pamutil shared library in the argc and argv parameters, even if you don’t intend to use them. If useargskey is unset in config.ini, the library will ignore these parameters. You can subsequently enable the useargskey option without needing to recompile the program.
SetInitialPasswords
To set initial passwords as encrypted in the creds.ini file.
int SetInitialPasswords( const char* cfgFilePath,-
const char* userkey,
const char* adminid,
const char* adminpw,
const char* proxyid,
const char* proxypw,
int argc,
char** argv,
char* errmsg,
unsigned int errmsg_bufsz
);where:
cfgFilePath [in]: File name to open and read config settings from
userkey [in]: An unencrypted null-terminated string to add to the encryption key
adminid [in]: An unencrypted null-terminated string to set the __OTP__ credential ID to
adminpw [in]: An unencrypted null-terminated string to set the __OTP__ credential password to
proxyid [in]: An unencrypted null-terminated string to set the __PROXY__ credential ID
proxypw [in]: An unencrypted null-terminated string to set the __PROXY__ credential password to
argc [in]: The number of elements in argv. Ignored if useargskey=0
argv [in]: An array of null-terminated strings which will be incorporated into the encryption key. Ignored if useargskey=0
errmsg [out]: Pointer to a buffer to place an error message in
errmsg_bufsz [in]: Size of the errmsg buffer
GetErrorMessage
To obtain a complete error message from a pamutil return code, including whether the password was cached and the IDAPI error number:
int GetErrorMessage( int error,
char* output,
unsigned int outputlen
);where:
error [in]: The error returned by
pamutiloutput [out]: Pointer to a buffer to place the error message in
outputlen [in]: Size of the error message buffer
Returns a pamutil error code with only specific and general fields set.
GetSpecificErrorMessage
To obtain the specific error message from a pamutil return code:
const char* GetSpecificErrorMessage( int error);
where:
error [in]: The error returned by
pamutil
Returns a pointer to the error message associated with the specific field of error (ignoring all other fields), or null if there is no message associated with that code.
GetGeneralErrorMessage
To obtain a general error message from a pamutil return code:
const char* GetGeneralErrorMessage( int error);
where:
error [in]: The error returned by
pamutil
Returns a pointer to the error message associated with the general field of error (ignoring all other fields), or null if there is no message associated with that code.
You do not need to free the returned string from either GetSpecificErrorMessage or GetGeneralErrorMessage.
The error messages returned by GetGeneralErrorMessage and GetSpecificErrorMessage are the same as those used by GetErrorMessage, except it dynamically creates an error message using every field of the error code, thus requires an output buffer to be allocated by the caller and may fail if this buffer is not large enough. You can use GetSpecificErrorMessage to determine why GetErrorMessage failed. A common error is "53547008: insufficient output buffer size".
Disabling caching
It is possible to fetch a password from the API or command-line and find that it did not work – perhaps the password was (incorrectly) cached, and you need to fetch a new one from the API, skipping the cache.
To force the password to come from the Bravura Privilege web services API and not from the local cache, set expirecache to 1 if using the API or use the -expirecache argument to runwithpass.
In this case, the cache will still be written to.
Returning invalid cache contents
If either the library or program attempts to contact the web service, but it is unreachable, they will still return cached material if it is available, along with an error message. This is intended to improve service availability, even in cases where Bravura Privilege is unreachable.
Using useargskey to tie API account, managed account, and command together
Enabling useargskey in the config.ini file provides higher security by tying one Bravura Privilege API account, one managed account, and one command together. By default, this key is set to 1. When enabled, the command line to runwithpass is included in the encryption key, preventing it from being used to run any other program. Ensure that you give an absolute path to runwithpass , so the command lines are consistent between runs.
Some command line arguments are excluded from the encryption key. This includes -v , -expirecache, and -initial.
If the useargskey key is set and creds.ini is to be shared between runwithpass and a program using the dynamic library:
Set the
argvargument to an array of strings where each string is one argument passed torunwithpass, including the command used to runrunwithpass.Set
argcto the size of the array.Set userkey to NULL.
For example:
argv = {"C:\runwithpass.exe", "-conf", "config.ini", "-res", "SSH",
"-acct", "psadmin"}
argc = 7