static void do_locked1_cb(struct db_record *rec, void *private_data) { struct do_locked1_state *state = (struct do_locked1_state *)private_data; state->status = dbwrap_record_store(rec, state->value, 0); }
static int backup_copy_fn(struct db_record *orig_rec, void *state) { struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state; struct db_record *new_rec; NTSTATUS status; TDB_DATA key; TDB_DATA value; key = dbwrap_record_get_key(orig_rec); new_rec = dbwrap_fetch_locked(bs->new_db, talloc_tos(), key); if (new_rec == NULL) { bs->success = false; return 1; } value = dbwrap_record_get_value(orig_rec); status = dbwrap_record_store(new_rec, value, TDB_INSERT); TALLOC_FREE(new_rec); if (!NT_STATUS_IS_OK(status)) { bs->success = false; return 1; } return 0; }
static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, files_struct *fsp, DATA_BLOB *pblob) { uint8_t id_buf[16]; struct file_id id; TDB_DATA data; struct db_context *db = acl_db; struct db_record *rec; NTSTATUS status; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp_str_dbg(fsp))); status = vfs_stat_fsp(fsp); if (!NT_STATUS_IS_OK(status)) { return status; } id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st); /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); rec = dbwrap_fetch_locked(db, talloc_tos(), make_tdb_data(id_buf, sizeof(id_buf))); if (rec == NULL) { DEBUG(0, ("store_acl_blob_fsp_tdb: fetch_lock failed\n")); return NT_STATUS_INTERNAL_DB_CORRUPTION; } data.dptr = pblob->data; data.dsize = pblob->length; return dbwrap_record_store(rec, data, 0); }
bool serverid_register_msg_flags(const struct server_id id, bool do_reg, uint32_t msg_flags) { struct db_context *db; struct serverid_key key; struct serverid_data *data; struct db_record *rec; TDB_DATA tdbkey; TDB_DATA value; NTSTATUS status; bool ret = false; db = serverid_db(); if (db == NULL) { return false; } serverid_fill_key(&id, &key); tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key)); rec = dbwrap_fetch_locked(db, talloc_tos(), tdbkey); if (rec == NULL) { DEBUG(1, ("Could not fetch_lock serverid.tdb record\n")); return false; } value = dbwrap_record_get_value(rec); if (value.dsize != sizeof(struct serverid_data)) { DEBUG(1, ("serverid record has unexpected size %d " "(wanted %d)\n", (int)value.dsize, (int)sizeof(struct serverid_data))); goto done; } data = (struct serverid_data *)value.dptr; if (do_reg) { data->msg_flags |= msg_flags; } else { data->msg_flags &= ~msg_flags; } status = dbwrap_record_store(rec, value, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Storing serverid.tdb record failed: %s\n", nt_errstr(status))); goto done; } ret = true; done: TALLOC_FREE(rec); return ret; }
static int share_mode_data_destructor(struct share_mode_data *d) { NTSTATUS status; TDB_DATA data; if (!d->modified) { return 0; } data = unparse_share_modes(d); if (data.dptr == NULL) { if (!d->fresh) { /* There has been an entry before, delete it */ status = dbwrap_record_delete(d->record); if (!NT_STATUS_IS_OK(status)) { char *errmsg; DEBUG(0, ("delete_rec returned %s\n", nt_errstr(status))); if (asprintf(&errmsg, "could not delete share " "entry: %s\n", nt_errstr(status)) == -1) { smb_panic("could not delete share" "entry"); } smb_panic(errmsg); } } goto done; } status = dbwrap_record_store(d->record, data, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { char *errmsg; DEBUG(0, ("store returned %s\n", nt_errstr(status))); if (asprintf(&errmsg, "could not store share mode entry: %s", nt_errstr(status)) == -1) { smb_panic("could not store share mode entry"); } smb_panic(errmsg); } done: return 0; }
NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key, TDB_DATA data, int flags) { struct db_record *rec; NTSTATUS status; rec = dbwrap_fetch_locked(db, talloc_tos(), key); if (rec == NULL) { return NT_STATUS_NO_MEMORY; } status = dbwrap_record_store(rec, data, flags); TALLOC_FREE(rec); return status; }
bool serverid_register(const struct server_id id, uint32_t msg_flags) { struct db_context *db; struct serverid_key key; struct serverid_data data; struct db_record *rec; TDB_DATA tdbkey, tdbdata; NTSTATUS status; bool ret = false; db = serverid_db(); if (db == NULL) { return false; } serverid_fill_key(&id, &key); tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key)); rec = dbwrap_fetch_locked(db, talloc_tos(), tdbkey); if (rec == NULL) { DEBUG(1, ("Could not fetch_lock serverid.tdb record\n")); return false; } ZERO_STRUCT(data); data.unique_id = id.unique_id; data.msg_flags = msg_flags; tdbdata = make_tdb_data((uint8_t *)&data, sizeof(data)); status = dbwrap_record_store(rec, tdbdata, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Storing serverid.tdb record failed: %s\n", nt_errstr(status))); goto done; } if (lp_clustering() && ctdb_serverids_exist_supported(messaging_ctdbd_connection())) { register_with_ctdbd(messaging_ctdbd_connection(), id.unique_id, NULL, NULL); } ret = true; done: TALLOC_FREE(rec); return ret; }
NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key, TDB_DATA data, int flags) { struct db_record *rec; NTSTATUS status; TALLOC_CTX *frame = talloc_stackframe(); rec = dbwrap_fetch_locked(db, frame, key); if (rec == NULL) { TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } status = dbwrap_record_store(rec, data, flags); TALLOC_FREE(frame); return status; }
static NTSTATUS dbwrap_change_uint32_atomic_action(struct db_context *db, void *private_data) { struct db_record *rec; uint32_t val = (uint32_t)-1; uint32_t v_store; NTSTATUS ret; struct dbwrap_change_uint32_atomic_context *state; TDB_DATA value; state = (struct dbwrap_change_uint32_atomic_context *)private_data; rec = dbwrap_fetch_locked(db, talloc_tos(), string_term_tdb_data(state->keystr)); if (!rec) { return NT_STATUS_UNSUCCESSFUL; } value = dbwrap_record_get_value(rec); if (value.dptr == NULL) { val = *(state->oldval); } else if (value.dsize == sizeof(val)) { val = IVAL(value.dptr, 0); *(state->oldval) = val; } else { ret = NT_STATUS_UNSUCCESSFUL; goto done; } val += state->change_val; SIVAL(&v_store, 0, val); ret = dbwrap_record_store(rec, make_tdb_data((const uint8_t *)&v_store, sizeof(v_store)), TDB_REPLACE); done: TALLOC_FREE(rec); return ret; }
/* save the notify array */ static NTSTATUS notify_save(struct notify_context *notify, struct db_record *rec) { TDB_DATA dbuf; DATA_BLOB blob; NTSTATUS status; enum ndr_err_code ndr_err; TALLOC_CTX *tmp_ctx; /* if possible, remove some depth arrays */ while (notify->array->num_depths > 0 && notify->array->depth[notify->array->num_depths-1].num_entries == 0) { notify->array->num_depths--; } /* we might just be able to delete the record */ if (notify->array->num_depths == 0) { return dbwrap_record_delete(rec); } tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); return ndr_map_error2ntstatus(ndr_err); } if (DEBUGLEVEL >= 10) { DEBUG(10, ("notify_save:\n")); NDR_PRINT_DEBUG(notify_array, notify->array); } dbuf.dptr = blob.data; dbuf.dsize = blob.length; status = dbwrap_record_store(rec, dbuf, TDB_REPLACE); talloc_free(tmp_ctx); return status; }
NTSTATUS dbwrap_store_int32_bystring(struct db_context *db, const char *keystr, int32_t v) { struct db_record *rec; int32_t v_store; NTSTATUS status; rec = dbwrap_fetch_locked(db, talloc_tos(), string_term_tdb_data(keystr)); if (rec == NULL) { return NT_STATUS_UNSUCCESSFUL; } SIVAL(&v_store, 0, v); status = dbwrap_record_store(rec, make_tdb_data((const uint8_t *)&v_store, sizeof(v_store)), TDB_REPLACE); TALLOC_FREE(rec); return status; }
static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data) { struct db_record *rec = NULL; NTSTATUS status; struct dbwrap_store_context *store_ctx; store_ctx = (struct dbwrap_store_context *)private_data; rec = dbwrap_fetch_locked(db, talloc_tos(), *(store_ctx->key)); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); return NT_STATUS_NO_MEMORY; } status = dbwrap_record_store(rec, *(store_ctx->dbuf), store_ctx->flag); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("store returned %s\n", nt_errstr(status))); } TALLOC_FREE(rec); return status; }
static NTSTATUS smbXsrv_tcon_create(struct smbXsrv_tcon_table *table, enum protocol_types protocol, struct server_id server_id, NTTIME now, struct smbXsrv_tcon **_tcon) { struct db_record *local_rec = NULL; struct smbXsrv_tcon *tcon = NULL; void *ptr = NULL; TDB_DATA val; struct smbXsrv_tcon_global0 *global = NULL; NTSTATUS status; if (table->local.num_tcons >= table->local.max_tcons) { return NT_STATUS_INSUFFICIENT_RESOURCES; } tcon = talloc_zero(table, struct smbXsrv_tcon); if (tcon == NULL) { return NT_STATUS_NO_MEMORY; } tcon->table = table; tcon->status = NT_STATUS_INTERNAL_ERROR; tcon->idle_time = now; status = smbXsrv_tcon_global_allocate(table->global.db_ctx, tcon, &global); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(tcon); return status; } tcon->global = global; if (protocol >= PROTOCOL_SMB2_02) { uint64_t id = global->tcon_global_id; uint8_t key_buf[SMBXSRV_TCON_LOCAL_TDB_KEY_SIZE]; TDB_DATA key; global->tcon_wire_id = id; tcon->local_id = global->tcon_global_id; key = smbXsrv_tcon_local_id_to_key(tcon->local_id, key_buf); local_rec = dbwrap_fetch_locked(table->local.db_ctx, tcon, key); if (local_rec == NULL) { TALLOC_FREE(tcon); return NT_STATUS_NO_MEMORY; } val = dbwrap_record_get_value(local_rec); if (val.dsize != 0) { TALLOC_FREE(tcon); return NT_STATUS_INTERNAL_DB_CORRUPTION; } } else { status = smb1srv_tcon_local_allocate_id(table->local.db_ctx, table->local.lowest_id, table->local.highest_id, tcon, &local_rec, &tcon->local_id); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(tcon); return status; } global->tcon_wire_id = tcon->local_id; } global->creation_time = now; global->server_id = server_id; ptr = tcon; val = make_tdb_data((uint8_t const *)&ptr, sizeof(ptr)); status = dbwrap_record_store(local_rec, val, TDB_REPLACE); TALLOC_FREE(local_rec); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(tcon); return status; } table->local.num_tcons += 1; talloc_set_destructor(tcon, smbXsrv_tcon_destructor); status = smbXsrv_tcon_global_store(global); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_tcon_create: " "global_id (0x%08x) store failed - %s\n", tcon->global->tcon_global_id, nt_errstr(status))); TALLOC_FREE(tcon); return status; } if (DEBUGLVL(10)) { struct smbXsrv_tconB tcon_blob; ZERO_STRUCT(tcon_blob); tcon_blob.version = SMBXSRV_VERSION_0; tcon_blob.info.info0 = tcon; DEBUG(10,("smbXsrv_tcon_create: global_id (0x%08x) stored\n", tcon->global->tcon_global_id)); NDR_PRINT_DEBUG(smbXsrv_tconB, &tcon_blob); } *_tcon = tcon; return NT_STATUS_OK; }
static NTSTATUS smbXsrv_tcon_global_store(struct smbXsrv_tcon_global0 *global) { struct smbXsrv_tcon_globalB global_blob; DATA_BLOB blob = data_blob_null; TDB_DATA key; TDB_DATA val; NTSTATUS status; enum ndr_err_code ndr_err; /* * TODO: if we use other versions than '0' * we would add glue code here, that would be able to * store the information in the old format. */ if (global->db_rec == NULL) { return NT_STATUS_INTERNAL_ERROR; } key = dbwrap_record_get_key(global->db_rec); val = dbwrap_record_get_value(global->db_rec); ZERO_STRUCT(global_blob); global_blob.version = smbXsrv_version_global_current(); if (val.dsize >= 8) { global_blob.seqnum = IVAL(val.dptr, 4); } global_blob.seqnum += 1; global_blob.info.info0 = global; ndr_err = ndr_push_struct_blob(&blob, global->db_rec, &global_blob, (ndr_push_flags_fn_t)ndr_push_smbXsrv_tcon_globalB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(1,("smbXsrv_tcon_global_store: key '%s' ndr_push - %s\n", hex_encode_talloc(global->db_rec, key.dptr, key.dsize), nt_errstr(status))); TALLOC_FREE(global->db_rec); return status; } val = make_tdb_data(blob.data, blob.length); status = dbwrap_record_store(global->db_rec, val, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("smbXsrv_tcon_global_store: key '%s' store - %s\n", hex_encode_talloc(global->db_rec, key.dptr, key.dsize), nt_errstr(status))); TALLOC_FREE(global->db_rec); return status; } if (DEBUGLVL(10)) { DEBUG(10,("smbXsrv_tcon_global_store: key '%s' stored\n", hex_encode_talloc(global->db_rec, key.dptr, key.dsize))); NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); } TALLOC_FREE(global->db_rec); return NT_STATUS_OK; }
static int tdbsam_convert_one(struct db_record *rec, void *priv) { struct tdbsam_convert_state *state = (struct tdbsam_convert_state *)priv; struct samu *user; TDB_DATA data; NTSTATUS status; bool ret; TDB_DATA key; TDB_DATA value; key = dbwrap_record_get_key(rec); if (key.dsize < USERPREFIX_LEN) { return 0; } if (strncmp((char *)key.dptr, USERPREFIX, USERPREFIX_LEN) != 0) { return 0; } user = samu_new(talloc_tos()); if (user == NULL) { DEBUG(0,("tdbsam_convert: samu_new() failed!\n")); state->success = false; return -1; } DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) " "(version:%d)\n", (char *)key.dptr, state->from)); value = dbwrap_record_get_value(rec); switch (state->from) { case 0: ret = init_samu_from_buffer(user, SAMU_BUFFER_V0, (uint8_t *)value.dptr, value.dsize); break; case 1: ret = init_samu_from_buffer(user, SAMU_BUFFER_V1, (uint8_t *)value.dptr, value.dsize); break; case 2: ret = init_samu_from_buffer(user, SAMU_BUFFER_V2, (uint8_t *)value.dptr, value.dsize); break; case 3: ret = init_samu_from_buffer(user, SAMU_BUFFER_V3, (uint8_t *)value.dptr, value.dsize); break; case 4: ret = init_samu_from_buffer(user, SAMU_BUFFER_V4, (uint8_t *)value.dptr, value.dsize); break; default: /* unknown tdbsam version */ ret = False; } if (!ret) { DEBUG(0,("tdbsam_convert: Bad struct samu entry returned " "from TDB (key:%s) (version:%d)\n", (char *)key.dptr, state->from)); TALLOC_FREE(user); state->success = false; return -1; } data.dsize = init_buffer_from_samu(&data.dptr, user, false); TALLOC_FREE(user); if (data.dsize == -1) { DEBUG(0,("tdbsam_convert: cannot pack the struct samu into " "the new format\n")); state->success = false; return -1; } status = dbwrap_record_store(rec, data, TDB_MODIFY); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not store the new record: %s\n", nt_errstr(status))); state->success = false; return -1; } return 0; }
NTSTATUS smbXsrv_open_create(struct smbXsrv_connection *conn, struct auth_session_info *session_info, NTTIME now, struct smbXsrv_open **_open) { struct smbXsrv_open_table *table = conn->client->open_table; struct db_record *local_rec = NULL; struct smbXsrv_open *op = NULL; void *ptr = NULL; TDB_DATA val; struct smbXsrv_open_global0 *global = NULL; NTSTATUS status; struct dom_sid *current_sid = NULL; struct security_token *current_token = NULL; if (session_info == NULL) { return NT_STATUS_INVALID_HANDLE; } current_token = session_info->security_token; if (current_token == NULL) { return NT_STATUS_INVALID_HANDLE; } if (current_token->num_sids > PRIMARY_USER_SID_INDEX) { current_sid = ¤t_token->sids[PRIMARY_USER_SID_INDEX]; } if (current_sid == NULL) { return NT_STATUS_INVALID_HANDLE; } if (table->local.num_opens >= table->local.max_opens) { return NT_STATUS_INSUFFICIENT_RESOURCES; } op = talloc_zero(table, struct smbXsrv_open); if (op == NULL) { return NT_STATUS_NO_MEMORY; } op->table = table; op->status = NT_STATUS_OK; /* TODO: start with INTERNAL_ERROR */ op->idle_time = now; status = smbXsrv_open_global_allocate(table->global.db_ctx, op, &global); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } op->global = global; status = smbXsrv_open_local_allocate_id(table->local.db_ctx, table->local.lowest_id, table->local.highest_id, op, &local_rec, &op->local_id); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } global->open_persistent_id = global->open_global_id; global->open_volatile_id = op->local_id; global->server_id = messaging_server_id(conn->msg_ctx); global->open_time = now; global->open_owner = *current_sid; if (conn->protocol >= PROTOCOL_SMB2_10) { global->client_guid = conn->smb2.client.guid; } ptr = op; val = make_tdb_data((uint8_t const *)&ptr, sizeof(ptr)); status = dbwrap_record_store(local_rec, val, TDB_REPLACE); TALLOC_FREE(local_rec); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } table->local.num_opens += 1; talloc_set_destructor(op, smbXsrv_open_destructor); status = smbXsrv_open_global_store(global); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_open_create: " "global_id (0x%08x) store failed - %s\n", op->global->open_global_id, nt_errstr(status))); TALLOC_FREE(op); return status; } if (CHECK_DEBUGLVL(10)) { struct smbXsrv_openB open_blob; ZERO_STRUCT(open_blob); open_blob.version = SMBXSRV_VERSION_0; open_blob.info.info0 = op; DEBUG(10,("smbXsrv_open_create: global_id (0x%08x) stored\n", op->global->open_global_id)); NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob); } *_open = op; return NT_STATUS_OK; }
NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn, struct auth_session_info *session_info, uint64_t persistent_id, const struct GUID *create_guid, NTTIME now, struct smbXsrv_open **_open) { struct smbXsrv_open_table *table = conn->client->open_table; struct db_record *local_rec = NULL; struct smbXsrv_open *op = NULL; void *ptr = NULL; TDB_DATA val; uint32_t global_id = persistent_id & UINT32_MAX; uint64_t global_zeros = persistent_id & 0xFFFFFFFF00000000LLU; NTSTATUS status; 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; } op = talloc_zero(table, struct smbXsrv_open); if (op == NULL) { return NT_STATUS_NO_MEMORY; } op->table = table; 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 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; } if (!security_token_is_sid(current_token, &op->global->open_owner)) { TALLOC_FREE(op); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (!op->global->durable) { TALLOC_FREE(op); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (table->local.num_opens >= table->local.max_opens) { TALLOC_FREE(op); return NT_STATUS_INSUFFICIENT_RESOURCES; } status = smbXsrv_open_local_allocate_id(table->local.db_ctx, table->local.lowest_id, table->local.highest_id, op, &local_rec, &op->local_id); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } op->idle_time = now; op->status = NT_STATUS_FILE_CLOSED; op->global->open_volatile_id = op->local_id; op->global->server_id = messaging_server_id(conn->msg_ctx); ptr = op; val = make_tdb_data((uint8_t const *)&ptr, sizeof(ptr)); status = dbwrap_record_store(local_rec, val, TDB_REPLACE); TALLOC_FREE(local_rec); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } table->local.num_opens += 1; talloc_set_destructor(op, smbXsrv_open_destructor); status = smbXsrv_open_global_store(op->global); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } if (CHECK_DEBUGLVL(10)) { struct smbXsrv_openB open_blob; ZERO_STRUCT(open_blob); open_blob.version = 0; open_blob.info.info0 = op; DEBUG(10,("smbXsrv_open_recreate: global_id (0x%08x) stored\n", op->global->open_global_id)); NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob); } *_open = op; return NT_STATUS_OK; }
static void test_store_records(struct db_context *db, struct tevent_context *ev) { TDB_DATA key; uint32_t *counters; TALLOC_CTX *tmp_ctx = talloc_stackframe(); struct timeval start; key = string_term_tdb_data("testkey"); start = timeval_current(); while ((timelimit == 0) || (timeval_elapsed(&start) < timelimit)) { struct db_record *rec; TDB_DATA data; TDB_DATA value; int ret; NTSTATUS status; if (!no_trans) { if (verbose) DEBUG(1, ("starting transaction\n")); ret = dbwrap_transaction_start(db); if (ret != 0) { DEBUG(0, ("Failed to start transaction on node " "%d\n", pnn)); goto fail; } if (verbose) DEBUG(1, ("transaction started\n")); do_sleep(torture_delay); } if (verbose) DEBUG(1, ("calling fetch_lock\n")); rec = dbwrap_fetch_locked(db, tmp_ctx, key); if (rec == NULL) { DEBUG(0, ("Failed to fetch record\n")); goto fail; } if (verbose) DEBUG(1, ("fetched record ok\n")); do_sleep(torture_delay); value = dbwrap_record_get_value(rec); data.dsize = MAX(value.dsize, sizeof(uint32_t) * (pnn+1)); data.dptr = (unsigned char *)talloc_zero_size(tmp_ctx, data.dsize); if (data.dptr == NULL) { DEBUG(0, ("Failed to allocate data\n")); goto fail; } memcpy(data.dptr, value.dptr, value.dsize); counters = (uint32_t *)data.dptr; /* bump our counter */ counters[pnn]++; if (verbose) DEBUG(1, ("storing data\n")); status = dbwrap_record_store(rec, data, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to store record\n")); if (!no_trans) { ret = dbwrap_transaction_cancel(db); if (ret != 0) { DEBUG(0, ("Error cancelling transaction.\n")); } } goto fail; } talloc_free(rec); if (verbose) DEBUG(1, ("stored data ok\n")); do_sleep(torture_delay); if (!no_trans) { if (verbose) DEBUG(1, ("calling transaction_commit\n")); ret = dbwrap_transaction_commit(db); if (ret != 0) { DEBUG(0, ("Failed to commit transaction\n")); goto fail; } if (verbose) DEBUG(1, ("transaction committed\n")); } /* store the counters and verify that they are sane */ if (verbose || (pnn == 0)) { if (!check_counters(db, data)) { goto fail; } } talloc_free(data.dptr); do_sleep(torture_delay); } goto done; fail: success = false; done: talloc_free(tmp_ctx); return; }
static int share_mode_data_destructor(struct share_mode_data *d) { NTSTATUS status; TDB_DATA data; if (!d->modified) { return 0; } data = unparse_share_modes(d); if (data.dptr == NULL) { if (!d->fresh) { /* There has been an entry before, delete it */ status = dbwrap_record_delete(d->record); if (!NT_STATUS_IS_OK(status)) { char *errmsg; DEBUG(0, ("delete_rec returned %s\n", nt_errstr(status))); if (asprintf(&errmsg, "could not delete share " "entry: %s\n", nt_errstr(status)) == -1) { smb_panic("could not delete share" "entry"); } smb_panic(errmsg); } } /* * Nothing to store in cache - allow the normal * release of record lock and memory free. */ return 0; } status = dbwrap_record_store(d->record, data, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { char *errmsg; DEBUG(0, ("store returned %s\n", nt_errstr(status))); if (asprintf(&errmsg, "could not store share mode entry: %s", nt_errstr(status)) == -1) { smb_panic("could not store share mode entry"); } smb_panic(errmsg); } /* * Release the record lock before putting in the cache. */ TALLOC_FREE(d->record); /* * Reparent d into the in-memory cache so it can be reused if the * sequence number matches. See parse_share_modes() * for details. */ share_mode_memcache_store(d); return -1; }