sniper          Sun Apr 17 12:26:00 2005 EDT

  Modified files:              
    /php-src/ext/ldap   ldap.c 
  Log:
  - Fixed bug #30819 (Better support for LDAP SASL bind)
  
http://cvs.php.net/diff.php/php-src/ext/ldap/ldap.c?r1=1.156&r2=1.157&ty=u
Index: php-src/ext/ldap/ldap.c
diff -u php-src/ext/ldap/ldap.c:1.156 php-src/ext/ldap/ldap.c:1.157
--- php-src/ext/ldap/ldap.c:1.156       Tue Apr  5 16:31:10 2005
+++ php-src/ext/ldap/ldap.c     Sun Apr 17 12:25:59 2005
@@ -22,7 +22,7 @@
    +----------------------------------------------------------------------+
  */
  
-/* $Id: ldap.c,v 1.156 2005/04/05 20:31:10 tony2001 Exp $ */
+/* $Id: ldap.c,v 1.157 2005/04/17 16:25:59 sniper Exp $ */
 #define IS_EXT_MODULE
 
 #ifdef HAVE_CONFIG_H
@@ -265,6 +265,13 @@
        REGISTER_LONG_CONSTANT("LDAP_OPT_DEBUG_LEVEL", LDAP_OPT_DEBUG_LEVEL, 
CONST_PERSISTENT | CONST_CS);
 #endif
 
+#ifdef HAVE_LDAP_SASL
+       REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_MECH", LDAP_OPT_X_SASL_MECH, 
CONST_PERSISTENT | CONST_CS);
+       REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_REALM", LDAP_OPT_X_SASL_REALM, 
CONST_PERSISTENT | CONST_CS);
+       REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHCID", 
LDAP_OPT_X_SASL_AUTHCID, CONST_PERSISTENT | CONST_CS);
+       REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHZID", 
LDAP_OPT_X_SASL_AUTHZID, CONST_PERSISTENT | CONST_CS);
+#endif
+
 #ifdef ORALDAP
        REGISTER_LONG_CONSTANT("GSLC_SSL_NO_AUTH", GSLC_SSL_NO_AUTH, 
CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, 
CONST_PERSISTENT | CONST_CS);
@@ -303,7 +310,7 @@
 
        php_info_print_table_start();
        php_info_print_table_row(2, "LDAP Support", "enabled");
-       php_info_print_table_row(2, "RCS Version", "$Id: ldap.c,v 1.156 
2005/04/05 20:31:10 tony2001 Exp $");
+       php_info_print_table_row(2, "RCS Version", "$Id: ldap.c,v 1.157 
2005/04/17 16:25:59 sniper Exp $");
 
        if (LDAPG(max_links) == -1) {
                snprintf(tmp, 31, "%ld/unlimited", LDAPG(num_links));
@@ -478,42 +485,122 @@
 /* }}} */
 
 #ifdef HAVE_LDAP_SASL
+typedef struct {
+       char *mech;
+       char *realm;
+       char *authcid;
+       char *passwd;
+       char *authzid;
+} php_ldap_bictx;
+
+/* {{{ _php_sasl_setdefs
+ */
+static php_ldap_bictx *_php_sasl_setdefs(LDAP *ld, char *sasl_mech, char 
*sasl_realm, char *binddn, char *pass, char *sasl_authz_id)
+{
+       php_ldap_bictx *ctx;
+
+       ctx = ber_memalloc(sizeof(php_ldap_bictx));     
+       ctx->mech    = (sasl_mech) ? ber_strdup(sasl_mech) : NULL;
+       ctx->realm   = (sasl_realm) ? ber_strdup(sasl_realm) : NULL;
+       ctx->authcid = (binddn) ? ber_strdup(binddn) : NULL;
+       ctx->passwd  = (pass) ? ber_strdup(pass) : NULL;
+       ctx->authzid = (sasl_authz_id) ? ber_strdup(sasl_authz_id) : NULL;
+
+       if (ctx->mech == NULL) {
+               ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &ctx->mech);
+       }
+       if (ctx->realm == NULL) {
+               ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &ctx->realm);
+       }
+       if (ctx->authcid == NULL) {
+               ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &ctx->authcid);
+       }
+       if (ctx->authzid == NULL) {
+               ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &ctx->authzid);
+       }
+
+       return ctx;
+}
+
+/* {{{ _php_sasl_setdefs
+ */
+static void _php_sasl_freedefs(php_ldap_bictx *ctx)
+{
+       if (ctx->mech) ber_memfree(ctx->mech);
+       if (ctx->realm) ber_memfree(ctx->realm);
+       if (ctx->authcid) ber_memfree(ctx->authcid);
+       if (ctx->passwd) ber_memfree(ctx->passwd);
+       if (ctx->authzid) ber_memfree(ctx->authzid);
+       ber_memfree(ctx);
+}
+
 /* {{{ _php_sasl_interact
-   Interact function for SASL */
+   Internal interact function for SASL */
 static int _php_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void 
*in)
 {
        sasl_interact_t *interact = in;
+       const char *p;
+       php_ldap_bictx *ctx = defaults;
 
-       while (interact->id != SASL_CB_LIST_END) {
-               const char *dflt = interact->defresult;
-
-               interact->result = strdup((dflt && *dflt) ? dflt : "");
-               interact->len = interact->result ? strlen(interact->result) : 0;
-               interact++;
-       };
+       for (;interact->id != SASL_CB_LIST_END;interact++) {
+               p = NULL;
+               switch(interact->id) {
+                       case SASL_CB_GETREALM:
+                               p = ctx->realm;
+                               break;
+                       case SASL_CB_AUTHNAME:
+                               p = ctx->authcid;
+                               break;
+                       case SASL_CB_USER:
+                               p = ctx->authzid;
+                               break;
+                       case SASL_CB_PASS:
+                               p = ctx->passwd;
+                               break;
+               }
+               if (p) {
+                       interact->result = p;
+                       interact->len = strlen(interact->result);
+               }
+       }
        return LDAP_SUCCESS;
 }
 
-/* {{{ proto bool ldap_sasl_bind(resource link)
+/* {{{ proto bool ldap_sasl_bind(resource link [, string binddn, string 
password, string sasl_mech, string sasl_realm, string sasl_authz_id, string 
props])
    Bind to LDAP directory using SASL */
 PHP_FUNCTION(ldap_sasl_bind)
 {
        zval *link;
        ldap_linkdata *ld;
-       int rc;
+       char *binddn = NULL;
+       char *pass = NULL;
+       char *sasl_mech = NULL;
+       char *sasl_realm = NULL;
+       char *sasl_authz_id = NULL;
+       char *props = NULL;
+       int rc, dn_len, pass_len, mech_len, realm_len, authz_id_len, props_len;
+       php_ldap_bictx *ctx;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &link) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ssssss", &link, 
&binddn, &dn_len, &pass, &pass_len, &sasl_mech, &mech_len, &sasl_realm, 
&realm_len, &sasl_authz_id, &authz_id_len, &props, &props_len) == FAILURE) {
                RETURN_FALSE;
        }
 
        ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", 
le_link);
 
-       if ((rc = ldap_sasl_interactive_bind_s(ld->link, NULL, NULL, NULL, 
NULL, LDAP_SASL_QUIET, _php_sasl_interact, NULL)) != LDAP_SUCCESS) {
+       ctx = _php_sasl_setdefs(ld->link, sasl_mech, sasl_realm, binddn, pass, 
sasl_authz_id);
+
+       if (props) {
+               ldap_set_option(ld->link, LDAP_OPT_X_SASL_SECPROPS, props);
+       }
+
+       rc = ldap_sasl_interactive_bind_s(ld->link, binddn, ctx->mech, NULL, 
NULL, LDAP_SASL_QUIET, _php_sasl_interact, ctx);
+       if (rc != LDAP_SUCCESS) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to 
server: %s", ldap_err2string(rc));
-               RETURN_FALSE;
+               RETVAL_FALSE;
        } else {
-               RETURN_TRUE;
+               RETVAL_TRUE;
        }
+       _php_sasl_freedefs(ctx);
 }
 /* }}} */
 #endif /* HAVE_LDAP_SASL */
@@ -1647,6 +1734,12 @@
        /* options with string value */
        case LDAP_OPT_HOST_NAME:
        case LDAP_OPT_ERROR_STRING:
+#ifdef HAVE_LDAP_SASL
+       case LDAP_OPT_X_SASL_MECH:   
+       case LDAP_OPT_X_SASL_REALM:
+       case LDAP_OPT_X_SASL_AUTHCID:
+       case LDAP_OPT_X_SASL_AUTHZID:
+#endif
 #ifdef LDAP_OPT_MATCHED_DN
        case LDAP_OPT_MATCHED_DN:
 #endif
@@ -1700,7 +1793,7 @@
        opt = Z_LVAL_PP(option);
 
        switch (opt) {
-               /* options with int value */
+       /* options with int value */
        case LDAP_OPT_DEREF:
        case LDAP_OPT_SIZELIMIT:
        case LDAP_OPT_TIMELIMIT:
@@ -1720,6 +1813,12 @@
                /* options with string value */
        case LDAP_OPT_HOST_NAME:
        case LDAP_OPT_ERROR_STRING:
+#ifdef HAVE_LDAP_SASL
+       case LDAP_OPT_X_SASL_MECH:   
+       case LDAP_OPT_X_SASL_REALM:
+       case LDAP_OPT_X_SASL_AUTHCID:
+       case LDAP_OPT_X_SASL_AUTHZID:
+#endif
 #ifdef LDAP_OPT_MATCHED_DN
        case LDAP_OPT_MATCHED_DN:
 #endif

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to