00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <linux/sched.h>
00010 #include <linux/smp_lock.h>
00011 #include <linux/module.h>
00012 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
00013 #include <linux/random.h>
00014 #endif
00015 #include <asm/uaccess.h>
00016 #include <rsbac/types.h>
00017 #include <rsbac/error.h>
00018 #include <rsbac/helpers.h>
00019 #include <rsbac/getname.h>
00020 #include <rsbac/debug.h>
00021 #include <rsbac/adf.h>
00022 #include <rsbac/aci_data_structures.h>
00023 #include <rsbac/proc_fs.h>
00024 #include <rsbac/rkmem.h>
00025 #include <rsbac/lists.h>
00026 #include <rsbac/gen_lists.h>
00027
00028
00029
00030
00031
00032 static struct rsbac_list_reg_head_t reg_head;
00033 static struct rsbac_list_lol_reg_head_t lol_reg_head;
00034 static rsbac_boolean_t list_initialized = FALSE;
00035
00036 #ifdef CONFIG_RSBAC_LIST_TRANS
00037 static struct rsbac_list_reg_item_t * ta_handle = NULL;
00038 static spinlock_t ta_lock = SPIN_LOCK_UNLOCKED;
00039 static rsbac_boolean_t ta_committing = FALSE;
00040 static rsbac_boolean_t ta_forgetting = FALSE;
00041 #ifndef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
00042 rsbac_list_ta_number_t ta_next = 1;
00043 #endif
00044 #endif
00045
00046 #ifdef CONFIG_RSBAC_LIST_TRANS
00047 static int do_forget(rsbac_list_ta_number_t ta_number);
00048 #endif
00049
00050 #ifdef CONFIG_RSBAC_LIST_REPL
00051 static struct rsbac_nanotime_t repl_last;
00052 static struct rsbac_list_reg_item_t * repl_partner_handle = NULL;
00053 #endif
00054
00055
00056
00057
00058
00059
00060 static struct rsbac_list_item_t * lookup_item_compare(
00061 struct rsbac_list_reg_item_t * list,
00062 void * desc)
00063 {
00064 struct rsbac_list_item_t * curr;
00065
00066 if(!list || !desc || !list->compare)
00067 return NULL;
00068
00069 curr = list->curr;
00070 if(!curr)
00071 {
00072 curr = list->head;
00073 if(!curr)
00074 return NULL;
00075 }
00076
00077
00078 if(list->compare(desc, &curr[1]))
00079 {
00080 if((list->compare(desc, &curr[1]) > 0))
00081 {
00082 curr = curr->next;
00083 while ( curr
00084 && (list->compare(desc, &curr[1]) > 0)
00085 )
00086 curr = curr->next;
00087 }
00088 else
00089 {
00090 curr = curr->prev;
00091 while ( curr
00092 && (list->compare(desc, &curr[1]) < 0)
00093 )
00094 curr = curr->prev;
00095 }
00096 if (curr)
00097 {
00098
00099 list->curr = curr;
00100 if(!list->compare(desc, &curr[1]))
00101 return curr;
00102 }
00103
00104 return NULL;
00105 }
00106
00107 return curr;
00108 }
00109
00110 static struct rsbac_list_item_t * lookup_item_memcmp(
00111 struct rsbac_list_reg_item_t * list,
00112 void * desc)
00113 {
00114 struct rsbac_list_item_t * curr;
00115
00116 if(!list || !desc)
00117 return NULL;
00118
00119 curr = list->curr;
00120 if(!curr)
00121 {
00122 curr = list->head;
00123 if(!curr)
00124 return NULL;
00125 }
00126
00127
00128 if(memcmp(desc,
00129 &curr[1],
00130 list->info.desc_size))
00131 {
00132 if(memcmp(desc,
00133 &curr[1],
00134 list->info.desc_size) > 0)
00135 {
00136 curr = curr->next;
00137 while ( curr
00138 && (memcmp(desc,
00139 &curr[1],
00140 list->info.desc_size) > 0)
00141 )
00142 curr = curr->next;
00143 }
00144 else
00145 {
00146 curr = curr->prev;
00147 while ( curr
00148 && (memcmp(desc,
00149 &curr[1],
00150 list->info.desc_size) < 0)
00151 )
00152 curr = curr->prev;
00153 }
00154 if (curr)
00155 {
00156
00157 list->curr = curr;
00158 if(!memcmp(desc,
00159 &curr[1],
00160 list->info.desc_size))
00161 return curr;
00162 }
00163
00164 return NULL;
00165 }
00166
00167 return curr;
00168 }
00169
00170 static struct rsbac_list_item_t * lookup_item(
00171 struct rsbac_list_reg_item_t * list,
00172 void * desc)
00173 {
00174 if(!list || !desc)
00175 return NULL;
00176
00177 if(list->compare)
00178 return lookup_item_compare(list, desc);
00179 else
00180 return lookup_item_memcmp(list, desc);
00181 }
00182
00183 #ifdef CONFIG_RSBAC_LIST_TRANS
00184 static struct rsbac_list_item_t * ta_lookup_item_compare(
00185 struct rsbac_list_reg_item_t * list,
00186 void * desc)
00187 {
00188 struct rsbac_list_item_t * curr;
00189
00190 if(!list || !desc || !list->compare)
00191 return NULL;
00192
00193 curr = list->ta_curr;
00194 if(!curr)
00195 {
00196 curr = list->ta_head;
00197 if(!curr)
00198 return NULL;
00199 }
00200
00201
00202 if(list->compare(desc, &curr[1]))
00203 {
00204 if((list->compare(desc, &curr[1]) > 0))
00205 {
00206 curr = curr->next;
00207 while ( curr
00208 && (list->compare(desc, &curr[1]) > 0)
00209 )
00210 curr = curr->next;
00211 }
00212 else
00213 {
00214 curr = curr->prev;
00215 while ( curr
00216 && (list->compare(desc, &curr[1]) < 0)
00217 )
00218 curr = curr->prev;
00219 }
00220 if(curr)
00221 {
00222
00223 list->ta_curr = curr;
00224 if(!list->compare(desc, &curr[1]))
00225 return curr;
00226 }
00227
00228 return NULL;
00229 }
00230
00231 return curr;
00232 }
00233
00234 static struct rsbac_list_item_t * ta_lookup_item_memcmp(
00235 struct rsbac_list_reg_item_t * list,
00236 void * desc)
00237 {
00238 struct rsbac_list_item_t * curr;
00239
00240 if(!list || !desc)
00241 return NULL;
00242
00243 curr = list->ta_curr;
00244 if(!curr)
00245 {
00246 curr = list->ta_head;
00247 if(!curr)
00248 return NULL;
00249 }
00250
00251
00252 if(memcmp(desc,
00253 &curr[1],
00254 list->info.desc_size))
00255 {
00256 if(memcmp(desc,
00257 &curr[1],
00258 list->info.desc_size) > 0)
00259 {
00260 curr = curr->next;
00261 while ( curr
00262 && (memcmp(desc,
00263 &curr[1],
00264 list->info.desc_size) > 0)
00265 )
00266 curr = curr->next;
00267 }
00268 else
00269 {
00270 curr = curr->prev;
00271 while ( curr
00272 && (memcmp(desc,
00273 &curr[1],
00274 list->info.desc_size) < 0)
00275 )
00276 curr = curr->prev;
00277 }
00278 if (curr)
00279 {
00280
00281 list->ta_curr = curr;
00282 if(!memcmp(desc,
00283 &curr[1],
00284 list->info.desc_size))
00285 return curr;
00286 }
00287
00288 return NULL;
00289 }
00290
00291 return curr;
00292 }
00293
00294 static struct rsbac_list_item_t * ta_lookup_item(
00295 rsbac_list_ta_number_t ta_number,
00296 struct rsbac_list_reg_item_t * list,
00297 void * desc)
00298 {
00299 if(!list || !desc)
00300 return NULL;
00301
00302 if(!list->ta_copied)
00303 return lookup_item(list, desc);
00304 if(list->ta_copied != ta_number)
00305 return NULL;
00306
00307 if(list->compare)
00308 return ta_lookup_item_compare(list, desc);
00309 else
00310 return ta_lookup_item_memcmp(list, desc);
00311 }
00312 #endif
00313
00314 static struct rsbac_list_item_t * lookup_item_data_compare(
00315 struct rsbac_list_reg_item_t * list,
00316 void * data,
00317 rsbac_list_data_compare_function_t compare)
00318 {
00319 struct rsbac_list_item_t * curr;
00320
00321 if(!list || !data || !compare)
00322 return NULL;
00323
00324 curr = list->head;
00325
00326
00327 while ( curr
00328 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00329 || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00330 )
00331 )
00332 curr = curr->next;
00333
00334 return curr;
00335 }
00336
00337 static struct rsbac_list_item_t * lookup_item_data_memcmp(
00338 struct rsbac_list_reg_item_t * list,
00339 void * data)
00340 {
00341 struct rsbac_list_item_t * curr;
00342
00343 if(!list || !data)
00344 return NULL;
00345
00346 curr = list->head;
00347
00348
00349 while ( curr
00350 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00351 || memcmp(data,
00352 &curr[1] + list->info.desc_size,
00353 list->info.data_size)
00354 )
00355 )
00356 curr = curr->next;
00357
00358 return curr;
00359 }
00360
00361 static struct rsbac_list_item_t * lookup_item_data(
00362 struct rsbac_list_reg_item_t * list,
00363 void * data,
00364 rsbac_list_data_compare_function_t compare)
00365 {
00366 if(!list || !data)
00367 return NULL;
00368
00369 if(compare)
00370 return lookup_item_data_compare(list, data, compare);
00371 else
00372 return lookup_item_data_memcmp(list, data);
00373 }
00374
00375 #ifdef CONFIG_RSBAC_LIST_TRANS
00376 static struct rsbac_list_item_t * ta_lookup_item_data_compare(
00377 struct rsbac_list_reg_item_t * list,
00378 void * data,
00379 rsbac_list_data_compare_function_t compare)
00380 {
00381 struct rsbac_list_item_t * curr;
00382
00383 if(!list || !data || !compare)
00384 return NULL;
00385
00386 curr = list->ta_head;
00387
00388
00389 while ( curr
00390 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00391 || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00392 )
00393 )
00394 curr = curr->next;
00395
00396 return curr;
00397 }
00398
00399 static struct rsbac_list_item_t * ta_lookup_item_data_memcmp(
00400 struct rsbac_list_reg_item_t * list,
00401 void * data)
00402 {
00403 struct rsbac_list_item_t * curr;
00404
00405 if(!list || !data)
00406 return NULL;
00407
00408 curr = list->ta_head;
00409
00410
00411 while ( curr
00412 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00413 || memcmp(data,
00414 &curr[1] + list->info.desc_size,
00415 list->info.data_size)
00416 )
00417 )
00418 curr = curr->next;
00419
00420 return curr;
00421 }
00422
00423 static struct rsbac_list_item_t * ta_lookup_item_data(
00424 rsbac_list_ta_number_t ta_number,
00425 struct rsbac_list_reg_item_t * list,
00426 void * data,
00427 rsbac_list_data_compare_function_t compare)
00428 {
00429 if(!list || !data)
00430 return NULL;
00431
00432 if(!list->ta_copied || list->ta_copied != ta_number)
00433 return lookup_item_data(list, data, compare);
00434
00435 if(compare)
00436 return ta_lookup_item_data_compare(list, data, compare);
00437 else
00438 return ta_lookup_item_data_memcmp(list, data);
00439 }
00440 #endif
00441
00442
00443
00444 static struct rsbac_list_item_t * lookup_lol_subitem_compare(
00445 struct rsbac_list_lol_reg_item_t * list,
00446 struct rsbac_list_lol_item_t * sublist,
00447 void * subdesc,
00448 rsbac_list_compare_function_t compare)
00449 {
00450 struct rsbac_list_item_t * curr;
00451
00452 if(!list || !sublist || !subdesc || !compare)
00453 return NULL;
00454
00455 curr = sublist->curr;
00456 if(!curr)
00457 {
00458 curr = sublist->head;
00459 if(!curr)
00460 return NULL;
00461 }
00462
00463
00464 if(compare(&curr[1],subdesc))
00465 {
00466 if((compare(&curr[1], subdesc) < 0))
00467 {
00468 curr = curr->next;
00469 while ( curr
00470 && (compare(&curr[1], subdesc) < 0)
00471 )
00472 curr = curr->next;
00473 }
00474 else
00475 {
00476 curr = curr->prev;
00477 while ( curr
00478 && (compare(&curr[1], subdesc) > 0)
00479 )
00480 curr = curr->prev;
00481 }
00482 if (curr)
00483 {
00484
00485 sublist->curr = curr;
00486 if(!compare(&curr[1], subdesc))
00487 return curr;
00488 }
00489
00490 return NULL;
00491 }
00492
00493 return curr;
00494 }
00495
00496 static struct rsbac_list_item_t * lookup_lol_subitem_memcmp(
00497 struct rsbac_list_lol_reg_item_t * list,
00498 struct rsbac_list_lol_item_t * sublist,
00499 void * subdesc)
00500 {
00501 struct rsbac_list_item_t * curr;
00502
00503 if(!list || !sublist || !subdesc)
00504 return NULL;
00505
00506 curr = sublist->curr;
00507 if(!curr)
00508 {
00509 curr = sublist->head;
00510 if(!curr)
00511 return NULL;
00512 }
00513
00514
00515 if(memcmp(subdesc,
00516 &curr[1],
00517 list->info.subdesc_size))
00518 {
00519 if(memcmp(subdesc,
00520 &curr[1],
00521 list->info.subdesc_size) > 0)
00522 {
00523 curr = curr->next;
00524 while ( curr
00525 && (memcmp(subdesc,
00526 &curr[1],
00527 list->info.subdesc_size) > 0)
00528 )
00529 curr = curr->next;
00530 }
00531 else
00532 {
00533 curr = curr->prev;
00534 while ( curr
00535 && (memcmp(subdesc,
00536 &curr[1],
00537 list->info.subdesc_size) < 0)
00538 )
00539 curr = curr->prev;
00540 }
00541 if (curr)
00542 {
00543
00544 sublist->curr = curr;
00545 if(!memcmp(subdesc,
00546 &curr[1],
00547 list->info.subdesc_size))
00548 return curr;
00549 }
00550
00551 return NULL;
00552 }
00553
00554 return curr;
00555 }
00556
00557 static struct rsbac_list_item_t * lookup_lol_subitem(
00558 struct rsbac_list_lol_reg_item_t * list,
00559 struct rsbac_list_lol_item_t * sublist,
00560 void * subdesc)
00561 {
00562 if(!list || !sublist || !subdesc)
00563 return NULL;
00564
00565 if(list->subcompare)
00566 return lookup_lol_subitem_compare(list, sublist, subdesc, list->subcompare);
00567 else
00568 return lookup_lol_subitem_memcmp(list, sublist, subdesc);
00569 }
00570
00571 static struct rsbac_list_item_t * lookup_lol_subitem_user_compare(
00572 struct rsbac_list_lol_reg_item_t * list,
00573 struct rsbac_list_lol_item_t * sublist,
00574 void * subdesc,
00575 rsbac_list_compare_function_t compare)
00576 {
00577 struct rsbac_list_item_t * curr;
00578
00579 if(!list || !sublist || !subdesc || !compare)
00580 return NULL;
00581
00582 curr = sublist->head;
00583
00584 while(curr)
00585 {
00586 if(!compare(&curr[1],subdesc))
00587 return curr;
00588 curr = curr->next;
00589 }
00590 return curr;
00591 }
00592
00593
00594
00595 static struct rsbac_list_lol_item_t * lookup_lol_item_compare(
00596 struct rsbac_list_lol_reg_item_t * list,
00597 void * desc)
00598 {
00599 struct rsbac_list_lol_item_t * curr;
00600
00601 if(!list || !desc || !list->compare)
00602 return NULL;
00603
00604 curr = list->curr;
00605 if(!curr)
00606 {
00607 curr = list->head;
00608 if(!curr)
00609 return NULL;
00610 }
00611
00612
00613 if(list->compare(desc, &curr[1]))
00614 {
00615 if((list->compare(desc, &curr[1]) > 0))
00616 {
00617 curr = curr->next;
00618 while ( curr
00619 && (list->compare(desc, &curr[1]) > 0)
00620 )
00621 curr = curr->next;
00622 }
00623 else
00624 {
00625 curr = curr->prev;
00626 while ( curr
00627 && (list->compare(desc, &curr[1]) < 0)
00628 )
00629 curr = curr->prev;
00630 }
00631 if (curr)
00632 {
00633
00634 list->curr = curr;
00635 if(!list->compare(desc, &curr[1]))
00636 return curr;
00637 }
00638
00639 return NULL;
00640 }
00641
00642 return curr;
00643 }
00644
00645 static struct rsbac_list_lol_item_t * lookup_lol_item_memcmp(
00646 struct rsbac_list_lol_reg_item_t * list,
00647 void * desc)
00648 {
00649 struct rsbac_list_lol_item_t * curr;
00650
00651 if(!list || !desc)
00652 return NULL;
00653
00654 curr = list->curr;
00655 if(!curr)
00656 {
00657 curr = list->head;
00658 if(!curr)
00659 return NULL;
00660 }
00661
00662
00663 if(memcmp(desc,
00664 &curr[1],
00665 list->info.desc_size))
00666 {
00667 if(memcmp(desc,
00668 &curr[1],
00669 list->info.desc_size) > 0)
00670 {
00671 curr = curr->next;
00672 while ( curr
00673 && (memcmp(desc,
00674 &curr[1],
00675 list->info.desc_size) > 0)
00676 )
00677 curr = curr->next;
00678 }
00679 else
00680 {
00681 curr = curr->prev;
00682 while ( curr
00683 && (memcmp(desc,
00684 &curr[1],
00685 list->info.desc_size) < 0)
00686 )
00687 curr = curr->prev;
00688 }
00689 if (curr)
00690 {
00691
00692 list->curr = curr;
00693 if(!memcmp(desc,
00694 &curr[1],
00695 list->info.desc_size))
00696 return curr;
00697 }
00698
00699 return NULL;
00700 }
00701
00702 return curr;
00703 }
00704
00705 static struct rsbac_list_lol_item_t * lookup_lol_item(
00706 struct rsbac_list_lol_reg_item_t * list,
00707 void * desc)
00708 {
00709 if(!list || !desc)
00710 return NULL;
00711
00712 if(list->compare)
00713 return lookup_lol_item_compare(list, desc);
00714 else
00715 return lookup_lol_item_memcmp(list, desc);
00716 }
00717
00718 #ifdef CONFIG_RSBAC_LIST_TRANS
00719 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_compare(
00720 struct rsbac_list_lol_reg_item_t * list,
00721 void * desc)
00722 {
00723 struct rsbac_list_lol_item_t * curr;
00724
00725 if(!list || !desc || !list->compare)
00726 return NULL;
00727
00728 curr = list->ta_curr;
00729 if(!curr)
00730 {
00731 curr = list->ta_head;
00732 if(!curr)
00733 return NULL;
00734 }
00735
00736
00737 if(list->compare(desc, &curr[1]))
00738 {
00739 if((list->compare(desc, &curr[1]) > 0))
00740 {
00741 curr = curr->next;
00742 while ( curr
00743 && (list->compare(desc, &curr[1]) > 0)
00744 )
00745 curr = curr->next;
00746 }
00747 else
00748 {
00749 curr = curr->prev;
00750 while ( curr
00751 && (list->compare(desc, &curr[1]) < 0)
00752 )
00753 curr = curr->prev;
00754 }
00755 if (curr)
00756 {
00757
00758 list->ta_curr = curr;
00759 if(!list->compare(desc, &curr[1]))
00760 return curr;
00761 }
00762
00763 return NULL;
00764 }
00765
00766 return curr;
00767 }
00768
00769 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_memcmp(
00770 struct rsbac_list_lol_reg_item_t * list,
00771 void * desc)
00772 {
00773 struct rsbac_list_lol_item_t * curr;
00774
00775 if(!list || !desc)
00776 return NULL;
00777
00778 curr = list->ta_curr;
00779 if(!curr)
00780 {
00781 curr = list->ta_head;
00782 if(!curr)
00783 return NULL;
00784 }
00785
00786
00787 if(memcmp(desc,
00788 &curr[1],
00789 list->info.desc_size))
00790 {
00791 if(memcmp(desc,
00792 &curr[1],
00793 list->info.desc_size) > 0)
00794 {
00795 curr = curr->next;
00796 while ( curr
00797 && (memcmp(desc,
00798 &curr[1],
00799 list->info.desc_size) > 0)
00800 )
00801 curr = curr->next;
00802 }
00803 else
00804 {
00805 curr = curr->prev;
00806 while ( curr
00807 && (memcmp(desc,
00808 &curr[1],
00809 list->info.desc_size) < 0)
00810 )
00811 curr = curr->prev;
00812 }
00813 if (curr)
00814 {
00815
00816 list->ta_curr = curr;
00817 if(!memcmp(desc,
00818 &curr[1],
00819 list->info.desc_size))
00820 return curr;
00821 }
00822
00823 return NULL;
00824 }
00825
00826 return curr;
00827 }
00828
00829 static struct rsbac_list_lol_item_t * ta_lookup_lol_item(
00830 rsbac_list_ta_number_t ta_number,
00831 struct rsbac_list_lol_reg_item_t * list,
00832 void * desc)
00833 {
00834 if(!list || !desc)
00835 return NULL;
00836
00837 if(!list->ta_copied)
00838 return lookup_lol_item(list, desc);
00839 if(list->ta_copied != ta_number)
00840 return NULL;
00841
00842 if(list->compare)
00843 return ta_lookup_lol_item_compare(list, desc);
00844 else
00845 return ta_lookup_lol_item_memcmp(list, desc);
00846 }
00847 #endif
00848
00849 static struct rsbac_list_lol_item_t * lookup_lol_item_data_compare(
00850 struct rsbac_list_lol_reg_item_t * list,
00851 void * data,
00852 rsbac_list_data_compare_function_t compare)
00853 {
00854 struct rsbac_list_lol_item_t * curr;
00855
00856 if(!list || !data || !compare)
00857 return NULL;
00858
00859 curr = list->head;
00860
00861
00862 while ( curr
00863 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00864 || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00865 )
00866 )
00867 curr = curr->next;
00868
00869 return curr;
00870 }
00871
00872 static struct rsbac_list_lol_item_t * lookup_lol_item_data_memcmp(
00873 struct rsbac_list_lol_reg_item_t * list,
00874 void * data)
00875 {
00876 struct rsbac_list_lol_item_t * curr;
00877
00878 if(!list || !data)
00879 return NULL;
00880
00881 curr = list->head;
00882
00883
00884 while ( curr
00885 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00886 || memcmp(data,
00887 &curr[1] + list->info.desc_size,
00888 list->info.data_size)
00889 )
00890 )
00891 curr = curr->next;
00892
00893 return curr;
00894 }
00895
00896 static struct rsbac_list_lol_item_t * lookup_lol_item_data(
00897 struct rsbac_list_lol_reg_item_t * list,
00898 void * data,
00899 rsbac_list_data_compare_function_t compare)
00900 {
00901 if(!list || !data)
00902 return NULL;
00903
00904 if(compare)
00905 return lookup_lol_item_data_compare(list, data, compare);
00906 else
00907 return lookup_lol_item_data_memcmp(list, data);
00908 }
00909
00910 #ifdef CONFIG_RSBAC_LIST_TRANS
00911 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data_compare(
00912 struct rsbac_list_lol_reg_item_t * list,
00913 void * data,
00914 rsbac_list_data_compare_function_t compare)
00915 {
00916 struct rsbac_list_lol_item_t * curr;
00917
00918 if(!list || !data || !compare)
00919 return NULL;
00920
00921 curr = list->ta_head;
00922
00923
00924 while ( curr
00925 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00926 || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data)
00927 )
00928 )
00929 curr = curr->next;
00930
00931 return curr;
00932 }
00933
00934 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data_memcmp(
00935 struct rsbac_list_lol_reg_item_t * list,
00936 void * data)
00937 {
00938 struct rsbac_list_lol_item_t * curr;
00939
00940 if(!list || !data)
00941 return NULL;
00942
00943 curr = list->ta_head;
00944
00945
00946 while ( curr
00947 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME))
00948 || memcmp(data,
00949 &curr[1] + list->info.desc_size,
00950 list->info.data_size)
00951 )
00952 )
00953 curr = curr->next;
00954
00955 return curr;
00956 }
00957
00958 static struct rsbac_list_lol_item_t * ta_lookup_lol_item_data(
00959 rsbac_list_ta_number_t ta_number,
00960 struct rsbac_list_lol_reg_item_t * list,
00961 void * data,
00962 rsbac_list_data_compare_function_t compare)
00963 {
00964 if(!list || !data)
00965 return NULL;
00966
00967 if(!list->ta_copied || list->ta_copied != ta_number)
00968 return lookup_lol_item_data(list, data, compare);
00969
00970 if(compare)
00971 return ta_lookup_lol_item_data_compare(list, data, compare);
00972 else
00973 return ta_lookup_lol_item_data_memcmp(list, data);
00974 }
00975 #endif
00976
00977
00978
00979 static struct rsbac_list_reg_item_t * lookup_reg(struct rsbac_list_reg_item_t * handle)
00980 {
00981 struct rsbac_list_reg_item_t * curr = reg_head.curr;
00982
00983 if(!handle)
00984 return NULL;
00985
00986 if(curr != handle)
00987 {
00988 curr = reg_head.head;
00989 while (curr && curr != handle)
00990 curr = curr->next;
00991 if (curr)
00992 reg_head.curr=curr;
00993 #ifdef CONFIG_RSBAC_DEBUG
00994 else
00995 if(rsbac_debug_lists)
00996 {
00997 rsbac_printk(KERN_DEBUG "lookup_reg(): Lookup of unknown list handle %p\n",
00998 handle);
00999 }
01000 #endif
01001 }
01002
01003 return curr;
01004 }
01005
01006 static struct rsbac_list_reg_item_t * lookup_reg_name(char * name, kdev_t device)
01007 {
01008 struct rsbac_list_reg_item_t * curr = reg_head.curr;
01009
01010 if(!name)
01011 return NULL;
01012
01013 if( !curr
01014 || ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01015 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01016 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01017 )
01018 )
01019 {
01020 curr = reg_head.head;
01021 while ( curr
01022 && ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01023 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01024 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01025 )
01026 )
01027 curr = curr->next;
01028 if (curr)
01029 reg_head.curr=curr;
01030 #ifdef CONFIG_RSBAC_DEBUG
01031 else
01032 if(rsbac_debug_lists)
01033 {
01034 rsbac_printk(KERN_DEBUG "lookup_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n",
01035 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
01036 }
01037 #endif
01038 }
01039
01040 return curr;
01041 }
01042
01043
01044
01045 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg(struct rsbac_list_lol_reg_item_t * handle)
01046 {
01047 struct rsbac_list_lol_reg_item_t * curr = lol_reg_head.curr;
01048
01049 if(!handle)
01050 return NULL;
01051
01052 if(curr != handle)
01053 {
01054 curr = lol_reg_head.head;
01055 while (curr && curr != handle)
01056 curr = curr->next;
01057 if (curr)
01058 lol_reg_head.curr=curr;
01059 #ifdef CONFIG_RSBAC_DEBUG
01060 else
01061 if(rsbac_debug_lists)
01062 {
01063 rsbac_printk(KERN_DEBUG "lookup_lol_reg(): Lookup of unknown list handle %p\n",
01064 handle);
01065 }
01066 #endif
01067 }
01068
01069 return curr;
01070 }
01071
01072 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg_name(char * name, kdev_t device)
01073 {
01074 struct rsbac_list_lol_reg_item_t * curr = lol_reg_head.curr;
01075
01076 if(!name)
01077 return NULL;
01078
01079 if( !curr
01080 || ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01081 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01082 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01083 )
01084 )
01085 {
01086 curr = lol_reg_head.head;
01087 while ( curr
01088 && ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME)
01089 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device))
01090 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device))
01091 )
01092 )
01093 curr = curr->next;
01094 if (curr)
01095 lol_reg_head.curr=curr;
01096 #ifdef CONFIG_RSBAC_DEBUG
01097 else
01098 if(rsbac_debug_lists)
01099 {
01100 rsbac_printk(KERN_DEBUG "lookup_lol_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n",
01101 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
01102 }
01103 #endif
01104 }
01105
01106 return curr;
01107 }
01108
01109
01110
01111
01112 static struct rsbac_list_item_t * insert_item_compare(
01113 struct rsbac_list_reg_item_t * list,
01114 void * desc,
01115 struct rsbac_list_item_t * new_item_p)
01116 {
01117 struct rsbac_list_item_t * curr;
01118
01119 curr = list->curr;
01120 if(!curr)
01121 curr = list->head;
01122 if((list->compare(desc, &curr[1]) > 0))
01123 {
01124 curr = curr->next;
01125 while ( curr
01126 && (list->compare(desc, &curr[1]) > 0)
01127 )
01128 curr = curr->next;
01129 if (curr)
01130 {
01131
01132 new_item_p->prev=curr->prev;
01133 new_item_p->next=curr;
01134 curr->prev->next=new_item_p;
01135 curr->prev=new_item_p;
01136 }
01137 else
01138 {
01139
01140 new_item_p->prev=list->tail;
01141 new_item_p->next=NULL;
01142 list->tail->next=new_item_p;
01143 list->tail=new_item_p;
01144 }
01145 }
01146 else
01147 {
01148 curr = curr->prev;
01149 while ( curr
01150 && (list->compare(desc, &curr[1]) < 0)
01151 )
01152 curr = curr->prev;
01153 if (curr)
01154 {
01155
01156 new_item_p->prev=curr;
01157 new_item_p->next=curr->next;
01158 curr->next->prev=new_item_p;
01159 curr->next=new_item_p;
01160 }
01161 else
01162 {
01163
01164 new_item_p->prev=NULL;
01165 new_item_p->next=list->head;
01166 list->head->prev=new_item_p;
01167 list->head=new_item_p;
01168 }
01169 }
01170 list->count++;
01171 list->curr=new_item_p;
01172 return new_item_p;
01173 }
01174
01175 static struct rsbac_list_item_t * insert_item_memcmp(
01176 struct rsbac_list_reg_item_t * list,
01177 void * desc,
01178 struct rsbac_list_item_t * new_item_p)
01179 {
01180 struct rsbac_list_item_t * curr;
01181
01182 curr = list->curr;
01183 if(!curr)
01184 curr = list->head;
01185 if(memcmp(desc,
01186 &curr[1],
01187 list->info.desc_size) > 0)
01188 {
01189 curr = curr->next;
01190 while ( curr
01191 && (memcmp(desc,
01192 &curr[1],
01193 list->info.desc_size) > 0
01194 )
01195 )
01196 curr = curr->next;
01197 if (curr)
01198 {
01199
01200 new_item_p->prev=curr->prev;
01201 new_item_p->next=curr;
01202 curr->prev->next=new_item_p;
01203 curr->prev=new_item_p;
01204 }
01205 else
01206 {
01207
01208 new_item_p->prev=list->tail;
01209 new_item_p->next=NULL;
01210 list->tail->next=new_item_p;
01211 list->tail=new_item_p;
01212 }
01213 }
01214 else
01215 {
01216 curr = curr->prev;
01217 while ( curr
01218 && (memcmp(desc,
01219 &curr[1],
01220 list->info.desc_size) < 0
01221 )
01222 )
01223 curr = curr->prev;
01224 if (curr)
01225 {
01226
01227 new_item_p->prev=curr;
01228 new_item_p->next=curr->next;
01229 curr->next->prev=new_item_p;
01230 curr->next=new_item_p;
01231 }
01232 else
01233 {
01234
01235 new_item_p->prev=NULL;
01236 new_item_p->next=list->head;
01237 list->head->prev=new_item_p;
01238 list->head=new_item_p;
01239 }
01240 }
01241 list->count++;
01242 list->curr=new_item_p;
01243 return new_item_p;
01244 }
01245
01246 static struct rsbac_list_item_t * add_item(
01247 struct rsbac_list_reg_item_t * list,
01248 rsbac_time_t max_age,
01249 void * desc,
01250 void * data)
01251 {
01252 struct rsbac_list_item_t * new_item_p = NULL;
01253
01254 if(!list || !desc)
01255 return NULL;
01256
01257 if(!list || !desc)
01258 return NULL;
01259 if(list->info.data_size && !data)
01260 return NULL;
01261
01262 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01263 return(NULL);
01264 new_item_p->max_age = max_age;
01265
01266 memcpy(&new_item_p[1],
01267 desc, list->info.desc_size);
01268
01269
01270 if(data && list->info.data_size)
01271 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01272 data,
01273 list->info.data_size);
01274
01275 if (!list->head)
01276 {
01277 list->head=new_item_p;
01278 list->tail=new_item_p;
01279 list->curr=new_item_p;
01280 list->count = 1;
01281 new_item_p->prev=NULL;
01282 new_item_p->next=NULL;
01283 return new_item_p;
01284 }
01285 if(list->compare)
01286 return insert_item_compare(list, desc, new_item_p);
01287 else
01288 return insert_item_memcmp(list, desc, new_item_p);
01289 }
01290
01291 #ifdef CONFIG_RSBAC_LIST_TRANS
01292 static void ta_remove_all_items(struct rsbac_list_reg_item_t * list);
01293
01294 static int ta_copy(
01295 rsbac_list_ta_number_t ta_number,
01296 struct rsbac_list_reg_item_t * list)
01297 {
01298 struct rsbac_list_item_t * curr;
01299 struct rsbac_list_item_t * new_item_p;
01300 u_int item_size = sizeof(*new_item_p)
01301 + list->info.desc_size
01302 + list->info.data_size;
01303
01304 curr = list->head;
01305 if(curr)
01306 {
01307 if ( !(new_item_p = rsbac_kmalloc(item_size) ))
01308 {
01309 ta_remove_all_items(list);
01310 return(-RSBAC_ENOMEM);
01311 }
01312 memcpy(new_item_p, curr, item_size);
01313 new_item_p->prev = NULL;
01314 new_item_p->next = NULL;
01315 list->ta_head = new_item_p;
01316 list->ta_tail = new_item_p;
01317 list->ta_curr = new_item_p;
01318 list->ta_count = 1;
01319 curr = curr->next;
01320 }
01321 else
01322 {
01323 list->ta_head = NULL;
01324 list->ta_tail = NULL;
01325 list->ta_curr = NULL;
01326 list->ta_count = 0;
01327 list->ta_copied = ta_number;
01328 return 0;
01329 }
01330 while(curr)
01331 {
01332 if ( !(new_item_p = rsbac_kmalloc(item_size)) )
01333 {
01334 ta_remove_all_items(list);
01335 return(-RSBAC_ENOMEM);
01336 }
01337 memcpy(new_item_p, curr, item_size);
01338 new_item_p->prev = list->ta_tail;
01339 new_item_p->next = NULL;
01340 list->ta_tail->next = new_item_p;
01341 list->ta_tail = new_item_p;
01342 list->ta_count++;
01343 curr = curr->next;
01344 }
01345 list->ta_copied = ta_number;
01346 return 0;
01347 }
01348
01349 static void ta_remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list);
01350
01351 static int ta_lol_copy(
01352 rsbac_list_ta_number_t ta_number,
01353 struct rsbac_list_lol_reg_item_t * list)
01354 {
01355 struct rsbac_list_lol_item_t * curr;
01356 struct rsbac_list_lol_item_t * new_item_p;
01357 struct rsbac_list_item_t * sub_curr;
01358 struct rsbac_list_item_t * new_subitem_p;
01359 u_int item_size = sizeof(*new_item_p)
01360 + list->info.desc_size
01361 + list->info.data_size;
01362 u_int subitem_size = sizeof(*new_subitem_p)
01363 + list->info.subdesc_size
01364 + list->info.subdata_size;
01365
01366 list->ta_head = NULL;
01367 list->ta_tail = NULL;
01368 list->ta_curr = NULL;
01369 list->ta_count = 0;
01370
01371 curr = list->head;
01372 while(curr)
01373 {
01374 if ( !(new_item_p = rsbac_kmalloc(item_size)) )
01375 {
01376 ta_remove_all_lol_items(list);
01377 return(-RSBAC_ENOMEM);
01378 }
01379 memcpy(new_item_p, curr, item_size);
01380 new_item_p->head = NULL;
01381 new_item_p->tail = NULL;
01382 new_item_p->curr = NULL;
01383 new_item_p->count = 0;
01384 new_item_p->prev = NULL;
01385 new_item_p->next = NULL;
01386 sub_curr = curr->head;
01387 while(sub_curr)
01388 {
01389 if ( !(new_subitem_p = rsbac_kmalloc(subitem_size)) )
01390 {
01391 ta_remove_all_lol_items(list);
01392 rsbac_kfree(new_item_p);
01393 return(-RSBAC_ENOMEM);
01394 }
01395 memcpy(new_subitem_p, sub_curr, subitem_size);
01396 new_subitem_p->prev = NULL;
01397 new_subitem_p->next = NULL;
01398 if(new_item_p->tail)
01399 {
01400 new_subitem_p->prev = new_item_p->tail;
01401 new_item_p->tail->next = new_subitem_p;
01402 new_item_p->tail = new_subitem_p;
01403 new_item_p->count++;
01404 }
01405 else
01406 {
01407 new_item_p->head = new_subitem_p;
01408 new_item_p->tail = new_subitem_p;
01409 new_item_p->count = 1;
01410 }
01411 sub_curr = sub_curr->next;
01412 }
01413 if(list->ta_tail)
01414 {
01415 new_item_p->prev = list->ta_tail;
01416 list->ta_tail->next = new_item_p;
01417 list->ta_tail = new_item_p;
01418 list->ta_count++;
01419 }
01420 else
01421 {
01422 list->ta_head = new_item_p;
01423 list->ta_tail = new_item_p;
01424 list->ta_curr = new_item_p;
01425 list->ta_count = 1;
01426 }
01427 curr = curr->next;
01428 }
01429 list->ta_copied = ta_number;
01430 return 0;
01431 }
01432
01433 static struct rsbac_list_item_t * ta_insert_item_compare(
01434 struct rsbac_list_reg_item_t * list,
01435 void * desc,
01436 struct rsbac_list_item_t * new_item_p)
01437 {
01438 struct rsbac_list_item_t * curr;
01439
01440 curr = list->ta_curr;
01441 if(!curr)
01442 curr = list->ta_head;
01443 if((list->compare(desc, &curr[1]) > 0))
01444 {
01445 curr = curr->next;
01446 while ( curr
01447 && (list->compare(desc, &curr[1]) > 0)
01448 )
01449 curr = curr->next;
01450 if (curr)
01451 {
01452
01453 new_item_p->prev=curr->prev;
01454 new_item_p->next=curr;
01455 curr->prev->next=new_item_p;
01456 curr->prev=new_item_p;
01457 }
01458 else
01459 {
01460
01461 new_item_p->prev=list->ta_tail;
01462 new_item_p->next=NULL;
01463 list->ta_tail->next=new_item_p;
01464 list->ta_tail=new_item_p;
01465 }
01466 }
01467 else
01468 {
01469 curr = curr->prev;
01470 while ( curr
01471 && (list->compare(desc, &curr[1]) < 0)
01472 )
01473 curr = curr->prev;
01474 if (curr)
01475 {
01476
01477 new_item_p->prev=curr;
01478 new_item_p->next=curr->next;
01479 curr->next->prev=new_item_p;
01480 curr->next=new_item_p;
01481 }
01482 else
01483 {
01484
01485 new_item_p->prev=NULL;
01486 new_item_p->next=list->ta_head;
01487 list->ta_head->prev=new_item_p;
01488 list->ta_head=new_item_p;
01489 }
01490 }
01491 list->ta_count++;
01492 list->ta_curr=new_item_p;
01493 return new_item_p;
01494 }
01495
01496 static struct rsbac_list_item_t * ta_insert_item_memcmp(
01497 struct rsbac_list_reg_item_t * list,
01498 void * desc,
01499 struct rsbac_list_item_t * new_item_p)
01500 {
01501 struct rsbac_list_item_t * curr;
01502
01503 curr = list->ta_curr;
01504 if(!curr)
01505 curr = list->ta_head;
01506 if(memcmp(desc,
01507 &curr[1],
01508 list->info.desc_size) > 0)
01509 {
01510 curr = curr->next;
01511 while ( curr
01512 && (memcmp(desc,
01513 &curr[1],
01514 list->info.desc_size) > 0
01515 )
01516 )
01517 curr = curr->next;
01518 if (curr)
01519 {
01520
01521 new_item_p->prev=curr->prev;
01522 new_item_p->next=curr;
01523 curr->prev->next=new_item_p;
01524 curr->prev=new_item_p;
01525 }
01526 else
01527 {
01528
01529 new_item_p->prev=list->ta_tail;
01530 new_item_p->next=NULL;
01531 list->ta_tail->next=new_item_p;
01532 list->ta_tail=new_item_p;
01533 }
01534 }
01535 else
01536 {
01537 curr = curr->prev;
01538 while ( curr
01539 && (memcmp(desc,
01540 &curr[1],
01541 list->info.desc_size) < 0
01542 )
01543 )
01544 curr = curr->prev;
01545 if (curr)
01546 {
01547
01548 new_item_p->prev=curr;
01549 new_item_p->next=curr->next;
01550 curr->next->prev=new_item_p;
01551 curr->next=new_item_p;
01552 }
01553 else
01554 {
01555
01556 new_item_p->prev=NULL;
01557 new_item_p->next=list->ta_head;
01558 list->ta_head->prev=new_item_p;
01559 list->ta_head=new_item_p;
01560 }
01561 }
01562 list->ta_count++;
01563 list->ta_curr=new_item_p;
01564 return new_item_p;
01565 }
01566
01567 static struct rsbac_list_item_t * ta_add_item(
01568 rsbac_list_ta_number_t ta_number,
01569 struct rsbac_list_reg_item_t * list,
01570 rsbac_time_t max_age,
01571 void * desc,
01572 void * data)
01573 {
01574 struct rsbac_list_item_t * new_item_p = NULL;
01575
01576 if(!list || !desc)
01577 return NULL;
01578
01579 if(!list || !desc)
01580 return NULL;
01581 if(list->info.data_size && !data)
01582 return NULL;
01583 if(!ta_number)
01584 return add_item(list, max_age, desc, data);
01585
01586 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01587 return(NULL);
01588 new_item_p->max_age = max_age;
01589
01590 memcpy(&new_item_p[1],
01591 desc, list->info.desc_size);
01592
01593
01594 if(data && list->info.data_size)
01595 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01596 data,
01597 list->info.data_size);
01598
01599 if(!list->ta_copied)
01600 {
01601 if(ta_copy(ta_number, list))
01602 {
01603 rsbac_kfree(new_item_p);
01604 return NULL;
01605 }
01606 }
01607 else
01608 {
01609 if(list->ta_copied != ta_number)
01610 {
01611 rsbac_kfree(new_item_p);
01612 return NULL;
01613 }
01614 }
01615
01616 if (!list->ta_head)
01617 {
01618 list->ta_head=new_item_p;
01619 list->ta_tail=new_item_p;
01620 list->ta_curr=new_item_p;
01621 list->ta_count = 1;
01622 new_item_p->prev=NULL;
01623 new_item_p->next=NULL;
01624 return new_item_p;
01625 }
01626 if(list->compare)
01627 return ta_insert_item_compare(list, desc, new_item_p);
01628 else
01629 return ta_insert_item_memcmp(list, desc, new_item_p);
01630 }
01631 #endif
01632
01633
01634 static struct rsbac_list_item_t * insert_lol_subitem_compare(
01635 struct rsbac_list_lol_reg_item_t * list,
01636 struct rsbac_list_lol_item_t * sublist,
01637 void * subdesc,
01638 struct rsbac_list_item_t * new_item_p)
01639 {
01640 struct rsbac_list_item_t * curr;
01641
01642 curr = sublist->curr;
01643 if(!curr)
01644 curr = sublist->head;
01645 if((list->subcompare(subdesc, &curr[1]) > 0))
01646 {
01647 curr = curr->next;
01648 while ( curr
01649 && (list->subcompare(subdesc, &curr[1]) > 0)
01650 )
01651 curr = curr->next;
01652 if (curr)
01653 {
01654
01655 new_item_p->prev=curr->prev;
01656 new_item_p->next=curr;
01657 curr->prev->next=new_item_p;
01658 curr->prev=new_item_p;
01659 }
01660 else
01661 {
01662
01663 new_item_p->prev=sublist->tail;
01664 new_item_p->next=NULL;
01665 sublist->tail->next=new_item_p;
01666 sublist->tail=new_item_p;
01667 }
01668 }
01669 else
01670 {
01671 curr = curr->prev;
01672 while ( curr
01673 && (list->subcompare(subdesc, &curr[1]) < 0)
01674 )
01675 curr = curr->prev;
01676 if (curr)
01677 {
01678
01679 new_item_p->prev=curr;
01680 new_item_p->next=curr->next;
01681 curr->next->prev=new_item_p;
01682 curr->next=new_item_p;
01683 }
01684 else
01685 {
01686
01687 new_item_p->prev=NULL;
01688 new_item_p->next=sublist->head;
01689 sublist->head->prev=new_item_p;
01690 sublist->head=new_item_p;
01691 }
01692 }
01693 sublist->count++;
01694 sublist->curr=new_item_p;
01695 return new_item_p;
01696 }
01697
01698 static struct rsbac_list_item_t * insert_lol_subitem_memcmp(
01699 struct rsbac_list_lol_reg_item_t * list,
01700 struct rsbac_list_lol_item_t * sublist,
01701 void * subdesc,
01702 struct rsbac_list_item_t * new_item_p)
01703 {
01704 struct rsbac_list_item_t * curr;
01705
01706 curr = sublist->curr;
01707 if(!curr)
01708 curr = sublist->head;
01709 if(memcmp(subdesc,
01710 &curr[1],
01711 list->info.subdesc_size) > 0)
01712 {
01713 curr = curr->next;
01714 while ( curr
01715 && (memcmp(subdesc,
01716 &curr[1],
01717 list->info.subdesc_size) > 0
01718 )
01719 )
01720 curr = curr->next;
01721 if (curr)
01722 {
01723
01724 new_item_p->prev=curr->prev;
01725 new_item_p->next=curr;
01726 curr->prev->next=new_item_p;
01727 curr->prev=new_item_p;
01728 }
01729 else
01730 {
01731
01732 new_item_p->prev=sublist->tail;
01733 new_item_p->next=NULL;
01734 sublist->tail->next=new_item_p;
01735 sublist->tail=new_item_p;
01736 }
01737 }
01738 else
01739 {
01740 curr = curr->prev;
01741 while ( curr
01742 && (memcmp(subdesc,
01743 &curr[1],
01744 list->info.subdesc_size) < 0
01745 )
01746 )
01747 curr = curr->prev;
01748 if (curr)
01749 {
01750
01751 new_item_p->prev=curr;
01752 new_item_p->next=curr->next;
01753 curr->next->prev=new_item_p;
01754 curr->next=new_item_p;
01755 }
01756 else
01757 {
01758
01759 new_item_p->prev=NULL;
01760 new_item_p->next=sublist->head;
01761 sublist->head->prev=new_item_p;
01762 sublist->head=new_item_p;
01763 }
01764 }
01765 sublist->count++;
01766 sublist->curr=new_item_p;
01767 return new_item_p;
01768 }
01769
01770 static struct rsbac_list_item_t * add_lol_subitem(
01771 struct rsbac_list_lol_reg_item_t * list,
01772 struct rsbac_list_lol_item_t * sublist,
01773 rsbac_time_t max_age,
01774 void * subdesc,
01775 void * subdata)
01776 {
01777 struct rsbac_list_item_t * new_item_p = NULL;
01778
01779 if(!list || !sublist || !subdesc)
01780 return NULL;
01781 if(list->info.subdata_size && !subdata)
01782 return NULL;
01783
01784 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.subdesc_size + list->info.subdata_size)) )
01785 return(NULL);
01786 new_item_p->max_age = max_age;
01787
01788 memcpy(&new_item_p[1],
01789 subdesc,
01790 list->info.subdesc_size);
01791
01792
01793 if(subdata && list->info.subdata_size)
01794 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.subdesc_size,
01795 subdata,
01796 list->info.subdata_size);
01797
01798
01799 if (!sublist->head)
01800 {
01801 sublist->head=new_item_p;
01802 sublist->tail=new_item_p;
01803 sublist->curr=new_item_p;
01804 sublist->count = 1;
01805 new_item_p->prev=NULL;
01806 new_item_p->next=NULL;
01807 return(new_item_p);
01808 }
01809 if(list->subcompare)
01810 return insert_lol_subitem_compare(list, sublist, subdesc, new_item_p);
01811 else
01812 return insert_lol_subitem_memcmp(list, sublist, subdesc, new_item_p);
01813 }
01814
01815 static struct rsbac_list_lol_item_t * insert_lol_item_compare(
01816 struct rsbac_list_lol_reg_item_t * list,
01817 void * desc,
01818 struct rsbac_list_lol_item_t * new_item_p)
01819 {
01820 struct rsbac_list_lol_item_t * curr;
01821
01822 curr = list->curr;
01823 if(!curr)
01824 curr = list->head;
01825 if((list->compare(desc, &curr[1]) > 0))
01826 {
01827 curr = curr->next;
01828 while ( curr
01829 && (list->compare(desc, &curr[1]) > 0)
01830 )
01831 curr = curr->next;
01832 if (curr)
01833 {
01834
01835 new_item_p->prev=curr->prev;
01836 new_item_p->next=curr;
01837 curr->prev->next=new_item_p;
01838 curr->prev=new_item_p;
01839 }
01840 else
01841 {
01842
01843 new_item_p->prev=list->tail;
01844 new_item_p->next=NULL;
01845 list->tail->next=new_item_p;
01846 list->tail=new_item_p;
01847 }
01848 }
01849 else
01850 {
01851 curr = curr->prev;
01852 while ( curr
01853 && (list->compare(desc, &curr[1]) < 0)
01854 )
01855 curr = curr->prev;
01856 if (curr)
01857 {
01858
01859 new_item_p->prev=curr;
01860 new_item_p->next=curr->next;
01861 curr->next->prev=new_item_p;
01862 curr->next=new_item_p;
01863 }
01864 else
01865 {
01866
01867 new_item_p->prev=NULL;
01868 new_item_p->next=list->head;
01869 list->head->prev=new_item_p;
01870 list->head=new_item_p;
01871 }
01872 }
01873 list->count++;
01874 list->curr=new_item_p;
01875 return new_item_p;
01876 }
01877
01878 static struct rsbac_list_lol_item_t * insert_lol_item_memcmp(
01879 struct rsbac_list_lol_reg_item_t * list,
01880 void * desc,
01881 struct rsbac_list_lol_item_t * new_item_p)
01882 {
01883 struct rsbac_list_lol_item_t * curr;
01884
01885 curr = list->curr;
01886 if(!curr)
01887 curr = list->head;
01888 if(memcmp(desc,
01889 &curr[1],
01890 list->info.desc_size) > 0)
01891 {
01892 curr = curr->next;
01893 while ( curr
01894 && (memcmp(desc,
01895 &curr[1],
01896 list->info.desc_size) > 0
01897 )
01898 )
01899 curr = curr->next;
01900 if (curr)
01901 {
01902
01903 new_item_p->prev=curr->prev;
01904 new_item_p->next=curr;
01905 curr->prev->next=new_item_p;
01906 curr->prev=new_item_p;
01907 }
01908 else
01909 {
01910
01911 new_item_p->prev=list->tail;
01912 new_item_p->next=NULL;
01913 list->tail->next=new_item_p;
01914 list->tail=new_item_p;
01915 }
01916 }
01917 else
01918 {
01919 curr = curr->prev;
01920 while ( curr
01921 && (memcmp(desc,
01922 &curr[1],
01923 list->info.desc_size) < 0
01924 )
01925 )
01926 curr = curr->prev;
01927 if (curr)
01928 {
01929
01930 new_item_p->prev=curr;
01931 new_item_p->next=curr->next;
01932 curr->next->prev=new_item_p;
01933 curr->next=new_item_p;
01934 }
01935 else
01936 {
01937
01938 new_item_p->prev=NULL;
01939 new_item_p->next=list->head;
01940 list->head->prev=new_item_p;
01941 list->head=new_item_p;
01942 }
01943 }
01944 list->count++;
01945 list->curr=new_item_p;
01946 return new_item_p;
01947 }
01948
01949 static struct rsbac_list_lol_item_t * add_lol_item(
01950 struct rsbac_list_lol_reg_item_t * list,
01951 rsbac_time_t max_age,
01952 void * desc,
01953 void * data)
01954 {
01955 struct rsbac_list_lol_item_t * new_item_p = NULL;
01956
01957 if(!list || !desc)
01958 return NULL;
01959 if(list->info.data_size && !data)
01960 return NULL;
01961
01962 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
01963 return(NULL);
01964
01965 new_item_p->head = NULL;
01966 new_item_p->tail = NULL;
01967 new_item_p->curr = NULL;
01968 new_item_p->count = 0;
01969 new_item_p->max_age = max_age;
01970
01971 memcpy(&new_item_p[1],
01972 desc,
01973 list->info.desc_size);
01974
01975
01976 if(data && list->info.data_size)
01977 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
01978 data,
01979 list->info.data_size);
01980
01981 if (!list->head)
01982 {
01983 list->head=new_item_p;
01984 list->tail=new_item_p;
01985 list->curr=new_item_p;
01986 list->count = 1;
01987 new_item_p->prev=NULL;
01988 new_item_p->next=NULL;
01989 return(new_item_p);
01990 }
01991 if(list->compare)
01992 return insert_lol_item_compare(list, desc, new_item_p);
01993 else
01994 return insert_lol_item_memcmp(list, desc, new_item_p);
01995 }
01996
01997 #ifdef CONFIG_RSBAC_LIST_TRANS
01998 static struct rsbac_list_lol_item_t * ta_insert_lol_item_compare(
01999 struct rsbac_list_lol_reg_item_t * list,
02000 void * desc,
02001 struct rsbac_list_lol_item_t * new_item_p)
02002 {
02003 struct rsbac_list_lol_item_t * curr;
02004
02005 curr = list->ta_curr;
02006 if(!curr)
02007 curr = list->ta_head;
02008 if((list->compare(desc, &curr[1]) > 0))
02009 {
02010 curr = curr->next;
02011 while ( curr
02012 && (list->compare(desc, &curr[1]) > 0)
02013 )
02014 curr = curr->next;
02015 if (curr)
02016 {
02017
02018 new_item_p->prev=curr->prev;
02019 new_item_p->next=curr;
02020 curr->prev->next=new_item_p;
02021 curr->prev=new_item_p;
02022 }
02023 else
02024 {
02025
02026 new_item_p->prev=list->ta_tail;
02027 new_item_p->next=NULL;
02028 list->ta_tail->next=new_item_p;
02029 list->ta_tail=new_item_p;
02030 }
02031 }
02032 else
02033 {
02034 curr = curr->prev;
02035 while ( curr
02036 && (list->compare(desc, &curr[1]) < 0)
02037 )
02038 curr = curr->prev;
02039 if (curr)
02040 {
02041
02042 new_item_p->prev=curr;
02043 new_item_p->next=curr->next;
02044 curr->next->prev=new_item_p;
02045 curr->next=new_item_p;
02046 }
02047 else
02048 {
02049
02050 new_item_p->prev=NULL;
02051 new_item_p->next=list->ta_head;
02052 list->ta_head->prev=new_item_p;
02053 list->ta_head=new_item_p;
02054 }
02055 }
02056 list->ta_count++;
02057 list->ta_curr=new_item_p;
02058 return new_item_p;
02059 }
02060
02061 static struct rsbac_list_lol_item_t * ta_insert_lol_item_memcmp(
02062 struct rsbac_list_lol_reg_item_t * list,
02063 void * desc,
02064 struct rsbac_list_lol_item_t * new_item_p)
02065 {
02066 struct rsbac_list_lol_item_t * curr;
02067
02068 curr = list->ta_curr;
02069 if(!curr)
02070 curr = list->ta_head;
02071 if(memcmp(desc,
02072 &curr[1],
02073 list->info.desc_size) > 0)
02074 {
02075 curr = curr->next;
02076 while ( curr
02077 && (memcmp(desc,
02078 &curr[1],
02079 list->info.desc_size) > 0
02080 )
02081 )
02082 curr = curr->next;
02083 if (curr)
02084 {
02085
02086 new_item_p->prev=curr->prev;
02087 new_item_p->next=curr;
02088 curr->prev->next=new_item_p;
02089 curr->prev=new_item_p;
02090 }
02091 else
02092 {
02093
02094 new_item_p->prev=list->ta_tail;
02095 new_item_p->next=NULL;
02096 list->ta_tail->next=new_item_p;
02097 list->ta_tail=new_item_p;
02098 }
02099 }
02100 else
02101 {
02102 curr = curr->prev;
02103 while ( curr
02104 && (memcmp(desc,
02105 &curr[1],
02106 list->info.desc_size) < 0
02107 )
02108 )
02109 curr = curr->prev;
02110 if (curr)
02111 {
02112
02113 new_item_p->prev=curr;
02114 new_item_p->next=curr->next;
02115 curr->next->prev=new_item_p;
02116 curr->next=new_item_p;
02117 }
02118 else
02119 {
02120
02121 new_item_p->prev=NULL;
02122 new_item_p->next=list->ta_head;
02123 list->ta_head->prev=new_item_p;
02124 list->ta_head=new_item_p;
02125 }
02126 }
02127 list->ta_count++;
02128 list->ta_curr=new_item_p;
02129 return new_item_p;
02130 }
02131
02132 static struct rsbac_list_lol_item_t * ta_add_lol_item(
02133 rsbac_list_ta_number_t ta_number,
02134 struct rsbac_list_lol_reg_item_t * list,
02135 rsbac_time_t max_age,
02136 void * desc,
02137 void * data)
02138 {
02139 struct rsbac_list_lol_item_t * new_item_p = NULL;
02140
02141 if(!list || !desc)
02142 return NULL;
02143 if(list->info.data_size && !data)
02144 return NULL;
02145 if(!ta_number)
02146 return add_lol_item(list, max_age, desc, data);
02147
02148 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) )
02149 return(NULL);
02150
02151 new_item_p->head = NULL;
02152 new_item_p->tail = NULL;
02153 new_item_p->curr = NULL;
02154 new_item_p->count = 0;
02155 new_item_p->max_age = max_age;
02156 new_item_p->prev=NULL;
02157 new_item_p->next=NULL;
02158
02159 memcpy(&new_item_p[1],
02160 desc,
02161 list->info.desc_size);
02162
02163
02164 if(data && list->info.data_size)
02165 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size,
02166 data,
02167 list->info.data_size);
02168
02169 if(!list->ta_copied)
02170 {
02171 if(ta_lol_copy(ta_number, list))
02172 {
02173 rsbac_kfree(new_item_p);
02174 return NULL;
02175 }
02176 }
02177 else
02178 {
02179 if(list->ta_copied != ta_number)
02180 {
02181 rsbac_kfree(new_item_p);
02182 return NULL;
02183 }
02184 }
02185
02186 if (!list->ta_head)
02187 {
02188 list->ta_head=new_item_p;
02189 list->ta_tail=new_item_p;
02190 list->ta_curr=new_item_p;
02191 list->ta_count = 1;
02192 return(new_item_p);
02193 }
02194 if(list->compare)
02195 return ta_insert_lol_item_compare(list, desc, new_item_p);
02196 else
02197 return ta_insert_lol_item_memcmp(list, desc, new_item_p);
02198 }
02199 #endif
02200
02201
02202
02203
02204 static inline struct rsbac_list_reg_item_t*
02205 create_reg(struct rsbac_list_info_t * info_p,
02206 u_int flags,
02207 rsbac_list_compare_function_t * compare,
02208 rsbac_list_get_conv_t * get_conv,
02209 void * def_data,
02210 char * name,
02211 kdev_t device)
02212 {
02213 struct rsbac_list_reg_item_t * new_item_p = NULL;
02214
02215 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) )
02216 return(NULL);
02217 new_item_p->info = *info_p;
02218 if(!def_data)
02219 flags &= ~RSBAC_LIST_DEF_DATA;
02220 new_item_p->flags = flags;
02221 new_item_p->compare = compare;
02222 new_item_p->get_conv = get_conv;
02223 if(flags & RSBAC_LIST_DEF_DATA)
02224 {
02225 new_item_p->def_data = rsbac_kmalloc(info_p->data_size);
02226 if(new_item_p->def_data)
02227 memcpy(new_item_p->def_data, def_data, info_p->data_size);
02228 else
02229 {
02230 rsbac_kfree(new_item_p);
02231 return NULL;
02232 }
02233 }
02234 else
02235 new_item_p->def_data = NULL;
02236 if(name)
02237 {
02238 strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME);
02239 new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
02240 }
02241 else
02242 {
02243 strcpy(new_item_p->name, RSBAC_LIST_NONAME);
02244 }
02245 new_item_p->device = device;
02246 new_item_p->head = NULL;
02247 new_item_p->tail = NULL;
02248 new_item_p->curr = NULL;
02249 new_item_p->lock = RW_LOCK_UNLOCKED;
02250 new_item_p->count = 0;
02251 new_item_p->dirty = FALSE;
02252 if(flags & RSBAC_LIST_NO_WRITE)
02253 new_item_p->no_write = TRUE;
02254 else
02255 new_item_p->no_write = FALSE;
02256 new_item_p->lastchange.sec = 0;
02257 new_item_p->lastchange.nsec = 0;
02258 #ifdef CONFIG_RSBAC_LIST_TRANS
02259 new_item_p->ta_copied = FALSE;
02260 new_item_p->ta_head = NULL;
02261 new_item_p->ta_tail = NULL;
02262 new_item_p->ta_curr = NULL;
02263 new_item_p->ta_count = 0;
02264 #endif
02265 new_item_p->self = new_item_p;
02266 return new_item_p;
02267 }
02268
02269
02270 static struct rsbac_list_reg_item_t*
02271 add_reg(struct rsbac_list_reg_item_t* new_item_p)
02272 {
02273 if (!reg_head.head)
02274 {
02275 reg_head.head=new_item_p;
02276 reg_head.tail=new_item_p;
02277 reg_head.curr=new_item_p;
02278 reg_head.count = 1;
02279 new_item_p->prev=NULL;
02280 new_item_p->next=NULL;
02281 }
02282 else
02283 {
02284 new_item_p->prev=reg_head.tail;
02285 new_item_p->next=NULL;
02286 reg_head.tail->next=new_item_p;
02287 reg_head.tail=new_item_p;
02288 reg_head.curr=new_item_p;
02289 reg_head.count++;
02290 };
02291 return(new_item_p);
02292 }
02293
02294
02295 static inline struct rsbac_list_lol_reg_item_t*
02296 create_lol_reg(struct rsbac_list_lol_info_t * info_p,
02297 u_int flags,
02298 rsbac_list_compare_function_t * compare,
02299 rsbac_list_compare_function_t * subcompare,
02300 rsbac_list_get_conv_t * get_conv,
02301 rsbac_list_get_conv_t * get_subconv,
02302 void * def_data,
02303 void * def_subdata,
02304 char * name,
02305 kdev_t device)
02306 {
02307 struct rsbac_list_lol_reg_item_t * new_item_p = NULL;
02308
02309 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) )
02310 return(NULL);
02311 new_item_p->info = *info_p;
02312 if(info_p->data_size && !def_data)
02313 flags &= ~RSBAC_LIST_DEF_DATA;
02314 if(!def_subdata)
02315 flags &= ~RSBAC_LIST_DEF_SUBDATA;
02316 new_item_p->flags = flags;
02317 new_item_p->compare = compare;
02318 new_item_p->subcompare = subcompare;
02319 new_item_p->get_conv = get_conv;
02320 new_item_p->get_subconv = get_subconv;
02321 if( (flags & RSBAC_LIST_DEF_DATA)
02322 && (info_p->data_size)
02323 )
02324 {
02325 new_item_p->def_data = rsbac_kmalloc(info_p->data_size);
02326 if(new_item_p->def_data)
02327 memcpy(new_item_p->def_data, def_data, info_p->data_size);
02328 else
02329 {
02330 rsbac_kfree(new_item_p);
02331 return NULL;
02332 }
02333 }
02334 else
02335 new_item_p->def_data = NULL;
02336 if(flags & RSBAC_LIST_DEF_SUBDATA)
02337 {
02338 new_item_p->def_subdata = rsbac_kmalloc(info_p->subdata_size);
02339 if(new_item_p->def_subdata)
02340 memcpy(new_item_p->def_subdata, def_subdata, info_p->subdata_size);
02341 else
02342 {
02343 if(new_item_p->def_data)
02344 rsbac_kfree(new_item_p->def_data);
02345 rsbac_kfree(new_item_p);
02346 return NULL;
02347 }
02348 }
02349 else
02350 new_item_p->def_subdata = NULL;
02351 if(name)
02352 {
02353 strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME);
02354 new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
02355 }
02356 else
02357 {
02358 strcpy(new_item_p->name, RSBAC_LIST_NONAME);
02359 }
02360 new_item_p->device = device;
02361 new_item_p->head = NULL;
02362 new_item_p->tail = NULL;
02363 new_item_p->curr = NULL;
02364 new_item_p->lock = RW_LOCK_UNLOCKED;
02365 new_item_p->count = 0;
02366 new_item_p->dirty = FALSE;
02367 if(flags & RSBAC_LIST_NO_WRITE)
02368 new_item_p->no_write = TRUE;
02369 else
02370 new_item_p->no_write = FALSE;
02371 new_item_p->lastchange.sec = 0;
02372 new_item_p->lastchange.nsec = 0;
02373 #ifdef CONFIG_RSBAC_LIST_TRANS
02374 new_item_p->ta_copied = FALSE;
02375 new_item_p->ta_head = NULL;
02376 new_item_p->ta_tail = NULL;
02377 new_item_p->ta_curr = NULL;
02378 new_item_p->ta_count = 0;
02379 #endif
02380 new_item_p->self = new_item_p;
02381 return(new_item_p);
02382 }
02383
02384
02385 static struct rsbac_list_lol_reg_item_t*
02386 add_lol_reg(struct rsbac_list_lol_reg_item_t * new_item_p)
02387 {
02388 if (!lol_reg_head.head)
02389 {
02390 lol_reg_head.head=new_item_p;
02391 lol_reg_head.tail=new_item_p;
02392 lol_reg_head.curr=new_item_p;
02393 lol_reg_head.count = 1;
02394 new_item_p->prev=NULL;
02395 new_item_p->next=NULL;
02396 }
02397 else
02398 {
02399 new_item_p->prev=lol_reg_head.tail;
02400 new_item_p->next=NULL;
02401 lol_reg_head.tail->next=new_item_p;
02402 lol_reg_head.tail=new_item_p;
02403 lol_reg_head.curr=new_item_p;
02404 lol_reg_head.count++;
02405 };
02406 return(new_item_p);
02407 }
02408
02409
02410
02411 static void do_remove_item(
02412 struct rsbac_list_reg_item_t * list,
02413 struct rsbac_list_item_t * item_p)
02414 {
02415 if(!list || !item_p)
02416 return;
02417
02418 if ( (list->head == item_p) )
02419 {
02420 if ( (list->tail == item_p) )
02421 {
02422 list->head = NULL;
02423 list->tail = NULL;
02424 }
02425 else
02426 {
02427 item_p->next->prev = NULL;
02428 list->head = item_p->next;
02429 };
02430 }
02431 else
02432 {
02433 if ( (list->tail == item_p) )
02434 {
02435 item_p->prev->next = NULL;
02436 list->tail = item_p->prev;
02437 }
02438 else
02439 {
02440 item_p->prev->next = item_p->next;
02441 item_p->next->prev = item_p->prev;
02442 }
02443 }
02444
02445 list->curr=NULL;
02446
02447 list->count--;
02448
02449 rsbac_kfree(item_p);
02450 }
02451
02452 static void remove_item(
02453 struct rsbac_list_reg_item_t * list,
02454 void * desc)
02455 {
02456 struct rsbac_list_item_t * item_p;
02457
02458 if(!list || !desc)
02459 return;
02460
02461 if ( (item_p = lookup_item(list, desc)) )
02462 {
02463 do_remove_item(list, item_p);
02464 }
02465 }
02466
02467 static void remove_all_items(struct rsbac_list_reg_item_t * list)
02468 {
02469 struct rsbac_list_item_t * item_p;
02470 struct rsbac_list_item_t * next_item_p;
02471
02472
02473 item_p = list->head;
02474 while(item_p)
02475 {
02476 next_item_p = item_p->next;
02477 rsbac_kfree(item_p);
02478 item_p = next_item_p;
02479 }
02480 list->head = NULL;
02481 list->tail = NULL;
02482 list->curr = NULL;
02483 list->count = 0;
02484 }
02485
02486 #ifdef CONFIG_RSBAC_LIST_TRANS
02487 static void ta_do_remove_item(
02488 struct rsbac_list_reg_item_t * list,
02489 struct rsbac_list_item_t * item_p)
02490 {
02491 if(!list || !item_p)
02492 return;
02493
02494 if ( (list->ta_head == item_p) )
02495 {
02496 if ( (list->ta_tail == item_p) )
02497 {
02498 list->ta_head = NULL;
02499 list->ta_tail = NULL;
02500 }
02501 else
02502 {
02503 item_p->next->prev = NULL;
02504 list->ta_head = item_p->next;
02505 }
02506 }
02507 else
02508 {
02509 if ( (list->ta_tail == item_p) )
02510 {
02511 item_p->prev->next = NULL;
02512 list->ta_tail = item_p->prev;
02513 }
02514 else
02515 {
02516 item_p->prev->next = item_p->next;
02517 item_p->next->prev = item_p->prev;
02518 }
02519 }
02520
02521 list->ta_curr=NULL;
02522
02523 list->ta_count--;
02524
02525 rsbac_kfree(item_p);
02526 }
02527
02528 static void ta_remove_item(
02529 rsbac_list_ta_number_t ta_number,
02530 struct rsbac_list_reg_item_t * list,
02531 void * desc)
02532 {
02533 struct rsbac_list_item_t * item_p;
02534
02535 if(!list || !desc)
02536 return;
02537 if(!ta_number)
02538 return remove_item(list, desc);
02539
02540 if ( (item_p = ta_lookup_item(ta_number, list, desc)) )
02541 {
02542 ta_do_remove_item(list, item_p);
02543 }
02544 }
02545
02546 static void ta_remove_all_items(struct rsbac_list_reg_item_t * list)
02547 {
02548 struct rsbac_list_item_t * item_p;
02549 struct rsbac_list_item_t * next_item_p;
02550
02551
02552 item_p = list->ta_head;
02553 while(item_p)
02554 {
02555 next_item_p = item_p->next;
02556 rsbac_kfree(item_p);
02557 item_p = next_item_p;
02558 }
02559 list->ta_head = NULL;
02560 list->ta_tail = NULL;
02561 list->ta_curr = NULL;
02562 list->ta_count = 0;
02563 }
02564 #endif
02565
02566 static void do_remove_lol_subitem(
02567 struct rsbac_list_lol_item_t * sublist,
02568 struct rsbac_list_item_t * item_p)
02569 {
02570 if(!sublist || !item_p)
02571 return;
02572
02573 if ( (sublist->head == item_p) )
02574 {
02575 if ( (sublist->tail == item_p) )
02576 {
02577 sublist->head = NULL;
02578 sublist->tail = NULL;
02579 }
02580 else
02581 {
02582 item_p->next->prev = NULL;
02583 sublist->head = item_p->next;
02584 }
02585 }
02586 else
02587 {
02588 if ( (sublist->tail == item_p) )
02589 {
02590 item_p->prev->next = NULL;
02591 sublist->tail = item_p->prev;
02592 }
02593 else
02594 {
02595 item_p->prev->next = item_p->next;
02596 item_p->next->prev = item_p->prev;
02597 }
02598 }
02599
02600 sublist->curr=NULL;
02601
02602 sublist->count--;
02603
02604 rsbac_kfree(item_p);
02605 }
02606
02607 static void remove_lol_subitem(
02608 struct rsbac_list_lol_reg_item_t * list,
02609 struct rsbac_list_lol_item_t * sublist,
02610 void * subdesc)
02611 {
02612 struct rsbac_list_item_t * item_p;
02613
02614 if(!list || !sublist || !subdesc)
02615 return;
02616
02617
02618 if ( (item_p = lookup_lol_subitem(list, sublist, subdesc)) )
02619 {
02620 do_remove_lol_subitem(sublist, item_p);
02621 }
02622 }
02623
02624
02625 static void do_remove_lol_item(
02626 struct rsbac_list_lol_reg_item_t * list,
02627 struct rsbac_list_lol_item_t * item_p)
02628 {
02629 struct rsbac_list_item_t * subitem_p;
02630 struct rsbac_list_item_t * next_subitem_p;
02631
02632 if(!list || !item_p)
02633 return;
02634
02635 if ( (list->head == item_p) )
02636 {
02637 if ( (list->tail == item_p) )
02638 {
02639 list->head = NULL;
02640 list->tail = NULL;
02641 }
02642 else
02643 {
02644 #ifdef CONFIG_RSBAC_DEBUG
02645 if(!item_p->next)
02646 {
02647 rsbac_printk(KERN_WARNING
02648 "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02649 list->name);
02650 }
02651 else
02652 #endif
02653 {
02654 item_p->next->prev = NULL;
02655 list->head = item_p->next;
02656 }
02657 }
02658 }
02659 else
02660 {
02661 if ( (list->tail == item_p) )
02662 {
02663 #ifdef CONFIG_RSBAC_DEBUG
02664 if(!item_p->prev)
02665 {
02666 rsbac_printk(KERN_WARNING
02667 "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02668 list->name);
02669 }
02670 else
02671 #endif
02672 {
02673 item_p->prev->next = NULL;
02674 list->tail = item_p->prev;
02675 }
02676 }
02677 else
02678 {
02679 #ifdef CONFIG_RSBAC_DEBUG
02680 if(!item_p->prev)
02681 {
02682 rsbac_printk(KERN_WARNING
02683 "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02684 list->name);
02685 }
02686 else
02687 if(!item_p->next)
02688 {
02689 rsbac_printk(KERN_WARNING
02690 "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02691 list->name);
02692 }
02693 else
02694 #endif
02695 {
02696 item_p->prev->next = item_p->next;
02697 item_p->next->prev = item_p->prev;
02698 }
02699 }
02700 }
02701
02702 list->curr=NULL;
02703
02704 list->count--;
02705
02706 subitem_p = item_p->head;
02707 while(subitem_p)
02708 {
02709 next_subitem_p = subitem_p->next;
02710 rsbac_kfree(subitem_p);
02711 subitem_p = next_subitem_p;
02712 }
02713
02714 rsbac_kfree(item_p);
02715 }
02716
02717 static void remove_lol_item(
02718 struct rsbac_list_lol_reg_item_t * list,
02719 void * desc)
02720 {
02721 struct rsbac_list_lol_item_t * item_p;
02722
02723 if(!list || !desc)
02724 return;
02725
02726
02727 if ( (item_p = lookup_lol_item(list, desc)) )
02728 {
02729 do_remove_lol_item(list, item_p);
02730 }
02731 }
02732
02733 #ifdef CONFIG_RSBAC_LIST_TRANS
02734 static void ta_do_remove_lol_item(
02735 struct rsbac_list_lol_reg_item_t * list,
02736 struct rsbac_list_lol_item_t * item_p)
02737 {
02738 struct rsbac_list_item_t * subitem_p;
02739 struct rsbac_list_item_t * next_subitem_p;
02740
02741 if(!list || !item_p)
02742 return;
02743
02744 if ( (list->ta_head == item_p) )
02745 {
02746 if ( (list->ta_tail == item_p) )
02747 {
02748 list->ta_head = NULL;
02749 list->ta_tail = NULL;
02750 }
02751 else
02752 {
02753 #ifdef CONFIG_RSBAC_DEBUG
02754 if(!item_p->next)
02755 {
02756 rsbac_printk(KERN_WARNING
02757 "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02758 list->name);
02759 }
02760 else
02761 #endif
02762 {
02763 item_p->next->prev = NULL;
02764 list->ta_head = item_p->next;
02765 }
02766 }
02767 }
02768 else
02769 {
02770 if ( (list->ta_tail == item_p) )
02771 {
02772 #ifdef CONFIG_RSBAC_DEBUG
02773 if(!item_p->prev)
02774 {
02775 rsbac_printk(KERN_WARNING
02776 "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02777 list->name);
02778 }
02779 else
02780 #endif
02781 {
02782 item_p->prev->next = NULL;
02783 list->ta_tail = item_p->prev;
02784 }
02785 }
02786 else
02787 {
02788 #ifdef CONFIG_RSBAC_DEBUG
02789 if(!item_p->prev)
02790 {
02791 rsbac_printk(KERN_WARNING
02792 "do_remove_lol_item(): list %s corrupted: invalid prev!\n",
02793 list->name);
02794 }
02795 else
02796 if(!item_p->next)
02797 {
02798 rsbac_printk(KERN_WARNING
02799 "do_remove_lol_item(): list %s corrupted: invalid next!\n",
02800 list->name);
02801 }
02802 else
02803 #endif
02804 {
02805 item_p->prev->next = item_p->next;
02806 item_p->next->prev = item_p->prev;
02807 }
02808 }
02809 }
02810
02811 list->ta_curr=NULL;
02812
02813 list->ta_count--;
02814
02815
02816 subitem_p = item_p->head;
02817 while(subitem_p)
02818 {
02819 next_subitem_p = subitem_p->next;
02820 rsbac_kfree(subitem_p);
02821 subitem_p = next_subitem_p;
02822 }
02823
02824 rsbac_kfree(item_p);
02825 }
02826
02827 static void ta_remove_lol_item(
02828 rsbac_list_ta_number_t ta_number,
02829 struct rsbac_list_lol_reg_item_t * list,
02830 void * desc)
02831 {
02832 struct rsbac_list_lol_item_t * item_p;
02833
02834 if(!list || !desc)
02835 return;
02836
02837
02838 if ( (item_p = ta_lookup_lol_item(ta_number, list, desc)) )
02839 {
02840 ta_do_remove_lol_item(list, item_p);
02841 }
02842 }
02843 #endif
02844
02845 static void remove_all_lol_subitems(
02846 struct rsbac_list_lol_item_t * sublist)
02847 {
02848 struct rsbac_list_item_t * subitem_p;
02849 struct rsbac_list_item_t * next_subitem_p;
02850
02851
02852 subitem_p = sublist->head;
02853 while(subitem_p)
02854 {
02855 next_subitem_p = subitem_p->next;
02856 rsbac_kfree(subitem_p);
02857 subitem_p = next_subitem_p;
02858 }
02859 sublist->head = NULL;
02860 sublist->tail = NULL;
02861 sublist->curr = NULL;
02862 sublist->count = 0;
02863 }
02864
02865 static void remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list)
02866 {
02867 struct rsbac_list_lol_item_t * item_p;
02868 struct rsbac_list_lol_item_t * next_item_p;
02869 struct rsbac_list_item_t * subitem_p;
02870 struct rsbac_list_item_t * next_subitem_p;
02871
02872
02873 item_p = list->head;
02874 while(item_p)
02875 {
02876
02877 subitem_p = item_p->head;
02878 while(subitem_p)
02879 {
02880 next_subitem_p = subitem_p->next;
02881 rsbac_kfree(subitem_p);
02882 subitem_p = next_subitem_p;
02883 }
02884 next_item_p = item_p->next;
02885 rsbac_kfree(item_p);
02886 item_p = next_item_p;
02887 }
02888 list->head = NULL;
02889 list->tail = NULL;
02890 list->curr = NULL;
02891 list->count = 0;
02892 }
02893
02894 #ifdef CONFIG_RSBAC_LIST_TRANS
02895 static void ta_remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list)
02896 {
02897 struct rsbac_list_lol_item_t * item_p;
02898 struct rsbac_list_lol_item_t * next_item_p;
02899 struct rsbac_list_item_t * subitem_p;
02900 struct rsbac_list_item_t * next_subitem_p;
02901
02902
02903 item_p = list->ta_head;
02904 while(item_p)
02905 {
02906
02907 subitem_p = item_p->head;
02908 while(subitem_p)
02909 {
02910 next_subitem_p = subitem_p->next;
02911 rsbac_kfree(subitem_p);
02912 subitem_p = next_subitem_p;
02913 }
02914 next_item_p = item_p->next;
02915 rsbac_kfree(item_p);
02916 item_p = next_item_p;
02917 }
02918 list->ta_head = NULL;
02919 list->ta_tail = NULL;
02920 list->ta_curr = NULL;
02921 list->ta_count = 0;
02922 }
02923 #endif
02924
02925
02926
02927
02928 static void clear_reg(struct rsbac_list_reg_item_t * item_p)
02929 {
02930 if(item_p)
02931 {
02932
02933 remove_all_items(item_p);
02934 if(item_p->def_data)
02935 rsbac_kfree(item_p->def_data);
02936 rsbac_kfree(item_p);
02937 }
02938 }
02939
02940
02941 static void remove_reg(struct rsbac_list_reg_item_t * handle)
02942 {
02943 struct rsbac_list_reg_item_t * item_p;
02944
02945
02946 if ( (item_p = lookup_reg(handle)) )
02947 {
02948
02949 item_p->self = NULL;
02950 if ( (reg_head.head == item_p) )
02951 {
02952 if ( (reg_head.tail == item_p) )
02953 {
02954 reg_head.head = NULL;
02955 reg_head.tail = NULL;
02956 }
02957 else
02958 {
02959 item_p->next->prev = NULL;
02960 reg_head.head = item_p->next;
02961 }
02962 }
02963 else
02964 {
02965 if ( (reg_head.tail == item_p) )
02966 {
02967 item_p->prev->next = NULL;
02968 reg_head.tail = item_p->prev;
02969 }
02970 else
02971 {
02972 item_p->prev->next = item_p->next;
02973 item_p->next->prev = item_p->prev;
02974 }
02975 }
02976
02977
02978 reg_head.curr=NULL;
02979
02980 reg_head.count--;
02981
02982 clear_reg(item_p);
02983 }
02984 }
02985
02986
02987 static void clear_lol_reg(struct rsbac_list_lol_reg_item_t * item_p)
02988 {
02989 if(item_p)
02990 {
02991
02992 remove_all_lol_items(item_p);
02993 if(item_p->def_data)
02994 rsbac_kfree(item_p->def_data);
02995 if(item_p->def_subdata)
02996 rsbac_kfree(item_p->def_subdata);
02997 rsbac_kfree(item_p);
02998 }
02999 }
03000
03001
03002 static void remove_lol_reg(struct rsbac_list_lol_reg_item_t * handle)
03003 {
03004 struct rsbac_list_lol_reg_item_t * item_p;
03005
03006
03007 if ( (item_p = lookup_lol_reg(handle)) )
03008 {
03009
03010 item_p->self = NULL;
03011 if ( (lol_reg_head.head == item_p) )
03012 {
03013 if ( (lol_reg_head.tail == item_p) )
03014 {
03015 lol_reg_head.head = NULL;
03016 lol_reg_head.tail = NULL;
03017 }
03018 else
03019 {
03020 item_p->next->prev = NULL;
03021 lol_reg_head.head = item_p->next;
03022 };
03023 }
03024 else
03025 {
03026 if ( (lol_reg_head.tail == item_p) )
03027 {
03028 item_p->prev->next = NULL;
03029 lol_reg_head.tail = item_p->prev;
03030 }
03031 else
03032 {
03033 item_p->prev->next = item_p->next;
03034 item_p->next->prev = item_p->prev;
03035 }
03036 }
03037
03038
03039 lol_reg_head.curr=NULL;
03040
03041 lol_reg_head.count--;
03042
03043 clear_lol_reg(item_p);
03044 }
03045 }
03046
03047 #if defined(CONFIG_RSBAC_LIST_REPL)
03048 inline void touch(struct rsbac_list_reg_item_t * list)
03049 {
03050 rsbac_get_current_nanotime(&list->lastchange);
03051 }
03052 #else
03053 #define touch(x)
03054 #endif
03055
03056 #if defined(CONFIG_RSBAC_LIST_REPL)
03057 inline void lol_touch(struct rsbac_list_lol_reg_item_t * list)
03058 {
03059 rsbac_get_current_nanotime(&list->lastchange);
03060 }
03061 #else
03062 #define lol_touch(x)
03063 #endif
03064
03065
03066
03067
03068
03069 static int read_list(struct rsbac_list_reg_item_t * list)
03070 {
03071 struct file * file_p;
03072 int err = 0;
03073 int tmperr;
03074 int converr;
03075 rsbac_version_t list_version;
03076 u_long read_count = 0;
03077 u_long flags;
03078 char * old_buf;
03079 char * new_buf;
03080 char * old_data;
03081 char * new_data;
03082 struct rsbac_list_info_t * list_info_p;
03083 rsbac_list_count_t list_count;
03084 rsbac_time_t timestamp;
03085 struct rsbac_nanotime_t lastchange;
03086 rsbac_time_t max_age = 0;
03087 rsbac_list_conv_function_t * conv = NULL;
03088 rsbac_boolean_t timeout = FALSE;
03089 mm_segment_t oldfs;
03090
03091 list_info_p = rsbac_kmalloc(sizeof(*list_info_p));
03092 if(!list_info_p)
03093 return -RSBAC_ENOMEM;
03094 file_p = rsbac_kmalloc(sizeof(*file_p));
03095 if(!file_p)
03096 {
03097 rsbac_kfree(list_info_p);
03098 return -RSBAC_ENOMEM;
03099 }
03100
03101 if ((err = rsbac_read_open(list->name,
03102 file_p,
03103 list->device) ))
03104 {
03105 rsbac_kfree(list_info_p);
03106 rsbac_kfree(file_p);
03107 return(err);
03108 }
03109
03110
03111
03112
03113
03114
03115
03116
03117 oldfs = get_fs();
03118 set_fs(KERNEL_DS);
03119
03120
03121 tmperr = file_p->f_op->read(file_p,
03122 (__u8 *) &list_version,
03123 sizeof(list_version),
03124 &file_p->f_pos);
03125 set_fs(oldfs);
03126
03127 if (tmperr < sizeof(list_version))
03128 {
03129 rsbac_printk(KERN_WARNING
03130 "read_list(): read error from file!\n");
03131 err = -RSBAC_EREADFAILED;
03132 goto end_read;
03133 }
03134
03135 switch(list_version)
03136 {
03137 case RSBAC_LIST_DISK_VERSION:
03138 case RSBAC_LIST_DISK_OLD_VERSION:
03139 break;
03140 default:
03141 rsbac_printk(KERN_WARNING
03142 "read_list(): wrong on-disk list version %u in file %s, expected %u - error!\n",
03143 list_version,
03144 list->name,
03145 RSBAC_LIST_DISK_VERSION);
03146 err = -RSBAC_EREADFAILED;
03147 goto end_read;
03148 }
03149
03150
03151 set_fs(KERNEL_DS);
03152 tmperr = file_p->f_op->read(file_p,
03153 (__u8 *) ×tamp,
03154 sizeof(timestamp),
03155 &file_p->f_pos);
03156 set_fs(oldfs);
03157
03158 if (tmperr < sizeof(timestamp))
03159 {
03160 rsbac_printk(KERN_WARNING
03161 "read_list(): timestamp read error from file %s!\n",
03162 list->name);
03163 err = -RSBAC_EREADFAILED;
03164 goto end_read;
03165 }
03166
03167
03168 set_fs(KERNEL_DS);
03169 tmperr = file_p->f_op->read(file_p,
03170 (__u8 *) list_info_p,
03171 sizeof(*list_info_p),
03172 &file_p->f_pos);
03173 set_fs(oldfs);
03174
03175 if (tmperr < sizeof(*list_info_p))
03176 {
03177 rsbac_printk(KERN_WARNING
03178 "read_list(): list info read error from file %s!\n",
03179 list->name);
03180 err = -RSBAC_EREADFAILED;
03181 goto end_read;
03182 }
03183
03184
03185 if( list_info_p->max_age
03186 && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME)
03187 timeout = TRUE;
03188
03189
03190 if (list_info_p->key != list->info.key)
03191 {
03192 if(timeout)
03193 {
03194 rsbac_printk(KERN_WARNING
03195 "read_list(): accessing timed out list %s with wrong key, ignoring old contents!\n",
03196 list->name);
03197 goto end_read;
03198 }
03199 else
03200 {
03201 rsbac_printk(KERN_WARNING
03202 "read_list(): try to access list %s with wrong key!\n",
03203 list->name);
03204 err = -EPERM;
03205 goto end_read;
03206 }
03207 }
03208
03209
03210 if(list->flags & RSBAC_LIST_IGNORE_OLD)
03211 goto end_read;
03212
03213 switch(list_version)
03214 {
03215 case RSBAC_LIST_DISK_VERSION:
03216 set_fs(KERNEL_DS);
03217 tmperr = file_p->f_op->read(file_p,
03218 (char *) &lastchange,
03219 sizeof(lastchange),
03220 &file_p->f_pos);
03221 set_fs(oldfs);
03222
03223 if (tmperr < sizeof(lastchange))
03224 {
03225 rsbac_printk(KERN_WARNING
03226 "read_list(): lastchange read error from file %s!\n",
03227 list->name);
03228 err = -RSBAC_EREADFAILED;
03229 goto end_read;
03230 }
03231 #if defined(CONFIG_RSBAC_LIST_REPL)
03232 else
03233 list->lastchange = lastchange;
03234 #endif
03235 break;
03236 case RSBAC_LIST_DISK_OLD_VERSION:
03237 break;
03238 default:
03239 break;
03240 }
03241
03242 if(list_info_p->version != list->info.version)
03243 {
03244 if(list->get_conv)
03245 conv = list->get_conv(list_info_p->version);
03246 if(!conv)
03247 {
03248 if(timeout)
03249 {
03250 rsbac_printk(KERN_WARNING
03251 "read_list(): accessing timed out list %s without conversion function, ignoring old contents!\n",
03252 list->name);
03253 goto end_read;
03254 }
03255 else
03256 {
03257
03258 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION))
03259 {
03260 rsbac_printk(KERN_WARNING
03261 "read_list(): cannot convert list version %u of file %s to version %u!\n",
03262 list_info_p->version,
03263 list->name,
03264 list->info.version);
03265 err = -RSBAC_EINVALIDVERSION;
03266 }
03267 goto end_read;
03268 }
03269 }
03270 else
03271 {
03272 rsbac_printk(KERN_WARNING
03273 "read_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n",
03274 list_info_p->version,
03275 list->name,
03276 RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device),
03277 list->info.version);
03278 }
03279 }
03280 else
03281 {
03282 if( (list_info_p->desc_size != list->info.desc_size)
03283 || (list_info_p->data_size != list->info.data_size)
03284 )
03285 {
03286 if(timeout)
03287 {
03288 rsbac_printk(KERN_WARNING
03289 "read_list(): accessing timed out list %s with wrong desc or data size, ignoring old contents!\n",
03290 list->name);
03291 goto end_read;
03292 }
03293 else
03294 {
03295 rsbac_printk(KERN_WARNING
03296 "read_list(): desc or data size mismatch on list %s!\n",
03297 list->name);
03298 err = -RSBAC_EINVALIDVALUE;
03299 goto end_read;
03300 }
03301 }
03302 }
03303
03304
03305 set_fs(KERNEL_DS);
03306 tmperr = file_p->f_op->read(file_p,
03307 (__u8 *) &list_count,
03308 sizeof(list_count),
03309 &file_p->f_pos);
03310 set_fs(oldfs);
03311
03312 if (tmperr < sizeof(list_count))
03313 {
03314 rsbac_printk(KERN_WARNING
03315 "read_list(): list count read error from file %s!\n",
03316 list->name);
03317 err = -RSBAC_EREADFAILED;
03318 goto end_read;
03319 }
03320
03321
03322 old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size);
03323 if(!old_buf)
03324 {
03325 rsbac_printk(KERN_WARNING
03326 "read_list(): cannot allocate memory!\n");
03327 err = -RSBAC_ENOMEM;
03328 goto end_read;
03329 }
03330 new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size);
03331 if(!new_buf)
03332 {
03333 rsbac_printk(KERN_WARNING
03334 "read_list(): cannot allocate memory!\n");
03335 rsbac_kfree(old_buf);
03336 err = -RSBAC_ENOMEM;
03337 goto end_read;
03338 }
03339
03340 if(list_info_p->data_size)
03341 old_data = old_buf + list_info_p->desc_size;
03342 else
03343 old_data = NULL;
03344 if(list->info.data_size)
03345 new_data = new_buf + list->info.desc_size;
03346 else
03347 new_data = NULL;
03348
03349
03350 do
03351 {
03352 set_fs(KERNEL_DS);
03353 tmperr = file_p->f_op->read(file_p,
03354 (char *) &max_age,
03355 sizeof(max_age),
03356 &file_p->f_pos);
03357 set_fs(oldfs);
03358 if(conv)
03359 {
03360 set_fs(KERNEL_DS);
03361 tmperr = file_p->f_op->read(file_p,
03362 old_buf,
03363 list_info_p->desc_size + list_info_p->data_size,
03364 &file_p->f_pos);
03365 set_fs(oldfs);
03366 if(tmperr > 0)
03367 {
03368 converr = conv(old_buf, old_data,
03369 new_buf, new_data);
03370 if(converr)
03371 tmperr = converr;
03372 }
03373 }
03374 else
03375 {
03376 set_fs(KERNEL_DS);
03377 tmperr = file_p->f_op->read(file_p,
03378 new_buf,
03379 list->info.desc_size + list->info.data_size,
03380 &file_p->f_pos);
03381 set_fs(oldfs);
03382 }
03383
03384 if (tmperr > 0)
03385 {
03386
03387 rsbac_write_lock(&list->lock, &flags);
03388 add_item(list, max_age, new_buf, new_data);
03389
03390 rsbac_write_unlock(&list->lock, &flags);
03391 read_count++;
03392
03393
03394
03395
03396
03397
03398 }
03399 }
03400 while (tmperr > 0);
03401
03402 if (tmperr < 0)
03403 {
03404 rsbac_printk(KERN_WARNING "read_list(): read error from file %s!\n",
03405 list->name);
03406 err = -RSBAC_EREADFAILED;
03407 }
03408 rsbac_kfree(old_buf);
03409 rsbac_kfree(new_buf);
03410
03411 if (read_count != list_count)
03412 {
03413 rsbac_printk(KERN_WARNING "read_list(): read %lu, expected %u items from file %s!\n",
03414 read_count,
03415 list_count,
03416 list->name);
03417 err = -RSBAC_EREADFAILED;
03418 }
03419
03420 end_read:
03421
03422 #ifdef CONFIG_RSBAC_DEBUG
03423 if (rsbac_debug_lists)
03424 {
03425 rsbac_printk(KERN_DEBUG "read_list(): %lu entries read.\n",
03426 read_count);
03427 }
03428 #endif
03429
03430 rsbac_read_close(file_p);
03431 rsbac_kfree(list_info_p);
03432 rsbac_kfree(file_p);
03433 return(err);
03434 }
03435
03436
03437 static int read_lol_list(struct rsbac_list_lol_reg_item_t * list)
03438 {
03439 struct file * file_p;
03440 int err = 0;
03441 int tmperr;
03442 int converr;
03443 rsbac_version_t list_version;
03444 u_long read_count = 0;
03445 u_long flags;
03446 u_long sublen;
03447 u_long i;
03448 char * old_buf;
03449 char * new_buf;
03450 char * old_data;
03451 char * new_data;
03452 char * old_subbuf;
03453 char * new_subbuf;
03454 char * old_subdata;
03455 char * new_subdata;
03456 struct rsbac_list_lol_info_t * list_info_p;
03457 rsbac_list_count_t list_count;
03458 rsbac_time_t timestamp;
03459 struct rsbac_nanotime_t lastchange;
03460 rsbac_time_t max_age = 0;
03461 rsbac_list_conv_function_t * conv = NULL;
03462 rsbac_list_conv_function_t * subconv = NULL;
03463 rsbac_boolean_t timeout = FALSE;
03464 struct rsbac_list_lol_item_t * item_p;
03465 mm_segment_t oldfs;
03466
03467 list_info_p = rsbac_kmalloc(sizeof(*list_info_p));
03468 if(!list_info_p)
03469 return -RSBAC_ENOMEM;
03470 file_p = rsbac_kmalloc(sizeof(*file_p));
03471 if(!file_p)
03472 {
03473 rsbac_kfree(list_info_p);
03474 return -RSBAC_ENOMEM;
03475 }
03476
03477 if ((err = rsbac_read_open(list->name,
03478 file_p,
03479 list->device) ))
03480 {
03481 rsbac_kfree(list_info_p);
03482 rsbac_kfree(file_p);
03483 return(err);
03484 }
03485
03486
03487
03488
03489
03490
03491
03492
03493 oldfs = get_fs();
03494 set_fs(KERNEL_DS);
03495
03496
03497 tmperr = file_p->f_op->read(file_p,
03498 (__u8 *) &list_version,
03499 sizeof(list_version),
03500 &file_p->f_pos);
03501 set_fs(oldfs);
03502
03503 if (tmperr < sizeof(list_version))
03504 {
03505 printk(KERN_WARNING
03506 "read_lol_list(): read error from file!\n");
03507 err = -RSBAC_EREADFAILED;
03508 goto end_read;
03509 }
03510
03511 switch(list_version)
03512 {
03513 case RSBAC_LIST_DISK_VERSION:
03514 case RSBAC_LIST_DISK_OLD_VERSION:
03515 break;
03516 default:
03517 rsbac_printk(KERN_WARNING
03518 "read_lol_list(): wrong on-disk list version %u in file %s, expected %u - error!\n",
03519 list_version,
03520 list->name,
03521 RSBAC_LIST_DISK_VERSION);
03522 err = -RSBAC_EREADFAILED;
03523 goto end_read;
03524 }
03525
03526
03527 set_fs(KERNEL_DS);
03528 tmperr = file_p->f_op->read(file_p,
03529 (__u8 *) ×tamp,
03530 sizeof(timestamp),
03531 &file_p->f_pos);
03532 set_fs(oldfs);
03533
03534 if (tmperr < sizeof(timestamp))
03535 {
03536 rsbac_printk(KERN_WARNING
03537 "read_lol_list(): timestamp read error from file %s!\n",
03538 list->name);
03539 err = -RSBAC_EREADFAILED;
03540 goto end_read;
03541 }
03542
03543
03544 set_fs(KERNEL_DS);
03545 tmperr = file_p->f_op->read(file_p,
03546 (__u8 *) list_info_p,
03547 sizeof(*list_info_p),
03548 &file_p->f_pos);
03549 set_fs(oldfs);
03550
03551 if (tmperr < sizeof(*list_info_p))
03552 {
03553 rsbac_printk(KERN_WARNING
03554 "read_lol_list(): list info read error from file %s!\n",
03555 list->name);
03556 err = -RSBAC_EREADFAILED;
03557 goto end_read;
03558 }
03559
03560
03561 if( list_info_p->max_age
03562 && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME)
03563 timeout = TRUE;
03564
03565
03566 if (list_info_p->key != list->info.key)
03567 {
03568 if(timeout)
03569 {
03570 rsbac_printk(KERN_WARNING
03571 "read_lol_list(): accessing timed out list %s with wrong key, ignoring old contents!\n",
03572 list->name);
03573 goto end_read;
03574 }
03575 else
03576 {
03577 rsbac_printk(KERN_WARNING
03578 "read_lol_list(): try to access list %s with wrong key!\n",
03579 list->name);
03580 err = -EPERM;
03581 goto end_read;
03582 }
03583 }
03584
03585
03586 if(list->flags & RSBAC_LIST_IGNORE_OLD)
03587 goto end_read;
03588
03589 switch(list_version)
03590 {
03591 case RSBAC_LIST_DISK_VERSION:
03592 set_fs(KERNEL_DS);
03593 tmperr = file_p->f_op->read(file_p,
03594 (char *) &lastchange,
03595 sizeof(lastchange),
03596 &file_p->f_pos);
03597 set_fs(oldfs);
03598
03599 if (tmperr < sizeof(lastchange))
03600 {
03601 rsbac_printk(KERN_WARNING
03602 "read_list(): lastchange read error from file %s!\n",
03603 list->name);
03604 err = -RSBAC_EREADFAILED;
03605 goto end_read;
03606 }
03607 #if defined(CONFIG_RSBAC_LIST_REPL)
03608 else
03609 list->lastchange = lastchange;
03610 #endif
03611 break;
03612 case RSBAC_LIST_DISK_OLD_VERSION:
03613 break;
03614 default:
03615 break;
03616 }
03617
03618 if(list_info_p->version != list->info.version)
03619 {
03620 if(list->get_conv)
03621 conv = list->get_conv(list_info_p->version);
03622 if(list->get_subconv)
03623 subconv = list->get_subconv(list_info_p->version);
03624 if(!conv || !subconv)
03625 {
03626 if(timeout)
03627 {
03628 rsbac_printk(KERN_WARNING
03629 "read_lol_list(): accessing timed out list %s without both conversion functions, ignoring old contents!\n",
03630 list->name);
03631 goto end_read;
03632 }
03633 else
03634 {
03635
03636 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION))
03637 {
03638 rsbac_printk(KERN_WARNING
03639 "read_lol_list(): cannot convert list version %u of file %s to version %u!\n",
03640 list_info_p->version,
03641 list->name,
03642 list->info.version);
03643 err = -RSBAC_EINVALIDVERSION;
03644 }
03645 goto end_read;
03646 }
03647 }
03648 else
03649 {
03650 rsbac_printk(KERN_WARNING
03651 "read_lol_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n",
03652 list_info_p->version,
03653 list->name,
03654 RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device),
03655 list->info.version);
03656 }
03657 }
03658 else
03659 {
03660 if( (list_info_p->desc_size != list->info.desc_size)
03661 || (list_info_p->data_size != list->info.data_size)
03662 || (list_info_p->subdesc_size != list->info.subdesc_size)
03663 || (list_info_p->subdata_size != list->info.subdata_size)
03664 )
03665 {
03666 if(timeout)
03667 {
03668 rsbac_printk(KERN_WARNING
03669 "read_lol_list(): accessing timed out list %s with wrong desc or data size(s), ignoring old contents!\n",
03670 list->name);
03671 goto end_read;
03672 }
03673 else
03674 {
03675 rsbac_printk(KERN_WARNING
03676 "read_lol_list(): desc or data size mismatch on list %s!\n",
03677 list->name);
03678 err = -RSBAC_EINVALIDVALUE;
03679 goto end_read;
03680 }
03681 }
03682 }
03683
03684
03685 set_fs(KERNEL_DS);
03686 tmperr = file_p->f_op->read(file_p,
03687 (__u8 *) &list_count,
03688 sizeof(list_count),
03689 &file_p->f_pos);
03690 set_fs(oldfs);
03691
03692 if (tmperr < sizeof(list_count))
03693 {
03694 rsbac_printk(KERN_WARNING
03695 "read_lol_list(): list count read error from file %s!\n",
03696 list->name);
03697 err = -RSBAC_EREADFAILED;
03698 goto end_read;
03699 }
03700
03701
03702 old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size);
03703 if(!old_buf)
03704 {
03705 rsbac_printk(KERN_WARNING
03706 "read_lol_list(): cannot allocate memory!\n");
03707 err = -RSBAC_ENOMEM;
03708 goto end_read;
03709 }
03710 new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size);
03711 if(!new_buf)
03712 {
03713 rsbac_printk(KERN_WARNING
03714 "read_lol_list(): cannot allocate memory!\n");
03715 rsbac_kfree(old_buf);
03716 err = -RSBAC_ENOMEM;
03717 goto end_read;
03718 }
03719 old_subbuf = rsbac_kmalloc(list_info_p->subdesc_size + list_info_p->subdata_size);
03720 if(!old_subbuf)
03721 {
03722 rsbac_printk(KERN_WARNING
03723 "read_lol_list(): cannot allocate memory!\n");
03724 rsbac_kfree(old_buf);
03725 rsbac_kfree(new_buf);
03726 err = -RSBAC_ENOMEM;
03727 goto end_read;
03728 }
03729 new_subbuf = rsbac_kmalloc(list->info.subdesc_size + list->info.subdata_size);
03730 if(!new_subbuf)
03731 {
03732 rsbac_printk(KERN_WARNING
03733 "read_lol_list(): cannot allocate memory!\n");
03734 rsbac_kfree(old_buf);
03735 rsbac_kfree(new_buf);
03736 rsbac_kfree(old_subbuf);
03737 err = -RSBAC_ENOMEM;
03738 goto end_read;
03739 }
03740
03741 if(list_info_p->data_size)
03742 old_data = old_buf + list_info_p->desc_size;
03743 else
03744 old_data = NULL;
03745 if(list->info.data_size)
03746 new_data = new_buf + list->info.desc_size;
03747 else
03748 new_data = NULL;
03749 if(list_info_p->subdata_size)
03750 old_subdata = old_subbuf + list_info_p->subdesc_size;
03751 else
03752 old_subdata = NULL;
03753 if(list->info.subdata_size)
03754 new_subdata = new_subbuf + list->info.subdesc_size;
03755 else
03756 new_subdata = NULL;
03757
03758
03759 do
03760 {
03761 set_fs(KERNEL_DS);
03762 tmperr = file_p->f_op->read(file_p,
03763 (char *) &max_age,
03764 sizeof(max_age),
03765 &file_p->f_pos);
03766 set_fs(oldfs);
03767 if(conv)
03768 {
03769 set_fs(KERNEL_DS);
03770 tmperr = file_p->f_op->read(file_p,
03771 old_buf,
03772 list_info_p->desc_size + list_info_p->data_size,
03773 &file_p->f_pos);
03774 set_fs(oldfs);
03775 if(tmperr > 0)
03776 {
03777 converr = conv(old_buf, old_data,
03778 new_buf, new_data);
03779 if(converr)
03780 tmperr = converr;
03781 }
03782 }
03783 else
03784 {
03785 set_fs(KERNEL_DS);
03786 tmperr = file_p->f_op->read(file_p,
03787 new_buf,
03788 list->info.desc_size + list->info.data_size,
03789 &file_p->f_pos);
03790 set_fs(oldfs);
03791 }
03792
03793 if (tmperr > 0)
03794 {
03795
03796 rsbac_write_lock(&list->lock, &flags);
03797 item_p = add_lol_item(list, max_age, new_buf, new_data);
03798
03799 rsbac_write_unlock(&list->lock, &flags);
03800 if(!item_p)
03801 {
03802 err = -RSBAC_ENOMEM;
03803 goto end_read_free;
03804 }
03805 read_count++;
03806
03807
03808
03809
03810
03811
03812 set_fs(KERNEL_DS);
03813 tmperr = file_p->f_op->read(file_p,
03814 (__u8 *) &sublen,
03815 sizeof(sublen),
03816 &file_p->f_pos);
03817 set_fs(oldfs);
03818
03819 if (tmperr > 0)
03820 {
03821 for(i=0;i<sublen;i++)
03822 {
03823 set_fs(KERNEL_DS);
03824 tmperr = file_p->f_op->read(file_p,
03825 (char *) &max_age,
03826 sizeof(max_age),
03827 &file_p->f_pos);
03828 set_fs(oldfs);
03829 if(subconv)
03830 {
03831 set_fs(KERNEL_DS);
03832 tmperr = file_p->f_op->read(file_p,
03833 old_subbuf,
03834 list_info_p->subdesc_size + list_info_p->subdata_size,
03835 &file_p->f_pos);
03836 set_fs(oldfs);
03837 if(tmperr > 0)
03838 {
03839 converr = subconv(old_subbuf, old_subdata,
03840 new_subbuf, new_subdata);
03841 if(converr)
03842 tmperr = converr;
03843 }
03844 }
03845 else
03846 {
03847 set_fs(KERNEL_DS);
03848 tmperr = file_p->f_op->read(file_p,
03849 new_subbuf,
03850 list->info.subdesc_size + list->info.subdata_size,
03851 &file_p->f_pos);
03852 set_fs(oldfs);
03853 }
03854 if(tmperr > 0)
03855 {
03856
03857 rsbac_write_lock(&list->lock, &flags);
03858 if (!add_lol_subitem(list,
03859 item_p,
03860 max_age,
03861 new_subbuf,
03862 new_subdata))
03863 {
03864 rsbac_printk(KERN_WARNING
03865 "read_lol_list(): could not add subitem!\n");
03866 i = sublen;
03867 tmperr = -1;
03868 }
03869
03870 rsbac_write_unlock(&list->lock, &flags);
03871 }
03872 else
03873 {
03874 i = sublen;
03875 tmperr = -1;
03876 }
03877 }
03878 }
03879 }
03880 }
03881 while (tmperr > 0);
03882
03883 if (tmperr < 0)
03884 {
03885 rsbac_printk(KERN_WARNING "read_lol_list(): read error from file %s!\n",
03886 list->name);
03887 err = -RSBAC_EREADFAILED;
03888 }
03889
03890 if (read_count != list_count)
03891 {
03892 rsbac_printk(KERN_WARNING "read_lol_list(): read %lu, expected %u items from file %s!\n",
03893 read_count,
03894 list_count,
03895 list->name);
03896 err = -RSBAC_EREADFAILED;
03897 }
03898
03899 end_read_free:
03900 rsbac_kfree(old_buf);
03901 rsbac_kfree(new_buf);
03902 rsbac_kfree(old_subbuf);
03903 rsbac_kfree(new_subbuf);
03904
03905 end_read:
03906
03907 #ifdef CONFIG_RSBAC_DEBUG
03908 if (rsbac_debug_lists)
03909 {
03910 rsbac_printk(KERN_DEBUG "read_lol_list(): %lu entries read.\n",
03911 read_count);
03912 }
03913 #endif
03914
03915 rsbac_read_close(file_p);
03916 rsbac_kfree(list_info_p);
03917 rsbac_kfree(file_p);
03918 return(err);
03919 }
03920
03921
03922 #ifndef CONFIG_RSBAC_NO_WRITE
03923 static int fill_buffer(struct rsbac_list_reg_item_t * list,
03924 struct rsbac_list_write_item_t ** write_item_pp)
03925 {
03926 struct rsbac_list_write_item_t * write_item_p;
03927 struct rsbac_list_item_t * current_p;
03928 u_long flags;
03929 char * buffer = NULL;
03930 u_long buflen;
03931 u_long write_count = 0;
03932 rsbac_boolean_t vmalloc_used = FALSE;
03933 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION;
03934 rsbac_time_t timestamp = RSBAC_CURRENT_TIME;
03935
03936 write_item_p = rsbac_kmalloc(sizeof(*write_item_p));
03937 if(!write_item_p)
03938 {
03939 *write_item_pp = NULL;
03940 return(-RSBAC_ENOMEM);
03941 }
03942
03943
03944 rsbac_read_lock(&list->lock, &flags);
03945
03946 buflen = sizeof(list_version)
03947 + sizeof(timestamp)
03948 + sizeof(list->info)
03949 + sizeof(list->lastchange)
03950 + sizeof(list->count)
03951 + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size);
03952
03953 buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used);
03954 if(!buffer)
03955 {
03956
03957 rsbac_read_unlock(&list->lock, &flags);
03958 rsbac_kfree(write_item_p);
03959 *write_item_pp = NULL;
03960 return(-RSBAC_ENOMEM);
03961 }
03962
03963 memcpy(buffer,
03964 (char *) &list_version,
03965 sizeof(list_version));
03966 write_count = sizeof(list_version);
03967
03968 memcpy(buffer+write_count,
03969 (char *) ×tamp,
03970 sizeof(timestamp));
03971 write_count += sizeof(timestamp);
03972
03973 memcpy(buffer+write_count,
03974 (char *) &list->info,
03975 sizeof(list->info));
03976 write_count += sizeof(list->info);
03977
03978 memcpy(buffer+write_count,
03979 (char *) &list->lastchange,
03980 sizeof(list->lastchange));
03981 write_count += sizeof(list->lastchange);
03982
03983 memcpy(buffer+write_count,
03984 (char *) &list->count,
03985 sizeof(list->count));
03986 write_count += sizeof(list->count);
03987
03988 current_p = list->head;
03989 while (current_p)
03990 {
03991 memcpy(buffer+write_count,
03992 ¤t_p->max_age,
03993 sizeof(current_p->max_age));
03994 write_count += sizeof(current_p->max_age);
03995 memcpy(buffer+write_count,
03996 ((char *) current_p) + sizeof(*current_p),
03997 list->info.desc_size + list->info.data_size);
03998 write_count += list->info.desc_size + list->info.data_size;
03999 current_p = current_p->next;
04000 }
04001
04002
04003 write_item_p->prev = NULL;
04004 write_item_p->next = NULL;
04005 write_item_p->list = list;
04006 write_item_p->buflen = write_count;
04007 write_item_p->buf = buffer;
04008 write_item_p->vmalloc_used = vmalloc_used;
04009 strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME);
04010 write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
04011 write_item_p->device = list->device;
04012
04013 *write_item_pp = write_item_p;
04014
04015
04016 rsbac_read_unlock(&list->lock, &flags);
04017
04018 return 0;
04019 }
04020
04021 static int rsbac_list_write_buffers(struct rsbac_list_write_head_t write_head,
04022 rsbac_boolean_t need_lock)
04023 {
04024 struct file * file_p;
04025 int count = 0;
04026 mm_segment_t oldfs;
04027 u_long written;
04028 u_long bytes;
04029 int tmperr = 0;
04030 struct rsbac_list_write_item_t * write_item_p;
04031 struct rsbac_list_write_item_t * next_item_p;
04032
04033 file_p = rsbac_kmalloc(sizeof(*file_p));
04034 if(!file_p)
04035 {
04036 return -RSBAC_ENOMEM;
04037 }
04038 write_item_p = write_head.head;
04039 while(write_item_p)
04040 {
04041 #ifdef CONFIG_RSBAC_DEBUG
04042 if (rsbac_debug_write)
04043 {
04044 rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): write list %s on device %02u:%02u.\n",
04045 write_item_p->name,
04046 RSBAC_MAJOR(write_item_p->device),
04047 RSBAC_MINOR(write_item_p->device));
04048 }
04049 #endif
04050 if(need_lock)
04051 lock_kernel();
04052
04053 if ((tmperr = rsbac_write_open(write_item_p->name,
04054 file_p,
04055 write_item_p->device) ))
04056 {
04057 if(tmperr != -RSBAC_ENOTWRITABLE)
04058 {
04059 rsbac_printk(KERN_WARNING
04060 "rsbac_list_write_buffers(): opening file %s on device %02u:%02u failed with error %i!\n",
04061 write_item_p->name,
04062 RSBAC_MAJOR(write_item_p->device),
04063 RSBAC_MINOR(write_item_p->device),
04064 tmperr);
04065 }
04066 count = tmperr;
04067 goto free_item;
04068 }
04069
04070
04071
04072
04073 oldfs = get_fs();
04074 set_fs(KERNEL_DS);
04075
04076 written = 0;
04077 while ((written < write_item_p->buflen) && (tmperr >= 0))
04078 {
04079 bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK);
04080 tmperr = file_p->f_op->write(file_p,
04081 write_item_p->buf + written,
04082 bytes,
04083 &file_p->f_pos);
04084 if(tmperr > 0)
04085 {
04086 written += tmperr;
04087 }
04088 }
04089 if (tmperr < 0)
04090 {
04091 rsbac_printk(KERN_WARNING
04092 "rsbac_list_write_buffers(): write error %i on device %02u:%02u file %s!\n",
04093 tmperr,
04094 RSBAC_MAJOR(write_item_p->device),
04095 RSBAC_MINOR(write_item_p->device),
04096 write_item_p->name);
04097 if(write_item_p->list->self == write_item_p->list)
04098 write_item_p->list->dirty = TRUE;
04099 }
04100 else
04101 count++;
04102
04103
04104
04105 set_fs(oldfs);
04106
04107 #ifdef CONFIG_RSBAC_DEBUG
04108 if (rsbac_debug_write)
04109 {
04110 rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): %lu bytes written.\n",
04111 written);
04112 }
04113 #endif
04114
04115 rsbac_write_close(file_p);
04116
04117 free_item:
04118 if(need_lock)
04119 unlock_kernel();
04120
04121 rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used);
04122 next_item_p = write_item_p->next;
04123 rsbac_kfree(write_item_p);
04124 write_item_p = next_item_p;
04125 }
04126
04127 rsbac_kfree(file_p);
04128 return count;
04129 }
04130
04131 static int fill_lol_buffer(struct rsbac_list_lol_reg_item_t * list,
04132 struct rsbac_list_lol_write_item_t ** write_item_pp)
04133 {
04134 struct rsbac_list_lol_write_item_t * write_item_p;
04135 struct rsbac_list_lol_item_t * current_p;
04136 struct rsbac_list_item_t * sub_p;
04137 u_long flags;
04138 char * buffer = NULL;
04139 u_long buflen;
04140 u_long write_count = 0;
04141 rsbac_boolean_t vmalloc_used = FALSE;
04142 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION;
04143 rsbac_time_t timestamp = RSBAC_CURRENT_TIME;
04144
04145 write_item_p = rsbac_kmalloc(sizeof(*write_item_p));
04146 if(!write_item_p)
04147 {
04148 *write_item_pp = NULL;
04149 return(-RSBAC_ENOMEM);
04150 }
04151
04152
04153 rsbac_read_lock(&list->lock, &flags);
04154
04155
04156 buflen = sizeof(list_version)
04157 + sizeof(timestamp)
04158 + sizeof(list->info)
04159 + sizeof(list->lastchange)
04160 + sizeof(list->count)
04161 + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size);
04162 current_p = list->head;
04163 while(current_p)
04164 {
04165 buflen += sizeof(current_p->count);
04166 buflen += current_p->count * (sizeof(current_p->max_age) + list->info.subdesc_size + list->info.subdata_size);
04167 current_p = current_p->next;
04168 }
04169
04170 buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used);
04171 if(!buffer)
04172 {
04173
04174 rsbac_read_unlock(&list->lock, &flags);
04175 rsbac_kfree(write_item_p);
04176 *write_item_pp = NULL;
04177 return(-RSBAC_ENOMEM);
04178 }
04179
04180 memcpy(buffer,
04181 (char *) &list_version,
04182 sizeof(list_version));
04183 write_count = sizeof(list_version);
04184
04185 memcpy(buffer+write_count,
04186 (char *) ×tamp,
04187 sizeof(timestamp));
04188 write_count += sizeof(timestamp);
04189
04190 memcpy(buffer+write_count,
04191 (char *) &list->info,
04192 sizeof(list->info));
04193 write_count += sizeof(list->info);
04194
04195 memcpy(buffer+write_count,
04196 (char *) &list->lastchange,
04197 sizeof(list->lastchange));
04198 write_count += sizeof(list->lastchange);
04199
04200 memcpy(buffer+write_count,
04201 (char *) &list->count,
04202 sizeof(list->count));
04203 write_count += sizeof(list->count);
04204
04205 current_p = list->head;
04206 while (current_p)
04207 {
04208 memcpy(buffer+write_count,
04209 ¤t_p->max_age,
04210 sizeof(current_p->max_age));
04211 write_count += sizeof(current_p->max_age);
04212 memcpy(buffer+write_count,
04213 ((char *) current_p) + sizeof(*current_p),
04214 list->info.desc_size + list->info.data_size);
04215 write_count += list->info.desc_size + list->info.data_size;
04216 memcpy(buffer+write_count,
04217 ¤t_p->count,
04218 sizeof(current_p->count));
04219 write_count += sizeof(current_p->count);
04220
04221 sub_p = current_p->head;
04222 while (sub_p)
04223 {
04224 memcpy(buffer+write_count,
04225 &sub_p->max_age,
04226 sizeof(sub_p->max_age));
04227 write_count += sizeof(sub_p->max_age);
04228 memcpy(buffer+write_count,
04229 ((char *) sub_p) + sizeof(*sub_p),
04230 list->info.subdesc_size + list->info.subdata_size);
04231 write_count += list->info.subdesc_size + list->info.subdata_size;
04232 sub_p = sub_p->next;
04233 }
04234 current_p = current_p->next;
04235 }
04236
04237
04238 write_item_p->prev = NULL;
04239 write_item_p->next = NULL;
04240 write_item_p->list = list;
04241 write_item_p->buflen = write_count;
04242 write_item_p->buf = buffer;
04243 write_item_p->vmalloc_used = vmalloc_used;
04244 strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME);
04245 write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0;
04246 write_item_p->device = list->device;
04247 *write_item_pp = write_item_p;
04248
04249
04250 rsbac_read_unlock(&list->lock, &flags);
04251
04252 return 0;
04253 }
04254
04255 static int rsbac_list_write_lol_buffers(struct rsbac_list_lol_write_head_t write_head,
04256 rsbac_boolean_t need_lock)
04257 {
04258 struct file * file_p;
04259 int count = 0;
04260 mm_segment_t oldfs;
04261 u_long written;
04262 u_long bytes;
04263 int tmperr = 0;
04264 struct rsbac_list_lol_write_item_t * write_item_p;
04265 struct rsbac_list_lol_write_item_t * next_item_p;
04266
04267 file_p = rsbac_kmalloc(sizeof(*file_p));
04268 if(!file_p)
04269 {
04270 return -RSBAC_ENOMEM;
04271 }
04272 write_item_p = write_head.head;
04273 while(write_item_p)
04274 {
04275 #ifdef CONFIG_RSBAC_DEBUG
04276 if (rsbac_debug_write)
04277 {
04278 rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): write list %s on device %02u:%02u.\n",
04279 write_item_p->name,
04280 RSBAC_MAJOR(write_item_p->device),
04281 RSBAC_MINOR(write_item_p->device));
04282 }
04283 #endif
04284 if(need_lock)
04285 lock_kernel();
04286
04287 if ((tmperr = rsbac_write_open(write_item_p->name,
04288 file_p,
04289 write_item_p->device) ))
04290 {
04291 if(tmperr != -RSBAC_ENOTWRITABLE)
04292 {
04293 rsbac_printk(KERN_WARNING
04294 "rsbac_list_write_lol_buffers(): opening file %s on device %02u:%02u failed with error %i!\n",
04295 write_item_p->name,
04296 RSBAC_MAJOR(write_item_p->device),
04297 RSBAC_MINOR(write_item_p->device),
04298 tmperr);
04299 }
04300 goto free_item;
04301 }
04302
04303
04304
04305
04306 oldfs = get_fs();
04307 set_fs(KERNEL_DS);
04308
04309 written = 0;
04310 while ((written < write_item_p->buflen) && (tmperr >= 0))
04311 {
04312 bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK);
04313 tmperr = file_p->f_op->write(file_p,
04314 write_item_p->buf + written,
04315 bytes,
04316 &file_p->f_pos);
04317 if(tmperr > 0)
04318 {
04319 written += tmperr;
04320 }
04321 }
04322 if (tmperr < 0)
04323 {
04324 rsbac_printk(KERN_WARNING
04325 "rsbac_list_write_lol_buffers(): write error %i on device %02u:%02u file %s!\n",
04326 tmperr,
04327 RSBAC_MAJOR(write_item_p->device),
04328 RSBAC_MINOR(write_item_p->device),
04329 write_item_p->name);
04330 if(write_item_p->list->self == write_item_p->list)
04331 write_item_p->list->dirty = TRUE;
04332 }
04333 else
04334 count++;
04335
04336
04337
04338 set_fs(oldfs);
04339
04340 #ifdef CONFIG_RSBAC_DEBUG
04341 if (rsbac_debug_write)
04342 {
04343 rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): %lu bytes written.\n",
04344 written);
04345 }
04346 #endif
04347
04348 rsbac_write_close(file_p);
04349
04350 free_item:
04351 if(need_lock)
04352 unlock_kernel();
04353
04354 rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used);
04355 next_item_p = write_item_p->next;
04356 rsbac_kfree(write_item_p);
04357 write_item_p = next_item_p;
04358 }
04359
04360 rsbac_kfree(file_p);
04361 return count;
04362 }
04363 #endif
04364
04365
04366
04367
04368
04369
04370 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
04371 static int
04372 lists_proc_info(char *buffer, char **start, off_t offset, int length)
04373 {
04374 int len = 0;
04375 off_t pos = 0;
04376 off_t begin = 0;
04377
04378 union rsbac_target_id_t rsbac_target_id;
04379 union rsbac_attribute_value_t rsbac_attribute_value;
04380 struct rsbac_list_reg_item_t * item_p;
04381 struct rsbac_list_lol_reg_item_t * lol_item_p;
04382 u_long flags;
04383
04384 if (!rsbac_is_initialized())
04385 return (-ENOSYS);
04386
04387 #ifdef CONFIG_RSBAC_DEBUG
04388 if (rsbac_debug_aef)
04389 {
04390 rsbac_printk(KERN_DEBUG "lists_proc_info(): calling ADF\n");
04391 }
04392 #endif
04393 rsbac_target_id.scd = ST_rsbac;
04394 rsbac_attribute_value.dummy = 0;
04395 if (!rsbac_adf_request(R_GET_STATUS_DATA,
04396 current->pid,
04397 T_SCD,
04398 rsbac_target_id,
04399 A_none,
04400 rsbac_attribute_value))
04401 {
04402 return -EPERM;
04403 }
04404
04405 len += sprintf(buffer, "Generic Lists Status\n--------------------\n");
04406 #ifdef CONFIG_RSBAC_LIST_TRANS
04407 if(rsbac_list_count(ta_handle) > 0)
04408 {
04409 int list_count;
04410 rsbac_list_ta_number_t * desc_array;
04411 struct rsbac_list_ta_data_t data;
04412
04413 len += sprintf(buffer+len, "Transactions active:\n\n");
04414 pos = begin + len;
04415 if (pos < offset)
04416 {
04417 len = 0;
04418 begin = pos;
04419 }
04420 if (pos > offset+length)
04421 goto out;
04422
04423 list_count = rsbac_list_get_all_desc(ta_handle, (void **) &desc_array);
04424 if(list_count > 0)
04425 {
04426 int i;
04427 rsbac_time_t now = RSBAC_CURRENT_TIME;
04428
04429 for(i=0; i<list_count; i++)
04430 {
04431 if(!rsbac_list_get_data(ta_handle, &desc_array[i], &data))
04432 {
04433 len += sprintf(buffer+len, "%u (ttl %is)\n",
04434 desc_array[i], data.timeout - now);
04435 pos = begin + len;
04436 if (pos < offset)
04437 {
04438 len = 0;
04439 begin = pos;
04440 }
04441 if (pos > offset+length)
04442 goto out;
04443 }
04444 }
04445 rsbac_vfree(desc_array);
04446 }
04447
04448 len += sprintf(buffer+len, "\nLists in Transaction\n--------------------\nName\t\tdevice\tta\t count\n");
04449 pos = begin + len;
04450 if (pos < offset)
04451 {
04452 len = 0;
04453 begin = pos;
04454 }
04455 if (pos > offset+length)
04456 goto out;
04457
04458 list_count = 0;
04459 rsbac_read_lock(®_head.lock, &flags);
04460 item_p=reg_head.head;
04461 while(item_p)
04462 {
04463 if(item_p->ta_copied)
04464 {
04465 len += sprintf(buffer + len, "%-16s%02u:%02u\t%10u\t%u\n",
04466 item_p->name,
04467 RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04468 item_p->ta_copied,
04469 item_p->ta_count);
04470 pos = begin + len;
04471 if (pos < offset)
04472 {
04473 len = 0;
04474 begin = pos;
04475 }
04476 if (pos > offset+length)
04477 {
04478 rsbac_read_unlock(®_head.lock, &flags);
04479 goto out;
04480 }
04481 list_count++;
04482 }
04483 item_p = item_p->next;
04484 }
04485 rsbac_read_unlock(®_head.lock, &flags);
04486
04487 len += sprintf(buffer + len, "\n %u lists in transaction.\n\n",
04488 list_count);
04489 pos = begin + len;
04490 if (pos < offset)
04491 {
04492 len = 0;
04493 begin = pos;
04494 }
04495 if (pos > offset+length)
04496 goto out;
04497
04498 len += sprintf(buffer+len, "Lists of Lists in Transaction\n-----------------------------\nName\t\tdevice\tta\t count\n");
04499 pos = begin + len;
04500 if (pos < offset)
04501 {
04502 len = 0;
04503 begin = pos;
04504 }
04505 if (pos > offset+length)
04506 goto out;
04507
04508 list_count = 0;
04509 rsbac_read_lock(&lol_reg_head.lock, &flags);
04510 lol_item_p=lol_reg_head.head;
04511 while(lol_item_p)
04512 {
04513 if(lol_item_p->ta_copied)
04514 {
04515 len += sprintf(buffer + len, "%-16s%02u:%02u\t%10u\t%u\n",
04516 lol_item_p->name,
04517 RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04518 lol_item_p->ta_copied,
04519 lol_item_p->ta_count);
04520 pos = begin + len;
04521 if (pos < offset)
04522 {
04523 len = 0;
04524 begin = pos;
04525 }
04526 if (pos > offset+length)
04527 {
04528 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04529 goto out;
04530 }
04531 list_count++;
04532 }
04533 lol_item_p = lol_item_p->next;
04534 }
04535 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04536
04537 len += sprintf(buffer + len, "\n %u lists of lists in transaction.\n\n\n",
04538 list_count);
04539 pos = begin + len;
04540 if (pos < offset)
04541 {
04542 len = 0;
04543 begin = pos;
04544 }
04545 if (pos > offset+length)
04546 goto out;
04547 }
04548 else
04549 len += sprintf(buffer+len, "No active transaction\n\n");
04550 pos = begin + len;
04551 if (pos < offset)
04552 {
04553 len = 0;
04554 begin = pos;
04555 }
04556 if (pos > offset+length)
04557 goto out;
04558 #endif
04559
04560 len += sprintf(buffer+len, "Registered Generic Lists\n------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n");
04561 pos = begin + len;
04562 if (pos < offset)
04563 {
04564 len = 0;
04565 begin = pos;
04566 }
04567 if (pos > offset+length)
04568 goto out;
04569
04570 rsbac_read_lock(®_head.lock, &flags);
04571 item_p=reg_head.head;
04572 while(item_p)
04573 {
04574 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n",
04575 item_p->name,
04576 RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04577 item_p->count,
04578 item_p->info.desc_size,
04579 item_p->info.data_size,
04580 item_p->flags & RSBAC_LIST_PERSIST,
04581 item_p->no_write,
04582 item_p->flags,
04583 item_p->dirty & (item_p->flags & RSBAC_LIST_PERSIST));
04584 pos = begin + len;
04585 if (pos < offset)
04586 {
04587 len = 0;
04588 begin = pos;
04589 }
04590 if (pos > offset+length)
04591 {
04592 rsbac_read_unlock(®_head.lock, &flags);
04593 goto out;
04594 }
04595 item_p = item_p->next;
04596 }
04597 rsbac_read_unlock(®_head.lock, &flags);
04598
04599 len += sprintf(buffer + len, "\n %u lists registered.\n\n",
04600 reg_head.count);
04601 pos = begin + len;
04602 if (pos < offset)
04603 {
04604 len = 0;
04605 begin = pos;
04606 }
04607 if (pos > offset+length)
04608 goto out;
04609
04610 len += sprintf(buffer + len, "Registered Generic Lists of Lists\n---------------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n");
04611 pos = begin + len;
04612 if (pos < offset)
04613 {
04614 len = 0;
04615 begin = pos;
04616 }
04617 if (pos > offset+length)
04618 goto out;
04619
04620 rsbac_read_lock(&lol_reg_head.lock, &flags);
04621 lol_item_p=lol_reg_head.head;
04622 while(lol_item_p)
04623 {
04624 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u+%u\t%u+%u\t%u\t%u\t%u\t%u\n",
04625 lol_item_p->name,
04626 RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04627 lol_item_p->count,
04628 lol_item_p->info.desc_size,
04629 lol_item_p->info.subdesc_size,
04630 lol_item_p->info.data_size,
04631 lol_item_p->info.subdata_size,
04632 lol_item_p->flags & RSBAC_LIST_PERSIST,
04633 lol_item_p->no_write,
04634 lol_item_p->flags,
04635 lol_item_p->dirty & (lol_item_p->flags & RSBAC_LIST_PERSIST));
04636 pos = begin + len;
04637 if (pos < offset)
04638 {
04639 len = 0;
04640 begin = pos;
04641 }
04642 if (pos > offset+length)
04643 {
04644 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04645 goto out;
04646 }
04647 lol_item_p = lol_item_p->next;
04648 }
04649 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04650
04651 len += sprintf(buffer + len, "\n %u lists of lists registered.\n",
04652 lol_reg_head.count);
04653 pos = begin + len;
04654 if (pos < offset)
04655 {
04656 len = 0;
04657 begin = pos;
04658 }
04659 if (pos > offset+length)
04660 goto out;
04661
04662 out:
04663 *start = buffer + (offset - begin);
04664 len -= (offset - begin);
04665
04666 if (len > length)
04667 len = length;
04668 return len;
04669 }
04670
04671 #if defined(CONFIG_RSBAC_LIST_REPL)
04672 static int
04673 repl_lists_proc_info(char *buffer, char **start, off_t offset, int length)
04674 {
04675 int len = 0;
04676 off_t pos = 0;
04677 off_t begin = 0;
04678
04679 union rsbac_target_id_t rsbac_target_id;
04680 union rsbac_attribute_value_t rsbac_attribute_value;
04681 struct rsbac_list_reg_item_t * item_p;
04682 struct rsbac_list_lol_reg_item_t * lol_item_p;
04683 u_long flags;
04684
04685 if (!rsbac_is_initialized())
04686 return (-ENOSYS);
04687
04688 #ifdef CONFIG_RSBAC_DEBUG
04689 if (rsbac_debug_aef)
04690 {
04691 rsbac_printk(KERN_DEBUG "repl_lists_proc_info(): calling ADF\n");
04692 }
04693 #endif
04694 rsbac_target_id.scd = ST_rsbac;
04695 rsbac_attribute_value.dummy = 0;
04696 if (!rsbac_adf_request(R_GET_STATUS_DATA,
04697 current->pid,
04698 T_SCD,
04699 rsbac_target_id,
04700 A_none,
04701 rsbac_attribute_value))
04702 {
04703 return -EPERM;
04704 }
04705
04706 len += sprintf(buffer, "List Replication Status\n--------------------\n");
04707 len += sprintf(buffer, "Last Replication at: %u:%u",
04708 repl_last.sec, repl_last.nsec);
04709
04710 len += sprintf(buffer+len, "Lists\n-----\nName\t\tdevice\tlastchange\n");
04711 pos = begin + len;
04712 if (pos < offset)
04713 {
04714 len = 0;
04715 begin = pos;
04716 }
04717 if (pos > offset+length)
04718 goto out;
04719
04720 rsbac_read_lock(®_head.lock, &flags);
04721 item_p=reg_head.head;
04722 while(item_p)
04723 {
04724 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u:%u\n",
04725 item_p->name,
04726 RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device),
04727 item_p->lastchange.sec,
04728 item_p->lastchange.nsec);
04729 pos = begin + len;
04730 if (pos < offset)
04731 {
04732 len = 0;
04733 begin = pos;
04734 }
04735 if (pos > offset+length)
04736 {
04737 rsbac_read_unlock(®_head.lock, &flags);
04738 goto out;
04739 }
04740 item_p = item_p->next;
04741 }
04742 rsbac_read_unlock(®_head.lock, &flags);
04743
04744 len += sprintf(buffer + len, "\n %u lists registered.\n\n",
04745 reg_head.count);
04746 pos = begin + len;
04747 if (pos < offset)
04748 {
04749 len = 0;
04750 begin = pos;
04751 }
04752 if (pos > offset+length)
04753 goto out;
04754
04755 len += sprintf(buffer + len, "Lists of Lists\n-----------------\nName\t\tdevice\tlastchange\n");
04756 pos = begin + len;
04757 if (pos < offset)
04758 {
04759 len = 0;
04760 begin = pos;
04761 }
04762 if (pos > offset+length)
04763 goto out;
04764
04765 rsbac_read_lock(&lol_reg_head.lock, &flags);
04766 lol_item_p=lol_reg_head.head;
04767 while(lol_item_p)
04768 {
04769 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u:%u\n",
04770 lol_item_p->name,
04771 RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device),
04772 lol_item_p->lastchange.sec,
04773 lol_item_p->lastchange.nsec);
04774 pos = begin + len;
04775 if (pos < offset)
04776 {
04777 len = 0;
04778 begin = pos;
04779 }
04780 if (pos > offset+length)
04781 {
04782 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04783 goto out;
04784 }
04785 lol_item_p = lol_item_p->next;
04786 }
04787 rsbac_read_unlock(&lol_reg_head.lock, &flags);
04788
04789 len += sprintf(buffer + len, "\n %u lists of lists registered.\n",
04790 lol_reg_head.count);
04791 pos = begin + len;
04792 if (pos < offset)
04793 {
04794 len = 0;
04795 begin = pos;
04796 }
04797 if (pos > offset+length)
04798 goto out;
04799
04800 out:
04801 *start = buffer + (offset - begin);
04802 len -= (offset - begin);
04803
04804 if (len > length)
04805 len = length;
04806 return len;
04807 }
04808 #endif
04809
04810
04811 static int backup_proc_read(char *page, char **start, off_t off,
04812 int count, int *eof, void *data)
04813 {
04814 int len = 0;
04815 off_t pos = 0;
04816 off_t begin = 0;
04817
04818 union rsbac_target_id_t rsbac_target_id;
04819 union rsbac_attribute_value_t rsbac_attribute_value;
04820 struct rsbac_list_reg_item_t * list;
04821 struct rsbac_list_item_t * current_p;
04822 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION;
04823 rsbac_time_t timestamp = RSBAC_CURRENT_TIME;
04824 u_long rflags, flags;
04825
04826 if (!rsbac_is_initialized())
04827 return -ENOSYS;
04828
04829 #ifdef CONFIG_RSBAC_DEBUG
04830 if (rsbac_debug_aef)
04831 {
04832 rsbac_printk(KERN_DEBUG "backup_proc_read(): calling ADF\n");
04833 }
04834 #endif
04835 rsbac_target_id.scd = ST_rsbac;
04836 rsbac_attribute_value.dummy = 0;
04837 if (!rsbac_adf_request(R_GET_STATUS_DATA,
04838 current->pid,
04839 T_SCD,
04840 rsbac_target_id,
04841 A_none,
04842 rsbac_attribute_value))
04843 {
04844 return -EPERM;
04845 }
04846
04847 rsbac_read_lock(®_head.lock, &rflags);
04848 list=lookup_reg(data);
04849 if(!list)
04850 {
04851 rsbac_read_unlock(®_head.lock, &rflags);
04852 return -ENOSYS;
04853 }
04854
04855 rsbac_read_lock(&list->lock, &flags);
04856
04857 memcpy(page,
04858 (char *) &list_version,
04859 sizeof(list_version));
04860 len = sizeof(list_version);
04861
04862 memcpy(page+len,
04863 (char *) ×tamp,
04864 sizeof(timestamp));
04865 len += sizeof(timestamp);
04866
04867 memcpy(page+len,
04868 (char *) &list->info,
04869 sizeof(list->info));
04870 len += sizeof(list->info);
04871 pos = begin + len;
04872 if (pos < off)
04873 {
04874 len = 0;
04875 begin = pos;
04876 }
04877 if (pos > off+count)
04878 {
04879 goto out;
04880 }
04881
04882
04883 current_p = list->head;
04884 while (current_p)
04885 {
04886 memcpy(page+len,
04887 ((char *) current_p) + sizeof(*current_p),
04888 list->info.desc_size + list->info.data_size);
04889 len += list->info.desc_size + list->info.data_size;
04890 pos = begin + len;
04891 if (pos < off)
04892 {
04893 len = 0;
04894 begin = pos;
04895 }
04896 if (pos > off+count)
04897 {
04898 goto out;
04899 }
04900 current_p = current_p->next;
04901 }
04902
04903 out:
04904
04905 rsbac_read_unlock(&list->lock, &flags);
04906 rsbac_read_unlock(®_head.lock, &rflags);
04907 if(len <= off+count)
04908 *eof=1;
04909 *start = page + (off - begin);
04910 len -= (off - begin);
04911
04912 if (len > count)
04913 len = count;
04914 return len;
04915 }
04916
04917
04918 static int lol_backup_proc_read(char *page, char **start, off_t off,
04919 int count, int *eof, void *data)
04920 {
04921 int len = 0;
04922 off_t pos = 0;
04923 off_t begin = 0;
04924
04925 union rsbac_target_id_t rsbac_target_id;
04926 union rsbac_attribute_value_t rsbac_attribute_value;
04927 struct rsbac_list_lol_reg_item_t * list;
04928 struct rsbac_list_lol_item_t * current_p;
04929 struct rsbac_list_item_t * sub_p;
04930 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION;
04931 rsbac_time_t timestamp = RSBAC_CURRENT_TIME;
04932 u_long rflags, flags;
04933
04934 if (!rsbac_is_initialized())
04935 return (-ENOSYS);
04936
04937 #ifdef CONFIG_RSBAC_DEBUG
04938 if (rsbac_debug_aef)
04939 {
04940 rsbac_printk(KERN_DEBUG "lol_backup_proc_read(): calling ADF\n");
04941 }
04942 #endif
04943 rsbac_target_id.scd = ST_rsbac;
04944 rsbac_attribute_value.dummy = 0;
04945 if (!rsbac_adf_request(R_GET_STATUS_DATA,
04946 current->pid,
04947 T_SCD,
04948 rsbac_target_id,
04949 A_none,
04950 rsbac_attribute_value))
04951 {
04952 return -EPERM;
04953 }
04954
04955 rsbac_read_lock(&lol_reg_head.lock, &rflags);
04956 list=lookup_lol_reg(data);
04957 if(!list)
04958 {
04959 rsbac_read_unlock(&lol_reg_head.lock, &rflags);
04960 return -ENOSYS;
04961 }
04962
04963 rsbac_read_lock(&list->lock, &flags);
04964
04965 memcpy(page,
04966 (char *) &list_version,
04967 sizeof(list_version));
04968 len = sizeof(list_version);
04969
04970 memcpy(page+len,
04971 (char *) ×tamp,
04972 sizeof(timestamp));
04973 len += sizeof(timestamp);
04974
04975 memcpy(page+len,
04976 (char *) &list->info,
04977 sizeof(list->info));
04978 len += sizeof(list->info);
04979 pos = begin + len;
04980 if (pos < off)
04981 {
04982 len = 0;
04983 begin = pos;
04984 }
04985 if (pos > off+count)
04986 {
04987 goto out;
04988 }
04989
04990
04991 current_p = list->head;
04992 while (current_p)
04993 {
04994 memcpy(page+len,
04995 ((char *) current_p) + sizeof(*current_p),
04996 list->info.desc_size + list->info.data_size);
04997 len += list->info.desc_size + list->info.data_size;
04998 memcpy(page+len,
04999 ¤t_p->count,
05000 sizeof(current_p->count));
05001 len += sizeof(current_p->count);
05002 pos = begin + len;
05003 if (pos < off)
05004 {
05005 len = 0;
05006 begin = pos;
05007 }
05008 if (pos > off+count)
05009 {
05010 goto out;
05011 }
05012
05013 sub_p = current_p->head;
05014 while (sub_p)
05015 {
05016 memcpy(page+len,
05017 ((char *) sub_p) + sizeof(*sub_p),
05018 list->info.subdesc_size + list->info.subdata_size);
05019 len += list->info.subdesc_size + list->info.subdata_size;
05020 pos = begin + len;
05021 if (pos < off)
05022 {
05023 len = 0;
05024 begin = pos;
05025 }
05026 if (pos > off+count)
05027 {
05028 goto out;
05029 }
05030 sub_p = sub_p->next;
05031 }
05032 current_p = current_p->next;
05033 }
05034
05035 out:
05036
05037 rsbac_read_unlock(&list->lock, &flags);
05038 rsbac_read_unlock(&lol_reg_head.lock, &rflags);
05039 if(len <= off+count)
05040 *eof=1;
05041 *start = page + (off - begin);
05042 len -= (off - begin);
05043
05044 if (len > count)
05045 len = count;
05046 return len;
05047 }
05048 #endif
05049
05050
05051
05052
05053
05054
05055 int rsbac_list_compare_u32(void * desc1, void * desc2)
05056 {
05057 if( *((__u32*) desc1) < *((__u32*) desc2))
05058 return -1;
05059 return( *((__u32*) desc1) != *((__u32*) desc2));
05060 }
05061
05062 #ifdef CONFIG_RSBAC_INIT_DELAY
05063 int rsbac_list_init(void)
05064 #else
05065 int __init rsbac_list_init(void)
05066 #endif
05067 {
05068 #ifdef CONFIG_RSBAC_LIST_TRANS
05069 int err;
05070 struct rsbac_list_info_t * list_info_p;
05071 #endif
05072
05073 reg_head.head = NULL;
05074 reg_head.tail = NULL;
05075 reg_head.curr = NULL;
05076 reg_head.lock = RW_LOCK_UNLOCKED;
05077 reg_head.count = 0;
05078
05079 lol_reg_head.head = NULL;
05080 lol_reg_head.tail = NULL;
05081 lol_reg_head.curr = NULL;
05082 lol_reg_head.lock = RW_LOCK_UNLOCKED;
05083 lol_reg_head.count = 0;
05084
05085 list_initialized = TRUE;
05086
05087 #ifdef CONFIG_RSBAC_LIST_REPL
05088 repl_last.sec = 0;
05089 repl_last.nsec = 0;
05090 #endif
05091
05092
05093 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
05094 {
05095 struct proc_dir_entry * tmp_entry_p;
05096
05097 tmp_entry_p = create_proc_entry(RSBAC_LIST_PROC_NAME,
05098 S_IFREG | S_IRUGO,
05099 proc_rsbac_root_p);
05100 if(tmp_entry_p)
05101 {
05102 tmp_entry_p->get_info = lists_proc_info;
05103 }
05104 #if defined(CONFIG_RSBAC_LIST_REPL)
05105 tmp_entry_p = create_proc_entry(RSBAC_LIST_REPL_PROC_NAME,
05106 S_IFREG | S_IRUGO,
05107 proc_rsbac_root_p);
05108 if(tmp_entry_p)
05109 {
05110 tmp_entry_p->get_info = repl_lists_proc_info;
05111 }
05112 #endif
05113 }
05114 #endif
05115
05116 #ifdef CONFIG_RSBAC_LIST_TRANS
05117 rsbac_printk(KERN_INFO
05118 "rsbac_list_init(): Registering transaction list.\n");
05119 list_info_p = kmalloc(sizeof(*list_info_p), GFP_KERNEL);
05120 if(!list_info_p)
05121 {
05122 return -ENOMEM;
05123 }
05124 list_info_p->version = 1;
05125 list_info_p->key = RSBAC_LIST_TA_KEY;
05126 list_info_p->desc_size = sizeof(rsbac_list_ta_number_t);
05127 list_info_p->data_size = sizeof(struct rsbac_list_ta_data_t);
05128 list_info_p->max_age = 0;
05129 err = rsbac_list_register(RSBAC_LIST_VERSION,
05130 (void **) &ta_handle,
05131 list_info_p,
05132 0,
05133 rsbac_list_compare_u32,
05134 NULL,
05135 NULL,
05136 "transactions",
05137 RSBAC_AUTO_DEV);
05138 if(err)
05139 {
05140 char * tmp = kmalloc(RSBAC_MAXNAMELEN, GFP_KERNEL);
05141
05142 if(tmp)
05143 {
05144 rsbac_printk(KERN_WARNING
05145 "rsbac_list_init(): Registering transaction list failed with error %s\n",
05146 get_error_name(tmp, err));
05147 kfree(tmp);
05148 }
05149 }
05150 kfree(list_info_p);
05151 #endif
05152
05153 #ifdef CONFIG_RSBAC_LIST_REPL
05154 rsbac_printk(KERN_INFO
05155 "rsbac_list_init(): Registering replication partner list.\n");
05156 list_info_p = kmalloc(sizeof(*list_info_p), GFP_KERNEL);
05157 if(!list_info_p)
05158 {
05159 return -ENOMEM;
05160 }
05161 list_info_p->version = RSBAC_LIST_REPL_PARTNER_VERSION;
05162 list_info_p->key = RSBAC_LIST_REPL_PARTNER_KEY;
05163 list_info_p->desc_size = sizeof(rsbac_list_repl_partner_number_t);
05164 list_info_p->data_size = sizeof(struct rsbac_list_repl_partner_entry_t);
05165 list_info_p->max_age = 0;
05166 err = rsbac_list_register(RSBAC_LIST_VERSION,
05167 (void **) &repl_partner_handle,
05168 list_info_p,
05169 RSBAC_LIST_PERSIST,
05170 NULL,
05171 NULL,
05172 NULL,
05173 RSBAC_LIST_REPL_PARTNER_FILENAME,
05174 RSBAC_AUTO_DEV);
05175 if(err)
05176 {
05177 char * tmp = kmalloc(RSBAC_MAXNAMELEN, GFP_KERNEL);
05178
05179 if(tmp)
05180 {
05181 rsbac_printk(KERN_WARNING
05182 "rsbac_list_init(): Registering replication partner list failed with error %s\n",
05183 get_error_name(tmp, err));
05184 kfree(tmp);
05185 }
05186 }
05187 kfree(list_info_p);
05188 #endif
05189
05190 return 0;
05191 }
05192
05193 int rsbac_list_mount(kdev_t kdev)
05194 {
05195 return 0;
05196 }
05197
05198 int rsbac_list_umount(kdev_t kdev)
05199 {
05200 return 0;
05201 }
05202
05203 #ifdef CONFIG_RSBAC_AUTO_WRITE
05204 int rsbac_write_lists(rsbac_boolean_t need_lock)
05205 {
05206 int count = 0;
05207 int subcount = 0;
05208 int error = 0;
05209 struct rsbac_list_reg_item_t * item_p;
05210 struct rsbac_list_lol_reg_item_t * lol_item_p;
05211 u_long lock_flags;
05212 struct rsbac_list_write_head_t write_head;
05213 struct rsbac_list_write_item_t * write_item_p;
05214 struct rsbac_list_lol_write_head_t write_lol_head;
05215 struct rsbac_list_lol_write_item_t * write_lol_item_p;
05216
05217
05218
05219
05220
05221
05222
05223 if(!list_initialized)
05224 return -RSBAC_ENOTINITIALIZED;
05225
05226 #ifdef CONFIG_RSBAC_LIST_TRANS
05227 if(rsbac_list_count(ta_handle) > 0)
05228 {
05229 int list_count;
05230 rsbac_list_ta_number_t * desc_array;
05231 struct rsbac_list_ta_data_t data;
05232
05233 list_count = rsbac_list_get_all_desc(ta_handle, (void **) &desc_array);
05234 if(list_count > 0)
05235 {
05236 int i;
05237 rsbac_time_t now = RSBAC_CURRENT_TIME;
05238
05239 for(i=0; i<list_count; i++)
05240 {
05241 if(!rsbac_list_get_data(ta_handle, &desc_array[i], &data))
05242 {
05243 if(data.timeout < now)
05244 {
05245 rsbac_printk(KERN_WARNING
05246 "rsbac_write_lists(): transaction %u timed out, forcing forget\n",
05247 desc_array[i]);
05248 do_forget(desc_array[i]);
05249 }
05250 }
05251 }
05252 rsbac_vfree(desc_array);
05253 }
05254 }
05255 #endif
05256
05257
05258 write_head.head=NULL;
05259 write_head.tail=NULL;
05260 write_head.total=0;
05261 write_head.count=0;
05262
05263 rsbac_read_lock(®_head.lock, &lock_flags);
05264 item_p=reg_head.head;
05265 while(item_p)
05266 {
05267 if( (item_p->flags & RSBAC_LIST_PERSIST)
05268 && item_p->dirty
05269 && !item_p->no_write
05270 )
05271 {
05272 item_p->dirty = FALSE;
05273
05274 error = fill_buffer(item_p, &write_item_p);
05275 if(!error)
05276 {
05277 if(!write_head.head)
05278 {
05279 write_head.head = write_item_p;
05280 write_head.tail = write_item_p;
05281 write_head.total = write_item_p->buflen;
05282 write_head.count = 1;
05283 }
05284 else
05285 {
05286 write_head.tail->next = write_item_p;
05287 write_item_p->prev = write_head.tail;
05288 write_head.tail = write_item_p;
05289 write_head.total += write_item_p->buflen;
05290 write_head.count++;
05291 }
05292 }
05293 else
05294 {
05295 if( (error != -RSBAC_ENOTWRITABLE)
05296 && (error != -RSBAC_ENOMEM)
05297 )
05298 {
05299 rsbac_printk(KERN_WARNING
05300 "rsbac_write_lists(): fill_buffer() for list %s returned error %i\n",
05301 item_p->name, error);
05302 }
05303 item_p->dirty = TRUE;
05304 }
05305 }
05306 item_p=item_p->next;
05307 }
05308 rsbac_read_unlock(®_head.lock, &lock_flags);
05309
05310 #ifdef CONFIG_RSBAC_DEBUG
05311 if( rsbac_debug_write
05312 && (write_head.count > 0)
05313 )
05314 {
05315 rsbac_printk(KERN_DEBUG
05316 "rsbac_write_lists(): %u lists copied to buffers, total of %lu bytes\n",
05317 write_head.count,
05318 write_head.total);
05319 }
05320 #endif
05321
05322
05323 if(write_head.count)
05324 {
05325 count = rsbac_list_write_buffers(write_head, need_lock);
05326 #ifdef CONFIG_RSBAC_DEBUG
05327 if(rsbac_debug_write)
05328 {
05329 rsbac_printk(KERN_DEBUG
05330 "rsbac_write_lists(): %u lists written to disk\n",
05331 count);
05332 }
05333 #endif
05334 }
05335
05336
05337
05338 write_lol_head.head=NULL;
05339 write_lol_head.tail=NULL;
05340 write_lol_head.total=0;
05341 write_lol_head.count=0;
05342
05343 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05344 lol_item_p=lol_reg_head.head;
05345 while(lol_item_p)
05346 {
05347 if( (lol_item_p->flags & RSBAC_LIST_PERSIST)
05348 && lol_item_p->dirty
05349 && !lol_item_p->no_write
05350 )
05351 {
05352 lol_item_p->dirty = FALSE;
05353
05354 error = fill_lol_buffer(lol_item_p, &write_lol_item_p);
05355 if(!error)
05356 {
05357 if(!write_lol_head.head)
05358 {
05359 write_lol_head.head = write_lol_item_p;
05360 write_lol_head.tail = write_lol_item_p;
05361 write_lol_head.total = write_lol_item_p->buflen;
05362 write_lol_head.count = 1;
05363 }
05364 else
05365 {
05366 write_lol_head.tail->next = write_lol_item_p;
05367 write_lol_item_p->prev = write_lol_head.tail;
05368 write_lol_head.tail = write_lol_item_p;
05369 write_lol_head.total += write_lol_item_p->buflen;
05370 write_lol_head.count++;
05371 }
05372 }
05373 else
05374 {
05375 if( (error != -RSBAC_ENOTWRITABLE)
05376 && (error != -RSBAC_ENOMEM)
05377 )
05378 {
05379 rsbac_printk(KERN_WARNING
05380 "rsbac_write_lists(): fill_lol_buffer() for list %s returned error %i\n",
05381 lol_item_p->name, error);
05382 }
05383 item_p->dirty = TRUE;
05384 }
05385 }
05386 lol_item_p=lol_item_p->next;
05387 }
05388 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05389
05390 #ifdef CONFIG_RSBAC_DEBUG
05391 if( rsbac_debug_write
05392 && (write_lol_head.count > 0)
05393 )
05394 {
05395 rsbac_printk(KERN_DEBUG
05396 "rsbac_write_lists(): %u lists of lists copied to buffers, total of %lu bytes\n",
05397 write_lol_head.count,
05398 write_lol_head.total);
05399 }
05400 #endif
05401
05402
05403 if(write_lol_head.count)
05404 {
05405 subcount = rsbac_list_write_lol_buffers(write_lol_head, need_lock);
05406 count += subcount;
05407 #ifdef CONFIG_RSBAC_DEBUG
05408 if(rsbac_debug_write)
05409 {
05410 rsbac_printk(KERN_DEBUG
05411 "rsbac_write_lists(): %u lists of lists written to disk\n",
05412 subcount);
05413 }
05414 #endif
05415 }
05416
05417 #ifdef CONFIG_RSBAC_DEBUG
05418 if (rsbac_debug_write)
05419 {
05420 rsbac_printk(KERN_DEBUG "rsbac_write_lists(): %u lists with a total of %lu bytes written.\n",
05421 count, write_head.total + write_lol_head.total);
05422 }
05423 #endif
05424 return count;
05425 }
05426 #endif
05427
05428
05429 int rsbac_check_lists(int correct)
05430 {
05431 struct rsbac_list_reg_item_t * list;
05432 struct rsbac_list_lol_reg_item_t * lol_list;
05433 struct rsbac_list_item_t * item_p;
05434 struct rsbac_list_item_t * next_item_p;
05435 struct rsbac_list_lol_item_t * lol_item_p;
05436 struct rsbac_list_lol_item_t * next_lol_item_p;
05437 struct rsbac_list_item_t * lol_subitem_p;
05438 struct rsbac_list_item_t * next_lol_subitem_p;
05439 u_long lock_flags, rlock_flags;
05440 u_long tmp_count;
05441 u_long tmp_subcount;
05442 u_long subitem_count;
05443 u_long dirty = 0;
05444
05445 #ifdef CONFIG_RSBAC_DEBUG
05446 if(rsbac_debug_lists)
05447 {
05448 rsbac_printk(KERN_DEBUG "rsbac_check_lists() called.\n");
05449 }
05450 #endif
05451 if(!list_initialized)
05452 return -RSBAC_ENOTINITIALIZED;
05453 rsbac_read_lock(®_head.lock, &rlock_flags);
05454 list = reg_head.head;
05455 while(list)
05456 {
05457
05458 rsbac_write_lock(&list->lock, &lock_flags);
05459 tmp_count = 0;
05460 item_p = list->head;
05461 while(item_p)
05462 {
05463 if( ( item_p->max_age
05464 && (item_p->max_age <= RSBAC_CURRENT_TIME)
05465 )
05466 || ( list->def_data
05467 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05468 list->def_data,
05469 list->info.data_size)
05470 )
05471 )
05472 {
05473 next_item_p = item_p->next;
05474 do_remove_item(list, item_p);
05475 item_p = next_item_p;
05476 }
05477 else
05478 {
05479 tmp_count++;
05480 item_p = item_p->next;
05481 }
05482 }
05483 if(tmp_count != list->count)
05484 {
05485 if(correct)
05486 {
05487 rsbac_printk(KERN_WARNING
05488 "rsbac_check_lists(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05489 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05490 list->count = tmp_count;
05491 }
05492 else
05493 {
05494 rsbac_printk(KERN_WARNING
05495 "rsbac_check_lists(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05496 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05497 }
05498 }
05499 rsbac_write_unlock(&list->lock, &lock_flags);
05500 if(list->dirty && (list->flags & RSBAC_LIST_PERSIST))
05501 {
05502 dirty++;
05503 #ifdef CONFIG_RSBAC_DEBUG
05504 if(rsbac_debug_lists)
05505 {
05506 rsbac_printk(KERN_DEBUG
05507 "rsbac_check_lists(): %s on %02u:%02u has %u items (list is dirty)\n",
05508 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05509 }
05510 #endif
05511 }
05512 #ifdef CONFIG_RSBAC_DEBUG
05513 else
05514 {
05515 if(rsbac_debug_lists)
05516 {
05517 rsbac_printk(KERN_DEBUG
05518 "rsbac_check_lists(): %s on %02u:%02u has %u items\n",
05519 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05520 }
05521 }
05522 #endif
05523 list = list->next;
05524 }
05525 rsbac_read_unlock(®_head.lock, &rlock_flags);
05526
05527 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05528 lol_list = lol_reg_head.head;
05529 while(lol_list)
05530 {
05531
05532 rsbac_write_lock(&lol_list->lock, &lock_flags);
05533 tmp_count = 0;
05534 subitem_count = 0;
05535 lol_item_p = lol_list->head;
05536 while(lol_item_p)
05537 {
05538 if( ( lol_item_p->max_age
05539 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05540 )
05541 || ( lol_list->def_data
05542 && !lol_item_p->count
05543 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05544 lol_list->def_data,
05545 lol_list->info.data_size)
05546 )
05547 || ( !lol_list->info.data_size
05548 && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05549 && !lol_item_p->count
05550 )
05551 )
05552 {
05553 next_lol_item_p = lol_item_p->next;
05554 do_remove_lol_item(lol_list, lol_item_p);
05555 lol_item_p = next_lol_item_p;
05556 }
05557 else
05558 {
05559 tmp_count++;
05560 tmp_subcount = 0;
05561 lol_subitem_p = lol_item_p->head;
05562 while(lol_subitem_p)
05563 {
05564 if( ( lol_subitem_p->max_age
05565 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05566 )
05567 || ( lol_list->def_subdata
05568 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05569 lol_list->def_subdata,
05570 lol_list->info.subdata_size)
05571 )
05572 )
05573 {
05574 next_lol_subitem_p = lol_subitem_p->next;
05575 do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05576 lol_subitem_p = next_lol_subitem_p;
05577 }
05578 else
05579 {
05580 tmp_subcount++;
05581 lol_subitem_p = lol_subitem_p->next;
05582 }
05583 }
05584 if(tmp_subcount != lol_item_p->count)
05585 {
05586 if(correct)
05587 {
05588 rsbac_printk(KERN_WARNING
05589 "rsbac_check_lists(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05590 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05591 lol_item_p->count = tmp_subcount;
05592 }
05593 else
05594 {
05595 rsbac_printk(KERN_WARNING
05596 "rsbac_check_lists(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05597 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05598 }
05599 }
05600 subitem_count += lol_item_p->count;
05601 lol_item_p = lol_item_p->next;
05602 }
05603 }
05604 if(tmp_count != lol_list->count)
05605 {
05606 if(correct)
05607 {
05608 rsbac_printk(KERN_WARNING
05609 "rsbac_check_lists(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05610 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05611 lol_list->count = tmp_count;
05612 }
05613 else
05614 {
05615 rsbac_printk(KERN_WARNING
05616 "rsbac_check_lists(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05617 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05618 }
05619 }
05620 rsbac_write_unlock(&lol_list->lock, &lock_flags);
05621 if(lol_list->dirty && (lol_list->flags & RSBAC_LIST_PERSIST))
05622 {
05623 dirty++;
05624 #ifdef CONFIG_RSBAC_DEBUG
05625 if(rsbac_debug_lists)
05626 {
05627 rsbac_printk(KERN_DEBUG
05628 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems (list is dirty)\n",
05629 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05630 }
05631 #endif
05632 }
05633 #ifdef CONFIG_RSBAC_DEBUG
05634 else
05635 {
05636 if(rsbac_debug_lists)
05637 {
05638 rsbac_printk(KERN_DEBUG
05639 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems\n",
05640 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05641 }
05642 }
05643 #endif
05644 lol_list = lol_list->next;
05645 }
05646 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05647 return 0;
05648 }
05649
05650 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05651 EXPORT_SYMBOL(rsbac_list_check);
05652 #endif
05653 int rsbac_list_check(
05654 rsbac_list_handle_t handle,
05655 int correct)
05656 {
05657 struct rsbac_list_reg_item_t * list;
05658 struct rsbac_list_item_t * item_p;
05659 struct rsbac_list_item_t * next_item_p;
05660 u_long lock_flags;
05661 u_long rlock_flags;
05662 u_long tmp_count;
05663
05664 if(!handle)
05665 return -RSBAC_EINVALIDVALUE;
05666 if(!list_initialized)
05667 return -RSBAC_ENOTINITIALIZED;
05668
05669 list = (struct rsbac_list_reg_item_t *) handle;
05670 if(!list || (list->self != list))
05671 return -RSBAC_EINVALIDVALUE;
05672
05673 rsbac_read_lock(®_head.lock, &rlock_flags);
05674 #ifdef CONFIG_RSBAC_DEBUG
05675 if(rsbac_debug_lists)
05676 rsbac_printk(KERN_DEBUG "rsbac_list_check: checking list %s.\n",
05677 list->name);
05678 #endif
05679 rsbac_write_lock(&list->lock, &lock_flags);
05680 tmp_count = 0;
05681 item_p = list->head;
05682 while(item_p)
05683 {
05684 if( ( item_p->max_age
05685 && (item_p->max_age <= RSBAC_CURRENT_TIME)
05686 )
05687 || ( list->def_data
05688 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05689 list->def_data,
05690 list->info.data_size)
05691 )
05692 )
05693 {
05694 next_item_p = item_p->next;
05695 do_remove_item(list, item_p);
05696 item_p = next_item_p;
05697 list->dirty = TRUE;
05698 }
05699 else
05700 {
05701 tmp_count++;
05702 item_p = item_p->next;
05703 }
05704 }
05705 if(tmp_count != list->count)
05706 {
05707 if(correct)
05708 {
05709 rsbac_printk(KERN_WARNING
05710 "rsbac_list_check(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05711 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05712 list->count = tmp_count;
05713 list->dirty = TRUE;
05714 }
05715 else
05716 {
05717 rsbac_printk(KERN_WARNING
05718 "rsbac_list_check(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05719 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05720 }
05721 }
05722 rsbac_write_unlock(&list->lock, &lock_flags);
05723 rsbac_read_unlock(®_head.lock, &rlock_flags);
05724 return 0;
05725 }
05726
05727 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05728 EXPORT_SYMBOL(rsbac_list_lol_check);
05729 #endif
05730 int rsbac_list_lol_check(
05731 rsbac_list_handle_t handle,
05732 int correct)
05733 {
05734 struct rsbac_list_lol_reg_item_t * lol_list;
05735 struct rsbac_list_lol_item_t * lol_item_p;
05736 struct rsbac_list_lol_item_t * next_lol_item_p;
05737 struct rsbac_list_item_t * lol_subitem_p;
05738 struct rsbac_list_item_t * next_lol_subitem_p;
05739 u_long lock_flags;
05740 u_long rlock_flags;
05741 u_long tmp_count;
05742 u_long tmp_subcount;
05743
05744 if(!handle)
05745 return -RSBAC_EINVALIDVALUE;
05746 if(!list_initialized)
05747 return -RSBAC_ENOTINITIALIZED;
05748
05749 lol_list = (struct rsbac_list_lol_reg_item_t *) handle;
05750 if(!lol_list || (lol_list->self != lol_list))
05751 return -RSBAC_EINVALIDVALUE;
05752
05753 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05754 #ifdef CONFIG_RSBAC_DEBUG
05755 if(rsbac_debug_lists)
05756 rsbac_printk(KERN_DEBUG "rsbac_list_lol_check: checking list %s.\n",
05757 lol_list->name);
05758 #endif
05759 rsbac_write_lock(&lol_list->lock, &lock_flags);
05760 tmp_count = 0;
05761 lol_item_p = lol_list->head;
05762 while(lol_item_p)
05763 {
05764 if( ( lol_item_p->max_age
05765 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05766 )
05767 || ( lol_list->def_data
05768 && !lol_item_p->count
05769 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05770 lol_list->def_data,
05771 lol_list->info.data_size)
05772 )
05773 || ( !lol_list->info.data_size
05774 && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05775 && !lol_item_p->count
05776 )
05777 )
05778 {
05779 next_lol_item_p = lol_item_p->next;
05780 do_remove_lol_item(lol_list, lol_item_p);
05781 lol_item_p = next_lol_item_p;
05782 }
05783 else
05784 {
05785 tmp_count++;
05786 tmp_subcount = 0;
05787 lol_subitem_p = lol_item_p->head;
05788 while(lol_subitem_p)
05789 {
05790 if( ( lol_subitem_p->max_age
05791 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05792 )
05793 || ( lol_list->def_subdata
05794 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05795 lol_list->def_subdata,
05796 lol_list->info.subdata_size)
05797 )
05798 )
05799 {
05800 next_lol_subitem_p = lol_subitem_p->next;
05801 do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05802 lol_subitem_p = next_lol_subitem_p;
05803 }
05804 else
05805 {
05806 tmp_subcount++;
05807 lol_subitem_p = lol_subitem_p->next;
05808 }
05809 }
05810 if(tmp_subcount != lol_item_p->count)
05811 {
05812 if(correct)
05813 {
05814 rsbac_printk(KERN_WARNING
05815 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05816 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05817 lol_item_p->count = tmp_subcount;
05818 }
05819 else
05820 {
05821 rsbac_printk(KERN_WARNING
05822 "rsbac_list_lol_check(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05823 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05824 }
05825 }
05826 lol_item_p = lol_item_p->next;
05827 }
05828 }
05829 if(tmp_count != lol_list->count)
05830 {
05831 if(correct)
05832 {
05833 rsbac_printk(KERN_WARNING
05834 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05835 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05836 lol_list->count = tmp_count;
05837 }
05838 else
05839 {
05840 rsbac_printk(KERN_WARNING
05841 "rsbac_list_lol_check(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05842 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05843 }
05844 }
05845 rsbac_write_unlock(&lol_list->lock, &lock_flags);
05846 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05847 return 0;
05848 }
05849
05850
05851
05852
05853
05854
05855
05856 rsbac_version_t rsbac_list_version(void)
05857 {
05858 return RSBAC_LIST_VERSION;
05859 }
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884
05885 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05886 EXPORT_SYMBOL(rsbac_list_register);
05887 #endif
05888 int rsbac_list_register(
05889 rsbac_version_t ds_version,
05890 rsbac_list_handle_t *handle_p,
05891 struct rsbac_list_info_t * info_p,
05892 u_int flags,
05893 rsbac_list_compare_function_t * compare,
05894 rsbac_list_get_conv_t * get_conv,
05895 void * def_data,
05896 char * name,
05897 kdev_t device)
05898 {
05899 struct rsbac_list_reg_item_t * reg_item_p;
05900 struct rsbac_list_reg_item_t * new_reg_item_p;
05901 u_long lock_flags;
05902 int err = 0;
05903
05904 if(ds_version != RSBAC_LIST_VERSION)
05905 {
05906 if(name)
05907 {
05908 rsbac_printk(KERN_WARNING
05909 "rsbac_list_register: wrong ds_version %u for list %s, expected %u!\n",
05910 ds_version,
05911 name,
05912 RSBAC_LIST_VERSION);
05913 }
05914 return -RSBAC_EINVALIDVERSION;
05915 }
05916 if(!handle_p || !info_p)
05917 return -RSBAC_EINVALIDPOINTER;
05918 *handle_p = NULL;
05919 if(!info_p->key || !info_p->version || !info_p->desc_size)
05920 return -RSBAC_EINVALIDVALUE;
05921 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
05922 return -RSBAC_EINVALIDVALUE;
05923 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
05924 return -RSBAC_EINVALIDVALUE;
05925 if(!list_initialized)
05926 return -RSBAC_ENOTINITIALIZED;
05927 if(name)
05928 {
05929 struct rsbac_list_lol_reg_item_t * lol_reg_item_p;
05930
05931 rsbac_read_lock(®_head.lock, &lock_flags);
05932 reg_item_p = lookup_reg_name(name, device);
05933 rsbac_read_unlock(®_head.lock, &lock_flags);
05934 if(reg_item_p)
05935 {
05936 #ifdef CONFIG_RSBAC_DEBUG
05937 if(rsbac_debug_lists)
05938 {
05939 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05940 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05941 }
05942 #endif
05943 return -RSBAC_EEXISTS;
05944 }
05945 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05946 lol_reg_item_p = lookup_lol_reg_name(name, device);
05947 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05948 if(lol_reg_item_p)
05949 {
05950 #ifdef CONFIG_RSBAC_DEBUG
05951 if(rsbac_debug_lists)
05952 {
05953 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05954 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05955 }
05956 #endif
05957 return -RSBAC_EEXISTS;
05958 }
05959 }
05960 else
05961 if(flags & RSBAC_LIST_PERSIST)
05962 {
05963 rsbac_printk(KERN_WARNING
05964 "rsbac_list_register: trial to register persistent list without name.\n");
05965 return -RSBAC_EINVALIDVALUE;
05966 }
05967
05968 if(flags & RSBAC_LIST_PERSIST)
05969 {
05970 if(RSBAC_IS_AUTO_DEV(device))
05971 device = rsbac_root_dev;
05972 if(!RSBAC_MAJOR(device))
05973 flags &= ~RSBAC_LIST_PERSIST;
05974 }
05975
05976 #ifdef CONFIG_RSBAC_DEBUG
05977 if(rsbac_debug_lists)
05978 {
05979 rsbac_printk(KERN_DEBUG "rsbac_list_register: registering list %s for device %02u:%02u.\n",
05980 name, RSBAC_MAJOR(device),RSBAC_MINOR(device));
05981 }
05982 #endif
05983 new_reg_item_p = create_reg(info_p, flags, compare, get_conv, def_data, name, device);
05984 if(!new_reg_item_p)
05985 {
05986 return -RSBAC_ECOULDNOTADDITEM;
05987 }
05988
05989 if( (flags & RSBAC_LIST_PERSIST)
05990 && RSBAC_MAJOR(device)
05991 )
05992 {
05993 #ifdef CONFIG_RSBAC_DEBUG
05994 if(rsbac_debug_lists)
05995 {
05996 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u.\n",
05997 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05998 }
05999 #endif
06000 err = read_list(new_reg_item_p);
06001
06002 if(err == -RSBAC_ENOTFOUND)
06003 err = 0;
06004 else
06005 if(err)
06006 {
06007 #ifdef CONFIG_RSBAC_DEBUG
06008 if(rsbac_debug_lists)
06009 {
06010 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06011
06012 if(tmp)
06013 {
06014 get_error_name(tmp, err);
06015 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06016 name,
06017 RSBAC_MAJOR(device),RSBAC_MINOR(device),
06018 tmp);
06019 rsbac_kfree(tmp);
06020 }
06021 }
06022 #endif
06023 clear_reg(new_reg_item_p);
06024 return err;
06025 }
06026 #ifdef CONFIG_RSBAC_DEBUG
06027 else
06028 {
06029 if(rsbac_debug_lists)
06030 {
06031 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u was successful.\n",
06032 name,
06033 RSBAC_MAJOR(device),RSBAC_MINOR(device));
06034 }
06035 }
06036 #endif
06037 }
06038
06039 rsbac_write_lock(®_head.lock, &lock_flags);
06040 reg_item_p = add_reg(new_reg_item_p);
06041 rsbac_write_unlock(®_head.lock, &lock_flags);
06042 if(!reg_item_p)
06043 {
06044 rsbac_printk(KERN_WARNING
06045 "rsbac_list_register: inserting list %s failed!\n",
06046 name);
06047
06048 clear_reg(new_reg_item_p);
06049 return -RSBAC_ECOULDNOTADDITEM;
06050 }
06051
06052
06053 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06054
06055 if(flags & RSBAC_LIST_BACKUP)
06056 {
06057 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06058 S_IFREG | S_IRUGO,
06059 proc_rsbac_backup_p);
06060 if(reg_item_p->proc_entry_p)
06061 {
06062 reg_item_p->proc_entry_p->read_proc = backup_proc_read;
06063 reg_item_p->proc_entry_p->data = reg_item_p;
06064 }
06065 }
06066 else
06067 {
06068 reg_item_p->proc_entry_p = NULL;
06069 }
06070 #endif
06071 *handle_p = reg_item_p;
06072 return err;
06073 }
06074
06075
06076
06077
06078
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106
06107 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06108 EXPORT_SYMBOL(rsbac_list_lol_register);
06109 #endif
06110 int rsbac_list_lol_register(
06111 rsbac_version_t ds_version,
06112 rsbac_list_handle_t *handle_p,
06113 struct rsbac_list_lol_info_t * info_p,
06114 u_int flags,
06115 rsbac_list_compare_function_t * compare,
06116 rsbac_list_compare_function_t * subcompare,
06117 rsbac_list_get_conv_t * get_conv,
06118 rsbac_list_get_conv_t * get_subconv,
06119 void * def_data,
06120 void * def_subdata,
06121 char * name,
06122 kdev_t device)
06123 {
06124 struct rsbac_list_lol_reg_item_t * reg_item_p;
06125 struct rsbac_list_lol_reg_item_t * new_reg_item_p;
06126 u_long lock_flags;
06127 int err = 0;
06128
06129 if(ds_version != RSBAC_LIST_VERSION)
06130 return -RSBAC_EINVALIDVERSION;
06131 if(!handle_p)
06132 return -RSBAC_EINVALIDPOINTER;
06133 *handle_p = NULL;
06134 if(!info_p->key || !info_p->version || !info_p->desc_size)
06135 return -RSBAC_EINVALIDVALUE;
06136 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
06137 return -RSBAC_EINVALIDVALUE;
06138 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
06139 return -RSBAC_EINVALIDVALUE;
06140 if(info_p->subdesc_size + info_p->subdata_size > RSBAC_LIST_MAX_ITEM_SIZE)
06141 return -RSBAC_EINVALIDVALUE;
06142 if(!list_initialized)
06143 return -RSBAC_ENOTINITIALIZED;
06144 if(name)
06145 {
06146 struct rsbac_list_reg_item_t * std_reg_item_p;
06147
06148 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06149 reg_item_p = lookup_lol_reg_name(name, device);
06150 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06151 if(reg_item_p)
06152 {
06153 #ifdef CONFIG_RSBAC_DEBUG
06154 if(rsbac_debug_lists)
06155 {
06156 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: list name %s already exists on device %02u:%02u!\n",
06157 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06158 }
06159 #endif
06160 return -RSBAC_EEXISTS;
06161 }
06162 rsbac_read_lock(®_head.lock, &lock_flags);
06163 std_reg_item_p = lookup_reg_name(name, device);
06164 rsbac_read_unlock(®_head.lock, &lock_flags);
06165 if(std_reg_item_p)
06166 {
06167 #ifdef CONFIG_RSBAC_DEBUG
06168 if(rsbac_debug_lists)
06169 {
06170 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
06171 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06172 }
06173 #endif
06174 return -RSBAC_EEXISTS;
06175 }
06176 }
06177 else
06178 if(flags & RSBAC_LIST_PERSIST)
06179 {
06180 rsbac_printk(KERN_WARNING
06181 "rsbac_list_lol_register: trial to register persistent list of lists without name.\n");
06182 return -RSBAC_EINVALIDVALUE;
06183 }
06184
06185 if(flags & RSBAC_LIST_PERSIST)
06186 {
06187 if(RSBAC_IS_AUTO_DEV(device))
06188 device = rsbac_root_dev;
06189 if(!RSBAC_MAJOR(device))
06190 flags &= ~RSBAC_LIST_PERSIST;
06191 }
06192
06193 #ifdef CONFIG_RSBAC_DEBUG
06194 if(rsbac_debug_lists)
06195 {
06196 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: registering list of lists %s.\n",
06197 name);
06198 }
06199 #endif
06200 new_reg_item_p = create_lol_reg(info_p, flags, compare, subcompare,
06201 get_conv, get_subconv,
06202 def_data, def_subdata,
06203 name, device);
06204 if(!new_reg_item_p)
06205 {
06206 return -RSBAC_ECOULDNOTADDITEM;
06207 }
06208
06209 if(flags & RSBAC_LIST_PERSIST)
06210 {
06211 #ifdef CONFIG_RSBAC_DEBUG
06212 if(rsbac_debug_lists)
06213 {
06214 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u.\n",
06215 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06216 }
06217 #endif
06218 err = read_lol_list(new_reg_item_p);
06219
06220 if(err == -RSBAC_ENOTFOUND)
06221 err = 0;
06222 else
06223 if(err)
06224 {
06225 #ifdef CONFIG_RSBAC_DEBUG
06226 if(rsbac_debug_lists)
06227 {
06228 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06229
06230 if(tmp)
06231 {
06232 get_error_name(tmp, err);
06233 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06234 name,
06235 RSBAC_MAJOR(device),RSBAC_MINOR(device),
06236 tmp);
06237 rsbac_kfree(tmp);
06238 }
06239 }
06240 #endif
06241 clear_lol_reg(new_reg_item_p);
06242 return err;
06243 }
06244 #ifdef CONFIG_RSBAC_DEBUG
06245 else
06246 {
06247 if(rsbac_debug_lists)
06248 {
06249 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u was successful.\n",
06250 name,
06251 RSBAC_MAJOR(device),RSBAC_MINOR(device));
06252 }
06253 }
06254 #endif
06255 }
06256
06257 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06258 reg_item_p = add_lol_reg(new_reg_item_p);
06259 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06260 if(!reg_item_p)
06261 {
06262 rsbac_printk(KERN_WARNING
06263 "rsbac_list_lol_register: inserting list %s failed!\n",
06264 name);
06265
06266 clear_lol_reg(new_reg_item_p);
06267 return -RSBAC_ECOULDNOTADDITEM;
06268 }
06269
06270
06271 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06272
06273 if(flags & RSBAC_LIST_BACKUP)
06274 {
06275 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06276 S_IFREG | S_IRUGO,
06277 proc_rsbac_backup_p);
06278 if(reg_item_p->proc_entry_p)
06279 {
06280 reg_item_p->proc_entry_p->read_proc = lol_backup_proc_read;
06281 reg_item_p->proc_entry_p->data = reg_item_p;
06282 }
06283 }
06284 else
06285 {
06286 reg_item_p->proc_entry_p = NULL;
06287 }
06288 #endif
06289 *handle_p = reg_item_p;
06290 return err;
06291 }
06292
06293
06294
06295
06296 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06297 EXPORT_SYMBOL(rsbac_list_destroy);
06298 #endif
06299 int rsbac_list_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06300 {
06301 struct rsbac_list_reg_item_t * reg_item_p;
06302 u_long lock_flags;
06303 int err = 0;
06304
06305 if(!handle_p)
06306 return -RSBAC_EINVALIDPOINTER;
06307 if(!*handle_p)
06308 return -RSBAC_EINVALIDVALUE;
06309 if(!list_initialized)
06310 return -RSBAC_ENOTINITIALIZED;
06311
06312 rsbac_write_lock(®_head.lock, &lock_flags);
06313 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06314 if(!reg_item_p)
06315 {
06316 rsbac_write_unlock(®_head.lock, &lock_flags);
06317 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list failed due to invalid handle!\n");
06318 return -RSBAC_EINVALIDVALUE;
06319 }
06320 if(reg_item_p->info.key != key)
06321 {
06322 rsbac_write_unlock(®_head.lock, &lock_flags);
06323 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list %s denied due to invalid key!\n",
06324 reg_item_p->name);
06325 return -EPERM;
06326 }
06327 #ifdef CONFIG_RSBAC_DEBUG
06328 if(rsbac_debug_lists)
06329 {
06330 rsbac_printk(KERN_DEBUG "rsbac_list_destroy: destroying list %s.\n",
06331 reg_item_p->name);
06332 }
06333 #endif
06334 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06335
06336 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06337 && reg_item_p->proc_entry_p
06338 )
06339 {
06340 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06341 reg_item_p->proc_entry_p = NULL;
06342 }
06343 #endif
06344
06345 #if 0
06346 if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06347 err = unlink_list(reg_item_p);
06348 #endif
06349
06350 remove_reg(reg_item_p);
06351 *handle_p = NULL;
06352 rsbac_write_unlock(®_head.lock, &lock_flags);
06353 return err;
06354 }
06355
06356 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06357 EXPORT_SYMBOL(rsbac_list_lol_destroy);
06358 #endif
06359 int rsbac_list_lol_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06360 {
06361 struct rsbac_list_lol_reg_item_t * reg_item_p;
06362 u_long lock_flags;
06363 int err = 0;
06364
06365 if(!handle_p)
06366 return -RSBAC_EINVALIDPOINTER;
06367 if(!*handle_p)
06368 return -RSBAC_EINVALIDVALUE;
06369 if(!list_initialized)
06370 return -RSBAC_ENOTINITIALIZED;
06371
06372 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06373 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06374 if(!reg_item_p)
06375 {
06376 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06377 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list failed due to invalid handle!\n");
06378 return -RSBAC_EINVALIDVALUE;
06379 }
06380 if(reg_item_p->info.key != key)
06381 {
06382 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06383 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list %s denied due to invalid key %u!\n",
06384 reg_item_p->name,
06385 key);
06386 return -EPERM;
06387 }
06388 #ifdef CONFIG_RSBAC_DEBUG
06389 if(rsbac_debug_lists)
06390 {
06391 rsbac_printk(KERN_DEBUG "rsbac_list_lol_destroy: destroying list %s.\n",
06392 reg_item_p->name);
06393 }
06394 #endif
06395 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06396
06397 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06398 && reg_item_p->proc_entry_p
06399 )
06400 {
06401 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06402 reg_item_p->proc_entry_p = NULL;
06403 }
06404 #endif
06405 #if 0
06406 if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06407 err = unlink_lol_list(reg_item_p);
06408 #endif
06409
06410 remove_lol_reg(reg_item_p);
06411 *handle_p = NULL;
06412 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06413 return err;
06414 }
06415
06416
06417
06418 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06419 EXPORT_SYMBOL(rsbac_list_detach);
06420 #endif
06421 int rsbac_list_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06422 {
06423 struct rsbac_list_reg_item_t * reg_item_p;
06424 u_long lock_flags;
06425 int err = 0;
06426
06427 if(!handle_p)
06428 return -RSBAC_EINVALIDPOINTER;
06429 if(!*handle_p)
06430 return -RSBAC_EINVALIDVALUE;
06431 if(!list_initialized)
06432 return -RSBAC_ENOTINITIALIZED;
06433
06434 rsbac_read_lock(®_head.lock, &lock_flags);
06435 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06436 if(!reg_item_p)
06437 {
06438 rsbac_read_unlock(®_head.lock, &lock_flags);
06439 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list failed due to invalid handle!\n");
06440 return -RSBAC_EINVALIDVALUE;
06441 }
06442 if(reg_item_p->info.key != key)
06443 {
06444 rsbac_read_unlock(®_head.lock, &lock_flags);
06445 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list %s denied due to invalid key %u!\n",
06446 reg_item_p->name,
06447 key);
06448 return -EPERM;
06449 }
06450 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06451
06452 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06453 && reg_item_p->proc_entry_p
06454 )
06455 {
06456 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06457 reg_item_p->proc_entry_p = NULL;
06458 }
06459 #endif
06460 #ifndef CONFIG_RSBAC_NO_WRITE
06461
06462 if( (reg_item_p->flags & RSBAC_LIST_PERSIST)
06463 && reg_item_p->dirty
06464 && !reg_item_p->no_write
06465 )
06466 {
06467 struct rsbac_list_write_head_t write_head;
06468 struct rsbac_list_write_item_t * write_item_p;
06469
06470 reg_item_p->dirty = FALSE;
06471 err = fill_buffer(reg_item_p, &write_item_p);
06472 if(!err)
06473 {
06474 write_head.head = write_item_p;
06475 write_head.tail = write_item_p;
06476 write_head.total = write_item_p->buflen;
06477 write_head.count = 1;
06478 rsbac_read_unlock(®_head.lock, &lock_flags);
06479 rsbac_list_write_buffers(write_head, TRUE);
06480 }
06481 else
06482 {
06483 rsbac_read_unlock(®_head.lock, &lock_flags);
06484 if(err != -RSBAC_ENOTWRITABLE)
06485 {
06486 rsbac_printk(KERN_WARNING
06487 "rsbac_list_detach(): fill_buffer() for list %s returned error %i\n",
06488 reg_item_p->name, err);
06489 }
06490 }
06491 }
06492 else
06493 rsbac_read_unlock(®_head.lock, &lock_flags);
06494 #else
06495 rsbac_read_unlock(®_head.lock, &lock_flags);
06496 #endif
06497
06498 *handle_p = NULL;
06499
06500 rsbac_write_lock(®_head.lock, &lock_flags);
06501 remove_reg(reg_item_p);
06502 rsbac_write_unlock(®_head.lock, &lock_flags);
06503 return err;
06504 }
06505
06506 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06507 EXPORT_SYMBOL(rsbac_list_lol_detach);
06508 #endif
06509 int rsbac_list_lol_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06510 {
06511 struct rsbac_list_lol_reg_item_t * reg_item_p;
06512 u_long lock_flags;
06513 int err = 0;
06514
06515 if(!handle_p)
06516 return -RSBAC_EINVALIDPOINTER;
06517 if(!*handle_p)
06518 return -RSBAC_EINVALIDVALUE;
06519 if(!list_initialized)
06520 return -RSBAC_ENOTINITIALIZED;
06521
06522 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06523 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06524 if(!reg_item_p)
06525 {
06526 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06527 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list failed due to invalid handle!\n");
06528 return -RSBAC_EINVALIDVALUE;
06529 }
06530 if(reg_item_p->info.key != key)
06531 {
06532 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06533 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list %s denied due to invalid key %u!\n",
06534 reg_item_p->name,
06535 key);
06536 return -EPERM;
06537 }
06538 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06539
06540 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06541 && reg_item_p->proc_entry_p
06542 )
06543 {
06544 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06545 reg_item_p->proc_entry_p = NULL;
06546 }
06547 #endif
06548 #ifndef CONFIG_RSBAC_NO_WRITE
06549
06550 if( (reg_item_p->flags & RSBAC_LIST_PERSIST)
06551 && reg_item_p->dirty
06552 && !reg_item_p->no_write
06553 )
06554 {
06555 struct rsbac_list_lol_write_head_t write_head;
06556 struct rsbac_list_lol_write_item_t * write_item_p;
06557
06558 reg_item_p->dirty = FALSE;
06559 err = fill_lol_buffer(reg_item_p, &write_item_p);
06560 if(!err)
06561 {
06562 write_head.head = write_item_p;
06563 write_head.tail = write_item_p;
06564 write_head.total = write_item_p->buflen;
06565 write_head.count = 1;
06566 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06567 rsbac_list_write_lol_buffers(write_head, TRUE);
06568 }
06569 else
06570 {
06571 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06572 if(err != -RSBAC_ENOTWRITABLE)
06573 {
06574 rsbac_printk(KERN_WARNING
06575 "rsbac_list_lol_detach(): fill_buffer() for list %s returned error %i\n",
06576 reg_item_p->name, err);
06577 }
06578 }
06579 }
06580 else
06581 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06582 #else
06583 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06584 #endif
06585
06586 *handle_p = NULL;
06587
06588 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06589 remove_lol_reg(reg_item_p);
06590 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06591 return err;
06592 }
06593
06594
06595
06596 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06597 EXPORT_SYMBOL(rsbac_list_no_write);
06598 #endif
06599 int rsbac_list_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06600 {
06601 struct rsbac_list_reg_item_t * reg_item_p;
06602 u_long lock_flags;
06603
06604 if( !handle
06605 || ( (no_write != FALSE )
06606 && (no_write != TRUE )
06607 )
06608 )
06609 return -RSBAC_EINVALIDVALUE;
06610 if(!list_initialized)
06611 return -RSBAC_ENOTINITIALIZED;
06612
06613 rsbac_read_lock(®_head.lock, &lock_flags);
06614 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) handle);
06615 if(!reg_item_p)
06616 {
06617 rsbac_read_unlock(®_head.lock, &lock_flags);
06618 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list denied due to invalid handle!\n");
06619 return -RSBAC_EINVALIDVALUE;
06620 }
06621 if(reg_item_p->info.key != key)
06622 {
06623 rsbac_read_unlock(®_head.lock, &lock_flags);
06624 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06625 reg_item_p->name,
06626 key);
06627 return -EPERM;
06628 }
06629 reg_item_p->no_write = no_write;
06630 rsbac_read_unlock(®_head.lock, &lock_flags);
06631 return 0;
06632 }
06633
06634 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06635 EXPORT_SYMBOL(rsbac_list_lol_no_write);
06636 #endif
06637 int rsbac_list_lol_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06638 {
06639 struct rsbac_list_lol_reg_item_t * reg_item_p;
06640 u_long lock_flags;
06641
06642 if( !handle
06643 || ( (no_write != FALSE )
06644 && (no_write != TRUE )
06645 )
06646 )
06647 return -RSBAC_EINVALIDVALUE;
06648 if(!list_initialized)
06649 return -RSBAC_ENOTINITIALIZED;
06650
06651 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06652 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) handle);
06653 if(!reg_item_p)
06654 {
06655 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06656 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list denied due to invalid handle!\n");
06657 return -RSBAC_EINVALIDVALUE;
06658 }
06659 if(reg_item_p->info.key != key)
06660 {
06661 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06662 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06663 reg_item_p->name,
06664 key);
06665 return -EPERM;
06666 }
06667 reg_item_p->no_write = no_write;
06668 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06669 return 0;
06670 }
06671
06672
06673
06674
06675
06676
06677 #ifdef CONFIG_RSBAC_LIST_TRANS
06678 static int do_commit(rsbac_list_ta_number_t ta_number)
06679 {
06680
06681
06682
06683
06684
06685
06686
06687
06688
06689
06690 struct rsbac_list_reg_item_t * list;
06691 struct rsbac_list_lol_reg_item_t * lol_list;
06692 u_long lock_flags;
06693 u_long lol_lock_flags;
06694
06695 rsbac_write_lock(®_head.lock, &lock_flags);
06696 rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06697 list = reg_head.head;
06698 while(list)
06699 {
06700 if(list->ta_copied == ta_number)
06701 {
06702 remove_all_items(list);
06703 list->head = list->ta_head;
06704 list->tail = list->ta_tail;
06705 list->curr = list->ta_curr;
06706 list->count = list->ta_count;
06707 list->ta_head = NULL;
06708 list->ta_tail = NULL;
06709 list->ta_curr = NULL;
06710 list->ta_count = 0;
06711 list->ta_copied = 0;
06712 list->dirty = TRUE;
06713 }
06714 list = list->next;
06715 }
06716 lol_list = lol_reg_head.head;
06717 while(lol_list)
06718 {
06719 if(lol_list->ta_copied == ta_number)
06720 {
06721 remove_all_lol_items(lol_list);
06722 lol_list->head = lol_list->ta_head;
06723 lol_list->tail = lol_list->ta_tail;
06724 lol_list->curr = lol_list->ta_curr;
06725 lol_list->count = lol_list->ta_count;
06726 lol_list->ta_head = NULL;
06727 lol_list->ta_tail = NULL;
06728 lol_list->ta_curr = NULL;
06729 lol_list->ta_count = 0;
06730 lol_list->ta_copied = 0;
06731 lol_list->dirty = TRUE;
06732 }
06733 lol_list = lol_list->next;
06734 }
06735 rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06736 rsbac_write_unlock(®_head.lock, &lock_flags);
06737
06738 return 0;
06739 }
06740
06741 int rsbac_list_ta_commit(rsbac_list_ta_number_t ta_number,
06742 char * password)
06743 {
06744 int err;
06745 struct rsbac_list_ta_data_t ta_data;
06746
06747 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06748 if(err)
06749 return err;
06750 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06751 && (ta_data.commit_uid != current->uid)
06752 )
06753 return -EPERM;
06754
06755 if(ta_data.password[0])
06756 {
06757 if(!password)
06758 return -EPERM;
06759 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06760 return -EPERM;
06761 }
06762 spin_lock(&ta_lock);
06763 if(ta_committing || ta_forgetting)
06764 {
06765 spin_unlock(&ta_lock);
06766 return -RSBAC_EBUSY;
06767 }
06768 ta_committing = TRUE;
06769 spin_unlock(&ta_lock);
06770
06771 rsbac_printk(KERN_INFO "rsbac_list_ta_commit(): committing transaction %u\n",
06772 ta_number);
06773
06774 err = do_commit(ta_number);
06775 if(!err)
06776 rsbac_list_remove(ta_handle, &ta_number);
06777 ta_committing = FALSE;
06778 return err;
06779 }
06780
06781 static int do_forget(rsbac_list_ta_number_t ta_number)
06782 {
06783 struct rsbac_list_reg_item_t * list;
06784 struct rsbac_list_lol_reg_item_t * lol_list;
06785 u_long lock_flags;
06786 u_long lol_lock_flags;
06787
06788 spin_lock(&ta_lock);
06789 if(ta_committing || ta_forgetting)
06790 {
06791 spin_unlock(&ta_lock);
06792 return -RSBAC_EBUSY;
06793 }
06794 ta_forgetting = TRUE;
06795 spin_unlock(&ta_lock);
06796
06797 rsbac_printk(KERN_INFO "rsbac_list_ta_forget(): removing transaction %u\n",
06798 ta_number);
06799
06800
06801
06802
06803
06804
06805
06806
06807
06808 rsbac_write_lock(®_head.lock, &lock_flags);
06809 rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06810 list = reg_head.head;
06811 while(list)
06812 {
06813 if(list->ta_copied == ta_number)
06814 {
06815 ta_remove_all_items(list);
06816 list->ta_copied = 0;
06817 }
06818 list = list->next;
06819 }
06820 lol_list = lol_reg_head.head;
06821 while(lol_list)
06822 {
06823 if(lol_list->ta_copied == ta_number)
06824 {
06825 ta_remove_all_lol_items(lol_list);
06826 lol_list->ta_copied = 0;
06827 }
06828 lol_list = lol_list->next;
06829 }
06830 rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06831 rsbac_write_unlock(®_head.lock, &lock_flags);
06832
06833 rsbac_list_remove(ta_handle, &ta_number);
06834 ta_forgetting = FALSE;
06835
06836 return 0;
06837 }
06838
06839 int rsbac_list_ta_forget(rsbac_list_ta_number_t ta_number,
06840 char * password)
06841 {
06842 int err;
06843 struct rsbac_list_ta_data_t ta_data;
06844
06845 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06846 if(err)
06847 return err;
06848 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06849 && (ta_data.commit_uid != current->uid)
06850 )
06851 return -EPERM;
06852 if(ta_data.password[0])
06853 {
06854 if(!password)
06855 return -EPERM;
06856 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06857 return -EPERM;
06858 }
06859 return do_forget(ta_number);
06860 }
06861
06862 int rsbac_list_ta_begin(
06863 rsbac_time_t ttl,
06864 rsbac_list_ta_number_t * ta_number_p,
06865 rsbac_uid_t commit_uid,
06866 char * password)
06867 {
06868 int err;
06869 rsbac_list_ta_number_t ta;
06870 struct rsbac_list_ta_data_t ta_data;
06871
06872 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06873 get_random_bytes(&ta, sizeof(ta));
06874 #else
06875 ta = ta_next++;
06876 #endif
06877 while(rsbac_list_exist(ta_handle, &ta))
06878 {
06879 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06880 get_random_bytes(&ta, sizeof(ta));
06881 #else
06882 ta = ta_next++;
06883 #endif
06884 }
06885 if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06886 ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06887
06888 rsbac_printk(KERN_INFO "rsbac_list_ta_begin(): starting transaction %u with ttl of %us\n",
06889 ta, ttl);
06890
06891 ta_data.start = RSBAC_CURRENT_TIME;
06892 ta_data.timeout = ta_data.start + ttl;
06893 ta_data.commit_uid = commit_uid;
06894 if(password)
06895 {
06896 strncpy(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN - 1);
06897 ta_data.password[RSBAC_LIST_TA_MAX_PASSLEN - 1] = 0;
06898 }
06899 else
06900 ta_data.password[0] = 0;
06901 err = rsbac_list_add(ta_handle, &ta, &ta_data);
06902 if(!err)
06903 *ta_number_p = ta;
06904 return err;
06905 }
06906
06907 int rsbac_list_ta_refresh(
06908 rsbac_time_t ttl,
06909 rsbac_list_ta_number_t ta_number,
06910 char * password)
06911 {
06912 struct rsbac_list_ta_data_t ta_data;
06913 int err;
06914
06915 if(!rsbac_list_exist(ta_handle, &ta_number))
06916 {
06917 return -RSBAC_ENOTFOUND;
06918 }
06919 if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06920 ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06921
06922 rsbac_printk(KERN_INFO "rsbac_list_ta_refresh(): refreshing transaction %u for %us\n",
06923 ta_number, ttl);
06924
06925 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06926 if(err)
06927 return err;
06928 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06929 && (ta_data.commit_uid != current->uid)
06930 )
06931 return -EPERM;
06932 if(ta_data.password[0])
06933 {
06934 if(!password)
06935 return -EPERM;
06936 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06937 return -EPERM;
06938 }
06939 ta_data.timeout = RSBAC_CURRENT_TIME + ttl;
06940 return rsbac_list_add(ta_handle, &ta_number, &ta_data);
06941 }
06942 #endif
06943
06944
06945
06946
06947
06948
06949
06950
06951 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06952 EXPORT_SYMBOL(rsbac_ta_list_add_ttl);
06953 #endif
06954 int rsbac_ta_list_add_ttl(
06955 rsbac_list_ta_number_t ta_number,
06956 rsbac_list_handle_t handle,
06957 rsbac_time_t ttl,
06958 void * desc,
06959 void * data)
06960 {
06961 struct rsbac_list_reg_item_t * list;
06962 struct rsbac_list_item_t * item_p;
06963 u_long lock_flags, rlock_flags;
06964
06965 if(!handle || !desc)
06966 return -RSBAC_EINVALIDVALUE;
06967 if(!list_initialized)
06968 return -RSBAC_ENOTINITIALIZED;
06969
06970 list = (struct rsbac_list_reg_item_t *) handle;
06971 if(!list || (list->self != list))
06972 return -RSBAC_EINVALIDVALUE;
06973
06974 #ifdef CONFIG_RSBAC_LIST_TRANS
06975 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
06976 return -RSBAC_EINVALIDTRANSACTION;
06977 #endif
06978
06979 rsbac_read_lock(®_head.lock, &rlock_flags);
06980 if(list->info.data_size && !data)
06981 {
06982 rsbac_read_unlock(®_head.lock, &rlock_flags);
06983 return -RSBAC_EINVALIDVALUE;
06984 }
06985
06986
06987
06988
06989
06990
06991
06992
06993 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
06994 {
06995 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
06996 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
06997 ttl += RSBAC_CURRENT_TIME;
06998 }
06999 rsbac_write_lock(&list->lock, &lock_flags);
07000
07001 #ifdef CONFIG_RSBAC_LIST_TRANS
07002 if(!ta_number)
07003 #endif
07004 {
07005 item_p = lookup_item(list, desc);
07006 if(item_p)
07007 {
07008 if(ttl != RSBAC_LIST_TTL_KEEP)
07009 item_p->max_age = ttl;
07010 if(data && list->info.data_size)
07011 {
07012 if( list->def_data
07013 && !item_p->max_age
07014 && !memcmp(list->def_data, data, list->info.data_size)
07015 )
07016 do_remove_item(list, item_p);
07017 else
07018 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07019 data, list->info.data_size);
07020 }
07021 }
07022 else
07023 {
07024 if(ttl == RSBAC_LIST_TTL_KEEP)
07025 ttl = 0;
07026 if( !list->def_data
07027 || memcmp(list->def_data, data, list->info.data_size)
07028 )
07029 add_item(list, ttl, desc, data);
07030 }
07031 touch(list);
07032 list->dirty = TRUE;
07033 }
07034 #ifdef CONFIG_RSBAC_LIST_TRANS
07035 if( list->ta_copied
07036 || ta_number
07037 )
07038 {
07039 if(!list->ta_copied)
07040 ta_copy(ta_number, list);
07041 else
07042 if(ta_number)
07043 {
07044 if(list->ta_copied != ta_number)
07045 {
07046 rsbac_write_unlock(&list->lock, &lock_flags);
07047 rsbac_read_unlock(®_head.lock, &rlock_flags);
07048 return -RSBAC_EBUSY;
07049 }
07050 }
07051 else
07052 ta_number = list->ta_copied;
07053 item_p = ta_lookup_item(ta_number, list, desc);
07054 if(item_p)
07055 {
07056 if(ttl != RSBAC_LIST_TTL_KEEP)
07057 item_p->max_age = ttl;
07058 if(data && list->info.data_size)
07059 {
07060 if( list->def_data
07061 && !item_p->max_age
07062 && !memcmp(list->def_data, data, list->info.data_size)
07063 )
07064 ta_do_remove_item(list, item_p);
07065 else
07066 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07067 data, list->info.data_size);
07068 }
07069 }
07070 else
07071 {
07072 if(ttl == RSBAC_LIST_TTL_KEEP)
07073 ttl = 0;
07074 if( !list->def_data
07075 || memcmp(list->def_data, data, list->info.data_size)
07076 )
07077 ta_add_item(ta_number, list, ttl, desc, data);
07078 }
07079 }
07080 #endif
07081 rsbac_write_unlock(&list->lock, &lock_flags);
07082 rsbac_read_unlock(®_head.lock, &rlock_flags);
07083 return 0;
07084 }
07085
07086 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07087 EXPORT_SYMBOL(rsbac_list_add_ttl);
07088 #endif
07089 int rsbac_list_add_ttl(
07090 rsbac_list_handle_t handle,
07091 rsbac_time_t ttl,
07092 void * desc,
07093 void * data)
07094 {
07095 return rsbac_ta_list_add_ttl(0, handle, ttl, desc, data);
07096 }
07097
07098 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07099 EXPORT_SYMBOL(rsbac_list_add);
07100 #endif
07101 int rsbac_list_add(
07102 rsbac_list_handle_t handle,
07103 void * desc,
07104 void * data)
07105 {
07106 return rsbac_ta_list_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07107 }
07108
07109
07110
07111 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07112 EXPORT_SYMBOL(rsbac_ta_list_lol_subadd_ttl);
07113 #endif
07114 int rsbac_ta_list_lol_subadd_ttl(
07115 rsbac_list_ta_number_t ta_number,
07116 rsbac_list_handle_t handle,
07117 rsbac_time_t ttl,
07118 void * desc,
07119 void * subdesc,
07120 void * subdata)
07121 {
07122 struct rsbac_list_lol_reg_item_t * list;
07123 struct rsbac_list_lol_item_t * sublist;
07124 struct rsbac_list_item_t * item_p;
07125 u_long lock_flags, rlock_flags;
07126 int err = 0;
07127
07128 if(!handle || !desc || !subdesc)
07129 return -RSBAC_EINVALIDVALUE;
07130 if(!list_initialized)
07131 return -RSBAC_ENOTINITIALIZED;
07132
07133 list = (struct rsbac_list_lol_reg_item_t *) handle;
07134 if(!list || (list->self != list))
07135 return -RSBAC_EINVALIDVALUE;
07136
07137 #ifdef CONFIG_RSBAC_LIST_TRANS
07138 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07139 return -RSBAC_EINVALIDTRANSACTION;
07140 #endif
07141
07142 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07143 if(list->info.subdata_size && !subdata)
07144 {
07145 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07146 return -RSBAC_EINVALIDVALUE;
07147 }
07148
07149
07150
07151
07152
07153
07154
07155
07156 rsbac_write_lock(&list->lock, &lock_flags);
07157
07158 #ifdef CONFIG_RSBAC_LIST_TRANS
07159 if(!ta_number)
07160 #endif
07161 {
07162 sublist = lookup_lol_item(list, desc);
07163 if( !sublist
07164 && (list->flags & RSBAC_LIST_DEF_DATA)
07165 )
07166 sublist = add_lol_item(list, 0, desc, list->def_data);
07167 if(sublist)
07168 {
07169 if( sublist->max_age
07170 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07171 )
07172 {
07173 remove_lol_item(list, desc);
07174 err = -RSBAC_EINVALIDTARGET;
07175 }
07176 else
07177 {
07178
07179 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07180 {
07181 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07182 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07183 ttl += RSBAC_CURRENT_TIME;
07184 }
07185 item_p = lookup_lol_subitem(list, sublist, subdesc);
07186 if(item_p)
07187 {
07188 if(ttl != RSBAC_LIST_TTL_KEEP)
07189 item_p->max_age = ttl;
07190 if(subdata && list->info.subdata_size)
07191 {
07192 if( list->def_subdata
07193 && !item_p->max_age
07194 && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07195 )
07196 do_remove_lol_subitem(sublist, item_p);
07197 else
07198 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07199 subdata,
07200 list->info.subdata_size);
07201 }
07202 }
07203 else
07204 {
07205 if(ttl == RSBAC_LIST_TTL_KEEP)
07206 ttl = 0;
07207 if( !list->def_subdata
07208 || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07209 )
07210 add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07211 }
07212 lol_touch(list);
07213 list->dirty = TRUE;
07214 }
07215 }
07216 else
07217 {
07218 err = -RSBAC_EINVALIDTARGET;
07219 goto out_unlock;
07220 }
07221 }
07222 #ifdef CONFIG_RSBAC_LIST_TRANS
07223 if(list->ta_copied || ta_number)
07224 {
07225 if(!list->ta_copied)
07226 {
07227 if((err = ta_lol_copy(ta_number,list)))
07228 goto out_unlock;
07229 }
07230 else
07231 if(ta_number)
07232 {
07233 if(list->ta_copied != ta_number)
07234 {
07235 err = -RSBAC_EBUSY;
07236 goto out_unlock;
07237 }
07238 }
07239 else
07240 ta_number = list->ta_copied;
07241 sublist = ta_lookup_lol_item(ta_number, list, desc);
07242 if( !sublist
07243 && (list->flags & RSBAC_LIST_DEF_DATA)
07244 )
07245 sublist = ta_add_lol_item(ta_number, list, 0, desc, list->def_data);
07246 if(sublist)
07247 {
07248 if( sublist->max_age
07249 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07250 )
07251 {
07252 ta_remove_lol_item(ta_number, list, desc);
07253 err = -RSBAC_EINVALIDTARGET;
07254 }
07255 else
07256 {
07257
07258 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07259 {
07260 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07261 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07262 ttl += RSBAC_CURRENT_TIME;
07263 }
07264 item_p = lookup_lol_subitem(list, sublist, subdesc);
07265 if(item_p)
07266 {
07267 if(ttl != RSBAC_LIST_TTL_KEEP)
07268 item_p->max_age = ttl;
07269 if(subdata && list->info.subdata_size)
07270 {
07271 if( list->def_subdata
07272 && !item_p->max_age
07273 && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07274 )
07275 do_remove_lol_subitem(sublist, item_p);
07276 else
07277 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07278 subdata,
07279 list->info.subdata_size);
07280 }
07281 }
07282 else
07283 {
07284 if(ttl == RSBAC_LIST_TTL_KEEP)
07285 ttl = 0;
07286 if( !list->def_subdata
07287 || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07288 )
07289 add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07290 }
07291 }
07292 }
07293 else
07294 {
07295 err = -RSBAC_EINVALIDTARGET;
07296 }
07297 }
07298 #endif
07299
07300 out_unlock:
07301 rsbac_write_unlock(&list->lock, &lock_flags);
07302 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07303 return err;
07304 }
07305
07306 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07307 EXPORT_SYMBOL(rsbac_list_lol_subadd_ttl);
07308 #endif
07309 int rsbac_list_lol_subadd_ttl(
07310 rsbac_list_handle_t handle,
07311 rsbac_time_t ttl,
07312 void * desc,
07313 void * subdesc,
07314 void * subdata)
07315 {
07316 return rsbac_ta_list_lol_subadd_ttl(0, handle, ttl, desc, subdesc, subdata);
07317 }
07318
07319 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07320 EXPORT_SYMBOL(rsbac_list_lol_subadd);
07321 #endif
07322 int rsbac_list_lol_subadd(
07323 rsbac_list_handle_t handle,
07324 void * desc,
07325 void * subdesc,
07326 void * subdata)
07327 {
07328 return rsbac_ta_list_lol_subadd_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, subdesc, subdata);
07329 }
07330
07331
07332
07333 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07334 EXPORT_SYMBOL(rsbac_ta_list_lol_add_ttl);
07335 #endif
07336 int rsbac_ta_list_lol_add_ttl(
07337 rsbac_list_ta_number_t ta_number,
07338 rsbac_list_handle_t handle,
07339 rsbac_time_t ttl,
07340 void * desc,
07341 void * data)
07342 {
07343 struct rsbac_list_lol_reg_item_t * list;
07344 struct rsbac_list_lol_item_t * item_p;
07345 u_long lock_flags, rlock_flags;
07346
07347 if(!handle || !desc)
07348 return -RSBAC_EINVALIDVALUE;
07349 if(!list_initialized)
07350 return -RSBAC_ENOTINITIALIZED;
07351
07352 list = (struct rsbac_list_lol_reg_item_t *) handle;
07353 if(!list || (list->self != list))
07354 return -RSBAC_EINVALIDVALUE;
07355
07356 #ifdef CONFIG_RSBAC_LIST_TRANS
07357 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07358 return -RSBAC_EINVALIDTRANSACTION;
07359 #endif
07360
07361 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07362 {
07363 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07364 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07365 ttl += RSBAC_CURRENT_TIME;
07366 }
07367
07368 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07369 if(list->info.data_size && !data)
07370 {
07371 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07372 return -RSBAC_EINVALIDVALUE;
07373 }
07374
07375
07376
07377
07378
07379
07380
07381
07382 rsbac_write_lock(&list->lock, &lock_flags);
07383
07384 #ifdef CONFIG_RSBAC_LIST_TRANS
07385 if(!ta_number)
07386 #endif
07387 {
07388 item_p = lookup_lol_item(list, desc);
07389 if(item_p)
07390 {
07391 if(ttl != RSBAC_LIST_TTL_KEEP)
07392 item_p->max_age = ttl;
07393 if(data && list->info.data_size)
07394 {
07395 if( list->def_data
07396 && !item_p->max_age
07397 && !memcmp(list->def_data, data, list->info.data_size)
07398 && !item_p->count
07399 )
07400 do_remove_lol_item(list, item_p);
07401 else
07402 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07403 data, list->info.data_size);
07404 }
07405 }
07406 else
07407 {
07408 if(ttl == RSBAC_LIST_TTL_KEEP)
07409 ttl = 0;
07410 if( !list->def_data
07411 || memcmp(list->def_data, data, list->info.data_size)
07412 )
07413 add_lol_item(list, ttl, desc, data);
07414 }
07415 lol_touch(list);
07416 list->dirty = TRUE;
07417 }
07418 #ifdef CONFIG_RSBAC_LIST_TRANS
07419 if(list->ta_copied || ta_number)
07420 {
07421 if(!list->ta_copied)
07422 ta_lol_copy(ta_number, list);
07423 else
07424 if(ta_number)
07425 {
07426 if(list->ta_copied != ta_number)
07427 {
07428 rsbac_write_unlock(&list->lock, &lock_flags);
07429 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07430 return -RSBAC_EBUSY;
07431 }
07432 }
07433 else
07434 ta_number = list->ta_copied;
07435 item_p = ta_lookup_lol_item(ta_number, list, desc);
07436 if(item_p)
07437 {
07438 if(ttl != RSBAC_LIST_TTL_KEEP)
07439 item_p->max_age = ttl;
07440 if(data && list->info.data_size)
07441 {
07442 if( list->def_data
07443 && !item_p->max_age
07444 && !memcmp(list->def_data, data, list->info.data_size)
07445 && !item_p->count
07446 )
07447 ta_do_remove_lol_item(list, item_p);
07448 else
07449 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07450 data, list->info.data_size);
07451 }
07452 }
07453 else
07454 {
07455 if(ttl == RSBAC_LIST_TTL_KEEP)
07456 ttl = 0;
07457 if( !list->def_data
07458 || memcmp(list->def_data, data, list->info.data_size)
07459 )
07460 ta_add_lol_item(ta_number, list, ttl, desc, data);
07461 }
07462 }
07463 #endif
07464 rsbac_write_unlock(&list->lock, &lock_flags);
07465 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07466 return 0;
07467 }
07468
07469 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07470 EXPORT_SYMBOL(rsbac_list_lol_add_ttl);
07471 #endif
07472 int rsbac_list_lol_add_ttl(
07473 rsbac_list_handle_t handle,
07474 rsbac_time_t ttl,
07475 void * desc,
07476 void * data)
07477 {
07478 return rsbac_ta_list_lol_add_ttl(0, handle, ttl, desc, data);
07479 }
07480
07481 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07482 EXPORT_SYMBOL(rsbac_list_lol_add);
07483 #endif
07484 int rsbac_list_lol_add(
07485 rsbac_list_handle_t handle,
07486 void * desc,
07487 void * data)
07488 {
07489 return rsbac_ta_list_lol_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07490 }
07491
07492
07493 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07494 EXPORT_SYMBOL(rsbac_ta_list_remove);
07495 #endif
07496 int rsbac_ta_list_remove(
07497 rsbac_list_ta_number_t ta_number,
07498 rsbac_list_handle_t handle,
07499 void * desc)
07500 {
07501 struct rsbac_list_reg_item_t * list;
07502 u_long lock_flags, rlock_flags;
07503
07504 if(!handle || !desc)
07505 return -RSBAC_EINVALIDVALUE;
07506 if(!list_initialized)
07507 return -RSBAC_ENOTINITIALIZED;
07508
07509 list = (struct rsbac_list_reg_item_t *) handle;
07510 if(!list || (list->self != list))
07511 return -RSBAC_EINVALIDVALUE;
07512
07513 #ifdef CONFIG_RSBAC_LIST_TRANS
07514 if(ta_number)
07515 {
07516 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07517 return -RSBAC_EINVALIDTRANSACTION;
07518 }
07519 #endif
07520
07521 rsbac_read_lock(®_head.lock, &rlock_flags);
07522
07523
07524
07525
07526
07527
07528
07529 rsbac_write_lock(&list->lock, &lock_flags);
07530 #ifdef CONFIG_RSBAC_LIST_TRANS
07531 if(list->ta_copied)
07532 {
07533 if(ta_number)
07534 {
07535 if(ta_lookup_item(list->ta_copied, list, desc))
07536 {
07537 if(list->ta_copied != ta_number)
07538 {
07539 rsbac_write_unlock(&list->lock, &lock_flags);
07540 rsbac_read_unlock(®_head.lock, &rlock_flags);
07541 return -RSBAC_EBUSY;
07542 }
07543 else
07544 ta_remove_item(ta_number, list, desc);
07545 }
07546 }
07547 else
07548 ta_remove_item(list->ta_copied, list, desc);
07549 }
07550 else
07551 {
07552 if(ta_number && lookup_item(list, desc))
07553 {
07554 ta_copy(ta_number, list);
07555 ta_remove_item(ta_number, list, desc);
07556 }
07557 }
07558 if(!ta_number)
07559 #endif
07560 {
07561 if(lookup_item(list, desc))
07562 {
07563 remove_item(list, desc);
07564 touch(list);
07565 list->dirty = TRUE;
07566 }
07567 }
07568 rsbac_write_unlock(&list->lock, &lock_flags);
07569 rsbac_read_unlock(®_head.lock, &rlock_flags);
07570 return 0;
07571 }
07572
07573 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07574 EXPORT_SYMBOL(rsbac_list_remove);
07575 #endif
07576 int rsbac_list_remove(
07577 rsbac_list_handle_t handle,
07578 void * desc)
07579 {
07580 return rsbac_ta_list_remove(0, handle, desc);
07581 }
07582
07583
07584 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07585 EXPORT_SYMBOL(rsbac_ta_list_remove_all);
07586 #endif
07587 int rsbac_ta_list_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
07588 {
07589 struct rsbac_list_reg_item_t * list;
07590 u_long lock_flags, rlock_flags;
07591
07592 if(!handle)
07593 return -RSBAC_EINVALIDVALUE;
07594 if(!list_initialized)
07595 return -RSBAC_ENOTINITIALIZED;
07596
07597 list = (struct rsbac_list_reg_item_t *) handle;
07598 if(list->self != list)
07599 return -RSBAC_EINVALIDVALUE;
07600
07601 #ifdef CONFIG_RSBAC_LIST_TRANS
07602 if(ta_number)
07603 {
07604 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07605 return -RSBAC_EINVALIDTRANSACTION;
07606 }
07607 #endif
07608
07609 rsbac_read_lock(®_head.lock, &rlock_flags);
07610
07611
07612
07613
07614
07615
07616
07617 rsbac_write_lock(&list->lock, &lock_flags);
07618 #ifdef CONFIG_RSBAC_LIST_TRANS
07619 if(list->ta_copied)
07620 {
07621 if(ta_number)
07622 {
07623 if(list->ta_copied == ta_number)
07624 {
07625 ta_remove_all_items(list);
07626 if(!list->head)
07627 {
07628 list->ta_copied = 0;
07629 }
07630 }
07631 else
07632 {
07633 rsbac_write_unlock(&list->lock, &lock_flags);
07634 rsbac_read_unlock(®_head.lock, &rlock_flags);
07635 return -RSBAC_EBUSY;
07636 }
07637 }
07638 else
07639 ta_remove_all_items(list);
07640 }
07641 else
07642 {
07643 if(ta_number)
07644 {
07645 if(list->head)
07646 {
07647 list->ta_head = NULL;
07648 list->ta_tail = NULL;
07649 list->ta_curr = NULL;
07650 list->ta_count = 0;
07651 list->ta_copied = ta_number;
07652 }
07653 }
07654 }
07655
07656 if(!ta_number)
07657 #endif
07658 if(list->head)
07659 {
07660 remove_all_items(list);
07661 touch(list);
07662 list->dirty = TRUE;
07663 }
07664 rsbac_write_unlock(&list->lock, &lock_flags);
07665 rsbac_read_unlock(®_head.lock, &rlock_flags);
07666 return 0;
07667 }
07668
07669 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07670 EXPORT_SYMBOL(rsbac_list_remove_all);
07671 #endif
07672 int rsbac_list_remove_all(rsbac_list_handle_t handle)
07673 {
07674 return rsbac_ta_list_remove_all(0, handle);
07675 }
07676
07677 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07678 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove);
07679 #endif
07680 int rsbac_ta_list_lol_subremove(
07681 rsbac_list_ta_number_t ta_number,
07682 rsbac_list_handle_t handle,
07683 void * desc,
07684 void * subdesc)
07685 {
07686 struct rsbac_list_lol_reg_item_t * list;
07687 struct rsbac_list_lol_item_t * sublist;
07688 u_long lock_flags, rlock_flags;
07689
07690 if(!handle || !desc || !subdesc)
07691 return -RSBAC_EINVALIDVALUE;
07692 if(!list_initialized)
07693 return -RSBAC_ENOTINITIALIZED;
07694
07695 list = (struct rsbac_list_lol_reg_item_t *) handle;
07696 if(list->self != list)
07697 return -RSBAC_EINVALIDVALUE;
07698
07699 #ifdef CONFIG_RSBAC_LIST_TRANS
07700 if(ta_number)
07701 {
07702 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07703 return -RSBAC_EINVALIDTRANSACTION;
07704 }
07705 #endif
07706
07707 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07708
07709
07710
07711
07712
07713
07714
07715
07716 rsbac_write_lock(&list->lock, &lock_flags);
07717 #ifdef CONFIG_RSBAC_LIST_TRANS
07718 if(list->ta_copied)
07719 {
07720 sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07721 if(sublist)
07722 {
07723 if( sublist->max_age
07724 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07725 )
07726 {
07727 ta_do_remove_lol_item(list, sublist);
07728 }
07729 else
07730 {
07731 if(ta_number && (list->ta_copied != ta_number))
07732 {
07733 rsbac_write_unlock(&list->lock, &lock_flags);
07734 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07735 return -RSBAC_EBUSY;
07736 }
07737 if(lookup_lol_subitem(list, sublist, subdesc))
07738 remove_lol_subitem(list, sublist, subdesc);
07739 if( !sublist->count
07740 && ( ( list->def_data
07741 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07742 list->def_data,
07743 list->info.data_size)
07744 )
07745 || ( !list->info.data_size
07746 && (list->flags & RSBAC_LIST_DEF_DATA)
07747 )
07748 )
07749 )
07750 {
07751 ta_do_remove_lol_item(list, sublist);
07752 }
07753 }
07754 }
07755 }
07756 else
07757 {
07758 if(ta_number && lookup_lol_item(list, desc))
07759 {
07760 ta_lol_copy(ta_number, list);
07761 ta_remove_lol_item(ta_number, list, desc);
07762 }
07763 }
07764 if(!ta_number)
07765 #endif
07766 {
07767 sublist = lookup_lol_item(list, desc);
07768 if(sublist)
07769 {
07770 if( sublist->max_age
07771 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07772 )
07773 {
07774 do_remove_lol_item(list, sublist);
07775 lol_touch(list);
07776 list->dirty = TRUE;
07777 }
07778 else
07779 {
07780 if(lookup_lol_subitem(list, sublist, subdesc))
07781 {
07782 remove_lol_subitem(list, sublist, subdesc);
07783 lol_touch(list);
07784 list->dirty = TRUE;
07785 }
07786 if( !sublist->count
07787 && ( ( list->def_data
07788 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07789 list->def_data,
07790 list->info.data_size)
07791 )
07792 || ( !list->info.data_size
07793 && (list->flags & RSBAC_LIST_DEF_DATA)
07794 )
07795 )
07796 )
07797 {
07798 do_remove_lol_item(list, sublist);
07799 lol_touch(list);
07800 list->dirty = TRUE;
07801 }
07802 }
07803 }
07804 }
07805 rsbac_write_unlock(&list->lock, &lock_flags);
07806 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07807 return 0;
07808 }
07809
07810 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07811 EXPORT_SYMBOL(rsbac_list_lol_subremove);
07812 #endif
07813 int rsbac_list_lol_subremove(
07814 rsbac_list_handle_t handle,
07815 void * desc,
07816 void * subdesc)
07817 {
07818 return rsbac_ta_list_lol_subremove(0, handle, desc, subdesc);
07819 }
07820
07821
07822 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07823 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_from_all);
07824 #endif
07825 int rsbac_ta_list_lol_subremove_from_all(
07826 rsbac_list_ta_number_t ta_number,
07827 rsbac_list_handle_t handle,
07828 void * subdesc)
07829 {
07830 struct rsbac_list_lol_reg_item_t * list;
07831 struct rsbac_list_lol_item_t * sublist;
07832 u_long lock_flags, rlock_flags;
07833
07834 if(!handle || !subdesc)
07835 return -RSBAC_EINVALIDVALUE;
07836 if(!list_initialized)
07837 return -RSBAC_ENOTINITIALIZED;
07838
07839 list = (struct rsbac_list_lol_reg_item_t *) handle;
07840 if(list->self != list)
07841 return -RSBAC_EINVALIDVALUE;
07842
07843 #ifdef CONFIG_RSBAC_LIST_TRANS
07844 if(ta_number)
07845 {
07846 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07847 return -RSBAC_EINVALIDTRANSACTION;
07848 }
07849 #endif
07850
07851 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07852
07853
07854
07855
07856
07857
07858
07859 rsbac_write_lock(&list->lock, &lock_flags);
07860 #ifdef CONFIG_RSBAC_LIST_TRANS
07861 if(list->ta_copied)
07862 {
07863 if(ta_number && (list->ta_copied != ta_number))
07864 {
07865 rsbac_write_unlock(&list->lock, &lock_flags);
07866 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07867 return -RSBAC_EBUSY;
07868 }
07869 sublist = list->head;
07870 while(sublist)
07871 {
07872 remove_lol_subitem(list, sublist, subdesc);
07873 sublist = sublist->next;
07874 }
07875 }
07876 else
07877 {
07878 if(ta_number)
07879 {
07880 ta_lol_copy(ta_number, list);
07881 sublist = list->head;
07882 while(sublist)
07883 {
07884 remove_lol_subitem(list, sublist, subdesc);
07885 sublist = sublist->next;
07886 }
07887 }
07888 }
07889 if(!ta_number)
07890 #endif
07891 {
07892 sublist = list->head;
07893 while(sublist)
07894 {
07895 if(lookup_lol_subitem(list, sublist, subdesc))
07896 {
07897 remove_lol_subitem(list, sublist, subdesc);
07898 lol_touch(list);
07899 list->dirty = TRUE;
07900 }
07901 sublist = sublist->next;
07902 }
07903 }
07904 rsbac_write_unlock(&list->lock, &lock_flags);
07905 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07906 return 0;
07907 }
07908
07909 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07910 EXPORT_SYMBOL(rsbac_list_lol_subremove_from_all);
07911 #endif
07912 int rsbac_list_lol_subremove_from_all(
07913 rsbac_list_handle_t handle,
07914 void * subdesc)
07915 {
07916 return rsbac_ta_list_lol_subremove_from_all(0, handle, subdesc);
07917 }
07918
07919
07920 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07921 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_all);
07922 #endif
07923 int rsbac_ta_list_lol_subremove_all(
07924 rsbac_list_ta_number_t ta_number,
07925 rsbac_list_handle_t handle,
07926 void * desc)
07927 {
07928 struct rsbac_list_lol_reg_item_t * list;
07929 struct rsbac_list_lol_item_t * sublist;
07930 u_long lock_flags, rlock_flags;
07931
07932 if(!handle)
07933 return -RSBAC_EINVALIDVALUE;
07934 if(!list_initialized)
07935 return -RSBAC_ENOTINITIALIZED;
07936
07937 list = (struct rsbac_list_lol_reg_item_t *) handle;
07938 if(list->self != list)
07939 return -RSBAC_EINVALIDVALUE;
07940
07941 #ifdef CONFIG_RSBAC_LIST_TRANS
07942 if(ta_number)
07943 {
07944 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07945 return -RSBAC_EINVALIDTRANSACTION;
07946 }
07947 #endif
07948
07949 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07950
07951
07952
07953
07954
07955
07956
07957 rsbac_write_lock(&list->lock, &lock_flags);
07958 #ifdef CONFIG_RSBAC_LIST_TRANS
07959 if(list->ta_copied)
07960 {
07961 sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07962 if(sublist)
07963 {
07964 if( sublist->max_age
07965 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07966 )
07967 {
07968 ta_do_remove_lol_item(list, sublist);
07969 }
07970 else
07971 {
07972 if(ta_number && (list->ta_copied != ta_number))
07973 {
07974 rsbac_write_unlock(&list->lock, &lock_flags);
07975 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07976 return -RSBAC_EBUSY;
07977 }
07978 remove_all_lol_subitems(sublist);
07979 if( ( list->def_data
07980 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07981 list->def_data,
07982 list->info.data_size)
07983 )
07984 || ( !list->info.data_size
07985 && (list->flags & RSBAC_LIST_DEF_DATA)
07986 )
07987
07988 )
07989 {
07990 ta_do_remove_lol_item(list, sublist);
07991 }
07992 }
07993 }
07994 }
07995 else
07996 {
07997 if(ta_number && lookup_lol_item(list, desc))
07998 {
07999 ta_lol_copy(ta_number, list);
08000 sublist = ta_lookup_lol_item(ta_number, list, desc);
08001 if(sublist)
08002 remove_all_lol_subitems(sublist);
08003 }
08004 }
08005 if(!ta_number)
08006 #endif
08007 {
08008 sublist = lookup_lol_item(list, desc);
08009 if(sublist && sublist->head)
08010 {
08011 remove_all_lol_subitems(sublist);
08012 lol_touch(list);
08013 list->dirty = TRUE;
08014 }
08015 }
08016 rsbac_write_unlock(&list->lock, &lock_flags);
08017 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08018 return 0;
08019 }
08020
08021 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08022 EXPORT_SYMBOL(rsbac_list_lol_subremove_all);
08023 #endif
08024 int rsbac_list_lol_subremove_all(rsbac_list_handle_t handle, void * desc)
08025 {
08026 return rsbac_ta_list_lol_subremove_all(0, handle, desc);
08027 }
08028
08029 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08030 EXPORT_SYMBOL(rsbac_ta_list_lol_remove);
08031 #endif
08032 int rsbac_ta_list_lol_remove(
08033 rsbac_list_ta_number_t ta_number,
08034 rsbac_list_handle_t handle,
08035 void * desc)
08036 {
08037 struct rsbac_list_lol_reg_item_t * list;
08038 u_long lock_flags, rlock_flags;
08039
08040 if(!handle || !desc)
08041 return -RSBAC_EINVALIDVALUE;
08042 if(!list_initialized)
08043 return -RSBAC_ENOTINITIALIZED;
08044
08045 list = (struct rsbac_list_lol_reg_item_t *) handle;
08046 if(list->self != list)
08047 return -RSBAC_EINVALIDVALUE;
08048
08049 #ifdef CONFIG_RSBAC_LIST_TRANS
08050 if(ta_number)
08051 {
08052 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08053 return -RSBAC_EINVALIDTRANSACTION;
08054 }
08055 #endif
08056
08057 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08058
08059
08060
08061
08062
08063
08064
08065 rsbac_write_lock(&list->lock, &lock_flags);
08066 #ifdef CONFIG_RSBAC_LIST_TRANS
08067 if(list->ta_copied)
08068 {
08069 if(ta_number)
08070 {
08071 if(ta_lookup_lol_item(list->ta_copied, list, desc))
08072 {
08073 if(list->ta_copied != ta_number)
08074 {
08075 rsbac_write_unlock(&list->lock, &lock_flags);
08076 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08077 return -RSBAC_EBUSY;
08078 }
08079 else
08080 ta_remove_lol_item(ta_number, list, desc);
08081 }
08082 }
08083 else
08084 ta_remove_lol_item(list->ta_copied, list, desc);
08085 }
08086 else
08087 {
08088 if(ta_number && lookup_lol_item(list, desc))
08089 {
08090 ta_lol_copy(ta_number, list);
08091 ta_remove_lol_item(ta_number, list, desc);
08092 }
08093 }
08094 if(!ta_number)
08095 #endif
08096 {
08097 if(lookup_lol_item(list, desc))
08098 {
08099 remove_lol_item(list, desc);
08100 lol_touch(list);
08101 list->dirty = TRUE;
08102 }
08103 }
08104 rsbac_write_unlock(&list->lock, &lock_flags);
08105 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08106 return 0;
08107 }
08108
08109 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08110 EXPORT_SYMBOL(rsbac_list_lol_remove);
08111 #endif
08112 int rsbac_list_lol_remove(
08113 rsbac_list_handle_t handle,
08114 void * desc)
08115 {
08116 return rsbac_ta_list_lol_remove(0, handle, desc);
08117 }
08118
08119
08120 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08121 EXPORT_SYMBOL(rsbac_ta_list_lol_remove_all);
08122 #endif
08123 int rsbac_ta_list_lol_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
08124 {
08125 struct rsbac_list_lol_reg_item_t * list;
08126 u_long lock_flags, rlock_flags;
08127
08128 if(!handle)
08129 return -RSBAC_EINVALIDVALUE;
08130 if(!list_initialized)
08131 return -RSBAC_ENOTINITIALIZED;
08132
08133 list = (struct rsbac_list_lol_reg_item_t *) handle;
08134 if(list->self != list)
08135 return -RSBAC_EINVALIDVALUE;
08136
08137 #ifdef CONFIG_RSBAC_LIST_TRANS
08138 if(ta_number)
08139 {
08140 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08141 return -RSBAC_EINVALIDTRANSACTION;
08142 }
08143 #endif
08144
08145 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08146
08147
08148
08149
08150
08151
08152
08153 rsbac_write_lock(&list->lock, &lock_flags);
08154 #ifdef CONFIG_RSBAC_LIST_TRANS
08155 if(list->ta_copied)
08156 {
08157 if(ta_number)
08158 {
08159 if(list->ta_copied == ta_number)
08160 {
08161 ta_remove_all_lol_items(list);
08162 if(!list->head)
08163 {
08164 list->ta_copied = 0;
08165 }
08166 }
08167 else
08168 {
08169 rsbac_write_unlock(&list->lock, &lock_flags);
08170 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08171 return -RSBAC_EBUSY;
08172 }
08173 }
08174 else
08175 ta_remove_all_lol_items(list);
08176 }
08177 else
08178 {
08179 if(ta_number)
08180 {
08181 if(list->head)
08182 {
08183 list->ta_head = NULL;
08184 list->ta_tail = NULL;
08185 list->ta_curr = NULL;
08186 list->ta_count = 0;
08187 list->ta_copied = ta_number;
08188 }
08189 }
08190 }
08191
08192 if(!ta_number)
08193 #endif
08194 if(list->head)
08195 {
08196 remove_all_lol_items(list);
08197 lol_touch(list);
08198 list->dirty = TRUE;
08199 }
08200 rsbac_write_unlock(&list->lock, &lock_flags);
08201 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08202 return 0;
08203 }
08204
08205 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08206 EXPORT_SYMBOL(rsbac_list_lol_remove_all);
08207 #endif
08208 int rsbac_list_lol_remove_all(rsbac_list_handle_t handle)
08209 {
08210 return rsbac_ta_list_lol_remove_all(0, handle);
08211 }
08212
08213
08214
08215
08216 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08217 EXPORT_SYMBOL(rsbac_ta_list_get_data_ttl);
08218 #endif
08219 int rsbac_ta_list_get_data_ttl(
08220 rsbac_list_ta_number_t ta_number,
08221 rsbac_list_handle_t handle,
08222 rsbac_time_t * ttl_p,
08223 void * desc,
08224 void * data)
08225 {
08226 struct rsbac_list_reg_item_t * list;
08227 struct rsbac_list_item_t * item_p;
08228 u_long lock_flags, rlock_flags;
08229 int err = 0;
08230
08231 if(!handle || !desc)
08232 return -RSBAC_EINVALIDVALUE;
08233 if(!list_initialized)
08234 return -RSBAC_ENOTINITIALIZED;
08235
08236 list = (struct rsbac_list_reg_item_t *) handle;
08237 if(list->self != list)
08238 return -RSBAC_EINVALIDVALUE;
08239
08240 #ifdef CONFIG_RSBAC_LIST_TRANS
08241 if(ta_number)
08242 {
08243 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08244 return -RSBAC_EINVALIDTRANSACTION;
08245 }
08246 #endif
08247
08248 rsbac_read_lock(®_head.lock, &rlock_flags);
08249
08250
08251
08252
08253
08254
08255
08256 if(data && !list->info.data_size)
08257 {
08258 rsbac_read_unlock(®_head.lock, &rlock_flags);
08259 return -RSBAC_EINVALIDREQUEST;
08260 }
08261
08262 rsbac_read_lock(&list->lock, &lock_flags);
08263 #ifdef CONFIG_RSBAC_LIST_TRANS
08264 if(ta_number && (list->ta_copied == ta_number))
08265 item_p = ta_lookup_item(ta_number, list, desc);
08266 else
08267 #endif
08268 item_p = lookup_item(list, desc);
08269 if( item_p
08270 && ( !item_p->max_age
08271 || (item_p->max_age > RSBAC_CURRENT_TIME)
08272 )
08273 )
08274 {
08275 if(ttl_p)
08276 {
08277 if(item_p->max_age)
08278 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08279 else
08280 *ttl_p = 0;
08281 }
08282 if(data)
08283 {
08284 memcpy(data,
08285 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08286 list->info.data_size);
08287 }
08288 }
08289 else
08290 {
08291 if(!list->def_data)
08292 err = -RSBAC_ENOTFOUND;
08293 else
08294 {
08295 if(ttl_p)
08296 *ttl_p = 0;
08297 if(data)
08298 memcpy(data,
08299 list->def_data,
08300 list->info.data_size);
08301 }
08302 }
08303 rsbac_read_unlock(&list->lock, &lock_flags);
08304 rsbac_read_unlock(®_head.lock, &rlock_flags);
08305 return err;
08306 }
08307
08308 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08309 EXPORT_SYMBOL(rsbac_list_get_data_ttl);
08310 #endif
08311 int rsbac_list_get_data_ttl(rsbac_list_handle_t handle,
08312 rsbac_time_t * ttl_p,
08313 void * desc,
08314 void * data)
08315 {
08316 return rsbac_ta_list_get_data_ttl(0, handle, ttl_p, desc, data);
08317 }
08318
08319 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08320 EXPORT_SYMBOL(rsbac_list_get_data);
08321 #endif
08322 int rsbac_list_get_data(rsbac_list_handle_t handle, void * desc, void * data)
08323 {
08324 return rsbac_ta_list_get_data_ttl(0, handle, NULL, desc, data);
08325 }
08326
08327 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08328 EXPORT_SYMBOL(rsbac_ta_list_lol_get_subdata_ttl);
08329 #endif
08330 int rsbac_ta_list_lol_get_subdata_ttl(
08331 rsbac_list_ta_number_t ta_number,
08332 rsbac_list_handle_t handle,
08333 rsbac_time_t * ttl_p,
08334 void * desc,
08335 void * subdesc,
08336 void * subdata)
08337 {
08338 struct rsbac_list_lol_reg_item_t * list;
08339 struct rsbac_list_lol_item_t * sublist;
08340 struct rsbac_list_item_t * item_p;
08341 u_long lock_flags, rlock_flags;
08342 int err = 0;
08343
08344 if(!handle || !desc || !subdesc)
08345 return -RSBAC_EINVALIDVALUE;
08346 if(!list_initialized)
08347 return -RSBAC_ENOTINITIALIZED;
08348
08349 list = (struct rsbac_list_lol_reg_item_t *) handle;
08350 if(list->self != list)
08351 return -RSBAC_EINVALIDVALUE;
08352
08353 #ifdef CONFIG_RSBAC_LIST_TRANS
08354 if(ta_number)
08355 {
08356 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08357 return -RSBAC_EINVALIDTRANSACTION;
08358 }
08359 #endif
08360
08361 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08362
08363
08364
08365
08366
08367
08368
08369 if(subdata && !list->info.subdata_size)
08370 {
08371 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08372 return -RSBAC_EINVALIDREQUEST;
08373 }
08374
08375 rsbac_read_lock(&list->lock, &lock_flags);
08376
08377 #ifdef CONFIG_RSBAC_LIST_TRANS
08378 if(ta_number && (list->ta_copied == ta_number))
08379 sublist = ta_lookup_lol_item(ta_number, list, desc);
08380 else
08381 #endif
08382 sublist = lookup_lol_item(list, desc);
08383 if(sublist)
08384 {
08385 item_p = lookup_lol_subitem(list, sublist, subdesc);
08386 if( item_p
08387 && ( !item_p->max_age
08388 || (item_p->max_age > RSBAC_CURRENT_TIME)
08389 )
08390 )
08391 {
08392 if(ttl_p)
08393 {
08394 if(item_p->max_age)
08395 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08396 else
08397 *ttl_p = 0;
08398 }
08399 if(subdata)
08400 {
08401 memcpy(subdata,
08402 ((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
08403 list->info.subdata_size);
08404 }
08405 }
08406 else
08407 {
08408 if(!list->def_subdata)
08409 err = -RSBAC_ENOTFOUND;
08410 else
08411 {
08412 if(ttl_p)
08413 *ttl_p = 0;
08414 if(subdata)
08415 memcpy(subdata,
08416 list->def_subdata,
08417 list->info.subdata_size);
08418 }
08419 }
08420 }
08421 else
08422 {
08423 if(!list->def_subdata)
08424 err = -RSBAC_ENOTFOUND;
08425 else
08426 {
08427 if(ttl_p)
08428 *ttl_p = 0;
08429 if(subdata)
08430 memcpy(subdata,
08431 list->def_subdata,
08432 list->info.subdata_size);
08433 }
08434 }
08435 rsbac_read_unlock(&list->lock, &lock_flags);
08436 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08437 return err;
08438 }
08439
08440 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08441 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_ttl);
08442 #endif
08443 int rsbac_list_lol_get_subdata_ttl(
08444 rsbac_list_handle_t handle,
08445 rsbac_time_t * ttl_p,
08446 void * desc,
08447 void * subdesc,
08448 void * subdata)
08449 {
08450 return rsbac_ta_list_lol_get_subdata_ttl(0, handle,
08451 ttl_p, desc, subdesc, subdata);
08452 }
08453
08454 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08455 EXPORT_SYMBOL(rsbac_list_lol_get_subdata);
08456 #endif
08457 int rsbac_list_lol_get_subdata(
08458 rsbac_list_handle_t handle,
08459 void * desc,
08460 void * subdesc,
08461 void * subdata)
08462 {
08463 return rsbac_ta_list_lol_get_subdata_ttl(0, handle, NULL, desc, subdesc, subdata);
08464 }
08465
08466 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08467 EXPORT_SYMBOL(rsbac_ta_list_lol_get_data_ttl);
08468 #endif
08469 int rsbac_ta_list_lol_get_data_ttl(
08470 rsbac_list_ta_number_t ta_number,
08471 rsbac_list_handle_t handle,
08472 rsbac_time_t * ttl_p,
08473 void * desc,
08474 void * data)
08475 {
08476 struct rsbac_list_lol_reg_item_t * list;
08477 struct rsbac_list_lol_item_t * item_p;
08478 u_long lock_flags, rlock_flags;
08479 int err = 0;
08480
08481 if(!handle || !desc)
08482 return -RSBAC_EINVALIDVALUE;
08483 if(!list_initialized)
08484 return -RSBAC_ENOTINITIALIZED;
08485
08486 list = (struct rsbac_list_lol_reg_item_t *) handle;
08487 if(list->self != list)
08488 return -RSBAC_EINVALIDVALUE;
08489
08490 #ifdef CONFIG_RSBAC_LIST_TRANS
08491 if(ta_number)
08492 {
08493 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08494 return -RSBAC_EINVALIDTRANSACTION;
08495 }
08496 #endif
08497
08498 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08499
08500
08501
08502
08503
08504
08505
08506 if(data && !list->info.data_size)
08507 {
08508 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08509 return -RSBAC_EINVALIDREQUEST;
08510 }
08511
08512 rsbac_read_lock(&list->lock, &lock_flags);
08513
08514 #ifdef CONFIG_RSBAC_LIST_TRANS
08515 if(ta_number && (list->ta_copied == ta_number))
08516 item_p = ta_lookup_lol_item(ta_number, list, desc);
08517 else
08518 #endif
08519 item_p = lookup_lol_item(list, desc);
08520 if( item_p
08521 && ( !item_p->max_age
08522 || (item_p->max_age > RSBAC_CURRENT_TIME)
08523 )
08524 )
08525 {
08526 if(ttl_p)
08527 {
08528 if(item_p->max_age)
08529 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08530 else
08531 *ttl_p = 0;
08532 }
08533 if(data)
08534 {
08535 memcpy(data,
08536 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08537 list->info.data_size);
08538 }
08539 }
08540 else
08541 {
08542 if(!list->def_data)
08543 err = -RSBAC_ENOTFOUND;
08544 else
08545 {
08546 if(ttl_p)
08547 *ttl_p = 0;
08548 if(data)
08549 memcpy(data,
08550 list->def_data,
08551 list->info.data_size);
08552 }
08553 }
08554 rsbac_read_unlock(&list->lock, &lock_flags);
08555 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08556 return err;
08557 }
08558
08559 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08560 EXPORT_SYMBOL(rsbac_list_lol_get_data_ttl);
08561 #endif
08562 int rsbac_list_lol_get_data_ttl(rsbac_list_handle_t handle,
08563 rsbac_time_t * ttl_p,
08564 void * desc,
08565 void * data)
08566 {
08567 return rsbac_ta_list_lol_get_data_ttl(0, handle, ttl_p, desc, data);
08568 }
08569
08570 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08571 EXPORT_SYMBOL(rsbac_list_lol_get_data);
08572 #endif
08573 int rsbac_list_lol_get_data(rsbac_list_handle_t handle,
08574 void * desc,
08575 void * data)
08576 {
08577 return rsbac_ta_list_lol_get_data_ttl(0, handle, NULL, desc, data);
08578 }
08579
08580 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08581 EXPORT_SYMBOL(rsbac_ta_list_get_max_desc);
08582 #endif
08583 int rsbac_ta_list_get_max_desc(
08584 rsbac_list_ta_number_t ta_number,
08585 rsbac_list_handle_t handle,
08586 void * desc)
08587 {
08588 struct rsbac_list_reg_item_t * list;
08589 struct rsbac_list_item_t * item_p;
08590 u_long lock_flags, rlock_flags;
08591 int err = 0;
08592
08593 if(!handle)
08594 return -RSBAC_EINVALIDVALUE;
08595 if(!list_initialized)
08596 return -RSBAC_ENOTINITIALIZED;
08597
08598 list = (struct rsbac_list_reg_item_t *) handle;
08599 if(list->self != list)
08600 return -RSBAC_EINVALIDVALUE;
08601
08602 #ifdef CONFIG_RSBAC_LIST_TRANS
08603 if(ta_number)
08604 {
08605 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08606 return -RSBAC_EINVALIDTRANSACTION;
08607 }
08608 #endif
08609
08610 rsbac_read_lock(®_head.lock, &rlock_flags);
08611
08612
08613
08614
08615
08616
08617
08618 rsbac_read_lock(&list->lock, &lock_flags);
08619 #ifdef CONFIG_RSBAC_LIST_TRANS
08620 if(ta_number && (list->ta_copied == ta_number))
08621 item_p = list->ta_tail;
08622 else
08623 #endif
08624 item_p = list->tail;
08625 while( item_p
08626 && item_p->max_age
08627 && (item_p->max_age > RSBAC_CURRENT_TIME)
08628 )
08629 item_p = item_p->prev;
08630 if(item_p)
08631 memcpy(desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08632 else
08633 {
08634 memset(desc, 0, list->info.desc_size);
08635 err = -RSBAC_ENOTFOUND;
08636 }
08637 rsbac_read_unlock(&list->lock, &lock_flags);
08638 rsbac_read_unlock(®_head.lock, &rlock_flags);
08639 return err;
08640 }
08641
08642 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08643 EXPORT_SYMBOL(rsbac_list_get_max_desc);
08644 #endif
08645 int rsbac_list_get_max_desc(rsbac_list_handle_t handle, void * desc)
08646 {
08647 return rsbac_ta_list_get_max_desc(0, handle, desc);
08648 }
08649
08650 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08651 EXPORT_SYMBOL(rsbac_ta_list_get_next_desc);
08652 #endif
08653 int rsbac_ta_list_get_next_desc(
08654 rsbac_list_ta_number_t ta_number,
08655 rsbac_list_handle_t handle,
08656 void * old_desc,
08657 void * next_desc)
08658 {
08659 struct rsbac_list_reg_item_t * list;
08660 struct rsbac_list_item_t * item_p;
08661 u_long lock_flags, rlock_flags;
08662
08663 if(!handle)
08664 return -RSBAC_EINVALIDVALUE;
08665 if(!list_initialized)
08666 return -RSBAC_ENOTINITIALIZED;
08667 if(!next_desc)
08668 return -RSBAC_EINVALIDPOINTER;
08669
08670 list = (struct rsbac_list_reg_item_t *) handle;
08671 if(list->self != list)
08672 return -RSBAC_EINVALIDVALUE;
08673
08674 #ifdef CONFIG_RSBAC_LIST_TRANS
08675 if(ta_number)
08676 {
08677 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08678 return -RSBAC_EINVALIDTRANSACTION;
08679 }
08680 #endif
08681
08682 rsbac_read_lock(®_head.lock, &rlock_flags);
08683
08684
08685
08686
08687
08688
08689
08690 rsbac_read_lock(&list->lock, &lock_flags);
08691 if(old_desc)
08692 {
08693 #ifdef CONFIG_RSBAC_LIST_TRANS
08694 if(ta_number && (list->ta_copied == ta_number))
08695 item_p = ta_lookup_item(ta_number, list, old_desc);
08696 else
08697 #endif
08698 item_p = lookup_item(list, old_desc);
08699 if(item_p)
08700 item_p = item_p->next;
08701 }
08702 else
08703 #ifdef CONFIG_RSBAC_LIST_TRANS
08704 if(ta_number && (list->ta_copied == ta_number))
08705 item_p = list->ta_head;
08706 else
08707 #endif
08708 item_p = list->head;
08709 while( item_p
08710 && item_p->max_age
08711 && (item_p->max_age > RSBAC_CURRENT_TIME)
08712 )
08713 item_p = item_p->next;
08714 if(item_p)
08715 {
08716 memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08717 list->curr = item_p;
08718 }
08719 rsbac_read_unlock(&list->lock, &lock_flags);
08720 rsbac_read_unlock(®_head.lock, &rlock_flags);
08721 if(item_p)
08722 return 0;
08723 else
08724 return -RSBAC_ENOTFOUND;
08725 }
08726
08727 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08728 EXPORT_SYMBOL(rsbac_list_get_next_desc);
08729 #endif
08730 int rsbac_list_get_next_desc(rsbac_list_handle_t handle, void * old_desc, void * next_desc)
08731 {
08732 return rsbac_ta_list_get_next_desc(0, handle, old_desc, next_desc);
08733 }
08734
08735 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08736 EXPORT_SYMBOL(rsbac_ta_list_lol_get_next_desc);
08737 #endif
08738 int rsbac_ta_list_lol_get_next_desc(
08739 rsbac_list_ta_number_t ta_number,
08740 rsbac_list_handle_t handle,
08741 void * old_desc,
08742 void * next_desc)
08743 {
08744 struct rsbac_list_lol_reg_item_t * list;
08745 struct rsbac_list_lol_item_t * item_p;
08746 u_long lock_flags, rlock_flags;
08747
08748 if(!handle)
08749 return -RSBAC_EINVALIDVALUE;
08750 if(!list_initialized)
08751 return -RSBAC_ENOTINITIALIZED;
08752 if(!next_desc)
08753 return -RSBAC_EINVALIDPOINTER;
08754
08755 list = (struct rsbac_list_lol_reg_item_t *) handle;
08756 if(list->self != list)
08757 return -RSBAC_EINVALIDVALUE;
08758
08759 #ifdef CONFIG_RSBAC_LIST_TRANS
08760 if(ta_number)
08761 {
08762 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08763 return -RSBAC_EINVALIDTRANSACTION;
08764 }
08765 #endif
08766
08767 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08768
08769
08770
08771
08772
08773
08774
08775 rsbac_read_lock(&list->lock, &lock_flags);
08776 if(old_desc)
08777 {
08778 #ifdef CONFIG_RSBAC_LIST_TRANS
08779 if(ta_number && (list->ta_copied == ta_number))
08780 item_p = ta_lookup_lol_item(ta_number, list, old_desc);
08781 else
08782 #endif
08783 item_p = lookup_lol_item(list, old_desc);
08784 if(item_p)
08785 item_p = item_p->next;
08786 }
08787 else
08788 #ifdef CONFIG_RSBAC_LIST_TRANS
08789 if(ta_number && (list->ta_copied == ta_number))
08790 item_p = list->ta_head;
08791 else
08792 #endif
08793 item_p = list->head;
08794 while( item_p
08795 && item_p->max_age
08796 && (item_p->max_age > RSBAC_CURRENT_TIME)
08797 )
08798 item_p = item_p->next;
08799 if(item_p)
08800 {
08801 memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08802 list->curr = item_p;
08803 }
08804 rsbac_read_unlock(&list->lock, &lock_flags);
08805 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08806 if(item_p)
08807 return 0;
08808 else
08809 return -RSBAC_ENOTFOUND;
08810 }
08811
08812 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08813 EXPORT_SYMBOL(rsbac_list_lol_get_next_desc);
08814 #endif
08815 int rsbac_list_lol_get_next_desc(
08816 rsbac_list_handle_t handle,
08817 void * old_desc,
08818 void * next_desc)
08819 {
08820 return rsbac_ta_list_lol_get_next_desc(0, handle, old_desc, next_desc);
08821 }
08822
08823
08824
08825
08826
08827
08828
08829
08830
08831 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08832 EXPORT_SYMBOL(rsbac_ta_list_get_desc);
08833 #endif
08834 int rsbac_ta_list_get_desc(
08835 rsbac_list_ta_number_t ta_number,
08836 rsbac_list_handle_t handle,
08837 void * desc,
08838 void * data,
08839 rsbac_list_data_compare_function_t compare)
08840 {
08841 struct rsbac_list_reg_item_t * list;
08842 struct rsbac_list_item_t * item_p;
08843 u_long lock_flags, rlock_flags;
08844 int err = 0;
08845
08846 if(!handle || !desc || !data)
08847 return -RSBAC_EINVALIDVALUE;
08848 if(!list_initialized)
08849 return -RSBAC_ENOTINITIALIZED;
08850
08851 list = (struct rsbac_list_reg_item_t *) handle;
08852 if(list->self != list)
08853 return -RSBAC_EINVALIDVALUE;
08854
08855 #ifdef CONFIG_RSBAC_LIST_TRANS
08856 if(ta_number)
08857 {
08858 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08859 return -RSBAC_EINVALIDTRANSACTION;
08860 }
08861 #endif
08862
08863 rsbac_read_lock(®_head.lock, &rlock_flags);
08864
08865
08866
08867
08868
08869
08870
08871 if(!list->info.data_size)
08872 {
08873 rsbac_read_unlock(®_head.lock, &rlock_flags);
08874 return -RSBAC_EINVALIDREQUEST;
08875 }
08876
08877 rsbac_read_lock(&list->lock, &lock_flags);
08878
08879 #ifdef CONFIG_RSBAC_LIST_TRANS
08880 if(ta_number && (list->ta_copied == ta_number))
08881 item_p = ta_lookup_item_data(ta_number, list, data, compare);
08882 else
08883 #endif
08884 item_p = lookup_item_data(list, data, compare);
08885 if(item_p)
08886 {
08887 memcpy(desc,
08888 ((char *) item_p) + sizeof(*item_p),
08889 list->info.desc_size);
08890 }
08891 else
08892 {
08893 err = -RSBAC_ENOTFOUND;
08894 }
08895 rsbac_read_unlock(&list->lock, &lock_flags);
08896 rsbac_read_unlock(®_head.lock, &rlock_flags);
08897 return err;
08898 }
08899
08900 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08901 EXPORT_SYMBOL(rsbac_list_get_desc);
08902 #endif
08903 int rsbac_list_get_desc(
08904 rsbac_list_handle_t handle,
08905 void * desc,
08906 void * data,
08907 rsbac_list_data_compare_function_t compare)
08908 {
08909 return rsbac_ta_list_get_desc(0, handle, desc, data, compare);
08910 }
08911
08912 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08913 EXPORT_SYMBOL(rsbac_ta_list_lol_get_desc);
08914 #endif
08915 int rsbac_ta_list_lol_get_desc(
08916 rsbac_list_ta_number_t ta_number,
08917 rsbac_list_handle_t handle,
08918 void * desc,
08919 void * data,
08920 rsbac_list_data_compare_function_t compare)
08921 {
08922 struct rsbac_list_lol_reg_item_t * list;
08923 struct rsbac_list_lol_item_t * item_p;
08924 u_long lock_flags, rlock_flags;
08925 int err = 0;
08926
08927 if(!handle || !desc || !data)
08928 return -RSBAC_EINVALIDVALUE;
08929 if(!list_initialized)
08930 return -RSBAC_ENOTINITIALIZED;
08931
08932 list = (struct rsbac_list_lol_reg_item_t *) handle;
08933 if(list->self != list)
08934 return -RSBAC_EINVALIDVALUE;
08935
08936 #ifdef CONFIG_RSBAC_LIST_TRANS
08937 if(ta_number)
08938 {
08939 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08940 return -RSBAC_EINVALIDTRANSACTION;
08941 }
08942 #endif
08943
08944 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08945
08946
08947
08948
08949
08950
08951
08952 if(!list->info.data_size)
08953 {
08954 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08955 return -RSBAC_EINVALIDREQUEST;
08956 }
08957
08958 rsbac_read_lock(&list->lock, &lock_flags);
08959
08960 #ifdef CONFIG_RSBAC_LIST_TRANS
08961 if(ta_number && (list->ta_copied == ta_number))
08962 item_p = ta_lookup_lol_item_data(ta_number, list, data, compare);
08963 else
08964 #endif
08965 item_p = lookup_lol_item_data(list, data, compare);
08966 if(item_p)
08967 {
08968 memcpy(desc,
08969 ((char *) item_p) + sizeof(*item_p),
08970 list->info.desc_size);
08971 }
08972 else
08973 {
08974 err = -RSBAC_ENOTFOUND;
08975 }
08976 rsbac_read_unlock(&list->lock, &lock_flags);
08977 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08978 return err;
08979 }
08980
08981 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08982 EXPORT_SYMBOL(rsbac_list_lol_get_desc);
08983 #endif
08984 int rsbac_list_lol_get_desc(
08985 rsbac_list_handle_t handle,
08986 void * desc,
08987 void * data,
08988 rsbac_list_data_compare_function_t compare)
08989 {
08990 return rsbac_ta_list_lol_get_desc(0, handle, desc, data, compare);
08991 }
08992
08993
08994 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08995 EXPORT_SYMBOL(rsbac_ta_list_exist);
08996 #endif
08997 int rsbac_ta_list_exist(
08998 rsbac_list_ta_number_t ta_number,
08999 rsbac_list_handle_t handle,
09000 void * desc)
09001 {
09002 struct rsbac_list_reg_item_t * list;
09003 u_long lock_flags, rlock_flags;
09004 struct rsbac_list_item_t * item_p;
09005 int result;
09006
09007 if(!handle || !desc)
09008 return FALSE;
09009 if(!list_initialized)
09010 return FALSE;
09011
09012 list = (struct rsbac_list_reg_item_t *) handle;
09013 if(list->self != list)
09014 return -RSBAC_EINVALIDVALUE;
09015
09016 #ifdef CONFIG_RSBAC_LIST_TRANS
09017 if(ta_number)
09018 {
09019 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09020 return -RSBAC_EINVALIDTRANSACTION;
09021 }
09022 #endif
09023
09024 rsbac_read_lock(®_head.lock, &rlock_flags);
09025
09026
09027
09028
09029
09030
09031
09032 rsbac_read_lock(&list->lock, &lock_flags);
09033
09034 #ifdef CONFIG_RSBAC_LIST_TRANS
09035 if(ta_number && (list->ta_copied == ta_number))
09036 item_p = ta_lookup_item(ta_number, list, desc);
09037 else
09038 #endif
09039 item_p = lookup_item(list, desc);
09040 if( item_p
09041 && ( !item_p->max_age
09042 || (item_p->max_age > RSBAC_CURRENT_TIME)
09043 )
09044 )
09045 {
09046 result = TRUE;
09047 }
09048 else
09049 {
09050 result = FALSE;
09051 }
09052 rsbac_read_unlock(&list->lock, &lock_flags);
09053 rsbac_read_unlock(®_head.lock, &rlock_flags);
09054 return result;
09055 }
09056
09057 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09058 EXPORT_SYMBOL(rsbac_list_exist);
09059 #endif
09060 int rsbac_list_exist(
09061 rsbac_list_handle_t handle,
09062 void * desc)
09063 {
09064 return rsbac_ta_list_exist(0, handle, desc);
09065 }
09066
09067
09068 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09069 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist);
09070 #endif
09071 int rsbac_ta_list_lol_subexist(
09072 rsbac_list_ta_number_t ta_number,
09073 rsbac_list_handle_t handle,
09074 void * desc,
09075 void * subdesc)
09076 {
09077 struct rsbac_list_lol_reg_item_t * list;
09078 struct rsbac_list_lol_item_t * sublist;
09079 u_long lock_flags, rlock_flags;
09080 struct rsbac_list_item_t * item_p;
09081 int result;
09082
09083 if(!handle || !desc || !subdesc)
09084 return FALSE;
09085 if(!list_initialized)
09086 return FALSE;
09087
09088 list = (struct rsbac_list_lol_reg_item_t *) handle;
09089 if(list->self != list)
09090 return -RSBAC_EINVALIDVALUE;
09091
09092 #ifdef CONFIG_RSBAC_LIST_TRANS
09093 if(ta_number)
09094 {
09095 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09096 return -RSBAC_EINVALIDTRANSACTION;
09097 }
09098 #endif
09099
09100 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09101
09102
09103
09104
09105
09106
09107
09108 rsbac_read_lock(&list->lock, &lock_flags);
09109
09110 #ifdef CONFIG_RSBAC_LIST_TRANS
09111 if(ta_number && (list->ta_copied == ta_number))
09112 sublist = ta_lookup_lol_item(ta_number, list, desc);
09113 else
09114 #endif
09115 sublist = lookup_lol_item(list, desc);
09116 if(sublist)
09117 {
09118 item_p = lookup_lol_subitem(list, sublist, subdesc);
09119 if( item_p
09120 && ( !item_p->max_age
09121 || (item_p->max_age > RSBAC_CURRENT_TIME)
09122 )
09123 )
09124 {
09125 result = TRUE;
09126 }
09127 else
09128 {
09129 result = FALSE;
09130 }
09131 }
09132 else
09133 {
09134 result = FALSE;
09135 }
09136 rsbac_read_unlock(&list->lock, &lock_flags);
09137 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09138 return result;
09139 }
09140
09141 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09142 EXPORT_SYMBOL(rsbac_list_lol_subexist);
09143 #endif
09144 int rsbac_list_lol_subexist(
09145 rsbac_list_handle_t handle,
09146 void * desc,
09147 void * subdesc)
09148 {
09149 return rsbac_ta_list_lol_subexist(0, handle, desc, subdesc);
09150 }
09151
09152 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09153 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist_compare);
09154 #endif
09155 int rsbac_ta_list_lol_subexist_compare(
09156 rsbac_list_ta_number_t ta_number,
09157 rsbac_list_handle_t handle,
09158 void * desc,
09159 void * subdesc,
09160 rsbac_list_compare_function_t compare)
09161 {
09162 struct rsbac_list_lol_reg_item_t * list;
09163 struct rsbac_list_lol_item_t * sublist;
09164 u_long lock_flags, rlock_flags;
09165 struct rsbac_list_item_t * item_p;
09166 int result;
09167
09168 if(!handle || !desc || !subdesc)
09169 return FALSE;
09170 if(!list_initialized)
09171 return FALSE;
09172
09173 if(!compare)
09174 return rsbac_list_lol_subexist(handle, desc, subdesc);
09175
09176 list = (struct rsbac_list_lol_reg_item_t *) handle;
09177 if(list->self != list)
09178 return -RSBAC_EINVALIDVALUE;
09179
09180 #ifdef CONFIG_RSBAC_LIST_TRANS
09181 if(ta_number)
09182 {
09183 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09184 return -RSBAC_EINVALIDTRANSACTION;
09185 }
09186 #endif
09187
09188 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09189
09190
09191
09192
09193
09194
09195
09196 rsbac_read_lock(&list->lock, &lock_flags);
09197
09198 #ifdef CONFIG_RSBAC_LIST_TRANS
09199 if(ta_number && (list->ta_copied == ta_number))
09200 sublist = ta_lookup_lol_item(ta_number, list, desc);
09201 else
09202 #endif
09203 sublist = lookup_lol_item(list, desc);
09204 if(sublist)
09205 {
09206 item_p = lookup_lol_subitem_user_compare(list, sublist, subdesc, compare);
09207 if( item_p
09208 && ( !item_p->max_age
09209 || (item_p->max_age > RSBAC_CURRENT_TIME)
09210 )
09211 )
09212 {
09213 result = TRUE;
09214 }
09215 else
09216 {
09217 result = FALSE;
09218 }
09219 }
09220 else
09221 {
09222 result = FALSE;
09223 }
09224 rsbac_read_unlock(&list->lock, &lock_flags);
09225 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09226 return result;
09227 }
09228
09229 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09230 EXPORT_SYMBOL(rsbac_list_lol_subexist_compare);
09231 #endif
09232 int rsbac_list_lol_subexist_compare(
09233 rsbac_list_handle_t handle,
09234 void * desc,
09235 void * subdesc,
09236 rsbac_list_compare_function_t compare)
09237 {
09238 return rsbac_ta_list_lol_subexist_compare(0, handle,
09239 desc, subdesc, compare);
09240 }
09241
09242 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09243 EXPORT_SYMBOL(rsbac_ta_list_lol_exist);
09244 #endif
09245 int rsbac_ta_list_lol_exist(
09246 rsbac_list_ta_number_t ta_number,
09247 rsbac_list_handle_t handle,
09248 void * desc)
09249 {
09250 struct rsbac_list_lol_reg_item_t * list;
09251 u_long lock_flags, rlock_flags;
09252 struct rsbac_list_lol_item_t * item_p;
09253 int result;
09254
09255 if(!handle || !desc)
09256 return FALSE;
09257 if(!list_initialized)
09258 return FALSE;
09259
09260 list = (struct rsbac_list_lol_reg_item_t *) handle;
09261 if(list->self != list)
09262 return -RSBAC_EINVALIDVALUE;
09263
09264 #ifdef CONFIG_RSBAC_LIST_TRANS
09265 if(ta_number)
09266 {
09267 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09268 return -RSBAC_EINVALIDTRANSACTION;
09269 }
09270 #endif
09271
09272 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09273
09274
09275
09276
09277
09278
09279
09280 rsbac_read_lock(&list->lock, &lock_flags);
09281
09282 #ifdef CONFIG_RSBAC_LIST_TRANS
09283 if(ta_number && (list->ta_copied == ta_number))
09284 item_p = ta_lookup_lol_item(ta_number, list, desc);
09285 else
09286 #endif
09287 item_p = lookup_lol_item(list, desc);
09288 if( item_p
09289 && ( !item_p->max_age
09290 || (item_p->max_age > RSBAC_CURRENT_TIME)
09291 )
09292 )
09293 {
09294 result = TRUE;
09295 }
09296 else
09297 {
09298 result = FALSE;
09299 }
09300 rsbac_read_unlock(&list->lock, &lock_flags);
09301 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09302 return result;
09303 }
09304
09305 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09306 EXPORT_SYMBOL(rsbac_list_lol_exist);
09307 #endif
09308 int rsbac_list_lol_exist(
09309 rsbac_list_handle_t handle,
09310 void * desc)
09311 {
09312 return rsbac_ta_list_lol_exist(0, handle, desc);
09313 }
09314
09315
09316
09317 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09318 EXPORT_SYMBOL(rsbac_ta_list_lol_subcount);
09319 #endif
09320 long rsbac_ta_list_lol_subcount(
09321 rsbac_list_ta_number_t ta_number,
09322 rsbac_list_handle_t handle,
09323 void * desc)
09324 {
09325 struct rsbac_list_lol_reg_item_t * list;
09326 struct rsbac_list_lol_item_t * sublist;
09327 u_long lock_flags, rlock_flags;
09328 long result;
09329
09330 if(!handle)
09331 return -RSBAC_EINVALIDVALUE;
09332 if(!list_initialized)
09333 return -RSBAC_ENOTINITIALIZED;
09334
09335 list = (struct rsbac_list_lol_reg_item_t *) handle;
09336 if(list->self != list)
09337 return -RSBAC_EINVALIDVALUE;
09338
09339 #ifdef CONFIG_RSBAC_LIST_TRANS
09340 if(ta_number)
09341 {
09342 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09343 return -RSBAC_EINVALIDTRANSACTION;
09344 }
09345 #endif
09346
09347 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09348
09349
09350
09351
09352
09353
09354
09355 rsbac_read_lock(&list->lock, &lock_flags);
09356
09357 #ifdef CONFIG_RSBAC_LIST_TRANS
09358 if(ta_number && (list->ta_copied == ta_number))
09359 sublist = ta_lookup_lol_item(ta_number, list, desc);
09360 else
09361 #endif
09362 sublist = lookup_lol_item(list, desc);
09363 if(sublist)
09364 {
09365 result = sublist->count;
09366 }
09367 else
09368 {
09369 result = -RSBAC_ENOTFOUND;
09370 }
09371 rsbac_read_unlock(&list->lock, &lock_flags);
09372 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09373 return result;
09374 }
09375
09376 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09377 EXPORT_SYMBOL(rsbac_list_lol_subcount);
09378 #endif
09379 long rsbac_list_lol_subcount(
09380 rsbac_list_handle_t handle,
09381 void * desc)
09382 {
09383 return rsbac_ta_list_lol_subcount(0, handle, desc);
09384 }
09385
09386 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09387 EXPORT_SYMBOL(rsbac_ta_list_lol_all_subcount);
09388 #endif
09389 long rsbac_ta_list_lol_all_subcount(
09390 rsbac_list_ta_number_t ta_number,
09391 rsbac_list_handle_t handle)
09392 {
09393 struct rsbac_list_lol_reg_item_t * list;
09394 struct rsbac_list_lol_item_t * sublist;
09395 u_long lock_flags, rlock_flags;
09396 long result = 0;
09397
09398 if(!handle)
09399 return -RSBAC_EINVALIDVALUE;
09400 if(!list_initialized)
09401 return -RSBAC_ENOTINITIALIZED;
09402
09403 list = (struct rsbac_list_lol_reg_item_t *) handle;
09404 if(list->self != list)
09405 return -RSBAC_EINVALIDVALUE;
09406
09407 #ifdef CONFIG_RSBAC_LIST_TRANS
09408 if(ta_number)
09409 {
09410 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09411 return -RSBAC_EINVALIDTRANSACTION;
09412 }
09413 #endif
09414
09415 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09416
09417
09418
09419
09420
09421
09422
09423 rsbac_read_lock(&list->lock, &lock_flags);
09424
09425 #ifdef CONFIG_RSBAC_LIST_TRANS
09426 if(ta_number && (list->ta_copied == ta_number))
09427 sublist = list->ta_head;
09428 else
09429 #endif
09430 sublist = list->head;
09431 while(sublist)
09432 {
09433 result += sublist->count;
09434 sublist = sublist->next;
09435 }
09436 rsbac_read_unlock(&list->lock, &lock_flags);
09437 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09438 return result;
09439 }
09440
09441 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09442 EXPORT_SYMBOL(rsbac_list_lol_all_subcount);
09443 #endif
09444 long rsbac_list_lol_all_subcount(rsbac_list_handle_t handle)
09445 {
09446 return rsbac_ta_list_lol_all_subcount(0, handle);
09447 }
09448
09449 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09450 EXPORT_SYMBOL(rsbac_ta_list_lol_count);
09451 #endif
09452 long rsbac_ta_list_lol_count(
09453 rsbac_list_ta_number_t ta_number,
09454 rsbac_list_handle_t handle)
09455 {
09456 struct rsbac_list_lol_reg_item_t * list;
09457
09458 if(!handle)
09459 return -RSBAC_EINVALIDVALUE;
09460 if(!list_initialized)
09461 return -RSBAC_ENOTINITIALIZED;
09462
09463 list = (struct rsbac_list_lol_reg_item_t *) handle;
09464 if(list->self != list)
09465 return -RSBAC_EINVALIDVALUE;
09466
09467 #ifdef CONFIG_RSBAC_LIST_TRANS
09468 if(ta_number)
09469 {
09470 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09471 return -RSBAC_EINVALIDTRANSACTION;
09472 }
09473 #endif
09474
09475
09476
09477
09478
09479
09480
09481
09482 #ifdef CONFIG_RSBAC_LIST_TRANS
09483 if(ta_number && (list->ta_copied == ta_number))
09484 return list->ta_count;
09485 else
09486 #endif
09487 return list->count;
09488 }
09489
09490 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09491 EXPORT_SYMBOL(rsbac_list_lol_count);
09492 #endif
09493 long rsbac_list_lol_count(rsbac_list_handle_t handle)
09494 {
09495 return rsbac_ta_list_lol_count(0, handle);
09496 }
09497
09498 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09499 EXPORT_SYMBOL(rsbac_ta_list_count);
09500 #endif
09501 long rsbac_ta_list_count(
09502 rsbac_list_ta_number_t ta_number,
09503 rsbac_list_handle_t handle)
09504 {
09505 struct rsbac_list_reg_item_t * list;
09506
09507 if(!handle)
09508 return -RSBAC_EINVALIDVALUE;
09509 if(!list_initialized)
09510 return -RSBAC_ENOTINITIALIZED;
09511
09512 list = (struct rsbac_list_reg_item_t *) handle;
09513 if(list->self != list)
09514 return -RSBAC_EINVALIDVALUE;
09515
09516 #ifdef CONFIG_RSBAC_LIST_TRANS
09517 if(ta_number)
09518 {
09519 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09520 return -RSBAC_EINVALIDTRANSACTION;
09521 }
09522 #endif
09523
09524 #ifdef CONFIG_RSBAC_LIST_TRANS
09525 if(ta_number && (list->ta_copied == ta_number))
09526 return list->ta_count;
09527 else
09528 #endif
09529 return list->count;
09530 }
09531
09532 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09533 EXPORT_SYMBOL(rsbac_list_count);
09534 #endif
09535 long rsbac_list_count(rsbac_list_handle_t handle)
09536 {
09537 return rsbac_ta_list_count(0, handle);
09538 }
09539
09540
09541
09542
09543
09544
09545
09546 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09547 EXPORT_SYMBOL(rsbac_ta_list_get_all_desc);
09548 #endif
09549 long rsbac_ta_list_get_all_desc(
09550 rsbac_list_ta_number_t ta_number,
09551 rsbac_list_handle_t handle,
09552 void ** array_p)
09553 {
09554 struct rsbac_list_reg_item_t * list;
09555 struct rsbac_list_item_t * item_p;
09556 char * buffer;
09557 u_long lock_flags, rlock_flags;
09558 u_long offset = 0;
09559 long result = 0;
09560 u_int item_size;
09561
09562 if(!handle)
09563 return -RSBAC_EINVALIDVALUE;
09564 if(!array_p)
09565 return -RSBAC_EINVALIDVALUE;
09566 if(!list_initialized)
09567 return -RSBAC_ENOTINITIALIZED;
09568
09569 list = (struct rsbac_list_reg_item_t *) handle;
09570 if(list->self != list)
09571 return -RSBAC_EINVALIDVALUE;
09572 *array_p = NULL;
09573
09574 #ifdef CONFIG_RSBAC_LIST_TRANS
09575 if(ta_number)
09576 {
09577 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09578 return -RSBAC_EINVALIDTRANSACTION;
09579 }
09580 #endif
09581
09582 rsbac_read_lock(®_head.lock, &rlock_flags);
09583
09584
09585
09586
09587
09588
09589
09590 rsbac_read_lock(&list->lock, &lock_flags);
09591 #ifdef CONFIG_RSBAC_LIST_TRANS
09592 if(ta_number && (list->ta_copied == ta_number))
09593 {
09594 if(list->ta_count)
09595 {
09596 item_size = list->info.desc_size;
09597 buffer = rsbac_vmalloc(item_size * list->ta_count);
09598 if(buffer)
09599 {
09600 item_p = list->ta_head;
09601 while(item_p)
09602 {
09603 if( !item_p->max_age
09604 || (item_p->max_age > RSBAC_CURRENT_TIME)
09605 )
09606 {
09607 memcpy(buffer + offset,
09608 ((char *) item_p) + sizeof(*item_p),
09609 item_size);
09610 offset += item_size;
09611 result++;
09612 }
09613 item_p = item_p->next;
09614 }
09615 *array_p = buffer;
09616 }
09617 else
09618 {
09619 result = -RSBAC_ENOMEM;
09620 }
09621 }
09622 }
09623 else
09624 #endif
09625 if(list->count)
09626 {
09627 item_size = list->info.desc_size;
09628 buffer = rsbac_vmalloc(item_size * list->count);
09629 if(buffer)
09630 {
09631 item_p = list->head;
09632 while(item_p)
09633 {
09634 if( !item_p->max_age
09635 || (item_p->max_age > RSBAC_CURRENT_TIME)
09636 )
09637 {
09638 memcpy(buffer + offset,
09639 ((char *) item_p) + sizeof(*item_p),
09640 item_size);
09641 offset += item_size;
09642 result++;
09643 }
09644 item_p = item_p->next;
09645 }
09646 *array_p = buffer;
09647 }
09648 else
09649 {
09650 result = -RSBAC_ENOMEM;
09651 }
09652 }
09653 rsbac_read_unlock(&list->lock, &lock_flags);
09654 rsbac_read_unlock(®_head.lock, &rlock_flags);
09655 return result;
09656 }
09657
09658 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09659 EXPORT_SYMBOL(rsbac_list_get_all_desc);
09660 #endif
09661 long rsbac_list_get_all_desc(
09662 rsbac_list_handle_t handle,
09663 void ** array_p)
09664 {
09665 return rsbac_ta_list_get_all_desc(0, handle, array_p);
09666 }
09667
09668 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09669 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdesc_ttl);
09670 #endif
09671 long rsbac_ta_list_lol_get_all_subdesc_ttl(
09672 rsbac_list_ta_number_t ta_number,
09673 rsbac_list_handle_t handle,
09674 void * desc,
09675 void ** array_p,
09676 rsbac_time_t ** ttl_array_p)
09677 {
09678 struct rsbac_list_lol_reg_item_t * list;
09679 struct rsbac_list_lol_item_t * sublist;
09680 struct rsbac_list_item_t * item_p;
09681 char * buffer;
09682 rsbac_time_t * ttl_p = NULL;
09683 u_long lock_flags, rlock_flags;
09684 u_long offset = 0;
09685 long result = 0;
09686 u_int item_size;
09687
09688 if(!handle)
09689 return -RSBAC_EINVALIDVALUE;
09690 if(!array_p)
09691 return -RSBAC_EINVALIDVALUE;
09692 if(!list_initialized)
09693 return -RSBAC_ENOTINITIALIZED;
09694
09695 list = (struct rsbac_list_lol_reg_item_t *) handle;
09696 if(list->self != list)
09697 return -RSBAC_EINVALIDVALUE;
09698 *array_p = NULL;
09699
09700 #ifdef CONFIG_RSBAC_LIST_TRANS
09701 if(ta_number)
09702 {
09703 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09704 return -RSBAC_EINVALIDTRANSACTION;
09705 }
09706 #endif
09707
09708 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09709
09710
09711
09712
09713
09714
09715
09716 rsbac_read_lock(&list->lock, &lock_flags);
09717 #ifdef CONFIG_RSBAC_LIST_TRANS
09718 if(ta_number && (list->ta_copied == ta_number))
09719 sublist = ta_lookup_lol_item(ta_number, list, desc);
09720 else
09721 #endif
09722 sublist = lookup_lol_item(list, desc);
09723 if(sublist && sublist->count)
09724 {
09725 item_size = list->info.subdesc_size;
09726 buffer = rsbac_vmalloc(item_size * sublist->count);
09727 if(buffer)
09728 {
09729 if(ttl_array_p)
09730 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
09731 item_p = sublist->head;
09732 while(item_p)
09733 {
09734 if( !item_p->max_age
09735 || (item_p->max_age > RSBAC_CURRENT_TIME)
09736 )
09737 {
09738 memcpy(buffer + offset,
09739 ((char *) item_p) + sizeof(*item_p),
09740 item_size);
09741 if(ttl_p)
09742 {
09743 if(item_p->max_age)
09744 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
09745 else
09746 ttl_p[result] = 0;
09747 }
09748 offset += item_size;
09749 result++;
09750 }
09751 item_p = item_p->next;
09752 }
09753 *array_p = buffer;
09754 if(ttl_array_p)
09755 *ttl_array_p = ttl_p;
09756 }
09757 else
09758 {
09759 result = -RSBAC_ENOMEM;
09760 }
09761 }
09762 rsbac_read_unlock(&list->lock, &lock_flags);
09763 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09764 return result;
09765 }
09766
09767 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09768 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc_ttl);
09769 #endif
09770 long rsbac_list_lol_get_all_subdesc_ttl(
09771 rsbac_list_handle_t handle,
09772 void * desc,
09773 void ** array_p,
09774 rsbac_time_t ** ttl_array_p)
09775 {
09776 return rsbac_ta_list_lol_get_all_subdesc_ttl(0,
09777 handle,
09778 desc,
09779 array_p,
09780 ttl_array_p);
09781 }
09782
09783 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09784 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc);
09785 #endif
09786 long rsbac_list_lol_get_all_subdesc(rsbac_list_handle_t handle, void * desc, void ** array_p)
09787 {
09788 return rsbac_ta_list_lol_get_all_subdesc_ttl(0, handle,
09789 desc, array_p, NULL);
09790 }
09791
09792 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09793 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_desc);
09794 #endif
09795 long rsbac_ta_list_lol_get_all_desc(
09796 rsbac_list_ta_number_t ta_number,
09797 rsbac_list_handle_t handle,
09798 void ** array_p)
09799 {
09800 struct rsbac_list_lol_reg_item_t * list;
09801 struct rsbac_list_lol_item_t * item_p;
09802 char * buffer;
09803 u_long lock_flags, rlock_flags;
09804 u_long offset = 0;
09805 long result = 0;
09806 u_int item_size;
09807
09808 if(!handle)
09809 return -RSBAC_EINVALIDVALUE;
09810 if(!array_p)
09811 return -RSBAC_EINVALIDVALUE;
09812 if(!list_initialized)
09813 return -RSBAC_ENOTINITIALIZED;
09814
09815 list = (struct rsbac_list_lol_reg_item_t *) handle;
09816 if(list->self != list)
09817 return -RSBAC_EINVALIDVALUE;
09818 *array_p = NULL;
09819
09820 #ifdef CONFIG_RSBAC_LIST_TRANS
09821 if(ta_number)
09822 {
09823 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09824 return -RSBAC_EINVALIDTRANSACTION;
09825 }
09826 #endif
09827
09828 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09829
09830
09831
09832
09833
09834
09835
09836 rsbac_read_lock(&list->lock, &lock_flags);
09837 #ifdef CONFIG_RSBAC_LIST_TRANS
09838 if(ta_number && (list->ta_copied == ta_number))
09839 {
09840 if(list->ta_count)
09841 {
09842 item_size = list->info.desc_size;
09843 buffer = rsbac_vmalloc(item_size * list->ta_count);
09844 if(buffer)
09845 {
09846 item_p = list->ta_head;
09847 while(item_p)
09848 {
09849 if( !item_p->max_age
09850 || (item_p->max_age > RSBAC_CURRENT_TIME)
09851 )
09852 {
09853 memcpy(buffer + offset,
09854 ((char *) item_p) + sizeof(*item_p),
09855 item_size);
09856 offset += item_size;
09857 result++;
09858 }
09859 item_p = item_p->next;
09860 }
09861 *array_p = buffer;
09862 }
09863 else
09864 {
09865 result = -RSBAC_ENOMEM;
09866 }
09867 }
09868 }
09869 else
09870 #endif
09871 if(list->count)
09872 {
09873 item_size = list->info.desc_size;
09874 buffer = rsbac_vmalloc(item_size * list->count);
09875 if(buffer)
09876 {
09877 item_p = list->head;
09878 while(item_p)
09879 {
09880 if( !item_p->max_age
09881 || (item_p->max_age > RSBAC_CURRENT_TIME)
09882 )
09883 {
09884 memcpy(buffer + offset,
09885 ((char *) item_p) + sizeof(*item_p),
09886 item_size);
09887 offset += item_size;
09888 result++;
09889 }
09890 item_p = item_p->next;
09891 }
09892 *array_p = buffer;
09893 }
09894 else
09895 {
09896 result = -RSBAC_ENOMEM;
09897 }
09898 }
09899 rsbac_read_unlock(&list->lock, &lock_flags);
09900 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09901 return result;
09902 }
09903
09904 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09905 EXPORT_SYMBOL(rsbac_list_lol_get_all_desc);
09906 #endif
09907 long rsbac_list_lol_get_all_desc(rsbac_list_handle_t handle, void ** array_p)
09908 {
09909 return rsbac_ta_list_lol_get_all_desc(0, handle, array_p);
09910 }
09911
09912
09913
09914
09915
09916
09917 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09918 EXPORT_SYMBOL(rsbac_ta_list_get_all_data);
09919 #endif
09920 long rsbac_ta_list_get_all_data(
09921 rsbac_list_ta_number_t ta_number,
09922 rsbac_list_handle_t handle,
09923 void ** array_p)
09924 {
09925 struct rsbac_list_reg_item_t * list;
09926 struct rsbac_list_item_t * item_p;
09927 char * buffer;
09928 u_long lock_flags, rlock_flags;
09929 u_long offset = 0;
09930 long result = 0;
09931 u_int item_size;
09932 u_int item_offset;
09933
09934 if(!handle)
09935 return -RSBAC_EINVALIDVALUE;
09936 if(!array_p)
09937 return -RSBAC_EINVALIDVALUE;
09938 if(!list_initialized)
09939 return -RSBAC_ENOTINITIALIZED;
09940
09941 list = (struct rsbac_list_reg_item_t *) handle;
09942 if(list->self != list)
09943 return -RSBAC_EINVALIDVALUE;
09944 *array_p = NULL;
09945
09946 #ifdef CONFIG_RSBAC_LIST_TRANS
09947 if(ta_number)
09948 {
09949 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09950 return -RSBAC_EINVALIDTRANSACTION;
09951 }
09952 #endif
09953
09954 rsbac_read_lock(®_head.lock, &rlock_flags);
09955
09956
09957
09958
09959
09960
09961
09962 rsbac_read_lock(&list->lock, &lock_flags);
09963 if(!list->info.data_size)
09964 {
09965 rsbac_read_unlock(&list->lock, &lock_flags);
09966 rsbac_read_unlock(®_head.lock, &rlock_flags);
09967 return -RSBAC_EINVALIDREQUEST;
09968 }
09969 #ifdef CONFIG_RSBAC_LIST_TRANS
09970 if(ta_number && (list->ta_copied == ta_number))
09971 {
09972 if(list->ta_count)
09973 {
09974 item_size = list->info.data_size;
09975 item_offset = list->info.desc_size;
09976 buffer = rsbac_vmalloc(item_size * list->ta_count);
09977 if(buffer)
09978 {
09979 item_p = list->ta_head;
09980 while(item_p)
09981 {
09982 if( !item_p->max_age
09983 || (item_p->max_age > RSBAC_CURRENT_TIME)
09984 )
09985 {
09986 memcpy(buffer + offset,
09987 ((char *) item_p) + sizeof(*item_p) + item_offset,
09988 item_size);
09989 offset += item_size;
09990 result++;
09991 }
09992 item_p = item_p->next;
09993 }
09994 *array_p = buffer;
09995 }
09996 else
09997 {
09998 result = -RSBAC_ENOMEM;
09999 }
10000 }
10001 }
10002 else
10003 #endif
10004 if(list->count)
10005 {
10006 item_size = list->info.data_size;
10007 item_offset = list->info.desc_size;
10008 buffer = rsbac_vmalloc(item_size * list->count);
10009 if(buffer)
10010 {
10011 item_p = list->head;
10012 while(item_p)
10013 {
10014 if( !item_p->max_age
10015 || (item_p->max_age > RSBAC_CURRENT_TIME)
10016 )
10017 {
10018 memcpy(buffer + offset,
10019 ((char *) item_p) + sizeof(*item_p) + item_offset,
10020 item_size);
10021 offset += item_size;
10022 result++;
10023 }
10024 item_p = item_p->next;
10025 }
10026 *array_p = buffer;
10027 }
10028 else
10029 {
10030 result = -RSBAC_ENOMEM;
10031 }
10032 }
10033 rsbac_read_unlock(&list->lock, &lock_flags);
10034 rsbac_read_unlock(®_head.lock, &rlock_flags);
10035 return result;
10036 }
10037
10038 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10039 EXPORT_SYMBOL(rsbac_list_get_all_data);
10040 #endif
10041 long rsbac_list_get_all_data(
10042 rsbac_list_handle_t handle,
10043 void ** array_p)
10044 {
10045 return rsbac_ta_list_get_all_data(0, handle, array_p);
10046 }
10047
10048 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10049 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdata);
10050 #endif
10051 long rsbac_ta_list_lol_get_all_subdata(
10052 rsbac_list_ta_number_t ta_number,
10053 rsbac_list_handle_t handle,
10054 void * desc,
10055 void ** array_p)
10056 {
10057 struct rsbac_list_lol_reg_item_t * list;
10058 struct rsbac_list_lol_item_t * sublist;
10059 struct rsbac_list_item_t * item_p;
10060 char * buffer;
10061 u_long lock_flags, rlock_flags;
10062 u_long offset = 0;
10063 long result = 0;
10064 u_int item_size;
10065 u_int item_offset;
10066
10067 if(!handle)
10068 return -RSBAC_EINVALIDVALUE;
10069 if(!array_p)
10070 return -RSBAC_EINVALIDVALUE;
10071 if(!list_initialized)
10072 return -RSBAC_ENOTINITIALIZED;
10073
10074 list = (struct rsbac_list_lol_reg_item_t *) handle;
10075 if(list->self != list)
10076 return -RSBAC_EINVALIDVALUE;
10077 *array_p = NULL;
10078
10079 #ifdef CONFIG_RSBAC_LIST_TRANS
10080 if(ta_number)
10081 {
10082 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10083 return -RSBAC_EINVALIDTRANSACTION;
10084 }
10085 #endif
10086
10087 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10088
10089
10090
10091
10092
10093
10094
10095 rsbac_read_lock(&list->lock, &lock_flags);
10096 if(!list->info.subdata_size)
10097 {
10098 rsbac_read_unlock(&list->lock, &lock_flags);
10099 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10100 return -RSBAC_EINVALIDREQUEST;
10101 }
10102 #ifdef CONFIG_RSBAC_LIST_TRANS
10103 if(ta_number && (list->ta_copied == ta_number))
10104 sublist = ta_lookup_lol_item(ta_number, list, desc);
10105 else
10106 #endif
10107 sublist = lookup_lol_item(list, desc);
10108 if(sublist && sublist->count)
10109 {
10110 item_size = list->info.subdata_size;
10111 item_offset = list->info.subdesc_size;
10112 buffer = rsbac_vmalloc(item_size * sublist->count);
10113 if(buffer)
10114 {
10115 item_p = sublist->head;
10116 while(item_p)
10117 {
10118 if( !item_p->max_age
10119 || (item_p->max_age > RSBAC_CURRENT_TIME)
10120 )
10121 {
10122 memcpy(buffer + offset,
10123 ((char *) item_p) + sizeof(*item_p) + item_offset,
10124 item_size);
10125 offset += item_size;
10126 result++;
10127 }
10128 item_p = item_p->next;
10129 }
10130 *array_p = buffer;
10131 }
10132 else
10133 {
10134 result = -RSBAC_ENOMEM;
10135 }
10136 }
10137 rsbac_read_unlock(&list->lock, &lock_flags);
10138 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10139 return result;
10140 }
10141
10142 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10143 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdata);
10144 #endif
10145 long rsbac_list_lol_get_all_subdata(
10146 rsbac_list_handle_t handle,
10147 void * desc,
10148 void ** array_p)
10149 {
10150 return rsbac_ta_list_lol_get_all_subdata(0, handle, desc, array_p);
10151 }
10152
10153 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10154 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_data);
10155 #endif
10156 long rsbac_ta_list_lol_get_all_data(
10157 rsbac_list_ta_number_t ta_number,
10158 rsbac_list_handle_t handle,
10159 void ** array_p)
10160 {
10161 struct rsbac_list_lol_reg_item_t * list;
10162 struct rsbac_list_lol_item_t * item_p;
10163 char * buffer;
10164 u_long lock_flags, rlock_flags;
10165 u_long offset = 0;
10166 long result = 0;
10167 u_int item_size;
10168 u_int item_offset;
10169
10170 if(!handle)
10171 return -RSBAC_EINVALIDVALUE;
10172 if(!array_p)
10173 return -RSBAC_EINVALIDVALUE;
10174 if(!list_initialized)
10175 return -RSBAC_ENOTINITIALIZED;
10176
10177 list = (struct rsbac_list_lol_reg_item_t *) handle;
10178 if(list->self != list)
10179 return -RSBAC_EINVALIDVALUE;
10180 *array_p = NULL;
10181
10182 #ifdef CONFIG_RSBAC_LIST_TRANS
10183 if(ta_number)
10184 {
10185 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10186 return -RSBAC_EINVALIDTRANSACTION;
10187 }
10188 #endif
10189
10190 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10191
10192
10193
10194
10195
10196
10197
10198 rsbac_read_lock(&list->lock, &lock_flags);
10199 if(!list->info.data_size)
10200 {
10201 rsbac_read_unlock(&list->lock, &lock_flags);
10202 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10203 return -RSBAC_EINVALIDREQUEST;
10204 }
10205 #ifdef CONFIG_RSBAC_LIST_TRANS
10206 if(ta_number && (list->ta_copied == ta_number))
10207 {
10208 if(list->ta_count)
10209 {
10210 item_size = list->info.data_size;
10211 item_offset = list->info.desc_size;
10212 buffer = rsbac_vmalloc(item_size * list->ta_count);
10213 if(buffer)
10214 {
10215 item_p = list->ta_head;
10216 while(item_p)
10217 {
10218 if( !item_p->max_age
10219 || (item_p->max_age > RSBAC_CURRENT_TIME)
10220 )
10221 {
10222 memcpy(buffer + offset,
10223 ((char *) item_p) + sizeof(*item_p) + item_offset,
10224 item_size);
10225 offset += item_size;
10226 result++;
10227 }
10228 item_p = item_p->next;
10229 }
10230 *array_p = buffer;
10231 }
10232 else
10233 {
10234 result = -RSBAC_ENOMEM;
10235 }
10236 }
10237 }
10238 else
10239 #endif
10240 if(list->count)
10241 {
10242 item_size = list->info.data_size;
10243 item_offset = list->info.desc_size;
10244 buffer = rsbac_vmalloc(item_size * list->count);
10245 if(buffer)
10246 {
10247 item_p = list->head;
10248 while(item_p)
10249 {
10250 if( !item_p->max_age
10251 || (item_p->max_age > RSBAC_CURRENT_TIME)
10252 )
10253 {
10254 memcpy(buffer + offset,
10255 ((char *) item_p) + sizeof(*item_p) + item_offset,
10256 item_size);
10257 offset += item_size;
10258 result++;
10259 }
10260 item_p = item_p->next;
10261 }
10262 *array_p = buffer;
10263 }
10264 else
10265 {
10266 result = -RSBAC_ENOMEM;
10267 }
10268 }
10269 rsbac_read_unlock(&list->lock, &lock_flags);
10270 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10271 return result;
10272 }
10273
10274 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10275 EXPORT_SYMBOL(rsbac_list_lol_get_all_data);
10276 #endif
10277 long rsbac_list_lol_get_all_data(
10278 rsbac_list_handle_t handle,
10279 void ** array_p)
10280 {
10281 return rsbac_ta_list_lol_get_all_data(0, handle, array_p);
10282 }
10283
10284
10285
10286 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10287 EXPORT_SYMBOL(rsbac_list_get_item_size);
10288 #endif
10289 int rsbac_list_get_item_size(rsbac_list_handle_t handle)
10290 {
10291 struct rsbac_list_reg_item_t * list;
10292
10293 if(!handle)
10294 return -RSBAC_EINVALIDVALUE;
10295 if(!list_initialized)
10296 return -RSBAC_ENOTINITIALIZED;
10297
10298 list = (struct rsbac_list_reg_item_t *) handle;
10299 if(list->self != list)
10300 return -RSBAC_EINVALIDVALUE;
10301 return list->info.desc_size + list->info.data_size;
10302 }
10303
10304 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10305 EXPORT_SYMBOL(rsbac_list_lol_get_subitem_size);
10306 #endif
10307 int rsbac_list_lol_get_subitem_size(rsbac_list_handle_t handle)
10308 {
10309 struct rsbac_list_lol_reg_item_t * list;
10310
10311 if(!handle)
10312 return -RSBAC_EINVALIDVALUE;
10313 if(!list_initialized)
10314 return -RSBAC_ENOTINITIALIZED;
10315
10316 list = (struct rsbac_list_lol_reg_item_t *) handle;
10317 if(list->self != list)
10318 return -RSBAC_EINVALIDVALUE;
10319 return list->info.subdesc_size + list->info.subdata_size;
10320 }
10321
10322 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10323 EXPORT_SYMBOL(rsbac_list_lol_get_item_size);
10324 #endif
10325 int rsbac_list_lol_get_item_size(rsbac_list_handle_t handle)
10326 {
10327 struct rsbac_list_lol_reg_item_t * list;
10328
10329 if(!handle)
10330 return -RSBAC_EINVALIDVALUE;
10331 if(!list_initialized)
10332 return -RSBAC_ENOTINITIALIZED;
10333
10334 list = (struct rsbac_list_lol_reg_item_t *) handle;
10335 if(list->self != list)
10336 return -RSBAC_EINVALIDVALUE;
10337 return list->info.desc_size + list->info.data_size;
10338 }
10339
10340
10341
10342
10343
10344
10345
10346 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10347 EXPORT_SYMBOL(rsbac_ta_list_get_all_items_ttl);
10348 #endif
10349 long rsbac_ta_list_get_all_items_ttl(
10350 rsbac_list_ta_number_t ta_number,
10351 rsbac_list_handle_t handle,
10352 void ** array_p,
10353 rsbac_time_t ** ttl_array_p)
10354 {
10355 struct rsbac_list_reg_item_t * list;
10356 struct rsbac_list_item_t * item_p;
10357 char * buffer;
10358 rsbac_time_t * ttl_p = NULL;
10359 u_long lock_flags, rlock_flags;
10360 u_long offset = 0;
10361 long result = 0;
10362 u_int item_size;
10363
10364 if(!handle)
10365 return -RSBAC_EINVALIDVALUE;
10366 if(!array_p)
10367 return -RSBAC_EINVALIDPOINTER;
10368 if(!list_initialized)
10369 return -RSBAC_ENOTINITIALIZED;
10370
10371 list = (struct rsbac_list_reg_item_t *) handle;
10372 if(list->self != list)
10373 return -RSBAC_EINVALIDVALUE;
10374 *array_p = NULL;
10375
10376 #ifdef CONFIG_RSBAC_LIST_TRANS
10377 if(ta_number)
10378 {
10379 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10380 return -RSBAC_EINVALIDTRANSACTION;
10381 }
10382 #endif
10383
10384 rsbac_read_lock(®_head.lock, &rlock_flags);
10385
10386
10387
10388
10389
10390
10391
10392 rsbac_read_lock(&list->lock, &lock_flags);
10393 #ifdef CONFIG_RSBAC_LIST_TRANS
10394 if(ta_number && (list->ta_copied == ta_number))
10395 {
10396 if(list->ta_count)
10397 {
10398 item_size = list->info.desc_size + list->info.data_size;
10399 buffer = rsbac_vmalloc(item_size * list->ta_count);
10400 if(buffer)
10401 {
10402 if(ttl_array_p)
10403 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->ta_count);
10404 item_p = list->ta_head;
10405 while(item_p)
10406 {
10407 if( !item_p->max_age
10408 || (item_p->max_age > RSBAC_CURRENT_TIME)
10409 )
10410 {
10411 memcpy(buffer + offset,
10412 ((char *) item_p) + sizeof(*item_p),
10413 item_size);
10414 if(ttl_p)
10415 {
10416 if(item_p->max_age)
10417 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10418 else
10419 ttl_p[result] = 0;
10420 }
10421 offset += item_size;
10422 result++;
10423 }
10424 item_p = item_p->next;
10425 }
10426 *array_p = buffer;
10427 if(ttl_array_p)
10428 *ttl_array_p = ttl_p;
10429 }
10430 else
10431 {
10432 result = -RSBAC_ENOMEM;
10433 }
10434 }
10435 }
10436 else
10437 #endif
10438 if(list->count)
10439 {
10440 item_size = list->info.desc_size + list->info.data_size;
10441 buffer = rsbac_vmalloc(item_size * list->count);
10442 if(buffer)
10443 {
10444 if(ttl_array_p)
10445 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->count);
10446 item_p = list->head;
10447 while(item_p)
10448 {
10449 if( !item_p->max_age
10450 || (item_p->max_age > RSBAC_CURRENT_TIME)
10451 )
10452 {
10453 memcpy(buffer + offset,
10454 ((char *) item_p) + sizeof(*item_p),
10455 item_size);
10456 if(ttl_p)
10457 {
10458 if(item_p->max_age)
10459 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10460 else
10461 ttl_p[result] = 0;
10462 }
10463 offset += item_size;
10464 result++;
10465 }
10466 item_p = item_p->next;
10467 }
10468 *array_p = buffer;
10469 if(ttl_array_p)
10470 *ttl_array_p = ttl_p;
10471 }
10472 else
10473 {
10474 result = -RSBAC_ENOMEM;
10475 }
10476 }
10477 rsbac_read_unlock(&list->lock, &lock_flags);
10478 rsbac_read_unlock(®_head.lock, &rlock_flags);
10479 return result;
10480 }
10481
10482 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10483 EXPORT_SYMBOL(rsbac_list_get_all_items_ttl);
10484 #endif
10485 long rsbac_list_get_all_items_ttl(
10486 rsbac_list_handle_t handle,
10487 void ** array_p,
10488 rsbac_time_t ** ttl_array_p)
10489 {
10490 return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, ttl_array_p);
10491 }
10492
10493 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10494 EXPORT_SYMBOL(rsbac_list_get_all_items);
10495 #endif
10496 long rsbac_list_get_all_items(rsbac_list_handle_t handle, void ** array_p)
10497 {
10498 return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, NULL);
10499 }
10500
10501 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10502 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subitems_ttl);
10503 #endif
10504 long rsbac_ta_list_lol_get_all_subitems_ttl(
10505 rsbac_list_ta_number_t ta_number,
10506 rsbac_list_handle_t handle,
10507 void * desc,
10508 void ** array_p,
10509 rsbac_time_t ** ttl_array_p)
10510 {
10511 struct rsbac_list_lol_reg_item_t * list;
10512 struct rsbac_list_lol_item_t * sublist;
10513 struct rsbac_list_item_t * item_p;
10514 char * buffer;
10515 rsbac_time_t * ttl_p = NULL;
10516 u_long lock_flags, rlock_flags;
10517 u_long offset = 0;
10518 long result = 0;
10519 u_int item_size;
10520
10521 if(!handle)
10522 return -RSBAC_EINVALIDVALUE;
10523 if(!array_p)
10524 return -RSBAC_EINVALIDVALUE;
10525 if(!list_initialized)
10526 return -RSBAC_ENOTINITIALIZED;
10527
10528 list = (struct rsbac_list_lol_reg_item_t *) handle;
10529 if(list->self != list)
10530 return -RSBAC_EINVALIDVALUE;
10531 *array_p = NULL;
10532
10533 #ifdef CONFIG_RSBAC_LIST_TRANS
10534 if(ta_number)
10535 {
10536 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10537 return -RSBAC_EINVALIDTRANSACTION;
10538 }
10539 #endif
10540
10541 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10542
10543
10544
10545
10546
10547
10548
10549 rsbac_read_lock(&list->lock, &lock_flags);
10550 #ifdef CONFIG_RSBAC_LIST_TRANS
10551 if(ta_number && (list->ta_copied == ta_number))
10552 sublist = ta_lookup_lol_item(ta_number, list, desc);
10553 else
10554 #endif
10555 sublist = lookup_lol_item(list, desc);
10556 if(sublist && sublist->count)
10557 {
10558 item_size = list->info.subdesc_size + list->info.subdata_size;
10559 buffer = rsbac_vmalloc(item_size * sublist->count);
10560 if(buffer)
10561 {
10562 if(ttl_array_p)
10563 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
10564 item_p = sublist->head;
10565 while(item_p)
10566 {
10567 if( !item_p->max_age
10568 || (item_p->max_age > RSBAC_CURRENT_TIME)
10569 )
10570 {
10571 memcpy(buffer + offset,
10572 ((char *) item_p) + sizeof(*item_p),
10573 item_size);
10574 if(ttl_p)
10575 {
10576 if(item_p->max_age)
10577 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10578 else
10579 ttl_p[result] = 0;
10580 }
10581 offset += item_size;
10582 result++;
10583 }
10584 item_p = item_p->next;
10585 }
10586 *array_p = buffer;
10587 if(ttl_array_p)
10588 *ttl_array_p = ttl_p;
10589 }
10590 else
10591 {
10592 result = -RSBAC_ENOMEM;
10593 }
10594 }
10595 rsbac_read_unlock(&list->lock, &lock_flags);
10596 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10597 return result;
10598 }
10599
10600 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10601 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems_ttl);
10602 #endif
10603 long rsbac_list_lol_get_all_subitems_ttl(
10604 rsbac_list_handle_t handle,
10605 void * desc,
10606 void ** array_p,
10607 rsbac_time_t ** ttl_array_p)
10608 {
10609 return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10610 array_p, ttl_array_p);
10611 }
10612
10613 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10614 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems);
10615 #endif
10616 long rsbac_list_lol_get_all_subitems(rsbac_list_handle_t handle, void * desc, void ** array_p)
10617 {
10618 return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10619 array_p, NULL);
10620 }
10621
10622 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10623 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_items);
10624 #endif
10625 long rsbac_ta_list_lol_get_all_items(
10626 rsbac_list_ta_number_t ta_number,
10627 rsbac_list_handle_t handle,
10628 void ** array_p)
10629 {
10630 struct rsbac_list_lol_reg_item_t * list;
10631 struct rsbac_list_lol_item_t * item_p;
10632 char * buffer;
10633 u_long lock_flags, rlock_flags;
10634 u_long offset = 0;
10635 long result = 0;
10636 u_int item_size;
10637
10638 if(!handle)
10639 return -RSBAC_EINVALIDVALUE;
10640 if(!array_p)
10641 return -RSBAC_EINVALIDVALUE;
10642 if(!list_initialized)
10643 return -RSBAC_ENOTINITIALIZED;
10644
10645 list = (struct rsbac_list_lol_reg_item_t *) handle;
10646 if(list->self != list)
10647 return -RSBAC_EINVALIDVALUE;
10648 *array_p = NULL;
10649
10650 #ifdef CONFIG_RSBAC_LIST_TRANS
10651 if(ta_number)
10652 {
10653 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10654 return -RSBAC_EINVALIDTRANSACTION;
10655 }
10656 #endif
10657
10658 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10659
10660
10661
10662
10663
10664
10665
10666 rsbac_read_lock(&list->lock, &lock_flags);
10667 #ifdef CONFIG_RSBAC_LIST_TRANS
10668 if(ta_number && (list->ta_copied == ta_number))
10669 {
10670 if(list->ta_count)
10671 {
10672 item_size = list->info.desc_size + list->info.data_size;
10673 buffer = rsbac_vmalloc(item_size * list->ta_count);
10674 if(buffer)
10675 {
10676 item_p = list->ta_head;
10677 while(item_p)
10678 {
10679 if( !item_p->max_age
10680 || (item_p->max_age > RSBAC_CURRENT_TIME)
10681 )
10682 {
10683 memcpy(buffer + offset,
10684 ((char *) item_p) + sizeof(*item_p),
10685 item_size);
10686 offset += item_size;
10687 result++;
10688 }
10689 item_p = item_p->next;
10690 }
10691 *array_p = buffer;
10692 }
10693 else
10694 {
10695 result = -RSBAC_ENOMEM;
10696 }
10697 }
10698 }
10699 else
10700 #endif
10701 if(list->count)
10702 {
10703 item_size = list->info.desc_size + list->info.data_size;
10704 buffer = rsbac_vmalloc(item_size * list->count);
10705 if(buffer)
10706 {
10707 item_p = list->head;
10708 while(item_p)
10709 {
10710 if( !item_p->max_age
10711 || (item_p->max_age > RSBAC_CURRENT_TIME)
10712 )
10713 {
10714 memcpy(buffer + offset,
10715 ((char *) item_p) + sizeof(*item_p),
10716 item_size);
10717 offset += item_size;
10718 result++;
10719 }
10720 item_p = item_p->next;
10721 }
10722 *array_p = buffer;
10723 }
10724 else
10725 {
10726 result = -RSBAC_ENOMEM;
10727 }
10728 }
10729 rsbac_read_unlock(&list->lock, &lock_flags);
10730 rsbac_read_unlock(®_head.lock, &rlock_flags);
10731 return result;
10732 }
10733
10734 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10735 EXPORT_SYMBOL(rsbac_list_lol_get_all_items);
10736 #endif
10737 long rsbac_list_lol_get_all_items(
10738 rsbac_list_handle_t handle,
10739 void ** array_p)
10740 {
10741 return rsbac_ta_list_lol_get_all_items(0, handle, array_p);
10742 }
10743
10744