php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15431 Resource destructor called too early
Submitted: 2002-02-07 13:58 UTC Modified: 2002-07-04 06:57 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: jonny at 1409 dot org Assigned:
Status: Closed Package: LDAP related
PHP Version: 4.1.1 OS: RedHat Linux 7.2
Private report: No CVE-ID: None
 [2002-02-07 13:58 UTC] jonny at 1409 dot org
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");

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-06-29 20:12 UTC] sniper@php.net
Some resource bug was fixed recently in CVS. Please try this snapshot:

http://snaps.php.net/php4-latest.tar.gz

 [2002-07-04 06:38 UTC] jonny at 1409 dot org
I've only taken ldap.c from the snapshot. The bugs seems to have gone. Thanks a lot!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 11:01:28 2024 UTC