@@ -176,35 +176,44 @@ var LDAPResultCodeMap = map[uint16]string{
176176 ErrorEmptyPassword : "Empty password not allowed by the client" ,
177177}
178178
179- func getLDAPResultCode (packet * ber.Packet ) (code uint16 , description string ) {
180- if packet == nil {
181- return ErrorUnexpectedResponse , "Empty packet"
182- } else if len (packet .Children ) >= 2 {
183- response := packet .Children [1 ]
184- if response == nil {
185- return ErrorUnexpectedResponse , "Empty response in packet"
186- }
187- if response .ClassType == ber .ClassApplication && response .TagType == ber .TypeConstructed && len (response .Children ) >= 3 {
188- // Children[1].Children[2] is the diagnosticMessage which is guaranteed to exist as seen here: https://tools.ietf.org/html/rfc4511#section-4.1.9
189- return uint16 (response .Children [0 ].Value .(int64 )), response .Children [2 ].Value .(string )
190- }
191- }
192-
193- return ErrorNetwork , "Invalid packet format"
194- }
195-
196179// Error holds LDAP error information
197180type Error struct {
198181 // Err is the underlying error
199182 Err error
200183 // ResultCode is the LDAP error code
201184 ResultCode uint16
185+ // MatchedDN is the matchedDN returned if any
186+ MatchedDN string
202187}
203188
204189func (e * Error ) Error () string {
205190 return fmt .Sprintf ("LDAP Result Code %d %q: %s" , e .ResultCode , LDAPResultCodeMap [e .ResultCode ], e .Err .Error ())
206191}
207192
193+ // GetLDAPError creates an Error out of a BER packet representing a LDAPResult
194+ // The return is an error object. It can be casted to a Error structure.
195+ // This function returns nil if resultCode in the LDAPResult sequence is success(0).
196+ func GetLDAPError (packet * ber.Packet ) error {
197+ if packet == nil {
198+ return & Error {ResultCode : ErrorUnexpectedResponse , Err : fmt .Errorf ("Empty packet" )}
199+ } else if len (packet .Children ) >= 2 {
200+ response := packet .Children [1 ]
201+ if response == nil {
202+ return & Error {ResultCode : ErrorUnexpectedResponse , Err : fmt .Errorf ("Empty response in packet" )}
203+ }
204+ if response .ClassType == ber .ClassApplication && response .TagType == ber .TypeConstructed && len (response .Children ) >= 3 {
205+ resultCode := uint16 (response .Children [0 ].Value .(int64 ))
206+ if resultCode == 0 { // No error
207+ return nil
208+ }
209+ return & Error {ResultCode : resultCode , MatchedDN : response .Children [1 ].Value .(string ),
210+ Err : fmt .Errorf (response .Children [2 ].Value .(string ))}
211+ }
212+ }
213+
214+ return & Error {ResultCode : ErrorNetwork , Err : fmt .Errorf ("Invalid packet format" )}
215+ }
216+
208217// NewError creates an LDAP error with the given code and underlying error
209218func NewError (resultCode uint16 , err error ) error {
210219 return & Error {ResultCode : resultCode , Err : err }
0 commit comments