File httpd-2.2.x-bnc727071-mod_authnz_ldap-utf8.diff of Package apache2

diff -rNU 20 ../httpd-2.2.12-o/modules/aaa/mod_authnz_ldap.c ./modules/aaa/mod_authnz_ldap.c
--- ../httpd-2.2.12-o/modules/aaa/mod_authnz_ldap.c	2009-01-16 03:45:23.000000000 +0100
+++ ./modules/aaa/mod_authnz_ldap.c	2011-11-24 03:57:56.000000000 +0100
@@ -136,40 +136,63 @@
 
     if (lang_line) {
         lang_line = apr_pstrdup(r->pool, lang_line);
         for (lang = lang_line;*lang;lang++) {
             if ((*lang == ',') || (*lang == ';')) {
                 *lang = '\0';
                 break;
             }
         }
         lang = derive_codepage_from_lang(r->pool, lang_line);
 
         if (lang && (apr_xlate_open(&convset, to_charset, lang, r->pool) == APR_SUCCESS)) {
             return convset;
         }
     }
 
     return NULL;
 }
 
 
+static const char* authn_ldap_xlate_password(request_rec *r,
+                                             const char* sent_password)
+{
+    apr_xlate_t *convset = NULL;
+    apr_size_t inbytes;
+    apr_size_t outbytes;
+    char *outbuf;
+
+    if (charset_conversions && (convset = get_conv_set(r)) ) {
+        inbytes = strlen(sent_password);
+        outbytes = (inbytes+1)*3;
+        outbuf = apr_pcalloc(r->pool, outbytes);
+
+        /* Convert the password to UTF-8. */
+        if (apr_xlate_conv_buffer(convset, sent_password, &inbytes, outbuf,
+                                  &outbytes) == APR_SUCCESS)
+            return outbuf;
+    }
+
+    return sent_password;
+}
+
+
 /*
  * Build the search filter, or at least as much of the search filter that
  * will fit in the buffer. We don't worry about the buffer not being able
  * to hold the entire filter. If the buffer wasn't big enough to hold the
  * filter, ldap_search_s will complain, but the only situation where this
  * is likely to happen is if the client sent a really, really long
  * username, most likely as part of an attack.
  *
  * The search filter consists of the filter provided with the URL,
  * combined with a filter made up of the attribute provided with the URL,
  * and the actual username passed by the HTTP client. For example, assume
  * that the LDAP URL is
  *
  *   ldap://ldap.airius.com/ou=People, o=Airius?uid??(posixid=*)
  *
  * Further, assume that the userid passed by the client was `userj'.  The
  * search filter will be (&(posixid=*)(uid=userj)).
  */
 #define FILTER_LENGTH MAX_STRING_LEN
 static void authn_ldap_build_filter(char *filtbuf,
@@ -325,40 +348,41 @@
  *
  * This phase authenticates the credentials the user has sent with
  * the request (ie the username and password are checked). This is done
  * by making an attempt to bind to the LDAP server using this user's
  * DN and the supplied password.
  *
  */
 static authn_status authn_ldap_check_password(request_rec *r, const char *user,
                                               const char *password)
 {
     int failures = 0;
     const char **vals = NULL;
     char filtbuf[FILTER_LENGTH];
     authn_ldap_config_t *sec =
         (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
 
     util_ldap_connection_t *ldc = NULL;
     int result = 0;
     int remote_user_attribute_set = 0;
     const char *dn = NULL;
+    const char *utfpassword;
 
     authn_ldap_request_t *req =
         (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t));
     ap_set_module_config(r->request_config, &authnz_ldap_module, req);
 
 /*
     if (!sec->enabled) {
         return AUTH_USER_NOT_FOUND;
     }
 */
 
     /*
      * Basic sanity checks before any LDAP operations even happen.
      */
     if (!sec->have_ldap_url) {
         return AUTH_GENERAL_ERROR;
     }
 
 start_over:
 
@@ -378,43 +402,47 @@
                   "[%" APR_PID_T_FMT "] auth_ldap authenticate: using URL %s", getpid(), sec->url);
 
     /* Get the password that the client sent */
     if (password == NULL) {
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                       "[%" APR_PID_T_FMT "] auth_ldap authenticate: no password specified", getpid());
         util_ldap_connection_close(ldc);
         return AUTH_GENERAL_ERROR;
     }
 
     if (user == NULL) {
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                       "[%" APR_PID_T_FMT "] auth_ldap authenticate: no user specified", getpid());
         util_ldap_connection_close(ldc);
         return AUTH_GENERAL_ERROR;
     }
 
     /* build the username filter */
     authn_ldap_build_filter(filtbuf, r, user, NULL, sec);
 
+    /* convert password to utf-8 */
+    utfpassword = authn_ldap_xlate_password(r, password);
+
     /* do the user search */
     result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
-                                         sec->attributes, filtbuf, password, &dn, &vals);
+                                         sec->attributes, filtbuf, utfpassword,
+                                         &dn, &vals);
     util_ldap_connection_close(ldc);
 
     /* sanity check - if server is down, retry it up to 5 times */
     if (AP_LDAP_IS_SERVER_DOWN(result)) {
         if (failures++ <= 5) {
             goto start_over;
         }
     }
 
     /* handle bind failure */
     if (result != LDAP_SUCCESS) {
         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                       "[%" APR_PID_T_FMT "] auth_ldap authenticate: "
                       "user %s authentication failed; URI %s [%s][%s]",
                       getpid(), user, r->uri, ldc->reason, ldap_err2string(result));
 
         return (LDAP_NO_SUCH_OBJECT == result) ? AUTH_USER_NOT_FOUND
 #ifdef LDAP_SECURITY_ERROR
                  : (LDAP_SECURITY_ERROR(result)) ? AUTH_DENIED
 #else
openSUSE Build Service is sponsored by