You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

add.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. package ldap
  10. import (
  11. "errors"
  12. "log"
  13. "gopkg.in/asn1-ber.v1"
  14. )
  15. // Attribute represents an LDAP attribute
  16. type Attribute struct {
  17. // Type is the name of the LDAP attribute
  18. Type string
  19. // Vals are the LDAP attribute values
  20. Vals []string
  21. }
  22. func (a *Attribute) encode() *ber.Packet {
  23. seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
  24. seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.Type, "Type"))
  25. set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
  26. for _, value := range a.Vals {
  27. set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
  28. }
  29. seq.AppendChild(set)
  30. return seq
  31. }
  32. // AddRequest represents an LDAP AddRequest operation
  33. type AddRequest struct {
  34. // DN identifies the entry being added
  35. DN string
  36. // Attributes list the attributes of the new entry
  37. Attributes []Attribute
  38. // Controls hold optional controls to send with the request
  39. Controls []Control
  40. }
  41. func (a AddRequest) encode() *ber.Packet {
  42. request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
  43. request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.DN, "DN"))
  44. attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
  45. for _, attribute := range a.Attributes {
  46. attributes.AppendChild(attribute.encode())
  47. }
  48. request.AppendChild(attributes)
  49. return request
  50. }
  51. // Attribute adds an attribute with the given type and values
  52. func (a *AddRequest) Attribute(attrType string, attrVals []string) {
  53. a.Attributes = append(a.Attributes, Attribute{Type: attrType, Vals: attrVals})
  54. }
  55. // NewAddRequest returns an AddRequest for the given DN, with no attributes
  56. func NewAddRequest(dn string, controls []Control) *AddRequest {
  57. return &AddRequest{
  58. DN: dn,
  59. Controls: controls,
  60. }
  61. }
  62. // Add performs the given AddRequest
  63. func (l *Conn) Add(addRequest *AddRequest) error {
  64. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
  65. packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
  66. packet.AppendChild(addRequest.encode())
  67. if len(addRequest.Controls) > 0 {
  68. packet.AppendChild(encodeControls(addRequest.Controls))
  69. }
  70. l.Debug.PrintPacket(packet)
  71. msgCtx, err := l.sendMessage(packet)
  72. if err != nil {
  73. return err
  74. }
  75. defer l.finishMessage(msgCtx)
  76. l.Debug.Printf("%d: waiting for response", msgCtx.id)
  77. packetResponse, ok := <-msgCtx.responses
  78. if !ok {
  79. return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
  80. }
  81. packet, err = packetResponse.ReadPacket()
  82. l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
  83. if err != nil {
  84. return err
  85. }
  86. if l.Debug {
  87. if err := addLDAPDescriptions(packet); err != nil {
  88. return err
  89. }
  90. ber.PrintPacket(packet)
  91. }
  92. if packet.Children[1].Tag == ApplicationAddResponse {
  93. err := GetLDAPError(packet)
  94. if err != nil {
  95. return err
  96. }
  97. } else {
  98. log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
  99. }
  100. l.Debug.Printf("%d: returning", msgCtx.id)
  101. return nil
  102. }