Fail alias rename if the resulting (name,accessor) exists already (#12473)

This commit is contained in:
Nick Cabatoff 2021-09-21 08:19:44 -04:00 committed by GitHub
parent 9ff3fd39a2
commit 2bd95232cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 5 deletions

3
changelog/12473.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
identity: Fail alias rename if the resulting (name,accessor) exists already
```

View File

@ -4,12 +4,12 @@ import (
"testing"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/credential/github"
credLdap "github.com/hashicorp/vault/builtin/credential/ldap"
"github.com/hashicorp/vault/builtin/credential/userpass"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/vault"
"github.com/hashicorp/vault/builtin/credential/github"
credLdap "github.com/hashicorp/vault/builtin/credential/ldap"
)
func TestIdentityStore_EntityAliasLocalMount(t *testing.T) {
@ -219,3 +219,85 @@ func TestIdentityStore_ListAlias(t *testing.T) {
}
}
}
// TestIdentityStore_RenameAlias_CannotMergeEntity verifies that an error is
// returned on an attempt to rename an alias to match another alias with the
// same mount accessor. This used to result in a merge entity.
func TestIdentityStore_RenameAlias_CannotMergeEntity(t *testing.T) {
coreConfig := &vault.CoreConfig{
CredentialBackends: map[string]logical.Factory{
"userpass": userpass.Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
defer cluster.Cleanup()
client := cluster.Cores[0].Client
err := client.Sys().EnableAuthWithOptions("userpass", &api.EnableAuthOptions{
Type: "userpass",
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("auth/userpass/users/bsmith", map[string]interface{}{
"password": "training",
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("auth/userpass/login/bsmith", map[string]interface{}{
"password": "training",
})
if err != nil {
t.Fatal(err)
}
mounts, err := client.Sys().ListAuth()
if err != nil {
t.Fatal(err)
}
var mountAccessor string
for k, v := range mounts {
if k == "userpass/" {
mountAccessor = v.Accessor
break
}
}
if mountAccessor == "" {
t.Fatal("did not find userpass accessor")
}
// Now create a new unrelated entity and alias
entityResp, err := client.Logical().Write("identity/entity", map[string]interface{}{
"name": "bob-smith",
})
if err != nil {
t.Fatalf("err:%v resp:%#v", err, entityResp)
}
if entityResp == nil {
t.Fatalf("expected a non-nil response")
}
aliasResp, err := client.Logical().Write("identity/entity-alias", map[string]interface{}{
"name": "bob",
"mount_accessor": mountAccessor,
})
if err != nil {
t.Fatalf("err:%v resp:%#v", err, aliasResp)
}
aliasID2 := aliasResp.Data["id"].(string)
// Rename this new alias to have the same name as the one implicitly created by our login as bsmith
_, err = client.Logical().Write("identity/entity-alias/id/"+aliasID2, map[string]interface{}{
"name": "bsmith",
})
if err == nil {
t.Fatal("expected rename over existing entity to fail")
}
}

View File

@ -334,7 +334,7 @@ func (i *IdentityStore) handleAliasUpdate(ctx context.Context, req *logical.Requ
}
// Bail unless it's just a case change
if existingAlias != nil && !strings.EqualFold(existingAlias.Name, name) {
if existingAlias != nil && existingAlias.ID != alias.ID {
return logical.ErrorResponse("alias with combination of mount accessor and name already exists"), nil
}
@ -369,7 +369,7 @@ func (i *IdentityStore) handleAliasUpdate(ctx context.Context, req *logical.Requ
return logical.ErrorResponse("given 'canonical_id' associated with entity in a different namespace from the alias"), logical.ErrPermissionDenied
}
// Update the canonical ID value and move it from the current enitity to the new one
// Update the canonical ID value and move it from the current entity to the new one
alias.CanonicalID = newEntity.ID
newEntity.Aliases = append(newEntity.Aliases, alias)
for aliasIndex, item := range currentEntity.Aliases {