-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathldapbackend.go
98 lines (76 loc) · 2.57 KB
/
ldapbackend.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
package ldapbackend
import (
"net"
"context"
"strings"
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
clog "github.com/coredns/coredns/plugin/pkg/log"
ldap "github.com/go-ldap/ldap/v3"
)
var log = clog.NewWithPlugin("ldapbackend")
type LdapBackend struct {
Next plugin.Handler
LdapConn *ldap.Conn
BaseDn string
}
func (l LdapBackend) Name() string {
return "LdapBackend"
}
func (l LdapBackend) OnShutdown() {
log.Debug("Closing ldap connection...\n")
l.LdapConn.Close()
}
func (l LdapBackend) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
// Validate
// Search
searchRequest := ldap.NewSearchRequest(
l.BaseDn,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=dNSZone))",
[]string{"dn", "cn", "dNSTTL", "relativeDomainName"},
nil,
)
sr, err := l.LdapConn.Search(searchRequest)
if err != nil && !ldap.IsErrorAnyOf(err, ldap.LDAPResultNoSuchObject) {
log.Fatal(err)
}
// If not found: try other plugins
if len(sr.Entries) == 0 {
log.Debug("Executed search and didn't find any entries")
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
}
// If found: return result
state := request.Request{W: w, Req: r}
for _, entry := range sr.Entries {
var ldapRecordPrefix string
switch r.Question[0].Qtype {
case dns.TypeA:
log.Debug("Got A")
ldapRecordPrefix = "aRecord="
case dns.TypePTR:
log.Debug("Got PTR")
ldapRecordPrefix = "pTRRecord="
}
if strings.HasPrefix(entry.DN, ldapRecordPrefix) {
// Found the record! Just trim it down
tmpStrWithSuffix := strings.TrimPrefix(entry.DN, ldapRecordPrefix)
finalIp := strings.TrimSuffix(tmpStrWithSuffix, "," + l.BaseDn)
log.Debug(entry)
for _, a := range entry.Attributes {
log.Debug(a)
}
header := dns.RR_Header{ Name: state.QName(), Rrtype: dns.TypeA, Class: state.QClass(), Ttl: 86400}
message := new(dns.Msg)
message.SetReply(r)
message.Authoritative = true
message.Answer = []dns.RR{ &dns.A{ Hdr: header, A: net.ParseIP(finalIp)} }
log.Debug("Sending: ")
log.Debug(message)
w.WriteMsg(message)
return dns.RcodeSuccess, nil
}
}
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
}