diff options
Diffstat (limited to 'path_rotate.go')
-rw-r--r-- | path_rotate.go | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/path_rotate.go b/path_rotate.go index d06c7ac..a836a5b 100644 --- a/path_rotate.go +++ b/path_rotate.go @@ -77,7 +77,7 @@ func (b *krbBackend) pathRotateRootCredentialsUpdate(ctx context.Context, req *l newPassword := password.Generate() // Update the password remotely. - if err := (*client).SetPassword(config.Username, newPassword); err != nil { + if err := (*client).SetPassword(ctx, config.Username, newPassword); err != nil { return nil, err } @@ -100,15 +100,54 @@ func (b *krbBackend) pathRotateRoleCredentialsUpdate(ctx context.Context, req *l return logical.ErrorResponse("empty role name attribute given"), nil } - ictx, _ := context.WithTimeout(context.Background(), time.Minute*60) - go b.doRotation(ictx, name, req.Storage) + role, err := b.getRole(ctx, req.Storage, name) + if err != nil { + return nil, fmt.Errorf("error fetching role from storage: %s", err) + } + if role == nil { + return nil, fmt.Errorf("role does not exist: %s", name) + } + + b.backgroundRotation(name, req.Storage) + return nil, nil } +func (b *krbBackend) backgroundRotation(name string, storage logical.Storage) { + // make sure we're not in the rotation list already, and add us if not. + // this ensures we dont have two credential rotations running for the same principal + // at the same time. + b.rotationListLock.Lock() + + _, ok := b.rotationList[name] + if ok { + b.rotationListLock.Unlock() + b.Logger().With("role", name).Debug("rotation already in progress, not starting another one") + return + } + + b.rotationList[name] = true + + // done adding to list + b.rotationListLock.Unlock() + + ictx, _ := context.WithTimeout(context.Background(), time.Minute*60) + go b.doRotation(ictx, name, storage) +} + func (b *krbBackend) doRotation(ctx context.Context, name string, storage logical.Storage) { log := b.Logger().With("role", name) log.Debug("starting to rotate role") + defer func() { + // remove from rotation list + b.rotationListLock.Lock() + if _, ok := b.rotationList[name]; ok { + delete(b.rotationList, name) + } + b.rotationListLock.Unlock() + }() + for { err, retry := b.attemptRotation(ctx, name, storage) // TODO if err == nil { @@ -121,7 +160,7 @@ func (b *krbBackend) doRotation(ctx context.Context, name string, storage logica log.Error("unrecoverable error rotating credentials") } - timer := time.NewTimer(30 * time.Second) + timer := time.NewTimer(5 * time.Second) select { case <-timer.C: continue @@ -135,7 +174,7 @@ func (b *krbBackend) doRotation(ctx context.Context, name string, storage logica func (b *krbBackend) attemptRotation(ctx context.Context, name string, storage logical.Storage) (error, bool) { role, err := b.getRole(ctx, storage, name) if err != nil { - return fmt.Errorf("error fetching role from storage: %e", err), true + return fmt.Errorf("error fetching role from storage: %s", err), true } if role == nil { return fmt.Errorf("role does not exist: %s", name), false @@ -143,13 +182,13 @@ func (b *krbBackend) attemptRotation(ctx context.Context, name string, storage l c, err := b.getClient(ctx, storage) if err != nil { - return fmt.Errorf("error getting client: %e", err), true + return fmt.Errorf("error getting client: %s", err), true } newPassword := password.Generate() - err = (*c).SetPassword(role.Principal, newPassword) + err = (*c).SetPassword(ctx, role.Principal, newPassword) if err != nil { - return fmt.Errorf("error setting password: %e", err), true + return fmt.Errorf("error setting password: %s", err), true } role.Password = newPassword |