On Fri, Sep 11, 2015 at 11:23:38AM +0200, tilt! wrote:
> Unadressed remains the lifecycle of $XDG_RUNTIME_DIR, specifically:
>
> * When is $XDG_RUNTIME_PREFIX created?
>
> If $XDG_RUNTIME_PREFIX hosts every user's runtime directory,
> it may not be created with ownership of the user, so to do
> this alone:
>
> # as user:
>
> mkdir -p -m 700 "$XDG_RUNTIME_DIR" # wrong!
>
> is the wrong approach, the prefix has to be created owned by
> root, readable by all, and subdirectories have to be created
> owned by user, read/writeable for user only.
>
> # as root:
>
> mkdir -p -m 755 "$XDG_RUNTIME_PREFIX"
>
> Currently my best guess is that this should be performed
> at system startup.
Yes.
> * When is $XDG_RUNTIME_DIR created?
>
> If the prefix is created like described above, it requires
> root permissions to create the per-user directory:
>
> # as root:
>
> # let $uid be the user ID of the affected user;
> # let $xdg:runtime_dir be the requested runtime directory:
>
> if ! test -d "$xdg_runtime_dir" ; then
> mkdir -p -m 700 "$xdg_runtime_dir"
> chown $uid:$(id -g $uid) "$xdg_runtime_dir"
> fi
>
> Currently my best guess is that this should be performed
> everytime the user starts an X session (it's an X thing
> after all, right), but Xsession.d is executed as the
> user, not root. Changing into the user ID is a thing of
> the display manager, there's no general way to hook in.
> Remains PAM. Probably.
PAM would probably work well.
If I were implementing it (note: I'm the sort of guy who doesn't use
PAM, or logind, or policykit...), I'd use a setuid helper that will
construct a path based on a fixed prefix, the user ID, and optionally
a six-character random string (ie, the "-n" option appends _XXXXXX and
calls mktemp).
It will then create this directory, change the owner and permissions,
and print it to stdout, so that you could do:
XDG_RUNTIME_DIR=`mkxdgrt -n`
if you want a new session.
This helper would be called from the login or X startup scripts.
Alternately, you could theoretically create a new mount namespace for
each user (at login, check if there are any processes with the target
uid, and if so join their namespace).
If you created a new namespace, mount some sort of RAM-backed filesystem
with a size limit at XDG_RUNTIME_DIR; its contents will go away with the
last user process.
> * When is $XDG_RUNTIME_DIR deleted?
>
> If the per-user runtime directory is created as i described
> above, user permissions suffice to delete it, so it was
> sufficent to
>
> # as user:
>
> rm -rf "$XDG_RUNTIME_DIR"
>
> Unfortunately i am in the dark over what it means that a
> user has "fully logged out". Does it mean that no processes
> run with the user's identity anymore? That the user has no
> X session running? That the user has no PAM session running?
> And, if any of these mean that the user has "fully logged
> out", how to hook into such an event and perform the code
> suggested above?
Officially, when the last process owned by the user exits.
(This is the main advantage of the mount-namespace based approach.)
In practice, *I* would be fine with "at shutdown, and make sure it's
gone at boot."
HTH,
Isaac Dunham