Skip to content

Commit 21d1415

Browse files
authored
chore: Mirror v3 to root directory (#468)
1 parent 80095a3 commit 21d1415

File tree

7 files changed

+292
-35
lines changed

7 files changed

+292
-35
lines changed

bind.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ func (l *Conn) GSSAPIBind(client GSSAPIClient, servicePrincipal, authzid string)
614614

615615
// GSSAPIBindRequest performs the GSSAPI SASL bind using the provided GSSAPI client.
616616
func (l *Conn) GSSAPIBindRequest(client GSSAPIClient, req *GSSAPIBindRequest) error {
617-
// nolint:errcheck
617+
//nolint:errcheck
618618
defer client.DeleteSecContext()
619619

620620
var err error

conn.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,9 @@ func (l *Conn) Close() (err error) {
288288
l.chanMessage <- &messagePacket{Op: MessageQuit}
289289

290290
timeoutCtx := context.Background()
291-
requestTimeout := l.getTimeout()
292-
if requestTimeout > 0 {
291+
if l.getTimeout() > 0 {
293292
var cancelFunc context.CancelFunc
294-
timeoutCtx, cancelFunc = context.WithTimeout(timeoutCtx, time.Duration(requestTimeout))
293+
timeoutCtx, cancelFunc = context.WithTimeout(timeoutCtx, time.Duration(l.getTimeout()))
295294
defer cancelFunc()
296295
}
297296
select {

conn_test.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ func TestUnresponsiveConnection(t *testing.T) {
5858
}
5959
}
6060

61-
// TestInvalidStateCloseDeadlock tests that we do not enter deadlock when the
62-
// message handler is blocked or inactive.
63-
func TestInvalidStateCloseDeadlock(t *testing.T) {
61+
func TestRequestTimeoutDeadlock(t *testing.T) {
6462
// The do-nothing server that accepts requests and does nothing
6563
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
6664
}))
@@ -72,14 +70,23 @@ func TestInvalidStateCloseDeadlock(t *testing.T) {
7270

7371
// Create an Ldap connection
7472
conn := NewConn(c, false)
75-
conn.SetTimeout(time.Millisecond)
73+
conn.Start()
74+
// trigger a race condition on accessing request timeout
75+
n := 3
76+
for i := 0; i < n; i++ {
77+
go func() {
78+
conn.SetTimeout(time.Millisecond)
79+
}()
80+
}
7681

7782
// Attempt to close the connection when the message handler is
7883
// blocked or inactive
7984
conn.Close()
8085
}
8186

82-
func TestRequestTimeoutDeadlock(t *testing.T) {
87+
// TestInvalidStateCloseDeadlock tests that we do not enter deadlock when the
88+
// message handler is blocked or inactive.
89+
func TestInvalidStateCloseDeadlock(t *testing.T) {
8390
// The do-nothing server that accepts requests and does nothing
8491
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
8592
}))
@@ -91,14 +98,7 @@ func TestRequestTimeoutDeadlock(t *testing.T) {
9198

9299
// Create an Ldap connection
93100
conn := NewConn(c, false)
94-
conn.Start()
95-
// trigger a race condition on accessing request timeout
96-
n := 3
97-
for i := 0; i < n; i++ {
98-
go func() {
99-
conn.SetTimeout(time.Millisecond)
100-
}()
101-
}
101+
conn.SetTimeout(time.Millisecond)
102102

103103
// Attempt to close the connection when the message handler is
104104
// blocked or inactive

control.go

+219-16
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ const (
2424
// ControlTypeSubtreeDelete - https://datatracker.ietf.org/doc/html/draft-armijo-ldap-treedelete-02
2525
ControlTypeSubtreeDelete = "1.2.840.113556.1.4.805"
2626

27+
// ControlTypeServerSideSorting - https://www.ietf.org/rfc/rfc2891.txt
28+
ControlTypeServerSideSorting = "1.2.840.113556.1.4.473"
29+
// ControlTypeServerSideSorting - https://www.ietf.org/rfc/rfc2891.txt
30+
ControlTypeServerSideSortingResult = "1.2.840.113556.1.4.474"
31+
2732
// ControlTypeMicrosoftNotification - https://msdn.microsoft.com/en-us/library/aa366983(v=vs.85).aspx
2833
ControlTypeMicrosoftNotification = "1.2.840.113556.1.4.528"
2934
// ControlTypeMicrosoftShowDeleted - https://msdn.microsoft.com/en-us/library/aa366989(v=vs.85).aspx
@@ -53,18 +58,20 @@ const (
5358

5459
// ControlTypeMap maps controls to text descriptions
5560
var ControlTypeMap = map[string]string{
56-
ControlTypePaging: "Paging",
57-
ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
58-
ControlTypeManageDsaIT: "Manage DSA IT",
59-
ControlTypeSubtreeDelete: "Subtree Delete Control",
60-
ControlTypeMicrosoftNotification: "Change Notification - Microsoft",
61-
ControlTypeMicrosoftShowDeleted: "Show Deleted Objects - Microsoft",
62-
ControlTypeMicrosoftServerLinkTTL: "Return TTL-DNs for link values with associated expiry times - Microsoft",
63-
ControlTypeDirSync: "DirSync",
64-
ControlTypeSyncRequest: "Sync Request",
65-
ControlTypeSyncState: "Sync State",
66-
ControlTypeSyncDone: "Sync Done",
67-
ControlTypeSyncInfo: "Sync Info",
61+
ControlTypePaging: "Paging",
62+
ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
63+
ControlTypeManageDsaIT: "Manage DSA IT",
64+
ControlTypeSubtreeDelete: "Subtree Delete Control",
65+
ControlTypeMicrosoftNotification: "Change Notification - Microsoft",
66+
ControlTypeMicrosoftShowDeleted: "Show Deleted Objects - Microsoft",
67+
ControlTypeMicrosoftServerLinkTTL: "Return TTL-DNs for link values with associated expiry times - Microsoft",
68+
ControlTypeServerSideSorting: "Server Side Sorting Request - LDAP Control Extension for Server Side Sorting of Search Results (RFC2891)",
69+
ControlTypeServerSideSortingResult: "Server Side Sorting Results - LDAP Control Extension for Server Side Sorting of Search Results (RFC2891)",
70+
ControlTypeDirSync: "DirSync",
71+
ControlTypeSyncRequest: "Sync Request",
72+
ControlTypeSyncState: "Sync State",
73+
ControlTypeSyncDone: "Sync Done",
74+
ControlTypeSyncInfo: "Sync Info",
6875
}
6976

7077
// Control defines an interface controls provide to encode and describe themselves
@@ -521,6 +528,10 @@ func DecodeControl(packet *ber.Packet) (Control, error) {
521528
return NewControlMicrosoftServerLinkTTL(), nil
522529
case ControlTypeSubtreeDelete:
523530
return NewControlSubtreeDelete(), nil
531+
case ControlTypeServerSideSorting:
532+
return NewControlServerSideSorting(value)
533+
case ControlTypeServerSideSortingResult:
534+
return NewControlServerSideSortingResult(value)
524535
case ControlTypeDirSync:
525536
value.Description += " (DirSync)"
526537
return NewResponseControlDirSync(value)
@@ -716,6 +727,193 @@ func (c *ControlDirSync) SetCookie(cookie []byte) {
716727
c.Cookie = cookie
717728
}
718729

730+
// ControlServerSideSorting
731+
732+
type SortKey struct {
733+
Reverse bool
734+
AttributeType string
735+
MatchingRule string
736+
}
737+
738+
type ControlServerSideSorting struct {
739+
SortKeys []*SortKey
740+
}
741+
742+
func (c *ControlServerSideSorting) GetControlType() string {
743+
return ControlTypeServerSideSorting
744+
}
745+
746+
func NewControlServerSideSorting(value *ber.Packet) (*ControlServerSideSorting, error) {
747+
sortKeys := []*SortKey{}
748+
749+
val := value.Children[1].Children
750+
751+
if len(val) != 1 {
752+
return nil, fmt.Errorf("no sequence value in packet")
753+
}
754+
755+
sequences := val[0].Children
756+
757+
for i, sequence := range sequences {
758+
sortKey := &SortKey{}
759+
760+
if len(sequence.Children) < 2 {
761+
return nil, fmt.Errorf("attributeType or matchingRule is missing from sequence %d", i)
762+
}
763+
764+
sortKey.AttributeType = sequence.Children[0].Value.(string)
765+
sortKey.MatchingRule = sequence.Children[1].Value.(string)
766+
767+
if len(sequence.Children) == 3 {
768+
sortKey.Reverse = sequence.Children[2].Value.(bool)
769+
}
770+
771+
sortKeys = append(sortKeys, sortKey)
772+
}
773+
774+
return &ControlServerSideSorting{SortKeys: sortKeys}, nil
775+
}
776+
777+
func NewControlServerSideSortingWithSortKeys(sortKeys []*SortKey) *ControlServerSideSorting {
778+
return &ControlServerSideSorting{SortKeys: sortKeys}
779+
}
780+
781+
func (c *ControlServerSideSorting) Encode() *ber.Packet {
782+
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
783+
control := ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.GetControlType(), "Control Type")
784+
785+
value := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value")
786+
seqs := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "SortKeyList")
787+
788+
for _, f := range c.SortKeys {
789+
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "")
790+
791+
seq.AppendChild(
792+
ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, f.AttributeType, "attributeType"),
793+
)
794+
seq.AppendChild(
795+
ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, f.MatchingRule, "orderingRule"),
796+
)
797+
if f.Reverse {
798+
seq.AppendChild(
799+
ber.NewBoolean(ber.ClassContext, ber.TypePrimitive, 1, f.Reverse, "reverseOrder"),
800+
)
801+
}
802+
803+
seqs.AppendChild(seq)
804+
}
805+
806+
value.AppendChild(seqs)
807+
808+
packet.AppendChild(control)
809+
packet.AppendChild(value)
810+
811+
return packet
812+
}
813+
814+
func (c *ControlServerSideSorting) String() string {
815+
return fmt.Sprintf(
816+
"Control Type: %s (%q) Criticality:%t %+v",
817+
"Server Side Sorting",
818+
c.GetControlType(),
819+
false,
820+
c.SortKeys,
821+
)
822+
}
823+
824+
// ControlServerSideSortingResponse
825+
826+
const (
827+
ControlServerSideSortingCodeSuccess ControlServerSideSortingCode = 0
828+
ControlServerSideSortingCodeOperationsError ControlServerSideSortingCode = 1
829+
ControlServerSideSortingCodeTimeLimitExceeded ControlServerSideSortingCode = 2
830+
ControlServerSideSortingCodeStrongAuthRequired ControlServerSideSortingCode = 8
831+
ControlServerSideSortingCodeAdminLimitExceeded ControlServerSideSortingCode = 11
832+
ControlServerSideSortingCodeNoSuchAttribute ControlServerSideSortingCode = 16
833+
ControlServerSideSortingCodeInappropriateMatching ControlServerSideSortingCode = 18
834+
ControlServerSideSortingCodeInsufficientAccessRights ControlServerSideSortingCode = 50
835+
ControlServerSideSortingCodeBusy ControlServerSideSortingCode = 51
836+
ControlServerSideSortingCodeUnwillingToPerform ControlServerSideSortingCode = 53
837+
ControlServerSideSortingCodeOther ControlServerSideSortingCode = 80
838+
)
839+
840+
var ControlServerSideSortingCodes = []ControlServerSideSortingCode{
841+
ControlServerSideSortingCodeSuccess,
842+
ControlServerSideSortingCodeOperationsError,
843+
ControlServerSideSortingCodeTimeLimitExceeded,
844+
ControlServerSideSortingCodeStrongAuthRequired,
845+
ControlServerSideSortingCodeAdminLimitExceeded,
846+
ControlServerSideSortingCodeNoSuchAttribute,
847+
ControlServerSideSortingCodeInappropriateMatching,
848+
ControlServerSideSortingCodeInsufficientAccessRights,
849+
ControlServerSideSortingCodeBusy,
850+
ControlServerSideSortingCodeUnwillingToPerform,
851+
ControlServerSideSortingCodeOther,
852+
}
853+
854+
type ControlServerSideSortingCode int64
855+
856+
// Valid test the code contained in the control against the ControlServerSideSortingCodes slice and return an error if the code is unknown.
857+
func (c ControlServerSideSortingCode) Valid() error {
858+
for _, validRet := range ControlServerSideSortingCodes {
859+
if c == validRet {
860+
return nil
861+
}
862+
}
863+
return fmt.Errorf("unknown return code : %d", c)
864+
}
865+
866+
func NewControlServerSideSortingResult(pkt *ber.Packet) (*ControlServerSideSortingResult, error) {
867+
control := &ControlServerSideSortingResult{}
868+
869+
if pkt == nil || len(pkt.Children) == 0 {
870+
return nil, fmt.Errorf("bad packet")
871+
}
872+
873+
codeInt, err := ber.ParseInt64(pkt.Children[0].Data.Bytes())
874+
if err != nil {
875+
return nil, err
876+
}
877+
878+
code := ControlServerSideSortingCode(codeInt)
879+
if err := code.Valid(); err != nil {
880+
return nil, err
881+
}
882+
883+
return control, nil
884+
}
885+
886+
type ControlServerSideSortingResult struct {
887+
Criticality bool
888+
889+
Result ControlServerSideSortingCode
890+
891+
// Not populated for now. I can't get openldap to send me this value, so I think this is specific to other directory server
892+
// AttributeType string
893+
}
894+
895+
func (control *ControlServerSideSortingResult) GetControlType() string {
896+
return ControlTypeServerSideSortingResult
897+
}
898+
899+
func (c *ControlServerSideSortingResult) Encode() *ber.Packet {
900+
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "SortResult sequence")
901+
sortResult := ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, int64(c.Result), "SortResult")
902+
packet.AppendChild(sortResult)
903+
904+
return packet
905+
}
906+
907+
func (c *ControlServerSideSortingResult) String() string {
908+
return fmt.Sprintf(
909+
"Control Type: %s (%q) Criticality:%t ResultCode:%+v",
910+
"Server Side Sorting Result",
911+
c.GetControlType(),
912+
c.Criticality,
913+
c.Result,
914+
)
915+
}
916+
719917
// Mode for ControlTypeSyncRequest
720918
type ControlSyncRequestMode int64
721919

@@ -752,9 +950,12 @@ func (c *ControlSyncRequest) GetControlType() string {
752950
func (c *ControlSyncRequest) Encode() *ber.Packet {
753951
_mode := int64(c.Mode)
754952
mode := ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, _mode, "Mode")
755-
cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
756-
cookie.Value = c.Cookie
757-
cookie.Data.Write(c.Cookie)
953+
var cookie *ber.Packet
954+
if len(c.Cookie) > 0 {
955+
cookie = ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
956+
cookie.Value = c.Cookie
957+
cookie.Data.Write(c.Cookie)
958+
}
758959
reloadHint := ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.ReloadHint, "Reload Hint")
759960

760961
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
@@ -764,7 +965,9 @@ func (c *ControlSyncRequest) Encode() *ber.Packet {
764965
val := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Sync Request)")
765966
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Sync Request Value")
766967
seq.AppendChild(mode)
767-
seq.AppendChild(cookie)
968+
if cookie != nil {
969+
seq.AppendChild(cookie)
970+
}
768971
seq.AppendChild(reloadHint)
769972
val.AppendChild(seq)
770973

0 commit comments

Comments
 (0)