[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: PHP+LDAP not really works [includes small debug patch to 2.1.12]
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;
> }