1 package ldap
2
3 import (
4 "fmt"
5
6 ber "github.com/go-asn1-ber/asn1-ber"
7 )
8
9
10 const (
11 LDAPResultSuccess = 0
12 LDAPResultOperationsError = 1
13 LDAPResultProtocolError = 2
14 LDAPResultTimeLimitExceeded = 3
15 LDAPResultSizeLimitExceeded = 4
16 LDAPResultCompareFalse = 5
17 LDAPResultCompareTrue = 6
18 LDAPResultAuthMethodNotSupported = 7
19 LDAPResultStrongAuthRequired = 8
20 LDAPResultReferral = 10
21 LDAPResultAdminLimitExceeded = 11
22 LDAPResultUnavailableCriticalExtension = 12
23 LDAPResultConfidentialityRequired = 13
24 LDAPResultSaslBindInProgress = 14
25 LDAPResultNoSuchAttribute = 16
26 LDAPResultUndefinedAttributeType = 17
27 LDAPResultInappropriateMatching = 18
28 LDAPResultConstraintViolation = 19
29 LDAPResultAttributeOrValueExists = 20
30 LDAPResultInvalidAttributeSyntax = 21
31 LDAPResultNoSuchObject = 32
32 LDAPResultAliasProblem = 33
33 LDAPResultInvalidDNSyntax = 34
34 LDAPResultIsLeaf = 35
35 LDAPResultAliasDereferencingProblem = 36
36 LDAPResultInappropriateAuthentication = 48
37 LDAPResultInvalidCredentials = 49
38 LDAPResultInsufficientAccessRights = 50
39 LDAPResultBusy = 51
40 LDAPResultUnavailable = 52
41 LDAPResultUnwillingToPerform = 53
42 LDAPResultLoopDetect = 54
43 LDAPResultSortControlMissing = 60
44 LDAPResultOffsetRangeError = 61
45 LDAPResultNamingViolation = 64
46 LDAPResultObjectClassViolation = 65
47 LDAPResultNotAllowedOnNonLeaf = 66
48 LDAPResultNotAllowedOnRDN = 67
49 LDAPResultEntryAlreadyExists = 68
50 LDAPResultObjectClassModsProhibited = 69
51 LDAPResultResultsTooLarge = 70
52 LDAPResultAffectsMultipleDSAs = 71
53 LDAPResultVirtualListViewErrorOrControlError = 76
54 LDAPResultOther = 80
55 LDAPResultServerDown = 81
56 LDAPResultLocalError = 82
57 LDAPResultEncodingError = 83
58 LDAPResultDecodingError = 84
59 LDAPResultTimeout = 85
60 LDAPResultAuthUnknown = 86
61 LDAPResultFilterError = 87
62 LDAPResultUserCanceled = 88
63 LDAPResultParamError = 89
64 LDAPResultNoMemory = 90
65 LDAPResultConnectError = 91
66 LDAPResultNotSupported = 92
67 LDAPResultControlNotFound = 93
68 LDAPResultNoResultsReturned = 94
69 LDAPResultMoreResultsToReturn = 95
70 LDAPResultClientLoop = 96
71 LDAPResultReferralLimitExceeded = 97
72 LDAPResultInvalidResponse = 100
73 LDAPResultAmbiguousResponse = 101
74 LDAPResultTLSNotSupported = 112
75 LDAPResultIntermediateResponse = 113
76 LDAPResultUnknownType = 114
77 LDAPResultCanceled = 118
78 LDAPResultNoSuchOperation = 119
79 LDAPResultTooLate = 120
80 LDAPResultCannotCancel = 121
81 LDAPResultAssertionFailed = 122
82 LDAPResultAuthorizationDenied = 123
83 LDAPResultSyncRefreshRequired = 4096
84
85 ErrorNetwork = 200
86 ErrorFilterCompile = 201
87 ErrorFilterDecompile = 202
88 ErrorDebugging = 203
89 ErrorUnexpectedMessage = 204
90 ErrorUnexpectedResponse = 205
91 ErrorEmptyPassword = 206
92 )
93
94
95 var LDAPResultCodeMap = map[uint16]string{
96 LDAPResultSuccess: "Success",
97 LDAPResultOperationsError: "Operations Error",
98 LDAPResultProtocolError: "Protocol Error",
99 LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
100 LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
101 LDAPResultCompareFalse: "Compare False",
102 LDAPResultCompareTrue: "Compare True",
103 LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
104 LDAPResultStrongAuthRequired: "Strong Auth Required",
105 LDAPResultReferral: "Referral",
106 LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
107 LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
108 LDAPResultConfidentialityRequired: "Confidentiality Required",
109 LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
110 LDAPResultNoSuchAttribute: "No Such Attribute",
111 LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
112 LDAPResultInappropriateMatching: "Inappropriate Matching",
113 LDAPResultConstraintViolation: "Constraint Violation",
114 LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
115 LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
116 LDAPResultNoSuchObject: "No Such Object",
117 LDAPResultAliasProblem: "Alias Problem",
118 LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
119 LDAPResultIsLeaf: "Is Leaf",
120 LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
121 LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
122 LDAPResultInvalidCredentials: "Invalid Credentials",
123 LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
124 LDAPResultBusy: "Busy",
125 LDAPResultUnavailable: "Unavailable",
126 LDAPResultUnwillingToPerform: "Unwilling To Perform",
127 LDAPResultLoopDetect: "Loop Detect",
128 LDAPResultSortControlMissing: "Sort Control Missing",
129 LDAPResultOffsetRangeError: "Result Offset Range Error",
130 LDAPResultNamingViolation: "Naming Violation",
131 LDAPResultObjectClassViolation: "Object Class Violation",
132 LDAPResultResultsTooLarge: "Results Too Large",
133 LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
134 LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
135 LDAPResultEntryAlreadyExists: "Entry Already Exists",
136 LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
137 LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
138 LDAPResultVirtualListViewErrorOrControlError: "Failed because of a problem related to the virtual list view",
139 LDAPResultOther: "Other",
140 LDAPResultServerDown: "Cannot establish a connection",
141 LDAPResultLocalError: "An error occurred",
142 LDAPResultEncodingError: "LDAP encountered an error while encoding",
143 LDAPResultDecodingError: "LDAP encountered an error while decoding",
144 LDAPResultTimeout: "LDAP timeout while waiting for a response from the server",
145 LDAPResultAuthUnknown: "The auth method requested in a bind request is unknown",
146 LDAPResultFilterError: "An error occurred while encoding the given search filter",
147 LDAPResultUserCanceled: "The user canceled the operation",
148 LDAPResultParamError: "An invalid parameter was specified",
149 LDAPResultNoMemory: "Out of memory error",
150 LDAPResultConnectError: "A connection to the server could not be established",
151 LDAPResultNotSupported: "An attempt has been made to use a feature not supported LDAP",
152 LDAPResultControlNotFound: "The controls required to perform the requested operation were not found",
153 LDAPResultNoResultsReturned: "No results were returned from the server",
154 LDAPResultMoreResultsToReturn: "There are more results in the chain of results",
155 LDAPResultClientLoop: "A loop has been detected. For example when following referrals",
156 LDAPResultReferralLimitExceeded: "The referral hop limit has been exceeded",
157 LDAPResultCanceled: "Operation was canceled",
158 LDAPResultNoSuchOperation: "Server has no knowledge of the operation requested for cancellation",
159 LDAPResultTooLate: "Too late to cancel the outstanding operation",
160 LDAPResultCannotCancel: "The identified operation does not support cancellation or the cancel operation cannot be performed",
161 LDAPResultAssertionFailed: "An assertion control given in the LDAP operation evaluated to false causing the operation to not be performed",
162 LDAPResultSyncRefreshRequired: "Refresh Required",
163 LDAPResultInvalidResponse: "Invalid Response",
164 LDAPResultAmbiguousResponse: "Ambiguous Response",
165 LDAPResultTLSNotSupported: "Tls Not Supported",
166 LDAPResultIntermediateResponse: "Intermediate Response",
167 LDAPResultUnknownType: "Unknown Type",
168 LDAPResultAuthorizationDenied: "Authorization Denied",
169
170 ErrorNetwork: "Network Error",
171 ErrorFilterCompile: "Filter Compile Error",
172 ErrorFilterDecompile: "Filter Decompile Error",
173 ErrorDebugging: "Debugging Error",
174 ErrorUnexpectedMessage: "Unexpected Message",
175 ErrorUnexpectedResponse: "Unexpected Response",
176 ErrorEmptyPassword: "Empty password not allowed by the client",
177 }
178
179
180 type Error struct {
181
182 Err error
183
184 ResultCode uint16
185
186 MatchedDN string
187
188 Packet *ber.Packet
189 }
190
191 func (e *Error) Error() string {
192 return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
193 }
194
195 func (e *Error) Unwrap() error { return e.Err }
196
197
198
199
200 func GetLDAPError(packet *ber.Packet) error {
201 if packet == nil {
202 return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty packet")}
203 }
204
205 if len(packet.Children) >= 2 {
206 response := packet.Children[1]
207 if response == nil {
208 return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet"), Packet: packet}
209 }
210 if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
211 if ber.Type(response.Children[0].Tag) == ber.Type(ber.TagInteger) || ber.Type(response.Children[0].Tag) == ber.Type(ber.TagEnumerated) {
212 resultCode := uint16(response.Children[0].Value.(int64))
213 if resultCode == 0 {
214 return nil
215 }
216
217 if ber.Type(response.Children[1].Tag) == ber.Type(ber.TagOctetString) &&
218 ber.Type(response.Children[2].Tag) == ber.Type(ber.TagOctetString) {
219 return &Error{
220 ResultCode: resultCode,
221 MatchedDN: response.Children[1].Value.(string),
222 Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
223 Packet: packet,
224 }
225 }
226 }
227 }
228 }
229
230 return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid packet format"), Packet: packet}
231 }
232
233
234 func NewError(resultCode uint16, err error) error {
235 return &Error{ResultCode: resultCode, Err: err}
236 }
237
238
239 func IsErrorAnyOf(err error, codes ...uint16) bool {
240 if err == nil {
241 return false
242 }
243
244 serverError, ok := err.(*Error)
245 if !ok {
246 return false
247 }
248
249 for _, code := range codes {
250 if serverError.ResultCode == code {
251 return true
252 }
253 }
254
255 return false
256 }
257
258
259 func IsErrorWithCode(err error, desiredResultCode uint16) bool {
260 return IsErrorAnyOf(err, desiredResultCode)
261 }
262
View as plain text