Accessing the IDVAULT with LotusScript

NotesIdVault and NotesUserId are new classes as of IBM Notes 9.0.1 FP9. These classes provide a representation of the secure storage facility for UserIDs that may be configured for Domino by policy.

The classes are also available in Java and JavaScript.

This sound promising. As a developer you are now able to access the IDVAULT programmatically, get and put UserIds, resetPassword, mark an ID as active or inactive and force a resync if an ID becomes corrupt for some reason.

Well, this is what I thought when I first read about the new classes.

Let us take a closer look at some methods.

When you look at the list of methods in the NotesIDVault class, you can easily see that a couple of methods are not available.

  • ExtractIdFile
  • MarkIdActive
  • MarkIdInactive

I have tested other methods, and all of them do what they are supposed to do. Except GetUserId.

GetUserId returns an NotesUserID. This might not be too bad, because this is exactly what we want to get when calling this method. But, if you expect to be able to download the id file to the local file system, you’ll be disappointed.

The documentation says

This object is primarily used to obtain the names of the private encryption keys which are available for use within the UserID object.

Frankly said, completely useless.

You could get the attached user.id with traditional Lotsuscript ( locate the document, detach the embedded object ), but I would expect this as a method in either the NotesIDVault or NotesUserId class.  Once again, half backed stuff. I hope that the guys and gals at HCL are more open for enhancement requests than IBM was.

UPDATE: There IS actually a method in the NotesIDVault class to detach the user.id from the vault document to the local file system!

At the bottom of this article you find an updated version of my IDVAULT class the extends the NotesIdVault class and lets you extract an id file.

A couple of years ago, I wrote my own IDVault class in Lotusscript. It uses LS2CAPI functions that let you do more than the provided LS classes.

The class provides methods to

  • IdFileGet()
  • IdFilePut()
  • IdFileExtract()
  • ResetPassword()
  • MarkActive()
  • MarkInactive()

IdFileGet() lets you download the user.id file from the vault document to the local file system. Much better than the method from the LS class, isn’t it.

IdFileExtract() lets you get the user.id from the vault document to the local file system WITHOUT knowing the password. It uses the ResetPassword method to apply a new password to the user.id and some “magic” to llet the original vault document remain unchanged.

The magic behind this is that you must make a copy of the vault document prior to resetting the password. The copy MUST be stored in another  database. After you have downloaded the ID with IDFileGet(), you must replace the vault document with the copy.

Here is a sample agent ( the agent signer must be a password reset authority in the IDVault )

%REM
	Agent test
	Created Sep 18, 2015 by Ulrich Krause/singultus
%END REM

Option Declare
Use "IDVault"

Sub Initialize
	Dim idv_db As NotesIdVaultDb
	Dim bck_db As NotesIdVaultDb
	Dim vaultServer As String
	Dim vaultDb As String
	Dim vaultDb_backup As String
	
	vaultServer = "develop1/gotham"
	vaultDb = "IBM_ID_VAULT\batcave.nsf"
	vaultDb_backup =  "IBM_ID_VAULT\batcave_bck.nsf"
	
	Dim idv_doc As NotesIdVaultDocument

	Set idv_db = New NotesIdVaultDb(vaultServer, vaultDb)
	
	If ( idv_db.IsConnected() ) then
		Set idv_doc = New NotesIdVaultDocument(idv_db.db,nothing)
		Set bck_db = New NotesIdVaultDb(vaultServer, vaultDb_backup)
		
		If ( bck_db.IsConnected() ) Then
			Set idv_doc = New NotesIdVaultDocument(idv_db.db, bck_db.db)
		Else
			Set idv_doc = New NotesIdVaultDocument(idv_db.db, Nothing)
		End If
		
		idv_doc.ServerName = vaultServer
		idv_doc.UserName = "cn=Harvey Dent/o=gotham"
		idv_doc.Password = "hdent001"
		idv_doc.IdFilePathName = "C:\Notes\Data\ids\people\backup\hdent_with_new_pwd.id"
		'Call idv_doc.ResetPassword()
		'Call idv_doc.IdFileGet()
		'Call idv_doc.IdFilePut()
		Call idv_doc.IdFileExtract()
		'Call idv_doc.markInactive()
		'Call idv_doc.markActive()
		MsgBox idv_doc.LastErrorString

	End if
	
End Sub

Here is the updated version. This version is also platform independend