github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/ldap.v2/add.go (about) 1 // 2 // https://tools.ietf.org/html/rfc4511 3 // 4 // AddRequest ::= [APPLICATION 8] SEQUENCE { 5 // entry LDAPDN, 6 // attributes AttributeList } 7 // 8 // AttributeList ::= SEQUENCE OF attribute Attribute 9 10 package ldap 11 12 import ( 13 "errors" 14 "log" 15 16 "gopkg.in/asn1-ber.v1" 17 ) 18 19 // Attribute represents an LDAP attribute 20 type Attribute struct { 21 // Type is the name of the LDAP attribute 22 Type string 23 // Vals are the LDAP attribute values 24 Vals []string 25 } 26 27 func (a *Attribute) encode() *ber.Packet { 28 seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute") 29 seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.Type, "Type")) 30 set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue") 31 for _, value := range a.Vals { 32 set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals")) 33 } 34 seq.AppendChild(set) 35 return seq 36 } 37 38 // AddRequest represents an LDAP AddRequest operation 39 type AddRequest struct { 40 // DN identifies the entry being added 41 DN string 42 // Attributes list the attributes of the new entry 43 Attributes []Attribute 44 } 45 46 func (a AddRequest) encode() *ber.Packet { 47 request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request") 48 request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.DN, "DN")) 49 attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes") 50 for _, attribute := range a.Attributes { 51 attributes.AppendChild(attribute.encode()) 52 } 53 request.AppendChild(attributes) 54 return request 55 } 56 57 // Attribute adds an attribute with the given type and values 58 func (a *AddRequest) Attribute(attrType string, attrVals []string) { 59 a.Attributes = append(a.Attributes, Attribute{Type: attrType, Vals: attrVals}) 60 } 61 62 // NewAddRequest returns an AddRequest for the given DN, with no attributes 63 func NewAddRequest(dn string) *AddRequest { 64 return &AddRequest{ 65 DN: dn, 66 } 67 68 } 69 70 // Add performs the given AddRequest 71 func (l *Conn) Add(addRequest *AddRequest) error { 72 packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") 73 packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) 74 packet.AppendChild(addRequest.encode()) 75 76 l.Debug.PrintPacket(packet) 77 78 msgCtx, err := l.sendMessage(packet) 79 if err != nil { 80 return err 81 } 82 defer l.finishMessage(msgCtx) 83 84 l.Debug.Printf("%d: waiting for response", msgCtx.id) 85 packetResponse, ok := <-msgCtx.responses 86 if !ok { 87 return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) 88 } 89 packet, err = packetResponse.ReadPacket() 90 l.Debug.Printf("%d: got response %p", msgCtx.id, packet) 91 if err != nil { 92 return err 93 } 94 95 if l.Debug { 96 if err := addLDAPDescriptions(packet); err != nil { 97 return err 98 } 99 ber.PrintPacket(packet) 100 } 101 102 if packet.Children[1].Tag == ApplicationAddResponse { 103 resultCode, resultDescription := getLDAPResultCode(packet) 104 if resultCode != 0 { 105 return NewError(resultCode, errors.New(resultDescription)) 106 } 107 } else { 108 log.Printf("Unexpected Response: %d", packet.Children[1].Tag) 109 } 110 111 l.Debug.Printf("%d: returning", msgCtx.id) 112 return nil 113 }