diff options
author | Jeremy Allison <jra@samba.org> | 2002-09-17 23:45:21 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-09-17 23:45:21 +0000 |
commit | 8b46126a076075aeed31dae1c80eca1ed9f5a251 (patch) | |
tree | f562440e4e262cf8c91b4892c7a4375394dd27a2 /source3/passdb/secrets.c | |
parent | fe92e9caedbb68756f9d4fcb8ee20c2573e9c4ae (diff) | |
download | samba-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.c | 66 |
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 )); +} |