forked from shanghai-edu/ldap-test-tool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ldap.go
152 lines (140 loc) · 3.52 KB
/
ldap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package models
import (
"crypto/tls"
"errors"
"fmt"
ldap "gopkg.in/ldap.v2"
)
type LDAP_CONFIG struct {
Addr string `json:"addr"`
BaseDn string `json:"baseDn"`
BindDn string `json:"bindDn`
BindPass string `json:"bindPass"`
AuthFilter string `json:"authFilter"`
Attributes []string `json:"attributes"`
TLS bool `json:"tls"`
StartTLS bool `json:"startTLS"`
Conn *ldap.Conn
}
type LDAP_RESULT struct {
DN string `json:"dn"`
Attributes map[string][]string `json:"attributes"`
}
func (lc *LDAP_CONFIG) Close() {
if lc.Conn != nil {
lc.Conn.Close()
lc.Conn = nil
}
}
func (lc *LDAP_CONFIG) Connect() (err error) {
if lc.TLS {
lc.Conn, err = ldap.DialTLS("tcp", lc.Addr, &tls.Config{InsecureSkipVerify: true})
} else {
lc.Conn, err = ldap.Dial("tcp", lc.Addr)
}
if err != nil {
return err
}
if !lc.TLS && lc.StartTLS {
err = lc.Conn.StartTLS(&tls.Config{InsecureSkipVerify: true})
if err != nil {
lc.Conn.Close()
return err
}
}
err = lc.Conn.Bind(lc.BindDn, lc.BindPass)
if err != nil {
lc.Conn.Close()
return err
}
return err
}
func (lc *LDAP_CONFIG) Auth(username, password string) (success bool, err error) {
searchRequest := ldap.NewSearchRequest(
lc.BaseDn, // The base dn to search
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf(lc.AuthFilter, username), // The filter to apply
lc.Attributes, // A list attributes to retrieve
nil,
)
sr, err := lc.Conn.Search(searchRequest)
if err != nil {
return
}
if len(sr.Entries) == 0 {
err = errors.New("Cannot find such user")
return
}
if len(sr.Entries) > 1 {
err = errors.New("Multi users in search")
return
}
err = lc.Conn.Bind(sr.Entries[0].DN, password)
if err != nil {
return
}
//Rebind as the search user for any further queries
err = lc.Conn.Bind(lc.BindDn, lc.BindPass)
if err != nil {
return
}
success = true
return
}
func (lc *LDAP_CONFIG) Search_User(username string) (user LDAP_RESULT, err error) {
searchRequest := ldap.NewSearchRequest(
lc.BaseDn, // The base dn to search
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf(lc.AuthFilter, username), // The filter to apply
lc.Attributes, // A list attributes to retrieve
nil,
)
sr, err := lc.Conn.Search(searchRequest)
if err != nil {
return
}
if len(sr.Entries) == 0 {
err = errors.New("Cannot find such user")
return
}
if len(sr.Entries) > 1 {
err = errors.New("Multi users in search")
return
}
attributes := make(map[string][]string)
for _, attr := range sr.Entries[0].Attributes {
attributes[attr.Name] = attr.Values
}
user.DN = sr.Entries[0].DN
user.Attributes = attributes
return
}
func (lc *LDAP_CONFIG) Search(SearchFilter string) (results []LDAP_RESULT, err error) {
searchRequest := ldap.NewSearchRequest(
lc.BaseDn, // The base dn to search
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
SearchFilter, // The filter to apply
lc.Attributes, // A list attributes to retrieve
nil,
)
sr, err := lc.Conn.Search(searchRequest)
if err != nil {
return
}
if len(sr.Entries) == 0 {
err = errors.New("Cannot find such dn")
return
}
results = []LDAP_RESULT{}
var result LDAP_RESULT
for _, entry := range sr.Entries {
attributes := make(map[string][]string)
for _, attr := range entry.Attributes {
attributes[attr.Name] = attr.Values
}
result.DN = entry.DN
result.Attributes = attributes
results = append(results, result)
}
return
}