tech: adds/removes in vendor folder according to dep 0.4.0.
This commit is contained in:
-31
@@ -1,31 +0,0 @@
|
||||
language: go
|
||||
env:
|
||||
global:
|
||||
- VET_VERSIONS="1.6 1.7 1.8 1.9 tip"
|
||||
- LINT_VERSIONS="1.6 1.7 1.8 1.9 tip"
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
- tip
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
go_import_path: gopkg.in/ldap.v2
|
||||
install:
|
||||
- go get gopkg.in/asn1-ber.v1
|
||||
- go get gopkg.in/ldap.v2
|
||||
- go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/golang/lint/golint || true
|
||||
- go build -v ./...
|
||||
script:
|
||||
- make test
|
||||
- make fmt
|
||||
- if [[ "$VET_VERSIONS" == *"$TRAVIS_GO_VERSION"* ]]; then make vet; fi
|
||||
- if [[ "$LINT_VERSIONS" == *"$TRAVIS_GO_VERSION"* ]]; then make lint; fi
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
.PHONY: default install build test quicktest fmt vet lint
|
||||
|
||||
GO_VERSION := $(shell go version | cut -d' ' -f3 | cut -d. -f2)
|
||||
|
||||
# Only use the `-race` flag on newer versions of Go
|
||||
IS_OLD_GO := $(shell test $(GO_VERSION) -le 2 && echo true)
|
||||
ifeq ($(IS_OLD_GO),true)
|
||||
RACE_FLAG :=
|
||||
else
|
||||
RACE_FLAG := -race -cpu 1,2,4
|
||||
endif
|
||||
|
||||
default: fmt vet lint build quicktest
|
||||
|
||||
install:
|
||||
go get -t -v ./...
|
||||
|
||||
build:
|
||||
go build -v ./...
|
||||
|
||||
test:
|
||||
go test -v $(RACE_FLAG) -cover ./...
|
||||
|
||||
quicktest:
|
||||
go test ./...
|
||||
|
||||
# Capture output and force failure when there is non-empty output
|
||||
fmt:
|
||||
@echo gofmt -l .
|
||||
@OUTPUT=`gofmt -l . 2>&1`; \
|
||||
if [ "$$OUTPUT" ]; then \
|
||||
echo "gofmt must be run on the following files:"; \
|
||||
echo "$$OUTPUT"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Only run on go1.5+
|
||||
vet:
|
||||
go tool vet -atomic -bool -copylocks -nilfunc -printf -shadow -rangeloops -unreachable -unsafeptr -unusedresult .
|
||||
|
||||
# https://github.com/golang/lint
|
||||
# go get github.com/golang/lint/golint
|
||||
# Capture output and force failure when there is non-empty output
|
||||
# Only run on go1.5+
|
||||
lint:
|
||||
@echo golint ./...
|
||||
@OUTPUT=`golint ./... 2>&1`; \
|
||||
if [ "$$OUTPUT" ]; then \
|
||||
echo "golint errors:"; \
|
||||
echo "$$OUTPUT"; \
|
||||
exit 1; \
|
||||
fi
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
[](https://godoc.org/gopkg.in/ldap.v2)
|
||||
[](https://travis-ci.org/go-ldap/ldap)
|
||||
|
||||
# Basic LDAP v3 functionality for the GO programming language.
|
||||
|
||||
## Install
|
||||
|
||||
For the latest version use:
|
||||
|
||||
go get gopkg.in/ldap.v2
|
||||
|
||||
Import the latest version with:
|
||||
|
||||
import "gopkg.in/ldap.v2"
|
||||
|
||||
## Required Libraries:
|
||||
|
||||
- gopkg.in/asn1-ber.v1
|
||||
|
||||
## Features:
|
||||
|
||||
- Connecting to LDAP server (non-TLS, TLS, STARTTLS)
|
||||
- Binding to LDAP server
|
||||
- Searching for entries
|
||||
- Filter Compile / Decompile
|
||||
- Paging Search Results
|
||||
- Modify Requests / Responses
|
||||
- Add Requests / Responses
|
||||
- Delete Requests / Responses
|
||||
|
||||
## Examples:
|
||||
|
||||
- search
|
||||
- modify
|
||||
|
||||
## Contributing:
|
||||
|
||||
Bug reports and pull requests are welcome!
|
||||
|
||||
Before submitting a pull request, please make sure tests and verification scripts pass:
|
||||
```
|
||||
make all
|
||||
```
|
||||
|
||||
To set up a pre-push hook to run the tests and verify scripts before pushing:
|
||||
```
|
||||
ln -s ../../.githooks/pre-push .git/hooks/pre-push
|
||||
```
|
||||
|
||||
---
|
||||
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
|
||||
The design is licensed under the Creative Commons 3.0 Attributions license.
|
||||
Read this article for more details: http://blog.golang.org/gopher
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
package ldap_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/ldap.v2"
|
||||
)
|
||||
|
||||
func TestSuccessfulDNParsing(t *testing.T) {
|
||||
testcases := map[string]ldap.DN{
|
||||
"": ldap.DN{[]*ldap.RelativeDN{}},
|
||||
"cn=Jim\\2C \\22Hasse Hö\\22 Hansson!,dc=dummy,dc=com": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"cn", "Jim, \"Hasse Hö\" Hansson!"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"dc", "dummy"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"dc", "com"}}}}},
|
||||
"UID=jsmith,DC=example,DC=net": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"UID", "jsmith"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "example"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
|
||||
"OU=Sales+CN=J. Smith,DC=example,DC=net": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
|
||||
&ldap.AttributeTypeAndValue{"OU", "Sales"},
|
||||
&ldap.AttributeTypeAndValue{"CN", "J. Smith"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "example"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
|
||||
"1.3.6.1.4.1.1466.0=#04024869": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"1.3.6.1.4.1.1466.0", "Hi"}}}}},
|
||||
"1.3.6.1.4.1.1466.0=#04024869,DC=net": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"1.3.6.1.4.1.1466.0", "Hi"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
|
||||
"CN=Lu\\C4\\8Di\\C4\\87": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}},
|
||||
" CN = Lu\\C4\\8Di\\C4\\87 ": ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}},
|
||||
` A = 1 , B = 2 `: ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"A", "1"}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"B", "2"}}}}},
|
||||
` A = 1 + B = 2 `: ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
|
||||
&ldap.AttributeTypeAndValue{"A", "1"},
|
||||
&ldap.AttributeTypeAndValue{"B", "2"}}}}},
|
||||
` \ \ A\ \ = \ \ 1\ \ , \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" A ", " 1 "}}},
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" B ", " 2 "}}}}},
|
||||
` \ \ A\ \ = \ \ 1\ \ + \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{
|
||||
&ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
|
||||
&ldap.AttributeTypeAndValue{" A ", " 1 "},
|
||||
&ldap.AttributeTypeAndValue{" B ", " 2 "}}}}},
|
||||
}
|
||||
|
||||
for test, answer := range testcases {
|
||||
dn, err := ldap.ParseDN(test)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(dn, &answer) {
|
||||
t.Errorf("Parsed DN %s is not equal to the expected structure", test)
|
||||
t.Logf("Expected:")
|
||||
for _, rdn := range answer.RDNs {
|
||||
for _, attribs := range rdn.Attributes {
|
||||
t.Logf("#%v\n", attribs)
|
||||
}
|
||||
}
|
||||
t.Logf("Actual:")
|
||||
for _, rdn := range dn.RDNs {
|
||||
for _, attribs := range rdn.Attributes {
|
||||
t.Logf("#%v\n", attribs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorDNParsing(t *testing.T) {
|
||||
testcases := map[string]string{
|
||||
"*": "DN ended with incomplete type, value pair",
|
||||
"cn=Jim\\0Test": "Failed to decode escaped character: encoding/hex: invalid byte: U+0054 'T'",
|
||||
"cn=Jim\\0": "Got corrupted escaped character",
|
||||
"DC=example,=net": "DN ended with incomplete type, value pair",
|
||||
"1=#0402486": "Failed to decode BER encoding: encoding/hex: odd length hex string",
|
||||
"test,DC=example,DC=com": "incomplete type, value pair",
|
||||
"=test,DC=example,DC=com": "incomplete type, value pair",
|
||||
}
|
||||
|
||||
for test, answer := range testcases {
|
||||
_, err := ldap.ParseDN(test)
|
||||
if err == nil {
|
||||
t.Errorf("Expected %s to fail parsing but succeeded\n", test)
|
||||
} else if err.Error() != answer {
|
||||
t.Errorf("Unexpected error on %s:\n%s\nvs.\n%s\n", test, answer, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNEqual(t *testing.T) {
|
||||
testcases := []struct {
|
||||
A string
|
||||
B string
|
||||
Equal bool
|
||||
}{
|
||||
// Exact match
|
||||
{"", "", true},
|
||||
{"o=A", "o=A", true},
|
||||
{"o=A", "o=B", false},
|
||||
|
||||
{"o=A,o=B", "o=A,o=B", true},
|
||||
{"o=A,o=B", "o=A,o=C", false},
|
||||
|
||||
{"o=A+o=B", "o=A+o=B", true},
|
||||
{"o=A+o=B", "o=A+o=C", false},
|
||||
|
||||
// Case mismatch in type is ignored
|
||||
{"o=A", "O=A", true},
|
||||
{"o=A,o=B", "o=A,O=B", true},
|
||||
{"o=A+o=B", "o=A+O=B", true},
|
||||
|
||||
// Case mismatch in value is significant
|
||||
{"o=a", "O=A", false},
|
||||
{"o=a,o=B", "o=A,O=B", false},
|
||||
{"o=a+o=B", "o=A+O=B", false},
|
||||
|
||||
// Multi-valued RDN order mismatch is ignored
|
||||
{"o=A+o=B", "O=B+o=A", true},
|
||||
// Number of RDN attributes is significant
|
||||
{"o=A+o=B", "O=B+o=A+O=B", false},
|
||||
|
||||
// Missing values are significant
|
||||
{"o=A+o=B", "O=B+o=A+O=C", false}, // missing values matter
|
||||
{"o=A+o=B+o=C", "O=B+o=A", false}, // missing values matter
|
||||
|
||||
// Whitespace tests
|
||||
// Matching
|
||||
{
|
||||
"cn=John Doe, ou=People, dc=sun.com",
|
||||
"cn=John Doe, ou=People, dc=sun.com",
|
||||
true,
|
||||
},
|
||||
// Difference in leading/trailing chars is ignored
|
||||
{
|
||||
"cn=John Doe, ou=People, dc=sun.com",
|
||||
"cn=John Doe,ou=People,dc=sun.com",
|
||||
true,
|
||||
},
|
||||
// Difference in values is significant
|
||||
{
|
||||
"cn=John Doe, ou=People, dc=sun.com",
|
||||
"cn=John Doe, ou=People, dc=sun.com",
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
a, err := ldap.ParseDN(tc.A)
|
||||
if err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
continue
|
||||
}
|
||||
b, err := ldap.ParseDN(tc.B)
|
||||
if err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if expected, actual := tc.Equal, a.Equal(b); expected != actual {
|
||||
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
|
||||
continue
|
||||
}
|
||||
if expected, actual := tc.Equal, b.Equal(a); expected != actual {
|
||||
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNAncestor(t *testing.T) {
|
||||
testcases := []struct {
|
||||
A string
|
||||
B string
|
||||
Ancestor bool
|
||||
}{
|
||||
// Exact match returns false
|
||||
{"", "", false},
|
||||
{"o=A", "o=A", false},
|
||||
{"o=A,o=B", "o=A,o=B", false},
|
||||
{"o=A+o=B", "o=A+o=B", false},
|
||||
|
||||
// Mismatch
|
||||
{"ou=C,ou=B,o=A", "ou=E,ou=D,ou=B,o=A", false},
|
||||
|
||||
// Descendant
|
||||
{"ou=C,ou=B,o=A", "ou=E,ou=C,ou=B,o=A", true},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
a, err := ldap.ParseDN(tc.A)
|
||||
if err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
continue
|
||||
}
|
||||
b, err := ldap.ParseDN(tc.B)
|
||||
if err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if expected, actual := tc.Ancestor, a.AncestorOf(b); expected != actual {
|
||||
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
-305
@@ -1,305 +0,0 @@
|
||||
package ldap_test
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gopkg.in/ldap.v2"
|
||||
)
|
||||
|
||||
// ExampleConn_Bind demonstrates how to bind a connection to an ldap user
|
||||
// allowing access to restricted attributes that user has access to
|
||||
func ExampleConn_Bind() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleConn_Search demonstrates how to use the search interface
|
||||
func ExampleConn_Search() {
|
||||
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"))
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleStartTLS demonstrates how to start a TLS connection
|
||||
func ExampleConn_StartTLS() {
|
||||
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)
|
||||
}
|
||||
|
||||
// Operations via l are now encrypted
|
||||
}
|
||||
|
||||
// ExampleConn_Compare demonstrates how to compare an attribute with a value
|
||||
func ExampleConn_Compare() {
|
||||
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 ExampleConn_PasswordModify_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())
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleConn_PasswordModify_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)
|
||||
}
|
||||
|
||||
func ExampleConn_PasswordModify_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())
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleConn_Modify() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// Example User Authentication shows how a typical application can verify a login attempt
|
||||
func Example_userAuthentication() {
|
||||
// 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 further queries
|
||||
err = l.Bind(bindusername, bindpassword)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func 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 available.\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)
|
||||
}
|
||||
}
|
||||
|
||||
func 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)
|
||||
}
|
||||
}
|
||||
-254
@@ -1,254 +0,0 @@
|
||||
package ldap_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/asn1-ber.v1"
|
||||
"gopkg.in/ldap.v2"
|
||||
)
|
||||
|
||||
type compileTest struct {
|
||||
filterStr string
|
||||
|
||||
expectedFilter string
|
||||
expectedType int
|
||||
expectedErr string
|
||||
}
|
||||
|
||||
var testFilters = []compileTest{
|
||||
compileTest{
|
||||
filterStr: "(&(sn=Miller)(givenName=Bob))",
|
||||
expectedFilter: "(&(sn=Miller)(givenName=Bob))",
|
||||
expectedType: ldap.FilterAnd,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(|(sn=Miller)(givenName=Bob))",
|
||||
expectedFilter: "(|(sn=Miller)(givenName=Bob))",
|
||||
expectedType: ldap.FilterOr,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(!(sn=Miller))",
|
||||
expectedFilter: "(!(sn=Miller))",
|
||||
expectedType: ldap.FilterNot,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=Miller)",
|
||||
expectedFilter: "(sn=Miller)",
|
||||
expectedType: ldap.FilterEqualityMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=Mill*)",
|
||||
expectedFilter: "(sn=Mill*)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=*Mill)",
|
||||
expectedFilter: "(sn=*Mill)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=*Mill*)",
|
||||
expectedFilter: "(sn=*Mill*)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=*i*le*)",
|
||||
expectedFilter: "(sn=*i*le*)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=Mi*l*r)",
|
||||
expectedFilter: "(sn=Mi*l*r)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
// substring filters escape properly
|
||||
compileTest{
|
||||
filterStr: `(sn=Mi*함*r)`,
|
||||
expectedFilter: `(sn=Mi*\ed\95\a8*r)`,
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
// already escaped substring filters don't get double-escaped
|
||||
compileTest{
|
||||
filterStr: `(sn=Mi*\ed\95\a8*r)`,
|
||||
expectedFilter: `(sn=Mi*\ed\95\a8*r)`,
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=Mi*le*)",
|
||||
expectedFilter: "(sn=Mi*le*)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=*i*ler)",
|
||||
expectedFilter: "(sn=*i*ler)",
|
||||
expectedType: ldap.FilterSubstrings,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn>=Miller)",
|
||||
expectedFilter: "(sn>=Miller)",
|
||||
expectedType: ldap.FilterGreaterOrEqual,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn<=Miller)",
|
||||
expectedFilter: "(sn<=Miller)",
|
||||
expectedType: ldap.FilterLessOrEqual,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn=*)",
|
||||
expectedFilter: "(sn=*)",
|
||||
expectedType: ldap.FilterPresent,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: "(sn~=Miller)",
|
||||
expectedFilter: "(sn~=Miller)",
|
||||
expectedType: ldap.FilterApproxMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(objectGUID='\fc\fe\a3\ab\f9\90N\aaGm\d5I~\d12)`,
|
||||
expectedFilter: `(objectGUID='\fc\fe\a3\ab\f9\90N\aaGm\d5I~\d12)`,
|
||||
expectedType: ldap.FilterEqualityMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(objectGUID=абвгдеёжзийклмнопрстуфхцчшщъыьэюя)`,
|
||||
expectedFilter: `(objectGUID=\d0\b0\d0\b1\d0\b2\d0\b3\d0\b4\d0\b5\d1\91\d0\b6\d0\b7\d0\b8\d0\b9\d0\ba\d0\bb\d0\bc\d0\bd\d0\be\d0\bf\d1\80\d1\81\d1\82\d1\83\d1\84\d1\85\d1\86\d1\87\d1\88\d1\89\d1\8a\d1\8b\d1\8c\d1\8d\d1\8e\d1\8f)`,
|
||||
expectedType: ldap.FilterEqualityMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(objectGUID=함수목록)`,
|
||||
expectedFilter: `(objectGUID=\ed\95\a8\ec\88\98\eb\aa\a9\eb\a1\9d)`,
|
||||
expectedType: ldap.FilterEqualityMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(objectGUID=`,
|
||||
expectedFilter: ``,
|
||||
expectedType: 0,
|
||||
expectedErr: "unexpected end of filter",
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(objectGUID=함수목록`,
|
||||
expectedFilter: ``,
|
||||
expectedType: 0,
|
||||
expectedErr: "unexpected end of filter",
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `((cn=)`,
|
||||
expectedFilter: ``,
|
||||
expectedType: 0,
|
||||
expectedErr: "unexpected end of filter",
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(&(objectclass=inetorgperson)(cn=中文))`,
|
||||
expectedFilter: `(&(objectclass=inetorgperson)(cn=\e4\b8\ad\e6\96\87))`,
|
||||
expectedType: 0,
|
||||
},
|
||||
// attr extension
|
||||
compileTest{
|
||||
filterStr: `(memberOf:=foo)`,
|
||||
expectedFilter: `(memberOf:=foo)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
// attr+named matching rule extension
|
||||
compileTest{
|
||||
filterStr: `(memberOf:test:=foo)`,
|
||||
expectedFilter: `(memberOf:test:=foo)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
// attr+oid matching rule extension
|
||||
compileTest{
|
||||
filterStr: `(cn:1.2.3.4.5:=Fred Flintstone)`,
|
||||
expectedFilter: `(cn:1.2.3.4.5:=Fred Flintstone)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
// attr+dn+oid matching rule extension
|
||||
compileTest{
|
||||
filterStr: `(sn:dn:2.4.6.8.10:=Barney Rubble)`,
|
||||
expectedFilter: `(sn:dn:2.4.6.8.10:=Barney Rubble)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
// attr+dn extension
|
||||
compileTest{
|
||||
filterStr: `(o:dn:=Ace Industry)`,
|
||||
expectedFilter: `(o:dn:=Ace Industry)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
// dn extension
|
||||
compileTest{
|
||||
filterStr: `(:dn:2.4.6.8.10:=Dino)`,
|
||||
expectedFilter: `(:dn:2.4.6.8.10:=Dino)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
compileTest{
|
||||
filterStr: `(memberOf:1.2.840.113556.1.4.1941:=CN=User1,OU=blah,DC=mydomain,DC=net)`,
|
||||
expectedFilter: `(memberOf:1.2.840.113556.1.4.1941:=CN=User1,OU=blah,DC=mydomain,DC=net)`,
|
||||
expectedType: ldap.FilterExtensibleMatch,
|
||||
},
|
||||
|
||||
// compileTest{ filterStr: "()", filterType: FilterExtensibleMatch },
|
||||
}
|
||||
|
||||
var testInvalidFilters = []string{
|
||||
`(objectGUID=\zz)`,
|
||||
`(objectGUID=\a)`,
|
||||
}
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
// Test Compiler and Decompiler
|
||||
for _, i := range testFilters {
|
||||
filter, err := ldap.CompileFilter(i.filterStr)
|
||||
if err != nil {
|
||||
if i.expectedErr == "" || !strings.Contains(err.Error(), i.expectedErr) {
|
||||
t.Errorf("Problem compiling '%s' - '%v' (expected error to contain '%v')", i.filterStr, err, i.expectedErr)
|
||||
}
|
||||
} else if filter.Tag != ber.Tag(i.expectedType) {
|
||||
t.Errorf("%q Expected %q got %q", i.filterStr, ldap.FilterMap[uint64(i.expectedType)], ldap.FilterMap[uint64(filter.Tag)])
|
||||
} else {
|
||||
o, err := ldap.DecompileFilter(filter)
|
||||
if err != nil {
|
||||
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error())
|
||||
} else if i.expectedFilter != o {
|
||||
t.Errorf("%q expected, got %q", i.expectedFilter, o)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidFilter(t *testing.T) {
|
||||
for _, filterStr := range testInvalidFilters {
|
||||
if _, err := ldap.CompileFilter(filterStr); err == nil {
|
||||
t.Errorf("Problem compiling %s - expected err", filterStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFilterCompile(b *testing.B) {
|
||||
b.StopTimer()
|
||||
filters := make([]string, len(testFilters))
|
||||
|
||||
// Test Compiler and Decompiler
|
||||
for idx, i := range testFilters {
|
||||
filters[idx] = i.filterStr
|
||||
}
|
||||
|
||||
maxIdx := len(filters)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ldap.CompileFilter(filters[i%maxIdx])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFilterDecompile(b *testing.B) {
|
||||
b.StopTimer()
|
||||
filters := make([]*ber.Packet, len(testFilters))
|
||||
|
||||
// Test Compiler and Decompiler
|
||||
for idx, i := range testFilters {
|
||||
filters[idx], _ = ldap.CompileFilter(i.filterStr)
|
||||
}
|
||||
|
||||
maxIdx := len(filters)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ldap.DecompileFilter(filters[i%maxIdx])
|
||||
}
|
||||
}
|
||||
-275
@@ -1,275 +0,0 @@
|
||||
package ldap_test
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/ldap.v2"
|
||||
)
|
||||
|
||||
var ldapServer = "ldap.itd.umich.edu"
|
||||
var ldapPort = uint16(389)
|
||||
var ldapTLSPort = uint16(636)
|
||||
var baseDN = "dc=umich,dc=edu"
|
||||
var filter = []string{
|
||||
"(cn=cis-fac)",
|
||||
"(&(owner=*)(cn=cis-fac))",
|
||||
"(&(objectclass=rfc822mailgroup)(cn=*Computer*))",
|
||||
"(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))"}
|
||||
var attributes = []string{
|
||||
"cn",
|
||||
"description"}
|
||||
|
||||
func TestDial(t *testing.T) {
|
||||
fmt.Printf("TestDial: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
fmt.Printf("TestDial: finished...\n")
|
||||
}
|
||||
|
||||
func TestDialTLS(t *testing.T) {
|
||||
fmt.Printf("TestDialTLS: starting...\n")
|
||||
l, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapTLSPort), &tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
fmt.Printf("TestDialTLS: finished...\n")
|
||||
}
|
||||
|
||||
func TestStartTLS(t *testing.T) {
|
||||
fmt.Printf("TestStartTLS: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Printf("TestStartTLS: finished...\n")
|
||||
}
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
fmt.Printf("TestSearch: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[0],
|
||||
attributes,
|
||||
nil)
|
||||
|
||||
sr, err := l.Search(searchRequest)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestSearch: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries))
|
||||
}
|
||||
|
||||
func TestSearchStartTLS(t *testing.T) {
|
||||
fmt.Printf("TestSearchStartTLS: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[0],
|
||||
attributes,
|
||||
nil)
|
||||
|
||||
sr, err := l.Search(searchRequest)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestSearchStartTLS: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries))
|
||||
|
||||
fmt.Printf("TestSearchStartTLS: upgrading with startTLS\n")
|
||||
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
sr, err = l.Search(searchRequest)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestSearchStartTLS: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries))
|
||||
}
|
||||
|
||||
func TestSearchWithPaging(t *testing.T) {
|
||||
fmt.Printf("TestSearchWithPaging: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
err = l.Bind("", "")
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[2],
|
||||
attributes,
|
||||
nil)
|
||||
sr, err := l.SearchWithPaging(searchRequest, 5)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestSearchWithPaging: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries))
|
||||
|
||||
searchRequest = ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[2],
|
||||
attributes,
|
||||
[]ldap.Control{ldap.NewControlPaging(5)})
|
||||
sr, err = l.SearchWithPaging(searchRequest, 5)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestSearchWithPaging: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries))
|
||||
|
||||
searchRequest = ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[2],
|
||||
attributes,
|
||||
[]ldap.Control{ldap.NewControlPaging(500)})
|
||||
sr, err = l.SearchWithPaging(searchRequest, 5)
|
||||
if err == nil {
|
||||
t.Errorf("expected an error when paging size in control in search request doesn't match size given in call, got none")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func searchGoroutine(t *testing.T, l *ldap.Conn, results chan *ldap.SearchResult, i int) {
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
|
||||
filter[i],
|
||||
attributes,
|
||||
nil)
|
||||
sr, err := l.Search(searchRequest)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
results <- nil
|
||||
return
|
||||
}
|
||||
results <- sr
|
||||
}
|
||||
|
||||
func testMultiGoroutineSearch(t *testing.T, TLS bool, startTLS bool) {
|
||||
fmt.Printf("TestMultiGoroutineSearch: starting...\n")
|
||||
var l *ldap.Conn
|
||||
var err error
|
||||
if TLS {
|
||||
l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapTLSPort), &tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
} else {
|
||||
l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
if startTLS {
|
||||
fmt.Printf("TestMultiGoroutineSearch: using StartTLS...\n")
|
||||
err := l.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
results := make([]chan *ldap.SearchResult, len(filter))
|
||||
for i := range filter {
|
||||
results[i] = make(chan *ldap.SearchResult)
|
||||
go searchGoroutine(t, l, results[i], i)
|
||||
}
|
||||
for i := range filter {
|
||||
sr := <-results[i]
|
||||
if sr == nil {
|
||||
t.Errorf("Did not receive results from goroutine for %q", filter[i])
|
||||
} else {
|
||||
fmt.Printf("TestMultiGoroutineSearch(%d): %s -> num of entries = %d\n", i, filter[i], len(sr.Entries))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiGoroutineSearch(t *testing.T) {
|
||||
testMultiGoroutineSearch(t, false, false)
|
||||
testMultiGoroutineSearch(t, true, true)
|
||||
testMultiGoroutineSearch(t, false, true)
|
||||
}
|
||||
|
||||
func TestEscapeFilter(t *testing.T) {
|
||||
if got, want := ldap.EscapeFilter("a\x00b(c)d*e\\f"), `a\00b\28c\29d\2ae\5cf`; got != want {
|
||||
t.Errorf("Got %s, expected %s", want, got)
|
||||
}
|
||||
if got, want := ldap.EscapeFilter("Lučić"), `Lu\c4\8di\c4\87`; got != want {
|
||||
t.Errorf("Got %s, expected %s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
fmt.Printf("TestCompare: starting...\n")
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
dn := "cn=math mich,ou=User Groups,ou=Groups,dc=umich,dc=edu"
|
||||
attribute := "cn"
|
||||
value := "math mich"
|
||||
|
||||
sr, err := l.Compare(dn, attribute, value)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("TestCompare: -> %v\n", sr)
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestNewEntry tests that repeated calls to NewEntry return the same value with the same input
|
||||
func TestNewEntry(t *testing.T) {
|
||||
dn := "testDN"
|
||||
attributes := map[string][]string{
|
||||
"alpha": {"value"},
|
||||
"beta": {"value"},
|
||||
"gamma": {"value"},
|
||||
"delta": {"value"},
|
||||
"epsilon": {"value"},
|
||||
}
|
||||
executedEntry := NewEntry(dn, attributes)
|
||||
|
||||
iteration := 0
|
||||
for {
|
||||
if iteration == 100 {
|
||||
break
|
||||
}
|
||||
testEntry := NewEntry(dn, attributes)
|
||||
if !reflect.DeepEqual(executedEntry, testEntry) {
|
||||
t.Fatalf("subsequent calls to NewEntry did not yield the same result:\n\texpected:\n\t%s\n\tgot:\n\t%s\n", executedEntry, testEntry)
|
||||
}
|
||||
iteration = iteration + 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user