diff options
-rw-r--r-- | lib/ldap.c | 92 |
1 files changed, 66 insertions, 26 deletions
diff --git a/lib/ldap.c b/lib/ldap.c index e4ce503c5..ce586caf8 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -81,7 +81,12 @@ typedef struct { char *lud_host; int lud_port; +#if defined(CURL_LDAP_WIN) && \ + (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI)) + TCHAR *lud_dn; +#else char *lud_dn; +#endif; char **lud_attrs; int lud_scope; char *lud_filter; @@ -681,15 +686,6 @@ static bool unescape_elements (void *data, LDAPURLDesc *ludp) ludp->lud_attrs_dups++; } - if(ludp->lud_dn) { - char *dn = ludp->lud_dn; - char *new_dn = curl_easy_unescape(data, dn, 0, NULL); - - free(dn); - ludp->lud_dn = new_dn; - if(!new_dn) - return (FALSE); - } return (TRUE); } @@ -709,7 +705,10 @@ static bool unescape_elements (void *data, LDAPURLDesc *ludp) */ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) { - char *p, *q; + int rc = LDAP_SUCCESS; + char *path; + char *p; + char *q; int i; if(!conn->data || @@ -722,21 +721,48 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) ludp->lud_port = conn->remote_port; ludp->lud_host = conn->host.name; - /* parse DN (Distinguished Name). - */ - ludp->lud_dn = strdup(conn->data->state.path+1); - if(!ludp->lud_dn) + /* Duplicate the path */ + p = path = strdup(conn->data->state.path + 1); + if(!path) return LDAP_NO_MEMORY; - p = strchr(ludp->lud_dn, '?'); - LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) : - strlen(ludp->lud_dn), ludp->lud_dn)); + /* Parse the DN (Distinguished Name) */ + q = strchr(p, '?'); + if(q) + *q++ = '\0'; + + if(*p) { + char *dn = p; + char *unescapped; + + LDAP_TRACE("DN '%s'\n", dn); + + unescapped = curl_easy_unescape(conn->data, dn, 0, NULL); + if(!unescapped) { + rc = LDAP_NO_MEMORY; + + goto quit; + } + +#if defined(CURL_LDAP_WIN) && \ + (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI)) + ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescapped); + if(!ludp->lud_dn) { + Curl_safefree(unescapped); + + rc = LDAP_NO_MEMORY; + + goto quit; + } +#else + ludp->lud_dn = unescapped; +#endif + } + p = q; if(!p) goto success; - *p++ = '\0'; - /* parse attributes. skip "??". */ q = strchr(p, '?'); @@ -745,8 +771,11 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) if(*p && *p != '?') { ludp->lud_attrs = split_str(p); - if(!ludp->lud_attrs) - return LDAP_NO_MEMORY; + if(!ludp->lud_attrs) { + rc = LDAP_NO_MEMORY; + + goto quit; + } for(i = 0; ludp->lud_attrs[i]; i++) LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i])); @@ -765,7 +794,9 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) if(*p && *p != '?') { ludp->lud_scope = str2scope(p); if(ludp->lud_scope == -1) { - return LDAP_INVALID_SYNTAX; + rc = LDAP_INVALID_SYNTAX; + + goto quit; } LDAP_TRACE (("scope %d\n", ludp->lud_scope)); } @@ -780,16 +811,25 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) if(q) *q++ = '\0'; if(!*p) { - return LDAP_INVALID_SYNTAX; + rc = LDAP_INVALID_SYNTAX; + + goto quit; } ludp->lud_filter = p; LDAP_TRACE (("filter '%s'\n", ludp->lud_filter)); - success: +success: if(!unescape_elements(conn->data, ludp)) - return LDAP_NO_MEMORY; - return LDAP_SUCCESS; + rc = LDAP_NO_MEMORY; + +quit: +#if defined(CURL_LDAP_WIN) && \ + (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI)) + Curl_unicodefree(path); +#endif + + return rc; } static int _ldap_url_parse (const struct connectdata *conn, |