Files
ldaps/server_bind.go
timmy ab779df95a Allow sending an error message with the ldap response
Cleanup interfaces and allow the errorMessage ldap field to be used

Use the correct ldap server-side error code
LDAPResultNotSupported(92) is for a client side error
LDAPResultUnavailable(52) is for when a subsystem is not available
LDAPResultOther(80) is for generic server errors

Provide better errors

Fix binding dn to connection

Fix tests

Make handleSearchRequest conform to rfc4511

Plumb contexts through all connections

Add a server context instead of a public quit channel
2026-08-06 16:02:23 -07:00

63 lines
1.9 KiB
Go

package ldaps
import (
"context"
"errors"
"log"
"net"
"runtime/debug"
"fmt"
ber "github.com/go-asn1-ber/asn1-ber"
"github.com/go-ldap/ldap/v3"
)
func HandleBindRequest(ctx context.Context, req *ber.Packet, fns map[string]Binder, conn net.Conn) (boundDN string, res *ldap.SimpleBindResult, resultErr error) {
defer func() {
if r := recover(); r != nil {
log.Printf("Recovered from panic in BindFn: %s\n%s", r, string(debug.Stack()))
resultErr = fmt.Errorf("Bind function panic: %s", r)
}
}()
// we only support ldapv3
ldapVersion, ok := req.Children[0].Value.(int64)
if !ok {
return "", nil, ldap.NewError(ldap.LDAPResultProtocolError, fmt.Errorf("error reading LDAP version: %v", req.Children[0].Value))
}
if ldapVersion != 3 {
return "", nil, ldap.NewError(ldap.LDAPResultProtocolError, fmt.Errorf("unsupported LDAP version: %d. Please use version 3", ldapVersion))
}
// auth types
bindDN, ok := req.Children[1].Value.(string)
if !ok {
return "", nil, ldap.NewError(ldap.LDAPResultProtocolError, fmt.Errorf("error reading bindDN: %v", req.Children[1].Value))
}
bindAuth := req.Children[2]
switch bindAuth.Tag {
default:
return bindDN, nil, ldap.NewError(ldap.LDAPResultInappropriateAuthentication, fmt.Errorf("unknown LDAP authentication method: %v", bindAuth.Tag))
case LDAPBindAuthSimple:
if len(req.Children) != 3 {
return bindDN, nil, ldap.NewError(ldap.LDAPResultInappropriateAuthentication, fmt.Errorf("simple bind request has %v packets, expected 3", len(req.Children)))
}
fnNames := []string{}
for k := range fns {
fnNames = append(fnNames, k)
}
fn := routeFunc(bindDN, fnNames)
ret, err := fns[fn].Bind(ctx, bindDN, bindAuth.Data.String(), conn)
return bindDN, ret, err
case LDAPBindAuthSASL:
return bindDN, nil, ldap.NewError(ldap.LDAPResultInappropriateAuthentication, errors.New("SASL authentication is not supported"))
}
}