github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/systemd/dbus.go (about)

     1  package systemd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strconv"
     8  
     9  	"github.com/containers/podman/v2/pkg/rootless"
    10  	"github.com/coreos/go-systemd/v22/dbus"
    11  	godbus "github.com/godbus/dbus/v5"
    12  )
    13  
    14  func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godbus.Conn, error)) (*godbus.Conn, error) {
    15  	conn, err := createBus()
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	methods := []godbus.Auth{godbus.AuthExternal(strconv.Itoa(rootless.GetRootlessUID()))}
    21  
    22  	err = conn.Auth(methods)
    23  	if err != nil {
    24  		conn.Close()
    25  		return nil, err
    26  	}
    27  
    28  	return conn, nil
    29  }
    30  
    31  func newRootlessConnection() (*dbus.Conn, error) {
    32  	return dbus.NewConnection(func() (*godbus.Conn, error) {
    33  		return dbusAuthRootlessConnection(func(opts ...godbus.ConnOption) (*godbus.Conn, error) {
    34  			path := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "systemd/private")
    35  			return godbus.Dial(fmt.Sprintf("unix:path=%s", path))
    36  		})
    37  	})
    38  }
    39  
    40  // ConnectToDBUS returns a DBUS connection.  It works both as root and non-root
    41  // users.
    42  func ConnectToDBUS() (*dbus.Conn, error) {
    43  	if rootless.IsRootless() {
    44  		return newRootlessConnection()
    45  	}
    46  	return dbus.NewSystemdConnection()
    47  }