update go-ldap (#4776)

This commit is contained in:
Becca Petrin
2018-06-15 10:13:57 -07:00
committed by GitHub
parent bd0b7f1861
commit 6acad689c8
17 changed files with 269 additions and 141 deletions

12
vendor/github.com/go-ldap/ldap/CONTRIBUTING.md generated vendored Normal file
View File

@@ -0,0 +1,12 @@
# Contribution Guidelines
We welcome contribution and improvements.
## Guiding Principles
To begin with here is a draft from an email exchange:
* take compatibility seriously (our semvers, compatibility with older go versions, etc)
* don't tag untested code for release
* beware of baking in implicit behavior based on other libraries/tools choices
* be as high-fidelity as possible in plumbing through LDAP data (don't mask errors or reduce power of someone using the library)

View File

@@ -27,6 +27,7 @@ Import the latest version with:
- Modify Requests / Responses - Modify Requests / Responses
- Add Requests / Responses - Add Requests / Responses
- Delete Requests / Responses - Delete Requests / Responses
- Modify DN Requests / Responses
## Examples: ## Examples:

View File

@@ -41,6 +41,8 @@ type AddRequest struct {
DN string DN string
// Attributes list the attributes of the new entry // Attributes list the attributes of the new entry
Attributes []Attribute Attributes []Attribute
// Controls hold optional controls to send with the request
Controls []Control
} }
func (a AddRequest) encode() *ber.Packet { func (a AddRequest) encode() *ber.Packet {
@@ -60,9 +62,10 @@ func (a *AddRequest) Attribute(attrType string, attrVals []string) {
} }
// NewAddRequest returns an AddRequest for the given DN, with no attributes // NewAddRequest returns an AddRequest for the given DN, with no attributes
func NewAddRequest(dn string) *AddRequest { func NewAddRequest(dn string, controls []Control) *AddRequest {
return &AddRequest{ return &AddRequest{
DN: dn, DN: dn,
Controls: controls,
} }
} }
@@ -72,6 +75,9 @@ func (l *Conn) Add(addRequest *AddRequest) error {
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
packet.AppendChild(addRequest.encode()) packet.AppendChild(addRequest.encode())
if len(addRequest.Controls) > 0 {
packet.AppendChild(encodeControls(addRequest.Controls))
}
l.Debug.PrintPacket(packet) l.Debug.PrintPacket(packet)

View File

@@ -1,13 +0,0 @@
// +build go1.4
package ldap
import (
"sync/atomic"
)
// For compilers that support it, we just use the underlying sync/atomic.Value
// type.
type atomicValue struct {
atomic.Value
}

View File

@@ -1,28 +0,0 @@
// +build !go1.4
package ldap
import (
"sync"
)
// This is a helper type that emulates the use of the "sync/atomic.Value"
// struct that's available in Go 1.4 and up.
type atomicValue struct {
value interface{}
lock sync.RWMutex
}
func (av *atomicValue) Store(val interface{}) {
av.lock.Lock()
av.value = val
av.lock.Unlock()
}
func (av *atomicValue) Load() interface{} {
av.lock.RLock()
ret := av.value
av.lock.RUnlock()
return ret
}

View File

@@ -2,6 +2,7 @@ package ldap
import ( import (
"errors" "errors"
"fmt"
"gopkg.in/asn1-ber.v1" "gopkg.in/asn1-ber.v1"
) )
@@ -40,10 +41,6 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name")) request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name"))
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password")) request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password"))
if len(bindRequest.Controls) > 0 {
request.AppendChild(encodeControls(bindRequest.Controls))
}
return request return request
} }
@@ -57,6 +54,9 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
encodedBindRequest := simpleBindRequest.encode() encodedBindRequest := simpleBindRequest.encode()
packet.AppendChild(encodedBindRequest) packet.AppendChild(encodedBindRequest)
if len(simpleBindRequest.Controls) > 0 {
packet.AppendChild(encodeControls(simpleBindRequest.Controls))
}
if l.Debug { if l.Debug {
ber.PrintPacket(packet) ber.PrintPacket(packet)
@@ -91,7 +91,11 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
if len(packet.Children) == 3 { if len(packet.Children) == 3 {
for _, child := range packet.Children[2].Children { for _, child := range packet.Children[2].Children {
result.Controls = append(result.Controls, DecodeControl(child)) decodedChild, err := DecodeControl(child)
if err != nil {
return nil, fmt.Errorf("failed to decode child control: %s", err)
}
result.Controls = append(result.Controls, decodedChild)
} }
} }

View File

@@ -18,6 +18,7 @@ type Client interface {
Add(addRequest *AddRequest) error Add(addRequest *AddRequest) error
Del(delRequest *DelRequest) error Del(delRequest *DelRequest) error
Modify(modifyRequest *ModifyRequest) error Modify(modifyRequest *ModifyRequest) error
ModifyDN(modifyDNRequest *ModifyDNRequest) error
Compare(dn, attribute, value string) (bool, error) Compare(dn, attribute, value string) (bool, error)
PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)

View File

@@ -77,5 +77,5 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
return false, NewError(resultCode, errors.New(resultDescription)) return false, NewError(resultCode, errors.New(resultDescription))
} }
} }
return false, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag) return false, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag)
} }

View File

@@ -80,7 +80,7 @@ type Conn struct {
conn net.Conn conn net.Conn
isTLS bool isTLS bool
closing uint32 closing uint32
closeErr atomicValue closeErr atomic.Value
isStartingTLS bool isStartingTLS bool
Debug debugging Debug debugging
chanConfirm chan struct{} chanConfirm chan struct{}
@@ -117,17 +117,10 @@ func Dial(network, addr string) (*Conn, error) {
// DialTLS connects to the given address on the given network using tls.Dial // DialTLS connects to the given address on the given network using tls.Dial
// and then returns a new Conn for the connection. // and then returns a new Conn for the connection.
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
dc, err := net.DialTimeout(network, addr, DefaultTimeout) c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
if err != nil { if err != nil {
return nil, NewError(ErrorNetwork, err) return nil, NewError(ErrorNetwork, err)
} }
c := tls.Client(dc, config)
err = c.Handshake()
if err != nil {
// Handshake error, close the established connection before we return an error
dc.Close()
return nil, NewError(ErrorNetwork, err)
}
conn := NewConn(c, true) conn := NewConn(c, true)
conn.Start() conn.Start()
return conn, nil return conn, nil

View File

@@ -249,7 +249,7 @@ func FindControl(controls []Control, controlType string) Control {
} }
// DecodeControl returns a control read from the given packet, or nil if no recognized control can be made // DecodeControl returns a control read from the given packet, or nil if no recognized control can be made
func DecodeControl(packet *ber.Packet) Control { func DecodeControl(packet *ber.Packet) (Control, error) {
var ( var (
ControlType = "" ControlType = ""
Criticality = false Criticality = false
@@ -259,7 +259,7 @@ func DecodeControl(packet *ber.Packet) Control {
switch len(packet.Children) { switch len(packet.Children) {
case 0: case 0:
// at least one child is required for control type // at least one child is required for control type
return nil return nil, fmt.Errorf("at least one child is required for control type")
case 1: case 1:
// just type, no criticality or value // just type, no criticality or value
@@ -292,17 +292,20 @@ func DecodeControl(packet *ber.Packet) Control {
default: default:
// more than 3 children is invalid // more than 3 children is invalid
return nil return nil, fmt.Errorf("more than 3 children is invalid for controls")
} }
switch ControlType { switch ControlType {
case ControlTypeManageDsaIT: case ControlTypeManageDsaIT:
return NewControlManageDsaIT(Criticality) return NewControlManageDsaIT(Criticality), nil
case ControlTypePaging: case ControlTypePaging:
value.Description += " (Paging)" value.Description += " (Paging)"
c := new(ControlPaging) c := new(ControlPaging)
if value.Value != nil { if value.Value != nil {
valueChildren := ber.DecodePacket(value.Data.Bytes()) valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
}
value.Data.Truncate(0) value.Data.Truncate(0)
value.Value = nil value.Value = nil
value.AppendChild(valueChildren) value.AppendChild(valueChildren)
@@ -314,12 +317,15 @@ func DecodeControl(packet *ber.Packet) Control {
c.PagingSize = uint32(value.Children[0].Value.(int64)) c.PagingSize = uint32(value.Children[0].Value.(int64))
c.Cookie = value.Children[1].Data.Bytes() c.Cookie = value.Children[1].Data.Bytes()
value.Children[1].Value = c.Cookie value.Children[1].Value = c.Cookie
return c return c, nil
case ControlTypeBeheraPasswordPolicy: case ControlTypeBeheraPasswordPolicy:
value.Description += " (Password Policy - Behera)" value.Description += " (Password Policy - Behera)"
c := NewControlBeheraPasswordPolicy() c := NewControlBeheraPasswordPolicy()
if value.Value != nil { if value.Value != nil {
valueChildren := ber.DecodePacket(value.Data.Bytes()) valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
}
value.Data.Truncate(0) value.Data.Truncate(0)
value.Value = nil value.Value = nil
value.AppendChild(valueChildren) value.AppendChild(valueChildren)
@@ -331,7 +337,10 @@ func DecodeControl(packet *ber.Packet) Control {
if child.Tag == 0 { if child.Tag == 0 {
//Warning //Warning
warningPacket := child.Children[0] warningPacket := child.Children[0]
packet := ber.DecodePacket(warningPacket.Data.Bytes()) packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
}
val, ok := packet.Value.(int64) val, ok := packet.Value.(int64)
if ok { if ok {
if warningPacket.Tag == 0 { if warningPacket.Tag == 0 {
@@ -346,7 +355,10 @@ func DecodeControl(packet *ber.Packet) Control {
} }
} else if child.Tag == 1 { } else if child.Tag == 1 {
// Error // Error
packet := ber.DecodePacket(child.Data.Bytes()) packet, err := ber.DecodePacketErr(child.Data.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
}
val, ok := packet.Value.(int8) val, ok := packet.Value.(int8)
if !ok { if !ok {
// what to do? // what to do?
@@ -357,22 +369,22 @@ func DecodeControl(packet *ber.Packet) Control {
c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error] c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
} }
} }
return c return c, nil
case ControlTypeVChuPasswordMustChange: case ControlTypeVChuPasswordMustChange:
c := &ControlVChuPasswordMustChange{MustChange: true} c := &ControlVChuPasswordMustChange{MustChange: true}
return c return c, nil
case ControlTypeVChuPasswordWarning: case ControlTypeVChuPasswordWarning:
c := &ControlVChuPasswordWarning{Expire: -1} c := &ControlVChuPasswordWarning{Expire: -1}
expireStr := ber.DecodeString(value.Data.Bytes()) expireStr := ber.DecodeString(value.Data.Bytes())
expire, err := strconv.ParseInt(expireStr, 10, 64) expire, err := strconv.ParseInt(expireStr, 10, 64)
if err != nil { if err != nil {
return nil return nil, fmt.Errorf("failed to parse value as int: %s", err)
} }
c.Expire = expire c.Expire = expire
value.Value = c.Expire value.Value = c.Expire
return c return c, nil
default: default:
c := new(ControlString) c := new(ControlString)
c.ControlType = ControlType c.ControlType = ControlType
@@ -380,7 +392,7 @@ func DecodeControl(packet *ber.Packet) Control {
if value != nil { if value != nil {
c.ControlValue = value.Value.(string) c.ControlValue = value.Value.(string)
} }
return c return c, nil
} }
} }

13
vendor/github.com/go-ldap/ldap/dn.go generated vendored
View File

@@ -100,15 +100,15 @@ func ParseDN(str string) (*DN, error) {
} }
// Not a special character, assume hex encoded octet // Not a special character, assume hex encoded octet
if len(str) == i+1 { if len(str) == i+1 {
return nil, errors.New("Got corrupted escaped character") return nil, errors.New("got corrupted escaped character")
} }
dst := []byte{0} dst := []byte{0}
n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2])) n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to decode escaped character: %s", err) return nil, fmt.Errorf("failed to decode escaped character: %s", err)
} else if n != 1 { } else if n != 1 {
return nil, fmt.Errorf("Expected 1 byte when un-escaping, got %d", n) return nil, fmt.Errorf("expected 1 byte when un-escaping, got %d", n)
} }
buffer.WriteByte(dst[0]) buffer.WriteByte(dst[0])
i++ i++
@@ -131,9 +131,12 @@ func ParseDN(str string) (*DN, error) {
} }
rawBER, err := enchex.DecodeString(data) rawBER, err := enchex.DecodeString(data)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to decode BER encoding: %s", err) return nil, fmt.Errorf("failed to decode BER encoding: %s", err)
}
packet, err := ber.DecodePacketErr(rawBER)
if err != nil {
return nil, fmt.Errorf("failed to decode BER packet: %s", err)
} }
packet := ber.DecodePacket(rawBER)
buffer.WriteString(packet.Data.String()) buffer.WriteString(packet.Data.String())
i += len(data) - 1 i += len(data) - 1
} }

View File

@@ -2,6 +2,7 @@ package ldap
import ( import (
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -97,13 +98,13 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
switch application { switch application {
case ApplicationBindRequest: case ApplicationBindRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationBindResponse: case ApplicationBindResponse:
addDefaultLDAPResponseDescriptions(packet) err = addDefaultLDAPResponseDescriptions(packet)
case ApplicationUnbindRequest: case ApplicationUnbindRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationSearchRequest: case ApplicationSearchRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationSearchResultEntry: case ApplicationSearchResultEntry:
packet.Children[1].Children[0].Description = "Object Name" packet.Children[1].Children[0].Description = "Object Name"
packet.Children[1].Children[1].Description = "Attributes" packet.Children[1].Children[1].Description = "Attributes"
@@ -116,37 +117,37 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
} }
} }
if len(packet.Children) == 3 { if len(packet.Children) == 3 {
addControlDescriptions(packet.Children[2]) err = addControlDescriptions(packet.Children[2])
} }
case ApplicationSearchResultDone: case ApplicationSearchResultDone:
addDefaultLDAPResponseDescriptions(packet) err = addDefaultLDAPResponseDescriptions(packet)
case ApplicationModifyRequest: case ApplicationModifyRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationModifyResponse: case ApplicationModifyResponse:
case ApplicationAddRequest: case ApplicationAddRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationAddResponse: case ApplicationAddResponse:
case ApplicationDelRequest: case ApplicationDelRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationDelResponse: case ApplicationDelResponse:
case ApplicationModifyDNRequest: case ApplicationModifyDNRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationModifyDNResponse: case ApplicationModifyDNResponse:
case ApplicationCompareRequest: case ApplicationCompareRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationCompareResponse: case ApplicationCompareResponse:
case ApplicationAbandonRequest: case ApplicationAbandonRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationSearchResultReference: case ApplicationSearchResultReference:
case ApplicationExtendedRequest: case ApplicationExtendedRequest:
addRequestDescriptions(packet) err = addRequestDescriptions(packet)
case ApplicationExtendedResponse: case ApplicationExtendedResponse:
} }
return nil return err
} }
func addControlDescriptions(packet *ber.Packet) { func addControlDescriptions(packet *ber.Packet) error {
packet.Description = "Controls" packet.Description = "Controls"
for _, child := range packet.Children { for _, child := range packet.Children {
var value *ber.Packet var value *ber.Packet
@@ -155,7 +156,7 @@ func addControlDescriptions(packet *ber.Packet) {
switch len(child.Children) { switch len(child.Children) {
case 0: case 0:
// at least one child is required for control type // at least one child is required for control type
continue return fmt.Errorf("at least one child is required for control type")
case 1: case 1:
// just type, no criticality or value // just type, no criticality or value
@@ -184,8 +185,9 @@ func addControlDescriptions(packet *ber.Packet) {
default: default:
// more than 3 children is invalid // more than 3 children is invalid
continue return fmt.Errorf("more than 3 children for control packet found")
} }
if value == nil { if value == nil {
continue continue
} }
@@ -193,7 +195,10 @@ func addControlDescriptions(packet *ber.Packet) {
case ControlTypePaging: case ControlTypePaging:
value.Description += " (Paging)" value.Description += " (Paging)"
if value.Value != nil { if value.Value != nil {
valueChildren := ber.DecodePacket(value.Data.Bytes()) valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
if err != nil {
return fmt.Errorf("failed to decode data bytes: %s", err)
}
value.Data.Truncate(0) value.Data.Truncate(0)
value.Value = nil value.Value = nil
valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes() valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes()
@@ -206,7 +211,10 @@ func addControlDescriptions(packet *ber.Packet) {
case ControlTypeBeheraPasswordPolicy: case ControlTypeBeheraPasswordPolicy:
value.Description += " (Password Policy - Behera Draft)" value.Description += " (Password Policy - Behera Draft)"
if value.Value != nil { if value.Value != nil {
valueChildren := ber.DecodePacket(value.Data.Bytes()) valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
if err != nil {
return fmt.Errorf("failed to decode data bytes: %s", err)
}
value.Data.Truncate(0) value.Data.Truncate(0)
value.Value = nil value.Value = nil
value.AppendChild(valueChildren) value.AppendChild(valueChildren)
@@ -216,7 +224,10 @@ func addControlDescriptions(packet *ber.Packet) {
if child.Tag == 0 { if child.Tag == 0 {
//Warning //Warning
warningPacket := child.Children[0] warningPacket := child.Children[0]
packet := ber.DecodePacket(warningPacket.Data.Bytes()) packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
if err != nil {
return fmt.Errorf("failed to decode data bytes: %s", err)
}
val, ok := packet.Value.(int64) val, ok := packet.Value.(int64)
if ok { if ok {
if warningPacket.Tag == 0 { if warningPacket.Tag == 0 {
@@ -231,7 +242,10 @@ func addControlDescriptions(packet *ber.Packet) {
} }
} else if child.Tag == 1 { } else if child.Tag == 1 {
// Error // Error
packet := ber.DecodePacket(child.Data.Bytes()) packet, err := ber.DecodePacketErr(child.Data.Bytes())
if err != nil {
return fmt.Errorf("failed to decode data bytes: %s", err)
}
val, ok := packet.Value.(int8) val, ok := packet.Value.(int8)
if !ok { if !ok {
val = -1 val = -1
@@ -242,18 +256,20 @@ func addControlDescriptions(packet *ber.Packet) {
} }
} }
} }
return nil
} }
func addRequestDescriptions(packet *ber.Packet) { func addRequestDescriptions(packet *ber.Packet) error {
packet.Description = "LDAP Request" packet.Description = "LDAP Request"
packet.Children[0].Description = "Message ID" packet.Children[0].Description = "Message ID"
packet.Children[1].Description = ApplicationMap[uint8(packet.Children[1].Tag)] packet.Children[1].Description = ApplicationMap[uint8(packet.Children[1].Tag)]
if len(packet.Children) == 3 { if len(packet.Children) == 3 {
addControlDescriptions(packet.Children[2]) return addControlDescriptions(packet.Children[2])
} }
return nil
} }
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) { func addDefaultLDAPResponseDescriptions(packet *ber.Packet) error {
resultCode, _ := getLDAPResultCode(packet) resultCode, _ := getLDAPResultCode(packet)
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")" packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")"
packet.Children[1].Children[1].Description = "Matched DN" packet.Children[1].Children[1].Description = "Matched DN"
@@ -262,8 +278,9 @@ func addDefaultLDAPResponseDescriptions(packet *ber.Packet) {
packet.Children[1].Children[3].Description = "Referral" packet.Children[1].Children[3].Description = "Referral"
} }
if len(packet.Children) == 3 { if len(packet.Children) == 3 {
addControlDescriptions(packet.Children[2]) return addControlDescriptions(packet.Children[2])
} }
return nil
} }
// DebugBinaryFile reads and prints packets from the given filename // DebugBinaryFile reads and prints packets from the given filename
@@ -273,8 +290,13 @@ func DebugBinaryFile(fileName string) error {
return NewError(ErrorDebugging, err) return NewError(ErrorDebugging, err)
} }
ber.PrintBytes(os.Stdout, file, "") ber.PrintBytes(os.Stdout, file, "")
packet := ber.DecodePacket(file) packet, err := ber.DecodePacketErr(file)
addLDAPDescriptions(packet) if err != nil {
return fmt.Errorf("failed to decode packet: %s", err)
}
if err := addLDAPDescriptions(packet); err != nil {
return err
}
ber.PrintPacket(packet) ber.PrintPacket(packet)
return nil return nil

104
vendor/github.com/go-ldap/ldap/moddn.go generated vendored Normal file
View File

@@ -0,0 +1,104 @@
// Package ldap - moddn.go contains ModifyDN functionality
//
// https://tools.ietf.org/html/rfc4511
// ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
// entry LDAPDN,
// newrdn RelativeLDAPDN,
// deleteoldrdn BOOLEAN,
// newSuperior [0] LDAPDN OPTIONAL }
//
//
package ldap
import (
"errors"
"log"
"gopkg.in/asn1-ber.v1"
)
// ModifyDNRequest holds the request to modify a DN
type ModifyDNRequest struct {
DN string
NewRDN string
DeleteOldRDN bool
NewSuperior string
}
// NewModifyDNRequest creates a new request which can be passed to ModifyDN().
//
// To move an object in the tree, set the "newSup" to the new parent entry DN. Use an
// empty string for just changing the object's RDN.
//
// For moving the object without renaming, the "rdn" must be the first
// RDN of the given DN.
//
// A call like
// mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "")
// will setup the request to just rename uid=someone,dc=example,dc=org to
// uid=newname,dc=example,dc=org.
func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest {
return &ModifyDNRequest{
DN: dn,
NewRDN: rdn,
DeleteOldRDN: delOld,
NewSuperior: newSup,
}
}
func (m ModifyDNRequest) encode() *ber.Packet {
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request")
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.NewRDN, "New RDN"))
request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, m.DeleteOldRDN, "Delete old RDN"))
if m.NewSuperior != "" {
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, m.NewSuperior, "New Superior"))
}
return request
}
// ModifyDN renames the given DN and optionally move to another base (when the "newSup" argument
// to NewModifyDNRequest() is not "").
func (l *Conn) ModifyDN(m *ModifyDNRequest) error {
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
packet.AppendChild(m.encode())
l.Debug.PrintPacket(packet)
msgCtx, err := l.sendMessage(packet)
if err != nil {
return err
}
defer l.finishMessage(msgCtx)
l.Debug.Printf("%d: waiting for response", msgCtx.id)
packetResponse, ok := <-msgCtx.responses
if !ok {
return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
}
packet, err = packetResponse.ReadPacket()
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
if err != nil {
return err
}
if l.Debug {
if err := addLDAPDescriptions(packet); err != nil {
return err
}
ber.PrintPacket(packet)
}
if packet.Children[1].Tag == ApplicationModifyDNResponse {
resultCode, resultDescription := getLDAPResultCode(packet)
if resultCode != 0 {
return NewError(resultCode, errors.New(resultDescription))
}
} else {
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
}
l.Debug.Printf("%d: returning", msgCtx.id)
return nil
}

View File

@@ -58,54 +58,56 @@ func (p *PartialAttribute) encode() *ber.Packet {
return seq return seq
} }
// Change for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
type Change struct {
// Operation is the type of change to be made
Operation uint
// Modification is the attribute to be modified
Modification PartialAttribute
}
func (c *Change) encode() *ber.Packet {
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(c.Operation), "Operation"))
change.AppendChild(c.Modification.encode())
return change
}
// ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 // ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
type ModifyRequest struct { type ModifyRequest struct {
// DN is the distinguishedName of the directory entry to modify // DN is the distinguishedName of the directory entry to modify
DN string DN string
// AddAttributes contain the attributes to add // Changes contain the attributes to modify
AddAttributes []PartialAttribute Changes []Change
// DeleteAttributes contain the attributes to delete // Controls hold optional controls to send with the request
DeleteAttributes []PartialAttribute Controls []Control
// ReplaceAttributes contain the attributes to replace
ReplaceAttributes []PartialAttribute
} }
// Add inserts the given attribute to the list of attributes to add // Add appends the given attribute to the list of changes to be made
func (m *ModifyRequest) Add(attrType string, attrVals []string) { func (m *ModifyRequest) Add(attrType string, attrVals []string) {
m.AddAttributes = append(m.AddAttributes, PartialAttribute{Type: attrType, Vals: attrVals}) m.appendChange(AddAttribute, attrType, attrVals)
} }
// Delete inserts the given attribute to the list of attributes to delete // Delete appends the given attribute to the list of changes to be made
func (m *ModifyRequest) Delete(attrType string, attrVals []string) { func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
m.DeleteAttributes = append(m.DeleteAttributes, PartialAttribute{Type: attrType, Vals: attrVals}) m.appendChange(DeleteAttribute, attrType, attrVals)
} }
// Replace inserts the given attribute to the list of attributes to replace // Replace appends the given attribute to the list of changes to be made
func (m *ModifyRequest) Replace(attrType string, attrVals []string) { func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
m.ReplaceAttributes = append(m.ReplaceAttributes, PartialAttribute{Type: attrType, Vals: attrVals}) m.appendChange(ReplaceAttribute, attrType, attrVals)
}
func (m *ModifyRequest) appendChange(operation uint, attrType string, attrVals []string) {
m.Changes = append(m.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}})
} }
func (m ModifyRequest) encode() *ber.Packet { func (m ModifyRequest) encode() *ber.Packet {
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request") request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request")
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN")) request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes") changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes")
for _, attribute := range m.AddAttributes { for _, change := range m.Changes {
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") changes.AppendChild(change.encode())
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
change.AppendChild(attribute.encode())
changes.AppendChild(change)
}
for _, attribute := range m.DeleteAttributes {
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation"))
change.AppendChild(attribute.encode())
changes.AppendChild(change)
}
for _, attribute := range m.ReplaceAttributes {
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation"))
change.AppendChild(attribute.encode())
changes.AppendChild(change)
} }
request.AppendChild(changes) request.AppendChild(changes)
return request return request
@@ -114,9 +116,11 @@ func (m ModifyRequest) encode() *ber.Packet {
// NewModifyRequest creates a modify request for the given DN // NewModifyRequest creates a modify request for the given DN
func NewModifyRequest( func NewModifyRequest(
dn string, dn string,
controls []Control,
) *ModifyRequest { ) *ModifyRequest {
return &ModifyRequest{ return &ModifyRequest{
DN: dn, DN: dn,
Controls: controls,
} }
} }
@@ -125,6 +129,9 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
packet.AppendChild(modifyRequest.encode()) packet.AppendChild(modifyRequest.encode())
if len(modifyRequest.Controls) > 0 {
packet.AppendChild(encodeControls(modifyRequest.Controls))
}
l.Debug.PrintPacket(packet) l.Debug.PrintPacket(packet)

View File

@@ -129,7 +129,7 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa
return nil, NewError(resultCode, errors.New(resultDescription)) return nil, NewError(resultCode, errors.New(resultDescription))
} }
} else { } else {
return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag)) return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag))
} }
extendedResponse := packet.Children[1] extendedResponse := packet.Children[1]

View File

@@ -309,10 +309,10 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32)
} else { } else {
castControl, ok := control.(*ControlPaging) castControl, ok := control.(*ControlPaging)
if !ok { if !ok {
return nil, fmt.Errorf("Expected paging control to be of type *ControlPaging, got %v", control) return nil, fmt.Errorf("expected paging control to be of type *ControlPaging, got %v", control)
} }
if castControl.PagingSize != pagingSize { if castControl.PagingSize != pagingSize {
return nil, fmt.Errorf("Paging size given in search request (%d) conflicts with size given in search call (%d)", castControl.PagingSize, pagingSize) return nil, fmt.Errorf("paging size given in search request (%d) conflicts with size given in search call (%d)", castControl.PagingSize, pagingSize)
} }
pagingControl = castControl pagingControl = castControl
} }
@@ -433,7 +433,11 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
} }
if len(packet.Children) == 3 { if len(packet.Children) == 3 {
for _, child := range packet.Children[2].Children { for _, child := range packet.Children[2].Children {
result.Controls = append(result.Controls, DecodeControl(child)) decodedChild, err := DecodeControl(child)
if err != nil {
return nil, fmt.Errorf("failed to decode child control: %s", err)
}
result.Controls = append(result.Controls, decodedChild)
} }
} }
foundSearchResultDone = true foundSearchResultDone = true

6
vendor/vendor.json vendored
View File

@@ -919,10 +919,10 @@
"revisionTime": "2017-11-19T05:34:21Z" "revisionTime": "2017-11-19T05:34:21Z"
}, },
{ {
"checksumSHA1": "3qxR+iktZ/aLpuq9by7pel2YM7w=", "checksumSHA1": "LNa/QGlcDDDflNa3srgRR8QLwcc=",
"path": "github.com/go-ldap/ldap", "path": "github.com/go-ldap/ldap",
"revision": "23c4ee25d1434f2231f92afaeebfbfa7900ebbb0", "revision": "ef52f0f48a85a3a669e1f6bdcf90a62b97762952",
"revisionTime": "2017-12-09T13:38:01Z" "revisionTime": "2018-06-07T15:29:25Z"
}, },
{ {
"checksumSHA1": "ZbU8qGzETzJZ2t30LmHxla5PLMY=", "checksumSHA1": "ZbU8qGzETzJZ2t30LmHxla5PLMY=",