models for user sessions, ssh, su, etc.

Havoc Pennington hp at pobox.com
Tue May 25 11:40:12 PDT 2010


Hi,

In https://bugs.freedesktop.org/show_bug.cgi?id=17970 and in the
discussion of the user bus just now on this list, I've claimed that
spelling out the big picture plan and all cases that will and won't
work is important before embarking on changing everything to match The
Plan.

Seems like 1) there's no (sane and simple) design where all the things
people think they want to do will work; if you go complex enough to
handle all cases in theory, it will be so complex that it will often
fail in practice; and 2) that because of 1 there are tradeoffs, and if
you make the tradeoffs and then try to "fix" the stuff that was traded
off, you'll break the stuff that was supposed to work. Worse, you'll
probably break it, then refix it rebreaking the other thing, and back
and forth over the years. So bottom line it's essential to document
what works, what doesn't, and when someone complains about what
doesn't, or doesn't follow The Plan, you WONTFIX and link to The Plan.
That way stuff works when it's supposed to, doesn't work when it isn't
supposed to, it stays that way over time, and people (eventually)
learn wtf is going on.

I guess The Plan could be called the "user sessions spec" or something
like that. I won't write it. But I wanted to do an email to try to map
out the issues a bit.

Simple model: in a very simple model, you have 1 machine (set of
hardware), 1 home directory, 1 user, 1 graphical display, 1 instance
of each singleton app, etc. There's 1 instance of dbus to go with all
this, and 1 instance of each thing on dbus. Developers from a
Windows-type background are probably thinking along these lines.

Things that can mess up the simple model
===

* su (either N users, homedirs, etc. per display OR can't connect to display)
* ssh to another machine (may create N users, sets of apps, etc. per
display; or can't connect to display)
* ssh from another machine (may create N sets of apps, dbus, etc. to
go with 1 user or 1 homedir)
* use *dm/startx to create two sessions on the same machine (N sets of
apps, dbus, displays for 1 user and homedir)
* cron jobs run something as a user (may create another set of
dbus/apps, or may not; may use an existing display or may not)
* network home directories (N everything else per home directory)
* multi-user systems (N user/app/homedir collections per 1 set of hardware)
* automounters (anything running outside of a login session has no
homedir, or prevents homedir from unmounting)
* I think some sites us a model where they run all openoffice on one
server, all firefox on another server, etc.

Problem statement: if you're building a desktop or just an app or a
service, you'll have a horrible time making *all* of these things work
(even if it were clear how some of them are supposed to work; in
several cases it's not well-defined yet whether it's right to join an
existing display or existing dbus, or start a new one, and users may
expect either one at different times).

Need for a spec: However things are going to work, all the apps have
to agree on the model. It can't be "configurable" by the app developer
because people need to put together a whole working session from lots
of apps and services, so all those must have a compatible approach.

Scenarios and what people might want in them
===

* Singleton GUI application, such as a music player. Launching it
again on the same display should run the existing instance. Launching
it again on a different display on the same machine should run a new
GUI - for bonus points, the two GUIs could share the same backend,
rather than having different music stomping on each other. But
stomping could be fine - "don't do that then." Launching it again on
the same display but on a _different machine_ is even more fun, and
this case has with-same-homedir and without-same-homedir subcases.

* So say you go to open a url from app A which is not a browser, the
relationship to the browser could be:
- app A is on the same bus as the browser, same display, same homedir
- app A is on a different bus (session? su?) from browser, but same display
- app A is on a different machine from the browser, but same display
and homedir.
- app A is on a different machine from the browser, but same display
and different homedir.

* "Suppress screensaver" API used by presentation and multimedia apps.
This should be per-display.

* GUI app from a second user, created with su or sudo, displaying on
first users display. How do the following work:
- suppress screensaver API
- open an URL in browser
- save settings to a configuration service
- receive "about to logout" warning message and run a conversation to
block logout while showing a dialog
- add an icon to panel

* tray icons / window manager plugins / window manager itself: one per display

* hardware-related services: one per machine, but UI such as tray
icons may be per-display. may be a (user,machine) service as well as
per-machine service? Power manager, pulseaudio, network manager, etc.
Some of these may go on system bus and simply be system services, as
well.

Research tasks that would be helpful
===

* Log into a default desktop session and list every name on dbus.
Document what each one does and what whether it would ideally be
per-user or per-display or per-homedir or per-machine. Document what
would ideally happen with su and sudo and etc.

* What do users actually expect in various cases. Unfortunately I
think the expectations may be contradictory. But map out the
user-visible scenarios much better.

Possible directions (largely cut-and-pasted from su bug and lennart mail)
=====

Possible direction 1
===

Concept: every app has to be in some session, but sessions can share an X
server

* A session can be for the same user or a separate user.

* Everything in a session must have the same homedir, dbus-daemon, and X
server.

* Multiple sessions can share an X server.

* We try to keep only 1 session per home directory on each X server, though
this is not strictly required

* everything on a dbus-daemon can assume it shares homedir and X server with
everything else on that daemon

* There is some way to create a session on a remote system, and tell the remote
app how to join it (probably by setting DISPLAY and DBUS_SESSION_BUS_ADDRESS)

* ssh default is to have the remote app join the existing session or error out
"No session available; to create one, run xyz then run the app again using abc
env variables" OR ssh default is to autolaunch a session in such a way that
everything else on that machine will find it

* some session on the X server has to "claim" all the singleton X server stuff
such as: screensaver; settings-daemon; other sessions probably have to
communicate with this session via X server (in fact using dbus for these
X-specific functions probably becomes broken)

* some session on the X server has to own login/logout ("uber session" "owner
session" "master session"?)

* the owning session has to tell the others when logout is happening, etc. ...
probably using dbus becomes wrong, we have to use X

Possible direction 2
===

Concept: every app on an X server must be in the same session

* A session can have multiple homedirs and users in it

* dbus-daemon singletons can't assume everything in the session shares the same
homedir, only that they share the same dbus-daemon and X server; however, they
can assume no other daemons or sessions are using the X server.

* in this direction, screensaver, settings-daemon, logout notification, etc.
can be done with dbus, because we know there aren't other things using the X
server on a different dbus daemon. While in the multi-sessions-per-X-server
case, we really ought to throw all these things off dbus, or at least tunnel
them through X.

* if you "su" in this direction, then the su'd app is basically running with
the original users' stuff (settings, etc.) but not the original user's home
directory. Same for running an app on a remote machine.

* A behavior here might be, you read root's email as root in a root-owned email
app, but clicking links opens in your regular-user firefox rather than
launching a firefox for root.

* this direction is more like the historical behavior - if you have X resources
for configuration, for example, they would be used by all apps from any user,
on the same X server. Or if you use an X-associated networked audio server.
This approach is the "traditional" way X was intended to work a long time ago,
I think.

* this direction requires implementing dbus forwarding for ssh/su,
and/or tunneling dbus through X protocol, and/or the autolauncher
pulling the bus address off DISPLAY combined with working TCP dbus

Possible direction 3
===

No guarantees to apps; the stuff on the bus may or may not share a
display, homedir, user, etc. with your app.

Possible direction 4
===

(text taken from Lennart's mail)

Concept: Every pair ($HOME,$MACHINE) gets its own session, and multiple
         sessions can connect to the same display, as well as one
         session can connect to multiple displays.

* A dbus session can only have one $HOME. Apps may rely that sending a
  file path over the bus allows the other side to access it, both
  namespace-wise and permission-wise.

* A dbus session can only have one $MACHINE. Apps may rely that sending a
  device if in some way over the bus allows the other side to access it,
  both namespace-wise and permission-wise.

* D-Bus singletons should include the display identifier if they want to
  be startable on more than one display at a time.

* logout notification for displays should be done via X11, not via
  D-Bus. If a display goes away when an app is still talking to it, it
  will be terminated by libx11 or libgtk from within the process.

* both su and remote ssh logins would talk to different session
  busses. Other machines and other user would be blocked from accessing
  the local bus.

* If you log in as normal user, and then run thunderbird as root via su,
  and follow a link there you will get a new firefox instance started as
  root, it won't end up in the already running instance of your own
  user.

* If you run "ssh -X foo firefox" and then "ssh -X foo thunderbird"
  they'll get the same session bus on the machine "foo".

Possible direction 5
===

* Concept: Apps in a session must share user and homedir. When
launching an app on an existing display with another user or homedir
or machine, instead of joining the current session create a new
session *with its own X server*.

* This is most viable if we have a rootless X server. So there would
be some command (just "su -"?) that would create a new rootless X
server, new session bus, and run the rootless X server on your current
X server. You can launch new apps in this new session.

* This could be a user option added to direction 2, rather than
mandatory, but in that case apps don't get the "same user and homedir
for everything in session" guarantee.

* It could be OK, though odd, if the X server were nested instead of
rootless (like a vnc, virtual machine, or Xephyr). Or it could even be
another toplevel X server managed by gdm I suppose.

* nested X server would make clearer the weird limitations, for
example, no cut-and-paste between the two sessions.

Possible direction 6
===

Concept: Have two buses, combining 2 and 4.

* The (user,machine) bus in 4 ensures a single homedir for that bus as
well. So any services that use files in the homedir need to be on that
bus. While services that do X stuff (screensaver, applet-ish thingies,
display settings) need to be on the session bus. The session bus must
be forwarded via su and ssh so apps joining the display can talk to
the X stuff. But su and ssh would have to create a *new* user,machine
bus (if changing user) or use the old one (if not changing user) so
it's not a simple forwarding of this bus.

* There could be multiple users on the session bus, but one of them
would be the session bus owner and the default user that would spawn
new apps. So if I activate the browser to open an URL, the session bus
would launch it always as the user who started that session. I _guess_
the only exception would be if someone manually launches a browser as
another user, then that other-user browser would take over and own the
browser service.

* variant: basically do this except force using system bus or
lockfiles or other mechanisms for the per-(homedir,machine) stuff, so
there's only one bus daemon

* what if you need to communicate between per-(user,machine) stuff and
X? Let's say there's a hardware-related service (power manager) and a
tray indicator related to it. It seems the tray indicator should use
the "session bus owner" user's (user,machine) bus. So there would need
to be some call to get that bus - which could even be coded
client-side today I suppose, since I think we have a way to get the
UID of a bus.

Editorial
===

* I think 1 and 4 have the problem that you can't do any X stuff on
dbus, such as screensaver, panel applets, singleton GUI apps,
display-affecting settings, or whatever.
- with 1 there are lots of bus daemons per display (with su, ssh) so
you can't reliably communicate to all the apps on the display via dbus
- with 4 you can scope services per-display, but that doesn't fix it,
because you can still have apps from other users (su, ssh) joining
your display but not your bus

* direction 1 may work best "de facto" right now, because the
forwarding stuff is broken, but if you just "su -" and dbus-launch
then things mostly work just because apps don't use dbus in a way that
breaks

* direction 6 (=2+4) is the most complex but does seem most practical
since it lets services pick whether to bind to homedir,machine or to
display. However, it may require splitting up some existing services.
Often the split may be logical anyway, in a model/view backend/UI kind
of way.

* the big problem with direction 6 I guess is that it's more complex
to explain and document. It would look like adding a
"DBUS_BUS_USER_MACHINE" next to DBUS_BUS_SESSION, DBUS_BUS_SYSTEM I
guess. It also involves all the work needed for both 2 (ssh/su
forwarding, X11 tunnelling) and 4 (creating a new bus type)

* it isn't clear sometimes which bus something should be on. If I'm
opening a URL, maybe it's a file: URL and I need to open it assuming
my homedir. But otherwise (for http), maybe I just want one browser
per display. In general I'd want anything that works with documents on
the homedir bus perhaps ... but other stuff maybe not. Anyway this
isn't going to be able to Do What People Mean all the time perhaps and
it would just be documented that either 1) maybe file: links won't
work right or 2) maybe you get two browsers and the documented bug
gets a big WONTFIX.

Hopefully people can build on the above.

Havoc


More information about the dbus mailing list