authn: serialize ldap authn calls

Some LDAP servers are not MT-safe in that when searches happen with binds
in flight leads to errors such as:
"comment: No other operations may be performed on the connection while a
bind is outstanding"

Add goroutine-id in logs to help debug MT bugs.

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
This commit is contained in:
Ramkumar Chinchani
2021-09-18 00:00:59 +00:00
committed by Ramkumar Chinchani
parent 62e724532a
commit 008d382446
4 changed files with 33 additions and 12 deletions
+2 -2
View File
@@ -14,13 +14,13 @@ import (
type contextKey int
const (
// actions
// actions.
CREATE = "create"
READ = "read"
UPDATE = "update"
DELETE = "delete"
// request-local context key
// request-local context key.
authzCtxKey contextKey = 0
)
+6 -8
View File
@@ -3,6 +3,7 @@
package api
import (
"sync"
"time"
"crypto/tls"
@@ -34,6 +35,7 @@ type LDAPClient struct {
ClientCertificates []tls.Certificate // Adding client certificates
ClientCAs *x509.CertPool
Log log.Logger
lock sync.Mutex
}
// Connect connects to the ldap backend.
@@ -118,6 +120,10 @@ func sleepAndRetry(retries, maxRetries int) bool {
// Authenticate authenticates the user against the ldap backend.
func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]string, error) {
// serialize LDAP calls since some LDAP servers don't allow searches when binds are in flight
lc.lock.Lock()
defer lc.lock.Unlock()
if password == "" {
// RFC 4513 section 5.1.2
return false, nil, errors.ErrLDAPEmptyPassphrase
@@ -206,13 +212,5 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
return false, user, err
}
// Rebind as the read only user for any further queries
if lc.BindDN != "" && lc.BindPassword != "" {
err = lc.Conn.Bind(lc.BindDN, lc.BindPassword)
if err != nil {
return true, user, err
}
}
return true, user, nil
}
-1
View File
@@ -943,7 +943,6 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
// @Failure 500 {string} string "internal server error"
// @Router /v2/{name}/blobs/uploads/{session_id} [put].
func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request) {
rh.c.Log.Info().Interface("headers", r.Header).Msg("HEADERS")
vars := mux.Vars(r)
name, ok := vars["name"]