diff options
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | pam_fscrypt/config | 2 | ||||
| -rw-r--r-- | pam_fscrypt/pam_fscrypt.go | 42 |
3 files changed, 33 insertions, 20 deletions
@@ -415,15 +415,12 @@ auth optional pam_fscrypt.so after `pam_unix.so` in `/etc/pam.d/common-auth` or similar, and to add the line: ``` -session optional pam_fscrypt.so drop_caches lock_policies +session optional pam_fscrypt.so lock_policies ``` after `pam_unix.so` in `/etc/pam.d/common-session` or similar. The `lock_policies` option locks the directories protected with the user's login -passphrase when the last session ends. The `drop_caches` option tells `fscrypt` -to clear the filesystem caches when the last session closes, ensuring all the -locked data is inaccessible; this only needed for v1 encryption policies. All -the types also support the `debug` option which prints additional debug -information to the syslog. +passphrase when the last session ends. All the types also support the `debug` +option which prints additional debug information to the syslog. ### Allowing `fscrypt` to check your login passphrase diff --git a/pam_fscrypt/config b/pam_fscrypt/config index 9b2eb8f..d2fbf68 100644 --- a/pam_fscrypt/config +++ b/pam_fscrypt/config @@ -7,7 +7,7 @@ Auth-Final: Session-Type: Additional Session-Interactive-Only: yes Session-Final: - optional PAM_INSTALL_PATH drop_caches lock_policies + optional PAM_INSTALL_PATH lock_policies Password-Type: Additional Password-Final: optional PAM_INSTALL_PATH diff --git a/pam_fscrypt/pam_fscrypt.go b/pam_fscrypt/pam_fscrypt.go index a7582cc..195ba43 100644 --- a/pam_fscrypt/pam_fscrypt.go +++ b/pam_fscrypt/pam_fscrypt.go @@ -48,7 +48,12 @@ const ( // These flags are used to toggle behavior of the PAM module. debugFlag = "debug" lockFlag = "lock_policies" - cacheFlag = "drop_caches" + + // This option is accepted for compatibility with existing config files, + // but it no longer does anything. pam_fscrypt now drops caches if and + // only if it is needed. (Usually it is not needed anymore, as the + // FS_IOC_REMOVE_ENCRYPTION_KEY ioctl handles this automatically.) + dropCachesFlag = "drop_caches" ) var ( @@ -213,15 +218,20 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { return err } + if args[dropCachesFlag] { + log.Print("ignoring deprecated 'drop_caches' option (now auto-detected)") + } + + needDropCaches := false var errLock, errCache error // Don't automatically drop privileges, since we may need them to // deprovision policies or to drop caches. if args[lockFlag] { log.Print("locking polices protected with login protector") - errLock = lockLoginPolicies(handle) + needDropCaches, errLock = lockLoginPolicies(handle) } - if args[cacheFlag] { + if needDropCaches { log.Print("dropping appropriate filesystem caches at session close") errCache = security.DropFilesystemCache() } @@ -232,11 +242,14 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { return errCache } -// lockLoginPolicies deprovisions all policy keys that are protected by -// the user's login protector. -func lockLoginPolicies(handle *pam.Handle) error { +// lockLoginPolicies deprovisions all policy keys that are protected by the +// user's login protector. It returns true if dropping filesystem caches will +// be needed afterwards to completely lock the relevant directories. +func lockLoginPolicies(handle *pam.Handle) (bool, error) { + needDropCaches := false + if err := handle.StartAsPamUser(); err != nil { - return err + return needDropCaches, err } defer handle.StopAsPamUser() @@ -244,16 +257,16 @@ func lockLoginPolicies(handle *pam.Handle) error { protector, err := loginProtector(handle) if err != nil { log.Printf("nothing to lock: %s", err) - return nil + return needDropCaches, nil } policies := policiesUsingProtector(protector) if len(policies) == 0 { log.Print("no policies to lock") - return nil + return needDropCaches, nil } if err = setupUserKeyringIfNeeded(handle, policies); err != nil { - return errors.Wrapf(err, "setting up user keyring") + return needDropCaches, errors.Wrapf(err, "setting up user keyring") } // We will try to deprovision all of the policies. @@ -263,12 +276,15 @@ func lockLoginPolicies(handle *pam.Handle) error { policy.Descriptor(), handle.PamUser.Username) continue } + if policy.NeedsUserKeyring() { + needDropCaches = true + } if err := beginProvisioningOp(handle, policy); err != nil { - return err + return needDropCaches, err } deprovisionErr := policy.Deprovision(false) if err := endProvisioningOp(handle, policy); err != nil { - return err + return needDropCaches, err } if deprovisionErr != nil { log.Printf("deprovisioning policy %s: %s", policy.Descriptor(), deprovisionErr) @@ -276,7 +292,7 @@ func lockLoginPolicies(handle *pam.Handle) error { } log.Printf("policy %s deprovisioned by %v", policy.Descriptor(), handle.PamUser.Username) } - return nil + return needDropCaches, nil } // Chauthtok rewraps the login protector when the passphrase changes. |