Use paircursor for iteration where appropriate
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 29 May 2013 13:51:47 +0000 (09:51 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 29 May 2013 13:52:38 +0000 (09:52 -0400)
45 files changed:
src/include/libradius.h
src/lib/print.c
src/lib/valuepair.c
src/main/auth.c
src/main/command.c
src/main/detail.c
src/main/evaluate.c
src/main/exec.c
src/main/log.c
src/main/modcall.c
src/main/process.c
src/main/radattr.c
src/main/radclient.c
src/main/radsniff.c
src/main/tls.c
src/main/valuepair.c
src/modules/proto_dhcp/dhcp.c
src/modules/proto_dhcp/dhcpclient.c
src/modules/proto_dhcp/rlm_dhcp.c
src/modules/proto_vmps/vqp.c
src/modules/rlm_attr_filter/rlm_attr_filter.c
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_detail/rlm_detail.c
src/modules/rlm_digest/rlm_digest.c
src/modules/rlm_eap/eap.c
src/modules/rlm_eap/libeap/eapcommon.c
src/modules/rlm_eap/libeap/eapsimlib.c
src/modules/rlm_eap/rlm_eap.c
src/modules/rlm_eap/types/rlm_eap_peap/peap.c
src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c
src/modules/rlm_files/rlm_files.c
src/modules/rlm_ldap/attrmap.c
src/modules/rlm_ldap/groups.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_pap/rlm_pap.c
src/modules/rlm_passwd/rlm_passwd.c
src/modules/rlm_perl/rlm_perl.c
src/modules/rlm_preprocess/rlm_preprocess.c
src/modules/rlm_python/rlm_python.c
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_replicate/rlm_replicate.c
src/modules/rlm_rest/rest.c
src/modules/rlm_ruby/rlm_ruby.c
src/modules/rlm_unix/rlm_unix.c
src/modules/rlm_utf8/rlm_utf8.c

index 48325e1..1416341 100644 (file)
@@ -214,6 +214,12 @@ typedef struct value_pair {
 } VALUE_PAIR;
 
 
+typedef struct vp_cursor {
+       VALUE_PAIR      **root;                 //!< Currently unused.
+       VALUE_PAIR      *last;                  //!< Temporary only use for pairinsert
+       VALUE_PAIR      *next;                  //!< Next attribute to process.
+} vp_cursor_t;
+
 typedef struct value_pair_raw {
        char l_opand[64];                       //!< Left hand side of the
                                                //!< pair.
@@ -419,11 +425,20 @@ VALUE_PAIR        *pairalloc(TALLOC_CTX *ctx, DICT_ATTR const *da);
 VALUE_PAIR     *paircreate(TALLOC_CTX *ctx, unsigned int attr, unsigned int vendor);
 int            pair2unknown(VALUE_PAIR *vp);
 void           pairfree(VALUE_PAIR **);
-void       pairbasicfree(VALUE_PAIR *pair);
+void           pairbasicfree(VALUE_PAIR *pair);
 VALUE_PAIR     *pairfind(VALUE_PAIR *, unsigned int attr, unsigned int vendor, int8_t tag);
+
+#define                paircursor(_x, _y)      paircursorc(_x,(VALUE_PAIR const * const *) _y)
+VALUE_PAIR     *paircursorc(vp_cursor_t *cursor, VALUE_PAIR const * const *node);
+VALUE_PAIR     *pairfirst(vp_cursor_t *cursor);
+VALUE_PAIR     *pairfindnext(vp_cursor_t *cursor, unsigned int attr, unsigned int vendor, int8_t tag);
+VALUE_PAIR     *pairnext(vp_cursor_t *cursor);
+VALUE_PAIR     *pairlast(vp_cursor_t *cursor);
+VALUE_PAIR     *paircurrent(vp_cursor_t *cursor);
+void           pairinsert(vp_cursor_t *cursor, VALUE_PAIR *vp);
 void           pairdelete(VALUE_PAIR **, unsigned int attr, unsigned int vendor, int8_t tag);
 void           pairadd(VALUE_PAIR **, VALUE_PAIR *);
-void       pairreplace(VALUE_PAIR **first, VALUE_PAIR *add);
+void           pairreplace(VALUE_PAIR **first, VALUE_PAIR *add);
 int            paircmp(VALUE_PAIR *check, VALUE_PAIR *data);
 int            paircmp_op(VALUE_PAIR const *one, FR_TOKEN op, VALUE_PAIR const *two);
 VALUE_PAIR     *paircopyvp(TALLOC_CTX *ctx, VALUE_PAIR const *vp);
index 6f399fc..f102a80 100644 (file)
@@ -831,7 +831,8 @@ void vp_print(FILE *fp, VALUE_PAIR const *vp)
  */
 void vp_printlist(FILE *fp, VALUE_PAIR const *vp)
 {
-       for (; vp; vp = vp->next) {
+       vp_cursor_t cursor;
+       for (vp = paircursorc(&cursor, &vp); vp; vp = pairnext(&cursor)) {
                vp_print(fp, vp);
        }
 }
index bcabac7..90ce565 100644 (file)
@@ -148,16 +148,18 @@ void pairbasicfree(VALUE_PAIR *vp)
  */
 void pairfree(VALUE_PAIR **vps)
 {
-       VALUE_PAIR      *next, *vp;
-
-       if (!vps) return;
-       vp = *vps;
+       VALUE_PAIR      *vp;
+       vp_cursor_t     cursor;
 
-       while (vp) {
+       if (!vps) {
+               return;
+       }
+       
+       for (vp = paircursor(&cursor, vps);
+            vp;
+            vp = pairnext(&cursor)) {
                VERIFY(vp);
-               next = vp->next;
                pairbasicfree(vp);
-               vp = next;
        }
 
        *vps = NULL;
@@ -192,21 +194,132 @@ int pair2unknown(VALUE_PAIR *vp)
  * @todo should take DAs and do a pointer comparison.
  */
 VALUE_PAIR *pairfind(VALUE_PAIR *vp, unsigned int attr, unsigned int vendor,
-                     int8_t tag)
+                    int8_t tag)
 {
-       while (vp) {
-               VERIFY(vp);
-               if ((vp->da->attr == attr) && (vp->da->vendor == vendor)
-                   && ((tag == TAG_ANY) || (vp->da->flags.has_tag &&
-                       (vp->tag == tag)))) {
-                       return vp;
+       vp_cursor_t     cursor;
+       VALUE_PAIR      *i;
+       
+       for (i = paircursor(&cursor, &vp);
+            i;
+            i = pairnext(&cursor)) {
+               VERIFY(i);
+               if ((i->da->attr == attr) && (i->da->vendor == vendor)
+                   && ((tag == TAG_ANY) || (i->da->flags.has_tag &&
+                       (i->tag == tag)))) {
+                       return i;
                }
-               vp = vp->next;
        }
 
        return NULL;
 }
 
+/** Setup a cursor to iterate over attribute pairs
+ *
+ * @param cursor Where to initialise the cursor (uses existing structure).
+ * @param node to start from.
+ */
+VALUE_PAIR *paircursorc(vp_cursor_t *cursor, VALUE_PAIR const * const *node)
+{
+       memset(cursor, 0, sizeof(*cursor));
+       
+       if (!node || !cursor) {
+               return NULL;
+       }
+       
+       memcpy(&cursor->root, &node, sizeof(cursor->root));
+       cursor->next = *cursor->root;
+       
+       return cursor->next;
+}
+
+VALUE_PAIR *pairfirst(vp_cursor_t *cursor) 
+{
+       cursor->next = *cursor->root;
+
+       return cursor->next;
+}
+
+/** Iterate over attributes of a given type in the pairlist
+ *
+ *
+ */
+VALUE_PAIR *pairfindnext(vp_cursor_t *cursor, unsigned int attr, unsigned int vendor, int8_t tag)
+{
+       VALUE_PAIR *i;
+       
+       i = pairfind(cursor->next, attr, vendor, tag);
+       if (i) {
+               cursor->next = i->next;
+       }
+
+       return i;
+}
+
+/** Retrieve the next VALUE_PAIR
+ *
+ *
+ */
+VALUE_PAIR *pairnext(vp_cursor_t *cursor)
+{
+       if (!cursor->next) {
+               return NULL;
+       }
+       
+       cursor->next = cursor->next->next;
+       
+       return cursor->next;
+}
+
+VALUE_PAIR *paircurrent(vp_cursor_t *cursor)
+{
+       return cursor->next;
+}
+
+/** Insert a VP 
+ *
+ * @todo don't use with pairdelete
+ */
+void pairinsert(vp_cursor_t *cursor, VALUE_PAIR *add)
+{
+       VALUE_PAIR *i;
+
+       if (!add) {
+               return;
+       }
+       
+       VERIFY(add);
+
+       /*
+        *      Cursor was initialised with a pointer to a NULL value_pair
+        */
+       if (!*cursor->root) {
+               *cursor->root = add;
+               cursor->next = add;
+               cursor->last = add;
+               
+               return;
+       }
+       
+       /*
+        *      We don't yet know where the last VALUE_PAIR is
+        */
+       if (!cursor->last) {
+               for (i = cursor->next; i; i = i->next) {
+                       cursor->last = VERIFY(i);
+               }
+       }
+       
+       /*
+        *      Something outside of the cursor added another VALUE_PAIR
+        */
+       if (cursor->last->next) {
+               for (i = cursor->last; i; i = i->next) {
+                       cursor->last = VERIFY(i);
+               }
+       }
+       
+       cursor->last->next = add;
+}
 
 /** Delete matching pairs
  *
index 7380465..db1e4fc 100644 (file)
@@ -168,8 +168,8 @@ static int rad_authlog(char const *msg, REQUEST *request, int goodpass)
  */
 static int rad_check_password(REQUEST *request)
 {
+       vp_cursor_t cursor;
        VALUE_PAIR *auth_type_pair;
-       VALUE_PAIR *cur_config_item;
        int auth_type = -1;
        int result;
        int auth_type_count = 0;
@@ -180,17 +180,15 @@ static int rad_check_password(REQUEST *request)
         *      if the authentication type is PW_AUTHTYPE_ACCEPT or
         *      PW_AUTHTYPE_REJECT.
         */
-       cur_config_item = request->config_items;
-       while(((auth_type_pair = pairfind(cur_config_item, PW_AUTH_TYPE, 0, TAG_ANY))) != NULL) {
+       paircursor(&cursor, &request->config_items);
+       while ((auth_type_pair = pairfindnext(&cursor, PW_AUTH_TYPE, 0, TAG_ANY))) {
                auth_type = auth_type_pair->vp_integer;
                auth_type_count++;
 
-               RDEBUG2("Found Auth-Type = %s",
-                       dict_valnamebyattr(PW_AUTH_TYPE, 0, auth_type));
-               cur_config_item = auth_type_pair->next;
-
+               RDEBUG2("Found Auth-Type = %s", dict_valnamebyattr(PW_AUTH_TYPE, 0, auth_type));
                if (auth_type == PW_AUTHTYPE_REJECT) {
                        RDEBUG2("Auth-Type = Reject, rejecting user");
+                       
                        return -2;
                }
        }
@@ -199,7 +197,7 @@ static int rad_check_password(REQUEST *request)
         *      Warn if more than one Auth-Type was found, because only the last
         *      one found will actually be used.
         */
-       if (( auth_type_count > 1) && (debug_flag)) {
+       if ((auth_type_count > 1) && (debug_flag)) {
                RERROR("Warning:  Found %d auth-types on request for user '%s'",
                        auth_type_count, request->username->vp_strvalue);
        }
index 4474461..9293d0c 100644 (file)
@@ -1123,6 +1123,7 @@ static int null_socket_dencode(UNUSED rad_listen_t *listener, UNUSED REQUEST *re
 
 static int null_socket_send(UNUSED rad_listen_t *listener, REQUEST *request)
 {
+       vp_cursor_t cursor;
        char *output_file;
        FILE *fp;
        VALUE_PAIR *vp;
@@ -1158,7 +1159,9 @@ static int null_socket_send(UNUSED rad_listen_t *listener, REQUEST *request)
                                         request->reply->code, request->reply->id);
                }
 
-               for (vp = request->reply->vps; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, request->reply->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        vp_prints(buffer, sizeof(buffer), vp);
                        fprintf(fp, "%s\n", buffer);
                        if (debug_flag) {
@@ -1275,6 +1278,7 @@ static int command_inject_file(rad_listen_t *listener, int argc, char *argv[])
        fr_command_socket_t *sock = listener->data;
        rad_listen_t *fake;
        RADIUS_PACKET *packet;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp;
        FILE *fp;
        RAD_REQUEST_FUNP fun = NULL;
@@ -1358,7 +1362,9 @@ static int command_inject_file(rad_listen_t *listener, int argc, char *argv[])
                                          buffer, sizeof(buffer)),
                                packet->code, packet->id);
                
-               for (vp = packet->vps; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, &packet->vps); 
+                    vp;
+                    vp = pairnext(&cursor)) {
                        vp_prints(buffer, sizeof(buffer), vp);
                        DEBUG("\t%s", buffer);
                }
index dc0c6a7..6e814e5 100644 (file)
@@ -300,7 +300,8 @@ static int detail_open(rad_listen_t *this)
 int detail_recv(rad_listen_t *listener)
 {
        char            key[256], op[8], value[1024];
-       VALUE_PAIR      *vp, **tail;
+       vp_cursor_t     cursor;
+       VALUE_PAIR      *vp;
        RADIUS_PACKET   *packet;
        char            buffer[2048];
        listen_detail_t *data = listener->data;
@@ -469,8 +470,7 @@ int detail_recv(rad_listen_t *listener)
                        goto do_header;
        }
        
-       tail = &data->vps;
-       while (*tail) tail = &(*tail)->next;
+       paircursor(&cursor, &data->vps);
 
        /*
         *      Read a header, OR a value-pair.
@@ -563,8 +563,7 @@ int detail_recv(rad_listen_t *listener)
                        vp = paircreate(data, PW_PACKET_ORIGINAL_TIMESTAMP, 0);
                        if (vp) {
                                vp->vp_date = (uint32_t) data->timestamp;
-                               *tail = vp;
-                               tail = &(vp->next);
+                               pairinsert(&cursor, vp);
                        }
                        continue;
                }
@@ -578,8 +577,7 @@ int detail_recv(rad_listen_t *listener)
                vp = NULL;
                if ((userparse(data, buffer, &vp) > 0) &&
                    (vp != NULL)) {
-                       *tail = vp;
-                       tail = &(vp->next);
+                       pairinsert(&cursor, vp);
                }
        }
 
@@ -727,7 +725,9 @@ int detail_recv(rad_listen_t *listener)
 
        if (debug_flag) {
                fr_printf_log("detail_recv: Read packet from %s\n", data->filename_work);
-               for (vp = packet->vps; vp; vp = vp->next) {
+               for (vp = paircursor(&cursor, &packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        debug_pair(vp);
                }
        }
index fce597d..ca92748 100644 (file)
@@ -640,6 +640,7 @@ int radius_evaluate_cond(REQUEST *request, int modreturn, int depth,
 void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from)
 {
        int i, j, count, from_count, to_count, tailto;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp, *next, **last;
        VALUE_PAIR **from_list, **to_list;
        int *edited = NULL;
@@ -667,10 +668,10 @@ void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from)
         *      the matching attributes are deleted.
         */
        count = 0;
-       for (vp = from; vp != NULL; vp = vp->next) count++;
+       for (vp = paircursor(&cursor, &from); vp; vp = pairnext(&cursor)) count++;
        from_list = rad_malloc(sizeof(*from_list) * count);
 
-       for (vp = *to; vp != NULL; vp = vp->next) count++;
+       for (vp = paircursor(&cursor, *to); vp; vp = pairnext(&cursor)) count++;
        to_list = rad_malloc(sizeof(*to_list) * count);
 
        /*
index 515559b..5d4cf78 100644 (file)
@@ -148,6 +148,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request,
        envp[0] = NULL;
 
        if (input_pairs) {
+               vp_cursor_t cursor;
                int envlen;
                char buffer[1024];
 
@@ -159,7 +160,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request,
                 */
                envlen = 0;
 
-               for (vp = input_pairs; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, &input_pairs); vp; vp = pairnext(&cursor)) {
                        /*
                         *      Hmm... maybe we shouldn't pass the
                         *      user's password in an environment
index 0491a15..6e6b0c8 100644 (file)
@@ -321,8 +321,11 @@ int radlog(log_type_t type, char const *msg, ...)
  */
 void vp_listdebug(VALUE_PAIR *vp)
 {
+       vp_cursor_t cursor;
        char tmpPair[70];
-       for (; vp; vp = vp->next) {
+       for (vp = paircursor(&cursor, &vp);
+            vp;
+            vp = pairnext(&cursor)) {
                vp_prints(tmpPair, sizeof(tmpPair), vp);
                DEBUG2("     %s", tmpPair);
        }
index 6b0f05a..1f03f07 100644 (file)
@@ -396,6 +396,7 @@ static void pairfree_wrapper(void *data)
  */
 int modcall(int component, modcallable *c, REQUEST *request)
 {
+       vp_cursor_t cursor;
        int myresult, mypriority;
        modcall_stack stack;
        modcallable *parent, *child;
@@ -579,8 +580,8 @@ int modcall(int component, modcallable *c, REQUEST *request)
                                        if (myresult == MOD_ACTION_RETURN) {
                                                break;
                                        }
-                                       vp = pairfind(vp->next, vp->da->attr,
-                                                     vp->da->vendor, TAG_ANY);
+                                       paircursor(&cursor, &vp);
+                                       vp = pairfindnext(&cursor, vp->da->attr, vp->da->vendor, TAG_ANY);
 
                                        /*
                                         *      Delete the cached attribute,
index 127d587..4c8cb90 100644 (file)
@@ -278,6 +278,7 @@ static void tv_add(struct timeval *tv, int usec_delay)
 
 static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, int direction)
 {
+       vp_cursor_t cursor;
        VALUE_PAIR *vp;
        char buffer[1024];
        char const *received, *from;
@@ -320,7 +321,9 @@ static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, int direction)
                       packet->code, packet->id, packet->data_len);
        }
 
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &packet->vps);
+            vp; 
+            vp = pairnext(&cursor)) {
                vp_prints(buffer, sizeof(buffer), vp);
                RDEBUG("\t%s", buffer);
        }
@@ -2214,11 +2217,14 @@ static int request_will_proxy(REQUEST *request)
                 */
                vp = pairfind(request->proxy->vps, PW_USER_NAME, 0, TAG_ANY);
                if (!vp) {
+                       vp_cursor_t cursor;
                        vp = radius_paircreate(request, NULL,
                                               PW_USER_NAME, 0);
                        rad_assert(vp != NULL); /* handled by above function */
                        /* Insert at the START of the list */
-                       vp->next = request->proxy->vps;
+                       /* FIXME: Can't make assumptions about ordering */
+                       paircursor(&cursor, vp);
+                       pairinsert(&cursor, request->proxy->vps);
                        request->proxy->vps = vp;
                }
                pairstrcpy(vp, strippedname->vp_strvalue);
index 2d2fe28..b7f765f 100644 (file)
@@ -734,8 +734,11 @@ static void process_file(char const *filename)
                         *      it if so.
                         */
                        if (head) {
+                               vp_cursor_t cursor;
                                p = output;
-                               for (vp = head; vp != NULL; vp = vp->next) {
+                               for (vp = paircursor(&cursor, &head);
+                                    vp;
+                                    vp = pairnext(&cursor)) {
                                        vp_prints(p, sizeof(output) - (p - output), vp);
                                        p += strlen(p);
                                        
index bc221d9..1742a29 100644 (file)
@@ -208,6 +208,7 @@ static int mschapv1_encode(RADIUS_PACKET *packet, VALUE_PAIR **request,
 static int radclient_init(char const *filename)
 {
        FILE *fp;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp;
        radclient_t *radclient;
        int filedone = 0;
@@ -292,7 +293,9 @@ static int radclient_init(char const *filename)
                /*
                 *      Fix up Digest-Attributes issues
                 */
-               for (vp = radclient->request->vps; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, &radclient->request->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        if (!vp->da->vendor) switch (vp->da->attr) {
                        default:
                                break;
@@ -423,7 +426,6 @@ static int radclient_sane(radclient_t *radclient)
                                radclient->packet_number, radclient->filename);
                        return -1;
                }
-
                radclient->request->code = packet_code;
        }
        radclient->request->sockfd = -1;
index 0ec92ea..2702dda 100644 (file)
@@ -66,16 +66,19 @@ static char const *radsniff_version = "radsniff version " RADIUSD_VERSION_STRING
 
 static int filter_packet(RADIUS_PACKET *packet)
 {
+       vp_cursor_t cursor, check_cursor;
        VALUE_PAIR *check_item;
        VALUE_PAIR *vp;
        unsigned int pass, fail;
        int compare;
 
        pass = fail = 0;
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
-               for (check_item = filter_vps;
-                    check_item != NULL;
-                    check_item = check_item->next)
+       for (vp = paircursor(&cursor, &packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
+               for (check_item = paircursor(&check_cursor, &filter_vps);
+                    check_item;
+                    check_item = pairnext(&check_cursor))
                        if ((check_item->da == vp->da)
                         && (check_item->op != T_OP_SET)) {
                                compare = paircmp(check_item, vp);
@@ -148,11 +151,14 @@ static int filter_packet(RADIUS_PACKET *packet)
 static void sort(RADIUS_PACKET *packet)
 {
        int i, j, size;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp, *tmp;
        VALUE_PAIR *array[1024]; /* way more than necessary */
 
        size = 0;
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                array[size++] = vp;
        }
 
index 6fb0c03..d71b02c 100644 (file)
@@ -2482,12 +2482,15 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
                                if (vp_file == NULL) {
                                        RDEBUG2("Could not write session VPs to persistent cache: %s", strerror(errno));
                                } else {
+                                       vp_cursor_t cursor;
                                        /* generate a dummy user-style entry which is easy to read back */
                                        fprintf(vp_file, "# SSL cached session\n");
                                        fprintf(vp_file, "%s\n", buffer);
-                                       for (vp=vps; vp; vp = vp->next) {
+                                       for (vp = paircursor(&cursor, vps);
+                                            vp;
+                                            vp = pairnext(&cursor)) {
                                                vp_prints(buf, sizeof(buf), vp);
-                                               fprintf(vp_file, "\t%s%s\n", buf, vp->next ? "," : "");
+                                               fprintf(vp_file, "\t%s%s\n", buf, ",");
                                        }
                                        fclose(vp_file);
                                }
@@ -2518,11 +2521,14 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
                        return -1;
 
                } else {
-                       RDEBUG("Adding cached attributes for session %s:",
-                              buffer);
+                       vp_cursor_t cursor;
+                       
+                       RDEBUG("Adding cached attributes for session %s:", buffer);
                        debug_pair_list(vps);
 
-                       for (vp = vps; vp != NULL; vp = vp->next) {
+                       for (vp = paircursor(&cursor, vps);
+                            vp;
+                            vp = pairnext(&cursor)) {
                                /*
                                 *      TLS-* attrs get added back to
                                 *      the request list.
index 6ccbfc5..5aad540 100644 (file)
@@ -471,6 +471,7 @@ void paircompare_unregister_instance(void *instance)
 int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check,
                VALUE_PAIR **rep_list)
 {
+       vp_cursor_t cursor;
        VALUE_PAIR *check_item;
        VALUE_PAIR *auth_item;
        
@@ -478,9 +479,9 @@ int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check,
        int compare;
        int other;
 
-       for (check_item = check;
-            check_item != NULL;
-            check_item = check_item->next) {
+       for (check_item = paircursor(&cursor, check);
+            check_item;
+            check_item = pairnext(&cursor)) {
                /*
                 *      If the user is setting a configuration value,
                 *      then don't bother comparing it to any attributes
@@ -535,9 +536,7 @@ int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check,
        try_again:
                if (other >= 0) {
                        while (auth_item != NULL) {
-                               if ((auth_item->da->attr ==
-                                   (unsigned int) other) ||
-                                   (other == 0)) {
+                               if ((auth_item->da->attr == (unsigned int) other) || (other == 0)) {
                                        break;
                                }
                                auth_item = auth_item->next;
@@ -855,9 +854,12 @@ void debug_pair(VALUE_PAIR *vp)
  */
 void debug_pair_list(VALUE_PAIR *vp)
 {
+       vp_cursor_t cursor;
        if (!vp || !debug_flag || !fr_log_fp) return;
 
-       while (vp) {
+       for (vp = paircursor(&cursor, &vp);
+            vp;
+            vp = pairnext(&cursor)) {
                /*
                 *      Take this opportunity to verify all the VALUE_PAIRs are still valid.
                 */
@@ -869,7 +871,6 @@ void debug_pair_list(VALUE_PAIR *vp)
                }
                
                vp_print(fr_log_fp, vp);
-               vp = vp->next;
        }
        fflush(fr_log_fp);
 }
@@ -882,10 +883,13 @@ void debug_pair_list(VALUE_PAIR *vp)
  */
 void rdebug_pair_list(int level, REQUEST *request, VALUE_PAIR *vp)
 {
+       vp_cursor_t cursor;
        char buffer[256];
        if (!vp || !request || !request->radlog) return;
        
-       while (vp) {
+       for (vp = paircursor(&cursor, &vp);
+            vp;
+            vp = pairnext(&cursor)) {
                /*
                 *      Take this opportunity to verify all the VALUE_PAIRs are still valid.
                 */
@@ -899,7 +903,6 @@ void rdebug_pair_list(int level, REQUEST *request, VALUE_PAIR *vp)
                vp_prints(buffer, sizeof(buffer), vp);
                
                request->radlog(L_DBG, level, request, "\t%s", buffer);
-               vp = vp->next;
        }       
 }
 
@@ -998,6 +1001,7 @@ VALUE_PAIR **radius_list(REQUEST *request, pair_lists_t list)
 int radius_map2request(REQUEST *request, value_pair_map_t const *map,
                       UNUSED char const *src, radius_tmpl_getvalue_t func, void *ctx)
 {
+       vp_cursor_t cursor;
        VALUE_PAIR **list, *vp, *head;
        char buffer[MAX_STRING_LEN];
        
@@ -1023,7 +1027,7 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
                return -1;
        }
 
-       if (debug_flag) for (vp = head; vp != NULL; vp = vp->next) {
+       if (debug_flag) for (vp = paircursor(&cursor, &head); vp; vp = pairnext(&cursor)) {
                 rad_assert(vp->op == map->op);
 
                 vp_prints_value(buffer, sizeof(buffer), vp, 1);
index ab7d2db..26d4ff8 100644 (file)
@@ -455,7 +455,8 @@ static int fr_dhcp_attr2vp(RADIUS_PACKET *packet, VALUE_PAIR *vp, uint8_t const
 static int decode_tlv(RADIUS_PACKET *packet, VALUE_PAIR *tlv, uint8_t const *data, size_t data_len)
 {
        const uint8_t *p;
-       VALUE_PAIR *head, **tail, *vp;
+       VALUE_PAIR *head, *vp;
+       vp_cursor_t cursor;
 
        /*
         *      Take a pass at parsing it.
@@ -472,8 +473,8 @@ static int decode_tlv(RADIUS_PACKET *packet, VALUE_PAIR *tlv, uint8_t const *dat
         *      Got here... must be well formed.
         */
        head = NULL;
-       tail = &head;
-
+       paircursor(&cursor, &head);
+       
        p = data;
        while (p < (data + data_len)) {
                vp = paircreate(packet, tlv->da->attr | (p[0] << 8), DHCP_MAGIC_VENDOR);
@@ -487,8 +488,7 @@ static int decode_tlv(RADIUS_PACKET *packet, VALUE_PAIR *tlv, uint8_t const *dat
                        goto make_tlv;
                }
 
-               *tail = vp;
-               tail = &(vp->next);
+               pairinsert(&cursor, vp);
                p += 2 + p[1];
        }
 
@@ -585,12 +585,14 @@ ssize_t fr_dhcp_decode_options(RADIUS_PACKET *packet,
                               uint8_t const *data, size_t len, VALUE_PAIR **head)
 {
        int i;
-       VALUE_PAIR *vp, **tail;
+       VALUE_PAIR *vp;
+       vp_cursor_t cursor;
        uint8_t const *p, *next;
        next = data;
 
        *head = NULL;
-       tail = head;
+       paircursor(&cursor, &head);
+
        /*
         *      FIXME: This should also check sname && file fields.
         *      See the dhcp_get_option() function above.
@@ -680,10 +682,12 @@ ssize_t fr_dhcp_decode_options(RADIUS_PACKET *packet,
                                return -1;
                        }
 
-                       *tail = vp;
-                       while (*tail) {
-                               debug_pair(*tail);
-                               tail = &(*tail)->next;
+                       pairinsert(&cursor, vp);
+                       
+                       for (vp = paircurrent(&cursor);
+                            vp;
+                            vp = pairnext(&cursor)) {
+                               debug_pair(vp);
                        }
                        p += alen;
                } /* loop over array entries */
@@ -697,11 +701,12 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
        size_t i;
        uint8_t *p;
        uint32_t giaddr;
-       VALUE_PAIR *head, *vp, **tail;
+       vp_cursor_t cursor;
+       VALUE_PAIR *head, *vp;
        VALUE_PAIR *maxms, *mtu;
 
        head = NULL;
-       tail = &head;
+       paircursor(&cursor, &head);
        p = packet->data;
 
        if ((fr_debug_flag > 2) && fr_log_fp) {
@@ -791,8 +796,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                if (!vp) continue;
 
                debug_pair(vp);
-               *tail = vp;
-               tail = &vp->next;
+               pairinsert(&cursor, vp);
        }
 
        /*
@@ -803,10 +807,18 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
         *      Nothing uses tail after this call, if it does in the future
         *      it'll need to find the new tail...
         */
-       if (fr_dhcp_decode_options(packet,
-                                  packet->data + 240, packet->data_len - 240,
-                                  tail) < 0) {
-               return -1;
+       {
+               VALUE_PAIR *options = NULL;
+               
+               if (fr_dhcp_decode_options(packet,
+                                          packet->data + 240, packet->data_len - 240,
+                                          &options) < 0) {
+                       return -1;
+               }
+               
+               if (options) {
+                       pairinsert(&cursor, options);
+               }
        }
 
        /*
@@ -868,12 +880,6 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                maxms->vp_integer = mtu->vp_integer;
        }
 
-       if (fr_debug_flag > 0) {
-               for (vp = packet->vps; vp != NULL; vp = vp->next) {
-                       /* Print debug output here? */
-               }
-       }
-
        if (fr_debug_flag) fflush(stdout);
 
        return 0;
@@ -970,6 +976,7 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(RADIUS_PACKET *packet, VALUE_PAIR *vps)
        int length;
        unsigned int attribute;
        uint8_t *ptr;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp, *tlv;
 
        attribute = vps->da->attr & 0xffff00ff;
@@ -978,7 +985,9 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(RADIUS_PACKET *packet, VALUE_PAIR *vps)
        if (!tlv) return NULL;
 
        tlv->length = 0;
-       for (vp = vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &vps);
+            vp;
+            vp = pairnext(&cursor)) {
                /*
                 *      Group the attributes ONLY until we see a
                 *      non-TLV attribute.
@@ -1004,7 +1013,9 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(RADIUS_PACKET *packet, VALUE_PAIR *vps)
        }
 
        ptr = tlv->vp_tlv;
-       for (vp = vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &vps);
+            vp;
+            vp = pairnext(&cursor)) {
                if (!vp->da->flags.is_tlv ||
                    vp->da->flags.extended ||
                    ((vp->da->attr & 0xffff00ff) != attribute)) {
@@ -1035,6 +1046,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet)
 {
        unsigned int i, num_vps;
        uint8_t *p;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp;
        uint32_t lvalue, mms;
        size_t dhcp_size, length;
@@ -1314,30 +1326,31 @@ int fr_dhcp_encode(RADIUS_PACKET *packet)
         *      the later code.
         */
        num_vps = 0;
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                num_vps++;
        }
        if (num_vps > 1) {
-               VALUE_PAIR **array, **last;
+               VALUE_PAIR **array;
 
                array = talloc_array(packet, VALUE_PAIR*, num_vps);
 
                i = 0;
-               for (vp = packet->vps; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, &packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        array[i++] = vp;
                }
 
                /*
                 *      Sort the attributes.
                 */
-               qsort(array, (size_t) num_vps, sizeof(VALUE_PAIR *),
-                     attr_cmp);
+               qsort(array, (size_t) num_vps, sizeof(VALUE_PAIR *), attr_cmp);
 
-               last = &packet->vps;
+               paircursor(&cursor, &packet->vps);
                for (i = 0; i < num_vps; i++) {
-                       *last = array[i];
-                       array[i]->next = NULL;
-                       last = &(array[i]->next);
+                       pairinsert(&cursor, array[i]->next);
                }
                talloc_free(array);
        }
@@ -1366,7 +1379,9 @@ int fr_dhcp_encode(RADIUS_PACKET *packet)
 
                length = vp->length;
 
-               for (same = vp->next; same != NULL; same = same->next) {
+               for (same = paircursor(&cursor, &vp->next);
+                    same;
+                    same = pairnext(&cursor)) {
                        if (same->da->attr != vp->da->attr) break;
                        num_entries++;
                }
index e0311db..660edd3 100644 (file)
@@ -89,6 +89,7 @@ static void NEVER_RETURNS usage(void)
 static int request_init(char const *filename)
 {
        FILE *fp;
+       vp_cursor_t cursor;
        VALUE_PAIR *vp;
        int filedone = 0;
 
@@ -121,7 +122,7 @@ static int request_init(char const *filename)
        /*
         *      Fix / set various options
         */
-       for (vp = request->vps; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &request->vps); vp; vp = pairnext(&cursor)) {
                switch (vp->da->attr) {
                default:
                        break;
index 6a00981..53043ce 100644 (file)
@@ -48,7 +48,8 @@ typedef struct rlm_dhcp_t {
 static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
                                char const *fmt, char *out, size_t freespace)
 {
-       VALUE_PAIR *vp, *head = NULL, *next;
+       vp_cursor_t cursor;
+       VALUE_PAIR *vp, *head = NULL;
        int decoded = 0;
        
        while (isspace((int) *fmt)) fmt++;
@@ -67,13 +68,13 @@ static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
                goto fail;
        }
        
-       next = head;
-       
-       do {
-                next = next->next;
-                decoded++;
-       } while (next);
-       
+
+       for (vp = paircursor(&cursor, &head);
+            vp;
+            vp = pairnext(&cursor)) {
+               decoded++;
+       }
+
        pairmove(request->packet, &(request->packet->vps), &head);
        
        /* Free any unmoved pairs */
index a061383..e5913f1 100644 (file)
@@ -426,14 +426,14 @@ int vqp_decode(RADIUS_PACKET *packet)
 {
        uint8_t *ptr, *end;
        int attribute, length;
-       VALUE_PAIR *vp, **tail;
+       vp_cursor_t cursor;
+       VALUE_PAIR *vp;
 
        if (!packet || !packet->data) return -1;
 
        if (packet->data_len < VQP_HDR_LEN) return -1;
 
-       tail = &packet->vps;
-
+       paircursor(&cursor, &packet->vps);
        vp = paircreate(packet, PW_VQP_PACKET_TYPE, 0);
        if (!vp) {
                fr_strerror_printf("No memory");
@@ -441,9 +441,7 @@ int vqp_decode(RADIUS_PACKET *packet)
        }
        vp->vp_integer = packet->data[1];
        debug_pair(vp);
-
-       *tail = vp;
-       tail = &(vp->next);
+       pairinsert(&cursor, vp);
 
        vp = paircreate(packet, PW_VQP_ERROR_CODE, 0);
        if (!vp) {
@@ -452,10 +450,8 @@ int vqp_decode(RADIUS_PACKET *packet)
        }
        vp->vp_integer = packet->data[2];
        debug_pair(vp);
-
-       *tail = vp;
-       tail = &(vp->next);
-
+       pairinsert(&cursor, vp);
+       
        vp = paircreate(packet, PW_VQP_SEQUENCE_NUMBER, 0);
        if (!vp) {
                fr_strerror_printf("No memory");
@@ -463,9 +459,7 @@ int vqp_decode(RADIUS_PACKET *packet)
        }
        vp->vp_integer = packet->id; /* already set by vqp_recv */
        debug_pair(vp);
-
-       *tail = vp;
-       tail = &(vp->next);
+       pairinsert(&cursor, vp);
 
        ptr = packet->data + VQP_HDR_LEN;
        end = packet->data + packet->data_len;
@@ -525,9 +519,7 @@ int vqp_decode(RADIUS_PACKET *packet)
                }
                ptr += length;
                debug_pair(vp);
-
-               *tail = vp;
-               tail = &(vp->next);
+               pairinsert(&cursor, vp);
        }
 
        /*
index d3ff555..f512260 100644 (file)
@@ -75,6 +75,7 @@ static void check_pair(VALUE_PAIR *check_item, VALUE_PAIR *reply_item,
 
 static int attr_filter_getfile(TALLOC_CTX *ctx, char const *filename, PAIR_LIST **pair_list)
 {
+       vp_cursor_t cursor;
        int rcode;
        PAIR_LIST *attrs = NULL;
        PAIR_LIST *entry;
@@ -91,12 +92,12 @@ static int attr_filter_getfile(TALLOC_CTX *ctx, char const *filename, PAIR_LIST
 
        entry = attrs;
        while (entry) {
-
                entry->check = entry->reply;
                entry->reply = NULL;
 
-               for (vp = entry->check; vp != NULL; vp = vp->next) {
-
+               for (vp = paircursor(&cursor, &entry->check);
+                    vp;
+                    vp = pairnext(&cursor)) {
                    /*
                     * If it's NOT a vendor attribute,
                     * and it's NOT a wire protocol
@@ -141,25 +142,22 @@ static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
 /*
  *     Common attr_filter checks
  */
-static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
-                                     RADIUS_PACKET *packet)
+static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request, RADIUS_PACKET *packet)
 {
        rlm_attr_filter_t *inst = instance;
+       vp_cursor_t     cursor;
+       vp_cursor_t     out;
        VALUE_PAIR      *vp;
-       VALUE_PAIR      *output;
-       VALUE_PAIR      **output_tail;
+       VALUE_PAIR      *output, *input;
        VALUE_PAIR      *check_item;
        PAIR_LIST       *pl;
        int             found = 0;
        int             pass, fail = 0;
        char const      *keyname = NULL;
-       VALUE_PAIR      **input;
        char            buffer[256];
 
        if (!packet) return RLM_MODULE_NOOP;
 
-       input = &(packet->vps);
-
        if (!inst->key) {
                VALUE_PAIR      *namepair;
 
@@ -181,8 +179,11 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                keyname = buffer;
        }
 
+       /*
+        *      Head of the output list
+        */
        output = NULL;
-       output_tail = &output;
+       paircursor(&out, &output);
 
        /*
         *      Find the attr_filter profile entry for the entry.
@@ -201,13 +202,12 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                    continue;
                }
 
-               RDEBUG2("Matched entry %s at line %d", pl->name,
-                      pl->lineno);
+               RDEBUG2("Matched entry %s at line %d", pl->name, pl->lineno);
                found = 1;
 
-               for (check_item = pl->check;
-                       check_item != NULL;
-                       check_item = check_item->next) {
+               for (check_item = paircursor(&cursor, &pl->check);
+                    check_item;
+                    check_item = pairnext(&cursor)) {
                        if (!check_item->da->vendor &&
                            (check_item->da->attr == PW_FALL_THROUGH) &&
                                (check_item->vp_integer == 1)) {
@@ -227,11 +227,10 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                        if (check_item->op == T_OP_SET ) {
                                vp = paircopyvp(packet, check_item);
                                if (!vp) {
-                                       pairfree(&output);
-                                       return RLM_MODULE_FAIL;
+                                       goto error;
                                }
-                               radius_xlat_move(request, output_tail, &vp);
-                               output_tail = &((*output_tail)->next);
+                               radius_xlat_do(request, vp);
+                               pairinsert(&out, vp);
                        }
                }
 
@@ -243,7 +242,9 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                 *      only if it matches all rules that describe an
                 *      Idle-Timeout.
                 */
-               for (vp = *input; vp != NULL; vp = vp->next ) {
+               for (input = paircursor(&cursor, &packet->vps);
+                    input;
+                    input = pairnext(&cursor)) {
                        /* reset the pass,fail vars for each reply item */
                        pass = fail = 0;
 
@@ -251,24 +252,22 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                         *      reset the check_item pointer to
                         *      beginning of the list
                         */
-                       for (check_item = pl->check;
-                            check_item != NULL;
-                            check_item = check_item->next) {
+                       for (check_item = pairfirst(&cursor);
+                            check_item;
+                            check_item = pairnext(&cursor)) {
                                /*
                                 *      Vendor-Specific is special, and
                                 *      matches any VSA if the comparison
                                 *      is always true.
                                 */
-                               if ((check_item->da->attr == PW_VENDOR_SPECIFIC) &&
-                                       (vp->da->vendor != 0) &&
-                                       (check_item->op == T_OP_CMP_TRUE)) {
+                               if ((check_item->da->attr == PW_VENDOR_SPECIFIC) && (input->da->vendor != 0) &&
+                                   (check_item->op == T_OP_CMP_TRUE)) {
                                        pass++;
                                        continue;
                                }
 
                                if (vp->da->attr == check_item->da->attr) {
-                                       check_pair(check_item, vp,
-                                                  &pass, &fail);
+                                       check_pair(check_item, input, &pass, &fail);
                                }
                        }
 
@@ -281,18 +280,18 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                                if (!pass) {
                                        RDEBUG3("Attribute (%s) allowed by relaxed mode", vp->da->name);
                                }
-                               *output_tail = paircopyvp(packet, vp);
-                               if (!*output_tail) {
-                                       pairfree(&output);
-                                       return RLM_MODULE_FAIL;
+                               vp = paircopyvp(packet, vp);
+                               if (!vp) {
+                                       goto error;
                                }
-                               output_tail = &((*output_tail)->next);
+                               pairinsert(&out, vp);
                        }
                }
 
                /* If we shouldn't fall through, break */
-               if (!fall_through)
+               if (!fall_through) {
                        break;
+               }
        }
 
        /*
@@ -303,8 +302,11 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
                return RLM_MODULE_NOOP;
        }
 
-       pairfree(input);
-       *input = output;
+       /*
+        *      Replace the existing request list with our filtered one
+        */
+       pairfree(&packet->vps);
+       packet->vps = output;
 
        if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
                request->username = pairfind(request->packet->vps, PW_STRIPPED_USER_NAME, 0, TAG_ANY);
@@ -314,6 +316,10 @@ static rlm_rcode_t attr_filter_common(void *instance, REQUEST *request,
        }
 
        return RLM_MODULE_UPDATED;
+       
+       error:
+       pairfree(&output);
+       return RLM_MODULE_FAIL;
 }
 
 #define RLM_AF_FUNC(_x, _y) static rlm_rcode_t mod_##_x(void *instance, REQUEST *request) \
index a39ba15..934c9fe 100644 (file)
@@ -394,30 +394,28 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
                                
                                break;
                        case T_OP_ADD:
-                               do {
-                                       vp = map->dst->type == VPT_TYPE_LIST ?
-                                               paircopyvp(c, found) :
-                                               paircopyvpdata(c, map->dst->da,
-                                                              found);
-                                       if (!vp) continue;
+                               {
+                                       vp_cursor_t cursor;
                                        
-                                       vp->op = map->op;
-                                       pairadd(to_cache, vp);
+                                       for (found = paircursor(&cursor, &found);
+                                            found;
+                                            found = pairfindnext(&cursor, da->attr, da->vendor, TAG_ANY)) {
+                                               vp = map->dst->type == VPT_TYPE_LIST ?
+                                                       paircopyvp(c, found) :
+                                                       paircopyvpdata(c, map->dst->da, found);
+                                               if (!vp) continue;
                                        
-                                       if (to_req) {
-                                               vp = paircopyvp(request, vp);
-                                               radius_pairmove(request, to_req,
-                                                               vp);
-                                                               
-                                       }
+                                               vp->op = map->op;
+                                               pairadd(to_cache, vp);
                                        
-                                       found = pairfind(found->next,
-                                                        da->attr,
-                                                        da->vendor,
-                                                        TAG_ANY);
-                               } while (found);
+                                               if (to_req) {
+                                                       vp = paircopyvp(request, vp);
+                                                       radius_pairmove(request, to_req, vp);
                                                                
-                               break;
+                                               }
+                                       }                       
+                                       break;
+                               }
                                
                        default:
                                rad_assert(0);
@@ -425,35 +423,40 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
                        }
                        break;
                case VPT_TYPE_LIST:
-                       rad_assert(map->src->type == VPT_TYPE_LIST);
+                       {
+                               vp_cursor_t cursor;
+                               VALUE_PAIR *i;
+                               
+                               rad_assert(map->src->type == VPT_TYPE_LIST);
                        
-                       from = NULL;
-                       context = request;
-                       if (radius_request(&context, map->src->request) == 0) {
-                               from = radius_list(context, map->src->list);
-                       }
-                       if (!from) continue;
+                               from = NULL;
+                               context = request;
+                               if (radius_request(&context, map->src->request) == 0) {
+                                       from = radius_list(context, map->src->list);
+                               }
+                               if (!from) continue;
                        
-                       found = paircopy(c, *from);
-                       if (!found) continue;
+                               found = paircopy(c, *from);
+                               if (!found) continue;
                        
-                       for (vp = found; vp != NULL; vp = vp->next) {
-                               RDEBUG("\t%s %s %s (%s)", map->dst->name,
-                                      fr_int2str(fr_tokens, map->op,
-                                                 "¿unknown?"),
-                                      map->src->name,
-                                      vp->da->name);
-                               vp->op = map->op;
-                       }
+                               for (i = paircursor(&cursor, &vp);
+                                    i != NULL;
+                                    i = pairnext(&cursor)) {
+                                       RDEBUG("\t%s %s %s (%s)", map->dst->name,
+                                              fr_int2str(fr_tokens, map->op, "¿unknown?"),
+                                              map->src->name, i->da->name);
+                                       i->op = map->op;
+                               }
                        
-                       pairadd(to_cache, found);
+                               pairadd(to_cache, found);
                        
-                       if (to_req) {
-                               vp = paircopy(request, found);
-                               radius_pairmove(request, to_req, vp);
-                       }
+                               if (to_req) {
+                                       vp = paircopy(request, found);
+                                       radius_pairmove(request, to_req, vp);
+                               }
                        
-                       break;
+                               break;
+                       }
                /*
                 *      It was most likely a double quoted string that now
                 *      needs to be expanded.
index 9bbf31a..e76f7ae 100644 (file)
@@ -414,20 +414,25 @@ static rlm_rcode_t do_detail(void *instance, REQUEST *request, RADIUS_PACKET *pa
                vp_print(fp, &dst_vp);
        }
 
-       /* Write each attribute/value to the log file */
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
-               if (inst->ht &&
-                   fr_hash_table_finddata(inst->ht, &vp->da)) continue;
+       {
+               vp_cursor_t cursor;
+               /* Write each attribute/value to the log file */
+               for (vp = paircursor(&cursor, &packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
+                       if (inst->ht &&
+                           fr_hash_table_finddata(inst->ht, &vp->da)) continue;
 
-               /*
-                *      Don't print passwords in old format...
-                */
-               if (compat && !vp->da->vendor && (vp->da->attr == PW_USER_PASSWORD)) continue;
+                       /*
+                        *      Don't print passwords in old format...
+                        */
+                       if (compat && !vp->da->vendor && (vp->da->attr == PW_USER_PASSWORD)) continue;
 
-               /*
-                *      Print all of the attributes.
-                */
-               vp_print(fp, vp);
+                       /*
+                        *      Print all of the attributes.
+                        */
+                       vp_print(fp, vp);
+               }
        }
 
        /*
index 4fc0683..7f27e41 100644 (file)
@@ -28,28 +28,21 @@ RCSID("$Id$")
 
 static int digest_fix(REQUEST *request)
 {
-       VALUE_PAIR *vp;
-
+       VALUE_PAIR *first, *i;
+       vp_cursor_t cursor;
+       
        /*
         *      We need both of these attributes to do the authentication.
         */
-       vp = pairfind(request->packet->vps, PW_DIGEST_RESPONSE, 0, TAG_ANY);
-       if (!vp) {
+       first = pairfind(request->packet->vps, PW_DIGEST_RESPONSE, 0, TAG_ANY);
+       if (!first) {
                return RLM_MODULE_NOOP;
        }
 
        /*
         *      Check the sanity of the attribute.
         */
-       if (vp->length != 32) {
-               return RLM_MODULE_NOOP;
-       }
-
-       /*
-        *      We need these, too.
-        */
-       vp = pairfind(request->packet->vps, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY);
-       if (!vp) {
+       if (first->length != 32) {
                return RLM_MODULE_NOOP;
        }
 
@@ -57,10 +50,17 @@ static int digest_fix(REQUEST *request)
         *      Check for proper format of the Digest-Attributes
         */
        RDEBUG("Checking for correctly formatted Digest-Attributes");
-       while (vp) {
-               int length = vp->length;
+       
+       first = pairfind(request->packet->vps, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY);
+       if (!first) {
+               return RLM_MODULE_NOOP;
+       }
+       
+       paircursor(&cursor, &first);
+       while ((i = pairfindnext(&cursor, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY))) {
+               int length = i->length;
                int attrlen;
-               uint8_t const *p = vp->vp_octets;
+               uint8_t const *p = i->vp_octets;
 
                /*
                 *      Until this stupidly encoded attribute is exhausted.
@@ -95,22 +95,17 @@ static int digest_fix(REQUEST *request)
                        length -= attrlen;
                        p += attrlen;
                } /* loop over this one attribute */
-
-               /*
-                *      Find the next one, if it exists.
-                */
-               vp = pairfind(vp->next, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY);
        }
 
        /*
         *      Convert them to something sane.
         */
-       RDEBUG("Digest-Attributes look OK.  Converting them to something more usful.");
-       vp = pairfind(request->packet->vps, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY);
-       while (vp) {
-               int length = vp->length;
+       RDEBUG("Digest-Attributes look OK.  Converting them to something more useful.");
+       pairfirst(&cursor);
+       while ((i = pairfindnext(&cursor, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY))) {
+               int length = i->length;
                int attrlen;
-               uint8_t const *p = vp->vp_octets;
+               uint8_t const *p = &i->vp_octets[0];
                char *q;
                VALUE_PAIR *sub;
 
@@ -169,11 +164,6 @@ static int digest_fix(REQUEST *request)
                        length -= attrlen;
                        p += attrlen;
                } /* loop over this one attribute */
-
-               /*
-                *      Find the next one, if it exists.
-                */
-               vp = pairfind(vp->next, PW_DIGEST_ATTRIBUTES, 0, TAG_ANY);
        }
 
        return RLM_MODULE_OK;
index e62753b..4ae1b0b 100644 (file)
@@ -1095,13 +1095,10 @@ eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p,
                        *       correctly
                        */
                       RDEBUG2("Broken NAS did not set User-Name, setting from EAP Identity");
-                      vp = pairmake(request->packet, NULL, "User-Name", handler->identity, T_OP_EQ);
+                      vp = pairmake(request->packet, &request->packet->vps, "User-Name", handler->identity, T_OP_EQ);
                       if (!vp) {
                               goto error;
                       }
-                      vp->next = request->packet->vps;
-                      request->packet->vps = vp;
-
               } else {
                       /*
                        *      A little more paranoia.  If the NAS
@@ -1145,12 +1142,10 @@ eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p,
                        *       correctly
                        */
                       RWDEBUG2("NAS did not set User-Name.  Setting it locally from EAP Identity");
-                      vp = pairmake(request->packet, NULL, "User-Name", handler->identity, T_OP_EQ);
+                      vp = pairmake(request->packet, &request->packet->vps, "User-Name", handler->identity, T_OP_EQ);
                       if (!vp) {
                               goto error2;
                       }
-                      vp->next = request->packet->vps;
-                      request->packet->vps = vp;
               } else {
                       /*
                        *      Paranoia.  If the NAS *did* set the
index 327ff7b..5930fd0 100644 (file)
@@ -252,8 +252,8 @@ VALUE_PAIR *eap_packet2vp(RADIUS_PACKET *packet, eap_packet_raw_t const *eap)
        int             total, size;
        const uint8_t   *ptr;
        VALUE_PAIR      *head = NULL;
-       VALUE_PAIR      **tail = &head;
        VALUE_PAIR      *vp;
+       vp_cursor_t     out;
 
        total = eap->length[0] * 256 + eap->length[1];
 
@@ -264,6 +264,7 @@ VALUE_PAIR *eap_packet2vp(RADIUS_PACKET *packet, eap_packet_raw_t const *eap)
 
        ptr = (uint8_t const *) eap;
 
+       paircursor(&out, &head);
        do {
                size = total;
                if (size > 253) size = 253;
@@ -275,8 +276,7 @@ VALUE_PAIR *eap_packet2vp(RADIUS_PACKET *packet, eap_packet_raw_t const *eap)
                }
                pairmemcpy(vp, ptr, size);
 
-               *tail = vp;
-               tail = &(vp->next);
+               pairinsert(&out, vp);
 
                ptr += size;
                total -= size;
@@ -295,11 +295,12 @@ VALUE_PAIR *eap_packet2vp(RADIUS_PACKET *packet, eap_packet_raw_t const *eap)
  */
 eap_packet_raw_t *eap_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps)
 {
-       VALUE_PAIR *first, *vp;
+       VALUE_PAIR *first, *i;
        eap_packet_raw_t *eap_packet;
        unsigned char *ptr;
        uint16_t len;
        int total_len;
+       vp_cursor_t cursor;
 
        /*
         *      Get only EAP-Message attribute list
@@ -337,8 +338,9 @@ eap_packet_raw_t *eap_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps)
         *      Sanity check the length, BEFORE allocating  memory.
         */
        total_len = 0;
-       for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               total_len += vp->length;
+       paircursor(&cursor, &first);
+       while ((i = pairfindnext(&cursor, PW_EAP_MESSAGE, 0, TAG_ANY))) {
+               total_len += i->length;
 
                if (total_len > len) {
                        DEBUG("rlm_eap: Malformed EAP packet.  Length in packet header does not match actual length");
@@ -368,9 +370,10 @@ eap_packet_raw_t *eap_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps)
        ptr = (unsigned char *)eap_packet;
 
        /* RADIUS ensures order of attrs, so just concatenate all */
-       for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               memcpy(ptr, vp->vp_strvalue, vp->length);
-               ptr += vp->length;
+       pairfirst(&cursor);
+       while ((i = pairfindnext(&cursor, PW_EAP_MESSAGE, 0, TAG_ANY))) {
+               memcpy(ptr, i->vp_strvalue, i->length);
+               ptr += i->length;
        }
 
        return eap_packet;
index 1c6afe8..3e0e4ae 100644 (file)
@@ -70,6 +70,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, eap_packet_t *ep)
        uint8_t const   *append;
        int             appendlen;
        unsigned char   subtype;
+       vp_cursor_t     cursor;
 
        macspace = NULL;
        append = NULL;
@@ -94,7 +95,9 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, eap_packet_t *ep)
         * that we need to encode all of this.
         */
        encoded_size = 0;
-       for (vp = r->vps; vp; vp = vp->next) {
+       for (vp = paircursor(&cursor, &r->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                int roundedlen;
                int vplen;
 
@@ -160,8 +163,6 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, eap_packet_t *ep)
         * SIM code adds a subtype, and 2 bytes of reserved = 3.
         *
         */
-
-
        encoded_size += 3;
        encodedmsg = talloc_array(ep, uint8_t, encoded_size);
        if (!encodedmsg) {
@@ -178,7 +179,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, eap_packet_t *ep)
         */
        attr = encodedmsg+3;
 
-       for(vp = r->vps; vp != NULL; vp = vp->next) {
+       for (vp = pairfirst(&cursor); vp; vp = pairnext(&cursor)) {
                int roundedlen;
 
                if(vp->da->attr < ATTRIBUTE_EAP_SIM_BASE ||
index 15f9a8a..f506739 100644 (file)
@@ -549,6 +549,7 @@ static rlm_rcode_t mod_post_proxy(void *inst, REQUEST *request)
        char            *p;
        VALUE_PAIR      *vp;
        eap_handler_t   *handler;
+       vp_cursor_t     cursor;
 
        /*
         *      Just in case the admin lists EAP in post-proxy-type Fail.
@@ -640,7 +641,7 @@ static rlm_rcode_t mod_post_proxy(void *inst, REQUEST *request)
         *      There may be more than one Cisco-AVPair.
         *      Ensure we find the one with the LEAP attribute.
         */
-       vp = request->proxy_reply->vps;
+       paircursor(&cursor, &request->proxy_reply->vps);
        for (;;) {
                /*
                 *      Hmm... there's got to be a better way to
@@ -649,7 +650,7 @@ static rlm_rcode_t mod_post_proxy(void *inst, REQUEST *request)
                 *      This is vendor Cisco (9), Cisco-AVPair
                 *      attribute (1)
                 */
-               vp = pairfind(vp, 1, 9, TAG_ANY);
+               vp = pairfindnext(&cursor, 1, 9, TAG_ANY);
                if (!vp) {
                        return RLM_MODULE_NOOP;
                }
@@ -662,11 +663,6 @@ static rlm_rcode_t mod_post_proxy(void *inst, REQUEST *request)
                if (strncasecmp(vp->vp_strvalue, "leap:session-key=", 17) == 0) {
                        break;
                }
-
-               /*
-                *      Not this AV-pair.  Go to the next one.
-                */
-               vp = vp->next;
        }
 
        /*
index 919e200..5765f09 100644 (file)
@@ -270,7 +270,8 @@ static VALUE_PAIR *eap2vp(REQUEST *request, RADIUS_PACKET *packet,
 {
        size_t total;
        uint8_t *p;
-       VALUE_PAIR *vp = NULL, *head, **tail;
+       VALUE_PAIR *vp = NULL, *head = NULL;
+       vp_cursor_t cursor;
 
        if (data_len > 65535) return NULL; /* paranoia */
 
@@ -296,8 +297,8 @@ static VALUE_PAIR *eap2vp(REQUEST *request, RADIUS_PACKET *packet,
 
        memcpy(p + EAP_HEADER_LEN, data, total);
 
-       head = vp;
-       tail = &(vp->next);
+       paircursor(&cursor, &head);
+       pairinsert(&cursor, vp);
        while (total < data_len) {
                vp = paircreate(packet, PW_EAP_MESSAGE, 0);
                if (!vp) {
@@ -309,8 +310,8 @@ static VALUE_PAIR *eap2vp(REQUEST *request, RADIUS_PACKET *packet,
                pairmemcpy(vp, data + total, (data_len - total));
                
                total += vp->length;
-               *tail = vp;
-               tail = &(vp->next);
+
+               pairinsert(&cursor, vp);
        }
 
        return head;
@@ -324,6 +325,8 @@ static VALUE_PAIR *eap2vp(REQUEST *request, RADIUS_PACKET *packet,
 static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp)
 {
        rad_assert(vp != NULL);
+       VALUE_PAIR *this;
+       vp_cursor_t cursor;
 
        /*
         *      Skip the id, code, and length.  Just write the EAP
@@ -331,42 +334,44 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp)
         */
 #ifndef NDEBUG
        if ((debug_flag > 2) && fr_log_fp) {
-               size_t i, total;
-               VALUE_PAIR *this;
-
+               size_t i, total, start = EAP_HEADER_LEN;
                total = 0;
 
-               for (this = vp; this != NULL; this = this->next) {
-                       int start = 0;
-
-                       if (this == vp) start = EAP_HEADER_LEN;
-                       
+               for (this = paircursor(&cursor, &vp); this; this = pairnext(&cursor)) {
                        for (i = start; i < vp->length; i++) {
-                         if ((total & 0x0f) == 0) fprintf(fr_log_fp, "  PEAP tunnel data out %04x: ", (int) total);
-
+                               if ((total & 0x0f) == 0) {
+                                       fprintf(fr_log_fp, "  PEAP tunnel data out %04x: ", (int) total);
+                               }               
                                fprintf(fr_log_fp, "%02x ", vp->vp_octets[i]);
                                
-                               if ((total & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");
+                               if ((total & 0x0f) == 0x0f) {
+                                       fprintf(fr_log_fp, "\n");
+                               }
+                               
                                total++;
                        }
+                       
+                       start = 0;
+               }
+               
+               if ((total & 0x0f) != 0) {
+                       fprintf(fr_log_fp, "\n");
                }
-               if ((total & 0x0f) != 0) fprintf(fr_log_fp, "\n");
        }
 #endif
 
        /*
         *      Send the EAP data, WITHOUT the header.
         */
-       (tls_session->record_plus)(&tls_session->clean_in,
-                                  vp->vp_octets + EAP_HEADER_LEN,
-                                  vp->length - EAP_HEADER_LEN);
+       (tls_session->record_plus)(&tls_session->clean_in, vp->vp_octets + EAP_HEADER_LEN, vp->length - EAP_HEADER_LEN);
        
        /*
         *      Send the rest of the EAP data.
         */
-       for (vp = vp->next; vp != NULL; vp = vp->next) {
-               (tls_session->record_plus)(&tls_session->clean_in,
-                                          vp->vp_octets, vp->length);
+       for (this = paircursor(&cursor, &vp);
+            this;
+            this = pairnext(&cursor)) {
+               (tls_session->record_plus)(&tls_session->clean_in, this->vp_octets, this->length);
        }
 
        tls_handshake_send(request, tls_session);
@@ -1247,14 +1252,16 @@ static int setup_fake_request(REQUEST *request, REQUEST *fake, peap_tunnel_t *t)
         */
        if (t->copy_request_to_tunnel) {
                VALUE_PAIR *copy;
+               vp_cursor_t cursor;
 
-               for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
+               for (vp = paircursor(&cursor, &request->packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        /*
                         *      The attribute is a server-side thingy,
                         *      don't copy it.
                         */
-                       if ((vp->da->attr > 255) &&
-                           (((vp->da->attr >> 16) & 0xffff) == 0)) {
+                       if ((vp->da->attr > 255) && (((vp->da->attr >> 16) & 0xffff) == 0)) {
                                continue;
                        }
 
index 9f3defc..bb321bc 100644 (file)
@@ -144,11 +144,13 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,
        size_t          size;
        size_t          data_left = data_len;
        char            *p;
-       VALUE_PAIR      *first = NULL;
-       VALUE_PAIR      **last = &first;
+       VALUE_PAIR      *first;
        VALUE_PAIR      *vp;
        RADIUS_PACKET   *packet = fake->packet; /* FIXME: api issues */
-
+       vp_cursor_t     out;
+       
+       paircursor(&out, &first);
+       
        while (data_left > 0) {
                rad_assert(data_left <= data_len);
                memcpy(&attr, data, sizeof(attr));
@@ -198,8 +200,7 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,
                 *      Normal attributes cannot be.
                 */
                if ((attr > 255) && (vendor == 0)) {
-                       RWDEBUG2("Skipping Diameter attribute %u",
-                               attr);
+                       RWDEBUG2("Skipping Diameter attribute %u", attr);
                        goto next_attr;
                }
 
@@ -247,11 +248,7 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,
                                goto do_octets;
                        }
 
-                       *last = vp;
-                       do {
-                               last = &(vp->next);
-                               vp = vp->next;
-                       } while (vp != NULL);
+                       pairinsert(&out, vp);
 
                        goto next_attr;
                }
@@ -418,8 +415,7 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,
                /*
                 *      Update the list.
                 */
-               *last = vp;
-               last = &(vp->next);
+               pairinsert(&out, vp);
 
        next_attr:
                /*
@@ -469,11 +465,12 @@ static int vp2diameter(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR
        size_t          total;
        uint64_t        attr64;
        VALUE_PAIR      *vp;
+       vp_cursor_t     cursor;
 
        p = buffer;
        total = 0;
 
-       for (vp = first; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &first); vp; vp = pairnext(&cursor)) {
                /*
                 *      Too much data: die.
                 */
@@ -1097,8 +1094,9 @@ int eapttls_process(eap_handler_t *handler, tls_session_t *tls_session)
         */
        if (t->copy_request_to_tunnel) {
                VALUE_PAIR *copy;
-
-               for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
+               vp_cursor_t cursor;
+               
+               for (vp = paircursor(&cursor, &request->packet->vps); vp; vp = pairnext(&cursor)) {
                        /*
                         *      The attribute is a server-side thingy,
                         *      don't copy it.
index 70fbc47..782c9b0 100644 (file)
@@ -151,6 +151,7 @@ static int getusersfile(TALLOC_CTX *ctx, char const *filename, fr_hash_table_t *
 
                entry = users;
                while (entry) {
+                       vp_cursor_t cursor;
                        if (compat_mode) {
                                DEBUG("[%s]:%d Cistron compatibility checks for entry %s ...",
                                                filename, entry->lineno,
@@ -164,7 +165,7 @@ static int getusersfile(TALLOC_CTX *ctx, char const *filename, fr_hash_table_t *
                         *      and probably ':=' for server
                         *      configuration items.
                         */
-                       for (vp = entry->check; vp != NULL; vp = vp->next) {
+                       for (vp = paircursor(&cursor, &entry->check); vp; vp = pairnext(&cursor)) {
                                /*
                                 *      Ignore attributes which are set
                                 *      properly.
@@ -231,7 +232,7 @@ static int getusersfile(TALLOC_CTX *ctx, char const *filename, fr_hash_table_t *
                         *      It's a common enough mistake, that it's
                         *      worth doing.
                         */
-                       for (vp = entry->reply; vp != NULL; vp = vp->next) {
+                       for (vp = paircursor(&cursor, &entry->reply); vp; vp = pairnext(&cursor)) {
                                /*
                                 *      If it's NOT a vendor attribute,
                                 *      and it's NOT a wire protocol
index 17cb9f6..3792de6 100644 (file)
 static VALUE_PAIR *rlm_ldap_map_getvalue(REQUEST *request, value_pair_map_t const *map, void *ctx)
 {
        rlm_ldap_result_t *self = ctx;
-       VALUE_PAIR *head, **tail, *vp;
+       VALUE_PAIR *head = NULL, *vp;
+       vp_cursor_t out;
        int i;
        
-       head = NULL;
-       tail = &head;
+       paircursor(&out, &head);
        
        /*
         *      Iterate over all the retrieved values,
@@ -52,8 +52,7 @@ static VALUE_PAIR *rlm_ldap_map_getvalue(REQUEST *request, value_pair_map_t cons
                }
                
                vp->op = map->op;
-               *tail = vp;
-               tail = &(vp->next);
+               pairinsert(&out, vp);
        }
        
        return head;            
index 505305a..6a1d625 100644 (file)
@@ -686,9 +686,10 @@ rlm_rcode_t rlm_ldap_check_cached(ldap_instance_t const *inst, REQUEST *request,
 {
        VALUE_PAIR      *vp;
        int             ret;
+       vp_cursor_t     cursor;
 
-       vp = request->config_items;
-       while ((vp = pairfind(vp, inst->group_da->attr, inst->group_da->vendor, TAG_ANY))) {
+       paircursor(&cursor, &request->config_items);
+       while ((vp = pairfindnext(&cursor, inst->group_da->attr, inst->group_da->vendor, TAG_ANY))) {
                ret = radius_compare_vps(request, check, vp);
                if (ret == 0) {
                        RDEBUG2("User found. Matched cached membership");
@@ -698,7 +699,6 @@ rlm_rcode_t rlm_ldap_check_cached(ldap_instance_t const *inst, REQUEST *request,
                if (ret < 0) {
                        return RLM_MODULE_FAIL;
                }
-               vp = vp->next;
        }
        
        RDEBUG2("Membership not found");
index 81868ab..405693e 100644 (file)
@@ -1457,9 +1457,13 @@ static rlm_rcode_t mod_authenticate(void * instance, REQUEST *request)
                 * 06:<mschapid>:00:02:<2nd chunk>
                 * 06:<mschapid>:00:03:<3rd chunk>
                 */
-               for (seq=1;seq<4;seq++) {
-                       int found=0;
-                       for (nt_enc=request->packet->vps; nt_enc; nt_enc=nt_enc->next) {
+               for (seq = 1; seq < 4; seq++) {
+                       vp_cursor_t cursor;
+                       int found = 0;
+                       
+                       for (nt_enc = paircursor(&cursor, &request->packet->vps);
+                            nt_enc;
+                            nt_enc = pairnext(&cursor)) {
                                if (nt_enc->da->vendor != VENDORPEC_MICROSOFT)
                                        continue;
 
index 10b0691..0b3922a 100644 (file)
@@ -160,11 +160,12 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
        rlm_pap_t *inst = instance;
        int auth_type = false;
        int found_pw = false;
-       VALUE_PAIR *vp, *next;
-
-       for (vp = request->config_items; vp != NULL; vp = next) {
-               next = vp->next;
-
+       VALUE_PAIR *vp;
+       vp_cursor_t cursor;
+       
+       for (vp = paircursor(&cursor, &request->config_items);
+            vp;
+            vp = pairnext(&cursor)) {
                switch (vp->da->attr) {
                case PW_USER_PASSWORD: /* deprecated */
                        RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
@@ -621,7 +622,9 @@ static rlm_rcode_t mod_authenticate(UNUSED void *instance, REQUEST *request)
 {
        VALUE_PAIR *vp;
        rlm_rcode_t rc = RLM_MODULE_INVALID;
+       vp_cursor_t cursor;
        int (*auth_func)(REQUEST *, VALUE_PAIR *) = NULL;
+       
 
        if (!request->password ||
            (request->password->da->attr != PW_USER_PASSWORD)) {
@@ -644,7 +647,9 @@ static rlm_rcode_t mod_authenticate(UNUSED void *instance, REQUEST *request)
         *      config items, to find out which authentication
         *      function to call.
         */
-       for (vp = request->config_items; vp != NULL; vp = vp->next) {
+       for (vp = paircursor(&cursor, &request->config_items);
+            vp;
+            vp = pairnext(&cursor)) {
                if (!vp->da->vendor) switch (vp->da->attr) {
                case PW_CLEARTEXT_PASSWORD:
                        auth_func = &pap_auth_clear;
index 1e97706..1ab1a86 100644 (file)
@@ -352,7 +352,7 @@ int main(void){
                buffer[strlen(buffer)-1] = 0;
                pw = get_pw_nam(buffer, ht, &last_found);
                printpw(pw,4);
-               while (pw = get_next(buffer, ht, &last_found)) printpw(pw,4);
+               while ((pw = get_next(buffer, ht, &last_found))) printpw(pw,4);
        }
        release_ht(ht);
 }
@@ -518,31 +518,36 @@ static rlm_rcode_t passwd_map(void *instance, REQUEST *request)
 {
 #define inst ((struct passwd_instance *)instance)
        char buffer[1024];
-       VALUE_PAIR * key;
+       VALUE_PAIR *key, *i;
        struct mypasswd * pw, *last_found;
-       int found = 0;
+       vp_cursor_t cursor;
 
-       for (key = request->packet->vps;
-            key && (key = pairfind(key, inst->keyattr->attr, inst->keyattr->vendor, TAG_ANY));
-            key = key->next ){
+       key = pairfind(request->packet->vps, inst->keyattr->attr, inst->keyattr->vendor, TAG_ANY);
+       if (!key) {
+               return RLM_MODULE_NOTFOUND;
+       }
+       
+       for (i = paircursor(&cursor, &key);
+            i;
+            i = pairfindnext(&cursor, inst->keyattr->attr, inst->keyattr->vendor, TAG_ANY)){
                /*
                 *      Ensure we have the string form of the attribute
                 */
-               vp_prints_value(buffer, sizeof(buffer), key, 0);
-               if (! (pw = get_pw_nam(buffer, inst->ht, &last_found)) ) {
+               vp_prints_value(buffer, sizeof(buffer), i, 0);
+               if (!(pw = get_pw_nam(buffer, inst->ht, &last_found)) ) {
                        continue;
                }
                do {
                        addresult(inst, request, request, &request->config_items, pw, 0, "config_items");
                        addresult(inst, request, request->reply, &request->reply->vps, pw, 1, "reply_items");
-                       addresult(inst, request, request->packet, &request->packet->vps,        pw, 2, "request_items");
-               } while ( (pw = get_next(buffer, inst->ht, &last_found)) );
-               found++;
-               if (!inst->allowmultiple) break;
-       }
-       if(!found) {
-               return RLM_MODULE_NOTFOUND;
+                       addresult(inst, request, request->packet, &request->packet->vps, pw, 2, "request_items");
+               } while ((pw = get_next(buffer, inst->ht, &last_found)));
+               
+               if (!inst->allowmultiple) {
+                       break;
+               }
        }
+       
        return RLM_MODULE_OK;
 
 #undef inst
index c8c03a7..2b345d5 100644 (file)
@@ -493,6 +493,7 @@ static void perl_store_vps(TALLOC_CTX *ctx, VALUE_PAIR *vps, HV *rad_hv)
        head = paircopy(ctx, vps);
 
        while (head) {
+               vp_cursor_t cursor;
                /*
                 *      Tagged attributes are added to the hash with name
                 *      <attribute>:<tag>, others just use the normal attribute
@@ -513,14 +514,17 @@ static void perl_store_vps(TALLOC_CTX *ctx, VALUE_PAIR *vps, HV *rad_hv)
                sublist = NULL;
                pairfilter(ctx, &sublist, &head, head->da->attr, head->da->vendor, head->tag);
 
+               paircursor(&cursor, &sublist);
                /*
                 *      Attribute has multiple values
                 */
-               if (sublist->next) {
+               if (pairnext(&cursor)) {
                        VALUE_PAIR *vp;
 
                        av = newAV();
-                       for (vp = sublist; vp; vp = vp->next) {
+                       for (vp = pairfirst(&cursor);
+                            vp;
+                            vp = pairnext(&cursor)) {
                                len = vp_prints_value(buffer, sizeof(buffer), vp, false);
                                av_push(av, newSVpv(buffer, len));
                        }
index 4c39827..455cf7d 100644 (file)
@@ -117,8 +117,10 @@ static void cisco_vsa_hack(REQUEST *request)
        char            *ptr;
        char            newattr[MAX_STRING_LEN];
        VALUE_PAIR      *vp;
-
-       for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
+       vp_cursor_t     cursor;
+       for (vp = paircursor(&cursor, &request->packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                vendorcode = vp->da->vendor;
                if (!((vendorcode == 9) || (vendorcode == 6618))) {
                        continue; /* not a Cisco or Quintum VSA, continue */
@@ -174,8 +176,11 @@ static void cisco_vsa_hack(REQUEST *request)
 static void alvarion_vsa_hack(VALUE_PAIR *vp)
 {
        int number = 1;
-
-       for ( ; vp != NULL; vp = vp->next) {
+       vp_cursor_t cursor;
+       
+       for (vp = paircursor(&cursor, &vp);
+            vp;
+            vp = pairnext(&cursor)) {
                const DICT_ATTR *da;
 
                if (vp->da->vendor != 12394) {
@@ -266,6 +271,7 @@ static void rad_mangle(rlm_preprocess_t *inst, REQUEST *request)
        VALUE_PAIR      *namepair;
        VALUE_PAIR      *request_pairs;
        VALUE_PAIR      *tmp;
+       vp_cursor_t     cursor;
 
        /*
         *      Get the username from the request
@@ -320,7 +326,9 @@ static void rad_mangle(rlm_preprocess_t *inst, REQUEST *request)
        }
 
        num_proxy_state = 0;
-       for (tmp = request->packet->vps; tmp != NULL; tmp = tmp->next) {
+       for (tmp = paircursor(&cursor, &request->packet->vps);
+            tmp;
+            tmp = pairnext(&cursor)) {
                if (tmp->da->vendor != 0) {
                        continue;
                }
@@ -345,21 +353,20 @@ static void rad_mangle(rlm_preprocess_t *inst, REQUEST *request)
  */
 static int hunt_paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check)
 {
-       VALUE_PAIR      *check_item = check;
+       vp_cursor_t     cursor;
+       VALUE_PAIR      *check_item;
        VALUE_PAIR      *tmp;
        int             result = -1;
 
        if (!check) return 0;
 
-       while (result != 0 && check_item != NULL) {
-
-               tmp = check_item->next;
-               check_item->next = NULL;
-
+       for (check_item = paircursor(&cursor, check);
+            check_item && (result != 0);
+            check_item = pairnext(&cursor)) {
+               /* FIXME: paircopy should be removed once VALUE_PAIRs are no longer in linked lists */
+               tmp = paircopyvp(request, check_item);
                result = paircompare(req, request, check_item, NULL);
-
-               check_item->next = tmp;
-               check_item = check_item->next;
+               pairfree(&tmp);
        }
 
        return result;
index 78cdca9..27b7442 100644 (file)
@@ -356,6 +356,7 @@ failed:
 static int do_python(REQUEST *request, PyObject *pFunc,
                     char const *funcname)
 {
+       vp_cursor_t     cursor;
        VALUE_PAIR      *vp;
        PyObject        *pRet = NULL;
        PyObject        *pArgs = NULL;
@@ -381,8 +382,11 @@ static int do_python(REQUEST *request, PyObject *pFunc,
         */
        tuplelen = 0;
        if (request != NULL) {
-               for (vp = request->packet->vps; vp; vp = vp->next)
+               for (vp = paircursor(&cursor, &request->packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        tuplelen++;
+               }
        }
 
        gstate = PyGILState_Ensure();
@@ -395,9 +399,9 @@ static int do_python(REQUEST *request, PyObject *pFunc,
                if ((pArgs = PyTuple_New(tuplelen)) == NULL)
                        goto failed;
 
-               for (vp = request->packet->vps;
-                    vp != NULL;
-                    vp = vp->next, i++) {
+               for (vp = paircursor(&cursor, &request->packet->vps);
+                    vp;
+                    vp = pairnext(&cursor), i++) {
                        PyObject *pPair;
                        
                        /* The inside tuple has two only: */
index 0020231..3c614e4 100644 (file)
@@ -150,6 +150,7 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
 {
        rlm_rcode_t     rcode = RLM_MODULE_OK;
        struct radutmp  ut, u;
+       vp_cursor_t     cursor;
        VALUE_PAIR      *vp;
        int             status = -1;
        int             protocol = -1;
@@ -222,7 +223,9 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        /*
         *      First, find the interesting attributes.
         */
-       for (vp = request->packet->vps; vp; vp = vp->next) {
+       for (vp = paircursor(&cursor, &request->packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                if (!vp->da->vendor) switch (vp->da->attr) {
                        case PW_LOGIN_IP_HOST:
                        case PW_FRAMED_IP_ADDRESS:
index e380687..2a983b2 100644 (file)
@@ -54,23 +54,19 @@ static int replicate_packet(UNUSED void *instance, REQUEST *request,
                            pair_lists_t list, unsigned int code)
 {
        int rcode = RLM_MODULE_NOOP;
-       VALUE_PAIR *vp, **vps, *last;
+       VALUE_PAIR *vp, **vps;
+       vp_cursor_t cursor;
        home_server *home;
        REALM *realm;
        home_pool_t *pool;
        RADIUS_PACKET *packet = NULL;
 
-       last = request->config_items;
-
        /*
         *      Send as many packets as necessary to different
         *      destinations.
         */
-       while (1) {
-               vp = pairfind(last, PW_REPLICATE_TO_REALM, 0, TAG_ANY);
-               if (!vp) break;
-
-               last = vp->next;
+       paircursor(&cursor, &request->config_items);
+       while ((vp = pairfindnext(&cursor, PW_REPLICATE_TO_REALM, 0, TAG_ANY))) {
 
                realm = realm_find2(vp->vp_strvalue);
                if (!realm) {
index 54aae06..8e680c1 100644 (file)
@@ -852,6 +852,7 @@ static void rest_read_ctx_init(REQUEST *request,
        unsigned short count = 0, i;
        unsigned short swap;
 
+       vp_cursor_t cursor;
        VALUE_PAIR **current, *tmp;
 
        /*
@@ -863,21 +864,23 @@ static void rest_read_ctx_init(REQUEST *request,
        /*
         * Create sorted array of VP pointers
         */
-       tmp = request->packet->vps;
-       while (tmp != NULL) {
-               tmp = tmp->next;
+       for (tmp = paircursor(&cursor, &request->packet->vps);
+            tmp;
+            tmp = pairnext(&cursor)) {
                count++;
        }
 
        ctx->first = current = rad_malloc((sizeof(tmp) * (count + 1)));
        ctx->next = ctx->first;
+       
+       current[0] = NULL;
 
-       tmp = request->packet->vps;
-       while (tmp != NULL) {
-               *current++ = tmp;
-               tmp = tmp->next;
+       for (tmp = paircursor(&cursor, &request->packet->vps);
+            tmp;
+            tmp = pairnext(&cursor)) {
+               *current++ = tmp;    
        }
-       current[0] = NULL;
+            
        current = ctx->first;
 
        if (!sort || (count < 2)) return;
index 196adfd..7ab140a 100644 (file)
@@ -189,8 +189,8 @@ static void add_vp_tuple(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vpp, VA
 #define BUF_SIZE 1024
 static rlm_rcode_t do_ruby(REQUEST *request, unsigned long func,
                           VALUE module, char const *function_name) {
-                               
        rlm_rcode_t rcode = RLM_MODULE_OK;
+       vp_cursor_t cursor;
 
        char buf[BUF_SIZE]; /* same size as vp_print buffer */
 
@@ -210,8 +210,10 @@ static rlm_rcode_t do_ruby(REQUEST *request, unsigned long func,
        n_tuple = 0;
 
        if (request) {
-               for (vp = request->packet->vps; vp; vp = vp->next) {
-                       n_tuple++;
+               for (vp = paircursor(&cursor, &request->packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
+                        n_tuple++;    
                }
        }
 
@@ -222,7 +224,9 @@ static rlm_rcode_t do_ruby(REQUEST *request, unsigned long func,
        */
        rb_request = rb_ary_new2(n_tuple);
        if (request) {
-               for (vp = request->packet->vps; vp; vp = vp->next) {
+               for (vp = paircursor(&cursor, &request->packet->vps);
+                    vp;
+                    vp = pairnext(&cursor)) {
                        VALUE tmp = rb_ary_new2(2);
 
                        /* The name. logic from vp_prints, lib/print.c */
index dedb022..85e25d9 100644 (file)
@@ -308,6 +308,7 @@ static char *uue(void *in)
 static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
 {
        VALUE_PAIR      *vp;
+       vp_cursor_t     cursor;
        FILE            *fp;
        struct utmp     ut;
        time_t          t;
@@ -366,7 +367,9 @@ static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
        /*
         *      First, find the interesting attributes.
         */
-       for (vp = request->packet->vps; vp; vp = vp->next) {
+       for (vp = paircursor(&cursor, &request->packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                if (!vp->da->vendor) switch (vp->da->attr) {
                        case PW_USER_NAME:
                                if (vp->length >= sizeof(ut.ut_name)) {
index cb9c7b0..e4938f7 100644 (file)
@@ -31,11 +31,12 @@ RCSID("$Id$")
 static rlm_rcode_t utf8_clean(UNUSED void *instance, REQUEST *request)
 {
        size_t i, len;
-       VALUE_PAIR *vp, *next;
-
-       for (vp = request->packet->vps; vp != NULL; vp = next) {
-               next = vp->next;
+       VALUE_PAIR *vp;
+       vp_cursor_t cursor;
 
+       for (vp = paircursor(&cursor, &request->packet->vps);
+            vp;
+            vp = pairnext(&cursor)) {
                if (vp->da->type != PW_TYPE_STRING) continue;
 
                for (i = 0; i < vp->length; i += len) {