]> granicus.if.org Git - php/commitdiff
MFH: Fixing #48441 (ldap_search() with sizelimit/timelimit/deref options makes those...
authorPatrick Allaert <patrickallaert@php.net>
Mon, 15 Jun 2009 15:18:48 +0000 (15:18 +0000)
committerPatrick Allaert <patrickallaert@php.net>
Mon, 15 Jun 2009 15:18:48 +0000 (15:18 +0000)
ext/ldap/ldap.c
ext/ldap/tests/bug48441.phpt [new file with mode: 0644]
ext/ldap/tests/connect.inc [new file with mode: 0644]
ext/ldap/tests/skipifbindfailure.inc [new file with mode: 0644]

index 2b52871818178d0744c57c42b152db293c2b1edf..754a490d8235f1a51ac3d47c4bb0794703354747 100644 (file)
@@ -641,13 +641,15 @@ PHP_FUNCTION(ldap_unbind)
 
 /* {{{ php_set_opts
  */
-static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
+static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, int *old_sizelimit, int *old_timelimit, int *old_deref)
 {
        /* sizelimit */
        if (sizelimit > -1) {
 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+               ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit);
                ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
 #else
+               *old_sizelimit = ldap->ld_sizelimit; 
                ldap->ld_sizelimit = sizelimit; 
 #endif
        }
@@ -655,8 +657,10 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
        /* timelimit */
        if (timelimit > -1) {
 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+               ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_timelimit);
                ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
 #else
+               *old_timelimit = ldap->ld_timelimit; 
                ldap->ld_timelimit = timelimit; 
 #endif
        }
@@ -664,8 +668,10 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
        /* deref */
        if (deref > -1) {
 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+               ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_deref);
                ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
 #else
+               *old_deref = ldap->ld_deref; 
                ldap->ld_deref = deref; 
 #endif
        }
@@ -686,6 +692,9 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
        int ldap_sizelimit = -1; 
        int ldap_timelimit = -1; 
        int ldap_deref = -1;     
+       int old_ldap_sizelimit = -1; 
+       int old_ldap_timelimit = -1; 
+       int old_ldap_deref = -1;         
        int num_attribs = 0;
        int i, errno;
        int myargcount = ZEND_NUM_ARGS();
@@ -820,7 +829,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
                                ldap_filter = Z_STRVAL_PP(entry);
                        }
 
-                       php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref);
+                       php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
 
                        /* Run the actual search */     
                        rcs[i] = ldap_search(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly);
@@ -862,7 +871,7 @@ cleanup_parallel:
                        goto cleanup;
                }
 
-               php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref);
+               php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
 
                /* Run the actual search */     
                errno = ldap_search_s(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, &ldap_res);
@@ -893,6 +902,8 @@ cleanup_parallel:
        }
 
 cleanup:
+       // Restoring previous options
+       php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref);
        if (ldap_attrs != NULL) {
                efree(ldap_attrs);
        }
diff --git a/ext/ldap/tests/bug48441.phpt b/ext/ldap/tests/bug48441.phpt
new file mode 100644 (file)
index 0000000..8725661
--- /dev/null
@@ -0,0 +1,169 @@
+--TEST--
+ldap_search() bug 48441 - options persists after specifying them in ldap_search
+--CREDITS--
+Patrick Allaert <patrickallaert@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifbindfailure.inc');
+?>
+--FILE--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+insert_dummy_data($link);
+
+$dn = "dc=my-domain,dc=com";
+$filter = "(objectclass=person)";
+
+var_dump(
+       $result = ldap_search($link, $dn, $filter, array('sn')),
+       ldap_get_entries($link, $result)
+);
+var_dump(
+       $result = ldap_search($link, $dn, $filter, array('sn'), 1, 1, 1, LDAP_DEREF_ALWAYS),
+       ldap_get_entries($link, $result)
+);
+var_dump(
+       $result = ldap_search($link, $dn, $filter, array('sn')),
+       ldap_get_entries($link, $result)
+);
+?>
+===DONE===
+--CLEAN--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+remove_dummy_data($link);
+?>
+--EXPECTF--
+resource(%d) of type (ldap result)
+array(4) {
+  ["count"]=>
+  int(3)
+  [0]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN1"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+  [1]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN2"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userB,dc=my-domain,dc=com"
+  }
+  [2]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN3"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
+  }
+}
+
+Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d
+resource(%d) of type (ldap result)
+array(2) {
+  ["count"]=>
+  int(1)
+  [0]=>
+  array(4) {
+    ["sn"]=>
+    array(1) {
+      ["count"]=>
+      int(0)
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+}
+resource(%d) of type (ldap result)
+array(4) {
+  ["count"]=>
+  int(3)
+  [0]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN1"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+  [1]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN2"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userB,dc=my-domain,dc=com"
+  }
+  [2]=>
+  array(4) {
+    ["sn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(7) "testSN3"
+    }
+    [0]=>
+    string(2) "sn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
+  }
+}
+===DONE===
diff --git a/ext/ldap/tests/connect.inc b/ext/ldap/tests/connect.inc
new file mode 100644 (file)
index 0000000..ddb5782
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/*
+Default values are "localhost", "root", database "test" and empty password.
+Change the LDAP_TEST_* environment values if you want to use another configuration.
+*/
+
+$host                  = getenv("LDAP_TEST_HOST")      ? getenv("LDAP_TEST_HOST")      : "localhost";
+$port                  = getenv("LDAP_TEST_PORT")      ? getenv("LDAP_TEST_PORT")      : 389;
+$user                  = getenv("LDAP_TEST_USER")      ? getenv("LDAP_TEST_USER")      : "cn=Manager,dc=my-domain,dc=com";
+$sasl_user             = getenv("LDAP_TEST_SASL_USER") ? getenv("LDAP_TEST_SASL_USER") : "Manager";
+$passwd                        = getenv("LDAP_TEST_PASSWD")    ? getenv("LDAP_TEST_PASSWD")    : "secret";
+$protocol_version      = getenv("LDAP_TEST_OPT_PROTOCOL_VERSION")      ? getenv("LDAP_TEST_OPT_PROTOCOL_VERSION")      : 3;
+$skip_on_bind_failure  = getenv("LDAP_TEST_SKIP_BIND_FAILURE") ? getenv("LDAP_TEST_SKIP_BIND_FAILURE") : true;
+
+function ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version) {
+       $link = ldap_connect($host, $port);
+       ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
+       ldap_bind($link, $user, $passwd);
+       return $link;
+}
+
+function insert_dummy_data($link) {
+       ldap_add($link, "dc=my-domain,dc=com", array(
+               "objectClass"   => array(
+                       "top",
+                       "dcObject",
+                       "organization"),
+               "dc"                    => "my-domain",
+               "o"                             => "my-domain",
+       ));
+       ldap_add($link, "cn=userA,dc=my-domain,dc=com", array(
+               "objectclass" => "person",
+               "cn" => "userA",
+               "sn" => "testSN1",
+               "userPassword" => "oops",
+               "telephoneNumber" => "xx-xx-xx-xx-xx",
+               "description" => "user A",
+       ));
+       ldap_add($link, "cn=userB,dc=my-domain,dc=com", array(
+               "objectclass" => "person",
+               "cn" => "userB",
+               "sn" => "testSN2",
+               "userPassword" => "oopsIDitItAgain",
+               "description" => "user B",
+       ));
+       ldap_add($link, "cn=userC,cn=userB,dc=my-domain,dc=com", array(
+               "objectclass" => "person",
+               "cn" => "userC",
+               "sn" => "testSN3",
+               "userPassword" => "0r1g1na1 passw0rd",
+       ));
+}
+
+function remove_dummy_data($link) {
+       ldap_delete($link, "cn=userC,cn=userB,dc=my-domain,dc=com");
+       ldap_delete($link, "cn=userA,dc=my-domain,dc=com");
+       ldap_delete($link, "cn=userB,dc=my-domain,dc=com");
+       ldap_delete($link, "dc=my-domain,dc=com");
+}
+?>
diff --git a/ext/ldap/tests/skipifbindfailure.inc b/ext/ldap/tests/skipifbindfailure.inc
new file mode 100644 (file)
index 0000000..f79bb9d
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+require_once 'connect.inc';
+
+if ($skip_on_bind_failure) {
+
+       $link = ldap_connect($host, $port);
+       ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
+       if (!@ldap_bind($link, $user, $passwd))
+               die(sprintf("skip Can't bind to LDAP Server - [%d] %s", ldap_errno($link), ldap_error($link)));
+
+       ldap_unbind($link);
+}
+?>