Move over to using GvdbPath when checking for writability of a key.
This has two advantages:
The first is that we only hash the key once during writability checks,
even if we have multiple stacked databases.
The second is that we can now lock down entire subpaths in dconf.
The way the code is written also means that it is now theoretically
possible to "unlock" a given path or key, which means that a database
can introduce a lock for "/" but unlock "/org/gnome/myapp/", in effect,
preventing writes to any area outside of that path. The "best" (ie:
most specific) result is taken as authorative. These 'negative locks'
are not (yet?) supported in the dconf(1) update/compile commands, but
they will be used for proxied databases for application confinement.
Note: each database is consulted separately. That means that a
higher-level database cannot undo a lock of a lower-level database with
a more-specific unlock. The security model is therefore the same as
what it was before.
In the case that the user database file does not exist on disk,
"re"opening it for the first time will fail, causing the refresh
function to return FALSE. This means that we will not end up
recomputing the value of has_locks as was previously assumed.
To avoid this problem, we fill in the proper value from the start,
instead of guessing.
Previously, if we had fewer split points ('/') than the number of
pre-allocated items in the arrays in the structure, we would simply use
them. At 16, this number is already extremely high, and it's
implausible to imagine a real case for which this would be insufficient.
This commit simplifies things a bit: if there are more than 16 segments,
we will just ignore the later ones, except for the final one (ie: the
complete path).
For the sake of an example, let the limit be 4, rather than 16. This
means that you could lock:
With 16 segments, everything here could be locked, and much more.
In this way, we preserve the previous behaviour of always being able to
lock a particular individual key of any depth, while introducing
path-based locks for all reasonable cases, and we avoid memory
allocations in all cases.
Write a helper function to answer the question of "does this source have
any lock for the given key?". Although this logic is currently trivial,
it will soon get more complex.
Add a fast path for avoiding writability checks for the very common case
where there are no databases installed that have locks (ie: the default
configuration).
This allows us to avoid iterating a changeset to check for writability
before sending it off to the service, for example.