package module
v0.0.0-...-f8dae05 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2022 License: BSD-3-Clause Imports: 12 Imported by: 0


LDAP for Golang

This library provides basic LDAP v3 functionality for the GO programming language.

The client portion is limited, but sufficient to perform LDAP authentication and directory lookups (binds and searches) against any modern LDAP server (tested with OpenLDAP and AD).

The server portion implements Bind and Search from RFC4510, has good testing coverage, and is compatible with any LDAPv3 client. It provides the building blocks for a custom LDAP server, but you must implement the backend datastore of your choice.

LDAP client notes:

A simple LDAP bind operation:
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
// be sure to add error checking!
defer l.Close()
err = l.Bind(user, passwd)
if err==nil {
  // authenticated
} else {
  // invalid authentication
A simple LDAP search operation:
search := &SearchRequest{
  BaseDN: "dc=example,dc=com",
  Filter: "(objectclass=*)",
searchResults, err := l.Search(search)
// be sure to add error checking!
  • Connecting, binding to LDAP server
  • Searching for entries with filtering and paging controls
  • Compiling string filters to LDAP filters
  • Modify Requests / Responses
Not implemented:
  • Add, Delete, Modify DN, Compare operations
  • Most tests / benchmarks
LDAP client examples:
  • examples/search.go: Basic client bind and search
  • examples/searchSSL.go: Client bind and search over SSL
  • examples/searchTLS.go: Client bind and search over TLS
  • examples/modify.go: Client modify operation

Client library by: mmitton, with contributions from: uavila, vanackere, juju2013, johnweldon, marcsauter, and nmcclain

LDAP server notes:

The server library is modeled after net/http - you designate handlers for the LDAP operations you want to support (Bind/Search/etc.), then start the server with ListenAndServe(). You can specify different handlers for different baseDNs - they must implement the interfaces of the operations you want to support:

type Binder interface {
    Bind(bindDN, bindSimplePw string, conn net.Conn) (LDAPResultCode, error)
type Searcher interface {
    Search(boundDN string, searchReq SearchRequest, conn net.Conn) (ServerSearchResult, error)
type Closer interface {
    Close(conn net.Conn) error
A basic bind-only LDAP server
func main() {
  s := ldap.NewServer()
  handler := ldapHandler{}
  s.BindFunc("", handler)
  if err := s.ListenAndServe("localhost:389"); err != nil {
    log.Fatal("LDAP Server Failed: %s", err.Error())
type ldapHandler struct {
func (h ldapHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldap.LDAPResultCode, error) {
	if bindDN == "" && bindSimplePw == "" {
		return ldap.LDAPResultSuccess, nil
	return ldap.LDAPResultInvalidCredentials, nil
  • Server.EnforceLDAP: Normally, the LDAP server will return whatever results your handler provides. Set the Server.EnforceLDAP flag to true and the server will apply the LDAP search filter, attributes limits, size/time limits, search scope, and base DN matching to your handler's dataset. This makes it a lot simpler to write a custom LDAP server without worrying about LDAP internals.
LDAP server examples:
  • examples/server.go: Basic LDAP authentication (bind and search only)
  • examples/proxy.go: Simple LDAP proxy server.
  • server_test.go: The _test.go files have examples of all server functions.
Known limitations:
  • Golang's TLS implementation does not support SSLv2. Some old OSs require SSLv2, and are not able to connect to an LDAP server created with this library's ListenAndServeTLS() function. If you must support legacy (read: insecure) SSLv2 clients, run your LDAP server behind HAProxy.
Not implemented:

From the server perspective, all of RFC4510 is implemented except:

  • SearchRequest.derefAliases
  • SearchRequest.timeLimit
  • SearchRequest.typesOnly
  • 4.14. StartTLS Operation

Server library by: nmcclain




View Source
const (
	MessageQuit     = 0
	MessageRequest  = 1
	MessageResponse = 2
	MessageFinish   = 3
View Source
const (
	FilterAnd             = 0
	FilterOr              = 1
	FilterNot             = 2
	FilterEqualityMatch   = 3
	FilterSubstrings      = 4
	FilterGreaterOrEqual  = 5
	FilterLessOrEqual     = 6
	FilterPresent         = 7
	FilterApproxMatch     = 8
	FilterExtensibleMatch = 9
View Source
const (
	FilterSubstringsInitial = 0
	FilterSubstringsAny     = 1
	FilterSubstringsFinal   = 2
View Source
const (
	ApplicationBindRequest           = 0
	ApplicationBindResponse          = 1
	ApplicationUnbindRequest         = 2
	ApplicationSearchRequest         = 3
	ApplicationSearchResultEntry     = 4
	ApplicationSearchResultDone      = 5
	ApplicationModifyRequest         = 6
	ApplicationModifyResponse        = 7
	ApplicationAddRequest            = 8
	ApplicationAddResponse           = 9
	ApplicationDelRequest            = 10
	ApplicationDelResponse           = 11
	ApplicationModifyDNRequest       = 12
	ApplicationModifyDNResponse      = 13
	ApplicationCompareRequest        = 14
	ApplicationCompareResponse       = 15
	ApplicationAbandonRequest        = 16
	ApplicationSearchResultReference = 19
	ApplicationExtendedRequest       = 23
	ApplicationExtendedResponse      = 24

LDAP Application Codes

View Source
const (
	LDAPResultSuccess                      = 0
	LDAPResultOperationsError              = 1
	LDAPResultProtocolError                = 2
	LDAPResultTimeLimitExceeded            = 3
	LDAPResultSizeLimitExceeded            = 4
	LDAPResultCompareFalse                 = 5
	LDAPResultCompareTrue                  = 6
	LDAPResultAuthMethodNotSupported       = 7
	LDAPResultStrongAuthRequired           = 8
	LDAPResultReferral                     = 10
	LDAPResultAdminLimitExceeded           = 11
	LDAPResultUnavailableCriticalExtension = 12
	LDAPResultConfidentialityRequired      = 13
	LDAPResultSaslBindInProgress           = 14
	LDAPResultNoSuchAttribute              = 16
	LDAPResultUndefinedAttributeType       = 17
	LDAPResultInappropriateMatching        = 18
	LDAPResultConstraintViolation          = 19
	LDAPResultAttributeOrValueExists       = 20
	LDAPResultInvalidAttributeSyntax       = 21
	LDAPResultNoSuchObject                 = 32
	LDAPResultAliasProblem                 = 33
	LDAPResultInvalidDNSyntax              = 34
	LDAPResultAliasDereferencingProblem    = 36
	LDAPResultInappropriateAuthentication  = 48
	LDAPResultInvalidCredentials           = 49
	LDAPResultInsufficientAccessRights     = 50
	LDAPResultBusy                         = 51
	LDAPResultUnavailable                  = 52
	LDAPResultUnwillingToPerform           = 53
	LDAPResultLoopDetect                   = 54
	LDAPResultNamingViolation              = 64
	LDAPResultObjectClassViolation         = 65
	LDAPResultNotAllowedOnNonLeaf          = 66
	LDAPResultNotAllowedOnRDN              = 67
	LDAPResultEntryAlreadyExists           = 68
	LDAPResultObjectClassModsProhibited    = 69
	LDAPResultAffectsMultipleDSAs          = 71
	LDAPResultOther                        = 80

	ErrorNetwork         = 200
	ErrorFilterCompile   = 201
	ErrorFilterDecompile = 202
	ErrorDebugging       = 203

LDAP Result Codes

View Source
const (
	LDAPBindAuthSimple = 0
	LDAPBindAuthSASL   = 3

Other LDAP constants

View Source
const (
	AddAttribute     = 0
	DeleteAttribute  = 1
	ReplaceAttribute = 2
View Source
const (
	ScopeBaseObject   = 0
	ScopeSingleLevel  = 1
	ScopeWholeSubtree = 2
View Source
const (
	NeverDerefAliases   = 0
	DerefInSearching    = 1
	DerefFindingBaseObj = 2
	DerefAlways         = 3
View Source
const (
	ControlTypePaging = "1.2.840.113556.1.4.319"


View Source
var ApplicationMap = map[uint8]string{
	ApplicationBindRequest:           "Bind Request",
	ApplicationBindResponse:          "Bind Response",
	ApplicationUnbindRequest:         "Unbind Request",
	ApplicationSearchRequest:         "Search Request",
	ApplicationSearchResultEntry:     "Search Result Entry",
	ApplicationSearchResultDone:      "Search Result Done",
	ApplicationModifyRequest:         "Modify Request",
	ApplicationModifyResponse:        "Modify Response",
	ApplicationAddRequest:            "Add Request",
	ApplicationAddResponse:           "Add Response",
	ApplicationDelRequest:            "Del Request",
	ApplicationDelResponse:           "Del Response",
	ApplicationModifyDNRequest:       "Modify DN Request",
	ApplicationModifyDNResponse:      "Modify DN Response",
	ApplicationCompareRequest:        "Compare Request",
	ApplicationCompareResponse:       "Compare Response",
	ApplicationAbandonRequest:        "Abandon Request",
	ApplicationSearchResultReference: "Search Result Reference",
	ApplicationExtendedRequest:       "Extended Request",
	ApplicationExtendedResponse:      "Extended Response",
View Source
var ControlTypeMap = map[string]string{
	ControlTypePaging: "Paging",
View Source
var DerefMap = map[int]string{
	NeverDerefAliases:   "NeverDerefAliases",
	DerefInSearching:    "DerefInSearching",
	DerefFindingBaseObj: "DerefFindingBaseObj",
	DerefAlways:         "DerefAlways",
View Source
var FilterMap = map[uint8]string{
	FilterAnd:             "And",
	FilterOr:              "Or",
	FilterNot:             "Not",
	FilterEqualityMatch:   "Equality Match",
	FilterSubstrings:      "Substrings",
	FilterGreaterOrEqual:  "Greater Or Equal",
	FilterLessOrEqual:     "Less Or Equal",
	FilterPresent:         "Present",
	FilterApproxMatch:     "Approx Match",
	FilterExtensibleMatch: "Extensible Match",
View Source
var LDAPModifyAttributeMap = map[uint64]string{
	AddAttribute:     "Add",
	DeleteAttribute:  "Delete",
	ReplaceAttribute: "Replace",
View Source
var LDAPResultCodeMap = map[LDAPResultCode]string{
	LDAPResultSuccess:                      "Success",
	LDAPResultOperationsError:              "Operations Error",
	LDAPResultProtocolError:                "Protocol Error",
	LDAPResultTimeLimitExceeded:            "Time Limit Exceeded",
	LDAPResultSizeLimitExceeded:            "Size Limit Exceeded",
	LDAPResultCompareFalse:                 "Compare False",
	LDAPResultCompareTrue:                  "Compare True",
	LDAPResultAuthMethodNotSupported:       "Auth Method Not Supported",
	LDAPResultStrongAuthRequired:           "Strong Auth Required",
	LDAPResultReferral:                     "Referral",
	LDAPResultAdminLimitExceeded:           "Admin Limit Exceeded",
	LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
	LDAPResultConfidentialityRequired:      "Confidentiality Required",
	LDAPResultSaslBindInProgress:           "Sasl Bind In Progress",
	LDAPResultNoSuchAttribute:              "No Such Attribute",
	LDAPResultUndefinedAttributeType:       "Undefined Attribute Type",
	LDAPResultInappropriateMatching:        "Inappropriate Matching",
	LDAPResultConstraintViolation:          "Constraint Violation",
	LDAPResultAttributeOrValueExists:       "Attribute Or Value Exists",
	LDAPResultInvalidAttributeSyntax:       "Invalid Attribute Syntax",
	LDAPResultNoSuchObject:                 "No Such Object",
	LDAPResultAliasProblem:                 "Alias Problem",
	LDAPResultInvalidDNSyntax:              "Invalid DN Syntax",
	LDAPResultAliasDereferencingProblem:    "Alias Dereferencing Problem",
	LDAPResultInappropriateAuthentication:  "Inappropriate Authentication",
	LDAPResultInvalidCredentials:           "Invalid Credentials",
	LDAPResultInsufficientAccessRights:     "Insufficient Access Rights",
	LDAPResultBusy:                         "Busy",
	LDAPResultUnavailable:                  "Unavailable",
	LDAPResultUnwillingToPerform:           "Unwilling To Perform",
	LDAPResultLoopDetect:                   "Loop Detect",
	LDAPResultNamingViolation:              "Naming Violation",
	LDAPResultObjectClassViolation:         "Object Class Violation",
	LDAPResultNotAllowedOnNonLeaf:          "Not Allowed On Non Leaf",
	LDAPResultNotAllowedOnRDN:              "Not Allowed On RDN",
	LDAPResultEntryAlreadyExists:           "Entry Already Exists",
	LDAPResultObjectClassModsProhibited:    "Object Class Mods Prohibited",
	LDAPResultAffectsMultipleDSAs:          "Affects Multiple DSAs",
	LDAPResultOther:                        "Other",
View Source
var ScopeMap = map[int]string{
	ScopeBaseObject:   "Base Object",
	ScopeSingleLevel:  "Single Level",
	ScopeWholeSubtree: "Whole Subtree",


func CompileFilter

func CompileFilter(filter string) (*ber.Packet, error)

func DebugBinaryFile

func DebugBinaryFile(fileName string) error

func DecompileFilter

func DecompileFilter(packet *ber.Packet) (ret string, err error)

func GetFilterObjectClass

func GetFilterObjectClass(filter string) (string, error)

func HandleAbandonRequest

func HandleAbandonRequest(req *ber.Packet, boundDN string, fns map[string]Abandoner, conn net.Conn) error

func HandleSearchRequest

func HandleSearchRequest(req *ber.Packet, controls *[]Control, messageID uint64, boundDN string, server *Server, conn net.Conn) (resultErr error)

func NewError

func NewError(resultCode LDAPResultCode, err error) error


type Abandoner

type Abandoner interface {
	Abandon(boundDN string, conn net.Conn) error

type AddRequest

type AddRequest struct {
	// contains filtered or unexported fields

type Adder

type Adder interface {
	Add(boundDN string, req AddRequest, conn net.Conn) (LDAPResultCode, error)

type Attribute

type Attribute struct {
	// contains filtered or unexported fields

type AttributeValueAssertion

type AttributeValueAssertion struct {
	// contains filtered or unexported fields

type Binder

type Binder interface {
	Bind(bindDN, bindSimplePw string, conn net.Conn) (LDAPResultCode, error)

type Closer

type Closer interface {
	Close(boundDN string, conn net.Conn) error

type CompareRequest

type CompareRequest struct {
	// contains filtered or unexported fields

type Comparer

type Comparer interface {
	Compare(boundDN string, req CompareRequest, conn net.Conn) (LDAPResultCode, error)

type Conn

type Conn struct {
	Debug debugging
	// contains filtered or unexported fields

Conn represents an LDAP Connection

func Dial

func Dial(network, addr string) (*Conn, error)

Dial connects to the given address on the given network using net.Dial and then returns a new Conn for the connection.

func DialTLS

func DialTLS(network, addr string, config *tls.Config) (*Conn, error)

DialTLS connects to the given address on the given network using tls.Dial and then returns a new Conn for the connection.

func DialTLSDialer

func DialTLSDialer(network, addr string, config *tls.Config, dialer *net.Dialer) (*Conn, error)

DialTLSDialer connects to the given address on the given network using tls.DialWithDialer and then returns a new Conn for the connection.

func DialTimeout

func DialTimeout(network, addr string, timeout time.Duration) (*Conn, error)

DialTimeout connects to the given address on the given network using net.DialTimeout and then returns a new Conn for the connection. Acts like Dial but takes a timeout.

func NewConn

func NewConn(conn net.Conn) *Conn

NewConn returns a new Conn using conn for network I/O.

func (*Conn) Bind

func (l *Conn) Bind(username, password string) error

func (*Conn) Close

func (l *Conn) Close()

Close closes the connection.

func (*Conn) Modify

func (l *Conn) Modify(modifyRequest *ModifyRequest) error

func (*Conn) Ping

func (l *Conn) Ping() error

Use Abandon operation to perform connection keepalives

func (*Conn) Search

func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error)

func (*Conn) SearchWithPaging

func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)

func (*Conn) StartTLS

func (l *Conn) StartTLS(config *tls.Config) error

StartTLS sends the command to start a TLS session and then creates a new TLS Client

func (*Conn) Unbind

func (l *Conn) Unbind() error

type Control

type Control interface {
	GetControlType() string
	Encode() *ber.Packet
	String() string

func DecodeControl

func DecodeControl(packet *ber.Packet) Control

func FindControl

func FindControl(controls []Control, controlType string) Control

type ControlPaging

type ControlPaging struct {
	PagingSize uint32
	Cookie     []byte

func NewControlPaging

func NewControlPaging(pagingSize uint32) *ControlPaging

func (*ControlPaging) Encode

func (c *ControlPaging) Encode() *ber.Packet

func (*ControlPaging) GetControlType

func (c *ControlPaging) GetControlType() string

func (*ControlPaging) SetCookie

func (c *ControlPaging) SetCookie(cookie []byte)

func (*ControlPaging) String

func (c *ControlPaging) String() string

type ControlString

type ControlString struct {
	ControlType  string
	Criticality  bool
	ControlValue string

func NewControlString

func NewControlString(controlType string, criticality bool, controlValue string) *ControlString

func (*ControlString) Encode

func (c *ControlString) Encode() *ber.Packet

func (*ControlString) GetControlType

func (c *ControlString) GetControlType() string

func (*ControlString) String

func (c *ControlString) String() string

type DeleteRequest

type DeleteRequest struct {
	// contains filtered or unexported fields

type Deleter

type Deleter interface {
	Delete(boundDN, deleteDN string, conn net.Conn) (LDAPResultCode, error)

type Entry

type Entry struct {
	DN         string
	Attributes []*EntryAttribute

func (*Entry) GetAttributeValue

func (e *Entry) GetAttributeValue(attribute string) string

func (*Entry) GetAttributeValues

func (e *Entry) GetAttributeValues(attribute string) []string

func (*Entry) PrettyPrint

func (e *Entry) PrettyPrint(indent int)

func (*Entry) Print

func (e *Entry) Print()

type EntryAttribute

type EntryAttribute struct {
	Name   string
	Values []string

func (*EntryAttribute) PrettyPrint

func (e *EntryAttribute) PrettyPrint(indent int)

func (*EntryAttribute) Print

func (e *EntryAttribute) Print()

type Error

type Error struct {
	Err        error
	ResultCode LDAPResultCode

func (*Error) Error

func (e *Error) Error() string

type ExtendedRequest

type ExtendedRequest struct {
	// contains filtered or unexported fields

type Extender

type Extender interface {
	Extended(boundDN string, req ExtendedRequest, conn net.Conn) (LDAPResultCode, error)

type LDAPResultCode

type LDAPResultCode uint8

func HandleAddRequest

func HandleAddRequest(req *ber.Packet, boundDN string, fns map[string]Adder, conn net.Conn) (resultCode LDAPResultCode)

func HandleBindRequest

func HandleBindRequest(req *ber.Packet, fns map[string]Binder, conn net.Conn) (resultCode LDAPResultCode)

func HandleCompareRequest

func HandleCompareRequest(req *ber.Packet, boundDN string, fns map[string]Comparer, conn net.Conn) (resultCode LDAPResultCode)

func HandleDeleteRequest

func HandleDeleteRequest(req *ber.Packet, boundDN string, fns map[string]Deleter, conn net.Conn) (resultCode LDAPResultCode)

func HandleExtendedRequest

func HandleExtendedRequest(req *ber.Packet, boundDN string, fns map[string]Extender, conn net.Conn) (resultCode LDAPResultCode)

func HandleModifyDNRequest

func HandleModifyDNRequest(req *ber.Packet, boundDN string, fns map[string]ModifyDNr, conn net.Conn) (resultCode LDAPResultCode)

func HandleModifyRequest

func HandleModifyRequest(req *ber.Packet, boundDN string, fns map[string]Modifier, conn net.Conn) (resultCode LDAPResultCode)

func ServerApplyFilter

func ServerApplyFilter(f *ber.Packet, entry *Entry) (bool, LDAPResultCode)

type Modifier

type Modifier interface {
	Modify(boundDN string, req ModifyRequest, conn net.Conn) (LDAPResultCode, error)

type ModifyDNRequest

type ModifyDNRequest struct {
	// contains filtered or unexported fields

type ModifyDNr

type ModifyDNr interface {
	ModifyDN(boundDN string, req ModifyDNRequest, conn net.Conn) (LDAPResultCode, error)

type ModifyRequest

type ModifyRequest struct {
	Dn                string
	AddAttributes     []PartialAttribute
	DeleteAttributes  []PartialAttribute
	ReplaceAttributes []PartialAttribute

func NewModifyRequest

func NewModifyRequest(
	dn string,
) *ModifyRequest

func (*ModifyRequest) Add

func (m *ModifyRequest) Add(attrType string, attrVals []string)

func (*ModifyRequest) Delete

func (m *ModifyRequest) Delete(attrType string, attrVals []string)

func (*ModifyRequest) Replace

func (m *ModifyRequest) Replace(attrType string, attrVals []string)

type PartialAttribute

type PartialAttribute struct {
	AttrType string
	AttrVals []string

type SearchRequest

type SearchRequest struct {
	BaseDN       string
	Scope        int
	DerefAliases int
	SizeLimit    int
	TimeLimit    int
	TypesOnly    bool
	Filter       string
	Attributes   []string
	Controls     []Control

func NewSearchRequest

func NewSearchRequest(
	BaseDN string,
	Scope, DerefAliases, SizeLimit, TimeLimit int,
	TypesOnly bool,
	Filter string,
	Attributes []string,
	Controls []Control,
) *SearchRequest

type SearchResult

type SearchResult struct {
	Entries   []*Entry
	Referrals []string
	Controls  []Control

func (*SearchResult) PrettyPrint

func (s *SearchResult) PrettyPrint(indent int)

func (*SearchResult) Print

func (s *SearchResult) Print()

type Searcher

type Searcher interface {
	Search(boundDN string, req SearchRequest, conn net.Conn) (ServerSearchResult, error)

type Server

type Server struct {
	BindFns     map[string]Binder
	SearchFns   map[string]Searcher
	AddFns      map[string]Adder
	ModifyFns   map[string]Modifier
	DeleteFns   map[string]Deleter
	ModifyDNFns map[string]ModifyDNr
	CompareFns  map[string]Comparer
	AbandonFns  map[string]Abandoner
	ExtendedFns map[string]Extender
	UnbindFns   map[string]Unbinder
	CloseFns    map[string]Closer
	Quit        chan bool
	EnforceLDAP bool
	Stats       *Stats
	TLSConfig   *tls.Config // used for StartTLS

func NewServer

func NewServer() *Server

func (*Server) AbandonFunc

func (server *Server) AbandonFunc(baseDN string, f Abandoner)

func (*Server) AddFunc

func (server *Server) AddFunc(baseDN string, f Adder)

func (*Server) BindFunc

func (server *Server) BindFunc(baseDN string, f Binder)

func (*Server) CloseFunc

func (server *Server) CloseFunc(baseDN string, f Closer)

func (*Server) CompareFunc

func (server *Server) CompareFunc(baseDN string, f Comparer)

func (*Server) DeleteFunc

func (server *Server) DeleteFunc(baseDN string, f Deleter)

func (*Server) ExtendedFunc

func (server *Server) ExtendedFunc(baseDN string, f Extender)

func (*Server) GetStats

func (server *Server) GetStats() Stats

func (*Server) ListenAndServe

func (server *Server) ListenAndServe(listenString string) error

func (*Server) ListenAndServeTLS

func (server *Server) ListenAndServeTLS(listenString string, certFile string, keyFile string) error

func (*Server) ModifyDNFunc

func (server *Server) ModifyDNFunc(baseDN string, f ModifyDNr)

func (*Server) ModifyFunc

func (server *Server) ModifyFunc(baseDN string, f Modifier)

func (*Server) QuitChannel

func (server *Server) QuitChannel(quit chan bool)

func (*Server) SearchFunc

func (server *Server) SearchFunc(baseDN string, f Searcher)

func (*Server) Serve

func (server *Server) Serve(ln net.Listener) error

func (*Server) SetStats

func (server *Server) SetStats(enable bool)

func (*Server) UnbindFunc

func (server *Server) UnbindFunc(baseDN string, f Unbinder)

type ServerSearchResult

type ServerSearchResult struct {
	Entries    []*Entry
	Referrals  []string
	Controls   []Control
	ResultCode LDAPResultCode

type Stats

type Stats struct {
	Conns    int
	Binds    int
	Unbinds  int
	Searches int
	// contains filtered or unexported fields

type Unbinder

type Unbinder interface {
	Unbind(boundDN string, conn net.Conn) (LDAPResultCode, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL