summaryrefslogtreecommitdiff
path: root/pkg/systemd/dbus.go
blob: 76ea2b9b44e99206b1d46635f893bf645730ec88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package systemd

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"

	"github.com/containers/libpod/v2/pkg/rootless"
	"github.com/coreos/go-systemd/v22/dbus"
	godbus "github.com/godbus/dbus/v5"
)

func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godbus.Conn, error)) (*godbus.Conn, error) {
	conn, err := createBus()
	if err != nil {
		return nil, err
	}

	methods := []godbus.Auth{godbus.AuthExternal(strconv.Itoa(rootless.GetRootlessUID()))}

	err = conn.Auth(methods)
	if err != nil {
		conn.Close()
		return nil, err
	}

	return conn, nil
}

func newRootlessConnection() (*dbus.Conn, error) {
	return dbus.NewConnection(func() (*godbus.Conn, error) {
		return dbusAuthRootlessConnection(func(opts ...godbus.ConnOption) (*godbus.Conn, error) {
			path := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "systemd/private")
			return godbus.Dial(fmt.Sprintf("unix:path=%s", path))
		})
	})
}

// ConnectToDBUS returns a DBUS connection.  It works both as root and non-root
// users.
func ConnectToDBUS() (*dbus.Conn, error) {
	if rootless.IsRootless() {
		return newRootlessConnection()
	}
	return dbus.NewSystemdConnection()
}