Skip to content

Commit b1f4816

Browse files
add ModifyWithResult to v3
1 parent 7e064f4 commit b1f4816

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

v3/client.go

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type Client interface {
2121
Del(*DelRequest) error
2222
Modify(*ModifyRequest) error
2323
ModifyDN(*ModifyDNRequest) error
24+
ModifyWithResult(*ModifyRequest) (*ModifyResult, error)
2425

2526
Compare(dn, attribute, value string) (bool, error)
2627
PasswordModify(*PasswordModifyRequest) (*PasswordModifyResult, error)

v3/modify.go

+66
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package ldap
2727

2828
import (
29+
"errors"
2930
"log"
3031

3132
ber "github.com/go-asn1-ber/asn1-ber"
@@ -39,6 +40,12 @@ const (
3940
IncrementAttribute = 3 // (https://tools.ietf.org/html/rfc4525)
4041
)
4142

43+
// ModifyResult holds the server's response to a modify request
44+
type ModifyResult struct {
45+
// Controls are the returned controls
46+
Controls []Control
47+
}
48+
4249
// PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
4350
type PartialAttribute struct {
4451
// Type is the type of the partial attribute
@@ -155,3 +162,62 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
155162
}
156163
return nil
157164
}
165+
166+
// ModifyWithResult performs the ModifyRequest and returns the result
167+
func (l *Conn) ModifyWithResult(modifyRequest *ModifyRequest) (*ModifyResult, error) {
168+
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
169+
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
170+
packet.AppendChild(modifyRequest.encode())
171+
if len(modifyRequest.Controls) > 0 {
172+
packet.AppendChild(encodeControls(modifyRequest.Controls))
173+
}
174+
175+
l.Debug.PrintPacket(packet)
176+
177+
msgCtx, err := l.sendMessage(packet)
178+
if err != nil {
179+
return nil, err
180+
}
181+
defer l.finishMessage(msgCtx)
182+
183+
result := &ModifyResult{
184+
Controls: make([]Control, 0),
185+
}
186+
187+
l.Debug.Printf("%d: waiting for response", msgCtx.id)
188+
packetResponse, ok := <-msgCtx.responses
189+
if !ok {
190+
return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
191+
}
192+
packet, err = packetResponse.ReadPacket()
193+
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
194+
if err != nil {
195+
return nil, err
196+
}
197+
198+
if l.Debug {
199+
if err := addLDAPDescriptions(packet); err != nil {
200+
return nil, err
201+
}
202+
ber.PrintPacket(packet)
203+
}
204+
205+
switch packet.Children[1].Tag {
206+
case ApplicationModifyResponse:
207+
err := GetLDAPError(packet)
208+
if err != nil {
209+
return nil, err
210+
}
211+
if len(packet.Children) == 3 {
212+
for _, child := range packet.Children[2].Children {
213+
decodedChild, err := DecodeControl(child)
214+
if err != nil {
215+
return nil, errors.New("failed to decode child control: " + err.Error())
216+
}
217+
result.Controls = append(result.Controls, decodedChild)
218+
}
219+
}
220+
}
221+
l.Debug.Printf("%d: returning", msgCtx.id)
222+
return result, nil
223+
}

0 commit comments

Comments
 (0)