github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/ldap.v2/compare.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 // 5 // File contains Compare functionality 6 // 7 // https://tools.ietf.org/html/rfc4511 8 // 9 // CompareRequest ::= [APPLICATION 14] SEQUENCE { 10 // entry LDAPDN, 11 // ava AttributeValueAssertion } 12 // 13 // AttributeValueAssertion ::= SEQUENCE { 14 // attributeDesc AttributeDescription, 15 // assertionValue AssertionValue } 16 // 17 // AttributeDescription ::= LDAPString 18 // -- Constrained to <attributedescription> 19 // -- [RFC4512] 20 // 21 // AttributeValue ::= OCTET STRING 22 // 23 24 package ldap 25 26 import ( 27 "errors" 28 "fmt" 29 30 "gopkg.in/asn1-ber.v1" 31 ) 32 33 // Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise 34 // false with any error that occurs if any. 35 func (l *Conn) Compare(dn, attribute, value string) (bool, error) { 36 packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") 37 packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) 38 39 request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request") 40 request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN")) 41 42 ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion") 43 ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "AttributeDesc")) 44 ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagOctetString, value, "AssertionValue")) 45 request.AppendChild(ava) 46 packet.AppendChild(request) 47 48 l.Debug.PrintPacket(packet) 49 50 msgCtx, err := l.sendMessage(packet) 51 if err != nil { 52 return false, err 53 } 54 defer l.finishMessage(msgCtx) 55 56 l.Debug.Printf("%d: waiting for response", msgCtx.id) 57 packetResponse, ok := <-msgCtx.responses 58 if !ok { 59 return false, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) 60 } 61 packet, err = packetResponse.ReadPacket() 62 l.Debug.Printf("%d: got response %p", msgCtx.id, packet) 63 if err != nil { 64 return false, err 65 } 66 67 if l.Debug { 68 if err := addLDAPDescriptions(packet); err != nil { 69 return false, err 70 } 71 ber.PrintPacket(packet) 72 } 73 74 if packet.Children[1].Tag == ApplicationCompareResponse { 75 resultCode, resultDescription := getLDAPResultCode(packet) 76 if resultCode == LDAPResultCompareTrue { 77 return true, nil 78 } else if resultCode == LDAPResultCompareFalse { 79 return false, nil 80 } else { 81 return false, NewError(resultCode, errors.New(resultDescription)) 82 } 83 } 84 return false, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag) 85 }