summaryrefslogtreecommitdiffstats
path: root/server_bind.go
diff options
context:
space:
mode:
Diffstat (limited to 'server_bind.go')
-rw-r--r--server_bind.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/server_bind.go b/server_bind.go
new file mode 100644
index 0000000..5a80bf5
--- /dev/null
+++ b/server_bind.go
@@ -0,0 +1,73 @@
+package ldap
+
+import (
+ "github.com/nmcclain/asn1-ber"
+ "log"
+ "net"
+)
+
+func HandleBindRequest(req *ber.Packet, fns map[string]Binder, conn net.Conn) (resultCode LDAPResultCode) {
+ defer func() {
+ if r := recover(); r != nil {
+ resultCode = LDAPResultOperationsError
+ }
+ }()
+
+ // we only support ldapv3
+ ldapVersion, ok := req.Children[0].Value.(uint64)
+ if !ok {
+ return LDAPResultProtocolError
+ }
+ if ldapVersion != 3 {
+ log.Printf("Unsupported LDAP version: %d", ldapVersion)
+ return LDAPResultInappropriateAuthentication
+ }
+
+ // auth types
+ bindDN, ok := req.Children[1].Value.(string)
+ if !ok {
+ return LDAPResultProtocolError
+ }
+ bindAuth := req.Children[2]
+ switch bindAuth.Tag {
+ default:
+ log.Print("Unknown LDAP authentication method")
+ return LDAPResultInappropriateAuthentication
+ case LDAPBindAuthSimple:
+ if len(req.Children) == 3 {
+ fnNames := []string{}
+ for k := range fns {
+ fnNames = append(fnNames, k)
+ }
+ fn := routeFunc(bindDN, fnNames)
+ resultCode, err := fns[fn].Bind(bindDN, bindAuth.Data.String(), conn)
+ if err != nil {
+ log.Printf("BindFn Error %s", err.Error())
+ return LDAPResultOperationsError
+ }
+ return resultCode
+ } else {
+ log.Print("Simple bind request has wrong # children. len(req.Children) != 3")
+ return LDAPResultInappropriateAuthentication
+ }
+ case LDAPBindAuthSASL:
+ log.Print("SASL authentication is not supported")
+ return LDAPResultInappropriateAuthentication
+ }
+ return LDAPResultOperationsError
+}
+
+func encodeBindResponse(messageID uint64, ldapResultCode LDAPResultCode) *ber.Packet {
+ responsePacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Response")
+ responsePacket.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "Message ID"))
+
+ bindReponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindResponse, nil, "Bind Response")
+ bindReponse.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ldapResultCode), "resultCode: "))
+ bindReponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "matchedDN: "))
+ bindReponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "errorMessage: "))
+
+ responsePacket.AppendChild(bindReponse)
+
+ // ber.PrintPacket(responsePacket)
+ return responsePacket
+}