aboutsummaryrefslogtreecommitdiff
path: root/.examples
diff options
context:
space:
mode:
Diffstat (limited to '.examples')
-rw-r--r--.examples/enterprise.ldif63
-rw-r--r--.examples/modify.go91
-rw-r--r--.examples/proxy.go107
-rw-r--r--.examples/search.go54
-rw-r--r--.examples/searchSSL.go47
-rw-r--r--.examples/searchTLS.go47
-rw-r--r--.examples/server.go67
-rw-r--r--.examples/slapd.conf67
8 files changed, 543 insertions, 0 deletions
diff --git a/.examples/enterprise.ldif b/.examples/enterprise.ldif
new file mode 100644
index 0000000..f0ec28f
--- /dev/null
+++ b/.examples/enterprise.ldif
@@ -0,0 +1,63 @@
+dn: dc=enterprise,dc=org
+objectClass: dcObject
+objectClass: organization
+o: acme
+
+dn: cn=admin,dc=enterprise,dc=org
+objectClass: person
+cn: admin
+sn: admin
+description: "LDAP Admin"
+
+dn: ou=crew,dc=enterprise,dc=org
+ou: crew
+objectClass: organizationalUnit
+
+
+dn: cn=kirkj,ou=crew,dc=enterprise,dc=org
+cn: kirkj
+sn: Kirk
+gn: James Tiberius
+objectClass: inetOrgPerson
+
+dn: cn=spock,ou=crew,dc=enterprise,dc=org
+cn: spock
+sn: Spock
+objectClass: inetOrgPerson
+
+dn: cn=mccoyl,ou=crew,dc=enterprise,dc=org
+cn: mccoyl
+sn: McCoy
+gn: Leonard
+objectClass: inetOrgPerson
+
+dn: cn=scottm,ou=crew,dc=enterprise,dc=org
+cn: scottm
+sn: Scott
+gn: Montgomery
+objectClass: inetOrgPerson
+
+dn: cn=uhuran,ou=crew,dc=enterprise,dc=org
+cn: uhuran
+sn: Uhura
+gn: Nyota
+objectClass: inetOrgPerson
+
+dn: cn=suluh,ou=crew,dc=enterprise,dc=org
+cn: suluh
+sn: Sulu
+gn: Hikaru
+objectClass: inetOrgPerson
+
+dn: cn=chekovp,ou=crew,dc=enterprise,dc=org
+cn: chekovp
+sn: Chekov
+gn: pavel
+objectClass: inetOrgPerson
diff --git a/.examples/modify.go b/.examples/modify.go
new file mode 100644
index 0000000..c02b921
--- /dev/null
+++ b/.examples/modify.go
@@ -0,0 +1,91 @@
+// +build ignore
+
+// Copyright 2014 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 main
+
+import (
+ "errors"
+ "fmt"
+ "log"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+var (
+ LdapServer string = "localhost"
+ LdapPort uint16 = 389
+ BaseDN string = "dc=enterprise,dc=org"
+ BindDN string = "cn=admin,dc=enterprise,dc=org"
+ BindPW string = "enterprise"
+ Filter string = "(cn=kirkj)"
+)
+
+func search(l *ldapserver.Conn, filter string, attributes []string) (*ldapserver.Entry, *ldapserver.Error) {
+ search := ldapserver.NewSearchRequest(
+ BaseDN,
+ ldapserver.ScopeWholeSubtree, ldapserver.NeverDerefAliases, 0, 0, false,
+ filter,
+ attributes,
+ nil)
+
+ sr, err := l.Search(search)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err)
+ return nil, err
+ }
+
+ log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries))
+ if len(sr.Entries) == 0 {
+ return nil, ldapserver.NewError(ldapserver.ErrorDebugging, errors.New(fmt.Sprintf("no entries found for: %s", filter)))
+ }
+ return sr.Entries[0], nil
+}
+
+func main() {
+ l, err := ldapserver.Dial("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort))
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ }
+ defer l.Close()
+ // l.Debug = true
+
+ l.Bind(BindDN, BindPW)
+
+ log.Printf("The Search for Kirk ... %s\n", Filter)
+ entry, err := search(l, Filter, []string{})
+ if err != nil {
+ log.Fatal("could not get entry")
+ }
+ entry.PrettyPrint(0)
+
+ log.Printf("modify the mail address and add a description ... \n")
+ modify := ldapserver.NewModifyRequest(entry.DN)
+ modify.Add("description", []string{"Captain of the USS Enterprise"})
+ modify.Replace("mail", []string{"[email protected]"})
+ if err := l.Modify(modify); err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ }
+
+ entry, err = search(l, Filter, []string{})
+ if err != nil {
+ log.Fatal("could not get entry")
+ }
+ entry.PrettyPrint(0)
+
+ log.Printf("reset the entry ... \n")
+ modify = ldapserver.NewModifyRequest(entry.DN)
+ modify.Delete("description", []string{})
+ modify.Replace("mail", []string{"[email protected]"})
+ if err := l.Modify(modify); err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ }
+
+ entry, err = search(l, Filter, []string{})
+ if err != nil {
+ log.Fatal("could not get entry")
+ }
+ entry.PrettyPrint(0)
+}
diff --git a/.examples/proxy.go b/.examples/proxy.go
new file mode 100644
index 0000000..2966b7d
--- /dev/null
+++ b/.examples/proxy.go
@@ -0,0 +1,107 @@
+package main
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "log"
+ "net"
+ "sync"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+type ldapHandler struct {
+ sessions map[string]session
+ lock sync.Mutex
+ ldapServer string
+ ldapPort int
+}
+
+///////////// Run a simple LDAP proxy
+func main() {
+ s := ldapserver.NewServer()
+
+ handler := ldapHandler{
+ sessions: make(map[string]session),
+ ldapServer: "localhost",
+ ldapPort: 3389,
+ }
+ s.BindFunc("", handler)
+ s.SearchFunc("", handler)
+ s.CloseFunc("", handler)
+
+ // start the server
+ if err := s.ListenAndServe("localhost:3388"); err != nil {
+ log.Fatal("LDAP Server Failed: %s", err.Error())
+ }
+}
+
+/////////////
+type session struct {
+ id string
+ c net.Conn
+ ldap *ldapserver.Conn
+}
+
+func (h ldapHandler) getSession(conn net.Conn) (session, error) {
+ id := connID(conn)
+ h.lock.Lock()
+ s, ok := h.sessions[id] // use server connection if it exists
+ h.lock.Unlock()
+ if !ok { // open a new server connection if not
+ l, err := ldapserver.Dial("tcp", fmt.Sprintf("%s:%d", h.ldapServer, h.ldapPort))
+ if err != nil {
+ return session{}, err
+ }
+ s = session{id: id, c: conn, ldap: l}
+ h.lock.Lock()
+ h.sessions[s.id] = s
+ h.lock.Unlock()
+ }
+ return s, nil
+}
+
+/////////////
+func (h ldapHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (uint64, error) {
+ s, err := h.getSession(conn)
+ if err != nil {
+ return ldapserver.LDAPResultOperationsError, err
+ }
+ if err := s.ldap.Bind(bindDN, bindSimplePw); err != nil {
+ return ldapserver.LDAPResultOperationsError, err
+ }
+ return ldapserver.LDAPResultSuccess, nil
+}
+
+/////////////
+func (h ldapHandler) Search(boundDN string, searchReq ldapserver.SearchRequest, conn net.Conn) (ldapserver.ServerSearchResult, error) {
+ s, err := h.getSession(conn)
+ if err != nil {
+ return ldapserver.ServerSearchResult{ResultCode: ldapserver.LDAPResultOperationsError}, nil
+ }
+ search := ldapserver.NewSearchRequest(
+ searchReq.BaseDN,
+ ldapserver.ScopeWholeSubtree, ldapserver.NeverDerefAliases, 0, 0, false,
+ searchReq.Filter,
+ searchReq.Attributes,
+ nil)
+ sr, err := s.ldap.Search(search)
+ if err != nil {
+ return ldapserver.ServerSearchResult{}, err
+ }
+ //log.Printf("P: Search OK: %s -> num of entries = %d\n", search.Filter, len(sr.Entries))
+ return ldapserver.ServerSearchResult{sr.Entries, []string{}, []ldapserver.Control{}, ldapserver.LDAPResultSuccess}, nil
+}
+func (h ldapHandler) Close(conn net.Conn) error {
+ conn.Close() // close connection to the server when then client is closed
+ h.lock.Lock()
+ defer h.lock.Unlock()
+ delete(h.sessions, connID(conn))
+ return nil
+}
+func connID(conn net.Conn) string {
+ h := sha256.New()
+ h.Write([]byte(conn.LocalAddr().String() + conn.RemoteAddr().String()))
+ sha := fmt.Sprintf("% x", h.Sum(nil))
+ return string(sha)
+}
diff --git a/.examples/search.go b/.examples/search.go
new file mode 100644
index 0000000..54fbb1c
--- /dev/null
+++ b/.examples/search.go
@@ -0,0 +1,54 @@
+// +build ignore
+
+// Copyright 2014 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 main
+
+import (
+ "fmt"
+ "log"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+var (
+ ldapServer string = "adserver"
+ ldapPort uint16 = 3268
+ baseDN string = "dc=*,dc=*"
+ filter string = "(&(objectClass=user)(sAMAccountName=*)(memberOf=CN=*,OU=*,DC=*,DC=*))"
+ Attributes []string = []string{"memberof"}
+ user string = "*"
+ passwd string = "*"
+)
+
+func main() {
+ l, err := ldapserver.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ }
+ defer l.Close()
+ // l.Debug = true
+
+ err = l.Bind(user, passwd)
+ if err != nil {
+ log.Printf("ERROR: Cannot bind: %s\n", err.Error())
+ return
+ }
+ search := ldapserver.NewSearchRequest(
+ baseDN,
+ ldapserver.ScopeWholeSubtree, ldapserver.NeverDerefAliases, 0, 0, false,
+ filter,
+ Attributes,
+ nil)
+
+ sr, err := l.Search(search)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ return
+ }
+
+ log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries))
+ sr.PrettyPrint(0)
+}
diff --git a/.examples/searchSSL.go b/.examples/searchSSL.go
new file mode 100644
index 0000000..4226b4c
--- /dev/null
+++ b/.examples/searchSSL.go
@@ -0,0 +1,47 @@
+// +build ignore
+
+// Copyright 2014 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 main
+
+import (
+ "fmt"
+ "log"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+var (
+ LdapServer string = "localhost"
+ LdapPort uint16 = 636
+ BaseDN string = "dc=enterprise,dc=org"
+ Filter string = "(cn=kirkj)"
+ Attributes []string = []string{"mail"}
+)
+
+func main() {
+ l, err := ldapserver.DialSSL("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.String())
+ }
+ defer l.Close()
+ // l.Debug = true
+
+ search := ldapserver.NewSearchRequest(
+ BaseDN,
+ ldapserver.ScopeWholeSubtree, ldapserver.NeverDerefAliases, 0, 0, false,
+ Filter,
+ Attributes,
+ nil)
+
+ sr, err := l.Search(search)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.String())
+ return
+ }
+
+ log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries))
+ sr.PrettyPrint(0)
+}
diff --git a/.examples/searchTLS.go b/.examples/searchTLS.go
new file mode 100644
index 0000000..63c60c7
--- /dev/null
+++ b/.examples/searchTLS.go
@@ -0,0 +1,47 @@
+// +build ignore
+
+// Copyright 2014 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 main
+
+import (
+ "fmt"
+ "log"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+var (
+ LdapServer string = "localhost"
+ LdapPort uint16 = 389
+ BaseDN string = "dc=enterprise,dc=org"
+ Filter string = "(cn=kirkj)"
+ Attributes []string = []string{"mail"}
+)
+
+func main() {
+ l, err := ldapserver.DialTLS("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ }
+ defer l.Close()
+ // l.Debug = true
+
+ search := ldapserver.NewSearchRequest(
+ BaseDN,
+ ldapserver.ScopeWholeSubtree, ldapserver.NeverDerefAliases, 0, 0, false,
+ Filter,
+ Attributes,
+ nil)
+
+ sr, err := l.Search(search)
+ if err != nil {
+ log.Fatalf("ERROR: %s\n", err.Error())
+ return
+ }
+
+ log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries))
+ sr.PrettyPrint(0)
+}
diff --git a/.examples/server.go b/.examples/server.go
new file mode 100644
index 0000000..688fb22
--- /dev/null
+++ b/.examples/server.go
@@ -0,0 +1,67 @@
+package main
+
+import (
+ "log"
+ "net"
+
+ ldapserver "github.com/metala/ldap"
+)
+
+/////////////
+// Sample searches you can try against this simple LDAP server:
+//
+// ldapsearch -H ldap://localhost:3389 -x -b 'dn=test,dn=com'
+// ldapsearch -H ldap://localhost:3389 -x -b 'dn=test,dn=com' 'cn=ned'
+// ldapsearch -H ldap://localhost:3389 -x -b 'dn=test,dn=com' 'uidnumber=5000'
+/////////////
+
+///////////// Run a simple LDAP server
+func main() {
+ s := ldapserver.NewServer()
+
+ // register Bind and Search function handlers
+ handler := ldapHandler{}
+ s.BindFunc("", handler)
+ s.SearchFunc("", handler)
+
+ // start the server
+ listen := "localhost:3389"
+ log.Printf("Starting example LDAP server on %s", listen)
+ if err := s.ListenAndServe(listen); err != nil {
+ log.Fatal("LDAP Server Failed: %s", err.Error())
+ }
+}
+
+type ldapHandler struct {
+}
+
+///////////// Allow anonymous binds only
+func (h ldapHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldapserver.LDAPResultCode, error) {
+ if bindDN == "" && bindSimplePw == "" {
+ return ldapserver.LDAPResultSuccess, nil
+ }
+ return ldapserver.LDAPResultInvalidCredentials, nil
+}
+
+///////////// Return some hardcoded search results - we'll respond to any baseDN for testing
+func (h ldapHandler) Search(boundDN string, searchReq ldapserver.SearchRequest, conn net.Conn) (ldapserver.ServerSearchResult, error) {
+ entries := []*ldapserver.Entry{
+ &ldapserver.Entry{"cn=ned," + searchReq.BaseDN, []*ldapserver.EntryAttribute{
+ &ldapserver.EntryAttribute{"cn", []string{"ned"}},
+ &ldapserver.EntryAttribute{"uidNumber", []string{"5000"}},
+ &ldapserver.EntryAttribute{"accountStatus", []string{"active"}},
+ &ldapserver.EntryAttribute{"uid", []string{"ned"}},
+ &ldapserver.EntryAttribute{"description", []string{"ned"}},
+ &ldapserver.EntryAttribute{"objectClass", []string{"posixAccount"}},
+ }},
+ &ldapserver.Entry{"cn=trent," + searchReq.BaseDN, []*ldapserver.EntryAttribute{
+ &ldapserver.EntryAttribute{"cn", []string{"trent"}},
+ &ldapserver.EntryAttribute{"uidNumber", []string{"5005"}},
+ &ldapserver.EntryAttribute{"accountStatus", []string{"active"}},
+ &ldapserver.EntryAttribute{"uid", []string{"trent"}},
+ &ldapserver.EntryAttribute{"description", []string{"trent"}},
+ &ldapserver.EntryAttribute{"objectClass", []string{"posixAccount"}},
+ }},
+ }
+ return ldapserver.ServerSearchResult{entries, []string{}, []ldapserver.Control{}, ldapserver.LDAPResultSuccess}, nil
+}
diff --git a/.examples/slapd.conf b/.examples/slapd.conf
new file mode 100644
index 0000000..0354eed
--- /dev/null
+++ b/.examples/slapd.conf
@@ -0,0 +1,67 @@
+#
+# See slapd.conf(5) for details on configuration options.
+# This file should NOT be world readable.
+#
+include /private/etc/openldap/schema/core.schema
+include /private/etc/openldap/schema/cosine.schema
+include /private/etc/openldap/schema/inetorgperson.schema
+
+# Define global ACLs to disable default read access.
+
+# Do not enable referrals until AFTER you have a working directory
+# service AND an understanding of referrals.
+#referral ldap://root.openldap.org
+
+pidfile /private/var/db/openldap/run/slapd.pid
+argsfile /private/var/db/openldap/run/slapd.args
+
+# Load dynamic backend modules:
+# modulepath /usr/libexec/openldap
+# moduleload back_bdb.la
+# moduleload back_hdb.la
+# moduleload back_ldap.la
+
+# Sample security restrictions
+# Require integrity protection (prevent hijacking)
+# Require 112-bit (3DES or better) encryption for updates
+# Require 63-bit encryption for simple bind
+# security ssf=1 update_ssf=112 simple_bind=64
+
+# Sample access control policy:
+# Root DSE: allow anyone to read it
+# Subschema (sub)entry DSE: allow anyone to read it
+# Other DSEs:
+# Allow self write access
+# Allow authenticated users read access
+# Allow anonymous users to authenticate
+# Directives needed to implement policy:
+# access to dn.base="" by * read
+# access to dn.base="cn=Subschema" by * read
+# access to *
+# by self write
+# by users read
+# by anonymous auth
+#
+# if no access controls are present, the default policy
+# allows anyone and everyone to read anything but restricts
+# updates to rootdn. (e.g., "access to * by * read")
+#
+# rootdn can always read and write EVERYTHING!
+
+#######################################################################
+# BDB database definitions
+#######################################################################
+
+database bdb
+suffix "dc=enterprise,dc=org"
+rootdn "cn=admin,dc=enterprise,dc=org"
+# Cleartext passwords, especially for the rootdn, should
+# be avoid. See slappasswd(8) and slapd.conf(5) for details.
+# Use of strong authentication encouraged.
+rootpw {SSHA}laO00HsgszhK1O0Z5qR0/i/US69Osfeu
+# The database directory MUST exist prior to running slapd AND
+# should only be accessible by the slapd and slap tools.
+# Mode 700 recommended.
+directory /private/var/db/openldap/openldap-data
+# Indices to maintain
+index objectClass eq