From:             [EMAIL PROTECTED]
Operating system: RedHat Linux 7.2
PHP version:      4.1.1
PHP Bug Type:     LDAP related
Bug description:  Resource destructor called too early

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");

-- 
Edit bug report at http://bugs.php.net/?id=15431&edit=1
-- 
Fixed in CVS:        http://bugs.php.net/fix.php?id=15431&r=fixedcvs
Fixed in release:    http://bugs.php.net/fix.php?id=15431&r=alreadyfixed
Need backtrace:      http://bugs.php.net/fix.php?id=15431&r=needtrace
Try newer version:   http://bugs.php.net/fix.php?id=15431&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=15431&r=support
Expected behavior:   http://bugs.php.net/fix.php?id=15431&r=notwrong
Not enough info:     http://bugs.php.net/fix.php?id=15431&r=notenoughinfo


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to