#define DBGC_CLASS DBGC_AUTH
extern bool global_machine_password_needs_changing;
+static struct named_mutex *mutex;
/**
* Connect to a remote server for (inter)domain security authenticaion.
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
*/
- if (!grab_server_mutex(dc_name)) {
+ mutex = grab_named_mutex(NULL, dc_name, 10);
+ if (mutex == NULL) {
return NT_STATUS_NO_LOGON_SERVERS;
}
*cli = NULL;
}
- release_server_mutex();
+ TALLOC_FREE(mutex);
return result;
}
machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
cli_shutdown(*cli);
*cli = NULL;
- release_server_mutex();
+ TALLOC_FREE(mutex);
return result;
}
domain));
cli_shutdown(*cli);
*cli = NULL;
- release_server_mutex();
+ TALLOC_FREE(mutex);
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
if (!NT_STATUS_IS_OK(result)) {
cli_shutdown(*cli);
*cli = NULL;
- release_server_mutex();
+ TALLOC_FREE(mutex);
return result;
}
}
machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
cli_shutdown(*cli);
*cli = NULL;
- release_server_mutex();
+ TALLOC_FREE(mutex);
return NT_STATUS_NO_LOGON_SERVERS;
}
/* Let go as soon as possible so we avoid any potential deadlocks
with winbind lookup up users or groups. */
- release_server_mutex();
+ TALLOC_FREE(mutex);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("domain_client_validate: unable to validate password "
const char *p;
char *pserver = NULL;
bool connected_ok = False;
+ struct named_mutex *mutex;
if (!(cli = cli_initialise()))
return NULL;
session setup yet it will send a TCP reset to the first
connection (tridge) */
- if (!grab_server_mutex(desthost)) {
+ mutex = grab_named_mutex(talloc_tos(), desthost, 10);
+ if (mutex == NULL) {
cli_shutdown(cli);
return NULL;
}
}
DEBUG(10,("server_cryptkey: failed to connect to server %s. Error %s\n",
desthost, nt_errstr(status) ));
- release_server_mutex();
+ TALLOC_FREE(mutex);
}
if (!connected_ok) {
if (!attempt_netbios_session_request(&cli, global_myname(),
desthost, &dest_ss)) {
- release_server_mutex();
+ TALLOC_FREE(mutex);
DEBUG(1,("password server fails session request\n"));
cli_shutdown(cli);
return NULL;
DEBUG(3,("got session\n"));
if (!cli_negprot(cli)) {
+ TALLOC_FREE(mutex);
DEBUG(1,("%s rejected the negprot\n",desthost));
- release_server_mutex();
cli_shutdown(cli);
return NULL;
}
if (cli->protocol < PROTOCOL_LANMAN2 ||
!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+ TALLOC_FREE(mutex);
DEBUG(1,("%s isn't in user level security mode\n",desthost));
- release_server_mutex();
cli_shutdown(cli);
return NULL;
}
if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,
""))) {
+ TALLOC_FREE(mutex);
DEBUG(0,("%s rejected the initial session setup (%s)\n",
desthost, cli_errstr(cli)));
- release_server_mutex();
cli_shutdown(cli);
return NULL;
}
- release_server_mutex();
+ TALLOC_FREE(mutex);
DEBUG(3,("password server OK\n"));
struct idle_event;
struct share_mode_entry;
struct uuid;
+struct named_mutex;
struct vfs_fsp_data {
struct vfs_fsp_data *next;
This locking allows smbd's mutlithread architecture to look
like the single-connection that NT makes. */
-static char *mutex_server_name;
+struct named_mutex {
+ struct tdb_wrap *tdb;
+ char *name;
+};
-bool grab_server_mutex(const char *name)
+static int unlock_named_mutex(struct named_mutex *mutex)
{
- mutex_server_name = SMB_STRDUP(name);
- if (!mutex_server_name) {
- DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name));
- return False;
+ tdb_unlock_bystring(mutex->tdb->tdb, mutex->name);
+ return 0;
+}
+
+struct named_mutex *grab_named_mutex(TALLOC_CTX *mem_ctx, const char *name,
+ int timeout)
+{
+ struct named_mutex *result;
+
+ result = talloc(mem_ctx, struct named_mutex);
+ if (result == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
}
- if (!secrets_named_mutex(mutex_server_name, 10)) {
- DEBUG(10,("grab_server_mutex: failed for %s\n", name));
- SAFE_FREE(mutex_server_name);
- return False;
+
+ result->name = talloc_strdup(result, name);
+ if (result->name == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ TALLOC_FREE(result);
+ return NULL;
}
- return True;
-}
+ result->tdb = tdb_wrap_open(result, lock_path("mutex.tdb"), 0,
+ TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (result->tdb == NULL) {
+ DEBUG(1, ("Could not open mutex.tdb: %s\n",
+ strerror(errno)));
+ TALLOC_FREE(result);
+ return NULL;
+ }
-void release_server_mutex(void)
-{
- if (mutex_server_name) {
- secrets_named_mutex_release(mutex_server_name);
- SAFE_FREE(mutex_server_name);
+ if (tdb_lock_bystring_with_timeout(result->tdb->tdb, name,
+ timeout) == -1) {
+ DEBUG(1, ("Could not get the lock for %s\n", name));
+ TALLOC_FREE(result);
+ return NULL;
}
+
+ talloc_set_destructor(result, unlock_named_mutex);
+ return result;
}
krb5_const_principal client_principal = NULL;
char *host_princ_s = NULL;
bool auth_ok = False;
- bool got_replay_mutex = False;
bool got_auth_data = False;
+ struct named_mutex *mutex = NULL;
ZERO_STRUCT(packet);
ZERO_STRUCT(auth_data);
locking in the MIT krb5 code surrounding the replay
cache... */
- if (!grab_server_mutex("replay cache mutex")) {
+ mutex = grab_named_mutex(talloc_tos(), "replay cache mutex",
+ 10);
+ if (mutex == NULL) {
DEBUG(1,("ads_verify_ticket: unable to protect "
"replay cache with mutex.\n"));
ret = KRB5_CC_IO;
goto out;
}
- got_replay_mutex = True;
-
/* JRA. We must set the rcache here. This will prevent
replay attacks. */
}
if ( use_replay_cache ) {
- release_server_mutex();
- got_replay_mutex = False;
+ TALLOC_FREE(mutex);
#if 0
/* Heimdal leaks here, if we fix the leak, MIT crashes */
if (rcache) {
out:
- if (got_replay_mutex) {
- release_server_mutex();
- }
+ TALLOC_FREE(mutex);
if (!NT_STATUS_IS_OK(sret)) {
data_blob_free(&auth_data);
return NT_STATUS_OK;
}
-/*******************************************************************************
- 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)
-{
- int ret = 0;
-
- if (!secrets_init()) {
- return false;
- }
-
- ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
- 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(const char *name)
-{
- tdb_unlock_bystring(tdb, name);
- DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
-}
-
/*******************************************************************************
Store a complete AFS keyfile into secrets.tdb.
*******************************************************************************/
char *ipc_domain = NULL;
char *ipc_password = NULL;
- bool got_mutex;
+ struct named_mutex *mutex;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
*retry = True;
- got_mutex = secrets_named_mutex(controller,
- WINBIND_SERVER_MUTEX_WAIT_TIME);
-
- if (!got_mutex) {
+ mutex = grab_named_mutex(talloc_tos(), controller,
+ WINBIND_SERVER_MUTEX_WAIT_TIME);
+ if (mutex == NULL) {
DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
controller));
result = NT_STATUS_POSSIBLE_DEADLOCK;
goto done;
}
- secrets_named_mutex_release(controller);
- got_mutex = False;
+ TALLOC_FREE(mutex);
*retry = False;
/* set the domain if empty; needed for schannel connections */
result = NT_STATUS_OK;
done:
- if (got_mutex) {
- secrets_named_mutex_release(controller);
- }
-
+ TALLOC_FREE(mutex);
SAFE_FREE(machine_account);
SAFE_FREE(machine_password);
SAFE_FREE(machine_krb5_principal);