summaryrefslogtreecommitdiffstats
path: root/modify.go
diff options
context:
space:
mode:
authortmfkams <tmfkams@gmail.com>2014-01-19 23:04:16 +0100
committerSamuel Stauffer <samuel@descolada.com>2014-03-19 21:57:58 +0100
commite45f83457931e08f9f6d5aec48f51fd390a01eb8 (patch)
treed95a79f94932115bf5c0441f2eeb520959bbda0d /modify.go
parentMerge pull request #4 from bollenberger/master (diff)
downloadldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.gz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.bz2
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.lz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.xz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.zst
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.zip
Diffstat (limited to 'modify.go')
-rw-r--r--modify.go154
1 files changed, 154 insertions, 0 deletions
diff --git a/modify.go b/modify.go
new file mode 100644
index 0000000..ad49f94
--- /dev/null
+++ b/modify.go
@@ -0,0 +1,154 @@
+// Copyright 2014 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.
+//
+// File contains Modify functionality
+//
+// https://tools.ietf.org/html/rfc4511
+//
+// ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+// object LDAPDN,
+// changes SEQUENCE OF change SEQUENCE {
+// operation ENUMERATED {
+// add (0),
+// delete (1),
+// replace (2),
+// ... },
+// modification PartialAttribute } }
+//
+// PartialAttribute ::= SEQUENCE {
+// type AttributeDescription,
+// vals SET OF value AttributeValue }
+//
+// AttributeDescription ::= LDAPString
+// -- Constrained to <attributedescription>
+// -- [RFC4512]
+//
+// AttributeValue ::= OCTET STRING
+//
+package ldap
+
+import (
+ "errors"
+ "github.com/tmfkams/asn1-ber"
+ "log"
+)
+
+const (
+ AddAttribute = 0
+ DeleteAttribute = 1
+ ReplaceAttribute = 2
+)
+
+type PartialAttribute struct {
+ attrType string
+ attrVals []string
+}
+
+func (p *PartialAttribute) encode() *ber.Packet {
+ seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute")
+ seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, p.attrType, "Type"))
+ set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
+ for _, value := range p.attrVals {
+ set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, value, "Vals"))
+ }
+ seq.AppendChild(set)
+ return seq
+}
+
+type ModifyRequest struct {
+ dn string
+ addAttributes []PartialAttribute
+ deleteAttributes []PartialAttribute
+ replaceAttributes []PartialAttribute
+}
+
+func (m *ModifyRequest) Add(attrType string, attrVals []string) {
+ m.addAttributes = append(m.addAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
+}
+
+func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
+ m.deleteAttributes = append(m.deleteAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
+}
+
+func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
+ m.replaceAttributes = append(m.replaceAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals})
+}
+
+func (m ModifyRequest) encode() *ber.Packet {
+ request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request")
+ request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, m.dn, "DN"))
+ changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes")
+ for _, attribute := range m.addAttributes {
+ change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
+ change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimative, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
+ change.AppendChild(attribute.encode())
+ changes.AppendChild(change)
+ }
+ for _, attribute := range m.deleteAttributes {
+ change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
+ change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimative, ber.TagEnumerated, uint64(DeleteAttribute), "Operation"))
+ change.AppendChild(attribute.encode())
+ changes.AppendChild(change)
+ }
+ for _, attribute := range m.replaceAttributes {
+ change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
+ change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimative, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation"))
+ change.AppendChild(attribute.encode())
+ changes.AppendChild(change)
+ }
+ request.AppendChild(changes)
+ return request
+}
+
+func NewModifyRequest(
+ dn string,
+) *ModifyRequest {
+ return &ModifyRequest{
+ dn: dn,
+ }
+}
+
+func (l *Conn) Modify(modifyRequest *ModifyRequest) *Error {
+ messageID := l.nextMessageID()
+ packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
+ packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimative, ber.TagInteger, messageID, "MessageID"))
+ packet.AppendChild(modifyRequest.encode())
+
+ l.Debug.PrintPacket(packet)
+
+ channel, err := l.sendMessage(packet)
+ if err != nil {
+ return err
+ }
+ if channel == nil {
+ return NewError(ErrorNetwork, errors.New("Could not send message"))
+ }
+ defer l.finishMessage(messageID)
+
+ l.Debug.Printf("%d: waiting for response\n", messageID)
+ packet = <-channel
+ l.Debug.Printf("%d: got response %p\n", messageID, packet)
+ if packet == nil {
+ return NewError(ErrorNetwork, errors.New("Could not retrieve message"))
+ }
+
+ if l.Debug {
+ if err := addLDAPDescriptions(packet); err != nil {
+ return NewError(ErrorDebugging, err.Err)
+ }
+ ber.PrintPacket(packet)
+ }
+
+ if packet.Children[1].Tag == ApplicationModifyResponse {
+ resultCode, resultDescription := getLDAPResultCode(packet)
+ if resultCode != 0 {
+ return NewError(resultCode, errors.New(resultDescription))
+ }
+ } else {
+ log.Printf("Unexpected Response: %d\n", packet.Children[1].Tag)
+ }
+
+ l.Debug.Printf("%d: returning\n", messageID)
+ return nil
+}