Start of dynamically allocated xlat expansions
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 4 Apr 2013 20:33:25 +0000 (16:33 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 4 Apr 2013 20:36:21 +0000 (16:36 -0400)
42 files changed:
src/include/radiusd.h
src/main/auth.c
src/main/evaluate.c
src/main/log.c
src/main/mainconfig.c
src/main/modcall.c
src/main/radconf2xml.c
src/main/radmin.c
src/main/radwho.c
src/main/tls.c
src/main/util.c
src/main/valuepair.c
src/main/xlat.c
src/modules/rlm_attr_filter/rlm_attr_filter.c
src/modules/rlm_attr_rewrite/rlm_attr_rewrite.c
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_detail/rlm_detail.c
src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c
src/modules/rlm_eap/types/rlm_eap_tnc/rlm_eap_tnc.c
src/modules/rlm_expiration/rlm_expiration.c
src/modules/rlm_expr/paircmp.c
src/modules/rlm_expr/rlm_expr.c
src/modules/rlm_files/rlm_files.c
src/modules/rlm_ippool/rlm_ippool.c
src/modules/rlm_ldap/attrmap.c
src/modules/rlm_ldap/groups.c
src/modules/rlm_ldap/ldap.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_linelog/rlm_linelog.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_otp/rlm_otp.c
src/modules/rlm_pap/rlm_pap.c
src/modules/rlm_perl/rlm_perl.c
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_rest/rest.c
src/modules/rlm_rest/rest.h
src/modules/rlm_rest/rlm_rest.c
src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sql/sql.c
src/modules/rlm_sqlcounter/rlm_sqlcounter.c
src/modules/rlm_sqlippool/rlm_sqlippool.c
src/modules/rlm_yubikey/rlm_yubikey.c

index 53220a3..b09a9fa 100644 (file)
@@ -745,8 +745,12 @@ void module_failure_msg(REQUEST *request, const char *fmt, ...);
 /* 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);
index 7aa0123..b7effd4 100644 (file)
@@ -75,6 +75,7 @@ static int rad_authlog(const char *msg, REQUEST *request, int goodpass)
        char clean_username[1024];
        char buf[1024];
        char extra[1024];
+       char *p;
        VALUE_PAIR *username = NULL;
 
        if (!request->root->log_auth) {
@@ -136,8 +137,8 @@ static int rad_authlog(const char *msg, REQUEST *request, int goodpass)
 
        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';
        }
index bffc722..c2a8870 100644 (file)
@@ -100,7 +100,7 @@ static const char *expand_string(char *buffer, size_t sizeof_buffer,
        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;
        }
 
index 932b183..7be8353 100644 (file)
@@ -317,8 +317,7 @@ void radlog_request(int lvl, int priority, REQUEST *request, const char *msg, ..
                 *      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);
index 955dc19..3508e6f 100644 (file)
@@ -360,7 +360,7 @@ static size_t xlat_config(UNUSED void *instance, UNUSED REQUEST *request, const
        /*
         *      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;
        }
 
index 7fee1ee..8c866d1 100644 (file)
@@ -622,8 +622,7 @@ int modcall(int component, modcallable *c, REQUEST *request)
                        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,
@@ -715,18 +714,14 @@ int modcall(int component, modcallable *c, REQUEST *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) {
@@ -755,10 +750,8 @@ int modcall(int component, modcallable *c, REQUEST *request)
 
                        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.
index f8a7016..ad47177 100644 (file)
@@ -45,9 +45,8 @@ int debug_flag = 0;
 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;
 }
index ed07456..ddf4841 100644 (file)
@@ -93,9 +93,8 @@ int debug_flag = 0;
 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;
 }
index 5e2cade..056c4b2 100644 (file)
@@ -67,9 +67,8 @@ int log_stripped_names;
 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;
index 83b1e3a..f7c7965 100644 (file)
@@ -1683,9 +1683,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
                 *      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 {
index c07d526..b271959 100644 (file)
@@ -861,7 +861,7 @@ int rad_expand_xlat(REQUEST *request, const char *cmd,
 
                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) {
                                /*
index 0a7bbaf..a026b16 100644 (file)
@@ -670,7 +670,7 @@ int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check,
  */
 int radius_xlat_do(REQUEST *request, VALUE_PAIR *vp)
 {
-       size_t len;
+       ssize_t len;
        
        char buffer[1024];
        
@@ -678,12 +678,12 @@ int radius_xlat_do(REQUEST *request, VALUE_PAIR *vp)
        
        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;
        }
        
index 49a6162..ac612ae 100644 (file)
@@ -664,7 +664,7 @@ static size_t xlat_xlat(UNUSED void *instance, REQUEST *request,
 
        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
@@ -939,9 +939,8 @@ void xlat_free(void)
  * @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;
@@ -1042,7 +1041,11 @@ static int decode_attribute(const char **from, char **to, int freespace,
                 *      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;
@@ -1053,8 +1056,11 @@ static int decode_attribute(const char **from, char **to, int freespace,
                 *      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;
                        }
@@ -1148,11 +1154,14 @@ do_xlat:
                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);
@@ -1176,7 +1185,10 @@ do_xlat:
                 *      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;
 
@@ -1189,36 +1201,52 @@ done:
  *
  * 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;
@@ -1264,7 +1292,11 @@ size_t radius_xlat(char *out, int outlen, const char *fmt,
                } 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 '%':
@@ -1394,12 +1426,29 @@ size_t radius_xlat(char *out, int outlen, const char *fmt,
                                        *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);
 }
index 4f5a769..744ca5a 100644 (file)
@@ -173,9 +173,11 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
        } 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;
index 3d7ef68..4614d6b 100644 (file)
@@ -171,8 +171,7 @@ static rlm_rcode_t do_attr_rewrite(void *instance, REQUEST *request)
 
        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;
                }
 
@@ -271,7 +270,8 @@ do_again:
                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;
                }
@@ -364,8 +364,7 @@ do_again:
 
                        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;
index c251dae..d6edcc0 100644 (file)
@@ -459,8 +459,7 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
                 *      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;               
                        }
 
@@ -610,7 +609,9 @@ static size_t cache_xlat(void *instance, REQUEST *request,
        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);
        
@@ -792,9 +793,11 @@ static rlm_rcode_t cache_it(void *instance, REQUEST *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);
index 8109b4d..b1dc4de 100644 (file)
@@ -197,9 +197,7 @@ static rlm_rcode_t do_detail(void *instance, REQUEST *request, RADIUS_PACKET *pa
         *      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);
@@ -342,9 +340,7 @@ static rlm_rcode_t do_detail(void *instance, REQUEST *request, RADIUS_PACKET *pa
                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;
        }
index 24244cc..1c7a04b 100644 (file)
@@ -92,8 +92,7 @@ static int gtc_initiate(void *instance, eap_handler_t *handler)
        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;
        }
 
index d7573ee..632d1db 100644 (file)
@@ -144,7 +144,7 @@ static int tnc_initiate(void *instance, eap_handler_t *handler)
        REQUEST *request = NULL;
        
        char buff[71];
-       size_t len = 0;
+       ssize_t len = 0;
        
        TNC_Result result;
        TNC_ConnectionID conn_id;
@@ -171,11 +171,8 @@ static int tnc_initiate(void *instance, eap_handler_t *handler)
        /*
         *      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;
        }
 
index 606b962..0333caa 100644 (file)
@@ -63,7 +63,8 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
        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?
                *
@@ -76,8 +77,7 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
                        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;
                                }
 
@@ -85,7 +85,7 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
                                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;
                }
                /*
@@ -94,17 +94,15 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
                 */
                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;
 }
 
index 5e4614b..37c2a20 100644 (file)
@@ -99,8 +99,10 @@ static int portcmp(UNUSED void *instance, REQUEST *req UNUSED, VALUE_PAIR *reque
  */
 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;
@@ -108,13 +110,14 @@ static int presufcmp(UNUSED void *instance,
        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);
@@ -135,9 +138,10 @@ static int presufcmp(UNUSED void *instance,
                        }
                        break;
        }
-       if (ret != 0)
+       if (ret != 0) {
                return ret;
-
+       }
+       
        /*
         *      If Strip-User-Name == No, then don't do any more.
         */
@@ -168,13 +172,14 @@ static int presufcmp(UNUSED void *instance,
 /*
  *     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;
        }
 
@@ -184,14 +189,14 @@ static int packetcmp(void *instance UNUSED, REQUEST *req,
 /*
  *     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;
        }
 
@@ -201,12 +206,12 @@ static int responsecmp(void *instance UNUSED,
 /*
  *     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)) {
@@ -217,7 +222,9 @@ static int genericcmp(void *instance UNUSED,
 
                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);
 
                /*
@@ -252,7 +259,7 @@ static int genericcmp(void *instance UNUSED,
        /*
         *      Will do the xlat for us
         */
-       return radius_compare_vps(req, check, NULL);
+       return radius_compare_vps(request, check, NULL);
 }
 
 static int generic_attrs[] = {
index 25640ce..21e9bc9 100644 (file)
@@ -255,8 +255,7 @@ static size_t expr_xlat(UNUSED void *instance, REQUEST *request, const char *fmt
        /*
         * 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;
        }
@@ -292,7 +291,7 @@ static size_t rand_xlat(UNUSED void *instance, REQUEST *request, const char *fmt
        /*
         * 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;
@@ -326,16 +325,15 @@ static size_t randstr_xlat(UNUSED void *instance, REQUEST *request,
        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;
        }
@@ -436,13 +434,12 @@ static size_t urlquote_xlat(UNUSED void *instance, REQUEST *request,
        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;
        }
@@ -490,13 +487,12 @@ static size_t escape_xlat(UNUSED void *instance, REQUEST *request,
        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;
        }
@@ -542,7 +538,7 @@ static size_t lc_xlat(UNUSED void *instance, REQUEST *request,
 
        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;
        }
@@ -572,9 +568,10 @@ static size_t uc_xlat(UNUSED void *instance, REQUEST *request,
        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;
        }
 
@@ -601,9 +598,10 @@ static size_t md5_xlat(UNUSED void *instance, REQUEST *request,
        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;
        }
 
@@ -631,16 +629,16 @@ static size_t md5_xlat(UNUSED void *instance, REQUEST *request,
 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;
@@ -662,27 +660,29 @@ static size_t base64_to_hex_xlat(UNUSED void *instance, REQUEST *request,
        
        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++);
                
index 50d43a9..60833e0 100644 (file)
@@ -381,10 +381,12 @@ static rlm_rcode_t file_common(rlm_files_t *inst, REQUEST *request,
        } 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;
index 810c624..e71f3c3 100644 (file)
@@ -276,8 +276,7 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        }
        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);
@@ -429,10 +428,10 @@ static rlm_rcode_t mod_post_auth(UNUSED void *instance, UNUSED REQUEST *request)
        }
 #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);
index f472c41..8509f96 100644 (file)
@@ -161,7 +161,7 @@ void rlm_ldap_map_xlat_free(const rlm_ldap_map_xlat_t *expanded)
                switch (map->src->type) {
                case VPT_TYPE_XLAT:             
                case VPT_TYPE_ATTR:
-                       rad_cfree(name);
+                       rad_const_free(name);
                        break;
                default:
                        break;
@@ -176,27 +176,27 @@ int rlm_ldap_map_xlat(REQUEST *request, const value_pair_map_t *maps, rlm_ldap_m
 {
        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;
@@ -206,14 +206,10 @@ int rlm_ldap_map_xlat(REQUEST *request, const value_pair_map_t *maps, rlm_ldap_m
                        }
                        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:
index f01e6ee..00a0dc4 100644 (file)
@@ -378,7 +378,7 @@ rlm_rcode_t rlm_ldap_cacheable_groupobj(const ldap_instance_t *inst, REQUEST *re
                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;
@@ -485,8 +485,8 @@ rlm_rcode_t rlm_ldap_check_groupobj_dynamic(const ldap_instance_t *inst, REQUEST
                /*
                 *      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");
index dd6c22e..a1bfec3 100644 (file)
@@ -158,7 +158,7 @@ ssize_t rlm_ldap_xlat_filter(REQUEST *request, const char **sub, size_t sublen,
        const char *in;
        char *p = buffer;
        
-       size_t len = 0;
+       ssize_t len = 0;
        
        unsigned int i;
        int cnt = 0;
@@ -190,7 +190,7 @@ ssize_t rlm_ldap_xlat_filter(REQUEST *request, const char **sub, size_t sublen,
                        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");
                                        
@@ -209,8 +209,8 @@ ssize_t rlm_ldap_xlat_filter(REQUEST *request, const char **sub, size_t sublen,
                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;
@@ -842,14 +842,14 @@ const char *rlm_ldap_find_user(const ldap_instance_t *inst, REQUEST *request, ld
                (*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;
index e062f42..8103b79 100644 (file)
@@ -201,7 +201,7 @@ static size_t ldap_xlat(void *instance, REQUEST *request, const char *fmt,
        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;
                }
@@ -972,7 +972,7 @@ static rlm_rcode_t user_modify(ldap_instance_t *inst, REQUEST *request, ldap_acc
                *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;     
        }
 
@@ -1043,17 +1043,18 @@ static rlm_rcode_t user_modify(ldap_instance_t *inst, REQUEST *request, ldap_acc
                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
                 */
@@ -1132,7 +1133,7 @@ static rlm_rcode_t user_modify(ldap_instance_t *inst, REQUEST *request, ldap_acc
         *      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);
index bce3932..b0ab894 100644 (file)
@@ -213,8 +213,13 @@ static rlm_rcode_t do_linelog(void *instance, REQUEST *request)
                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 */
 
                /*
@@ -251,8 +256,9 @@ static rlm_rcode_t do_linelog(void *instance, REQUEST *request)
         *      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,'/');
@@ -296,8 +302,13 @@ static rlm_rcode_t do_linelog(void *instance, REQUEST *request)
        /*
         *      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");
index d6714de..9a67f05 100644 (file)
@@ -36,6 +36,7 @@ RCSID("$Id$")
 #include       "smbdes.h"
 
 #ifdef HAVE_OPENSSL_CRYPTO_H
+USES_APPLE_DEPRECATED_API      /* OpenSSL API has been deprecated by Apple */
 #  include     <openssl/rc4.h>
 #endif
 
@@ -450,8 +451,7 @@ static size_t mschap_xlat(void *instance, REQUEST *request,
 
                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;
                }
@@ -476,8 +476,7 @@ static size_t mschap_xlat(void *instance, REQUEST *request,
 
                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;
                }
@@ -699,9 +698,13 @@ static int do_mschap_cpw(rlm_mschap_t *inst,
                 */
 
                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");
@@ -712,9 +715,13 @@ static int do_mschap_cpw(rlm_mschap_t *inst,
                }
 
                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");
@@ -829,8 +836,9 @@ ntlm_auth_err:
 
                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;
@@ -955,8 +963,10 @@ ntlm_auth_err:
                /*
                 * 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;
                }
index ff3daec..caef3e7 100644 (file)
@@ -243,8 +243,9 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
         */
        {
                VALUE_PAIR *vp;
-               char buff[1024];
-               size_t len;
+
+               char *expanded = NULL;
+               ssize_t len;
 
                /*
                 *      First add the internal OTP challenge attribute to
@@ -266,18 +267,20 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
                 *      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;
                
index 88f6bac..043f576 100644 (file)
@@ -503,9 +503,8 @@ static int pap_auth_ssha(REQUEST *request, VALUE_PAIR *vp)
 
 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.");
 
@@ -515,13 +514,11 @@ static int pap_auth_nt(REQUEST *request, VALUE_PAIR *vp)
                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;
@@ -533,9 +530,8 @@ static int pap_auth_nt(REQUEST *request, VALUE_PAIR *vp)
 
 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.");
 
@@ -545,13 +541,11 @@ static int pap_auth_lm(REQUEST *request, VALUE_PAIR *vp)
                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;
index 285675f..e5f110b 100644 (file)
@@ -314,16 +314,15 @@ static size_t perl_xlat(void *instance, REQUEST *request, const char *fmt,
 
        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;
        }
 
@@ -340,7 +339,7 @@ static size_t perl_xlat(void *instance, REQUEST *request, const char *fmt,
                dSP;
                ENTER;SAVETMPS;
 
-               ptr = strtok(params, " ");
+               ptr = strtok(expanded, " ");
 
                PUSHMARK(SP);
 
@@ -363,8 +362,7 @@ static size_t perl_xlat(void *instance, REQUEST *request, const char *fmt,
                        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 ;
@@ -372,6 +370,9 @@ static size_t perl_xlat(void *instance, REQUEST *request, const char *fmt,
                LEAVE ;
 
        }
+       
+       talloc_free(expanded);
+       
        return ret;
 }
 /*
index 06df91c..04283c5 100644 (file)
@@ -147,21 +147,23 @@ static NAS_PORT *nas_port_find(NAS_PORT *nas_port_list, uint32_t nasaddr, unsign
  */
 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!");
@@ -292,64 +294,65 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        /*
         *      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
@@ -359,15 +362,17 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
         *      - 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;
        }
 
        /*
@@ -375,9 +380,10 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
         */
        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;
        }
 
        /*
@@ -388,8 +394,7 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        /*
         *      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);
        }
 
@@ -397,36 +402,32 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        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",
@@ -434,20 +435,17 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
                                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.
@@ -459,8 +457,10 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
                        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 */
@@ -469,8 +469,7 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
         *      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.
@@ -501,12 +500,18 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
                        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
@@ -524,22 +529,26 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
  */
 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.
@@ -552,16 +561,24 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
                /*
                 *      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;
        }
 
        /*
@@ -575,10 +592,9 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
         *      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;
                }
        }
@@ -587,20 +603,23 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
         *      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.
@@ -615,10 +634,8 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
         */
        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];
 
@@ -648,17 +665,15 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
                         *      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) {
                                /*
@@ -669,28 +684,28 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request)
                                /*
                                 *      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
 
index f78a29b..ccd4867 100644 (file)
@@ -949,7 +949,7 @@ static int rest_decode_post(rlm_rest_t *instance,
        char *name  = NULL;
        char *value = NULL;
        
-       char buffer[1024];
+       char *expanded = NULL;
 
        const DICT_ATTR *da;
        VALUE_PAIR *vp;
@@ -965,6 +965,7 @@ static int rest_decode_post(rlm_rest_t *instance,
        int curl_len; /* Length from last curl_easy_unescape call */
 
        int count = 0;
+       int ret;
 
        processed[0] = NULL;
 
@@ -1025,8 +1026,7 @@ static int rest_decode_post(rlm_rest_t *instance,
 
                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);
@@ -1045,8 +1045,7 @@ static int rest_decode_post(rlm_rest_t *instance,
                
                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;
                }
 
@@ -1054,7 +1053,8 @@ static int rest_decode_post(rlm_rest_t *instance,
                if (!vp) {
                        radlog(L_ERR, "rlm_rest (%s): Failed creating"
                               " valuepair", instance->xlat_name);
-
+                       talloc_free(expanded);
+                       
                        goto error;
                }
 
@@ -1078,7 +1078,9 @@ static int rest_decode_post(rlm_rest_t *instance,
                        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;
@@ -1129,13 +1131,14 @@ static int rest_decode_post(rlm_rest_t *instance,
  * @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;
 
@@ -1152,28 +1155,31 @@ static VALUE_PAIR *json_pairmake_leaf(rlm_rest_t *instance,
        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;
        }
 
@@ -1975,49 +1981,49 @@ int rest_request_config(rlm_rest_t *instance, rlm_rest_section_t *section,
        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
                }
@@ -2343,17 +2349,17 @@ static size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen,
  * @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;
 
@@ -2376,18 +2382,30 @@ ssize_t rest_uri_build(rlm_rest_t *instance, rlm_rest_section_t *section,
 
        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;
 }
index 78519de..35ac641 100644 (file)
@@ -260,5 +260,4 @@ void rest_request_cleanup(rlm_rest_t *instance, rlm_rest_section_t *section,
 /*
  *     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);
index daeb44d..79ae7ae 100644 (file)
@@ -102,31 +102,28 @@ static int rlm_rest_perform (rlm_rest_t *instance, rlm_rest_section_t *section,
                             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;
 
        /*
index 5e03f00..0b274b2 100644 (file)
@@ -126,59 +126,55 @@ static size_t sql_escape_func(REQUEST *, char *out, size_t outlen, const char *i
  *  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;
                }
 
                /*
@@ -190,64 +186,70 @@ static size_t sql_xlat(void *instance, REQUEST *request,
                 *      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;
 }
 
@@ -451,10 +453,10 @@ static size_t sql_escape_func(UNUSED REQUEST *request, char *out, size_t outlen,
  */
 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;
@@ -464,15 +466,17 @@ int sql_set_user(rlm_sql_t *inst, REQUEST *request, const char *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);
 
@@ -482,31 +486,33 @@ int sql_set_user(rlm_sql_t *inst, REQUEST *request, const char *username)
 }
 
 
-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)
@@ -602,24 +608,23 @@ static int sql_groupcmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *req
        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) {
@@ -629,108 +634,82 @@ static int rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_han
                 */
                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;
 }
 
 
@@ -964,7 +943,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
 
 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;
@@ -976,45 +955,46 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
        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)) {       
@@ -1022,34 +1002,35 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
                        
                        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) {
@@ -1060,34 +1041,31 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
                        
                        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;
        }
 
        /*
@@ -1103,40 +1081,40 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
                                      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;
 }
 
 /*
@@ -1149,42 +1127,47 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST * request)
  *     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);
@@ -1193,30 +1176,38 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
        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
@@ -1227,10 +1218,14 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
                 *  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);
        
                /*
@@ -1238,10 +1233,10 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
                 *  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");
                }
@@ -1257,9 +1252,9 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
                if (!pair) {
                        RDEBUG("No additional queries configured");
                        
-                       ret = RLM_MODULE_NOOP;
+                       rcode = RLM_MODULE_NOOP;
                        
-                       goto release;
+                       goto finish;
                }
 
                RDEBUG("Trying next query...");
@@ -1267,10 +1262,12 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request,
        
        (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
@@ -1301,82 +1298,92 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST * request) {
  */
 
 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;
        }
 
        /*
@@ -1384,35 +1391,43 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request) {
         */
        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.
@@ -1446,33 +1461,35 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request) {
                        /*
                         *      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
 
index 967caf5..0176153 100644 (file)
@@ -447,32 +447,38 @@ void rlm_sql_query_log(rlm_sql_t *inst, REQUEST *request,
 {
        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 */
 }
index f21487f..2f8b753 100644 (file)
@@ -239,7 +239,7 @@ static int find_prev_reset(rlm_sqlcounter_t *inst, time_t timeval)
  *
  */
 
-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;
@@ -251,7 +251,7 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, rlm_sqlcoun
        /* Calculate freespace in output */
        freespace = outlen - (q - out);
                if (freespace <= 1)
-                       break;
+                       return -1;
                c = *p;
                if ((c != '%') && (c != '\\')) {
                        *q++ = *p;
@@ -310,25 +310,53 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, rlm_sqlcoun
 /*
  *     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;
 }
@@ -445,15 +473,18 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
        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
                 */
@@ -461,15 +492,16 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
                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;
        }
 
@@ -480,33 +512,58 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
                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
@@ -519,8 +576,7 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
                 *      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;
@@ -532,26 +588,24 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
                 */
                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
@@ -563,8 +617,8 @@ static rlm_rcode_t mod_authorize(UNUSED void *instance, UNUSED REQUEST *request)
                                   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;
index 06910be..a41f65d 100644 (file)
@@ -281,33 +281,38 @@ static int sqlippool_expand(char * out, int outlen, const char * fmt,
 /*
  * 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;
 }
 
@@ -324,32 +329,35 @@ static int sqlippool_query1(char *out, int outlen, 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];
-       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]) {
@@ -369,8 +377,8 @@ static int sqlippool_query1(char *out, int outlen, const char *fmt,
                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;
 }
 
@@ -417,19 +425,22 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
 
 
 /*
- *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;
 }
index 476ac57..438ba88 100644 (file)
@@ -60,39 +60,42 @@ static const CONF_PARSER module_config[] = {
 };
 
 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;
@@ -105,41 +108,30 @@ static size_t modhex2bin(const char *hex, uint8_t *bin, size_t len)
  */
 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;
 }
 
 /*