autorid: fix a potential for data corruption.
commit0bfb0787194184ac154e4d5c9d16cc0b9e84e007
authorMichael Adam <obnox@samba.org>
Thu, 20 Mar 2014 11:07:19 +0000 (20 12:07 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 2 Apr 2014 22:26:28 +0000 (3 00:26 +0200)
treed0202abc026c2f34980ed988fe80c9d384747a54
parent758308c25a70da3591ce62e377f1ff449a357dd9
autorid: fix a potential for data corruption.

The initialization of the HWM values in autorid.tdb was racy:

It did:

1. fetch the HWM value
2. if it did not exist, store 0 in a transaction.

This can be racy if two processes at the same time try to
run the initialization code, especially in a cluster, when
winbindd and smbd are started simultaneously on all nodes.
The race is that the HWM is not re-fetched inside the transaction.

Assume both processes see that the HWM does not exist.
Both try to start a transaction. Process 1 gets the lock
and process 2 blocks. After Process 1 has stored the
HWM, it proceeds and manages to start subsequent transactions
which also bump the HWM value (e.g. a range allocation,
which is also triggered from allocation code). When
process 2 finally manages to start the transaction, the
HWM value is aready > 0. But process 2 does not look again
and simply overwrites the HWM with 0.

So the next allocation will overwrite an existing mapping,
at least partially.

This patch changes the mechanism to:

1. fetch the hwm value
2. if it does not exist start a transaction
3.   fetch the hwm value
4.   if it does not exist, store 0
5. commit the transaction.

Note: this is not theoretical. Corruptions have been
seen in cluster environments.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/winbindd/idmap_autorid_tdb.c