Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Memory leaks while using Microsoft LDAP C API with the LDAP_OPT_CLIENT_CERTIFICATE

17 views
Skip to first unread message

hag...@yahoo.com

unread,
Oct 5, 2006, 12:33:42 PM10/5/06
to
Hello,

I am using Microsoft LDAP C API on windows 2003 server to work with
remote LDAP directories (active directory, Sun One, etc...), I want to
use SSL connection with the directories.

I have used code from the MSDN and it worked correctly, how ever I have
encountered cases in which the LDAP API tried to perform client
authentication in the SSL handshake (I saw this happening when I had
certificates in the local certificates store that were signed by the
same CA that signed the certificate of the relevant directory server),
I would like to avoid this behavior, I want to make sure that SSL
client authentication will never occur.

in order to achieve this I tried using the LDAP_OPT_CLIENT_CERTIFICATE
session option, I have set a callback function that always return
FALSE, this way there will be no client certificate available for the
SSL client authentication and my target will be achieved.

This worked for me, everything worked ok but I noticed that the memory
consumption of my application is continuously rising. I don't know if
I am making a mistake in the usage or maybe not releasing something
that I need to release.

I have created a short example program (based on the program from the
MSDN) that performs SSL connections to a directory server in an
infinite loop, the memory consumption of this program is continuously
rising.

Does any one have nay idea what is the problem with my program?

Thanks,
Hagai.

Example program:

#include <windows.h>
#include <ntldap.h>
#include <winldap.h>
#include <schnlsp.h>
#include <stdio.h>

BOOLEAN _cdecl GetClientCertRoutine(void *Connection,
void *trusted_CAs,
void *ppCertificate) {
return (FALSE);
}

int main(int argc, char* argv[])
{
LDAP* ld = NULL;
INT iRtn = 0;
INT connectSuccess = 0;
PCHAR pHost = NULL;
ULONG version = LDAP_VERSION3;
SecPkgContext_ConnectionInfo sslInfo;
LONG lv = 0;

// Verify that the user passed a hostname.
if (argc > 1)
{
pHost = argv[1];
printf("\nConnecting to host \"%s\" ...\n",pHost);
}
// If not, perform a 'serverless' bind.
else
{
pHost = NULL;
printf("\nConnecting to DEFAULT LDAP host ...\n");
}

while (1) {
// Create an LDAP session.
ld = ldap_sslinit(pHost,LDAP_SSL_PORT,1);
if (ld == NULL)
{
printf( "ldap_sslinit failed with 0x%x.\n",GetLastError());
return -1;
}

// Specify version 3; the default is version 2.
printf("Setting Protocol version to 3.\n");
iRtn = ldap_set_option(ld,
LDAP_OPT_PROTOCOL_VERSION,
(void*)&version);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;

// setting function to avoid client authetication
printf("Setting function to avoid client authentication.\n");
iRtn = ldap_set_option(ld,
LDAP_OPT_CLIENT_CERTIFICATE,
&GetClientCertRoutine);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;

// Verify that SSL is enabled on the connection.
// (returns LDAP_OPT_ON/_OFF).
printf("Checking if SSL is enabled\n");
iRtn = ldap_get_option(ld,LDAP_OPT_SSL,(void*)&lv);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;

// If SSL is not enabled, enable it.
if ((void*)lv == LDAP_OPT_ON)
printf("SSL is enabled\n");
else
{
printf("SSL not enabled.\n SSL being enabled...\n");
iRtn = ldap_set_option(ld,LDAP_OPT_SSL,LDAP_OPT_ON);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;
}

// Connect to the server.
connectSuccess = ldap_connect(ld, NULL);

if(connectSuccess == LDAP_SUCCESS)
printf("ldap_connect succeeded \n");
else
{
printf("ldap_connect failed with 0x%x.\n",connectSuccess);
goto FatalExit;
}

// Bind with current credentials.
printf("Binding ...\n");
iRtn =
ldap_bind_s(ld,"cn=administrator,cn=users,dc=infradc,dc=com","Local",LDAP_AUTH_SIMPLE);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;

// Retrieve the SSL cipher strength.
printf("Getting SSL info\n");
iRtn = ldap_get_option(ld,LDAP_OPT_SSL_INFO,&sslInfo);
if (iRtn != LDAP_SUCCESS)
goto FatalExit;

printf("SSL cipher strength = %d
bits\n",sslInfo.dwCipherStrength);

goto NormalExit;

// Cleanup.
NormalExit:
if (ld != NULL) {
ldap_unbind_s(ld);
continue;
}

// Cleanup after an error.
FatalExit:
if( ld != NULL )
ldap_unbind_s(ld);
printf( "\n\nERROR: 0x%x\n", iRtn);
break;
}
}

Joe Richards [MVP]

unread,
Oct 5, 2006, 7:49:09 PM10/5/06
to
I verified what appears to be a leak as well with the code below,
commenting out the ldap_set_option LDAP_OPT_CLIENT_CERTIFICATE fixes it
so it appears that that is the cause. Let me see if I can chase it up
with someone at MSFT.

joe

--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm

Joe Kaplan

unread,
Oct 5, 2006, 8:05:57 PM10/5/06
to
This is very interesting to me, as I use this feature occasionally, but only
through .NET, and I haven't noticed a leak (although they can be hard to
find in garbage collected environments, especially if you aren't making lots
of connections).

I'd like to hear what comes out of this. I'll also poke around in the .NET
code and see if I can figure out what they do (if they do something
different).

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
--
"Joe Richards [MVP]" <humore...@hotmail.com> wrote in message
news:OSLibjN...@TK2MSFTNGP05.phx.gbl...

Joe Richards [MVP]

unread,
Oct 6, 2006, 9:47:38 AM10/6/06
to
I looked at the source I am pretty confident now that there is a leak.
However it could be a simple case that the docs are missing a step that
needs to be taken in the Client Cert Routine as I figured out how to
make it not leak. I am in conversation with MSFT about it to see how
they want to handle it.

I will post back here when I know more.

joe


--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm

Joe Richards [MVP]

unread,
Oct 6, 2006, 6:50:23 PM10/6/06
to j...@joeware.net
Ok I have heard back from MSFT.

The leak I located in the source has been confirmed. A case has been
opened to correct the issue. If you want to pursue getting a QFE, you
can open a case with MSFT Support (should be free - this is a bug) and
have them ping the appropriate engineer. If you want to do that, email
me offline and I can supply you with the name of the engineer to give to
the support folks.

In the meanwhile, if you are ok with a workaround, here is some code
that will remove the leak for you.


BOOLEAN _cdecl GetClientCertRoutine(void *Connection,
void *trusted_CAs,
void *ppCertificate)
{

SecPkgContext_IssuerListInfoEx *p =
(SecPkgContext_IssuerListInfoEx *)trusted_CAs;
FreeContextBuffer((void*)p->aIssuers);
return (FALSE);
}

Note I simply added a couple of lines to release the memory allocated
for the trusted_CAs that are passed to you.


joe


--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm

Joe Kaplan

unread,
Oct 6, 2006, 9:47:41 PM10/6/06
to
I'm guessing this issue is in .NET 2.0 System.DirectoryServices.Protocols as
well, as it just interops directly with wldap32 and doesn't include that
workaround code. Unfortunately, I don't think you could implement the
workaround Joe mentions as the .NET layer marshals the issuer list into an
array of bytes and doesn't give you a structure with a pointer to free. I
think a patch to WLDAP32 or a patch to .NET S.DS.Protocols would be the only
solution there.

Thanks for the follow up. Any word on when this fix will get merged into
Windows? I'm guessing it is too late for Win2K3 SP2 and maybe Longhorn
Server (although I hope not). It isn't a huge big deal, but it should be
fixed.

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
--
"Joe Richards [MVP]" <humore...@hotmail.com> wrote in message

news:4526DDAF...@hotmail.com...

Joe Richards [MVP]

unread,
Oct 7, 2006, 9:59:36 PM10/7/06
to
I didn't get any feedback on when it would make it in. I would NOT be
surprised if it were even Vista and LH SP1s... I don't know the
criticality that is assigned to it. Since this is the first reported
incident since October 1999, I am not sure what kind of rush needs to be
applied to it.

hag...@yahoo.com

unread,
Oct 8, 2006, 3:44:36 AM10/8/06
to
Hello,

Thanks allot for your help clarifying the problem and the possible
solutions, currently I am not interested in pursuing a QFE.

Best Regards,
Hagai.

0 new messages