Пример #1
0
/** Insert a new entry into the data store
 *
 * @param inst main rlm_cache instance.
 * @param request The current request.
 * @param handle Pointer to memcached handle.
 * @param c entry to insert.
 * @return CACHE_OK on success else CACHE_ERROR on error.
 */
static cache_status_t cache_entry_insert(UNUSED rlm_cache_t *inst, REQUEST *request, rlm_cache_handle_t **handle,
					 rlm_cache_entry_t *c)
{
	rlm_cache_memcached_handle_t *mandle = *handle;

	memcached_return_t ret;

	TALLOC_CTX *pool;
	char *to_store;

	pool = talloc_pool(NULL, 1024);
	if (!pool) return CACHE_ERROR;

	if (cache_serialize(pool, &to_store, c) < 0) {
		talloc_free(pool);

		return CACHE_ERROR;
	}

	ret = memcached_set(mandle->handle, c->key, talloc_array_length(c->key) - 1,
		            to_store ? to_store : "",
		            to_store ? talloc_array_length(to_store) - 1 : 0, c->expires, 0);
	talloc_free(pool);
	if (ret != MEMCACHED_SUCCESS) {
		RERROR("Failed storing entry with key \"%s\": %s: %s", c->key,
		       memcached_strerror(mandle->handle, ret),
		       memcached_last_error_message(mandle->handle));

		return CACHE_ERROR;
	}

	return CACHE_OK;
}
Пример #2
0
/*
 *	Convert field X to a VP.
 */
static int csv_map_getvalue(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx)
{
	char const *str = uctx;
	VALUE_PAIR *head = NULL, *vp;
	vp_cursor_t cursor;
	DICT_ATTR const *da;

	rad_assert(ctx != NULL);
	fr_cursor_init(&cursor, &head);

	/*
	 *	FIXME: allow multiple entries.
	 */
	if (map->lhs->type == TMPL_TYPE_ATTR) {
		da = map->lhs->tmpl_da;

	} else {
		char *attr;

		if (tmpl_aexpand(ctx, &attr, request, map->lhs, NULL, NULL) <= 0) {
			RWDEBUG("Failed expanding string");
			return -1;
		}

		da = dict_attrbyname(attr);
		if (!da) {
			RWDEBUG("No such attribute '%s'", attr);
			return -1;
		}

		talloc_free(attr);
	}

	vp = pairalloc(ctx, da);
	rad_assert(vp);

	if (pairparsevalue(vp, str, talloc_array_length(str) - 1) < 0) {
		char *escaped;

		escaped = fr_aprints(vp, str, talloc_array_length(str) - 1, '\'');
		RWDEBUG("Failed parsing value \"%s\" for attribute %s: %s", escaped,
			map->lhs->tmpl_da->name, fr_strerror());

		talloc_free(vp); /* also frees escaped */
		return -1;
	}

	vp->op = map->op;
	fr_cursor_merge(&cursor, vp);

	*out = head;
	return 0;
}
Пример #3
0
/** Create a new memcached handle
 *
 * @param ctx to allocate handle in.
 * @param instance data.
 */
static void *mod_conn_create(TALLOC_CTX *ctx, void *instance)
{
	rlm_cache_t			*inst = instance;
	rlm_cache_memcached_t		*driver = inst->driver;
	rlm_cache_memcached_handle_t	*mandle;

	memcached_st			*sandle;
	memcached_return_t		ret;

	sandle = memcached(driver->options, talloc_array_length(driver->options) -1);
	if (!sandle) {
		ERROR("rlm_cache_memcached: Failed creating memcached connection");

		return NULL;
	}

	ret = memcached_version(sandle);
	if (ret != MEMCACHED_SUCCESS) {
		ERROR("rlm_cache_memcached: Failed getting server info: %s: %s", memcached_strerror(sandle, ret),
		      memcached_last_error_message(sandle));
		memcached_free(sandle);
		return NULL;
	}

	mandle = talloc_zero(ctx, rlm_cache_memcached_handle_t);
	mandle->handle = sandle;
	talloc_set_destructor(mandle, _mod_conn_free);

	return mandle;
}
Пример #4
0
static bool tldap_add_blob_vals(TALLOC_CTX *mem_ctx, struct tldap_mod *mod,
				DATA_BLOB *newvals, int num_newvals)
{
	int num_values = talloc_array_length(mod->values);
	int i;
	DATA_BLOB *tmp;

	tmp = talloc_realloc(mem_ctx, mod->values, DATA_BLOB,
			     num_values + num_newvals);
	if (tmp == NULL) {
		return false;
	}
	mod->values = tmp;

	for (i=0; i<num_newvals; i++) {
		mod->values[i+num_values].data = (uint8_t *)talloc_memdup(
			mod->values, newvals[i].data, newvals[i].length);
		if (mod->values[i+num_values].data == NULL) {
			return false;
		}
		mod->values[i+num_values].length = newvals[i].length;
	}
	mod->num_values = num_values + num_newvals;
	return true;
}
Пример #5
0
/*
 *	Xlat for %{attr_by_num:<number>}
 */
static ssize_t xlat_dict_attr_by_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
				     UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
				     REQUEST *request, char const *fmt)
{
	char			*q;
	unsigned int		number;
	fr_dict_attr_t const	*da;

	*out = NULL;

	number = (unsigned int)strtoul(fmt, &q, 10);
	if ((q == fmt) || (*q != '\0')) {
		REDEBUG("Trailing garbage \"%s\" in attribute number string \"%s\"", q, fmt);
		return -1;
	}

	da = fr_dict_attr_child_by_num(fr_dict_root(request->dict), number);
	if (!da) {
		REDEBUG("No attribute found with number %u", number);
		return -1;
	}

	*out = talloc_typed_strdup(ctx, da->name);

	return talloc_array_length(*out) - 1;
}
Пример #6
0
size_t command_data_len_from_at_cmd_res(uint8_t *packet) {
    size_t packet_len = talloc_array_length(packet);
    if (packet_len > AT_CMD_RES_MIN_LEN)
        return packet_len - AT_CMD_RES_MIN_LEN;
    else
        return 0;
}
Пример #7
0
size_t ni_string_len_from_node_id(uint8_t *packet) {
    size_t packet_len = talloc_array_length(packet);
    if (packet_len > NODE_ID_MIN_LEN)
        return packet_len - NODE_ID_MIN_LEN;
    else
        return 0;
}
Пример #8
0
/**
 * Convert @mappings into load @script statements at the given @cursor
 * position.  This function returns the new cursor position.
 */
static void *transcript_mappings(void *cursor, const Mapping *mappings)
{
	size_t nb_mappings;
	size_t i;

	nb_mappings = talloc_array_length(mappings);
	for (i = 0; i < nb_mappings; i++) {
		LoadStatement *statement = cursor;

		if ((mappings[i].flags & MAP_ANONYMOUS) != 0)
			statement->action = LOAD_ACTION_MMAP_ANON;
		else
			statement->action = LOAD_ACTION_MMAP_FILE;

		statement->mmap.addr   = mappings[i].addr;
		statement->mmap.length = mappings[i].length;
		statement->mmap.prot   = mappings[i].prot;
		statement->mmap.offset = mappings[i].offset;
		statement->mmap.clear_length = mappings[i].clear_length;

		cursor += LOAD_STATEMENT_SIZE(*statement, mmap);
	}

	return cursor;
}
/* initialize couchbase connection */
static int mod_instantiate(CONF_SECTION *conf, void *instance) {
	static bool version_done;

	rlm_couchbase_t *inst = instance;   /* our module instance */

	if (!version_done) {
		version_done = true;
		INFO("rlm_couchbase: json-c version: %s", json_c_version());
		INFO("rlm_couchbase: libcouchbase version: %s", lcb_get_version(NULL));
	}

	{
		char *server, *p;
		size_t len, i;
		bool sep = false;

		len = talloc_array_length(inst->server_raw);
		server = p = talloc_array(inst, char, len);
		for (i = 0; i < len; i++) {
			switch (inst->server_raw[i]) {
			case '\t':
			case ' ':
			case ',':
				/* Consume multiple separators occurring in sequence */
				if (sep == true) continue;

				sep = true;
				*p++ = ';';
				break;

			default:
				sep = false;
				*p++ = inst->server_raw[i];
				break;
			}
		}

		*p = '\0';
		inst->server = server;
	}

	/* setup item map */
	if (mod_build_attribute_element_map(conf, inst) != 0) {
		/* fail */
		return -1;
	}

	/* initiate connection pool */
	inst->pool = fr_connection_pool_module_init(conf, inst, mod_conn_create, mod_conn_alive, NULL);

	/* check connection pool */
	if (!inst->pool) {
		ERROR("rlm_couchbase: failed to initiate connection pool");
		/* fail */
		return -1;
	}

	/* return okay */
	return 0;
}
Пример #10
0
/** Converts a string value into a #VALUE_PAIR
 *
 * @param[in,out] ctx to allocate #VALUE_PAIR (s).
 * @param[out] out where to write the resulting #VALUE_PAIR.
 * @param[in] request The current request.
 * @param[in] map to process.
 * @param[in] uctx The value to parse.
 * @return
 *	- 0 on success.
 *	- -1 on failure.
 */
static int _sql_map_proc_get_value(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx)
{
	VALUE_PAIR	*vp;
	char const	*value = uctx;

	vp = fr_pair_afrom_da(ctx, map->lhs->tmpl_da);
	/*
	 *	Buffer not always talloced, sometimes it's
	 *	just a pointer to a field in a result struct.
	 */
	if (fr_pair_value_from_str(vp, value, strlen(value)) < 0) {
		char *escaped;

		escaped = fr_asprint(vp, value, talloc_array_length(value), '"');
		REDEBUG("Failed parsing value \"%s\" for attribute %s: %s", escaped,
			map->lhs->tmpl_da->name, fr_strerror());
		talloc_free(vp);

		return -1;
	}

	vp->op = map->op;
	*out = vp;

	return 0;
}
Пример #11
0
static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
{
	struct wkssvc_NetWkstaInfo102 *info102;
	char **users;

	info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
	if (info102 == NULL) {
		return NULL;
	}

	info102->platform_id	 = PLATFORM_ID_NT;	/* unknown */
	info102->version_major	 = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
	info102->version_minor	 = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;

	info102->server_name = talloc_asprintf_strupper_m(
		info102, "%s", lp_netbios_name());
	info102->domain_name = talloc_asprintf_strupper_m(
		info102, "%s", lp_workgroup());
	info102->lan_root = "";

	users = get_logged_on_userlist(talloc_tos());
	info102->logged_on_users = talloc_array_length(users);

	TALLOC_FREE(users);

	return info102;
}
Пример #12
0
/** Extract a named subcapture value from the request
 *
 * @note This is the PCRE variant of the function.
 *
 * @param[in] ctx	To allocate subcapture buffer in.
 * @param[out] out	Where to write the subcapture string.
 * @param[in] request	to extract.
 * @param[in] name	of subcapture.
 * @return
 *	- 0 on success.
 *	- -1 on notfound.
 */
int regex_request_to_sub_named(TALLOC_CTX *ctx, char **out, REQUEST *request, char const *name)
{
	fr_regcapture_t	*rc;
	char const	*p;
	int		ret;

	rc = request_data_reference(request, request, REQUEST_DATA_REGEX);
	if (!rc) {
		RDEBUG4("No subcapture data found");
		*out = NULL;
		return 1;
	}

	ret = pcre_get_named_substring(rc->preg->compiled, rc->regmatch->subject,
				       (int *)rc->regmatch->match_data, (int)rc->regmatch->used, name, &p);
	switch (ret) {
	case PCRE_ERROR_NOMEMORY:
		MEM(NULL);
		/*
		 *	We can't really fall through, but GCC 7.3 is
		 *	too stupid to realise that we can never get
		 *	here despite _fr_exit_now being marked as
		 *	NEVER_RETURNS.
		 *
		 *	If we did anything else, compilers and static
		 *	analysis tools would probably complain about
		 *	code that could never be executed *sigh*.
		 */
		/* FALL-THROUGH */
	/*
	 *	Not finding a substring is fine
	 */
	case PCRE_ERROR_NOSUBSTRING:
		RDEBUG4("No named capture group \"%s\"", name);
		*out = NULL;
		return -1;

	default:
		if (ret < 0) {
			*out = NULL;
			return -1;
		}

		/*
		 *	Check libpcre really is using our overloaded
		 *	memory allocation and freeing talloc wrappers.
		 */
		talloc_set_type(p, char);
		talloc_steal(ctx, p);

		RDEBUG4("Found \"%s\": %pV (%zu)", name,
			fr_box_strvalue_buffer(p), talloc_array_length(p) - 1);

		memcpy(out, &p, sizeof(*out));

		break;
	}

	return 0;
}
Пример #13
0
static int _map_proc_client_get_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request,
				   vp_map_t const *map, void *uctx)
{
	client_get_vp_ctx_t	*client = uctx;
	VALUE_PAIR		*head = NULL, *vp;
	fr_cursor_t		cursor;
	fr_dict_attr_t const	*da;
	CONF_PAIR const		*cp;

	rad_assert(ctx != NULL);

	fr_cursor_init(&cursor, &head);

	/*
	 *	FIXME: allow multiple entries.
	 */
	if (map->lhs->type == TMPL_TYPE_ATTR) {
		da = map->lhs->tmpl_da;
	} else {
		char *attr;

		if (tmpl_aexpand(ctx, &attr, request, map->lhs, NULL, NULL) <= 0) {
			RWDEBUG("Failed expanding string");
			return -1;
		}

		da = fr_dict_attr_by_name(request->dict, attr);
		if (!da) {
			RWDEBUG("No such attribute '%s'", attr);
			return -1;
		}

		talloc_free(attr);
	}

	for (cp = client->cp;
	     cp;
	     cp = cf_pair_find_next(client->cs, cp, client->field)) {
		char const *value = cf_pair_value(cp);

		MEM(vp = fr_pair_afrom_da(ctx, da));
		if (fr_pair_value_from_str(vp, value, talloc_array_length(value) - 1, '\0', false) < 0) {
			RWDEBUG("Failed parsing value \"%pV\" for attribute %s: %s", fr_box_strvalue(value),
				map->lhs->tmpl_da->name, fr_strerror());
			fr_pair_list_free(&head);
			talloc_free(vp);
			return -1;
		}

		vp->op = map->op;
		fr_cursor_append(&cursor, vp);

		if (map->op != T_OP_ADD) break;	/* Create multiple attribute for multiple CONF_PAIRs */
	}

	*out = head;

	return 0;
}
Пример #14
0
/** Extract a subcapture value from the request
 *
 * @note This is the PCRE variant of the function.
 *
 * @param[in] ctx	To allocate subcapture buffer in.
 * @param[out] out	Where to write the subcapture string.
 * @param[in] request	to extract.
 * @param[in] num	Subcapture index (0 for entire match).
 * @return
 *	- 0 on success.
 *	- -1 on notfound.
 */
int regex_request_to_sub(TALLOC_CTX *ctx, char **out, REQUEST *request, uint32_t num)
{
	fr_regcapture_t		*rc;
	char			*buff;
	size_t			len;
	int			ret;
	pcre2_match_data	*match_data;

	rc = request_data_reference(request, request, REQUEST_DATA_REGEX);
	if (!rc) {
		RDEBUG4("No subcapture data found");
		*out = NULL;
		return 1;
	}
	match_data = talloc_get_type_abort(rc->regmatch->match_data, pcre2_match_data);

	ret = pcre2_substring_length_bynumber(match_data, num, &len);
	switch (ret) {
	case PCRE2_ERROR_NOMEMORY:
		MEM(NULL);
		/*
		 *	We can't really fall through, but GCC 7.3 is
		 *	too stupid to realise that we can never get
		 *	here despite _fr_exit_now being marked as
		 *	NEVER_RETURNS.
		 *
		 *	If we did anything else, compilers and static
		 *	analysis tools would probably complain about
		 *	code that could never be executed *sigh*.
		 */
		/* FALL-THROUGH */

	/*
	 *	Not finding a substring is fine
	 */
	case PCRE2_ERROR_NOSUBSTRING:
		RDEBUG4("%i/%zu Not found", num + 1, rc->regmatch->used);
		*out = NULL;
		return -1;

	default:
		if (ret < 0) {
			*out = NULL;
			return -1;
		}

		MEM(buff = talloc_array(ctx, char, ++len));	/* +1 for \0, it'll get reset by pcre2_substring */
		pcre2_substring_copy_bynumber(match_data, num, (PCRE2_UCHAR *)buff, &len); /* can't error */

		RDEBUG4("%i/%zu Found: %pV (%zu)", num + 1, rc->regmatch->used,
			fr_box_strvalue_buffer(buff), talloc_array_length(buff) - 1);

		*out = buff;
		break;
	}

	return 0;
}
Пример #15
0
/*
 *	Instantiate the module.
 */
static int mod_instantiate(void *instance, CONF_SECTION *conf)
{
	rlm_logtee_t	*inst = instance;
	char		prefix[100];

	/*
	 *	Escape filenames only if asked.
	 */
	if (inst->file.escape) {
		inst->file.escape_func = rad_filename_escape;
	} else {
		inst->file.escape_func = rad_filename_make_safe;
	}

	inst->log_dst = fr_str2int(logtee_dst_table, inst->log_dst_str, LOGTEE_DST_INVALID);
	if (inst->log_dst == LOGTEE_DST_INVALID) {
		cf_log_err(conf, "Invalid log destination \"%s\"", inst->log_dst_str);
		return -1;
	}

	inst->name = cf_section_name2(conf);
	if (!inst->name) inst->name = cf_section_name1(conf);

	snprintf(prefix, sizeof(prefix), "rlm_logtee (%s)", inst->name);

	FR_SIZE_BOUND_CHECK("buffer_depth", inst->buffer_depth, >=, (size_t)1);
	FR_SIZE_BOUND_CHECK("buffer_depth", inst->buffer_depth, <=, (size_t)1000000);	/* 1 Million messages */

	/*
	 *	Setup the logging destination
	 */
	switch (inst->log_dst) {
	case LOGTEE_DST_FILE:
		cf_log_err(conf, "Teeing to files NYI");
		return -1;

	case LOGTEE_DST_UNIX:
#ifndef HAVE_SYS_UN_H
		cf_log_err(conf, "Unix sockets are not supported on this sytem");
		return -1;
#endif

	case LOGTEE_DST_UDP:
		break;

	case LOGTEE_DST_TCP:
		break;

	case LOGTEE_DST_INVALID:
		rad_assert(0);
		break;
	}

	inst->delimiter_len = talloc_array_length(inst->delimiter) - 1;

	return 0;
}
Пример #16
0
/** Print one attribute value to a string
 *
 * @param ctx to allocate string in.
 * @param vp to print.
 * @param[in] quote the quotation character
 * @return a talloced buffer with the attribute operator and value.
 */
char *vp_aprints_value(TALLOC_CTX *ctx, VALUE_PAIR const *vp, char quote)
{
	VERIFY_VP(vp);

	if (vp->type == VT_XLAT) {
		return fr_aprints(ctx, vp->value.xlat, talloc_array_length(vp->value.xlat) - 1, quote);
	}

	return value_data_aprints(ctx, vp->da->type, vp->da, &vp->data, vp->vp_length, quote);
}
Пример #17
0
/** Extract a subcapture value from the request
 *
 * @note This is the POSIX variant of the function.
 *
 * @param[in] ctx	To allocate subcapture buffer in.
 * @param[out] out	Where to write the subcapture string.
 * @param[in] request	to extract.
 * @param[in] num	Subcapture index (0 for entire match).
 * @return
 *	- 0 on success.
 *	- -1 on notfound.
 */
int regex_request_to_sub(TALLOC_CTX *ctx, char **out, REQUEST *request, uint32_t num)
{
	fr_regcapture_t	*rc;
	char 		*buff;
	char const	*start;
	size_t		len;
	regmatch_t	*match_data;

	rc = request_data_reference(request, request, REQUEST_DATA_REGEX);
	if (!rc) {
		RDEBUG4("No subcapture data found");
		*out = NULL;
		return -1;
	}
	match_data = rc->regmatch->match_data;

	/*
	 *	Greater than our capture array
	 *
	 *	-1 means no value in this capture group.
	 */
	if ((num >= rc->regmatch->used) || (match_data[num].rm_eo == -1) || (match_data[num].rm_so == -1)) {
		RDEBUG4("%i/%zu Not found", num + 1, rc->regmatch->used);
		*out = NULL;
		return -1;
	}

	/*
	 *	Sanity checks on the offsets
	 */
	rad_assert(match_data[num].rm_eo <= (regoff_t)talloc_array_length(rc->regmatch->subject));
	rad_assert(match_data[num].rm_so <= (regoff_t)talloc_array_length(rc->regmatch->subject));

	start = rc->regmatch->subject + match_data[num].rm_so;
	len = match_data[num].rm_eo - match_data[num].rm_so;

	MEM(buff = talloc_bstrndup(ctx, start, len));
	RDEBUG4("%i/%zu Found: %pV (%zu)", num + 1, rc->regmatch->used, fr_box_strvalue_buffer(buff), len);

	*out = buff;

	return 0;
}
Пример #18
0
static errno_t
nodes_cached_objects(TALLOC_CTX *mem_ctx,
                     struct ifp_ctx *ifp_ctx,
                     enum ifp_cache_type type,
                     const char *prefix,
                     const char ***_nodes)
{
    TALLOC_CTX *tmp_ctx;
    const char **paths;
    const char **nodes;
    const char *node;
    int num_paths;
    errno_t ret;
    int i;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
        return ENOMEM;
    }

    ret = ifp_cache_list_domains(tmp_ctx, ifp_ctx->rctx->domains, type, &paths);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain cache objects list "
              "[%d]: %s\n", ret, sss_strerror(ret));
        goto done;
    }

    num_paths = talloc_array_length(paths) - 1;
    nodes = talloc_zero_array(tmp_ctx, const char *, num_paths + 1);
    if (nodes == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
        ret = ENOMEM;
        goto done;
    }

    for (i = 0; i < num_paths; i++) {
        node = sbus_opath_strip_prefix(paths[i], prefix);
        nodes[i] = talloc_strdup(nodes, node);
        if (nodes[i] == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
            ret = ENOMEM;
            goto done;
        }
    }

    *_nodes = talloc_steal(mem_ctx, nodes);

    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
Пример #19
0
/** Return the attribute number of an attribute reference
 *
 */
static ssize_t xlat_attr_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
			     UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			     REQUEST *request, char const *fmt)
{
	VALUE_PAIR *vp;

	fr_skip_spaces(fmt);

	if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return 0;

	*out = talloc_typed_asprintf(ctx, "%i", vp->da->attr);
	return talloc_array_length(*out) - 1;
}
Пример #20
0
/** Return the vendor number of an attribute reference
 *
 */
static ssize_t xlat_vendor_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
			       UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			       REQUEST *request, char const *fmt)
{
	VALUE_PAIR *vp;

	while (isspace((int) *fmt)) fmt++;

	if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return 0;

	*out = talloc_typed_asprintf(ctx, "%i", fr_dict_vendor_num_by_da(vp->da));
	return talloc_array_length(*out) - 1;
}
Пример #21
0
static void print_nodes(uint32_t *nodes, uint32_t pnn_mode)
{
	int i;

	printf("NODES:");
	for (i = 0; i < talloc_array_length(nodes); i++) {
		printf(" %lu", (unsigned long) nodes[i]);
	}
	printf("\n");

	printf("PNN MODE: %s (%lu)\n",
	       decode_pnn_mode(pnn_mode), (unsigned long) pnn_mode);
}
Пример #22
0
/*
 *	Convert field X to a VP.
 */
static int csv_map_getvalue(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx)
{
	char const		*str = uctx;
	VALUE_PAIR		*head = NULL, *vp;
	fr_cursor_t		cursor;
	fr_dict_attr_t		const *da;

	rad_assert(ctx != NULL);
	fr_cursor_init(&cursor, &head);

	/*
	 *	FIXME: allow multiple entries.
	 */
	if (map->lhs->type == TMPL_TYPE_ATTR) {
		da = map->lhs->tmpl_da;

	} else {
		char *attr;

		if (tmpl_aexpand(ctx, &attr, request, map->lhs, NULL, NULL) <= 0) {
			RWDEBUG("Failed expanding string");
			return -1;
		}


		da = fr_dict_attr_by_name(request->dict, attr);
		if (!da) {
			RWDEBUG("No such attribute '%s'", attr);
			return -1;
		}

		talloc_free(attr);
	}

	vp = fr_pair_afrom_da(ctx, da);
	rad_assert(vp);

	if (fr_pair_value_from_str(vp, str, talloc_array_length(str) - 1, '\0', true) < 0) {
		RWDEBUG("Failed parsing value \"%pV\" for attribute %s: %s", fr_box_strvalue_buffer(str),
			map->lhs->tmpl_da->name, fr_strerror());
		talloc_free(vp);

		return -1;
	}

	vp->op = map->op;
	fr_cursor_append(&cursor, vp);

	*out = head;
	return 0;
}
Пример #23
0
int main(int argc, char *argv[])
{
	char **split, *str;
	void *ctx;

	plan_tests(16);
	split = strsplit(NULL, "hello  world", " ");
	ok1(talloc_array_length(split) == 4);
	ok1(!strcmp(split[0], "hello"));
	ok1(!strcmp(split[1], ""));
	ok1(!strcmp(split[2], "world"));
	ok1(split[3] == NULL);
	talloc_free(split);

	split = strsplit(NULL, "hello  world", "o ");
	ok1(talloc_array_length(split) == 6);
	ok1(!strcmp(split[0], "hell"));
	ok1(!strcmp(split[1], ""));
	ok1(!strcmp(split[2], ""));
	ok1(!strcmp(split[3], "w"));
	ok1(!strcmp(split[4], "rld"));
	ok1(split[5] == NULL);

	ctx = split;
	split = strsplit(ctx, "hello  world", "o ");
	ok1(talloc_parent(split) == ctx);
	talloc_free(ctx);

	str = strjoin(NULL, (char **)substrings, ", ");
	ok1(!strcmp(str, "far, bar, baz, b, ba, z, ar, "));
	ctx = str;
	str = strjoin(ctx, (char **)substrings, "");
	ok1(!strcmp(str, "farbarbazbbazar"));
	ok1(talloc_parent(str) == ctx);
	talloc_free(ctx);

	return exit_status();
}				
Пример #24
0
/** Return the attribute name of an attribute reference
 *
 */
static ssize_t xlat_attr(TALLOC_CTX *ctx, char **out, size_t outlen,
			 UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			 REQUEST *request, char const *fmt)
{
	VALUE_PAIR *vp;

	fr_skip_spaces(fmt);

	if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
	strlcpy(*out, vp->da->name, outlen);

	*out = talloc_typed_strdup(ctx, vp->da->name);
	return talloc_array_length(*out) - 1;
}
Пример #25
0
/** Convert attr tmpl to an xlat for &attr[*]
 *
 * @param ctx to allocate new xlat_expt_t in.
 * @param vpt to convert.
 * @return
 *	- NULL if unable to convert (not necessarily error).
 *	- a new #vp_tmpl_t.
 */
xlat_exp_t *xlat_from_tmpl_attr(TALLOC_CTX *ctx, vp_tmpl_t *vpt)
{
	xlat_exp_t *node;

	if (vpt->type != TMPL_TYPE_ATTR) return NULL;

	node = talloc_zero(ctx, xlat_exp_t);
	node->type = XLAT_ATTRIBUTE;
	node->fmt = talloc_bstrndup(node, vpt->name, vpt->len);
	node->attr = tmpl_alloc(node, TMPL_TYPE_ATTR, node->fmt, talloc_array_length(node->fmt) - 1, T_BARE_WORD);
	memcpy(&node->attr->data, &vpt->data, sizeof(vpt->data));

	return node;
}
Пример #26
0
/*
 *	Xlat for %{client:[<ipaddr>.]foo}
 */
static ssize_t xlat_client(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
			   UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			   REQUEST *request, char const *fmt)
{
	char const	*value = NULL;
	char		buffer[INET6_ADDRSTRLEN], *q;
	char const	*p = fmt;
	fr_ipaddr_t	ip;
	CONF_PAIR	*cp;
	RADCLIENT	*client = NULL;

	*out = NULL;

	q = strrchr(p, '.');
	if (q) {
		strlcpy(buffer, p, (q + 1) - p);
		if (fr_inet_pton(&ip, buffer, -1, AF_UNSPEC, false, true) < 0) goto request_client;

		p = q + 1;

		client = client_find(NULL, &ip, IPPROTO_IP);
		if (!client) {
			RDEBUG("No client found with IP \"%s\"", buffer);
			return 0;
		}
	} else {
	request_client:
		client = request->client;
		if (!client) {
			RERROR("No client associated with this request");

			return -1;
		}
	}

	cp = cf_pair_find(client->cs, p);
	if (!cp || !(value = cf_pair_value(cp))) {
		if (strcmp(fmt, "shortname") == 0 && request->client->shortname) {
			value = request->client->shortname;
		}
		else if (strcmp(fmt, "nas_type") == 0 && request->client->nas_type) {
			value = request->client->nas_type;
		}
		if (!value) return 0;
	}

	*out = talloc_typed_strdup(ctx, value);
	return talloc_array_length(*out) - 1;
}
Пример #27
0
/** There's space available to write data, so do that...
 *
 */
static void _logtee_conn_writable(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
{
	rlm_logtee_thread_t	*t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
	char			*msg;

	/*
	 *	Fixme in general...
	 */
	while ((msg = fr_fring_next(t->fring))) {
		ssize_t slen;

		slen = write(sock, msg, talloc_array_length(msg) - 1) ;
	write_error:
		if (slen < 0) {
			switch (errno) {
			case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
			case EWOULDBLOCK:
#endif
			case EINTR:
			case ENOBUFS:
				return;

			case ECONNRESET:
			case EDESTADDRREQ:
			case EIO:
			case ENXIO:
			case EPIPE:
			case ENETDOWN:
				fr_connection_signal_reconnect(t->conn);
				return;

			/*
			 *	Shouldn't be any other errors
			 *	If there are, investigate why we get them...
			 */
			default:
				rad_assert(0);
			}
		}

		slen = write(sock, t->inst->delimiter, t->inst->delimiter_len);
		if (slen < 0) goto write_error;
	}

	logtee_fd_idle(t);
}
Пример #28
0
/** Return the vendor of an attribute reference
 *
 */
static ssize_t xlat_vendor(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
			   UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			   REQUEST *request, char const *fmt)
{
	VALUE_PAIR *vp;
	fr_dict_vendor_t const *vendor;

	fr_skip_spaces(fmt);

	if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return 0;

	vendor = fr_dict_vendor_by_da(vp->da);
	if (!vendor) return 0;

	*out = talloc_typed_strdup(ctx, vendor->name);
	return talloc_array_length(*out) - 1;
}
Пример #29
0
/** Call delete the cache entry from memcached
 *
 * @param inst main rlm_cache instance.
 * @param request The current request.
 * @param handle Pointer to memcached handle.
 * @param c entry to expire.
 * @return CACHE_OK on success else CACHE_ERROR.
 */
static cache_status_t cache_entry_expire(UNUSED rlm_cache_t *inst, REQUEST *request, rlm_cache_handle_t **handle,
					 rlm_cache_entry_t *c)
{
	rlm_cache_memcached_handle_t *mandle = *handle;

	memcached_return_t ret;

	ret = memcached_delete(mandle->handle, c->key, talloc_array_length(c->key) - 1, 0);
	if (ret != MEMCACHED_SUCCESS) {
		RERROR("Failed deleting entry with key \"%s\": %s", c->key,
		       memcached_last_error_message(mandle->handle));

		return CACHE_ERROR;
	}

	return CACHE_OK;
}
Пример #30
0
/** Create a new rlm_cache_memcached instance
 *
 * @param conf memcached specific conf section.
 * @param inst main rlm_cache instance.
 * @return 0 on success, -1 on failure.
 */
static int mod_instantiate(CONF_SECTION *conf, rlm_cache_t *inst)
{
	rlm_cache_memcached_t *driver;
	memcached_return_t ret;

	char buffer[256];

	static bool version_done;

	buffer[0] = '\0';

	/*
	 *	Get version info from the libmemcached API.
	 */
	if (!version_done) {
		version_done = true;

		INFO("rlm_cache_memcached: libmemcached version: %s", memcached_lib_version());
	}

	driver = talloc_zero(inst, rlm_cache_memcached_t);
	talloc_set_destructor(driver, _mod_detach);

	if (cf_section_parse(conf, driver, driver_config) < 0) return -1;

	ret = libmemcached_check_configuration(driver->options, talloc_array_length(driver->options) -1,
					       buffer, sizeof(buffer));
	if (ret != MEMCACHED_SUCCESS) {
		ERROR("rlm_cache_memcached: Failed validating options string: %s", buffer);
		return -1;
	}

	inst->driver = driver;

	snprintf(buffer, sizeof(buffer), "rlm_cache (%s)", inst->name);

	driver->pool = fr_connection_pool_module_init(conf, inst, mod_conn_create, NULL, buffer);
	if (!driver->pool) return -1;

	if (inst->max_entries > 0) WARN("rlm_cache_memcached: max_entries is not supported by this driver");

	return 0;
}