@@ -35,6 +35,7 @@ import (
3535 "log"
3636 "log/syslog"
3737 "os"
38+ "os/user"
3839 "path/filepath"
3940 "runtime/debug"
4041 "unsafe"
@@ -57,6 +58,10 @@ const (
5758 countDirectoryPermissions = 0700
5859 countFilePermissions = 0600
5960 countFileFormat = "%d\n "
61+ // uidMin is the first UID that can be used for a regular user (as
62+ // opposed to a system user or root). This value is fairly standard
63+ // across Linux distros, but it can be adjusted if needed.
64+ uidMin = 1000
6065)
6166
6267// PamFunc is used to define the various actions in the PAM module.
@@ -67,6 +72,14 @@ type PamFunc struct {
6772 impl func (handle * pam.Handle , args map [string ]bool ) error
6873}
6974
75+ // isSystemUser checks if a user is a system user. pam_fscrypt should never
76+ // need to do anything for system users since they should never have login
77+ // protectors. Therefore, we detect them early to avoid wasting resources.
78+ func isSystemUser (user * user.User ) bool {
79+ uid := util .AtoiOrPanic (user .Uid )
80+ return uid < uidMin && uid != 0
81+ }
82+
7083// Run is used to convert between the Go functions and exported C funcs.
7184func (f * PamFunc ) Run (pamh unsafe.Pointer , argc C.int , argv * * C.char ) (ret C.int ) {
7285 args := parseArgs (argc , argv )
@@ -85,7 +98,13 @@ func (f *PamFunc) Run(pamh unsafe.Pointer, argc C.int, argv **C.char) (ret C.int
8598 log .Printf ("%s(%v) starting" , f .name , args )
8699 handle , err := pam .NewHandle (pamh )
87100 if err == nil {
88- err = f .impl (handle , args )
101+ if isSystemUser (handle .PamUser ) {
102+ log .Printf ("invoked for system user %q (%s), doing nothing" ,
103+ handle .PamUser .Username , handle .PamUser .Uid )
104+ err = nil
105+ } else {
106+ err = f .impl (handle , args )
107+ }
89108 }
90109 if err != nil {
91110 fmt .Fprintf (errorWriter , "%s(%v) failed: %s" , f .name , args , err )
0 commit comments