/* xlat.c */
typedef size_t (*RADIUS_ESCAPE_STRING)(REQUEST *, char *out, size_t outlen, const char *in, void *arg);
-size_t radius_xlat(char * out, int outlen, const char *fmt,
- REQUEST * request, RADIUS_ESCAPE_STRING func, void *funcarg);
+ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, const char *fmt, RADIUS_ESCAPE_STRING escape,
+ void *escape_ctx);
+
+ssize_t radius_axlat(char **out, REQUEST *request, const char *fmt, RADIUS_ESCAPE_STRING escape,
+ void *escape_ctx);
+
typedef size_t (*RAD_XLAT_FUNC)(void *instance, REQUEST *, const char *, char *, size_t);
int xlat_register(const char *module, RAD_XLAT_FUNC func,
void *instance);
char clean_username[1024];
char buf[1024];
char extra[1024];
+ char *p;
VALUE_PAIR *username = NULL;
if (!request->root->log_auth) {
if (extra_msg) {
extra[0] = ' ';
- radius_xlat(extra + 1, sizeof(extra) - 1, extra_msg, request,
- NULL, NULL);
+ p = extra + 1;
+ radius_xlat(p, sizeof(extra) - 1, request, extra_msg, NULL, NULL);
} else {
*extra = '\0';
}
case T_DOUBLE_QUOTED_STRING:
if (!strchr(value, '%')) return value;
- radius_xlat(buffer, sizeof_buffer, value, request, NULL, NULL);
+ radius_xlat(buffer, sizeof_buffer, request, value, NULL, NULL);
return buffer;
}
* in every request is NOT recommended!
*/
- radius_xlat(buffer, sizeof(buffer), filename,
- request, NULL, NULL); /* FIXME: escape chars! */
+ radius_xlat(buffer, sizeof(buffer), request, filename, NULL, NULL); /* FIXME: escape chars! */
request->radlog = rl;
p = strrchr(buffer, FR_DIR_SEP);
/*
* Expand it safely.
*/
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, config_escape_func, NULL)) {
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, config_escape_func, NULL) < 0) {
return 0;
}
char buffer[128];
if (!mx->exec) {
- radius_xlat(buffer, sizeof(buffer),
- mx->xlat_name, request, NULL, NULL);
+ radius_xlat(buffer, sizeof(buffer), request, mx->xlat_name, NULL, NULL);
} else {
RDEBUG("`%s`", mx->xlat_name);
radius_exec_program(mx->xlat_name, request,
if (!strchr(child->name, '%')) {
VALUE_PAIR *vp = NULL;
- radius_get_vp(request, child->name,
- &vp);
+ radius_get_vp(request, child->name, &vp);
if (vp) {
- vp_prints_value(buffer,
- sizeof(buffer),
- vp, 0);
+ vp_prints_value(buffer, sizeof(buffer), vp, 0);
} else {
*buffer = '\0';
}
} else {
- radius_xlat(buffer, sizeof(buffer),
- child->name, request, NULL, NULL);
+ radius_xlat(buffer, sizeof(buffer), request, child->name, NULL, NULL);
}
null_case = q = NULL;
for(p = g->children; p; p = p->next) {
stack.start[stack.pointer] = stack.children[stack.pointer];
- RDEBUG2("%.*s- entering %s %s {...}",
- stack.pointer, modcall_spaces,
- group_name[child->type],
- child->name ? child->name : "");
+ RDEBUG2("%.*s- entering %s %s {...}", stack.pointer, modcall_spaces, group_name[child->type],
+ child->name ? child->name : "");
/*
* Catch the special case of a NULL group.
struct main_config_t mainconfig;
char *request_log_file = NULL;
char *debug_log_file = NULL;
-size_t radius_xlat(UNUSED char *out, UNUSED int outlen, UNUSED const char *fmt,
- UNUSED REQUEST *request,
- UNUSED RADIUS_ESCAPE_STRING func, UNUSED void *arg)
+ssize_t radius_xlat(UNUSED char *out, UNUSED size_t outlen, UNUSED REQUEST *request, UNUSED const char *fmt,
+ UNUSED RADIUS_ESCAPE_STRING func, UNUSED void *arg)
{
return -1;
}
struct main_config_t mainconfig;
char *request_log_file = NULL;
char *debug_log_file = NULL;
-size_t radius_xlat(UNUSED char *out, UNUSED int outlen, UNUSED const char *fmt,
- UNUSED REQUEST *request,
- UNUSED RADIUS_ESCAPE_STRING func, UNUSED void *arg)
+ssize_t radius_xlat(UNUSED char *out, UNUSED size_t outlen, UNUSED REQUEST *request, UNUSED const char *fmt,
+ UNUSED RADIUS_ESCAPE_STRING escape, UNUSED void *escape_ctx)
{
return -1;
}
struct main_config_t mainconfig;
char *request_log_file = NULL;
char *debug_log_file = NULL;
-size_t radius_xlat(char *out, UNUSED int outlen, UNUSED const char *fmt,
- UNUSED REQUEST *request,
- UNUSED RADIUS_ESCAPE_STRING func, UNUSED void *arg)
+ssize_t radius_xlat(char *out, UNUSED size_t outlen, UNUSED REQUEST *request, UNUSED const char *fmt,
+ UNUSED RADIUS_ESCAPE_STRING escape, UNUSED void *escape_ctx)
{
*out = 0;
return 0;
* previous checks passed.
*/
if (my_ok && conf->check_cert_cn) {
- if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, request, NULL, NULL)) {
- radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
- conf->check_cert_cn);
+ if (radius_xlat(cn_str, sizeof(cn_str), request, conf->check_cert_cn, NULL, NULL) < 0) {
/* if this fails, fail the verification */
my_ok = 0;
} else {
if (!request) continue;
- sublen = radius_xlat(to, left - 1, argv[i], request, NULL, NULL);
+ sublen = radius_xlat(to, left - 1, request, argv[i], NULL, NULL);
if (sublen <= 0) {
if (can_fail) {
/*
*/
int radius_xlat_do(REQUEST *request, VALUE_PAIR *vp)
{
- size_t len;
+ ssize_t len;
char buffer[1024];
vp->type = VT_DATA;
- len = radius_xlat(buffer, sizeof(buffer), vp->value.xlat, request,
- NULL, NULL);
+ len = radius_xlat(buffer, sizeof(buffer), request, vp->value.xlat, NULL, NULL);
+
rad_const_free(vp->value.xlat);
vp->value.xlat = NULL;
- if (!len) {
+ if (len < 0) {
return -1;
}
if ((radius_get_vp(request, fmt, &vp) < 0) || !vp) goto nothing;
- return radius_xlat(out, outlen, vp->vp_strvalue, request, NULL, NULL);
+ return radius_xlat(out, outlen, request, vp->vp_strvalue, NULL, NULL);
}
#ifdef HAVE_REGEX_H
* @param[in] funcarg pointer to pass to escape function.
* @return 0 on success, -1 on failure.
*/
-static int decode_attribute(const char **from, char **to, int freespace,
- REQUEST *request,
- RADIUS_ESCAPE_STRING func, void *funcarg)
+static ssize_t decode_attribute(const char **from, char **to, int freespace, REQUEST *request,
+ RADIUS_ESCAPE_STRING func, void *funcarg)
{
int do_length = 0;
const char *module_name, *xlat_str;
* Expand the first one. If we did, exit the
* conditional.
*/
- retlen = radius_xlat(q, freespace, buffer, request, func, funcarg);
+ retlen = radius_xlat(q, freespace, request, buffer, func, funcarg);
+ if (retlen < 0) {
+ return retlen;
+ }
+
if (retlen) {
q += retlen;
goto done;
* Expand / copy the second string if required.
*/
if (expand2) {
- retlen = radius_xlat(q, freespace, l,
- request, func, funcarg);
+ retlen = radius_xlat(q, freespace, request, l, func, funcarg);
+ if (retlen < 0) {
+ return retlen;
+ }
+
if (retlen) {
q += retlen;
}
return -1;
}
- if (!c->internal) RDEBUG3("radius_xlat: Running registered xlat function of module %s for string \'%s\'",
- c->module, xlat_str);
+ if (!c->internal) {
+ RDEBUG3("Running registered xlat function of module %s for string \'%s\'",
+ c->module, xlat_str);
+ }
if (func) {
/* xlat to a temporary buffer, then escape */
char tmpbuf[8192];
+
retlen = c->do_xlat(c->instance, request, xlat_str, tmpbuf, sizeof(tmpbuf));
if (retlen > 0) {
retlen = func(request, q, freespace, tmpbuf, funcarg);
* Expand the second bit.
*/
RDEBUG2("\t... expanding second conditional");
- retlen = radius_xlat(q, freespace, next, request, func, funcarg);
+ retlen = radius_xlat(q, freespace, request, next, func, funcarg);
+ if (retlen < 0) {
+ return retlen;
+ }
}
q += retlen;
*
* See 'doc/variables.txt' for more information.
*
- * @param[out] out output buffer.
- * @param[in] outlen size of output buffer.
- * @param[in] fmt string to expand.
+ * @param[out] out Where to write pointer to output buffer.
+ * @param[in] ctx Where to write the pointer to the output buffer.
* @param[in] request current request.
+ * @param[in] fmt string to expand.
* @param[in] func function to escape final value e.g. SQL quoting.
- * @param[in] funcarg pointer to pass to escape function.
+ * @param[in] ctx pointer to pass to escape function.
* @return length of string written @bug should really have -1 for failure
- */
-size_t radius_xlat(char *out, int outlen, const char *fmt,
- REQUEST *request,
- RADIUS_ESCAPE_STRING func, void *funcarg)
+ */
+static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, const char *fmt, RADIUS_ESCAPE_STRING escape,
+ void *ctx)
{
- int c, len, freespace;
+ char *buff;
+
+ int c, freespace;
const char *p;
char *q;
char *nl;
VALUE_PAIR *tmp;
struct tm *TM, s_TM;
char tmpdt[40]; /* For temporary storing of dates */
-
+ ssize_t len, bufflen;
+
+ rad_assert(fmt);
+ rad_assert(request);
+
/*
- * Catch bad modules.
+ * Caller either needs to pass us a NULL buffer and a 0 length size, or a non-NULL buffer
+ * and the size of that buffer.
*/
- if (!fmt || !out || !request) return 0;
+ if (!out) {
+ rad_assert(outlen == 0);
+
+ *out = buff = talloc_array(request, char, 8192);
+ bufflen = 8192;
+ } else {
+ rad_assert(outlen != 0);
+
+ buff = *out;
+ bufflen = outlen;
+ }
- q = out;
+ q = buff;
p = fmt;
while (*p) {
/* Calculate freespace in output */
- freespace = outlen - (q - out);
+ freespace = bufflen - (q - buff);
if (freespace <= 1)
break;
c = *p;
} else if (c == '%') switch(*p) {
case '{':
p--;
- if (decode_attribute(&p, &q, freespace, request, func, funcarg) < 0) return 0;
+ len = decode_attribute(&p, &q, freespace, request, escape, ctx);
+ if (len < 0) {
+ return len;
+ }
+
break;
case '%':
*q++ = '%';
*q++ = *p++;
}
- break;
+
+ goto error;
}
}
*q = '\0';
- RDEBUG2("\texpand: '%s' -> '%s'", fmt, out);
+ RDEBUG2("\texpand: '%s' -> '%s'", fmt, buff);
- return strlen(out);
+ return strlen(buff);
+
+ error:
+ talloc_free(*out);
+ *out = NULL;
+
+ return -1;
+}
+
+ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, const char *fmt, RADIUS_ESCAPE_STRING escape, void *ctx)
+{
+ return xlat_expand(&out, outlen, request, fmt, escape, ctx);
+}
+
+ssize_t radius_axlat(char **out, REQUEST *request, const char *fmt, RADIUS_ESCAPE_STRING escape, void *ctx)
+{
+ return xlat_expand(out, 0, request, fmt, escape, ctx);
}
} else {
int len;
- len = radius_xlat(buffer, sizeof(buffer), inst->key,
- request, NULL, NULL);
- if (!len) {
+ len = radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL);
+ if (len < 0) {
+ return RLM_MODULE_FAIL;
+ }
+ if (len == 0) {
return RLM_MODULE_NOOP;
}
keyname = buffer;
if (inst->new_attr){
/* new_attribute = yes */
- if (!radius_xlat(replace_STR, sizeof(replace_STR), inst->replace, request, NULL, NULL)) {
- DEBUG2("%s: xlat on replace string failed.", inst->name);
+ if (radius_xlat(replace_STR, sizeof(replace_STR), request, inst->replace, NULL, NULL) < 0) {
return rcode;
}
if (inst->nocase)
cflags |= REG_ICASE;
- if (!radius_xlat(search_STR, sizeof(search_STR), inst->search, request, NULL, NULL) && inst->search_len != 0) {
+ if ((radius_xlat(search_STR, sizeof(search_STR), request, inst->search, NULL, NULL) < 0) &&
+ (inst->search_len != 0)) {
DEBUG2("%s: xlat on search string failed.", inst->name);
return rcode;
}
if (!done_xlat){
if (inst->replace_len != 0 &&
- radius_xlat(replace_STR, sizeof(replace_STR), inst->replace, request, NULL, NULL) == 0) {
- DEBUG2("%s: xlat on replace string failed.", inst->name);
+ radius_xlat(replace_STR, sizeof(replace_STR), request, inst->replace, NULL, NULL) < 0) {
return rcode;
}
replace_len = (inst->replace_len != 0) ? strlen(replace_STR) : 0;
* needs to be expanded.
*/
case VPT_TYPE_XLAT:
- if (radius_xlat(buffer, sizeof(buffer), map->src->name,
- request, NULL, NULL) <= 0) {
+ if (radius_xlat(buffer, sizeof(buffer), request, map->src->name, NULL, NULL) <= 0) {
continue;
}
char buffer[1024];
int ret = 0;
- radius_xlat(buffer, sizeof(buffer), inst->key, request, NULL, NULL);
+ if (radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL) < 0) {
+ return 0;
+ }
list = radius_list_name(&p, PAIR_LIST_REQUEST);
rlm_cache_t *inst = instance;
VALUE_PAIR *vp;
char buffer[1024];
- int rcode;
+ rlm_rcode_t rcode;
- radius_xlat(buffer, sizeof(buffer), inst->key, request, NULL, NULL);
+ if (radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
PTHREAD_MUTEX_LOCK(&inst->cache_mutex);
c = cache_find(inst, request, buffer);
* feed it through radius_xlat() to expand the
* variables.
*/
- if (radius_xlat(buffer, sizeof(buffer), inst->detailfile, request, NULL, NULL) == 0) {
- radlog_request(L_ERR, 0, request, "rlm_detail: Failed to expand detail file %s",
- inst->detailfile);
+ if (radius_xlat(buffer, sizeof(buffer), request, inst->detailfile, NULL, NULL) < 0) {
return RLM_MODULE_FAIL;
}
RDEBUG2("%s expands to %s", inst->detailfile, buffer);
return RLM_MODULE_FAIL;
}
- if (radius_xlat(timestamp, sizeof(timestamp), inst->header, request, NULL, NULL) == 0) {
- radlog_request(L_ERR, 0, request, "rlm_detail: Unable to expand detail header format %s",
- inst->header);
+ if (radius_xlat(timestamp, sizeof(timestamp), request, inst->header, NULL, NULL) < 0) {
close(outfd);
return RLM_MODULE_FAIL;
}
EAP_DS *eap_ds = handler->eap_ds;
rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) instance;
- if (!radius_xlat(challenge_str, sizeof(challenge_str), inst->challenge, handler->request, NULL, NULL)) {
- radlog(L_ERR, "rlm_eap_gtc: xlat of \"%s\" failed", inst->challenge);
+ if (radius_xlat(challenge_str, sizeof(challenge_str), handler->request, inst->challenge, NULL, NULL) < 0) {
return 0;
}
REQUEST *request = NULL;
char buff[71];
- size_t len = 0;
+ ssize_t len = 0;
TNC_Result result;
TNC_ConnectionID conn_id;
/*
* Build the connection string
*/
- len = radius_xlat(buff, sizeof(buff), inst->connection_string, request,
- NULL, NULL);
- if(len == 0){
- radlog(L_ERR, "rlm_eap_tnc: Connection string expansion failed");
-
+ len = radius_xlat(buff, sizeof(buff), request, inst->connection_string, NULL, NULL);
+ if (len < 0){
return 0;
}
VALUE_PAIR *vp, *check_item = NULL;
char msg[MAX_STRING_LEN];
- if ((check_item = pairfind(request->config_items, PW_EXPIRATION, 0, TAG_ANY)) != NULL){
+ check_item = pairfind(request->config_items, PW_EXPIRATION, 0, TAG_ANY);
+ if (check_item != NULL) {
/*
* Has this user's password expired?
*
RDEBUG("Account has expired");
if (inst->msg && inst->msg[0]){
- if (!radius_xlat(msg, sizeof(msg), inst->msg, request, NULL, NULL)) {
- radlog(L_ERR, "rlm_expiration: xlat failed.");
+ if (radius_xlat(msg, sizeof(msg), request, inst->msg, NULL, NULL) < 0) {
return RLM_MODULE_FAIL;
}
pairmake_reply("Reply-Message", msg, T_OP_ADD);
}
- RDEBUGE("Account has expired [Expiration %s]",check_item->vp_strvalue);
+ RDEBUGE("Account has expired [Expiration %s]", check_item->vp_strvalue);
return RLM_MODULE_USERLOCK;
}
/*
*/
vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT, 0, TAG_ANY);
if (!vp) {
- vp = radius_paircreate(request, &request->reply->vps,
- PW_SESSION_TIMEOUT, 0);
+ vp = radius_paircreate(request, &request->reply->vps, PW_SESSION_TIMEOUT, 0);
vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp);
-
} else if (vp->vp_date > ((uint32_t) (((time_t) check_item->vp_date) - request->timestamp))) {
vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp);
}
- }
- else
+ } else {
return RLM_MODULE_NOOP;
-
+ }
+
return RLM_MODULE_OK;
}
*/
static int presufcmp(UNUSED void *instance,
REQUEST *req,
- VALUE_PAIR *request, VALUE_PAIR *check,
- VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
+ VALUE_PAIR *request,
+ VALUE_PAIR *check,
+ VALUE_PAIR *check_pairs,
+ UNUSED VALUE_PAIR **reply_pairs)
{
VALUE_PAIR *vp;
char *name;
int len, namelen;
int ret = -1;
- if (!request) return -1;
-
+ if (!request) {
+ return -1;
+ }
+
name = request->vp_strvalue;
#if 0 /* DEBUG */
- printf("Comparing %s and %s, check->attr is %d\n",
- name, check->vp_strvalue, check->attribute);
+ printf("Comparing %s and %s, check->attr is %d\n", name, check->vp_strvalue, check->attribute);
#endif
len = strlen((char *)check->vp_strvalue);
}
break;
}
- if (ret != 0)
+ if (ret != 0) {
return ret;
-
+ }
+
/*
* If Strip-User-Name == No, then don't do any more.
*/
/*
* Compare the request packet type.
*/
-static int packetcmp(void *instance UNUSED, REQUEST *req,
- VALUE_PAIR *request UNUSED,
+static int packetcmp(UNUSED void *instance,
+ REQUEST *request,
+ UNUSED VALUE_PAIR *req,
VALUE_PAIR *check,
- VALUE_PAIR *check_pairs UNUSED,
- VALUE_PAIR **reply_pairs UNUSED)
+ UNUSED VALUE_PAIR *check_pairs,
+ UNUSED VALUE_PAIR **reply_pairs)
{
- if (req->packet->code == check->vp_integer) {
+ if (request->packet->code == check->vp_integer) {
return 0;
}
/*
* Compare the response packet type.
*/
-static int responsecmp(void *instance UNUSED,
- REQUEST *req,
- VALUE_PAIR *request UNUSED,
+static int responsecmp(UNUSED void *instance,
+ REQUEST *request,
+ UNUSED VALUE_PAIR *req,
VALUE_PAIR *check,
- VALUE_PAIR *check_pairs UNUSED,
- VALUE_PAIR **reply_pairs UNUSED)
+ UNUSED VALUE_PAIR *check_pairs,
+ UNUSED VALUE_PAIR **reply_pairs)
{
- if (req->reply->code == check->vp_integer) {
+ if (request->reply->code == check->vp_integer) {
return 0;
}
/*
* Generic comparisons, via xlat.
*/
-static int genericcmp(void *instance UNUSED,
- REQUEST *req,
- VALUE_PAIR *request UNUSED,
+static int genericcmp(UNUSED void *instance,
+ REQUEST *request,
+ UNUSED VALUE_PAIR *req,
VALUE_PAIR *check,
- VALUE_PAIR *check_pairs UNUSED,
- VALUE_PAIR **reply_pairs UNUSED)
+ UNUSED VALUE_PAIR *check_pairs,
+ UNUSED VALUE_PAIR **reply_pairs)
{
if ((check->op != T_OP_REG_EQ) &&
(check->op != T_OP_REG_NE)) {
snprintf(name, sizeof(name), "%%{%s}", check->da->name);
- radius_xlat(value, sizeof(value), name, req, NULL, NULL);
+ if (radius_xlat(value, sizeof(value), request, name, NULL, NULL) < 0) {
+ return 0;
+ }
vp = pairmake(req, NULL, check->da->name, value, check->op);
/*
/*
* Will do the xlat for us
*/
- return radius_compare_vps(req, check, NULL);
+ return radius_compare_vps(request, check, NULL);
}
static int generic_attrs[] = {
/*
* Do an xlat on the provided string (nice recursive operation).
*/
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL)) {
- RDEBUGE("xlat failed.");
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL) < 0) {
*out = '\0';
return 0;
}
/*
* Do an xlat on the provided string (nice recursive operation).
*/
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL)) {
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL) < 0) {
RDEBUGE("xlat failed.");
*out = '\0';
return 0;
char buffer[1024];
unsigned int result;
size_t freespace = outlen;
- size_t len;
+ ssize_t len;
if (outlen <= 1) return 0;
/*
* Do an xlat on the provided string (nice recursive operation).
*/
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
- if (!len) {
- RDEBUGE("xlat failed.");
+ len = radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL);
+ if (len < 0) {
*out = '\0';
return 0;
}
char *p;
char buffer[1024];
size_t freespace = outlen;
- size_t len;
+ ssize_t len;
if (outlen <= 1) return 0;
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
- if (!len) {
- RDEBUGE("xlat failed.");
+ len = radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL);
+ if (len < 0) {
*out = '\0';
return 0;
}
char *p;
char buffer[1024];
size_t freespace = outlen;
- size_t len;
+ ssize_t len;
if (outlen <= 1) return 0;
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
- if (!len) {
- RDEBUGE("xlat failed.");
+ len = radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL);
+ if (len < 0) {
*out = '\0';
return 0;
}
if (outlen <= 1) return 0;
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL)) {
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL) < 0) {
*out = '\0';
return 0;
}
char buffer[1024];
if (outlen <= 1) return 0;
-
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL)) {
- *out = '\0';
+
+ *out = '\0';
+
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL) < 0) {
return 0;
}
uint8_t digest[16];
int i;
FR_MD5_CTX ctx;
-
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL)) {
- *out = '\0';
+
+ *out = '\0';
+
+ if (radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL) < 0) {
return 0;
}
static size_t base64_xlat(UNUSED void *instance, REQUEST *request,
const char *fmt, char *out, size_t outlen)
{
- size_t len;
+ ssize_t len;
char buffer[1024];
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
+ len = radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL);
/*
* We can accurately calculate the length of the output string
* if it's larger than outlen, the output would be useless so abort.
*/
- if (!len || ((FR_BASE64_ENC_LENGTH(len) + 1) > outlen)) {
+ if ((len < 0) || ((FR_BASE64_ENC_LENGTH(len) + 1) > (ssize_t) outlen)) {
RDEBUGE("xlat failed.");
*out = '\0';
return 0;
ssize_t declen;
size_t freespace = outlen;
- size_t len;
+ ssize_t len;
+
+ *out = '\0';
+
+ len = radius_xlat(buffer, sizeof(buffer), request, fmt, NULL, NULL);
+ if (len < 0) {
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
-
- if (!len) {
- RDEBUGE("xlat failed.");
- *out = '\0';
return 0;
}
+ *out = '\0';
+
declen = fr_base64_decode(buffer, len, decbuf, sizeof(decbuf));
if (declen < 0) {
- RDEBUGE("base64 string invalid");
- *out = '\0';
+ RDEBUGE("Base64 string invalid");
return 0;
}
p = decbuf;
while ((declen-- > 0) && (--freespace > 0)) {
- if (freespace < 3)
+ if (freespace < 3) {
break;
+ }
snprintf(out, 3, "%02x", *p++);
} else {
int len;
- len = radius_xlat(buffer, sizeof(buffer), inst->key,
- request, NULL, NULL);
- if (len) name = buffer;
- else name = "NONE";
+ len = radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL);
+ if (len < 0) {
+ return RLM_MODULE_FAIL;
+ }
+
+ name = len ? buffer : "NONE";
}
if (!ht) return RLM_MODULE_NOOP;
}
switch(acctstatustype){
case PW_STATUS_STOP:
- if (!radius_xlat(xlat_str,MAX_STRING_LEN,inst->key, request, NULL, NULL)){
- RDEBUG("xlat on the 'key' directive failed");
+ if (radius_xlat(xlat_str, sizeof(xlat_str), request, inst->key, NULL, NULL) < 0){
return RLM_MODULE_NOOP;
}
fr_MD5Init(&md5_context);
}
#endif
- if (!radius_xlat(xlat_str,MAX_STRING_LEN,inst->key, request, NULL, NULL)){
- RDEBUG("xlat on the 'key' directive failed");
+ if (radius_xlat(xlat_str, sizeof(xlat_str), request, inst->key, NULL, NULL) < 0){
return RLM_MODULE_NOOP;
}
+
fr_MD5Init(&md5_context);
fr_MD5Update(&md5_context, (uint8_t *)xlat_str, strlen(xlat_str));
fr_MD5Final(key_str, &md5_context);
switch (map->src->type) {
case VPT_TYPE_XLAT:
case VPT_TYPE_ATTR:
- rad_cfree(name);
+ rad_const_free(name);
break;
default:
break;
{
const value_pair_map_t *map;
unsigned int total = 0;
-
size_t len;
- char *buffer;
-
+
VALUE_PAIR *found, **from = NULL;
REQUEST *context;
for (map = maps; map != NULL; map = map->next) {
switch (map->src->type) {
case VPT_TYPE_XLAT:
- buffer = rad_malloc(LDAP_MAX_ATTR_STR_LEN);
- len = radius_xlat(buffer, LDAP_MAX_ATTR_STR_LEN, map->src->name, request, NULL, NULL);
-
- if (len <= 0) {
- RDEBUG("Expansion of LDAP attribute \"%s\" failed", map->src->name);
+ {
+ char *exp = NULL;
+
+ len = radius_xlat(exp, 0, request, map->src->name, NULL, NULL);
+ if (len <= 0) {
+ RDEBUG("Expansion of LDAP attribute \"%s\" failed", map->src->name);
- goto error;
- }
+ goto error;
+ }
- expanded->attrs[total++] = buffer;
- break;
+ expanded->attrs[total++] = exp;
+ break;
+ }
case VPT_TYPE_ATTR:
context = request;
}
if (!from) continue;
- found = pairfind(*from, map->src->da->attr,
- map->src->da->vendor, TAG_ANY);
+ found = pairfind(*from, map->src->da->attr, map->src->da->vendor, TAG_ANY);
if (!found) continue;
- buffer = rad_malloc(LDAP_MAX_ATTR_STR_LEN);
- strlcpy(buffer, found->vp_strvalue, LDAP_MAX_ATTR_STR_LEN);
-
- expanded->attrs[total++] = buffer;
+ expanded->attrs[total++] = talloc_strdup(request, found->vp_strvalue);
break;
case VPT_TYPE_LITERAL:
return RLM_MODULE_INVALID;
}
- if (!radius_xlat(base_dn, sizeof(base_dn), inst->groupobj_base_dn, request, rlm_ldap_escape_func, NULL)) {
+ if (radius_xlat(base_dn, sizeof(base_dn), request, inst->groupobj_base_dn, rlm_ldap_escape_func, NULL) < 0) {
RDEBUGE("Failed creating base_dn");
return RLM_MODULE_INVALID;
/*
* rlm_ldap_find_user does this, too. Oh well.
*/
- if (!radius_xlat(base_dn, sizeof(base_dn), inst->groupobj_base_dn, request,
- rlm_ldap_escape_func, NULL)) {
+ if (radius_xlat(base_dn, sizeof(base_dn), request, inst->groupobj_base_dn,
+ rlm_ldap_escape_func, NULL) < 0) {
rcode = RLM_MODULE_INVALID;
RDEBUGE("Failed creating base_dn");
const char *in;
char *p = buffer;
- size_t len = 0;
+ ssize_t len = 0;
unsigned int i;
int cnt = 0;
if (sub[i] && (*sub[i] != '\0')) {
len += strlcpy(p + len, sub[i], outlen - len);
- if (len >= outlen) {
+ if ((size_t) len >= outlen) {
oob:
RDEBUGE("Out of buffer space creating filter");
in = buffer;
}
- len = radius_xlat(out, outlen, in, request, rlm_ldap_escape_func, NULL);
- if (!len) {
+ len = radius_xlat(out, outlen, request, in, rlm_ldap_escape_func, NULL);
+ if (len < 0) {
RDEBUGE("Failed creating filter");
return -1;
(*pconn)->rebound = FALSE;
}
- if (!radius_xlat(filter, sizeof(filter), inst->userobj_filter, request, rlm_ldap_escape_func, NULL)) {
+ if (radius_xlat(filter, sizeof(filter), request, inst->userobj_filter, rlm_ldap_escape_func, NULL) < 0) {
RDEBUGE("Unable to create filter");
*rcode = RLM_MODULE_INVALID;
return NULL;
}
- if (!radius_xlat(base_dn, sizeof(base_dn), inst->userobj_base_dn, request, rlm_ldap_escape_func, NULL)) {
+ if (radius_xlat(base_dn, sizeof(base_dn), request, inst->userobj_base_dn, rlm_ldap_escape_func, NULL) < 0) {
RDEBUGE("Unable to create base_dn");
*rcode = RLM_MODULE_INVALID;
char buffer[LDAP_MAX_DN_STR_LEN + LDAP_MAX_FILTER_STR_LEN];
if (strchr(fmt, '%') != NULL) {
- if (!radius_xlat(buffer, sizeof(buffer), fmt, request, rlm_ldap_escape_func, NULL)) {
+ if (!radius_xlat(buffer, sizeof(buffer), request, fmt, rlm_ldap_escape_func, NULL)) {
RDEBUGE("Unable to create LDAP URL");
return 0;
}
*p++ = '.';
}
- if (!radius_xlat(p, (sizeof(path) - (p - path)) - 1, section->reference, request, NULL, NULL)) {
+ if (radius_xlat(p, (sizeof(path) - (p - path)) - 1, request, section->reference, NULL, NULL) < 0) {
goto error;
}
if (op == T_OP_CMP_FALSE) {
passed[last_pass] = NULL;
} else if (do_xlat) {
- p = rad_malloc(1024);
- if (radius_xlat(p, 1024, value, request, NULL, NULL) <= 0) {
- RDEBUG("xlat failed or empty value string, skipping attribute \"%s\"", attr);
+ char *exp = NULL;
+
+ if (radius_xlat(exp, 0, request, value, NULL, NULL) <= 0) {
+ RDEBUG("Skipping attribute \"%s\"", attr);
- free(p);
+ talloc_free(exp);
continue;
}
- expanded[last_exp++] = p;
- passed[last_pass] = p;
+ expanded[last_exp++] = exp;
+ passed[last_pass] = exp;
/*
* Static strings
*/
* Free up any buffers we allocated for xlat expansion
*/
for (i = 0; i < last_exp; i++) {
- free(expanded[i]);
+ talloc_free(expanded[i]);
}
rlm_ldap_release_socket(inst, conn);
CONF_ITEM *ci;
CONF_PAIR *cp;
- radius_xlat(line + 1, sizeof(line) - 2, inst->reference,
- request, linelog_escape_func, NULL);
+ p = line + 1;
+
+ if (radius_xlat(p, sizeof(line) - 2, request, inst->reference, linelog_escape_func,
+ NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
+
line[0] = '.'; /* force to be in current section */
/*
* FIXME: Check length.
*/
if (strcmp(inst->filename, "syslog") != 0) {
- radius_xlat(buffer, sizeof(buffer), inst->filename, request,
- NULL, NULL);
+ if (radius_xlat(buffer, sizeof(buffer), request, inst->filename, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
/* check path and eventually create subdirs */
p = strrchr(buffer,'/');
/*
* FIXME: Check length.
*/
- radius_xlat(line, sizeof(line) - 1, value, request,
- linelog_escape_func, NULL);
+ if (radius_xlat(line, sizeof(line) - 1, request, value, linelog_escape_func, NULL) < 0) {
+ if (fd > -1) {
+ close(fd);
+ }
+
+ return RLM_MODULE_FAIL;
+ }
if (fd >= 0) {
strcat(line, "\n");
#include "smbdes.h"
#ifdef HAVE_OPENSSL_CRYPTO_H
+USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
# include <openssl/rc4.h>
#endif
while (isspace(*p)) p++;
- if (!radius_xlat(buf2, sizeof(buf2),p,request,NULL,NULL)) {
- RDEBUG("xlat failed");
+ if (radius_xlat(buf2, sizeof(buf2), request, p, NULL, NULL) < 0) {
*buffer = '\0';
return 0;
}
while (isspace(*p)) p++;
- if (!radius_xlat(buf2, sizeof(buf2),p,request,NULL,NULL)) {
- RDEBUG("xlat failed");
+ if (radius_xlat(buf2, sizeof(buf2), request, p, NULL, NULL) < 0) {
*buffer = '\0';
return 0;
}
*/
if (inst->ntlm_cpw_username) {
- len = radius_xlat(buf, sizeof(buf) - 2, inst->ntlm_cpw_username, request, NULL, NULL);
- strcat(buf, "\n");
- len++;
+ len = radius_xlat(buf, sizeof(buf) - 2, request, inst->ntlm_cpw_username, NULL, NULL);
+ if (len < 0) {
+ goto ntlm_auth_err;
+ }
+
+ buf[len++] = '\n';
+ buf[len] = '\0';
if (write_all(to_child, buf, len) != len) {
RDEBUG2("failed to write username to child");
}
if (inst->ntlm_cpw_domain) {
- len = radius_xlat(buf, sizeof(buf) - 2, inst->ntlm_cpw_domain, request, NULL, NULL);
- strcat(buf, "\n");
- len++;
+ len = radius_xlat(buf, sizeof(buf) - 2, request, inst->ntlm_cpw_domain, NULL, NULL);
+ if (len < 0) {
+ goto ntlm_auth_err;
+ }
+
+ buf[len++] = '\n';
+ buf[len] = '\0';
if (write_all(to_child, buf, len) != len) {
RDEBUG2("failed to write domain to child");
VALUE_PAIR *new_pass, *new_hash;
uint8_t *p;
- size_t i, result_len;
+ size_t i;
size_t passlen;
+ ssize_t result_len;
char result[253];
uint8_t nt_pass_decrypted[516], old_nt_hash_expected[16];
RC4_KEY key;
/*
* perform the xlat
*/
- result_len = radius_xlat(result, sizeof(result), inst->local_cpw, request, NULL, NULL);
- if (!result_len) {
+ result_len = radius_xlat(result, sizeof(result), request, inst->local_cpw, NULL, NULL);
+ if (result_len < 0){
+ return -1;
+ } else if (result_len == 0) {
RDEBUG("Local MS-CHAPv2 password change - xlat didn't give any result, assuming failure");
return -1;
}
*/
{
VALUE_PAIR *vp;
- char buff[1024];
- size_t len;
+
+ char *expanded = NULL;
+ ssize_t len;
/*
* First add the internal OTP challenge attribute to
* what the challenge value is.
*/
- len = radius_xlat(buff, sizeof(buff), inst->chal_prompt,
- request, NULL, NULL);
- if (len == 0) {
+ len = radius_axlat(&expanded, request, inst->chal_prompt, NULL, NULL);
+ if (len < 0) {
return RLM_MODULE_FAIL;
}
vp = paircreate(request->reply, PW_REPLY_MESSAGE, 0);
if (!vp) {
+ talloc_free(expanded);
return RLM_MODULE_FAIL;
}
- memcpy(vp->vp_strvalue, challenge, len);
+ memcpy(vp->vp_strvalue, expanded, len);
+ talloc_free(expanded);
+
vp->length = inst->challenge_len;
vp->op = T_OP_SET;
static int pap_auth_nt(REQUEST *request, VALUE_PAIR *vp)
{
- uint8_t binbuf[128];
- char charbuf[128];
- char buff2[MAX_STRING_LEN + 50];
+ uint8_t binbuf[16];
+ char charbuf[32 + 1];
RDEBUG("Using NT encryption.");
return RLM_MODULE_REJECT;
}
- strlcpy(buff2, "%{mschap:NT-Hash %{User-Password}}", sizeof(buff2));
- if (!radius_xlat(charbuf, sizeof(charbuf),buff2,request,NULL,NULL)){
- RDEBUGE("mschap xlat failed");
+ if (!radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:NT-Hash %{User-Password}}", NULL, NULL) < 0){
return RLM_MODULE_REJECT;
}
- if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) ||
+ if ((fr_hex2bin(charbuf, binbuf, sizeof(binbuf)) != vp->length) ||
(rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) {
RDEBUGE("NT password check failed");
return RLM_MODULE_REJECT;
static int pap_auth_lm(REQUEST *request, VALUE_PAIR *vp)
{
- uint8_t binbuf[128];
- char charbuf[128];
- char buff2[MAX_STRING_LEN + 50];
+ uint8_t binbuf[16];
+ char charbuf[32 + 1];
RDEBUG("Using LM encryption.");
return RLM_MODULE_REJECT;
}
- strlcpy(buff2, "%{mschap:LM-Hash %{User-Password}}", sizeof(buff2));
- if (!radius_xlat(charbuf,sizeof(charbuf),buff2,request,NULL,NULL)){
- RDEBUGE("mschap xlat failed");
+ if (!radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:LM-Hash %{User-Password}}", NULL, NULL) < 0){
return RLM_MODULE_REJECT;
}
- if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) ||
+ if ((fr_hex2bin(charbuf, binbuf, sizeof(binbuf)) != vp->length) ||
(rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) {
RDEBUGE("LM password check failed");
return RLM_MODULE_REJECT;
rlm_perl_t *inst= (rlm_perl_t *) instance;
PerlInterpreter *perl;
- char params[1024], *ptr, *tmp;
+ char *expanded, *ptr, *tmp;
int count;
size_t ret = 0;
STRLEN n_a;
/*
- * Do an xlat on the provided string (nice recursive operation).
+ * Do an xlat on the provided string (nice recursive operation).
*/
- if (!radius_xlat(params, sizeof(params), fmt, request, NULL, NULL)) {
- radlog(L_ERR, "rlm_perl: xlat failed.");
+ if (radius_axlat(&expanded, request, fmt, NULL, NULL) < 0) {
return 0;
}
dSP;
ENTER;SAVETMPS;
- ptr = strtok(params, " ");
+ ptr = strtok(expanded, " ");
PUSHMARK(SP);
strlcpy(out, tmp, freespace);
ret = strlen(out);
- radlog(L_DBG,"rlm_perl: Len is %zu , out is %s freespace is %zu",
- ret, out, freespace);
+ radlog(L_DBG,"rlm_perl: Len is %zu , out is %s freespace is %zu", ret, out, freespace);
}
PUTBACK ;
LEAVE ;
}
+
+ talloc_free(expanded);
+
return ret;
}
/*
*/
static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
{
+ rlm_rcode_t rcode = RLM_MODULE_OK;
struct radutmp ut, u;
VALUE_PAIR *vp;
int status = -1;
int protocol = -1;
time_t t;
- int fd;
+ int fd = -1;
int port_seen = 0;
int off;
rlm_radutmp_t *inst = instance;
- char buffer[256];
- char filename[1024];
char ip_name[32]; /* 255.255.255.255 */
const char *nas;
NAS_PORT *cache;
int r;
+
+ char *filename = NULL;
+ char *expanded = NULL;
if (request->packet->src_ipaddr.af != AF_INET) {
DEBUG("rlm_radutmp: IPv6 not supported!");
/*
* Set the protocol field.
*/
- if (protocol == PW_PPP)
+ if (protocol == PW_PPP) {
ut.proto = 'P';
- else if (protocol == PW_SLIP)
+ } else if (protocol == PW_SLIP) {
ut.proto = 'S';
- else
+ } else {
ut.proto = 'T';
+ }
+
ut.time = t - ut.delay;
/*
* Get the utmp filename, via xlat.
*/
- radius_xlat(filename, sizeof(filename), inst->filename, request, NULL, NULL);
+ if (radius_xlat(filename, 0, request, inst->filename, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
/*
* See if this was a reboot.
*
- * Hmm... we may not want to zap all of the users when
- * the NAS comes up, because of issues with receiving
+ * Hmm... we may not want to zap all of the users when the NAS comes up, because of issues with receiving
* UDP packets out of order.
*/
- if (status == PW_STATUS_ACCOUNTING_ON &&
- (ut.nas_address != htonl(INADDR_NONE))) {
- radlog(L_INFO, "rlm_radutmp: NAS %s restarted (Accounting-On packet seen)",
- nas);
+ if (status == PW_STATUS_ACCOUNTING_ON && (ut.nas_address != htonl(INADDR_NONE))) {
+ radlog(L_INFO, "rlm_radutmp: NAS %s restarted (Accounting-On packet seen)", nas);
radutmp_zap(request, filename, ut.nas_address, ut.time);
- return RLM_MODULE_OK;
+ rcode = RLM_MODULE_OK;
+
+ goto finish;
}
- if (status == PW_STATUS_ACCOUNTING_OFF &&
- (ut.nas_address != htonl(INADDR_NONE))) {
- radlog(L_INFO, "rlm_radutmp: NAS %s rebooted (Accounting-Off packet seen)",
- nas);
+ if (status == PW_STATUS_ACCOUNTING_OFF && (ut.nas_address != htonl(INADDR_NONE))) {
+ radlog(L_INFO, "rlm_radutmp: NAS %s rebooted (Accounting-Off packet seen)", nas);
radutmp_zap(request, filename, ut.nas_address, ut.time);
- return RLM_MODULE_OK;
+ rcode = RLM_MODULE_OK;
+
+ goto finish;
}
/*
* If we don't know this type of entry pretend we succeeded.
*/
- if (status != PW_STATUS_START &&
- status != PW_STATUS_STOP &&
- status != PW_STATUS_ALIVE) {
- RDEBUGE("NAS %s port %u unknown packet type %d)",
- nas, ut.nas_port, status);
- return RLM_MODULE_NOOP;
+ if (status != PW_STATUS_START && status != PW_STATUS_STOP && status != PW_STATUS_ALIVE) {
+ RDEBUGE("NAS %s port %u unknown packet type %d)", nas, ut.nas_port, status);
+ rcode = RLM_MODULE_NOOP;
+
+ goto finish;
}
/*
- * Translate the User-Name attribute, or whatever else
- * they told us to use.
+ * Translate the User-Name attribute, or whatever else they told us to use.
*/
- *buffer = '\0';
- radius_xlat(buffer, sizeof(buffer), inst->username, request, NULL, NULL);
-
- /*
- * Copy the previous translated user name.
- */
- strlcpy(ut.login, buffer, RUT_NAMESIZE);
+ if (radius_axlat(&expanded, request, inst->username, NULL, NULL) < 0) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+ strlcpy(ut.login, expanded, RUT_NAMESIZE);
+ TALLOC_FREE(expanded);
/*
* Perhaps we don't want to store this record into
* - with the username "!root" (console admin login)
*/
if (!port_seen) {
- DEBUG2(" rlm_radutmp: No NAS-Port seen. Cannot do anything.");
- DEBUG2W("checkrad will probably not work!");
- return RLM_MODULE_NOOP;
+ RDEBUG2W("No NAS-Port seen. Cannot do anything. Checkrad will probably not work!");
+ rcode = RLM_MODULE_NOOP;
+
+ goto finish;
}
if (strncmp(ut.login, "!root", RUT_NAMESIZE) == 0) {
- DEBUG2(" rlm_radutmp: Not recording administrative user");
-
- return RLM_MODULE_NOOP;
+ RDEBUG2("Not recording administrative user");
+ rcode = RLM_MODULE_NOOP;
+
+ goto finish;
}
/*
*/
fd = open(filename, O_RDWR|O_CREAT, inst->permission);
if (fd < 0) {
- RDEBUGE("Error accessing file %s: %s",
- filename, strerror(errno));
- return RLM_MODULE_FAIL;
+ RDEBUGE("Error accessing file %s: %s", filename, strerror(errno));
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
/*
/*
* Find the entry for this NAS / portno combination.
*/
- if ((cache = nas_port_find(inst->nas_port_list, ut.nas_address,
- ut.nas_port)) != NULL) {
+ if ((cache = nas_port_find(inst->nas_port_list, ut.nas_address, ut.nas_port)) != NULL) {
lseek(fd, (off_t)cache->offset, SEEK_SET);
}
off = 0;
while (read(fd, &u, sizeof(u)) == sizeof(u)) {
off += sizeof(u);
- if (u.nas_address != ut.nas_address ||
- u.nas_port != ut.nas_port)
+ if ((u.nas_address != ut.nas_address) || (u.nas_port != ut.nas_port)) {
continue;
+ }
/*
* Don't compare stop records to unused entries.
*/
- if (status == PW_STATUS_STOP &&
- u.type == P_IDLE) {
+ if (status == PW_STATUS_STOP && u.type == P_IDLE) {
continue;
}
- if (status == PW_STATUS_STOP &&
- strncmp(ut.session_id, u.session_id,
- sizeof(u.session_id)) != 0) {
+ if ((status == PW_STATUS_STOP) && strncmp(ut.session_id, u.session_id, sizeof(u.session_id)) != 0) {
/*
* Don't complain if this is not a
* login record (some clients can
* send _only_ logout records).
*/
- if (u.type == P_LOGIN)
- RDEBUGW("Logout entry for NAS %s port %u has wrong ID",
- nas, u.nas_port);
+ if (u.type == P_LOGIN) {
+ RDEBUGW("Logout entry for NAS %s port %u has wrong ID", nas, u.nas_port);
+ }
+
r = -1;
break;
}
- if (status == PW_STATUS_START &&
- strncmp(ut.session_id, u.session_id,
- sizeof(u.session_id)) == 0 &&
+ if ((status == PW_STATUS_START) && strncmp(ut.session_id, u.session_id, sizeof(u.session_id)) == 0 &&
u.time >= ut.time) {
if (u.type == P_LOGIN) {
radlog(L_INFO, "rlm_radutmp: Login entry for NAS %s port %u duplicate",
r = -1;
break;
}
- RDEBUGW("Login entry for NAS %s port %u wrong order",
- nas, u.nas_port);
+
+ RDEBUGW("Login entry for NAS %s port %u wrong order", nas, u.nas_port);
r = -1;
break;
}
/*
- * FIXME: the ALIVE record could need
- * some more checking, but anyway I'd
+ * FIXME: the ALIVE record could need some more checking, but anyway I'd
* rather rewrite this mess -- miquels.
*/
- if (status == PW_STATUS_ALIVE &&
- strncmp(ut.session_id, u.session_id,
- sizeof(u.session_id)) == 0 &&
+ if ((status == PW_STATUS_ALIVE) && strncmp(ut.session_id, u.session_id, sizeof(u.session_id)) == 0 &&
u.type == P_LOGIN) {
/*
* Keep the original login time.
RDEBUGW("negative lseek!");
lseek(fd, (off_t)0, SEEK_SET);
off = 0;
- } else
+ } else {
off -= sizeof(u);
+ }
+
r = 1;
break;
} /* read the file until we find a match */
* Found the entry, do start/update it with
* the information from the packet.
*/
- if (r >= 0 && (status == PW_STATUS_START ||
- status == PW_STATUS_ALIVE)) {
+ if ((r >= 0) && (status == PW_STATUS_START || status == PW_STATUS_ALIVE)) {
/*
* Remember where the entry was, because it's
* easier than searching through the entire file.
u.delay = ut.delay;
write(fd, &u, sizeof(u));
} else if (r == 0) {
- RDEBUGW("Logout for NAS %s port %u, but no Login record",
- nas, ut.nas_port);
+ RDEBUGW("Logout for NAS %s port %u, but no Login record", nas, ut.nas_port);
}
}
- close(fd); /* and implicitely release the locks */
+ finish:
+
+ talloc_free(filename);
+
+ if (fd > -1) {
+ close(fd); /* and implicitely release the locks */
+ }
+
return RLM_MODULE_OK;
}
#endif
*/
static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
{
+ rlm_rcode_t rcode = RLM_MODULE_OK;
struct radutmp u;
- int fd;
+ int fd = -1;
VALUE_PAIR *vp;
uint32_t ipno = 0;
char *call_num = NULL;
- int rcode;
rlm_radutmp_t *inst = instance;
- char login[256];
- char filename[1024];
+
+ char *expanded = NULL;
+ ssize_t len;
/*
* Get the filename, via xlat.
*/
- radius_xlat(filename, sizeof(filename), inst->filename, request, NULL, NULL);
+ if (radius_axlat(&expanded, request, inst->filename, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
- if ((fd = open(filename, O_RDWR)) < 0) {
+ fd = open(expanded, O_RDWR);
+ if (fd < 0) {
/*
* If the file doesn't exist, then no users
* are logged in.
/*
* Error accessing the file.
*/
- radlog(L_ERR, "rlm_radumtp: Error accessing file %s: %s",
- filename, strerror(errno));
+ radlog(L_ERR, "rlm_radumtp: Error accessing file %s: %s", expanded, strerror(errno));
+
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+
+ TALLOC_FREE(expanded);
+
+ len = radius_axlat(&expanded, request, inst->username, NULL, NULL);
+ if (len < 0) {
return RLM_MODULE_FAIL;
}
+
+ if (!len) {
+ rcode = RLM_MODULE_NOOP;
- *login = '\0';
- radius_xlat(login, sizeof(login), inst->username, request, NULL, NULL);
- if (!*login) {
- close(fd);
- return RLM_MODULE_NOOP;
+ goto finish;
}
/*
* Loop over utmp, counting how many people MAY be logged in.
*/
while (read(fd, &u, sizeof(u)) == sizeof(u)) {
- if (((strncmp(login, u.login, RUT_NAMESIZE) == 0) ||
- (!inst->case_sensitive &&
- (strncasecmp(login, u.login, RUT_NAMESIZE) == 0))) &&
- (u.type == P_LOGIN)) {
+ if (((strncmp(expanded, u.login, RUT_NAMESIZE) == 0) ||
+ (!inst->case_sensitive && (strncasecmp(expanded, u.login, RUT_NAMESIZE) == 0))) &&
+ (u.type == P_LOGIN)) {
++request->simul_count;
}
}
* The number of users logged in is OK,
* OR, we've been told to not check the NAS.
*/
- if ((request->simul_count < request->simul_max) ||
- !inst->check_nas) {
- close(fd);
- return RLM_MODULE_OK;
+ if ((request->simul_count < request->simul_max) || !inst->check_nas) {
+ rcode = RLM_MODULE_OK;
+
+ goto finish;
}
lseek(fd, (off_t)0, SEEK_SET);
/*
* Setup some stuff, like for MPP detection.
*/
- if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL)
+ if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL) {
ipno = vp->vp_ipaddr;
- if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL)
+ }
+
+ if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL) {
call_num = vp->vp_strvalue;
+ }
/*
* lock the file while reading/writing.
*/
request->simul_count = 0;
while (read(fd, &u, sizeof(u)) == sizeof(u)) {
- if (((strncmp(login, u.login, RUT_NAMESIZE) == 0) ||
- (!inst->case_sensitive &&
- (strncasecmp(login, u.login, RUT_NAMESIZE) == 0))) &&
- (u.type == P_LOGIN)) {
+ if (((strncmp(expanded, u.login, RUT_NAMESIZE) == 0) || (!inst->case_sensitive &&
+ (strncasecmp(expanded, u.login, RUT_NAMESIZE) == 0))) && (u.type == P_LOGIN)) {
char session_id[sizeof(u.session_id) + 1];
char utmp_login[sizeof(u.login) + 1];
* to block everyone else while
* that's happening. */
rad_unlockfd(fd, LOCK_LEN);
- rcode = rad_check_ts(u.nas_address, u.nas_port,
- utmp_login, session_id);
+ rcode = rad_check_ts(u.nas_address, u.nas_port, utmp_login, session_id);
rad_lockfd(fd, LOCK_LEN);
if (rcode == 0) {
/*
* Stale record - zap it.
*/
- session_zap(request, u.nas_address,
- u.nas_port, login, session_id,
- u.framed_address, u.proto,0);
+ session_zap(request, u.nas_address, u.nas_port, expanded, session_id,
+ u.framed_address, u.proto, 0);
}
else if (rcode == 1) {
/*
/*
* Does it look like a MPP attempt?
*/
- if (strchr("SCPA", u.proto) &&
- ipno && u.framed_address == ipno)
+ if (strchr("SCPA", u.proto) && ipno && u.framed_address == ipno) {
request->simul_mpp = 2;
- else if (strchr("SCPA", u.proto) && call_num &&
- !strncmp(u.caller_id,call_num,16))
+ } else if (strchr("SCPA", u.proto) && call_num && !strncmp(u.caller_id, call_num,16)) {
request->simul_mpp = 2;
- }
- else {
- /*
- * Failed to check the terminal
- * server for duplicate logins:
- * Return an error.
- */
- close(fd);
+ }
+ } else {
RDEBUGW("Failed to check the terminal server for user '%s'.", utmp_login);
- return RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
}
}
- close(fd); /* and implicitely release the locks */
-
- return RLM_MODULE_OK;
+ finish:
+
+ talloc_free(expanded);
+
+ if (fd > -1) {
+ close(fd); /* and implicitely release the locks */
+ }
+
+ return rcode;
}
#endif
char *name = NULL;
char *value = NULL;
- char buffer[1024];
+ char *expanded = NULL;
const DICT_ATTR *da;
VALUE_PAIR *vp;
int curl_len; /* Length from last curl_easy_unescape call */
int count = 0;
+ int ret;
processed[0] = NULL;
assert(vps);
- RDEBUG2("\tType : %s", fr_int2str(dict_attr_types, da->type,
- "¿Unknown?"));
+ RDEBUG2("\tType : %s", fr_int2str(dict_attr_types, da->type, "¿Unknown?"));
q = strchr(p, '&');
len = (!q) ? (rawlen - (p - raw)) : (unsigned)(q - p);
RDEBUG("Performing xlat expansion of response value");
- if (!radius_xlat(buffer, sizeof(buffer),
- value, request, NULL, NULL)) {
+ if (!radius_axlat(&expanded, request, value, NULL, NULL)) {
goto skip;
}
if (!vp) {
radlog(L_ERR, "rlm_rest (%s): Failed creating"
" valuepair", instance->xlat_name);
-
+ talloc_free(expanded);
+
goto error;
}
current[1] = NULL;
}
- if (!pairparsevalue(vp, buffer)) {
+ ret = pairparsevalue(vp, expanded);
+ talloc_free(expanded);
+ if (!ret) {
RDEBUG("Incompatible value assignment, skipping");
pairbasicfree(vp);
goto skip;
* @param[in] leaf object containing the VALUE_PAIR value.
* @return The VALUE_PAIR just created, or NULL on error.
*/
-static VALUE_PAIR *json_pairmake_leaf(rlm_rest_t *instance,
+static VALUE_PAIR *json_pairmake_leaf(UNUSED rlm_rest_t *instance,
UNUSED rlm_rest_section_t *section,
REQUEST *request, const DICT_ATTR *da,
json_flags_t *flags, json_object *leaf)
{
const char *value, *to_parse;
- char buffer[1024];
+ char *expanded = NULL;
+ int ret;
VALUE_PAIR *vp;
RDEBUG2("\tValue : \"%s\"", value);
if (flags->do_xlat) {
- if (!radius_xlat(buffer, sizeof(buffer), value,
- request, NULL, NULL)) {
+ if (radius_axlat(&expanded, request, value, NULL, NULL) < 0) {
return NULL;
}
- to_parse = buffer;
+ to_parse = expanded;
} else {
to_parse = value;
}
vp = paircreate(NULL, da->attr, da->vendor);
if (!vp) {
- radlog(L_ERR, "rlm_rest (%s): Failed creating valuepair",
- instance->xlat_name);
+ RDEBUGE("Failed creating valuepair");
+ talloc_free(expanded);
+
return NULL;
}
vp->op = flags->op;
- if (!pairparsevalue(vp, to_parse)) {
+ ret = pairparsevalue(vp, to_parse);
+ talloc_free(expanded);
+ if (!ret) {
RDEBUG("Incompatible value assignment, skipping");
pairbasicfree(vp);
+
return NULL;
}
if (auth) {
if ((auth >= HTTP_AUTH_BASIC) &&
(auth <= HTTP_AUTH_ANY_SAFE)) {
- ret = curl_easy_setopt(candle, CURLOPT_HTTPAUTH,
- http_curl_auth[auth]);
+ ret = curl_easy_setopt(candle, CURLOPT_HTTPAUTH, http_curl_auth[auth]);
if (ret != CURLE_OK) goto error;
- if (section->username) {
- radius_xlat(buffer, sizeof(buffer),
- section->username, request, NULL, NULL);
-
- ret = curl_easy_setopt(candle, CURLOPT_USERNAME,
- buffer);
- if (ret != CURLE_OK) goto error;
+ if (section->username) {
+ if (radius_xlat(buffer, sizeof(buffer), request, section->username, NULL, NULL) < 0) {
+ goto error;
+ }
+ ret = curl_easy_setopt(candle, CURLOPT_USERNAME, buffer);
+ if (ret != CURLE_OK) {
+ goto error;
+ }
}
- if (section->password) {
- radius_xlat(buffer, sizeof(buffer),
- section->password, request, NULL, NULL);
-
- ret = curl_easy_setopt(candle, CURLOPT_PASSWORD,
- buffer);
- if (ret != CURLE_OK) goto error;
+ if (section->password) {
+ if (radius_xlat(buffer, sizeof(buffer), request, section->password, NULL, NULL) < 0) {
+ goto error;
+ }
+ ret = curl_easy_setopt(candle, CURLOPT_PASSWORD, buffer);
+ if (ret != CURLE_OK) {
+ goto error;
+ }
}
#ifdef CURLOPT_TLSAUTH_USERNAME
} else if (type == HTTP_AUTH_TLS_SRP) {
- ret = curl_easy_setopt(candle, CURLOPT_TLSAUTH_TYPE,
- http_curl_auth[auth]);
+ ret = curl_easy_setopt(candle, CURLOPT_TLSAUTH_TYPE, http_curl_auth[auth]);
if (section->username) {
- radius_xlat(buffer, sizeof(buffer),
- section->username, request, NULL, NULL);
-
- ret = curl_easy_setopt(candle,
- CURLOPT_TLSAUTH_USERNAME,
- buffer);
- if (ret != CURLE_OK) goto error;
+ if (radius_xlat(buffer, sizeof(buffer), request, section->username, NULL, NULL) < 0) {
+ goto error;
+ }
+ ret = curl_easy_setopt(candle, CURLOPT_TLSAUTH_USERNAME, buffer);
+ if (ret != CURLE_OK) {
+ goto error;
+ }
}
if (section->password) {
- radius_xlat(buffer, sizeof(buffer),
- section->password, request, NULL, NULL);
-
- ret = curl_easy_setopt(candle,
- CURLOPT_TLSAUTH_PASSWORD,
- buffer);
- if (ret != CURLE_OK) goto error;
+ if (radius_xlat(buffer, sizeof(buffer), request, section->password, NULL, NULL) < 0) {
+ goto error;
+ }
+ ret = curl_easy_setopt(candle, CURLOPT_TLSAUTH_PASSWORD, buffer);
+ if (ret != CURLE_OK) {
+ goto error;
+ }
}
#endif
}
* @return length of data written to buffer (excluding NULL) or < 0 if an error
* occurred.
*/
-ssize_t rest_uri_build(rlm_rest_t *instance, rlm_rest_section_t *section,
- REQUEST *request, char *buffer, size_t bufsize)
+ssize_t rest_uri_build(char **out, rlm_rest_t *instance, rlm_rest_section_t *section, REQUEST *request)
{
const char *p, *q;
-
- char *out, *scheme;
+ char *path_exp = NULL;
+
+ char *scheme;
const char *path;
unsigned short count = 0;
- size_t len;
+ ssize_t len, outlen;
p = section->uri;
len = (q - p);
- scheme = rad_malloc(len + 1);
+ scheme = talloc_array(request, char, len + 1);
strlcpy(scheme, section->uri, len + 1);
path = (q + 1);
- out = buffer;
- out += radius_xlat(out, bufsize, scheme, request, NULL, NULL);
+ len = radius_axlat(out, request, scheme, NULL, NULL);
+ talloc_free(scheme);
+ if (len < 0) {
+ TALLOC_FREE(*out);
+
+ return 0;
+ }
- free(scheme);
+ outlen = len;
- out += radius_xlat(out, (bufsize - (buffer - out)), path, request,
- rest_uri_escape, NULL);
+ len = radius_axlat(&path_exp, request, path, rest_uri_escape, NULL);
+ if (len < 0) {
+ TALLOC_FREE(*out);
+
+ return 0;
+ }
- return (buffer - out);
+ *out = talloc_strdup_append(*out, path_exp);
+ talloc_free(path_exp);
+
+ return outlen += len;
}
/*
* Helper functions
*/
-ssize_t rest_uri_build(rlm_rest_t *instance, rlm_rest_section_t *section,
- REQUEST *request, char *buffer, size_t bufsize);
+ssize_t rest_uri_build(char **out, rlm_rest_t *instance, rlm_rest_section_t *section, REQUEST *request);
void *handle, REQUEST *request)
{
size_t uri_len;
- char uri[REST_URI_MAX_LEN];
+ char *uri = NULL;
int ret;
RDEBUG("Expanding URI components");
+
/*
* Build xlat'd URI, this allows REST servers to be specified by
* request attributes.
*/
- uri_len = rest_uri_build(instance, section, request, uri, sizeof(uri));
+ uri_len = rest_uri_build(&uri, instance, section, request);
if (uri_len <= 0) return -1;
- RDEBUG("Sending HTTP %s to \"%s\"",
- fr_int2str(http_method_table, section->method, NULL),
- uri);
+ RDEBUG("Sending HTTP %s to \"%s\"", fr_int2str(http_method_table, section->method, NULL), uri);
/*
* Configure various CURL options, and initialise the read/write
* context data.
*/
- ret = rest_request_config(instance, section, request,
- handle,
- section->method,
- section->body,
- uri);
+ ret = rest_request_config(instance, section, request, handle, section->method, section->body, uri);
+ talloc_free(uri);
+
if (ret <= 0) return -1;
/*
* for inserts, updates and deletes the number of rows afftected will be
* returned instead.
*/
-static size_t sql_xlat(void *instance, REQUEST *request,
- const char *fmt, char *out, size_t freespace)
+static size_t sql_xlat(void *instance, REQUEST *request, const char *fmt, char *out, size_t freespace)
{
- rlm_sql_handle_t *handle;
+ rlm_sql_handle_t *handle = NULL;
rlm_sql_row_t row;
rlm_sql_t *inst = instance;
- char querystr[MAX_QUERY_LEN];
size_t ret = 0;
-
- RDEBUG("sql_xlat");
+
+ char *expanded = NULL;
/*
- * Add SQL-User-Name attribute just in case it is needed
- * We could search the string fmt for SQL-User-Name to see if this is
- * needed or not
+ * Add SQL-User-Name attribute just in case it is needed
+ * We could search the string fmt for SQL-User-Name to see if this is
+ * needed or not
*/
sql_set_user(inst, request, NULL);
+
/*
- * Do an xlat on the provided string (nice recursive operation).
+ * Do an xlat on the provided string (nice recursive operation).
*/
- if (!radius_xlat(querystr, sizeof(querystr), fmt, request, sql_escape_func, inst)) {
- radlog(L_ERR, "rlm_sql (%s): xlat failed.",
- inst->config->xlat_name);
+ if (radius_axlat(&expanded, request, fmt, sql_escape_func, inst) < 0) {
return 0;
}
handle = sql_get_socket(inst);
- if (!handle)
+ if (!handle) {
return 0;
-
- rlm_sql_query_log(inst, request, NULL, querystr);
+ }
+
+ rlm_sql_query_log(inst, request, NULL, expanded);
/*
* If the query starts with any of the following prefixes,
* then return the number of rows affected
*/
- if ((strncasecmp(querystr, "insert", 6) == 0) ||
- (strncasecmp(querystr, "update", 6) == 0) ||
- (strncasecmp(querystr, "delete", 6) == 0)) {
+ if ((strncasecmp(expanded, "insert", 6) == 0) ||
+ (strncasecmp(expanded, "update", 6) == 0) ||
+ (strncasecmp(expanded, "delete", 6) == 0)) {
int numaffected;
char buffer[21]; /* 64bit max is 20 decimal chars + null byte */
- if (rlm_sql_query(&handle,inst,querystr)) {
- sql_release_socket(inst,handle);
-
- return 0;
+ if (rlm_sql_query(&handle, inst, expanded)) {
+ goto finish;
}
- numaffected = (inst->module->sql_affected_rows)(handle,
- inst->config);
+ numaffected = (inst->module->sql_affected_rows)(handle, inst->config);
if (numaffected < 1) {
- RDEBUG("rlm_sql (%s): SQL query affected no rows",
- inst->config->xlat_name);
+ RDEBUG("SQL query affected no rows");
+
+ goto finish;
}
/*
* if the output buffer was large enough.
*/
snprintf(buffer, sizeof(buffer), "%d", numaffected);
+
ret = strlen(buffer);
if (ret >= freespace){
- RDEBUG("rlm_sql (%s): Can't write result, insufficient string space",
- inst->config->xlat_name);
- (inst->module->sql_finish_query)(handle,
- inst->config);
- sql_release_socket(inst,handle);
- return 0;
+ RDEBUG("rlm_sql (%s): Can't write result, insufficient string space", inst->config->xlat_name);
+
+ (inst->module->sql_finish_query)(handle, inst->config);
+
+ ret = 0;
+ goto finish;
}
memcpy(out, buffer, ret + 1); /* we did bounds checking above */
(inst->module->sql_finish_query)(handle, inst->config);
- sql_release_socket(inst,handle);
- return ret;
+
+ goto finish;
} /* else it's a SELECT statement */
- if (rlm_sql_select_query(&handle,inst,querystr)){
- sql_release_socket(inst,handle);
- return 0;
+ if (rlm_sql_select_query(&handle, inst, expanded)){
+ goto finish;
}
ret = rlm_sql_fetch_row(&handle, inst);
if (ret) {
- RDEBUG("SQL query did not succeed");
+ RDEBUG("SQL query failed");
(inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst,handle);
- return 0;
+
+ goto finish;
}
row = handle->row;
if (!row) {
- RDEBUG("SQL query did not return any results");
+ RDEBUG("SQL query returned no results");
(inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst,handle);
- return 0;
+
+ goto finish;
}
if (!row[0]){
RDEBUG("Null value in first column");
(inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst,handle);
- return 0;
+
+ goto finish;
}
+
ret = strlen(row[0]);
if (ret >= freespace){
RDEBUG("Insufficient string space");
(inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst,handle);
- return 0;
+
+ ret = 0;
+ goto finish;
}
- strlcpy(out,row[0],freespace);
+ strlcpy(out, row[0], freespace);
RDEBUG("sql_xlat finished");
(inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst,handle);
+
+ finish:
+ talloc_free(expanded);
+ sql_release_socket(inst, handle);
+
return ret;
}
*/
int sql_set_user(rlm_sql_t *inst, REQUEST *request, const char *username)
{
- char buffer[254];
+ char *expanded = NULL;
VALUE_PAIR *vp = NULL;
const char *sqluser;
- size_t len;
+ ssize_t len;
if (username != NULL) {
sqluser = username;
return 0;
}
- len = radius_xlat(buffer, sizeof(buffer), sqluser, request, NULL, NULL);
- if (!len) {
+ len = radius_axlat(&expanded, request, sqluser, NULL, NULL);
+ if (len < 0) {
return -1;
}
vp = pairalloc(request->packet, inst->sql_user);
vp->op = T_OP_SET;
- strlcpy(vp->vp_strvalue, buffer, sizeof(vp->vp_strvalue));
+ strlcpy(vp->vp_strvalue, expanded, sizeof(vp->vp_strvalue));
+ talloc_free(expanded);
+
vp->length = strlen(vp->vp_strvalue);
pairadd(&request->packet->vps, vp);
}
-static int sql_get_grouplist(rlm_sql_t *inst, rlm_sql_handle_t *handle,
- REQUEST *request, rlm_sql_grouplist_t **phead)
+static int sql_get_grouplist(rlm_sql_t *inst, rlm_sql_handle_t *handle, REQUEST *request,
+ rlm_sql_grouplist_t **phead)
{
- char querystr[MAX_QUERY_LEN];
+ char *expanded = NULL;
int num_groups = 0;
rlm_sql_row_t row;
rlm_sql_grouplist_t *entry;
+ int ret;
/* NOTE: sql_set_user should have been run before calling this function */
entry = *phead = NULL;
- if (!inst->config->groupmemb_query ||
- (inst->config->groupmemb_query[0] == 0))
+ if (!inst->config->groupmemb_query || (inst->config->groupmemb_query[0] == 0)) {
return 0;
+ }
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->groupmemb_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request, "xlat \"%s\" failed.",
- inst->config->groupmemb_query);
+ if (!radius_axlat(&expanded, request, inst->config->groupmemb_query, sql_escape_func, inst) < 0) {
return -1;
}
- if (rlm_sql_select_query(&handle, inst, querystr) < 0) {
+ ret = rlm_sql_select_query(&handle, inst, expanded);
+ talloc_free(expanded);
+ if (ret < 0) {
return -1;
}
+
while (rlm_sql_fetch_row(&handle, inst) == 0) {
row = handle->row;
if (!row)
return 1;
}
-
-
-static int rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, int *dofallthrough)
+static rlm_rcode_t rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle,
+ int *dofallthrough)
{
- VALUE_PAIR *check_tmp = NULL;
- VALUE_PAIR *reply_tmp = NULL;
- rlm_sql_grouplist_t *head, *entry;
- VALUE_PAIR *sql_group = NULL;
- char querystr[MAX_QUERY_LEN];
- int found = 0;
- int rows;
+ rlm_rcode_t rcode = RLM_MODULE_NOOP;
+ VALUE_PAIR *check_tmp = NULL, *reply_tmp = NULL, *sql_group = NULL;
+ rlm_sql_grouplist_t *head = NULL, *entry = NULL;
+
+ char *expanded = NULL;
+ int rows;
/*
* Get the list of groups this user is a member of
*/
if (sql_get_grouplist(inst, handle, request, &head) < 0) {
radlog_request(L_ERR, 0, request, "Error retrieving group list");
- return -1;
+
+ return RLM_MODULE_FAIL;
}
for (entry = head; entry != NULL && *dofallthrough != 0; entry = entry->next) {
*/
sql_group = pairmake_packet("Sql-Group", entry->name, T_OP_EQ);
if (!sql_group) {
- radlog_request(L_ERR, 0, request,
- "Error creating Sql-Group attribute");
- talloc_free(head);
- return -1;
+ RDEBUGE("Error creating Sql-Group attribute");
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request,
- "Error generating query; rejecting user");
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- talloc_free(head);
- return -1;
+
+ /*
+ * Expand the group query
+ */
+ if (radius_axlat(&expanded, request, inst->config->authorize_group_check_query, sql_escape_func,
+ inst) < 0) {
+ RDEBUGE("Error generating query");
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
- rows = sql_getvpdata(inst, &handle, request, &check_tmp, querystr);
+
+ rows = sql_getvpdata(inst, &handle, request, &check_tmp, expanded);
+ TALLOC_FREE(expanded);
if (rows < 0) {
- radlog_request(L_ERR, 0, request, "Error retrieving check pairs for group %s",
- entry->name);
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- talloc_free(head);
- return -1;
- } else if (rows > 0) {
- /*
- * Only do this if *some* check pairs were returned
- */
- if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) {
- found = 1;
- RDEBUG2("User found in group %s",
- entry->name);
- /*
- * Now get the reply pairs since the paircompare matched
- */
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- talloc_free(head);
- return -1;
- }
- if (sql_getvpdata(inst, &handle, request->reply, &reply_tmp, querystr) < 0) {
- radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
- entry->name);
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- pairfree(&reply_tmp);
- talloc_free(head);
- return -1;
- }
- *dofallthrough = fallthrough(reply_tmp);
- radius_xlat_move(request, &request->reply->vps, &reply_tmp);
- radius_xlat_move(request, &request->config_items, &check_tmp);
- }
- } else {
- /*
- * rows == 0. This is like having the username on a line
- * in the user's file with no check vp's. As such, we treat
- * it as found and add the reply attributes, so that we
- * match expected behavior
- */
- found = 1;
- RDEBUG2("User found in group %s",
- entry->name);
- /*
- * Now get the reply pairs since the paircompare matched
- */
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- talloc_free(head);
- return -1;
- }
- if (sql_getvpdata(inst, &handle, request->reply, &reply_tmp, querystr) < 0) {
- radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
- entry->name);
- /* Remove the grouup we added above */
- pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- pairfree(&reply_tmp);
- talloc_free(head);
- return -1;
- }
- *dofallthrough = fallthrough(reply_tmp);
- radius_xlat_move(request, &request->reply->vps, &reply_tmp);
- radius_xlat_move(request, &request->config_items, &check_tmp);
+ RDEBUGE("Error retrieving check pairs for group %s", entry->name);
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
+
+ /*
+ * If we got check rows we need to process them before we decide to process the reply rows
+ */
+ if ((rows > 0) && (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) != 0)) {
+ pairfree(&check_tmp);
+ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
+ continue;
+ }
+
+ RDEBUG2("User found in= RLM_MODULE_OK; group %s", entry->name);
+
/*
- * Delete the Sql-Group we added above
- * And clear out the pairlists
+ * Now get the reply pairs since the paircompare matched
*/
+ if (radius_axlat(&expanded, request, inst->config->authorize_group_reply_query, sql_escape_func,
+ inst) < 0) {
+ RDEBUGE("Error generating query");
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+
+ if (sql_getvpdata(inst, &handle, request->reply, &reply_tmp, expanded) < 0) {
+ RDEBUGE("Error retrieving reply pairs for group %s", entry->name);
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+
+ *dofallthrough = fallthrough(reply_tmp);
+
pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
- pairfree(&check_tmp);
- pairfree(&reply_tmp);
+
+ radius_xlat_move(request, &request->reply->vps, &reply_tmp);
+ reply_tmp = NULL;
+
+ radius_xlat_move(request, &request->config_items, &check_tmp);
+ check_tmp = NULL;
}
-
+
+ finish:
+
+ talloc_free(expanded);
talloc_free(head);
- return found;
+
+ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
+ pairfree(&check_tmp);
+
+ return rcode;
}
static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
{
- int ret = RLM_MODULE_NOTFOUND;
+ int rcode = RLM_MODULE_NOTFOUND;
rlm_sql_t *inst = instance;
rlm_sql_handle_t *handle;
int dofallthrough = 1;
int rows;
- char querystr[MAX_QUERY_LEN];
+ char *expanded = NULL;
/*
* Set, escape, and check the user attr here
*/
- if (sql_set_user(inst, request, NULL) < 0)
+ if (sql_set_user(inst, request, NULL) < 0) {
return RLM_MODULE_FAIL;
+ }
/*
- * Reserve a socket
+ * Reserve a socket
*
- * After this point use goto error or goto release to cleanup sockets
- * temporary pairlists and temporary attributes.
+ * After this point use goto error or goto release to cleanup socket temporary pairlists and
+ * temporary attributes.
*/
handle = sql_get_socket(inst);
if (!handle)
goto error;
/*
- * Query the check table to find any conditions associated with
- * this user/realm/whatever...
+ * Query the check table to find any conditions associated with this user/realm/whatever...
*/
- if (inst->config->authorize_check_query &&
- *inst->config->authorize_check_query) {
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
+ if (inst->config->authorize_check_query && *inst->config->authorize_check_query) {
+ if (radius_axlat(&expanded, request, inst->config->authorize_check_query,
+ sql_escape_func, inst) < 0) {
+ RDEBUGE("Error generating query");
goto error;
}
- rows = sql_getvpdata(inst, &handle, request, &check_tmp, querystr);
+ rows = sql_getvpdata(inst, &handle, request, &check_tmp, expanded);
if (rows < 0) {
- radlog_request(L_ERR, 0, request, "SQL query error; rejecting user");
+ RDEBUGE("SQL query error");
goto error;
}
+ TALLOC_FREE(expanded);
/*
- * Only do this if *some* check pairs were returned
+ * Only do this if *some* check pairs were returned
*/
if ((rows > 0) &&
(paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0)) {
radius_xlat_move(request, &request->config_items, &check_tmp);
- ret = RLM_MODULE_OK;
+ rcode = RLM_MODULE_OK;
}
/*
- * We only process reply table items if check conditions
- * were verified
+ * We only process reply table items if check conditions were verified
*/
- else
+ else {
goto skipreply;
+ }
}
- if (inst->config->authorize_reply_query &&
- *inst->config->authorize_reply_query) {
+ if (inst->config->authorize_reply_query && *inst->config->authorize_reply_query) {
/*
- * Now get the reply pairs since the paircompare matched
+ * Now get the reply pairs since the paircompare matched
*/
- if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func, inst)) {
- radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
+ if (radius_axlat(&expanded, request, inst->config->authorize_reply_query,
+ sql_escape_func, inst) < 0) {
+ RDEBUGE("Error generating query");
goto error;
}
- rows = sql_getvpdata(inst, &handle, request->reply, &reply_tmp, querystr);
+ rows = sql_getvpdata(inst, &handle, request->reply, &reply_tmp, expanded);
if (rows < 0) {
- radlog_request(L_ERR, 0, request, "SQL query error; rejecting user");
+ RDEBUGE("SQL query error");
goto error;
}
+ TALLOC_FREE(expanded);
if (rows > 0) {
if (!inst->config->read_groups) {
radius_xlat_move(request, &request->reply->vps, &reply_tmp);
- ret = RLM_MODULE_OK;
+ rcode = RLM_MODULE_OK;
}
}
skipreply:
/*
- * Clear out the pairlists
+ * Clear out the pairlists
*/
pairfree(&check_tmp);
pairfree(&reply_tmp);
/*
- * dofallthrough is set to 1 by default so that if the user information
- * is not found, we will still process groups. If the user information,
- * however, *is* found, Fall-Through must be set in order to process
- * the groups as well.
+ * dofallthrough is set to 1 by default so that if the user information
+ * is not found, we will still process groups. If the user information,
+ * however, *is* found, Fall-Through must be set in order to process
+ * the groups as well.
*/
if (dofallthrough) {
- rows = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
- if (rows < 0) {
- radlog_request(L_ERR, 0, request, "Error processing groups; rejecting user");
+ rcode = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
+ if (rcode != RLM_MODULE_OK) {
+ RDEBUGE("Error processing groups");
- goto error;
+ goto release;
}
-
- if (rows > 0)
- ret = RLM_MODULE_OK;
}
/*
user_profile->vp_strvalue :
inst->config->default_profile;
- if (!profile || !*profile)
+ if (!profile || !*profile) {
goto release;
+ }
RDEBUG("Checking profile %s", profile);
if (sql_set_user(inst, request, profile) < 0) {
- radlog_request(L_ERR, 0, request, "Error setting profile; rejecting user");
+ RDEBUGE("Error setting profile");
goto error;
}
- rows = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
- if (rows < 0) {
- radlog_request(L_ERR, 0, request, "Error processing profile groups; rejecting user");
+ rcode = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
+ if (rcode != RLM_MODULE_OK) {
+ RDEBUGE("Error processing profile groups");
- goto error;
+ goto release;
}
-
- if (rows > 0)
- ret = RLM_MODULE_OK;
}
goto release;
error:
- ret = RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
release:
+ TALLOC_FREE(expanded);
+
sql_release_socket(inst, handle);
pairfree(&check_tmp);
pairfree(&reply_tmp);
- return ret;
+ return rcode;
}
/*
* doesn't update any rows, the next matching config item is used.
*
*/
-static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
- sql_acct_section_t *section)
+static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t *section)
{
- int ret = RLM_MODULE_OK;
+ rlm_rcode_t rcode = RLM_MODULE_OK;
rlm_sql_handle_t *handle = NULL;
- int sql_ret;
- int numaffected = 0;
+ int sql_ret;
+ int numaffected = 0;
- CONF_ITEM *item;
- CONF_PAIR *pair;
- const char *attr = NULL;
- const char *value;
+ CONF_ITEM *item;
+ CONF_PAIR *pair;
+ const char *attr = NULL;
+ const char *value;
- char path[MAX_STRING_LEN];
- char querystr[MAX_QUERY_LEN];
-
- char *p = path;
+ char path[MAX_STRING_LEN];
+ char *p = path;
+ char *expanded = NULL;
rad_assert(section);
- if (section->reference[0] != '.')
+ if (section->reference[0] != '.') {
*p++ = '.';
+ }
- if (!radius_xlat(p, (sizeof(path) - (p - path)) - 1,
- section->reference, request, NULL, NULL))
- return RLM_MODULE_FAIL;
+ if (radius_xlat(p, sizeof(path) - (p - path), request, section->reference, NULL, NULL) < 0) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
item = cf_reference_item(NULL, section->cs, path);
- if (!item)
- return RLM_MODULE_FAIL;
-
+ if (!item) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+
if (cf_item_is_section(item)){
- radlog(L_ERR, "Sections are not supported as references");
+ RDEBUGE("Sections are not supported as references");
+ rcode = RLM_MODULE_FAIL;
- return RLM_MODULE_FAIL;
+ goto finish;
}
pair = cf_itemtopair(item);
RDEBUG2("Using query template '%s'", attr);
handle = sql_get_socket(inst);
- if (!handle)
- return RLM_MODULE_FAIL;
+ if (!handle) {
+ rcode = RLM_MODULE_FAIL;
+ goto finish;
+ }
+
sql_set_user(inst, request, NULL);
while (TRUE) {
value = cf_pair_value(pair);
if (!value) {
RDEBUG("Ignoring null query");
- ret = RLM_MODULE_NOOP;
+ rcode = RLM_MODULE_NOOP;
- goto release;
+ goto finish;
+ }
+
+ if (radius_axlat(&expanded, request, value, sql_escape_func, inst) < 0) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
- radius_xlat(querystr, sizeof(querystr), value, request,
- sql_escape_func, inst);
- if (!*querystr) {
+ if (!*expanded) {
RDEBUG("Ignoring null query");
- ret = RLM_MODULE_NOOP;
+ rcode = RLM_MODULE_NOOP;
+ talloc_free(expanded);
- goto release;
+ goto finish;
}
- rlm_sql_query_log(inst, request, section, querystr);
+ rlm_sql_query_log(inst, request, section, expanded);
/*
* If rlm_sql_query cannot use the socket it'll try and
* were exhausted, and we couldn't create a new connection,
* so we do not need to call sql_release_socket.
*/
- sql_ret = rlm_sql_query(&handle, inst, querystr);
- if (sql_ret == SQL_DOWN)
- return RLM_MODULE_FAIL;
+ sql_ret = rlm_sql_query(&handle, inst, expanded);
+ TALLOC_FREE(expanded);
+ if (sql_ret == SQL_DOWN) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
rad_assert(handle);
/*
* operation failed and its not a client or SQL syntax error.
*/
if (sql_ret == 0) {
- numaffected = (inst->module->sql_affected_rows)
- (handle, inst->config);
- if (numaffected > 0)
+ numaffected = (inst->module->sql_affected_rows)(handle, inst->config);
+ if (numaffected > 0) {
break;
+ }
RDEBUG("No records updated");
}
if (!pair) {
RDEBUG("No additional queries configured");
- ret = RLM_MODULE_NOOP;
+ rcode = RLM_MODULE_NOOP;
- goto release;
+ goto finish;
}
RDEBUG("Trying next query...");
(inst->module->sql_finish_query)(handle, inst->config);
- release:
+ finish:
+ talloc_free(path);
+ talloc_free(expanded);
sql_release_socket(inst, handle);
- return ret;
+ return rcode;
}
#ifdef WITH_ACCOUNTING
*/
static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request) {
- rlm_sql_handle_t *handle;
- rlm_sql_t *inst = instance;
+ rlm_rcode_t rcode = RLM_MODULE_OK;
+ rlm_sql_handle_t *handle = NULL;
+ rlm_sql_t *inst = instance;
rlm_sql_row_t row;
- char querystr[MAX_QUERY_LEN];
- int check = 0;
- uint32_t ipno = 0;
- char *call_num = NULL;
- VALUE_PAIR *vp;
- int ret;
- uint32_t nas_addr = 0;
- int nas_port = 0;
+ int check = 0;
+ uint32_t ipno = 0;
+ char *call_num = NULL;
+ VALUE_PAIR *vp;
+ int ret;
+ uint32_t nas_addr = 0;
+ int nas_port = 0;
+
+ char *expanded = NULL;
/* If simul_count_query is not defined, we don't do any checking */
- if (!inst->config->simul_count_query ||
- (inst->config->simul_count_query[0] == 0)) {
+ if (!inst->config->simul_count_query || (inst->config->simul_count_query[0] == '\0')) {
return RLM_MODULE_NOOP;
}
- if((!request->username) || (request->username->length == 0)) {
- radlog_request(L_ERR, 0, request,
- "Zero Length username not permitted\n");
+ if((!request->username) || (request->username->length == '\0')) {
+ RDEBUGE("Zero Length username not permitted");
+
return RLM_MODULE_INVALID;
}
- if(sql_set_user(inst, request, NULL) < 0)
+ if(sql_set_user(inst, request, NULL) < 0) {
return RLM_MODULE_FAIL;
+ }
- radius_xlat(querystr, sizeof(querystr), inst->config->simul_count_query, request, sql_escape_func, inst);
+ if (radius_axlat(&expanded, request, inst->config->simul_count_query, sql_escape_func, inst) < 0) {
+ return RLM_MODULE_FAIL;
+ }
/* initialize the sql socket */
handle = sql_get_socket(inst);
- if(!handle)
- return RLM_MODULE_FAIL;
-
- if(rlm_sql_select_query(&handle, inst, querystr)) {
- sql_release_socket(inst, handle);
+ if (!handle) {
+ talloc_free(expanded);
return RLM_MODULE_FAIL;
}
+
+ if (rlm_sql_select_query(&handle, inst, expanded)) {
+ rcode = RLM_MODULE_FAIL;
+ goto finish;
+ }
ret = rlm_sql_fetch_row(&handle, inst);
if (ret != 0) {
- (inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst, handle);
- return RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
+ goto finish;
}
row = handle->row;
if (!row) {
- (inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst, handle);
- return RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
+ goto finish;
}
request->simul_count = atoi(row[0]);
+
(inst->module->sql_finish_select_query)(handle, inst->config);
+ TALLOC_FREE(expanded);
if(request->simul_count < request->simul_max) {
- sql_release_socket(inst, handle);
- return RLM_MODULE_OK;
+ rcode = RLM_MODULE_OK;
+ goto finish;
}
/*
* Looks like too many sessions, so let's start verifying
* them, unless told to rely on count query only.
*/
- if (!inst->config->simul_verify_query ||
- (inst->config->simul_verify_query[0] == '\0')) {
- sql_release_socket(inst, handle);
- return RLM_MODULE_OK;
+ if (!inst->config->simul_verify_query || (inst->config->simul_verify_query[0] == '\0')) {
+ rcode = RLM_MODULE_OK;
+
+ goto finish;
}
- radius_xlat(querystr, sizeof(querystr), inst->config->simul_verify_query, request, sql_escape_func, inst);
- if(rlm_sql_select_query(&handle, inst, querystr)) {
- sql_release_socket(inst, handle);
- return RLM_MODULE_FAIL;
+ if (radius_axlat(&expanded, request, inst->config->simul_verify_query, sql_escape_func, inst) < 0) {
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
+ }
+
+ if(rlm_sql_select_query(&handle, inst, expanded)) {
+ goto finish;
}
/*
*/
request->simul_count = 0;
- if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL)
+ if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL) {
ipno = vp->vp_ipaddr;
- if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL)
+ }
+
+ if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL) {
call_num = vp->vp_strvalue;
-
+ }
while (rlm_sql_fetch_row(&handle, inst) == 0) {
row = handle->row;
- if (!row)
+ if (!row) {
break;
+ }
+
if (!row[2]){
- (inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst, handle);
RDEBUG("Cannot zap stale entry. No username present in entry.", inst->config->xlat_name);
- return RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
+
if (!row[1]){
- (inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst, handle);
RDEBUG("Cannot zap stale entry. No session id in entry.", inst->config->xlat_name);
- return RLM_MODULE_FAIL;
+ rcode = RLM_MODULE_FAIL;
+
+ goto finish;
}
- if (row[3])
+
+ if (row[3]) {
nas_addr = inet_addr(row[3]);
- if (row[4])
+ }
+
+ if (row[4]) {
nas_port = atoi(row[4]);
-
+ }
+
check = rad_check_ts(nas_addr, nas_port, row[2], row[1]);
-
if (check == 0) {
/*
* Stale record - zap it.
/*
* Does it look like a MPP attempt?
*/
- if (row[5] && ipno && inet_addr(row[5]) == ipno)
+ if (row[5] && ipno && inet_addr(row[5]) == ipno) {
request->simul_mpp = 2;
- else if (row[6] && call_num &&
- !strncmp(row[6],call_num,16))
+ } else if (row[6] && call_num && !strncmp(row[6],call_num,16)) {
request->simul_mpp = 2;
- }
- else {
+ }
+ } else {
/*
* Failed to check the terminal server for
* duplicate logins: return an error.
*/
- (inst->module->sql_finish_select_query)(handle, inst->config);
- sql_release_socket(inst, handle);
radlog_request(L_ERR, 0, request, "Failed to check the terminal server for user '%s'.", row[2]);
- return RLM_MODULE_FAIL;
+
+ rcode = RLM_MODULE_FAIL;
+ goto finish;
}
}
+ finish:
+
(inst->module->sql_finish_select_query)(handle, inst->config);
sql_release_socket(inst, handle);
+ talloc_free(expanded);
/*
* The Auth module apparently looks at request->simul_count,
* not the return value of this module when deciding to deny
* a call for too many sessions.
*/
- return RLM_MODULE_OK;
+ return rcode;
}
#endif
{
int fd;
const char *filename = NULL;
- char buffer[8192];
+ char *expanded = NULL;
- if (section) filename = section->logfile;
-
- if (!filename) filename = inst->config->logfile;
-
- if (!filename) return;
-
- if (!radius_xlat(buffer, sizeof(buffer), filename, request, NULL, NULL)) {
- radlog(L_ERR, "rlm_sql (%s): xlat failed.",
- inst->config->xlat_name);
+ if (section) {
+ filename = section->logfile;
+ }
+
+ if (!filename) {
+ filename = inst->config->logfile;
+
+ if (!filename) {
+ return;
+ }
+ }
+
+ if (radius_axlat(&expanded, request, filename, NULL, NULL) < 0) {
return;
}
fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0666);
if (fd < 0) {
- radlog(L_ERR, "rlm_sql (%s): Couldn't open logfile '%s': %s",
- inst->config->xlat_name, buffer, strerror(errno));
+ radlog(L_ERR, "rlm_sql (%s): Couldn't open logfile '%s': %s", inst->config->xlat_name,
+ expanded, strerror(errno));
+
+ talloc_free(expanded);
return;
}
- if ((rad_lockfd(fd, MAX_QUERY_LEN) < 0) ||
- (write(fd, query, strlen(query)) < 0) ||
- (write(fd, ";\n", 2) < 0)) {
- radlog(L_ERR, "rlm_sql (%s): Failed writing to logfile '%s': %s",
- inst->config->xlat_name, buffer, strerror(errno));
+ if ((rad_lockfd(fd, MAX_QUERY_LEN) < 0) || (write(fd, query, strlen(query)) < 0) || (write(fd, ";\n", 2) < 0)) {
+ radlog(L_ERR, "rlm_sql (%s): Failed writing to logfile '%s': %s", inst->config->xlat_name, expanded,
+ strerror(errno));
}
+
+ talloc_free(expanded);
close(fd); /* and release the lock */
}
*
*/
-static int sqlcounter_expand(char *out, int outlen, const char *fmt, rlm_sqlcounter_t *inst)
+static size_t sqlcounter_expand(char *out, int outlen, const char *fmt, rlm_sqlcounter_t *inst)
{
int c,freespace;
const char *p;
/* Calculate freespace in output */
freespace = outlen - (q - out);
if (freespace <= 1)
- break;
+ return -1;
c = *p;
if ((c != '%') && (c != '\\')) {
*q++ = *p;
/*
* See if the counter matches.
*/
-static int sqlcounter_cmp(void *instance, REQUEST *req,
- UNUSED VALUE_PAIR *request, VALUE_PAIR *check,
+static int sqlcounter_cmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *req , VALUE_PAIR *check,
UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
{
rlm_sqlcounter_t *inst = instance;
int counter;
- char querystr[MAX_QUERY_LEN];
- char sqlxlat[MAX_QUERY_LEN];
- /* first, expand %k, %b and %e in query */
- sqlcounter_expand(querystr, MAX_QUERY_LEN, inst->query, inst);
+ char *p;
+ char query[MAX_QUERY_LEN];
+ char *expanded = NULL;
+
+ size_t len;
- /* third, wrap query with sql module call & expand */
- snprintf(sqlxlat, sizeof(sqlxlat), "%%{%s:%s}", inst->sqlmod_inst, querystr);
+ len = snprintf(query, sizeof(query), "%%{%s:", inst->sqlmod_inst, query);
+ if (len >= sizeof(query) - 1) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p = query + len;
+
+ /* first, expand %k, %b and %e in query */
+ len = sqlcounter_expand(p, p - query, inst->query, inst);
+ if (len <= 0) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p += len;
+
+ if ((p - query) < 2) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p[0] = '}';
+ p[1] = '\0';
/* Finally, xlat resulting SQL query */
- radius_xlat(querystr, MAX_QUERY_LEN, sqlxlat, req, NULL, NULL);
+ if (radius_axlat(&expanded, request, query, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
- counter = atoi(querystr);
+ counter = atoi(expanded);
+ talloc_free(expanded);
return counter - check->vp_integer;
}
VALUE_PAIR *key_vp, *check_vp;
VALUE_PAIR *reply_item;
char msg[128];
- char querystr[MAX_QUERY_LEN];
- char sqlxlat[MAX_QUERY_LEN];
+
+ char *p;
+ char query[MAX_QUERY_LEN];
+ char *expanded = NULL;
+
+ size_t len;
/*
* Before doing anything else, see if we have to reset
* the counters.
*/
if (inst->reset_time && (inst->reset_time <= request->timestamp)) {
-
/*
* Re-set the next time and prev_time for this counters range
*/
find_next_reset(inst,request->timestamp);
}
-
/*
* Look for the key. User-Name is special. It means
* The REAL username, after stripping.
*/
- DEBUG2("rlm_sqlcounter: Entering module authorize code");
- key_vp = ((inst->key_attr->vendor == 0) && (inst->key_attr->attr == PW_USER_NAME)) ? request->username : pairfind(request->packet->vps, inst->key_attr->attr, inst->key_attr->vendor, TAG_ANY);
+ RDEBUG2("Entering module authorize code");
+ key_vp = ((inst->key_attr->vendor == 0) && (inst->key_attr->attr == PW_USER_NAME)) ?
+ request->username :
+ pairfind(request->packet->vps, inst->key_attr->attr, inst->key_attr->vendor, TAG_ANY);
if (!key_vp) {
- DEBUG2("rlm_sqlcounter: Could not find Key value pair");
+ RDEBUG2("Could not find Key value pair");
return rcode;
}
return rcode;
}
/* DEBUG2("rlm_sqlcounter: Found Check item attribute %d", dattr->attr); */
- if ((check_vp= pairfind(request->config_items, dattr->attr, dattr->vendor, TAG_ANY)) == NULL) {
- DEBUG2("rlm_sqlcounter: Could not find Check item value pair");
+ if ((check_vp = pairfind(request->config_items, dattr->attr, dattr->vendor, TAG_ANY)) == NULL) {
+ RDEBUG2("Could not find Check item value pair");
return rcode;
}
+ len = snprintf(query, sizeof(query), "%%{%s:", inst->sqlmod_inst, query);
+ if (len >= sizeof(query) - 1) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p = query + len;
+
/* first, expand %k, %b and %e in query */
- sqlcounter_expand(querystr, MAX_QUERY_LEN, inst->query, inst);
-
- /* next, wrap query with sql module & expand */
- snprintf(sqlxlat, sizeof(sqlxlat), "%%{%s:%s}", inst->sqlmod_inst, querystr);
+ len = sqlcounter_expand(p, p - query, inst->query, inst);
+ if (len <= 0) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p += len;
+
+ if ((p - query) < 2) {
+ RDEBUGE("Insufficient query buffer space");
+
+ return RLM_MODULE_FAIL;
+ }
+
+ p[0] = '}';
+ p[1] = '\0';
/* Finally, xlat resulting SQL query */
- radius_xlat(querystr, MAX_QUERY_LEN, sqlxlat, request, NULL, NULL);
+ if (radius_axlat(&expanded, request, query, NULL, NULL) < 0) {
+ return RLM_MODULE_FAIL;
+ }
- if (sscanf(querystr, "%u", &counter) != 1) {
- DEBUG2("rlm_sqlcounter: No integer found in string \"%s\"",
- querystr);
+ if (sscanf(expanded, "%u", &counter) != 1) {
+ RDEBUG2("No integer found in string \"%s\"", expanded);
return RLM_MODULE_NOOP;
}
+ talloc_free(expanded);
+
/*
* Check if check item > counter
*/
if (check_vp->vp_integer > counter) {
unsigned int res = check_vp->vp_integer - counter;
- DEBUG2("rlm_sqlcounter: Check item is greater than query result");
+ RDEBUG2("Check item is greater than query result");
/*
* We are assuming that simultaneous-use=1. But
* even if that does not happen then our user
* limit, so that the user will not need to login
* again. Do this only for Session-Timeout.
*/
- if ((inst->reply_attr->attr == PW_SESSION_TIMEOUT) &&
- inst->reset_time &&
+ if ((inst->reply_attr->attr == PW_SESSION_TIMEOUT) && inst->reset_time &&
(res >= (inst->reset_time - request->timestamp))) {
res = inst->reset_time - request->timestamp;
res += check_vp->vp_integer;
*/
reply_item = pairfind(request->reply->vps, inst->reply_attr->attr, inst->reply_attr->vendor, TAG_ANY);
if (reply_item) {
- if (reply_item->vp_integer > res)
+ if (reply_item->vp_integer > res) {
reply_item->vp_integer = res;
-
+ }
} else {
- reply_item = radius_paircreate(request,
- &request->reply->vps,
- inst->reply_attr->attr,
+ reply_item = radius_paircreate(request, &request->reply->vps, inst->reply_attr->attr,
inst->reply_attr->vendor);
reply_item->vp_integer = res;
}
rcode = RLM_MODULE_OK;
- DEBUG2("rlm_sqlcounter: Authorized user %s, check_item=%u, counter=%u",
- key_vp->vp_strvalue,check_vp->vp_integer,counter);
- DEBUG2("rlm_sqlcounter: Sent Reply-Item for user %s, Type=%s, value=%u",
- key_vp->vp_strvalue,inst->reply_name,reply_item->vp_integer);
+ RDEBUG2("Authorized user %s, check_item=%u, counter=%u", key_vp->vp_strvalue, check_vp->vp_integer,
+ counter);
+ RDEBUG2("Sent Reply-Item for user %s, Type=%s, value=%u", key_vp->vp_strvalue, inst->reply_name,
+ reply_item->vp_integer);
}
else{
- DEBUG2("rlm_sqlcounter: (Check item - counter) is less than zero");
+ RDEBUG2("(Check item - counter) is less than zero");
/*
* User is denied access, send back a reply message
inst->reset);
rcode = RLM_MODULE_REJECT;
- DEBUG2("rlm_sqlcounter: Rejected user %s, check_item=%u, counter=%u",
- key_vp->vp_strvalue,check_vp->vp_integer,counter);
+ RDEBUG2("Rejected user %s, check_item=%u, counter=%u", key_vp->vp_strvalue,
+ check_vp->vp_integer,counter);
}
return rcode;
/*
* Query the database executing a command with no result rows
*/
-static int sqlippool_command(const char * fmt, rlm_sql_handle_t * handle,
- rlm_sqlippool_t *data, REQUEST * request,
+static int sqlippool_command(const char * fmt, rlm_sql_handle_t * handle, rlm_sqlippool_t *data, REQUEST * request,
char * param, int param_len)
{
- char expansion[MAX_QUERY_LEN];
char query[MAX_QUERY_LEN];
+ char *expanded = NULL;
+
+ int ret;
/*
* If we don't have a command, do nothing.
*/
if (!*fmt) return 0;
- sqlippool_expand(expansion, sizeof(expansion),
- fmt, data, param, param_len);
+ /*
+ * @todo this needs to die (should just be done in xlat expansion)
+ */
+ sqlippool_expand(query, sizeof(query), fmt, data, param, param_len);
- if (!radius_xlat(query, sizeof(query), expansion, request, data->sql_inst->sql_escape_func, data->sql_inst)) {
- RDEBUGE("xlat failed on: '%s'", query);
+ if (radius_axlat(&expanded, request, query, data->sql_inst->sql_escape_func, data->sql_inst) < 0) {
return 0;
}
- if (data->sql_inst->sql_query(&handle, data->sql_inst, query)){
- RDEBUGE("database query error in: '%s'", query);
+ ret = data->sql_inst->sql_query(&handle, data->sql_inst, expanded);
+ if (!ret){
+ RDEBUGE("database query error in: '%s'", expanded);
+ talloc_free(expanded);
+
return 0;
}
+ talloc_free(expanded);
- (data->sql_inst->module->sql_finish_query)(handle,
- data->sql_inst->config);
+ (data->sql_inst->module->sql_finish_query)(handle, data->sql_inst->config);
return 0;
}
rlm_sql_handle_t *handle, rlm_sqlippool_t *data,
REQUEST *request, char *param, int param_len)
{
- char expansion[MAX_QUERY_LEN];
char query[MAX_QUERY_LEN];
- int rlen, retval = 0;
+ char *expanded = NULL;
+
+ int rlen, retval;
- sqlippool_expand(expansion, sizeof(expansion),
- fmt, data, param, param_len);
+ /*
+ * @todo this needs to die (should just be done in xlat expansion)
+ */
+ sqlippool_expand(query, sizeof(query), fmt, data, param, param_len);
rad_assert(request != NULL);
+ *out = '\0';
+
/*
- *Do an xlat on the provided string
+ * Do an xlat on the provided string
*/
- if (!radius_xlat(query, sizeof(query), expansion, request, data->sql_inst->sql_escape_func, data->sql_inst)) {
- DEBUGE("xlat failed on '%s'", expansion);
- out[0] = '\0';
- return 0;
+ if (radius_axlat(&expanded, request, query, data->sql_inst->sql_escape_func, data->sql_inst) < 0) {
+ return 0;
}
-
- if (data->sql_inst->sql_select_query(&handle, data->sql_inst, query)){
+ retval = data->sql_inst->sql_select_query(&handle, data->sql_inst, expanded);
+ talloc_free(expanded);
+
+ if (retval != 0){
RDEBUGE("database query error on '%s'", query);
- out[0] = '\0';
+
return 0;
}
- out[0] = '\0';
-
if (!data->sql_inst->sql_fetch_row(&handle, data->sql_inst)) {
if (handle->row) {
if (handle->row[0]) {
RDEBUG("SQL query did not succeed");
}
- (data->sql_inst->module->sql_finish_select_query)(handle,
- data->sql_inst->config);
+ (data->sql_inst->module->sql_finish_select_query)(handle, data->sql_inst->config);
+
return retval;
}
/*
- *if we have something to log, then we log it
- *otherwise we return the retcode as soon as possible
+ * If we have something to log, then we log it.
+ * Otherwise we return the retcode as soon as possible
*/
static int do_logging(REQUEST *request, char *str, int rcode)
{
- char buffer[1024];
-
+ char *expanded = NULL;
+
if (!str || !*str) return rcode;
- radius_xlat(buffer, sizeof(buffer), str, request, NULL, NULL);
- if (!*buffer) return rcode;
+ if (radius_axlat(&expanded, request, str, NULL, NULL) < 0) {
+ return rcode;
+ }
- pairmake_config("Module-Success-Message", buffer, T_OP_SET);
+ pairmake_config("Module-Success-Message", expanded, T_OP_SET);
+
+ talloc_free(expanded);
return rcode;
}
};
static const char *modhextab = "cbdefghijklnrtuv";
+static const char *hextab = "0123456789abcdef";
#define is_modhex(x) (memchr(modhextab, tolower(x), 16))
-/** Convert yubikey modhex data to binary
+/** Convert yubikey modhex to normal hex
*
- * This is a simpler version of the yubikey function which also does input
- * checking.
+ * The same buffer may be passed as modhex and hex to convert the modhex in place.
*
- * @param[in] hex modhex data.
- * @param[out] bin where to write the decoded data.
- * @param[in] len The size of the output buffer.
+ * Modhex and hex must be the same size.
+ *
+ * @param[in] modhex data.
+ * @param[out] hex where to write the standard hexits.
* @return The number of bytes written to the output buffer, or -1 on error.
*/
-static size_t modhex2bin(const char *hex, uint8_t *bin, size_t len)
+static ssize_t modhex2hex(const char *modhex, uint8_t *hex, size_t len)
{
size_t i;
char *c1, *c2;
for (i = 0; i < len; i++) {
- if (hex[i << 1] == '\0') {
+ if (modhex[i << 1] == '\0') {
break;
}
/*
* We only deal with whole bytes
*/
- if (hex[(i << 1) + 1] == '\0')
+ if (modhex[(i << 1) + 1] == '\0')
return -1;
- if (!(c1 = memchr(modhextab, tolower((int) hex[i << 1]), 16)) ||
- !(c2 = memchr(modhextab, tolower((int) hex[(i << 1) + 1]), 16)))
+ if (!(c1 = memchr(modhextab, tolower((int) modhex[i << 1]), 16)) ||
+ !(c2 = memchr(modhextab, tolower((int) modhex[(i << 1) + 1]), 16)))
return -1;
- bin[i] = ((c1 - modhextab) <<4) + (c2 - modhextab);
+
+ hex[i] = hextab[c1 - modhextab];
+ hex[i + 1] = hextab[c2 - modhextab];
}
return i;
*/
static size_t modhex_to_hex_xlat(UNUSED void *instance, REQUEST *request, const char *fmt, char *out, size_t outlen)
{
- char buffer[1024];
- uint8_t decbuf[1024], *p;
-
- ssize_t declen;
- size_t freespace = outlen;
- size_t len;
+ ssize_t len;
- len = radius_xlat(buffer, sizeof(buffer), fmt, request, NULL, NULL);
- if (!len) {
- RDEBUGE("expansion of format string failed.");
- *out = '\0';
- return 0;
+ char *expanded = NULL;
+ len = radius_axlat(&expanded, request, fmt, NULL, NULL);
+ if (len < 0) {
+ return len;
}
- declen = modhex2bin(buffer, decbuf, sizeof(decbuf));
- if (declen < 0) {
- RDEBUGE("modhex string invalid");
+ /*
+ * mod2hex allows conversions in place
+ */
+ len = modhex2hex(expanded, (uint8_t *) expanded, strlen(expanded));
+ if (len <= 0) {
+ talloc_free(expanded);
*out = '\0';
- return 0;
- }
-
- p = decbuf;
- while ((declen-- > 0) && (--freespace > 0)) {
- if (freespace < 3) {
- break;
- }
- snprintf(out, 3, "%02x", *p++);
+ RDEBUGE("Modhex string invalid");
- /* Already decremented */
- freespace -= 1;
- out += 2;
+ return len;
}
-
- return outlen - freespace;
+
+ strlcpy(out, expanded, outlen);
+
+ return len;
}
/*