]> git.apps.os.sepia.ceph.com Git - fscrypt.git/commitdiff
pam_fscrypt: filter out irrelevant policies earlier
authorEric Biggers <ebiggers@google.com>
Sat, 3 Dec 2022 06:13:01 +0000 (22:13 -0800)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 4 Dec 2022 21:05:00 +0000 (13:05 -0800)
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
pam_fscrypt/run_fscrypt.go

index bd6b04d3733a9cb000921cdf550aaab8c667986f..2daff8979dd9d7486e7876ffb87078517990f899 100644 (file)
@@ -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
                }
index 6b40854c9e9995c09c8f09d6947b2684f17842a6..db86d017dd2061eab8a3922c15f0cba7865536f3 100644 (file)
@@ -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