Add \0 safe parsing of LDAP binary attributes
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 28 May 2014 15:05:44 +0000 (16:05 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 28 May 2014 15:05:44 +0000 (16:05 +0100)
src/lib/valuepair.c
src/modules/rlm_ldap/attrmap.c
src/modules/rlm_ldap/ldap.h

index 985e635..c3b1fd8 100644 (file)
@@ -1199,8 +1199,8 @@ static char const *hextab = "0123456789abcdef";
  *
  * @param vp to assign value to.
  * @param value string to convert. Binary safe for variable length values if len is provided.
- * @param inlen may be 0 in which case strlen(len) is used to determine length, else the length
- *       of the string or sub string to parse.
+ * @param inlen may be 0 in which case strlen(len) is used to determine length, else inline
+ *       should be the length of the string or sub string to parse.
  * @return true on success, else false.
  */
 bool pairparsevalue(VALUE_PAIR *vp, char const *value, size_t inlen)
index 71ed2dc..57ec056 100644 (file)
@@ -51,17 +51,17 @@ static int rlm_ldap_map_getvalue(VALUE_PAIR **out, REQUEST *request, value_pair_
                for (i = 0; i < self->count; i++) {
                        value_pair_map_t *attr = NULL;
 
-                       RDEBUG3("Parsing valuepair string \"%s\"", self->values[i]);
-                       if (radius_strpair2map(&attr, request, self->values[i],
+                       RDEBUG3("Parsing valuepair string \"%s\"", self->values[i]->bv_val);
+                       if (radius_strpair2map(&attr, request, self->values[i]->bv_val,
                                               map->dst->vpt_request, map->dst->vpt_list,
                                               REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
-                               RWDEBUG("Failed parsing \"%s\" as valuepair, skipping...", self->values[i]);
+                               RWDEBUG("Failed parsing \"%s\" as valuepair, skipping...", self->values[i]->bv_val);
                                continue;
                        }
 
                        if (attr->dst->vpt_request != map->dst->vpt_request) {
                                RWDEBUG("valuepair \"%s\" has conflicting request qualifier (%s vs %s), skipping...",
-                                       self->values[i],
+                                       self->values[i]->bv_val,
                                        fr_int2str(request_refs, attr->dst->vpt_request, "<INVALID>"),
                                        fr_int2str(request_refs, map->dst->vpt_request, "<INVALID>"));
                        next_pair:
@@ -71,14 +71,14 @@ static int rlm_ldap_map_getvalue(VALUE_PAIR **out, REQUEST *request, value_pair_
 
                        if ((attr->dst->vpt_list != map->dst->vpt_list)) {
                                RWDEBUG("valuepair \"%s\" has conflicting list qualifier (%s vs %s), skipping...",
-                                       self->values[i],
+                                       self->values[i]->bv_val,
                                        fr_int2str(pair_lists, attr->dst->vpt_list, "<INVALID>"),
                                        fr_int2str(pair_lists, map->dst->vpt_list, "<INVALID>"));
                                goto next_pair;
                        }
 
                        if (radius_map2vp(&vp, request, attr, NULL) < 0) {
-                               RWDEBUG("Failed creating attribute for \"%s\", skipping...", self->values[i]);
+                               RWDEBUG("Failed creating attribute for \"%s\", skipping...", self->values[i]->bv_val);
                                goto next_pair;
                        }
 
@@ -97,7 +97,7 @@ static int rlm_ldap_map_getvalue(VALUE_PAIR **out, REQUEST *request, value_pair_
                        vp = pairalloc(request, map->dst->vpt_da);
                        rad_assert(vp);
 
-                       if (!pairparsevalue(vp, self->values[i], 0)) {
+                       if (!pairparsevalue(vp, self->values[i]->bv_val, self->values[i]->bv_len)) {
                                RDEBUG("Failed parsing value for \"%s\"", map->dst->vpt_da->name);
 
                                talloc_free(vp);
@@ -348,7 +348,10 @@ void rlm_ldap_map_do(UNUSED const ldap_instance_t *inst, REQUEST *request, LDAP
        for (map = expanded->maps; map != NULL; map = map->next) {
                name = expanded->attrs[total++];
 
-               result.values = ldap_get_values(handle, entry, name);
+               /*
+                *      Binary safe
+                */
+               result.values = ldap_get_values_len(handle, entry, name);
                if (!result.values) {
                        RDEBUG3("Attribute \"%s\" not found in LDAP object", name);
 
@@ -359,7 +362,7 @@ void rlm_ldap_map_do(UNUSED const ldap_instance_t *inst, REQUEST *request, LDAP
                 *      Find out how many values there are for the
                 *      attribute and extract all of them.
                 */
-               result.count = ldap_count_values(result.values);
+               result.count = ldap_count_values_len(result.values);
 
                /*
                 *      If something bad happened, just skip, this is probably
@@ -372,7 +375,7 @@ void rlm_ldap_map_do(UNUSED const ldap_instance_t *inst, REQUEST *request, LDAP
 
                next:
 
-               ldap_value_free(result.values);
+               ldap_value_free_len(result.values);
        }
 
        /*
index 352bc58..e58ba4f 100644 (file)
@@ -235,8 +235,9 @@ typedef struct rlm_ldap_map_xlat {
 } rlm_ldap_map_xlat_t;
 
 typedef struct rlm_ldap_result {
-       char    **values;
-       int     count;
+       struct berval   **values;                       //!< libldap struct containing bv_val (char *)
+                                                       //!< and length bv_len.
+       int             count;                          //!< Number of values.
 } rlm_ldap_result_t;
 
 typedef enum {