session: parse DesktopNames for XDG_CURRENT_DESKTOP, wire utmpx, fix shell
- .desktop files now parse DesktopNames: first ;-entry → XDG_SESSION_DESKTOP, full list with : separators → XDG_CURRENT_DESKTOP - AddUtmpx/Close wired into spawnSession (logins appear in who/w/last) - Credentials.Shell reads from /etc/passwd instead of hardcoded /bin/sh - Added SetDesktopVars to env.go
This commit is contained in:
@@ -37,9 +37,11 @@ static struct pam_conv makePAMConv(void *data) {
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
ouser "os/user"
|
ouser "os/user"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/cgo"
|
"runtime/cgo"
|
||||||
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -169,7 +171,7 @@ func Validate(user, pass, service string) (*Credentials, error) {
|
|||||||
PrimaryGID: gid,
|
PrimaryGID: gid,
|
||||||
AllGIDs: gids,
|
AllGIDs: gids,
|
||||||
HomeDir: u.HomeDir,
|
HomeDir: u.HomeDir,
|
||||||
Shell: "/bin/sh",
|
Shell: shellFromPasswd(uid),
|
||||||
pamHandle: pamh,
|
pamHandle: pamh,
|
||||||
pamData: cData,
|
pamData: cData,
|
||||||
pamCB: h,
|
pamCB: h,
|
||||||
@@ -211,3 +213,21 @@ func atou32(s string) uint32 {
|
|||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shellFromPasswd(uid uint32) string {
|
||||||
|
data, err := os.ReadFile("/etc/passwd")
|
||||||
|
if err != nil {
|
||||||
|
return "/bin/sh"
|
||||||
|
}
|
||||||
|
uidStr := fmt.Sprint(uid)
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
parts := strings.Split(line, ":")
|
||||||
|
if len(parts) >= 7 && parts[2] == uidStr && parts[6] != "" {
|
||||||
|
sh := parts[6]
|
||||||
|
if sh != "/sbin/nologin" && sh != "/usr/sbin/nologin" && sh != "/bin/false" {
|
||||||
|
return sh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "/bin/sh"
|
||||||
|
}
|
||||||
|
|||||||
@@ -165,12 +165,16 @@ func spawnSession(res *login.Result) error {
|
|||||||
session.SetSeatVars(res.Config.TTY)
|
session.SetSeatVars(res.Config.TTY)
|
||||||
session.SetSessionVars(creds.UID)
|
session.SetSessionVars(creds.UID)
|
||||||
session.SetXDGCommonPaths(creds.HomeDir)
|
session.SetXDGCommonPaths(creds.HomeDir)
|
||||||
|
session.SetDesktopVars(res.Env.DesktopNames, res.Env.SessionDesktop)
|
||||||
|
|
||||||
sess, err := session.Spawn(&res.Env, creds.UID, creds.PrimaryGID, creds.AllGIDs, &res.Config)
|
sess, err := session.Spawn(&res.Env, creds.UID, creds.PrimaryGID, creds.AllGIDs, &res.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("spawn: %w", err)
|
return fmt.Errorf("spawn: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utmpx := auth.AddUtmpx(creds.Username, res.Config.TTY, uint32(sess.PID()))
|
||||||
|
defer utmpx.Close()
|
||||||
|
|
||||||
err = sess.Wait()
|
err = sess.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("session exited: %v", err)
|
log.Printf("session exited: %v", err)
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ func SetXDGCommonPaths(home string) {
|
|||||||
setOrOwn("XDG_CONFIG_DIRS", "/etc/xdg")
|
setOrOwn("XDG_CONFIG_DIRS", "/etc/xdg")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetDesktopVars(currentDesktop, sessionDesktop string) {
|
||||||
|
if currentDesktop != "" {
|
||||||
|
setOrOwn("XDG_CURRENT_DESKTOP", currentDesktop)
|
||||||
|
}
|
||||||
|
if sessionDesktop != "" {
|
||||||
|
setOrOwn("XDG_SESSION_DESKTOP", sessionDesktop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setOrOwn(k, v string) {
|
func setOrOwn(k, v string) {
|
||||||
if _, ok := os.LookupEnv(k); !ok {
|
if _, ok := os.LookupEnv(k); !ok {
|
||||||
os.Setenv(k, v)
|
os.Setenv(k, v)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ type PostLoginEnv struct {
|
|||||||
Title string
|
Title string
|
||||||
XinitrcPath string
|
XinitrcPath string
|
||||||
ScriptPath string
|
ScriptPath string
|
||||||
|
DesktopNames string // for XDG_CURRENT_DESKTOP (colon-separated)
|
||||||
|
SessionDesktop string // for XDG_SESSION_DESKTOP
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpawnedEnv struct {
|
type SpawnedEnv struct {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
type DesktopEntry struct {
|
type DesktopEntry struct {
|
||||||
Name string
|
Name string
|
||||||
Exec string
|
Exec string
|
||||||
|
DesktopNames string
|
||||||
Hidden bool
|
Hidden bool
|
||||||
NoDisplay bool
|
NoDisplay bool
|
||||||
}
|
}
|
||||||
@@ -51,6 +52,8 @@ func parseDesktopEntry(path string) (*DesktopEntry, error) {
|
|||||||
e.Name = v
|
e.Name = v
|
||||||
case "Exec":
|
case "Exec":
|
||||||
e.Exec = v
|
e.Exec = v
|
||||||
|
case "DesktopNames":
|
||||||
|
e.DesktopNames = v
|
||||||
case "Hidden":
|
case "Hidden":
|
||||||
e.Hidden = strings.EqualFold(v, "true")
|
e.Hidden = strings.EqualFold(v, "true")
|
||||||
case "NoDisplay":
|
case "NoDisplay":
|
||||||
@@ -97,15 +100,28 @@ func scanDesktopDir(dir, kind string, envs *[]PostLoginEnv) {
|
|||||||
if err != nil || de.Hidden || de.NoDisplay {
|
if err != nil || de.Hidden || de.NoDisplay {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
desktopNames, sessionDesktop := splitDesktopNames(de.DesktopNames, e.Name())
|
||||||
*envs = append(*envs, PostLoginEnv{
|
*envs = append(*envs, PostLoginEnv{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Title: de.Name,
|
Title: de.Name,
|
||||||
XinitrcPath: de.Exec,
|
XinitrcPath: de.Exec,
|
||||||
ScriptPath: de.Exec,
|
ScriptPath: de.Exec,
|
||||||
|
DesktopNames: desktopNames,
|
||||||
|
SessionDesktop: sessionDesktop,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func splitDesktopNames(raw, fallback string) (currentDesktop, sessionDesktop string) {
|
||||||
|
if raw == "" {
|
||||||
|
return fallback, fallback
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(raw, ";", 2)
|
||||||
|
sessionDesktop = strings.TrimSpace(parts[0])
|
||||||
|
currentDesktop = strings.ReplaceAll(raw, ";", ":")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func scanScriptDir(dir, kind string, envs *[]PostLoginEnv) {
|
func scanScriptDir(dir, kind string, envs *[]PostLoginEnv) {
|
||||||
entries, err := os.ReadDir(dir)
|
entries, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user