Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ai3
accountserver
Commits
31b56bba
Commit
31b56bba
authored
Feb 17, 2019
by
ale
Browse files
Update to go-ldap v3
parent
94a5363e
Changes
32
Hide whitespace changes
Inline
Side-by-side
backend/model.go
View file @
31b56bba
...
...
@@ -9,7 +9,7 @@ import (
"time"
ldaputil
"git.autistici.org/ai3/go-common/ldap"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
as
"git.autistici.org/ai3/accountserver"
)
...
...
backend/resources.go
View file @
31b56bba
...
...
@@ -6,7 +6,7 @@ import (
"strconv"
"strings"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
as
"git.autistici.org/ai3/accountserver"
)
...
...
backend/resources_test.go
View file @
31b56bba
...
...
@@ -4,7 +4,7 @@ import (
"testing"
"github.com/go-test/deep"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
as
"git.autistici.org/ai3/accountserver"
)
...
...
backend/tx.go
View file @
31b56bba
...
...
@@ -5,7 +5,7 @@ import (
"log"
"strings"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
)
// Generic interface to LDAP - allows us to stub out the LDAP client while
...
...
@@ -134,7 +134,7 @@ func (tx *ldapTX) aggregateChanges(ctx context.Context) (map[string]*ldap.AddReq
if
_
,
isNew
:=
tx
.
newDNs
[
c
.
dn
];
isNew
{
ar
,
ok
:=
adds
[
c
.
dn
]
if
!
ok
{
ar
=
ldap
.
NewAddRequest
(
c
.
dn
)
ar
=
ldap
.
NewAddRequest
(
c
.
dn
,
nil
)
adds
[
c
.
dn
]
=
ar
dns
=
append
(
dns
,
c
.
dn
)
}
...
...
@@ -144,7 +144,7 @@ func (tx *ldapTX) aggregateChanges(ctx context.Context) (map[string]*ldap.AddReq
}
else
{
mr
,
ok
:=
mods
[
c
.
dn
]
if
!
ok
{
mr
=
ldap
.
NewModifyRequest
(
c
.
dn
)
mr
=
ldap
.
NewModifyRequest
(
c
.
dn
,
nil
)
mods
[
c
.
dn
]
=
mr
dns
=
append
(
dns
,
c
.
dn
)
}
...
...
@@ -198,9 +198,7 @@ func (tx *ldapTX) readAttributeValues(ctx context.Context, dn, attr string) []st
}
func
isEmptyModifyRequest
(
mr
*
ldap
.
ModifyRequest
)
bool
{
return
(
len
(
mr
.
AddAttributes
)
==
0
&&
len
(
mr
.
DeleteAttributes
)
==
0
&&
len
(
mr
.
ReplaceAttributes
)
==
0
)
return
len
(
mr
.
Changes
)
==
0
}
func
isEmptyAddRequest
(
ar
*
ldap
.
AddRequest
)
bool
{
...
...
backend/util.go
View file @
31b56bba
...
...
@@ -6,7 +6,7 @@ import (
"strings"
"time"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
)
// queryTemplate is the template for a single parametrized LDAP query.
...
...
vendor/git.autistici.org/ai3/go-common/ldap/parse.go
View file @
31b56bba
...
...
@@ -3,7 +3,7 @@ package ldaputil
import
(
"fmt"
"gopkg.in/ldap.v
2
"
"gopkg.in/ldap.v
3
"
)
// ParseScope parses a string representation of an LDAP scope into the
...
...
vendor/git.autistici.org/ai3/go-common/ldap/pool.go
View file @
31b56bba
...
...
@@ -8,7 +8,8 @@ import (
"time"
"github.com/cenkalti/backoff"
"gopkg.in/ldap.v2"
"go.opencensus.io/trace"
"gopkg.in/ldap.v3"
)
// Parameters that define the exponential backoff algorithm used.
...
...
@@ -147,9 +148,18 @@ func NewConnectionPool(uri, bindDN, bindPw string, cacheSize int) (*ConnectionPo
},
nil
}
func
(
p
*
ConnectionPool
)
doRequest
(
ctx
context
.
Context
,
fn
func
(
*
ldap
.
Conn
)
error
)
error
{
return
backoff
.
Retry
(
func
()
error
{
conn
,
err
:=
p
.
Get
(
ctx
)
func
(
p
*
ConnectionPool
)
doRequest
(
ctx
context
.
Context
,
name
string
,
attrs
[]
trace
.
Attribute
,
fn
func
(
*
ldap
.
Conn
)
error
)
error
{
// Tracing: initialize a new client span.
sctx
,
span
:=
trace
.
StartSpan
(
ctx
,
name
,
trace
.
WithSpanKind
(
trace
.
SpanKindClient
))
defer
span
.
End
()
if
len
(
attrs
)
>
0
{
span
.
AddAttributes
(
attrs
...
)
}
rerr
:=
backoff
.
Retry
(
func
()
error
{
conn
,
err
:=
p
.
Get
(
sctx
)
if
err
!=
nil
{
// Here conn is nil, so we don't need to Release it.
if
isTemporaryLDAPError
(
err
)
{
...
...
@@ -158,7 +168,7 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro
return
backoff
.
Permanent
(
err
)
}
if
deadline
,
ok
:=
ctx
.
Deadline
();
ok
{
if
deadline
,
ok
:=
s
ctx
.
Deadline
();
ok
{
conn
.
SetTimeout
(
time
.
Until
(
deadline
))
}
...
...
@@ -169,30 +179,42 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro
}
return
err
},
backoff
.
WithContext
(
newExponentialBackOff
(),
ctx
))
// Tracing: set the final status.
span
.
SetStatus
(
errorToTraceStatus
(
rerr
))
return
rerr
}
// Search performs the given search request. It will retry the request
// on temporary errors.
func
(
p
*
ConnectionPool
)
Search
(
ctx
context
.
Context
,
searchRequest
*
ldap
.
SearchRequest
)
(
*
ldap
.
SearchResult
,
error
)
{
var
result
*
ldap
.
SearchResult
err
:=
p
.
doRequest
(
ctx
,
func
(
conn
*
ldap
.
Conn
)
error
{
var
err
error
result
,
err
=
conn
.
Search
(
searchRequest
)
return
err
err
:=
p
.
doRequest
(
ctx
,
"ldap.Search"
,
[]
trace
.
Attribute
{
trace
.
StringAttribute
(
"ldap.base"
,
searchRequest
.
BaseDN
),
trace
.
StringAttribute
(
"ldap.filter"
,
searchRequest
.
Filter
),
trace
.
Int64Attribute
(
"ldap.scope"
,
int64
(
searchRequest
.
Scope
)),
},
func
(
conn
*
ldap
.
Conn
)
(
cerr
error
)
{
result
,
cerr
=
conn
.
Search
(
searchRequest
)
return
})
return
result
,
err
}
// Modify issues a ModifyRequest to the LDAP server.
func
(
p
*
ConnectionPool
)
Modify
(
ctx
context
.
Context
,
modifyRequest
*
ldap
.
ModifyRequest
)
error
{
return
p
.
doRequest
(
ctx
,
func
(
conn
*
ldap
.
Conn
)
error
{
return
p
.
doRequest
(
ctx
,
"ldap.Modify"
,
[]
trace
.
Attribute
{
trace
.
StringAttribute
(
"ldap.dn"
,
modifyRequest
.
DN
),
},
func
(
conn
*
ldap
.
Conn
)
error
{
return
conn
.
Modify
(
modifyRequest
)
})
}
// Add issues an AddRequest to the LDAP server.
func
(
p
*
ConnectionPool
)
Add
(
ctx
context
.
Context
,
addRequest
*
ldap
.
AddRequest
)
error
{
return
p
.
doRequest
(
ctx
,
func
(
conn
*
ldap
.
Conn
)
error
{
return
p
.
doRequest
(
ctx
,
"ldap.Add"
,
[]
trace
.
Attribute
{
trace
.
StringAttribute
(
"ldap.dn"
,
addRequest
.
DN
),
},
func
(
conn
*
ldap
.
Conn
)
error
{
return
conn
.
Add
(
addRequest
)
})
}
...
...
@@ -219,3 +241,16 @@ func isTemporaryLDAPError(err error) bool {
return
false
}
}
func
errorToTraceStatus
(
err
error
)
trace
.
Status
{
switch
err
{
case
nil
:
return
trace
.
Status
{
Code
:
trace
.
StatusCodeOK
,
Message
:
"OK"
}
case
context
.
Canceled
:
return
trace
.
Status
{
Code
:
trace
.
StatusCodeCancelled
,
Message
:
"CANCELED"
}
case
context
.
DeadlineExceeded
:
return
trace
.
Status
{
Code
:
trace
.
StatusCodeDeadlineExceeded
,
Message
:
"DEADLINE_EXCEEDED"
}
default
:
return
trace
.
Status
{
Code
:
trace
.
StatusCodeUnknown
,
Message
:
err
.
Error
()}
}
}
vendor/gopkg.in/ldap.v2/atomic_value.go
deleted
100644 → 0
View file @
94a5363e
// +build go1.4
package
ldap
import
(
"sync/atomic"
)
// For compilers that support it, we just use the underlying sync/atomic.Value
// type.
type
atomicValue
struct
{
atomic
.
Value
}
vendor/gopkg.in/ldap.v2/atomic_value_go13.go
deleted
100644 → 0
View file @
94a5363e
// +build !go1.4
package
ldap
import
(
"sync"
)
// This is a helper type that emulates the use of the "sync/atomic.Value"
// struct that's available in Go 1.4 and up.
type
atomicValue
struct
{
value
interface
{}
lock
sync
.
RWMutex
}
func
(
av
*
atomicValue
)
Store
(
val
interface
{})
{
av
.
lock
.
Lock
()
av
.
value
=
val
av
.
lock
.
Unlock
()
}
func
(
av
*
atomicValue
)
Load
()
interface
{}
{
av
.
lock
.
RLock
()
ret
:=
av
.
value
av
.
lock
.
RUnlock
()
return
ret
}
vendor/gopkg.in/ldap.v2/error.go
deleted
100644 → 0
View file @
94a5363e
package
ldap
import
(
"fmt"
"gopkg.in/asn1-ber.v1"
)
// 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
)
// 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"
,
ErrorNetwork
:
"Network Error"
,
ErrorFilterCompile
:
"Filter Compile Error"
,
ErrorFilterDecompile
:
"Filter Decompile Error"
,
ErrorDebugging
:
"Debugging Error"
,
ErrorUnexpectedMessage
:
"Unexpected Message"
,
ErrorUnexpectedResponse
:
"Unexpected Response"
,
}
func
getLDAPResultCode
(
packet
*
ber
.
Packet
)
(
code
uint8
,
description
string
)
{
if
packet
==
nil
{
return
ErrorUnexpectedResponse
,
"Empty packet"
}
else
if
len
(
packet
.
Children
)
>=
2
{
response
:=
packet
.
Children
[
1
]
if
response
==
nil
{
return
ErrorUnexpectedResponse
,
"Empty response in packet"
}
if
response
.
ClassType
==
ber
.
ClassApplication
&&
response
.
TagType
==
ber
.
TypeConstructed
&&
len
(
response
.
Children
)
>=
3
{
// Children[1].Children[2] is the diagnosticMessage which is guaranteed to exist as seen here: https://tools.ietf.org/html/rfc4511#section-4.1.9
return
uint8
(
response
.
Children
[
0
]
.
Value
.
(
int64
)),
response
.
Children
[
2
]
.
Value
.
(
string
)
}
}
return
ErrorNetwork
,
"Invalid packet format"
}
// Error holds LDAP error information
type
Error
struct
{
// Err is the underlying error
Err
error
// ResultCode is the LDAP error code
ResultCode
uint8
}
func
(
e
*
Error
)
Error
()
string
{
return
fmt
.
Sprintf
(
"LDAP Result Code %d %q: %s"
,
e
.
ResultCode
,
LDAPResultCodeMap
[
e
.
ResultCode
],
e
.
Err
.
Error
())
}
// NewError creates an LDAP error with the given code and underlying error
func
NewError
(
resultCode
uint8
,
err
error
)
error
{
return
&
Error
{
ResultCode
:
resultCode
,
Err
:
err
}
}
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
func
IsErrorWithCode
(
err
error
,
desiredResultCode
uint8
)
bool
{
if
err
==
nil
{
return
false
}
serverError
,
ok
:=
err
.
(
*
Error
)
if
!
ok
{
return
false
}
return
serverError
.
ResultCode
==
desiredResultCode
}
vendor/gopkg.in/ldap.v3/CONTRIBUTING.md
0 → 100644
View file @
31b56bba
# Contribution Guidelines
We welcome contribution and improvements.
## Guiding Principles
To begin with here is a draft from an email exchange:
*
take compatibility seriously (our semvers, compatibility with older go versions, etc)
*
don't tag untested code for release
*
beware of baking in implicit behavior based on other libraries/tools choices
*
be as high-fidelity as possible in plumbing through LDAP data (don't mask errors or reduce power of someone using the library)
vendor/gopkg.in/ldap.v
2
/LICENSE
→
vendor/gopkg.in/ldap.v
3
/LICENSE
View file @
31b56bba
File moved
vendor/gopkg.in/ldap.v
2
/Makefile
→
vendor/gopkg.in/ldap.v
3
/Makefile
View file @
31b56bba
...
...
@@ -36,7 +36,23 @@ fmt:
# Only run on go1.5+
vet
:
go tool vet
-atomic
-bool
-copylocks
-nilfunc
-printf
-shadow
-rangeloops
-unreachable
-unsafeptr
-unusedresult
.
@
go tool
-n
vet
>
/dev/null 2>&1
;
\
if
[
$$
?
-eq
0
]
;
then
\
echo
"go vet"
;
\
go tool vet
\
-atomic
\
-bool
\
-copylocks
\
-nilfunc
\
-printf
\
-shadow
\
-rangeloops
\
-unreachable
\
-unsafeptr
\
-unusedresult
\
.
;
\
fi
;
# https://github.com/golang/lint
# go get github.com/golang/lint/golint
...
...
@@ -44,7 +60,7 @@ vet:
# Only run on go1.5+
lint
:
@
echo
golint ./...
@
OUTPUT
=
`
golint ./... 2>&1
`
;
\
@
OUTPUT
=
`
command
-v
golint
>
/dev/null 2>&1
&&
golint ./... 2>&1
`
;
\
if
[
"
$$
OUTPUT"
]
;
then
\
echo
"golint errors:"
;
\
echo
"
$$
OUTPUT"
;
\
...
...
vendor/gopkg.in/ldap.v
2
/README.md
→
vendor/gopkg.in/ldap.v
3
/README.md
View file @
31b56bba
[

](https://godoc.org/gopkg.in/ldap.v
2
)
[

](https://godoc.org/gopkg.in/ldap.v
3
)
[

](https://travis-ci.org/go-ldap/ldap)
# Basic LDAP v3 functionality for the GO programming language.
...
...
@@ -7,11 +7,11 @@
For the latest version use:
go get gopkg.in/ldap.v
2
go get gopkg.in/ldap.v
3
Import the latest version with:
import "gopkg.in/ldap.v
2
"
import "gopkg.in/ldap.v
3
"
## Required Libraries:
...
...
@@ -27,6 +27,7 @@ Import the latest version with:
-
Modify Requests / Responses
-
Add Requests / Responses
-
Delete Requests / Responses
-
Modify DN Requests / Responses
## Examples:
...
...
vendor/gopkg.in/ldap.v
2
/add.go
→
vendor/gopkg.in/ldap.v
3
/add.go
View file @
31b56bba
...
...
@@ -41,6 +41,8 @@ type AddRequest struct {
DN
string
// Attributes list the attributes of the new entry
Attributes
[]
Attribute
// Controls hold optional controls to send with the request
Controls
[]
Control
}
func
(
a
AddRequest
)
encode
()
*
ber
.
Packet
{
...
...
@@ -60,9 +62,10 @@ func (a *AddRequest) Attribute(attrType string, attrVals []string) {
}
// NewAddRequest returns an AddRequest for the given DN, with no attributes
func
NewAddRequest
(
dn
string
)
*
AddRequest
{
func
NewAddRequest
(
dn
string
,
controls
[]
Control
)
*
AddRequest
{
return
&
AddRequest
{
DN
:
dn
,
DN
:
dn
,
Controls
:
controls
,
}
}
...
...
@@ -72,6 +75,9 @@ func (l *Conn) Add(addRequest *AddRequest) error {
packet
:=
ber
.
Encode
(
ber
.
ClassUniversal
,
ber
.
TypeConstructed
,
ber
.
TagSequence
,
nil
,
"LDAP Request"
)
packet
.
AppendChild
(
ber
.
NewInteger
(
ber
.
ClassUniversal
,
ber
.
TypePrimitive
,
ber
.
TagInteger
,
l
.
nextMessageID
(),
"MessageID"
))
packet
.
AppendChild
(
addRequest
.
encode
())
if
len
(
addRequest
.
Controls
)
>
0
{
packet
.
AppendChild
(
encodeControls
(
addRequest
.
Controls
))
}
l
.
Debug
.
PrintPacket
(
packet
)
...
...
@@ -100,9 +106,9 @@ func (l *Conn) Add(addRequest *AddRequest) error {
}
if
packet
.
Children
[
1
]
.
Tag
==
ApplicationAddResponse
{
resultCode
,
resultDescription
:=
g
etLDAP
ResultCode
(
packet
)
if
resultCode
!=
0
{
return
NewError
(
resultCode
,
errors
.
New
(
resultDescription
))
err
:=
G
etLDAP
Error
(
packet
)
if
err
!=
nil
{
return
err
}
}
else
{
log
.
Printf
(
"Unexpected Response: %d"
,
packet
.
Children
[
1
]
.
Tag
)
...
...
vendor/gopkg.in/ldap.v
2
/bind.go
→
vendor/gopkg.in/ldap.v
3
/bind.go
View file @
31b56bba
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
ldap
import
(
"errors"
"fmt"
"gopkg.in/asn1-ber.v1"
)
...
...
@@ -18,6 +15,9 @@ type SimpleBindRequest struct {
Password
string
// Controls are optional controls to send with the bind request
Controls
[]
Control
// AllowEmptyPassword sets whether the client allows binding with an empty password
// (normally used for unauthenticated bind).
AllowEmptyPassword
bool
}
// SimpleBindResult contains the response from the server
...
...
@@ -28,9 +28,10 @@ type SimpleBindResult struct {
// NewSimpleBindRequest returns a bind request
func
NewSimpleBindRequest
(
username
string
,
password
string
,
controls
[]
Control
)
*
SimpleBindRequest
{
return
&
SimpleBindRequest
{
Username
:
username
,
Password
:
password
,
Controls
:
controls
,
Username
:
username
,
Password
:
password
,
Controls
:
controls
,
AllowEmptyPassword
:
false
,
}
}
...
...
@@ -40,17 +41,22 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
request
.
AppendChild
(
ber
.
NewString
(
ber
.
ClassUniversal
,
ber
.
TypePrimitive
,
ber
.
TagOctetString
,
bindRequest
.
Username
,
"User Name"
))
request
.
AppendChild
(
ber
.
NewString
(
ber
.
ClassContext
,
ber
.
TypePrimitive
,
0
,
bindRequest
.
Password
,
"Password"
))
request
.
AppendChild
(
encodeControls
(
bindRequest
.
Controls
))
return
request
}
// SimpleBind performs the simple bind operation defined in the given request
func
(
l
*
Conn
)
SimpleBind
(
simpleBindRequest
*
SimpleBindRequest
)
(
*
SimpleBindResult
,
error
)
{
if
simpleBindRequest
.
Password
==
""
&&
!
simpleBindRequest
.
AllowEmptyPassword
{
return
nil
,
NewError
(
ErrorEmptyPassword
,
errors
.
New
(
"ldap: empty password not allowed by the client"
))
}
packet
:=
ber
.
Encode
(
ber
.
ClassUniversal
,
ber
.
TypeConstructed
,
ber
.
TagSequence
,
nil
,
"LDAP Request"
)
packet
.
AppendChild
(
ber
.
NewInteger
(
ber
.
ClassUniversal
,
ber
.
TypePrimitive
,
ber
.
TagInteger
,
l
.
nextMessageID
(),
"MessageID"
))
encodedBindRequest
:=
simpleBindRequest
.
encode
()
packet
.
AppendChild
(
encodedBindRequest
)
if
len
(
simpleBindRequest
.
Controls
)
>
0
{
packet
.
AppendChild
(
encodeControls
(
simpleBindRequest
.
Controls
))
}
if
l
.
Debug
{
ber
.
PrintPacket
(
packet
)
...
...
@@ -73,7 +79,7 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
}
if
l
.
Debug
{
if
err
:
=
addLDAPDescriptions
(
packet
);
err
!=
nil
{
if
err
=
addLDAPDescriptions
(
packet
);
err
!=
nil
{
return
nil
,
err
}
ber
.
PrintPacket
(
packet
)
...
...
@@ -85,59 +91,45 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
if
len
(
packet
.
Children
)
==
3
{
for
_
,
child
:=
range
packet
.
Children
[
2
]
.
Children
{
result
.
Controls
=
append
(
result
.
Controls
,
DecodeControl
(
child
))
decodedChild
,
decodeErr
:=
DecodeControl
(
child
)
if
decodeErr
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to decode child control: %s"
,
decodeErr
)
}
result
.
Controls
=
append
(
result
.
Controls
,
decodedChild
)
}
}
resultCode
,
resultDescription
:=
getLDAPResultCode
(
packet
)
if
resultCode
!=
0
{
return
result
,
NewError
(
resultCode
,
errors
.
New
(
resultDescription
))
}
return
result
,
nil
err
=
GetLDAPError
(
packet
)
return
result
,
err
}
// Bind performs a bind with the given username and password
// Bind performs a bind with the given username and password.
//
// It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method
// for that.
func
(
l
*
Conn
)
Bind
(
username
,
password
string
)
error
{
packet
:=
ber
.
Encode
(
ber
.
ClassUniversal
,
ber
.
TypeConstructed
,
ber
.
TagSequence
,
nil
,
"LDAP Request"
)
packet
.
AppendChild
(
ber
.
NewInteger
(
ber
.
ClassUniversal
,
ber
.
TypePrimitive
,
ber
.
TagInteger
,
l
.
nextMessageID
(),
"MessageID"
))