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 }
05304 }
05305 item_p=item_p->next;
05306 }
05307 rsbac_read_unlock(®_head.lock, &lock_flags);
05308
05309 #ifdef CONFIG_RSBAC_DEBUG
05310 if( rsbac_debug_write
05311 && (write_head.count > 0)
05312 )
05313 {
05314 rsbac_printk(KERN_DEBUG
05315 "rsbac_write_lists(): %u lists copied to buffers, total of %lu bytes\n",
05316 write_head.count,
05317 write_head.total);
05318 }
05319 #endif
05320
05321
05322 if(write_head.count)
05323 {
05324 count = rsbac_list_write_buffers(write_head, need_lock);
05325 #ifdef CONFIG_RSBAC_DEBUG
05326 if(rsbac_debug_write)
05327 {
05328 rsbac_printk(KERN_DEBUG
05329 "rsbac_write_lists(): %u lists written to disk\n",
05330 count);
05331 }
05332 #endif
05333 }
05334
05335
05336
05337 write_lol_head.head=NULL;
05338 write_lol_head.tail=NULL;
05339 write_lol_head.total=0;
05340 write_lol_head.count=0;
05341
05342 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05343 lol_item_p=lol_reg_head.head;
05344 while(lol_item_p)
05345 {
05346 if( (lol_item_p->flags & RSBAC_LIST_PERSIST)
05347 && lol_item_p->dirty
05348 && !lol_item_p->no_write
05349 )
05350 {
05351 lol_item_p->dirty = FALSE;
05352
05353 error = fill_lol_buffer(lol_item_p, &write_lol_item_p);
05354 if(!error)
05355 {
05356 if(!write_lol_head.head)
05357 {
05358 write_lol_head.head = write_lol_item_p;
05359 write_lol_head.tail = write_lol_item_p;
05360 write_lol_head.total = write_lol_item_p->buflen;
05361 write_lol_head.count = 1;
05362 }
05363 else
05364 {
05365 write_lol_head.tail->next = write_lol_item_p;
05366 write_lol_item_p->prev = write_lol_head.tail;
05367 write_lol_head.tail = write_lol_item_p;
05368 write_lol_head.total += write_lol_item_p->buflen;
05369 write_lol_head.count++;
05370 }
05371 }
05372 else
05373 {
05374 if( (error != -RSBAC_ENOTWRITABLE)
05375 && (error != -RSBAC_ENOMEM)
05376 )
05377 {
05378 rsbac_printk(KERN_WARNING
05379 "rsbac_write_lists(): fill_lol_buffer() for list %s returned error %i\n",
05380 lol_item_p->name, error);
05381 }
05382 }
05383 }
05384 lol_item_p=lol_item_p->next;
05385 }
05386 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05387
05388 #ifdef CONFIG_RSBAC_DEBUG
05389 if( rsbac_debug_write
05390 && (write_lol_head.count > 0)
05391 )
05392 {
05393 rsbac_printk(KERN_DEBUG
05394 "rsbac_write_lists(): %u lists of lists copied to buffers, total of %lu bytes\n",
05395 write_lol_head.count,
05396 write_lol_head.total);
05397 }
05398 #endif
05399
05400
05401 if(write_lol_head.count)
05402 {
05403 subcount = rsbac_list_write_lol_buffers(write_lol_head, need_lock);
05404 count += subcount;
05405 #ifdef CONFIG_RSBAC_DEBUG
05406 if(rsbac_debug_write)
05407 {
05408 rsbac_printk(KERN_DEBUG
05409 "rsbac_write_lists(): %u lists of lists written to disk\n",
05410 subcount);
05411 }
05412 #endif
05413 }
05414
05415 #ifdef CONFIG_RSBAC_DEBUG
05416 if (rsbac_debug_write)
05417 {
05418 rsbac_printk(KERN_DEBUG "rsbac_write_lists(): %u lists with a total of %lu bytes written.\n",
05419 count, write_head.total + write_lol_head.total);
05420 }
05421 #endif
05422 return count;
05423 }
05424 #endif
05425
05426
05427 int rsbac_check_lists(int correct)
05428 {
05429 struct rsbac_list_reg_item_t * list;
05430 struct rsbac_list_lol_reg_item_t * lol_list;
05431 struct rsbac_list_item_t * item_p;
05432 struct rsbac_list_item_t * next_item_p;
05433 struct rsbac_list_lol_item_t * lol_item_p;
05434 struct rsbac_list_lol_item_t * next_lol_item_p;
05435 struct rsbac_list_item_t * lol_subitem_p;
05436 struct rsbac_list_item_t * next_lol_subitem_p;
05437 u_long lock_flags, rlock_flags;
05438 u_long tmp_count;
05439 u_long tmp_subcount;
05440 u_long subitem_count;
05441 u_long dirty = 0;
05442
05443 #ifdef CONFIG_RSBAC_DEBUG
05444 if(rsbac_debug_lists)
05445 {
05446 rsbac_printk(KERN_DEBUG "rsbac_check_lists() called.\n");
05447 }
05448 #endif
05449 if(!list_initialized)
05450 return -RSBAC_ENOTINITIALIZED;
05451 rsbac_read_lock(®_head.lock, &rlock_flags);
05452 list = reg_head.head;
05453 while(list)
05454 {
05455
05456 rsbac_write_lock(&list->lock, &lock_flags);
05457 tmp_count = 0;
05458 item_p = list->head;
05459 while(item_p)
05460 {
05461 if( ( item_p->max_age
05462 && (item_p->max_age <= RSBAC_CURRENT_TIME)
05463 )
05464 || ( list->def_data
05465 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05466 list->def_data,
05467 list->info.data_size)
05468 )
05469 )
05470 {
05471 next_item_p = item_p->next;
05472 do_remove_item(list, item_p);
05473 item_p = next_item_p;
05474 }
05475 else
05476 {
05477 tmp_count++;
05478 item_p = item_p->next;
05479 }
05480 }
05481 if(tmp_count != list->count)
05482 {
05483 if(correct)
05484 {
05485 rsbac_printk(KERN_WARNING
05486 "rsbac_check_lists(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05487 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05488 list->count = tmp_count;
05489 }
05490 else
05491 {
05492 rsbac_printk(KERN_WARNING
05493 "rsbac_check_lists(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05494 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05495 }
05496 }
05497 rsbac_write_unlock(&list->lock, &lock_flags);
05498 if(list->dirty && (list->flags & RSBAC_LIST_PERSIST))
05499 {
05500 dirty++;
05501 #ifdef CONFIG_RSBAC_DEBUG
05502 if(rsbac_debug_lists)
05503 {
05504 rsbac_printk(KERN_DEBUG
05505 "rsbac_check_lists(): %s on %02u:%02u has %u items (list is dirty)\n",
05506 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05507 }
05508 #endif
05509 }
05510 #ifdef CONFIG_RSBAC_DEBUG
05511 else
05512 {
05513 if(rsbac_debug_lists)
05514 {
05515 rsbac_printk(KERN_DEBUG
05516 "rsbac_check_lists(): %s on %02u:%02u has %u items\n",
05517 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count);
05518 }
05519 }
05520 #endif
05521 list = list->next;
05522 }
05523 rsbac_read_unlock(®_head.lock, &rlock_flags);
05524
05525 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05526 lol_list = lol_reg_head.head;
05527 while(lol_list)
05528 {
05529
05530 rsbac_write_lock(&lol_list->lock, &lock_flags);
05531 tmp_count = 0;
05532 subitem_count = 0;
05533 lol_item_p = lol_list->head;
05534 while(lol_item_p)
05535 {
05536 if( ( lol_item_p->max_age
05537 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05538 )
05539 || ( lol_list->def_data
05540 && !lol_item_p->count
05541 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05542 lol_list->def_data,
05543 lol_list->info.data_size)
05544 )
05545 || ( !lol_list->info.data_size
05546 && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05547 && !lol_item_p->count
05548 )
05549 )
05550 {
05551 next_lol_item_p = lol_item_p->next;
05552 do_remove_lol_item(lol_list, lol_item_p);
05553 lol_item_p = next_lol_item_p;
05554 }
05555 else
05556 {
05557 tmp_count++;
05558 tmp_subcount = 0;
05559 lol_subitem_p = lol_item_p->head;
05560 while(lol_subitem_p)
05561 {
05562 if( ( lol_subitem_p->max_age
05563 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05564 )
05565 || ( lol_list->def_subdata
05566 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05567 lol_list->def_subdata,
05568 lol_list->info.subdata_size)
05569 )
05570 )
05571 {
05572 next_lol_subitem_p = lol_subitem_p->next;
05573 do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05574 lol_subitem_p = next_lol_subitem_p;
05575 }
05576 else
05577 {
05578 tmp_subcount++;
05579 lol_subitem_p = lol_subitem_p->next;
05580 }
05581 }
05582 if(tmp_subcount != lol_item_p->count)
05583 {
05584 if(correct)
05585 {
05586 rsbac_printk(KERN_WARNING
05587 "rsbac_check_lists(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05588 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05589 lol_item_p->count = tmp_subcount;
05590 }
05591 else
05592 {
05593 rsbac_printk(KERN_WARNING
05594 "rsbac_check_lists(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05595 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05596 }
05597 }
05598 subitem_count += lol_item_p->count;
05599 lol_item_p = lol_item_p->next;
05600 }
05601 }
05602 if(tmp_count != lol_list->count)
05603 {
05604 if(correct)
05605 {
05606 rsbac_printk(KERN_WARNING
05607 "rsbac_check_lists(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05608 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05609 lol_list->count = tmp_count;
05610 }
05611 else
05612 {
05613 rsbac_printk(KERN_WARNING
05614 "rsbac_check_lists(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05615 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05616 }
05617 }
05618 rsbac_write_unlock(&lol_list->lock, &lock_flags);
05619 if(lol_list->dirty && (lol_list->flags & RSBAC_LIST_PERSIST))
05620 {
05621 dirty++;
05622 #ifdef CONFIG_RSBAC_DEBUG
05623 if(rsbac_debug_lists)
05624 {
05625 rsbac_printk(KERN_DEBUG
05626 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems (list is dirty)\n",
05627 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05628 }
05629 #endif
05630 }
05631 #ifdef CONFIG_RSBAC_DEBUG
05632 else
05633 {
05634 if(rsbac_debug_lists)
05635 {
05636 rsbac_printk(KERN_DEBUG
05637 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems\n",
05638 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count);
05639 }
05640 }
05641 #endif
05642 lol_list = lol_list->next;
05643 }
05644 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05645 return 0;
05646 }
05647
05648 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05649 EXPORT_SYMBOL(rsbac_list_check);
05650 #endif
05651 int rsbac_list_check(
05652 rsbac_list_handle_t handle,
05653 int correct)
05654 {
05655 struct rsbac_list_reg_item_t * list;
05656 struct rsbac_list_item_t * item_p;
05657 struct rsbac_list_item_t * next_item_p;
05658 u_long lock_flags;
05659 u_long rlock_flags;
05660 u_long tmp_count;
05661
05662 if(!handle)
05663 return -RSBAC_EINVALIDVALUE;
05664 if(!list_initialized)
05665 return -RSBAC_ENOTINITIALIZED;
05666
05667 list = (struct rsbac_list_reg_item_t *) handle;
05668 if(!list || (list->self != list))
05669 return -RSBAC_EINVALIDVALUE;
05670
05671 rsbac_read_lock(®_head.lock, &rlock_flags);
05672 #ifdef CONFIG_RSBAC_DEBUG
05673 if(rsbac_debug_lists)
05674 rsbac_printk(KERN_DEBUG "rsbac_list_check: checking list %s.\n",
05675 list->name);
05676 #endif
05677 rsbac_write_lock(&list->lock, &lock_flags);
05678 tmp_count = 0;
05679 item_p = list->head;
05680 while(item_p)
05681 {
05682 if( ( item_p->max_age
05683 && (item_p->max_age <= RSBAC_CURRENT_TIME)
05684 )
05685 || ( list->def_data
05686 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
05687 list->def_data,
05688 list->info.data_size)
05689 )
05690 )
05691 {
05692 next_item_p = item_p->next;
05693 do_remove_item(list, item_p);
05694 item_p = next_item_p;
05695 list->dirty = TRUE;
05696 }
05697 else
05698 {
05699 tmp_count++;
05700 item_p = item_p->next;
05701 }
05702 }
05703 if(tmp_count != list->count)
05704 {
05705 if(correct)
05706 {
05707 rsbac_printk(KERN_WARNING
05708 "rsbac_list_check(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n",
05709 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05710 list->count = tmp_count;
05711 list->dirty = TRUE;
05712 }
05713 else
05714 {
05715 rsbac_printk(KERN_WARNING
05716 "rsbac_list_check(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n",
05717 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count);
05718 }
05719 }
05720 rsbac_write_unlock(&list->lock, &lock_flags);
05721 rsbac_read_unlock(®_head.lock, &rlock_flags);
05722 return 0;
05723 }
05724
05725 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05726 EXPORT_SYMBOL(rsbac_list_lol_check);
05727 #endif
05728 int rsbac_list_lol_check(
05729 rsbac_list_handle_t handle,
05730 int correct)
05731 {
05732 struct rsbac_list_lol_reg_item_t * lol_list;
05733 struct rsbac_list_lol_item_t * lol_item_p;
05734 struct rsbac_list_lol_item_t * next_lol_item_p;
05735 struct rsbac_list_item_t * lol_subitem_p;
05736 struct rsbac_list_item_t * next_lol_subitem_p;
05737 u_long lock_flags;
05738 u_long rlock_flags;
05739 u_long tmp_count;
05740 u_long tmp_subcount;
05741
05742 if(!handle)
05743 return -RSBAC_EINVALIDVALUE;
05744 if(!list_initialized)
05745 return -RSBAC_ENOTINITIALIZED;
05746
05747 lol_list = (struct rsbac_list_lol_reg_item_t *) handle;
05748 if(!lol_list || (lol_list->self != lol_list))
05749 return -RSBAC_EINVALIDVALUE;
05750
05751 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
05752 #ifdef CONFIG_RSBAC_DEBUG
05753 if(rsbac_debug_lists)
05754 rsbac_printk(KERN_DEBUG "rsbac_list_lol_check: checking list %s.\n",
05755 lol_list->name);
05756 #endif
05757 rsbac_write_lock(&lol_list->lock, &lock_flags);
05758 tmp_count = 0;
05759 lol_item_p = lol_list->head;
05760 while(lol_item_p)
05761 {
05762 if( ( lol_item_p->max_age
05763 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME)
05764 )
05765 || ( lol_list->def_data
05766 && !lol_item_p->count
05767 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size,
05768 lol_list->def_data,
05769 lol_list->info.data_size)
05770 )
05771 || ( !lol_list->info.data_size
05772 && (lol_list->flags & RSBAC_LIST_DEF_DATA)
05773 && !lol_item_p->count
05774 )
05775 )
05776 {
05777 next_lol_item_p = lol_item_p->next;
05778 do_remove_lol_item(lol_list, lol_item_p);
05779 lol_item_p = next_lol_item_p;
05780 }
05781 else
05782 {
05783 tmp_count++;
05784 tmp_subcount = 0;
05785 lol_subitem_p = lol_item_p->head;
05786 while(lol_subitem_p)
05787 {
05788 if( ( lol_subitem_p->max_age
05789 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME)
05790 )
05791 || ( lol_list->def_subdata
05792 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size,
05793 lol_list->def_subdata,
05794 lol_list->info.subdata_size)
05795 )
05796 )
05797 {
05798 next_lol_subitem_p = lol_subitem_p->next;
05799 do_remove_lol_subitem(lol_item_p, lol_subitem_p);
05800 lol_subitem_p = next_lol_subitem_p;
05801 }
05802 else
05803 {
05804 tmp_subcount++;
05805 lol_subitem_p = lol_subitem_p->next;
05806 }
05807 }
05808 if(tmp_subcount != lol_item_p->count)
05809 {
05810 if(correct)
05811 {
05812 rsbac_printk(KERN_WARNING
05813 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n",
05814 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05815 lol_item_p->count = tmp_subcount;
05816 }
05817 else
05818 {
05819 rsbac_printk(KERN_WARNING
05820 "rsbac_list_lol_check(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n",
05821 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount);
05822 }
05823 }
05824 lol_item_p = lol_item_p->next;
05825 }
05826 }
05827 if(tmp_count != lol_list->count)
05828 {
05829 if(correct)
05830 {
05831 rsbac_printk(KERN_WARNING
05832 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n",
05833 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05834 lol_list->count = tmp_count;
05835 }
05836 else
05837 {
05838 rsbac_printk(KERN_WARNING
05839 "rsbac_list_lol_check(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n",
05840 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count);
05841 }
05842 }
05843 rsbac_write_unlock(&lol_list->lock, &lock_flags);
05844 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
05845 return 0;
05846 }
05847
05848
05849
05850
05851
05852
05853
05854 rsbac_version_t rsbac_list_version(void)
05855 {
05856 return RSBAC_LIST_VERSION;
05857 }
05858
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 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
05884 EXPORT_SYMBOL(rsbac_list_register);
05885 #endif
05886 int rsbac_list_register(
05887 rsbac_version_t ds_version,
05888 rsbac_list_handle_t *handle_p,
05889 struct rsbac_list_info_t * info_p,
05890 u_int flags,
05891 rsbac_list_compare_function_t * compare,
05892 rsbac_list_get_conv_t * get_conv,
05893 void * def_data,
05894 char * name,
05895 kdev_t device)
05896 {
05897 struct rsbac_list_reg_item_t * reg_item_p;
05898 struct rsbac_list_reg_item_t * new_reg_item_p;
05899 u_long lock_flags;
05900 int err = 0;
05901
05902 if(ds_version != RSBAC_LIST_VERSION)
05903 {
05904 if(name)
05905 {
05906 rsbac_printk(KERN_WARNING
05907 "rsbac_list_register: wrong ds_version %u for list %s, expected %u!\n",
05908 ds_version,
05909 name,
05910 RSBAC_LIST_VERSION);
05911 }
05912 return -RSBAC_EINVALIDVERSION;
05913 }
05914 if(!handle_p || !info_p)
05915 return -RSBAC_EINVALIDPOINTER;
05916 *handle_p = NULL;
05917 if(!info_p->key || !info_p->version || !info_p->desc_size)
05918 return -RSBAC_EINVALIDVALUE;
05919 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
05920 return -RSBAC_EINVALIDVALUE;
05921 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
05922 return -RSBAC_EINVALIDVALUE;
05923 if(!list_initialized)
05924 return -RSBAC_ENOTINITIALIZED;
05925 if(name)
05926 {
05927 struct rsbac_list_lol_reg_item_t * lol_reg_item_p;
05928
05929 rsbac_read_lock(®_head.lock, &lock_flags);
05930 reg_item_p = lookup_reg_name(name, device);
05931 rsbac_read_unlock(®_head.lock, &lock_flags);
05932 if(reg_item_p)
05933 {
05934 #ifdef CONFIG_RSBAC_DEBUG
05935 if(rsbac_debug_lists)
05936 {
05937 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05938 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05939 }
05940 #endif
05941 return -RSBAC_EEXISTS;
05942 }
05943 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
05944 lol_reg_item_p = lookup_lol_reg_name(name, device);
05945 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
05946 if(lol_reg_item_p)
05947 {
05948 #ifdef CONFIG_RSBAC_DEBUG
05949 if(rsbac_debug_lists)
05950 {
05951 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
05952 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05953 }
05954 #endif
05955 return -RSBAC_EEXISTS;
05956 }
05957 }
05958 else
05959 if(flags & RSBAC_LIST_PERSIST)
05960 {
05961 rsbac_printk(KERN_WARNING
05962 "rsbac_list_register: trial to register persistent list without name.\n");
05963 return -RSBAC_EINVALIDVALUE;
05964 }
05965
05966 if(flags & RSBAC_LIST_PERSIST)
05967 {
05968 if(RSBAC_IS_AUTO_DEV(device))
05969 device = rsbac_root_dev;
05970 if(!RSBAC_MAJOR(device))
05971 flags &= ~RSBAC_LIST_PERSIST;
05972 }
05973
05974 #ifdef CONFIG_RSBAC_DEBUG
05975 if(rsbac_debug_lists)
05976 {
05977 rsbac_printk(KERN_DEBUG "rsbac_list_register: registering list %s for device %02u:%02u.\n",
05978 name, RSBAC_MAJOR(device),RSBAC_MINOR(device));
05979 }
05980 #endif
05981 new_reg_item_p = create_reg(info_p, flags, compare, get_conv, def_data, name, device);
05982 if(!new_reg_item_p)
05983 {
05984 return -RSBAC_ECOULDNOTADDITEM;
05985 }
05986
05987 if( (flags & RSBAC_LIST_PERSIST)
05988 && RSBAC_MAJOR(device)
05989 )
05990 {
05991 #ifdef CONFIG_RSBAC_DEBUG
05992 if(rsbac_debug_lists)
05993 {
05994 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u.\n",
05995 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
05996 }
05997 #endif
05998 err = read_list(new_reg_item_p);
05999
06000 if(err == -RSBAC_ENOTFOUND)
06001 err = 0;
06002 else
06003 if(err)
06004 {
06005 #ifdef CONFIG_RSBAC_DEBUG
06006 if(rsbac_debug_lists)
06007 {
06008 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06009
06010 if(tmp)
06011 {
06012 get_error_name(tmp, err);
06013 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06014 name,
06015 RSBAC_MAJOR(device),RSBAC_MINOR(device),
06016 tmp);
06017 rsbac_kfree(tmp);
06018 }
06019 }
06020 #endif
06021 clear_reg(new_reg_item_p);
06022 return err;
06023 }
06024 #ifdef CONFIG_RSBAC_DEBUG
06025 else
06026 {
06027 if(rsbac_debug_lists)
06028 {
06029 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u was successful.\n",
06030 name,
06031 RSBAC_MAJOR(device),RSBAC_MINOR(device));
06032 }
06033 }
06034 #endif
06035 }
06036
06037 rsbac_write_lock(®_head.lock, &lock_flags);
06038 reg_item_p = add_reg(new_reg_item_p);
06039 rsbac_write_unlock(®_head.lock, &lock_flags);
06040 if(!reg_item_p)
06041 {
06042 rsbac_printk(KERN_WARNING
06043 "rsbac_list_register: inserting list %s failed!\n",
06044 name);
06045
06046 clear_reg(new_reg_item_p);
06047 return -RSBAC_ECOULDNOTADDITEM;
06048 }
06049
06050
06051 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06052
06053 if(flags & RSBAC_LIST_BACKUP)
06054 {
06055 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06056 S_IFREG | S_IRUGO,
06057 proc_rsbac_backup_p);
06058 if(reg_item_p->proc_entry_p)
06059 {
06060 reg_item_p->proc_entry_p->read_proc = backup_proc_read;
06061 reg_item_p->proc_entry_p->data = reg_item_p;
06062 }
06063 }
06064 else
06065 {
06066 reg_item_p->proc_entry_p = NULL;
06067 }
06068 #endif
06069 *handle_p = reg_item_p;
06070 return err;
06071 }
06072
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 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06106 EXPORT_SYMBOL(rsbac_list_lol_register);
06107 #endif
06108 int rsbac_list_lol_register(
06109 rsbac_version_t ds_version,
06110 rsbac_list_handle_t *handle_p,
06111 struct rsbac_list_lol_info_t * info_p,
06112 u_int flags,
06113 rsbac_list_compare_function_t * compare,
06114 rsbac_list_compare_function_t * subcompare,
06115 rsbac_list_get_conv_t * get_conv,
06116 rsbac_list_get_conv_t * get_subconv,
06117 void * def_data,
06118 void * def_subdata,
06119 char * name,
06120 kdev_t device)
06121 {
06122 struct rsbac_list_lol_reg_item_t * reg_item_p;
06123 struct rsbac_list_lol_reg_item_t * new_reg_item_p;
06124 u_long lock_flags;
06125 int err = 0;
06126
06127 if(ds_version != RSBAC_LIST_VERSION)
06128 return -RSBAC_EINVALIDVERSION;
06129 if(!handle_p)
06130 return -RSBAC_EINVALIDPOINTER;
06131 *handle_p = NULL;
06132 if(!info_p->key || !info_p->version || !info_p->desc_size)
06133 return -RSBAC_EINVALIDVALUE;
06134 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT)
06135 return -RSBAC_EINVALIDVALUE;
06136 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE)
06137 return -RSBAC_EINVALIDVALUE;
06138 if(info_p->subdesc_size + info_p->subdata_size > RSBAC_LIST_MAX_ITEM_SIZE)
06139 return -RSBAC_EINVALIDVALUE;
06140 if(!list_initialized)
06141 return -RSBAC_ENOTINITIALIZED;
06142 if(name)
06143 {
06144 struct rsbac_list_reg_item_t * std_reg_item_p;
06145
06146 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06147 reg_item_p = lookup_lol_reg_name(name, device);
06148 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06149 if(reg_item_p)
06150 {
06151 #ifdef CONFIG_RSBAC_DEBUG
06152 if(rsbac_debug_lists)
06153 {
06154 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: list name %s already exists on device %02u:%02u!\n",
06155 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06156 }
06157 #endif
06158 return -RSBAC_EEXISTS;
06159 }
06160 rsbac_read_lock(®_head.lock, &lock_flags);
06161 std_reg_item_p = lookup_reg_name(name, device);
06162 rsbac_read_unlock(®_head.lock, &lock_flags);
06163 if(std_reg_item_p)
06164 {
06165 #ifdef CONFIG_RSBAC_DEBUG
06166 if(rsbac_debug_lists)
06167 {
06168 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n",
06169 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06170 }
06171 #endif
06172 return -RSBAC_EEXISTS;
06173 }
06174 }
06175 else
06176 if(flags & RSBAC_LIST_PERSIST)
06177 {
06178 rsbac_printk(KERN_WARNING
06179 "rsbac_list_lol_register: trial to register persistent list of lists without name.\n");
06180 return -RSBAC_EINVALIDVALUE;
06181 }
06182
06183 if(flags & RSBAC_LIST_PERSIST)
06184 {
06185 if(RSBAC_IS_AUTO_DEV(device))
06186 device = rsbac_root_dev;
06187 if(!RSBAC_MAJOR(device))
06188 flags &= ~RSBAC_LIST_PERSIST;
06189 }
06190
06191 #ifdef CONFIG_RSBAC_DEBUG
06192 if(rsbac_debug_lists)
06193 {
06194 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: registering list of lists %s.\n",
06195 name);
06196 }
06197 #endif
06198 new_reg_item_p = create_lol_reg(info_p, flags, compare, subcompare,
06199 get_conv, get_subconv,
06200 def_data, def_subdata,
06201 name, device);
06202 if(!new_reg_item_p)
06203 {
06204 return -RSBAC_ECOULDNOTADDITEM;
06205 }
06206
06207 if(flags & RSBAC_LIST_PERSIST)
06208 {
06209 #ifdef CONFIG_RSBAC_DEBUG
06210 if(rsbac_debug_lists)
06211 {
06212 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u.\n",
06213 name, RSBAC_MAJOR(device), RSBAC_MINOR(device));
06214 }
06215 #endif
06216 err = read_lol_list(new_reg_item_p);
06217
06218 if(err == -RSBAC_ENOTFOUND)
06219 err = 0;
06220 else
06221 if(err)
06222 {
06223 #ifdef CONFIG_RSBAC_DEBUG
06224 if(rsbac_debug_lists)
06225 {
06226 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
06227
06228 if(tmp)
06229 {
06230 get_error_name(tmp, err);
06231 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n",
06232 name,
06233 RSBAC_MAJOR(device),RSBAC_MINOR(device),
06234 tmp);
06235 rsbac_kfree(tmp);
06236 }
06237 }
06238 #endif
06239 clear_lol_reg(new_reg_item_p);
06240 return err;
06241 }
06242 #ifdef CONFIG_RSBAC_DEBUG
06243 else
06244 {
06245 if(rsbac_debug_lists)
06246 {
06247 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u was successful.\n",
06248 name,
06249 RSBAC_MAJOR(device),RSBAC_MINOR(device));
06250 }
06251 }
06252 #endif
06253 }
06254
06255 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06256 reg_item_p = add_lol_reg(new_reg_item_p);
06257 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06258 if(!reg_item_p)
06259 {
06260 rsbac_printk(KERN_WARNING
06261 "rsbac_list_lol_register: inserting list %s failed!\n",
06262 name);
06263
06264 clear_lol_reg(new_reg_item_p);
06265 return -RSBAC_ECOULDNOTADDITEM;
06266 }
06267
06268
06269 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06270
06271 if(flags & RSBAC_LIST_BACKUP)
06272 {
06273 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name,
06274 S_IFREG | S_IRUGO,
06275 proc_rsbac_backup_p);
06276 if(reg_item_p->proc_entry_p)
06277 {
06278 reg_item_p->proc_entry_p->read_proc = lol_backup_proc_read;
06279 reg_item_p->proc_entry_p->data = reg_item_p;
06280 }
06281 }
06282 else
06283 {
06284 reg_item_p->proc_entry_p = NULL;
06285 }
06286 #endif
06287 *handle_p = reg_item_p;
06288 return err;
06289 }
06290
06291
06292
06293
06294 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06295 EXPORT_SYMBOL(rsbac_list_destroy);
06296 #endif
06297 int rsbac_list_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06298 {
06299 struct rsbac_list_reg_item_t * reg_item_p;
06300 u_long lock_flags;
06301 int err = 0;
06302
06303 if(!handle_p)
06304 return -RSBAC_EINVALIDPOINTER;
06305 if(!*handle_p)
06306 return -RSBAC_EINVALIDVALUE;
06307 if(!list_initialized)
06308 return -RSBAC_ENOTINITIALIZED;
06309
06310 rsbac_write_lock(®_head.lock, &lock_flags);
06311 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06312 if(!reg_item_p)
06313 {
06314 rsbac_write_unlock(®_head.lock, &lock_flags);
06315 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list failed due to invalid handle!\n");
06316 return -RSBAC_EINVALIDVALUE;
06317 }
06318 if(reg_item_p->info.key != key)
06319 {
06320 rsbac_write_unlock(®_head.lock, &lock_flags);
06321 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list %s denied due to invalid key!\n",
06322 reg_item_p->name);
06323 return -EPERM;
06324 }
06325 #ifdef CONFIG_RSBAC_DEBUG
06326 if(rsbac_debug_lists)
06327 {
06328 rsbac_printk(KERN_DEBUG "rsbac_list_destroy: destroying list %s.\n",
06329 reg_item_p->name);
06330 }
06331 #endif
06332 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06333
06334 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06335 && reg_item_p->proc_entry_p
06336 )
06337 {
06338 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06339 reg_item_p->proc_entry_p = NULL;
06340 }
06341 #endif
06342
06343 #if 0
06344 if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06345 err = unlink_list(reg_item_p);
06346 #endif
06347
06348 remove_reg(reg_item_p);
06349 *handle_p = NULL;
06350 rsbac_write_unlock(®_head.lock, &lock_flags);
06351 return err;
06352 }
06353
06354 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06355 EXPORT_SYMBOL(rsbac_list_lol_destroy);
06356 #endif
06357 int rsbac_list_lol_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06358 {
06359 struct rsbac_list_lol_reg_item_t * reg_item_p;
06360 u_long lock_flags;
06361 int err = 0;
06362
06363 if(!handle_p)
06364 return -RSBAC_EINVALIDPOINTER;
06365 if(!*handle_p)
06366 return -RSBAC_EINVALIDVALUE;
06367 if(!list_initialized)
06368 return -RSBAC_ENOTINITIALIZED;
06369
06370 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06371 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06372 if(!reg_item_p)
06373 {
06374 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06375 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list failed due to invalid handle!\n");
06376 return -RSBAC_EINVALIDVALUE;
06377 }
06378 if(reg_item_p->info.key != key)
06379 {
06380 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06381 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list %s denied due to invalid key %u!\n",
06382 reg_item_p->name,
06383 key);
06384 return -EPERM;
06385 }
06386 #ifdef CONFIG_RSBAC_DEBUG
06387 if(rsbac_debug_lists)
06388 {
06389 rsbac_printk(KERN_DEBUG "rsbac_list_lol_destroy: destroying list %s.\n",
06390 reg_item_p->name);
06391 }
06392 #endif
06393 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06394
06395 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06396 && reg_item_p->proc_entry_p
06397 )
06398 {
06399 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06400 reg_item_p->proc_entry_p = NULL;
06401 }
06402 #endif
06403 #if 0
06404 if(reg_item_p->flags & RSBAC_LIST_PERSIST)
06405 err = unlink_lol_list(reg_item_p);
06406 #endif
06407
06408 remove_lol_reg(reg_item_p);
06409 *handle_p = NULL;
06410 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06411 return err;
06412 }
06413
06414
06415
06416 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06417 EXPORT_SYMBOL(rsbac_list_detach);
06418 #endif
06419 int rsbac_list_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06420 {
06421 struct rsbac_list_reg_item_t * reg_item_p;
06422 u_long lock_flags;
06423 int err = 0;
06424
06425 if(!handle_p)
06426 return -RSBAC_EINVALIDPOINTER;
06427 if(!*handle_p)
06428 return -RSBAC_EINVALIDVALUE;
06429 if(!list_initialized)
06430 return -RSBAC_ENOTINITIALIZED;
06431
06432 rsbac_read_lock(®_head.lock, &lock_flags);
06433 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p);
06434 if(!reg_item_p)
06435 {
06436 rsbac_read_unlock(®_head.lock, &lock_flags);
06437 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list failed due to invalid handle!\n");
06438 return -RSBAC_EINVALIDVALUE;
06439 }
06440 if(reg_item_p->info.key != key)
06441 {
06442 rsbac_read_unlock(®_head.lock, &lock_flags);
06443 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list %s denied due to invalid key %u!\n",
06444 reg_item_p->name,
06445 key);
06446 return -EPERM;
06447 }
06448 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06449
06450 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06451 && reg_item_p->proc_entry_p
06452 )
06453 {
06454 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06455 reg_item_p->proc_entry_p = NULL;
06456 }
06457 #endif
06458 #ifndef CONFIG_RSBAC_NO_WRITE
06459
06460 if( (reg_item_p->flags & RSBAC_LIST_PERSIST)
06461 && reg_item_p->dirty
06462 && !reg_item_p->no_write
06463 )
06464 {
06465 struct rsbac_list_write_head_t write_head;
06466 struct rsbac_list_write_item_t * write_item_p;
06467
06468 reg_item_p->dirty = FALSE;
06469 err = fill_buffer(reg_item_p, &write_item_p);
06470 if(!err)
06471 {
06472 write_head.head = write_item_p;
06473 write_head.tail = write_item_p;
06474 write_head.total = write_item_p->buflen;
06475 write_head.count = 1;
06476 rsbac_read_unlock(®_head.lock, &lock_flags);
06477 rsbac_list_write_buffers(write_head, TRUE);
06478 }
06479 else
06480 {
06481 rsbac_read_unlock(®_head.lock, &lock_flags);
06482 if(err != -RSBAC_ENOTWRITABLE)
06483 {
06484 rsbac_printk(KERN_WARNING
06485 "rsbac_list_detach(): fill_buffer() for list %s returned error %i\n",
06486 reg_item_p->name, err);
06487 }
06488 }
06489 }
06490 else
06491 rsbac_read_unlock(®_head.lock, &lock_flags);
06492 #else
06493 rsbac_read_unlock(®_head.lock, &lock_flags);
06494 #endif
06495
06496 *handle_p = NULL;
06497
06498 rsbac_write_lock(®_head.lock, &lock_flags);
06499 remove_reg(reg_item_p);
06500 rsbac_write_unlock(®_head.lock, &lock_flags);
06501 return err;
06502 }
06503
06504 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06505 EXPORT_SYMBOL(rsbac_list_lol_detach);
06506 #endif
06507 int rsbac_list_lol_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key)
06508 {
06509 struct rsbac_list_lol_reg_item_t * reg_item_p;
06510 u_long lock_flags;
06511 int err = 0;
06512
06513 if(!handle_p)
06514 return -RSBAC_EINVALIDPOINTER;
06515 if(!*handle_p)
06516 return -RSBAC_EINVALIDVALUE;
06517 if(!list_initialized)
06518 return -RSBAC_ENOTINITIALIZED;
06519
06520 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06521 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p);
06522 if(!reg_item_p)
06523 {
06524 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06525 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list failed due to invalid handle!\n");
06526 return -RSBAC_EINVALIDVALUE;
06527 }
06528 if(reg_item_p->info.key != key)
06529 {
06530 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06531 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list %s denied due to invalid key %u!\n",
06532 reg_item_p->name,
06533 key);
06534 return -EPERM;
06535 }
06536 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
06537
06538 if( (reg_item_p->flags & RSBAC_LIST_BACKUP)
06539 && reg_item_p->proc_entry_p
06540 )
06541 {
06542 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p);
06543 reg_item_p->proc_entry_p = NULL;
06544 }
06545 #endif
06546 #ifndef CONFIG_RSBAC_NO_WRITE
06547
06548 if( (reg_item_p->flags & RSBAC_LIST_PERSIST)
06549 && reg_item_p->dirty
06550 && !reg_item_p->no_write
06551 )
06552 {
06553 struct rsbac_list_lol_write_head_t write_head;
06554 struct rsbac_list_lol_write_item_t * write_item_p;
06555
06556 reg_item_p->dirty = FALSE;
06557 err = fill_lol_buffer(reg_item_p, &write_item_p);
06558 if(!err)
06559 {
06560 write_head.head = write_item_p;
06561 write_head.tail = write_item_p;
06562 write_head.total = write_item_p->buflen;
06563 write_head.count = 1;
06564 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06565 rsbac_list_write_lol_buffers(write_head, TRUE);
06566 }
06567 else
06568 {
06569 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06570 if(err != -RSBAC_ENOTWRITABLE)
06571 {
06572 rsbac_printk(KERN_WARNING
06573 "rsbac_list_lol_detach(): fill_buffer() for list %s returned error %i\n",
06574 reg_item_p->name, err);
06575 }
06576 }
06577 }
06578 else
06579 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06580 #else
06581 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06582 #endif
06583
06584 *handle_p = NULL;
06585
06586 rsbac_write_lock(&lol_reg_head.lock, &lock_flags);
06587 remove_lol_reg(reg_item_p);
06588 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags);
06589 return err;
06590 }
06591
06592
06593
06594 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06595 EXPORT_SYMBOL(rsbac_list_no_write);
06596 #endif
06597 int rsbac_list_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06598 {
06599 struct rsbac_list_reg_item_t * reg_item_p;
06600 u_long lock_flags;
06601
06602 if( !handle
06603 || ( (no_write != FALSE )
06604 && (no_write != TRUE )
06605 )
06606 )
06607 return -RSBAC_EINVALIDVALUE;
06608 if(!list_initialized)
06609 return -RSBAC_ENOTINITIALIZED;
06610
06611 rsbac_read_lock(®_head.lock, &lock_flags);
06612 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) handle);
06613 if(!reg_item_p)
06614 {
06615 rsbac_read_unlock(®_head.lock, &lock_flags);
06616 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list denied due to invalid handle!\n");
06617 return -RSBAC_EINVALIDVALUE;
06618 }
06619 if(reg_item_p->info.key != key)
06620 {
06621 rsbac_read_unlock(®_head.lock, &lock_flags);
06622 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06623 reg_item_p->name,
06624 key);
06625 return -EPERM;
06626 }
06627 reg_item_p->no_write = no_write;
06628 rsbac_read_unlock(®_head.lock, &lock_flags);
06629 return 0;
06630 }
06631
06632 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06633 EXPORT_SYMBOL(rsbac_list_lol_no_write);
06634 #endif
06635 int rsbac_list_lol_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, rsbac_boolean_t no_write)
06636 {
06637 struct rsbac_list_lol_reg_item_t * reg_item_p;
06638 u_long lock_flags;
06639
06640 if( !handle
06641 || ( (no_write != FALSE )
06642 && (no_write != TRUE )
06643 )
06644 )
06645 return -RSBAC_EINVALIDVALUE;
06646 if(!list_initialized)
06647 return -RSBAC_ENOTINITIALIZED;
06648
06649 rsbac_read_lock(&lol_reg_head.lock, &lock_flags);
06650 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) handle);
06651 if(!reg_item_p)
06652 {
06653 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06654 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list denied due to invalid handle!\n");
06655 return -RSBAC_EINVALIDVALUE;
06656 }
06657 if(reg_item_p->info.key != key)
06658 {
06659 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06660 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list %s denied due to invalid key %u!\n",
06661 reg_item_p->name,
06662 key);
06663 return -EPERM;
06664 }
06665 reg_item_p->no_write = no_write;
06666 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags);
06667 return 0;
06668 }
06669
06670
06671
06672
06673
06674
06675 #ifdef CONFIG_RSBAC_LIST_TRANS
06676 static int do_commit(rsbac_list_ta_number_t ta_number)
06677 {
06678
06679
06680
06681
06682
06683
06684
06685
06686
06687
06688 struct rsbac_list_reg_item_t * list;
06689 struct rsbac_list_lol_reg_item_t * lol_list;
06690 u_long lock_flags;
06691 u_long lol_lock_flags;
06692
06693 rsbac_write_lock(®_head.lock, &lock_flags);
06694 rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06695 list = reg_head.head;
06696 while(list)
06697 {
06698 if(list->ta_copied == ta_number)
06699 {
06700 remove_all_items(list);
06701 list->head = list->ta_head;
06702 list->tail = list->ta_tail;
06703 list->curr = list->ta_curr;
06704 list->count = list->ta_count;
06705 list->ta_head = NULL;
06706 list->ta_tail = NULL;
06707 list->ta_curr = NULL;
06708 list->ta_count = 0;
06709 list->ta_copied = 0;
06710 list->dirty = TRUE;
06711 }
06712 list = list->next;
06713 }
06714 lol_list = lol_reg_head.head;
06715 while(lol_list)
06716 {
06717 if(lol_list->ta_copied == ta_number)
06718 {
06719 remove_all_lol_items(lol_list);
06720 lol_list->head = lol_list->ta_head;
06721 lol_list->tail = lol_list->ta_tail;
06722 lol_list->curr = lol_list->ta_curr;
06723 lol_list->count = lol_list->ta_count;
06724 lol_list->ta_head = NULL;
06725 lol_list->ta_tail = NULL;
06726 lol_list->ta_curr = NULL;
06727 lol_list->ta_count = 0;
06728 lol_list->ta_copied = 0;
06729 lol_list->dirty = TRUE;
06730 }
06731 lol_list = lol_list->next;
06732 }
06733 rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06734 rsbac_write_unlock(®_head.lock, &lock_flags);
06735
06736 return 0;
06737 }
06738
06739 int rsbac_list_ta_commit(rsbac_list_ta_number_t ta_number,
06740 char * password)
06741 {
06742 int err;
06743 struct rsbac_list_ta_data_t ta_data;
06744
06745 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06746 if(err)
06747 return err;
06748 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06749 && (ta_data.commit_uid != current->uid)
06750 )
06751 return -EPERM;
06752
06753 if(ta_data.password[0])
06754 {
06755 if(!password)
06756 return -EPERM;
06757 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06758 return -EPERM;
06759 }
06760 spin_lock(&ta_lock);
06761 if(ta_committing || ta_forgetting)
06762 {
06763 spin_unlock(&ta_lock);
06764 return -RSBAC_EBUSY;
06765 }
06766 ta_committing = TRUE;
06767 spin_unlock(&ta_lock);
06768
06769 rsbac_printk(KERN_INFO "rsbac_list_ta_commit(): committing transaction %u\n",
06770 ta_number);
06771
06772 err = do_commit(ta_number);
06773 if(!err)
06774 rsbac_list_remove(ta_handle, &ta_number);
06775 ta_committing = FALSE;
06776 return err;
06777 }
06778
06779 static int do_forget(rsbac_list_ta_number_t ta_number)
06780 {
06781 struct rsbac_list_reg_item_t * list;
06782 struct rsbac_list_lol_reg_item_t * lol_list;
06783 u_long lock_flags;
06784 u_long lol_lock_flags;
06785
06786 spin_lock(&ta_lock);
06787 if(ta_committing || ta_forgetting)
06788 {
06789 spin_unlock(&ta_lock);
06790 return -RSBAC_EBUSY;
06791 }
06792 ta_forgetting = TRUE;
06793 spin_unlock(&ta_lock);
06794
06795 rsbac_printk(KERN_INFO "rsbac_list_ta_forget(): removing transaction %u\n",
06796 ta_number);
06797
06798
06799
06800
06801
06802
06803
06804
06805
06806 rsbac_write_lock(®_head.lock, &lock_flags);
06807 rsbac_write_lock(&lol_reg_head.lock, &lol_lock_flags);
06808 list = reg_head.head;
06809 while(list)
06810 {
06811 if(list->ta_copied == ta_number)
06812 {
06813 ta_remove_all_items(list);
06814 list->ta_copied = 0;
06815 }
06816 list = list->next;
06817 }
06818 lol_list = lol_reg_head.head;
06819 while(lol_list)
06820 {
06821 if(lol_list->ta_copied == ta_number)
06822 {
06823 ta_remove_all_lol_items(lol_list);
06824 lol_list->ta_copied = 0;
06825 }
06826 lol_list = lol_list->next;
06827 }
06828 rsbac_write_unlock(&lol_reg_head.lock, &lol_lock_flags);
06829 rsbac_write_unlock(®_head.lock, &lock_flags);
06830
06831 rsbac_list_remove(ta_handle, &ta_number);
06832 ta_forgetting = FALSE;
06833
06834 return 0;
06835 }
06836
06837 int rsbac_list_ta_forget(rsbac_list_ta_number_t ta_number,
06838 char * password)
06839 {
06840 int err;
06841 struct rsbac_list_ta_data_t ta_data;
06842
06843 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06844 if(err)
06845 return err;
06846 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06847 && (ta_data.commit_uid != current->uid)
06848 )
06849 return -EPERM;
06850 if(ta_data.password[0])
06851 {
06852 if(!password)
06853 return -EPERM;
06854 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06855 return -EPERM;
06856 }
06857 return do_forget(ta_number);
06858 }
06859
06860 int rsbac_list_ta_begin(
06861 rsbac_time_t ttl,
06862 rsbac_list_ta_number_t * ta_number_p,
06863 rsbac_uid_t commit_uid,
06864 char * password)
06865 {
06866 int err;
06867 rsbac_list_ta_number_t ta;
06868 struct rsbac_list_ta_data_t ta_data;
06869
06870 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06871 get_random_bytes(&ta, sizeof(ta));
06872 #else
06873 ta = ta_next++;
06874 #endif
06875 while(rsbac_list_exist(ta_handle, &ta))
06876 {
06877 #ifdef CONFIG_RSBAC_LIST_TRANS_RANDOM_TA
06878 get_random_bytes(&ta, sizeof(ta));
06879 #else
06880 ta = ta_next++;
06881 #endif
06882 }
06883 if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06884 ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06885
06886 rsbac_printk(KERN_INFO "rsbac_list_ta_begin(): starting transaction %u with ttl of %us\n",
06887 ta, ttl);
06888
06889 ta_data.start = RSBAC_CURRENT_TIME;
06890 ta_data.timeout = ta_data.start + ttl;
06891 ta_data.commit_uid = commit_uid;
06892 if(password)
06893 {
06894 strncpy(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN - 1);
06895 ta_data.password[RSBAC_LIST_TA_MAX_PASSLEN - 1] = 0;
06896 }
06897 else
06898 ta_data.password[0] = 0;
06899 err = rsbac_list_add(ta_handle, &ta, &ta_data);
06900 if(!err)
06901 *ta_number_p = ta;
06902 return err;
06903 }
06904
06905 int rsbac_list_ta_refresh(
06906 rsbac_time_t ttl,
06907 rsbac_list_ta_number_t ta_number,
06908 char * password)
06909 {
06910 struct rsbac_list_ta_data_t ta_data;
06911 int err;
06912
06913 if(!rsbac_list_exist(ta_handle, &ta_number))
06914 {
06915 return -RSBAC_ENOTFOUND;
06916 }
06917 if(!ttl || (ttl > CONFIG_RSBAC_LIST_TRANS_MAX_TTL))
06918 ttl = CONFIG_RSBAC_LIST_TRANS_MAX_TTL;
06919
06920 rsbac_printk(KERN_INFO "rsbac_list_ta_refresh(): refreshing transaction %u for %us\n",
06921 ta_number, ttl);
06922
06923 err = rsbac_list_get_data(ta_handle, &ta_number, &ta_data);
06924 if(err)
06925 return err;
06926 if( (ta_data.commit_uid != RSBAC_ALL_USERS)
06927 && (ta_data.commit_uid != current->uid)
06928 )
06929 return -EPERM;
06930 if(ta_data.password[0])
06931 {
06932 if(!password)
06933 return -EPERM;
06934 if(strncmp(ta_data.password, password, RSBAC_LIST_TA_MAX_PASSLEN))
06935 return -EPERM;
06936 }
06937 ta_data.timeout = RSBAC_CURRENT_TIME + ttl;
06938 return rsbac_list_add(ta_handle, &ta_number, &ta_data);
06939 }
06940 #endif
06941
06942
06943
06944
06945
06946
06947
06948
06949 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
06950 EXPORT_SYMBOL(rsbac_ta_list_add_ttl);
06951 #endif
06952 int rsbac_ta_list_add_ttl(
06953 rsbac_list_ta_number_t ta_number,
06954 rsbac_list_handle_t handle,
06955 rsbac_time_t ttl,
06956 void * desc,
06957 void * data)
06958 {
06959 struct rsbac_list_reg_item_t * list;
06960 struct rsbac_list_item_t * item_p;
06961 u_long lock_flags, rlock_flags;
06962
06963 if(!handle || !desc)
06964 return -RSBAC_EINVALIDVALUE;
06965 if(!list_initialized)
06966 return -RSBAC_ENOTINITIALIZED;
06967
06968 list = (struct rsbac_list_reg_item_t *) handle;
06969 if(!list || (list->self != list))
06970 return -RSBAC_EINVALIDVALUE;
06971
06972 #ifdef CONFIG_RSBAC_LIST_TRANS
06973 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
06974 return -RSBAC_EINVALIDTRANSACTION;
06975 #endif
06976
06977 rsbac_read_lock(®_head.lock, &rlock_flags);
06978 if(list->info.data_size && !data)
06979 {
06980 rsbac_read_unlock(®_head.lock, &rlock_flags);
06981 return -RSBAC_EINVALIDVALUE;
06982 }
06983
06984
06985
06986
06987
06988
06989
06990
06991 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
06992 {
06993 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
06994 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
06995 ttl += RSBAC_CURRENT_TIME;
06996 }
06997 rsbac_write_lock(&list->lock, &lock_flags);
06998
06999 #ifdef CONFIG_RSBAC_LIST_TRANS
07000 if(!ta_number)
07001 #endif
07002 {
07003 item_p = lookup_item(list, desc);
07004 if(item_p)
07005 {
07006 if(ttl != RSBAC_LIST_TTL_KEEP)
07007 item_p->max_age = ttl;
07008 if(data && list->info.data_size)
07009 {
07010 if( list->def_data
07011 && !item_p->max_age
07012 && !memcmp(list->def_data, data, list->info.data_size)
07013 )
07014 do_remove_item(list, item_p);
07015 else
07016 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07017 data, list->info.data_size);
07018 }
07019 }
07020 else
07021 {
07022 if(ttl == RSBAC_LIST_TTL_KEEP)
07023 ttl = 0;
07024 if( !list->def_data
07025 || memcmp(list->def_data, data, list->info.data_size)
07026 )
07027 add_item(list, ttl, desc, data);
07028 }
07029 touch(list);
07030 list->dirty = TRUE;
07031 }
07032 #ifdef CONFIG_RSBAC_LIST_TRANS
07033 if( list->ta_copied
07034 || ta_number
07035 )
07036 {
07037 if(!list->ta_copied)
07038 ta_copy(ta_number, list);
07039 else
07040 if(ta_number)
07041 {
07042 if(list->ta_copied != ta_number)
07043 {
07044 rsbac_write_unlock(&list->lock, &lock_flags);
07045 rsbac_read_unlock(®_head.lock, &rlock_flags);
07046 return -RSBAC_EBUSY;
07047 }
07048 }
07049 else
07050 ta_number = list->ta_copied;
07051 item_p = ta_lookup_item(ta_number, list, desc);
07052 if(item_p)
07053 {
07054 if(ttl != RSBAC_LIST_TTL_KEEP)
07055 item_p->max_age = ttl;
07056 if(data && list->info.data_size)
07057 {
07058 if( list->def_data
07059 && !item_p->max_age
07060 && !memcmp(list->def_data, data, list->info.data_size)
07061 )
07062 ta_do_remove_item(list, item_p);
07063 else
07064 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07065 data, list->info.data_size);
07066 }
07067 }
07068 else
07069 {
07070 if(ttl == RSBAC_LIST_TTL_KEEP)
07071 ttl = 0;
07072 if( !list->def_data
07073 || memcmp(list->def_data, data, list->info.data_size)
07074 )
07075 ta_add_item(ta_number, list, ttl, desc, data);
07076 }
07077 }
07078 #endif
07079 rsbac_write_unlock(&list->lock, &lock_flags);
07080 rsbac_read_unlock(®_head.lock, &rlock_flags);
07081 return 0;
07082 }
07083
07084 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07085 EXPORT_SYMBOL(rsbac_list_add_ttl);
07086 #endif
07087 int rsbac_list_add_ttl(
07088 rsbac_list_handle_t handle,
07089 rsbac_time_t ttl,
07090 void * desc,
07091 void * data)
07092 {
07093 return rsbac_ta_list_add_ttl(0, handle, ttl, desc, data);
07094 }
07095
07096 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07097 EXPORT_SYMBOL(rsbac_list_add);
07098 #endif
07099 int rsbac_list_add(
07100 rsbac_list_handle_t handle,
07101 void * desc,
07102 void * data)
07103 {
07104 return rsbac_ta_list_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07105 }
07106
07107
07108
07109 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07110 EXPORT_SYMBOL(rsbac_ta_list_lol_subadd_ttl);
07111 #endif
07112 int rsbac_ta_list_lol_subadd_ttl(
07113 rsbac_list_ta_number_t ta_number,
07114 rsbac_list_handle_t handle,
07115 rsbac_time_t ttl,
07116 void * desc,
07117 void * subdesc,
07118 void * subdata)
07119 {
07120 struct rsbac_list_lol_reg_item_t * list;
07121 struct rsbac_list_lol_item_t * sublist;
07122 struct rsbac_list_item_t * item_p;
07123 u_long lock_flags, rlock_flags;
07124 int err = 0;
07125
07126 if(!handle || !desc || !subdesc)
07127 return -RSBAC_EINVALIDVALUE;
07128 if(!list_initialized)
07129 return -RSBAC_ENOTINITIALIZED;
07130
07131 list = (struct rsbac_list_lol_reg_item_t *) handle;
07132 if(!list || (list->self != list))
07133 return -RSBAC_EINVALIDVALUE;
07134
07135 #ifdef CONFIG_RSBAC_LIST_TRANS
07136 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07137 return -RSBAC_EINVALIDTRANSACTION;
07138 #endif
07139
07140 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07141 if(list->info.subdata_size && !subdata)
07142 {
07143 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07144 return -RSBAC_EINVALIDVALUE;
07145 }
07146
07147
07148
07149
07150
07151
07152
07153
07154 rsbac_write_lock(&list->lock, &lock_flags);
07155
07156 #ifdef CONFIG_RSBAC_LIST_TRANS
07157 if(!ta_number)
07158 #endif
07159 {
07160 sublist = lookup_lol_item(list, desc);
07161 if( !sublist
07162 && (list->flags & RSBAC_LIST_DEF_DATA)
07163 )
07164 sublist = add_lol_item(list, 0, desc, list->def_data);
07165 if(sublist)
07166 {
07167 if( sublist->max_age
07168 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07169 )
07170 {
07171 remove_lol_item(list, desc);
07172 err = -RSBAC_EINVALIDTARGET;
07173 }
07174 else
07175 {
07176
07177 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07178 {
07179 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07180 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07181 ttl += RSBAC_CURRENT_TIME;
07182 }
07183 item_p = lookup_lol_subitem(list, sublist, subdesc);
07184 if(item_p)
07185 {
07186 if(ttl != RSBAC_LIST_TTL_KEEP)
07187 item_p->max_age = ttl;
07188 if(subdata && list->info.subdata_size)
07189 {
07190 if( list->def_subdata
07191 && !item_p->max_age
07192 && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07193 )
07194 do_remove_lol_subitem(sublist, item_p);
07195 else
07196 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07197 subdata,
07198 list->info.subdata_size);
07199 }
07200 }
07201 else
07202 {
07203 if(ttl == RSBAC_LIST_TTL_KEEP)
07204 ttl = 0;
07205 if( !list->def_subdata
07206 || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07207 )
07208 add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07209 }
07210 lol_touch(list);
07211 list->dirty = TRUE;
07212 }
07213 }
07214 else
07215 {
07216 err = -RSBAC_EINVALIDTARGET;
07217 goto out_unlock;
07218 }
07219 }
07220 #ifdef CONFIG_RSBAC_LIST_TRANS
07221 if(list->ta_copied || ta_number)
07222 {
07223 if(!list->ta_copied)
07224 {
07225 if((err = ta_lol_copy(ta_number,list)))
07226 goto out_unlock;
07227 }
07228 else
07229 if(ta_number)
07230 {
07231 if(list->ta_copied != ta_number)
07232 {
07233 err = -RSBAC_EBUSY;
07234 goto out_unlock;
07235 }
07236 }
07237 else
07238 ta_number = list->ta_copied;
07239 sublist = ta_lookup_lol_item(ta_number, list, desc);
07240 if( !sublist
07241 && (list->flags & RSBAC_LIST_DEF_DATA)
07242 )
07243 sublist = ta_add_lol_item(ta_number, list, 0, desc, list->def_data);
07244 if(sublist)
07245 {
07246 if( sublist->max_age
07247 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07248 )
07249 {
07250 ta_remove_lol_item(ta_number, list, desc);
07251 err = -RSBAC_EINVALIDTARGET;
07252 }
07253 else
07254 {
07255
07256 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07257 {
07258 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07259 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07260 ttl += RSBAC_CURRENT_TIME;
07261 }
07262 item_p = lookup_lol_subitem(list, sublist, subdesc);
07263 if(item_p)
07264 {
07265 if(ttl != RSBAC_LIST_TTL_KEEP)
07266 item_p->max_age = ttl;
07267 if(subdata && list->info.subdata_size)
07268 {
07269 if( list->def_subdata
07270 && !item_p->max_age
07271 && !memcmp(list->def_subdata, subdata, list->info.subdata_size)
07272 )
07273 do_remove_lol_subitem(sublist, item_p);
07274 else
07275 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
07276 subdata,
07277 list->info.subdata_size);
07278 }
07279 }
07280 else
07281 {
07282 if(ttl == RSBAC_LIST_TTL_KEEP)
07283 ttl = 0;
07284 if( !list->def_subdata
07285 || memcmp(list->def_subdata, subdata, list->info.subdata_size)
07286 )
07287 add_lol_subitem(list, sublist, ttl, subdesc, subdata);
07288 }
07289 }
07290 }
07291 else
07292 {
07293 err = -RSBAC_EINVALIDTARGET;
07294 }
07295 }
07296 #endif
07297
07298 out_unlock:
07299 rsbac_write_unlock(&list->lock, &lock_flags);
07300 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07301 return err;
07302 }
07303
07304 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07305 EXPORT_SYMBOL(rsbac_list_lol_subadd_ttl);
07306 #endif
07307 int rsbac_list_lol_subadd_ttl(
07308 rsbac_list_handle_t handle,
07309 rsbac_time_t ttl,
07310 void * desc,
07311 void * subdesc,
07312 void * subdata)
07313 {
07314 return rsbac_ta_list_lol_subadd_ttl(0, handle, ttl, desc, subdesc, subdata);
07315 }
07316
07317 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07318 EXPORT_SYMBOL(rsbac_list_lol_subadd);
07319 #endif
07320 int rsbac_list_lol_subadd(
07321 rsbac_list_handle_t handle,
07322 void * desc,
07323 void * subdesc,
07324 void * subdata)
07325 {
07326 return rsbac_ta_list_lol_subadd_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, subdesc, subdata);
07327 }
07328
07329
07330
07331 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07332 EXPORT_SYMBOL(rsbac_ta_list_lol_add_ttl);
07333 #endif
07334 int rsbac_ta_list_lol_add_ttl(
07335 rsbac_list_ta_number_t ta_number,
07336 rsbac_list_handle_t handle,
07337 rsbac_time_t ttl,
07338 void * desc,
07339 void * data)
07340 {
07341 struct rsbac_list_lol_reg_item_t * list;
07342 struct rsbac_list_lol_item_t * item_p;
07343 u_long lock_flags, rlock_flags;
07344
07345 if(!handle || !desc)
07346 return -RSBAC_EINVALIDVALUE;
07347 if(!list_initialized)
07348 return -RSBAC_ENOTINITIALIZED;
07349
07350 list = (struct rsbac_list_lol_reg_item_t *) handle;
07351 if(!list || (list->self != list))
07352 return -RSBAC_EINVALIDVALUE;
07353
07354 #ifdef CONFIG_RSBAC_LIST_TRANS
07355 if(ta_number && !rsbac_ta_list_exist(0, ta_handle, &ta_number))
07356 return -RSBAC_EINVALIDTRANSACTION;
07357 #endif
07358
07359 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP))
07360 {
07361 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT)
07362 ttl = RSBAC_LIST_MAX_AGE_LIMIT;
07363 ttl += RSBAC_CURRENT_TIME;
07364 }
07365
07366 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07367 if(list->info.data_size && !data)
07368 {
07369 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07370 return -RSBAC_EINVALIDVALUE;
07371 }
07372
07373
07374
07375
07376
07377
07378
07379
07380 rsbac_write_lock(&list->lock, &lock_flags);
07381
07382 #ifdef CONFIG_RSBAC_LIST_TRANS
07383 if(!ta_number)
07384 #endif
07385 {
07386 item_p = lookup_lol_item(list, desc);
07387 if(item_p)
07388 {
07389 if(ttl != RSBAC_LIST_TTL_KEEP)
07390 item_p->max_age = ttl;
07391 if(data && list->info.data_size)
07392 {
07393 if( list->def_data
07394 && !item_p->max_age
07395 && !memcmp(list->def_data, data, list->info.data_size)
07396 && !item_p->count
07397 )
07398 do_remove_lol_item(list, item_p);
07399 else
07400 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07401 data, list->info.data_size);
07402 }
07403 }
07404 else
07405 {
07406 if(ttl == RSBAC_LIST_TTL_KEEP)
07407 ttl = 0;
07408 if( !list->def_data
07409 || memcmp(list->def_data, data, list->info.data_size)
07410 )
07411 add_lol_item(list, ttl, desc, data);
07412 }
07413 lol_touch(list);
07414 list->dirty = TRUE;
07415 }
07416 #ifdef CONFIG_RSBAC_LIST_TRANS
07417 if(list->ta_copied || ta_number)
07418 {
07419 if(!list->ta_copied)
07420 ta_lol_copy(ta_number, list);
07421 else
07422 if(ta_number)
07423 {
07424 if(list->ta_copied != ta_number)
07425 {
07426 rsbac_write_unlock(&list->lock, &lock_flags);
07427 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07428 return -RSBAC_EBUSY;
07429 }
07430 }
07431 else
07432 ta_number = list->ta_copied;
07433 item_p = ta_lookup_lol_item(ta_number, list, desc);
07434 if(item_p)
07435 {
07436 if(ttl != RSBAC_LIST_TTL_KEEP)
07437 item_p->max_age = ttl;
07438 if(data && list->info.data_size)
07439 {
07440 if( list->def_data
07441 && !item_p->max_age
07442 && !memcmp(list->def_data, data, list->info.data_size)
07443 && !item_p->count
07444 )
07445 ta_do_remove_lol_item(list, item_p);
07446 else
07447 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
07448 data, list->info.data_size);
07449 }
07450 }
07451 else
07452 {
07453 if(ttl == RSBAC_LIST_TTL_KEEP)
07454 ttl = 0;
07455 if( !list->def_data
07456 || memcmp(list->def_data, data, list->info.data_size)
07457 )
07458 ta_add_lol_item(ta_number, list, ttl, desc, data);
07459 }
07460 }
07461 #endif
07462 rsbac_write_unlock(&list->lock, &lock_flags);
07463 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07464 return 0;
07465 }
07466
07467 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07468 EXPORT_SYMBOL(rsbac_list_lol_add_ttl);
07469 #endif
07470 int rsbac_list_lol_add_ttl(
07471 rsbac_list_handle_t handle,
07472 rsbac_time_t ttl,
07473 void * desc,
07474 void * data)
07475 {
07476 return rsbac_ta_list_lol_add_ttl(0, handle, ttl, desc, data);
07477 }
07478
07479 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07480 EXPORT_SYMBOL(rsbac_list_lol_add);
07481 #endif
07482 int rsbac_list_lol_add(
07483 rsbac_list_handle_t handle,
07484 void * desc,
07485 void * data)
07486 {
07487 return rsbac_ta_list_lol_add_ttl(0, handle, RSBAC_LIST_TTL_KEEP, desc, data);
07488 }
07489
07490
07491 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07492 EXPORT_SYMBOL(rsbac_ta_list_remove);
07493 #endif
07494 int rsbac_ta_list_remove(
07495 rsbac_list_ta_number_t ta_number,
07496 rsbac_list_handle_t handle,
07497 void * desc)
07498 {
07499 struct rsbac_list_reg_item_t * list;
07500 u_long lock_flags, rlock_flags;
07501
07502 if(!handle || !desc)
07503 return -RSBAC_EINVALIDVALUE;
07504 if(!list_initialized)
07505 return -RSBAC_ENOTINITIALIZED;
07506
07507 list = (struct rsbac_list_reg_item_t *) handle;
07508 if(!list || (list->self != list))
07509 return -RSBAC_EINVALIDVALUE;
07510
07511 #ifdef CONFIG_RSBAC_LIST_TRANS
07512 if(ta_number)
07513 {
07514 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07515 return -RSBAC_EINVALIDTRANSACTION;
07516 }
07517 #endif
07518
07519 rsbac_read_lock(®_head.lock, &rlock_flags);
07520
07521
07522
07523
07524
07525
07526
07527 rsbac_write_lock(&list->lock, &lock_flags);
07528 #ifdef CONFIG_RSBAC_LIST_TRANS
07529 if(list->ta_copied)
07530 {
07531 if(ta_number)
07532 {
07533 if(ta_lookup_item(list->ta_copied, list, desc))
07534 {
07535 if(list->ta_copied != ta_number)
07536 {
07537 rsbac_write_unlock(&list->lock, &lock_flags);
07538 rsbac_read_unlock(®_head.lock, &rlock_flags);
07539 return -RSBAC_EBUSY;
07540 }
07541 else
07542 ta_remove_item(ta_number, list, desc);
07543 }
07544 }
07545 else
07546 ta_remove_item(list->ta_copied, list, desc);
07547 }
07548 else
07549 {
07550 if(ta_number && lookup_item(list, desc))
07551 {
07552 ta_copy(ta_number, list);
07553 ta_remove_item(ta_number, list, desc);
07554 }
07555 }
07556 if(!ta_number)
07557 #endif
07558 {
07559 if(lookup_item(list, desc))
07560 {
07561 remove_item(list, desc);
07562 touch(list);
07563 list->dirty = TRUE;
07564 }
07565 }
07566 rsbac_write_unlock(&list->lock, &lock_flags);
07567 rsbac_read_unlock(®_head.lock, &rlock_flags);
07568 return 0;
07569 }
07570
07571 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07572 EXPORT_SYMBOL(rsbac_list_remove);
07573 #endif
07574 int rsbac_list_remove(
07575 rsbac_list_handle_t handle,
07576 void * desc)
07577 {
07578 return rsbac_ta_list_remove(0, handle, desc);
07579 }
07580
07581
07582 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07583 EXPORT_SYMBOL(rsbac_ta_list_remove_all);
07584 #endif
07585 int rsbac_ta_list_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
07586 {
07587 struct rsbac_list_reg_item_t * list;
07588 u_long lock_flags, rlock_flags;
07589
07590 if(!handle)
07591 return -RSBAC_EINVALIDVALUE;
07592 if(!list_initialized)
07593 return -RSBAC_ENOTINITIALIZED;
07594
07595 list = (struct rsbac_list_reg_item_t *) handle;
07596 if(list->self != list)
07597 return -RSBAC_EINVALIDVALUE;
07598
07599 #ifdef CONFIG_RSBAC_LIST_TRANS
07600 if(ta_number)
07601 {
07602 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07603 return -RSBAC_EINVALIDTRANSACTION;
07604 }
07605 #endif
07606
07607 rsbac_read_lock(®_head.lock, &rlock_flags);
07608
07609
07610
07611
07612
07613
07614
07615 rsbac_write_lock(&list->lock, &lock_flags);
07616 #ifdef CONFIG_RSBAC_LIST_TRANS
07617 if(list->ta_copied)
07618 {
07619 if(ta_number)
07620 {
07621 if(list->ta_copied == ta_number)
07622 {
07623 ta_remove_all_items(list);
07624 if(!list->head)
07625 {
07626 list->ta_copied = 0;
07627 }
07628 }
07629 else
07630 {
07631 rsbac_write_unlock(&list->lock, &lock_flags);
07632 rsbac_read_unlock(®_head.lock, &rlock_flags);
07633 return -RSBAC_EBUSY;
07634 }
07635 }
07636 else
07637 ta_remove_all_items(list);
07638 }
07639 else
07640 {
07641 if(ta_number)
07642 {
07643 if(list->head)
07644 {
07645 list->ta_head = NULL;
07646 list->ta_tail = NULL;
07647 list->ta_curr = NULL;
07648 list->ta_count = 0;
07649 list->ta_copied = ta_number;
07650 }
07651 }
07652 }
07653
07654 if(!ta_number)
07655 #endif
07656 if(list->head)
07657 {
07658 remove_all_items(list);
07659 touch(list);
07660 list->dirty = TRUE;
07661 }
07662 rsbac_write_unlock(&list->lock, &lock_flags);
07663 rsbac_read_unlock(®_head.lock, &rlock_flags);
07664 return 0;
07665 }
07666
07667 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07668 EXPORT_SYMBOL(rsbac_list_remove_all);
07669 #endif
07670 int rsbac_list_remove_all(rsbac_list_handle_t handle)
07671 {
07672 return rsbac_ta_list_remove_all(0, handle);
07673 }
07674
07675 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07676 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove);
07677 #endif
07678 int rsbac_ta_list_lol_subremove(
07679 rsbac_list_ta_number_t ta_number,
07680 rsbac_list_handle_t handle,
07681 void * desc,
07682 void * subdesc)
07683 {
07684 struct rsbac_list_lol_reg_item_t * list;
07685 struct rsbac_list_lol_item_t * sublist;
07686 u_long lock_flags, rlock_flags;
07687
07688 if(!handle || !desc || !subdesc)
07689 return -RSBAC_EINVALIDVALUE;
07690 if(!list_initialized)
07691 return -RSBAC_ENOTINITIALIZED;
07692
07693 list = (struct rsbac_list_lol_reg_item_t *) handle;
07694 if(list->self != list)
07695 return -RSBAC_EINVALIDVALUE;
07696
07697 #ifdef CONFIG_RSBAC_LIST_TRANS
07698 if(ta_number)
07699 {
07700 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07701 return -RSBAC_EINVALIDTRANSACTION;
07702 }
07703 #endif
07704
07705 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07706
07707
07708
07709
07710
07711
07712
07713
07714 rsbac_write_lock(&list->lock, &lock_flags);
07715 #ifdef CONFIG_RSBAC_LIST_TRANS
07716 if(list->ta_copied)
07717 {
07718 sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07719 if(sublist)
07720 {
07721 if( sublist->max_age
07722 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07723 )
07724 {
07725 ta_do_remove_lol_item(list, sublist);
07726 }
07727 else
07728 {
07729 if(ta_number && (list->ta_copied != ta_number))
07730 {
07731 rsbac_write_unlock(&list->lock, &lock_flags);
07732 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07733 return -RSBAC_EBUSY;
07734 }
07735 if(lookup_lol_subitem(list, sublist, subdesc))
07736 remove_lol_subitem(list, sublist, subdesc);
07737 if( !sublist->count
07738 && ( ( list->def_data
07739 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07740 list->def_data,
07741 list->info.data_size)
07742 )
07743 || ( !list->info.data_size
07744 && (list->flags & RSBAC_LIST_DEF_DATA)
07745 )
07746 )
07747 )
07748 {
07749 ta_do_remove_lol_item(list, sublist);
07750 }
07751 }
07752 }
07753 }
07754 else
07755 {
07756 if(ta_number && lookup_lol_item(list, desc))
07757 {
07758 ta_lol_copy(ta_number, list);
07759 ta_remove_lol_item(ta_number, list, desc);
07760 }
07761 }
07762 if(!ta_number)
07763 #endif
07764 {
07765 sublist = lookup_lol_item(list, desc);
07766 if(sublist)
07767 {
07768 if( sublist->max_age
07769 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07770 )
07771 {
07772 do_remove_lol_item(list, sublist);
07773 lol_touch(list);
07774 list->dirty = TRUE;
07775 }
07776 else
07777 {
07778 if(lookup_lol_subitem(list, sublist, subdesc))
07779 {
07780 remove_lol_subitem(list, sublist, subdesc);
07781 lol_touch(list);
07782 list->dirty = TRUE;
07783 }
07784 if( !sublist->count
07785 && ( ( list->def_data
07786 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07787 list->def_data,
07788 list->info.data_size)
07789 )
07790 || ( !list->info.data_size
07791 && (list->flags & RSBAC_LIST_DEF_DATA)
07792 )
07793 )
07794 )
07795 {
07796 do_remove_lol_item(list, sublist);
07797 lol_touch(list);
07798 list->dirty = TRUE;
07799 }
07800 }
07801 }
07802 }
07803 rsbac_write_unlock(&list->lock, &lock_flags);
07804 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07805 return 0;
07806 }
07807
07808 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07809 EXPORT_SYMBOL(rsbac_list_lol_subremove);
07810 #endif
07811 int rsbac_list_lol_subremove(
07812 rsbac_list_handle_t handle,
07813 void * desc,
07814 void * subdesc)
07815 {
07816 return rsbac_ta_list_lol_subremove(0, handle, desc, subdesc);
07817 }
07818
07819
07820 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07821 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_from_all);
07822 #endif
07823 int rsbac_ta_list_lol_subremove_from_all(
07824 rsbac_list_ta_number_t ta_number,
07825 rsbac_list_handle_t handle,
07826 void * subdesc)
07827 {
07828 struct rsbac_list_lol_reg_item_t * list;
07829 struct rsbac_list_lol_item_t * sublist;
07830 u_long lock_flags, rlock_flags;
07831
07832 if(!handle || !subdesc)
07833 return -RSBAC_EINVALIDVALUE;
07834 if(!list_initialized)
07835 return -RSBAC_ENOTINITIALIZED;
07836
07837 list = (struct rsbac_list_lol_reg_item_t *) handle;
07838 if(list->self != list)
07839 return -RSBAC_EINVALIDVALUE;
07840
07841 #ifdef CONFIG_RSBAC_LIST_TRANS
07842 if(ta_number)
07843 {
07844 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07845 return -RSBAC_EINVALIDTRANSACTION;
07846 }
07847 #endif
07848
07849 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07850
07851
07852
07853
07854
07855
07856
07857 rsbac_write_lock(&list->lock, &lock_flags);
07858 #ifdef CONFIG_RSBAC_LIST_TRANS
07859 if(list->ta_copied)
07860 {
07861 if(ta_number && (list->ta_copied != ta_number))
07862 {
07863 rsbac_write_unlock(&list->lock, &lock_flags);
07864 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07865 return -RSBAC_EBUSY;
07866 }
07867 sublist = list->head;
07868 while(sublist)
07869 {
07870 remove_lol_subitem(list, sublist, subdesc);
07871 sublist = sublist->next;
07872 }
07873 }
07874 else
07875 {
07876 if(ta_number)
07877 {
07878 ta_lol_copy(ta_number, list);
07879 sublist = list->head;
07880 while(sublist)
07881 {
07882 remove_lol_subitem(list, sublist, subdesc);
07883 sublist = sublist->next;
07884 }
07885 }
07886 }
07887 if(!ta_number)
07888 #endif
07889 {
07890 sublist = list->head;
07891 while(sublist)
07892 {
07893 if(lookup_lol_subitem(list, sublist, subdesc))
07894 {
07895 remove_lol_subitem(list, sublist, subdesc);
07896 lol_touch(list);
07897 list->dirty = TRUE;
07898 }
07899 sublist = sublist->next;
07900 }
07901 }
07902 rsbac_write_unlock(&list->lock, &lock_flags);
07903 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07904 return 0;
07905 }
07906
07907 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07908 EXPORT_SYMBOL(rsbac_list_lol_subremove_from_all);
07909 #endif
07910 int rsbac_list_lol_subremove_from_all(
07911 rsbac_list_handle_t handle,
07912 void * subdesc)
07913 {
07914 return rsbac_ta_list_lol_subremove_from_all(0, handle, subdesc);
07915 }
07916
07917
07918 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
07919 EXPORT_SYMBOL(rsbac_ta_list_lol_subremove_all);
07920 #endif
07921 int rsbac_ta_list_lol_subremove_all(
07922 rsbac_list_ta_number_t ta_number,
07923 rsbac_list_handle_t handle,
07924 void * desc)
07925 {
07926 struct rsbac_list_lol_reg_item_t * list;
07927 struct rsbac_list_lol_item_t * sublist;
07928 u_long lock_flags, rlock_flags;
07929
07930 if(!handle)
07931 return -RSBAC_EINVALIDVALUE;
07932 if(!list_initialized)
07933 return -RSBAC_ENOTINITIALIZED;
07934
07935 list = (struct rsbac_list_lol_reg_item_t *) handle;
07936 if(list->self != list)
07937 return -RSBAC_EINVALIDVALUE;
07938
07939 #ifdef CONFIG_RSBAC_LIST_TRANS
07940 if(ta_number)
07941 {
07942 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
07943 return -RSBAC_EINVALIDTRANSACTION;
07944 }
07945 #endif
07946
07947 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
07948
07949
07950
07951
07952
07953
07954
07955 rsbac_write_lock(&list->lock, &lock_flags);
07956 #ifdef CONFIG_RSBAC_LIST_TRANS
07957 if(list->ta_copied)
07958 {
07959 sublist = ta_lookup_lol_item(list->ta_copied, list, desc);
07960 if(sublist)
07961 {
07962 if( sublist->max_age
07963 && (sublist->max_age <= RSBAC_CURRENT_TIME)
07964 )
07965 {
07966 ta_do_remove_lol_item(list, sublist);
07967 }
07968 else
07969 {
07970 if(ta_number && (list->ta_copied != ta_number))
07971 {
07972 rsbac_write_unlock(&list->lock, &lock_flags);
07973 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
07974 return -RSBAC_EBUSY;
07975 }
07976 remove_all_lol_subitems(sublist);
07977 if( ( list->def_data
07978 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size,
07979 list->def_data,
07980 list->info.data_size)
07981 )
07982 || ( !list->info.data_size
07983 && (list->flags & RSBAC_LIST_DEF_DATA)
07984 )
07985
07986 )
07987 {
07988 ta_do_remove_lol_item(list, sublist);
07989 }
07990 }
07991 }
07992 }
07993 else
07994 {
07995 if(ta_number && lookup_lol_item(list, desc))
07996 {
07997 ta_lol_copy(ta_number, list);
07998 sublist = ta_lookup_lol_item(ta_number, list, desc);
07999 if(sublist)
08000 remove_all_lol_subitems(sublist);
08001 }
08002 }
08003 if(!ta_number)
08004 #endif
08005 {
08006 sublist = lookup_lol_item(list, desc);
08007 if(sublist && sublist->head)
08008 {
08009 remove_all_lol_subitems(sublist);
08010 lol_touch(list);
08011 list->dirty = TRUE;
08012 }
08013 }
08014 rsbac_write_unlock(&list->lock, &lock_flags);
08015 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08016 return 0;
08017 }
08018
08019 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08020 EXPORT_SYMBOL(rsbac_list_lol_subremove_all);
08021 #endif
08022 int rsbac_list_lol_subremove_all(rsbac_list_handle_t handle, void * desc)
08023 {
08024 return rsbac_ta_list_lol_subremove_all(0, handle, desc);
08025 }
08026
08027 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08028 EXPORT_SYMBOL(rsbac_ta_list_lol_remove);
08029 #endif
08030 int rsbac_ta_list_lol_remove(
08031 rsbac_list_ta_number_t ta_number,
08032 rsbac_list_handle_t handle,
08033 void * desc)
08034 {
08035 struct rsbac_list_lol_reg_item_t * list;
08036 u_long lock_flags, rlock_flags;
08037
08038 if(!handle || !desc)
08039 return -RSBAC_EINVALIDVALUE;
08040 if(!list_initialized)
08041 return -RSBAC_ENOTINITIALIZED;
08042
08043 list = (struct rsbac_list_lol_reg_item_t *) handle;
08044 if(list->self != list)
08045 return -RSBAC_EINVALIDVALUE;
08046
08047 #ifdef CONFIG_RSBAC_LIST_TRANS
08048 if(ta_number)
08049 {
08050 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08051 return -RSBAC_EINVALIDTRANSACTION;
08052 }
08053 #endif
08054
08055 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08056
08057
08058
08059
08060
08061
08062
08063 rsbac_write_lock(&list->lock, &lock_flags);
08064 #ifdef CONFIG_RSBAC_LIST_TRANS
08065 if(list->ta_copied)
08066 {
08067 if(ta_number)
08068 {
08069 if(ta_lookup_lol_item(list->ta_copied, list, desc))
08070 {
08071 if(list->ta_copied != ta_number)
08072 {
08073 rsbac_write_unlock(&list->lock, &lock_flags);
08074 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08075 return -RSBAC_EBUSY;
08076 }
08077 else
08078 ta_remove_lol_item(ta_number, list, desc);
08079 }
08080 }
08081 else
08082 ta_remove_lol_item(list->ta_copied, list, desc);
08083 }
08084 else
08085 {
08086 if(ta_number && lookup_lol_item(list, desc))
08087 {
08088 ta_lol_copy(ta_number, list);
08089 ta_remove_lol_item(ta_number, list, desc);
08090 }
08091 }
08092 if(!ta_number)
08093 #endif
08094 {
08095 if(lookup_lol_item(list, desc))
08096 {
08097 remove_lol_item(list, desc);
08098 lol_touch(list);
08099 list->dirty = TRUE;
08100 }
08101 }
08102 rsbac_write_unlock(&list->lock, &lock_flags);
08103 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08104 return 0;
08105 }
08106
08107 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08108 EXPORT_SYMBOL(rsbac_list_lol_remove);
08109 #endif
08110 int rsbac_list_lol_remove(
08111 rsbac_list_handle_t handle,
08112 void * desc)
08113 {
08114 return rsbac_ta_list_lol_remove(0, handle, desc);
08115 }
08116
08117
08118 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08119 EXPORT_SYMBOL(rsbac_ta_list_lol_remove_all);
08120 #endif
08121 int rsbac_ta_list_lol_remove_all(rsbac_list_ta_number_t ta_number, rsbac_list_handle_t handle)
08122 {
08123 struct rsbac_list_lol_reg_item_t * list;
08124 u_long lock_flags, rlock_flags;
08125
08126 if(!handle)
08127 return -RSBAC_EINVALIDVALUE;
08128 if(!list_initialized)
08129 return -RSBAC_ENOTINITIALIZED;
08130
08131 list = (struct rsbac_list_lol_reg_item_t *) handle;
08132 if(list->self != list)
08133 return -RSBAC_EINVALIDVALUE;
08134
08135 #ifdef CONFIG_RSBAC_LIST_TRANS
08136 if(ta_number)
08137 {
08138 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08139 return -RSBAC_EINVALIDTRANSACTION;
08140 }
08141 #endif
08142
08143 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08144
08145
08146
08147
08148
08149
08150
08151 rsbac_write_lock(&list->lock, &lock_flags);
08152 #ifdef CONFIG_RSBAC_LIST_TRANS
08153 if(list->ta_copied)
08154 {
08155 if(ta_number)
08156 {
08157 if(list->ta_copied == ta_number)
08158 {
08159 ta_remove_all_lol_items(list);
08160 if(!list->head)
08161 {
08162 list->ta_copied = 0;
08163 }
08164 }
08165 else
08166 {
08167 rsbac_write_unlock(&list->lock, &lock_flags);
08168 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08169 return -RSBAC_EBUSY;
08170 }
08171 }
08172 else
08173 ta_remove_all_lol_items(list);
08174 }
08175 else
08176 {
08177 if(ta_number)
08178 {
08179 if(list->head)
08180 {
08181 list->ta_head = NULL;
08182 list->ta_tail = NULL;
08183 list->ta_curr = NULL;
08184 list->ta_count = 0;
08185 list->ta_copied = ta_number;
08186 }
08187 }
08188 }
08189
08190 if(!ta_number)
08191 #endif
08192 if(list->head)
08193 {
08194 remove_all_lol_items(list);
08195 lol_touch(list);
08196 list->dirty = TRUE;
08197 }
08198 rsbac_write_unlock(&list->lock, &lock_flags);
08199 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08200 return 0;
08201 }
08202
08203 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08204 EXPORT_SYMBOL(rsbac_list_lol_remove_all);
08205 #endif
08206 int rsbac_list_lol_remove_all(rsbac_list_handle_t handle)
08207 {
08208 return rsbac_ta_list_lol_remove_all(0, handle);
08209 }
08210
08211
08212
08213
08214 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08215 EXPORT_SYMBOL(rsbac_ta_list_get_data_ttl);
08216 #endif
08217 int rsbac_ta_list_get_data_ttl(
08218 rsbac_list_ta_number_t ta_number,
08219 rsbac_list_handle_t handle,
08220 rsbac_time_t * ttl_p,
08221 void * desc,
08222 void * data)
08223 {
08224 struct rsbac_list_reg_item_t * list;
08225 struct rsbac_list_item_t * item_p;
08226 u_long lock_flags, rlock_flags;
08227 int err = 0;
08228
08229 if(!handle || !desc)
08230 return -RSBAC_EINVALIDVALUE;
08231 if(!list_initialized)
08232 return -RSBAC_ENOTINITIALIZED;
08233
08234 list = (struct rsbac_list_reg_item_t *) handle;
08235 if(list->self != list)
08236 return -RSBAC_EINVALIDVALUE;
08237
08238 #ifdef CONFIG_RSBAC_LIST_TRANS
08239 if(ta_number)
08240 {
08241 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08242 return -RSBAC_EINVALIDTRANSACTION;
08243 }
08244 #endif
08245
08246 rsbac_read_lock(®_head.lock, &rlock_flags);
08247
08248
08249
08250
08251
08252
08253
08254 if(data && !list->info.data_size)
08255 {
08256 rsbac_read_unlock(®_head.lock, &rlock_flags);
08257 return -RSBAC_EINVALIDREQUEST;
08258 }
08259
08260 rsbac_read_lock(&list->lock, &lock_flags);
08261 #ifdef CONFIG_RSBAC_LIST_TRANS
08262 if(ta_number && (list->ta_copied == ta_number))
08263 item_p = ta_lookup_item(ta_number, list, desc);
08264 else
08265 #endif
08266 item_p = lookup_item(list, desc);
08267 if( item_p
08268 && ( !item_p->max_age
08269 || (item_p->max_age > RSBAC_CURRENT_TIME)
08270 )
08271 )
08272 {
08273 if(ttl_p)
08274 {
08275 if(item_p->max_age)
08276 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08277 else
08278 *ttl_p = 0;
08279 }
08280 if(data)
08281 {
08282 memcpy(data,
08283 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08284 list->info.data_size);
08285 }
08286 }
08287 else
08288 {
08289 if(!list->def_data)
08290 err = -RSBAC_ENOTFOUND;
08291 else
08292 {
08293 if(ttl_p)
08294 *ttl_p = 0;
08295 if(data)
08296 memcpy(data,
08297 list->def_data,
08298 list->info.data_size);
08299 }
08300 }
08301 rsbac_read_unlock(&list->lock, &lock_flags);
08302 rsbac_read_unlock(®_head.lock, &rlock_flags);
08303 return err;
08304 }
08305
08306 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08307 EXPORT_SYMBOL(rsbac_list_get_data_ttl);
08308 #endif
08309 int rsbac_list_get_data_ttl(rsbac_list_handle_t handle,
08310 rsbac_time_t * ttl_p,
08311 void * desc,
08312 void * data)
08313 {
08314 return rsbac_ta_list_get_data_ttl(0, handle, ttl_p, desc, data);
08315 }
08316
08317 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08318 EXPORT_SYMBOL(rsbac_list_get_data);
08319 #endif
08320 int rsbac_list_get_data(rsbac_list_handle_t handle, void * desc, void * data)
08321 {
08322 return rsbac_ta_list_get_data_ttl(0, handle, NULL, desc, data);
08323 }
08324
08325 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08326 EXPORT_SYMBOL(rsbac_ta_list_lol_get_subdata_ttl);
08327 #endif
08328 int rsbac_ta_list_lol_get_subdata_ttl(
08329 rsbac_list_ta_number_t ta_number,
08330 rsbac_list_handle_t handle,
08331 rsbac_time_t * ttl_p,
08332 void * desc,
08333 void * subdesc,
08334 void * subdata)
08335 {
08336 struct rsbac_list_lol_reg_item_t * list;
08337 struct rsbac_list_lol_item_t * sublist;
08338 struct rsbac_list_item_t * item_p;
08339 u_long lock_flags, rlock_flags;
08340 int err = 0;
08341
08342 if(!handle || !desc || !subdesc)
08343 return -RSBAC_EINVALIDVALUE;
08344 if(!list_initialized)
08345 return -RSBAC_ENOTINITIALIZED;
08346
08347 list = (struct rsbac_list_lol_reg_item_t *) handle;
08348 if(list->self != list)
08349 return -RSBAC_EINVALIDVALUE;
08350
08351 #ifdef CONFIG_RSBAC_LIST_TRANS
08352 if(ta_number)
08353 {
08354 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08355 return -RSBAC_EINVALIDTRANSACTION;
08356 }
08357 #endif
08358
08359 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08360
08361
08362
08363
08364
08365
08366
08367 if(subdata && !list->info.subdata_size)
08368 {
08369 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08370 return -RSBAC_EINVALIDREQUEST;
08371 }
08372
08373 rsbac_read_lock(&list->lock, &lock_flags);
08374
08375 #ifdef CONFIG_RSBAC_LIST_TRANS
08376 if(ta_number && (list->ta_copied == ta_number))
08377 sublist = ta_lookup_lol_item(ta_number, list, desc);
08378 else
08379 #endif
08380 sublist = lookup_lol_item(list, desc);
08381 if(sublist)
08382 {
08383 item_p = lookup_lol_subitem(list, sublist, subdesc);
08384 if( item_p
08385 && ( !item_p->max_age
08386 || (item_p->max_age > RSBAC_CURRENT_TIME)
08387 )
08388 )
08389 {
08390 if(ttl_p)
08391 {
08392 if(item_p->max_age)
08393 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08394 else
08395 *ttl_p = 0;
08396 }
08397 if(subdata)
08398 {
08399 memcpy(subdata,
08400 ((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size,
08401 list->info.subdata_size);
08402 }
08403 }
08404 else
08405 {
08406 if(!list->def_subdata)
08407 err = -RSBAC_ENOTFOUND;
08408 else
08409 {
08410 if(ttl_p)
08411 *ttl_p = 0;
08412 if(subdata)
08413 memcpy(subdata,
08414 list->def_subdata,
08415 list->info.subdata_size);
08416 }
08417 }
08418 }
08419 else
08420 {
08421 if(!list->def_subdata)
08422 err = -RSBAC_ENOTFOUND;
08423 else
08424 {
08425 if(ttl_p)
08426 *ttl_p = 0;
08427 if(subdata)
08428 memcpy(subdata,
08429 list->def_subdata,
08430 list->info.subdata_size);
08431 }
08432 }
08433 rsbac_read_unlock(&list->lock, &lock_flags);
08434 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08435 return err;
08436 }
08437
08438 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08439 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_ttl);
08440 #endif
08441 int rsbac_list_lol_get_subdata_ttl(
08442 rsbac_list_handle_t handle,
08443 rsbac_time_t * ttl_p,
08444 void * desc,
08445 void * subdesc,
08446 void * subdata)
08447 {
08448 return rsbac_ta_list_lol_get_subdata_ttl(0, handle,
08449 ttl_p, desc, subdesc, subdata);
08450 }
08451
08452 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08453 EXPORT_SYMBOL(rsbac_list_lol_get_subdata);
08454 #endif
08455 int rsbac_list_lol_get_subdata(
08456 rsbac_list_handle_t handle,
08457 void * desc,
08458 void * subdesc,
08459 void * subdata)
08460 {
08461 return rsbac_ta_list_lol_get_subdata_ttl(0, handle, NULL, desc, subdesc, subdata);
08462 }
08463
08464 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08465 EXPORT_SYMBOL(rsbac_ta_list_lol_get_data_ttl);
08466 #endif
08467 int rsbac_ta_list_lol_get_data_ttl(
08468 rsbac_list_ta_number_t ta_number,
08469 rsbac_list_handle_t handle,
08470 rsbac_time_t * ttl_p,
08471 void * desc,
08472 void * data)
08473 {
08474 struct rsbac_list_lol_reg_item_t * list;
08475 struct rsbac_list_lol_item_t * item_p;
08476 u_long lock_flags, rlock_flags;
08477 int err = 0;
08478
08479 if(!handle || !desc)
08480 return -RSBAC_EINVALIDVALUE;
08481 if(!list_initialized)
08482 return -RSBAC_ENOTINITIALIZED;
08483
08484 list = (struct rsbac_list_lol_reg_item_t *) handle;
08485 if(list->self != list)
08486 return -RSBAC_EINVALIDVALUE;
08487
08488 #ifdef CONFIG_RSBAC_LIST_TRANS
08489 if(ta_number)
08490 {
08491 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08492 return -RSBAC_EINVALIDTRANSACTION;
08493 }
08494 #endif
08495
08496 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08497
08498
08499
08500
08501
08502
08503
08504 if(data && !list->info.data_size)
08505 {
08506 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08507 return -RSBAC_EINVALIDREQUEST;
08508 }
08509
08510 rsbac_read_lock(&list->lock, &lock_flags);
08511
08512 #ifdef CONFIG_RSBAC_LIST_TRANS
08513 if(ta_number && (list->ta_copied == ta_number))
08514 item_p = ta_lookup_lol_item(ta_number, list, desc);
08515 else
08516 #endif
08517 item_p = lookup_lol_item(list, desc);
08518 if( item_p
08519 && ( !item_p->max_age
08520 || (item_p->max_age > RSBAC_CURRENT_TIME)
08521 )
08522 )
08523 {
08524 if(ttl_p)
08525 {
08526 if(item_p->max_age)
08527 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME;
08528 else
08529 *ttl_p = 0;
08530 }
08531 if(data)
08532 {
08533 memcpy(data,
08534 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size,
08535 list->info.data_size);
08536 }
08537 }
08538 else
08539 {
08540 if(!list->def_data)
08541 err = -RSBAC_ENOTFOUND;
08542 else
08543 {
08544 if(ttl_p)
08545 *ttl_p = 0;
08546 if(data)
08547 memcpy(data,
08548 list->def_data,
08549 list->info.data_size);
08550 }
08551 }
08552 rsbac_read_unlock(&list->lock, &lock_flags);
08553 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08554 return err;
08555 }
08556
08557 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08558 EXPORT_SYMBOL(rsbac_list_lol_get_data_ttl);
08559 #endif
08560 int rsbac_list_lol_get_data_ttl(rsbac_list_handle_t handle,
08561 rsbac_time_t * ttl_p,
08562 void * desc,
08563 void * data)
08564 {
08565 return rsbac_ta_list_lol_get_data_ttl(0, handle, ttl_p, desc, data);
08566 }
08567
08568 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08569 EXPORT_SYMBOL(rsbac_list_lol_get_data);
08570 #endif
08571 int rsbac_list_lol_get_data(rsbac_list_handle_t handle,
08572 void * desc,
08573 void * data)
08574 {
08575 return rsbac_ta_list_lol_get_data_ttl(0, handle, NULL, desc, data);
08576 }
08577
08578 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08579 EXPORT_SYMBOL(rsbac_ta_list_get_max_desc);
08580 #endif
08581 int rsbac_ta_list_get_max_desc(
08582 rsbac_list_ta_number_t ta_number,
08583 rsbac_list_handle_t handle,
08584 void * desc)
08585 {
08586 struct rsbac_list_reg_item_t * list;
08587 struct rsbac_list_item_t * item_p;
08588 u_long lock_flags, rlock_flags;
08589 int err = 0;
08590
08591 if(!handle)
08592 return -RSBAC_EINVALIDVALUE;
08593 if(!list_initialized)
08594 return -RSBAC_ENOTINITIALIZED;
08595
08596 list = (struct rsbac_list_reg_item_t *) handle;
08597 if(list->self != list)
08598 return -RSBAC_EINVALIDVALUE;
08599
08600 #ifdef CONFIG_RSBAC_LIST_TRANS
08601 if(ta_number)
08602 {
08603 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08604 return -RSBAC_EINVALIDTRANSACTION;
08605 }
08606 #endif
08607
08608 rsbac_read_lock(®_head.lock, &rlock_flags);
08609
08610
08611
08612
08613
08614
08615
08616 rsbac_read_lock(&list->lock, &lock_flags);
08617 #ifdef CONFIG_RSBAC_LIST_TRANS
08618 if(ta_number && (list->ta_copied == ta_number))
08619 item_p = list->ta_tail;
08620 else
08621 #endif
08622 item_p = list->tail;
08623 while( item_p
08624 && item_p->max_age
08625 && (item_p->max_age > RSBAC_CURRENT_TIME)
08626 )
08627 item_p = item_p->prev;
08628 if(item_p)
08629 memcpy(desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08630 else
08631 {
08632 memset(desc, 0, list->info.desc_size);
08633 err = -RSBAC_ENOTFOUND;
08634 }
08635 rsbac_read_unlock(&list->lock, &lock_flags);
08636 rsbac_read_unlock(®_head.lock, &rlock_flags);
08637 return err;
08638 }
08639
08640 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08641 EXPORT_SYMBOL(rsbac_list_get_max_desc);
08642 #endif
08643 int rsbac_list_get_max_desc(rsbac_list_handle_t handle, void * desc)
08644 {
08645 return rsbac_ta_list_get_max_desc(0, handle, desc);
08646 }
08647
08648 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08649 EXPORT_SYMBOL(rsbac_ta_list_get_next_desc);
08650 #endif
08651 int rsbac_ta_list_get_next_desc(
08652 rsbac_list_ta_number_t ta_number,
08653 rsbac_list_handle_t handle,
08654 void * old_desc,
08655 void * next_desc)
08656 {
08657 struct rsbac_list_reg_item_t * list;
08658 struct rsbac_list_item_t * item_p;
08659 u_long lock_flags, rlock_flags;
08660
08661 if(!handle)
08662 return -RSBAC_EINVALIDVALUE;
08663 if(!list_initialized)
08664 return -RSBAC_ENOTINITIALIZED;
08665 if(!next_desc)
08666 return -RSBAC_EINVALIDPOINTER;
08667
08668 list = (struct rsbac_list_reg_item_t *) handle;
08669 if(list->self != list)
08670 return -RSBAC_EINVALIDVALUE;
08671
08672 #ifdef CONFIG_RSBAC_LIST_TRANS
08673 if(ta_number)
08674 {
08675 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08676 return -RSBAC_EINVALIDTRANSACTION;
08677 }
08678 #endif
08679
08680 rsbac_read_lock(®_head.lock, &rlock_flags);
08681
08682
08683
08684
08685
08686
08687
08688 rsbac_read_lock(&list->lock, &lock_flags);
08689 if(old_desc)
08690 {
08691 #ifdef CONFIG_RSBAC_LIST_TRANS
08692 if(ta_number && (list->ta_copied == ta_number))
08693 item_p = ta_lookup_item(ta_number, list, old_desc);
08694 else
08695 #endif
08696 item_p = lookup_item(list, old_desc);
08697 if(item_p)
08698 item_p = item_p->next;
08699 }
08700 else
08701 #ifdef CONFIG_RSBAC_LIST_TRANS
08702 if(ta_number && (list->ta_copied == ta_number))
08703 item_p = list->ta_head;
08704 else
08705 #endif
08706 item_p = list->head;
08707 while( item_p
08708 && item_p->max_age
08709 && (item_p->max_age > RSBAC_CURRENT_TIME)
08710 )
08711 item_p = item_p->next;
08712 if(item_p)
08713 {
08714 memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08715 list->curr = item_p;
08716 }
08717 rsbac_read_unlock(&list->lock, &lock_flags);
08718 rsbac_read_unlock(®_head.lock, &rlock_flags);
08719 if(item_p)
08720 return 0;
08721 else
08722 return -RSBAC_ENOTFOUND;
08723 }
08724
08725 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08726 EXPORT_SYMBOL(rsbac_list_get_next_desc);
08727 #endif
08728 int rsbac_list_get_next_desc(rsbac_list_handle_t handle, void * old_desc, void * next_desc)
08729 {
08730 return rsbac_ta_list_get_next_desc(0, handle, old_desc, next_desc);
08731 }
08732
08733 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08734 EXPORT_SYMBOL(rsbac_ta_list_lol_get_next_desc);
08735 #endif
08736 int rsbac_ta_list_lol_get_next_desc(
08737 rsbac_list_ta_number_t ta_number,
08738 rsbac_list_handle_t handle,
08739 void * old_desc,
08740 void * next_desc)
08741 {
08742 struct rsbac_list_lol_reg_item_t * list;
08743 struct rsbac_list_lol_item_t * item_p;
08744 u_long lock_flags, rlock_flags;
08745
08746 if(!handle)
08747 return -RSBAC_EINVALIDVALUE;
08748 if(!list_initialized)
08749 return -RSBAC_ENOTINITIALIZED;
08750 if(!next_desc)
08751 return -RSBAC_EINVALIDPOINTER;
08752
08753 list = (struct rsbac_list_lol_reg_item_t *) handle;
08754 if(list->self != list)
08755 return -RSBAC_EINVALIDVALUE;
08756
08757 #ifdef CONFIG_RSBAC_LIST_TRANS
08758 if(ta_number)
08759 {
08760 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08761 return -RSBAC_EINVALIDTRANSACTION;
08762 }
08763 #endif
08764
08765 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08766
08767
08768
08769
08770
08771
08772
08773 rsbac_read_lock(&list->lock, &lock_flags);
08774 if(old_desc)
08775 {
08776 #ifdef CONFIG_RSBAC_LIST_TRANS
08777 if(ta_number && (list->ta_copied == ta_number))
08778 item_p = ta_lookup_lol_item(ta_number, list, old_desc);
08779 else
08780 #endif
08781 item_p = lookup_lol_item(list, old_desc);
08782 if(item_p)
08783 item_p = item_p->next;
08784 }
08785 else
08786 #ifdef CONFIG_RSBAC_LIST_TRANS
08787 if(ta_number && (list->ta_copied == ta_number))
08788 item_p = list->ta_head;
08789 else
08790 #endif
08791 item_p = list->head;
08792 while( item_p
08793 && item_p->max_age
08794 && (item_p->max_age > RSBAC_CURRENT_TIME)
08795 )
08796 item_p = item_p->next;
08797 if(item_p)
08798 {
08799 memcpy(next_desc, (char *)item_p + sizeof(*item_p), list->info.desc_size);
08800 list->curr = item_p;
08801 }
08802 rsbac_read_unlock(&list->lock, &lock_flags);
08803 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08804 if(item_p)
08805 return 0;
08806 else
08807 return -RSBAC_ENOTFOUND;
08808 }
08809
08810 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08811 EXPORT_SYMBOL(rsbac_list_lol_get_next_desc);
08812 #endif
08813 int rsbac_list_lol_get_next_desc(
08814 rsbac_list_handle_t handle,
08815 void * old_desc,
08816 void * next_desc)
08817 {
08818 return rsbac_ta_list_lol_get_next_desc(0, handle, old_desc, next_desc);
08819 }
08820
08821
08822
08823
08824
08825
08826
08827
08828
08829 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08830 EXPORT_SYMBOL(rsbac_ta_list_get_desc);
08831 #endif
08832 int rsbac_ta_list_get_desc(
08833 rsbac_list_ta_number_t ta_number,
08834 rsbac_list_handle_t handle,
08835 void * desc,
08836 void * data,
08837 rsbac_list_data_compare_function_t compare)
08838 {
08839 struct rsbac_list_reg_item_t * list;
08840 struct rsbac_list_item_t * item_p;
08841 u_long lock_flags, rlock_flags;
08842 int err = 0;
08843
08844 if(!handle || !desc || !data)
08845 return -RSBAC_EINVALIDVALUE;
08846 if(!list_initialized)
08847 return -RSBAC_ENOTINITIALIZED;
08848
08849 list = (struct rsbac_list_reg_item_t *) handle;
08850 if(list->self != list)
08851 return -RSBAC_EINVALIDVALUE;
08852
08853 #ifdef CONFIG_RSBAC_LIST_TRANS
08854 if(ta_number)
08855 {
08856 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08857 return -RSBAC_EINVALIDTRANSACTION;
08858 }
08859 #endif
08860
08861 rsbac_read_lock(®_head.lock, &rlock_flags);
08862
08863
08864
08865
08866
08867
08868
08869 if(!list->info.data_size)
08870 {
08871 rsbac_read_unlock(®_head.lock, &rlock_flags);
08872 return -RSBAC_EINVALIDREQUEST;
08873 }
08874
08875 rsbac_read_lock(&list->lock, &lock_flags);
08876
08877 #ifdef CONFIG_RSBAC_LIST_TRANS
08878 if(ta_number && (list->ta_copied == ta_number))
08879 item_p = ta_lookup_item_data(ta_number, list, data, compare);
08880 else
08881 #endif
08882 item_p = lookup_item_data(list, data, compare);
08883 if(item_p)
08884 {
08885 memcpy(desc,
08886 ((char *) item_p) + sizeof(*item_p),
08887 list->info.desc_size);
08888 }
08889 else
08890 {
08891 err = -RSBAC_ENOTFOUND;
08892 }
08893 rsbac_read_unlock(&list->lock, &lock_flags);
08894 rsbac_read_unlock(®_head.lock, &rlock_flags);
08895 return err;
08896 }
08897
08898 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08899 EXPORT_SYMBOL(rsbac_list_get_desc);
08900 #endif
08901 int rsbac_list_get_desc(
08902 rsbac_list_handle_t handle,
08903 void * desc,
08904 void * data,
08905 rsbac_list_data_compare_function_t compare)
08906 {
08907 return rsbac_ta_list_get_desc(0, handle, desc, data, compare);
08908 }
08909
08910 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08911 EXPORT_SYMBOL(rsbac_ta_list_lol_get_desc);
08912 #endif
08913 int rsbac_ta_list_lol_get_desc(
08914 rsbac_list_ta_number_t ta_number,
08915 rsbac_list_handle_t handle,
08916 void * desc,
08917 void * data,
08918 rsbac_list_data_compare_function_t compare)
08919 {
08920 struct rsbac_list_lol_reg_item_t * list;
08921 struct rsbac_list_lol_item_t * item_p;
08922 u_long lock_flags, rlock_flags;
08923 int err = 0;
08924
08925 if(!handle || !desc || !data)
08926 return -RSBAC_EINVALIDVALUE;
08927 if(!list_initialized)
08928 return -RSBAC_ENOTINITIALIZED;
08929
08930 list = (struct rsbac_list_lol_reg_item_t *) handle;
08931 if(list->self != list)
08932 return -RSBAC_EINVALIDVALUE;
08933
08934 #ifdef CONFIG_RSBAC_LIST_TRANS
08935 if(ta_number)
08936 {
08937 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
08938 return -RSBAC_EINVALIDTRANSACTION;
08939 }
08940 #endif
08941
08942 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
08943
08944
08945
08946
08947
08948
08949
08950 if(!list->info.data_size)
08951 {
08952 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08953 return -RSBAC_EINVALIDREQUEST;
08954 }
08955
08956 rsbac_read_lock(&list->lock, &lock_flags);
08957
08958 #ifdef CONFIG_RSBAC_LIST_TRANS
08959 if(ta_number && (list->ta_copied == ta_number))
08960 item_p = ta_lookup_lol_item_data(ta_number, list, data, compare);
08961 else
08962 #endif
08963 item_p = lookup_lol_item_data(list, data, compare);
08964 if(item_p)
08965 {
08966 memcpy(desc,
08967 ((char *) item_p) + sizeof(*item_p),
08968 list->info.desc_size);
08969 }
08970 else
08971 {
08972 err = -RSBAC_ENOTFOUND;
08973 }
08974 rsbac_read_unlock(&list->lock, &lock_flags);
08975 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
08976 return err;
08977 }
08978
08979 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08980 EXPORT_SYMBOL(rsbac_list_lol_get_desc);
08981 #endif
08982 int rsbac_list_lol_get_desc(
08983 rsbac_list_handle_t handle,
08984 void * desc,
08985 void * data,
08986 rsbac_list_data_compare_function_t compare)
08987 {
08988 return rsbac_ta_list_lol_get_desc(0, handle, desc, data, compare);
08989 }
08990
08991
08992 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
08993 EXPORT_SYMBOL(rsbac_ta_list_exist);
08994 #endif
08995 int rsbac_ta_list_exist(
08996 rsbac_list_ta_number_t ta_number,
08997 rsbac_list_handle_t handle,
08998 void * desc)
08999 {
09000 struct rsbac_list_reg_item_t * list;
09001 u_long lock_flags, rlock_flags;
09002 struct rsbac_list_item_t * item_p;
09003 int result;
09004
09005 if(!handle || !desc)
09006 return FALSE;
09007 if(!list_initialized)
09008 return FALSE;
09009
09010 list = (struct rsbac_list_reg_item_t *) handle;
09011 if(list->self != list)
09012 return -RSBAC_EINVALIDVALUE;
09013
09014 #ifdef CONFIG_RSBAC_LIST_TRANS
09015 if(ta_number)
09016 {
09017 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09018 return -RSBAC_EINVALIDTRANSACTION;
09019 }
09020 #endif
09021
09022 rsbac_read_lock(®_head.lock, &rlock_flags);
09023
09024
09025
09026
09027
09028
09029
09030 rsbac_read_lock(&list->lock, &lock_flags);
09031
09032 #ifdef CONFIG_RSBAC_LIST_TRANS
09033 if(ta_number && (list->ta_copied == ta_number))
09034 item_p = ta_lookup_item(ta_number, list, desc);
09035 else
09036 #endif
09037 item_p = lookup_item(list, desc);
09038 if( item_p
09039 && ( !item_p->max_age
09040 || (item_p->max_age > RSBAC_CURRENT_TIME)
09041 )
09042 )
09043 {
09044 result = TRUE;
09045 }
09046 else
09047 {
09048 result = FALSE;
09049 }
09050 rsbac_read_unlock(&list->lock, &lock_flags);
09051 rsbac_read_unlock(®_head.lock, &rlock_flags);
09052 return result;
09053 }
09054
09055 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09056 EXPORT_SYMBOL(rsbac_list_exist);
09057 #endif
09058 int rsbac_list_exist(
09059 rsbac_list_handle_t handle,
09060 void * desc)
09061 {
09062 return rsbac_ta_list_exist(0, handle, desc);
09063 }
09064
09065
09066 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09067 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist);
09068 #endif
09069 int rsbac_ta_list_lol_subexist(
09070 rsbac_list_ta_number_t ta_number,
09071 rsbac_list_handle_t handle,
09072 void * desc,
09073 void * subdesc)
09074 {
09075 struct rsbac_list_lol_reg_item_t * list;
09076 struct rsbac_list_lol_item_t * sublist;
09077 u_long lock_flags, rlock_flags;
09078 struct rsbac_list_item_t * item_p;
09079 int result;
09080
09081 if(!handle || !desc || !subdesc)
09082 return FALSE;
09083 if(!list_initialized)
09084 return FALSE;
09085
09086 list = (struct rsbac_list_lol_reg_item_t *) handle;
09087 if(list->self != list)
09088 return -RSBAC_EINVALIDVALUE;
09089
09090 #ifdef CONFIG_RSBAC_LIST_TRANS
09091 if(ta_number)
09092 {
09093 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09094 return -RSBAC_EINVALIDTRANSACTION;
09095 }
09096 #endif
09097
09098 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09099
09100
09101
09102
09103
09104
09105
09106 rsbac_read_lock(&list->lock, &lock_flags);
09107
09108 #ifdef CONFIG_RSBAC_LIST_TRANS
09109 if(ta_number && (list->ta_copied == ta_number))
09110 sublist = ta_lookup_lol_item(ta_number, list, desc);
09111 else
09112 #endif
09113 sublist = lookup_lol_item(list, desc);
09114 if(sublist)
09115 {
09116 item_p = lookup_lol_subitem(list, sublist, subdesc);
09117 if( item_p
09118 && ( !item_p->max_age
09119 || (item_p->max_age > RSBAC_CURRENT_TIME)
09120 )
09121 )
09122 {
09123 result = TRUE;
09124 }
09125 else
09126 {
09127 result = FALSE;
09128 }
09129 }
09130 else
09131 {
09132 result = FALSE;
09133 }
09134 rsbac_read_unlock(&list->lock, &lock_flags);
09135 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09136 return result;
09137 }
09138
09139 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09140 EXPORT_SYMBOL(rsbac_list_lol_subexist);
09141 #endif
09142 int rsbac_list_lol_subexist(
09143 rsbac_list_handle_t handle,
09144 void * desc,
09145 void * subdesc)
09146 {
09147 return rsbac_ta_list_lol_subexist(0, handle, desc, subdesc);
09148 }
09149
09150 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09151 EXPORT_SYMBOL(rsbac_ta_list_lol_subexist_compare);
09152 #endif
09153 int rsbac_ta_list_lol_subexist_compare(
09154 rsbac_list_ta_number_t ta_number,
09155 rsbac_list_handle_t handle,
09156 void * desc,
09157 void * subdesc,
09158 rsbac_list_compare_function_t compare)
09159 {
09160 struct rsbac_list_lol_reg_item_t * list;
09161 struct rsbac_list_lol_item_t * sublist;
09162 u_long lock_flags, rlock_flags;
09163 struct rsbac_list_item_t * item_p;
09164 int result;
09165
09166 if(!handle || !desc || !subdesc)
09167 return FALSE;
09168 if(!list_initialized)
09169 return FALSE;
09170
09171 if(!compare)
09172 return rsbac_list_lol_subexist(handle, desc, subdesc);
09173
09174 list = (struct rsbac_list_lol_reg_item_t *) handle;
09175 if(list->self != list)
09176 return -RSBAC_EINVALIDVALUE;
09177
09178 #ifdef CONFIG_RSBAC_LIST_TRANS
09179 if(ta_number)
09180 {
09181 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09182 return -RSBAC_EINVALIDTRANSACTION;
09183 }
09184 #endif
09185
09186 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09187
09188
09189
09190
09191
09192
09193
09194 rsbac_read_lock(&list->lock, &lock_flags);
09195
09196 #ifdef CONFIG_RSBAC_LIST_TRANS
09197 if(ta_number && (list->ta_copied == ta_number))
09198 sublist = ta_lookup_lol_item(ta_number, list, desc);
09199 else
09200 #endif
09201 sublist = lookup_lol_item(list, desc);
09202 if(sublist)
09203 {
09204 item_p = lookup_lol_subitem_user_compare(list, sublist, subdesc, compare);
09205 if( item_p
09206 && ( !item_p->max_age
09207 || (item_p->max_age > RSBAC_CURRENT_TIME)
09208 )
09209 )
09210 {
09211 result = TRUE;
09212 }
09213 else
09214 {
09215 result = FALSE;
09216 }
09217 }
09218 else
09219 {
09220 result = FALSE;
09221 }
09222 rsbac_read_unlock(&list->lock, &lock_flags);
09223 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09224 return result;
09225 }
09226
09227 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09228 EXPORT_SYMBOL(rsbac_list_lol_subexist_compare);
09229 #endif
09230 int rsbac_list_lol_subexist_compare(
09231 rsbac_list_handle_t handle,
09232 void * desc,
09233 void * subdesc,
09234 rsbac_list_compare_function_t compare)
09235 {
09236 return rsbac_ta_list_lol_subexist_compare(0, handle,
09237 desc, subdesc, compare);
09238 }
09239
09240 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09241 EXPORT_SYMBOL(rsbac_ta_list_lol_exist);
09242 #endif
09243 int rsbac_ta_list_lol_exist(
09244 rsbac_list_ta_number_t ta_number,
09245 rsbac_list_handle_t handle,
09246 void * desc)
09247 {
09248 struct rsbac_list_lol_reg_item_t * list;
09249 u_long lock_flags, rlock_flags;
09250 struct rsbac_list_lol_item_t * item_p;
09251 int result;
09252
09253 if(!handle || !desc)
09254 return FALSE;
09255 if(!list_initialized)
09256 return FALSE;
09257
09258 list = (struct rsbac_list_lol_reg_item_t *) handle;
09259 if(list->self != list)
09260 return -RSBAC_EINVALIDVALUE;
09261
09262 #ifdef CONFIG_RSBAC_LIST_TRANS
09263 if(ta_number)
09264 {
09265 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09266 return -RSBAC_EINVALIDTRANSACTION;
09267 }
09268 #endif
09269
09270 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09271
09272
09273
09274
09275
09276
09277
09278 rsbac_read_lock(&list->lock, &lock_flags);
09279
09280 #ifdef CONFIG_RSBAC_LIST_TRANS
09281 if(ta_number && (list->ta_copied == ta_number))
09282 item_p = ta_lookup_lol_item(ta_number, list, desc);
09283 else
09284 #endif
09285 item_p = lookup_lol_item(list, desc);
09286 if( item_p
09287 && ( !item_p->max_age
09288 || (item_p->max_age > RSBAC_CURRENT_TIME)
09289 )
09290 )
09291 {
09292 result = TRUE;
09293 }
09294 else
09295 {
09296 result = FALSE;
09297 }
09298 rsbac_read_unlock(&list->lock, &lock_flags);
09299 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09300 return result;
09301 }
09302
09303 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09304 EXPORT_SYMBOL(rsbac_list_lol_exist);
09305 #endif
09306 int rsbac_list_lol_exist(
09307 rsbac_list_handle_t handle,
09308 void * desc)
09309 {
09310 return rsbac_ta_list_lol_exist(0, handle, desc);
09311 }
09312
09313
09314
09315 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09316 EXPORT_SYMBOL(rsbac_ta_list_lol_subcount);
09317 #endif
09318 long rsbac_ta_list_lol_subcount(
09319 rsbac_list_ta_number_t ta_number,
09320 rsbac_list_handle_t handle,
09321 void * desc)
09322 {
09323 struct rsbac_list_lol_reg_item_t * list;
09324 struct rsbac_list_lol_item_t * sublist;
09325 u_long lock_flags, rlock_flags;
09326 long result;
09327
09328 if(!handle)
09329 return -RSBAC_EINVALIDVALUE;
09330 if(!list_initialized)
09331 return -RSBAC_ENOTINITIALIZED;
09332
09333 list = (struct rsbac_list_lol_reg_item_t *) handle;
09334 if(list->self != list)
09335 return -RSBAC_EINVALIDVALUE;
09336
09337 #ifdef CONFIG_RSBAC_LIST_TRANS
09338 if(ta_number)
09339 {
09340 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09341 return -RSBAC_EINVALIDTRANSACTION;
09342 }
09343 #endif
09344
09345 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09346
09347
09348
09349
09350
09351
09352
09353 rsbac_read_lock(&list->lock, &lock_flags);
09354
09355 #ifdef CONFIG_RSBAC_LIST_TRANS
09356 if(ta_number && (list->ta_copied == ta_number))
09357 sublist = ta_lookup_lol_item(ta_number, list, desc);
09358 else
09359 #endif
09360 sublist = lookup_lol_item(list, desc);
09361 if(sublist)
09362 {
09363 result = sublist->count;
09364 }
09365 else
09366 {
09367 result = -RSBAC_ENOTFOUND;
09368 }
09369 rsbac_read_unlock(&list->lock, &lock_flags);
09370 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09371 return result;
09372 }
09373
09374 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09375 EXPORT_SYMBOL(rsbac_list_lol_subcount);
09376 #endif
09377 long rsbac_list_lol_subcount(
09378 rsbac_list_handle_t handle,
09379 void * desc)
09380 {
09381 return rsbac_ta_list_lol_subcount(0, handle, desc);
09382 }
09383
09384 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09385 EXPORT_SYMBOL(rsbac_ta_list_lol_all_subcount);
09386 #endif
09387 long rsbac_ta_list_lol_all_subcount(
09388 rsbac_list_ta_number_t ta_number,
09389 rsbac_list_handle_t handle)
09390 {
09391 struct rsbac_list_lol_reg_item_t * list;
09392 struct rsbac_list_lol_item_t * sublist;
09393 u_long lock_flags, rlock_flags;
09394 long result = 0;
09395
09396 if(!handle)
09397 return -RSBAC_EINVALIDVALUE;
09398 if(!list_initialized)
09399 return -RSBAC_ENOTINITIALIZED;
09400
09401 list = (struct rsbac_list_lol_reg_item_t *) handle;
09402 if(list->self != list)
09403 return -RSBAC_EINVALIDVALUE;
09404
09405 #ifdef CONFIG_RSBAC_LIST_TRANS
09406 if(ta_number)
09407 {
09408 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09409 return -RSBAC_EINVALIDTRANSACTION;
09410 }
09411 #endif
09412
09413 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09414
09415
09416
09417
09418
09419
09420
09421 rsbac_read_lock(&list->lock, &lock_flags);
09422
09423 #ifdef CONFIG_RSBAC_LIST_TRANS
09424 if(ta_number && (list->ta_copied == ta_number))
09425 sublist = list->ta_head;
09426 else
09427 #endif
09428 sublist = list->head;
09429 while(sublist)
09430 {
09431 result += sublist->count;
09432 sublist = sublist->next;
09433 }
09434 rsbac_read_unlock(&list->lock, &lock_flags);
09435 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09436 return result;
09437 }
09438
09439 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09440 EXPORT_SYMBOL(rsbac_list_lol_all_subcount);
09441 #endif
09442 long rsbac_list_lol_all_subcount(rsbac_list_handle_t handle)
09443 {
09444 return rsbac_ta_list_lol_all_subcount(0, handle);
09445 }
09446
09447 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09448 EXPORT_SYMBOL(rsbac_ta_list_lol_count);
09449 #endif
09450 long rsbac_ta_list_lol_count(
09451 rsbac_list_ta_number_t ta_number,
09452 rsbac_list_handle_t handle)
09453 {
09454 struct rsbac_list_lol_reg_item_t * list;
09455
09456 if(!handle)
09457 return -RSBAC_EINVALIDVALUE;
09458 if(!list_initialized)
09459 return -RSBAC_ENOTINITIALIZED;
09460
09461 list = (struct rsbac_list_lol_reg_item_t *) handle;
09462 if(list->self != list)
09463 return -RSBAC_EINVALIDVALUE;
09464
09465 #ifdef CONFIG_RSBAC_LIST_TRANS
09466 if(ta_number)
09467 {
09468 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09469 return -RSBAC_EINVALIDTRANSACTION;
09470 }
09471 #endif
09472
09473
09474
09475
09476
09477
09478
09479
09480 #ifdef CONFIG_RSBAC_LIST_TRANS
09481 if(ta_number && (list->ta_copied == ta_number))
09482 return list->ta_count;
09483 else
09484 #endif
09485 return list->count;
09486 }
09487
09488 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09489 EXPORT_SYMBOL(rsbac_list_lol_count);
09490 #endif
09491 long rsbac_list_lol_count(rsbac_list_handle_t handle)
09492 {
09493 return rsbac_ta_list_lol_count(0, handle);
09494 }
09495
09496 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09497 EXPORT_SYMBOL(rsbac_ta_list_count);
09498 #endif
09499 long rsbac_ta_list_count(
09500 rsbac_list_ta_number_t ta_number,
09501 rsbac_list_handle_t handle)
09502 {
09503 struct rsbac_list_reg_item_t * list;
09504
09505 if(!handle)
09506 return -RSBAC_EINVALIDVALUE;
09507 if(!list_initialized)
09508 return -RSBAC_ENOTINITIALIZED;
09509
09510 list = (struct rsbac_list_reg_item_t *) handle;
09511 if(list->self != list)
09512 return -RSBAC_EINVALIDVALUE;
09513
09514 #ifdef CONFIG_RSBAC_LIST_TRANS
09515 if(ta_number)
09516 {
09517 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09518 return -RSBAC_EINVALIDTRANSACTION;
09519 }
09520 #endif
09521
09522 #ifdef CONFIG_RSBAC_LIST_TRANS
09523 if(ta_number && (list->ta_copied == ta_number))
09524 return list->ta_count;
09525 else
09526 #endif
09527 return list->count;
09528 }
09529
09530 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09531 EXPORT_SYMBOL(rsbac_list_count);
09532 #endif
09533 long rsbac_list_count(rsbac_list_handle_t handle)
09534 {
09535 return rsbac_ta_list_count(0, handle);
09536 }
09537
09538
09539
09540
09541
09542
09543
09544 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09545 EXPORT_SYMBOL(rsbac_ta_list_get_all_desc);
09546 #endif
09547 long rsbac_ta_list_get_all_desc(
09548 rsbac_list_ta_number_t ta_number,
09549 rsbac_list_handle_t handle,
09550 void ** array_p)
09551 {
09552 struct rsbac_list_reg_item_t * list;
09553 struct rsbac_list_item_t * item_p;
09554 char * buffer;
09555 u_long lock_flags, rlock_flags;
09556 u_long offset = 0;
09557 long result = 0;
09558 u_int item_size;
09559
09560 if(!handle)
09561 return -RSBAC_EINVALIDVALUE;
09562 if(!array_p)
09563 return -RSBAC_EINVALIDVALUE;
09564 if(!list_initialized)
09565 return -RSBAC_ENOTINITIALIZED;
09566
09567 list = (struct rsbac_list_reg_item_t *) handle;
09568 if(list->self != list)
09569 return -RSBAC_EINVALIDVALUE;
09570 *array_p = NULL;
09571
09572 #ifdef CONFIG_RSBAC_LIST_TRANS
09573 if(ta_number)
09574 {
09575 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09576 return -RSBAC_EINVALIDTRANSACTION;
09577 }
09578 #endif
09579
09580 rsbac_read_lock(®_head.lock, &rlock_flags);
09581
09582
09583
09584
09585
09586
09587
09588 rsbac_read_lock(&list->lock, &lock_flags);
09589 #ifdef CONFIG_RSBAC_LIST_TRANS
09590 if(ta_number && (list->ta_copied == ta_number))
09591 {
09592 if(list->ta_count)
09593 {
09594 item_size = list->info.desc_size;
09595 buffer = rsbac_vmalloc(item_size * list->ta_count);
09596 if(buffer)
09597 {
09598 item_p = list->ta_head;
09599 while(item_p)
09600 {
09601 if( !item_p->max_age
09602 || (item_p->max_age > RSBAC_CURRENT_TIME)
09603 )
09604 {
09605 memcpy(buffer + offset,
09606 ((char *) item_p) + sizeof(*item_p),
09607 item_size);
09608 offset += item_size;
09609 result++;
09610 }
09611 item_p = item_p->next;
09612 }
09613 *array_p = buffer;
09614 }
09615 else
09616 {
09617 result = -RSBAC_ENOMEM;
09618 }
09619 }
09620 }
09621 else
09622 #endif
09623 if(list->count)
09624 {
09625 item_size = list->info.desc_size;
09626 buffer = rsbac_vmalloc(item_size * list->count);
09627 if(buffer)
09628 {
09629 item_p = list->head;
09630 while(item_p)
09631 {
09632 if( !item_p->max_age
09633 || (item_p->max_age > RSBAC_CURRENT_TIME)
09634 )
09635 {
09636 memcpy(buffer + offset,
09637 ((char *) item_p) + sizeof(*item_p),
09638 item_size);
09639 offset += item_size;
09640 result++;
09641 }
09642 item_p = item_p->next;
09643 }
09644 *array_p = buffer;
09645 }
09646 else
09647 {
09648 result = -RSBAC_ENOMEM;
09649 }
09650 }
09651 rsbac_read_unlock(&list->lock, &lock_flags);
09652 rsbac_read_unlock(®_head.lock, &rlock_flags);
09653 return result;
09654 }
09655
09656 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09657 EXPORT_SYMBOL(rsbac_list_get_all_desc);
09658 #endif
09659 long rsbac_list_get_all_desc(
09660 rsbac_list_handle_t handle,
09661 void ** array_p)
09662 {
09663 return rsbac_ta_list_get_all_desc(0, handle, array_p);
09664 }
09665
09666 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09667 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdesc_ttl);
09668 #endif
09669 long rsbac_ta_list_lol_get_all_subdesc_ttl(
09670 rsbac_list_ta_number_t ta_number,
09671 rsbac_list_handle_t handle,
09672 void * desc,
09673 void ** array_p,
09674 rsbac_time_t ** ttl_array_p)
09675 {
09676 struct rsbac_list_lol_reg_item_t * list;
09677 struct rsbac_list_lol_item_t * sublist;
09678 struct rsbac_list_item_t * item_p;
09679 char * buffer;
09680 rsbac_time_t * ttl_p = NULL;
09681 u_long lock_flags, rlock_flags;
09682 u_long offset = 0;
09683 long result = 0;
09684 u_int item_size;
09685
09686 if(!handle)
09687 return -RSBAC_EINVALIDVALUE;
09688 if(!array_p)
09689 return -RSBAC_EINVALIDVALUE;
09690 if(!list_initialized)
09691 return -RSBAC_ENOTINITIALIZED;
09692
09693 list = (struct rsbac_list_lol_reg_item_t *) handle;
09694 if(list->self != list)
09695 return -RSBAC_EINVALIDVALUE;
09696 *array_p = NULL;
09697
09698 #ifdef CONFIG_RSBAC_LIST_TRANS
09699 if(ta_number)
09700 {
09701 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09702 return -RSBAC_EINVALIDTRANSACTION;
09703 }
09704 #endif
09705
09706 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09707
09708
09709
09710
09711
09712
09713
09714 rsbac_read_lock(&list->lock, &lock_flags);
09715 #ifdef CONFIG_RSBAC_LIST_TRANS
09716 if(ta_number && (list->ta_copied == ta_number))
09717 sublist = ta_lookup_lol_item(ta_number, list, desc);
09718 else
09719 #endif
09720 sublist = lookup_lol_item(list, desc);
09721 if(sublist && sublist->count)
09722 {
09723 item_size = list->info.subdesc_size;
09724 buffer = rsbac_vmalloc(item_size * sublist->count);
09725 if(buffer)
09726 {
09727 if(ttl_array_p)
09728 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
09729 item_p = sublist->head;
09730 while(item_p)
09731 {
09732 if( !item_p->max_age
09733 || (item_p->max_age > RSBAC_CURRENT_TIME)
09734 )
09735 {
09736 memcpy(buffer + offset,
09737 ((char *) item_p) + sizeof(*item_p),
09738 item_size);
09739 if(ttl_p)
09740 {
09741 if(item_p->max_age)
09742 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
09743 else
09744 ttl_p[result] = 0;
09745 }
09746 offset += item_size;
09747 result++;
09748 }
09749 item_p = item_p->next;
09750 }
09751 *array_p = buffer;
09752 if(ttl_array_p)
09753 *ttl_array_p = ttl_p;
09754 }
09755 else
09756 {
09757 result = -RSBAC_ENOMEM;
09758 }
09759 }
09760 rsbac_read_unlock(&list->lock, &lock_flags);
09761 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09762 return result;
09763 }
09764
09765 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09766 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc_ttl);
09767 #endif
09768 long rsbac_list_lol_get_all_subdesc_ttl(
09769 rsbac_list_handle_t handle,
09770 void * desc,
09771 void ** array_p,
09772 rsbac_time_t ** ttl_array_p)
09773 {
09774 return rsbac_ta_list_lol_get_all_subdesc_ttl(0,
09775 handle,
09776 desc,
09777 array_p,
09778 ttl_array_p);
09779 }
09780
09781 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09782 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc);
09783 #endif
09784 long rsbac_list_lol_get_all_subdesc(rsbac_list_handle_t handle, void * desc, void ** array_p)
09785 {
09786 return rsbac_ta_list_lol_get_all_subdesc_ttl(0, handle,
09787 desc, array_p, NULL);
09788 }
09789
09790 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09791 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_desc);
09792 #endif
09793 long rsbac_ta_list_lol_get_all_desc(
09794 rsbac_list_ta_number_t ta_number,
09795 rsbac_list_handle_t handle,
09796 void ** array_p)
09797 {
09798 struct rsbac_list_lol_reg_item_t * list;
09799 struct rsbac_list_lol_item_t * item_p;
09800 char * buffer;
09801 u_long lock_flags, rlock_flags;
09802 u_long offset = 0;
09803 long result = 0;
09804 u_int item_size;
09805
09806 if(!handle)
09807 return -RSBAC_EINVALIDVALUE;
09808 if(!array_p)
09809 return -RSBAC_EINVALIDVALUE;
09810 if(!list_initialized)
09811 return -RSBAC_ENOTINITIALIZED;
09812
09813 list = (struct rsbac_list_lol_reg_item_t *) handle;
09814 if(list->self != list)
09815 return -RSBAC_EINVALIDVALUE;
09816 *array_p = NULL;
09817
09818 #ifdef CONFIG_RSBAC_LIST_TRANS
09819 if(ta_number)
09820 {
09821 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09822 return -RSBAC_EINVALIDTRANSACTION;
09823 }
09824 #endif
09825
09826 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
09827
09828
09829
09830
09831
09832
09833
09834 rsbac_read_lock(&list->lock, &lock_flags);
09835 #ifdef CONFIG_RSBAC_LIST_TRANS
09836 if(ta_number && (list->ta_copied == ta_number))
09837 {
09838 if(list->ta_count)
09839 {
09840 item_size = list->info.desc_size;
09841 buffer = rsbac_vmalloc(item_size * list->ta_count);
09842 if(buffer)
09843 {
09844 item_p = list->ta_head;
09845 while(item_p)
09846 {
09847 if( !item_p->max_age
09848 || (item_p->max_age > RSBAC_CURRENT_TIME)
09849 )
09850 {
09851 memcpy(buffer + offset,
09852 ((char *) item_p) + sizeof(*item_p),
09853 item_size);
09854 offset += item_size;
09855 result++;
09856 }
09857 item_p = item_p->next;
09858 }
09859 *array_p = buffer;
09860 }
09861 else
09862 {
09863 result = -RSBAC_ENOMEM;
09864 }
09865 }
09866 }
09867 else
09868 #endif
09869 if(list->count)
09870 {
09871 item_size = list->info.desc_size;
09872 buffer = rsbac_vmalloc(item_size * list->count);
09873 if(buffer)
09874 {
09875 item_p = list->head;
09876 while(item_p)
09877 {
09878 if( !item_p->max_age
09879 || (item_p->max_age > RSBAC_CURRENT_TIME)
09880 )
09881 {
09882 memcpy(buffer + offset,
09883 ((char *) item_p) + sizeof(*item_p),
09884 item_size);
09885 offset += item_size;
09886 result++;
09887 }
09888 item_p = item_p->next;
09889 }
09890 *array_p = buffer;
09891 }
09892 else
09893 {
09894 result = -RSBAC_ENOMEM;
09895 }
09896 }
09897 rsbac_read_unlock(&list->lock, &lock_flags);
09898 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
09899 return result;
09900 }
09901
09902 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09903 EXPORT_SYMBOL(rsbac_list_lol_get_all_desc);
09904 #endif
09905 long rsbac_list_lol_get_all_desc(rsbac_list_handle_t handle, void ** array_p)
09906 {
09907 return rsbac_ta_list_lol_get_all_desc(0, handle, array_p);
09908 }
09909
09910
09911
09912
09913
09914
09915 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
09916 EXPORT_SYMBOL(rsbac_ta_list_get_all_data);
09917 #endif
09918 long rsbac_ta_list_get_all_data(
09919 rsbac_list_ta_number_t ta_number,
09920 rsbac_list_handle_t handle,
09921 void ** array_p)
09922 {
09923 struct rsbac_list_reg_item_t * list;
09924 struct rsbac_list_item_t * item_p;
09925 char * buffer;
09926 u_long lock_flags, rlock_flags;
09927 u_long offset = 0;
09928 long result = 0;
09929 u_int item_size;
09930 u_int item_offset;
09931
09932 if(!handle)
09933 return -RSBAC_EINVALIDVALUE;
09934 if(!array_p)
09935 return -RSBAC_EINVALIDVALUE;
09936 if(!list_initialized)
09937 return -RSBAC_ENOTINITIALIZED;
09938
09939 list = (struct rsbac_list_reg_item_t *) handle;
09940 if(list->self != list)
09941 return -RSBAC_EINVALIDVALUE;
09942 *array_p = NULL;
09943
09944 #ifdef CONFIG_RSBAC_LIST_TRANS
09945 if(ta_number)
09946 {
09947 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
09948 return -RSBAC_EINVALIDTRANSACTION;
09949 }
09950 #endif
09951
09952 rsbac_read_lock(®_head.lock, &rlock_flags);
09953
09954
09955
09956
09957
09958
09959
09960 rsbac_read_lock(&list->lock, &lock_flags);
09961 if(!list->info.data_size)
09962 {
09963 rsbac_read_unlock(&list->lock, &lock_flags);
09964 rsbac_read_unlock(®_head.lock, &rlock_flags);
09965 return -RSBAC_EINVALIDREQUEST;
09966 }
09967 #ifdef CONFIG_RSBAC_LIST_TRANS
09968 if(ta_number && (list->ta_copied == ta_number))
09969 {
09970 if(list->ta_count)
09971 {
09972 item_size = list->info.data_size;
09973 item_offset = list->info.desc_size;
09974 buffer = rsbac_vmalloc(item_size * list->ta_count);
09975 if(buffer)
09976 {
09977 item_p = list->ta_head;
09978 while(item_p)
09979 {
09980 if( !item_p->max_age
09981 || (item_p->max_age > RSBAC_CURRENT_TIME)
09982 )
09983 {
09984 memcpy(buffer + offset,
09985 ((char *) item_p) + sizeof(*item_p) + item_offset,
09986 item_size);
09987 offset += item_size;
09988 result++;
09989 }
09990 item_p = item_p->next;
09991 }
09992 *array_p = buffer;
09993 }
09994 else
09995 {
09996 result = -RSBAC_ENOMEM;
09997 }
09998 }
09999 }
10000 else
10001 #endif
10002 if(list->count)
10003 {
10004 item_size = list->info.data_size;
10005 item_offset = list->info.desc_size;
10006 buffer = rsbac_vmalloc(item_size * list->count);
10007 if(buffer)
10008 {
10009 item_p = list->head;
10010 while(item_p)
10011 {
10012 if( !item_p->max_age
10013 || (item_p->max_age > RSBAC_CURRENT_TIME)
10014 )
10015 {
10016 memcpy(buffer + offset,
10017 ((char *) item_p) + sizeof(*item_p) + item_offset,
10018 item_size);
10019 offset += item_size;
10020 result++;
10021 }
10022 item_p = item_p->next;
10023 }
10024 *array_p = buffer;
10025 }
10026 else
10027 {
10028 result = -RSBAC_ENOMEM;
10029 }
10030 }
10031 rsbac_read_unlock(&list->lock, &lock_flags);
10032 rsbac_read_unlock(®_head.lock, &rlock_flags);
10033 return result;
10034 }
10035
10036 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10037 EXPORT_SYMBOL(rsbac_list_get_all_data);
10038 #endif
10039 long rsbac_list_get_all_data(
10040 rsbac_list_handle_t handle,
10041 void ** array_p)
10042 {
10043 return rsbac_ta_list_get_all_data(0, handle, array_p);
10044 }
10045
10046 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10047 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subdata);
10048 #endif
10049 long rsbac_ta_list_lol_get_all_subdata(
10050 rsbac_list_ta_number_t ta_number,
10051 rsbac_list_handle_t handle,
10052 void * desc,
10053 void ** array_p)
10054 {
10055 struct rsbac_list_lol_reg_item_t * list;
10056 struct rsbac_list_lol_item_t * sublist;
10057 struct rsbac_list_item_t * item_p;
10058 char * buffer;
10059 u_long lock_flags, rlock_flags;
10060 u_long offset = 0;
10061 long result = 0;
10062 u_int item_size;
10063 u_int item_offset;
10064
10065 if(!handle)
10066 return -RSBAC_EINVALIDVALUE;
10067 if(!array_p)
10068 return -RSBAC_EINVALIDVALUE;
10069 if(!list_initialized)
10070 return -RSBAC_ENOTINITIALIZED;
10071
10072 list = (struct rsbac_list_lol_reg_item_t *) handle;
10073 if(list->self != list)
10074 return -RSBAC_EINVALIDVALUE;
10075 *array_p = NULL;
10076
10077 #ifdef CONFIG_RSBAC_LIST_TRANS
10078 if(ta_number)
10079 {
10080 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10081 return -RSBAC_EINVALIDTRANSACTION;
10082 }
10083 #endif
10084
10085 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10086
10087
10088
10089
10090
10091
10092
10093 rsbac_read_lock(&list->lock, &lock_flags);
10094 if(!list->info.subdata_size)
10095 {
10096 rsbac_read_unlock(&list->lock, &lock_flags);
10097 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10098 return -RSBAC_EINVALIDREQUEST;
10099 }
10100 #ifdef CONFIG_RSBAC_LIST_TRANS
10101 if(ta_number && (list->ta_copied == ta_number))
10102 sublist = ta_lookup_lol_item(ta_number, list, desc);
10103 else
10104 #endif
10105 sublist = lookup_lol_item(list, desc);
10106 if(sublist && sublist->count)
10107 {
10108 item_size = list->info.subdata_size;
10109 item_offset = list->info.subdesc_size;
10110 buffer = rsbac_vmalloc(item_size * sublist->count);
10111 if(buffer)
10112 {
10113 item_p = sublist->head;
10114 while(item_p)
10115 {
10116 if( !item_p->max_age
10117 || (item_p->max_age > RSBAC_CURRENT_TIME)
10118 )
10119 {
10120 memcpy(buffer + offset,
10121 ((char *) item_p) + sizeof(*item_p) + item_offset,
10122 item_size);
10123 offset += item_size;
10124 result++;
10125 }
10126 item_p = item_p->next;
10127 }
10128 *array_p = buffer;
10129 }
10130 else
10131 {
10132 result = -RSBAC_ENOMEM;
10133 }
10134 }
10135 rsbac_read_unlock(&list->lock, &lock_flags);
10136 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10137 return result;
10138 }
10139
10140 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10141 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdata);
10142 #endif
10143 long rsbac_list_lol_get_all_subdata(
10144 rsbac_list_handle_t handle,
10145 void * desc,
10146 void ** array_p)
10147 {
10148 return rsbac_ta_list_lol_get_all_subdata(0, handle, desc, array_p);
10149 }
10150
10151 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10152 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_data);
10153 #endif
10154 long rsbac_ta_list_lol_get_all_data(
10155 rsbac_list_ta_number_t ta_number,
10156 rsbac_list_handle_t handle,
10157 void ** array_p)
10158 {
10159 struct rsbac_list_lol_reg_item_t * list;
10160 struct rsbac_list_lol_item_t * item_p;
10161 char * buffer;
10162 u_long lock_flags, rlock_flags;
10163 u_long offset = 0;
10164 long result = 0;
10165 u_int item_size;
10166 u_int item_offset;
10167
10168 if(!handle)
10169 return -RSBAC_EINVALIDVALUE;
10170 if(!array_p)
10171 return -RSBAC_EINVALIDVALUE;
10172 if(!list_initialized)
10173 return -RSBAC_ENOTINITIALIZED;
10174
10175 list = (struct rsbac_list_lol_reg_item_t *) handle;
10176 if(list->self != list)
10177 return -RSBAC_EINVALIDVALUE;
10178 *array_p = NULL;
10179
10180 #ifdef CONFIG_RSBAC_LIST_TRANS
10181 if(ta_number)
10182 {
10183 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10184 return -RSBAC_EINVALIDTRANSACTION;
10185 }
10186 #endif
10187
10188 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10189
10190
10191
10192
10193
10194
10195
10196 rsbac_read_lock(&list->lock, &lock_flags);
10197 if(!list->info.data_size)
10198 {
10199 rsbac_read_unlock(&list->lock, &lock_flags);
10200 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10201 return -RSBAC_EINVALIDREQUEST;
10202 }
10203 #ifdef CONFIG_RSBAC_LIST_TRANS
10204 if(ta_number && (list->ta_copied == ta_number))
10205 {
10206 if(list->ta_count)
10207 {
10208 item_size = list->info.data_size;
10209 item_offset = list->info.desc_size;
10210 buffer = rsbac_vmalloc(item_size * list->ta_count);
10211 if(buffer)
10212 {
10213 item_p = list->ta_head;
10214 while(item_p)
10215 {
10216 if( !item_p->max_age
10217 || (item_p->max_age > RSBAC_CURRENT_TIME)
10218 )
10219 {
10220 memcpy(buffer + offset,
10221 ((char *) item_p) + sizeof(*item_p) + item_offset,
10222 item_size);
10223 offset += item_size;
10224 result++;
10225 }
10226 item_p = item_p->next;
10227 }
10228 *array_p = buffer;
10229 }
10230 else
10231 {
10232 result = -RSBAC_ENOMEM;
10233 }
10234 }
10235 }
10236 else
10237 #endif
10238 if(list->count)
10239 {
10240 item_size = list->info.data_size;
10241 item_offset = list->info.desc_size;
10242 buffer = rsbac_vmalloc(item_size * list->count);
10243 if(buffer)
10244 {
10245 item_p = list->head;
10246 while(item_p)
10247 {
10248 if( !item_p->max_age
10249 || (item_p->max_age > RSBAC_CURRENT_TIME)
10250 )
10251 {
10252 memcpy(buffer + offset,
10253 ((char *) item_p) + sizeof(*item_p) + item_offset,
10254 item_size);
10255 offset += item_size;
10256 result++;
10257 }
10258 item_p = item_p->next;
10259 }
10260 *array_p = buffer;
10261 }
10262 else
10263 {
10264 result = -RSBAC_ENOMEM;
10265 }
10266 }
10267 rsbac_read_unlock(&list->lock, &lock_flags);
10268 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10269 return result;
10270 }
10271
10272 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10273 EXPORT_SYMBOL(rsbac_list_lol_get_all_data);
10274 #endif
10275 long rsbac_list_lol_get_all_data(
10276 rsbac_list_handle_t handle,
10277 void ** array_p)
10278 {
10279 return rsbac_ta_list_lol_get_all_data(0, handle, array_p);
10280 }
10281
10282
10283
10284 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10285 EXPORT_SYMBOL(rsbac_list_get_item_size);
10286 #endif
10287 int rsbac_list_get_item_size(rsbac_list_handle_t handle)
10288 {
10289 struct rsbac_list_reg_item_t * list;
10290
10291 if(!handle)
10292 return -RSBAC_EINVALIDVALUE;
10293 if(!list_initialized)
10294 return -RSBAC_ENOTINITIALIZED;
10295
10296 list = (struct rsbac_list_reg_item_t *) handle;
10297 if(list->self != list)
10298 return -RSBAC_EINVALIDVALUE;
10299 return list->info.desc_size + list->info.data_size;
10300 }
10301
10302 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10303 EXPORT_SYMBOL(rsbac_list_lol_get_subitem_size);
10304 #endif
10305 int rsbac_list_lol_get_subitem_size(rsbac_list_handle_t handle)
10306 {
10307 struct rsbac_list_lol_reg_item_t * list;
10308
10309 if(!handle)
10310 return -RSBAC_EINVALIDVALUE;
10311 if(!list_initialized)
10312 return -RSBAC_ENOTINITIALIZED;
10313
10314 list = (struct rsbac_list_lol_reg_item_t *) handle;
10315 if(list->self != list)
10316 return -RSBAC_EINVALIDVALUE;
10317 return list->info.subdesc_size + list->info.subdata_size;
10318 }
10319
10320 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10321 EXPORT_SYMBOL(rsbac_list_lol_get_item_size);
10322 #endif
10323 int rsbac_list_lol_get_item_size(rsbac_list_handle_t handle)
10324 {
10325 struct rsbac_list_lol_reg_item_t * list;
10326
10327 if(!handle)
10328 return -RSBAC_EINVALIDVALUE;
10329 if(!list_initialized)
10330 return -RSBAC_ENOTINITIALIZED;
10331
10332 list = (struct rsbac_list_lol_reg_item_t *) handle;
10333 if(list->self != list)
10334 return -RSBAC_EINVALIDVALUE;
10335 return list->info.desc_size + list->info.data_size;
10336 }
10337
10338
10339
10340
10341
10342
10343
10344 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10345 EXPORT_SYMBOL(rsbac_ta_list_get_all_items_ttl);
10346 #endif
10347 long rsbac_ta_list_get_all_items_ttl(
10348 rsbac_list_ta_number_t ta_number,
10349 rsbac_list_handle_t handle,
10350 void ** array_p,
10351 rsbac_time_t ** ttl_array_p)
10352 {
10353 struct rsbac_list_reg_item_t * list;
10354 struct rsbac_list_item_t * item_p;
10355 char * buffer;
10356 rsbac_time_t * ttl_p = NULL;
10357 u_long lock_flags, rlock_flags;
10358 u_long offset = 0;
10359 long result = 0;
10360 u_int item_size;
10361
10362 if(!handle)
10363 return -RSBAC_EINVALIDVALUE;
10364 if(!array_p)
10365 return -RSBAC_EINVALIDPOINTER;
10366 if(!list_initialized)
10367 return -RSBAC_ENOTINITIALIZED;
10368
10369 list = (struct rsbac_list_reg_item_t *) handle;
10370 if(list->self != list)
10371 return -RSBAC_EINVALIDVALUE;
10372 *array_p = NULL;
10373
10374 #ifdef CONFIG_RSBAC_LIST_TRANS
10375 if(ta_number)
10376 {
10377 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10378 return -RSBAC_EINVALIDTRANSACTION;
10379 }
10380 #endif
10381
10382 rsbac_read_lock(®_head.lock, &rlock_flags);
10383
10384
10385
10386
10387
10388
10389
10390 rsbac_read_lock(&list->lock, &lock_flags);
10391 #ifdef CONFIG_RSBAC_LIST_TRANS
10392 if(ta_number && (list->ta_copied == ta_number))
10393 {
10394 if(list->ta_count)
10395 {
10396 item_size = list->info.desc_size + list->info.data_size;
10397 buffer = rsbac_vmalloc(item_size * list->ta_count);
10398 if(buffer)
10399 {
10400 if(ttl_array_p)
10401 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->ta_count);
10402 item_p = list->ta_head;
10403 while(item_p)
10404 {
10405 if( !item_p->max_age
10406 || (item_p->max_age > RSBAC_CURRENT_TIME)
10407 )
10408 {
10409 memcpy(buffer + offset,
10410 ((char *) item_p) + sizeof(*item_p),
10411 item_size);
10412 if(ttl_p)
10413 {
10414 if(item_p->max_age)
10415 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10416 else
10417 ttl_p[result] = 0;
10418 }
10419 offset += item_size;
10420 result++;
10421 }
10422 item_p = item_p->next;
10423 }
10424 *array_p = buffer;
10425 if(ttl_array_p)
10426 *ttl_array_p = ttl_p;
10427 }
10428 else
10429 {
10430 result = -RSBAC_ENOMEM;
10431 }
10432 }
10433 }
10434 else
10435 #endif
10436 if(list->count)
10437 {
10438 item_size = list->info.desc_size + list->info.data_size;
10439 buffer = rsbac_vmalloc(item_size * list->count);
10440 if(buffer)
10441 {
10442 if(ttl_array_p)
10443 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->count);
10444 item_p = list->head;
10445 while(item_p)
10446 {
10447 if( !item_p->max_age
10448 || (item_p->max_age > RSBAC_CURRENT_TIME)
10449 )
10450 {
10451 memcpy(buffer + offset,
10452 ((char *) item_p) + sizeof(*item_p),
10453 item_size);
10454 if(ttl_p)
10455 {
10456 if(item_p->max_age)
10457 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10458 else
10459 ttl_p[result] = 0;
10460 }
10461 offset += item_size;
10462 result++;
10463 }
10464 item_p = item_p->next;
10465 }
10466 *array_p = buffer;
10467 if(ttl_array_p)
10468 *ttl_array_p = ttl_p;
10469 }
10470 else
10471 {
10472 result = -RSBAC_ENOMEM;
10473 }
10474 }
10475 rsbac_read_unlock(&list->lock, &lock_flags);
10476 rsbac_read_unlock(®_head.lock, &rlock_flags);
10477 return result;
10478 }
10479
10480 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10481 EXPORT_SYMBOL(rsbac_list_get_all_items_ttl);
10482 #endif
10483 long rsbac_list_get_all_items_ttl(
10484 rsbac_list_handle_t handle,
10485 void ** array_p,
10486 rsbac_time_t ** ttl_array_p)
10487 {
10488 return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, ttl_array_p);
10489 }
10490
10491 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10492 EXPORT_SYMBOL(rsbac_list_get_all_items);
10493 #endif
10494 long rsbac_list_get_all_items(rsbac_list_handle_t handle, void ** array_p)
10495 {
10496 return rsbac_ta_list_get_all_items_ttl(0, handle, array_p, NULL);
10497 }
10498
10499 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10500 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_subitems_ttl);
10501 #endif
10502 long rsbac_ta_list_lol_get_all_subitems_ttl(
10503 rsbac_list_ta_number_t ta_number,
10504 rsbac_list_handle_t handle,
10505 void * desc,
10506 void ** array_p,
10507 rsbac_time_t ** ttl_array_p)
10508 {
10509 struct rsbac_list_lol_reg_item_t * list;
10510 struct rsbac_list_lol_item_t * sublist;
10511 struct rsbac_list_item_t * item_p;
10512 char * buffer;
10513 rsbac_time_t * ttl_p = NULL;
10514 u_long lock_flags, rlock_flags;
10515 u_long offset = 0;
10516 long result = 0;
10517 u_int item_size;
10518
10519 if(!handle)
10520 return -RSBAC_EINVALIDVALUE;
10521 if(!array_p)
10522 return -RSBAC_EINVALIDVALUE;
10523 if(!list_initialized)
10524 return -RSBAC_ENOTINITIALIZED;
10525
10526 list = (struct rsbac_list_lol_reg_item_t *) handle;
10527 if(list->self != list)
10528 return -RSBAC_EINVALIDVALUE;
10529 *array_p = NULL;
10530
10531 #ifdef CONFIG_RSBAC_LIST_TRANS
10532 if(ta_number)
10533 {
10534 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10535 return -RSBAC_EINVALIDTRANSACTION;
10536 }
10537 #endif
10538
10539 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10540
10541
10542
10543
10544
10545
10546
10547 rsbac_read_lock(&list->lock, &lock_flags);
10548 #ifdef CONFIG_RSBAC_LIST_TRANS
10549 if(ta_number && (list->ta_copied == ta_number))
10550 sublist = ta_lookup_lol_item(ta_number, list, desc);
10551 else
10552 #endif
10553 sublist = lookup_lol_item(list, desc);
10554 if(sublist && sublist->count)
10555 {
10556 item_size = list->info.subdesc_size + list->info.subdata_size;
10557 buffer = rsbac_vmalloc(item_size * sublist->count);
10558 if(buffer)
10559 {
10560 if(ttl_array_p)
10561 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count);
10562 item_p = sublist->head;
10563 while(item_p)
10564 {
10565 if( !item_p->max_age
10566 || (item_p->max_age > RSBAC_CURRENT_TIME)
10567 )
10568 {
10569 memcpy(buffer + offset,
10570 ((char *) item_p) + sizeof(*item_p),
10571 item_size);
10572 if(ttl_p)
10573 {
10574 if(item_p->max_age)
10575 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME;
10576 else
10577 ttl_p[result] = 0;
10578 }
10579 offset += item_size;
10580 result++;
10581 }
10582 item_p = item_p->next;
10583 }
10584 *array_p = buffer;
10585 if(ttl_array_p)
10586 *ttl_array_p = ttl_p;
10587 }
10588 else
10589 {
10590 result = -RSBAC_ENOMEM;
10591 }
10592 }
10593 rsbac_read_unlock(&list->lock, &lock_flags);
10594 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags);
10595 return result;
10596 }
10597
10598 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10599 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems_ttl);
10600 #endif
10601 long rsbac_list_lol_get_all_subitems_ttl(
10602 rsbac_list_handle_t handle,
10603 void * desc,
10604 void ** array_p,
10605 rsbac_time_t ** ttl_array_p)
10606 {
10607 return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10608 array_p, ttl_array_p);
10609 }
10610
10611 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10612 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems);
10613 #endif
10614 long rsbac_list_lol_get_all_subitems(rsbac_list_handle_t handle, void * desc, void ** array_p)
10615 {
10616 return rsbac_ta_list_lol_get_all_subitems_ttl(0, handle, desc,
10617 array_p, NULL);
10618 }
10619
10620 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10621 EXPORT_SYMBOL(rsbac_ta_list_lol_get_all_items);
10622 #endif
10623 long rsbac_ta_list_lol_get_all_items(
10624 rsbac_list_ta_number_t ta_number,
10625 rsbac_list_handle_t handle,
10626 void ** array_p)
10627 {
10628 struct rsbac_list_lol_reg_item_t * list;
10629 struct rsbac_list_lol_item_t * item_p;
10630 char * buffer;
10631 u_long lock_flags, rlock_flags;
10632 u_long offset = 0;
10633 long result = 0;
10634 u_int item_size;
10635
10636 if(!handle)
10637 return -RSBAC_EINVALIDVALUE;
10638 if(!array_p)
10639 return -RSBAC_EINVALIDVALUE;
10640 if(!list_initialized)
10641 return -RSBAC_ENOTINITIALIZED;
10642
10643 list = (struct rsbac_list_lol_reg_item_t *) handle;
10644 if(list->self != list)
10645 return -RSBAC_EINVALIDVALUE;
10646 *array_p = NULL;
10647
10648 #ifdef CONFIG_RSBAC_LIST_TRANS
10649 if(ta_number)
10650 {
10651 if(!rsbac_ta_list_exist(0, ta_handle, &ta_number))
10652 return -RSBAC_EINVALIDTRANSACTION;
10653 }
10654 #endif
10655
10656 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags);
10657
10658
10659
10660
10661
10662
10663
10664 rsbac_read_lock(&list->lock, &lock_flags);
10665 #ifdef CONFIG_RSBAC_LIST_TRANS
10666 if(ta_number && (list->ta_copied == ta_number))
10667 {
10668 if(list->ta_count)
10669 {
10670 item_size = list->info.desc_size + list->info.data_size;
10671 buffer = rsbac_vmalloc(item_size * list->ta_count);
10672 if(buffer)
10673 {
10674 item_p = list->ta_head;
10675 while(item_p)
10676 {
10677 if( !item_p->max_age
10678 || (item_p->max_age > RSBAC_CURRENT_TIME)
10679 )
10680 {
10681 memcpy(buffer + offset,
10682 ((char *) item_p) + sizeof(*item_p),
10683 item_size);
10684 offset += item_size;
10685 result++;
10686 }
10687 item_p = item_p->next;
10688 }
10689 *array_p = buffer;
10690 }
10691 else
10692 {
10693 result = -RSBAC_ENOMEM;
10694 }
10695 }
10696 }
10697 else
10698 #endif
10699 if(list->count)
10700 {
10701 item_size = list->info.desc_size + list->info.data_size;
10702 buffer = rsbac_vmalloc(item_size * list->count);
10703 if(buffer)
10704 {
10705 item_p = list->head;
10706 while(item_p)
10707 {
10708 if( !item_p->max_age
10709 || (item_p->max_age > RSBAC_CURRENT_TIME)
10710 )
10711 {
10712 memcpy(buffer + offset,
10713 ((char *) item_p) + sizeof(*item_p),
10714 item_size);
10715 offset += item_size;
10716 result++;
10717 }
10718 item_p = item_p->next;
10719 }
10720 *array_p = buffer;
10721 }
10722 else
10723 {
10724 result = -RSBAC_ENOMEM;
10725 }
10726 }
10727 rsbac_read_unlock(&list->lock, &lock_flags);
10728 rsbac_read_unlock(®_head.lock, &rlock_flags);
10729 return result;
10730 }
10731
10732 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
10733 EXPORT_SYMBOL(rsbac_list_lol_get_all_items);
10734 #endif
10735 long rsbac_list_lol_get_all_items(
10736 rsbac_list_handle_t handle,
10737 void ** array_p)
10738 {
10739 return rsbac_ta_list_lol_get_all_items(0, handle, array_p);
10740 }
10741
10742