Example #1
0
/**
 * Initialize a key in the registry:
 * create each component key of the specified path.
 */
static WERROR init_registry_key_internal(struct db_context *db,
					 const char *add_path)
{
	WERROR werr;
	TALLOC_CTX *frame = talloc_stackframe();
	char *path = NULL;
	char *base = NULL;
	char *remaining = NULL;
	char *keyname;
	char *subkeyname;
	struct regsubkey_ctr *subkeys;
	const char *p, *p2;

	DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path));

	path = talloc_strdup(frame, add_path);
	base = talloc_strdup(frame, "");
	if (!path || !base) {
		werr = WERR_NOMEM;
		goto fail;
	}
	p = path;

	while (next_token_talloc(frame, &p, &keyname, "\\")) {

		/* build up the registry path from the components */

		if (*base) {
			base = talloc_asprintf(frame, "%s\\", base);
			if (!base) {
				werr = WERR_NOMEM;
				goto fail;
			}
		}
		base = talloc_asprintf_append(base, "%s", keyname);
		if (!base) {
			werr = WERR_NOMEM;
			goto fail;
		}

		/* get the immediate subkeyname (if we have one ) */

		subkeyname = talloc_strdup(frame, "");
		if (!subkeyname) {
			werr = WERR_NOMEM;
			goto fail;
		}
		if (*p) {
			remaining = talloc_strdup(frame, p);
			if (!remaining) {
				werr = WERR_NOMEM;
				goto fail;
			}
			p2 = remaining;

			if (!next_token_talloc(frame, &p2,
						&subkeyname, "\\"))
			{
				subkeyname = talloc_strdup(frame,p2);
				if (!subkeyname) {
					werr = WERR_NOMEM;
					goto fail;
				}
			}
		}

		DEBUG(10,("init_registry_key: Storing key [%s] with "
			  "subkey [%s]\n", base,
			  *subkeyname ? subkeyname : "NULL"));

		/* we don't really care if the lookup succeeds or not
		 * since we are about to update the record.
		 * We just want any subkeys already present */

		werr = regsubkey_ctr_init(frame, &subkeys);
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(0,("talloc() failure!\n"));
			goto fail;
		}

		werr = regdb_fetch_keys_internal(db, base, subkeys);
		if (!W_ERROR_IS_OK(werr) &&
		    !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
		{
			goto fail;
		}

		if (*subkeyname) {
			werr = regsubkey_ctr_addkey(subkeys, subkeyname);
			if (!W_ERROR_IS_OK(werr)) {
				goto fail;
			}
		}
		if (!regdb_store_keys_internal(db, base, subkeys)) {
			werr = WERR_CAN_NOT_COMPLETE;
			goto fail;
		}
	}

	werr = WERR_OK;

fail:
	TALLOC_FREE(frame);
	return werr;
}
Example #2
0
bool eventlog_init_keys(void)
{
    /* Find all of the eventlogs, add keys for each of them */
    const char **elogs = lp_eventlog_list();
    char *evtlogpath = NULL;
    char *evtfilepath = NULL;
    struct regsubkey_ctr *subkeys;
    REGVAL_CTR *values;
    uint32 uiMaxSize;
    uint32 uiRetention;
    uint32 uiCategoryCount;
    UNISTR2 data;
    TALLOC_CTX *ctx = talloc_tos();
    WERROR werr;

    while (elogs && *elogs) {
        werr = regsubkey_ctr_init(ctx, &subkeys);
        if (!W_ERROR_IS_OK(werr)) {
            DEBUG( 0, ( "talloc() failure!\n" ) );
            return False;
        }
        regdb_fetch_keys(KEY_EVENTLOG, subkeys);
        regsubkey_ctr_addkey( subkeys, *elogs );
        if ( !regdb_store_keys( KEY_EVENTLOG, subkeys ) ) {
            TALLOC_FREE(subkeys);
            return False;
        }
        TALLOC_FREE(subkeys);

        /* add in the key of form KEY_EVENTLOG/Application */
        DEBUG( 5,
               ( "Adding key of [%s] to path of [%s]\n", *elogs,
                 KEY_EVENTLOG ) );

        evtlogpath = talloc_asprintf(ctx, "%s\\%s",
                                     KEY_EVENTLOG, *elogs);
        if (!evtlogpath) {
            return false;
        }
        /* add in the key of form KEY_EVENTLOG/Application/Application */
        DEBUG( 5,
               ( "Adding key of [%s] to path of [%s]\n", *elogs,
                 evtlogpath ) );
        werr = regsubkey_ctr_init(ctx, &subkeys);
        if (!W_ERROR_IS_OK(werr)) {
            DEBUG( 0, ( "talloc() failure!\n" ) );
            return False;
        }
        regdb_fetch_keys( evtlogpath, subkeys );
        regsubkey_ctr_addkey( subkeys, *elogs );

        if ( !regdb_store_keys( evtlogpath, subkeys ) ) {
            TALLOC_FREE(subkeys);
            return False;
        }
        TALLOC_FREE( subkeys );

        /* now add the values to the KEY_EVENTLOG/Application form key */
        if (!(values = TALLOC_ZERO_P(ctx, REGVAL_CTR))) {
            DEBUG( 0, ( "talloc() failure!\n" ) );
            return False;
        }
        DEBUG( 5,
               ( "Storing values to eventlog path of [%s]\n",
                 evtlogpath ) );
        regdb_fetch_values( evtlogpath, values );


        if (!regval_ctr_key_exists(values, "MaxSize")) {

            /* assume we have none, add them all */

            /* hard code some initial values */

            /* uiDisplayNameId = 0x00000100; */
            uiMaxSize = 0x00080000;
            uiRetention = 0x93A80;

            regval_ctr_addvalue(values, "MaxSize", REG_DWORD,
                                (char *)&uiMaxSize,
                                sizeof(uint32));

            regval_ctr_addvalue(values, "Retention", REG_DWORD,
                                (char *)&uiRetention,
                                sizeof(uint32));
            init_unistr2(&data, *elogs, UNI_STR_TERMINATE);

            regval_ctr_addvalue(values, "PrimaryModule", REG_SZ,
                                (char *)data.buffer,
                                data.uni_str_len *
                                sizeof(uint16));
            init_unistr2(&data, *elogs, UNI_STR_TERMINATE);

            regval_ctr_addvalue(values, "Sources", REG_MULTI_SZ,
                                (char *)data.buffer,
                                data.uni_str_len *
                                sizeof(uint16));

            evtfilepath = talloc_asprintf(ctx,
                                          "%%SystemRoot%%\\system32\\config\\%s.tdb",
                                          *elogs);
            if (!evtfilepath) {
                TALLOC_FREE(values);
            }
            init_unistr2(&data, evtfilepath, UNI_STR_TERMINATE);
            regval_ctr_addvalue(values, "File", REG_EXPAND_SZ, (char *)data.buffer,
                                data.uni_str_len * sizeof(uint16));
            regdb_store_values(evtlogpath, values);

        }

        TALLOC_FREE(values);

        /* now do the values under KEY_EVENTLOG/Application/Application */
        TALLOC_FREE(evtlogpath);
        evtlogpath = talloc_asprintf(ctx, "%s\\%s\\%s",
                                     KEY_EVENTLOG, *elogs, *elogs);
        if (!evtlogpath) {
            return false;
        }
        if (!(values = TALLOC_ZERO_P(ctx, REGVAL_CTR))) {
            DEBUG( 0, ( "talloc() failure!\n" ) );
            return False;
        }
        DEBUG( 5,
               ( "Storing values to eventlog path of [%s]\n",
                 evtlogpath));
        regdb_fetch_values(evtlogpath, values);
        if (!regval_ctr_key_exists( values, "CategoryCount")) {

            /* hard code some initial values */

            uiCategoryCount = 0x00000007;
            regval_ctr_addvalue( values, "CategoryCount",
                                 REG_DWORD,
                                 ( char * ) &uiCategoryCount,
                                 sizeof( uint32 ) );
            init_unistr2( &data,
                          "%SystemRoot%\\system32\\eventlog.dll",
                          UNI_STR_TERMINATE );

            regval_ctr_addvalue( values, "CategoryMessageFile",
                                 REG_EXPAND_SZ,
                                 ( char * ) data.buffer,
                                 data.uni_str_len *
                                 sizeof( uint16 ) );
            regdb_store_values( evtlogpath, values );
        }
        TALLOC_FREE(values);
        elogs++;
    }

    return true;
}
Example #3
0
static BOOL init_registry_data( void )
{
	pstring path, base, remaining;
	fstring keyname, subkeyname;
	REGSUBKEY_CTR *subkeys;
	REGVAL_CTR *values;
	int i;
	const char *p, *p2;
	UNISTR2 data;

	/*
	 * 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.
	 */

	if ( tdb_transaction_start( tdb_reg ) == -1 ) {
		DEBUG(0, ("init_registry_data: tdb_transaction_start "
			  "failed\n"));
		return False;
	}
	
	/* loop over all of the predefined paths and add each component */
	
	for ( i=0; builtin_registry_paths[i] != NULL; i++ ) {

		DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i]));

		pstrcpy( path, builtin_registry_paths[i] );
		pstrcpy( base, "" );
		p = path;
		
		while ( next_token(&p, keyname, "\\", sizeof(keyname)) ) {
		
			/* build up the registry path from the components */
			
			if ( *base )
				pstrcat( base, "\\" );
			pstrcat( base, keyname );
			
			/* get the immediate subkeyname (if we have one ) */
			
			*subkeyname = '\0';
			if ( *p ) {
				pstrcpy( remaining, p );
				p2 = remaining;
				
				if ( !next_token(&p2, subkeyname, "\\", sizeof(subkeyname)) )
					fstrcpy( subkeyname, p2 );
			}

			DEBUG(10,("init_registry_data: Storing key [%s] with subkey [%s]\n",
				base, *subkeyname ? subkeyname : "NULL"));
			
			/* we don't really care if the lookup succeeds or not since
			   we are about to update the record.  We just want any 
			   subkeys already present */
			
			if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
				DEBUG(0,("talloc() failure!\n"));
				goto fail;
			}

			regdb_fetch_keys( base, subkeys );
			if ( *subkeyname ) 
				regsubkey_ctr_addkey( subkeys, subkeyname );
			if ( !regdb_store_keys( base, subkeys ))
				goto fail;
			
			TALLOC_FREE( subkeys );
		}
	}

	/* loop over all of the predefined values and add each component */
	
	for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
		if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
			DEBUG(0,("talloc() failure!\n"));
			goto fail;
		}

		regdb_fetch_values( 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 ) ) 
		{
			switch( builtin_registry_values[i].type ) {
			case REG_DWORD:
				regval_ctr_addvalue( values, 
				                     builtin_registry_values[i].valuename,
						     REG_DWORD,
						     (char*)&builtin_registry_values[i].data.dw_value,
						     sizeof(uint32) );
				break;
				
			case REG_SZ:
				init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
				regval_ctr_addvalue( values, 
				                     builtin_registry_values[i].valuename,
						     REG_SZ,
						     (char*)data.buffer,
						     data.uni_str_len*sizeof(uint16) );
				break;
			
			default:
				DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
					builtin_registry_values[i].type));
			}
			regdb_store_values( builtin_registry_values[i].path, values );
		}
		
		TALLOC_FREE( values );
	}
	
	if (tdb_transaction_commit( tdb_reg ) == -1) {
		DEBUG(0, ("init_registry_data: Could not commit "
			  "transaction\n"));
		return False;
	}

	return True;

 fail:

	if (tdb_transaction_cancel( tdb_reg ) == -1) {
		smb_panic("init_registry_data: tdb_transaction_cancel "
			  "failed\n");
	}

	return False;
}
Example #4
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;
		}
	}

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

	TALLOC_FREE( subkeys );

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

	return True;
}
Example #5
0
static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
{
	const char *environments[] = {
		"Windows 4.0",
		"Windows NT x86",
		"Windows NT R4000",
		"Windows NT Alpha_AXP",
		"Windows NT PowerPC",
		"Windows IA64",
		"Windows x64",
		NULL };
	fstring *drivers = NULL;
	int i, env_index, num_drivers;
	char *keystr, *base, *subkeypath;
	char *key2 = NULL;
	int num_subkeys = -1;
	int version;
	TALLOC_CTX *ctx = talloc_tos();

	DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));

	keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) );

	/* list all possible architectures */

	if ( !keystr ) {
		for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ )
			regsubkey_ctr_addkey( subkeys, 	environments[num_subkeys] );

		return num_subkeys;
	}

	/* we are dealing with a subkey of "Environments */
	key2 = talloc_strdup(ctx, keystr);
	if (!key2) {
		return -1;
	}
	keystr = key2;
	if (!reg_split_path(keystr, &base, &subkeypath )) {
		return -1;
	}

	/* sanity check */

	for ( env_index=0; environments[env_index]; env_index++ ) {
		if ( strequal( environments[env_index], base ) )
			break;
	}
	if ( !environments[env_index] )
		return -1;

	/* ...\Print\Environements\...\ */

	if ( !subkeypath ) {
		regsubkey_ctr_addkey( subkeys, "Drivers" );
		regsubkey_ctr_addkey( subkeys, "Print Processors" );

		return 2;
	}

	/* more of the key path to process */

	keystr = subkeypath;
	if (!reg_split_path( keystr, &base, &subkeypath )) {
		return -1;
	}

	/* ...\Print\Environements\...\Drivers\ */

	if ( !subkeypath ) {
		if ( strequal(base, "Drivers") ) {
			switch ( env_index ) {
				case 0:	/* Win9x */
					regsubkey_ctr_addkey( subkeys, "Version-0" );
					break;
				default: /* Windows NT based systems */
					regsubkey_ctr_addkey( subkeys, "Version-2" );
					regsubkey_ctr_addkey( subkeys, "Version-3" );
					break;
			}

			return regsubkey_ctr_numkeys( subkeys );
		} else if ( strequal(base, "Print Processors") ) {
			if ( env_index == 1 || env_index == 5 || env_index == 6 )


			return regsubkey_ctr_numkeys( subkeys );
		} else
			return -1;	/* bad path */
	}

	/* we finally get to enumerate the drivers */

	/* only one possible subkey below PrintProc key */

	if ( strequal(base, "Print Processors") ) {
		keystr = subkeypath;
		if (!reg_split_path( keystr, &base, &subkeypath )) {
			return -1;
		}

		/* no subkeys below this point */

		if ( subkeypath )
			return -1;

		/* only allow one keyname here -- 'winprint' */

		return strequal( base, "winprint" ) ? 0 : -1;
	}

	/* only dealing with drivers from here on out */

	keystr = subkeypath;
	if (!reg_split_path( keystr, &base, &subkeypath )) {
		return -1;
	}

	version = atoi(&base[strlen(base)-1]);

	switch (env_index) {
	case 0:
		if ( version != 0 )
			return -1;
		break;
	default:
		if ( version != 2 && version != 3 )
			return -1;
		break;
	}


	if ( !subkeypath ) {
		num_drivers = get_ntdrivers( &drivers, environments[env_index], version );
		for ( i=0; i<num_drivers; i++ )
			regsubkey_ctr_addkey( subkeys, drivers[i] );

		return regsubkey_ctr_numkeys( subkeys );
	}

	/* if anything else left, just say if has no subkeys */

	DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n",
		key, subkeypath ));

	return 0;
}
Example #6
0
static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
{
	int n_services = lp_numservices();
	int snum;
	fstring sname;
	int i;
	int num_subkeys = 0;
	char *printers_key;
	char *printername, *printerdatakey;
	NT_PRINTER_INFO_LEVEL *printer = NULL;
	fstring *subkey_names = NULL;

	DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));

	printers_key = strip_printers_prefix( key );

	if ( !printers_key ) {
		/* enumerate all printers */

		for (snum=0; snum<n_services; snum++) {
			if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
				continue;

			/* don't report the [printers] share */

			if ( strequal( lp_servicename(snum), PRINTERS_NAME ) )
				continue;

			fstrcpy( sname, lp_servicename(snum) );

			regsubkey_ctr_addkey( subkeys, sname );
		}

		num_subkeys = regsubkey_ctr_numkeys( subkeys );
		goto done;
	}

	/* get information for a specific printer */

	if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
		return -1;
	}

	/* validate the printer name */

	for (snum=0; snum<n_services; snum++) {
		if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
			continue;
		if (strequal( lp_servicename(snum), printername ) )
			break;
	}

	if ( snum>=n_services
		|| !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) 
	{
		return -1;
	}

	num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
	
	for ( i=0; i<num_subkeys; i++ )
		regsubkey_ctr_addkey( subkeys, subkey_names[i] );
	
	free_a_printer( &printer, 2 );
			
	/* no other subkeys below here */

done:	
	SAFE_FREE( subkey_names );
	
	return num_subkeys;
}
Example #7
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;
}