From:             [EMAIL PROTECTED]
Operating system: irrelevant
PHP version:      5.2CVS-2008-11-06 (snap)
PHP Bug Type:     LDAP related
Bug description:  add support to build against Novell CLDAP SDK

Description:
------------
Here's a patch which enables the ldap extension to build against Novell
CLDAP SDK. This SDK is available for free on almost every platform, and
provides enhanced SSL functionality:
http://developer.novell.com/wiki/index.php/LDAP_Libraries_for_C
Although we've used this patch since PHP 5.0 on NetWare platform only, I
think it should build on every platform including Win32.
I've also checked with Novell that it is legal to build with the CLDAP
SDK, and then ship the resulting binaries together with the CLDAP SDK
library binaries.
Everything is blocked with HAVE_NOVELLLDAP.
The patch below is available as unified diff file here:
http://www.gknw.net/test/php_issues/ldap.diff

--- ldap.c.orig Sun May 04 23:35:37 2008
+++ ldap.c      Thu Nov 06 14:54:32 2008
@@ -30,12 +30,6 @@
 #include "config.h"
 #endif
 
-/* Additional headers for NetWare */
-#if defined(NETWARE) && (NEW_LIBC)
-#include <sys/select.h>
-#include <sys/timeval.h>
-#endif
-
 #include "php.h"
 #include "php_ini.h"
 
@@ -165,6 +159,9 @@
        PHP_FE(ldap_t61_to_8859,                                                
        NULL)
        PHP_FE(ldap_8859_to_t61,                                                
        NULL)
 #endif
+#ifdef HAVE_NOVELLLDAP
+       PHP_FE(ldap_change_password,                                            
        NULL)
+#endif
 
        {NULL, NULL, NULL}
 };
@@ -230,6 +227,9 @@
  */
 PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY_EX("ldap.max_links", "-1", PHP_INI_SYSTEM,
OnUpdateLong, max_links, zend_ldap_globals, ldap_globals,
display_link_numbers)
+#ifdef HAVE_NOVELLLDAP
+       STD_PHP_INI_ENTRY_EX("ldap.ssl_cert_dir", PHP_LDAP_CERT_DIR,
PHP_INI_SYSTEM, OnUpdateString, ssl_cert_dir, zend_ldap_globals,
ldap_globals, display_link_numbers)
+#endif
 PHP_INI_END()
 /* }}} */
 
@@ -297,6 +297,49 @@
 
        Z_TYPE(ldap_module_entry) = type;
 
+#ifdef HAVE_NOVELLLDAP
+       {
+       int cert_type;
+       DIR *dir_ptr = NULL, *save_dir_ptr = NULL;
+       char *cert_dir = NULL, *tmp_ptr = NULL;
+       char cert_fileName[1024];
+
+       ldapssl_client_init(NULL, NULL);
+
+       cert_dir = LDAPG(ssl_cert_dir);
+       if (cert_dir == NULL || strlen(cert_dir) == 0) {
+               cert_dir = PHP_LDAP_CERT_DIR;
+       }
+
+       save_dir_ptr = opendir(cert_dir);
+       dir_ptr = save_dir_ptr;
+       while (dir_ptr) {
+               dir_ptr = readdir(dir_ptr);
+               if (dir_ptr && dir_ptr->d_type == DT_REG) {
+                       strcpy(cert_fileName, cert_dir);
+                       strcat(cert_fileName, "/");
+                       strcat(cert_fileName, dir_ptr->d_name);
+                       tmp_ptr = strrchr(dir_ptr->d_name, '.') + 1;
+                       if (tmp_ptr && (!stricmp(tmp_ptr, "b64") || 
!stricmp(tmp_ptr, "pem")))
{
+                               cert_type = LDAPSSL_CERT_FILETYPE_B64;
+                       } else {
+                               cert_type = LDAPSSL_CERT_FILETYPE_DER;
+                       }
+                       if (ldapssl_add_trusted_cert(cert_fileName, cert_type) 
==
LDAP_SUCCESS) {
+                               php_error(E_NOTICE, "LDAP: added certificate: 
%s", cert_fileName);
+                       } else {
+                               php_error(E_WARNING, "LDAP: Could not add 
certificate: %s",
cert_fileName);
+                       }
+               }
+       }        
+       if (save_dir_ptr) {
+               closedir(save_dir_ptr);
+       } else {
+               php_error(E_WARNING, "LDAP: Could not open certificates 
directory: %s",
cert_dir);
+       }
+       }
+#endif
+
        return SUCCESS;
 }
 /* }}} */
@@ -306,6 +349,9 @@
 PHP_MSHUTDOWN_FUNCTION(ldap)
 {
        UNREGISTER_INI_ENTRIES();
+#ifdef HAVE_NOVELLLDAP
+       ldapssl_client_deinit();
+#endif
        return SUCCESS;
 }
 /* }}} */
@@ -368,7 +414,15 @@
        php_info_print_table_row(2, "SASL Support", "Enabled");
 #endif
 
+#ifdef HAVE_NOVELLLDAP
+       php_info_print_table_row(2, "SSL Support", "Enabled");
+#endif
+
        php_info_print_table_end();
+
+#ifdef HAVE_NOVELLLDAP
+       DISPLAY_INI_ENTRIES();
+#endif
 }
 /* }}} */
 
@@ -426,6 +480,37 @@
        } else {
                ldap = ldap_init(host, port);
        }
+#elif defined(HAVE_NOVELLLDAP)
+       {
+       int rc=0, ssl=0;
+       char *pHost=host;
+       LDAPURLDesc   *ludp=NULL;
+
+       if ((rc=ldap_url_parse(host, &ludp)) == LDAP_URL_SUCCESS ) {
+               pHost = ludp->lud_host;
+               if (ludp->lud_scheme && strstr(ludp->lud_scheme, "ldaps")) {
+                       ssl=1;
+               }
+               port=ludp->lud_port;
+        }
+       else if (rc == LDAP_URL_ERR_BADSCHEME ){
+               // possibly only server name. Consider port number to decide 
scheme.
+               //
+               if (port == 636) {
+                       ssl=1;
+               }
+       }
+       else {
+               php_error(E_WARNING, "LDAP: invalid URL string");
+               RETURN_FALSE;
+       }
+       
+
+       ldap = ldapssl_init(pHost,port,ssl);
+       if (ludp)
+               ldap_free_urldesc(ludp);
+
+       }
 #else
        ldap = ldap_open(host, port);
 #endif
@@ -487,7 +572,14 @@
 
        ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link",
le_link);
 
+#ifdef HAVE_NOVELLLDAP
+       /* The function ldap_bind_s has been deprecated with Novell CLDAP NDK.
If used
+        * with Novell CLDAP NDK it gives the result, but also displays warning
messages.
+        */
+       if ((rc = ldap_simple_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw)) !=
LDAP_SUCCESS) {
+#else
        if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw,
LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
+#endif
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to 
server:
%s", ldap_err2string(rc));
                RETURN_FALSE;
        } else {
@@ -2123,10 +2215,14 @@
        }
 
        ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link",
le_link);
-
+#ifdef HAVE_NOVELLLDAP
+       if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION,
&protocol)) != LDAP_SUCCESS) ||
+          ((rc = ldapssl_start_tls(ld->link)) != LDAP_SUCCESS)) {
+#else
        if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION,
&protocol)) != LDAP_SUCCESS) ||
                ((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
        ) {
+#endif
                php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to start 
TLS: %s",
ldap_err2string(rc));
                RETURN_FALSE;
        } else {
@@ -2223,6 +2319,85 @@
 }
 /* }}} */
 #endif
+
+#ifdef HAVE_NOVELLLDAP
+/* {{{ proto bool ldap_change_password(resource link, string dn, string
newpassword [, string oldpassword])
+   Change the users password for eDirectory based LDAP functions
+   For eDirectory, change password is two operations, delete and add in
one modify call */
+PHP_FUNCTION(ldap_change_password)
+{
+       pval **link, **entry_dn, **old_password, **new_password;
+       char *ldap_dn, *ldap_old_password="", *ldap_new_password;
+       char *oldValues[2], *newValues[2];
+       LDAPMod ldap_delmod, ldap_addmod, ldap_replacemod, *modify[3];
+       ldap_linkdata *ld;
+
+       switch(ZEND_NUM_ARGS()) {
+               case 4 :
+                       if (zend_get_parameters_ex(4, &link, &entry_dn, 
&new_password,
&old_password) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       convert_to_string_ex(old_password);
+                       ldap_old_password = Z_STRVAL_PP(old_password);
+                       break;
+               case 3:
+                       if (zend_get_parameters_ex(3, &link, &entry_dn, 
&new_password) ==
FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link",
le_link);
+
+       convert_to_string_ex(new_password);
+       ldap_new_password = Z_STRVAL_PP(new_password);
+
+       convert_to_string_ex(entry_dn);
+       ldap_dn = Z_STRVAL_PP(entry_dn);
+
+       // First try to set password (for admin). If fails then replace the
password
+       //
+       ldap_replacemod.mod_op = LDAP_MOD_REPLACE;
+       ldap_replacemod.mod_type   = "userPassword";
+       newValues[0] = ldap_new_password;
+       newValues[1] = NULL;
+       ldap_replacemod.mod_values = newValues;
+       modify[0] = &ldap_replacemod;
+       modify[1] = NULL;
+       if (ldap_modify_s( ld->link, ldap_dn, modify) == LDAP_SUCCESS) {
+               RETURN_TRUE;
+       }
+
+
+       ldap_delmod.mod_op   = LDAP_MOD_DELETE;
+       ldap_delmod.mod_type = "userPassword";
+       oldValues[0] = ldap_old_password;
+       oldValues[1] = NULL;
+       ldap_delmod.mod_values = oldValues;
+
+       ldap_addmod.mod_op   = LDAP_MOD_ADD;
+       ldap_addmod.mod_type = "userPassword";
+       newValues[0] = ldap_new_password;
+       newValues[1] = NULL;
+       ldap_addmod.mod_values = newValues;
+
+       modify[0] = &ldap_delmod;
+       modify[1] = &ldap_addmod;
+       modify[2] = NULL;
+
+       if (ldap_modify_s( ld->link, ldap_dn, modify) != LDAP_SUCCESS) {
+               php_error(E_WARNING, "LDAP:  Unable to change password:
%s",ldap_err2string(_get_lderrno(ld->link)));
+               RETURN_FALSE;
+       } else {
+               RETURN_TRUE;
+       }
+}
+
+#endif
+
 
 #ifdef STR_TRANSLATION
 /* {{{ php_ldap_do_translate
##############################################################################

--- php_ldap.h.orig     Mon Dec 31 08:33:30 2007
+++ php_ldap.h  Thu Nov 06 14:59:23 2008
@@ -28,6 +28,14 @@
 #endif
 #include <ldap.h>
 
+/* Additional headers and defines for Novell CLDAP NDK */
+#ifdef HAVE_NOVELLLDAP
+#include <ldap_ssl.h>
+#ifndef PHP_LDAP_CERT_DIR
+#define PHP_LDAP_CERT_DIR "./ldapcert"
+#endif
+#endif
+
 extern zend_module_entry ldap_module_entry;
 #define ldap_module_ptr &ldap_module_entry
 
@@ -96,9 +104,16 @@
 PHP_FUNCTION(ldap_8859_to_t61);
 #endif
 
+#ifdef HAVE_NOVELLLDAP
+PHP_FUNCTION(ldap_change_password);
+#endif
+
 ZEND_BEGIN_MODULE_GLOBALS(ldap)
        long num_links;
        long max_links;
+#ifdef HAVE_NOVELLLDAP
+       char *ssl_cert_dir;
+#endif
 ZEND_END_MODULE_GLOBALS(ldap)
 
 #ifdef ZTS



-- 
Edit bug report at http://bugs.php.net/?id=46507&edit=1
-- 
Try a CVS snapshot (PHP 5.2):        
http://bugs.php.net/fix.php?id=46507&r=trysnapshot52
Try a CVS snapshot (PHP 5.3):        
http://bugs.php.net/fix.php?id=46507&r=trysnapshot53
Try a CVS snapshot (PHP 6.0):        
http://bugs.php.net/fix.php?id=46507&r=trysnapshot60
Fixed in CVS:                        
http://bugs.php.net/fix.php?id=46507&r=fixedcvs
Fixed in CVS and need be documented: 
http://bugs.php.net/fix.php?id=46507&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=46507&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=46507&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=46507&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=46507&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=46507&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=46507&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=46507&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=46507&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=46507&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=46507&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=46507&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=46507&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=46507&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=46507&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=46507&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=46507&r=mysqlcfg

Reply via email to