[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: (ITS#6018) TLS memory leak
--000e0cd149d4a04c48046533de2c
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
The sample code is as follows.
Make command:
g++ testmem.C lib/libldap-2.4.so.2 lib/libsasl2.so.2 lib/liblber-2.4.so.2
-Iinclude/ -Llib/ -DLDAP_DEPRECATED -g -lpthread
If mode is normal, it's ok. If mode is TLS, there is memory leak even if you
don't input bind dn. If mode is SSL, memory leak only happens when you input
bind dn and password.
The openLDAP lib is the latest release version 2.4.15.
I am sure that this is a bug of openLDAP.
#include "ldap.h"
#include <string>
#include <unistd.h>
using namespace std;
typedef enum LDAP_TRANS_METHOD {LDAP_TRANS_NORMAL, LDAP_TRANS_TLS,
LDAP_TRANS_SSL};
LDAP_TRANS_METHOD transMethod = LDAP_TRANS_NORMAL;
const char * host = NULL;
const char * binddn = NULL;
const char * bindpwd = NULL;
int connectnum = 0;
void * connectLDAP(void * param)
{
LDAP * ld;
int rc;
string url;
if( transMethod == LDAP_TRANS_SSL )
url = "ldaps://";
else
url = "ldap://";
if( host == NULL )
return NULL;
url.append(host);
struct timeval tvout;
tvout.tv_sec = 10;
tvout.tv_usec = 0;
if( ldap_set_option( NULL, LDAP_OPT_NETWORK_TIMEOUT, &tvout ) !=
LDAP_OPT_SUCCESS )
{
printf("ldap_set_option LDAP_OPT_NETWORK_TIMEOUT failed\n");
return NULL;
}
rc = ldap_initialize(&ld, url.c_str());
if( rc != LDAP_SUCCESS || ld == NULL )
{
printf("ldap_initialize failed!\n");
return NULL;
}
if( transMethod == LDAP_TRANS_TLS || transMethod == LDAP_TRANS_SSL )
{
int protocol = 3;
if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol ) !=
LDAP_OPT_SUCCESS )
{
printf("ldap_set_option LDAP_OPT_PROTOCOL_VERSION failed\n");
return NULL;
}
int cert = 0;
if( ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert ) !=
LDAP_OPT_SUCCESS )
{
printf("ldap_set_option LDAP_OPT_X_TLS_REQUIRE_CERT failed\n");
return NULL;
}
}
if( transMethod == LDAP_TRANS_TLS )
{
rc = ldap_start_tls_s( ld, NULL, NULL );
if( rc != LDAP_SUCCESS )
{
printf("ldap_start_tls_s failed\n");
return NULL;
}
}
if( binddn != NULL && bindpwd != NULL )
{
rc = ldap_bind_s(ld, binddn, bindpwd, LDAP_AUTH_SIMPLE);
if ( LDAP_SUCCESS != rc )
{
printf("ldap_bind_s failed\n");
return NULL;
}
}
ldap_unbind_s(ld);
connectnum++;
printf("%d connect ok\n", connectnum);
return NULL;
}
int main(int argc, char ** argv)
{
if(argc < 2)
{
printf("Usage: testmem <host> [mode] [bind dn] [bind pwd]\n");
printf("mode: default: NORMAL; SSL;TLS\n");
return 0;
}
string mode="NORMAL";
if( argc > 2 )
mode = argv[2];
if( mode == "SSL" )
transMethod = LDAP_TRANS_SSL;
if( mode == "TLS" )
transMethod = LDAP_TRANS_TLS;
host = argv[1];
if( argc > 4 )
{
binddn = argv[3];
bindpwd = argv[4];
}
do
{
pthread_t instance_thread ;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int rc = pthread_create(&instance_thread, &attr, connectLDAP, NULL) ;
pthread_attr_destroy(&attr);
if (rc)
{
printf("Fail to create policy server instance thread\n") ;
break;
}
sleep(1);
}while(1);
return 0;
}
--000e0cd149d4a04c48046533de2c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
The sample code is as follows.<br>Make command:<br>g++ testmem.C lib/liblda=
p-2.4.so.2 lib/libsasl2.so.2 lib/liblber-2.4.so.2 -Iinclude/ -Llib/ -DLDAP_=
DEPRECATED -g -lpthread<br>If mode is normal, it's ok. If mode is TLS, =
there is memory leak even if you don't input bind dn. If mode is SSL, m=
emory leak only happens when you input bind dn and password.<br>
The openLDAP lib is the latest release version 2.4.15.<br><br>I am sure tha=
t this is a bug of openLDAP.<br><br>#include "ldap.h"<br>#include=
<string><br>#include <unistd.h><br><br>using namespace std;<br=
>
<br>typedef enum LDAP_TRANS_METHOD {LDAP_TRANS_NORMAL, LDAP_TRANS_TLS, LDAP=
_TRANS_SSL};<br><br>LDAP_TRANS_METHOD transMethod =3D LDAP_TRANS_NORMAL;<br=
>const char * host =3D NULL;<br>const char * binddn =3D NULL;<br>const char=
* bindpwd =3D NULL;<br>
int connectnum =3D 0;<br><br>void * connectLDAP(void * param)<br>{<br>=A0=
=A0=A0 LDAP * ld;<br>=A0=A0=A0 <br>=A0 int rc;<br>=A0 string url;<br>=A0 if=
( transMethod =3D=3D LDAP_TRANS_SSL )<br>=A0=A0=A0=A0=A0 url =3D "ldap=
s://";<br>=A0 else<br>=A0=A0=A0=A0=A0 url =3D "ldap://";<br>
=A0 if( host =3D=3D NULL )<br>=A0 =A0=A0=A0 return NULL;<br>=A0 url.append(=
host);<br>=A0=A0=A0 <br>=A0 struct timeval tvout;<br>=A0 tvout.tv_sec =3D 1=
0;<br>=A0 tvout.tv_usec =3D 0;<br><br>=A0=A0=A0 if( ldap_set_option( NULL, =
LDAP_OPT_NETWORK_TIMEOUT, &tvout ) !=3D LDAP_OPT_SUCCESS )<br>
=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 printf("ldap_set_option LDAP_OPT_NE=
TWORK_TIMEOUT failed\n");<br>=A0=A0=A0 =A0=A0=A0 return NULL;<br>=A0=
=A0=A0 }<br>=A0=A0=A0 <br>=A0 rc =3D ldap_initialize(&ld, url.c_str());=
<br>=A0 if( rc !=3D LDAP_SUCCESS || ld =3D=3D NULL )<br>
=A0 {<br>=A0 =A0=A0=A0 printf("ldap_initialize failed!\n");<br>=
=A0=A0=A0 return NULL;<br>=A0 }<br><br>=A0 if( transMethod =3D=3D LDAP_TRAN=
S_TLS || transMethod =3D=3D LDAP_TRANS_SSL )<br>=A0 {<br>=A0=A0=A0 =A0=A0=
=A0 int protocol =3D 3;<br>=A0=A0=A0 if( ldap_set_option( ld, LDAP_OPT_PROT=
OCOL_VERSION, &protocol ) !=3D LDAP_OPT_SUCCESS )<br>
=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 printf("ldap_set_option L=
DAP_OPT_PROTOCOL_VERSION failed\n");<br>=A0=A0=A0=A0=A0=A0=A0 return N=
ULL;<br>=A0=A0=A0 }<br>=A0=A0=A0 int cert =3D 0;<br>=A0=A0=A0 if( ldap_set_=
option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert ) !=3D LDAP_OPT_SUCCES=
S )<br>
=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 =A0 printf("ldap_set_option LDAP_OP=
T_X_TLS_REQUIRE_CERT failed\n");<br>=A0=A0=A0=A0=A0=A0=A0 return NULL;=
<br>=A0=A0=A0 }<br>=A0 }<br><br>=A0 if( transMethod =3D=3D LDAP_TRANS_TLS )=
<br>=A0 {<br>=A0=A0=A0 rc =3D ldap_start_tls_s( ld, NULL, NULL );<br>
=A0=A0=A0 if( rc !=3D LDAP_SUCCESS )<br>=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 =
=A0 printf("ldap_start_tls_s failed\n");<br>=A0=A0=A0=A0=A0=A0=A0=
return NULL;<br>=A0=A0=A0 }<br>=A0 }<br><br>=A0=A0=A0 if( binddn !=3D NULL=
&& bindpwd !=3D NULL )<br>=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 rc =
=3D ldap_bind_s(ld,=A0 binddn, bindpwd, LDAP_AUTH_SIMPLE);<br>
=A0 =A0=A0=A0 if ( LDAP_SUCCESS !=3D rc )<br>=A0 =A0=A0=A0 {<br>=A0 =A0=A0=
=A0 =A0=A0=A0 printf("ldap_bind_s failed\n");<br>=A0=A0=A0=A0=A0 =
return NULL;<br>=A0 =A0=A0=A0 }<br>=A0=A0=A0 }<br>=A0=A0=A0 <br>=A0=A0=A0 l=
dap_unbind_s(ld);<br>=A0=A0=A0 connectnum++;<br>=A0=A0=A0 printf("%d c=
onnect ok\n", connectnum);<br>
=A0=A0=A0 return NULL;<br>}<br><br>int main(int argc, char ** argv)<br>{<br=
>=A0=A0=A0 if(argc < 2)<br>=A0=A0=A0 {<br>=A0=A0=A0 =A0=A0=A0 printf(&qu=
ot;Usage: testmem <host> [mode] [bind dn] [bind pwd]\n");<br>=A0=
=A0=A0 =A0=A0=A0 printf("mode: default: NORMAL; SSL;TLS\n");<br>
=A0=A0=A0 =A0=A0=A0 return 0;<br>=A0=A0=A0 }<br>=A0=A0=A0 string mode=3D&qu=
ot;NORMAL";<br>=A0=A0=A0 if( argc > 2 )<br>=A0=A0=A0 =A0=A0=A0 mode=
=3D argv[2];<br><br>=A0=A0=A0 if( mode =3D=3D "SSL" )<br>=A0=A0=
=A0 =A0=A0=A0 transMethod =3D LDAP_TRANS_SSL;<br>=A0 if( mode =3D=3D "=
TLS" )<br>
=A0=A0=A0 transMethod =3D LDAP_TRANS_TLS;<br>=A0 host =3D argv[1];<br>=A0 <=
br>=A0=A0=A0 if( argc > 4 )<br>=A0=A0=A0 {<br>=A0 =A0=A0=A0 binddn =3D a=
rgv[3];<br>=A0 =A0=A0=A0 bindpwd =3D argv[4];<br>=A0=A0=A0=A0 }<br>=A0 <br>=
=A0 do<br>=A0 {<br>=A0=A0=A0 pthread_t instance_thread ;<br>=A0 =A0=A0=A0 p=
thread_attr_t attr;<br>
=A0 =A0=A0=A0 pthread_attr_init(&attr);<br>=A0 =A0=A0=A0 pthread_attr_s=
etdetachstate(&attr, PTHREAD_CREATE_DETACHED);<br>=A0 =A0=A0=A0 int rc =
=3D pthread_create(&instance_thread, &attr, connectLDAP, NULL) ;<br=
>=A0 =A0=A0=A0 pthread_attr_destroy(&attr);<br>
=A0=A0=A0 if (rc)<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 printf("Fail=
to create policy server instance thread\n") ;<br>=A0=A0=A0=A0=A0=A0=
=A0 break;<br>=A0=A0=A0 }<br>=A0=A0=A0 sleep(1);<br>=A0=A0=A0 }while(1);<br=
>=A0=A0=A0 return 0;<br>}<br><br>
--000e0cd149d4a04c48046533de2c--