func (l *conn) StartTLS(config *tls.Config) error { msg := ldapMessage{ MessageId: l.id.Next(), ProtocolOp: asn1.OptionValue{Opts: "application,tag:23", Value: extendedRequest{Name: []byte("1.3.6.1.4.1.1466.20037")}}, } enc := asn1.NewEncoder(l) enc.Implicit = true if err := enc.Encode(msg); err != nil { return fmt.Errorf("Encode: %v", err) } var r extendedResponse resp := ldapMessage{ProtocolOp: asn1.OptionValue{Opts: "application,tag:24", Value: &r}} dec := asn1.NewDecoder(l) dec.Implicit = true if err := dec.Decode(&resp); err != nil { return fmt.Errorf("Decode: %v", err) } if r.Result.ResultCode != Success { return fmt.Errorf("ResultCode = %d", r.Result.ResultCode) } l.Conn = tls.Client(l.Conn, config) return nil }
func (l *conn) Bind(user, password string) (err error) { msg := ldapMessage{ MessageId: l.id.Next(), ProtocolOp: asn1.OptionValue{ Opts: "application,tag:0", Value: bindRequest{ Version: 3, Name: []byte(user), // TODO: Support SASL Auth: simpleAuth(password), }, }, } enc := asn1.NewEncoder(l) enc.Implicit = true if err = enc.Encode(msg); err != nil { return fmt.Errorf("Encode: %v", err) } var result ldapResult msg = ldapMessage{ ProtocolOp: asn1.OptionValue{Opts: "application,tag:1", Value: &result}, } dec := asn1.NewDecoder(l) dec.Implicit = true if err = dec.Decode(&msg); err != nil { return fmt.Errorf("Decode: %v", err) } if result.ResultCode != Success { return fmt.Errorf("ldap.Bind unsuccessful: resultCode = %v", result.ResultCode) } return nil }
func (l *conn) Search(req SearchRequest) ([]SearchResult, error) { msg := ldapMessage{ MessageId: l.id.Next(), ProtocolOp: asn1.OptionValue{Opts: "application,tag:3", Value: req}, } enc := asn1.NewEncoder(l) enc.Implicit = true if err := enc.Encode(msg); err != nil { return nil, fmt.Errorf("Encode: %v", err) } dec := asn1.NewDecoder(l) dec.Implicit = true results := []SearchResult{} loop: for { var raw asn1.RawValue resp := ldapMessage{ProtocolOp: &raw} if err := dec.Decode(&resp); err != nil { return nil, fmt.Errorf("Decode Envelope: %v", err) } rdec := asn1.NewDecoder(bytes.NewBuffer(raw.RawBytes)) rdec.Implicit = true switch raw.Tag { case 4: var r struct { Name []byte Attributes []struct { Type []byte Values [][]byte `asn1:"set"` } } if err := rdec.Decode(asn1.OptionValue{Opts: "application,tag:4", Value: &r}); err != nil { return nil, fmt.Errorf("Decode SearchResult: %v", err) } result := SearchResult{string(r.Name), make(map[string][]string)} for _, a := range r.Attributes { vals := []string{} for _, v := range a.Values { vals = append(vals, string(v)) } result.Attributes[string(a.Type)] = vals } results = append(results, result) case 5: // SearchResultDone var r ldapResult if err := rdec.Decode(asn1.OptionValue{Opts: "application,tag:5", Value: &r}); err != nil { return nil, fmt.Errorf("Decode SearchResultDone: %v", err) } if r.ResultCode != Success { return nil, fmt.Errorf("ResultCode = %d", r.ResultCode) } break loop case 19: // SearchResultReference // TODO } } return results, nil }