/** 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; }
/* * 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; }
/** 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; }
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; }
/* * 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; }
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; }
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; }
/** * 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; }
/** 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; }
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; }
/** 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; }
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; }
/** 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; }
/* * 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; }
/** 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); }
/** 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; }
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; }
/** 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; }
/** 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; }
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); }
/* * 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; }
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(); }
/** 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; }
/** 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; }
/* * 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; }
/** 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); }
/** 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; }
/** 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; }
/** 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; }