]> git.apps.os.sepia.ceph.com Git - fscrypt.git/commitdiff
pam_fscrypt: ignore system users
authorEric Biggers <ebiggers@google.com>
Wed, 23 Feb 2022 20:35:04 +0000 (12:35 -0800)
committerEric Biggers <ebiggers@google.com>
Wed, 23 Feb 2022 20:35:04 +0000 (12:35 -0800)
pam_fscrypt should never need to do anything for system users, so detect
them early so that we can avoid wasting any resources looking for their
login protector.

pam_fscrypt/run_fscrypt.go

index a563ab5c3d3fe072e6cfc300a109b01e863e403c..6b40854c9e9995c09c8f09d6947b2684f17842a6 100644 (file)
@@ -35,6 +35,7 @@ import (
        "log"
        "log/syslog"
        "os"
+       "os/user"
        "path/filepath"
        "runtime/debug"
        "unsafe"
@@ -57,6 +58,10 @@ const (
        countDirectoryPermissions = 0700
        countFilePermissions      = 0600
        countFileFormat           = "%d\n"
+       // uidMin is the first UID that can be used for a regular user (as
+       // opposed to a system user or root).  This value is fairly standard
+       // across Linux distros, but it can be adjusted if needed.
+       uidMin = 1000
 )
 
 // PamFunc is used to define the various actions in the PAM module.
@@ -67,6 +72,14 @@ type PamFunc struct {
        impl func(handle *pam.Handle, args map[string]bool) error
 }
 
+// isSystemUser checks if a user is a system user.  pam_fscrypt should never
+// need to do anything for system users since they should never have login
+// protectors.  Therefore, we detect them early to avoid wasting resources.
+func isSystemUser(user *user.User) bool {
+       uid := util.AtoiOrPanic(user.Uid)
+       return uid < uidMin && uid != 0
+}
+
 // Run is used to convert between the Go functions and exported C funcs.
 func (f *PamFunc) Run(pamh unsafe.Pointer, argc C.int, argv **C.char) (ret C.int) {
        args := parseArgs(argc, argv)
@@ -85,7 +98,13 @@ func (f *PamFunc) Run(pamh unsafe.Pointer, argc C.int, argv **C.char) (ret C.int
        log.Printf("%s(%v) starting", f.name, args)
        handle, err := pam.NewHandle(pamh)
        if err == nil {
-               err = f.impl(handle, args)
+               if isSystemUser(handle.PamUser) {
+                       log.Printf("invoked for system user %q (%s), doing nothing",
+                               handle.PamUser.Username, handle.PamUser.Uid)
+                       err = nil
+               } else {
+                       err = f.impl(handle, args)
+               }
        }
        if err != nil {
                fmt.Fprintf(errorWriter, "%s(%v) failed: %s", f.name, args, err)