add.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. type Attribute struct {
  16. attrType string
  17. attrVals []string
  18. }
  19. func (a *Attribute) encode() *ber.Packet {
  20. seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
  21. seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.attrType, "Type"))
  22. set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
  23. for _, value := range a.attrVals {
  24. set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
  25. }
  26. seq.AppendChild(set)
  27. return seq
  28. }
  29. type AddRequest struct {
  30. dn string
  31. attributes []Attribute
  32. }
  33. func (a AddRequest) encode() *ber.Packet {
  34. request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
  35. request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.dn, "DN"))
  36. attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
  37. for _, attribute := range a.attributes {
  38. attributes.AppendChild(attribute.encode())
  39. }
  40. request.AppendChild(attributes)
  41. return request
  42. }
  43. func (a *AddRequest) Attribute(attrType string, attrVals []string) {
  44. a.attributes = append(a.attributes, Attribute{attrType: attrType, attrVals: attrVals})
  45. }
  46. func NewAddRequest(dn string) *AddRequest {
  47. return &AddRequest{
  48. dn: dn,
  49. }
  50. }
  51. func (l *Conn) Add(addRequest *AddRequest) error {
  52. messageID := l.nextMessageID()
  53. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
  54. packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
  55. packet.AppendChild(addRequest.encode())
  56. l.Debug.PrintPacket(packet)
  57. channel, err := l.sendMessage(packet)
  58. if err != nil {
  59. return err
  60. }
  61. if channel == nil {
  62. return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
  63. }
  64. defer l.finishMessage(messageID)
  65. l.Debug.Printf("%d: waiting for response", messageID)
  66. packet = <-channel
  67. l.Debug.Printf("%d: got response %p", messageID, packet)
  68. if packet == nil {
  69. return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
  70. }
  71. if l.Debug {
  72. if err := addLDAPDescriptions(packet); err != nil {
  73. return err
  74. }
  75. ber.PrintPacket(packet)
  76. }
  77. if packet.Children[1].Tag == ApplicationAddResponse {
  78. resultCode, resultDescription := getLDAPResultCode(packet)
  79. if resultCode != 0 {
  80. return NewError(resultCode, errors.New(resultDescription))
  81. }
  82. } else {
  83. log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
  84. }
  85. l.Debug.Printf("%d: returning", messageID)
  86. return nil
  87. }