vforteli/Flexinets.Ldap.Server

Question: push more properties

Sammuel-Miranda opened this issue · 22 comments

Hi, first of all, great project - actualy, maybe the greatest project ever! Since it's so simple (both this one and it's dependecy) - so congratulations.

I'm trying to do a little more than that, but due to my lack of knowledge on the subject (and even reading the RFC4511 documentation) i can't seem to be able to properly send FirstName, LastName and e-mail (for outlook to read it) as a property/value pair.

Can you point out the proper way to do it? I placed it on your code just by this (on the HandleSearchRequest method):

private void HandleSearchRequest(NetworkStream stream, LdapPacket requestPacket)
        {
            var searchRequest = requestPacket.ChildAttributes.SingleOrDefault(o => o.LdapOperation == LdapOperation.SearchRequest);
            var filter = searchRequest.ChildAttributes[6];
            if ((LdapFilterChoice)filter.ContextType == LdapFilterChoice.equalityMatch && filter.ChildAttributes[0].GetValue<String>() == "sAMAccountName" && filter.ChildAttributes[1].GetValue<String>() == "testuser") // equalityMatch
            {
                var responseEntryPacket = new LdapPacket(requestPacket.MessageId);
                var searchResultEntry = new LdapAttribute(LdapOperation.SearchResultEntry);
                searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "cn=testuser,cn=Users,dc=dev,dc=company,dc=com"));
                //this was my first try
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "mail=testuser@company.com"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "givenName=userfirstname"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "surname=userlastname"));
                //up to here, then later i tryed this
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "mail"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "testuser@company.com"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.Sequence));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "givenName"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "userfirstname"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.Sequence));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "surname"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "userlastname"));
                //searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.Sequence));
                //up to here | both without success
                searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.Sequence));
                responseEntryPacket.ChildAttributes.Add(searchResultEntry);
                var responsEntryBytes = responseEntryPacket.GetBytes();
                stream.Write(responsEntryBytes, 0, responsEntryBytes.Length);
            }
            var responseDonePacket = new LdapPacket(requestPacket.MessageId);
            responseDonePacket.ChildAttributes.Add(new LdapResultAttribute(LdapOperation.SearchResultDone, LdapResult.success));
            var responseDoneBytes = responseDonePacket.GetBytes();
            stream.Write(responseDoneBytes, 0, responseDoneBytes.Length);
        }

Sorry, i beleave issue #2 Issue constructing answers my question (it was closed and i didn't see it).

I think you may get away with something like this

var partialAttributeList = new LdapAttribute(UniversalDataType.Sequence);
var givenNameAttribute = new LdapAttribute(UniversalDataType.Sequence);
givenNameAttribute.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "givenName"));
givenNameAttribute.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "John"));
partialAttributeList.ChildAttributes.Add(givenNameAttribute);

ps. I think the surname attribute name should be just "sn", could be wrong though

Sorry to return this (closed it before) - i forked the project here but still, using the method provided by you here and on the #2 Issue constructing post i have problems still. If the "partialAttributeList" (as discribed on the #2 ) exceeds 255 bytes when converted to byte array, it causes the issue. What can be done?

PS: here's the fork - @Sammuel-Miranda/LdapServerLib

Basicaly, i refered here to call on the method you showed before:
LdapServer.cs, line 590

Made some changes, the method is now on LdapServer.cs, line637; still not enought to do any good.

Oh, never noticed the edited comment a while ago. Ill have a look

Ok, I know exactly what the problem is, and a fix is on its way

Thank you for seeing so fast - i'm away for now (at home) and i don't have Outlook here to try to connect - tryed with Thunderbird, but in that case, neither way worked (that is due to thunderbird, for some reason, only sending the Bind request - no search request sent whatsoever) - i'll try on outllok (monday) to see if it worked.

Hi there - awesome! Outlook works perfectly with the changed code - but Mozilla Thunderbird not so much - it sends only the BindRequest, not the SearchRequest! I'll check about it on the Mozilla forum.

Thank you so much.

Well, if you have some packet dump I can see if there is something obvious

Sure! You really are very helpful!
This is a log of thunderbird (i wrote it to be hexadecimal - so every couple of characters are 1 byte as HEX).

Basically this is 1 call from Outlook:

income: (a bind request from outlook)
3002010A608400000011020103040561646D696E80053132333435

outgo: (my bind response)
300F02040000000A61070A010004000400

income: (i pressed "n" key in the search box on outlook)
3002010B63840000018E041A636E3D55736572732C64633D636F6D70616E792C64633D636F6D0A01020A0103020203E702010F010100A08400000077A18400000071A4840000000F04046D61696C30840000000380016EA4840000000D0402636E30840000000380016EA4840000000D0402736E30840000000380016EA484000000140409676976656E4E616D6530840000000380016EA48400000016040B646973706C61794E616D6530840000000380016E3084000000DF0402636E040A636F6D6D6F6E4E616D6504046D61696C040C726F6C654F63637570616E74040C646973706C61792D6E616D65040B646973706C61796E616D650402736E04077375726E616D650402636F04106F7267616E697A6174696F6E4E616D6504016F0409676976656E4E616D6504106C656761637945786368616E6765444E040B6F626A656374436C6173730403756964040C6D61696C4E69636B6E616D6504057469746C650407636F6D70616E79041A706879736963616C44656C69766572794F66666963654E616D65040F74656C6570686F6E654E756D626572

outgo: (my 3 result entries)
30840000012702040000000B64840000011B042C636E3D61696E7A2E6F6F616C2E676F776E2C636E3D55736572732C64633D636F6D70616E792C64633D636F6D3084000000E730160402636E3110040E61696E7A2E6F6F616C2E676F776E301E040A636F6D6D6F6E4E616D653110040E61696E7A2E6F6F616C2E676F776E301F04046D61696C3117041561696E7A73616D61406E617A617269636B2E636F6D301F040B646973706C61796E616D653110040E41696E7A204F6F616C20476F776E3020040C646973706C61792D6E616D653110040E41696E7A204F6F616C20476F776E301A0407636F6D70616E79310F040D4E617A617269636B20496E632E302D040B6F626A656374436C617373311E040E73414D4163636F756E744E616D65040C506F7369784163636F756E74

30840000013302040000000B648400000127042B636E3D7368616C6C746561722E6266662C636E3D55736572732C64633D636F6D70616E792C64633D636F6D3084000000F430150402636E310F040D7368616C6C746561722E626666301D040A636F6D6D6F6E4E616D65310F040D7368616C6C746561722E626666302004046D61696C311804167368616C6C74656172406E617A617269636B2E636F6D3026040B646973706C61796E616D65311704155368616C6C7465617220426C6F6F6466616C6C656E3027040C646973706C61792D6E616D65311704155368616C6C7465617220426C6F6F6466616C6C656E301A0407636F6D70616E79310F040D4E617A617269636B20496E632E302D040B6F626A656374436C617373311E040E73414D4163636F756E744E616D65040C506F7369784163636F756E74

30840000011502040000000B6484000001090426636E3D6E6172626572616C2C636E3D55736572732C64633D636F6D70616E792C64633D636F6D3084000000DB30100402636E310A04086E6172626572616C3018040A636F6D6D6F6E4E616D65310A04086E6172626572616C301F04046D61696C311704156E6172626572616C406E617A617269636B2E636F6D301F040B646973706C61796E616D653110040E4E6172626572616C2047616D6D613020040C646973706C61792D6E616D653110040E4E6172626572616C2047616D6D61301A0407636F6D70616E79310F040D4E617A617269636B20496E632E302D040B6F626A656374436C617373311E040E73414D4163636F756E744E616D65040C506F7369784163636F756E74

outgo: (my search done response)
300F02040000000B65070A010004000400

This is working great so far ... never thought i'd see the day! But then ... Thunderbird does this:

income: (a bind request from Thunderbird)
300201016011020103040561646D696E80053132333435

outgo: (my bind response)
300F02040000000161070A010004000400

Not only doesn't send any new requests, but also, starts consuming 100% of processing power! Crazy Thunderbirds ... so that's it.

New version available again, which may fix this

No way ... really? Uau, you're reallly fast!
I'll check it out

No luck - i'll post questions about it on Mozilla's forum. The code from my Fork of your project @Sammuel-Miranda/LdapServerLib is updated be your changes, and Outlook runs smooth on it; for some unknow reason (unknow to me ... lol) Thunderbird doesn't send anything back after the bind, and the processing consumption gost from 4% CPU use to 90% CPU use, until i terminate the server or Thunderbird.

I got a bit curious and just had to test it with the latest thunderbird, with the following result:

2018-10-03 20.39.13 357 :: Getting "Port" from ServiceRuntime: FAIL.
2018-10-03 20.39.13 365 :: Getting "Port" from ConfigurationManager: PASS.
2018-10-03 23:39:16,861 [10] DEBUG LdapServer - Connection from 127.0.0.1:55698
2018-10-03 23:39:16,885 [10] DEBUG LdapServer - Packet dump
> Universal:Sequence - Type: System.String - 
>> Universal:Integer - Type: System.Int32 - 1
>> Application:BindRequest - Type: System.String - 
>>> Universal:Integer - Type: System.Int32 - 3
>>> Universal:OctetString - Type: System.String - cn=user,dc=example,dc=com
>>> Context:0 - Type: System.String - 123

Bind response
2018-10-03 23:39:16,899 [10] DEBUG LdapServer - 302802010160230201030419636e3d757365722c64633d6578616d706c652c64633d636f6d8003313233
2018-10-03 23:39:16,914 [10] DEBUG LdapServer - response
2018-10-03 23:39:16,917 [10] DEBUG LdapServer - > Universal:Sequence - Type: System.String - 
>> Universal:Integer - Type: System.Int32 - 1
>> Application:BindResponse - Type: System.String - 
>>> Universal:Enumerated - Type: System.String - 
>>> Universal:OctetString - Type: System.String - cn=foo,dc=example,dc=com
>>> Universal:OctetString - Type: System.String - 

Here thunderbird sends the searchrequest after the bind response:
2018-10-03 23:39:16,930 [10] DEBUG LdapServer - Packet dump
> Universal:Sequence - Type: System.String - 
>> Universal:Integer - Type: System.Int32 - 2
>> Application:SearchRequest - Type: System.String - 
>>> Universal:OctetString - Type: System.String - dc=example,dc=com
>>> Universal:Enumerated - Type: System.String - �
>>> Universal:Enumerated - Type: System.String - 
>>> Universal:Integer - Type: System.Int32 - 100
>>> Universal:Integer - Type: System.Int32 - 0
>>> Universal:Boolean - Type: System.Boolean - False
>>> Context:0 - Type: System.String - 
>>>> Context:1 - Type: System.String - 
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - cn
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - givenName
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - sn
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - mozillaNickname
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - mail
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - mozillaSecondEmail
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:0 - Type: System.String - 
>>>>>> Context:4 - Type: System.String - 
>>>>>>> Universal:OctetString - Type: System.String - description
>>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - o
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - ou
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - title
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - mozillaWorkUrl
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>>>> Context:4 - Type: System.String - 
>>>>>> Universal:OctetString - Type: System.String - mozillaHomeUrl
>>>>>> Universal:Sequence - Type: System.String - 
>>>>>>> Context:1 - Type: System.String - hmm
>>> Universal:Sequence - Type: System.String - 
>>>> Universal:OctetString - Type: System.String - title
>>>> Universal:OctetString - Type: System.String - sn
>>>> Universal:OctetString - Type: System.String - surname
>>>> Universal:OctetString - Type: System.String - mozillaHomeLocalityName
>>>> Universal:OctetString - Type: System.String - cn
>>>> Universal:OctetString - Type: System.String - commonname
>>>> Universal:OctetString - Type: System.String - givenName
>>>> Universal:OctetString - Type: System.String - mozillaHomeState
>>>> Universal:OctetString - Type: System.String - mail
>>>> Universal:OctetString - Type: System.String - o
>>>> Universal:OctetString - Type: System.String - company
>>>> Universal:OctetString - Type: System.String - mozillaHomeStreet2
>>>> Universal:OctetString - Type: System.String - mozillaNickname
>>>> Universal:OctetString - Type: System.String - xmozillanickname
>>>> Universal:OctetString - Type: System.String - mobile
>>>> Universal:OctetString - Type: System.String - cellphone
>>>> Universal:OctetString - Type: System.String - carphone
>>>> Universal:OctetString - Type: System.String - modifytimestamp
>>>> Universal:OctetString - Type: System.String - nsAIMid
>>>> Universal:OctetString - Type: System.String - nscpaimscreenname
>>>> Universal:OctetString - Type: System.String - telephoneNumber
>>>> Universal:OctetString - Type: System.String - birthyear
>>>> Universal:OctetString - Type: System.String - c
>>>> Universal:OctetString - Type: System.String - countryname
>>>> Universal:OctetString - Type: System.String - mozillaHomeStreet
>>>> Universal:OctetString - Type: System.String - postalCode
>>>> Universal:OctetString - Type: System.String - zip
>>>> Universal:OctetString - Type: System.String - mozillaCustom1
>>>> Universal:OctetString - Type: System.String - custom1
>>>> Universal:OctetString - Type: System.String - mozillaHomeCountryName
>>>> Universal:OctetString - Type: System.String - st
>>>> Universal:OctetString - Type: System.String - region
>>>> Universal:OctetString - Type: System.String - mozillaCustom2
>>>> Universal:OctetString - Type: System.String - custom2
>>>> Universal:OctetString - Type: System.String - mozillaHomeUrl
>>>> Universal:OctetString - Type: System.String - homeurl
>>>> Universal:OctetString - Type: System.String - mozillaWorkStreet2
>>>> Universal:OctetString - Type: System.String - mozillaSecondEmail
>>>> Universal:OctetString - Type: System.String - xmozillasecondemail
>>>> Universal:OctetString - Type: System.String - facsimiletelephonenumber
>>>> Universal:OctetString - Type: System.String - fax
>>>> Universal:OctetString - Type: System.String - description
>>>> Universal:OctetString - Type: System.String - notes
>>>> Universal:OctetString - Type: System.String - mozillaCustom3
>>>> Universal:OctetString - Type: System.String - custom3
>>>> Universal:OctetString - Type: System.String - homePhone
>>>> Universal:OctetString - Type: System.String - mozillaUseHtmlMail
>>>> Universal:OctetString - Type: System.String - xmozillausehtmlmail
>>>> Universal:OctetString - Type: System.String - birthday
>>>> Universal:OctetString - Type: System.String - street
>>>> Universal:OctetString - Type: System.String - streetaddress
>>>> Universal:OctetString - Type: System.String - postOfficeBox
>>>> Universal:OctetString - Type: System.String - mozillaCustom4
>>>> Universal:OctetString - Type: System.String - custom4
>>>> Universal:OctetString - Type: System.String - l
>>>> Universal:OctetString - Type: System.String - locality
>>>> Universal:OctetString - Type: System.String - pager
>>>> Universal:OctetString - Type: System.String - pagerphone
>>>> Universal:OctetString - Type: System.String - ou
>>>> Universal:OctetString - Type: System.String - department
>>>> Universal:OctetString - Type: System.String - departmentnumber
>>>> Universal:OctetString - Type: System.String - orgunit
>>>> Universal:OctetString - Type: System.String - birthmonth
>>>> Universal:OctetString - Type: System.String - mozillaWorkUrl
>>>> Universal:OctetString - Type: System.String - workurl
>>>> Universal:OctetString - Type: System.String - labeledURI
>>>> Universal:OctetString - Type: System.String - mozillaHomePostalCode
>>>> Universal:OctetString - Type: System.String - objectClass

2018-10-03 23:39:16,932 [10] DEBUG LdapServer - 30840000047602010263840000046d041164633d6578616d706c652c64633d636f6d0a01020a0100020164020100010100a084000000eda184000000e7a40b0402636e30058103686d6da4120409676976656e4e616d6530058103686d6da40b0402736e30058103686d6da418040f6d6f7a696c6c614e69636b6e616d6530058103686d6da40d04046d61696c30058103686d6da41b04126d6f7a696c6c615365636f6e64456d61696c30058103686d6da016a414040b6465736372697074696f6e30058103686d6da40a04016f30058103686d6da40b04026f7530058103686d6da40e04057469746c6530058103686d6da417040e6d6f7a696c6c61576f726b55726c30058103686d6da417040e6d6f7a696c6c61486f6d6555726c30058103686d6d30840000035204057469746c650402736e04077375726e616d6504176d6f7a696c6c61486f6d654c6f63616c6974794e616d650402636e040a636f6d6d6f6e6e616d650409676976656e4e616d6504106d6f7a696c6c61486f6d65537461746504046d61696c04016f0407636f6d70616e7904126d6f7a696c6c61486f6d6553747265657432040f6d6f7a696c6c614e69636b6e616d650410786d6f7a696c6c616e69636b6e616d6504066d6f62696c65040963656c6c70686f6e65040863617270686f6e65040f6d6f6469667974696d657374616d7004076e7341494d696404116e73637061696d73637265656e6e616d65040f74656c6570686f6e654e756d6265720409626972746879656172040163040b636f756e7472796e616d6504116d6f7a696c6c61486f6d65537472656574040a706f7374616c436f646504037a6970040e6d6f7a696c6c61437573746f6d310407637573746f6d3104166d6f7a696c6c61486f6d65436f756e7472794e616d65040273740406726567696f6e040e6d6f7a696c6c61437573746f6d320407637573746f6d32040e6d6f7a696c6c61486f6d6555726c0407686f6d6575726c04126d6f7a696c6c61576f726b5374726565743204126d6f7a696c6c615365636f6e64456d61696c0413786d6f7a696c6c617365636f6e64656d61696c041866616373696d696c6574656c6570686f6e656e756d6265720403666178040b6465736372697074696f6e04056e6f746573040e6d6f7a696c6c61437573746f6d330407637573746f6d330409686f6d6550686f6e6504126d6f7a696c6c6155736548746d6c4d61696c0413786d6f7a696c6c6175736568746d6c6d61696c040862697274686461790406737472656574040d73747265657461646472657373040d706f73744f6666696365426f78040e6d6f7a696c6c61437573746f6d340407637573746f6d3404016c04086c6f63616c69747904057061676572040a706167657270686f6e6504026f75040a6465706172746d656e7404106465706172746d656e746e756d62657204076f7267756e6974040a62697274686d6f6e7468040e6d6f7a696c6c61576f726b55726c0407776f726b75726c040a6c6162656c656455524904156d6f7a696c6c61486f6d65506f7374616c436f6465040b6f626a656374436c617373

fwiw this is the code i used when getting a proper search from thunderbird https://github.com/vforteli/Flexinets.Ldap.Server/tree/randomteststuff. There is a lot of test junk in there, but maybe it can be helpful.
Settings in thunderbird:
image

Huummm ... so, maybe some change i did may be provoking that. Because this Random Server, Line 96 never gets there.

And those are my settings:

Name: LocalHost
Server: 127.0.0.1
Base DN: cn=Users,dc=company,dc=com
Port: 389
Bind DN: admin

My fault! When you corrected the "BerLengthToInt" method, i only changed the code in 1 of then and Outlook worked! I saw now that both "BerLengthToInt(Stream, out Int32)" and "BerLengthToInt(Byte[], Int32, out Int32)" where different from what i had. It works on Thunderbird as well!

yes it does need a bit of refactoring in those methods :p

You really made it possible. I thank you very much for the project (as it was) and for all the analisys and upgrades - i would not have figured it out, not in a million years. I'm building my project (the fork of yours) on the filters that the SearchRequest does, and so far is giving me the results i needed. I do not intend however to implement the modification methods (add, update and delete) since the idea is to provide information to Address Books (and maybe more) softwares; primarily Microsoft Outlook and Mozilla Thunderbird. Those are ready! I'll check for more and more integrations that may be used here, but the code as it is now has everything i wanted to go into a "production" server.

So really, thank you so much.