fr_ldap_str_list_afrom_result gains leading slots the caller fills with borrowed strings, so the default, group and user profile DNs merge into a single pooled array with the user values read in place from the result message. The now unused fr_ldap_berval_to_string_list is removed.
char *fr_ldap_berval_to_string(TALLOC_CTX *ctx, struct berval const *in);
-char const **fr_ldap_berval_to_string_list(TALLOC_CTX *ctx, struct berval **values, int count, size_t extra);
-
int fr_ldap_result_values_len(size_t *num, size_t *strings_len, LDAP *handle, LDAPMessage *result,
char const *attr);
int fr_ldap_entry_value_find(struct berval *out, LDAP *handle, LDAPMessage *entry, char const *attr);
talloc_str_list_t *fr_ldap_str_list_afrom_result(TALLOC_CTX *ctx, LDAP *handle, LDAPMessage *result,
- char const *attr);
+ char const *attr, size_t extra);
uint8_t *fr_ldap_berval_to_bin(TALLOC_CTX *ctx, struct berval const *in);
return (sss_end - sss_p);
}
-/** Convert a list of bervals to a NULL terminated list of talloced strings
- *
- * A list variant of fr_ldap_berval_to_string. Where talloc_pooled_object is
- * available the pointer array and every string are allocated from a single
- * talloc pool, so building the list costs one malloc. Zero length values
- * are skipped.
- *
- * @param[in] ctx to parent the list.
- * @param[in] values to copy.
- * @param[in] count Number of values.
- * @param[in] extra Leading pointer array entries to leave NULL, for the
- * caller to fill with strings not copied into the pool.
- * @return NULL terminated array of \0 terminated strings.
- */
-char const **fr_ldap_berval_to_string_list(TALLOC_CTX *ctx, struct berval **values, int count, size_t extra)
-{
- char const **list;
- size_t num = extra;
- int i;
-
-#ifdef HAVE_TALLOC_ZERO_POOLED_OBJECT
- {
- size_t strings_size = 0;
-
- for (i = 0; i < count; i++) {
- strings_size += values[i]->bv_len + 1;
- }
- MEM(list = _talloc_zero_pooled_object(ctx, sizeof(char const *) * (count + extra + 1),
- "char const *[]", count, strings_size));
- }
-#else
- MEM(list = talloc_zero_array(ctx, char const *, count + extra + 1));
-#endif
-
- for (i = 0; i < count; i++) {
- if (values[i]->bv_len == 0) continue;
- MEM(list[num++] = fr_ldap_berval_to_string(list, values[i]));
- }
-
- return list;
-}
-
/** Sum the lengths of an attribute's values across every entry of a result
*
* The values are read in place from the result message, no arrays are
* @param[in] ctx to allocate the list in.
* @param[in] handle the result was received on.
* @param[in] result Head of the result message chain.
- * @param[in] attr whose values to copy.
+ * @param[in] attr whose values to copy. May be NULL, in which case
+ * only the extra slots are allocated.
+ * @param[in] extra Leading pointer array slots to leave NULL, for the
+ * caller to fill with strings not copied into the pool.
* @return
* - List of the attribute's values. Empty if the result holds no
* values for the attribute.
* - NULL if an entry could not be parsed.
*/
-talloc_str_list_t *fr_ldap_str_list_afrom_result(TALLOC_CTX *ctx, LDAP *handle, LDAPMessage *result, char const *attr)
+talloc_str_list_t *fr_ldap_str_list_afrom_result(TALLOC_CTX *ctx, LDAP *handle, LDAPMessage *result,
+ char const *attr, size_t extra)
{
talloc_str_list_t *list = NULL;
LDAPMessage *entry;
BerElement *ber = NULL;
- size_t attr_len = strlen(attr), num, strings_len;
+ size_t attr_len, num = 0, strings_len = 0;
+
+ if (attr) {
+ if (unlikely(fr_ldap_result_values_len(&num, &strings_len, handle, result, attr) < 0)) return NULL;
+ }
- if (unlikely(fr_ldap_result_values_len(&num, &strings_len, handle, result, attr) < 0)) return NULL;
+ MEM(list = talloc_str_list_alloc(ctx, num + extra, strings_len));
+ list->p += extra;
- MEM(list = talloc_str_list_alloc(ctx, num, strings_len));
+ if (num == 0) return list;
+ attr_len = strlen(attr);
for (entry = ldap_first_entry(handle, result); entry; entry = ldap_next_entry(handle, entry)) {
struct berval dn, name, value;
fr_assert(!autz_ctx->group_profile_dn_list);
autz_ctx->group_profile_dn_list = fr_ldap_str_list_afrom_result(autz_ctx, query->ldap_conn->handle,
- query->result, group_ctx->profile_attr);
+ query->result, group_ctx->profile_attr, 0);
if (unlikely(!autz_ctx->group_profile_dn_list)) {
RPERROR("Failed parsing profiles from group objects");
rcode = RLM_MODULE_FAIL;
case LDAP_AUTZ_PROFILES:
{
- struct berval **values = NULL;
- char const *profile_attr;
- char const **dn_p;
- bool have_default = !fr_box_is_null(&call_env->default_profile);
- int count, group_count = 0, i;
+ talloc_str_list_t *list;
+ char const *profile_attr;
+ char const **dn_p;
+ bool have_default = !fr_box_is_null(&call_env->default_profile);
+ size_t count = 0, strings_len = 0, group_count = 0, i;
/*
* Which set of profiles to apply depends on the user's
profile_attr = rlm_ldap_profile_attr_select(inst->user.profile_attr, inst->user.profile_attr_suspend,
autz_ctx->access_state);
if (profile_attr) {
- values = ldap_get_values_len(handle, autz_ctx->entry, profile_attr);
- count = ldap_count_values_len(values);
+ if (unlikely(fr_ldap_result_values_len(&count, &strings_len, handle,
+ autz_ctx->query->result, profile_attr) < 0)) {
+ RPERROR("Failed parsing user object");
+ p_result->rcode = RLM_MODULE_FAIL;
+ goto finish;
+ }
if (count > 0) {
- RDEBUG2("Processing %i profile(s) found in attribute \"%s\"", count, profile_attr);
+ RDEBUG2("Processing %zu profile(s) found in attribute \"%s\"", count, profile_attr);
} else {
RDEBUG2("No profile(s) found in attribute \"%s\"", profile_attr);
}
- } else {
- count = 0;
}
if (autz_ctx->group_profile_dn_list) {
- group_count = (int)talloc_str_list_num(autz_ctx->group_profile_dn_list);
- RDEBUG2("Processing %i profile(s) found in group objects", group_count);
+ group_count = talloc_str_list_num(autz_ctx->group_profile_dn_list);
+ RDEBUG2("Processing %zu profile(s) found in group objects", group_count);
}
if (!have_default && (group_count == 0) && (count == 0)) break;
* profile first, then the profiles from the group
* objects, then the profiles from the user object.
*/
- autz_ctx->profile_dn_list = fr_ldap_berval_to_string_list(autz_ctx, values, count,
- (have_default ? 1 : 0) + group_count);
- dn_p = autz_ctx->profile_dn_list;
+ MEM(list = fr_ldap_str_list_afrom_result(autz_ctx, handle, autz_ctx->query->result,
+ count ? profile_attr : NULL,
+ (have_default ? 1 : 0) + group_count));
+ dn_p = list->strings;
if (have_default) *dn_p++ = call_env->default_profile.vb_strvalue;
for (i = 0; i < group_count; i++) *dn_p++ = autz_ctx->group_profile_dn_list->strings[i];
- if (values) ldap_value_free_len(values);
+ autz_ctx->profile_dn_list = list->strings;
profile_dn_list_dedupe(autz_ctx->profile_dn_list);
if (!autz_ctx->profile_dn_list[0]) break;