Reg Exp
Web Design
Notes Client
Is Database Encrypted
A customer of ours has an application that involves attaching Notes databases and templates to documents for various purposes. Well, it finally happened. Someone had locally encrypted the database and attached it to the document. So nobody (except that one person) could use the attachment. So we were asked to check to see if the database/template was encrypted before the attachment was allowed to happen. This can be done through the Notes API.

Just like many of our other API tips, we'll need to get the path to the database, open the database, check the values (the encryption setting), and close the database all through API calls. The definitions for the API calls are placed in the (Declarations) section of the script library:

Declare Function W32_OSPathNetConstruct Lib "nnotes.dll" Alias "OSPathNetConstruct" _
(Byval portName As Integer, Byval serverName As String, Byval fileName As String, _
Byval pathName As String) As Integer
Declare Function W32_NSFDbOpen Lib "nnotes.dll" Alias "NSFDbOpen" _
(Byval dbName As String, hDb As Long) As Integer
Declare Function W32_NSFDbIsLocallyEncrypted Lib "nnotes.dll" _
Alias "NSFDbIsLocallyEncrypted" (Byval hDb As Long, retVal As Integer) As Integer
Declare Function W32_NSFDbClose Lib "nnotes.dll" Alias "NSFDbClose" _
(Byval hDb As Long) As Integer

The API documentation is where you will want to go to learn more about these calls and what all the parameters mean.

The function is really pretty basic. It just provides an interface into the API calls. I'll go over it in pieces, however.

Function IsDbEncrypted(source As NotesDatabase) As Integer
   On Error Goto BubbleError
   Dim fullPath As String*256
   Dim hDb As Long
   Dim status As Integer
   Dim isEncrypted As Integer

This part simply defines the variables that will be needed in the function, and sets up our standard error trapping.

   If source Is Nothing Then
      IsDbEncrypted = False
      Exit Function   ' ============
   End If

A simple validation check is made to make sure that an actual database or template has been passed in to the function. If Nothing has been passed in, then return an indicator saying the "database" is not encrypted.

   Call W32_OSPathNetConstruct(0, source.Server, source.FilePath, fullPath)
   status = W32_NSFDbOpen(fullPath, hDb)
   If status <> 0 Then
      IsDbEncrypted = False
      Exit Function   ' ============
   End If

The path to the database is computed, then the database is opened with the API. Note that the database most likely will be local when you are performing this kind of a check, but I guess there's nothing stopping you from encrypting a server database and using this code to check to see if the server database is encrypted or not. So that's why I used OSPathNetConstruct to compute the path instead of making any assumptions.

   status = W32_NSFDbIsLocallyEncrypted(hDb, isEncrypted)
   If status <> 0 Then
      IsDbEncrypted = False
   Elseif isEncrypted = 0 Then
      IsDbEncrypted = False
   Else   ' isEncrypted = 1
      IsDbEncrypted = True
   End If

Here, the database or template is checked for encryption using the API. If this results in an error (status not equal to zero) then FALSE will be returned (the database is not encrypted). The isEncrypted variable will be either 0 or 1 if the API call was a success. 0 means the database/template is not encrypted, and 1 means it is encrypted. Set the appropriate function return value, based on the results of the successful API call.

   status = W32_NSFDbClose(hDb)
   Exit Function
   Error Err, Error$ & Chr$(10) & " in procedure " & Getthreadinfo(1) & ", line " & Cstr(Erl)
End Function

Finally, close the database through the API. The return value was set above, so we can simply exit the function. At the bottom of the function is our standard error trapping code which bubbles any error back to the calling routing for additional handling.

The script library is pretty easy to test. Just locally encrypt one of your databases (don't do names.nsf or bookmark.nsf or other core databases). In the test agent, get a handle to the encrypted database, pass it to the function, and make sure that TRUE is returned. Note that if the database/template is locally encrypted with someone else's ID, you won't have access to the database/template, so you won't be able to create a handle through LotusScript, so you won't have anything to pass into this function.