From 5373b314473b08f13372ab55b551738307a85fbd Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 2 Dec 2022 22:13:01 -0800 Subject: pam_fscrypt: filter out irrelevant policies earlier If a session is opened for a user twice and the second doesn't have the AUTHTOK data, pam_fscrypt prints an error message that says it failed to unlock a protector because AUTHTOK data is missing. This is misleading because the protector and its associated policies were already unlocked by the first session. To avoid this, move the check for whether the policy is provisioned or not into policiesUsingProtector(). Also do the same for CloseSession. --- pam_fscrypt/pam_fscrypt.go | 14 ++------------ pam_fscrypt/run_fscrypt.go | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 16 deletions(-) (limited to 'pam_fscrypt') diff --git a/pam_fscrypt/pam_fscrypt.go b/pam_fscrypt/pam_fscrypt.go index bd6b04d..2daff89 100644 --- a/pam_fscrypt/pam_fscrypt.go +++ b/pam_fscrypt/pam_fscrypt.go @@ -193,7 +193,7 @@ func OpenSession(handle *pam.Handle, _ map[string]bool) error { log.Printf("no protector to unlock: %s", err) return nil } - policies := policiesUsingProtector(protector) + policies := policiesUsingProtector(protector, false) if len(policies) == 0 { log.Print("no policies to unlock") return nil @@ -234,11 +234,6 @@ func OpenSession(handle *pam.Handle, _ map[string]bool) error { // We don't stop provisioning polices on error, we try all of them. for _, policy := range policies { - if policy.IsProvisionedByTargetUser() { - log.Printf("policy %s already provisioned by %v", - policy.Descriptor(), handle.PamUser.Username) - continue - } if err := policy.UnlockWithProtector(protector); err != nil { log.Printf("unlocking policy %s: %s", policy.Descriptor(), err) continue @@ -316,7 +311,7 @@ func lockLoginPolicies(handle *pam.Handle) (bool, error) { log.Printf("nothing to lock: %s", err) return needDropCaches, nil } - policies := policiesUsingProtector(protector) + policies := policiesUsingProtector(protector, true) if len(policies) == 0 { log.Print("no policies to lock") return needDropCaches, nil @@ -328,11 +323,6 @@ func lockLoginPolicies(handle *pam.Handle) (bool, error) { // We will try to deprovision all of the policies. for _, policy := range policies { - if !policy.IsProvisionedByTargetUser() { - log.Printf("policy %s not provisioned by %v", - policy.Descriptor(), handle.PamUser.Username) - continue - } if policy.NeedsUserKeyring() { needDropCaches = true } diff --git a/pam_fscrypt/run_fscrypt.go b/pam_fscrypt/run_fscrypt.go index 6b40854..db86d01 100644 --- a/pam_fscrypt/run_fscrypt.go +++ b/pam_fscrypt/run_fscrypt.go @@ -179,8 +179,10 @@ func loginProtector(handle *pam.Handle) (*actions.Protector, error) { } // policiesUsingProtector searches all the mountpoints for any policies -// protected with the specified protector. -func policiesUsingProtector(protector *actions.Protector) []*actions.Policy { +// protected with the specified protector. If provisioned is true, then only +// policies provisioned by the target user are returned; otherwise only policies +// *not* provisioned by the target user are returned. +func policiesUsingProtector(protector *actions.Protector, provisioned bool) []*actions.Policy { mounts, err := filesystem.AllFilesystems() if err != nil { log.Print(err) @@ -213,9 +215,23 @@ func policiesUsingProtector(protector *actions.Protector) []*actions.Policy { continue } - if policy.UsesProtector(protector) { - policies = append(policies, policy) + if !policy.UsesProtector(protector) { + continue + } + if provisioned { + if !policy.IsProvisionedByTargetUser() { + log.Printf("policy %s not provisioned by %v", + policy.Descriptor(), ctx.TargetUser.Username) + continue + } + } else { + if policy.IsProvisionedByTargetUser() { + log.Printf("policy %s already provisioned by %v", + policy.Descriptor(), ctx.TargetUser.Username) + continue + } } + policies = append(policies, policy) } } return policies -- cgit v1.2.3