Delete trailing whitespace.
[freeradius.git] / src / main / xlat.c
index 1459494..f2528ed 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000,2006  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-static const char rcsid[] =
-"$Id$";
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#include       "autoconf.h"
-#include       "libradius.h"
+#include       <freeradius-devel/radiusd.h>
+#include       <freeradius-devel/rad_assert.h>
 
-#include       <stdio.h>
-#include       <stdlib.h>
-#include       <string.h>
 #include       <ctype.h>
 
-#include       "radiusd.h"
-
-#include       "rad_assert.h"
-
 typedef struct xlat_t {
        char            module[MAX_STRING_LEN];
        int             length;
@@ -50,17 +43,17 @@ static rbtree_t *xlat_root = NULL;
 /*
  *     Define all xlat's in the structure.
  */
-static const char *internal_xlat[] = {"check",
-                                     "request",
-                                     "reply",
-                                     "proxy-request",
-                                     "proxy-reply",
-                                     NULL};
+static const char * const internal_xlat[] = {"check",
+                                            "request",
+                                            "reply",
+                                            "proxy-request",
+                                            "proxy-reply",
+                                            NULL};
 
 #if REQUEST_MAX_REGEX > 8
 #error Please fix the following line
 #endif
-static int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };        /* up to 8 for regex */
+static const int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };  /* up to 8 for regex */
 
 
 /*
@@ -78,19 +71,22 @@ static int valuepair2str(char * out,int outlen,VALUE_PAIR * pair,
 
        switch (type) {
        case PW_TYPE_STRING :
-               strNcpy(out,"_",outlen);
+               strlcpy(out,"_",outlen);
                break;
        case PW_TYPE_INTEGER :
-               strNcpy(out,"0",outlen);
+               strlcpy(out,"0",outlen);
                break;
        case PW_TYPE_IPADDR :
-               strNcpy(out,"?.?.?.?",outlen);
+               strlcpy(out,"?.?.?.?",outlen);
+               break;
+       case PW_TYPE_IPV6ADDR :
+               strlcpy(out,":?:",outlen);
                break;
        case PW_TYPE_DATE :
-               strNcpy(out,"0",outlen);
+               strlcpy(out,"0",outlen);
                break;
        default :
-               strNcpy(out,"unknown_type",outlen);
+               strlcpy(out,"unknown_type",outlen);
        }
        return strlen(out);
 }
@@ -142,14 +138,14 @@ static int xlat_packet(void *instance, REQUEST *request,
         */
        da = dict_attrbyname(fmt);
        if (!da) {
-               int index;
+               int count;
                const char *p = strchr(fmt, '[');
                char buffer[256];
 
                if (!p) return 0;
                if (strlen(fmt) > sizeof(buffer)) return 0;
 
-               strNcpy(buffer, fmt, p - fmt + 1);
+               strlcpy(buffer, fmt, p - fmt + 1);
 
                da = dict_attrbyname(buffer);
                if (!da) return 0;
@@ -159,33 +155,33 @@ static int xlat_packet(void *instance, REQUEST *request,
                 *      attributes of that name in the list.
                 */
                if ((p[1] == '#') && (p[2] == ']')) {
-                       index = 0;
+                       count = 0;
 
                        for (vp = pairfind(vps, da->attr);
                             vp != NULL;
                             vp = pairfind(vp->next, da->attr)) {
-                               index++;
+                               count++;
                        }
-                       snprintf(out, outlen, "%d", index);
+                       snprintf(out, outlen, "%d", count);
                        return strlen(out);
                }
 
                /*
                 *      %{Attribute-Name[*]} returns ALL of the
                 *      the attributes, separated by a newline.
-                */             
+                */
                if ((p[1] == '*') && (p[2] == ']')) {
                        int total = 0;
 
                        for (vp = pairfind(vps, da->attr);
                             vp != NULL;
                             vp = pairfind(vp->next, da->attr)) {
-                               index = valuepair2str(out, outlen - 1, vp, da->type, func);
-                               rad_assert(index <= outlen);
-                               total += index + 1;
-                               outlen -= (index + 1);
-                               out += index;
-                               
+                               count = valuepair2str(out, outlen - 1, vp, da->type, func);
+                               rad_assert(count <= outlen);
+                               total += count + 1;
+                               outlen -= (count + 1);
+                               out += count;
+
                                *(out++) = '\n';
 
                                if (outlen == 0) break;
@@ -193,8 +189,8 @@ static int xlat_packet(void *instance, REQUEST *request,
 
                        return total;
                }
-               
-               index = atoi(p + 1);
+
+               count = atoi(p + 1);
 
                /*
                 *      Skip the numbers.
@@ -212,8 +208,8 @@ static int xlat_packet(void *instance, REQUEST *request,
                for (vp = pairfind(vps, da->attr);
                     vp != NULL;
                     vp = pairfind(vp->next, da->attr)) {
-                       if (index == 0) break;
-                       index--;
+                       if (count == 0) break;
+                       count--;
                }
 
                /*
@@ -229,17 +225,20 @@ static int xlat_packet(void *instance, REQUEST *request,
                /*
                 *      Some "magic" handlers, which are never in VP's, but
                 *      which are in the packet.
+                *
+                *      FIXME: We should really do this in a more
+                *      intelligent way...
                 */
                if (packet) {
                        VALUE_PAIR localvp;
 
-                       localvp.strvalue[0] = 0;
+                       localvp.vp_strvalue[0] = 0;
 
                        switch (da->attr) {
                        case PW_PACKET_TYPE:
                        {
                                DICT_VALUE *dval;
-                               
+
                                dval = dict_valbyattr(da->attr, packet->code);
                                if (dval) {
                                        snprintf(out, outlen, "%s", dval->name);
@@ -250,29 +249,36 @@ static int xlat_packet(void *instance, REQUEST *request,
                        }
                        break;
 
+                       case PW_CLIENT_IP_ADDRESS: /* the same as below */
                        case PW_PACKET_SRC_IP_ADDRESS:
+                               if (packet->src_ipaddr.af != AF_INET) {
+                                       return 0;
+                               }
                                localvp.attribute = da->attr;
-                               localvp.lvalue = packet->src_ipaddr;
+                               localvp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
                                break;
-                       
+
                        case PW_PACKET_DST_IP_ADDRESS:
+                               if (packet->dst_ipaddr.af != AF_INET) {
+                                       return 0;
+                               }
                                localvp.attribute = da->attr;
-                               localvp.lvalue = packet->dst_ipaddr;
+                               localvp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
                                break;
-                       
+
                        case PW_PACKET_SRC_PORT:
                                localvp.attribute = da->attr;
-                               localvp.lvalue = packet->src_port;
+                               localvp.vp_integer = packet->src_port;
                                break;
-                       
+
                        case PW_PACKET_DST_PORT:
                                localvp.attribute = da->attr;
-                               localvp.lvalue = packet->dst_port;
+                               localvp.vp_integer = packet->dst_port;
                                break;
 
                        case PW_PACKET_AUTHENTICATION_VECTOR:
                                localvp.attribute = da->attr;
-                               memcpy(localvp.strvalue, packet->vector,
+                               memcpy(localvp.vp_strvalue, packet->vector,
                                       sizeof(packet->vector));
                                localvp.length = sizeof(packet->vector);
                                break;
@@ -282,12 +288,39 @@ static int xlat_packet(void *instance, REQUEST *request,
                                 */
                        case PW_REQUEST_PROCESSING_STAGE:
                                if (request->component) {
-                                       strNcpy(out, request->component, outlen);
+                                       strlcpy(out, request->component, outlen);
                                } else {
-                                       strNcpy(out, "server_core", outlen);
+                                       strlcpy(out, "server_core", outlen);
+                               }
+                               return strlen(out);
+
+                       case PW_PACKET_SRC_IPV6_ADDRESS:
+                               if (packet->src_ipaddr.af != AF_INET6) {
+                                       return 0;
                                }
+                               localvp.attribute = da->attr;
+                               memcpy(localvp.vp_strvalue,
+                                      &packet->src_ipaddr.ipaddr.ip6addr,
+                                      sizeof(packet->src_ipaddr.ipaddr.ip6addr));
+                               break;
+
+                       case PW_PACKET_DST_IPV6_ADDRESS:
+                               if (packet->dst_ipaddr.af != AF_INET6) {
+                                       return 0;
+                               }
+                               localvp.attribute = da->attr;
+                               memcpy(localvp.vp_strvalue,
+                                      &packet->dst_ipaddr.ipaddr.ip6addr,
+                                      sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
+                               break;
+
+                       case PW_SERVER_IDENTITY:
+                               if (!request->listener || !request->listener->identity) return 0;
+
+                               snprintf(out, outlen, "%s", request->listener->identity);
                                return strlen(out);
-                       
+                               break;
+
                        default:
                                return 0; /* not found */
                                break;
@@ -328,8 +361,8 @@ static int xlat_regex(void *instance, REQUEST *request,
         */
        fmt = fmt;              /* -Wunused */
        func = func;            /* -Wunused FIXME: do escaping? */
-       
-       regex = request_data_get(request, request,
+
+       regex = request_data_reference(request, request,
                                 REQUEST_DATA_REGEX | *(int *)instance);
        if (!regex) return 0;
 
@@ -337,12 +370,12 @@ static int xlat_regex(void *instance, REQUEST *request,
         *      Copy UP TO "freespace" bytes, including
         *      a zero byte.
         */
-       strNcpy(out, regex, outlen);
-       free(regex); /* was strdup'd */
+       strlcpy(out, regex, outlen);
        return strlen(out);
 }
 #endif                         /* HAVE_REGEX_H */
 
+
 /*
  *     Compare two xlat_t structs, based ONLY on the module name.
  */
@@ -361,18 +394,28 @@ static int xlat_cmp(const void *a, const void *b)
 /*
  *     find the appropriate registered xlat function.
  */
-static xlat_t *xlat_find(const char *module)
+static const xlat_t *xlat_find(const char *module)
 {
-       char *p;
        xlat_t my_xlat;
 
-       p = my_xlat.module;
-       my_xlat.length = 0;
-       while (*module && (*module != ':')) {
-               *(p++) = *(module++);
-               my_xlat.length++;
+       /*
+        *      Look for dictionary attributes first.
+        */
+       if ((dict_attrbyname(module) != NULL) ||
+           (strchr(module, '[') != NULL)) {
+               static const xlat_t dict_xlat = {
+                       "request",
+                       7,
+                       &xlat_inst[1],
+                       xlat_packet,
+                       TRUE
+               };
+
+               return &dict_xlat;
        }
-       *p = '\0';
+
+       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
+       my_xlat.length = strlen(my_xlat.module);
 
        return rbtree_finddata(xlat_root, &my_xlat);
 }
@@ -437,7 +480,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        /*
         *      If it already exists, replace the instance.
         */
-       strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
        my_xlat.length = strlen(my_xlat.module);
        c = rbtree_finddata(xlat_root, &my_xlat);
        if (c) {
@@ -458,7 +501,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        memset(c, 0, sizeof(*c));
 
        c->do_xlat = func;
-       strNcpy(c->module, module, sizeof(c->module));
+       strlcpy(c->module, module, sizeof(c->module));
        c->length = strlen(c->module);
        c->instance = instance;
 
@@ -480,7 +523,9 @@ void xlat_unregister(const char *module, RAD_XLAT_FUNC func)
 
        func = func;            /* -Wunused */
 
-       strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+       if (!module) return;
+
+       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
        my_xlat.length = strlen(my_xlat.module);
 
        node = rbtree_find(xlat_root, &my_xlat);
@@ -503,17 +548,19 @@ void xlat_free(void)
  *     Decode an attribute name into a string.
  */
 static void decode_attribute(const char **from, char **to, int freespace,
-                            int *open, REQUEST *request,
+                            int *open_p, REQUEST *request,
                             RADIUS_ESCAPE_STRING func)
 {
        int     do_length = 0;
        char    xlat_name[128];
        char    *xlat_string = NULL; /* can be large */
+       int     free_xlat_string = FALSE;
        const char *p;
        char *q, *pa;
        int found=0, retlen=0;
-       int openbraces = *open;
-       xlat_t *c;
+       int openbraces = *open_p;
+       const xlat_t *c;
+       int spaces = FALSE;
 
        p = *from;
        q = *to;
@@ -555,39 +602,51 @@ static void decode_attribute(const char **from, char **to, int freespace,
                DEBUG("xlat: Invalid syntax in %s", *from);
 
                /*
-                *      %{name} is a simple attribute reference, use it.
+                *      %{name} is a simple attribute reference,
+                *      or regex reference.
                 */
        } else if (*p == '}') {
                openbraces--;
+               rad_assert(openbraces == *open_p);
+
                p++;
-               rad_assert(openbraces == *open);
+               xlat_string = xlat_name;
+               goto do_xlat;
 
-               if ((retlen = xlat_packet(&xlat_inst[1], request, xlat_name,
-                                         q, freespace, func)) > 0) {
-                       found = 1;
-               }
        } else if (p[1] == '-') { /* handle ':- */
                p += 2;
-               if ((retlen = xlat_packet(&xlat_inst[1], request, xlat_name,
-                                         q, freespace, func)) > 0) {
-                       found = 1;
-               }
-               
+               xlat_string = xlat_name;
+               goto do_xlat;
+
        } else {      /* module name, followed by per-module string */
                int stop = 0;
+               int delimitbrace = *open_p;
 
                rad_assert(*p == ':');
                p++;                    /* skip the ':' */
-               
+
+               /*
+                *  If there's a brace immediately following the colon,
+                *  then we've chosen to delimite the per-module string,
+                *  so keep track of that.
+                */
+               if (*p == '{') {
+                       delimitbrace = openbraces;
+                       openbraces++;
+                       p++;
+               }
+
                xlat_string = rad_malloc(strlen(p) + 1); /* always returns */
+               free_xlat_string = TRUE;
                pa = xlat_string;
-               
+
                /*
                 *  Copy over the rest of the string, which is per-module
                 *  data.
                 */
                while (*p && !stop) {
                        switch(*p) {
+
                                /*
                                 *      What the heck is this supposed
                                 *      to be doing?
@@ -597,6 +656,13 @@ static void decode_attribute(const char **from, char **to, int freespace,
                                *pa++ = *p++;
                                break;
 
+                       case ':':
+                               if (!spaces && p[1] == '-') {
+                                       p += 2;
+                                       stop = 1;
+                                       break;
+                               }
+
                                /*
                                 *      This is pretty hokey...  we
                                 *      should use the functions in
@@ -609,14 +675,19 @@ static void decode_attribute(const char **from, char **to, int freespace,
 
                        case '}':
                                openbraces--;
-                               if (openbraces == *open) {
+                               if (openbraces == delimitbrace) {
                                        p++;
                                        stop=1;
                                } else {
                                        *pa++ = *p++;
                                }
                                break;
-                               
+
+                       case ' ':
+                       case '\t':
+                               spaces = TRUE;
+                               /* FALL-THROUGH */
+
                        default:
                                *pa++ = *p++;
                                break;
@@ -624,11 +695,22 @@ static void decode_attribute(const char **from, char **to, int freespace,
                }
 
                *pa = '\0';
-               
+
+               /*
+                *      Now check to see if we're at the end of the string
+                *      we were sent.  If we're not, check for :-
+                */
+               if (openbraces == delimitbrace) {
+                       if (p[0] == ':' && p[1] == '-') {
+                               p += 2;
+                       }
+               }
+
                /*
                 *      Look up almost everything in the new tree of xlat
                 *      functions.  This makes it a little quicker...
                 */
+       do_xlat:
                if ((c = xlat_find(xlat_name)) != NULL) {
                        if (!c->internal) DEBUG("radius_xlat: Running registered xlat function of module %s for string \'%s\'",
                                                c->module, xlat_string);
@@ -659,7 +741,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
 
                q += retlen;
 
-               while((*p != '\0') && (openbraces > 0)) {
+               while((*p != '\0') && (openbraces > *open_p)) {
                        /*
                         *      Handle escapes outside of the loop.
                         */
@@ -688,11 +770,11 @@ static void decode_attribute(const char **from, char **to, int freespace,
                        p++;    /* skip the character */
                }
        }
-       
+
        done:
-       if (xlat_string) free(xlat_string);
+       if (free_xlat_string) free(xlat_string);
 
-       *open = openbraces;
+       *open_p = openbraces;
        *from = p;
        *to = q;
 }
@@ -704,30 +786,23 @@ static void decode_attribute(const char **from, char **to, int freespace,
  */
 static int xlat_copy(char *out, int outlen, const char *in)
 {
-       int len = 0;
+       int freespace = outlen;
 
-       while (*in) {
-               /*
-                *  Truncate, if too much.
-                */
-               if (len >= outlen) {
-                       break;
-               }
+       rad_assert(outlen > 0);
 
+       while ((*in) && (freespace > 1)) {
                /*
                 *  Copy data.
                 *
                 *  FIXME: Do escaping of bad stuff!
                 */
-               *out = *in;
+               *(out++) = *(in++);
 
-               out++;
-               in++;
-               len++;
+               freespace--;
        }
-
        *out = '\0';
-       return len;
+
+       return (outlen - freespace); /* count does not include NUL */
 }
 
 /*
@@ -738,9 +813,10 @@ static int xlat_copy(char *out, int outlen, const char *in)
 int radius_xlat(char *out, int outlen, const char *fmt,
                REQUEST *request, RADIUS_ESCAPE_STRING func)
 {
-       int i, c,freespace;
+       int c, len, freespace;
        const char *p;
        char *q;
+       char *nl;
        VALUE_PAIR *tmp;
        struct tm *TM, s_TM;
        char tmpdt[40]; /* For temporary storing of dates */
@@ -843,9 +919,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                break;
                        case 'd': /* request day */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%d",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'f': /* Framed IP address */
@@ -858,16 +936,18 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                break;
                        case 'l': /* request timestamp */
                                snprintf(tmpdt, sizeof(tmpdt), "%lu",
-                                        (unsigned long) request->timestamp);
-                               strNcpy(q,tmpdt,freespace);
+                                        (unsigned long) request->received.tv_sec);
+                               strlcpy(q,tmpdt,freespace);
                                q += strlen(q);
                                p++;
                                break;
                        case 'm': /* request month */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%m",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'n': /* NAS IP address */
@@ -883,13 +963,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 't': /* request timestamp */
-                               CTIME_R(&request->timestamp, q, freespace);
-                               q = strchr(q, '\n');
-                               if (q) {
-                                       *q = '\0';
-                               } else {
-                                       q += strlen(q);
-                               }
+                               CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));
+                               nl = strchr(tmpdt, '\n');
+                               if (nl) *nl = '\0';
+                               strlcpy(q, tmpdt, freespace);
+                               q += strlen(q);
                                p++;
                                break;
                        case 'u': /* User name */
@@ -897,31 +975,35 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'A': /* radacct_dir */
-                               strNcpy(q,radacct_dir,freespace-1);
+                               strlcpy(q,radacct_dir,freespace);
                                q += strlen(q);
                                p++;
                                break;
                        case 'C': /* ClientName */
-                               strNcpy(q,client_name(request->packet->src_ipaddr),freespace-1);
+                               strlcpy(q,client_name_old(&request->packet->src_ipaddr),freespace);
                                q += strlen(q);
                                p++;
                                break;
                        case 'D': /* request date */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%Y%m%d",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'H': /* request hour */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%H",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'L': /* radlog_dir */
-                               strNcpy(q,radlog_dir,freespace-1);
+                               strlcpy(q,radlog_dir,freespace);
                                q += strlen(q);
                                p++;
                                break;
@@ -930,22 +1012,26 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'R': /* radius_dir */
-                               strNcpy(q,radius_dir,freespace-1);
+                               strlcpy(q,radius_dir,freespace);
                                q += strlen(q);
                                p++;
                                break;
                        case 'S': /* request timestamp in SQL format*/
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d %H:%M:%S",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'T': /* request timestamp */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d-%H.%M.%S.000000",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'U': /* Stripped User name */
@@ -953,28 +1039,27 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'V': /* Request-Authenticator */
-                               if (request->packet->verified)
-                                       strNcpy(q,"Verified",freespace-1);
-                               else
-                                       strNcpy(q,"None",freespace-1);
+                               strlcpy(q,"Verified",freespace);
                                q += strlen(q);
                                p++;
                                break;
                        case 'Y': /* request year */
                                TM = localtime_r(&request->timestamp, &s_TM);
-                               strftime(tmpdt,sizeof(tmpdt),"%Y",TM);
-                               strNcpy(q,tmpdt,freespace);
-                               q += strlen(q);
+                               len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);
+                               if (len > 0) {
+                                       strlcpy(q, tmpdt, freespace);
+                                       q += strlen(q);
+                               }
                                p++;
                                break;
                        case 'Z': /* Full request pairs except password */
                                tmp = request->packet->vps;
                                while (tmp && (freespace > 3)) {
-                                       if (tmp->attribute != PW_PASSWORD) {
+                                       if (tmp->attribute != PW_USER_PASSWORD) {
                                                *q++ = '\t';
-                                               i = vp_prints(q,freespace-2,tmp);
-                                               q += i;
-                                               freespace -= (i+2);
+                                               len = vp_prints(q, freespace - 2, tmp);
+                                               q += len;
+                                               freespace -= (len + 2);
                                                *q++ = '\n';
                                        }
                                        tmp = tmp->next;