PSKeePass / PoShKeePass

PowerShell module for KeePass
MIT License
255 stars 56 forks source link

Possible race condition when adding entries #185

Open DamionD opened 4 years ago

DamionD commented 4 years ago

I have found the following issue when adding multiple entries to a KeePass database stored on an SMB share:

@(1..9) | %{ New-KeePassEntry -KeePassEntryGroupPath "Test" -DatabaseProfileName "Test" -MasterKey $Password -Title "Test$($_)" -UserName "Test$($_)" -KeePassPassword $Password }

Add-KpEntry : Exception calling "Save" with "1" argument(s): "The process cannot access the file '\\SERVER\Share\Test.kdbx' because it is being used by another process."
At C:\Program Files\WindowsPowerShell\Modules\PoshKeePass\2.1.3.0\PoShKeePass.psm1:793 char:13
+             Add-KpEntry @addKpEntrySplat | ConvertTo-KPPSObject -Data ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-KPEntry], MethodInvocationException
    + FullyQualifiedErrorId : IOException,Add-KPEntry

The process manages to add 1 to 4 of the entries before failing. Adding the entries individually works normally, as it does if I add a delay:

@(1..9) | %{ New-KeePassEntry -KeePassEntryGroupPath "Test" -DatabaseProfileName "Test" -MasterKey $Password -Title "Test$($_)" -UserName "Test$($_)" -KeePassPassword $Password; Start-Sleep -Milliseconds 15 }

The minimum delay that appears to be needed is 11 milliseconds.

EDIT: The delay required seems to increase with the number of entries being processed (and possibly network latency).

jkdba commented 4 years ago

@DamionD It might be curious to setup a file watcher to ensure that there isn't something else scanning your file or utilizing it in some capacity that may cause the blocking.

In my setup I also have the DB on a CIFS and very occasionally I will get a write error with the same message when I have one process trying to write (typically me on command line) and other automated processes are accessing the DB of which I probably have 100s of calls a minute.

It could be the sleep is just spacing out your calls enough to avoid the other potential processes.

Can you replicate this on a test DB that is not used by anything else?

DamionD commented 4 years ago

@DamionD It might be curious to setup a file watcher to ensure that there isn't something else scanning your file or utilizing it in some capacity that may cause the blocking.

In my setup I also have the DB on a CIFS and very occasionally I will get a write error with the same message when I have one process trying to write (typically me on command line) and other automated processes are accessing the DB of which I probably have 100s of calls a minute.

It could be the sleep is just spacing out your calls enough to avoid the other potential processes.

Can you replicate this on a test DB that is not used by anything else?

Hi @jkdba, this testing was performed on a brand new test database. The SMB server has Sophos anti-virus with on-demand scanning enabled; could this be relevant?