Allow backends to see taint status.

This can be seen via System(). In the PKI backend, if the CA is
reconfigured but not fully (e.g. an intermediate CSR is generated but no
corresponding cert set) and there are already leases (issued certs), the
CRL is unable to be built. As a result revocation fails. But in this
case we don't actually need revocation to be successful since the CRL is
useless after unmounting. By checking taint status we know if we can
simply fast-path out of revocation with a success in this case.

Fixes #946
This commit is contained in:
Jeff Mitchell 2016-01-22 17:01:22 -05:00
parent d663c46757
commit 12c00b97ef
3 changed files with 29 additions and 0 deletions

View file

@ -18,6 +18,15 @@ type revocationInfo struct {
// Revokes a cert, and tries to be smart about error recovery // Revokes a cert, and tries to be smart about error recovery
func revokeCert(b *backend, req *logical.Request, serial string) (*logical.Response, error) { func revokeCert(b *backend, req *logical.Request, serial string) (*logical.Response, error) {
// As this backend is self-contained and this function does not hook into
// third parties to manage users or resources, if the mount is tainted,
// revocation doesn't matter anyways -- the CRL that would be written will
// be immediately blown away by the view being cleared. So we can simply
// fast path a successful exit.
if b.System().Tainted() {
return nil, nil
}
alreadyRevoked := false alreadyRevoked := false
var revInfo revocationInfo var revInfo revocationInfo

View file

@ -16,12 +16,23 @@ type SystemView interface {
// SudoPrivilege returns true if given path has sudo privileges // SudoPrivilege returns true if given path has sudo privileges
// for the given client token // for the given client token
SudoPrivilege(path string, token string) bool SudoPrivilege(path string, token string) bool
// Returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions.
// If revocation of a backend's leases fails it can keep the unmounting
// process from being successful. If the reason for this failure is not
// relevant when the mount is tainted (for instance, saving a CRL to disk
// when the stored CRL will be removed during the unmounting process
// anyways), we can ignore the errors to allow unmounting to complete.
Tainted() bool
} }
type StaticSystemView struct { type StaticSystemView struct {
DefaultLeaseTTLVal time.Duration DefaultLeaseTTLVal time.Duration
MaxLeaseTTLVal time.Duration MaxLeaseTTLVal time.Duration
SudoPrivilegeVal bool SudoPrivilegeVal bool
TaintedVal bool
} }
func (d StaticSystemView) DefaultLeaseTTL() time.Duration { func (d StaticSystemView) DefaultLeaseTTL() time.Duration {
@ -35,3 +46,7 @@ func (d StaticSystemView) MaxLeaseTTL() time.Duration {
func (d StaticSystemView) SudoPrivilege(path string, token string) bool { func (d StaticSystemView) SudoPrivilege(path string, token string) bool {
return d.SudoPrivilegeVal return d.SudoPrivilegeVal
} }
func (d StaticSystemView) Tainted() bool {
return d.TaintedVal
}

View file

@ -64,3 +64,8 @@ func (d dynamicSystemView) fetchTTLs() (def, max time.Duration) {
return return
} }
// Tainted indicates that the mount is in the process of being removed
func (d dynamicSystemView) Tainted() bool {
return d.mountEntry.Tainted
}