Merge pull request #1338 from srenatus/sr/update-go-ldap
update go-ldap, improve errors
This commit is contained in:
		@@ -293,6 +293,9 @@ func (c *ldapConnector) do(ctx context.Context, f func(c *ldap.Conn) error) erro
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// If bindDN and bindPW are empty this will default to an anonymous bind.
 | 
						// If bindDN and bindPW are empty this will default to an anonymous bind.
 | 
				
			||||||
	if err := conn.Bind(c.BindDN, c.BindPW); err != nil {
 | 
						if err := conn.Bind(c.BindDN, c.BindPW); err != nil {
 | 
				
			||||||
 | 
							if c.BindDN == "" && c.BindPW == "" {
 | 
				
			||||||
 | 
								return fmt.Errorf("ldap: initial anonymous bind failed: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return fmt.Errorf("ldap: initial bind for user %q failed: %v", c.BindDN, err)
 | 
							return fmt.Errorf("ldap: initial bind for user %q failed: %v", c.BindDN, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -472,7 +475,7 @@ func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username,
 | 
				
			|||||||
func (c *ldapConnector) Refresh(ctx context.Context, s connector.Scopes, ident connector.Identity) (connector.Identity, error) {
 | 
					func (c *ldapConnector) Refresh(ctx context.Context, s connector.Scopes, ident connector.Identity) (connector.Identity, error) {
 | 
				
			||||||
	var data refreshData
 | 
						var data refreshData
 | 
				
			||||||
	if err := json.Unmarshal(ident.ConnectorData, &data); err != nil {
 | 
						if err := json.Unmarshal(ident.ConnectorData, &data); err != nil {
 | 
				
			||||||
		return ident, fmt.Errorf("ldap: failed to unamrshal internal data: %v", err)
 | 
							return ident, fmt.Errorf("ldap: failed to unmarshal internal data: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var user ldap.Entry
 | 
						var user ldap.Entry
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
hash: fe29de07f5c1580c51de0e78796bce522d933602d88a4c397b586bd88ca7ca76
 | 
					hash: e5972bbdf15ad612d99ce8cd34e19537b9eacb5ff53688f339e0da285eb8ec22
 | 
				
			||||||
updated: 2018-10-24T14:58:32.448481302-07:00
 | 
					updated: 2018-11-12T19:38:56.235070564+01:00
 | 
				
			||||||
imports:
 | 
					imports:
 | 
				
			||||||
- name: github.com/beevik/etree
 | 
					- name: github.com/beevik/etree
 | 
				
			||||||
  version: 4cd0dd976db869f817248477718071a28e978df0
 | 
					  version: 4cd0dd976db869f817248477718071a28e978df0
 | 
				
			||||||
@@ -180,7 +180,7 @@ imports:
 | 
				
			|||||||
- name: gopkg.in/asn1-ber.v1
 | 
					- name: gopkg.in/asn1-ber.v1
 | 
				
			||||||
  version: 4e86f4367175e39f69d9358a5f17b4dda270378d
 | 
					  version: 4e86f4367175e39f69d9358a5f17b4dda270378d
 | 
				
			||||||
- name: gopkg.in/ldap.v2
 | 
					- name: gopkg.in/ldap.v2
 | 
				
			||||||
  version: 0e7db8eb77695b5a952f0e5d78df9ab160050c73
 | 
					  version: bb7a9ca6e4fbc2129e3db588a34bc970ffe811a9
 | 
				
			||||||
- name: gopkg.in/square/go-jose.v2
 | 
					- name: gopkg.in/square/go-jose.v2
 | 
				
			||||||
  version: 8254d6c783765f38c8675fae4427a1fe73fbd09d
 | 
					  version: 8254d6c783765f38c8675fae4427a1fe73fbd09d
 | 
				
			||||||
  subpackages:
 | 
					  subpackages:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ import:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# LDAP dependencies.
 | 
					# LDAP dependencies.
 | 
				
			||||||
- package: gopkg.in/ldap.v2
 | 
					- package: gopkg.in/ldap.v2
 | 
				
			||||||
  version: 0e7db8eb77695b5a952f0e5d78df9ab160050c73
 | 
					  version: v2.5.1
 | 
				
			||||||
- package: gopkg.in/asn1-ber.v1
 | 
					- package: gopkg.in/asn1-ber.v1
 | 
				
			||||||
  version: 4e86f4367175e39f69d9358a5f17b4dda270378d
 | 
					  version: 4e86f4367175e39f69d9358a5f17b4dda270378d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								vendor/gopkg.in/ldap.v2/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/gopkg.in/ldap.v2/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,27 +1,22 @@
 | 
				
			|||||||
Copyright (c) 2012 The Go Authors. All rights reserved.
 | 
					The MIT License (MIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Redistribution and use in source and binary forms, with or without
 | 
					Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
 | 
				
			||||||
modification, are permitted provided that the following conditions are
 | 
					Portions copyright (c) 2015-2016 go-ldap Authors
 | 
				
			||||||
met:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   * Redistributions of source code must retain the above copyright
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
notice, this list of conditions and the following disclaimer.
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
   * Redistributions in binary form must reproduce the above
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
copyright notice, this list of conditions and the following disclaimer
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
in the documentation and/or other materials provided with the
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
distribution.
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
   * Neither the name of Google Inc. nor the names of its
 | 
					 | 
				
			||||||
contributors may be used to endorse or promote products derived from
 | 
					 | 
				
			||||||
this software without specific prior written permission.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
					
 | 
				
			||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
					SOFTWARE.
 | 
				
			||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										49
									
								
								vendor/gopkg.in/ldap.v2/add.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/gopkg.in/ldap.v2/add.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,73 +16,78 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Attribute represents an LDAP attribute
 | 
				
			||||||
type Attribute struct {
 | 
					type Attribute struct {
 | 
				
			||||||
	attrType string
 | 
						// Type is the name of the LDAP attribute
 | 
				
			||||||
	attrVals []string
 | 
						Type string
 | 
				
			||||||
 | 
						// Vals are the LDAP attribute values
 | 
				
			||||||
 | 
						Vals []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *Attribute) encode() *ber.Packet {
 | 
					func (a *Attribute) encode() *ber.Packet {
 | 
				
			||||||
	seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
 | 
						seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
 | 
				
			||||||
	seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.attrType, "Type"))
 | 
						seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.Type, "Type"))
 | 
				
			||||||
	set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
 | 
						set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
 | 
				
			||||||
	for _, value := range a.attrVals {
 | 
						for _, value := range a.Vals {
 | 
				
			||||||
		set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
 | 
							set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	seq.AppendChild(set)
 | 
						seq.AppendChild(set)
 | 
				
			||||||
	return seq
 | 
						return seq
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddRequest represents an LDAP AddRequest operation
 | 
				
			||||||
type AddRequest struct {
 | 
					type AddRequest struct {
 | 
				
			||||||
	dn         string
 | 
						// DN identifies the entry being added
 | 
				
			||||||
	attributes []Attribute
 | 
						DN string
 | 
				
			||||||
 | 
						// Attributes list the attributes of the new entry
 | 
				
			||||||
 | 
						Attributes []Attribute
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a AddRequest) encode() *ber.Packet {
 | 
					func (a AddRequest) encode() *ber.Packet {
 | 
				
			||||||
	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
 | 
						request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
 | 
				
			||||||
	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.dn, "DN"))
 | 
						request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.DN, "DN"))
 | 
				
			||||||
	attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
 | 
						attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
 | 
				
			||||||
	for _, attribute := range a.attributes {
 | 
						for _, attribute := range a.Attributes {
 | 
				
			||||||
		attributes.AppendChild(attribute.encode())
 | 
							attributes.AppendChild(attribute.encode())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	request.AppendChild(attributes)
 | 
						request.AppendChild(attributes)
 | 
				
			||||||
	return request
 | 
						return request
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Attribute adds an attribute with the given type and values
 | 
				
			||||||
func (a *AddRequest) Attribute(attrType string, attrVals []string) {
 | 
					func (a *AddRequest) Attribute(attrType string, attrVals []string) {
 | 
				
			||||||
	a.attributes = append(a.attributes, Attribute{attrType: attrType, attrVals: attrVals})
 | 
						a.Attributes = append(a.Attributes, Attribute{Type: attrType, Vals: attrVals})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewAddRequest returns an AddRequest for the given DN, with no attributes
 | 
				
			||||||
func NewAddRequest(dn string) *AddRequest {
 | 
					func NewAddRequest(dn string) *AddRequest {
 | 
				
			||||||
	return &AddRequest{
 | 
						return &AddRequest{
 | 
				
			||||||
		dn: dn,
 | 
							DN: dn,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add performs the given AddRequest
 | 
				
			||||||
func (l *Conn) Add(addRequest *AddRequest) error {
 | 
					func (l *Conn) Add(addRequest *AddRequest) error {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	packet.AppendChild(addRequest.encode())
 | 
						packet.AppendChild(addRequest.encode())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -103,6 +108,6 @@ func (l *Conn) Add(addRequest *AddRequest) error {
 | 
				
			|||||||
		log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
							log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: returning", messageID)
 | 
						l.Debug.Printf("%d: returning", msgCtx.id)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								vendor/gopkg.in/ldap.v2/atomic_value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/gopkg.in/ldap.v2/atomic_value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					// +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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								vendor/gopkg.in/ldap.v2/atomic_value_go13.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/gopkg.in/ldap.v2/atomic_value_go13.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					// +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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								vendor/gopkg.in/ldap.v2/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/gopkg.in/ldap.v2/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,16 +10,22 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SimpleBindRequest represents a username/password bind operation
 | 
				
			||||||
type SimpleBindRequest struct {
 | 
					type SimpleBindRequest struct {
 | 
				
			||||||
 | 
						// Username is the name of the Directory object that the client wishes to bind as
 | 
				
			||||||
	Username string
 | 
						Username string
 | 
				
			||||||
 | 
						// Password is the credentials to bind with
 | 
				
			||||||
	Password string
 | 
						Password string
 | 
				
			||||||
 | 
						// Controls are optional controls to send with the bind request
 | 
				
			||||||
	Controls []Control
 | 
						Controls []Control
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SimpleBindResult contains the response from the server
 | 
				
			||||||
type SimpleBindResult struct {
 | 
					type SimpleBindResult struct {
 | 
				
			||||||
	Controls []Control
 | 
						Controls []Control
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewSimpleBindRequest returns a bind request
 | 
				
			||||||
func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest {
 | 
					func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest {
 | 
				
			||||||
	return &SimpleBindRequest{
 | 
						return &SimpleBindRequest{
 | 
				
			||||||
		Username: username,
 | 
							Username: username,
 | 
				
			||||||
@@ -39,11 +45,10 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
 | 
				
			|||||||
	return request
 | 
						return request
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SimpleBind performs the simple bind operation defined in the given request
 | 
				
			||||||
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
 | 
					func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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, messageID, "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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,21 +56,18 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
 | 
				
			|||||||
		ber.PrintPacket(packet)
 | 
							ber.PrintPacket(packet)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -95,11 +97,10 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
 | 
				
			|||||||
	return result, nil
 | 
						return result, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Bind performs a bind with the given username and password
 | 
				
			||||||
func (l *Conn) Bind(username, password string) error {
 | 
					func (l *Conn) Bind(username, password string) error {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
 | 
						bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
 | 
				
			||||||
	bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
 | 
						bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
 | 
				
			||||||
	bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name"))
 | 
						bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name"))
 | 
				
			||||||
@@ -110,21 +111,18 @@ func (l *Conn) Bind(username, password string) error {
 | 
				
			|||||||
		ber.PrintPacket(packet)
 | 
							ber.PrintPacket(packet)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								vendor/gopkg.in/ldap.v2/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/gopkg.in/ldap.v2/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -33,9 +33,8 @@ import (
 | 
				
			|||||||
// Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise
 | 
					// Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise
 | 
				
			||||||
// false with any error that occurs if any.
 | 
					// false with any error that occurs if any.
 | 
				
			||||||
func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
 | 
					func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request")
 | 
						request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request")
 | 
				
			||||||
	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN"))
 | 
						request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN"))
 | 
				
			||||||
@@ -48,22 +47,19 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false, err
 | 
							return false, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return false, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return false, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return false, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false, err
 | 
							return false, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										210
									
								
								vendor/gopkg.in/ldap.v2/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										210
									
								
								vendor/gopkg.in/ldap.v2/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,24 +11,34 @@ import (
 | 
				
			|||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	MessageQuit     = 0
 | 
						// MessageQuit causes the processMessages loop to exit
 | 
				
			||||||
	MessageRequest  = 1
 | 
						MessageQuit = 0
 | 
				
			||||||
 | 
						// MessageRequest sends a request to the server
 | 
				
			||||||
 | 
						MessageRequest = 1
 | 
				
			||||||
 | 
						// MessageResponse receives a response from the server
 | 
				
			||||||
	MessageResponse = 2
 | 
						MessageResponse = 2
 | 
				
			||||||
	MessageFinish   = 3
 | 
						// MessageFinish indicates the client considers a particular message ID to be finished
 | 
				
			||||||
	MessageTimeout  = 4
 | 
						MessageFinish = 3
 | 
				
			||||||
 | 
						// MessageTimeout indicates the client-specified timeout for a particular message ID has been reached
 | 
				
			||||||
 | 
						MessageTimeout = 4
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PacketResponse contains the packet or error encountered reading a response
 | 
				
			||||||
type PacketResponse struct {
 | 
					type PacketResponse struct {
 | 
				
			||||||
 | 
						// Packet is the packet read from the server
 | 
				
			||||||
	Packet *ber.Packet
 | 
						Packet *ber.Packet
 | 
				
			||||||
	Error  error
 | 
						// Error is an error encountered while reading
 | 
				
			||||||
 | 
						Error error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReadPacket returns the packet or an error
 | 
				
			||||||
func (pr *PacketResponse) ReadPacket() (*ber.Packet, error) {
 | 
					func (pr *PacketResponse) ReadPacket() (*ber.Packet, error) {
 | 
				
			||||||
	if (pr == nil) || (pr.Packet == nil && pr.Error == nil) {
 | 
						if (pr == nil) || (pr.Packet == nil && pr.Error == nil) {
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
 | 
							return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
 | 
				
			||||||
@@ -36,11 +46,31 @@ func (pr *PacketResponse) ReadPacket() (*ber.Packet, error) {
 | 
				
			|||||||
	return pr.Packet, pr.Error
 | 
						return pr.Packet, pr.Error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type messageContext struct {
 | 
				
			||||||
 | 
						id int64
 | 
				
			||||||
 | 
						// close(done) should only be called from finishMessage()
 | 
				
			||||||
 | 
						done chan struct{}
 | 
				
			||||||
 | 
						// close(responses) should only be called from processMessages(), and only sent to from sendResponse()
 | 
				
			||||||
 | 
						responses chan *PacketResponse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sendResponse should only be called within the processMessages() loop which
 | 
				
			||||||
 | 
					// is also responsible for closing the responses channel.
 | 
				
			||||||
 | 
					func (msgCtx *messageContext) sendResponse(packet *PacketResponse) {
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
						case msgCtx.responses <- packet:
 | 
				
			||||||
 | 
							// Successfully sent packet to message handler.
 | 
				
			||||||
 | 
						case <-msgCtx.done:
 | 
				
			||||||
 | 
							// The request handler is done and will not receive more
 | 
				
			||||||
 | 
							// packets.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type messagePacket struct {
 | 
					type messagePacket struct {
 | 
				
			||||||
	Op        int
 | 
						Op        int
 | 
				
			||||||
	MessageID int64
 | 
						MessageID int64
 | 
				
			||||||
	Packet    *ber.Packet
 | 
						Packet    *ber.Packet
 | 
				
			||||||
	Channel   chan *PacketResponse
 | 
						Context   *messageContext
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type sendMessageFlags uint
 | 
					type sendMessageFlags uint
 | 
				
			||||||
@@ -53,19 +83,18 @@ const (
 | 
				
			|||||||
type Conn struct {
 | 
					type Conn struct {
 | 
				
			||||||
	conn                net.Conn
 | 
						conn                net.Conn
 | 
				
			||||||
	isTLS               bool
 | 
						isTLS               bool
 | 
				
			||||||
	isClosing           bool
 | 
						closing             uint32
 | 
				
			||||||
 | 
						closeErr            atomicValue
 | 
				
			||||||
	isStartingTLS       bool
 | 
						isStartingTLS       bool
 | 
				
			||||||
	Debug               debugging
 | 
						Debug               debugging
 | 
				
			||||||
	chanConfirm         chan bool
 | 
						chanConfirm         chan struct{}
 | 
				
			||||||
	chanResults         map[int64]chan *PacketResponse
 | 
						messageContexts     map[int64]*messageContext
 | 
				
			||||||
	chanMessage         chan *messagePacket
 | 
						chanMessage         chan *messagePacket
 | 
				
			||||||
	chanMessageID       chan int64
 | 
						chanMessageID       chan int64
 | 
				
			||||||
	wgSender            sync.WaitGroup
 | 
					 | 
				
			||||||
	wgClose             sync.WaitGroup
 | 
						wgClose             sync.WaitGroup
 | 
				
			||||||
	once                sync.Once
 | 
					 | 
				
			||||||
	outstandingRequests uint
 | 
						outstandingRequests uint
 | 
				
			||||||
	messageMutex        sync.Mutex
 | 
						messageMutex        sync.Mutex
 | 
				
			||||||
	requestTimeout      time.Duration
 | 
						requestTimeout      int64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _ Client = &Conn{}
 | 
					var _ Client = &Conn{}
 | 
				
			||||||
@@ -111,28 +140,39 @@ func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
 | 
				
			|||||||
// NewConn returns a new Conn using conn for network I/O.
 | 
					// NewConn returns a new Conn using conn for network I/O.
 | 
				
			||||||
func NewConn(conn net.Conn, isTLS bool) *Conn {
 | 
					func NewConn(conn net.Conn, isTLS bool) *Conn {
 | 
				
			||||||
	return &Conn{
 | 
						return &Conn{
 | 
				
			||||||
		conn:           conn,
 | 
							conn:            conn,
 | 
				
			||||||
		chanConfirm:    make(chan bool),
 | 
							chanConfirm:     make(chan struct{}),
 | 
				
			||||||
		chanMessageID:  make(chan int64),
 | 
							chanMessageID:   make(chan int64),
 | 
				
			||||||
		chanMessage:    make(chan *messagePacket, 10),
 | 
							chanMessage:     make(chan *messagePacket, 10),
 | 
				
			||||||
		chanResults:    map[int64]chan *PacketResponse{},
 | 
							messageContexts: map[int64]*messageContext{},
 | 
				
			||||||
		requestTimeout: 0,
 | 
							requestTimeout:  0,
 | 
				
			||||||
		isTLS:          isTLS,
 | 
							isTLS:           isTLS,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Start initializes goroutines to read responses and process messages
 | 
				
			||||||
func (l *Conn) Start() {
 | 
					func (l *Conn) Start() {
 | 
				
			||||||
	go l.reader()
 | 
						go l.reader()
 | 
				
			||||||
	go l.processMessages()
 | 
						go l.processMessages()
 | 
				
			||||||
	l.wgClose.Add(1)
 | 
						l.wgClose.Add(1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// isClosing returns whether or not we're currently closing.
 | 
				
			||||||
 | 
					func (l *Conn) isClosing() bool {
 | 
				
			||||||
 | 
						return atomic.LoadUint32(&l.closing) == 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setClosing sets the closing value to true
 | 
				
			||||||
 | 
					func (l *Conn) setClosing() bool {
 | 
				
			||||||
 | 
						return atomic.CompareAndSwapUint32(&l.closing, 0, 1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close closes the connection.
 | 
					// Close closes the connection.
 | 
				
			||||||
func (l *Conn) Close() {
 | 
					func (l *Conn) Close() {
 | 
				
			||||||
	l.once.Do(func() {
 | 
						l.messageMutex.Lock()
 | 
				
			||||||
		l.isClosing = true
 | 
						defer l.messageMutex.Unlock()
 | 
				
			||||||
		l.wgSender.Wait()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if l.setClosing() {
 | 
				
			||||||
		l.Debug.Printf("Sending quit message and waiting for confirmation")
 | 
							l.Debug.Printf("Sending quit message and waiting for confirmation")
 | 
				
			||||||
		l.chanMessage <- &messagePacket{Op: MessageQuit}
 | 
							l.chanMessage <- &messagePacket{Op: MessageQuit}
 | 
				
			||||||
		<-l.chanConfirm
 | 
							<-l.chanConfirm
 | 
				
			||||||
@@ -140,62 +180,56 @@ func (l *Conn) Close() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		l.Debug.Printf("Closing network connection")
 | 
							l.Debug.Printf("Closing network connection")
 | 
				
			||||||
		if err := l.conn.Close(); err != nil {
 | 
							if err := l.conn.Close(); err != nil {
 | 
				
			||||||
			log.Print(err)
 | 
								log.Println(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		l.wgClose.Done()
 | 
							l.wgClose.Done()
 | 
				
			||||||
	})
 | 
						}
 | 
				
			||||||
	l.wgClose.Wait()
 | 
						l.wgClose.Wait()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Sets the time after a request is sent that a MessageTimeout triggers
 | 
					// SetTimeout sets the time after a request is sent that a MessageTimeout triggers
 | 
				
			||||||
func (l *Conn) SetTimeout(timeout time.Duration) {
 | 
					func (l *Conn) SetTimeout(timeout time.Duration) {
 | 
				
			||||||
	if timeout > 0 {
 | 
						if timeout > 0 {
 | 
				
			||||||
		l.requestTimeout = timeout
 | 
							atomic.StoreInt64(&l.requestTimeout, int64(timeout))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns the next available messageID
 | 
					// Returns the next available messageID
 | 
				
			||||||
func (l *Conn) nextMessageID() int64 {
 | 
					func (l *Conn) nextMessageID() int64 {
 | 
				
			||||||
	if l.chanMessageID != nil {
 | 
						if messageID, ok := <-l.chanMessageID; ok {
 | 
				
			||||||
		if messageID, ok := <-l.chanMessageID; ok {
 | 
							return messageID
 | 
				
			||||||
			return messageID
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StartTLS sends the command to start a TLS session and then creates a new TLS Client
 | 
					// StartTLS sends the command to start a TLS session and then creates a new TLS Client
 | 
				
			||||||
func (l *Conn) StartTLS(config *tls.Config) error {
 | 
					func (l *Conn) StartTLS(config *tls.Config) error {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if l.isTLS {
 | 
						if l.isTLS {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: already encrypted"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: already encrypted"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS")
 | 
						request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS")
 | 
				
			||||||
	request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command"))
 | 
						request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command"))
 | 
				
			||||||
	packet.AppendChild(request)
 | 
						packet.AppendChild(request)
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessageWithFlags(packet, startTLS)
 | 
						msgCtx, err := l.sendMessageWithFlags(packet, startTLS)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -226,45 +260,51 @@ func (l *Conn) StartTLS(config *tls.Config) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l *Conn) sendMessage(packet *ber.Packet) (chan *PacketResponse, error) {
 | 
					func (l *Conn) sendMessage(packet *ber.Packet) (*messageContext, error) {
 | 
				
			||||||
	return l.sendMessageWithFlags(packet, 0)
 | 
						return l.sendMessageWithFlags(packet, 0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (chan *PacketResponse, error) {
 | 
					func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (*messageContext, error) {
 | 
				
			||||||
	if l.isClosing {
 | 
						if l.isClosing() {
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
 | 
							return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.messageMutex.Lock()
 | 
						l.messageMutex.Lock()
 | 
				
			||||||
	l.Debug.Printf("flags&startTLS = %d", flags&startTLS)
 | 
						l.Debug.Printf("flags&startTLS = %d", flags&startTLS)
 | 
				
			||||||
	if l.isStartingTLS {
 | 
						if l.isStartingTLS {
 | 
				
			||||||
		l.messageMutex.Unlock()
 | 
							l.messageMutex.Unlock()
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: connection is in startls phase."))
 | 
							return nil, NewError(ErrorNetwork, errors.New("ldap: connection is in startls phase"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if flags&startTLS != 0 {
 | 
						if flags&startTLS != 0 {
 | 
				
			||||||
		if l.outstandingRequests != 0 {
 | 
							if l.outstandingRequests != 0 {
 | 
				
			||||||
			l.messageMutex.Unlock()
 | 
								l.messageMutex.Unlock()
 | 
				
			||||||
			return nil, NewError(ErrorNetwork, errors.New("ldap: cannot StartTLS with outstanding requests"))
 | 
								return nil, NewError(ErrorNetwork, errors.New("ldap: cannot StartTLS with outstanding requests"))
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			l.isStartingTLS = true
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							l.isStartingTLS = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.outstandingRequests++
 | 
						l.outstandingRequests++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.messageMutex.Unlock()
 | 
						l.messageMutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	out := make(chan *PacketResponse)
 | 
						responses := make(chan *PacketResponse)
 | 
				
			||||||
 | 
						messageID := packet.Children[0].Value.(int64)
 | 
				
			||||||
	message := &messagePacket{
 | 
						message := &messagePacket{
 | 
				
			||||||
		Op:        MessageRequest,
 | 
							Op:        MessageRequest,
 | 
				
			||||||
		MessageID: packet.Children[0].Value.(int64),
 | 
							MessageID: messageID,
 | 
				
			||||||
		Packet:    packet,
 | 
							Packet:    packet,
 | 
				
			||||||
		Channel:   out,
 | 
							Context: &messageContext{
 | 
				
			||||||
 | 
								id:        messageID,
 | 
				
			||||||
 | 
								done:      make(chan struct{}),
 | 
				
			||||||
 | 
								responses: responses,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.sendProcessMessage(message)
 | 
						l.sendProcessMessage(message)
 | 
				
			||||||
	return out, nil
 | 
						return message.Context, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l *Conn) finishMessage(messageID int64) {
 | 
					func (l *Conn) finishMessage(msgCtx *messageContext) {
 | 
				
			||||||
	if l.isClosing {
 | 
						close(msgCtx.done)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if l.isClosing() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -277,18 +317,18 @@ func (l *Conn) finishMessage(messageID int64) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	message := &messagePacket{
 | 
						message := &messagePacket{
 | 
				
			||||||
		Op:        MessageFinish,
 | 
							Op:        MessageFinish,
 | 
				
			||||||
		MessageID: messageID,
 | 
							MessageID: msgCtx.id,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.sendProcessMessage(message)
 | 
						l.sendProcessMessage(message)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l *Conn) sendProcessMessage(message *messagePacket) bool {
 | 
					func (l *Conn) sendProcessMessage(message *messagePacket) bool {
 | 
				
			||||||
	if l.isClosing {
 | 
						l.messageMutex.Lock()
 | 
				
			||||||
 | 
						defer l.messageMutex.Unlock()
 | 
				
			||||||
 | 
						if l.isClosing() {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.wgSender.Add(1)
 | 
					 | 
				
			||||||
	l.chanMessage <- message
 | 
						l.chanMessage <- message
 | 
				
			||||||
	l.wgSender.Done()
 | 
					 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -297,13 +337,17 @@ func (l *Conn) processMessages() {
 | 
				
			|||||||
		if err := recover(); err != nil {
 | 
							if err := recover(); err != nil {
 | 
				
			||||||
			log.Printf("ldap: recovered panic in processMessages: %v", err)
 | 
								log.Printf("ldap: recovered panic in processMessages: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for messageID, channel := range l.chanResults {
 | 
							for messageID, msgCtx := range l.messageContexts {
 | 
				
			||||||
 | 
								// If we are closing due to an error, inform anyone who
 | 
				
			||||||
 | 
								// is waiting about the error.
 | 
				
			||||||
 | 
								if l.isClosing() && l.closeErr.Load() != nil {
 | 
				
			||||||
 | 
									msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			l.Debug.Printf("Closing channel for MessageID %d", messageID)
 | 
								l.Debug.Printf("Closing channel for MessageID %d", messageID)
 | 
				
			||||||
			close(channel)
 | 
								close(msgCtx.responses)
 | 
				
			||||||
			delete(l.chanResults, messageID)
 | 
								delete(l.messageContexts, messageID)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		close(l.chanMessageID)
 | 
							close(l.chanMessageID)
 | 
				
			||||||
		l.chanConfirm <- true
 | 
					 | 
				
			||||||
		close(l.chanConfirm)
 | 
							close(l.chanConfirm)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -312,11 +356,7 @@ func (l *Conn) processMessages() {
 | 
				
			|||||||
		select {
 | 
							select {
 | 
				
			||||||
		case l.chanMessageID <- messageID:
 | 
							case l.chanMessageID <- messageID:
 | 
				
			||||||
			messageID++
 | 
								messageID++
 | 
				
			||||||
		case message, ok := <-l.chanMessage:
 | 
							case message := <-l.chanMessage:
 | 
				
			||||||
			if !ok {
 | 
					 | 
				
			||||||
				l.Debug.Printf("Shutting down - message channel is closed")
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			switch message.Op {
 | 
								switch message.Op {
 | 
				
			||||||
			case MessageQuit:
 | 
								case MessageQuit:
 | 
				
			||||||
				l.Debug.Printf("Shutting down - quit message received")
 | 
									l.Debug.Printf("Shutting down - quit message received")
 | 
				
			||||||
@@ -324,24 +364,30 @@ func (l *Conn) processMessages() {
 | 
				
			|||||||
			case MessageRequest:
 | 
								case MessageRequest:
 | 
				
			||||||
				// Add to message list and write to network
 | 
									// Add to message list and write to network
 | 
				
			||||||
				l.Debug.Printf("Sending message %d", message.MessageID)
 | 
									l.Debug.Printf("Sending message %d", message.MessageID)
 | 
				
			||||||
				l.chanResults[message.MessageID] = message.Channel
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				buf := message.Packet.Bytes()
 | 
									buf := message.Packet.Bytes()
 | 
				
			||||||
				_, err := l.conn.Write(buf)
 | 
									_, err := l.conn.Write(buf)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					l.Debug.Printf("Error Sending Message: %s", err.Error())
 | 
										l.Debug.Printf("Error Sending Message: %s", err.Error())
 | 
				
			||||||
 | 
										message.Context.sendResponse(&PacketResponse{Error: fmt.Errorf("unable to send request: %s", err)})
 | 
				
			||||||
 | 
										close(message.Context.responses)
 | 
				
			||||||
					break
 | 
										break
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Only add to messageContexts if we were able to
 | 
				
			||||||
 | 
									// successfully write the message.
 | 
				
			||||||
 | 
									l.messageContexts[message.MessageID] = message.Context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Add timeout if defined
 | 
									// Add timeout if defined
 | 
				
			||||||
				if l.requestTimeout > 0 {
 | 
									requestTimeout := time.Duration(atomic.LoadInt64(&l.requestTimeout))
 | 
				
			||||||
 | 
									if requestTimeout > 0 {
 | 
				
			||||||
					go func() {
 | 
										go func() {
 | 
				
			||||||
						defer func() {
 | 
											defer func() {
 | 
				
			||||||
							if err := recover(); err != nil {
 | 
												if err := recover(); err != nil {
 | 
				
			||||||
								log.Printf("ldap: recovered panic in RequestTimeout: %v", err)
 | 
													log.Printf("ldap: recovered panic in RequestTimeout: %v", err)
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}()
 | 
											}()
 | 
				
			||||||
						time.Sleep(l.requestTimeout)
 | 
											time.Sleep(requestTimeout)
 | 
				
			||||||
						timeoutMessage := &messagePacket{
 | 
											timeoutMessage := &messagePacket{
 | 
				
			||||||
							Op:        MessageTimeout,
 | 
												Op:        MessageTimeout,
 | 
				
			||||||
							MessageID: message.MessageID,
 | 
												MessageID: message.MessageID,
 | 
				
			||||||
@@ -351,26 +397,26 @@ func (l *Conn) processMessages() {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			case MessageResponse:
 | 
								case MessageResponse:
 | 
				
			||||||
				l.Debug.Printf("Receiving message %d", message.MessageID)
 | 
									l.Debug.Printf("Receiving message %d", message.MessageID)
 | 
				
			||||||
				if chanResult, ok := l.chanResults[message.MessageID]; ok {
 | 
									if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
 | 
				
			||||||
					chanResult <- &PacketResponse{message.Packet, nil}
 | 
										msgCtx.sendResponse(&PacketResponse{message.Packet, nil})
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					log.Printf("Received unexpected message %d, %v", message.MessageID, l.isClosing)
 | 
										log.Printf("Received unexpected message %d, %v", message.MessageID, l.isClosing())
 | 
				
			||||||
					ber.PrintPacket(message.Packet)
 | 
										ber.PrintPacket(message.Packet)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case MessageTimeout:
 | 
								case MessageTimeout:
 | 
				
			||||||
				// Handle the timeout by closing the channel
 | 
									// Handle the timeout by closing the channel
 | 
				
			||||||
				// All reads will return immediately
 | 
									// All reads will return immediately
 | 
				
			||||||
				if chanResult, ok := l.chanResults[message.MessageID]; ok {
 | 
									if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
 | 
				
			||||||
					chanResult <- &PacketResponse{message.Packet, errors.New("ldap: connection timed out")}
 | 
					 | 
				
			||||||
					l.Debug.Printf("Receiving message timeout for %d", message.MessageID)
 | 
										l.Debug.Printf("Receiving message timeout for %d", message.MessageID)
 | 
				
			||||||
					delete(l.chanResults, message.MessageID)
 | 
										msgCtx.sendResponse(&PacketResponse{message.Packet, errors.New("ldap: connection timed out")})
 | 
				
			||||||
					close(chanResult)
 | 
										delete(l.messageContexts, message.MessageID)
 | 
				
			||||||
 | 
										close(msgCtx.responses)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case MessageFinish:
 | 
								case MessageFinish:
 | 
				
			||||||
				l.Debug.Printf("Finished message %d", message.MessageID)
 | 
									l.Debug.Printf("Finished message %d", message.MessageID)
 | 
				
			||||||
				if chanResult, ok := l.chanResults[message.MessageID]; ok {
 | 
									if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
 | 
				
			||||||
					close(chanResult)
 | 
										delete(l.messageContexts, message.MessageID)
 | 
				
			||||||
					delete(l.chanResults, message.MessageID)
 | 
										close(msgCtx.responses)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -396,7 +442,8 @@ func (l *Conn) reader() {
 | 
				
			|||||||
		packet, err := ber.ReadPacket(l.conn)
 | 
							packet, err := ber.ReadPacket(l.conn)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			// A read error is expected here if we are closing the connection...
 | 
								// A read error is expected here if we are closing the connection...
 | 
				
			||||||
			if !l.isClosing {
 | 
								if !l.isClosing() {
 | 
				
			||||||
 | 
									l.closeErr.Store(fmt.Errorf("unable to read LDAP response packet: %s", err))
 | 
				
			||||||
				l.Debug.Printf("reader error: %s", err.Error())
 | 
									l.Debug.Printf("reader error: %s", err.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
@@ -419,6 +466,5 @@ func (l *Conn) reader() {
 | 
				
			|||||||
		if !l.sendProcessMessage(message) {
 | 
							if !l.sendProcessMessage(message) {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										144
									
								
								vendor/gopkg.in/ldap.v2/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										144
									
								
								vendor/gopkg.in/ldap.v2/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,35 +12,48 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	ControlTypePaging                 = "1.2.840.113556.1.4.319"
 | 
						// ControlTypePaging - https://www.ietf.org/rfc/rfc2696.txt
 | 
				
			||||||
	ControlTypeBeheraPasswordPolicy   = "1.3.6.1.4.1.42.2.27.8.5.1"
 | 
						ControlTypePaging = "1.2.840.113556.1.4.319"
 | 
				
			||||||
 | 
						// ControlTypeBeheraPasswordPolicy - https://tools.ietf.org/html/draft-behera-ldap-password-policy-10
 | 
				
			||||||
 | 
						ControlTypeBeheraPasswordPolicy = "1.3.6.1.4.1.42.2.27.8.5.1"
 | 
				
			||||||
 | 
						// ControlTypeVChuPasswordMustChange - https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
 | 
				
			||||||
	ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4"
 | 
						ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4"
 | 
				
			||||||
	ControlTypeVChuPasswordWarning    = "2.16.840.1.113730.3.4.5"
 | 
						// ControlTypeVChuPasswordWarning - https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
 | 
				
			||||||
	ControlTypeManageDsaIT            = "2.16.840.1.113730.3.4.2"
 | 
						ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
 | 
				
			||||||
 | 
						// ControlTypeManageDsaIT - https://tools.ietf.org/html/rfc3296
 | 
				
			||||||
 | 
						ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlTypeMap maps controls to text descriptions
 | 
				
			||||||
var ControlTypeMap = map[string]string{
 | 
					var ControlTypeMap = map[string]string{
 | 
				
			||||||
	ControlTypePaging:               "Paging",
 | 
						ControlTypePaging:               "Paging",
 | 
				
			||||||
	ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
 | 
						ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
 | 
				
			||||||
	ControlTypeManageDsaIT:          "Manage DSA IT",
 | 
						ControlTypeManageDsaIT:          "Manage DSA IT",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Control defines an interface controls provide to encode and describe themselves
 | 
				
			||||||
type Control interface {
 | 
					type Control interface {
 | 
				
			||||||
 | 
						// GetControlType returns the OID
 | 
				
			||||||
	GetControlType() string
 | 
						GetControlType() string
 | 
				
			||||||
 | 
						// Encode returns the ber packet representation
 | 
				
			||||||
	Encode() *ber.Packet
 | 
						Encode() *ber.Packet
 | 
				
			||||||
 | 
						// String returns a human-readable description
 | 
				
			||||||
	String() string
 | 
						String() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlString implements the Control interface for simple controls
 | 
				
			||||||
type ControlString struct {
 | 
					type ControlString struct {
 | 
				
			||||||
	ControlType  string
 | 
						ControlType  string
 | 
				
			||||||
	Criticality  bool
 | 
						Criticality  bool
 | 
				
			||||||
	ControlValue string
 | 
						ControlValue string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlString) GetControlType() string {
 | 
					func (c *ControlString) GetControlType() string {
 | 
				
			||||||
	return c.ControlType
 | 
						return c.ControlType
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlString) Encode() *ber.Packet {
 | 
					func (c *ControlString) Encode() *ber.Packet {
 | 
				
			||||||
	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
						packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
				
			||||||
	packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")"))
 | 
						packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")"))
 | 
				
			||||||
@@ -51,26 +64,32 @@ func (c *ControlString) Encode() *ber.Packet {
 | 
				
			|||||||
	return packet
 | 
						return packet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlString) String() string {
 | 
					func (c *ControlString) String() string {
 | 
				
			||||||
	return fmt.Sprintf("Control Type: %s (%q)  Criticality: %t  Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue)
 | 
						return fmt.Sprintf("Control Type: %s (%q)  Criticality: %t  Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlPaging implements the paging control described in https://www.ietf.org/rfc/rfc2696.txt
 | 
				
			||||||
type ControlPaging struct {
 | 
					type ControlPaging struct {
 | 
				
			||||||
 | 
						// PagingSize indicates the page size
 | 
				
			||||||
	PagingSize uint32
 | 
						PagingSize uint32
 | 
				
			||||||
	Cookie     []byte
 | 
						// Cookie is an opaque value returned by the server to track a paging cursor
 | 
				
			||||||
 | 
						Cookie []byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlPaging) GetControlType() string {
 | 
					func (c *ControlPaging) GetControlType() string {
 | 
				
			||||||
	return ControlTypePaging
 | 
						return ControlTypePaging
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlPaging) Encode() *ber.Packet {
 | 
					func (c *ControlPaging) Encode() *ber.Packet {
 | 
				
			||||||
	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
						packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
				
			||||||
	packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")"))
 | 
						packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)")
 | 
						p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)")
 | 
				
			||||||
	seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value")
 | 
						seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value")
 | 
				
			||||||
	seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size"))
 | 
						seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(c.PagingSize), "Paging Size"))
 | 
				
			||||||
	cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
 | 
						cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
 | 
				
			||||||
	cookie.Value = c.Cookie
 | 
						cookie.Value = c.Cookie
 | 
				
			||||||
	cookie.Data.Write(c.Cookie)
 | 
						cookie.Data.Write(c.Cookie)
 | 
				
			||||||
@@ -81,6 +100,7 @@ func (c *ControlPaging) Encode() *ber.Packet {
 | 
				
			|||||||
	return packet
 | 
						return packet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlPaging) String() string {
 | 
					func (c *ControlPaging) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"Control Type: %s (%q)  Criticality: %t  PagingSize: %d  Cookie: %q",
 | 
							"Control Type: %s (%q)  Criticality: %t  PagingSize: %d  Cookie: %q",
 | 
				
			||||||
@@ -91,21 +111,29 @@ func (c *ControlPaging) String() string {
 | 
				
			|||||||
		c.Cookie)
 | 
							c.Cookie)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetCookie stores the given cookie in the paging control
 | 
				
			||||||
func (c *ControlPaging) SetCookie(cookie []byte) {
 | 
					func (c *ControlPaging) SetCookie(cookie []byte) {
 | 
				
			||||||
	c.Cookie = cookie
 | 
						c.Cookie = cookie
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlBeheraPasswordPolicy implements the control described in https://tools.ietf.org/html/draft-behera-ldap-password-policy-10
 | 
				
			||||||
type ControlBeheraPasswordPolicy struct {
 | 
					type ControlBeheraPasswordPolicy struct {
 | 
				
			||||||
	Expire      int64
 | 
						// Expire contains the number of seconds before a password will expire
 | 
				
			||||||
	Grace       int64
 | 
						Expire int64
 | 
				
			||||||
	Error       int8
 | 
						// Grace indicates the remaining number of times a user will be allowed to authenticate with an expired password
 | 
				
			||||||
 | 
						Grace int64
 | 
				
			||||||
 | 
						// Error indicates the error code
 | 
				
			||||||
 | 
						Error int8
 | 
				
			||||||
 | 
						// ErrorString is a human readable error
 | 
				
			||||||
	ErrorString string
 | 
						ErrorString string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlBeheraPasswordPolicy) GetControlType() string {
 | 
					func (c *ControlBeheraPasswordPolicy) GetControlType() string {
 | 
				
			||||||
	return ControlTypeBeheraPasswordPolicy
 | 
						return ControlTypeBeheraPasswordPolicy
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet {
 | 
					func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet {
 | 
				
			||||||
	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
						packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
				
			||||||
	packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeBeheraPasswordPolicy, "Control Type ("+ControlTypeMap[ControlTypeBeheraPasswordPolicy]+")"))
 | 
						packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeBeheraPasswordPolicy, "Control Type ("+ControlTypeMap[ControlTypeBeheraPasswordPolicy]+")"))
 | 
				
			||||||
@@ -113,6 +141,7 @@ func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet {
 | 
				
			|||||||
	return packet
 | 
						return packet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlBeheraPasswordPolicy) String() string {
 | 
					func (c *ControlBeheraPasswordPolicy) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"Control Type: %s (%q)  Criticality: %t  Expire: %d  Grace: %d  Error: %d, ErrorString: %s",
 | 
							"Control Type: %s (%q)  Criticality: %t  Expire: %d  Grace: %d  Error: %d, ErrorString: %s",
 | 
				
			||||||
@@ -125,39 +154,49 @@ func (c *ControlBeheraPasswordPolicy) String() string {
 | 
				
			|||||||
		c.ErrorString)
 | 
							c.ErrorString)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlVChuPasswordMustChange implements the control described in https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
 | 
				
			||||||
type ControlVChuPasswordMustChange struct {
 | 
					type ControlVChuPasswordMustChange struct {
 | 
				
			||||||
 | 
						// MustChange indicates if the password is required to be changed
 | 
				
			||||||
	MustChange bool
 | 
						MustChange bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlVChuPasswordMustChange) GetControlType() string {
 | 
					func (c *ControlVChuPasswordMustChange) GetControlType() string {
 | 
				
			||||||
	return ControlTypeVChuPasswordMustChange
 | 
						return ControlTypeVChuPasswordMustChange
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet {
 | 
					func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlVChuPasswordMustChange) String() string {
 | 
					func (c *ControlVChuPasswordMustChange) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"Control Type: %s (%q)  Criticality: %t  MustChange: %b",
 | 
							"Control Type: %s (%q)  Criticality: %t  MustChange: %v",
 | 
				
			||||||
		ControlTypeMap[ControlTypeVChuPasswordMustChange],
 | 
							ControlTypeMap[ControlTypeVChuPasswordMustChange],
 | 
				
			||||||
		ControlTypeVChuPasswordMustChange,
 | 
							ControlTypeVChuPasswordMustChange,
 | 
				
			||||||
		false,
 | 
							false,
 | 
				
			||||||
		c.MustChange)
 | 
							c.MustChange)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlVChuPasswordWarning implements the control described in https://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00
 | 
				
			||||||
type ControlVChuPasswordWarning struct {
 | 
					type ControlVChuPasswordWarning struct {
 | 
				
			||||||
 | 
						// Expire indicates the time in seconds until the password expires
 | 
				
			||||||
	Expire int64
 | 
						Expire int64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlVChuPasswordWarning) GetControlType() string {
 | 
					func (c *ControlVChuPasswordWarning) GetControlType() string {
 | 
				
			||||||
	return ControlTypeVChuPasswordWarning
 | 
						return ControlTypeVChuPasswordWarning
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlVChuPasswordWarning) Encode() *ber.Packet {
 | 
					func (c *ControlVChuPasswordWarning) Encode() *ber.Packet {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlVChuPasswordWarning) String() string {
 | 
					func (c *ControlVChuPasswordWarning) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"Control Type: %s (%q)  Criticality: %t  Expire: %b",
 | 
							"Control Type: %s (%q)  Criticality: %t  Expire: %b",
 | 
				
			||||||
@@ -167,14 +206,18 @@ func (c *ControlVChuPasswordWarning) String() string {
 | 
				
			|||||||
		c.Expire)
 | 
							c.Expire)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ControlManageDsaIT implements the control described in https://tools.ietf.org/html/rfc3296
 | 
				
			||||||
type ControlManageDsaIT struct {
 | 
					type ControlManageDsaIT struct {
 | 
				
			||||||
 | 
						// Criticality indicates if this control is required
 | 
				
			||||||
	Criticality bool
 | 
						Criticality bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetControlType returns the OID
 | 
				
			||||||
func (c *ControlManageDsaIT) GetControlType() string {
 | 
					func (c *ControlManageDsaIT) GetControlType() string {
 | 
				
			||||||
	return ControlTypeManageDsaIT
 | 
						return ControlTypeManageDsaIT
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode returns the ber packet representation
 | 
				
			||||||
func (c *ControlManageDsaIT) Encode() *ber.Packet {
 | 
					func (c *ControlManageDsaIT) Encode() *ber.Packet {
 | 
				
			||||||
	//FIXME
 | 
						//FIXME
 | 
				
			||||||
	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
						packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
 | 
				
			||||||
@@ -185,6 +228,7 @@ func (c *ControlManageDsaIT) Encode() *ber.Packet {
 | 
				
			|||||||
	return packet
 | 
						return packet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a human-readable description
 | 
				
			||||||
func (c *ControlManageDsaIT) String() string {
 | 
					func (c *ControlManageDsaIT) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"Control Type: %s (%q)  Criticality: %t",
 | 
							"Control Type: %s (%q)  Criticality: %t",
 | 
				
			||||||
@@ -193,10 +237,12 @@ func (c *ControlManageDsaIT) String() string {
 | 
				
			|||||||
		c.Criticality)
 | 
							c.Criticality)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewControlManageDsaIT returns a ControlManageDsaIT control
 | 
				
			||||||
func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT {
 | 
					func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT {
 | 
				
			||||||
	return &ControlManageDsaIT{Criticality: Criticality}
 | 
						return &ControlManageDsaIT{Criticality: Criticality}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindControl returns the first control of the given type in the list, or nil
 | 
				
			||||||
func FindControl(controls []Control, controlType string) Control {
 | 
					func FindControl(controls []Control, controlType string) Control {
 | 
				
			||||||
	for _, c := range controls {
 | 
						for _, c := range controls {
 | 
				
			||||||
		if c.GetControlType() == controlType {
 | 
							if c.GetControlType() == controlType {
 | 
				
			||||||
@@ -206,20 +252,56 @@ func FindControl(controls []Control, controlType string) Control {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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 {
 | 
				
			||||||
	ControlType := packet.Children[0].Value.(string)
 | 
						var (
 | 
				
			||||||
	Criticality := false
 | 
							ControlType = ""
 | 
				
			||||||
 | 
							Criticality = false
 | 
				
			||||||
 | 
							value       *ber.Packet
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch len(packet.Children) {
 | 
				
			||||||
 | 
						case 0:
 | 
				
			||||||
 | 
							// at least one child is required for control type
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							// just type, no criticality or value
 | 
				
			||||||
 | 
							packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
 | 
				
			||||||
 | 
							ControlType = packet.Children[0].Value.(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
 | 
				
			||||||
 | 
							ControlType = packet.Children[0].Value.(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Children[1] could be criticality or value (both are optional)
 | 
				
			||||||
 | 
							// duck-type on whether this is a boolean
 | 
				
			||||||
 | 
							if _, ok := packet.Children[1].Value.(bool); ok {
 | 
				
			||||||
 | 
								packet.Children[1].Description = "Criticality"
 | 
				
			||||||
 | 
								Criticality = packet.Children[1].Value.(bool)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								packet.Children[1].Description = "Control Value"
 | 
				
			||||||
 | 
								value = packet.Children[1]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 3:
 | 
				
			||||||
 | 
							packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
 | 
				
			||||||
 | 
							ControlType = packet.Children[0].Value.(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
 | 
					 | 
				
			||||||
	value := packet.Children[1]
 | 
					 | 
				
			||||||
	if len(packet.Children) == 3 {
 | 
					 | 
				
			||||||
		value = packet.Children[2]
 | 
					 | 
				
			||||||
		packet.Children[1].Description = "Criticality"
 | 
							packet.Children[1].Description = "Criticality"
 | 
				
			||||||
		Criticality = packet.Children[1].Value.(bool)
 | 
							Criticality = packet.Children[1].Value.(bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							packet.Children[2].Description = "Control Value"
 | 
				
			||||||
 | 
							value = packet.Children[2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// more than 3 children is invalid
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	value.Description = "Control Value"
 | 
					 | 
				
			||||||
	switch ControlType {
 | 
						switch ControlType {
 | 
				
			||||||
 | 
						case ControlTypeManageDsaIT:
 | 
				
			||||||
 | 
							return NewControlManageDsaIT(Criticality)
 | 
				
			||||||
	case ControlTypePaging:
 | 
						case ControlTypePaging:
 | 
				
			||||||
		value.Description += " (Paging)"
 | 
							value.Description += " (Paging)"
 | 
				
			||||||
		c := new(ControlPaging)
 | 
							c := new(ControlPaging)
 | 
				
			||||||
@@ -252,18 +334,18 @@ func DecodeControl(packet *ber.Packet) Control {
 | 
				
			|||||||
		for _, child := range sequence.Children {
 | 
							for _, child := range sequence.Children {
 | 
				
			||||||
			if child.Tag == 0 {
 | 
								if child.Tag == 0 {
 | 
				
			||||||
				//Warning
 | 
									//Warning
 | 
				
			||||||
				child := child.Children[0]
 | 
									warningPacket := child.Children[0]
 | 
				
			||||||
				packet := ber.DecodePacket(child.Data.Bytes())
 | 
									packet := ber.DecodePacket(warningPacket.Data.Bytes())
 | 
				
			||||||
				val, ok := packet.Value.(int64)
 | 
									val, ok := packet.Value.(int64)
 | 
				
			||||||
				if ok {
 | 
									if ok {
 | 
				
			||||||
					if child.Tag == 0 {
 | 
										if warningPacket.Tag == 0 {
 | 
				
			||||||
						//timeBeforeExpiration
 | 
											//timeBeforeExpiration
 | 
				
			||||||
						c.Expire = val
 | 
											c.Expire = val
 | 
				
			||||||
						child.Value = c.Expire
 | 
											warningPacket.Value = c.Expire
 | 
				
			||||||
					} else if child.Tag == 1 {
 | 
										} else if warningPacket.Tag == 1 {
 | 
				
			||||||
						//graceAuthNsRemaining
 | 
											//graceAuthNsRemaining
 | 
				
			||||||
						c.Grace = val
 | 
											c.Grace = val
 | 
				
			||||||
						child.Value = c.Grace
 | 
											warningPacket.Value = c.Grace
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else if child.Tag == 1 {
 | 
								} else if child.Tag == 1 {
 | 
				
			||||||
@@ -294,15 +376,19 @@ func DecodeControl(packet *ber.Packet) Control {
 | 
				
			|||||||
		c.Expire = expire
 | 
							c.Expire = expire
 | 
				
			||||||
		value.Value = c.Expire
 | 
							value.Value = c.Expire
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return c
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							c := new(ControlString)
 | 
				
			||||||
 | 
							c.ControlType = ControlType
 | 
				
			||||||
 | 
							c.Criticality = Criticality
 | 
				
			||||||
 | 
							if value != nil {
 | 
				
			||||||
 | 
								c.ControlValue = value.Value.(string)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return c
 | 
							return c
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c := new(ControlString)
 | 
					 | 
				
			||||||
	c.ControlType = ControlType
 | 
					 | 
				
			||||||
	c.Criticality = Criticality
 | 
					 | 
				
			||||||
	c.ControlValue = value.Value.(string)
 | 
					 | 
				
			||||||
	return c
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewControlString returns a generic control
 | 
				
			||||||
func NewControlString(controlType string, criticality bool, controlValue string) *ControlString {
 | 
					func NewControlString(controlType string, criticality bool, controlValue string) *ControlString {
 | 
				
			||||||
	return &ControlString{
 | 
						return &ControlString{
 | 
				
			||||||
		ControlType:  controlType,
 | 
							ControlType:  controlType,
 | 
				
			||||||
@@ -311,10 +397,12 @@ func NewControlString(controlType string, criticality bool, controlValue string)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewControlPaging returns a paging control
 | 
				
			||||||
func NewControlPaging(pagingSize uint32) *ControlPaging {
 | 
					func NewControlPaging(pagingSize uint32) *ControlPaging {
 | 
				
			||||||
	return &ControlPaging{PagingSize: pagingSize}
 | 
						return &ControlPaging{PagingSize: pagingSize}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewControlBeheraPasswordPolicy returns a ControlBeheraPasswordPolicy
 | 
				
			||||||
func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy {
 | 
					func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy {
 | 
				
			||||||
	return &ControlBeheraPasswordPolicy{
 | 
						return &ControlBeheraPasswordPolicy{
 | 
				
			||||||
		Expire: -1,
 | 
							Expire: -1,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/gopkg.in/ldap.v2/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/gopkg.in/ldap.v2/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// debbuging type
 | 
					// debugging type
 | 
				
			||||||
//     - has a Printf method to write the debug output
 | 
					//     - has a Printf method to write the debug output
 | 
				
			||||||
type debugging bool
 | 
					type debugging bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								vendor/gopkg.in/ldap.v2/del.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/gopkg.in/ldap.v2/del.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,8 +12,11 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DelRequest implements an LDAP deletion request
 | 
				
			||||||
type DelRequest struct {
 | 
					type DelRequest struct {
 | 
				
			||||||
	DN       string
 | 
						// DN is the name of the directory entry to delete
 | 
				
			||||||
 | 
						DN string
 | 
				
			||||||
 | 
						// Controls hold optional controls to send with the request
 | 
				
			||||||
	Controls []Control
 | 
						Controls []Control
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,6 +26,7 @@ func (d DelRequest) encode() *ber.Packet {
 | 
				
			|||||||
	return request
 | 
						return request
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewDelRequest creates a delete request for the given DN and controls
 | 
				
			||||||
func NewDelRequest(DN string,
 | 
					func NewDelRequest(DN string,
 | 
				
			||||||
	Controls []Control) *DelRequest {
 | 
						Controls []Control) *DelRequest {
 | 
				
			||||||
	return &DelRequest{
 | 
						return &DelRequest{
 | 
				
			||||||
@@ -31,10 +35,10 @@ func NewDelRequest(DN string,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Del executes the given delete request
 | 
				
			||||||
func (l *Conn) Del(delRequest *DelRequest) error {
 | 
					func (l *Conn) Del(delRequest *DelRequest) error {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	packet.AppendChild(delRequest.encode())
 | 
						packet.AppendChild(delRequest.encode())
 | 
				
			||||||
	if delRequest.Controls != nil {
 | 
						if delRequest.Controls != nil {
 | 
				
			||||||
		packet.AppendChild(encodeControls(delRequest.Controls))
 | 
							packet.AppendChild(encodeControls(delRequest.Controls))
 | 
				
			||||||
@@ -42,22 +46,19 @@ func (l *Conn) Del(delRequest *DelRequest) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -78,6 +79,6 @@ func (l *Conn) Del(delRequest *DelRequest) error {
 | 
				
			|||||||
		log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
							log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: returning", messageID)
 | 
						l.Debug.Printf("%d: returning", msgCtx.id)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										124
									
								
								vendor/gopkg.in/ldap.v2/dn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										124
									
								
								vendor/gopkg.in/ldap.v2/dn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,7 +2,7 @@
 | 
				
			|||||||
// Use of this source code is governed by a BSD-style
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
// license that can be found in the LICENSE file.
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// File contains DN parsing functionallity
 | 
					// File contains DN parsing functionality
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// https://tools.ietf.org/html/rfc4514
 | 
					// https://tools.ietf.org/html/rfc4514
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -52,22 +52,28 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ber "gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AttributeTypeAndValue represents an attributeTypeAndValue from https://tools.ietf.org/html/rfc4514
 | 
				
			||||||
type AttributeTypeAndValue struct {
 | 
					type AttributeTypeAndValue struct {
 | 
				
			||||||
	Type  string
 | 
						// Type is the attribute type
 | 
				
			||||||
 | 
						Type string
 | 
				
			||||||
 | 
						// Value is the attribute value
 | 
				
			||||||
	Value string
 | 
						Value string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RelativeDN represents a relativeDistinguishedName from https://tools.ietf.org/html/rfc4514
 | 
				
			||||||
type RelativeDN struct {
 | 
					type RelativeDN struct {
 | 
				
			||||||
	Attributes []*AttributeTypeAndValue
 | 
						Attributes []*AttributeTypeAndValue
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
 | 
				
			||||||
type DN struct {
 | 
					type DN struct {
 | 
				
			||||||
	RDNs []*RelativeDN
 | 
						RDNs []*RelativeDN
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseDN returns a distinguishedName or an error
 | 
				
			||||||
func ParseDN(str string) (*DN, error) {
 | 
					func ParseDN(str string) (*DN, error) {
 | 
				
			||||||
	dn := new(DN)
 | 
						dn := new(DN)
 | 
				
			||||||
	dn.RDNs = make([]*RelativeDN, 0)
 | 
						dn.RDNs = make([]*RelativeDN, 0)
 | 
				
			||||||
@@ -77,9 +83,19 @@ func ParseDN(str string) (*DN, error) {
 | 
				
			|||||||
	attribute := new(AttributeTypeAndValue)
 | 
						attribute := new(AttributeTypeAndValue)
 | 
				
			||||||
	escaping := false
 | 
						escaping := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unescapedTrailingSpaces := 0
 | 
				
			||||||
 | 
						stringFromBuffer := func() string {
 | 
				
			||||||
 | 
							s := buffer.String()
 | 
				
			||||||
 | 
							s = s[0 : len(s)-unescapedTrailingSpaces]
 | 
				
			||||||
 | 
							buffer.Reset()
 | 
				
			||||||
 | 
							unescapedTrailingSpaces = 0
 | 
				
			||||||
 | 
							return s
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < len(str); i++ {
 | 
						for i := 0; i < len(str); i++ {
 | 
				
			||||||
		char := str[i]
 | 
							char := str[i]
 | 
				
			||||||
		if escaping {
 | 
							if escaping {
 | 
				
			||||||
 | 
								unescapedTrailingSpaces = 0
 | 
				
			||||||
			escaping = false
 | 
								escaping = false
 | 
				
			||||||
			switch char {
 | 
								switch char {
 | 
				
			||||||
			case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\':
 | 
								case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\':
 | 
				
			||||||
@@ -94,19 +110,17 @@ func ParseDN(str string) (*DN, error) {
 | 
				
			|||||||
			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, errors.New(
 | 
									return nil, fmt.Errorf("Failed to decode escaped character: %s", err)
 | 
				
			||||||
					fmt.Sprintf("Failed to decode escaped character: %s", err))
 | 
					 | 
				
			||||||
			} else if n != 1 {
 | 
								} else if n != 1 {
 | 
				
			||||||
				return nil, errors.New(
 | 
									return nil, fmt.Errorf("Expected 1 byte when un-escaping, got %d", n)
 | 
				
			||||||
					fmt.Sprintf("Expected 1 byte when un-escaping, got %d", n))
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			buffer.WriteByte(dst[0])
 | 
								buffer.WriteByte(dst[0])
 | 
				
			||||||
			i++
 | 
								i++
 | 
				
			||||||
		} else if char == '\\' {
 | 
							} else if char == '\\' {
 | 
				
			||||||
 | 
								unescapedTrailingSpaces = 0
 | 
				
			||||||
			escaping = true
 | 
								escaping = true
 | 
				
			||||||
		} else if char == '=' {
 | 
							} else if char == '=' {
 | 
				
			||||||
			attribute.Type = buffer.String()
 | 
								attribute.Type = stringFromBuffer()
 | 
				
			||||||
			buffer.Reset()
 | 
					 | 
				
			||||||
			// Special case: If the first character in the value is # the
 | 
								// Special case: If the first character in the value is # the
 | 
				
			||||||
			// following data is BER encoded so we can just fast forward
 | 
								// following data is BER encoded so we can just fast forward
 | 
				
			||||||
			// and decode.
 | 
								// and decode.
 | 
				
			||||||
@@ -119,18 +133,20 @@ func ParseDN(str string) (*DN, error) {
 | 
				
			|||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					data = str[i:]
 | 
										data = str[i:]
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				raw_ber, err := enchex.DecodeString(data)
 | 
									rawBER, err := enchex.DecodeString(data)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, errors.New(
 | 
										return nil, fmt.Errorf("Failed to decode BER encoding: %s", err)
 | 
				
			||||||
						fmt.Sprintf("Failed to decode BER encoding: %s", err))
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				packet := ber.DecodePacket(raw_ber)
 | 
									packet := ber.DecodePacket(rawBER)
 | 
				
			||||||
				buffer.WriteString(packet.Data.String())
 | 
									buffer.WriteString(packet.Data.String())
 | 
				
			||||||
				i += len(data) - 1
 | 
									i += len(data) - 1
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if char == ',' || char == '+' {
 | 
							} else if char == ',' || char == '+' {
 | 
				
			||||||
			// We're done with this RDN or value, push it
 | 
								// We're done with this RDN or value, push it
 | 
				
			||||||
			attribute.Value = buffer.String()
 | 
								if len(attribute.Type) == 0 {
 | 
				
			||||||
 | 
									return nil, errors.New("incomplete type, value pair")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								attribute.Value = stringFromBuffer()
 | 
				
			||||||
			rdn.Attributes = append(rdn.Attributes, attribute)
 | 
								rdn.Attributes = append(rdn.Attributes, attribute)
 | 
				
			||||||
			attribute = new(AttributeTypeAndValue)
 | 
								attribute = new(AttributeTypeAndValue)
 | 
				
			||||||
			if char == ',' {
 | 
								if char == ',' {
 | 
				
			||||||
@@ -138,8 +154,17 @@ func ParseDN(str string) (*DN, error) {
 | 
				
			|||||||
				rdn = new(RelativeDN)
 | 
									rdn = new(RelativeDN)
 | 
				
			||||||
				rdn.Attributes = make([]*AttributeTypeAndValue, 0)
 | 
									rdn.Attributes = make([]*AttributeTypeAndValue, 0)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			buffer.Reset()
 | 
							} else if char == ' ' && buffer.Len() == 0 {
 | 
				
			||||||
 | 
								// ignore unescaped leading spaces
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								if char == ' ' {
 | 
				
			||||||
 | 
									// Track unescaped spaces in case they are trailing and we need to remove them
 | 
				
			||||||
 | 
									unescapedTrailingSpaces++
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									// Reset if we see a non-space char
 | 
				
			||||||
 | 
									unescapedTrailingSpaces = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			buffer.WriteByte(char)
 | 
								buffer.WriteByte(char)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -147,9 +172,76 @@ func ParseDN(str string) (*DN, error) {
 | 
				
			|||||||
		if len(attribute.Type) == 0 {
 | 
							if len(attribute.Type) == 0 {
 | 
				
			||||||
			return nil, errors.New("DN ended with incomplete type, value pair")
 | 
								return nil, errors.New("DN ended with incomplete type, value pair")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		attribute.Value = buffer.String()
 | 
							attribute.Value = stringFromBuffer()
 | 
				
			||||||
		rdn.Attributes = append(rdn.Attributes, attribute)
 | 
							rdn.Attributes = append(rdn.Attributes, attribute)
 | 
				
			||||||
		dn.RDNs = append(dn.RDNs, rdn)
 | 
							dn.RDNs = append(dn.RDNs, rdn)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return dn, nil
 | 
						return dn, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
 | 
				
			||||||
 | 
					// Returns true if they have the same number of relative distinguished names
 | 
				
			||||||
 | 
					// and corresponding relative distinguished names (by position) are the same.
 | 
				
			||||||
 | 
					func (d *DN) Equal(other *DN) bool {
 | 
				
			||||||
 | 
						if len(d.RDNs) != len(other.RDNs) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := range d.RDNs {
 | 
				
			||||||
 | 
							if !d.RDNs[i].Equal(other.RDNs[i]) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AncestorOf returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN.
 | 
				
			||||||
 | 
					// "ou=widgets,o=acme.com" is an ancestor of "ou=sprockets,ou=widgets,o=acme.com"
 | 
				
			||||||
 | 
					// "ou=widgets,o=acme.com" is not an ancestor of "ou=sprockets,ou=widgets,o=foo.com"
 | 
				
			||||||
 | 
					// "ou=widgets,o=acme.com" is not an ancestor of "ou=widgets,o=acme.com"
 | 
				
			||||||
 | 
					func (d *DN) AncestorOf(other *DN) bool {
 | 
				
			||||||
 | 
						if len(d.RDNs) >= len(other.RDNs) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Take the last `len(d.RDNs)` RDNs from the other DN to compare against
 | 
				
			||||||
 | 
						otherRDNs := other.RDNs[len(other.RDNs)-len(d.RDNs):]
 | 
				
			||||||
 | 
						for i := range d.RDNs {
 | 
				
			||||||
 | 
							if !d.RDNs[i].Equal(otherRDNs[i]) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
 | 
				
			||||||
 | 
					// Relative distinguished names are the same if and only if they have the same number of AttributeTypeAndValues
 | 
				
			||||||
 | 
					// and each attribute of the first RDN is the same as the attribute of the second RDN with the same attribute type.
 | 
				
			||||||
 | 
					// The order of attributes is not significant.
 | 
				
			||||||
 | 
					// Case of attribute types is not significant.
 | 
				
			||||||
 | 
					func (r *RelativeDN) Equal(other *RelativeDN) bool {
 | 
				
			||||||
 | 
						if len(r.Attributes) != len(other.Attributes) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return r.hasAllAttributes(other.Attributes) && other.hasAllAttributes(r.Attributes)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) bool {
 | 
				
			||||||
 | 
						for _, attr := range attrs {
 | 
				
			||||||
 | 
							found := false
 | 
				
			||||||
 | 
							for _, myattr := range r.Attributes {
 | 
				
			||||||
 | 
								if myattr.Equal(attr) {
 | 
				
			||||||
 | 
									found = true
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Equal returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue
 | 
				
			||||||
 | 
					// Case of the attribute type is not significant
 | 
				
			||||||
 | 
					func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool {
 | 
				
			||||||
 | 
						return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/ldap.v2/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/ldap.v2/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -56,6 +56,7 @@ const (
 | 
				
			|||||||
	ErrorUnexpectedResponse = 205
 | 
						ErrorUnexpectedResponse = 205
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LDAPResultCodeMap contains string descriptions for LDAP error codes
 | 
				
			||||||
var LDAPResultCodeMap = map[uint8]string{
 | 
					var LDAPResultCodeMap = map[uint8]string{
 | 
				
			||||||
	LDAPResultSuccess:                      "Success",
 | 
						LDAPResultSuccess:                      "Success",
 | 
				
			||||||
	LDAPResultOperationsError:              "Operations Error",
 | 
						LDAPResultOperationsError:              "Operations Error",
 | 
				
			||||||
@@ -96,6 +97,13 @@ var LDAPResultCodeMap = map[uint8]string{
 | 
				
			|||||||
	LDAPResultObjectClassModsProhibited:    "Object Class Mods Prohibited",
 | 
						LDAPResultObjectClassModsProhibited:    "Object Class Mods Prohibited",
 | 
				
			||||||
	LDAPResultAffectsMultipleDSAs:          "Affects Multiple DSAs",
 | 
						LDAPResultAffectsMultipleDSAs:          "Affects Multiple DSAs",
 | 
				
			||||||
	LDAPResultOther:                        "Other",
 | 
						LDAPResultOther:                        "Other",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ErrorNetwork:            "Network Error",
 | 
				
			||||||
 | 
						ErrorFilterCompile:      "Filter Compile Error",
 | 
				
			||||||
 | 
						ErrorFilterDecompile:    "Filter Decompile Error",
 | 
				
			||||||
 | 
						ErrorDebugging:          "Debugging Error",
 | 
				
			||||||
 | 
						ErrorUnexpectedMessage:  "Unexpected Message",
 | 
				
			||||||
 | 
						ErrorUnexpectedResponse: "Unexpected Response",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
 | 
					func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
 | 
				
			||||||
@@ -115,8 +123,11 @@ func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
 | 
				
			|||||||
	return ErrorNetwork, "Invalid packet format"
 | 
						return ErrorNetwork, "Invalid packet format"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Error holds LDAP error information
 | 
				
			||||||
type Error struct {
 | 
					type Error struct {
 | 
				
			||||||
	Err        error
 | 
						// Err is the underlying error
 | 
				
			||||||
 | 
						Err error
 | 
				
			||||||
 | 
						// ResultCode is the LDAP error code
 | 
				
			||||||
	ResultCode uint8
 | 
						ResultCode uint8
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -124,10 +135,12 @@ func (e *Error) Error() string {
 | 
				
			|||||||
	return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
 | 
						return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewError creates an LDAP error with the given code and underlying error
 | 
				
			||||||
func NewError(resultCode uint8, err error) error {
 | 
					func NewError(resultCode uint8, err error) error {
 | 
				
			||||||
	return &Error{ResultCode: resultCode, Err: err}
 | 
						return &Error{ResultCode: resultCode, Err: err}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
 | 
				
			||||||
func IsErrorWithCode(err error, desiredResultCode uint8) bool {
 | 
					func IsErrorWithCode(err error, desiredResultCode uint8) bool {
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								vendor/gopkg.in/ldap.v2/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								vendor/gopkg.in/ldap.v2/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,6 +15,7 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Filter choices
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	FilterAnd             = 0
 | 
						FilterAnd             = 0
 | 
				
			||||||
	FilterOr              = 1
 | 
						FilterOr              = 1
 | 
				
			||||||
@@ -28,6 +29,7 @@ const (
 | 
				
			|||||||
	FilterExtensibleMatch = 9
 | 
						FilterExtensibleMatch = 9
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FilterMap contains human readable descriptions of Filter choices
 | 
				
			||||||
var FilterMap = map[uint64]string{
 | 
					var FilterMap = map[uint64]string{
 | 
				
			||||||
	FilterAnd:             "And",
 | 
						FilterAnd:             "And",
 | 
				
			||||||
	FilterOr:              "Or",
 | 
						FilterOr:              "Or",
 | 
				
			||||||
@@ -41,18 +43,21 @@ var FilterMap = map[uint64]string{
 | 
				
			|||||||
	FilterExtensibleMatch: "Extensible Match",
 | 
						FilterExtensibleMatch: "Extensible Match",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SubstringFilter options
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	FilterSubstringsInitial = 0
 | 
						FilterSubstringsInitial = 0
 | 
				
			||||||
	FilterSubstringsAny     = 1
 | 
						FilterSubstringsAny     = 1
 | 
				
			||||||
	FilterSubstringsFinal   = 2
 | 
						FilterSubstringsFinal   = 2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FilterSubstringsMap contains human readable descriptions of SubstringFilter choices
 | 
				
			||||||
var FilterSubstringsMap = map[uint64]string{
 | 
					var FilterSubstringsMap = map[uint64]string{
 | 
				
			||||||
	FilterSubstringsInitial: "Substrings Initial",
 | 
						FilterSubstringsInitial: "Substrings Initial",
 | 
				
			||||||
	FilterSubstringsAny:     "Substrings Any",
 | 
						FilterSubstringsAny:     "Substrings Any",
 | 
				
			||||||
	FilterSubstringsFinal:   "Substrings Final",
 | 
						FilterSubstringsFinal:   "Substrings Final",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MatchingRuleAssertion choices
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	MatchingRuleAssertionMatchingRule = 1
 | 
						MatchingRuleAssertionMatchingRule = 1
 | 
				
			||||||
	MatchingRuleAssertionType         = 2
 | 
						MatchingRuleAssertionType         = 2
 | 
				
			||||||
@@ -60,6 +65,7 @@ const (
 | 
				
			|||||||
	MatchingRuleAssertionDNAttributes = 4
 | 
						MatchingRuleAssertionDNAttributes = 4
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MatchingRuleAssertionMap contains human readable descriptions of MatchingRuleAssertion choices
 | 
				
			||||||
var MatchingRuleAssertionMap = map[uint64]string{
 | 
					var MatchingRuleAssertionMap = map[uint64]string{
 | 
				
			||||||
	MatchingRuleAssertionMatchingRule: "Matching Rule Assertion Matching Rule",
 | 
						MatchingRuleAssertionMatchingRule: "Matching Rule Assertion Matching Rule",
 | 
				
			||||||
	MatchingRuleAssertionType:         "Matching Rule Assertion Type",
 | 
						MatchingRuleAssertionType:         "Matching Rule Assertion Type",
 | 
				
			||||||
@@ -67,6 +73,7 @@ var MatchingRuleAssertionMap = map[uint64]string{
 | 
				
			|||||||
	MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
 | 
						MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CompileFilter converts a string representation of a filter into a BER-encoded packet
 | 
				
			||||||
func CompileFilter(filter string) (*ber.Packet, error) {
 | 
					func CompileFilter(filter string) (*ber.Packet, error) {
 | 
				
			||||||
	if len(filter) == 0 || filter[0] != '(' {
 | 
						if len(filter) == 0 || filter[0] != '(' {
 | 
				
			||||||
		return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('"))
 | 
							return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('"))
 | 
				
			||||||
@@ -75,12 +82,16 @@ func CompileFilter(filter string) (*ber.Packet, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if pos != len(filter) {
 | 
						switch {
 | 
				
			||||||
 | 
						case pos > len(filter):
 | 
				
			||||||
 | 
							return nil, NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter"))
 | 
				
			||||||
 | 
						case pos < len(filter):
 | 
				
			||||||
		return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:])))
 | 
							return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:])))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return packet, nil
 | 
						return packet, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DecompileFilter converts a packet representation of a filter into a string representation
 | 
				
			||||||
func DecompileFilter(packet *ber.Packet) (ret string, err error) {
 | 
					func DecompileFilter(packet *ber.Packet) (ret string, err error) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -239,11 +250,13 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
		packet.AppendChild(child)
 | 
							packet.AppendChild(child)
 | 
				
			||||||
		return packet, newPos, err
 | 
							return packet, newPos, err
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		READING_ATTR := 0
 | 
							const (
 | 
				
			||||||
		READING_EXTENSIBLE_MATCHING_RULE := 1
 | 
								stateReadingAttr                   = 0
 | 
				
			||||||
		READING_CONDITION := 2
 | 
								stateReadingExtensibleMatchingRule = 1
 | 
				
			||||||
 | 
								stateReadingCondition              = 2
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		state := READING_ATTR
 | 
							state := stateReadingAttr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		attribute := ""
 | 
							attribute := ""
 | 
				
			||||||
		extensibleDNAttributes := false
 | 
							extensibleDNAttributes := false
 | 
				
			||||||
@@ -261,56 +274,56 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			switch state {
 | 
								switch state {
 | 
				
			||||||
			case READING_ATTR:
 | 
								case stateReadingAttr:
 | 
				
			||||||
				switch {
 | 
									switch {
 | 
				
			||||||
				// Extensible rule, with only DN-matching
 | 
									// Extensible rule, with only DN-matching
 | 
				
			||||||
				case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:="):
 | 
									case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:="):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
				
			||||||
					extensibleDNAttributes = true
 | 
										extensibleDNAttributes = true
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 5
 | 
										newPos += 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Extensible rule, with DN-matching and a matching OID
 | 
									// Extensible rule, with DN-matching and a matching OID
 | 
				
			||||||
				case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:"):
 | 
									case currentRune == ':' && strings.HasPrefix(remainingFilter, ":dn:"):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
				
			||||||
					extensibleDNAttributes = true
 | 
										extensibleDNAttributes = true
 | 
				
			||||||
					state = READING_EXTENSIBLE_MATCHING_RULE
 | 
										state = stateReadingExtensibleMatchingRule
 | 
				
			||||||
					newPos += 4
 | 
										newPos += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Extensible rule, with attr only
 | 
									// Extensible rule, with attr only
 | 
				
			||||||
				case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
 | 
									case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 2
 | 
										newPos += 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Extensible rule, with no DN attribute matching
 | 
									// Extensible rule, with no DN attribute matching
 | 
				
			||||||
				case currentRune == ':':
 | 
									case currentRune == ':':
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterExtensibleMatch, nil, FilterMap[FilterExtensibleMatch])
 | 
				
			||||||
					state = READING_EXTENSIBLE_MATCHING_RULE
 | 
										state = stateReadingExtensibleMatchingRule
 | 
				
			||||||
					newPos += 1
 | 
										newPos++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Equality condition
 | 
									// Equality condition
 | 
				
			||||||
				case currentRune == '=':
 | 
									case currentRune == '=':
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch])
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 1
 | 
										newPos++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Greater-than or equal
 | 
									// Greater-than or equal
 | 
				
			||||||
				case currentRune == '>' && strings.HasPrefix(remainingFilter, ">="):
 | 
									case currentRune == '>' && strings.HasPrefix(remainingFilter, ">="):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual])
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 2
 | 
										newPos += 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Less-than or equal
 | 
									// Less-than or equal
 | 
				
			||||||
				case currentRune == '<' && strings.HasPrefix(remainingFilter, "<="):
 | 
									case currentRune == '<' && strings.HasPrefix(remainingFilter, "<="):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual])
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 2
 | 
										newPos += 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Approx
 | 
									// Approx
 | 
				
			||||||
				case currentRune == '~' && strings.HasPrefix(remainingFilter, "~="):
 | 
									case currentRune == '~' && strings.HasPrefix(remainingFilter, "~="):
 | 
				
			||||||
					packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterApproxMatch])
 | 
										packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterApproxMatch])
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 2
 | 
										newPos += 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Still reading the attribute name
 | 
									// Still reading the attribute name
 | 
				
			||||||
@@ -319,12 +332,12 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
					newPos += currentWidth
 | 
										newPos += currentWidth
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case READING_EXTENSIBLE_MATCHING_RULE:
 | 
								case stateReadingExtensibleMatchingRule:
 | 
				
			||||||
				switch {
 | 
									switch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Matching rule OID is done
 | 
									// Matching rule OID is done
 | 
				
			||||||
				case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
 | 
									case currentRune == ':' && strings.HasPrefix(remainingFilter, ":="):
 | 
				
			||||||
					state = READING_CONDITION
 | 
										state = stateReadingCondition
 | 
				
			||||||
					newPos += 2
 | 
										newPos += 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Still reading the matching rule oid
 | 
									// Still reading the matching rule oid
 | 
				
			||||||
@@ -333,7 +346,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
					newPos += currentWidth
 | 
										newPos += currentWidth
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case READING_CONDITION:
 | 
								case stateReadingCondition:
 | 
				
			||||||
				// append to the condition
 | 
									// append to the condition
 | 
				
			||||||
				condition += fmt.Sprintf("%c", currentRune)
 | 
									condition += fmt.Sprintf("%c", currentRune)
 | 
				
			||||||
				newPos += currentWidth
 | 
									newPos += currentWidth
 | 
				
			||||||
@@ -369,9 +382,9 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Add the value (only required child)
 | 
								// Add the value (only required child)
 | 
				
			||||||
			encodedString, err := escapedStringToEncodedBytes(condition)
 | 
								encodedString, encodeErr := escapedStringToEncodedBytes(condition)
 | 
				
			||||||
			if err != nil {
 | 
								if encodeErr != nil {
 | 
				
			||||||
				return packet, newPos, err
 | 
									return packet, newPos, encodeErr
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchValue, encodedString, MatchingRuleAssertionMap[MatchingRuleAssertionMatchValue]))
 | 
								packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchValue, encodedString, MatchingRuleAssertionMap[MatchingRuleAssertionMatchValue]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -401,17 +414,17 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
 | 
				
			|||||||
				default:
 | 
									default:
 | 
				
			||||||
					tag = FilterSubstringsAny
 | 
										tag = FilterSubstringsAny
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				encodedString, err := escapedStringToEncodedBytes(part)
 | 
									encodedString, encodeErr := escapedStringToEncodedBytes(part)
 | 
				
			||||||
				if err != nil {
 | 
									if encodeErr != nil {
 | 
				
			||||||
					return packet, newPos, err
 | 
										return packet, newPos, encodeErr
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, tag, encodedString, FilterSubstringsMap[uint64(tag)]))
 | 
									seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, tag, encodedString, FilterSubstringsMap[uint64(tag)]))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			packet.AppendChild(seq)
 | 
								packet.AppendChild(seq)
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			encodedString, err := escapedStringToEncodedBytes(condition)
 | 
								encodedString, encodeErr := escapedStringToEncodedBytes(condition)
 | 
				
			||||||
			if err != nil {
 | 
								if encodeErr != nil {
 | 
				
			||||||
				return packet, newPos, err
 | 
									return packet, newPos, encodeErr
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))
 | 
								packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))
 | 
				
			||||||
			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, encodedString, "Condition"))
 | 
								packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, encodedString, "Condition"))
 | 
				
			||||||
@@ -440,12 +453,12 @@ func escapedStringToEncodedBytes(escapedString string) (string, error) {
 | 
				
			|||||||
			if i+2 > len(escapedString) {
 | 
								if i+2 > len(escapedString) {
 | 
				
			||||||
				return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter"))
 | 
									return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter"))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if escByte, decodeErr := hexpac.DecodeString(escapedString[i+1 : i+3]); decodeErr != nil {
 | 
								escByte, decodeErr := hexpac.DecodeString(escapedString[i+1 : i+3])
 | 
				
			||||||
 | 
								if decodeErr != nil {
 | 
				
			||||||
				return "", NewError(ErrorFilterCompile, errors.New("ldap: invalid characters for escape in filter"))
 | 
									return "", NewError(ErrorFilterCompile, errors.New("ldap: invalid characters for escape in filter"))
 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				buffer.WriteByte(escByte[0])
 | 
					 | 
				
			||||||
				i += 2 // +1 from end of loop, so 3 total for \xx.
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteByte(escByte[0])
 | 
				
			||||||
 | 
								i += 2 // +1 from end of loop, so 3 total for \xx.
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			buffer.WriteRune(currentRune)
 | 
								buffer.WriteRune(currentRune)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								vendor/gopkg.in/ldap.v2/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/gopkg.in/ldap.v2/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,7 +9,7 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ber "gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LDAP Application Codes
 | 
					// LDAP Application Codes
 | 
				
			||||||
@@ -36,6 +36,7 @@ const (
 | 
				
			|||||||
	ApplicationExtendedResponse      = 24
 | 
						ApplicationExtendedResponse      = 24
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ApplicationMap contains human readable descriptions of LDAP Application Codes
 | 
				
			||||||
var ApplicationMap = map[uint8]string{
 | 
					var ApplicationMap = map[uint8]string{
 | 
				
			||||||
	ApplicationBindRequest:           "Bind Request",
 | 
						ApplicationBindRequest:           "Bind Request",
 | 
				
			||||||
	ApplicationBindResponse:          "Bind Response",
 | 
						ApplicationBindResponse:          "Bind Response",
 | 
				
			||||||
@@ -72,6 +73,7 @@ const (
 | 
				
			|||||||
	BeheraPasswordInHistory           = 8
 | 
						BeheraPasswordInHistory           = 8
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BeheraPasswordPolicyErrorMap contains human readable descriptions of Behera Password Policy error codes
 | 
				
			||||||
var BeheraPasswordPolicyErrorMap = map[int8]string{
 | 
					var BeheraPasswordPolicyErrorMap = map[int8]string{
 | 
				
			||||||
	BeheraPasswordExpired:             "Password expired",
 | 
						BeheraPasswordExpired:             "Password expired",
 | 
				
			||||||
	BeheraAccountLocked:               "Account locked",
 | 
						BeheraAccountLocked:               "Account locked",
 | 
				
			||||||
@@ -151,16 +153,47 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
 | 
				
			|||||||
func addControlDescriptions(packet *ber.Packet) {
 | 
					func addControlDescriptions(packet *ber.Packet) {
 | 
				
			||||||
	packet.Description = "Controls"
 | 
						packet.Description = "Controls"
 | 
				
			||||||
	for _, child := range packet.Children {
 | 
						for _, child := range packet.Children {
 | 
				
			||||||
 | 
							var value *ber.Packet
 | 
				
			||||||
 | 
							controlType := ""
 | 
				
			||||||
		child.Description = "Control"
 | 
							child.Description = "Control"
 | 
				
			||||||
		child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")"
 | 
							switch len(child.Children) {
 | 
				
			||||||
		value := child.Children[1]
 | 
							case 0:
 | 
				
			||||||
		if len(child.Children) == 3 {
 | 
								// at least one child is required for control type
 | 
				
			||||||
			child.Children[1].Description = "Criticality"
 | 
								continue
 | 
				
			||||||
			value = child.Children[2]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		value.Description = "Control Value"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch child.Children[0].Value.(string) {
 | 
							case 1:
 | 
				
			||||||
 | 
								// just type, no criticality or value
 | 
				
			||||||
 | 
								controlType = child.Children[0].Value.(string)
 | 
				
			||||||
 | 
								child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 2:
 | 
				
			||||||
 | 
								controlType = child.Children[0].Value.(string)
 | 
				
			||||||
 | 
								child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
 | 
				
			||||||
 | 
								// Children[1] could be criticality or value (both are optional)
 | 
				
			||||||
 | 
								// duck-type on whether this is a boolean
 | 
				
			||||||
 | 
								if _, ok := child.Children[1].Value.(bool); ok {
 | 
				
			||||||
 | 
									child.Children[1].Description = "Criticality"
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									child.Children[1].Description = "Control Value"
 | 
				
			||||||
 | 
									value = child.Children[1]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 3:
 | 
				
			||||||
 | 
								// criticality and value present
 | 
				
			||||||
 | 
								controlType = child.Children[0].Value.(string)
 | 
				
			||||||
 | 
								child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")"
 | 
				
			||||||
 | 
								child.Children[1].Description = "Criticality"
 | 
				
			||||||
 | 
								child.Children[2].Description = "Control Value"
 | 
				
			||||||
 | 
								value = child.Children[2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								// more than 3 children is invalid
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if value == nil {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch controlType {
 | 
				
			||||||
		case ControlTypePaging:
 | 
							case ControlTypePaging:
 | 
				
			||||||
			value.Description += " (Paging)"
 | 
								value.Description += " (Paging)"
 | 
				
			||||||
			if value.Value != nil {
 | 
								if value.Value != nil {
 | 
				
			||||||
@@ -186,18 +219,18 @@ func addControlDescriptions(packet *ber.Packet) {
 | 
				
			|||||||
			for _, child := range sequence.Children {
 | 
								for _, child := range sequence.Children {
 | 
				
			||||||
				if child.Tag == 0 {
 | 
									if child.Tag == 0 {
 | 
				
			||||||
					//Warning
 | 
										//Warning
 | 
				
			||||||
					child := child.Children[0]
 | 
										warningPacket := child.Children[0]
 | 
				
			||||||
					packet := ber.DecodePacket(child.Data.Bytes())
 | 
										packet := ber.DecodePacket(warningPacket.Data.Bytes())
 | 
				
			||||||
					val, ok := packet.Value.(int64)
 | 
										val, ok := packet.Value.(int64)
 | 
				
			||||||
					if ok {
 | 
										if ok {
 | 
				
			||||||
						if child.Tag == 0 {
 | 
											if warningPacket.Tag == 0 {
 | 
				
			||||||
							//timeBeforeExpiration
 | 
												//timeBeforeExpiration
 | 
				
			||||||
							value.Description += " (TimeBeforeExpiration)"
 | 
												value.Description += " (TimeBeforeExpiration)"
 | 
				
			||||||
							child.Value = val
 | 
												warningPacket.Value = val
 | 
				
			||||||
						} else if child.Tag == 1 {
 | 
											} else if warningPacket.Tag == 1 {
 | 
				
			||||||
							//graceAuthNsRemaining
 | 
												//graceAuthNsRemaining
 | 
				
			||||||
							value.Description += " (GraceAuthNsRemaining)"
 | 
												value.Description += " (GraceAuthNsRemaining)"
 | 
				
			||||||
							child.Value = val
 | 
												warningPacket.Value = val
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if child.Tag == 1 {
 | 
									} else if child.Tag == 1 {
 | 
				
			||||||
@@ -237,6 +270,7 @@ func addDefaultLDAPResponseDescriptions(packet *ber.Packet) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DebugBinaryFile reads and prints packets from the given filename
 | 
				
			||||||
func DebugBinaryFile(fileName string) error {
 | 
					func DebugBinaryFile(fileName string) error {
 | 
				
			||||||
	file, err := ioutil.ReadFile(fileName)
 | 
						file, err := ioutil.ReadFile(fileName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										66
									
								
								vendor/gopkg.in/ldap.v2/modify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										66
									
								
								vendor/gopkg.in/ldap.v2/modify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -36,64 +36,76 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Change operation choices
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	AddAttribute     = 0
 | 
						AddAttribute     = 0
 | 
				
			||||||
	DeleteAttribute  = 1
 | 
						DeleteAttribute  = 1
 | 
				
			||||||
	ReplaceAttribute = 2
 | 
						ReplaceAttribute = 2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
 | 
				
			||||||
type PartialAttribute struct {
 | 
					type PartialAttribute struct {
 | 
				
			||||||
	attrType string
 | 
						// Type is the type of the partial attribute
 | 
				
			||||||
	attrVals []string
 | 
						Type string
 | 
				
			||||||
 | 
						// Vals are the values of the partial attribute
 | 
				
			||||||
 | 
						Vals []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *PartialAttribute) encode() *ber.Packet {
 | 
					func (p *PartialAttribute) encode() *ber.Packet {
 | 
				
			||||||
	seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute")
 | 
						seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute")
 | 
				
			||||||
	seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.attrType, "Type"))
 | 
						seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.Type, "Type"))
 | 
				
			||||||
	set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
 | 
						set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
 | 
				
			||||||
	for _, value := range p.attrVals {
 | 
						for _, value := range p.Vals {
 | 
				
			||||||
		set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
 | 
							set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	seq.AppendChild(set)
 | 
						seq.AppendChild(set)
 | 
				
			||||||
	return seq
 | 
						return seq
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
 | 
				
			||||||
type ModifyRequest struct {
 | 
					type ModifyRequest struct {
 | 
				
			||||||
	dn                string
 | 
						// DN is the distinguishedName of the directory entry to modify
 | 
				
			||||||
	addAttributes     []PartialAttribute
 | 
						DN string
 | 
				
			||||||
	deleteAttributes  []PartialAttribute
 | 
						// AddAttributes contain the attributes to add
 | 
				
			||||||
	replaceAttributes []PartialAttribute
 | 
						AddAttributes []PartialAttribute
 | 
				
			||||||
 | 
						// DeleteAttributes contain the attributes to delete
 | 
				
			||||||
 | 
						DeleteAttributes []PartialAttribute
 | 
				
			||||||
 | 
						// ReplaceAttributes contain the attributes to replace
 | 
				
			||||||
 | 
						ReplaceAttributes []PartialAttribute
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add inserts the given attribute to the list of attributes to add
 | 
				
			||||||
func (m *ModifyRequest) Add(attrType string, attrVals []string) {
 | 
					func (m *ModifyRequest) Add(attrType string, attrVals []string) {
 | 
				
			||||||
	m.addAttributes = append(m.addAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
 | 
						m.AddAttributes = append(m.AddAttributes, PartialAttribute{Type: attrType, Vals: attrVals})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete inserts the given attribute to the list of attributes to delete
 | 
				
			||||||
func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
 | 
					func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
 | 
				
			||||||
	m.deleteAttributes = append(m.deleteAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
 | 
						m.DeleteAttributes = append(m.DeleteAttributes, PartialAttribute{Type: attrType, Vals: attrVals})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Replace inserts the given attribute to the list of attributes to replace
 | 
				
			||||||
func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
 | 
					func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
 | 
				
			||||||
	m.replaceAttributes = append(m.replaceAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
 | 
						m.ReplaceAttributes = append(m.ReplaceAttributes, 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 _, attribute := range m.AddAttributes {
 | 
				
			||||||
		change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
 | 
							change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
 | 
				
			||||||
		change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
 | 
							change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
 | 
				
			||||||
		change.AppendChild(attribute.encode())
 | 
							change.AppendChild(attribute.encode())
 | 
				
			||||||
		changes.AppendChild(change)
 | 
							changes.AppendChild(change)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, attribute := range m.deleteAttributes {
 | 
						for _, attribute := range m.DeleteAttributes {
 | 
				
			||||||
		change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
 | 
							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(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation"))
 | 
				
			||||||
		change.AppendChild(attribute.encode())
 | 
							change.AppendChild(attribute.encode())
 | 
				
			||||||
		changes.AppendChild(change)
 | 
							changes.AppendChild(change)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, attribute := range m.replaceAttributes {
 | 
						for _, attribute := range m.ReplaceAttributes {
 | 
				
			||||||
		change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
 | 
							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(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation"))
 | 
				
			||||||
		change.AppendChild(attribute.encode())
 | 
							change.AppendChild(attribute.encode())
 | 
				
			||||||
@@ -103,38 +115,36 @@ func (m ModifyRequest) encode() *ber.Packet {
 | 
				
			|||||||
	return request
 | 
						return request
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewModifyRequest creates a modify request for the given DN
 | 
				
			||||||
func NewModifyRequest(
 | 
					func NewModifyRequest(
 | 
				
			||||||
	dn string,
 | 
						dn string,
 | 
				
			||||||
) *ModifyRequest {
 | 
					) *ModifyRequest {
 | 
				
			||||||
	return &ModifyRequest{
 | 
						return &ModifyRequest{
 | 
				
			||||||
		dn: dn,
 | 
							DN: dn,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Modify performs the ModifyRequest
 | 
				
			||||||
func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
 | 
					func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	packet.AppendChild(modifyRequest.encode())
 | 
						packet.AppendChild(modifyRequest.encode())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -155,6 +165,6 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
 | 
				
			|||||||
		log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
							log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: returning", messageID)
 | 
						l.Debug.Printf("%d: returning", msgCtx.id)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										42
									
								
								vendor/gopkg.in/ldap.v2/passwdmodify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/gopkg.in/ldap.v2/passwdmodify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,13 +16,21 @@ const (
 | 
				
			|||||||
	passwordModifyOID = "1.3.6.1.4.1.4203.1.11.1"
 | 
						passwordModifyOID = "1.3.6.1.4.1.4203.1.11.1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PasswordModifyRequest implements the Password Modify Extended Operation as defined in https://www.ietf.org/rfc/rfc3062.txt
 | 
				
			||||||
type PasswordModifyRequest struct {
 | 
					type PasswordModifyRequest struct {
 | 
				
			||||||
 | 
						// UserIdentity is an optional string representation of the user associated with the request.
 | 
				
			||||||
 | 
						// This string may or may not be an LDAPDN [RFC2253].
 | 
				
			||||||
 | 
						// If no UserIdentity field is present, the request acts up upon the password of the user currently associated with the LDAP session
 | 
				
			||||||
	UserIdentity string
 | 
						UserIdentity string
 | 
				
			||||||
	OldPassword  string
 | 
						// OldPassword, if present, contains the user's current password
 | 
				
			||||||
	NewPassword  string
 | 
						OldPassword string
 | 
				
			||||||
 | 
						// NewPassword, if present, contains the desired password for this user
 | 
				
			||||||
 | 
						NewPassword string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PasswordModifyResult holds the server response to a PasswordModifyRequest
 | 
				
			||||||
type PasswordModifyResult struct {
 | 
					type PasswordModifyResult struct {
 | 
				
			||||||
 | 
						// GeneratedPassword holds a password generated by the server, if present
 | 
				
			||||||
	GeneratedPassword string
 | 
						GeneratedPassword string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -47,7 +55,7 @@ func (r *PasswordModifyRequest) encode() (*ber.Packet, error) {
 | 
				
			|||||||
	return request, nil
 | 
						return request, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create a new PasswordModifyRequest
 | 
					// NewPasswordModifyRequest creates a new PasswordModifyRequest
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// According to the RFC 3602:
 | 
					// According to the RFC 3602:
 | 
				
			||||||
// userIdentity is a string representing the user associated with the request.
 | 
					// userIdentity is a string representing the user associated with the request.
 | 
				
			||||||
@@ -72,11 +80,10 @@ func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPasswo
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PasswordModify performs the modification request
 | 
				
			||||||
func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) {
 | 
					func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	encodedPasswordModifyRequest, err := passwordModifyRequest.encode()
 | 
						encodedPasswordModifyRequest, err := passwordModifyRequest.encode()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -86,24 +93,21 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result := &PasswordModifyResult{}
 | 
						result := &PasswordModifyResult{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l.Debug.Printf("%d: waiting for response", messageID)
 | 
						l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
	packetResponse, ok := <-channel
 | 
						packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
							return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	packet, err = packetResponse.ReadPacket()
 | 
						packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
	l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
						l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -131,10 +135,10 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa
 | 
				
			|||||||
	extendedResponse := packet.Children[1]
 | 
						extendedResponse := packet.Children[1]
 | 
				
			||||||
	for _, child := range extendedResponse.Children {
 | 
						for _, child := range extendedResponse.Children {
 | 
				
			||||||
		if child.Tag == 11 {
 | 
							if child.Tag == 11 {
 | 
				
			||||||
			passwordModifyReponseValue := ber.DecodePacket(child.Data.Bytes())
 | 
								passwordModifyResponseValue := ber.DecodePacket(child.Data.Bytes())
 | 
				
			||||||
			if len(passwordModifyReponseValue.Children) == 1 {
 | 
								if len(passwordModifyResponseValue.Children) == 1 {
 | 
				
			||||||
				if passwordModifyReponseValue.Children[0].Tag == 0 {
 | 
									if passwordModifyResponseValue.Children[0].Tag == 0 {
 | 
				
			||||||
					result.GeneratedPassword = ber.DecodeString(passwordModifyReponseValue.Children[0].Data.Bytes())
 | 
										result.GeneratedPassword = ber.DecodeString(passwordModifyResponseValue.Children[0].Data.Bytes())
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								vendor/gopkg.in/ldap.v2/search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/gopkg.in/ldap.v2/search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -68,18 +68,21 @@ import (
 | 
				
			|||||||
	"gopkg.in/asn1-ber.v1"
 | 
						"gopkg.in/asn1-ber.v1"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// scope choices
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	ScopeBaseObject   = 0
 | 
						ScopeBaseObject   = 0
 | 
				
			||||||
	ScopeSingleLevel  = 1
 | 
						ScopeSingleLevel  = 1
 | 
				
			||||||
	ScopeWholeSubtree = 2
 | 
						ScopeWholeSubtree = 2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ScopeMap contains human readable descriptions of scope choices
 | 
				
			||||||
var ScopeMap = map[int]string{
 | 
					var ScopeMap = map[int]string{
 | 
				
			||||||
	ScopeBaseObject:   "Base Object",
 | 
						ScopeBaseObject:   "Base Object",
 | 
				
			||||||
	ScopeSingleLevel:  "Single Level",
 | 
						ScopeSingleLevel:  "Single Level",
 | 
				
			||||||
	ScopeWholeSubtree: "Whole Subtree",
 | 
						ScopeWholeSubtree: "Whole Subtree",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// derefAliases
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	NeverDerefAliases   = 0
 | 
						NeverDerefAliases   = 0
 | 
				
			||||||
	DerefInSearching    = 1
 | 
						DerefInSearching    = 1
 | 
				
			||||||
@@ -87,6 +90,7 @@ const (
 | 
				
			|||||||
	DerefAlways         = 3
 | 
						DerefAlways         = 3
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DerefMap contains human readable descriptions of derefAliases choices
 | 
				
			||||||
var DerefMap = map[int]string{
 | 
					var DerefMap = map[int]string{
 | 
				
			||||||
	NeverDerefAliases:   "NeverDerefAliases",
 | 
						NeverDerefAliases:   "NeverDerefAliases",
 | 
				
			||||||
	DerefInSearching:    "DerefInSearching",
 | 
						DerefInSearching:    "DerefInSearching",
 | 
				
			||||||
@@ -114,11 +118,15 @@ func NewEntry(dn string, attributes map[string][]string) *Entry {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Entry represents a single search result entry
 | 
				
			||||||
type Entry struct {
 | 
					type Entry struct {
 | 
				
			||||||
	DN         string
 | 
						// DN is the distinguished name of the entry
 | 
				
			||||||
 | 
						DN string
 | 
				
			||||||
 | 
						// Attributes are the returned attributes for the entry
 | 
				
			||||||
	Attributes []*EntryAttribute
 | 
						Attributes []*EntryAttribute
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAttributeValues returns the values for the named attribute, or an empty list
 | 
				
			||||||
func (e *Entry) GetAttributeValues(attribute string) []string {
 | 
					func (e *Entry) GetAttributeValues(attribute string) []string {
 | 
				
			||||||
	for _, attr := range e.Attributes {
 | 
						for _, attr := range e.Attributes {
 | 
				
			||||||
		if attr.Name == attribute {
 | 
							if attr.Name == attribute {
 | 
				
			||||||
@@ -128,6 +136,7 @@ func (e *Entry) GetAttributeValues(attribute string) []string {
 | 
				
			|||||||
	return []string{}
 | 
						return []string{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetRawAttributeValues returns the byte values for the named attribute, or an empty list
 | 
				
			||||||
func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
 | 
					func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
 | 
				
			||||||
	for _, attr := range e.Attributes {
 | 
						for _, attr := range e.Attributes {
 | 
				
			||||||
		if attr.Name == attribute {
 | 
							if attr.Name == attribute {
 | 
				
			||||||
@@ -137,6 +146,7 @@ func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
 | 
				
			|||||||
	return [][]byte{}
 | 
						return [][]byte{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAttributeValue returns the first value for the named attribute, or ""
 | 
				
			||||||
func (e *Entry) GetAttributeValue(attribute string) string {
 | 
					func (e *Entry) GetAttributeValue(attribute string) string {
 | 
				
			||||||
	values := e.GetAttributeValues(attribute)
 | 
						values := e.GetAttributeValues(attribute)
 | 
				
			||||||
	if len(values) == 0 {
 | 
						if len(values) == 0 {
 | 
				
			||||||
@@ -145,6 +155,7 @@ func (e *Entry) GetAttributeValue(attribute string) string {
 | 
				
			|||||||
	return values[0]
 | 
						return values[0]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetRawAttributeValue returns the first value for the named attribute, or an empty slice
 | 
				
			||||||
func (e *Entry) GetRawAttributeValue(attribute string) []byte {
 | 
					func (e *Entry) GetRawAttributeValue(attribute string) []byte {
 | 
				
			||||||
	values := e.GetRawAttributeValues(attribute)
 | 
						values := e.GetRawAttributeValues(attribute)
 | 
				
			||||||
	if len(values) == 0 {
 | 
						if len(values) == 0 {
 | 
				
			||||||
@@ -153,6 +164,7 @@ func (e *Entry) GetRawAttributeValue(attribute string) []byte {
 | 
				
			|||||||
	return values[0]
 | 
						return values[0]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print outputs a human-readable description
 | 
				
			||||||
func (e *Entry) Print() {
 | 
					func (e *Entry) Print() {
 | 
				
			||||||
	fmt.Printf("DN: %s\n", e.DN)
 | 
						fmt.Printf("DN: %s\n", e.DN)
 | 
				
			||||||
	for _, attr := range e.Attributes {
 | 
						for _, attr := range e.Attributes {
 | 
				
			||||||
@@ -160,6 +172,7 @@ func (e *Entry) Print() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrettyPrint outputs a human-readable description indenting
 | 
				
			||||||
func (e *Entry) PrettyPrint(indent int) {
 | 
					func (e *Entry) PrettyPrint(indent int) {
 | 
				
			||||||
	fmt.Printf("%sDN: %s\n", strings.Repeat(" ", indent), e.DN)
 | 
						fmt.Printf("%sDN: %s\n", strings.Repeat(" ", indent), e.DN)
 | 
				
			||||||
	for _, attr := range e.Attributes {
 | 
						for _, attr := range e.Attributes {
 | 
				
			||||||
@@ -180,38 +193,51 @@ func NewEntryAttribute(name string, values []string) *EntryAttribute {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EntryAttribute holds a single attribute
 | 
				
			||||||
type EntryAttribute struct {
 | 
					type EntryAttribute struct {
 | 
				
			||||||
	Name       string
 | 
						// Name is the name of the attribute
 | 
				
			||||||
	Values     []string
 | 
						Name string
 | 
				
			||||||
 | 
						// Values contain the string values of the attribute
 | 
				
			||||||
 | 
						Values []string
 | 
				
			||||||
 | 
						// ByteValues contain the raw values of the attribute
 | 
				
			||||||
	ByteValues [][]byte
 | 
						ByteValues [][]byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print outputs a human-readable description
 | 
				
			||||||
func (e *EntryAttribute) Print() {
 | 
					func (e *EntryAttribute) Print() {
 | 
				
			||||||
	fmt.Printf("%s: %s\n", e.Name, e.Values)
 | 
						fmt.Printf("%s: %s\n", e.Name, e.Values)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrettyPrint outputs a human-readable description with indenting
 | 
				
			||||||
func (e *EntryAttribute) PrettyPrint(indent int) {
 | 
					func (e *EntryAttribute) PrettyPrint(indent int) {
 | 
				
			||||||
	fmt.Printf("%s%s: %s\n", strings.Repeat(" ", indent), e.Name, e.Values)
 | 
						fmt.Printf("%s%s: %s\n", strings.Repeat(" ", indent), e.Name, e.Values)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SearchResult holds the server's response to a search request
 | 
				
			||||||
type SearchResult struct {
 | 
					type SearchResult struct {
 | 
				
			||||||
	Entries   []*Entry
 | 
						// Entries are the returned entries
 | 
				
			||||||
 | 
						Entries []*Entry
 | 
				
			||||||
 | 
						// Referrals are the returned referrals
 | 
				
			||||||
	Referrals []string
 | 
						Referrals []string
 | 
				
			||||||
	Controls  []Control
 | 
						// Controls are the returned controls
 | 
				
			||||||
 | 
						Controls []Control
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print outputs a human-readable description
 | 
				
			||||||
func (s *SearchResult) Print() {
 | 
					func (s *SearchResult) Print() {
 | 
				
			||||||
	for _, entry := range s.Entries {
 | 
						for _, entry := range s.Entries {
 | 
				
			||||||
		entry.Print()
 | 
							entry.Print()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrettyPrint outputs a human-readable description with indenting
 | 
				
			||||||
func (s *SearchResult) PrettyPrint(indent int) {
 | 
					func (s *SearchResult) PrettyPrint(indent int) {
 | 
				
			||||||
	for _, entry := range s.Entries {
 | 
						for _, entry := range s.Entries {
 | 
				
			||||||
		entry.PrettyPrint(indent)
 | 
							entry.PrettyPrint(indent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SearchRequest represents a search request to send to the server
 | 
				
			||||||
type SearchRequest struct {
 | 
					type SearchRequest struct {
 | 
				
			||||||
	BaseDN       string
 | 
						BaseDN       string
 | 
				
			||||||
	Scope        int
 | 
						Scope        int
 | 
				
			||||||
@@ -247,6 +273,7 @@ func (s *SearchRequest) encode() (*ber.Packet, error) {
 | 
				
			|||||||
	return request, nil
 | 
						return request, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewSearchRequest creates a new search request
 | 
				
			||||||
func NewSearchRequest(
 | 
					func NewSearchRequest(
 | 
				
			||||||
	BaseDN string,
 | 
						BaseDN string,
 | 
				
			||||||
	Scope, DerefAliases, SizeLimit, TimeLimit int,
 | 
						Scope, DerefAliases, SizeLimit, TimeLimit int,
 | 
				
			||||||
@@ -341,10 +368,10 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32)
 | 
				
			|||||||
	return searchResult, nil
 | 
						return searchResult, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Search performs the given search request
 | 
				
			||||||
func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
 | 
					func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
 | 
				
			||||||
	messageID := l.nextMessageID()
 | 
					 | 
				
			||||||
	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, messageID, "MessageID"))
 | 
						packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
 | 
				
			||||||
	// encode search request
 | 
						// encode search request
 | 
				
			||||||
	encodedSearchRequest, err := searchRequest.encode()
 | 
						encodedSearchRequest, err := searchRequest.encode()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -358,14 +385,11 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	l.Debug.PrintPacket(packet)
 | 
						l.Debug.PrintPacket(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel, err := l.sendMessage(packet)
 | 
						msgCtx, err := l.sendMessage(packet)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel == nil {
 | 
						defer l.finishMessage(msgCtx)
 | 
				
			||||||
		return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer l.finishMessage(messageID)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result := &SearchResult{
 | 
						result := &SearchResult{
 | 
				
			||||||
		Entries:   make([]*Entry, 0),
 | 
							Entries:   make([]*Entry, 0),
 | 
				
			||||||
@@ -374,13 +398,13 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	foundSearchResultDone := false
 | 
						foundSearchResultDone := false
 | 
				
			||||||
	for !foundSearchResultDone {
 | 
						for !foundSearchResultDone {
 | 
				
			||||||
		l.Debug.Printf("%d: waiting for response", messageID)
 | 
							l.Debug.Printf("%d: waiting for response", msgCtx.id)
 | 
				
			||||||
		packetResponse, ok := <-channel
 | 
							packetResponse, ok := <-msgCtx.responses
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			return nil, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
 | 
								return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		packet, err = packetResponse.ReadPacket()
 | 
							packet, err = packetResponse.ReadPacket()
 | 
				
			||||||
		l.Debug.Printf("%d: got response %p", messageID, packet)
 | 
							l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -421,6 +445,6 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
 | 
				
			|||||||
			result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string))
 | 
								result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l.Debug.Printf("%d: returning", messageID)
 | 
						l.Debug.Printf("%d: returning", msgCtx.id)
 | 
				
			||||||
	return result, nil
 | 
						return result, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user