Initial QSfera import
This commit is contained in:
+111
@@ -0,0 +1,111 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
// ExtendedRequest represents an extended request to send to the server
|
||||
// See: https://www.rfc-editor.org/rfc/rfc4511#section-4.12
|
||||
type ExtendedRequest struct {
|
||||
// ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
|
||||
// requestName [0] LDAPOID,
|
||||
// requestValue [1] OCTET STRING OPTIONAL }
|
||||
|
||||
Name string
|
||||
Value *ber.Packet
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// NewExtendedRequest returns a new ExtendedRequest. The value can be
|
||||
// nil depending on the type of request
|
||||
func NewExtendedRequest(name string, value *ber.Packet) *ExtendedRequest {
|
||||
return &ExtendedRequest{
|
||||
Name: name,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (er ExtendedRequest) appendTo(envelope *ber.Packet) error {
|
||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Extended Request")
|
||||
pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, ber.TagEOC, er.Name, "Extended Request Name"))
|
||||
if er.Value != nil {
|
||||
pkt.AppendChild(er.Value)
|
||||
}
|
||||
envelope.AppendChild(pkt)
|
||||
if len(er.Controls) > 0 {
|
||||
envelope.AppendChild(encodeControls(er.Controls))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtendedResponse represents the response from the directory server
|
||||
// after sending an extended request
|
||||
// See: https://www.rfc-editor.org/rfc/rfc4511#section-4.12
|
||||
type ExtendedResponse struct {
|
||||
// ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
|
||||
// COMPONENTS OF LDAPResult,
|
||||
// responseName [10] LDAPOID OPTIONAL,
|
||||
// responseValue [11] OCTET STRING OPTIONAL }
|
||||
|
||||
Name string
|
||||
Value *ber.Packet
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// Extended performs an extended request. The resulting
|
||||
// ExtendedResponse may return a value in the form of a *ber.Packet
|
||||
func (l *Conn) Extended(er *ExtendedRequest) (*ExtendedResponse, error) {
|
||||
if er == nil {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ExtendedRequest cannot be nil"))
|
||||
}
|
||||
|
||||
msgCtx, err := l.doRequest(er)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = GetLDAPError(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
extResp := packet.Children[1]
|
||||
if len(extResp.Children) < 3 {
|
||||
return nil, fmt.Errorf(
|
||||
"ldap: malformed extended response: expected at least 3 children, got %d",
|
||||
len(packet.Children),
|
||||
)
|
||||
}
|
||||
|
||||
response := &ExtendedResponse{
|
||||
Controls: make([]Control, 0),
|
||||
}
|
||||
|
||||
for _, child := range extResp.Children {
|
||||
switch child.Tag {
|
||||
case ber.TagEnumerated:
|
||||
response.Name = child.Data.String()
|
||||
case ber.TagEmbeddedPDV:
|
||||
response.Value = child
|
||||
}
|
||||
}
|
||||
|
||||
if len(packet.Children) == 3 {
|
||||
for _, child := range packet.Children[2].Children {
|
||||
decodedChild, decodeErr := DecodeControl(child)
|
||||
if decodeErr != nil {
|
||||
return nil, fmt.Errorf("failed to decode child control: %s", decodeErr)
|
||||
}
|
||||
response.Controls = append(response.Controls, decodedChild)
|
||||
}
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
Reference in New Issue
Block a user