HCL Domino 12 – Active Directory Password Sync (part 2)

During my tests with HCL Domino 12 Beta2 I ran into a couple of issues where the Active Directory Password Sync did not work as expected. The problems are not caused by the beta code. However, I am writing down my observations here, since the errors may also appear later in a productive environment. Maybe my lines will save one or the other a long search.

Request Creator replicates with multiple servers

In the console log of a request creator you see replcation events with multiple servers.

There are 2 databases that are replicated on the request creator, Domino Directory (names.nsf) and Directory Assistance (da.nsf). Both databases are replicated with their admin servers to start every config update cycle. Important to know is that the admin server for each database is determined seperately separately. In my test environment, the admin server for da.nsf was different than the one for names.nsf resulting in multiple replication events.

Wrong configuration document

If you have more than 1 Domain Controller that syncs users passwords with your Domino environment, you must install and configure a request creator on each Domain Controller. In addition, you need a configuration document for each of your request creators. Each request creator should have the same configuration settings. Best practice would therefore be a single configuration document that applies to a group of servers.

During my tests I could observe that instead of the assigned configuration document the default configuration document was used.

There was no Statistics output in the console log and I could also not see any DEBUG log output. Also the configuration was not refreshed in the configured interval. I discussed this with HCL Development and it turnd out that the configuration document was not used due to a problem with the view index in names.nsf on the request creator.

I needed to stop the sync process on the request creator, open names.nsf in the Notes Client. After restarting the AD Domain Controller machine, the correct configuration document was used.

Most likely, this issue occurs when you use a configuration document for a single request creator and later switch to a group based configuration document. I would suggest to use a group based configuration document from the start on.

Is Active Directory Password Sync cluster ready?

You can designate as many request processors as you want, and it’s a good way to provide failover.

The decision as to where the AD Domain Controller sends a request is admittedly not overly sophisticated. It works sequentially through an in-memory list it holds of all servers which are designated as request processors, until it finds an available one. Have a look at the ($PWSProcessors) view in the directory. (Mark De Lellis, HCL Development)

This is where the list is built from, using all servers with Role “2” (Request Processor), in the order they appear in the view.


REPL_CURRENCY_EXCLUDE_DBS

The notes.ini parameter was added in 11.0.1FP2 (SPR# BSPRBSSPWH) to suppress output of Replication Currency alerts for specific databases that were intentionally marked as “replication disabled”. 

I used it in my environment for all databases in DominoDataDir/traveler/map. After upgrading to FP3 a couple of days ago, this parameter seemed not to work any longer. On the console I saw the following output

[2D58:0005-2910] ReplCurrency Source="traveler\map\custom\MapDir.nsf", Dest=CN=serv02/O=singultus (Q:0) traveler\map\custom\MapDir.nsf, UpdateToRepl2="03.04.2021 01:01:06", LastRepl="02.04.2020 04:01:25", TimeDiff= 16167 min, TimeDiff2=543026 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\iNotesPMap.nsf", Dest=CN=serv02/O=singultus (Q:1) traveler\map\iNotesPMap.nsf, UpdateToRepl2="10.04.2021 01:00:27", LastRepl="01.04.2020 15:26:41", TimeDiff= 6087 min, TimeDiff2=543781 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\JournalEntryMap.nsf", Dest=CN=serv02/O=singultus (Q:3) traveler\map\JournalEntryMap.nsf, UpdateToRepl2="10.04.2021 01:00:38", LastRepl="01.04.2020 15:26:41", TimeDiff= 6087 min, TimeDiff2=543781 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\MemoMap.nsf", Dest=CN=serv02/O=singultus (Q:3) traveler\map\MemoMap.nsf, UpdateToRepl2="10.04.2021 01:00:45", LastRepl="01.04.2020 15:26:41", TimeDiff= 6087 min, TimeDiff2=543781 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\PersonMap.nsf", Dest=CN=serv02/O=singultus (Q:1) traveler\map\PersonMap.nsf, UpdateToRepl2="10.04.2021 01:00:51", LastRepl="01.04.2020 15:26:41", TimeDiff= 6087 min, TimeDiff2=543781 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\R6JournalEntryMap.nsf", Dest=CN=serv02/O=singultus (Q:2) traveler\map\R6JournalEntryMap.nsf, UpdateToRepl2="03.04.2021 01:01:20", LastRepl="02.04.2020 04:01:51", TimeDiff= 16166 min, TimeDiff2=543026 min Warning="5000+ mins on replication."
 [2D58:0005-2910] ReplCurrency Source="traveler\map\R6PersonMap.nsf", Dest=CN=serv02/O=singultus (Q:1) traveler\map\R6PersonMap.nsf, UpdateToRepl2="10.04.2021 01:00:57", LastRepl="01.04.2020 15:26:42", TimeDiff= 6087 min, TimeDiff2=543781 min Warning="5000+ mins on replication."

I opened a support case with HCL. Here is the answer

In FP2 there was a bug where it excluded all except the first entry in the INI. The notes.ini does not allow directories to be listed, only databases. In your case, it appeared to work in FP2 because it blocked all databases except for “traveler/map” which is not a database. So, it blocked all databases from currency checks.
And, this is now fixed in 1101FP3 (SPR # BSPRBY9RPA).


The upcoming FP4 and V12 will not list replication disabled databases in the currency alerts (so no notes.ini is required to exclude databases disabled for replication). The notes.ini is still in FP4 and V12, but the need to exclude replication disabled databases is no longer necessary.

So, here, you need to add individual NSF names as comma separated list of dbs in the INI entry to exclude them from the replication currency check.


HCL Domino 12 – Active Directory Password Sync

Active Directory Password Sync applies the Windows passwords of users registered in an Active Directory domain to their Domino HTTP and/or Notes ID passwords.

Password synchronization is supported for

  • Registered HCL Notes, HCL Nomad, HCL Verse, and HCL iNotes users accessing Domino servers with HTTP passwords or Notes IDs.
  • HCL Traveler users accessing their mail through the web browser on their mobile devices.
  • Web users who are not registered in Domino but who have Person documents in the Domino directory accessing Domino web applications with HTTP passwords.

To setup and configure Active Directory Password Sync, you need at least 2 Domino v12 servers. One server acts as Request Creator and the other one has the role Request Processor.

On the “Active Directory Password Sync” tab of the configuration document for each of the servers you can configure which password changes should be processed. The refresh interval specifes the amount of times in minutes after a request is created to allow the request to be processed.

To sync passwords to Notes IDs, the Request Processor servers require password reset authority to the ID vault. I you miss this configuration step, you’ll see an error message on the console of the Request Processor:

[1DFC:0059-1694] 07.04.2021 10:13:23,00 AD Password Sync> PWSyncProcessStoredRequests: Failed to update password in Notes ID for CN=Herbert Feuerstein/O=singultus: Agent containing ResetUserPassword method must be signed by a designated Password Resetter.
[1DFC:0059-1694] 07.04.2021 10:13:23   Password Sync: Active Directory Password Sync failed for objectGUID 6630b191119c8b45b78b77865a37cc70: Agent containing ResetUserPassword method must be signed by a designated Password Resetter.

Request Creator must be installed on the AD Domain Controller. The install type is “Utility Server”. The server must be configured but will never run as a service.

After you have successfully configured the Request Creator, The installer will remove some of the Domino server executables

[0C14:0002-1284] Deleted Executable File 'C:\Domino\nserver.exe' for security reasons.
[0C14:0002-1284] Deleted Executable File 'C:\Domino\nhttp.exe' for security reasons.
[0C14:0002-1284] Deleted Executable File 'C:\Domino\nldap.exe' for security reasons.
[0C14:0002-1284] Deleted Executable File 'C:\Domino\nsmtp.exe' for security reasons.
[0C14:0002-1284] Deleted Executable File 'C:\Domino\npop3.exe' for security reasons.
[0C14:0002-1284] Deleted Executable File 'C:\Domino\nimap.exe' for security reasons.

The installer finally adds the Domino password library “npwsync.dll” to the Windows registry. The entry can be found here

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages

For security reason, the server id that is used for the Request Creator is encrypted during the installation and configuration process. Make sure that the id does not have a password on it. The secured id cannot be used on any other machine than the Request Creator.

A new application is created on the Request Processor. The application stores the requests that are created by the Request Creator. After a request has been successfully processed, the document is removed from the database.

Most of the items in the document are encrypted.

After you have setup and configured Request Creator and Request Processor, you should restart both machines (OS level).

When a user now updates his / her password, LSA processed the change thru the Domino password library, and a new document is created in the Active Directory Password Sync application. The Request Processor reads new documents from the application and processes them according to its configuration.

Here is an example of what you see on the Request Processor console

[0BD4:0002-1C70] Authenticate {19EC003F}: CN=serv01/O=singultus
[0BD4:0002-1C70]             T:RC2:128 E:0:  P:c:  S:RC2:0 A:2:0 L:N:N:N FS: 
[0BD4:0002-1C70] 07.04.2021 10:22:28   Starting replication with server serv01/singultus
[0BD4:0002-1C70] Authenticate {19EC0040}: CN=serv01/O=singultus
[0BD4:0002-1C70]             T:RC2:128 E:0:  P:c:  S:RC2:0 A:2:0 L:N:N:N FS: 
[0BD4:0002-1C70] 07.04.2021 10:22:28   Pulling names.nsf from serv01/singultus names.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Replicator added 1 document(s) to names.nsf from serv01/singultus names.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Replicator updated 2 document(s) in names.nsf from serv01/singultus names.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Pulling ddm.nsf from serv01/singultus ddm.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Pushing ddm.nsf to serv01/singultus ddm.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Pulling products\traveler\traveler-rules.nsf from serv01/singultus products\traveler\traveler-rules.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Replicator updated 10 document(s) in products\traveler\traveler-rules.nsf from serv01/singultus products\traveler\traveler-rules.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Pushing products\traveler\traveler-rules.nsf to serv01/singultus products\traveler\traveler-rules.nsf
[0BD4:0002-1C70] 07.04.2021 10:22:28   Finished replication with server serv01/singultus
[1DFC:0059-1694] Authenticate {19EC0041}: CN=serv04/O=singultus
[1DFC:0059-1694]             T:AES:128 E:1:  P:c:e S:AES-GCM:128 A:2:1 L:N:N:N FS:DHE-2048+X25519
[1DFC:0061-1234] Authenticate {19EC003E}: CN=serv04/O=singultus
[1DFC:0061-1234]             T:AES:128 E:1:  P:t:e S:AES-GCM:128 A:2:1 L:N:N:N FS:DHE-2048+X25519
[1DFC:0061-1234] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: IDVOpenVault: No error
[1DFC:0061-1234] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: IDVOpenNoteFromView: No error
[1DFC:0061-1234] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: Exiting: No error
[1DFC:0059-1694] ----- Trust cert lookup Subject: CN=serv03/O=singultus; Issuer: CN=Herbert Feuerstein/O=singultus, OrgCombo: O=singultus:PR:O=singultus
[1DFC:0059-1694] >> Matched Trust Certificate IssuedBy CN=Ulrich Krause/O=singultus, IssuedTo O=singultus, NoteId 8010
[1DFC:0059-1694] >> Matched Trust Certificate IssuedBy CN=serv04/O=singultus, IssuedTo O=singultus, NoteId 17150
[1DFC:0059-1694] >> Matched Trust Certificate IssuedBy CN=serv03/O=singultus, IssuedTo O=singultus, NoteId 19490
[1DFC:0059-1694] >> Matched Trust Certificate IssuedBy CN=serv02/O=singultus, IssuedTo O=singultus, NoteId 17146
[1DFC:0059-1694] >> Matched Trust Certificate IssuedBy CN=serv01/O=singultus, IssuedTo O=singultus, NoteId 3742
[1DFC:0061-1BE8] Authenticate {19EC0042}: CN=serv04/O=singultus
[1DFC:0061-1BE8]             T:AES:128 E:1:  P:t:e S:AES-GCM:128 A:2:1 L:N:N:N FS:DHE-2048+X25519
[1DFC:0059-1694] Authenticate {19EC0043}: CN=serv04/O=singultus
[1DFC:0059-1694]             T:AES:128 E:1:  P:c:e S:AES-GCM:128 A:2:1 L:N:N:N FS:DHE-2048+X25519
[1DFC:0061-11A0] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: IDVOpenVault: No error
[1DFC:0061-11A0] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: IDVOpenNoteFromView: No error
[1DFC:0061-11A0] 07.04.2021 10:23:23 IDVAULT: idvdb.c IDVFindIDInVault: Exiting: No error
[1DFC:0061-11A0] ----- Trust cert lookup Subject: CN=serv04/O=singultus; Issuer: CN=Herbert Feuerstein/O=singultus, OrgCombo: O=singultus:PR:O=singultus
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy CN=Ulrich Krause/O=singultus, IssuedTo O=singultus, NoteId 8010
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy CN=serv04/O=singultus, IssuedTo O=singultus, NoteId 17150
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy CN=serv03/O=singultus, IssuedTo O=singultus, NoteId 19490
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy CN=serv02/O=singultus, IssuedTo O=singultus, NoteId 17146
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy CN=serv01/O=singultus, IssuedTo O=singultus, NoteId 3742
[1DFC:0061-11A0] ----- Trust cert lookup Subject: O=IDVAULT; Issuer: CN=Herbert Feuerstein/O=singultus, OrgCombo: O=singultus:VT:O=IDVAULT
[1DFC:0061-11A0] >> Matched Trust Certificate IssuedBy O=IDVAULT, IssuedTo O=singultus, NoteId 17142
[1DFC:0061-11A0] -------- IDVValidateVTIssuer: PWD Resetter CN=serv04/O=singultus
[1DFC:0061-11A0] -------- PWD Resetter CN=serv04/O=singultus, Vault trust issuer O=singultus, need cross cert? 0
[1DFC:0061-11A0] ------- vault trust xcert PubKeySize	294
[1DFC:0061-11A0] ------- vault trust xcert SubjectNameDesc O=IDVAULT
[1DFC:0061-11A0] ------- vault trust xcert IssuerNameDesc	O=singultus
[1DFC:0061-11A0] ------- vault trust xcert ExpTimeDesc 13.03.2046 06:54:57
[1DFC:0061-11A0] ------- Vault VO cert PubKeySize	294
[1DFC:0061-11A0] ------- Vault VO cert SubjectNameDesc CN=VO-lrxr-oidv/OU=serv01/O=IDVAULT
[1DFC:0061-11A0] ------- Vault VO cert IssuerNameDesc	CN=serv01/O=singultus
[1DFC:0061-11A0] ------- Vault VO cert ExpTimeDesc 
[1DFC:0061-11A0] ------- Vault chain cert PubKeySize	294
[1DFC:0061-11A0] ------- Vault chain cert SubjectNameDesc O=IDVAULT
[1DFC:0061-11A0] ------- Vault chain cert IssuerNameDesc	O=IDVAULT
[1DFC:0061-11A0] ------- Vault chain cert ExpTimeDesc 13.03.2101 06:54:29
[1DFC:0061-11A0] ------- Vault chain cert PubKeySize	162
[1DFC:0061-11A0] ------- Vault chain cert SubjectNameDesc CN=serv01/O=singultus
[1DFC:0061-11A0] ------- Vault chain cert IssuerNameDesc	O=IDVAULT
[1DFC:0061-11A0] ------- Vault chain cert ExpTimeDesc 13.03.2121 06:54:29
[1DFC:0061-11A0] ------ Cert subject CN=serv01/O=singultus (=CN=serv01/O=singultus),	VO Cert	issuer CN=serv01/O=singultus
[1DFC:0059-1694] ------- vault trust xcert PubKeySize	294
[1DFC:0059-1694] ------- vault trust xcert SubjectNameDesc O=IDVAULT
[1DFC:0059-1694] ------- vault trust xcert IssuerNameDesc	O=singultus
[1DFC:0059-1694] ------- vault trust xcert ExpTimeDesc 13.03.2046 06:54:57
[1DFC:0059-1694] ------- Vault VO cert PubKeySize	294
[1DFC:0059-1694] ------- Vault VO cert SubjectNameDesc CN=VO-lrxr-oidv/OU=serv01/O=IDVAULT
[1DFC:0059-1694] ------- Vault VO cert IssuerNameDesc	CN=serv01/O=singultus
[1DFC:0059-1694] ------- Vault VO cert ExpTimeDesc 
[1DFC:0059-1694] ------- Vault chain cert PubKeySize	294
[1DFC:0059-1694] ------- Vault chain cert SubjectNameDesc O=IDVAULT
[1DFC:0059-1694] ------- Vault chain cert IssuerNameDesc	O=IDVAULT
[1DFC:0059-1694] ------- Vault chain cert ExpTimeDesc 13.03.2101 06:54:29
[1DFC:0059-1694] ------- Vault chain cert PubKeySize	162
[1DFC:0059-1694] ------- Vault chain cert SubjectNameDesc CN=serv01/O=singultus
[1DFC:0059-1694] ------- Vault chain cert IssuerNameDesc	O=IDVAULT
[1DFC:0059-1694] ------- Vault chain cert ExpTimeDesc 13.03.2121 06:54:29
[1DFC:0059-1694] ------ Cert subject CN=serv01/O=singultus (=CN=serv01/O=singultus),	VO Cert	issuer CN=serv01/O=singultus
[1DFC:0059-1694] -------- IDVValidateVTIssuer: PWD Resetter CN=serv04/O=singultus
[1DFC:0059-1694] -------- PWD Resetter CN=serv04/O=singultus, Vault trust issuer O=singultus, need cross cert? 0
[1DFC:0062-0BCC] Authenticate {19EC0045}: CN=serv01/O=singultus
[1DFC:0062-0BCC]             T:RC2:128 E:0:  P:c:  S:RC2:0 A:2:0 L:N:N:N FS: 
[1DFC:0062-0BCC] 07.04.2021 10:23:26   Starting replication with server serv01/singultus
[1DFC:0062-0BCC] 07.04.2021 10:23:26   Pushing C:\Domino\data\IBM_ID_VAULT\IDVAULT.nsf to serv01/singultus IBM_ID_VAULT\IDVAULT.nsf
[1DFC:0062-0BCC] Authenticate {19EC0046}: CN=serv02/O=singultus
[1DFC:0062-0BCC]             T:RC2:128 E:0:  P:c:  S:RC2:0 A:2:0 L:N:N:N FS: 
[1DFC:0062-0BCC] 07.04.2021 10:23:26   Replicator updated 1 document(s) in serv01/singultus IBM_ID_VAULT\IDVAULT.nsf from C:\Domino\data\IBM_ID_VAULT\IDVAULT.nsf
[1DFC:0062-0BCC] 07.04.2021 10:23:26   Finished replication with server serv01/singultus
[1DFC:0061-11A0] Authenticate {19EC0044}: CN=serv04/O=singultus
[1DFC:0061-11A0]             T:AES:128 E:0:  P:t:  S:RC2:0 A:2:0 L:N:N:N FS: 
[1DFC:0062-0BCC] Authenticate {19EC0047}: CN=serv04/O=singultus
[1DFC:0062-0BCC]             T:AES:128 E:0:  P:c:  S:RC2:0 A:2:0 L:N:N:N FS: 

Detailed information about installation and configuration can be found here https://help.hcltechsw.com/domino/12.0.0/admin/conf_adsync_password_sync.html


Java agents with imported .jar files

Many of us Notes developers know the problem. You have developed a Java agent that contains methods from imported .jar files in addition to the actual code.
When the agent is executed on a HCL Domino server, it works for a while ( sometimes longer, sometimes shorter ), but then causes problems due to memory leaks.
The problem lies in the architecture of Domino. The imported .jar files are reloaded every time the agent is started and over time they use more and more RAM.

The workaround was to dump the .jar files to the server’s file system. This works, but always causes problems where you as a developer do not always have access to the server.
Or there is already a .jar in the file directory; but not in the required version. Copying your own .jar into the file system can then lead to undesirable side effects.

I had therefore created a case at HCL to get a fix for the problem. The problem was tracked under SPR # BHUY8PRMKK. Yesterday I received an update from support:

The Product Development Team had developed a possible fix that mitigates the issue but the fix was of medium risk and it was decided not to submit the fix. As an alternative they have come up with a workaround. Set the following notes.ini, this will cache the agentloader objects and reuse them.

EnableJavaAgentCache=2

I have set the parameter on my test system. At the moment it looks like it solves the problem. I will continue testing.

Many thanks to HCL Development & HCL Support ( especially to Abhaysingh Shirke ).


Mailrules extended ( 2021 edition )

A few years ago, more precisely in 2008, I already wrote about an extension of the Rules Engine in Notes / Domino.

Although the existing programming covers a large part of users’ requirements, it would sometimes be desirable to be able to create more flexible rules.

If you look at how the rule created by the user is implemented internally, you will see that the rule is converted into an @formula.

So it is obvious to have a functionality that allows the direct input of a formula.

I have already posted ideas on the HCL portal (https://domino-ideas.hcltechsw.com/); these are also in “Likely to Implement” status.

Version 12 of Notes / Domino is currently in the beta phase. So I looked at programming in the Domino Directory template (pubnames.ntf). Unfortunately, at the moment it looks like the functionality is not yet implemented in V12.

If and when an implementation will take place; I have no information on that. Is that bad? No, I don’t think so.


The big advantage of Notes / Domino is that we can extend the functionality ourselves in many areas.
My extension of the rules from 2008 ran without change from version 8.5 to version 11.0.1FP2. I have looked at the current code of Beta2. This has changed only insignificantly. Therefore I have transferred my extensions into this code.

The changes concern 2 design elements.

Both design elements have no dependencies to other design elements.
Furthermore my function extensions are comprehensible for every average developer.

The “(RulesDlg)” form has been extended by a section that allows entering an @formula

The “condition” item was extended by the selection “@Formula

All changes in LotusScript library “Rules” are commented ‘Ulrich Krause, @Formula support. No change was made to the basic functionality.

The two design elements can be downloaded here.

To implement, simply replace the two design elements in the Domino Directory with the elements in the downloaded file.


DirSync fails to start if DIRSYNC_DEFAULT_ARGS is set to unsupported value

I came across a little something yesterday related to DirSync.

If you use a value in the notes.ini variable DIRSYNC_DEFAULT_ARGS that is not in the list of allowed values ( load dirsync -? ), then DirSync does not start anymore.
More precisely, Dirsync starts, and quits immediately.

No big deal, but for an admin it is certainly helpful if DirSync prints a message on the Domino console indicating that an incorrect value is used in the variable.

There is a SPR #SPPPBYJLZZ for this, but it doesn’t really have a high priority. Rather a nice to have.


“OneMK” – makefiles made easy.

HCL recently has released a new version of the C API Toolkit for Notes/Domino 11.0.1. I had already written about it here.

Thomas Hampel reported that there will also be another release of the toolkit after the release of version 12 of Notes / Domino. In this version the makefiles will be included again, which are missing in version 11.0.1.

Basically, there is nothing against using the makefiles from version 9.0.1. However, I think the makefiles are not very user-friendly, especially for beginners. In addition, a separate makefile with the platform-specific characteristics must be created for each platform.

There are a number of tools that do the manual assembly for you ( cmake, boost-build, automake etc ), but the tools themselves must be installed on each platform, and require a more or less extensive training in the handling.

I have worked with boost-build myself for a long time. To make it easier for beginners (and old hands) to work with makefiles, I started a small project over the turn of the year 2020 / 2021.

The goal is to create makefiles in a standardized way, and to be able to use one and the same makefile for the build of a project on different platforms. If possible, no additional software should be necessary.

The result is “OneMK“. The project consists of several files, which contain definitions for compiler and linker settings, and limit the configuration of a makefile to the absolutely necessary things.

Prerequisites

The project can be installed within an existing folder structure in the “makefiles” directory. Here is a screenshot of how I installed it.

Additionally an environment variable GIT_REPOSITORY is expected, which points to the root directory. (git)

If you are working on Linux, then you must also create a corresponding directory structure there and export the environment variable GIT_REPOSITORY accordingly.

The notesapi directory can contain one or more versions of the SDK.

There are several files in the makefiles directory.

  • common.notesapi.VERSION.mk contains the compiler and linker parameters necessary for the respective SDK version.
  • common.recipes.mk contains the “recipes” for the build of a project.

There are recipes for

  • clean – cleans the project directory and deletes .o and .pdb files of a previous build.
  • info – gives information about the source files and object files
  • make – the actual build process
  • install/ uninstall – installs or removes the generated binary file in a target directory to be specified

After “installing” “OneMK“, we can now start creating makefiles for our projects.

Simple example

Here is an example of what the makefile for an executable (application) looks like.

#### ######################################################### ####
# MAKEFILE FOR C/C++ PROJECT
# Author: Ulrich Krause
# Date:   2021/02/10
# sample makefile to build /notesapi/11.0.1/samples/basic/intro
#### ######################################################### ####
BASE_DIR = $(GIT_REPOSITORY)/
ifeq ($(BITNESS),)
BITNESS = 32
endif
TYPE = application
TARGET = intro
SUFFIX = c
#------------------------------------------------------------------
include $(BASE_DIR)makefiles/common.notesapi.11.0.1.mk
#------------------------------------------------------------------

SRCDIR =
INCLUDES = 

#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#
SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

#------------------------------------------------------------------
# Recipes (included from common.recipes.mk) 
#
include $(BASE_DIR)makefiles/common.recipes.mk
#------------------------------------------------------------------

Create a new file in the directory /notesapi/1101/samples/basic/intro/make.mk and copy the code into the file.
If the environment variable GIT_REPOSITORY is set, and the necessary files are in the previously described location, then you can start the build process with the following command in the directory /notesapi/1101/samples/basic/intro/.

This works on both Windows and Linux with the same makefile. You do not need to create separate makefiles for the different platforms. On Windows, make sure to open the appropriate command prompt for 32 or 64 bit.

make -f make.mk clean make 

will start the build process. you should see output similar to this on the console. For 32 Bit ( wich is the standard BITNESS in the makefile )

For 64Bit build, you can either set this as the default in your makefile or use

make -f make.mk clean make BITNESS=64

If you see WARNINGS during the build process, you can either fix them in your source code ( which is the preferred way to handle warnings and errors) or you can simply ignore them.

To suppress the console output, on Windows you can add #pragma statements into the pragma.h file in the makefiles folder. The file is a forced include and will be added to your project includes at build time.

If you want to install the builded binary, use

make -f make.mk clean make install INSTALLDIR=c:/notes

Keep in mind that INSTALLDIR is case-sensitive

You can use the exact same makefile also on Linux.

More complex example

Here is a more complex example for an extension manager ( shared dll / lib )

#### ######################################################### ####
# MAKEFILE FOR C/C++ PROJECT
# Author: Ulrich Krause
# Date:   2021/01/17
#### ######################################################### ####
BASE_DIR := $(GIT_REPOSITORY)/
ifeq ($(BITNESS),)
BITNESS = 64
endif
TYPE = shared
TARGET = secureid
SUFFIX = cpp
#------------------------------------------------------------------
include $(BASE_DIR)makefiles/common.notesapi.11.0.1.mk
#------------------------------------------------------------------
SRCDIR += src/

INCLUDES += inc
INCLUDES +=	$(BASE_DIR)hashlib/src
INCLUDES +=	$(BASE_DIR)undocumented

LDLIBS_ADDITIONAL_PATH += $(BASE_DIR)_static_libs

ifeq ($(DETECTED_OS),$(strip Windows))
LDLIBS += undocumented-w64.lib
LDLIBS += Iphlpapi.lib
LDLIBS += libhl++-64.lib
LDLIBS += /NODEFAULTLIB:libcmt
MDF := /DEF:secureid.def
WINVER = /DWINVER=0xA00 
else 
LDLIBS += -lhl++-64 
LDLIBS += -lstdc++fs
endif
LANGUAGE = c++17
#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#------------------------------------------------------------------

SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

#------------------------------------------------------------------
# Recipes (included from common.recipes.mk) 
include $(BASE_DIR)makefiles/common.recipes.mk
#------------------------------------------------------------------

If you need to exclude src files because the will not work on the target platform, you can do this

#------------------------------------------------------------------
# Create list of sourcefiles and calculate obj files accordingly
#------------------------------------------------------------------

SRCS := $(wildcard $(strip $(SRCDIR)*.$(SUFFIX)))
ifneq ($(DETECTED_OS),$(strip Windows))
SRCS:=$(subst src/windowsonly.cpp,,${SRCS})
endif
OBJS := $(SRCS:%.$(SUFFIX)=%.$(OBJ))

The windowsonly.cpp will be removed from the list of source files, if the DETECTED_OS is not “Windows”.

This is only a short introduction to OneMK. The content of the files is mostly self-explanatory ( or so I hope ). You should be able to create makefiles for your existing projects and build them successfully.

There is a lot room for improvements and I would be happy to get some feedback if you like the idea. And I also appreciate any help. I have tested OneMK with several of my projects, simple and complex. It should also work for you, but I do not guarantee it.


CAPI SDK 11.0.1 for HCL Notes / Domino released

HCL has released a new version of the CAPI SDK on Flexnet. The version number has increased from 9.0.1 to 11.0.1. Unfortunately, the changes are not documented. The “whats new” view only shows the changes in V9.0.1.

Therefore I did a comparison of the versions myself. Here is what I found.

Apart from many new constants and changes to existing constants ( IBM replaced by HCL ), version 11.0.1 offers hardly any new methods.

New methods:

adminp.h

STATUS LNPUBLIC ADMINReqDeleteInNABExt( DBHANDLE dbhAdmin4,
		char far *chAuthor,
		char far *chUserName,
		char far *chMailServerName,
		char far *chMailFileName,
		char far *chDeleteMailFile,
		char far *chIDVaultFlag,
		char far *chIDVaultName,
		ADMINReqParams far *arpAdminReqParamsPtr,
		WORD wAdminReqParamsSize);

STATUS LNPUBLIC ADMINReqDeleteInACLExt( DBHANDLE dbhAdmin4,
		char far *chAuthor,		    
        char far *chUserName,
		char far *chMailServerName,
		char far *chMailFileName,
		char far *chDeleteMailFile,
		char far *chIDVaultFlag,
		char far *chIDVaultName,
		ADMINReqParams far* arpAdminReqParamsPtr,
		WORD wAdminReqParamsSize);

misc.h

#ifdef IOS
        BOOL IOSGetAuthorizationStatus();
        STATUS IOSInitGPSCoordinates(long timeOutSeconds, BOOL highestAccuracy);
        double IOSGetGPSLatitude();
        double IOSGetGPSLongitude();
        double IOSGetGPSAltitude();
        double IOSGetGPSHorizontalAccuracy();
        double IOSGetGPSVerticalAccuracy();
        double IOSGetGPSHead();
        double IOSGetGPSSpeed();
#endif

nsfdb.h

STATUS far PASCAL NSFGetFolderChangesUNID(DBHANDLE hViewDB, 
        DBHANDLE hDataDB, 
        NOTEID ViewNoteID, 
        TIMEDATE *Since, 
        DWORD Flags, 
        HANDLE NoteIDs,
        DHANDLE *AddedNoteTable, 
        DHANDLE *RemovedNoteTable, 
        DHANDLE *AddedUNIDTable, 
        DHANDLE *RemovedUNIDTable, 
        DWORD *AddedUNIDCount, 
        DWORD *RemovedUNIDCount);

typedef STATUS (LNCALLBACKPTR NSFGETALLFOLDERCHANGESUNIDCALLBACK) (void *Param, 
        UNID *NoteUNID, 
        DHANDLE AddedNoteTable, 
        DHANDLE RemovedNoteTable, 
        DHANDLE AddedUNIDTable, 
        DHANDLE RemoveUNIDTable, 
        DWORD AddedUNIDCount, 
        DWORD RemovedUNIDCount);

STATUS LNPUBLIC NSFGetAllFolderChangesUNID(
        DHANDLE hViewDB, 
        DHANDLE hDataDB, 
        TIMEDATE *Since, 
        DWORD Flags, 
        DHANDLE hNoteIDs,
        NSFGETALLFOLDERCHANGESUNIDCALLBACK Callback, void *Param, TIMEDATE *Until);

nsfsearc.h

STATUS LNPUBLIC NSFSearchExt (DBHANDLE hDB,
		FORMULAHANDLE hFormula,
		char far *ViewTitle,
		DWORD SearchFlags,
		DWORD SearchFlags2,
		WORD NoteClassMask,
		TIMEDATE far *Since,
		NSFSEARCHPROC EnumRoutine,
		void far *EnumRoutineParameter,
		TIMEDATE far *retUntil);

oooapi.h

STATUS LNPUBLIC OOOSetAlternateAwayLine(
		OOOCTXPTR		*pOOOContext, 
		char			*altline);
		
STATUS LNPUBLIC OOOGetAlternateAwayLine(
		OOOCTXPTR 		*pOOOContext, 
		char			*altline,
		WORD			altlinelen);

Added are new header files, but they contain only #defines again.

New header files

  • gpserr.h
  • smi.h
  • smiext.h
  • smilcl.h
  • vim.h
  • vimext.h
  • vimlcl.h

The new SDK can now be used with Visual Studio 2017. The description of the compiler and link settings in the cmp directory has changed only slightly.

Probably the biggest change, and thus also the biggest annoyance; in the samples ALL makefiles were removed without replacement. If you have never worked with the SDK, and therefore have no makefiles, you will have a hard time building the samples and thus your own programs.

I can only hope that this was an error in the creation of the SDK, and HCL at least in a technote will provide examples for makefiles later.


NSD -monitor on Linux

NSD is a great tool to find the cause of a crash or hang ( if you are familiar with how to do the analysis ).
But sometimes the log file created by NSD does not include enough information to find the root cause of a problem.

In this case, you can start NSD in monitor mode.

If you are on Windows you would

  • stop the Domino server
  • from inside the Domino data directory invoke the command nsd -monitor
  • start the Domino server ( as normal application )

After you have reproduced the problem

  • type detach to detach NSD from running processes
  • quit NSD
  • restart your Domino server ( as a service )

I tried to do this on LINUX ( and inside a Docker container ) but the NSD -monitor command always returned an error

[notes@serv07 notesdata]$ /opt/hcl/domino/bin/nsd -monitor

INFO: NSD Monitor : Started
ERROR: NSD Monitor : No Processes Found or Specified
/opt/hcl/domino/notes/latest/linux/nsd.sh: line 8020: 11040 User defined signal 1 "$Nsd" "$@" -wrapper

I opened a case with HCL support and got a reply.

Here is what you have to do.

If you are running Domino 12 as participant of the HCL Domino Early Access program, you have to get into your Domino V12 container first

[root@docker ~]# docker exec -it container-id bash

The next steps are the same for Docker and Non-Docker environments

Identify the running Domino processes. Switch to /local/notesdata and issue the command

ps -fu $USER

You will get something like that

[notes@serv07 notesdata]$ ps -fu $USER
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
notes 2636 0.0 0.0 19200 2332 pts/1 Ss 11:58 0:00 bash
notes 2651 0.0 0.0 51808 1928 pts/1 R+ 11:59 0:00 _ ps -fu
notes 1 0.0 0.0 11988 1720 pts/0 Ss+ 11:52 0:00 /bin/bash /local/start.sh
notes 843 0.0 0.0 11988 1032 pts/0 S+ 11:52 0:00 /bin/bash /local/start.sh
notes 895 0.4 1.1 1466332 92908 pts/0 Sl+ 11:52 0:01 _ /opt/hcl/domino/notes/latest/linux/server
notes 903 0.0 0.3 339272 29448 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/logasio NOTESLOGGER reserved
notes 913 0.2 0.6 1374008 48860 pts/0 Sl+ 11:52 0:01 _ /opt/hcl/domino/notes/latest/linux/event
notes 1732 0.0 0.4 417372 38232 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/replica
notes 1733 0.1 0.5 624500 42024 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/router
notes 1734 0.0 0.4 486132 39296 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/update
notes 1735 0.0 0.5 422108 41700 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/amgr -s
notes 1975 0.0 0.4 421952 36988 pts/0 Sl+ 11:52 0:00 | _ /opt/hcl/domino/notes/latest/linux/amgr -e 1
notes 1737 0.1 0.5 619644 43332 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/adminp
notes 1738 0.0 0.4 487588 35024 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/daosmgr
notes 2424 0.0 0.5 417392 42164 pts/0 Sl+ 11:52 0:00 _ /opt/hcl/domino/notes/latest/linux/cldbdir
notes 2595 0.2 0.5 890580 47804 pts/0 Sl+ 11:52 0:01 _ /opt/hcl/domino/notes/latest/linux/clrepl

Write down the PIDs of interest. In my case it was 1735 and 1975 for the Agent Manager (amgr)

Now you can start NSD in monitor mode with

[notes@serv07 notesdata]$ /opt/hcl/domino/bin/nsd -monitor -pidlist 1735,1975

You can now start to reproduce the problem. In addition to the well known nsd … .log files in IBM_TECHNICAL_SUPPORT you will also find additional information in the nsd.notes folder


DirSync – OID rules for bitwise comparison.

As of FP2 for Domino / Notes 11.0.1, DirSync now supports filters using OID rules for bitwise comparison.

SPR# BSTS796FFJ – Server – Dirsync now supports filters using OID rules for bitwise comparison and other rules.

This extension of the filter options is very useful if you want to filter on attributes that contain the information as bit patterns.

For example, you want to sync only users that have an active (enabled) account in Active Directory. Whether an account is disabled is stored as a flag in the userAccountControl attribute.

If a user account is disabled, the userAccountControl attribute contains the disabled account flag 2. We can now build a filter rule to retrieve only person records that does NOT contain the flag ( and also are members of a specific group).

(&(objectClass=person)(memberOf=CN=BadGuys,CN=Sync,DC=ad,DC=fritz,DC=box)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))

For more information how to build a bitwise comparison filter rule on OID refer to the information here and here .


Setup MySQL on Docker – Order Matters

I wanted to create a new container on my Docker host for MySQL today. In general not a big deal. Pull the image from the repository and execute a docker run command along with some parameters and options to create the container.
I followed the instructions on https://hub.docker.com/_/mysql but ran into an issue, where the container started but exited after a couple of seconds.

I had created two volumes that should be mapped to the container to keep the configuration and the data persitent.

docker volume create mysql-data
docker volume create mysql-conf

Tis is not necessary because docker creates a volume when it creates the container. But the volume name is a cryptic string, and I wanted to have it in a human readable form.
I used the following command to create the container. I ran it without the -d option to be able to see output in the shell.

docker run --name=mysqlsrv -e MYSQL_ROOT_PASSWORD=SecretPassw0rd mysql:latest -p 3306:3306 -p 33060:33060 -v mysql-data:/var/lib/mysql -v mysql-conf:/etc/mysql

The container started, but then stopped.

2020-11-21 09:11:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
2020-11-21 09:11:50+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-11-21 09:11:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
2020-11-21 09:11:50+00:00 [Note] [Entrypoint]: Initializing database files
2020-11-21T09:11:50.346284Z 0 [ERROR] [MY-010083] [Server] --verbose is for use with --help; did you mean --log-error-verbosity?
2020-11-21T09:11:50.346355Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.22) initializing of server in progress as process 42
2020-11-21T09:11:50.351718Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-11-21T09:11:55.615069Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-11-21T09:12:02.486299Z 0 [ERROR] [MY-010147] [Server] Too many arguments (first extra is 'my-sql-data:/var/lib/mysql').
2020-11-21T09:12:02.486810Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
2020-11-21T09:12:02.487256Z 0 [ERROR] [MY-010119] [Server] Aborting
2020-11-21T09:12:07.897884Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.22) MySQL Community Server - GPL.

After some try and error it turned out that the order of the parameters matter. You have to put the -p and -v parameters before the mysql:tag.

docker run -d -p 3306:3306 -p 33060:33060 -v mysql-data:/var/lib/mysql -v mysql-conf:/etc/mysql --name=mysqlsrv -e MYSQL_ROOT_PASSWORD=SecretPassw0rd mysql:latest

After that MySQL starts and maps the volumes in /var/lib/docker/volumes to the paths inside the container.


Create random files with random content with Java

I was playing with DAOS in Domino 12 recently and needed a way to create thousands of test files with a given file size and random content.

I did not want to use existing files with real data for my tests. There are several programs available for Linux and Windows. Google for it. But as a developer, I should be able to create my one tool.

Here is some sample Java code that uses java.util.Random to create filnames and content in an easy way.

package de.eknori;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

public class DummyFileCreator {
	static int filesize = 129 * 1024;
	static int count = 9500;

	static File dir = new File("c:\\temp\\dummy\\");
	static String ext = ".txt";

	public static void main(String[] args) {
		byte[] bytes = new byte[filesize];
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;

		try {
			for (int i = 0; i < count; i++) {
				Random rand = new Random();

				String name = String.format("%s%s", System.currentTimeMillis(), rand.nextInt(100000) + ext);
				File file = new File(dir, name);

				fos = new FileOutputStream(file);
				bos = new BufferedOutputStream(fos);

				rand.nextBytes(bytes);
				bos.write(bytes);

				bos.flush();
				bos.close();
				fos.flush();
				fos.close();
			}

		} catch (FileNotFoundException fnfe) {
			System.out.println("File not found" + fnfe);
		} catch (IOException ioe) {
			System.out.println("Error while writing to file" + ioe);
		} finally {
			try {
				if (bos != null) {
					bos.flush();
					bos.close();
				}
				if (fos != null) {
					fos.flush();
					fos.close();
				}
			} catch (Exception e) {
				System.out.println("Error while closing streams" + e);
			}
		}
	}

}

The code is self-explanatory. Adjust the variables to your own needs, and you are ready to go


Domino DAOS T2 S3 Credentials

Starting in Domino 11, the Domino Attachment Object Service (DAOS) tier 2 storage feature enables you to use an S3-compatible storage service to store older attachment objects that haven’t been accessed within a specified number of days.

This feature allows you to reduce the amount of data stored on Domino® servers that use DAOS. It can also improve the performance of any incremental file backups that you do for DAOS.

Before you enable DAOS tier 2 storage, you must configure Domino® credential store to store the credentials that are used for connections to the storage service.

This document describes how to configure a new credential store. Section 5 describes how to add the storage service credentials to the Domino credential store.

The document says:

Create a text file, for example, dominocred.txt, that contains the service credentials

That means that you have to create a textfile in the Domino server file system.

I find this approach not very practical. In many cases Domino administrators do not necessarily have access to the file system. This means that sometimes cumbersome requests have to be made , so that authorized persons can copy the necessary file to the server.

Here another solution had to be found. I have thought about the following small workaround.

In credstore.nsf, I made a copy of the S3 Credential form and opened the existing items for editing. The form serves as a request document.


In the QueryClose event of the form I have a little LotusScript that calls an agent. The request document’s NoteId is passed to the agent.

import java.io.BufferedWriter;
import java.io.FileWriter;

import lotus.domino.AgentBase;
import lotus.domino.AgentContext;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.Session;

public class JavaAgent extends AgentBase {

	public void NotesMain() {

		try {
			Session session = getSession();
			Database db = session.getCurrentDatabase();
			Document param = null;
			AgentContext agentContext = session.getAgentContext();
			param = db.getDocumentByID(agentContext.getCurrentAgent().getParameterDocID());

			if (null != param) {
				String dataDir = session.getEnvironmentString("Directory",true) + "/";
				String fileName = dataDir + param.getUniversalID() + ".txt";
				BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true));
				writer.append("[" + param.getItemValueString("$ServiceTag") + "]\n");
				writer.append("aws_access_key_id = " + param.getItemValueString("AWSAccessKeyId") + "\n");
				writer.append("aws_secret_access_key = " + param.getItemValueString("Fingerprint") + "\n");
				writer.close();
				sleep(2000);
				String cmd = "tell daosmgr S3 storecred " + fileName;
				session.sendConsoleCommand("", cmd);
				param.remove(true);
			}

			param.recycle();
			db.recycle();
			session.recycle();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

The agent reads the items from the request document and creates a text file with the required format and content in the Domino datadir.
The agent then sends a console command to create the S3 credentials in the credstore.nsf.
The credentials are added to the credential store with the named credential.

The text file is deleted as well as the request document in the credstore.nsf. when the command completes. No credentials are visible at the console or in log files.

A small workaround that makes the life of a Domino administrator easier.


Testing new DataBase methods in Domino V12 Early Access without Domino Designer V12

Domino V12 Early Access CodeDrop 3 comes with a couple of new Java/LotusScript transaction methods that have been added to the (Notes)Database class.
At the moment, there is no Domino Designer V12 available. So how can we test the new methods?

If you are familiar with Java, then this is possible, because Java development not neccessarily needs Domino Designer.

All we need is the Notes.jar file from the V12 Domino Docker container.

To access the Domino V12 program directory you can use the commands as described in https://help.hcltechsw.com/domino/earlyaccess/inst_dock_useful_commands.html

or you can create a volume and access the program directory in the same way as you do with the data directory.

docker run -it -p 80:80 -p 443:443 -p 1352:1352 --hostname=serv03.fritz.box --name domino12 --cap-add=SYS_PTRACE --stop-timeout=90 -v notesdata:/local/notesdata -v d12:/opt/hcl/domino/notes/latest/linux domino-docker:V1200_10082020prod

Now that you have access to the Domino V12 program directory, copy the Notes.jar file located in /opt/hcl/domino/notes/latest/linux/ndext to your development environment.

I have created a small JaveServerAddin based on the work of Dmytro Pastovenskyi https://dpastov.blogspot.com/2020/10/javaserveraddin-in-domino-introduction.html.

You can download the sources from here

In the BuildPath change the location of Notes12.jar to the location of Notes.jar in your environment.

To build the project, change to the bin directory inside the project and issue the command

jar cfe D12Test.jar Domino12Test de 

Copy the resulting .Jar file to the ndext folder in the Domino V12 program directory. Make sure to set the correct execution rights ( 755 ). Now you can start the addin with

lo runjava de.eknori.Domino12Test

After the addin has started you will see the following on the Domino console

11/01/2020 05:45:15 Domino12Test: version 2
11/01/2020 05:45:15 Domino12Test: build date 2020-10-22 11:00 CET
11/01/2020 05:45:15 Domino12Test: java 1.8
11/01/2020 05:45:15 Domino12Test: seconds elapsed 30

During the next scheduled addin run, the code will create a new document in the d12test.nsf. You need to create this database on your server before running the addin. The database does not need to contain any design elements.

When the addin ran, you should see new documents in the database created with a form “commit”.

You should NOT see any documents that have a “rollback” form.

The same way, you can also test the new DQL enhancements in V12 Early Access Code Drop 3.


Update HTTPPassword item in names.nsf (backend)

Yesterday, we ran into an issue with the HTTP Password in the person record in names.nsf.

The problem occured after we upgraded the customers Domino server from V 9.0.1 to V11.0.1FP1.

The customer has some backend processes installed that let them delegate the process of register, update and delete users and groups to different departments. One part of the process is a piece of code that sets the HTTP password in the person record.

The issue was that the password was stored in clear text after upgrading the server. I looked into the design and could spot the root of the issue.

In pubnames_9.ntf, the HTTPPassword item has an input translation formula that encodes the password.

In V11 of the pubnames.ntf, the HTTPPassword item is missing and so is the input translation formula. The password encoding has been moved to the “Enter Password” button.

As a condequence, if you set the password in a backend agent, the String is not encoded and visible in clear text to others.

The fix is simple. We changed our agent code from

...
doc.HTTPPassword = pwdDoc.getItemValue("pwd").text
...

to

...
Dim result As Variant
result = Evaluate(|@Password("|+ pwddoc.getItemValue("pwd").text + |")|)
doc.HTTPPassword.result(0)
...
call doc.save(true, false)

to encode the password. This tipp might be useful, if you have similar processes implemented.

I have not looked into the design of Domino 10. But chances are that HCL has changed the design also in this release.


Domino 12 Early Access Program – Time-based one-time password (TOTP) authentication

The October code drop of Domino 12 ( Early Access Program) introduces TOTP as a new security feature.

A time-based one-time password (TOTP) is a temporary passcode generated by an algorithm that uses the current time of day as one of its authentication factors. Time-based one-time passwords are commonly used for two-factor authentication. In two-factor authentication scenarios, a user must enter a traditional, static password as well as a time-based one-time password to gain access to the computing system.

To configure TOTP, please follow the instructions in the documentation

TOTP uses the IDVault. It is important that the server running Domino 12 is the primary server for the IDVault by now. Development is still work in progress and you will run into issues with TOTP when you’re Domino 12 running together with Domino 11 like I do.

The IDVault in Domino 12 comes with an updated design to show information about TOTP.

After you have configured your server for TOTP, you will see a new login dialog when you access an application on the Domino 12 server that needs authentication.

If you acces the server for the first time and TOTP is not yet set up for your user, you need to setup a TOTP authentication device.

There are a couple of applications available. I am using TOTP Authenticator on an iPhone . I also tested with Authy

You’re not participating in the program yet? Read more about the HCL Domino 12 Early Access Program here.


HCL Ambassador Nomination 2021 is open

HCL Ambassadors nominations are open from 01-OCT to 31-OCT-2020.

HCL Ambassador is a distinction that HCL awards select members of the community that are both experts in their field and are passionate about sharing their HCL knowledge with others. 

HCL Ambassadors are exactly that, ambassadors. Importantly they are not employees, but their commitment to sharing their expertise has a huge impact on the HCL community. Whether they are blogging, writing books, speaking, running workshops, creating tutorials and classes, offering support in forums, or organizing and contributing to local events – they help make HCL’s mission of making technology play nice, possible.

HCL Ambassadors are eager to bring their technical expertise to new audiences both in person and online around the world.

More information about the program can be found here.

You can nominate yourself or someone else.

If you want to nominate ME, I would be happy. Permission is hereby explicitly granted.

Take a few minutes to fill out the nomination form.

Thanks in advance.


Gradle – Execution failed for task ‘clean’. Unable to delete file

I am using Gradle to build my Java projects. This works well on a Mac, but the build process fails on a Windows machine, when the task clean is going to be executed.

Task :clean FAILED
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':clean'.
Unable to delete file: C:\0.GIT\travelerrules-dots\de.midpoints.travelerrules.dots\build\unpuzzle_temp\maven-ant-tasks-2.1.4-SNAPSHOT

The jar file is build when I omit the clean task, but I always wanted the build process to to all the build steps on Windows and on the Mac. I never found a good solution, and also upgrading Gradle did not solve the problem.

Today, I found at least a workaround. Run the following command from the Windows command prompt.

TASKKILL /F /IM java.exe

now you can use

gradle cleanEclipse eclipse clean build

without any issues.


HCL Domino DirSync & the ‘&’

Yesterday, Martin Vogel from sirius-net GmbH sent me an email and asked for help with HCL Domino DirSync.

He had an issue with the filter syntax and also encountered some strange error messages when trying to sync from an Active Directory to Domino Directory.

Let’s first see, what the problem with the filter is. By default, DirSync syncs all person and group objects under the given SearchBase.

If you only want to get a subset of the possible results, you can use a filter in the DirSync Configuration document. Here is the filter.

(&(objectClass=person)(memberOf=CN=DistributionGroup,CN=Services &  Accounts,CN=Sync,DC=ad,DC=fritz,DC=box))

We checked the filter syntax by running a search from LDAPAdmin. The search returned the expected result.

But when we try to apply the filter to the DirSync configuration, the following error message occurs when trying to save the document.

Apparently there is a problem with the ‘&‘ in the ‘CN=Services & Accounts‘ part of the filter.

My first guess was that the ‘&’ character is not allowed in the filter string. But why is it possible to create an OU with this character in Active Directory?

And also, why does LDAPAdmin not complain about bad syntax?

The “Naming conventions in Active Directory for computers, domains, sites, and OUs” documentation does not mention any disallowed characters for OU names.

I took a closer look at the DirSyncUtil class in names.nsf. The error message is displayed during validation of the filter string. The code assumes that a “&” or “|” can only occur right after a “(“.

			Else
				state = State_inpar ' if we see an operator after this it's a problem.
			End If
			lastChar = ch
		Next
		If depth <> 0 Then
crunch:
			LDAPValidate = i
		End If
		Exit Function

If “&” or “|” occur after any other char, it is assumed an error. So the filter string is syntactically ok. But it is not validated as error-free.

Next, we needed to find a way to work around this limitation. One option would be to disable validation. Not a good idea. Or, we could set the filter string using Ytria ScanEZ.

This works, but in a productive environment this is certainly not the correct procedure.

Google to the rescue, we found another option to apply the filter string and validate it on document save & close.

Simply replace the ‘&’ char by it’s escape sequence ‘\26’. Our filter string will look like this then.

(&(objectClass=person)(memberOf=CN=DistributionGroup,CN=Services \26 Accounts,CN=Sync,DC=ad,DC=fritz,DC=box))

Now you can save & close the document without the error message. We then enabled the DirSync configuration. When DirSync tried to sync, we saw an error message on the server console.

"<ct sq="00003128" ti="0039C81D-C12585DF" ex="ndirsync" pi="17F0" tr="0004-0FB8" co="7">[17F0:0004-0FB8] DirSync> CSyncFromAD::SyncSpan( - 84: Decoding error)@syncfromad.cpp:2866 - 13171:DirSync encounterred LDAP error ./ct>"

We cross-checked the configuration on another machine and with another Active Directory.

Here the sync ran without any issues and the expected person records were synced into the Domino Directory.

We repeated the test without any filter string applied and even in this case, an error occurs. But the error has changed.

[17F0:0005-0324] DirSync ResyncAll by CheckBox: 0
[17F0:0005-0324] DirSync Preview: 0
[17F0:0005-0324] DirSync Level: 16
[17F0:0005-0324] DirSync SyncFlows: 2
[17F0:0005-0324] DirSync OnPremCookie:
[17F0:0005-0324] DirSync UserDirCookie: 54247270
[17F0:0005-0324] DirSync ResyncAll by Request: 1
[17F0:0005-0324] DirSync Sync all request calling SyncFromLDAPToNAB.
[17F0:0005-0324] DirSync SyncFromLDAPToNAB The parms were:
[17F0:0005-0324] DirSync base:
[17F0:0005-0324] DirSync scope: subtree
[17F0:0005-0324] DirSync filter: (&(|(objectClass=Group)(objectClass=Person))(uSNChanged>=0))
[17F0:0005-0324] DirSync attributes: co
, company
, department
, description
, facsimileTelephoneNumber
, givenName
, mail
, homephone
, initials
, l, manager

, mobile
, pager
, physicaldeliveryofficename
, postalcode
, sn
, st
, streetaddress
, telephonenumber
, title
, uid
, wWWHomePage
, memberOf
, objectClass
, objectGUID
, groupType
, member
, uSNChanged
[17F0:0005-0324] DirSync page size: 5000
[17F0:0005-0324] SyncFromLDAPToNAB ldap err: 54

Error code 54 stands for LDAP_LOOP_DETECTED. The documentation says that the error …

Indicates that the client discovered an alias or referral loop, and is thus unable to complete this request.

I am not an Active Directory expert. So I have no clue, why this errors occur on one machine, but not on the other. I’ve asked Mike O’Brien from HCL Development.

Odd. The error 84 (0x54) is an LDAP_DECODING_ERROR. This means that there was an issue decoding a server result. The 54 which is (0x36) is a LDAP_LOOP_DETECT which indicates a service issue.
The fact that he is seeing this with the default filter leads me to believe it is something service related.

Mike O’Brien, HCL

Apparently, the errors are related to the Active Directory configuration. Anyone any thoughts on this?


Docker – Prevent Container Autostart

Docker will autostart any container with a RestartPolicy of ‘always’ when the docker service initially starts.

I’ve mostly had this situation occur when a container was created with –restart always, and the situation later changed such that I no longer wanted this to happen.

You won’t find any evidence of this within cron or any other normal system startup scripts; you’ll have to dig into the container configuration to find it.

In order to quickly find the RestartPolicy config, you can use

docker inspect my-container | grep -A 3 RestartPolicy

The -A n grep option shows n lines after the match.

To update the RestartPolicy config you can use

docker update --restart=no my-container

Here is a sample from one of my containers.

docker inspect c2ea02bc1349 | grep -A 3 RestartPolicy
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},

docker update --restart=no c2ea02bc1349

docker inspect c2ea02bc1349 | grep -A 3 RestartPolicy
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},