mirror of https://github.com/go-gitea/gitea.git
Signed-off-by: Andrew Thornton <art27@cantab.net>pull/1763/head^2
parent
a380cfd8e0
commit
22770c324d
@ -1,13 +0,0 @@
|
|||||||
// +build go1.4
|
|
||||||
|
|
||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// For compilers that support it, we just use the underlying sync/atomic.Value
|
|
||||||
// type.
|
|
||||||
type atomicValue struct {
|
|
||||||
atomic.Value
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
// +build !go1.4
|
|
||||||
|
|
||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a helper type that emulates the use of the "sync/atomic.Value"
|
|
||||||
// struct that's available in Go 1.4 and up.
|
|
||||||
type atomicValue struct {
|
|
||||||
value interface{}
|
|
||||||
lock sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (av *atomicValue) Store(val interface{}) {
|
|
||||||
av.lock.Lock()
|
|
||||||
av.value = val
|
|
||||||
av.lock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (av *atomicValue) Load() interface{} {
|
|
||||||
av.lock.RLock()
|
|
||||||
ret := av.value
|
|
||||||
av.lock.RUnlock()
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
@ -1,155 +0,0 @@
|
|||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gopkg.in/asn1-ber.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LDAP Result Codes
|
|
||||||
const (
|
|
||||||
LDAPResultSuccess = 0
|
|
||||||
LDAPResultOperationsError = 1
|
|
||||||
LDAPResultProtocolError = 2
|
|
||||||
LDAPResultTimeLimitExceeded = 3
|
|
||||||
LDAPResultSizeLimitExceeded = 4
|
|
||||||
LDAPResultCompareFalse = 5
|
|
||||||
LDAPResultCompareTrue = 6
|
|
||||||
LDAPResultAuthMethodNotSupported = 7
|
|
||||||
LDAPResultStrongAuthRequired = 8
|
|
||||||
LDAPResultReferral = 10
|
|
||||||
LDAPResultAdminLimitExceeded = 11
|
|
||||||
LDAPResultUnavailableCriticalExtension = 12
|
|
||||||
LDAPResultConfidentialityRequired = 13
|
|
||||||
LDAPResultSaslBindInProgress = 14
|
|
||||||
LDAPResultNoSuchAttribute = 16
|
|
||||||
LDAPResultUndefinedAttributeType = 17
|
|
||||||
LDAPResultInappropriateMatching = 18
|
|
||||||
LDAPResultConstraintViolation = 19
|
|
||||||
LDAPResultAttributeOrValueExists = 20
|
|
||||||
LDAPResultInvalidAttributeSyntax = 21
|
|
||||||
LDAPResultNoSuchObject = 32
|
|
||||||
LDAPResultAliasProblem = 33
|
|
||||||
LDAPResultInvalidDNSyntax = 34
|
|
||||||
LDAPResultAliasDereferencingProblem = 36
|
|
||||||
LDAPResultInappropriateAuthentication = 48
|
|
||||||
LDAPResultInvalidCredentials = 49
|
|
||||||
LDAPResultInsufficientAccessRights = 50
|
|
||||||
LDAPResultBusy = 51
|
|
||||||
LDAPResultUnavailable = 52
|
|
||||||
LDAPResultUnwillingToPerform = 53
|
|
||||||
LDAPResultLoopDetect = 54
|
|
||||||
LDAPResultNamingViolation = 64
|
|
||||||
LDAPResultObjectClassViolation = 65
|
|
||||||
LDAPResultNotAllowedOnNonLeaf = 66
|
|
||||||
LDAPResultNotAllowedOnRDN = 67
|
|
||||||
LDAPResultEntryAlreadyExists = 68
|
|
||||||
LDAPResultObjectClassModsProhibited = 69
|
|
||||||
LDAPResultAffectsMultipleDSAs = 71
|
|
||||||
LDAPResultOther = 80
|
|
||||||
|
|
||||||
ErrorNetwork = 200
|
|
||||||
ErrorFilterCompile = 201
|
|
||||||
ErrorFilterDecompile = 202
|
|
||||||
ErrorDebugging = 203
|
|
||||||
ErrorUnexpectedMessage = 204
|
|
||||||
ErrorUnexpectedResponse = 205
|
|
||||||
)
|
|
||||||
|
|
||||||
// LDAPResultCodeMap contains string descriptions for LDAP error codes
|
|
||||||
var LDAPResultCodeMap = map[uint8]string{
|
|
||||||
LDAPResultSuccess: "Success",
|
|
||||||
LDAPResultOperationsError: "Operations Error",
|
|
||||||
LDAPResultProtocolError: "Protocol Error",
|
|
||||||
LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
|
|
||||||
LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
|
|
||||||
LDAPResultCompareFalse: "Compare False",
|
|
||||||
LDAPResultCompareTrue: "Compare True",
|
|
||||||
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
|
|
||||||
LDAPResultStrongAuthRequired: "Strong Auth Required",
|
|
||||||
LDAPResultReferral: "Referral",
|
|
||||||
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
|
|
||||||
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
|
|
||||||
LDAPResultConfidentialityRequired: "Confidentiality Required",
|
|
||||||
LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
|
|
||||||
LDAPResultNoSuchAttribute: "No Such Attribute",
|
|
||||||
LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
|
|
||||||
LDAPResultInappropriateMatching: "Inappropriate Matching",
|
|
||||||
LDAPResultConstraintViolation: "Constraint Violation",
|
|
||||||
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
|
|
||||||
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
|
|
||||||
LDAPResultNoSuchObject: "No Such Object",
|
|
||||||
LDAPResultAliasProblem: "Alias Problem",
|
|
||||||
LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
|
|
||||||
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
|
|
||||||
LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
|
|
||||||
LDAPResultInvalidCredentials: "Invalid Credentials",
|
|
||||||
LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
|
|
||||||
LDAPResultBusy: "Busy",
|
|
||||||
LDAPResultUnavailable: "Unavailable",
|
|
||||||
LDAPResultUnwillingToPerform: "Unwilling To Perform",
|
|
||||||
LDAPResultLoopDetect: "Loop Detect",
|
|
||||||
LDAPResultNamingViolation: "Naming Violation",
|
|
||||||
LDAPResultObjectClassViolation: "Object Class Violation",
|
|
||||||
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
|
|
||||||
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
|
|
||||||
LDAPResultEntryAlreadyExists: "Entry Already Exists",
|
|
||||||
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
|
|
||||||
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
|
|
||||||
LDAPResultOther: "Other",
|
|
||||||
|
|
||||||
ErrorNetwork: "Network Error",
|
|
||||||
ErrorFilterCompile: "Filter Compile Error",
|
|
||||||
ErrorFilterDecompile: "Filter Decompile Error",
|
|
||||||
ErrorDebugging: "Debugging Error",
|
|
||||||
ErrorUnexpectedMessage: "Unexpected Message",
|
|
||||||
ErrorUnexpectedResponse: "Unexpected Response",
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
|
|
||||||
if packet == nil {
|
|
||||||
return ErrorUnexpectedResponse, "Empty packet"
|
|
||||||
} else if len(packet.Children) >= 2 {
|
|
||||||
response := packet.Children[1]
|
|
||||||
if response == nil {
|
|
||||||
return ErrorUnexpectedResponse, "Empty response in packet"
|
|
||||||
}
|
|
||||||
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
|
|
||||||
// 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
|
|
||||||
return uint8(response.Children[0].Value.(int64)), response.Children[2].Value.(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ErrorNetwork, "Invalid packet format"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error holds LDAP error information
|
|
||||||
type Error struct {
|
|
||||||
// Err is the underlying error
|
|
||||||
Err error
|
|
||||||
// ResultCode is the LDAP error code
|
|
||||||
ResultCode uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewError creates an LDAP error with the given code and underlying error
|
|
||||||
func NewError(resultCode uint8, err error) error {
|
|
||||||
return &Error{ResultCode: resultCode, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
|
|
||||||
func IsErrorWithCode(err error, desiredResultCode uint8) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
serverError, ok := err.(*Error)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverError.ResultCode == desiredResultCode
|
|
||||||
}
|
|
@ -0,0 +1,234 @@
|
|||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/asn1-ber.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LDAP Result Codes
|
||||||
|
const (
|
||||||
|
LDAPResultSuccess = 0
|
||||||
|
LDAPResultOperationsError = 1
|
||||||
|
LDAPResultProtocolError = 2
|
||||||
|
LDAPResultTimeLimitExceeded = 3
|
||||||
|
LDAPResultSizeLimitExceeded = 4
|
||||||
|
LDAPResultCompareFalse = 5
|
||||||
|
LDAPResultCompareTrue = 6
|
||||||
|
LDAPResultAuthMethodNotSupported = 7
|
||||||
|
LDAPResultStrongAuthRequired = 8
|
||||||
|
LDAPResultReferral = 10
|
||||||
|
LDAPResultAdminLimitExceeded = 11
|
||||||
|
LDAPResultUnavailableCriticalExtension = 12
|
||||||
|
LDAPResultConfidentialityRequired = 13
|
||||||
|
LDAPResultSaslBindInProgress = 14
|
||||||
|
LDAPResultNoSuchAttribute = 16
|
||||||
|
LDAPResultUndefinedAttributeType = 17
|
||||||
|
LDAPResultInappropriateMatching = 18
|
||||||
|
LDAPResultConstraintViolation = 19
|
||||||
|
LDAPResultAttributeOrValueExists = 20
|
||||||
|
LDAPResultInvalidAttributeSyntax = 21
|
||||||
|
LDAPResultNoSuchObject = 32
|
||||||
|
LDAPResultAliasProblem = 33
|
||||||
|
LDAPResultInvalidDNSyntax = 34
|
||||||
|
LDAPResultIsLeaf = 35
|
||||||
|
LDAPResultAliasDereferencingProblem = 36
|
||||||
|
LDAPResultInappropriateAuthentication = 48
|
||||||
|
LDAPResultInvalidCredentials = 49
|
||||||
|
LDAPResultInsufficientAccessRights = 50
|
||||||
|
LDAPResultBusy = 51
|
||||||
|
LDAPResultUnavailable = 52
|
||||||
|
LDAPResultUnwillingToPerform = 53
|
||||||
|
LDAPResultLoopDetect = 54
|
||||||
|
LDAPResultSortControlMissing = 60
|
||||||
|
LDAPResultOffsetRangeError = 61
|
||||||
|
LDAPResultNamingViolation = 64
|
||||||
|
LDAPResultObjectClassViolation = 65
|
||||||
|
LDAPResultNotAllowedOnNonLeaf = 66
|
||||||
|
LDAPResultNotAllowedOnRDN = 67
|
||||||
|
LDAPResultEntryAlreadyExists = 68
|
||||||
|
LDAPResultObjectClassModsProhibited = 69
|
||||||
|
LDAPResultResultsTooLarge = 70
|
||||||
|
LDAPResultAffectsMultipleDSAs = 71
|
||||||
|
LDAPResultVirtualListViewErrorOrControlError = 76
|
||||||
|
LDAPResultOther = 80
|
||||||
|
LDAPResultServerDown = 81
|
||||||
|
LDAPResultLocalError = 82
|
||||||
|
LDAPResultEncodingError = 83
|
||||||
|
LDAPResultDecodingError = 84
|
||||||
|
LDAPResultTimeout = 85
|
||||||
|
LDAPResultAuthUnknown = 86
|
||||||
|
LDAPResultFilterError = 87
|
||||||
|
LDAPResultUserCanceled = 88
|
||||||
|
LDAPResultParamError = 89
|
||||||
|
LDAPResultNoMemory = 90
|
||||||
|
LDAPResultConnectError = 91
|
||||||
|
LDAPResultNotSupported = 92
|
||||||
|
LDAPResultControlNotFound = 93
|
||||||
|
LDAPResultNoResultsReturned = 94
|
||||||
|
LDAPResultMoreResultsToReturn = 95
|
||||||
|
LDAPResultClientLoop = 96
|
||||||
|
LDAPResultReferralLimitExceeded = 97
|
||||||
|
LDAPResultInvalidResponse = 100
|
||||||
|
LDAPResultAmbiguousResponse = 101
|
||||||
|
LDAPResultTLSNotSupported = 112
|
||||||
|
LDAPResultIntermediateResponse = 113
|
||||||
|
LDAPResultUnknownType = 114
|
||||||
|
LDAPResultCanceled = 118
|
||||||
|
LDAPResultNoSuchOperation = 119
|
||||||
|
LDAPResultTooLate = 120
|
||||||
|
LDAPResultCannotCancel = 121
|
||||||
|
LDAPResultAssertionFailed = 122
|
||||||
|
LDAPResultAuthorizationDenied = 123
|
||||||
|
LDAPResultSyncRefreshRequired = 4096
|
||||||
|
|
||||||
|
ErrorNetwork = 200
|
||||||
|
ErrorFilterCompile = 201
|
||||||
|
ErrorFilterDecompile = 202
|
||||||
|
ErrorDebugging = 203
|
||||||
|
ErrorUnexpectedMessage = 204
|
||||||
|
ErrorUnexpectedResponse = 205
|
||||||
|
ErrorEmptyPassword = 206
|
||||||
|
)
|
||||||
|
|
||||||
|
// LDAPResultCodeMap contains string descriptions for LDAP error codes
|
||||||
|
var LDAPResultCodeMap = map[uint16]string{
|
||||||
|
LDAPResultSuccess: "Success",
|
||||||
|
LDAPResultOperationsError: "Operations Error",
|
||||||
|
LDAPResultProtocolError: "Protocol Error",
|
||||||
|
LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
|
||||||
|
LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
|
||||||
|
LDAPResultCompareFalse: "Compare False",
|
||||||
|
LDAPResultCompareTrue: "Compare True",
|
||||||
|
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
|
||||||
|
LDAPResultStrongAuthRequired: "Strong Auth Required",
|
||||||
|
LDAPResultReferral: "Referral",
|
||||||
|
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
|
||||||
|
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
|
||||||
|
LDAPResultConfidentialityRequired: "Confidentiality Required",
|
||||||
|
LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
|
||||||
|
LDAPResultNoSuchAttribute: "No Such Attribute",
|
||||||
|
LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
|
||||||
|
LDAPResultInappropriateMatching: "Inappropriate Matching",
|
||||||
|
LDAPResultConstraintViolation: "Constraint Violation",
|
||||||
|
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
|
||||||
|
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
|
||||||
|
LDAPResultNoSuchObject: "No Such Object",
|
||||||
|
LDAPResultAliasProblem: "Alias Problem",
|
||||||
|
LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
|
||||||
|
LDAPResultIsLeaf: "Is Leaf",
|
||||||
|
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
|
||||||
|
LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
|
||||||
|
LDAPResultInvalidCredentials: "Invalid Credentials",
|
||||||
|
LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
|
||||||
|
LDAPResultBusy: "Busy",
|
||||||
|
LDAPResultUnavailable: "Unavailable",
|
||||||
|
LDAPResultUnwillingToPerform: "Unwilling To Perform",
|
||||||
|
LDAPResultLoopDetect: "Loop Detect",
|
||||||
|
LDAPResultSortControlMissing: "Sort Control Missing",
|
||||||
|
LDAPResultOffsetRangeError: "Result Offset Range Error",
|
||||||
|
LDAPResultNamingViolation: "Naming Violation",
|
||||||
|
LDAPResultObjectClassViolation: "Object Class Violation",
|
||||||
|
LDAPResultResultsTooLarge: "Results Too Large",
|
||||||
|
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
|
||||||
|
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
|
||||||
|
LDAPResultEntryAlreadyExists: "Entry Already Exists",
|
||||||
|
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
|
||||||
|
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
|
||||||
|
LDAPResultVirtualListViewErrorOrControlError: "Failed because of a problem related to the virtual list view",
|
||||||
|
LDAPResultOther: "Other",
|
||||||
|
LDAPResultServerDown: "Cannot establish a connection",
|
||||||
|
LDAPResultLocalError: "An error occurred",
|
||||||
|
LDAPResultEncodingError: "LDAP encountered an error while encoding",
|
||||||
|
LDAPResultDecodingError: "LDAP encountered an error while decoding",
|
||||||
|
LDAPResultTimeout: "LDAP timeout while waiting for a response from the server",
|
||||||
|
LDAPResultAuthUnknown: "The auth method requested in a bind request is unknown",
|
||||||
|
LDAPResultFilterError: "An error occurred while encoding the given search filter",
|
||||||
|
LDAPResultUserCanceled: "The user canceled the operation",
|
||||||
|
LDAPResultParamError: "An invalid parameter was specified",
|
||||||
|
LDAPResultNoMemory: "Out of memory error",
|
||||||
|
LDAPResultConnectError: "A connection to the server could not be established",
|
||||||
|
LDAPResultNotSupported: "An attempt has been made to use a feature not supported LDAP",
|
||||||
|
LDAPResultControlNotFound: "The controls required to perform the requested operation were not found",
|
||||||
|
LDAPResultNoResultsReturned: "No results were returned from the server",
|
||||||
|
LDAPResultMoreResultsToReturn: "There are more results in the chain of results",
|
||||||
|
LDAPResultClientLoop: "A loop has been detected. For example when following referrals",
|
||||||
|
LDAPResultReferralLimitExceeded: "The referral hop limit has been exceeded",
|
||||||
|
LDAPResultCanceled: "Operation was canceled",
|
||||||
|
LDAPResultNoSuchOperation: "Server has no knowledge of the operation requested for cancellation",
|
||||||
|
LDAPResultTooLate: "Too late to cancel the outstanding operation",
|
||||||
|
LDAPResultCannotCancel: "The identified operation does not support cancellation or the cancel operation cannot be performed",
|
||||||
|
LDAPResultAssertionFailed: "An assertion control given in the LDAP operation evaluated to false causing the operation to not be performed",
|
||||||
|
LDAPResultSyncRefreshRequired: "Refresh Required",
|
||||||
|
LDAPResultInvalidResponse: "Invalid Response",
|
||||||
|
LDAPResultAmbiguousResponse: "Ambiguous Response",
|
||||||
|
LDAPResultTLSNotSupported: "Tls Not Supported",
|
||||||
|
LDAPResultIntermediateResponse: "Intermediate Response",
|
||||||
|
LDAPResultUnknownType: "Unknown Type",
|
||||||
|
LDAPResultAuthorizationDenied: "Authorization Denied",
|
||||||
|
|
||||||
|
ErrorNetwork: "Network Error",
|
||||||
|
ErrorFilterCompile: "Filter Compile Error",
|
||||||
|
ErrorFilterDecompile: "Filter Decompile Error",
|
||||||
|
ErrorDebugging: "Debugging Error",
|
||||||
|
ErrorUnexpectedMessage: "Unexpected Message",
|
||||||
|
ErrorUnexpectedResponse: "Unexpected Response",
|
||||||
|
ErrorEmptyPassword: "Empty password not allowed by the client",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error holds LDAP error information
|
||||||
|
type Error struct {
|
||||||
|
// Err is the underlying error
|
||||||
|
Err error
|
||||||
|
// ResultCode is the LDAP error code
|
||||||
|
ResultCode uint16
|
||||||
|
// MatchedDN is the matchedDN returned if any
|
||||||
|
MatchedDN string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLDAPError creates an Error out of a BER packet representing a LDAPResult
|
||||||
|
// The return is an error object. It can be casted to a Error structure.
|
||||||
|
// This function returns nil if resultCode in the LDAPResult sequence is success(0).
|
||||||
|
func GetLDAPError(packet *ber.Packet) error {
|
||||||
|
if packet == nil {
|
||||||
|
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty packet")}
|
||||||
|
} else if len(packet.Children) >= 2 {
|
||||||
|
response := packet.Children[1]
|
||||||
|
if response == nil {
|
||||||
|
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet")}
|
||||||
|
}
|
||||||
|
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
|
||||||
|
resultCode := uint16(response.Children[0].Value.(int64))
|
||||||
|
if resultCode == 0 { // No error
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Error{ResultCode: resultCode, MatchedDN: response.Children[1].Value.(string),
|
||||||
|
Err: fmt.Errorf(response.Children[2].Value.(string))}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid packet format")}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewError creates an LDAP error with the given code and underlying error
|
||||||
|
func NewError(resultCode uint16, err error) error {
|
||||||
|
return &Error{ResultCode: resultCode, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
|
||||||
|
func IsErrorWithCode(err error, desiredResultCode uint16) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
serverError, ok := err.(*Error)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverError.ResultCode == desiredResultCode
|
||||||
|
}
|
@ -1,7 +1,3 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
@ -0,0 +1,104 @@
|
|||||||
|
// Package ldap - moddn.go contains ModifyDN functionality
|
||||||
|
//
|
||||||
|
// https://tools.ietf.org/html/rfc4511
|
||||||
|
// ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
|
||||||
|
// entry LDAPDN,
|
||||||
|
// newrdn RelativeLDAPDN,
|
||||||
|
// deleteoldrdn BOOLEAN,
|
||||||
|
// newSuperior [0] LDAPDN OPTIONAL }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"gopkg.in/asn1-ber.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModifyDNRequest holds the request to modify a DN
|
||||||
|
type ModifyDNRequest struct {
|
||||||
|
DN string
|
||||||
|
NewRDN string
|
||||||
|
DeleteOldRDN bool
|
||||||
|
NewSuperior string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewModifyDNRequest creates a new request which can be passed to ModifyDN().
|
||||||
|
//
|
||||||
|
// To move an object in the tree, set the "newSup" to the new parent entry DN. Use an
|
||||||
|
// empty string for just changing the object's RDN.
|
||||||
|
//
|
||||||
|
// For moving the object without renaming, the "rdn" must be the first
|
||||||
|
// RDN of the given DN.
|
||||||
|
//
|
||||||
|
// A call like
|
||||||
|
// mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "")
|
||||||
|
// will setup the request to just rename uid=someone,dc=example,dc=org to
|
||||||
|
// uid=newname,dc=example,dc=org.
|
||||||
|
func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest {
|
||||||
|
return &ModifyDNRequest{
|
||||||
|
DN: dn,
|
||||||
|
NewRDN: rdn,
|
||||||
|
DeleteOldRDN: delOld,
|
||||||
|
NewSuperior: newSup,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m ModifyDNRequest) encode() *ber.Packet {
|
||||||
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request")
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.NewRDN, "New RDN"))
|
||||||
|
request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, m.DeleteOldRDN, "Delete old RDN"))
|
||||||
|
if m.NewSuperior != "" {
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, m.NewSuperior, "New Superior"))
|
||||||
|
}
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyDN renames the given DN and optionally move to another base (when the "newSup" argument
|
||||||
|
// to NewModifyDNRequest() is not "").
|
||||||
|
func (l *Conn) ModifyDN(m *ModifyDNRequest) error {
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
|
packet.AppendChild(m.encode())
|
||||||
|
|
||||||
|
l.Debug.PrintPacket(packet)
|
||||||
|
|
||||||
|
msgCtx, err := l.sendMessage(packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer l.finishMessage(msgCtx)
|
||||||
|
|
||||||
|
l.Debug.Printf("%d: waiting for response", msgCtx.id)
|
||||||
|
packetResponse, ok := <-msgCtx.responses
|
||||||
|
if !ok {
|
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
|
||||||
|
}
|
||||||
|
packet, err = packetResponse.ReadPacket()
|
||||||
|
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.Debug {
|
||||||
|
if err := addLDAPDescriptions(packet); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ber.PrintPacket(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.Children[1].Tag == ApplicationModifyDNResponse {
|
||||||
|
err := GetLDAPError(packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Debug.Printf("%d: returning", msgCtx.id)
|
||||||
|
return nil
|
||||||
|
}
|
17
vendor/gopkg.in/ldap.v2/passwdmodify.go → vendor/gopkg.in/ldap.v3/passwdmodify.go
generated
vendored
17
vendor/gopkg.in/ldap.v2/passwdmodify.go → vendor/gopkg.in/ldap.v3/passwdmodify.go
generated
vendored
Loading…
Reference in New Issue