summaryrefslogtreecommitdiff
path: root/source3/passdb/secrets.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-09-17 23:45:21 +0000
committerJeremy Allison <jra@samba.org>2002-09-17 23:45:21 +0000
commit8b46126a076075aeed31dae1c80eca1ed9f5a251 (patch)
treef562440e4e262cf8c91b4892c7a4375394dd27a2 /source3/passdb/secrets.c
parentfe92e9caedbb68756f9d4fcb8ee20c2573e9c4ae (diff)
downloadsamba-8b46126a076075aeed31dae1c80eca1ed9f5a251.tar.gz
samba-8b46126a076075aeed31dae1c80eca1ed9f5a251.tar.bz2
samba-8b46126a076075aeed31dae1c80eca1ed9f5a251.zip
Never, *ever* hold a mutex lock in the message database where there may
be traversals being attempted. Yes, this was from bitter experience (and an out of control server :-). Also allow callers to break out of a tdb_chainlock with sigalarm if desired. Jeremy. (This used to be commit a7781f91d8c1177210bffc199cd2f3b7ff993eaf)
Diffstat (limited to 'source3/passdb/secrets.c')
-rw-r--r--source3/passdb/secrets.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 307dc132fc..b2bdaf2753 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -559,3 +559,69 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
return status;
}
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+/*
+ lock the secrets tdb based on a string - this is used as a primitive form of mutex
+ between smbd instances.
+*/
+BOOL secrets_named_mutex(const char *name, unsigned int timeout)
+{
+ TDB_DATA key;
+ int ret;
+
+ if (!message_init())
+ return False;
+
+ key.dptr = (char *)name;
+ key.dsize = strlen(name)+1;
+
+ /* Allow tdb_chainlock to be interrupted by an alarm. */
+ gotalarm = 0;
+ tdb_set_lock_alarm(&gotalarm);
+
+ if (timeout) {
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(timeout);
+ }
+
+ ret = tdb_chainlock(tdb, key);
+
+ /* Prevent tdb_chainlock from being interrupted by an alarm. */
+ tdb_set_lock_alarm(NULL);
+
+ if (timeout) {
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ if (gotalarm)
+ return False;
+ }
+
+ if (ret == 0)
+ DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
+
+ return (ret == 0);
+}
+
+/*
+ unlock a named mutex
+*/
+void secrets_named_mutex_release(char *name)
+{
+ TDB_DATA key;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ tdb_chainunlock(tdb, key);
+ DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
+}