mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 19:47:54 +00:00
Merge branch 'master-oss' into cubbyhole-the-world
This commit is contained in:
@@ -78,6 +78,7 @@ IMPROVEMENTS:
|
|||||||
backend [GH-1404]
|
backend [GH-1404]
|
||||||
* credential/ldap: If `groupdn` is not configured, skip searching LDAP and
|
* credential/ldap: If `groupdn` is not configured, skip searching LDAP and
|
||||||
only return policies for local groups, plus a warning [GH-1283]
|
only return policies for local groups, plus a warning [GH-1283]
|
||||||
|
* credential/ldap: `vault list` support for users and groups [GH-1270]
|
||||||
* credential/userpass: Add list support for users [GH-911]
|
* credential/userpass: Add list support for users [GH-911]
|
||||||
* credential/userpass: Remove user configuration paths from requiring sudo, in
|
* credential/userpass: Remove user configuration paths from requiring sudo, in
|
||||||
favor of normal ACL mechanisms [GH-1312]
|
favor of normal ACL mechanisms [GH-1312]
|
||||||
@@ -114,6 +115,8 @@ BUG FIXES:
|
|||||||
* credential/various: Fix renewal conditions when `default` policy is not
|
* credential/various: Fix renewal conditions when `default` policy is not
|
||||||
contained in the backend config [GH-1256]
|
contained in the backend config [GH-1256]
|
||||||
* physical/s3: Don't panic in certain error cases from bad S3 responses [GH-1353]
|
* physical/s3: Don't panic in certain error cases from bad S3 responses [GH-1353]
|
||||||
|
* secret/consul: Use non-pooled Consul API client to avoid leaving files open
|
||||||
|
[GH-1428]
|
||||||
* secret/pki: Don't check whether a certificate is destined to be a CA
|
* secret/pki: Don't check whether a certificate is destined to be a CA
|
||||||
certificate if sign-verbatim endpoint is used [GH-1250]
|
certificate if sign-verbatim endpoint is used [GH-1250]
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (b *backend) periodicFunc(req *logical.Request) error {
|
|||||||
if b.nextTidyTime.IsZero() || !time.Now().UTC().Before(b.nextTidyTime) {
|
if b.nextTidyTime.IsZero() || !time.Now().UTC().Before(b.nextTidyTime) {
|
||||||
// safety_buffer defaults to 180 days for roletag blacklist
|
// safety_buffer defaults to 180 days for roletag blacklist
|
||||||
safety_buffer := 15552000
|
safety_buffer := 15552000
|
||||||
tidyBlacklistConfigEntry, err := b.configTidyRoleTags(req.Storage)
|
tidyBlacklistConfigEntry, err := b.lockedConfigTidyRoleTags(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ func (b *backend) periodicFunc(req *logical.Request) error {
|
|||||||
|
|
||||||
// reset the safety_buffer to 72h
|
// reset the safety_buffer to 72h
|
||||||
safety_buffer = 259200
|
safety_buffer = 259200
|
||||||
tidyWhitelistConfigEntry, err := b.configTidyIdentities(req.Storage)
|
tidyWhitelistConfigEntry, err := b.lockedConfigTidyIdentities(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ func TestBackend_CreateParseVerifyRoleTag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read the created role entry
|
// read the created role entry
|
||||||
roleEntry, err := b.awsRole(storage, "abcd-123")
|
roleEntry, err := b.lockedAWSRole(storage, "abcd-123")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func TestBackend_CreateParseVerifyRoleTag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the entry of the newly created role entry
|
// get the entry of the newly created role entry
|
||||||
roleEntry2, err := b.awsRole(storage, "ami-6789")
|
roleEntry2, err := b.lockedAWSRole(storage, "ami-6789")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -1098,7 +1098,7 @@ func TestBackend_PathBlacklistRoleTag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to read the deleted entry
|
// try to read the deleted entry
|
||||||
tagEntry, err := b.blacklistRoleTagEntry(storage, tag)
|
tagEntry, err := b.lockedBlacklistRoleTagEntry(storage, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func (b *backend) getClientConfig(s logical.Storage, region string) (*aws.Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the configured secret key and access key
|
// Read the configured secret key and access key
|
||||||
config, err := b.clientConfigEntryInternal(s)
|
config, err := b.nonLockedClientConfigEntry(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ func (b *backend) pathConfigCertificateExistenceCheck(req *logical.Request, data
|
|||||||
return false, fmt.Errorf("missing cert_name")
|
return false, fmt.Errorf("missing cert_name")
|
||||||
}
|
}
|
||||||
|
|
||||||
entry, err := b.awsPublicCertificateEntry(req.Storage, certName)
|
entry, err := b.lockedAWSPublicCertificateEntry(req.Storage, certName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ func (b *backend) awsPublicCertificates(s logical.Storage) ([]*x509.Certificate,
|
|||||||
|
|
||||||
// Iterate through each certificate, parse and append it to a slice.
|
// Iterate through each certificate, parse and append it to a slice.
|
||||||
for _, cert := range registeredCerts {
|
for _, cert := range registeredCerts {
|
||||||
certEntry, err := b.awsPublicCertificateEntryInternal(s, cert)
|
certEntry, err := b.nonLockedAWSPublicCertificateEntry(s, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -180,15 +180,15 @@ func (b *backend) awsPublicCertificates(s logical.Storage) ([]*x509.Certificate,
|
|||||||
|
|
||||||
// awsPublicCertificate is used to get the configured AWS Public Key that is used
|
// awsPublicCertificate is used to get the configured AWS Public Key that is used
|
||||||
// to verify the PKCS#7 signature of the instance identity document.
|
// to verify the PKCS#7 signature of the instance identity document.
|
||||||
func (b *backend) awsPublicCertificateEntry(s logical.Storage, certName string) (*awsPublicCert, error) {
|
func (b *backend) lockedAWSPublicCertificateEntry(s logical.Storage, certName string) (*awsPublicCert, error) {
|
||||||
b.configMutex.RLock()
|
b.configMutex.RLock()
|
||||||
defer b.configMutex.RUnlock()
|
defer b.configMutex.RUnlock()
|
||||||
|
|
||||||
return b.awsPublicCertificateEntryInternal(s, certName)
|
return b.nonLockedAWSPublicCertificateEntry(s, certName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal version of the above that does no locking
|
// Internal version of the above that does no locking
|
||||||
func (b *backend) awsPublicCertificateEntryInternal(s logical.Storage, certName string) (*awsPublicCert, error) {
|
func (b *backend) nonLockedAWSPublicCertificateEntry(s logical.Storage, certName string) (*awsPublicCert, error) {
|
||||||
entry, err := s.Get("config/certificate/" + certName)
|
entry, err := s.Get("config/certificate/" + certName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -227,7 +227,7 @@ func (b *backend) pathConfigCertificateRead(
|
|||||||
return logical.ErrorResponse("missing cert_name"), nil
|
return logical.ErrorResponse("missing cert_name"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
certificateEntry, err := b.awsPublicCertificateEntry(req.Storage, certName)
|
certificateEntry, err := b.lockedAWSPublicCertificateEntry(req.Storage, certName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ func (b *backend) pathConfigCertificateCreateUpdate(
|
|||||||
defer b.configMutex.Unlock()
|
defer b.configMutex.Unlock()
|
||||||
|
|
||||||
// Check if there is already a certificate entry registered.
|
// Check if there is already a certificate entry registered.
|
||||||
certEntry, err := b.awsPublicCertificateEntryInternal(req.Storage, certName)
|
certEntry, err := b.nonLockedAWSPublicCertificateEntry(req.Storage, certName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,23 +48,23 @@ func pathConfigClient(b *backend) *framework.Path {
|
|||||||
func (b *backend) pathConfigClientExistenceCheck(
|
func (b *backend) pathConfigClientExistenceCheck(
|
||||||
req *logical.Request, data *framework.FieldData) (bool, error) {
|
req *logical.Request, data *framework.FieldData) (bool, error) {
|
||||||
|
|
||||||
entry, err := b.clientConfigEntry(req.Storage)
|
entry, err := b.lockedClientConfigEntry(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return entry != nil, nil
|
return entry != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the client configuration required to access the AWS API.
|
// Fetch the client configuration required to access the AWS API, after acquiring an exclusive lock.
|
||||||
func (b *backend) clientConfigEntry(s logical.Storage) (*clientConfig, error) {
|
func (b *backend) lockedClientConfigEntry(s logical.Storage) (*clientConfig, error) {
|
||||||
b.configMutex.RLock()
|
b.configMutex.RLock()
|
||||||
defer b.configMutex.RUnlock()
|
defer b.configMutex.RUnlock()
|
||||||
|
|
||||||
return b.clientConfigEntryInternal(s)
|
return b.nonLockedClientConfigEntry(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal version that does no locking
|
// Fetch the client configuration required to access the AWS API.
|
||||||
func (b *backend) clientConfigEntryInternal(s logical.Storage) (*clientConfig, error) {
|
func (b *backend) nonLockedClientConfigEntry(s logical.Storage) (*clientConfig, error) {
|
||||||
entry, err := s.Get("config/client")
|
entry, err := s.Get("config/client")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -82,7 +82,7 @@ func (b *backend) clientConfigEntryInternal(s logical.Storage) (*clientConfig, e
|
|||||||
|
|
||||||
func (b *backend) pathConfigClientRead(
|
func (b *backend) pathConfigClientRead(
|
||||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
clientConfig, err := b.clientConfigEntry(req.Storage)
|
clientConfig, err := b.lockedClientConfigEntry(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ func (b *backend) pathConfigClientCreateUpdate(
|
|||||||
b.configMutex.Lock()
|
b.configMutex.Lock()
|
||||||
defer b.configMutex.Unlock()
|
defer b.configMutex.Unlock()
|
||||||
|
|
||||||
configEntry, err := b.clientConfigEntryInternal(req.Storage)
|
configEntry, err := b.nonLockedClientConfigEntry(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,21 +44,21 @@ expiration, before it is removed from the backend storage.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) pathConfigTidyIdentityWhitelistExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
func (b *backend) pathConfigTidyIdentityWhitelistExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
||||||
entry, err := b.configTidyIdentities(req.Storage)
|
entry, err := b.lockedConfigTidyIdentities(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return entry != nil, nil
|
return entry != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) configTidyIdentities(s logical.Storage) (*tidyWhitelistIdentityConfig, error) {
|
func (b *backend) lockedConfigTidyIdentities(s logical.Storage) (*tidyWhitelistIdentityConfig, error) {
|
||||||
b.configMutex.RLock()
|
b.configMutex.RLock()
|
||||||
defer b.configMutex.RUnlock()
|
defer b.configMutex.RUnlock()
|
||||||
|
|
||||||
return b.configTidyIdentitiesInternal(s)
|
return b.nonLockedConfigTidyIdentities(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) configTidyIdentitiesInternal(s logical.Storage) (*tidyWhitelistIdentityConfig, error) {
|
func (b *backend) nonLockedConfigTidyIdentities(s logical.Storage) (*tidyWhitelistIdentityConfig, error) {
|
||||||
entry, err := s.Get(identityWhitelistConfigPath)
|
entry, err := s.Get(identityWhitelistConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -78,7 +78,7 @@ func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(req *logical.Reque
|
|||||||
b.configMutex.Lock()
|
b.configMutex.Lock()
|
||||||
defer b.configMutex.Unlock()
|
defer b.configMutex.Unlock()
|
||||||
|
|
||||||
configEntry, err := b.configTidyIdentitiesInternal(req.Storage)
|
configEntry, err := b.nonLockedConfigTidyIdentities(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(req *logical.Reque
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) pathConfigTidyIdentityWhitelistRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
func (b *backend) pathConfigTidyIdentityWhitelistRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
clientConfig, err := b.configTidyIdentities(req.Storage)
|
clientConfig, err := b.lockedConfigTidyIdentities(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,21 +46,21 @@ Defaults to 4320h (180 days).`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) pathConfigTidyRoletagBlacklistExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
func (b *backend) pathConfigTidyRoletagBlacklistExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
||||||
entry, err := b.configTidyRoleTags(req.Storage)
|
entry, err := b.lockedConfigTidyRoleTags(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return entry != nil, nil
|
return entry != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) configTidyRoleTags(s logical.Storage) (*tidyBlacklistRoleTagConfig, error) {
|
func (b *backend) lockedConfigTidyRoleTags(s logical.Storage) (*tidyBlacklistRoleTagConfig, error) {
|
||||||
b.configMutex.RLock()
|
b.configMutex.RLock()
|
||||||
defer b.configMutex.RUnlock()
|
defer b.configMutex.RUnlock()
|
||||||
|
|
||||||
return b.configTidyRoleTagsInternal(s)
|
return b.nonLockedConfigTidyRoleTags(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) configTidyRoleTagsInternal(s logical.Storage) (*tidyBlacklistRoleTagConfig, error) {
|
func (b *backend) nonLockedConfigTidyRoleTags(s logical.Storage) (*tidyBlacklistRoleTagConfig, error) {
|
||||||
entry, err := s.Get(roletagBlacklistConfigPath)
|
entry, err := s.Get(roletagBlacklistConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -81,7 +81,7 @@ func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(req *logical.Reques
|
|||||||
b.configMutex.Lock()
|
b.configMutex.Lock()
|
||||||
defer b.configMutex.Unlock()
|
defer b.configMutex.Unlock()
|
||||||
|
|
||||||
configEntry, err := b.configTidyRoleTagsInternal(req.Storage)
|
configEntry, err := b.nonLockedConfigTidyRoleTags(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(req *logical.Reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) pathConfigTidyRoletagBlacklistRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
func (b *backend) pathConfigTidyRoletagBlacklistRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
clientConfig, err := b.configTidyRoleTags(req.Storage)
|
clientConfig, err := b.lockedConfigTidyRoleTags(req.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ func (b *backend) pathLoginUpdate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the entry for the role used by the instance.
|
// Get the entry for the role used by the instance.
|
||||||
roleEntry, err := b.awsRole(req.Storage, roleName)
|
roleEntry, err := b.lockedAWSRole(req.Storage, roleName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -442,7 +442,7 @@ func (b *backend) handleRoleTagLogin(s logical.Storage, identityDoc *identityDoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the role tag is blacklisted.
|
// Check if the role tag is blacklisted.
|
||||||
blacklistEntry, err := b.blacklistRoleTagEntry(s, rTagValue)
|
blacklistEntry, err := b.lockedBlacklistRoleTagEntry(s, rTagValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -487,7 +487,7 @@ func (b *backend) pathLoginRenew(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that role entry is not deleted.
|
// Ensure that role entry is not deleted.
|
||||||
roleEntry, err := b.awsRole(req.Storage, storedIdentity.Role)
|
roleEntry, err := b.lockedAWSRole(req.Storage, storedIdentity.Role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func pathListRoles(b *backend) *framework.Path {
|
|||||||
// Establishes dichotomy of request operation between CreateOperation and UpdateOperation.
|
// Establishes dichotomy of request operation between CreateOperation and UpdateOperation.
|
||||||
// Returning 'true' forces an UpdateOperation, CreateOperation otherwise.
|
// Returning 'true' forces an UpdateOperation, CreateOperation otherwise.
|
||||||
func (b *backend) pathRoleExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
func (b *backend) pathRoleExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
|
||||||
entry, err := b.awsRole(req.Storage, strings.ToLower(data.Get("role").(string)))
|
entry, err := b.lockedAWSRole(req.Storage, strings.ToLower(data.Get("role").(string)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -109,14 +109,14 @@ func (b *backend) pathRoleExistenceCheck(req *logical.Request, data *framework.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
// awsRole is used to get the information registered for the given AMI ID.
|
// awsRole is used to get the information registered for the given AMI ID.
|
||||||
func (b *backend) awsRole(s logical.Storage, role string) (*awsRoleEntry, error) {
|
func (b *backend) lockedAWSRole(s logical.Storage, role string) (*awsRoleEntry, error) {
|
||||||
b.roleMutex.RLock()
|
b.roleMutex.RLock()
|
||||||
defer b.roleMutex.RUnlock()
|
defer b.roleMutex.RUnlock()
|
||||||
|
|
||||||
return b.awsRoleInternal(s, role)
|
return b.nonLockedAWSRole(s, role)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) awsRoleInternal(s logical.Storage, role string) (*awsRoleEntry, error) {
|
func (b *backend) nonLockedAWSRole(s logical.Storage, role string) (*awsRoleEntry, error) {
|
||||||
entry, err := s.Get("role/" + strings.ToLower(role))
|
entry, err := s.Get("role/" + strings.ToLower(role))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -162,7 +162,7 @@ func (b *backend) pathRoleList(
|
|||||||
// pathRoleRead is used to view the information registered for a given AMI ID.
|
// pathRoleRead is used to view the information registered for a given AMI ID.
|
||||||
func (b *backend) pathRoleRead(
|
func (b *backend) pathRoleRead(
|
||||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
roleEntry, err := b.awsRole(req.Storage, strings.ToLower(data.Get("role").(string)))
|
roleEntry, err := b.lockedAWSRole(req.Storage, strings.ToLower(data.Get("role").(string)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ func (b *backend) pathRoleCreateUpdate(
|
|||||||
b.roleMutex.Lock()
|
b.roleMutex.Lock()
|
||||||
defer b.roleMutex.Unlock()
|
defer b.roleMutex.Unlock()
|
||||||
|
|
||||||
roleEntry, err := b.awsRoleInternal(req.Storage, roleName)
|
roleEntry, err := b.nonLockedAWSRole(req.Storage, roleName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (b *backend) pathRoleTagUpdate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the role entry
|
// Fetch the role entry
|
||||||
roleEntry, err := b.awsRole(req.Storage, roleName)
|
roleEntry, err := b.lockedAWSRole(req.Storage, roleName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -346,7 +346,7 @@ func (b *backend) parseAndVerifyRoleTagValue(s logical.Storage, tag string) (*ro
|
|||||||
return nil, fmt.Errorf("missing role name")
|
return nil, fmt.Errorf("missing role name")
|
||||||
}
|
}
|
||||||
|
|
||||||
roleEntry, err := b.awsRole(s, rTag.Role)
|
roleEntry, err := b.lockedAWSRole(s, rTag.Role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,14 +72,14 @@ func (b *backend) pathRoletagBlacklistsList(
|
|||||||
|
|
||||||
// Fetch an entry from the role tag blacklist for a given tag.
|
// Fetch an entry from the role tag blacklist for a given tag.
|
||||||
// This method takes a role tag in its original form and not a base64 encoded form.
|
// This method takes a role tag in its original form and not a base64 encoded form.
|
||||||
func (b *backend) blacklistRoleTagEntry(s logical.Storage, tag string) (*roleTagBlacklistEntry, error) {
|
func (b *backend) lockedBlacklistRoleTagEntry(s logical.Storage, tag string) (*roleTagBlacklistEntry, error) {
|
||||||
b.blacklistMutex.RLock()
|
b.blacklistMutex.RLock()
|
||||||
defer b.blacklistMutex.RUnlock()
|
defer b.blacklistMutex.RUnlock()
|
||||||
|
|
||||||
return b.blacklistRoleTagEntryInternal(s, tag)
|
return b.nonLockedBlacklistRoleTagEntry(s, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) blacklistRoleTagEntryInternal(s logical.Storage, tag string) (*roleTagBlacklistEntry, error) {
|
func (b *backend) nonLockedBlacklistRoleTagEntry(s logical.Storage, tag string) (*roleTagBlacklistEntry, error) {
|
||||||
entry, err := s.Get("blacklist/roletag/" + base64.StdEncoding.EncodeToString([]byte(tag)))
|
entry, err := s.Get("blacklist/roletag/" + base64.StdEncoding.EncodeToString([]byte(tag)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -119,7 +119,7 @@ func (b *backend) pathRoletagBlacklistRead(
|
|||||||
return logical.ErrorResponse("missing role_tag"), nil
|
return logical.ErrorResponse("missing role_tag"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
entry, err := b.blacklistRoleTagEntry(req.Storage, tag)
|
entry, err := b.lockedBlacklistRoleTagEntry(req.Storage, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ func (b *backend) pathRoletagBlacklistUpdate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the entry for the role mentioned in the role tag.
|
// Get the entry for the role mentioned in the role tag.
|
||||||
roleEntry, err := b.awsRole(req.Storage, rTag.Role)
|
roleEntry, err := b.lockedAWSRole(req.Storage, rTag.Role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ func (b *backend) pathRoletagBlacklistUpdate(
|
|||||||
defer b.blacklistMutex.Unlock()
|
defer b.blacklistMutex.Unlock()
|
||||||
|
|
||||||
// Check if the role tag is already blacklisted. If yes, update it.
|
// Check if the role tag is already blacklisted. If yes, update it.
|
||||||
blEntry, err := b.blacklistRoleTagEntryInternal(req.Storage, tag)
|
blEntry, err := b.nonLockedBlacklistRoleTagEntry(req.Storage, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ func Backend() *framework.Backend {
|
|||||||
Paths: append([]*framework.Path{
|
Paths: append([]*framework.Path{
|
||||||
pathConfig(&b),
|
pathConfig(&b),
|
||||||
pathGroups(&b),
|
pathGroups(&b),
|
||||||
|
pathGroupsList(&b),
|
||||||
pathUsers(&b),
|
pathUsers(&b),
|
||||||
|
pathUsersList(&b),
|
||||||
},
|
},
|
||||||
mfa.MFAPaths(b.Backend, pathLogin(&b))...,
|
mfa.MFAPaths(b.Backend, pathLogin(&b))...,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ldap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -38,6 +39,8 @@ func TestBackend_basic(t *testing.T) {
|
|||||||
testAccStepGroup(t, "engineers", "bar"),
|
testAccStepGroup(t, "engineers", "bar"),
|
||||||
testAccStepUser(t, "tesla", "engineers"),
|
testAccStepUser(t, "tesla", "engineers"),
|
||||||
testAccStepLogin(t, "tesla", "password"),
|
testAccStepLogin(t, "tesla", "password"),
|
||||||
|
testAccStepGroupList(t, []string{"engineers", "scientists"}),
|
||||||
|
testAccStepUserList(t, []string{"tesla"}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -321,3 +324,39 @@ func TestLDAPEscape(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccStepGroupList(t *testing.T, groups []string) logicaltest.TestStep {
|
||||||
|
return logicaltest.TestStep{
|
||||||
|
Operation: logical.ListOperation,
|
||||||
|
Path: "groups",
|
||||||
|
Check: func(resp *logical.Response) error {
|
||||||
|
if resp.IsError() {
|
||||||
|
return fmt.Errorf("Got error response: %#v", *resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := groups
|
||||||
|
if !reflect.DeepEqual(exp, resp.Data["keys"].([]string)) {
|
||||||
|
return fmt.Errorf("expected:\n%#v\ngot:\n%#v\n", exp, resp.Data["keys"])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccStepUserList(t *testing.T, users []string) logicaltest.TestStep {
|
||||||
|
return logicaltest.TestStep{
|
||||||
|
Operation: logical.ListOperation,
|
||||||
|
Path: "users",
|
||||||
|
Check: func(resp *logical.Response) error {
|
||||||
|
if resp.IsError() {
|
||||||
|
return fmt.Errorf("Got error response: %#v", *resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := users
|
||||||
|
if !reflect.DeepEqual(exp, resp.Data["keys"].([]string)) {
|
||||||
|
return fmt.Errorf("expected:\n%#v\ngot:\n%#v\n", exp, resp.Data["keys"])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,19 @@ import (
|
|||||||
"github.com/hashicorp/vault/logical/framework"
|
"github.com/hashicorp/vault/logical/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func pathGroupsList(b *backend) *framework.Path {
|
||||||
|
return &framework.Path{
|
||||||
|
Pattern: "groups/?$",
|
||||||
|
|
||||||
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
|
logical.ListOperation: b.pathGroupList,
|
||||||
|
},
|
||||||
|
|
||||||
|
HelpSynopsis: pathGroupHelpSyn,
|
||||||
|
HelpDescription: pathGroupHelpDesc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func pathGroups(b *backend) *framework.Path {
|
func pathGroups(b *backend) *framework.Path {
|
||||||
return &framework.Path{
|
return &framework.Path{
|
||||||
Pattern: `groups/(?P<name>.+)`,
|
Pattern: `groups/(?P<name>.+)`,
|
||||||
@@ -94,6 +107,15 @@ func (b *backend) pathGroupWrite(
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *backend) pathGroupList(
|
||||||
|
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||||
|
groups, err := req.Storage.List("group/")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return logical.ListResponse(groups), nil
|
||||||
|
}
|
||||||
|
|
||||||
type GroupEntry struct {
|
type GroupEntry struct {
|
||||||
Policies []string
|
Policies []string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,19 @@ import (
|
|||||||
"github.com/hashicorp/vault/logical/framework"
|
"github.com/hashicorp/vault/logical/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func pathUsersList(b *backend) *framework.Path {
|
||||||
|
return &framework.Path{
|
||||||
|
Pattern: "users/?$",
|
||||||
|
|
||||||
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
|
logical.ListOperation: b.pathUserList,
|
||||||
|
},
|
||||||
|
|
||||||
|
HelpSynopsis: pathUserHelpSyn,
|
||||||
|
HelpDescription: pathUserHelpDesc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func pathUsers(b *backend) *framework.Path {
|
func pathUsers(b *backend) *framework.Path {
|
||||||
return &framework.Path{
|
return &framework.Path{
|
||||||
Pattern: `users/(?P<name>.+)`,
|
Pattern: `users/(?P<name>.+)`,
|
||||||
@@ -25,7 +38,7 @@ func pathUsers(b *backend) *framework.Path {
|
|||||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
logical.DeleteOperation: b.pathUserDelete,
|
logical.DeleteOperation: b.pathUserDelete,
|
||||||
logical.ReadOperation: b.pathUserRead,
|
logical.ReadOperation: b.pathUserRead,
|
||||||
logical.UpdateOperation: b.pathUserWrite,
|
logical.UpdateOperation: b.pathUserWrite,
|
||||||
},
|
},
|
||||||
|
|
||||||
HelpSynopsis: pathUserHelpSyn,
|
HelpSynopsis: pathUserHelpSyn,
|
||||||
@@ -99,6 +112,15 @@ func (b *backend) pathUserWrite(
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *backend) pathUserList(
|
||||||
|
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||||
|
users, err := req.Storage.List("user/")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return logical.ListResponse(users), nil
|
||||||
|
}
|
||||||
|
|
||||||
type UserEntry struct {
|
type UserEntry struct {
|
||||||
Groups []string
|
Groups []string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func client(s logical.Storage) (*api.Client, error) {
|
|||||||
return nil, fmt.Errorf("error reading root configuration: %s", err)
|
return nil, fmt.Errorf("error reading root configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
consulConf := api.DefaultConfig()
|
consulConf := api.DefaultNonPooledConfig()
|
||||||
consulConf.Address = conf.Address
|
consulConf.Address = conf.Address
|
||||||
consulConf.Scheme = conf.Scheme
|
consulConf.Scheme = conf.Scheme
|
||||||
consulConf.Token = conf.Token
|
consulConf.Token = conf.Token
|
||||||
|
|||||||
@@ -129,12 +129,17 @@ func (t TableFormatter) OutputSecret(ui cli.Ui, secret, s *api.Secret) error {
|
|||||||
|
|
||||||
input = append(input, fmt.Sprintf("Key %s Value", config.Delim))
|
input = append(input, fmt.Sprintf("Key %s Value", config.Delim))
|
||||||
|
|
||||||
|
input = append(input, fmt.Sprintf("--- %s -----", config.Delim))
|
||||||
|
|
||||||
if s.LeaseDuration > 0 {
|
if s.LeaseDuration > 0 {
|
||||||
if s.LeaseID != "" {
|
if s.LeaseID != "" {
|
||||||
input = append(input, fmt.Sprintf("lease_id %s %s", config.Delim, s.LeaseID))
|
input = append(input, fmt.Sprintf("lease_id %s %s", config.Delim, s.LeaseID))
|
||||||
|
input = append(input, fmt.Sprintf(
|
||||||
|
"lease_duration %s %d", config.Delim, s.LeaseDuration))
|
||||||
|
} else {
|
||||||
|
input = append(input, fmt.Sprintf(
|
||||||
|
"refresh_interval %s %d", config.Delim, s.LeaseDuration))
|
||||||
}
|
}
|
||||||
input = append(input, fmt.Sprintf(
|
|
||||||
"lease_duration %s %d", config.Delim, s.LeaseDuration))
|
|
||||||
if s.LeaseID != "" {
|
if s.LeaseID != "" {
|
||||||
input = append(input, fmt.Sprintf(
|
input = append(input, fmt.Sprintf(
|
||||||
"lease_renewable %s %s", config.Delim, strconv.FormatBool(s.Renewable)))
|
"lease_renewable %s %s", config.Delim, strconv.FormatBool(s.Renewable)))
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ active, dedicated users willing to help you through various mediums.
|
|||||||
<a href="https://github.com/hashicorp/vault/issues">Issue tracker
|
<a href="https://github.com/hashicorp/vault/issues">Issue tracker
|
||||||
on GitHub</a>. Please only use this for reporting bugs. Do not ask
|
on GitHub</a>. Please only use this for reporting bugs. Do not ask
|
||||||
for general help here. Use IRC or the mailing list for that.
|
for general help here. Use IRC or the mailing list for that.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Training:</strong>
|
||||||
|
Paid <a href="https://www.hashicorp.com/training.html">HashiCorp training courses</a>
|
||||||
|
are also available in a city near you. Private training courses are also available.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h1>People</h1>
|
<h1>People</h1>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
Reference in New Issue
Block a user