/**
     \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;
}
示例#2
0
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);
}
示例#3
0
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;
	}
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
文件: smbXsrv_open.c 项目: hef/samba
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;
}
示例#9
0
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);
}
示例#10
0
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;
}
示例#11
0
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);
}
示例#12
0
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;
}
示例#14
0
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;
}
示例#15
0
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);
}
示例#16
0
/**
 * 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;
}
示例#17
0
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);
}
示例#18
0
文件: smbXsrv_open.c 项目: hef/samba
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;
}