|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2002-06-29 20:12 UTC] sniper@php.net
[2002-07-04 06:38 UTC] jonny at 1409 dot org
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 19:00:01 2025 UTC |
This bug is weird and it took me several days to track it down. But I have found a way to reproduce it, so please read on. This might also be a general problem, not only LDAP related. I have reproduced it connecting to a NDS-LDAP-Gateway and an Active Directory Server. Both only support LDAP v2, so it *might* not be reproducable with a v3 server. To verify it I suggest to activate implicit flushing in php.ini and putting a php_printf() debug message into _free_ldap_result() in ldap.c, just before ldap_msgfree() gets called. This way you will see that the call to _free_ldap_result() will appear immediately after the PHP method get_entry() returns. After verification comment out the ldap_msgfree() call and you will notice that the segfault no longer occurs. Here is the code, the critical places have comments and debug messages included: class ldap { function connect($server,$user="",$pw="") { $this->link=ldap_connect($server); $r=ldap_bind($this->link,$user,$pw); } function get_entry($dn) { $res=ldap_read($this->link,$dn,"objectclass=*"); if (!$res) return false; print "*** calling ldap_first_entry()<br>\n";flush(); $this->entry=ldap_first_entry($this->link, $res); if (!$this->entry) return false; print "*** returning from get_entry()<br>\n"; return true; } function get_attributes() { if(!$this->entry) return false; print "*** calling ldap_get_attributes(), prepare ". "for segfault<br>\n";flush(); // Apache will segfault *here*, as the LDAPMessage // was already freed! $this->attributes=ldap_get_attributes($this->link, $this->entry); if(!$this->attributes) return false; return true; } function print_entry($dn) { if (!$this->get_entry($dn)) return false; print "*** returned from get_entry()<br>\n"; // _free_ldap_result from ldap.c gets called // although the resource is still referenced // through $this->entry!! if (!$this->get_attributes()) return false; for($i=0;$i<$this->attributes['count'];$i++) { $attrname=$this->attributes[$i]; $values=$this->attributes[$attrname]; for($j=0;$j<$values['count'];$j++) { print "- $attrname [$j]: ".$values[$j]."<br>\n"; } } } } $ldap=new ldap(); $ldap->connect("ldapserver.example.com", "ldapuser", "ldappassword"); $ldap->print_entry("CN=jonny,OU=User,DC=example,DC=com");