/** \details Test the Compressed RTF compression routine. This function: -# Loads some test data and checks it -# Compresses the test data -# Checks that the compressed data matches the expected result \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_rtfcp(struct mapitest *mt) { enum MAPISTATUS retval; uint8_t *compressed; size_t compressed_length; char *compressed_hex; /* compress the test data */ retval = compress_rtf(mt->mem_ctx, RTF_UNCOMPRESSED1, sizeof(RTF_UNCOMPRESSED1) - 1, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "compress_rtf - step 1 (bad retval)"); return false; } /* Check the compressed result matches the compressed array */ compressed_hex = hex_encode_talloc(mt->mem_ctx, compressed, compressed_length); if (strncasecmp(compressed_hex, RTF_COMPRESSED1_HEX, (size_t)98) != 0) { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED1 - mismatch\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED1_HEX); mapitest_print(mt, "- %s\n", compressed_hex); return false; } else { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED1 - match\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED1_HEX); mapitest_print(mt, "- %s\n", compressed_hex); } talloc_free(compressed_hex); talloc_free(compressed); /* compress the test data */ retval = compress_rtf(mt->mem_ctx, RTF_UNCOMPRESSED2, sizeof(RTF_UNCOMPRESSED2) - 1, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "compress_rtf - step 2 (bad retval)"); return false; } // Check the compressed result matches the compressed array. compressed_hex = hex_encode_talloc(mt->mem_ctx, compressed, compressed_length); if (strncasecmp(compressed_hex, RTF_COMPRESSED2_HEX, sizeof(RTF_COMPRESSED2_HEX)) != 0) { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED2 - mismatch\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED2_HEX); mapitest_print(mt, "- %s\n", compressed_hex); return false; } else { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED2 - match\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED2_HEX); mapitest_print(mt, "- %s\n", compressed_hex); } talloc_free(compressed_hex); talloc_free(compressed); return true; }
char *sid_binstring_hex_talloc(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { int len = ndr_size_dom_sid(sid, 0); uint8_t buf[len]; sid_linearize(buf, len, sid); return hex_encode_talloc(mem_ctx, buf, len); }
static void display_winreg_data(const char *v, enum winreg_Type type, uint8_t *data, uint32_t length) { int i; union winreg_Data r; DATA_BLOB blob = data_blob_const(data, length); WERROR result; result = pull_winreg_Data(talloc_tos(), &blob, &r, type); if (!W_ERROR_IS_OK(result)) { return; } switch (type) { case REG_DWORD: printf("%s: REG_DWORD: 0x%08x\n", v, r.value); break; case REG_SZ: printf("%s: REG_SZ: %s\n", v, r.string); break; case REG_BINARY: { char *hex = hex_encode_talloc(NULL, r.binary.data, r.binary.length); size_t len; printf("%s: REG_BINARY:", v); len = strlen(hex); for (i=0; i<len; i++) { if (hex[i] == '\0') { break; } if (i%40 == 0) { putchar('\n'); } putchar(hex[i]); } TALLOC_FREE(hex); putchar('\n'); break; } case REG_MULTI_SZ: printf("%s: REG_MULTI_SZ: ", v); for (i=0; r.string_array[i] != NULL; i++) { printf("%s ", r.string_array[i]); } printf("\n"); break; default: printf("%s: unknown type 0x%02x:\n", v, type); break; } }
static NTSTATUS smbXsrv_open_global_parse_record(TALLOC_CTX *mem_ctx, struct db_record *rec, struct smbXsrv_open_global0 **global) { TDB_DATA key = dbwrap_record_get_key(rec); TDB_DATA val = dbwrap_record_get_value(rec); DATA_BLOB blob = data_blob_const(val.dptr, val.dsize); struct smbXsrv_open_globalB global_blob; enum ndr_err_code ndr_err; NTSTATUS status; TALLOC_CTX *frame = talloc_stackframe(); ndr_err = ndr_pull_struct_blob(&blob, frame, &global_blob, (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_open_globalB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(1,("Invalid record in smbXsrv_open_global.tdb:" "key '%s' ndr_pull_struct_blob - %s\n", hex_encode_talloc(frame, key.dptr, key.dsize), ndr_errstr(ndr_err))); status = ndr_map_error2ntstatus(ndr_err); goto done; } if (global_blob.version != SMBXSRV_VERSION_0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; DEBUG(1,("Invalid record in smbXsrv_open_global.tdb:" "key '%s' unsuported version - %d - %s\n", hex_encode_talloc(frame, key.dptr, key.dsize), (int)global_blob.version, nt_errstr(status))); goto done; } *global = talloc_move(mem_ctx, &global_blob.info.info0); status = NT_STATUS_OK; done: talloc_free(frame); return status; }
NTSTATUS smbXsrv_tcon_update(struct smbXsrv_tcon *tcon) { struct smbXsrv_tcon_table *table = tcon->table; NTSTATUS status; uint8_t key_buf[SMBXSRV_TCON_GLOBAL_TDB_KEY_SIZE]; TDB_DATA key; if (tcon->global->db_rec != NULL) { DEBUG(0, ("smbXsrv_tcon_update(0x%08x): " "Called with db_rec != NULL'\n", tcon->global->tcon_global_id)); return NT_STATUS_INTERNAL_ERROR; } key = smbXsrv_tcon_global_id_to_key(tcon->global->tcon_global_id, key_buf); tcon->global->db_rec = dbwrap_fetch_locked(table->global.db_ctx, tcon->global, key); if (tcon->global->db_rec == NULL) { DEBUG(0, ("smbXsrv_tcon_update(0x%08x): " "Failed to lock global key '%s'\n", tcon->global->tcon_global_id, hex_encode_talloc(talloc_tos(), key.dptr, key.dsize))); return NT_STATUS_INTERNAL_DB_ERROR; } status = smbXsrv_tcon_global_store(tcon->global); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_tcon_update: " "global_id (0x%08x) store failed - %s\n", tcon->global->tcon_global_id, nt_errstr(status))); 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_update: global_id (0x%08x) stored\n", tcon->global->tcon_global_id)); NDR_PRINT_DEBUG(smbXsrv_tconB, &tcon_blob); } return NT_STATUS_OK; }
WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, const struct ldb_val *prefixMap, const struct ldb_val *schemaInfo) { WERROR werr; const char *schema_info; struct dsdb_schema_prefixmap *pfm; TALLOC_CTX *mem_ctx; /* verify schemaInfo blob is valid one */ if (!dsdb_schema_info_blob_is_valid(schemaInfo)) { DEBUG(0,(__location__": dsdb_schema_info_blob_is_valid() failed.\n")); return WERR_INVALID_PARAMETER; } mem_ctx = talloc_new(schema); W_ERROR_HAVE_NO_MEMORY(mem_ctx); /* fetch prefixMap */ werr = _dsdb_prefixmap_from_ldb_val(prefixMap, mem_ctx, &pfm); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " _dsdb_prefixmap_from_ldb_val failed: %s\n", win_errstr(werr))); talloc_free(mem_ctx); return werr; } /* decode schema_info */ schema_info = hex_encode_talloc(mem_ctx, schemaInfo->data, schemaInfo->length); if (!schema_info) { talloc_free(mem_ctx); return WERR_NOMEM; } /* store prefixMap and schema_info into cached Schema */ talloc_free(schema->prefixmap); schema->prefixmap = talloc_steal(schema, pfm); talloc_free(discard_const(schema->schema_info)); schema->schema_info = talloc_steal(schema, schema_info); /* clean up locally allocated mem */ talloc_free(mem_ctx); return WERR_OK; }
WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, const struct ldb_val *prefixMap, const struct ldb_val *schemaInfo) { WERROR status; const char *schema_info; struct dsdb_schema_prefixmap *pfm; TALLOC_CTX *mem_ctx; /* verify input params */ if (schemaInfo->length != 21) { return WERR_INVALID_PARAMETER; } if (schemaInfo->data[0] != 0xFF) { return WERR_INVALID_PARAMETER; } mem_ctx = talloc_new(schema); W_ERROR_HAVE_NO_MEMORY(mem_ctx); /* fetch prefixMap */ status = _dsdb_prefixmap_from_ldb_val(prefixMap, schema->iconv_convenience, mem_ctx, &pfm); W_ERROR_NOT_OK_RETURN(status); /* decode schema_info */ schema_info = hex_encode_talloc(mem_ctx, schemaInfo->data, schemaInfo->length); if (!schema_info) { talloc_free(mem_ctx); return WERR_NOMEM; } /* store prefixMap and schema_info into cached Schema */ talloc_free(schema->prefixmap); schema->prefixmap = talloc_steal(schema, pfm); talloc_free(discard_const(schema->schema_info)); schema->schema_info = talloc_steal(schema, schema_info); /* clean up locally allocated mem */ talloc_free(mem_ctx); return WERR_OK; }
static NTSTATUS smbXsrv_open_global_lookup(struct smbXsrv_open_table *table, uint32_t open_global_id, 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; *_global = NULL; if (table->global.db_ctx == NULL) { 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); 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; } smbXsrv_open_global_verify_record(global_rec, &is_free, NULL, mem_ctx, _global); if (is_free) { talloc_free(global_rec); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } (*_global)->db_rec = talloc_move(*_global, &global_rec); talloc_set_destructor(*_global, smbXsrv_open_global_destructor); return NT_STATUS_OK; }
static void db_ntdb_log_key(const char *prefix, NTDB_DATA key) { size_t len; char *keystr; if (DEBUGLEVEL < 10) { return; } len = key.dsize; if (DEBUGLEVEL == 10) { /* * Only fully spam at debuglevel > 10 */ len = MIN(10, key.dsize); } keystr = hex_encode_talloc(talloc_tos(), (unsigned char *)(key.dptr), len); DEBUG(10, ("%s key %s\n", prefix, keystr)); TALLOC_FREE(keystr); }
static struct db_record *smbXsrv_session_local_fetch_locked( struct db_context *db, uint32_t id, TALLOC_CTX *mem_ctx) { TDB_DATA key; uint8_t key_buf[SMBXSRV_SESSION_LOCAL_TDB_KEY_SIZE]; struct db_record *rec = NULL; key = smbXsrv_session_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 void db_tdb_log_key(const char *prefix, TDB_DATA key) { size_t len; char *keystr; TALLOC_CTX *frame; if (DEBUGLEVEL < 10) { return; } frame = talloc_stackframe(); len = key.dsize; if (DEBUGLEVEL == 10) { /* * Only fully spam at debuglevel > 10 */ len = MIN(10, key.dsize); } keystr = hex_encode_talloc(frame, (unsigned char *)(key.dptr), len); DEBUG(10, ("%s key %s\n", prefix, keystr)); TALLOC_FREE(frame); }
NTSTATUS smbXsrv_tcon_disconnect(struct smbXsrv_tcon *tcon, uint64_t vuid) { struct smbXsrv_tcon_table *table; struct db_record *local_rec = NULL; struct db_record *global_rec = NULL; NTSTATUS status; NTSTATUS error = NT_STATUS_OK; if (tcon->table == NULL) { return NT_STATUS_OK; } table = tcon->table; tcon->table = NULL; tcon->status = NT_STATUS_NETWORK_NAME_DELETED; global_rec = tcon->global->db_rec; tcon->global->db_rec = NULL; if (global_rec == NULL) { uint8_t key_buf[SMBXSRV_TCON_GLOBAL_TDB_KEY_SIZE]; TDB_DATA key; key = smbXsrv_tcon_global_id_to_key( tcon->global->tcon_global_id, key_buf); global_rec = dbwrap_fetch_locked(table->global.db_ctx, tcon->global, key); if (global_rec == NULL) { DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "Failed to lock global key '%s'\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(global_rec, key.dptr, key.dsize))); error = NT_STATUS_INTERNAL_ERROR; } } if (global_rec != NULL) { status = dbwrap_record_delete(global_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(global_rec); DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "failed to delete global key '%s': %s\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(global_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } } TALLOC_FREE(global_rec); local_rec = tcon->db_rec; if (local_rec == NULL) { uint8_t key_buf[SMBXSRV_TCON_LOCAL_TDB_KEY_SIZE]; TDB_DATA key; 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) { DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "Failed to lock local key '%s'\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(local_rec, key.dptr, key.dsize))); error = NT_STATUS_INTERNAL_ERROR; } } if (local_rec != NULL) { status = dbwrap_record_delete(local_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(local_rec); DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "failed to delete local key '%s': %s\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(local_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } table->local.num_tcons -= 1; } if (tcon->db_rec == NULL) { TALLOC_FREE(local_rec); } tcon->db_rec = NULL; if (tcon->compat) { bool ok; ok = set_current_service(tcon->compat, 0, true); if (!ok) { status = NT_STATUS_INTERNAL_ERROR; DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "set_current_service() failed: %s\n", tcon->global->tcon_global_id, tcon->global->share_name, nt_errstr(status))); tcon->compat = NULL; return status; } close_cnum(tcon->compat, vuid); tcon->compat = NULL; } return error; }
/** \details Test the Compressed RTF compression / decompression routines on a larger file \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_rtfcp_large(struct mapitest *mt) { enum MAPISTATUS retval; char *filename = NULL; char *original_uncompressed_data; size_t original_uncompressed_length; char *original_uncompressed_hex; uint8_t *compressed; size_t compressed_length; DATA_BLOB decompressed; char *decompressed_hex; /* load the test file */ filename = talloc_asprintf(mt->mem_ctx, "%s/testcase.rtf", LZFU_DATADIR); original_uncompressed_data = file_load(filename, &original_uncompressed_length, 0, mt->mem_ctx); if (!original_uncompressed_data) { perror(filename); mapitest_print(mt, "%s: Error while loading %s\n", __FUNCTION__, filename); talloc_free(filename); return false; } talloc_free(filename); original_uncompressed_hex = hex_encode_talloc(mt->mem_ctx, (const unsigned char*)original_uncompressed_data, original_uncompressed_length); /* compress it */ retval = compress_rtf(mt->mem_ctx, original_uncompressed_data, original_uncompressed_length, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapitest_noserver_rtfcp_large - step 1 (bad retval)", retval); return false; } /* decompress it */ retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &decompressed); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapitest_noserver_rtfcp_large - step 2 (bad retval)", retval); return false; } mapitest_print(mt, "Original data size = 0x%zx\n", original_uncompressed_length); mapitest_print(mt, "Decompressed size = 0x%zx\n", decompressed.length); { int i; int min; min = (original_uncompressed_length >= decompressed.length) ? decompressed.length : original_uncompressed_length; mapitest_print(mt, "Comparing data over 0x%x bytes\n", min); for (i = 0; i < min; i++) { if (decompressed.data[i] != original_uncompressed_data[i]) { mapitest_print(mt, "Bytes differ at offset 0x%x: original (0x%.2x) decompressed (0x%.2x)\n", i, original_uncompressed_data[i], decompressed.data[i]); } } } /* check the uncompressed version (less trailing null) matches the original test file contents */ decompressed_hex = hex_encode_talloc(mt->mem_ctx, decompressed.data, decompressed.length -1); if (strncasecmp(original_uncompressed_hex, decompressed_hex, original_uncompressed_length) != 0) { mapitest_print(mt, "* %-40s: compare results - mismatch\n", "RTFCP_LARGE"); return false; } else { mapitest_print(mt, "* %-40s: compare results - match\n", "RTFCP_LARGE"); // mapitest_print(mt, "- %s\n", original_uncompressed_hex); // mapitest_print(mt, "- %s\n", decompressed_hex); } /* clean up */ talloc_free(decompressed_hex); talloc_free(compressed); talloc_free(original_uncompressed_hex); return true; }
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 void smbXsrv_tcon_global_verify_record(struct db_record *db_rec, bool *is_free, bool *was_free, TALLOC_CTX *mem_ctx, struct smbXsrv_tcon_global0 **_g) { TDB_DATA key; TDB_DATA val; DATA_BLOB blob; struct smbXsrv_tcon_globalB global_blob; enum ndr_err_code ndr_err; struct smbXsrv_tcon_global0 *global = NULL; bool exists; TALLOC_CTX *frame = talloc_stackframe(); *is_free = false; if (was_free) { *was_free = false; } if (_g) { *_g = NULL; } key = dbwrap_record_get_key(db_rec); val = dbwrap_record_get_value(db_rec); if (val.dsize == 0) { TALLOC_FREE(frame); *is_free = true; if (was_free) { *was_free = true; } return; } blob = data_blob_const(val.dptr, val.dsize); ndr_err = ndr_pull_struct_blob(&blob, frame, &global_blob, (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_tcon_globalB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); DEBUG(1,("smbXsrv_tcon_global_verify_record: " "key '%s' ndr_pull_struct_blob - %s\n", hex_encode_talloc(frame, key.dptr, key.dsize), nt_errstr(status))); TALLOC_FREE(frame); return; } DEBUG(10,("smbXsrv_tcon_global_verify_record\n")); if (DEBUGLVL(10)) { NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); } if (global_blob.version != SMBXSRV_VERSION_0) { DEBUG(0,("smbXsrv_tcon_global_verify_record: " "key '%s' use unsupported version %u\n", hex_encode_talloc(frame, key.dptr, key.dsize), global_blob.version)); NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); TALLOC_FREE(frame); return; } global = global_blob.info.info0; exists = serverid_exists(&global->server_id); if (!exists) { struct server_id_buf idbuf; DEBUG(2,("smbXsrv_tcon_global_verify_record: " "key '%s' server_id %s does not exist.\n", hex_encode_talloc(frame, key.dptr, key.dsize), server_id_str_buf(global->server_id, &idbuf))); if (DEBUGLVL(2)) { NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); } TALLOC_FREE(frame); dbwrap_record_delete(db_rec); *is_free = true; return; } if (_g) { *_g = talloc_move(mem_ctx, &global); } TALLOC_FREE(frame); }
/** * Increments schemaInfo revision and save it to DB * setting our invocationID in the process * NOTE: this function should be called in a transaction * much in the same way prefixMap update function is called * * @param ldb_module current module * @param schema schema cache * @param dsdb_flags DSDB_FLAG_... flag of 0 */ int dsdb_module_schema_info_update(struct ldb_module *ldb_module, struct dsdb_schema *schema, int dsdb_flags, struct ldb_request *parent) { int ret; const struct GUID *invocation_id; DATA_BLOB ndr_blob; struct dsdb_schema_info *schema_info; const char *schema_info_str; WERROR werr; TALLOC_CTX *temp_ctx = talloc_new(schema); if (temp_ctx == NULL) { return ldb_module_oom(ldb_module); } invocation_id = samdb_ntds_invocation_id(ldb_module_get_ctx(ldb_module)); if (!invocation_id) { talloc_free(temp_ctx); return ldb_operr(ldb_module_get_ctx(ldb_module)); } /* read serialized schemaInfo from LDB */ ret = dsdb_module_schema_info_read(ldb_module, dsdb_flags, temp_ctx, &schema_info, parent); if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { /* make default value in case * we have no schemaInfo value yet */ werr = dsdb_schema_info_new(temp_ctx, &schema_info); if (!W_ERROR_IS_OK(werr)) { talloc_free(temp_ctx); return ldb_module_oom(ldb_module); } ret = LDB_SUCCESS; } if (ret != LDB_SUCCESS) { talloc_free(temp_ctx); return ret; } /* update schemaInfo */ schema_info->revision++; schema_info->invocation_id = *invocation_id; ret = dsdb_module_schema_info_write(ldb_module, dsdb_flags, schema_info, parent); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_module), "dsdb_module_schema_info_update: failed to save schemaInfo - %s\n", ldb_strerror(ret)); talloc_free(temp_ctx); return ret; } /* finally, update schema_info in the cache */ werr = dsdb_blob_from_schema_info(schema_info, temp_ctx, &ndr_blob); if (!W_ERROR_IS_OK(werr)) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_module), "Failed to get schema info"); talloc_free(temp_ctx); return ldb_operr(ldb_module_get_ctx(ldb_module)); } schema_info_str = hex_encode_talloc(schema, ndr_blob.data, ndr_blob.length); if (!schema_info_str) { talloc_free(temp_ctx); return ldb_module_oom(ldb_module); } talloc_unlink(schema, discard_const(schema->schema_info)); schema->schema_info = schema_info_str; talloc_free(temp_ctx); return LDB_SUCCESS; }
uint32_t smbXsrv_open_hash(struct smbXsrv_open *_open) { 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); 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; if (op->global->db_rec != NULL) { DEBUG(0, ("smbXsrv_open_update(0x%08x): " "Called with db_rec != NULL'\n", op->global->open_global_id)); return NT_STATUS_INTERNAL_ERROR; } 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) { return NT_STATUS_INTERNAL_DB_ERROR; } status = smbXsrv_open_global_store(op->global); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_open_update: " "global_id (0x%08x) store failed - %s\n", op->global->open_global_id, nt_errstr(status))); return status; } 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); open_blob.version = SMBXSRV_VERSION_0; open_blob.info.info0 = op; DEBUG(10,("smbXsrv_open_update: global_id (0x%08x) stored\n", op->global->open_global_id)); NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob); } return NT_STATUS_OK; } NTSTATUS smbXsrv_open_close(struct smbXsrv_open *op, NTTIME now) { struct smbXsrv_open_table *table; struct db_record *local_rec = NULL; struct db_record *global_rec = NULL; 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 error; } table = op->table; op->table = NULL; op->status = NT_STATUS_FILE_CLOSED; op->global->disconnect_time = now; server_id_set_disconnected(&op->global->server_id); global_rec = op->global->db_rec; op->global->db_rec = NULL; if (global_rec == NULL) { global_rec = smbXsrv_open_global_fetch_locked( table->global.db_ctx, op->global->open_global_id, op->global /* TALLOC_CTX */); if (global_rec == NULL) { error = NT_STATUS_INTERNAL_ERROR; } } if (global_rec != NULL && op->global->durable) { /* * If it is a durable open we need to update the global part * instead of deleting it */ op->global->db_rec = global_rec; status = smbXsrv_open_global_store(op->global); if (NT_STATUS_IS_OK(status)) { /* * smbXsrv_open_global_store does the free * of op->global->db_rec */ global_rec = NULL; } if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_open_close(0x%08x)" "smbXsrv_open_global_store() failed - %s\n", op->global->open_global_id, nt_errstr(status))); error = status; } if (NT_STATUS_IS_OK(status) && 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_close(0x%08x): " "stored disconnect\n", op->global->open_global_id)); NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob); } } if (global_rec != NULL) { status = dbwrap_record_delete(global_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(global_rec); DEBUG(0, ("smbXsrv_open_close(0x%08x): " "failed to delete global key '%s': %s\n", op->global->open_global_id, hex_encode_talloc(global_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } } TALLOC_FREE(global_rec); local_rec = op->db_rec; if (local_rec == NULL) { local_rec = smbXsrv_open_local_fetch_locked(table->local.db_ctx, op->local_id, op /* TALLOC_CTX*/); if (local_rec == NULL) { error = NT_STATUS_INTERNAL_ERROR; } } if (local_rec != NULL) { status = dbwrap_record_delete(local_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(local_rec); DEBUG(0, ("smbXsrv_open_close(0x%08x): " "failed to delete local key '%s': %s\n", op->global->open_global_id, hex_encode_talloc(local_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } table->local.num_opens -= 1; } if (op->db_rec == NULL) { TALLOC_FREE(local_rec); } op->db_rec = NULL; if (op->compat) { op->compat->op = NULL; file_free(NULL, op->compat); op->compat = NULL; } return error; } NTSTATUS smb1srv_open_table_init(struct smbXsrv_connection *conn) { uint32_t max_opens; /* * Allow a range from 1..65534. * * With real_max_open_files possible ids, * truncated to the SMB1 limit of 16-bit. * * 0 and 0xFFFF are no valid ids. */ 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); }
NTSTATUS smbXsrv_open_close(struct smbXsrv_open *op, NTTIME now) { struct smbXsrv_open_table *table; struct db_record *local_rec = NULL; struct db_record *global_rec = NULL; NTSTATUS status; NTSTATUS error = NT_STATUS_OK; if (op->table == NULL) { return NT_STATUS_OK; } table = op->table; op->table = NULL; op->status = NT_STATUS_FILE_CLOSED; op->global->disconnect_time = now; server_id_set_disconnected(&op->global->server_id); 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); 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; } } if (global_rec != NULL && op->global->durable) { /* * If it is a durable open we need to update the global part * instead of deleting it */ op->global->db_rec = global_rec; status = smbXsrv_open_global_store(op->global); if (NT_STATUS_IS_OK(status)) { /* * smbXsrv_open_global_store does the free * of op->global->db_rec */ global_rec = NULL; } if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smbXsrv_open_close(0x%08x)" "smbXsrv_open_global_store() failed - %s\n", op->global->open_global_id, nt_errstr(status))); error = status; } if (NT_STATUS_IS_OK(status) && 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_close(0x%08x): " "stored disconnect\n", op->global->open_global_id)); NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob); } } if (global_rec != NULL) { status = dbwrap_record_delete(global_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(global_rec); DEBUG(0, ("smbXsrv_open_close(0x%08x): " "failed to delete global key '%s': %s\n", op->global->open_global_id, hex_encode_talloc(global_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } } TALLOC_FREE(global_rec); 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); 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; } } if (local_rec != NULL) { status = dbwrap_record_delete(local_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(local_rec); DEBUG(0, ("smbXsrv_open_close(0x%08x): " "failed to delete local key '%s': %s\n", op->global->open_global_id, hex_encode_talloc(local_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } table->local.num_opens -= 1; } if (op->db_rec == NULL) { TALLOC_FREE(local_rec); } op->db_rec = NULL; if (op->compat) { op->compat->op = NULL; file_free(NULL, op->compat); op->compat = NULL; } return error; }