-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
LdapException messages on Unix do not include detail #46021
Comments
cc @joperezr |
Totally agree that our error messages in Linux could and should be much better. Thanks @danmosemsft for the detailed investigation. Without going into too much detail, the issue here is that all search requests in Linux always are handled in two steps by the native library: 1) you send the request to libldap which gives you back an id to later query for the result, and 2) you query the library using that id to see the results and if there was an error with the request, that second operation returns -1 which is were we get the error message from. That said, every time that happens we also call libldap again to get the reason of the failure (which not only gives you the error code from your table above, but actually gives you the error message itself to) we are just not returning this error code and message back to the end user which is what we have to fix. I'll add a pointer here to the line that has the required info to bubble up in case someone wants to try to fix this before I get to it. |
This is the important line Line 1463 in 8d6e098
servererror and responseMessage there have the info we need. |
@joperezr hmm, just based on code inspection, I'm not sure I see what work there is beyond fixing the mapping.
#define LDAP_OPT_RESULT_CODE 0x0031
#define LDAP_OPT_ERROR_NUMBER LDAP_OPT_RESULT_CODE
#define LDAP_OPT_DIAGNOSTIC_MESSAGE 0x0032
#define LDAP_OPT_ERROR_STRING LDAP_OPT_DIAGNOSTIC_MESSAGE
#define LDAP_OPT_MATCHED_DN 0x0033
/* 0x0034 - 0x3fff not defined */ so when we request LDAP_OPT_SERVER_ERROR = 0x33 on Unix, it looks like we're actually getting LDAP_OPT_MATCHED_DN ("Sets/gets a string containing the matched DN associated to the LDAP handle") which is probably wrong. On Unix, it looks like we should be requesting LDAP_OPT_DIAGNOSTIC_MESSAGE = 0x32. |
If so then I'm guessing 90% of fixing this is just setting up the environment... |
I checked all the other I did find this ancient mention of the discrepancy On Windows we're also not trying LDAP_OPT_SERVER_EXT_ERROR. No idea whether that is useful or not - no plans to try. |
@joperezr @tarekgh the tests for S.DS.P contain instructions for using the OpenDJ server, but I wonder whether that is legacy from the original port to .NET Core, since the tests currently seem to assume an Active Directory LDAP server because they append the domain to the LDAP URL. It also looks like only 9 of 526 tests hit a server, which will skip unless one is set up, do you know when we last ran those? It took a while (since I am not familiar with LDAP) but with some test fixes all but one of the tests pass against an OpenDJ docker container. Going forward we should probably test both, and maybe the slapd/Open LDAP server if there is an image for it. Anyway once I get those all passing, I can look at this and maybe some of the other bugs that may be specific to non-AD LDAP servers. |
It is correct that we only have 9 tests that actually hit a server, all the rest are just unit tests that test the interop with the native library, as well as the c# layer we have. Those 9 tests should theoretically work against any Ldap server (even though they have only ran against Active Directory), and in order to run them, you only need to manually edit the LDAP.Configuration.xml file on the unit tests project. We opted to not run them by default since that would require for us to checkin credentials on that xml file (with the way that things are setup currently), and given the fact that this code is not usually touched, we instead have manually ran them locally every time we do make some change on the code to make sure it works. When we do it, we run against an Active Directory server that we have setup, I can share details with you for connecting with it offline. As to when was the last time we ran them, I ran them every time I made a change when writing the Linux implementation (~6 months ago) and the code hasn't been touched since, so I would imagine they should be passing just fine today. We should definitely figure out a better way of running these regularly without having to checkin credentials as part of our outer-loop tests, one idea I had but haven't had the chance to implement yet was to set up tests against an actual Ldap server using a docker farm of clients/servers so that we don't have a network dependency and everything is just running inside different docker containers that emulate a network. This is the way that our enterprise Http tests are setup, so we should look into doing something similar for DirectoryServices. |
Sounds good. If we have a way to run a docker container somehow then automated testing is easy and I would imagine as you say that might be useful for networking tests too. Running manually is ok for a while more but it probably sounds be AD + another. I found your AD instructions and I'll try those. |
Here are the enterprise setup instructions if you are interested in checking out how the docker farm works, if you follow those steps you should be able to run the tests and we know they are passing since we currently have a build pipeline that runs them. That is what I want to do with DirectoryServices in the future. |
With respect to the discussion about The results - zero output from the former, and almost zero from the latter (only occasionally a string "FilterError"). So the fact that we're calling the wrong thing in some cases - not really an issue. The place where the good messages are is on directoryResponse.ErrorMessage and that may be worth including in the exception messages. |
Right now, many LdapException messages on Unix look like:
There is no way to tell from this message what the error was. For example in the case above say the ErrorCode was -7, then the exception message should include text like
The search filter is invalid.
. As it is you need to run under the debugger to get it, then look up in ldap.h to translate it. Examples of bugs where the specific message would have helped: #43621 #41617 #36947Generally these codes are dictated by an RFC that all platforms follow. A subset are represented in our code, across two enums:
LDAP_SUCCESS
throughLDAP_OTHER
inLDAP_RETCODE
in Winldap.h (exceptingLDAP_IS_LEAF
andLDAP_INVALID_CREDENTIALS
)LDAP_IS_LEAF
,LDAP_INVALID_CREDENTIALS
, andLDAP_SERVER_DOWN
throughLDAP_REFERRAL_LIMIT_EXCEEDED
plusLDAP_OPT_REFERRAL_CALLBACK
inLDAP_RETCODE
in Winldap.hI went through every one and they all match in name and value between Winldap.h and the Unix ones in ldap.h, except most of ResultCode have different values:
LDAP_SERVER_DOWN
throughLDAP_REFERRAL_LIMIT_EXCEEDED
have the values -1 through -17, whereas in Windows they have values 0x51-0x61(There are various other codes on both sides that aren't represented in the enumerations, but presumably we'll spot those if they ever happen and extend the enum/add messages.)
The fix is simply to extract the
LdapError
enum into LdapError.Windows.cs and LdapError.Linux.cs with the appropriate values for the platform. We should append the error code in the case that there is no mapping (ieThe LDAP server returned an unknown error '{0}'.
)mappings required
For reference, here's the Unix values
and here's the Windows values
The text was updated successfully, but these errors were encountered: