github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/ldap.v2/bind.go (about) 1 // Copyright 2011 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 package ldap 6 7 import ( 8 "errors" 9 10 "gopkg.in/asn1-ber.v1" 11 ) 12 13 // SimpleBindRequest represents a username/password bind operation 14 type SimpleBindRequest struct { 15 // Username is the name of the Directory object that the client wishes to bind as 16 Username string 17 // Password is the credentials to bind with 18 Password string 19 // Controls are optional controls to send with the bind request 20 Controls []Control 21 } 22 23 // SimpleBindResult contains the response from the server 24 type SimpleBindResult struct { 25 Controls []Control 26 } 27 28 // NewSimpleBindRequest returns a bind request 29 func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest { 30 return &SimpleBindRequest{ 31 Username: username, 32 Password: password, 33 Controls: controls, 34 } 35 } 36 37 func (bindRequest *SimpleBindRequest) encode() *ber.Packet { 38 request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") 39 request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) 40 request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name")) 41 request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password")) 42 43 request.AppendChild(encodeControls(bindRequest.Controls)) 44 45 return request 46 } 47 48 // SimpleBind performs the simple bind operation defined in the given request 49 func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) { 50 packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") 51 packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) 52 encodedBindRequest := simpleBindRequest.encode() 53 packet.AppendChild(encodedBindRequest) 54 55 if l.Debug { 56 ber.PrintPacket(packet) 57 } 58 59 msgCtx, err := l.sendMessage(packet) 60 if err != nil { 61 return nil, err 62 } 63 defer l.finishMessage(msgCtx) 64 65 packetResponse, ok := <-msgCtx.responses 66 if !ok { 67 return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) 68 } 69 packet, err = packetResponse.ReadPacket() 70 l.Debug.Printf("%d: got response %p", msgCtx.id, packet) 71 if err != nil { 72 return nil, err 73 } 74 75 if l.Debug { 76 if err := addLDAPDescriptions(packet); err != nil { 77 return nil, err 78 } 79 ber.PrintPacket(packet) 80 } 81 82 result := &SimpleBindResult{ 83 Controls: make([]Control, 0), 84 } 85 86 if len(packet.Children) == 3 { 87 for _, child := range packet.Children[2].Children { 88 result.Controls = append(result.Controls, DecodeControl(child)) 89 } 90 } 91 92 resultCode, resultDescription := getLDAPResultCode(packet) 93 if resultCode != 0 { 94 return result, NewError(resultCode, errors.New(resultDescription)) 95 } 96 97 return result, nil 98 } 99 100 // Bind performs a bind with the given username and password 101 func (l *Conn) Bind(username, password string) error { 102 packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") 103 packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) 104 bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") 105 bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) 106 bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name")) 107 bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password")) 108 packet.AppendChild(bindRequest) 109 110 if l.Debug { 111 ber.PrintPacket(packet) 112 } 113 114 msgCtx, err := l.sendMessage(packet) 115 if err != nil { 116 return err 117 } 118 defer l.finishMessage(msgCtx) 119 120 packetResponse, ok := <-msgCtx.responses 121 if !ok { 122 return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) 123 } 124 packet, err = packetResponse.ReadPacket() 125 l.Debug.Printf("%d: got response %p", msgCtx.id, packet) 126 if err != nil { 127 return err 128 } 129 130 if l.Debug { 131 if err := addLDAPDescriptions(packet); err != nil { 132 return err 133 } 134 ber.PrintPacket(packet) 135 } 136 137 resultCode, resultDescription := getLDAPResultCode(packet) 138 if resultCode != 0 { 139 return NewError(resultCode, errors.New(resultDescription)) 140 } 141 142 return nil 143 }