forked from mavricknz/ldap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
103 lines (84 loc) · 2.48 KB
/
request.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
// Copyright 2011 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 ldap
import (
"fmt"
"github.com/mavricknz/asn1-ber"
"time"
)
// messageID - messageID obtained from Conn.nextMessageID()
// opPacket - the operation BER encoded Packet e.g. Search/Modify/Delete/Compare
// controls - the controls to add to the Request
// returns the BER encoded LDAP request or an Error
func requestBuildPacket(messageID uint64, opPacket *ber.Packet, controls []Control) (p *ber.Packet, err error) {
p = ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
p.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimative, ber.TagInteger, messageID, "MessageID"))
p.AppendChild(opPacket)
if controls != nil && len(controls) > 0 {
cPacket, err := encodeControls(controls)
if err != nil {
return nil, err
}
p.AppendChild(cPacket)
}
return
}
func (l *LDAPConnection) sendReqRespPacket(messageID uint64, packet *ber.Packet) error {
if l.Debug {
ber.PrintPacket(packet)
}
channel, err := l.sendMessage(packet)
if err != nil {
return err
}
if channel == nil {
return NewLDAPError(ErrorNetwork, "Could not send message")
}
defer l.finishMessage(messageID)
if l.Debug {
fmt.Printf("%d: waiting for response\n", messageID)
}
var responsePacket *ber.Packet = nil
var ok bool
// If a timeout is set then use it, else use default.
timeout := l.ReadTimeout
if uint64(timeout) == 0 {
timeout = DefaultTimeout
}
select {
case responsePacket, ok = <-channel:
if !ok {
return NewLDAPError(ErrorClosing, "Response Channel Closed")
}
case <-time.After(timeout):
if l.AbandonMessageOnReadTimeout {
err = l.Abandon(messageID)
if err != nil {
return NewLDAPError(ErrorNetwork,
"Timeout waiting for Message and error on Abandon")
}
}
return NewLDAPError(ErrorNetwork, "Timeout waiting for Message")
}
if l.Debug {
fmt.Printf("%d: got response %p\n", messageID, responsePacket)
}
if responsePacket == nil {
return NewLDAPError(ErrorNetwork, "Could not retrieve message")
}
if l.Debug {
if err := addLDAPDescriptions(responsePacket); err != nil {
return err
}
ber.PrintPacket(responsePacket)
}
result_code, result_description := getLDAPResultCode(responsePacket)
if result_code != 0 {
return NewLDAPError(result_code, result_description)
}
if l.Debug {
fmt.Printf("%d: returning\n", messageID)
}
return nil
}