From a3079a7de2672b757096acf40090b65c7b21f23d Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Thu, 22 Jul 2021 12:13:21 -0700 Subject: [PATCH] fix: Add support for DurationSeconds in LDAP STS API (#12778) --- cmd/sts-handlers.go | 7 ++++- docs/sts/ldap.md | 39 ++++++++++++++++++++++++- internal/config/identity/ldap/config.go | 30 ++++++++++++++++--- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 89fffa71c..1af94c13a 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -541,7 +541,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * return } - expiryDur := globalLDAPConfig.GetExpiryDuration() + expiryDur, err := globalLDAPConfig.GetExpiryDuration(r.Form.Get(stsDurationSeconds)) + if err != nil { + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) + return + } + m := map[string]interface{}{ expClaim: UTCNow().Add(expiryDur).Unix(), ldapUser: ldapUserDN, diff --git a/docs/sts/ldap.md b/docs/sts/ldap.md index 053b3fdbf..632d4381a 100644 --- a/docs/sts/ldap.md +++ b/docs/sts/ldap.md @@ -1,5 +1,33 @@ # AssumeRoleWithLDAPIdentity [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) + +**Table of Contents** + +- [AssumeRoleWithLDAPIdentity [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io)](#assumerolewithldapidentity-slackhttpsslackminioslacktypesvghttpsslackminio) + - [Introduction](#introduction) + - [Configuring AD/LDAP on MinIO](#configuring-adldap-on-minio) + - [Supported modes of operation](#supported-modes-of-operation) + - [Lookup-Bind Mode](#lookup-bind-mode) + - [Username-Format Mode](#username-format-mode) + - [Group membership search](#group-membership-search) + - [Variable substitution in AD/LDAP configuration strings](#variable-substitution-in-adldap-configuration-strings) + - [Managing User/Group Access Policy](#managing-usergroup-access-policy) + - [API Request Parameters](#api-request-parameters) + - [LDAPUsername](#ldapusername) + - [LDAPPassword](#ldappassword) + - [Version](#version) + - [DurationSeconds](#durationseconds) + - [Policy](#policy) + - [Response Elements](#response-elements) + - [Errors](#errors) + - [Sample `POST` Request](#sample-post-request) + - [Sample Response](#sample-response) + - [Using LDAP STS API](#using-ldap-sts-api) + - [Explore Further](#explore-further) + + + + ## Introduction MinIO provides a custom STS API that allows integration with LDAP based corporate environments including Microsoft Active Directory. The MinIO server can be configured in two possible modes: either using a LDAP separate service account, called lookup-bind mode or in username-format mode. In either case the login flow for a user is the same as the STS flow: @@ -165,6 +193,15 @@ Indicates STS API version information, the only supported value is '2011-06-15'. | *Type* | *String* | | *Required* | *Yes* | +### DurationSeconds +The duration, in seconds. The value can range from 900 seconds (15 minutes) up to 365 days. If value is higher than this setting, then operation fails. By default, the value is set to 3600 seconds. + +| Params | Value | +| :-- | :-- | +| *Type* | *Integer* | +| *Valid Range* | *Minimum value of 900. Maximum value of 31536000.* | +| *Required* | *No* | + ### Policy An IAM policy in JSON format that you want to use as an inline session policy. This parameter is optional. Passing policies to this operation returns new temporary credentials. The resulting session's permissions are the intersection of the canned policy name and the policy set here. You cannot use this policy to grant more permissions than those allowed by the canned policy name being assumed. @@ -182,7 +219,7 @@ XML error response for this API is similar to [AWS STS AssumeRoleWithWebIdentity ## Sample `POST` Request ``` -http://minio.cluster:9000?Action=AssumeRoleWithLDAPIdentity&LDAPUsername=foouser&LDAPPassword=foouserpassword&Version=2011-06-15 +http://minio.cluster:9000?Action=AssumeRoleWithLDAPIdentity&LDAPUsername=foouser&LDAPPassword=foouserpassword&Version=2011-06-15&DurationSeconds=7200 ``` ## Sample Response diff --git a/internal/config/identity/ldap/config.go b/internal/config/identity/ldap/config.go index 9e40b07b0..c437d39d2 100644 --- a/internal/config/identity/ldap/config.go +++ b/internal/config/identity/ldap/config.go @@ -24,10 +24,12 @@ import ( "fmt" "math/rand" "net" + "strconv" "strings" "time" ldap "github.com/go-ldap/ldap/v3" + "github.com/minio/minio/internal/auth" "github.com/minio/minio/internal/config" "github.com/minio/pkg/env" ) @@ -36,6 +38,9 @@ const ( defaultLDAPExpiry = time.Hour * 1 dnDelimiter = ";" + + minLDAPExpiry time.Duration = 15 * time.Minute + maxLDAPExpiry time.Duration = 365 * 24 * time.Hour ) // Config contains AD/LDAP server connectivity information. @@ -416,8 +421,22 @@ func (l *Config) Connect() (ldapConn *ldap.Conn, err error) { } // GetExpiryDuration - return parsed expiry duration. -func (l Config) GetExpiryDuration() time.Duration { - return l.stsExpiryDuration +func (l Config) GetExpiryDuration(dsecs string) (time.Duration, error) { + if dsecs == "" { + return l.stsExpiryDuration, nil + } + + d, err := strconv.Atoi(dsecs) + if err != nil { + return 0, auth.ErrInvalidDuration + } + + dur := time.Duration(d) * time.Second + + if dur < minLDAPExpiry || dur > maxLDAPExpiry { + return 0, auth.ErrInvalidDuration + } + return dur, nil } func (l Config) testConnection() error { @@ -538,8 +557,11 @@ func Lookup(kvs config.KVS, rootCAs *x509.CertPool) (l Config, err error) { if err != nil { return l, errors.New("LDAP expiry time err:" + err.Error()) } - if expDur <= 0 { - return l, errors.New("LDAP expiry time has to be positive") + if expDur < minLDAPExpiry { + return l, fmt.Errorf("LDAP expiry time must be at least %s", minLDAPExpiry) + } + if expDur > maxLDAPExpiry { + return l, fmt.Errorf("LDAP expiry time may not exceed %s", maxLDAPExpiry) } l.STSExpiryDuration = v l.stsExpiryDuration = expDur