Emeric Vigier | 2f62582 | 2012-08-06 11:09:52 -0400 | [diff] [blame] | 1 | D-BUS System Activation |
| 2 | |
| 3 | Introduction: |
| 4 | |
| 5 | The dbus-daemon runs as the dbus user, and is therefore unprivileged. |
| 6 | Earlier attempts [1] by David Zeuthen at launching system scripts using a |
| 7 | custom DBUS protocol were reviewed, but deemed too difficult to audit, and |
| 8 | also due to a multi-threaded design, too difficult to test. |
| 9 | In the next few paragraphs I will outline a simpler setuid approach for |
| 10 | launching daemons as a configured user. |
| 11 | |
| 12 | Scope: |
| 13 | |
| 14 | Launching programs using dbus has been a topic of interest for many months. |
| 15 | This would allow simple systems to only start services that are needed, |
| 16 | and that are automatically started only when first requested. |
| 17 | This removes the need for an init system, and means that we can trivially |
| 18 | startup services in parallel. |
| 19 | This has immediate pressing need for OLPC, with a longer term evaluation for |
| 20 | perhaps Fedora and RHEL. |
| 21 | |
| 22 | Details: |
| 23 | |
| 24 | Setuid applications have to used only when absolutely necessary. |
| 25 | In this implementation I have an single executable, |
| 26 | dbus-daemon-launch-helper, with the ownership root:dbus. |
| 27 | This has the permissions 4750, i.e. u+rwx g+rx +setuid. |
| 28 | It is located in /usr/libexec/ and thus is not designed to be invoked by a |
| 29 | user directly. |
| 30 | |
| 31 | The helper must not be passed input that can be changed maliciously, and |
| 32 | therefore passing a random path with user id is totally out of the question. |
| 33 | In this implementation a similar idea as discussed with Davids' patch was |
| 34 | taken, that to pass a single name argument to the helper. |
| 35 | The service filename of "org.me.test.service" is then searched for in |
| 36 | /usr/share/dbus-1/system-services or other specified directories. |
| 37 | |
| 38 | If applications want to be activated on the system _and_ session busses, then |
| 39 | service files should be installed in both directories. |
| 40 | |
| 41 | A typical service file would look like: |
| 42 | |
| 43 | [D-BUS Service] |
| 44 | Name=org.me.test |
| 45 | Exec=/usr/sbin/dbus-test-server.py |
| 46 | User=ftp |
| 47 | |
| 48 | This gives the user to switch to, and also the path of the executable. |
| 49 | The service name must match that specified in the /etc/dbus-1/system.d conf file. |
| 50 | |
| 51 | Precautions taken: |
| 52 | |
| 53 | * Only the bus name is passed to the helper, and this is validated |
| 54 | * We are super paranoid about the user that called us, and what permissions we have. |
| 55 | * We clear all environment variables except for DBUS_VERBOSE which is used for debugging |
| 56 | * Anything out of the ordinary causes the helper to abort. |
| 57 | |
| 58 | Launching services: |
| 59 | |
| 60 | Trivial methods on services can be called directly and the launch helper will |
| 61 | start the service and execute the method on the service. The lauching of the |
| 62 | service is completely transparent to the caller, e.g.: |
| 63 | |
| 64 | dbus-send --system --print-reply \ |
| 65 | --dest=org.freedesktop.Hal \ |
| 66 | /org/freedesktop/Hal/Manager \ |
| 67 | org.freedesktop.Hal.Manager.DeviceExists \ |
| 68 | string:/org/freedesktop/Hal/devices/computer |
| 69 | |
| 70 | If you wish to activate the service without calling a well known method, |
| 71 | the standard dbus method StartServiceByName can be used: |
| 72 | |
| 73 | dbus-send --system --print-reply \ |
| 74 | --dest=org.freedesktop.DBus \ |
| 75 | /org/freedesktop/DBus \ |
| 76 | org.freedesktop.DBus.StartServiceByName \ |
| 77 | string:org.freedesktop.Hal uint32:0 |
| 78 | |
| 79 | [1] http://lists.freedesktop.org/archives/dbus/2006-October/006096.html |
| 80 | |