ldap: Create services accounts for LDAP and STS temp accounts (#11808)

This commit is contained in:
Anis Elleuch
2021-04-15 06:51:14 +01:00
committed by GitHub
parent b70c298c27
commit 291d2793ca
12 changed files with 731 additions and 178 deletions
+115 -16
View File
@@ -1050,19 +1050,25 @@ func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus)
return nil
}
type newServiceAccountOpts struct {
sessionPolicy *iampolicy.Policy
accessKey string
secretKey string
}
// NewServiceAccount - create a new service account
func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, groups []string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) {
func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, groups []string, opts newServiceAccountOpts) (auth.Credentials, error) {
if !sys.Initialized() {
return auth.Credentials{}, errServerNotInitialized
}
var policyBuf []byte
if sessionPolicy != nil {
err := sessionPolicy.Validate()
if opts.sessionPolicy != nil {
err := opts.sessionPolicy.Validate()
if err != nil {
return auth.Credentials{}, err
}
policyBuf, err = json.Marshal(sessionPolicy)
policyBuf, err = json.Marshal(opts.sessionPolicy)
if err != nil {
return auth.Credentials{}, err
}
@@ -1115,13 +1121,22 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro
m[iamPolicyClaimNameSA()] = "inherited-policy"
}
secret := globalActiveCred.SecretKey
cred, err := auth.GetNewCredentialsWithMetadata(m, secret)
var (
cred auth.Credentials
err error
)
if len(opts.accessKey) > 0 {
cred, err = auth.CreateNewCredentialsWithMetadata(opts.accessKey, opts.secretKey, m, globalActiveCred.SecretKey)
} else {
cred, err = auth.GetNewCredentialsWithMetadata(m, globalActiveCred.SecretKey)
}
if err != nil {
return auth.Credentials{}, err
}
cred.ParentUser = parentUser
cred.Groups = groups
cred.Status = string(madmin.AccountEnabled)
u := newUserIdentity(cred)
@@ -1134,8 +1149,69 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro
return cred, nil
}
type updateServiceAccountOpts struct {
sessionPolicy *iampolicy.Policy
secretKey string
status string
}
// UpdateServiceAccount - edit a service account
func (sys *IAMSys) UpdateServiceAccount(ctx context.Context, accessKey string, opts updateServiceAccountOpts) error {
if !sys.Initialized() {
return errServerNotInitialized
}
sys.store.lock()
defer sys.store.unlock()
cr, ok := sys.iamUsersMap[accessKey]
if !ok || !cr.IsServiceAccount() {
return errNoSuchServiceAccount
}
if opts.secretKey != "" {
cr.SecretKey = opts.secretKey
}
if opts.status != "" {
cr.Status = opts.status
}
if opts.sessionPolicy != nil {
m := make(map[string]interface{})
err := opts.sessionPolicy.Validate()
if err != nil {
return err
}
policyBuf, err := json.Marshal(opts.sessionPolicy)
if err != nil {
return err
}
if len(policyBuf) > 16*humanize.KiByte {
return fmt.Errorf("Session policy should not exceed 16 KiB characters")
}
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString(policyBuf)
m[iamPolicyClaimNameSA()] = "embedded-policy"
m[parentClaim] = cr.ParentUser
cr.SessionToken, err = auth.JWTSignWithAccessKey(accessKey, m, globalActiveCred.SecretKey)
if err != nil {
return err
}
}
u := newUserIdentity(cr)
if err := sys.store.saveUserIdentity(context.Background(), u.Credentials.AccessKey, srvAccUser, u); err != nil {
return err
}
sys.iamUsersMap[u.Credentials.AccessKey] = u.Credentials
return nil
}
// ListServiceAccounts - lists all services accounts associated to a specific user
func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) {
func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]auth.Credentials, error) {
if !sys.Initialized() {
return nil, errServerNotInitialized
}
@@ -1145,30 +1221,53 @@ func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([
sys.store.rlock()
defer sys.store.runlock()
var serviceAccounts []string
for k, v := range sys.iamUsersMap {
var serviceAccounts []auth.Credentials
for _, v := range sys.iamUsersMap {
if v.IsServiceAccount() && v.ParentUser == accessKey {
serviceAccounts = append(serviceAccounts, k)
// Hide secret key & session key here
v.SecretKey = ""
v.SessionToken = ""
serviceAccounts = append(serviceAccounts, v)
}
}
return serviceAccounts, nil
}
// GetServiceAccountParent - gets information about a service account
func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) {
// GetServiceAccount - gets information about a service account
func (sys *IAMSys) GetServiceAccount(ctx context.Context, accessKey string) (auth.Credentials, *iampolicy.Policy, error) {
if !sys.Initialized() {
return "", errServerNotInitialized
return auth.Credentials{}, nil, errServerNotInitialized
}
sys.store.rlock()
defer sys.store.runlock()
sa, ok := sys.iamUsersMap[accessKey]
if ok && sa.IsServiceAccount() {
return sa.ParentUser, nil
if !ok || !sa.IsServiceAccount() {
return auth.Credentials{}, nil, errNoSuchServiceAccount
}
return "", nil
var embeddedPolicy *iampolicy.Policy
jwtClaims, err := auth.ExtractClaims(sa.SessionToken, globalActiveCred.SecretKey)
if err == nil {
pt, ptok := jwtClaims.Lookup(iamPolicyClaimNameSA())
sp, spok := jwtClaims.Lookup(iampolicy.SessionPolicyName)
if ptok && spok && pt == "embedded-policy" {
p, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sp)))
if err == nil {
embeddedPolicy = &iampolicy.Policy{}
embeddedPolicy.Merge(*p)
}
}
}
// Hide secret & session keys
sa.SecretKey = ""
sa.SessionToken = ""
return sa, embeddedPolicy, nil
}
// DeleteServiceAccount - delete a service account