I have this little problem. I want to authenticate user against LDAP (Windows Active Directory), everything works OK, but the combination (good user, good password, wrong domain).
LDAP* ldap = ldap_init(L"myserver", 389);
ULONG ldap_version = 3;
ULONG ret = LDAP_SUCCESS;
ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void*)&ldap_version);
ret = ldap_connect(ldap, NULL);
SEC_WINNT_AUTH_IDENTITY ai;
ai.Domain = (unsigned short*)BAD_DOMAIN;
ai.DomainLength = wcslen(BAD_DOMAIN);
ai.User = (unsigned short*)OK_USER;
ai.UserLength = wcslen(OK_USER);
ai.Password = (unsigned short*)OK_PASS;
ai.PasswordLength = wcslen(OK_PASS);
ai.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
ret = ldap_bind_s(ldap, NULL, (PWCHAR) &ai, LDAP_AUTH_NTLM); // !!! HERE !!!
ret = ldap_unbind_s(ldap);
On the line marke '!!! HERE !!!' I'd expect 0x31 or any other error returned. Instead I get LDAP_SUCCESS :(
Any suggestions? Thx, Milan
Binding is successfull because the couple username/password is valid for the domain you're connected to during the ldap_init call. In this case, the domain supplied in the credentials is simply ignored.
To confirm this statment, you could try using some credentials from a trusted domain of this server. Because the user does not exist in the domain you're connected to, supplying an invalid domain name will result in a binding failure with INVALID_CREDENTIALS.
Hope that helps.
Are you checking the return values from ldap_init(), ldap_set_option(), and ldap_connect()?
I would try using a
SEC_WINNT_AUTH_IDENTITY_EX
structure and filling in the version and length.Otherwise, your code looks right to me.
It could also be falling back to anonymous access, or access as your logged-in user.
Windows can be quite "helpful" in matching domain and username strings. What are you passing for domain? Is it a plausible, but nonexistent domain string? If it violates naming rules, it could be ignored, and the user matched as if you didn't specify a username. In particular, well-known usernames like "Administrator" end up matching just about any local machine or domain.
Have you tried doing a simple query with the bound connection?
There is a weird case where a bind will succeed using an recently expired password, but then causes some operation for a subsequent bind on the same connection to fail arbitrarily. I don't think this is what you're seeing however. If you come across this odd case, I think the solution is buried in here somewhere: http://support.microsoft.com/default.aspx?scid=kb;EN-US;823659