Ejemplo n.º 1
0
static NTSTATUS init_registry_data_action(struct db_context *db,
					  void *private_data)
{
	NTSTATUS status;
	TALLOC_CTX *frame = talloc_stackframe();
	struct regval_ctr *values;
	int i;

	/* loop over all of the predefined paths and add each component */

	for (i=0; builtin_registry_paths[i] != NULL; i++) {
		if (regdb_key_exists(db, builtin_registry_paths[i])) {
			continue;
		}
		status = werror_to_ntstatus(init_registry_key_internal(db,
						  builtin_registry_paths[i]));
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
	}

	/* loop over all of the predefined values and add each component */

	for (i=0; builtin_registry_values[i].path != NULL; i++) {
		WERROR werr;

		werr = regval_ctr_init(frame, &values);
		if (!W_ERROR_IS_OK(werr)) {
			status = werror_to_ntstatus(werr);
			goto done;
		}

		regdb_fetch_values_internal(db,
					    builtin_registry_values[i].path,
					    values);

		/* preserve existing values across restarts. Only add new ones */

		if (!regval_ctr_key_exists(values,
					builtin_registry_values[i].valuename))
		{
			regdb_ctr_add_value(values,
					    &builtin_registry_values[i]);
			status = regdb_store_values_internal(db,
					builtin_registry_values[i].path,
					values);
			if (!NT_STATUS_IS_OK(status)) {
				goto done;
			}
		}
		TALLOC_FREE(values);
	}

	status = NT_STATUS_OK;

done:

	TALLOC_FREE(frame);
	return status;
}
Ejemplo n.º 2
0
WERROR init_registry_data(void)
{
	WERROR werr;
	TALLOC_CTX *frame = talloc_stackframe();
	struct regval_ctr *values;
	int i;

	/*
	 * First, check for the existence of the needed keys and values.
	 * If all do already exist, we can save the writes.
	 */
	for (i=0; builtin_registry_paths[i] != NULL; i++) {
		if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
			goto do_init;
		}
	}

	for (i=0; builtin_registry_values[i].path != NULL; i++) {
		werr = regval_ctr_init(frame, &values);
		W_ERROR_NOT_OK_GOTO_DONE(werr);

		regdb_fetch_values_internal(regdb,
					    builtin_registry_values[i].path,
					    values);
		if (!regval_ctr_key_exists(values,
					builtin_registry_values[i].valuename))
		{
			TALLOC_FREE(values);
			goto do_init;
		}

		TALLOC_FREE(values);
	}

	werr = WERR_OK;
	goto done;

do_init:

	/*
	 * There are potentially quite a few store operations which are all
	 * indiviually wrapped in tdb transactions. Wrapping them in a single
	 * transaction gives just a single transaction_commit() to actually do
	 * its fsync()s. See tdb/common/transaction.c for info about nested
	 * transaction behaviour.
	 */

	werr = regdb_trans_do(regdb,
			      init_registry_data_action,
			      NULL);

done:
	TALLOC_FREE(frame);
	return werr;
}
Ejemplo n.º 3
0
static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
                                REGF_NK_REC *parent, REGF_FILE *outfile,
                                const char *parentpath  )
{
	REGF_NK_REC *key, *subkey;
	struct security_descriptor *new_sd;
	struct regval_ctr *values;
	struct regsubkey_ctr *subkeys;
	int i;
	char *path;
	WERROR werr;

	/* swap out the SIDs in the security descriptor */

	if ( !(new_sd = dup_sec_desc( outfile->mem_ctx, nk->sec_desc->sec_desc )) ) {
		fprintf( stderr, "Failed to copy security descriptor!\n" );
		return False;
	}

	verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname);
	swap_sid_in_acl( new_sd, &old_sid, &new_sid );

	werr = regsubkey_ctr_init(NULL, &subkeys);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
		return False;
	}

	werr = regval_ctr_init(subkeys, &values);
	if (!W_ERROR_IS_OK(werr)) {
		TALLOC_FREE( subkeys );
		DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
		return False;
	}

	/* copy values into the struct regval_ctr */

	for ( i=0; i<nk->num_values; i++ ) {
		regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
			nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
	}

	/* copy subkeys into the struct regsubkey_ctr */

	while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
		regsubkey_ctr_addkey( subkeys, subkey->keyname );
	}

	key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent );

	/* write each one of the subkeys out */

	path = talloc_asprintf(subkeys, "%s%s%s",
			parentpath, parent ? "\\" : "",nk->keyname);
	if (!path) {
		TALLOC_FREE( subkeys );
		return false;
	}

	nk->subkey_index = 0;
	while ((subkey = regfio_fetch_subkey(infile, nk))) {
		if (!copy_registry_tree( infile, subkey, key, outfile, path)) {
			TALLOC_FREE(subkeys);
			return false;
		}
	}


	verbose_output("[%s]\n", path);

	/* values is a talloc()'d child of subkeys here so just throw it all away */
	TALLOC_FREE(subkeys);

	return True;
}
Ejemplo n.º 4
0
static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
			    REGF_NK_REC *key)
{
	REGF_NK_REC *subkey;
	struct registry_key_handle registry_key;
	struct regval_ctr *values;
	struct regsubkey_ctr *subkeys;
	int i;
	char *path = NULL;
	WERROR result = WERR_OK;

	/* initialize the struct registry_key_handle structure */

	registry_key.ops = reghook_cache_find(topkeypath);
	if (!registry_key.ops) {
		DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
			  "to [%s]\n", topkeypath));
		return WERR_BADFILE;
	}

	registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
	if (!registry_key.name) {
		DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
		return WERR_NOMEM;
	}

	/* now start parsing the values and subkeys */

	result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
	W_ERROR_NOT_OK_RETURN(result);

	result = regval_ctr_init(subkeys, &values);
	W_ERROR_NOT_OK_RETURN(result);

	/* copy values into the struct regval_ctr */

	for (i=0; i<key->num_values; i++) {
		regval_ctr_addvalue(values, key->values[i].valuename,
				    key->values[i].type,
				    key->values[i].data,
				    (key->values[i].data_size & ~VK_DATA_IN_OFFSET));
	}

	/* copy subkeys into the struct regsubkey_ctr */

	key->subkey_index = 0;
	while ((subkey = regfio_fetch_subkey( regfile, key ))) {
		result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
		if (!W_ERROR_IS_OK(result)) {
			TALLOC_FREE(subkeys);
			return result;
		}
	}

	/* write this key and values out */

	if (!store_reg_values(&registry_key, values)
	    || !store_reg_keys(&registry_key, subkeys))
	{
		DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
		result = WERR_REG_IO_FAILURE;
	}

	TALLOC_FREE(subkeys);

	if (!W_ERROR_IS_OK(result)) {
		return result;
	}

	/* now continue to load each subkey registry tree */

	key->subkey_index = 0;
	while ((subkey = regfio_fetch_subkey(regfile, key))) {
		path = talloc_asprintf(regfile->mem_ctx,
				       "%s\\%s",
				       topkeypath,
				       subkey->keyname);
		if (path == NULL) {
			return WERR_NOMEM;
		}
		result = reg_load_tree(regfile, path, subkey);
		if (!W_ERROR_IS_OK(result)) {
			break;
		}
	}

	return result;
}
Ejemplo n.º 5
0
static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
			     REGF_NK_REC *parent)
{
	REGF_NK_REC *key;
	struct regval_ctr *values;
	struct regsubkey_ctr *subkeys;
	int i, num_subkeys;
	char *key_tmp = NULL;
	char *keyname, *parentpath;
	char *subkeypath = NULL;
	char *subkeyname;
	struct registry_key_handle registry_key;
	WERROR result = WERR_OK;
	struct security_descriptor *sec_desc = NULL;

	if (!regfile) {
		return WERR_GENERAL_FAILURE;
	}

	if (!keypath) {
		return WERR_OBJECT_PATH_INVALID;
	}

	/* split up the registry key path */

	key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
	if (!key_tmp) {
		return WERR_NOMEM;
	}
	if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
		return WERR_OBJECT_PATH_INVALID;
	}

	if (!keyname) {
		keyname = parentpath;
	}

	/* we need a registry_key_handle object here to enumerate subkeys and values */

	ZERO_STRUCT(registry_key);

	registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
	if (registry_key.name == NULL) {
		return WERR_NOMEM;
	}

	registry_key.ops = reghook_cache_find(registry_key.name);
	if (registry_key.ops == NULL) {
		return WERR_BADFILE;
	}

	/* lookup the values and subkeys */

	result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
	W_ERROR_NOT_OK_RETURN(result);

	result = regval_ctr_init(subkeys, &values);
	W_ERROR_NOT_OK_RETURN(result);

	fetch_reg_keys(&registry_key, subkeys);
	fetch_reg_values(&registry_key, values);

	result = regkey_get_secdesc(regfile->mem_ctx, &registry_key, &sec_desc);
	if (!W_ERROR_IS_OK(result)) {
		goto done;
	}

	/* write out this key */

	key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
			       parent);
	if (key == NULL) {
		result = WERR_CAN_NOT_COMPLETE;
		goto done;
	}

	/* write each one of the subkeys out */

	num_subkeys = regsubkey_ctr_numkeys(subkeys);
	for (i=0; i<num_subkeys; i++) {
		subkeyname = regsubkey_ctr_specific_key(subkeys, i);
		subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
					     keypath, subkeyname);
		if (subkeypath == NULL) {
			result = WERR_NOMEM;
			goto done;
		}
		result = reg_write_tree(regfile, subkeypath, key);
		if (!W_ERROR_IS_OK(result))
			goto done;
	}

	DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));

done:
	TALLOC_FREE(subkeys);
	TALLOC_FREE(registry_key.name);

	return result;
}