Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Extended request operations #516

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

cpuschma
Copy link
Member

This implements the base for "Extended Requests" as defined in RFC2251 Section 4.12. I'm having trouble getting the requestValue to work, as this seems to get ignored by the server and Wireshark showing errors regarding unexpected fields. Additionally, submitting the requestName as LDAPOID (basically an alias for an BER-encoded OCTET STRING), the server immediately closes the connection without returning an error (tested against Active Directory and OpenLDAP). It works when switching to ber.TagEOC.

I'm open for ideas or anyone who has experience with implementing the "Extended Request" operation!

@cpuschma
Copy link
Member Author

@Denis-shl
Copy link

@cpuschma hi, I ran into the same problem and I'm working on it now.Tell me, did you manage to implement it?

@JesseCoretta
Copy link

This implements the base for "Extended Requests" as defined in RFC2251 Section 4.12.

Hi @cpuschma -- I'm going to try and reproduce this behavior on my end and see if I can discern what is going on.

Also, just in case you didn't already realize it, RFC2251 was obsoleted by RFC4511. The section number in question, however, remains 4.12.

Jesse 😃

@JesseCoretta
Copy link

JesseCoretta commented Oct 18, 2024

This implements the base for "Extended Requests" as defined in RFC2251 Section 4.12. I'm having trouble getting the requestValue to work, as this seems to get ignored by the server and Wireshark showing errors regarding unexpected fields. Additionally, submitting the requestName as LDAPOID (basically an alias for an BER-encoded OCTET STRING), the server immediately closes the connection without returning an error (tested against Active Directory and OpenLDAP). It works when switching to ber.TagEOC.

I'm open for ideas or anyone who has experience with implementing the "Extended Request" operation!

OK, to begin I cloned the feat/extend_request branch from your repo. I decided I'd just add a new Unit Test to be lazy. I decided to start with LDAP "Who Am I?" per RFC 4532.

As the hostname implies, I am using OpenDJ on my local system.

func TestExtendedRequest_Jesse(t *testing.T) {                          
        l, err := DialURL("ldap://opendj.example.com:389")              
        if err != nil {                                                 
                t.Errorf("%s failed: %v", t.Name(), err)                
                return                                                  
        }                                                               
        defer l.Close()

        l.Bind(``,``) // anonymous                                    
        //l.Bind(`cn=Directory Manager`,`password`) // my test root dn
        defer l.Unbind()

        rfc4532req := NewExtendedRequest(`1.3.6.1.4.1.4203.1.11.3`, nil)  // request value is <nil>

        var rfc4532resp *ExtendResponse
        if rfc4532resp, err = l.Extended(rfc4532req); err != nil {
                t.Errorf("%s failed: %v", t.Name(), err)
                return
        }

        t.Logf("%#v\n", rfc4532resp)
}
=== RUN   TestExtendedRequest_Jesse
    examples_test.go:45: &ldap.ExtendResponse{Name:"dn:", Value:(*ber.Packet)(nil)}
--- PASS: TestExtendedRequest_Jesse (0.13s)
PASS
ok  	github.com/go-ldap/ldap	0.132s

If I swap the Bind user to someone not anonymous, the response is also correct (for OpenDJ):

=== RUN   TestExtendedRequest_Jesse
    examples_test.go:49: &ldap.ExtendResponse{Name:"dn:cn=Directory Manager,cn=Root DNs,cn=config", Value:(*ber.Packet)(nil)}
--- PASS: TestExtendedRequest_Jesse (0.01s)

Now ... these are the correct results. The requestValue is supposed to be empty in the context of this particular extended request. You mentioned the server ignores it ... I suspect that is intentional and expected in some cases. For instance, note the following excerpt from RFC 4532 section 2.1:

   The whoami request is an ExtendedRequest with a requestName field
   containing the whoamiOID OID and an absent requestValue field.  For
   example, a whoami request could be encoded as the sequence of octets
   (in hex):

      30 1e 02 01 02 77 19 80  17 31 2e 33 2e 36 2e 31
      2e 34 2e 31 2e 34 32 30  33 2e 31 2e 31 31 2e 33

Note that specific detail:

... and an absent requestValue field ...

        ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
             requestName      [0] LDAPOID,
             requestValue     [1] OCTET STRING OPTIONAL }

Note it is OPTIONAL, as indicated. I am wondering if you were getting unexpected results because the OID you were testing with was perhaps of a similar use to LDAP "Who Am I?", in that NO value is expected? This is a wild, wild guess, but I'm offering it nonetheless.

Jesse 😃

@JesseCoretta
Copy link

Implementation suggestions:

  • I realize this is nit-picky, but type ExtendResponse struct should probably be type ExtendedResponse struct
  • Given that the requestValue MAY be nil, consider changing the NewExtendedRequest function signature to allow variadic input, e.g.: NewExtendedRequest(name string, value ...*ber.Packet) *ExtendedRequest { for convenience

@cpuschma
Copy link
Member Author

@JesseCoretta Thank you for pointing out the obsolete RFC document, didn't notice that! Also thank you for your suggestions regarding the function signatures 👍

@JesseCoretta
Copy link

@JesseCoretta Thank you for pointing out the obsolete RFC document, didn't notice that! Also thank you for your suggestions regarding the function signatures 👍

@cpuschma ... happy to help. Did you see my second comment, regarding the "Who Am I?" operation? If you tell me what OID you were testing with, I can reproduce on my end. I only used RFC 4532 because it is well known, no idea if thats what you were testing....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants