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