Fix pam Data

This commit is contained in:
2026-07-14 00:51:23 -03:00
parent fa990c2094
commit c6bfefe2fb
+37 -1
View File
@@ -10,6 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync/atomic" "sync/atomic"
"time"
"github.com/GehirnInc/crypt" "github.com/GehirnInc/crypt"
_ "github.com/GehirnInc/crypt/apr1_crypt" _ "github.com/GehirnInc/crypt/apr1_crypt"
@@ -61,7 +62,14 @@ func isPAMAuthEnabled() bool { return pamAuthEnabled.Load() }
// second concurrent/subsequent login for the same user is a no-op. // second concurrent/subsequent login for the same user is a no-op.
func importPAMUser(username string) { func importPAMUser(username string) {
cfg := UserConfig{Username: username, UsePAM: true} cfg := UserConfig{Username: username, UsePAM: true}
st := &UserState{Cfg: cfg} // Carry over the Linux account expiry (/etc/shadow field 8) so the panel's
// "Vence em" shows the real expiration instead of "—".
var expPtr *time.Time
if exp := shadowAccountExpiry(username); exp != nil {
cfg.ExpiresAt = exp.Format(time.RFC3339)
expPtr = exp
}
st := &UserState{Cfg: cfg, ExpiresAt: expPtr}
if !userMgr.AddIfAbsent(st) { if !userMgr.AddIfAbsent(st) {
return // already present in memory return // already present in memory
} }
@@ -97,6 +105,34 @@ func isRegularLoginUser(username string) bool {
return false return false
} }
// shadowAccountExpiry returns the account expiration date from /etc/shadow
// field 8 (days since 1970-01-01), or nil if the account never expires (empty
// field) or the value is unusable. This is the `chage -E` / `useradd -e` date,
// which maps to the panel's per-user expiry.
func shadowAccountExpiry(username string) *time.Time {
data, err := os.ReadFile(shadowFile)
if err != nil {
return nil
}
for _, line := range strings.Split(string(data), "\n") {
fields := strings.Split(strings.TrimRight(line, "\r"), ":")
if len(fields) < 8 || fields[0] != username {
continue
}
expStr := strings.TrimSpace(fields[7])
if expStr == "" {
return nil // no account expiry set
}
days, err := strconv.Atoi(expStr)
if err != nil || days <= 0 {
return nil
}
t := time.Unix(int64(days)*86400, 0).UTC()
return &t
}
return nil
}
// authenticatePAM verifies password against the Linux system account matching // authenticatePAM verifies password against the Linux system account matching
// username. It reads the account's hash from /etc/shadow (the panel runs as // username. It reads the account's hash from /etc/shadow (the panel runs as
// root) and recomputes it with the same algorithm — this is the "just the auth" // root) and recomputes it with the same algorithm — this is the "just the auth"