/** * 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; }
BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; REGSUBKEY_CTR *subkeys, *old_subkeys; char *oldkeyname; /* fetch a list of the old subkeys so we can determine if any were deleted */ if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return False; } regdb_fetch_keys( key, old_subkeys ); /* store the subkey list for the parent */ if ( !regdb_store_keys_internal( key, ctr ) ) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list for parent [%s}\n", key )); return False; } /* now delete removed keys */ num_subkeys = regsubkey_ctr_numkeys( old_subkeys ); for ( i=0; i<num_subkeys; i++ ) { oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i ); if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) { pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname ); normalize_reg_path( path ); tdb_delete_bystring( tdb_reg, path ); } } TALLOC_FREE( old_subkeys ); /* now create records for any subkeys that don't already exist */ num_subkeys = regsubkey_ctr_numkeys( ctr ); for ( i=0; i<num_subkeys; i++ ) { pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) ); if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return False; } if ( regdb_fetch_keys( path, subkeys ) == -1 ) { /* create a record with 0 subkeys */ if ( !regdb_store_keys_internal( path, subkeys ) ) { DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path )); TALLOC_FREE( subkeys ); return False; } } TALLOC_FREE( subkeys ); } return True; }