Skip to main content

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

Table 1. Return code fields

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 (idapi).



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
Table 2. General 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



Table 3. Specific error codes

#

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:

Table 4. Return codes

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 pamutil cannot resolve the hostname provided in config.ini , if the curl library could not be loaded on systems running psunix , or if the API Service’s SSL certificate was rejected.

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 pamutil has never successfully logged in, it is likely that the password was mistranscribed into the creds file. If this instance of pamutil was previously working immediate action should be taken. This error may mean that your API account has been compromised.

39874560

Retry limit exceeded when trying to lock the lock file. A cached password was not retrieved.

This error may occur when multiple pamutil instances are sharing the same config. It may be indicative of another pamutil instance misbehaving and starving other instances. If your application encounters this error occasionally, it is safe to retry. If it happens frequently, you may want to investigate what is locking the lockfile for long periods of time, or increase the locktries or locksleep values in the config file.

-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 pamutil

  • output [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".