[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: PHP+LDAP not really works [includes small debug patch to 2.1.12]



I have a php/ldap developpement, and I need to change code or php.ini at nearly any new version of php !. This is actually the case with redhat 8.0

$ rpm -qa | grep php
php-imap-4.2.2-8.0.5
php-4.2.2-8.0.5
php-ldap-4.2.2-8.0.5

beware of php.ini changements, Personnaly I needed to play with:
register_globals = Off / On
file_uploads = Off / On
short_open_tag = Off / On

either switch them back to On, or recode !

For example, I used $HTTP_GET_VARS, now it is $_GET, ie: $_GET[name] where "name" is your html form variable, this works with register_globals = Off, and is it suposed to be mode secure !.

good luck.

David Smith wrote:
Frode,

As much as I don't like to say it, I've heard some bad things about
RedHat8 and PHP. As a benchmark, why don't you try another PHP/LDAP
application on  your system to verify that your code is indeed working.
I can recommend DaveDAP:

http://students.cs.byu.edu/~djsmith/davedap/

If that doesn't work, then I'd recommend changing versions of PHP and/or
Apache. Note that you'll have to enable register_globals for DaveDAP to
run under RH8.

--Dave


On Sat, 2003-01-11 at 05:57, Frode E. Moe wrote:

On Sat, Jan 11, 2003 at 01:20:09PM +0100, Veres Imre wrote:

It's my first email to the list os firstly let me introduce myself: My
name is Imre Veres aged 27, I'm working in Hungary at the fourth biggest
hungarian software company. We are working for banks and other financial
institutes.

There is a working openldap 2.0.27 here which serve authenticating with
Samba, Apache and internal SSH, moreover ldap tree contains all data
from our colleagues and going to serve intranet applications. This is my
real problem now, I'm using PHP 4.2.2 (RedHat 8.0) and the modify
function to LDAP works in 40% of the cases without any error or
warning, works another 20% with warnings and doesn't work in the rest
of the cases either. I can't understand this situation. They could not
help me in the PHP list because my PHP code is perfect. :-) I think
there is some weird thing in the LDAP side.


I don't know your specific code or your specific errors, but we've been
experiencing random segfaults and crashes when using APACHE+PHP+LDAP to
access a windows Active Directory LDAP server. I've spent almost a day in
gdb trying to track down the error and it seems some "lr_parent" pointers in
LDAP structures are corrupted, as PHP and APACHE segfaults when PHP tries to
unbind from the LDAP server and free all objects; when the ldap code frees
up its request objects, it seems to traverse through 'parent' and 'children'
request pointers. As the parent pointer pointed into what seemed like the
remainings of a string buffer (the base DN?), segfault was inevitable as the
code tried interpreting the "parent" pointer part of the structure as a
pointer when in fact it was ASCII characters.

I tried turning on LDAP_MEMORY_DEBUG and LDAP_MEMORY_TRACE defines,  which,
by the way, in 2.1.12 doesn't even compile cleanly (there's a define in
libraries/liblber/memory.c at around line 55 which is wrong), here's
a short patch:

--- dist/openldap-2.1.12/libraries/liblber/memory.c	2002-10-17 17:08:01.000000000 +0200
+++ openldap-2.1.12/libraries/liblber/memory.c	2003-01-09 22:05:29.000000000 +0100
@@ -53,7 +53,7 @@
};

/* Pattern at top of allocated space */
-#define LLBER_MEM_JUNK 0xdeaddadaU
+#define LBER_MEM_JUNK 0xdeaddadaU

static const struct ber_mem_hdr ber_int_mem_hdr = { LBER_MEM_JUNK, 0, 0 };




When running with this DEBUG compiled library, after a long reponse (we have many user objects in AD, so a request for all users returns quite long a reponse), the ldap memory debug code stopped the application with failed assertions at locations such as this:

libraries/libldap/result.c around line 778 (in version 2.1.12):

				if ( !simple_request ) {
					ber_free( ber, 1 );
					ber = NULL;
					if ( build_result_ber( ld, &ber, lr )
					    == LBER_ERROR ) {
						rc = -1; /* fatal error */
					}
				}

The ber_free called failed an assertion that ber != NULL.  I'm not very
familiar with the openldap code base, but I compared this bit of source with
the old openldap 1.2.13, where it seems the corresponding code goes like
this:

libraries/libldap/result.c around line 400 (in version 1.2.13)

				if ( !simple_request ) {
					if ( ber.ber_buf != NULL ) {
						free( ber.ber_buf ); /* gack! */
						ber.ber_buf = NULL;
					}
					if ( build_result_ber( ld, &ber, lr )
					    == LBER_ERROR ) {
						ld->ld_errno = LDAP_NO_MEMORY;
						rc = -1; /* fatal error */
					}
				}

As you can see it probably makes more sense to set a member of the ber
struct to NULL and then re-use the ber object just afterwards, instead of
nulling the entire thing.



Well, to put a long story short:

I wrote a simple test case in C which for some time reproduced the error,
but at the end I couldn't even get the assertion failures to trigger. By
luck I happened to read upon the ldap_set_option PHP manual online, where
some people recommend explicitly setting the protocol version to v3. We
tried this and our problems went away, so I never bothered to track down the
exact bug.


It might also be that the assertions failed just because I was stupid
enough to use LD_PRELOAD tricks instead of overwriting my system
ldap libraries (i'm running debian linux by the way).

Here's an example of the assertion failures:
(see attached example application)

gdb ./test
GNU gdb 5.3-debian
(gdb) run
Starting program: /home/frode/temp/ldap-testcase/test ldap test case
0x00000000 0x0804abd8 -a- 25 ber_memalloc 25
0x00000001 0x0804ac10 -a- 18 ber_memalloc 43
0x00000002 0x0804ac40 -a- 8 ber_memalloc 51
0x00000003 0x0804ac68 -a- 18 ber_memalloc 69


 ( lots of memory debugging output )

0x00000042 0x0804af88 -f- 24 ber_memfree 22127
0x00000053 0x08050ca0 -a- 64 ber_memcalloc 22191
search ok
0x00000054 0x08050e50 -a- 44 ber_memcalloc 22235
0x00000055 0x08050e98 -a- 221 ber_memalloc 22456
0x00000056 0x0804af88 -a- 24 ber_memcalloc 22480
currently at numresults/numresponses 0/0 - type 100 0x00000055 0x08050e98 -f- 221 ber_memfree 22259
0x00000054 0x08050e50 -f- 44 ber_memfree 22215
0x00000056 0x0804af88 -f- 24 ber_memfree 22191
0x00000057 0x08050e50 -a- 44 ber_memcalloc 22235
0x00000058 0x08050e98 -a- 107 ber_memalloc 22342
0x00000059 0x0804af88 -a- 24 ber_memcalloc 22366
currently at numresults/numresponses 1/1 - type 100 0x00000058 0x08050e98 -f- 107 ber_memfree 22259
0x00000057 0x08050e50 -f- 44 ber_memfree 22215


 ( lots of more uninteresting output )

0x0000051c 0x08050e50 -a- 44 ber_memcalloc 22235
0x0000051d 0x08050d08 -a- 219 ber_memalloc 22454
0x0000051e 0x08050b88 -a- 24 ber_memcalloc 22478
currently at numresults/numresponses 408/408 - type 100 0x0000051d 0x08050d08 -f- 219 ber_memfree 22259
0x0000051c 0x08050e50 -f- 44 ber_memfree 22215
0x0000051e 0x08050b88 -f- 24 ber_memfree 22191
0x0000051f 0x08050e50 -a- 44 ber_memcalloc 22235
0x00000520 0x08050d08 -a- 112 ber_memalloc 22347
0x00000521 0x08050d98 -a- 1 ber_memalloc 22348
0x00000522 0x0804af40 -a- 96 ber_memalloc 22444
0x00000523 0x08050db8 -a- 79 ber_memalloc 22523
0x00000524 0x08050e98 -a- 40 ber_memcalloc 22563
0x00000525 0x08050bc0 -a- 5 ber_memalloc 22568
0x00000526 0x08050b88 -a- 25 ber_memalloc 22593
0x00000527 0x08050ee0 -a- 54 ber_memalloc 22647
0x00000523 0x08050db8 -f- 79 ber_memfree 22568
0x00000528 0x08050db8 -a- 37 ber_memalloc 22605
0x00000529 0x08050e00 -a- 44 ber_memcalloc 22649
0x0000052a 0x08050f38 -a- 24 ber_memcalloc 22673
0x0000052b 0x08050f70 -a- 4060 ber_memalloc 26733
0x0000052c 0x08051f68 -a- 24 ber_memcalloc 26757
0x00000528 0x08050db8 -f- 37 ber_memfree 26720
0x0000052c 0x08051f68 -f- 24 ber_memfree 26696
0x0000052a 0x08050f38 -f- 24 ber_memfree 26672
0x0000052d 0x08051f68 -a- 86 ber_memalloc 26758
0x0000052e 0x08050db8 -a- 44 ber_memcalloc 26802
0x0000052f 0x08050f38 -a- 28 ber_memcalloc 26830
0x00000530 0x08052028 -a- 20 ber_memalloc 26850
0x00000531 0x08052058 -a- 5 ber_memalloc 26855
0x00000532 0x08052080 -a- 20 ber_memalloc 26875
0x00000533 0x08051ff0 -a- 25 ber_memalloc 26900
0x00000534 0x080520b0 -a- 20 ber_memalloc 26920
0x00000535 0x080520e0 -a- 16 ber_memalloc 26936
0x00000536 0x08052110 -a- 16384 ber_memalloc 43320
0x00000537 0x08056130 -a- 20 ber_memalloc 43340
0x00000538 0x08056160 -a- 6 ber_memalloc 43346
0x00000539 0x08056188 -a- 176 ber_memalloc 43522
0x0000053a 0x08056258 -a- 5 ber_memalloc 43527
0x0000053b 0x08056280 -a- 25 ber_memalloc 43552
0x0000053c 0x080562b8 -a- 56 ber_memalloc 43608
0x0000053d 0x08056310 -a- 116 ber_memalloc 43724
0x0000053e 0x080563a0 -a- 12 ber_memalloc 43736
0x0000053f 0x080563c8 -a- 25 ber_memalloc 43761
0x00000533 0x08051ff0 -f- 25 ber_memfree 43736
0x00000540 0x08056400 -a- 40 ber_memalloc 43776
0x00000541 0x08056448 -a- 5 ber_memalloc 43781
0x00000542 0x08051ff0 -a- 25 ber_memalloc 43806
0x00000543 0x08056470 -a- 54 ber_memalloc 43860
0x00000544 0x080564c8 -a- 44 ber_memcalloc 43904
0x00000545 0x08056510 -a- 24 ber_memcalloc 43928
0x00000546 0x08056548 -a- 4060 ber_memalloc 47988
0x00000547 0x08057540 -a- 24 ber_memcalloc 48012
0x00000547 0x08057540 -f- 24 ber_memfree 47988
0x00000545 0x08056510 -f- 24 ber_memfree 47964
0x00000548 0x08057578 -a- 64 ber_memcalloc 48028
0x00000549 0x080575d8 -a- 44 ber_memcalloc 48072
0x0000054a 0x08057620 -a- 17 ber_memalloc 48089
0x0000054b 0x08057650 -a- 1 ber_memalloc 48090
0x0000054c 0x08057670 -a- 1 ber_memalloc 48091
0x00000546 0x08056548 -f- 4060 ber_memfree 44031
0x00000544 0x080564c8 -f- 44 ber_memfree 43987
0x0000054c 0x08057670 -f- 1 ber_memfree 43986
0x0000054b 0x08057650 -f- 1 ber_memfree 43985
0x00000548 0x08057578 -f- 64 ber_memfree 43921
0x0000054d 0x08056510 -a- 24 ber_memcalloc 43945
0x00000040 0x08050c80 -f- 1 ber_memfree 43944
0x0000003f 0x08050c60 -f- 1 ber_memfree 43943
0x0000054e 0x080564c8 -a- 44 ber_memcalloc 43987
0x0000054f 0x08050c60 -a- 1 ber_memalloc 43988
0x00000550 0x08050c80 -a- 1 ber_memalloc 43989
0x0000054e 0x080564c8 -f- 44 ber_memfree 43945
0x0000054a 0x08057620 -f- 17 ber_memfree 43928
0x00000549 0x080575d8 -f- 44 ber_memfree 43884
0x0000054d 0x08056510 -f- 24 ber_memfree 43860
0x00000551 0x08057578 -a- 64 ber_memcalloc 43924
0x0000052d 0x08051f68 -f- 86 ber_memfree 43838
0x00000525 0x08050bc0 -f- 5 ber_memfree 43833
0x00000526 0x08050b88 -f- 25 ber_memfree 43808
0x00000527 0x08050ee0 -f- 54 ber_memfree 43754
0x00000524 0x08050e98 -f- 40 ber_memfree 43714
0x00000522 0x0804af40 -f- 96 ber_memfree 43618
0x00000520 0x08050d08 -f- 112 ber_memfree 43506
0x0000051f 0x08050e50 -f- 44 ber_memfree 43462
0x00000552 0x08050e50 -a- 44 ber_memcalloc 43506
0x00000553 0x08050d08 -a- 107 ber_memalloc 43613
0x00000553 0x08050d08 -f- 107 ber_memfree 43506
0x00000552 0x08050e50 -f- 44 ber_memfree 43462
test: io.c:179: ber_free: Assertion `ber != ((void *)0)' failed.


Program received signal SIGABRT, Aborted.
0x40171911 in kill () from /lib/libc.so.6
(gdb) bt
#0 0x40171911 in kill () from /lib/libc.so.6
#1 0x40171732 in raise () from /lib/libc.so.6
#2 0x40172846 in abort () from /lib/libc.so.6
#3 0x4016b9a9 in __assert_fail () from /lib/libc.so.6
#4 0x400440d5 in ber_free (ber=0x0, freebuf=1) at io.c:187
#5 0x4001bc72 in try_read1msg (ld=0x804ae8c, msgid=-1, all=0, sb=0x8050f4c, lc=0x8050dcc, result=0xbffff670) at result.c:779
#6 0x4001b341 in wait4msg (ld=0x804ae8c, msgid=-1, all=0, timeout=0x8050dcc, result=0xbffff670) at result.c:354
#7 0x08048880 in main ()
#8 0x401609f1 in __libc_start_main () from /lib/libc.so.6
(gdb)




I intended to file a bug report, but the documentation claimed
the memory debugging could trigger false asserts and was for
experts only; seeing as I am not really familiar enough with the
openldap C interface and I had other urgent things to work on
I never got to report this.


Well, now I've reported my findings. Hope somebody here can pick
up on it and perhaps investigate to see if these memory leaks/
free troubles/null pointer troubles are a problem in the openldap
source code, or due to my abuse of the C API :)


With regards, Frode E. Moe Systems developer, Coretrek AS -- http://www.coretrek.com ----



/*
* Minimal LDAP testcase to provoke pointer failures
* a la PHP 4.3.0 (and earlier)
*
*/

//#define USE_LDAPv3

#define CROAK { fprintf(stderr, "failure at %s %d\n", __FILE__, __LINE__); exit(1); }

#include <ldap.h>


#include <stdio.h> #include <stdlib.h>

static char * LDAP_URI = "ldap://10.0.0.34";;
static char * BINDDN = "cn=Administrator,cn=Users,dc=testserver,dc=intra,dc=coretrek,dc=com";
static char * BASE = "dc=testserver,dc=intra,dc=coretrek,dc=com";
static char * PASSWORD = "XXX"; static char * attribs[] = { "displayName", "sAMAccountName", "mail" };
static char * search = "(&(objectCategory=person)(objectClass=user)(!(objectClass=computer)))";



int main(int argc, char**argv) {

	LDAP *ld = NULL;
	LDAPMessage *res, *msg;
	int rc, i;

	ber_int_t msgid;
	int numresults, numresponses;
   int msgtype;

	fprintf(stderr, "ldap test case\n");

rc = ldap_initialize(&ld, LDAP_URI);
if (rc != LDAP_SUCCESS) {
CROAK
}
#ifdef USE_LDAPv3
{
int version = 3;
ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
}
#endif



rc = ldap_bind_s (ld, BINDDN, PASSWORD, LDAP_AUTH_SIMPLE); if (rc != LDAP_SUCCESS) { CROAK }


rc = ldap_search_ext (ld, BASE, LDAP_SCOPE_SUBTREE, search,
attribs,
0, // attrsonly?
NULL, // sctrls
NULL, // cctrls
NULL, // timeout
-1, // sizelimit
&msgid
);


	if (rc != LDAP_SUCCESS) {
		CROAK
	}

	fprintf(stderr, "search ok\n");
	
	numresponses = 0;
   numresults = 0;
	res = NULL;
	
	while ( (rc = ldap_result (ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res)) > 0 ) {
	
		for ( msg = ldap_first_message(ld, res);
				msg != NULL;
				msg = ldap_next_message(ld,res) ) {
		
           msgtype = ldap_msgtype(msg);
	    	fprintf(stderr, "currently at numresults/numresponses %d/%d - type %d \n", numresults, numresponses, msgtype);
           numresponses++;

if (msgtype == LDAP_RES_SEARCH_RESULT) {
goto done;
}
// don't do much about the response
}


		numresults++;
		ldap_msgfree(res);
	}

done:	
   fprintf(stderr, "done!\n");
   ldap_msgfree(res);

fprintf(stderr, "numresults: %d\n", numresults);

ldap_unbind(ld);
fprintf(stderr, "Unbind OK\n");
return 0;
}