summaryrefslogtreecommitdiffstats
path: root/control.go
diff options
context:
space:
mode:
Diffstat (limited to 'control.go')
-rw-r--r--control.go157
1 files changed, 157 insertions, 0 deletions
diff --git a/control.go b/control.go
new file mode 100644
index 0000000..af145b2
--- /dev/null
+++ b/control.go
@@ -0,0 +1,157 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This package provides LDAP client functions.
+package ldap
+
+import (
+ "github.com/mmitton/asn1-ber"
+ "fmt"
+)
+
+const (
+ ControlTypePaging = "1.2.840.113556.1.4.319"
+)
+
+var ControlTypeMap = map[ string ] string {
+ ControlTypePaging : "Paging",
+}
+
+type Control interface {
+ GetControlType() string
+ Encode() *ber.Packet
+ String() string
+}
+
+type ControlString struct {
+ ControlType string
+ Criticality bool
+ ControlValue string
+}
+
+func (c *ControlString) GetControlType() string {
+ return c.ControlType
+}
+
+func (c *ControlString) Encode() (p *ber.Packet) {
+ p = ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control" )
+ p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, c.ControlType, "Control Type (" + ControlTypeMap[ c.ControlType ] + ")" ) )
+ if c.Criticality {
+ p.AppendChild( ber.NewBoolean( ber.ClassUniversal, ber.TypePrimative, ber.TagBoolean, c.Criticality, "Criticality" ) )
+ }
+ p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, c.ControlValue, "Control Value" ) )
+ return
+}
+
+func (c *ControlString) String() string {
+ return fmt.Sprintf( "Control Type: %s (%q) Criticality: %s Control Value: %s", ControlTypeMap[ c.ControlType ], c.ControlType, c.Criticality, c.ControlValue )
+}
+
+type ControlPaging struct {
+ PagingSize uint32
+ Cookie []byte
+}
+
+func (c *ControlPaging) GetControlType() string {
+ return ControlTypePaging
+}
+
+func (c *ControlPaging) Encode() (p *ber.Packet) {
+ p = ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control" )
+ p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, ControlTypePaging, "Control Type (" + ControlTypeMap[ ControlTypePaging ] + ")" ) )
+
+ p2 := ber.Encode( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, nil, "Control Value (Paging)" )
+ seq := ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value" )
+ seq.AppendChild( ber.NewInteger( ber.ClassUniversal, ber.TypePrimative, ber.TagInteger, uint64(c.PagingSize), "Paging Size" ) )
+ cookie := ber.Encode( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, nil, "Cookie" )
+ cookie.Value = c.Cookie
+ cookie.Data.Write( c.Cookie )
+ seq.AppendChild( cookie )
+ p2.AppendChild( seq )
+
+ p.AppendChild( p2 )
+ return
+}
+
+func (c *ControlPaging) String() string {
+ return fmt.Sprintf(
+ "Control Type: %s (%q) Criticality: %s PagingSize: %d Cookie: %q",
+ ControlTypeMap[ ControlTypePaging ],
+ ControlTypePaging,
+ false,
+ c.PagingSize,
+ c.Cookie )
+}
+
+func (c *ControlPaging) SetCookie( Cookie []byte ) {
+ c.Cookie = Cookie
+}
+
+func FindControl( Controls []Control, ControlType string ) Control {
+ for _, c := range Controls {
+ if c.GetControlType() == ControlType {
+ return c
+ }
+ }
+ return nil
+}
+
+func DecodeControl( p *ber.Packet ) Control {
+ ControlType := p.Children[ 0 ].Value.(string)
+ Criticality := false
+
+ p.Children[ 0 ].Description = "Control Type (" + ControlTypeMap[ ControlType ] + ")"
+ value := p.Children[ 1 ]
+ if len( p.Children ) == 3 {
+ value = p.Children[ 2 ]
+ p.Children[ 1 ].Description = "Criticality"
+ Criticality = p.Children[ 1 ].Value.(bool)
+ }
+
+ value.Description = "Control Value"
+ switch ControlType {
+ case ControlTypePaging:
+ value.Description += " (Paging)"
+ c := new( ControlPaging )
+ if value.Value != nil {
+ value_children := ber.DecodePacket( value.Data.Bytes() )
+ value.Data.Truncate( 0 )
+ value.Value = nil
+ value.AppendChild( value_children )
+ }
+ value = value.Children[ 0 ]
+ value.Description = "Search Control Value"
+ value.Children[ 0 ].Description = "Paging Size"
+ value.Children[ 1 ].Description = "Cookie"
+ c.PagingSize = uint32( value.Children[ 0 ].Value.(uint64) )
+ c.Cookie = value.Children[ 1 ].Data.Bytes()
+ value.Children[ 1 ].Value = c.Cookie
+ return c
+ }
+ c := new( ControlString )
+ c.ControlType = ControlType
+ c.Criticality = Criticality
+ c.ControlValue = value.Value.(string)
+ return c
+}
+
+func NewControlString( ControlType string, Criticality bool, ControlValue string ) *ControlString {
+ return &ControlString{
+ ControlType: ControlType,
+ Criticality: Criticality,
+ ControlValue: ControlValue,
+ }
+}
+
+func NewControlPaging( PagingSize uint32 ) *ControlPaging {
+ return &ControlPaging{ PagingSize: PagingSize }
+}
+
+func encodeControls( Controls []Control ) *ber.Packet {
+ p := ber.Encode( ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls" )
+ for _, control := range Controls {
+ p.AppendChild( control.Encode() )
+ }
+ return p
+}