summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/runtime.go10
-rw-r--r--pkg/systemd/dbus.go98
2 files changed, 108 insertions, 0 deletions
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 30659a3d4..1f403790f 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -30,6 +30,7 @@ import (
"github.com/containers/podman/v3/libpod/shutdown"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/systemd"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
@@ -500,6 +501,15 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// no containers running. Create immediately a namespace, as
// we will need to access the storage.
if needsUserns {
+ // warn users if mode is rootless and cgroup manager is systemd
+ // and no valid systemd session is present
+ // warn only whenever new namespace is created
+ if runtime.config.Engine.CgroupManager == config.SystemdCgroupsManager {
+ unified, _ := cgroups.IsCgroup2UnifiedMode()
+ if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
+ logrus.Debug("Invalid systemd user session for current user")
+ }
+ }
aliveLock.Unlock() // Unlock to avoid deadlock as BecomeRootInUserNS will reexec.
pausePid, err := util.GetRootlessPauseProcessPidPathGivenDir(runtime.config.Engine.TmpDir)
if err != nil {
diff --git a/pkg/systemd/dbus.go b/pkg/systemd/dbus.go
index 718082526..c49f537b6 100644
--- a/pkg/systemd/dbus.go
+++ b/pkg/systemd/dbus.go
@@ -9,8 +9,106 @@ import (
"github.com/containers/podman/v3/pkg/rootless"
"github.com/coreos/go-systemd/v22/dbus"
godbus "github.com/godbus/dbus/v5"
+ "github.com/sirupsen/logrus"
)
+// IsSystemdSessionValid checks if sessions is valid for provided rootless uid.
+func IsSystemdSessionValid(uid int) bool {
+ var conn *godbus.Conn
+ var err error
+ var object godbus.BusObject
+ var seat0Path godbus.ObjectPath
+ dbusDest := "org.freedesktop.login1"
+ dbusInterface := "org.freedesktop.login1.Manager"
+ dbusPath := "/org/freedesktop/login1"
+
+ if rootless.IsRootless() {
+ conn, err = GetLogindConnection(rootless.GetRootlessUID())
+ object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
+ if err != nil {
+ //unable to fetch systemd object for logind
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
+ if err := object.Call(dbusInterface+".GetSeat", 0, "seat0").Store(&seat0Path); err != nil {
+ //unable to get seat0 path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ seat0Obj := conn.Object(dbusDest, seat0Path)
+ activeSession, err := seat0Obj.GetProperty(dbusDest + ".Seat.ActiveSession")
+ if err != nil {
+ //unable to get active sessions.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionMap, ok := activeSession.Value().([]interface{})
+ if !ok || len(activeSessionMap) < 2 {
+ //unable to get active session map.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionPath, ok := activeSessionMap[1].(godbus.ObjectPath)
+ if !ok {
+ //unable to fetch active session path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionObj := conn.Object(dbusDest, activeSessionPath)
+ sessionUser, err := activeSessionObj.GetProperty(dbusDest + ".Session.User")
+ if err != nil {
+ //unable to fetch session user from activeSession path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ dbusUser, ok := sessionUser.Value().([]interface{})
+ if !ok {
+ // not a valid user.
+ return false
+ }
+ if len(dbusUser) < 2 {
+ // not a valid session user.
+ return false
+ }
+ activeUID, ok := dbusUser[0].(uint32)
+ if !ok {
+ return false
+ }
+ //active session found which belongs to following rootless user
+ if activeUID == uint32(uid) {
+ return true
+ }
+ return false
+ }
+ return true
+}
+
+// GetDbusConnection returns an user connection to D-BUS
+func GetLogindConnection(uid int) (*godbus.Conn, error) {
+ return dbusAuthConnectionLogind(uid)
+}
+
+func dbusAuthConnectionLogind(uid int) (*godbus.Conn, error) {
+ var conn *godbus.Conn
+ var err error
+ conn, err = godbus.SystemBusPrivate()
+ if err != nil {
+ return nil, err
+ }
+ methods := []godbus.Auth{godbus.AuthExternal(strconv.Itoa(uid))}
+ if err = conn.Auth(methods); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ err = conn.Hello()
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godbus.Conn, error)) (*godbus.Conn, error) {
conn, err := createBus()
if err != nil {