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;
 }
 
 

Reply via email to