Author: tridge Date: 2006-03-30 06:07:38 +0000 (Thu, 30 Mar 2006) New Revision: 14805
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=14805 Log: use tdb_lock_bystring() to prevent race conditions in notify add/remove Modified: branches/SAMBA_4_0/source/ntvfs/common/notify.c Changeset: Modified: branches/SAMBA_4_0/source/ntvfs/common/notify.c =================================================================== --- branches/SAMBA_4_0/source/ntvfs/common/notify.c 2006-03-30 05:50:09 UTC (rev 14804) +++ branches/SAMBA_4_0/source/ntvfs/common/notify.c 2006-03-30 06:07:38 UTC (rev 14805) @@ -109,7 +109,27 @@ return notify; } + /* + lock the notify db +*/ +static NTSTATUS notify_lock(struct notify_context *notify) +{ + if (tdb_lock_bystring(notify->w->tdb, NOTIFY_KEY) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; +} + +/* + unlock the notify db +*/ +static void notify_unlock(struct notify_context *notify) +{ + tdb_unlock_bystring(notify->w->tdb, NOTIFY_KEY); +} + +/* load the notify array */ static NTSTATUS notify_load(struct notify_context *notify) @@ -230,14 +250,21 @@ char *path = NULL; size_t len; - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + notify->array->entries = talloc_realloc(notify->array, notify->array->entries, struct notify_entry, notify->array->num_entries+1); if (notify->array->entries == NULL) { + notify_unlock(notify); return NT_STATUS_NO_MEMORY; } @@ -258,6 +285,9 @@ notify->array->num_entries++; status = notify_save(notify); + + notify_unlock(notify); + NT_STATUS_NOT_OK_RETURN(status); if (path) { @@ -293,9 +323,15 @@ return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + for (i=0;i<notify->array->num_entries;i++) { if (notify->server == notify->array->entries[i].server && private == notify->array->entries[i].private) { @@ -303,6 +339,7 @@ } } if (i == notify->array->num_entries) { + notify_unlock(notify); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -312,7 +349,11 @@ } notify->array->num_entries--; - return notify_save(notify); + status = notify_save(notify); + + notify_unlock(notify); + + return status; } /* @@ -327,9 +368,15 @@ return NT_STATUS_OK; } - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + for (i=0;i<notify->array->num_entries;i++) { if (notify->server == notify->array->entries[i].server) { if (i < notify->array->num_entries-1) { @@ -342,7 +389,11 @@ } - return notify_save(notify); + status = notify_save(notify); + + notify_unlock(notify); + + return status; }