ldap - ActiveState ActiveGo 1.8
...

Package ldap

import "gopkg.in/ldap.v2"
Overview
Index
Examples

Overview ▾

Package ldap provides basic LDAP v3 functionality.

Example (Beherappolicy)

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

controls := []ldap.Control{}
controls = append(controls, ldap.NewControlBeheraPasswordPolicy())
bindRequest := ldap.NewSimpleBindRequest("cn=admin,dc=example,dc=com", "password", controls)

r, err := l.SimpleBind(bindRequest)
ppolicyControl := ldap.FindControl(r.Controls, ldap.ControlTypeBeheraPasswordPolicy)

var ppolicy *ldap.ControlBeheraPasswordPolicy
if ppolicyControl != nil {
    ppolicy = ppolicyControl.(*ldap.ControlBeheraPasswordPolicy)
} else {
    log.Printf("ppolicyControl response not avaliable.\n")
}
if err != nil {
    errStr := "ERROR: Cannot bind: " + err.Error()
    if ppolicy != nil && ppolicy.Error >= 0 {
        errStr += ":" + ppolicy.ErrorString
    }
    log.Print(errStr)
} else {
    logStr := "Login Ok"
    if ppolicy != nil {
        if ppolicy.Expire >= 0 {
            logStr += fmt.Sprintf(". Password expires in %d seconds\n", ppolicy.Expire)
        } else if ppolicy.Grace >= 0 {
            logStr += fmt.Sprintf(". Password expired, %d grace logins remain\n", ppolicy.Grace)
        }
    }
    log.Print(logStr)
}

Example (UserAuthentication)

Example User Authentication shows how a typical application can verify a login attempt

Code:

// The username and password we want to check
username := "someuser"
password := "userpassword"

bindusername := "readonly"
bindpassword := "password"

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

// Reconnect with TLS
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
if err != nil {
    log.Fatal(err)
}

// First bind with a read only user
err = l.Bind(bindusername, bindpassword)
if err != nil {
    log.Fatal(err)
}

// Search for the given username
searchRequest := ldap.NewSearchRequest(
    "dc=example,dc=com",
    ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
    fmt.Sprintf("(&(objectClass=organizationalPerson)&(uid=%s))", username),
    []string{"dn"},
    nil,
)

sr, err := l.Search(searchRequest)
if err != nil {
    log.Fatal(err)
}

if len(sr.Entries) != 1 {
    log.Fatal("User does not exist or too many entries returned")
}

userdn := sr.Entries[0].DN

// Bind as the user to verify their password
err = l.Bind(userdn, password)
if err != nil {
    log.Fatal(err)
}

// Rebind as the read only user for any futher queries
err = l.Bind(bindusername, bindpassword)
if err != nil {
    log.Fatal(err)
}

Example (Vchuppolicy)

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()
l.Debug = true

bindRequest := ldap.NewSimpleBindRequest("cn=admin,dc=example,dc=com", "password", nil)

r, err := l.SimpleBind(bindRequest)

passwordMustChangeControl := ldap.FindControl(r.Controls, ldap.ControlTypeVChuPasswordMustChange)
var passwordMustChange *ldap.ControlVChuPasswordMustChange
if passwordMustChangeControl != nil {
    passwordMustChange = passwordMustChangeControl.(*ldap.ControlVChuPasswordMustChange)
}

if passwordMustChange != nil && passwordMustChange.MustChange {
    log.Printf("Password Must be changed.\n")
}

passwordWarningControl := ldap.FindControl(r.Controls, ldap.ControlTypeVChuPasswordWarning)

var passwordWarning *ldap.ControlVChuPasswordWarning
if passwordWarningControl != nil {
    passwordWarning = passwordWarningControl.(*ldap.ControlVChuPasswordWarning)
} else {
    log.Printf("ppolicyControl response not available.\n")
}
if err != nil {
    log.Print("ERROR: Cannot bind: " + err.Error())
} else {
    logStr := "Login Ok"
    if passwordWarning != nil {
        if passwordWarning.Expire >= 0 {
            logStr += fmt.Sprintf(". Password expires in %d seconds\n", passwordWarning.Expire)
        }
    }
    log.Print(logStr)
}

Index ▾

Constants
Variables
func CompileFilter(filter string) (*ber.Packet, error)
func DebugBinaryFile(fileName string) error
func DecompileFilter(packet *ber.Packet) (ret string, err error)
func EscapeFilter(filter string) string
func IsErrorWithCode(err error, desiredResultCode uint8) bool
func NewError(resultCode uint8, err error) error
type AddRequest
    func NewAddRequest(dn string) *AddRequest
    func (a *AddRequest) Attribute(attrType string, attrVals []string)
type Attribute
type AttributeTypeAndValue
    func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool
type Client
type Conn
    func Dial(network, addr string) (*Conn, error)
    func DialTLS(network, addr string, config *tls.Config) (*Conn, error)
    func NewConn(conn net.Conn, isTLS bool) *Conn
    func (l *Conn) Add(addRequest *AddRequest) error
    func (l *Conn) Bind(username, password string) error
    func (l *Conn) Close()
    func (l *Conn) Compare(dn, attribute, value string) (bool, error)
    func (l *Conn) Del(delRequest *DelRequest) error
    func (l *Conn) Modify(modifyRequest *ModifyRequest) error
    func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
    func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error)
    func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
    func (l *Conn) SetTimeout(timeout time.Duration)
    func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)
    func (l *Conn) Start()
    func (l *Conn) StartTLS(config *tls.Config) error
type Control
    func DecodeControl(packet *ber.Packet) Control
    func FindControl(controls []Control, controlType string) Control
type ControlBeheraPasswordPolicy
    func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy
    func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet
    func (c *ControlBeheraPasswordPolicy) GetControlType() string
    func (c *ControlBeheraPasswordPolicy) String() string
type ControlManageDsaIT
    func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT
    func (c *ControlManageDsaIT) Encode() *ber.Packet
    func (c *ControlManageDsaIT) GetControlType() string
    func (c *ControlManageDsaIT) String() string
type ControlPaging
    func NewControlPaging(pagingSize uint32) *ControlPaging
    func (c *ControlPaging) Encode() *ber.Packet
    func (c *ControlPaging) GetControlType() string
    func (c *ControlPaging) SetCookie(cookie []byte)
    func (c *ControlPaging) String() string
type ControlString
    func NewControlString(controlType string, criticality bool, controlValue string) *ControlString
    func (c *ControlString) Encode() *ber.Packet
    func (c *ControlString) GetControlType() string
    func (c *ControlString) String() string
type ControlVChuPasswordMustChange
    func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet
    func (c *ControlVChuPasswordMustChange) GetControlType() string
    func (c *ControlVChuPasswordMustChange) String() string
type ControlVChuPasswordWarning
    func (c *ControlVChuPasswordWarning) Encode() *ber.Packet
    func (c *ControlVChuPasswordWarning) GetControlType() string
    func (c *ControlVChuPasswordWarning) String() string
type DN
    func ParseDN(str string) (*DN, error)
    func (d *DN) AncestorOf(other *DN) bool
    func (d *DN) Equal(other *DN) bool
type DelRequest
    func NewDelRequest(DN string, Controls []Control) *DelRequest
type Entry
    func NewEntry(dn string, attributes map[string][]string) *Entry
    func (e *Entry) GetAttributeValue(attribute string) string
    func (e *Entry) GetAttributeValues(attribute string) []string
    func (e *Entry) GetRawAttributeValue(attribute string) []byte
    func (e *Entry) GetRawAttributeValues(attribute string) [][]byte
    func (e *Entry) PrettyPrint(indent int)
    func (e *Entry) Print()
type EntryAttribute
    func NewEntryAttribute(name string, values []string) *EntryAttribute
    func (e *EntryAttribute) PrettyPrint(indent int)
    func (e *EntryAttribute) Print()
type Error
    func (e *Error) Error() string
type ModifyRequest
    func NewModifyRequest(dn string) *ModifyRequest
    func (m *ModifyRequest) Add(attrType string, attrVals []string)
    func (m *ModifyRequest) Delete(attrType string, attrVals []string)
    func (m *ModifyRequest) Replace(attrType string, attrVals []string)
type PacketResponse
    func (pr *PacketResponse) ReadPacket() (*ber.Packet, error)
type PartialAttribute
type PasswordModifyRequest
    func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPassword string) *PasswordModifyRequest
type PasswordModifyResult
type RelativeDN
    func (r *RelativeDN) Equal(other *RelativeDN) bool
type SearchRequest
    func NewSearchRequest(BaseDN string, Scope, DerefAliases, SizeLimit, TimeLimit int, TypesOnly bool, Filter string, Attributes []string, Controls []Control) *SearchRequest
type SearchResult
    func (s *SearchResult) PrettyPrint(indent int)
    func (s *SearchResult) Print()
type SimpleBindRequest
    func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest
type SimpleBindResult

Package files

add.go bind.go client.go compare.go conn.go control.go debug.go del.go dn.go doc.go error.go filter.go ldap.go modify.go passwdmodify.go search.go

Constants

const (
    // MessageQuit causes the processMessages loop to exit
    MessageQuit = 0
    // MessageRequest sends a request to the server
    MessageRequest = 1
    // MessageResponse receives a response from the server
    MessageResponse = 2
    // MessageFinish indicates the client considers a particular message ID to be finished
    MessageFinish = 3
    // MessageTimeout indicates the client-specified timeout for a particular message ID has been reached
    MessageTimeout = 4
)
const (
    // ControlTypePaging - https://www.ietf.org/rfc/rfc2696.txt
    ControlTypePaging = "1.2.840.113556.1.4.319"
    // ControlTypeBeheraPasswordPolicy - https://tools.ietf.org/html/draft-behera-ldap-password-policy-10
    ControlTypeBeheraPasswordPolicy = "1.3.6.1.4.1.42.2.27.8.5.1"
    // ControlTypeVChuPasswordMustChange - https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
    ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4"
    // ControlTypeVChuPasswordWarning - https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
    ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
    // ControlTypeManageDsaIT - https://tools.ietf.org/html/rfc3296
    ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
)

LDAP Result Codes

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
    ErrorUnexpectedMessage  = 204
    ErrorUnexpectedResponse = 205
)

Filter choices

const (
    FilterAnd             = 0
    FilterOr              = 1
    FilterNot             = 2
    FilterEqualityMatch   = 3
    FilterSubstrings      = 4
    FilterGreaterOrEqual  = 5
    FilterLessOrEqual     = 6
    FilterPresent         = 7
    FilterApproxMatch     = 8
    FilterExtensibleMatch = 9
)

SubstringFilter options

const (
    FilterSubstringsInitial = 0
    FilterSubstringsAny     = 1
    FilterSubstringsFinal   = 2
)

MatchingRuleAssertion choices

const (
    MatchingRuleAssertionMatchingRule = 1
    MatchingRuleAssertionType         = 2
    MatchingRuleAssertionMatchValue   = 3
    MatchingRuleAssertionDNAttributes = 4
)

LDAP Application Codes

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 Behera Password Policy Draft 10 (https://tools.ietf.org/html/draft-behera-ldap-password-policy-10)

const (
    BeheraPasswordExpired             = 0
    BeheraAccountLocked               = 1
    BeheraChangeAfterReset            = 2
    BeheraPasswordModNotAllowed       = 3
    BeheraMustSupplyOldPassword       = 4
    BeheraInsufficientPasswordQuality = 5
    BeheraPasswordTooShort            = 6
    BeheraPasswordTooYoung            = 7
    BeheraPasswordInHistory           = 8
)

Change operation choices

const (
    AddAttribute     = 0
    DeleteAttribute  = 1
    ReplaceAttribute = 2
)

scope choices

const (
    ScopeBaseObject   = 0
    ScopeSingleLevel  = 1
    ScopeWholeSubtree = 2
)

derefAliases

const (
    NeverDerefAliases   = 0
    DerefInSearching    = 1
    DerefFindingBaseObj = 2
    DerefAlways         = 3
)

Variables

ApplicationMap contains human readable descriptions of LDAP Application Codes

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",
}

BeheraPasswordPolicyErrorMap contains human readable descriptions of Behera Password Policy error codes

var BeheraPasswordPolicyErrorMap = map[int8]string{
    BeheraPasswordExpired:             "Password expired",
    BeheraAccountLocked:               "Account locked",
    BeheraChangeAfterReset:            "Password must be changed",
    BeheraPasswordModNotAllowed:       "Policy prevents password modification",
    BeheraMustSupplyOldPassword:       "Policy requires old password in order to change password",
    BeheraInsufficientPasswordQuality: "Password fails quality checks",
    BeheraPasswordTooShort:            "Password is too short for policy",
    BeheraPasswordTooYoung:            "Password has been changed too recently",
    BeheraPasswordInHistory:           "New password is in list of old passwords",
}

ControlTypeMap maps controls to text descriptions

var ControlTypeMap = map[string]string{
    ControlTypePaging:               "Paging",
    ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
    ControlTypeManageDsaIT:          "Manage DSA IT",
}

DefaultTimeout is a package-level variable that sets the timeout value used for the Dial and DialTLS methods.

WARNING: since this is a package-level variable, setting this value from multiple places will probably result in undesired behaviour.

var DefaultTimeout = 60 * time.Second

DerefMap contains human readable descriptions of derefAliases choices

var DerefMap = map[int]string{
    NeverDerefAliases:   "NeverDerefAliases",
    DerefInSearching:    "DerefInSearching",
    DerefFindingBaseObj: "DerefFindingBaseObj",
    DerefAlways:         "DerefAlways",
}

FilterMap contains human readable descriptions of Filter choices

var FilterMap = map[uint64]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",
}

FilterSubstringsMap contains human readable descriptions of SubstringFilter choices

var FilterSubstringsMap = map[uint64]string{
    FilterSubstringsInitial: "Substrings Initial",
    FilterSubstringsAny:     "Substrings Any",
    FilterSubstringsFinal:   "Substrings Final",
}

LDAPResultCodeMap contains string descriptions for LDAP error codes

var LDAPResultCodeMap = map[uint8]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",
}

MatchingRuleAssertionMap contains human readable descriptions of MatchingRuleAssertion choices

var MatchingRuleAssertionMap = map[uint64]string{
    MatchingRuleAssertionMatchingRule: "Matching Rule Assertion Matching Rule",
    MatchingRuleAssertionType:         "Matching Rule Assertion Type",
    MatchingRuleAssertionMatchValue:   "Matching Rule Assertion Match Value",
    MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
}

ScopeMap contains human readable descriptions of scope choices

var ScopeMap = map[int]string{
    ScopeBaseObject:   "Base Object",
    ScopeSingleLevel:  "Single Level",
    ScopeWholeSubtree: "Whole Subtree",
}

func CompileFilter

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

CompileFilter converts a string representation of a filter into a BER-encoded packet

func DebugBinaryFile

func DebugBinaryFile(fileName string) error

DebugBinaryFile reads and prints packets from the given filename

func DecompileFilter

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

DecompileFilter converts a packet representation of a filter into a string representation

func EscapeFilter

func EscapeFilter(filter string) string

EscapeFilter escapes from the provided LDAP filter string the special characters in the set `()*\` and those out of the range 0 < c < 0x80, as defined in RFC4515.

func IsErrorWithCode

func IsErrorWithCode(err error, desiredResultCode uint8) bool

IsErrorWithCode returns true if the given error is an LDAP error with the given result code

func NewError

func NewError(resultCode uint8, err error) error

NewError creates an LDAP error with the given code and underlying error

type AddRequest

AddRequest represents an LDAP AddRequest operation

type AddRequest struct {
    // DN identifies the entry being added
    DN string
    // Attributes list the attributes of the new entry
    Attributes []Attribute
}

func NewAddRequest

func NewAddRequest(dn string) *AddRequest

NewAddRequest returns an AddRequest for the given DN, with no attributes

func (*AddRequest) Attribute

func (a *AddRequest) Attribute(attrType string, attrVals []string)

Attribute adds an attribute with the given type and values

type Attribute

Attribute represents an LDAP attribute

type Attribute struct {
    // Type is the name of the LDAP attribute
    Type string
    // Vals are the LDAP attribute values
    Vals []string
}

type AttributeTypeAndValue

AttributeTypeAndValue represents an attributeTypeAndValue from https://tools.ietf.org/html/rfc4514

type AttributeTypeAndValue struct {
    // Type is the attribute type
    Type string
    // Value is the attribute value
    Value string
}

func (*AttributeTypeAndValue) Equal

func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool

Equal returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue Case of the attribute type is not significant

type Client

Client knows how to interact with an LDAP server

type Client interface {
    Start()
    StartTLS(config *tls.Config) error
    Close()
    SetTimeout(time.Duration)

    Bind(username, password string) error
    SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)

    Add(addRequest *AddRequest) error
    Del(delRequest *DelRequest) error
    Modify(modifyRequest *ModifyRequest) error

    Compare(dn, attribute, value string) (bool, error)
    PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)

    Search(searchRequest *SearchRequest) (*SearchResult, error)
    SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
}

type Conn

Conn represents an LDAP Connection

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

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 NewConn

func NewConn(conn net.Conn, isTLS bool) *Conn

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

func (*Conn) Add

func (l *Conn) Add(addRequest *AddRequest) error

Add performs the given AddRequest

func (*Conn) Bind

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

Bind performs a bind with the given username and password

Example

ExampleConn_Bind demonstrates how to bind a connection to an ldap user allowing access to restricted attrabutes that user has access to

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

err = l.Bind("cn=read-only-admin,dc=example,dc=com", "password")
if err != nil {
    log.Fatal(err)
}

func (*Conn) Close

func (l *Conn) Close()

Close closes the connection.

func (*Conn) Compare

func (l *Conn) Compare(dn, attribute, value string) (bool, error)

Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise false with any error that occurs if any.

Example

ExampleConn_Compare demonstrates how to comapre an attribute with a value

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

matched, err := l.Compare("cn=user,dc=example,dc=com", "uid", "someuserid")
if err != nil {
    log.Fatal(err)
}

fmt.Println(matched)

func (*Conn) Del

func (l *Conn) Del(delRequest *DelRequest) error

Del executes the given delete request

func (*Conn) Modify

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

Modify performs the ModifyRequest

Example

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

// Add a description, and replace the mail attributes
modify := ldap.NewModifyRequest("cn=user,dc=example,dc=com")
modify.Add("description", []string{"An example user"})
modify.Replace("mail", []string{"user@example.org"})

err = l.Modify(modify)
if err != nil {
    log.Fatal(err)
}

func (*Conn) PasswordModify

func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)

PasswordModify performs the modification request

Example (Admin)

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

err = l.Bind("cn=admin,dc=example,dc=com", "password")
if err != nil {
    log.Fatal(err)
}

passwordModifyRequest := ldap.NewPasswordModifyRequest("cn=user,dc=example,dc=com", "", "NewPassword")
_, err = l.PasswordModify(passwordModifyRequest)

if err != nil {
    log.Fatalf("Password could not be changed: %s", err.Error())
}

Example (GeneratedPassword)

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

err = l.Bind("cn=user,dc=example,dc=com", "password")
if err != nil {
    log.Fatal(err)
}

passwordModifyRequest := ldap.NewPasswordModifyRequest("", "OldPassword", "")
passwordModifyResponse, err := l.PasswordModify(passwordModifyRequest)
if err != nil {
    log.Fatalf("Password could not be changed: %s", err.Error())
}

generatedPassword := passwordModifyResponse.GeneratedPassword
log.Printf("Generated password: %s\n", generatedPassword)

Example (SetNewPassword)

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

err = l.Bind("cn=user,dc=example,dc=com", "password")
if err != nil {
    log.Fatal(err)
}

passwordModifyRequest := ldap.NewPasswordModifyRequest("", "OldPassword", "NewPassword")
_, err = l.PasswordModify(passwordModifyRequest)

if err != nil {
    log.Fatalf("Password could not be changed: %s", err.Error())
}

func (*Conn) Search

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

Search performs the given search request

func (*Conn) SearchWithPaging

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

SearchWithPaging accepts a search request and desired page size in order to execute LDAP queries to fulfill the search request. All paged LDAP query responses will be buffered and the final result will be returned atomically. The following four cases are possible given the arguments:

- given SearchRequest missing a control of type ControlTypePaging: we will add one with the desired paging size
- given SearchRequest contains a control of type ControlTypePaging that isn't actually a ControlPaging: fail without issuing any queries
- given SearchRequest contains a control of type ControlTypePaging with pagingSize equal to the size requested: no change to the search request
- given SearchRequest contains a control of type ControlTypePaging with pagingSize not equal to the size requested: fail without issuing any queries

A requested pagingSize of 0 is interpreted as no limit by LDAP servers.

func (*Conn) SetTimeout

func (l *Conn) SetTimeout(timeout time.Duration)

SetTimeout sets the time after a request is sent that a MessageTimeout triggers

func (*Conn) SimpleBind

func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)

SimpleBind performs the simple bind operation defined in the given request

func (*Conn) Start

func (l *Conn) Start()

Start initializes goroutines to read responses and process messages

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

Example

ExampleStartTLS demonstrates how to start a TLS connection

Code:

l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
    log.Fatal(err)
}
defer l.Close()

// Reconnect with TLS
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
if err != nil {
    log.Fatal(err)
}

// Opertations via l are now encrypted

type Control

Control defines an interface controls provide to encode and describe themselves

type Control interface {
    // GetControlType returns the OID
    GetControlType() string
    // Encode returns the ber packet representation
    Encode() *ber.Packet
    // String returns a human-readable description
    String() string
}

func DecodeControl

func DecodeControl(packet *ber.Packet) Control

DecodeControl returns a control read from the given packet, or nil if no recognized control can be made

func FindControl

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

FindControl returns the first control of the given type in the list, or nil

type ControlBeheraPasswordPolicy

ControlBeheraPasswordPolicy implements the control described in https://tools.ietf.org/html/draft-behera-ldap-password-policy-10

type ControlBeheraPasswordPolicy struct {
    // Expire contains the number of seconds before a password will expire
    Expire int64
    // Grace indicates the remaining number of times a user will be allowed to authenticate with an expired password
    Grace int64
    // Error indicates the error code
    Error int8
    // ErrorString is a human readable error
    ErrorString string
}

func NewControlBeheraPasswordPolicy

func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy

NewControlBeheraPasswordPolicy returns a ControlBeheraPasswordPolicy

func (*ControlBeheraPasswordPolicy) Encode

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

Encode returns the ber packet representation

func (*ControlBeheraPasswordPolicy) GetControlType

func (c *ControlBeheraPasswordPolicy) GetControlType() string

GetControlType returns the OID

func (*ControlBeheraPasswordPolicy) String

func (c *ControlBeheraPasswordPolicy) String() string

String returns a human-readable description

type ControlManageDsaIT

ControlManageDsaIT implements the control described in https://tools.ietf.org/html/rfc3296

type ControlManageDsaIT struct {
    // Criticality indicates if this control is required
    Criticality bool
}

func NewControlManageDsaIT

func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT

NewControlManageDsaIT returns a ControlManageDsaIT control

func (*ControlManageDsaIT) Encode

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

Encode returns the ber packet representation

func (*ControlManageDsaIT) GetControlType

func (c *ControlManageDsaIT) GetControlType() string

GetControlType returns the OID

func (*ControlManageDsaIT) String

func (c *ControlManageDsaIT) String() string

String returns a human-readable description

type ControlPaging

ControlPaging implements the paging control described in https://www.ietf.org/rfc/rfc2696.txt

type ControlPaging struct {
    // PagingSize indicates the page size
    PagingSize uint32
    // Cookie is an opaque value returned by the server to track a paging cursor
    Cookie []byte
}

func NewControlPaging

func NewControlPaging(pagingSize uint32) *ControlPaging

NewControlPaging returns a paging control

func (*ControlPaging) Encode

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

Encode returns the ber packet representation

func (*ControlPaging) GetControlType

func (c *ControlPaging) GetControlType() string

GetControlType returns the OID

func (*ControlPaging) SetCookie

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

SetCookie stores the given cookie in the paging control

func (*ControlPaging) String

func (c *ControlPaging) String() string

String returns a human-readable description

type ControlString

ControlString implements the Control interface for simple controls

type ControlString struct {
    ControlType  string
    Criticality  bool
    ControlValue string
}

func NewControlString

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

NewControlString returns a generic control

func (*ControlString) Encode

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

Encode returns the ber packet representation

func (*ControlString) GetControlType

func (c *ControlString) GetControlType() string

GetControlType returns the OID

func (*ControlString) String

func (c *ControlString) String() string

String returns a human-readable description

type ControlVChuPasswordMustChange

ControlVChuPasswordMustChange implements the control described in https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00

type ControlVChuPasswordMustChange struct {
    // MustChange indicates if the password is required to be changed
    MustChange bool
}

func (*ControlVChuPasswordMustChange) Encode

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

Encode returns the ber packet representation

func (*ControlVChuPasswordMustChange) GetControlType

func (c *ControlVChuPasswordMustChange) GetControlType() string

GetControlType returns the OID

func (*ControlVChuPasswordMustChange) String

func (c *ControlVChuPasswordMustChange) String() string

String returns a human-readable description

type ControlVChuPasswordWarning

ControlVChuPasswordWarning implements the control described in https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00

type ControlVChuPasswordWarning struct {
    // Expire indicates the time in seconds until the password expires
    Expire int64
}

func (*ControlVChuPasswordWarning) Encode

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

Encode returns the ber packet representation

func (*ControlVChuPasswordWarning) GetControlType

func (c *ControlVChuPasswordWarning) GetControlType() string

GetControlType returns the OID

func (*ControlVChuPasswordWarning) String

func (c *ControlVChuPasswordWarning) String() string

String returns a human-readable description

type DN

DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514

type DN struct {
    RDNs []*RelativeDN
}

func ParseDN

func ParseDN(str string) (*DN, error)

ParseDN returns a distinguishedName or an error

func (*DN) AncestorOf

func (d *DN) AncestorOf(other *DN) bool

AncestorOf returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN. "ou=widgets,o=acme.com" is an ancestor of "ou=sprockets,ou=widgets,o=acme.com" "ou=widgets,o=acme.com" is not an ancestor of "ou=sprockets,ou=widgets,o=foo.com" "ou=widgets,o=acme.com" is not an ancestor of "ou=widgets,o=acme.com"

func (*DN) Equal

func (d *DN) Equal(other *DN) bool

Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). Returns true if they have the same number of relative distinguished names and corresponding relative distinguished names (by position) are the same.

type DelRequest

DelRequest implements an LDAP deletion request

type DelRequest struct {
    // DN is the name of the directory entry to delete
    DN string
    // Controls hold optional controls to send with the request
    Controls []Control
}

func NewDelRequest

func NewDelRequest(DN string,
    Controls []Control) *DelRequest

NewDelRequest creates a delete request for the given DN and controls

type Entry

Entry represents a single search result entry

type Entry struct {
    // DN is the distinguished name of the entry
    DN string
    // Attributes are the returned attributes for the entry
    Attributes []*EntryAttribute
}

func NewEntry

func NewEntry(dn string, attributes map[string][]string) *Entry

NewEntry returns an Entry object with the specified distinguished name and attribute key-value pairs. The map of attributes is accessed in alphabetical order of the keys in order to ensure that, for the same input map of attributes, the output entry will contain the same order of attributes

func (*Entry) GetAttributeValue

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

GetAttributeValue returns the first value for the named attribute, or ""

func (*Entry) GetAttributeValues

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

GetAttributeValues returns the values for the named attribute, or an empty list

func (*Entry) GetRawAttributeValue

func (e *Entry) GetRawAttributeValue(attribute string) []byte

GetRawAttributeValue returns the first value for the named attribute, or an empty slice

func (*Entry) GetRawAttributeValues

func (e *Entry) GetRawAttributeValues(attribute string) [][]byte

GetRawAttributeValues returns the byte values for the named attribute, or an empty list

func (*Entry) PrettyPrint

func (e *Entry) PrettyPrint(indent int)

PrettyPrint outputs a human-readable description indenting

func (*Entry) Print

func (e *Entry) Print()

Print outputs a human-readable description

type EntryAttribute

EntryAttribute holds a single attribute

type EntryAttribute struct {
    // Name is the name of the attribute
    Name string
    // Values contain the string values of the attribute
    Values []string
    // ByteValues contain the raw values of the attribute
    ByteValues [][]byte
}

func NewEntryAttribute

func NewEntryAttribute(name string, values []string) *EntryAttribute

NewEntryAttribute returns a new EntryAttribute with the desired key-value pair

func (*EntryAttribute) PrettyPrint

func (e *EntryAttribute) PrettyPrint(indent int)

PrettyPrint outputs a human-readable description with indenting

func (*EntryAttribute) Print

func (e *EntryAttribute) Print()

Print outputs a human-readable description

type Error

Error holds LDAP error information

type Error struct {
    // Err is the underlying error
    Err error
    // ResultCode is the LDAP error code
    ResultCode uint8
}

func (*Error) Error

func (e *Error) Error() string

type ModifyRequest

ModifyRequest as defined in https://tools.ietf.org/html/rfc4511

type ModifyRequest struct {
    // DN is the distinguishedName of the directory entry to modify
    DN string
    // AddAttributes contain the attributes to add
    AddAttributes []PartialAttribute
    // DeleteAttributes contain the attributes to delete
    DeleteAttributes []PartialAttribute
    // ReplaceAttributes contain the attributes to replace
    ReplaceAttributes []PartialAttribute
}

func NewModifyRequest

func NewModifyRequest(
    dn string,
) *ModifyRequest

NewModifyRequest creates a modify request for the given DN

func (*ModifyRequest) Add

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

Add inserts the given attribute to the list of attributes to add

func (*ModifyRequest) Delete

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

Delete inserts the given attribute to the list of attributes to delete

func (*ModifyRequest) Replace

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

Replace inserts the given attribute to the list of attributes to replace

type PacketResponse

PacketResponse contains the packet or error encountered reading a response

type PacketResponse struct {
    // Packet is the packet read from the server
    Packet *ber.Packet
    // Error is an error encountered while reading
    Error error
}

func (*PacketResponse) ReadPacket

func (pr *PacketResponse) ReadPacket() (*ber.Packet, error)

ReadPacket returns the packet or an error

type PartialAttribute

PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511

type PartialAttribute struct {
    // Type is the type of the partial attribute
    Type string
    // Vals are the values of the partial attribute
    Vals []string
}

type PasswordModifyRequest

PasswordModifyRequest implements the Password Modify Extended Operation as defined in https://www.ietf.org/rfc/rfc3062.txt

type PasswordModifyRequest struct {
    // UserIdentity is an optional string representation of the user associated with the request.
    // This string may or may not be an LDAPDN [RFC2253].
    // If no UserIdentity field is present, the request acts up upon the password of the user currently associated with the LDAP session
    UserIdentity string
    // OldPassword, if present, contains the user's current password
    OldPassword string
    // NewPassword, if present, contains the desired password for this user
    NewPassword string
}

func NewPasswordModifyRequest

func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPassword string) *PasswordModifyRequest

NewPasswordModifyRequest creates a new PasswordModifyRequest

According to the RFC 3602: userIdentity is a string representing the user associated with the request. This string may or may not be an LDAPDN (RFC 2253). If userIdentity is empty then the operation will act on the user associated with the session.

oldPassword is the current user's password, it can be empty or it can be needed depending on the session user access rights (usually an administrator can change a user's password without knowing the current one) and the password policy (see pwdSafeModify password policy's attribute)

newPassword is the desired user's password. If empty the server can return an error or generate a new password that will be available in the PasswordModifyResult.GeneratedPassword

type PasswordModifyResult

PasswordModifyResult holds the server response to a PasswordModifyRequest

type PasswordModifyResult struct {
    // GeneratedPassword holds a password generated by the server, if present
    GeneratedPassword string
}

type RelativeDN

RelativeDN represents a relativeDistinguishedName from https://tools.ietf.org/html/rfc4514

type RelativeDN struct {
    Attributes []*AttributeTypeAndValue
}

func (*RelativeDN) Equal

func (r *RelativeDN) Equal(other *RelativeDN) bool

Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). Relative distinguished names are the same if and only if they have the same number of AttributeTypeAndValues and each attribute of the first RDN is the same as the attribute of the second RDN with the same attribute type. The order of attributes is not significant. Case of attribute types is not significant.

type SearchRequest

SearchRequest represents a search request to send to the server

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

NewSearchRequest creates a new search request

type SearchResult

SearchResult holds the server's response to a search request

type SearchResult struct {
    // Entries are the returned entries
    Entries []*Entry
    // Referrals are the returned referrals
    Referrals []string
    // Controls are the returned controls
    Controls []Control
}

func (*SearchResult) PrettyPrint

func (s *SearchResult) PrettyPrint(indent int)

PrettyPrint outputs a human-readable description with indenting

func (*SearchResult) Print

func (s *SearchResult) Print()

Print outputs a human-readable description

type SimpleBindRequest

SimpleBindRequest represents a username/password bind operation

type SimpleBindRequest struct {
    // Username is the name of the Directory object that the client wishes to bind as
    Username string
    // Password is the credentials to bind with
    Password string
    // Controls are optional controls to send with the bind request
    Controls []Control
}

func NewSimpleBindRequest

func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest

NewSimpleBindRequest returns a bind request

type SimpleBindResult

SimpleBindResult contains the response from the server

type SimpleBindResult struct {
    Controls []Control
}