Typically, the top-level JSON object has to be an object, in any json
document we parse, hence let's add a simple way to enforce that.
Make use of this in various places.
(Note, various other JSON parsers insist on this logic right from the
beginning, but I actually thinking making this insisting optional like
this patch does it is the cleaner approach)
We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
parse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.
This matches a pattern we have in conf-parser.h, where we have both
void *userdata (more global) and void *data (per-config item). Here,
I opted for uintptr_t userdata. It seems that most of the time we'll
want to just pass an enum value. This works OK with no casts. I also
tried a void* and union. In both cases, much more boilerplate is needed:
either a cast or a macro to help avoid compiler warnings. uintptr_t
seems generic enough to cover foreseeable usecases with no fuss.
This is a noop refactoring. See next commit for an example.
So far we opened a new Varlink connection for every mountfsd/nsresourced
method call. Given each tool only does a very small number of calls
(usually 1…5) on them and the connections are cheap this is not too
wasteful. Nonetheless, let's do something about it, and allow reusing
the connection for multiple calls.
This not only makes things a bit more efficient, but has one more
important benefit: Varlink connections pin the security context of the
client when connecting. This means that varlink method calls done with a
connection established while some code was privileged will still operate
as privieged once privs are dropped, until the connection is closed.
This pinning effect is really nice, as it gives us behaviour in a
"capability system" like scheme. Later code is going to use that to
continue doing certain priv userns ops even after unsharing userns and
becoming fully unpriv.
Let's flush out all response state from the job, but let's keep the
request data previously configured, in particular the headers set. This
is useful to re-request a resource, just with a slightly modified or
identical URL.
If the IDL declares the method requires 'more' yet the call doesn't
have it set, varlink_idl_validate_method_call() should have rejected
it and the callback shouldn't be reached.
Currently, if we're copying a file, we won't copy the owner UID/GID
from the source. If we're copying a directory, we will copy the owner
UID/GID from the source. Let's give users a bit more control over this
behavior by introducing --copy-ownership= which will default to the
current behavior but allows users to explicitly enable/disable copying
of ownership.
If we're doing foreign UID range copying, we're going to be joining
a private user namespace before doing the copy. copy_tree() insists
on keeping all UIDs/GIDs the same when copying. Hence, all the
UIDs/GIDs of the files we're copying should be in the private UID
range, which means they need to be owned by the foreign UID range
and we always need to call mountfsd_mount_directory_fd(). So there's
no point in having a fallback path if the source directory is not
foreign UID range owned, we'd simply fail to copy it later. Hence,
insist on the source directory being foreign UID range owned.
Let's introduce these for the following two reasons:
- Using them makes sure the parameter names match between declaration
and definition (if both use the corresponding macros).
- They make sure developers can't forget the _const_ and _pure_
attributes for the declarations.
This commit also includes some include sorting fixes
Now that sd-event doesn't insist on blocking
SIGCHLD anymore when watching for process exit,
let's stop blocking SIGCHLD tree-wide where not
required anymore.
The indirection through variables doesn't seem that useful here:
OTOH, the lists are short, and OTOH, there is a bunch of different
programs with similar names. Overall, it's all easier to follow if
the lists are inline.