xref: /freebsd/crypto/krb5/src/ccapi/server/ccs_list_internal.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* ccapi/server/ccs_list_internal.c */
2 /*
3  * Copyright 2006, 2007 Massachusetts Institute of Technology.
4  * All Rights Reserved.
5  *
6  * Export of this software from the United States of America may
7  * require a specific license from the United States Government.
8  * It is the responsibility of any person or organization contemplating
9  * export to obtain such a license before exporting.
10  *
11  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12  * distribute this software and its documentation for any purpose and
13  * without fee is hereby granted, provided that the above copyright
14  * notice appear in all copies and that both that copyright notice and
15  * this permission notice appear in supporting documentation, and that
16  * the name of M.I.T. not be used in advertising or publicity pertaining
17  * to distribution of the software without specific, written prior
18  * permission.  Furthermore if you modify this software you must label
19  * your software as modified software and not distribute it in such a
20  * fashion that it might be confused with the original M.I.T. software.
21  * M.I.T. makes no representations about the suitability of
22  * this software for any purpose.  It is provided "as is" without express
23  * or implied warranty.
24  */
25 
26 #include "ccs_list_internal.h"
27 #include "cci_array_internal.h"
28 #include "cci_identifier.h"
29 #include "ccs_server.h"
30 
31 typedef enum {
32     ccs_list_action_insert,
33     ccs_list_action_remove,
34     ccs_list_action_push_front
35 } ccs_list_action_enum;
36 
37 /* ------------------------------------------------------------------------ */
38 
39 struct ccs_list_d {
40     cci_array_t objects;
41     cci_array_t iterators;
42 
43     cc_int32 object_not_found_err;
44     cc_int32 iterator_not_found_err;
45 
46     ccs_object_compare_identifier_t object_compare_identifier;
47 };
48 
49 struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL };
50 
51 /* ------------------------------------------------------------------------ */
52 
53 struct ccs_list_iterator_d {
54     cci_identifier_t identifier;
55     ccs_pipe_t client_pipe;
56     ccs_list_t list;
57     cc_uint64 current;
58 };
59 
60 struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, CCS_PIPE_NULL, NULL, 0 };
61 
62 static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
63                                        ccs_list_t           in_list,
64                                        ccs_pipe_t           in_client_pipe);
65 
66 static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator);
67 
68 static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t  io_list_iterator,
69                                           ccs_list_action_enum in_action,
70                                           cc_uint64 in_object_index);
71 
72 #ifdef TARGET_OS_MAC
73 #pragma mark -
74 #endif
75 
76 /* ------------------------------------------------------------------------ */
77 
ccs_list_new(ccs_list_t * out_list,cc_int32 in_object_not_found_err,cc_int32 in_iterator_not_found_err,ccs_object_compare_identifier_t in_object_compare_identifier,ccs_object_release_t in_object_release)78 cc_int32 ccs_list_new (ccs_list_t                      *out_list,
79                        cc_int32                         in_object_not_found_err,
80                        cc_int32                         in_iterator_not_found_err,
81                        ccs_object_compare_identifier_t  in_object_compare_identifier,
82                        ccs_object_release_t             in_object_release)
83 {
84     cc_int32 err = ccNoError;
85     ccs_list_t list = NULL;
86 
87     if (!out_list) { err = cci_check_error (ccErrBadParam); }
88 
89     if (!err) {
90         list = malloc (sizeof (*list));
91         if (list) {
92             *list = ccs_list_initializer;
93             list->object_not_found_err = in_object_not_found_err;
94             list->iterator_not_found_err = in_iterator_not_found_err;
95             list->object_compare_identifier = in_object_compare_identifier;
96         } else {
97             err = cci_check_error (ccErrNoMem);
98         }
99     }
100 
101     if (!err) {
102         err = cci_array_new (&list->objects, in_object_release);
103     }
104 
105     if (!err) {
106         err = cci_array_new (&list->iterators, ccs_list_iterator_object_release);
107     }
108 
109     if (!err) {
110         *out_list = list;
111         list = NULL;
112     }
113 
114     ccs_list_release (list);
115 
116     return cci_check_error (err);
117 }
118 
119 /* ------------------------------------------------------------------------ */
120 
ccs_list_release(ccs_list_t io_list)121 cc_int32 ccs_list_release (ccs_list_t io_list)
122 {
123     cc_int32 err = ccNoError;
124 
125     if (!err && io_list) {
126         cci_array_release (io_list->iterators);
127         cci_array_release (io_list->objects);
128         free (io_list);
129     }
130 
131     return err;
132 }
133 
134 /* ------------------------------------------------------------------------ */
135 
ccs_list_new_iterator(ccs_list_t io_list,ccs_pipe_t in_client_pipe,ccs_list_iterator_t * out_list_iterator)136 cc_int32 ccs_list_new_iterator (ccs_list_t           io_list,
137                                 ccs_pipe_t           in_client_pipe,
138                                 ccs_list_iterator_t *out_list_iterator)
139 {
140     return cci_check_error (ccs_list_iterator_new (out_list_iterator,
141                                                    io_list,
142                                                    in_client_pipe));
143 }
144 
145 /* ------------------------------------------------------------------------ */
146 
ccs_list_release_iterator(ccs_list_t io_list,cci_identifier_t in_identifier)147 cc_int32 ccs_list_release_iterator (ccs_list_t       io_list,
148                                     cci_identifier_t in_identifier)
149 {
150     cc_int32 err = ccNoError;
151     ccs_list_iterator_t iterator = NULL;
152 
153     if (!io_list      ) { err = cci_check_error (ccErrBadParam); }
154     if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
155 
156     if (!err) {
157         err = ccs_list_find_iterator (io_list, in_identifier, &iterator);
158     }
159 
160     if (!err) {
161         err = ccs_list_iterator_release (iterator);
162     }
163 
164     return cci_check_error (err);
165 }
166 
167 /* ------------------------------------------------------------------------ */
168 
ccs_list_count(ccs_list_t in_list,cc_uint64 * out_count)169 cc_int32 ccs_list_count (ccs_list_t  in_list,
170                          cc_uint64  *out_count)
171 {
172     cc_int32 err = ccNoError;
173 
174     if (!in_list  ) { err = cci_check_error (ccErrBadParam); }
175     if (!out_count) { err = cci_check_error (ccErrBadParam); }
176 
177     if (!err) {
178         *out_count = cci_array_count (in_list->objects);
179     }
180 
181     return cci_check_error (err);
182 }
183 
184 /* ------------------------------------------------------------------------ */
185 
ccs_list_iterator_at_index(ccs_list_t in_list,cc_uint64 in_index)186 static ccs_list_iterator_t ccs_list_iterator_at_index (ccs_list_t in_list,
187 						       cc_uint64  in_index)
188 {
189     return (ccs_list_iterator_t) cci_array_object_at_index (in_list->iterators, in_index);
190 }
191 
192 /* ------------------------------------------------------------------------ */
193 
ccs_list_find_index(ccs_list_t in_list,cci_identifier_t in_identifier,cc_uint64 * out_object_index)194 static cc_int32 ccs_list_find_index (ccs_list_t        in_list,
195                                      cci_identifier_t  in_identifier,
196                                      cc_uint64        *out_object_index)
197 {
198     cc_int32 err = ccNoError;
199     cc_int32 found = 0;
200 
201     if (!in_list         ) { err = cci_check_error (ccErrBadParam); }
202     if (!in_identifier   ) { err = cci_check_error (ccErrBadParam); }
203     if (!out_object_index) { err = cci_check_error (ccErrBadParam); }
204 
205     if (!err && !found) {
206         cc_uint64 i;
207 
208         for (i = 0; !err && i < cci_array_count (in_list->objects); i++) {
209             cc_uint32 equal = 0;
210             cci_array_object_t object = cci_array_object_at_index (in_list->objects, i);
211 
212             err = in_list->object_compare_identifier (object, in_identifier, &equal);
213 
214             if (!err && equal) {
215                 found = 1;
216                 *out_object_index = i;
217                 break;
218             }
219         }
220     }
221 
222     if (!err && !found) {
223         err = cci_check_error (in_list->object_not_found_err);
224     }
225 
226     return cci_check_error (err);
227 }
228 
229 /* ------------------------------------------------------------------------ */
ccs_list_find(ccs_list_t in_list,cci_identifier_t in_identifier,ccs_list_object_t * out_object)230 cc_int32 ccs_list_find (ccs_list_t         in_list,
231                         cci_identifier_t   in_identifier,
232                         ccs_list_object_t *out_object)
233 {
234     cc_int32 err = ccNoError;
235     cc_uint64 i;
236 
237     if (!in_list      ) { err = cci_check_error (ccErrBadParam); }
238     if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
239     if (!out_object   ) { err = cci_check_error (ccErrBadParam); }
240 
241     if (!err) {
242         err = ccs_list_find_index (in_list, in_identifier, &i);
243     }
244 
245     if (!err) {
246         *out_object = cci_array_object_at_index (in_list->objects, i);
247     }
248 
249     return cci_check_error (err);
250 }
251 
252 /* ------------------------------------------------------------------------ */
253 
ccs_list_find_iterator_index(ccs_list_t in_list,cci_identifier_t in_identifier,cc_uint64 * out_object_index)254 static cc_int32 ccs_list_find_iterator_index (ccs_list_t        in_list,
255                                               cci_identifier_t  in_identifier,
256                                               cc_uint64        *out_object_index)
257 {
258     cc_int32 err = ccNoError;
259     cc_int32 found = 0;
260 
261     if (!in_list         ) { err = cci_check_error (ccErrBadParam); }
262     if (!in_identifier   ) { err = cci_check_error (ccErrBadParam); }
263     if (!out_object_index) { err = cci_check_error (ccErrBadParam); }
264 
265     if (!err && !found) {
266         cc_uint64 i;
267 
268         for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) {
269             cc_uint32 equal = 0;
270             ccs_list_iterator_t iterator = ccs_list_iterator_at_index (in_list, i);
271 
272             err = cci_identifier_compare (iterator->identifier, in_identifier, &equal);
273 
274             if (!err && equal) {
275                 found = 1;
276                 *out_object_index = i;
277                 break;
278             }
279         }
280     }
281 
282     if (!err && !found) {
283         // Don't report this error to the log file.  Non-fatal.
284         return in_list->object_not_found_err;
285     } else {
286         return cci_check_error (err);
287     }
288 }
289 
290 /* ------------------------------------------------------------------------ */
291 
ccs_list_find_iterator(ccs_list_t in_list,cci_identifier_t in_identifier,ccs_list_iterator_t * out_list_iterator)292 cc_int32 ccs_list_find_iterator (ccs_list_t           in_list,
293                                  cci_identifier_t     in_identifier,
294                                  ccs_list_iterator_t *out_list_iterator)
295 {
296     cc_int32 err = ccNoError;
297     cc_uint64 i;
298 
299     if (!in_list          ) { err = cci_check_error (ccErrBadParam); }
300     if (!in_identifier    ) { err = cci_check_error (ccErrBadParam); }
301     if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
302 
303     if (!err) {
304         err = ccs_list_find_iterator_index (in_list, in_identifier, &i);
305     }
306 
307     if (!err) {
308         *out_list_iterator = ccs_list_iterator_at_index (in_list, i);
309     }
310 
311     return cci_check_error (err);
312 }
313 
314 /* ------------------------------------------------------------------------ */
315 
ccs_list_add(ccs_list_t io_list,ccs_list_object_t in_object)316 cc_int32 ccs_list_add (ccs_list_t        io_list,
317                        ccs_list_object_t in_object)
318 {
319     cc_int32 err = ccNoError;
320     cc_uint64 add_index;
321 
322     if (!io_list  ) { err = cci_check_error (ccErrBadParam); }
323     if (!in_object) { err = cci_check_error (ccErrBadParam); }
324 
325     if (!err) {
326         add_index = cci_array_count (io_list->objects);
327 
328         err = cci_array_insert (io_list->objects, in_object, add_index);
329     }
330 
331     if (!err) {
332         /* Fixup iterator indexes */
333         cc_uint64 i;
334 
335         for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
336             ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
337 
338             err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index);
339         }
340     }
341 
342     return cci_check_error (err);
343 }
344 
345 /* ------------------------------------------------------------------------ */
346 
ccs_list_remove(ccs_list_t io_list,cci_identifier_t in_identifier)347 cc_int32 ccs_list_remove (ccs_list_t       io_list,
348                           cci_identifier_t in_identifier)
349 {
350     cc_int32 err = ccNoError;
351     cc_uint64 remove_index;
352 
353     if (!io_list      ) { err = cci_check_error (ccErrBadParam); }
354     if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
355 
356     if (!err) {
357         err = ccs_list_find_index (io_list, in_identifier, &remove_index);
358     }
359 
360     if (!err) {
361         err = cci_array_remove (io_list->objects, remove_index);
362     }
363 
364     if (!err) {
365         /* Fixup iterator indexes */
366         cc_uint64 i;
367 
368         for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
369             ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
370 
371             err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index);
372         }
373     }
374 
375     return cci_check_error (err);
376 }
377 
378 /* ------------------------------------------------------------------------ */
379 
ccs_list_push_front(ccs_list_t io_list,cci_identifier_t in_identifier)380 cc_int32 ccs_list_push_front (ccs_list_t       io_list,
381                               cci_identifier_t in_identifier)
382 {
383     cc_int32 err = ccNoError;
384     cc_uint64 push_front_index;
385 
386     if (!io_list      ) { err = cci_check_error (ccErrBadParam); }
387     if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
388 
389     if (!err) {
390         err = ccs_list_find_index (io_list, in_identifier, &push_front_index);
391     }
392 
393     if (!err) {
394         err = cci_array_push_front (io_list->objects, push_front_index);
395     }
396 
397     if (!err) {
398         /* Fixup iterator indexes */
399         cc_uint64 i;
400 
401         for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) {
402             ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i);
403 
404             err = ccs_list_iterator_update (iterator,
405                                             ccs_list_action_push_front,
406                                             push_front_index);
407         }
408     }
409 
410     return cci_check_error (err);
411 }
412 
413 #ifdef TARGET_OS_MAC
414 #pragma mark -
415 #endif
416 
417 /* ------------------------------------------------------------------------ */
418 
ccs_list_iterator_new(ccs_list_iterator_t * out_list_iterator,ccs_list_t io_list,ccs_pipe_t in_client_pipe)419 static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
420                                        ccs_list_t           io_list,
421                                        ccs_pipe_t           in_client_pipe)
422 {
423     cc_int32 err = ccNoError;
424     ccs_list_iterator_t list_iterator = NULL;
425 
426     if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
427     if (!io_list          ) { err = cci_check_error (ccErrBadParam); }
428     /* client_pipe may be NULL if the iterator exists for internal server use */
429 
430     if (!err) {
431         list_iterator = malloc (sizeof (*list_iterator));
432         if (list_iterator) {
433             *list_iterator = ccs_list_iterator_initializer;
434         } else {
435             err = cci_check_error (ccErrNoMem);
436         }
437     }
438 
439     if (!err) {
440         err = ccs_server_new_identifier (&list_iterator->identifier);
441     }
442 
443     if (!err) {
444         list_iterator->list = io_list;
445         list_iterator->current = 0;
446 
447         err = cci_array_insert (io_list->iterators,
448                                 (cci_array_object_t) list_iterator,
449 				cci_array_count (io_list->iterators));
450     }
451 
452     if (!err && ccs_pipe_valid (in_client_pipe)) {
453         ccs_client_t client = NULL;
454 
455         err = ccs_pipe_copy (&list_iterator->client_pipe, in_client_pipe);
456 
457         if (!err) {
458             err = ccs_server_client_for_pipe (in_client_pipe, &client);
459         }
460 
461         if (!err) {
462             err = ccs_client_add_iterator (client, list_iterator);
463         }
464     }
465 
466     if (!err) {
467         *out_list_iterator = list_iterator;
468         list_iterator = NULL;
469     }
470 
471     ccs_list_iterator_release (list_iterator);
472 
473     return cci_check_error (err);
474 }
475 
476 /* ------------------------------------------------------------------------ */
477 
ccs_list_iterator_write(ccs_list_iterator_t in_list_iterator,k5_ipc_stream in_stream)478 cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator,
479                                   k5_ipc_stream        in_stream)
480 {
481     cc_int32 err = ccNoError;
482 
483     if (!in_list_iterator) { err = cci_check_error (ccErrBadParam); }
484     if (!in_stream       ) { err = cci_check_error (ccErrBadParam); }
485 
486     if (!err) {
487         err = cci_identifier_write (in_list_iterator->identifier,
488                                     in_stream);
489     }
490 
491     return cci_check_error (err);
492 }
493 
494 /* ------------------------------------------------------------------------ */
495 
ccs_list_iterator_clone(ccs_list_iterator_t in_list_iterator,ccs_list_iterator_t * out_list_iterator)496 cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t  in_list_iterator,
497                                   ccs_list_iterator_t *out_list_iterator)
498 {
499     cc_int32 err = ccNoError;
500     ccs_list_iterator_t list_iterator = NULL;
501 
502     if (!in_list_iterator ) { err = cci_check_error (ccErrBadParam); }
503     if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
504 
505     if (!err) {
506         err = ccs_list_iterator_new (&list_iterator,
507                                      in_list_iterator->list,
508                                      in_list_iterator->client_pipe);
509     }
510 
511     if (!err) {
512         list_iterator->current = in_list_iterator->current;
513 
514         *out_list_iterator = list_iterator;
515         list_iterator = NULL;
516     }
517 
518     ccs_list_iterator_release (list_iterator);
519 
520     return cci_check_error (err);
521 }
522 
523 /* ------------------------------------------------------------------------ */
524 
ccs_list_iterator_object_release(cci_array_object_t io_list_iterator)525 static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator)
526 {
527     cc_int32 err = ccNoError;
528     ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator;
529 
530     if (!io_list_iterator) { err = ccErrBadParam; }
531 
532     if (!err && ccs_pipe_valid (list_iterator->client_pipe)) {
533 	ccs_client_t client = NULL;
534 
535         err = ccs_server_client_for_pipe (list_iterator->client_pipe, &client);
536 
537         if (!err && client) {
538 	    /* if client object still has a reference to us, remove it */
539 	    err = ccs_client_remove_iterator (client, list_iterator);
540         }
541     }
542 
543     if (!err) {
544         ccs_pipe_release (list_iterator->client_pipe);
545         cci_identifier_release (list_iterator->identifier);
546         free (io_list_iterator);
547     }
548 
549     return err;
550 }
551 
552 /* ------------------------------------------------------------------------ */
553 
ccs_list_iterator_release(ccs_list_iterator_t io_list_iterator)554 cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator)
555 {
556     cc_int32 err = ccNoError;
557 
558     if (!err && io_list_iterator) {
559         cc_uint64 i = 0;
560 
561         if (ccs_list_find_iterator_index (io_list_iterator->list,
562                                           io_list_iterator->identifier,
563                                           &i) == ccNoError) {
564             /* cci_array_remove will call ccs_list_iterator_object_release */
565             err = cci_array_remove (io_list_iterator->list->iterators, i);
566         } else {
567             cci_debug_printf ("Warning: iterator not in iterator list!");
568         }
569     }
570 
571     return err;
572 }
573 
574 /* ------------------------------------------------------------------------ */
575 
ccs_list_iterator_invalidate(ccs_list_iterator_t io_list_iterator)576 cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator)
577 {
578     cc_int32 err = ccNoError;
579     ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator;
580 
581     if (!io_list_iterator) { err = ccErrBadParam; }
582 
583     if (!err) {
584         /* Client owner died.  Remove client reference and then the iterator. */
585         if (ccs_pipe_valid (list_iterator->client_pipe)) {
586             ccs_pipe_release (list_iterator->client_pipe);
587             list_iterator->client_pipe = CCS_PIPE_NULL;
588         }
589 
590         err = ccs_list_iterator_release (io_list_iterator);
591     }
592 
593     return err;
594 }
595 
596 /* ------------------------------------------------------------------------ */
597 
ccs_list_iterator_current(ccs_list_iterator_t io_list_iterator,ccs_list_object_t * out_object)598 cc_int32 ccs_list_iterator_current (ccs_list_iterator_t  io_list_iterator,
599                                     ccs_list_object_t   *out_object)
600 {
601     cc_int32 err = ccNoError;
602 
603     if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
604     if (!out_object      ) { err = cci_check_error (ccErrBadParam); }
605 
606     if (!err) {
607         if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) {
608             *out_object = cci_array_object_at_index (io_list_iterator->list->objects,
609                                                      io_list_iterator->current);
610         } else {
611             err = ccIteratorEnd;
612         }
613     }
614 
615     return cci_check_error (err);
616 }
617 
618 /* ------------------------------------------------------------------------ */
619 
ccs_list_iterator_next(ccs_list_iterator_t io_list_iterator,ccs_list_object_t * out_object)620 cc_int32 ccs_list_iterator_next (ccs_list_iterator_t  io_list_iterator,
621                                  ccs_list_object_t   *out_object)
622 {
623     cc_int32 err = ccNoError;
624 
625     if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
626     if (!out_object      ) { err = cci_check_error (ccErrBadParam); }
627 
628     if (!err) {
629         if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) {
630             *out_object = cci_array_object_at_index (io_list_iterator->list->objects,
631                                                      io_list_iterator->current);
632             io_list_iterator->current++;
633         } else {
634             err = ccIteratorEnd;
635         }
636     }
637 
638     return cci_check_error (err);
639 }
640 
641 /* ------------------------------------------------------------------------ */
642 
ccs_list_iterator_update(ccs_list_iterator_t io_list_iterator,ccs_list_action_enum in_action,cc_uint64 in_object_index)643 static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t  io_list_iterator,
644                                           ccs_list_action_enum in_action,
645                                           cc_uint64            in_object_index)
646 {
647     cc_int32 err = ccNoError;
648 
649     if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); }
650 
651     if (!err) {
652         /* When the list changes adjust the current index so that */
653         /* we don't unnecessarily skip or double count items      */
654         if (in_action == ccs_list_action_insert) {
655             if (io_list_iterator->current > in_object_index) {
656                 io_list_iterator->current++;
657             }
658 
659         } else if (in_action == ccs_list_action_remove) {
660             if (io_list_iterator->current >= in_object_index) {
661                 io_list_iterator->current--;
662             }
663 
664         } else if (in_action == ccs_list_action_push_front) {
665             if (io_list_iterator->current < in_object_index) {
666                 io_list_iterator->current++;
667             }
668 
669         } else {
670             err = cci_check_error (ccErrBadParam);
671         }
672     }
673 
674     return cci_check_error (err);
675 }
676