Documentation ¶
Overview ¶
Package ldap provides basic LDAP v3 functionality.
Example (Beherappolicy) ¶
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) }
Output:
Example (UserAuthentication) ¶
Example User Authentication shows how a typical application can verify a login attempt
// 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) }
Output:
Example (Vchuppolicy) ¶
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) }
Output:
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 EscapeValue(value string) (escaped string)
- func IsErrorWithCode(err error, desiredResultCode uint8) bool
- func NewError(resultCode uint8, err error) error
- type AddRequest
- type Attribute
- type AttributeTypeAndValue
- type Client
- type Conn
- func (l *Conn) Add(addRequest *AddRequest) error
- func (l *Conn) Alive() bool
- 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
- type ControlBeheraPasswordPolicy
- type ControlManageDsaIT
- type ControlPaging
- type ControlString
- type ControlVChuPasswordMustChange
- type ControlVChuPasswordWarning
- type DN
- func (dn *DN) Append(other *DN)
- func (dn *DN) Clone() *DN
- func (dn *DN) Equal(other *DN) bool
- func (dn *DN) IsSubordinate(other *DN) bool
- func (dn *DN) Move(newBase *DN)
- func (dn *DN) Parent() *DN
- func (dn *DN) RDN() string
- func (dn *DN) Rename(rdn *RelativeDN)
- func (dn *DN) String() string
- func (dn *DN) Strip(base *DN) error
- type DNs
- type DelRequest
- type 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
- type Error
- type LDIF
- type ModifyRequest
- type PacketResponse
- type PartialAttribute
- type PasswordModifyRequest
- type PasswordModifyResult
- type Pool
- type PoolConn
- func (p *PoolConn) Add(addRequest *AddRequest) error
- func (p *PoolConn) Alive() bool
- func (p *PoolConn) Bind(username, password string) error
- func (p *PoolConn) Close()
- func (p *PoolConn) Compare(dn, attribute, value string) (bool, error)
- func (p *PoolConn) Del(delRequest *DelRequest) error
- func (p *PoolConn) MarkUnusable()
- func (p *PoolConn) Modify(modifyRequest *ModifyRequest) error
- func (p *PoolConn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
- func (p *PoolConn) Search(searchRequest *SearchRequest) (*SearchResult, error)
- func (p *PoolConn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
- func (p *PoolConn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)
- func (p *PoolConn) Start()
- func (p *PoolConn) StartTLS(config *tls.Config) error
- type PoolFactory
- type RelativeDN
- type SearchRequest
- type SearchResult
- type SimpleBindRequest
- type SimpleBindResult
Examples ¶
Constants ¶
const ( MessageQuit = 0 MessageRequest = 1 MessageResponse = 2 MessageFinish = 3 MessageTimeout = 4 )
const ( ControlTypePaging = "1.2.840.113556.1.4.319" ControlTypeBeheraPasswordPolicy = "1.3.6.1.4.1.42.2.27.8.5.1" ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4" ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5" ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2" )
const ( LDAPResultSuccess = 0 LDAPResultOperationsError = 1 LDAPResultProtocolError = 2 LDAPResultTimeLimitExceeded = 3 LDAPResultSizeLimitExceeded = 4 LDAPResultCompareFalse = 5 LDAPResultCompareTrue = 6 LDAPResultAuthMethodNotSupported = 7 LDAPResultStrongAuthRequired = 8 LDAPResultReferral = 10 LDAPResultAdminLimitExceeded = 11 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 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 )
LDAP Result Codes
const ( FilterAnd = 0 FilterOr = 1 FilterNot = 2 FilterEqualityMatch = 3 FilterSubstrings = 4 FilterGreaterOrEqual = 5 FilterLessOrEqual = 6 FilterPresent = 7 FilterApproxMatch = 8 FilterExtensibleMatch = 9 )
const ( FilterSubstringsInitial = 0 FilterSubstringsAny = 1 FilterSubstringsFinal = 2 )
const ( MatchingRuleAssertionMatchingRule = 1 MatchingRuleAssertionType = 2 MatchingRuleAssertionMatchValue = 3 MatchingRuleAssertionDNAttributes = 4 )
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
const ( BeheraPasswordExpired = 0 BeheraAccountLocked = 1 BeheraChangeAfterReset = 2 BeheraPasswordModNotAllowed = 3 BeheraMustSupplyOldPassword = 4 BeheraInsufficientPasswordQuality = 5 BeheraPasswordTooShort = 6 BeheraPasswordTooYoung = 7 BeheraPasswordInHistory = 8 )
Ldap Behera Password Policy Draft 10 (https://tools.ietf.org/html/draft-behera-ldap-password-policy-10)
const ( AddAttribute = 0 DeleteAttribute = 1 ReplaceAttribute = 2 )
const ( ScopeBaseObject = 0 ScopeSingleLevel = 1 ScopeWholeSubtree = 2 )
const ( NeverDerefAliases = 0 DerefInSearching = 1 DerefFindingBaseObj = 2 DerefAlways = 3 )
Variables ¶
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", }
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", }
var CR byte = '\x0D'
var Comment byte = '#'
var ControlTypeMap = map[string]string{ ControlTypePaging: "Paging", ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft", ControlTypeManageDsaIT: "Manage DSA IT", }
var DefaultTimeout = 60 * time.Second
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 DerefMap = map[int]string{ NeverDerefAliases: "NeverDerefAliases", DerefInSearching: "DerefInSearching", DerefFindingBaseObj: "DerefFindingBaseObj", DerefAlways: "DerefAlways", }
var ( // ErrClosed is the error resulting if the pool is closed via pool.Close(). ErrClosed = errors.New("pool is closed") )
var ErrDNNotSubordinate = errors.New("Not a subordinate")
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", }
var FilterSubstringsMap = map[uint64]string{ FilterSubstringsInitial: "Substrings Initial", FilterSubstringsAny: "Substrings Any", FilterSubstringsFinal: "Substrings Final", }
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", }
var LF byte = '\x0A'
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", }
var RDNCompareFold bool = true
When true, uses strings.EqualFold to compare the values of an RDN. This is usually needed as true for most values, set to false when your DNs contain case sensitive values.
var SPACE byte = ' '
var SPACES = string(SPACE)
var ScopeMap = map[int]string{ ScopeBaseObject: "Base Object", ScopeSingleLevel: "Single Level", ScopeWholeSubtree: "Whole Subtree", }
Functions ¶
func CompileFilter ¶
func DebugBinaryFile ¶
func DecompileFilter ¶
func EscapeFilter ¶
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 EscapeValue ¶
func IsErrorWithCode ¶
Types ¶
type AddRequest ¶
func NewAddRequest ¶
func NewAddRequest(dn string) *AddRequest
func (*AddRequest) Attribute ¶
func (a *AddRequest) Attribute(attrType string, attrVals []string)
type AttributeTypeAndValue ¶
type Client ¶
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) }
Client knows how to interact with an LDAP server
type Conn ¶
type Conn struct { Debug debugging // contains filtered or unexported fields }
Conn represents an LDAP Connection
func Dial ¶
Dial connects to the given address on the given network using net.Dial and then returns a new Conn for the connection.
func DialTLS ¶
DialTLS connects to the given address on the given network using tls.Dial and then returns a new Conn for the connection.
func (*Conn) Add ¶
func (l *Conn) Add(addRequest *AddRequest) error
func (*Conn) Bind ¶
Example ¶
ExampleConn_Bind demonstrates how to bind a connection to an ldap user allowing access to restricted attrabutes that user has access to
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) }
Output:
func (*Conn) Compare ¶
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
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)
Output:
func (*Conn) Del ¶
func (l *Conn) Del(delRequest *DelRequest) error
func (*Conn) Modify ¶
func (l *Conn) Modify(modifyRequest *ModifyRequest) error
Example ¶
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) }
Output:
func (*Conn) PasswordModify ¶
func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
Example (Admin) ¶
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()) }
Output:
Example (GeneratedPassword) ¶
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)
Output:
Example (SetNewPassword) ¶
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()) }
Output:
func (*Conn) Search ¶
func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error)
Example ¶
ExampleConn_Search demonstrates how to use the search interface
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389)) if err != nil { log.Fatal(err) } defer l.Close() searchRequest := ldap.NewSearchRequest( "dc=example,dc=com", // The base dn to search ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, "(&(objectClass=organizationalPerson))", // The filter to apply []string{"dn", "cn"}, // A list attributes to retrieve nil, ) sr, err := l.Search(searchRequest) if err != nil { log.Fatal(err) } for _, entry := range sr.Entries { fmt.Printf("%s: %v\n", entry.DN, entry.GetAttributeValue("cn")) }
Output:
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 ¶
Sets the time after a request is sent that a MessageTimeout triggers
func (*Conn) SimpleBind ¶
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)
func (*Conn) StartTLS ¶
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
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
Output:
type Control ¶
func DecodeControl ¶
func DecodeControl(packet *ber.Packet) Control
func FindControl ¶
type ControlBeheraPasswordPolicy ¶
func NewControlBeheraPasswordPolicy ¶
func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy
func (*ControlBeheraPasswordPolicy) Encode ¶
func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet
func (*ControlBeheraPasswordPolicy) GetControlType ¶
func (c *ControlBeheraPasswordPolicy) GetControlType() string
func (*ControlBeheraPasswordPolicy) String ¶
func (c *ControlBeheraPasswordPolicy) String() string
type ControlManageDsaIT ¶
type ControlManageDsaIT struct {
Criticality bool
}
func NewControlManageDsaIT ¶
func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT
func (*ControlManageDsaIT) Encode ¶
func (c *ControlManageDsaIT) Encode() *ber.Packet
func (*ControlManageDsaIT) GetControlType ¶
func (c *ControlManageDsaIT) GetControlType() string
func (*ControlManageDsaIT) String ¶
func (c *ControlManageDsaIT) String() string
type ControlPaging ¶
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 ¶
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 ControlVChuPasswordMustChange ¶
type ControlVChuPasswordMustChange struct {
MustChange bool
}
func (*ControlVChuPasswordMustChange) Encode ¶
func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet
func (*ControlVChuPasswordMustChange) GetControlType ¶
func (c *ControlVChuPasswordMustChange) GetControlType() string
func (*ControlVChuPasswordMustChange) String ¶
func (c *ControlVChuPasswordMustChange) String() string
type ControlVChuPasswordWarning ¶
type ControlVChuPasswordWarning struct {
Expire int64
}
func (*ControlVChuPasswordWarning) Encode ¶
func (c *ControlVChuPasswordWarning) Encode() *ber.Packet
func (*ControlVChuPasswordWarning) GetControlType ¶
func (c *ControlVChuPasswordWarning) GetControlType() string
func (*ControlVChuPasswordWarning) String ¶
func (c *ControlVChuPasswordWarning) String() string
type DN ¶
type DN struct {
RDNs []*RelativeDN
}
func (*DN) Append ¶
appends the "other" DN to the "dn", e.g.
dn, err := ldap.ParseDN("CN=Someone") base, err := ldap.ParseDN("ou=people,dc=example,dc=org") dn.Append(base) -> "cn=Someone,ou=people,dc=example,dc=org"
func (*DN) IsSubordinate ¶
Returns true if the "other" DN is a parent of "dn"
func (*DN) RDN ¶
Returns the value of the first RDN, e.g.
dn, err := ldap.ParseDN("uid=someone,ou=people,dc=example,dc=org") dn.RDN() -> "someone"
func (*DN) Rename ¶
func (dn *DN) Rename(rdn *RelativeDN)
Changes the first RDN of DN to the given one
type DNs ¶
type DNs []*DN
Sorting DNs:
all := []*ldap.DN{dn1, dn2, dn3, dn4} sort.Sort(DNs(all)) for _, dn := range all { println(dn.String()) }
The result order from deepest part in tree upwards, so you could easily search for all dns in a base, sort them and then remove every DN in that order to remove the tree (including the search base)
type DelRequest ¶
func NewDelRequest ¶
func NewDelRequest(DN string, Controls []Control) *DelRequest
type Entry ¶
type Entry struct { DN string Attributes []*EntryAttribute }
func NewEntry ¶
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 (*Entry) GetAttributeValues ¶
func (*Entry) GetRawAttributeValue ¶
func (*Entry) GetRawAttributeValues ¶
func (*Entry) PrettyPrint ¶
type EntryAttribute ¶
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)
func (*EntryAttribute) Print ¶
func (e *EntryAttribute) Print()
type LDIF ¶
type LDIF struct { RelaxedParser bool // ignore parsing errors in a line Entries []*Entry // contains filtered or unexported fields }
A basic LDIF parser. This one does currently just support LDIFs like they're generated by tools like ldapsearch(1) / slapcat(8). Change records are not supported.
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 PacketResponse ¶
type PacketResponse struct { Packet *ber.Packet Error error }
func (*PacketResponse) ReadPacket ¶
func (pr *PacketResponse) ReadPacket() (*ber.Packet, error)
type PartialAttribute ¶
type PasswordModifyRequest ¶
func NewPasswordModifyRequest ¶
func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPassword string) *PasswordModifyRequest
Create 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 ¶
type PasswordModifyResult struct {
GeneratedPassword string
}
type Pool ¶
type Pool interface { // Get returns a new connection from the pool. Closing the connections puts // it back to the Pool. Closing it when the pool is destroyed or full will // be counted as an error. Get() (*PoolConn, error) // Close closes the pool and all its connections. After Close() the pool is // no longer usable. Close() // Len returns the current number of connections of the pool. Len() int }
Pool interface describes a pool implementation. A pool should have maximum capacity. An ideal pool is threadsafe and easy to use.
func NewChannelPool ¶
func NewChannelPool(initialCap, maxCap int, name string, factory PoolFactory, closeAt []uint8) (Pool, error)
NewChannelPool returns a new pool based on buffered channels with an initial capacity and maximum capacity. Factory is used when initial capacity is greater than zero to fill the pool. A zero initialCap doesn't fill the Pool until a new Get() is called. During a Get(), If there is no new connection available in the pool, a new connection will be created via the Factory() method.
closeAt will automagically mark the connection as unusable if the return code of the call is one of those passed, most likely you want to set this to something like
[]uint8{ldap.LDAPResultTimeLimitExceeded, ldap.ErrorNetwork}
type PoolConn ¶
type PoolConn struct { Conn Client // contains filtered or unexported fields }
PoolConn implements Client to override the Close() method
func (*PoolConn) Add ¶
func (p *PoolConn) Add(addRequest *AddRequest) error
func (*PoolConn) Close ¶
func (p *PoolConn) Close()
Close() puts the given connects back to the pool instead of closing it.
func (*PoolConn) Del ¶
func (p *PoolConn) Del(delRequest *DelRequest) error
func (*PoolConn) MarkUnusable ¶
func (p *PoolConn) MarkUnusable()
MarkUnusable() marks the connection not usable any more, to let the pool close it instead of returning it to pool.
func (*PoolConn) Modify ¶
func (p *PoolConn) Modify(modifyRequest *ModifyRequest) error
func (*PoolConn) PasswordModify ¶
func (p *PoolConn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
func (*PoolConn) Search ¶
func (p *PoolConn) Search(searchRequest *SearchRequest) (*SearchResult, error)
func (*PoolConn) SearchWithPaging ¶
func (p *PoolConn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
func (*PoolConn) SimpleBind ¶
func (p *PoolConn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error)
type PoolFactory ¶
PoolFactory is a function to create new connections.
type RelativeDN ¶
type RelativeDN struct {
Attributes []*AttributeTypeAndValue
}
func (*RelativeDN) Equal ¶
func (r *RelativeDN) Equal(o *RelativeDN) bool
Check if all types and values of both RDNs are equal, the result may be influenced by the value of RDNCompareFold.
func (*RelativeDN) Less ¶
func (r *RelativeDN) Less(o *RelativeDN) bool
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 ¶
type SearchResult ¶
func (*SearchResult) PrettyPrint ¶
func (s *SearchResult) PrettyPrint(indent int)
func (*SearchResult) Print ¶
func (s *SearchResult) Print()
type SimpleBindRequest ¶
func NewSimpleBindRequest ¶
func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest
type SimpleBindResult ¶
type SimpleBindResult struct {
Controls []Control
}