error.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package ldap
  2. import (
  3. "fmt"
  4. "gopkg.in/asn1-ber.v1"
  5. )
  6. // LDAP Result Codes
  7. const (
  8. LDAPResultSuccess = 0
  9. LDAPResultOperationsError = 1
  10. LDAPResultProtocolError = 2
  11. LDAPResultTimeLimitExceeded = 3
  12. LDAPResultSizeLimitExceeded = 4
  13. LDAPResultCompareFalse = 5
  14. LDAPResultCompareTrue = 6
  15. LDAPResultAuthMethodNotSupported = 7
  16. LDAPResultStrongAuthRequired = 8
  17. LDAPResultReferral = 10
  18. LDAPResultAdminLimitExceeded = 11
  19. LDAPResultUnavailableCriticalExtension = 12
  20. LDAPResultConfidentialityRequired = 13
  21. LDAPResultSaslBindInProgress = 14
  22. LDAPResultNoSuchAttribute = 16
  23. LDAPResultUndefinedAttributeType = 17
  24. LDAPResultInappropriateMatching = 18
  25. LDAPResultConstraintViolation = 19
  26. LDAPResultAttributeOrValueExists = 20
  27. LDAPResultInvalidAttributeSyntax = 21
  28. LDAPResultNoSuchObject = 32
  29. LDAPResultAliasProblem = 33
  30. LDAPResultInvalidDNSyntax = 34
  31. LDAPResultAliasDereferencingProblem = 36
  32. LDAPResultInappropriateAuthentication = 48
  33. LDAPResultInvalidCredentials = 49
  34. LDAPResultInsufficientAccessRights = 50
  35. LDAPResultBusy = 51
  36. LDAPResultUnavailable = 52
  37. LDAPResultUnwillingToPerform = 53
  38. LDAPResultLoopDetect = 54
  39. LDAPResultNamingViolation = 64
  40. LDAPResultObjectClassViolation = 65
  41. LDAPResultNotAllowedOnNonLeaf = 66
  42. LDAPResultNotAllowedOnRDN = 67
  43. LDAPResultEntryAlreadyExists = 68
  44. LDAPResultObjectClassModsProhibited = 69
  45. LDAPResultAffectsMultipleDSAs = 71
  46. LDAPResultOther = 80
  47. ErrorNetwork = 200
  48. ErrorFilterCompile = 201
  49. ErrorFilterDecompile = 202
  50. ErrorDebugging = 203
  51. ErrorUnexpectedMessage = 204
  52. ErrorUnexpectedResponse = 205
  53. ErrorEmptyPassword = 206
  54. )
  55. // LDAPResultCodeMap contains string descriptions for LDAP error codes
  56. var LDAPResultCodeMap = map[uint8]string{
  57. LDAPResultSuccess: "Success",
  58. LDAPResultOperationsError: "Operations Error",
  59. LDAPResultProtocolError: "Protocol Error",
  60. LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
  61. LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
  62. LDAPResultCompareFalse: "Compare False",
  63. LDAPResultCompareTrue: "Compare True",
  64. LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
  65. LDAPResultStrongAuthRequired: "Strong Auth Required",
  66. LDAPResultReferral: "Referral",
  67. LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
  68. LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
  69. LDAPResultConfidentialityRequired: "Confidentiality Required",
  70. LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
  71. LDAPResultNoSuchAttribute: "No Such Attribute",
  72. LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
  73. LDAPResultInappropriateMatching: "Inappropriate Matching",
  74. LDAPResultConstraintViolation: "Constraint Violation",
  75. LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
  76. LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
  77. LDAPResultNoSuchObject: "No Such Object",
  78. LDAPResultAliasProblem: "Alias Problem",
  79. LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
  80. LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
  81. LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
  82. LDAPResultInvalidCredentials: "Invalid Credentials",
  83. LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
  84. LDAPResultBusy: "Busy",
  85. LDAPResultUnavailable: "Unavailable",
  86. LDAPResultUnwillingToPerform: "Unwilling To Perform",
  87. LDAPResultLoopDetect: "Loop Detect",
  88. LDAPResultNamingViolation: "Naming Violation",
  89. LDAPResultObjectClassViolation: "Object Class Violation",
  90. LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
  91. LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
  92. LDAPResultEntryAlreadyExists: "Entry Already Exists",
  93. LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
  94. LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
  95. LDAPResultOther: "Other",
  96. ErrorNetwork: "Network Error",
  97. ErrorFilterCompile: "Filter Compile Error",
  98. ErrorFilterDecompile: "Filter Decompile Error",
  99. ErrorDebugging: "Debugging Error",
  100. ErrorUnexpectedMessage: "Unexpected Message",
  101. ErrorUnexpectedResponse: "Unexpected Response",
  102. ErrorEmptyPassword: "Empty password not allowed by the client",
  103. }
  104. func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
  105. if packet == nil {
  106. return ErrorUnexpectedResponse, "Empty packet"
  107. } else if len(packet.Children) >= 2 {
  108. response := packet.Children[1]
  109. if response == nil {
  110. return ErrorUnexpectedResponse, "Empty response in packet"
  111. }
  112. if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
  113. // 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
  114. return uint8(response.Children[0].Value.(int64)), response.Children[2].Value.(string)
  115. }
  116. }
  117. return ErrorNetwork, "Invalid packet format"
  118. }
  119. // Error holds LDAP error information
  120. type Error struct {
  121. // Err is the underlying error
  122. Err error
  123. // ResultCode is the LDAP error code
  124. ResultCode uint8
  125. }
  126. func (e *Error) Error() string {
  127. return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
  128. }
  129. // NewError creates an LDAP error with the given code and underlying error
  130. func NewError(resultCode uint8, err error) error {
  131. return &Error{ResultCode: resultCode, Err: err}
  132. }
  133. // IsErrorWithCode returns true if the given error is an LDAP error with the given result code
  134. func IsErrorWithCode(err error, desiredResultCode uint8) bool {
  135. if err == nil {
  136. return false
  137. }
  138. serverError, ok := err.(*Error)
  139. if !ok {
  140. return false
  141. }
  142. return serverError.ResultCode == desiredResultCode
  143. }