#include "includes.h"
#include "system/filesys.h"
+#include "lib/util/server_id.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "dbwrap/dbwrap.h"
#include "messages.h"
#include "lib/util/util_tdb.h"
#include "librpc/gen_ndr/ndr_smbXsrv.h"
-#include <ccan/hash/hash.h>
#include "serverid.h"
struct smbXsrv_open_table {
struct {
struct db_context *db_ctx;
+ struct db_context *replay_cache_db_ctx;
uint32_t lowest_id;
uint32_t highest_id;
uint32_t max_opens;
NTSTATUS smbXsrv_open_global_init(void)
{
- const char *global_path = NULL;
+ char *global_path = NULL;
struct db_context *db_ctx = NULL;
if (smbXsrv_open_global_db_ctx != NULL) {
}
global_path = lock_path("smbXsrv_open_global.tdb");
+ if (global_path == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
db_ctx = db_open(NULL, global_path,
0, /* hash_size */
TDB_CLEAR_IF_FIRST |
TDB_INCOMPATIBLE_HASH,
O_RDWR | O_CREAT, 0600,
- DBWRAP_LOCK_ORDER_1);
+ DBWRAP_LOCK_ORDER_1,
+ DBWRAP_FLAG_NONE);
+ TALLOC_FREE(global_path);
if (db_ctx == NULL) {
NTSTATUS status;
return NT_STATUS_OK;
}
+static struct db_record *smbXsrv_open_global_fetch_locked(
+ struct db_context *db,
+ uint32_t id,
+ TALLOC_CTX *mem_ctx)
+{
+ TDB_DATA key;
+ uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE];
+ struct db_record *rec = NULL;
+
+ key = smbXsrv_open_global_id_to_key(id, key_buf);
+
+ rec = dbwrap_fetch_locked(db, mem_ctx, key);
+
+ if (rec == NULL) {
+ DBG_DEBUG("Failed to lock global id 0x%08x, key '%s'\n", id,
+ hex_encode_talloc(talloc_tos(), key.dptr, key.dsize));
+ }
+
+ return rec;
+}
+
+static struct db_record *smbXsrv_open_local_fetch_locked(
+ struct db_context *db,
+ uint32_t id,
+ TALLOC_CTX *mem_ctx)
+{
+ TDB_DATA key;
+ uint8_t key_buf[SMBXSRV_OPEN_LOCAL_TDB_KEY_SIZE];
+ struct db_record *rec = NULL;
+
+ key = smbXsrv_open_local_id_to_key(id, key_buf);
+
+ rec = dbwrap_fetch_locked(db, mem_ctx, key);
+
+ if (rec == NULL) {
+ DBG_DEBUG("Failed to lock local id 0x%08x, key '%s'\n", id,
+ hex_encode_talloc(talloc_tos(), key.dptr, key.dsize));
+ }
+
+ return rec;
+}
+
static NTSTATUS smbXsrv_open_table_init(struct smbXsrv_connection *conn,
uint32_t lowest_id,
uint32_t highest_id,
uint32_t max_opens)
{
+ struct smbXsrv_client *client = conn->client;
struct smbXsrv_open_table *table;
NTSTATUS status;
uint64_t max_range;
return NT_STATUS_INTERNAL_ERROR;
}
- table = talloc_zero(conn, struct smbXsrv_open_table);
+ table = talloc_zero(client, struct smbXsrv_open_table);
if (table == NULL) {
return NT_STATUS_NO_MEMORY;
}
TALLOC_FREE(table);
return NT_STATUS_NO_MEMORY;
}
+ table->local.replay_cache_db_ctx = db_open_rbt(table);
+ if (table->local.replay_cache_db_ctx == NULL) {
+ TALLOC_FREE(table);
+ return NT_STATUS_NO_MEMORY;
+ }
table->local.lowest_id = lowest_id;
table->local.highest_id = highest_id;
table->local.max_opens = max_opens;
table->global.db_ctx = smbXsrv_open_global_db_ctx;
- conn->open_table = table;
+ client->open_table = table;
return NT_STATUS_OK;
}
for (i = 0; i < (range / 2); i++) {
uint32_t id;
- uint8_t key_buf[SMBXSRV_OPEN_LOCAL_TDB_KEY_SIZE];
- TDB_DATA key;
TDB_DATA val;
struct db_record *rec = NULL;
id = highest_id;
}
- key = smbXsrv_open_local_id_to_key(id, key_buf);
-
- rec = dbwrap_fetch_locked(db, mem_ctx, key);
+ rec = smbXsrv_open_local_fetch_locked(db, id, mem_ctx);
if (rec == NULL) {
return NT_STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_STATUS_IS_OK(state.status)) {
uint32_t id;
- uint8_t key_buf[SMBXSRV_OPEN_LOCAL_TDB_KEY_SIZE];
- TDB_DATA key;
TDB_DATA val;
struct db_record *rec = NULL;
id = state.useable_id;
- key = smbXsrv_open_local_id_to_key(id, key_buf);
-
- rec = dbwrap_fetch_locked(db, mem_ctx, key);
+ rec = smbXsrv_open_local_fetch_locked(db, id, mem_ctx);
if (rec == NULL) {
return NT_STATUS_INSUFFICIENT_RESOURCES;
}
&state);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
return NT_STATUS_FILE_CLOSED;
- } else if (!NT_STATUS_IS_OK(status)) {
+ }
+ if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (!NT_STATUS_IS_OK(state.status)) {
return NT_STATUS_FILE_CLOSED;
}
- state.op->idle_time = now;
+ if (now != 0) {
+ state.op->idle_time = now;
+ }
*_open = state.op;
return state.op->status;
bool is_free = false;
bool was_free = false;
uint32_t id;
- uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE];
- TDB_DATA key;
if (i >= min_tries && last_free != 0) {
id = last_free;
id--;
}
- key = smbXsrv_open_global_id_to_key(id, key_buf);
-
- global->db_rec = dbwrap_fetch_locked(db, mem_ctx, key);
+ global->db_rec = smbXsrv_open_global_fetch_locked(db, id, mem_ctx);
if (global->db_rec == NULL) {
talloc_free(global);
return NT_STATUS_INSUFFICIENT_RESOURCES;
val = dbwrap_record_get_value(db_rec);
if (val.dsize == 0) {
+ DEBUG(10, ("%s: empty value\n", __func__));
TALLOC_FREE(frame);
*is_free = true;
if (was_free) {
}
DEBUG(10,("smbXsrv_open_global_verify_record\n"));
- if (DEBUGLVL(10)) {
+ if (CHECK_DEBUGLVL(10)) {
NDR_PRINT_DEBUG(smbXsrv_open_globalB, &global_blob);
}
exists = serverid_exists(&global->server_id);
}
if (!exists) {
+ struct server_id_buf idbuf;
DEBUG(2,("smbXsrv_open_global_verify_record: "
"key '%s' server_id %s does not exist.\n",
hex_encode_talloc(frame, key.dptr, key.dsize),
- server_id_str(frame, &global->server_id)));
- if (DEBUGLVL(2)) {
+ server_id_str_buf(global->server_id, &idbuf)));
+ if (CHECK_DEBUGLVL(2)) {
NDR_PRINT_DEBUG(smbXsrv_open_globalB, &global_blob);
}
TALLOC_FREE(frame);
return status;
}
- if (DEBUGLVL(10)) {
+ if (CHECK_DEBUGLVL(10)) {
DEBUG(10,("smbXsrv_open_global_store: key '%s' stored\n",
hex_encode_talloc(global->db_rec, key.dptr, key.dsize)));
NDR_PRINT_DEBUG(smbXsrv_open_globalB, &global_blob);
TALLOC_CTX *mem_ctx,
struct smbXsrv_open_global0 **_global)
{
- TDB_DATA key;
- uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE];
struct db_record *global_rec = NULL;
bool is_free = false;
return NT_STATUS_INTERNAL_ERROR;
}
- key = smbXsrv_open_global_id_to_key(open_global_id, key_buf);
-
- global_rec = dbwrap_fetch_locked(table->global.db_ctx, mem_ctx, key);
+ global_rec = smbXsrv_open_global_fetch_locked(table->global.db_ctx,
+ open_global_id,
+ mem_ctx);
if (global_rec == NULL) {
- DEBUG(0, ("smbXsrv_open_global_lookup(0x%08x): "
- "Failed to lock global key '%s'\n",
- open_global_id,
- hex_encode_talloc(talloc_tos(), key.dptr,
- key.dsize)));
return NT_STATUS_INTERNAL_DB_ERROR;
}
mem_ctx,
_global);
if (is_free) {
+ DEBUG(10, ("%s: is_free=true\n", __func__));
talloc_free(global_rec);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
NTTIME now,
struct smbXsrv_open **_open)
{
- struct smbXsrv_open_table *table = conn->open_table;
+ struct smbXsrv_open_table *table = conn->client->open_table;
struct db_record *local_rec = NULL;
struct smbXsrv_open *op = NULL;
void *ptr = NULL;
return status;
}
- if (DEBUGLVL(10)) {
+ if (CHECK_DEBUGLVL(10)) {
struct smbXsrv_openB open_blob;
ZERO_STRUCT(open_blob);
{
uint8_t buf[8+8+8];
uint32_t ret;
+ TDB_DATA key;
SBVAL(buf, 0, _open->global->open_persistent_id);
SBVAL(buf, 8, _open->global->open_volatile_id);
SBVAL(buf, 16, _open->global->open_time);
- ret = hash(buf, sizeof(buf), 0);
+ key = (TDB_DATA) { .dptr = buf, .dsize = sizeof(buf) };
+ ret = tdb_jenkins_hash(&key);
if (ret == 0) {
ret = 1;
return ret;
}
+static NTSTATUS smbXsrv_open_set_replay_cache(struct smbXsrv_open *op)
+{
+ struct GUID *create_guid;
+ struct GUID_txt_buf buf;
+ char *guid_string;
+ struct db_context *db = op->table->local.replay_cache_db_ctx;
+ NTSTATUS status;
+
+ if (!(op->flags & SMBXSRV_OPEN_NEED_REPLAY_CACHE)) {
+ return NT_STATUS_OK;
+ }
+
+ if (op->flags & SMBXSRV_OPEN_HAVE_REPLAY_CACHE) {
+ return NT_STATUS_OK;
+ }
+
+ create_guid = &op->global->create_guid;
+ if (GUID_all_zero(create_guid)) {
+ return NT_STATUS_OK;
+ }
+
+ guid_string = GUID_buf_string(create_guid, &buf);
+ if (guid_string == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = dbwrap_store_uint32_bystring(db, guid_string, op->local_id);
+
+ if (NT_STATUS_IS_OK(status)) {
+ op->flags |= SMBXSRV_OPEN_HAVE_REPLAY_CACHE;
+ op->flags &= ~SMBXSRV_OPEN_NEED_REPLAY_CACHE;
+ }
+
+ return status;
+}
+
+static NTSTATUS smbXsrv_open_clear_replay_cache(struct smbXsrv_open *op)
+{
+ struct GUID *create_guid;
+ struct GUID_txt_buf buf;
+ char *guid_string;
+ struct db_context *db;
+ NTSTATUS status;
+
+ if (op->table == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ db = op->table->local.replay_cache_db_ctx;
+
+ if (!(op->flags & SMBXSRV_OPEN_HAVE_REPLAY_CACHE)) {
+ return NT_STATUS_OK;
+ }
+
+ create_guid = &op->global->create_guid;
+ if (GUID_all_zero(create_guid)) {
+ return NT_STATUS_OK;
+ }
+
+ guid_string = GUID_buf_string(create_guid, &buf);
+ if (guid_string == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = dbwrap_purge_bystring(db, guid_string);
+
+ if (NT_STATUS_IS_OK(status)) {
+ op->flags &= ~SMBXSRV_OPEN_HAVE_REPLAY_CACHE;
+ }
+
+ return status;
+}
+
NTSTATUS smbXsrv_open_update(struct smbXsrv_open *op)
{
struct smbXsrv_open_table *table = op->table;
NTSTATUS status;
- uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE];
- TDB_DATA key;
if (op->global->db_rec != NULL) {
DEBUG(0, ("smbXsrv_open_update(0x%08x): "
return NT_STATUS_INTERNAL_ERROR;
}
- key = smbXsrv_open_global_id_to_key(op->global->open_global_id,
- key_buf);
-
- op->global->db_rec = dbwrap_fetch_locked(table->global.db_ctx,
- op->global, key);
+ op->global->db_rec = smbXsrv_open_global_fetch_locked(
+ table->global.db_ctx,
+ op->global->open_global_id,
+ op->global /* TALLOC_CTX */);
if (op->global->db_rec == NULL) {
- DEBUG(0, ("smbXsrv_open_update(0x%08x): "
- "Failed to lock global key '%s'\n",
- op->global->open_global_id,
- hex_encode_talloc(talloc_tos(), key.dptr,
- key.dsize)));
return NT_STATUS_INTERNAL_DB_ERROR;
}
return status;
}
- if (DEBUGLVL(10)) {
+ status = smbXsrv_open_set_replay_cache(op);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("smbXsrv_open_set_replay_cache failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
+ if (CHECK_DEBUGLVL(10)) {
struct smbXsrv_openB open_blob;
ZERO_STRUCT(open_blob);
NTSTATUS status;
NTSTATUS error = NT_STATUS_OK;
+ error = smbXsrv_open_clear_replay_cache(op);
+ if (!NT_STATUS_IS_OK(error)) {
+ DBG_ERR("smbXsrv_open_clear_replay_cache failed: %s\n",
+ nt_errstr(error));
+ }
+
if (op->table == NULL) {
- return NT_STATUS_OK;
+ return error;
}
table = op->table;
global_rec = op->global->db_rec;
op->global->db_rec = NULL;
if (global_rec == NULL) {
- uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE];
- TDB_DATA key;
-
- key = smbXsrv_open_global_id_to_key(
- op->global->open_global_id,
- key_buf);
-
- global_rec = dbwrap_fetch_locked(table->global.db_ctx,
- op->global, key);
+ global_rec = smbXsrv_open_global_fetch_locked(
+ table->global.db_ctx,
+ op->global->open_global_id,
+ op->global /* TALLOC_CTX */);
if (global_rec == NULL) {
- DEBUG(0, ("smbXsrv_open_close(0x%08x): "
- "Failed to lock global key '%s'\n",
- op->global->open_global_id,
- hex_encode_talloc(global_rec, key.dptr,
- key.dsize)));
error = NT_STATUS_INTERNAL_ERROR;
}
}
error = status;
}
- if (NT_STATUS_IS_OK(status) && DEBUGLVL(10)) {
+ if (NT_STATUS_IS_OK(status) && CHECK_DEBUGLVL(10)) {
struct smbXsrv_openB open_blob;
ZERO_STRUCT(open_blob);
local_rec = op->db_rec;
if (local_rec == NULL) {
- uint8_t key_buf[SMBXSRV_OPEN_LOCAL_TDB_KEY_SIZE];
- TDB_DATA key;
-
- key = smbXsrv_open_local_id_to_key(op->local_id, key_buf);
-
- local_rec = dbwrap_fetch_locked(table->local.db_ctx,
- op, key);
+ local_rec = smbXsrv_open_local_fetch_locked(table->local.db_ctx,
+ op->local_id,
+ op /* TALLOC_CTX*/);
if (local_rec == NULL) {
- DEBUG(0, ("smbXsrv_open_close(0x%08x): "
- "Failed to lock local key '%s'\n",
- op->global->open_global_id,
- hex_encode_talloc(local_rec, key.dptr,
- key.dsize)));
error = NT_STATUS_INTERNAL_ERROR;
}
}
*
* 0 and 0xFFFF are no valid ids.
*/
- max_opens = conn->sconn->real_max_open_files;
+ max_opens = conn->client->sconn->real_max_open_files;
max_opens = MIN(max_opens, UINT16_MAX - 1);
return smbXsrv_open_table_init(conn, 1, UINT16_MAX - 1, max_opens);
uint16_t fnum, NTTIME now,
struct smbXsrv_open **_open)
{
- struct smbXsrv_open_table *table = conn->open_table;
+ struct smbXsrv_open_table *table = conn->client->open_table;
uint32_t local_id = fnum;
uint32_t global_id = 0;
* transport connection (as we still have a 1:1 mapping
* between process and transport connection).
*/
- max_opens = conn->sconn->real_max_open_files;
+ max_opens = conn->client->sconn->real_max_open_files;
max_opens = MIN(max_opens, UINT16_MAX - 1);
return smbXsrv_open_table_init(conn, 1, UINT32_MAX - 1, max_opens);
NTTIME now,
struct smbXsrv_open **_open)
{
- struct smbXsrv_open_table *table = conn->open_table;
+ struct smbXsrv_open_table *table = conn->client->open_table;
uint32_t local_id = volatile_id & UINT32_MAX;
uint64_t local_zeros = volatile_id & 0xFFFFFFFF00000000LLU;
uint32_t global_id = persistent_id & UINT32_MAX;
uint64_t global_zeros = persistent_id & 0xFFFFFFFF00000000LLU;
+ NTSTATUS status;
if (local_zeros != 0) {
return NT_STATUS_FILE_CLOSED;
return NT_STATUS_FILE_CLOSED;
}
- return smbXsrv_open_local_lookup(table, local_id, global_id, now, _open);
+ status = smbXsrv_open_local_lookup(table, local_id, global_id, now,
+ _open);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /*
+ * Clear the replay cache for this create_guid if it exists:
+ * This is based on the assumption that this lookup will be
+ * triggered by a client request using the file-id for lookup.
+ * Hence the client has proven that it has in fact seen the
+ * reply to its initial create call. So subsequent create replays
+ * should be treated as invalid. Hence the index for create_guid
+ * lookup needs to be removed.
+ */
+ status = smbXsrv_open_clear_replay_cache(*_open);
+
+ return status;
+}
+
+NTSTATUS smb2srv_open_lookup_replay_cache(struct smbXsrv_connection *conn,
+ const struct GUID *create_guid,
+ NTTIME now, /* TODO: needed ? */
+ struct smbXsrv_open **_open)
+{
+ NTSTATUS status;
+ char *guid_string;
+ struct GUID_txt_buf buf;
+ uint32_t local_id = 0;
+ struct smbXsrv_open_table *table = conn->client->open_table;
+ struct db_context *db = table->local.replay_cache_db_ctx;
+
+ if (GUID_all_zero(create_guid)) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ guid_string = GUID_buf_string(create_guid, &buf);
+ if (guid_string == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = dbwrap_fetch_uint32_bystring(db, guid_string, &local_id);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("failed to fetch local_id from replay cache: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
+ status = smbXsrv_open_local_lookup(table, local_id, 0, /* global_id */
+ now, _open);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("smbXsrv_open_local_lookup failed for local_id %u\n",
+ (unsigned)local_id);
+ }
+
+ return status;
}
NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
struct auth_session_info *session_info,
uint64_t persistent_id,
- struct GUID create_guid,
+ const struct GUID *create_guid,
NTTIME now,
struct smbXsrv_open **_open)
{
- struct smbXsrv_open_table *table = conn->open_table;
+ struct smbXsrv_open_table *table = conn->client->open_table;
struct db_record *local_rec = NULL;
struct smbXsrv_open *op = NULL;
void *ptr = NULL;
struct security_token *current_token = NULL;
if (session_info == NULL) {
+ DEBUG(10, ("session_info=NULL\n"));
return NT_STATUS_INVALID_HANDLE;
}
current_token = session_info->security_token;
if (current_token == NULL) {
+ DEBUG(10, ("current_token=NULL\n"));
return NT_STATUS_INVALID_HANDLE;
}
if (global_zeros != 0) {
+ DEBUG(10, ("global_zeros!=0\n"));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
status = smbXsrv_open_global_lookup(table, global_id, op, &op->global);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(op);
+ DEBUG(10, ("smbXsrv_open_global_lookup returned %s\n",
+ nt_errstr(status)));
return status;
}
- if (!GUID_equal(&op->global->create_guid, &create_guid)) {
+ /*
+ * If the provided create_guid is NULL, this means that
+ * the reconnect request was a v1 request. In that case
+ * we should skipt the create GUID verification, since
+ * it is valid to v1-reconnect a v2-opened handle.
+ */
+ if ((create_guid != NULL) &&
+ !GUID_equal(&op->global->create_guid, create_guid))
+ {
TALLOC_FREE(op);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
return status;
}
- if (DEBUGLVL(10)) {
+ if (CHECK_DEBUGLVL(10)) {
struct smbXsrv_openB open_blob;
ZERO_STRUCT(open_blob);
return status;
}
+
+NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct smbXsrv_open_global0 *op = NULL;
+ TDB_DATA val;
+ struct db_record *rec;
+ bool delete_open = false;
+ uint32_t global_id = persistent_id & UINT32_MAX;
+
+ rec = smbXsrv_open_global_fetch_locked(smbXsrv_open_global_db_ctx,
+ global_id,
+ frame);
+ if (rec == NULL) {
+ status = NT_STATUS_NOT_FOUND;
+ goto done;
+ }
+
+ val = dbwrap_record_get_value(rec);
+ if (val.dsize == 0) {
+ DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "empty record in %s, skipping...\n",
+ global_id, dbwrap_name(smbXsrv_open_global_db_ctx)));
+ goto done;
+ }
+
+ status = smbXsrv_open_global_parse_record(talloc_tos(), rec, &op);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "failed to read record: %s\n",
+ global_id, nt_errstr(status)));
+ goto done;
+ }
+
+ if (server_id_is_disconnected(&op->server_id)) {
+ struct timeval now, disconnect_time;
+ int64_t tdiff;
+ now = timeval_current();
+ nttime_to_timeval(&disconnect_time, op->disconnect_time);
+ tdiff = usec_time_diff(&now, &disconnect_time);
+ delete_open = (tdiff >= 1000*op->durable_timeout_msec);
+
+ DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "disconnected at [%s] %us ago with "
+ "timeout of %us -%s reached\n",
+ global_id,
+ nt_time_string(frame, op->disconnect_time),
+ (unsigned)(tdiff/1000000),
+ op->durable_timeout_msec / 1000,
+ delete_open ? "" : " not"));
+ } else if (!serverid_exists(&op->server_id)) {
+ struct server_id_buf idbuf;
+ DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "server[%s] does not exist\n",
+ global_id,
+ server_id_str_buf(op->server_id, &idbuf)));
+ delete_open = true;
+ }
+
+ if (!delete_open) {
+ goto done;
+ }
+
+ status = dbwrap_record_delete(rec);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "failed to delete record"
+ "from %s: %s\n", global_id,
+ dbwrap_name(smbXsrv_open_global_db_ctx),
+ nt_errstr(status)));
+ goto done;
+ }
+
+ DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] "
+ "delete record from %s\n",
+ global_id,
+ dbwrap_name(smbXsrv_open_global_db_ctx)));
+
+done:
+ talloc_free(frame);
+ return status;
+}