Pam diagnostic
This commit is contained in:
@@ -2206,18 +2206,18 @@ func passwordCallback(meta ssh.ConnMetadata, pass []byte) (*ssh.Permissions, err
|
|||||||
if !ok {
|
if !ok {
|
||||||
importPAMUser(meta.User())
|
importPAMUser(meta.User())
|
||||||
}
|
}
|
||||||
log.Printf("PAM: %q authenticated against /etc/shadow", meta.User())
|
pamLogf("PAM: %q authenticated against /etc/shadow", meta.User())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else {
|
} else {
|
||||||
log.Printf("PAM: %q rejected by /etc/shadow: %v", meta.User(), err)
|
pamLogf("PAM: %q rejected by /etc/shadow: %v", meta.User(), err)
|
||||||
}
|
}
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
log.Printf("PAM: %q is not a regular login account (needs an /etc/passwd entry with UID >= %d)", meta.User(), minLoginUID)
|
pamLogf("PAM: %q is not a regular login account (needs an /etc/passwd entry with UID >= %d)", meta.User(), minLoginUID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Printf("auth: user %q rejected (no panel account and PAM did not accept it)", meta.User())
|
pamLogf("auth: user %q rejected (no panel account and PAM did not accept it)", meta.User())
|
||||||
return nil, fmt.Errorf("authentication failed")
|
return nil, fmt.Errorf("authentication failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -33,6 +33,14 @@ const (
|
|||||||
|
|
||||||
var errNoSystemPassword = errors.New("account has no usable password")
|
var errNoSystemPassword = errors.New("account has no usable password")
|
||||||
|
|
||||||
|
// pamLogger writes PAM auth diagnostics straight to stderr (captured by
|
||||||
|
// journald) so they remain visible even when "Quiet Logs" redirects the default
|
||||||
|
// logger to io.Discard. Use pamLogf for anything an operator needs to see when
|
||||||
|
// debugging why a system login was accepted or refused.
|
||||||
|
var pamLogger = log.New(os.Stderr, "", log.LstdFlags)
|
||||||
|
|
||||||
|
func pamLogf(format string, args ...interface{}) { pamLogger.Printf(format, args...) }
|
||||||
|
|
||||||
// pamAuthEnabled mirrors Config.PAMAuthEnabled and is toggled live on config
|
// pamAuthEnabled mirrors Config.PAMAuthEnabled and is toggled live on config
|
||||||
// reload. Guarded atomically so passwordCallback can read it lock-free.
|
// reload. Guarded atomically so passwordCallback can read it lock-free.
|
||||||
var pamAuthEnabled atomic.Bool
|
var pamAuthEnabled atomic.Bool
|
||||||
@@ -50,10 +58,10 @@ func importPAMUser(username string) {
|
|||||||
if !userMgr.AddIfAbsent(st) {
|
if !userMgr.AddIfAbsent(st) {
|
||||||
return // already present in memory
|
return // already present in memory
|
||||||
}
|
}
|
||||||
log.Printf("PAM: auto-imported system user %s into the panel", username)
|
pamLogf("PAM: auto-imported system user %s into the panel", username)
|
||||||
if statsStore != nil {
|
if statsStore != nil {
|
||||||
if err := statsStore.UpsertUser(context.Background(), cfg); err != nil {
|
if err := statsStore.UpsertUser(context.Background(), cfg); err != nil {
|
||||||
log.Printf("PAM: failed to persist auto-imported user %s: %v", username, err)
|
pamLogf("PAM: failed to persist auto-imported user %s: %v", username, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +72,7 @@ func importPAMUser(username string) {
|
|||||||
func isRegularLoginUser(username string) bool {
|
func isRegularLoginUser(username string) bool {
|
||||||
data, err := os.ReadFile(passwdFile)
|
data, err := os.ReadFile(passwdFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("PAM: cannot read %s: %v", passwdFile, err)
|
pamLogf("PAM: cannot read %s: %v", passwdFile, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, line := range strings.Split(string(data), "\n") {
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
|||||||
Reference in New Issue
Block a user