Windows Server - LDAP - AD connection using GSS-SPNEGO SASL

Asked By Dhandapan on 03-Nov-08 06:40 AM
Hi,

I have installed AD in Windows 2003 Virtual OS. I could able to connect with
AD using simple and anonymous authentication method. But my code is failed
for any SASL methods.

The code is,

BERVAL Credential;
PBERVAL ServerData;

Credential.bv_val = "balar@dhandapani.com";
Credential.bv_len = 10;

iRtn = ldap_sasl_bind_s(pLdapConnection, "cn=bala,ou=users,ou=system",

The function is returning LDAP_INVALID_CREDENTIALS.

Please anybody assit me on this.

Thanks,
Dhandapani C




Joe Kaplan replied on 03-Nov-08 10:10 AM
The MS LDAP API docs on MSDN for ldap_bind_s are clear that you must supply
a SEC_WINNT_AUTH_IDENTITY structure for this when using it to do SASL bind.
They aren't so clear for ldap_sasl_bind_s, but I'm guessing you are supposed
to do the same thing there.  Typically you supply a null username in the
username parameter and instead use the appropriate field in the
SEC_WINNT_AUTH_IDENTITY for supplying the username instead.  Also note that
you should use a username format that works with Windows auth (domain\user,
UPN or plain username with the domain supplied in the domain field).

HTH,

Joe K.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
Deepik replied on 10-Dec-08 06:37 AM
"Joe Kaplan" wrote:
Deepik replied on 10-Dec-08 06:43 AM
Hi
I have a doubt with the usage of ldap_sasl_bind_s().
I checked this function details from the site
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/ldap_sasl_bind_s.htm
where it is mentioned that if mechanisnm is LDAP_MECHANISM_GSSAPI, then the
parameter dn has to be NULL.
Also parameter "cred" can also be NULL if TGT is already obtained from
Kerberos.
But this is optional i.e we can pass the credentials in this function.
now my doubt is that whether we can use GSS-API without kerberos mechanism
also.
Everywhere in other articles, i studied that GSS-API has to follow any of
the security mechanism and generally it follows kerberos.
Joe Kaplan replied on 10-Dec-08 10:22 AM
GSS API requires Kerberos.  GSS-SPNEGO uses the Windows negotiate protocol
which will select between Kerberos and NTLM.  Thus, if Kerberos is not
available for some reason, NTLM can still be used.  NTLM can also bind with
default credentials assuming the current security context is a domain user
and has proper network credentials.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 11-Dec-08 12:17 AM
Thanks Joe.
Can you please guide me the flow programmatically to initiate and complete
the security context and authentication between the client and LDAP server
using GSS SPNEGO.
Actually i went through many articles and found out that there are two
functions
1) InitializeSecurityContext() inside which we have
InitializeSecurityContext(Negotiate)
2) gss_init_sec_context().
Basically I am not sure of the functionality difference and do not know
which to use.
Also it is mentioned there may be number of exchange of token using these
functions.
How do we actually decide the how many times or do we have to use a loop?

Also i read there are functions called GSS_Wrap() and GSS_Unwrap() which are
used to encrypt the messages exchanged between the client and server.
My doubt is that is it necessary to exhange the data using these functions
or can we just limit the usage of GSS-SPNEGO only till authentication.
Joe Kaplan replied on 11-Dec-08 10:16 AM
Are you talking about this in the context of an LDAP bind?  If so, all you
need to do is call ldap_bind_s and provide the credentials you want to use.
The MS LDAP APIs will default to using GSS-SPNEGO and will negotiate the
authentication for you based on the credentials provided.  You don't call
ISC yourself.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 23-Dec-08 05:14 AM
I understood your above suggestion
Can you please see this link:
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/ldap_sasl_bind_s.htm
Just read in the section parameters where different mechanism are defind.
In case of LDAP_MECHANISM_GSSAPI , they have mentioned that cred parameter
can be NULL assuming that tickets have already been acquired. It will do the
rest of the mechanism under covers.
In my application, i acquired the ticket successfully and then i am calling
this function with cred as null.
It is throwing LDAP_PARAM_ERROR.
Any thought?
Joe Kaplan replied on 23-Dec-08 09:26 AM
I'm sorry, but I can't see enough here to know what the problem might be.
Does it work ok if you specific GSS-SPNEGO instead?

Note that I'm pretty sure you need to be impersonating this user to specify
null credentials.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 24-Dec-08 02:03 AM
No, it is still not working
this the way i am calling this fuction
Due to certain reasons i have used function pointers
bindFunction = (BINDFUNCTION)GetProcAddress(hDll,"ldap_sasl_bind_sW");
if(bindFunction!=NULL)
{
mioRespCode = LdapMapErrorToMIO((bindFunction)(g_hLDAP, NULL,"GSS-SPNEGO"
,NULL,NULL,NULL, &servercredp));
}
g_hLDAP is the handle.
This function i am calling after i have TGT.
Also i have a confusion that whether the parameter will be none for 'dn'.
Not sure for 'creds'.
Help!!!!
Joe Kaplan replied on 01-Jan-09 11:53 PM
My understanding is that binding with null credentials will cause
authentication to use the current thread's credentials, so you would need to
be impersonating the identity with the TGT for this to work.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 07-Jan-09 08:05 AM
I have used ldap_bind_s() to bind to AD using creds in
SEC_WINNT_AUTH_IDENTITY structure and LDAP_AUTH_NEGOTIATE as parameter as my
main aim was to use GSS-SPNEGO and kerberos.
the bind is successful but it uses NTLM inside
so i thot, i'll use ldap_sasl_bind_s() but the credential parameter in this
function is required in berval format while you mentioned before that creds
are required in SEC_WINNT_AUTH_IDENTITY format.
How to convert SEC_WINNT_AUTH_IDENTITY creds in berval format.
Will it hold any meaning if i do a direct casting?
Joe Kaplan replied on 07-Jan-09 10:09 AM
I don't have any idea what goes in the cred parameter for ldap_sasl_bind_s.
I assume that you still pass in null here as with GSS-SPNEGO for this use
case.

You should have gotten Kerberos with ldap_bind_s.  NTLM should only happen
if Kerb was not available.  Did you connect to the server using an IP
address or something?  Kerberos should work if you use the full DNS name of
the server (something that would match an LDAP SPN registered for the domain
controller).  Note also that the client must be domain joined as well.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 08-Jan-09 06:10 AM
ya i connected the server using IP address
Actually I am connecting to AD for LDAP service which is running by default
on Windows 2003 server(the Domain Controller and AD)
So my KDC server and desired server(where service is running) are same.
I have registered the SPN for ldap service running on administrator account.
On the same account KDC is also present.
i am using the following code
secIdent.User = "deepika"r;
secIdent.UserLength = strlen((const char*)secIdent.pUser);
secIdent.Password = "kmbt@123";
secIdent.PasswordLength = strlen((const char*)secIdent.pPass);
secIdent.Domain = "KMBT.SIMWIN";
secIdent.DomainLength = strlen((const char*)secIdent.pDomain);
secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
mioRespCode = ldap_bind_s(g_hLDAP, "ldap/kmbtsimwin01.kmbt.simwin",
(PCHAR)&secIdent, LDAP_AUTH_NEGOTIATE);
where my server name is : kmbtsimwin01
Domain KMBT.SIMWIN

my both PC are in same domain.
SPN is registered at the server.
as ldap/kmbtsimwin01.kmbt.simwin against 'hostname' as both LDAP service and
domain controller is on the same PC.
still it is not using kerberos:(
what to do else????
Deepik replied on 09-Jan-09 12:42 AM
hey boss thanks so much
finally got the kerberos
this last tip of ldap_init was useful.
i never thot in this direction.
Thanks so much
Deepik replied on 10-Jan-09 04:30 AM
hey now there is another problem.
I am using ldap_bind_s() for both simple and negotiate authentication.

GSS-SPNEGO is working absolutely fine along with search operation
But there is a problem in search operation using simple suthentication
I am doing simple authentication by the following line

mioRespCode = ldap_bind_s(g_hLDAP, NULL, (PCHAR)&secIdent, LDAP_AUTH_SIMPLE);

Binding is successful but when i am performing the search operation it is
giving LDAP_OPERATIONS_ERROR
I read that this error comes when the binding is not proper.
But when i am passing "dc=kmbt,dc=simwin" instead of NULL, it is giving
invalid credentials.
i do not know how to handle this problem
Joe Kaplan replied on 10-Jan-09 02:23 PM
The operations error happens because you are authenticating as anonymous and
AD does not allow anonymous searches as of the 2003 release.

When doing simple bind, you supply a valid user name for the DN parameter (a
DN, or for AD you can also use NT account name or UPN) and must supply the
password as pointer to unicode string (I think) in the cred parameter.

It might be easier to just call ldap_simple_bind_s when you need to do
simple bind though.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Deepik replied on 12-Jan-09 01:15 AM
ya now ldap_bind_s() is working with simple as well with successful search
operation.

Thanks for all your help
Deepik replied on 13-Feb-09 12:01 AM
Hi
Actually i am doing kerberos within the same domain.
Is it possible to perform kerberos across the domain?
I read in the documents that this is possible but i am not sure of the
settings required.
Actually while performing connection, I am using the DNS name.
With this, if i am trying to authenticate in cross domain, even the
connection is failing.
My doubt is that whether it is possible in any way to perform kerberos in
cross domain?
Deepik replied on 13-Feb-09 12:07 AM
Hi
Currently i am perofrming kerberos in same domain.
is this possible in cross domain?
I am connecting to the AD server using DNS name and the client and the
server are in the same domain.
when i am trying to connect to the server in the similar fashion across
domain, even the connection is failing,leave apart the authentication
mechanism.
And if i use IP to connc to that system, connection is success but
authentication mechanism in this case is NTLM.
My doubt is whether it is at all possible to perform kerberos across domain
using DNS name to connect?
My main aim is to authenticate to a server in another domain through kerberos.
Please guide.
Deepik replied on 13-Feb-09 12:07 AM
Hi
Currently i am perofrming kerberos in same domain.
is this possible in cross domain?
I am connecting to the AD server using DNS name and the client and the
server are in the same domain.
when i am trying to connect to the server in the similar fashion across
domain, even the connection is failing,leave apart the authentication
mechanism.
And if i use IP to connc to that system, connection is success but
authentication mechanism in this case is NTLM.
My doubt is whether it is at all possible to perform kerberos across domain
using DNS name to connect?
My main aim is to authenticate to a server in another domain through kerberos.
Please guide.
Joe Kaplan replied on 13-Feb-09 02:48 AM
Is there any trust between the domains (same forest)?  If so, Kerb should
still work.  If not, it will not, at least via LDAP and I don't think you
can by calling ISC directly.  Not sure if it is possible if you called
GSSAPI directly.  This would be the wrong group to ask about ISC or GSSAPI.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net