/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/data_structures/gen_lists.c

Go to the documentation of this file.
00001 /************************************* */ 00002 /* Rule Set Based Access Control */ 00003 /* Author and (c) 1999-2004: */ 00004 /* Amon Ott <ao@rsbac.org> */ 00005 /* Generic lists for all parts */ 00006 /* Last modified: 16/Jun/2004 */ 00007 /************************************* */ 00008 00009 #include <linux/sched.h> 00010 #include <linux/smp_lock.h> 00011 #include <linux/module.h> 00012 #include <asm/uaccess.h> 00013 #include <rsbac/types.h> 00014 #include <rsbac/error.h> 00015 #include <rsbac/helpers.h> 00016 #include <rsbac/getname.h> 00017 #include <rsbac/debug.h> 00018 #include <rsbac/adf.h> 00019 #include <rsbac/aci_data_structures.h> 00020 #include <rsbac/proc_fs.h> 00021 #include <rsbac/rkmem.h> 00022 #include <rsbac/lists.h> 00023 #include <rsbac/gen_lists.h> 00024 00025 /********************/ 00026 /* Global Variables */ 00027 /********************/ 00028 00029 static struct rsbac_list_reg_head_t reg_head; 00030 static struct rsbac_list_lol_reg_head_t lol_reg_head; 00031 static boolean list_initialized=FALSE; 00032 00033 /*********************************/ 00034 /* Data Structures */ 00035 /*********************************/ 00036 00037 static struct rsbac_list_item_t * lookup_item_compare( 00038 struct rsbac_list_reg_item_t * list, 00039 void * desc) 00040 { 00041 struct rsbac_list_item_t * curr; 00042 00043 if(!list || !desc || !list->compare) 00044 return NULL; 00045 00046 curr = list->curr; 00047 if(!curr) 00048 { 00049 curr = list->head; 00050 if(!curr) 00051 return NULL; 00052 } 00053 /* if current item is not the right one, search... */ 00054 /* note: item desc is behind official struct */ 00055 if(list->compare(desc, &curr[1])) 00056 { 00057 if((list->compare(desc, &curr[1]) > 0)) 00058 { 00059 curr = curr->next; 00060 while ( curr 00061 && (list->compare(desc, &curr[1]) > 0) 00062 ) 00063 { 00064 curr = curr->next; 00065 } 00066 } 00067 else 00068 { 00069 curr = curr->prev; 00070 while ( curr 00071 && (list->compare(desc, &curr[1]) < 0) 00072 ) 00073 { 00074 curr = curr->prev; 00075 } 00076 } 00077 if (curr) 00078 { 00079 /* keep for speedup */ 00080 list->curr = curr; 00081 if(!list->compare(desc, &curr[1])) 00082 { 00083 /* found */ 00084 return curr; 00085 } 00086 } 00087 /* NULL or not found */ 00088 return NULL; 00089 } 00090 /* it is the current item -> return it */ 00091 return (curr); 00092 }; 00093 00094 static struct rsbac_list_item_t * lookup_item_memcmp( 00095 struct rsbac_list_reg_item_t * list, 00096 void * desc) 00097 { 00098 struct rsbac_list_item_t * curr; 00099 00100 if(!list || !desc) 00101 return NULL; 00102 00103 curr = list->curr; 00104 if(!curr) 00105 { 00106 curr = list->head; 00107 if(!curr) 00108 return NULL; 00109 } 00110 /* if current item is not the right one, search... */ 00111 /* note: item desc is behind official struct */ 00112 if(memcmp(desc, 00113 &curr[1], 00114 list->info.desc_size)) 00115 { 00116 if(memcmp(desc, 00117 &curr[1], 00118 list->info.desc_size) > 0) 00119 { 00120 curr = curr->next; 00121 while ( curr 00122 && (memcmp(desc, 00123 &curr[1], 00124 list->info.desc_size) > 0) 00125 ) 00126 { 00127 curr = curr->next; 00128 } 00129 } 00130 else 00131 { 00132 curr = curr->prev; 00133 while ( curr 00134 && (memcmp(desc, 00135 &curr[1], 00136 list->info.desc_size) < 0) 00137 ) 00138 { 00139 curr = curr->prev; 00140 } 00141 } 00142 if (curr) 00143 { 00144 /* keep for speedup */ 00145 list->curr = curr; 00146 if(!memcmp(desc, 00147 &curr[1], 00148 list->info.desc_size)) 00149 { 00150 /* found */ 00151 return curr; 00152 } 00153 } 00154 /* not found */ 00155 return NULL; 00156 } 00157 /* it is the current item -> return it */ 00158 return (curr); 00159 }; 00160 00161 static struct rsbac_list_item_t * lookup_item( 00162 struct rsbac_list_reg_item_t * list, 00163 void * desc) 00164 { 00165 if(!list || !desc) 00166 return NULL; 00167 00168 if(list->compare) 00169 return lookup_item_compare(list, desc); 00170 else 00171 return lookup_item_memcmp(list, desc); 00172 } 00173 00174 static struct rsbac_list_item_t * lookup_item_data_compare( 00175 struct rsbac_list_reg_item_t * list, 00176 void * data, 00177 rsbac_list_data_compare_function_t compare) 00178 { 00179 struct rsbac_list_item_t * curr; 00180 00181 if(!list || !data || !compare) 00182 return NULL; 00183 00184 curr = list->head; 00185 00186 /* note: item desc is behind official struct */ 00187 while ( curr 00188 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME)) 00189 || compare((char *)curr + sizeof(*curr) + list->info.desc_size, data) 00190 ) 00191 ) 00192 { 00193 curr = curr->next; 00194 } 00195 /* it is the current item -> return it */ 00196 return (curr); 00197 }; 00198 00199 static struct rsbac_list_item_t * lookup_item_data_memcmp( 00200 struct rsbac_list_reg_item_t * list, 00201 void * data) 00202 { 00203 struct rsbac_list_item_t * curr; 00204 00205 if(!list || !data) 00206 return NULL; 00207 00208 curr = list->head; 00209 00210 /* note: item desc is behind official struct */ 00211 while ( curr 00212 && ( (curr->max_age && (curr->max_age <= RSBAC_CURRENT_TIME)) 00213 || memcmp(data, 00214 &curr[1] + list->info.desc_size, 00215 list->info.data_size) 00216 ) 00217 ) 00218 { 00219 curr = curr->next; 00220 } 00221 /* it is the current item -> return it */ 00222 return (curr); 00223 }; 00224 00225 static struct rsbac_list_item_t * lookup_item_data( 00226 struct rsbac_list_reg_item_t * list, 00227 void * data, 00228 rsbac_list_data_compare_function_t compare) 00229 { 00230 if(!list || !data) 00231 return NULL; 00232 00233 if(compare) 00234 return lookup_item_data_compare(list, data, compare); 00235 else 00236 return lookup_item_data_memcmp(list, data); 00237 } 00238 00239 /* list of lists - subitems */ 00240 00241 static struct rsbac_list_item_t * lookup_lol_subitem_compare( 00242 struct rsbac_list_lol_reg_item_t * list, 00243 struct rsbac_list_lol_item_t * sublist, 00244 void * subdesc, 00245 rsbac_list_compare_function_t compare) 00246 { 00247 struct rsbac_list_item_t * curr; 00248 00249 if(!list || !sublist || !subdesc || !compare) 00250 return NULL; 00251 00252 curr = sublist->curr; 00253 if(!curr) 00254 { 00255 curr = sublist->head; 00256 if(!curr) 00257 return NULL; 00258 } 00259 /* if current item is not the right one, search... */ 00260 /* note: item desc is behind official struct */ 00261 if(compare(&curr[1],subdesc)) 00262 { 00263 if((compare(&curr[1], subdesc) < 0)) 00264 { 00265 curr = curr->next; 00266 while ( curr 00267 && (compare(&curr[1], subdesc) < 0) 00268 ) 00269 { 00270 curr = curr->next; 00271 } 00272 } 00273 else 00274 { 00275 curr = curr->prev; 00276 while ( curr 00277 && (compare(&curr[1], subdesc) > 0) 00278 ) 00279 { 00280 curr = curr->prev; 00281 } 00282 } 00283 if (curr) 00284 { 00285 /* keep for speedup */ 00286 sublist->curr = curr; 00287 if(!compare(&curr[1], subdesc)) 00288 { 00289 /* found */ 00290 return curr; 00291 } 00292 } 00293 /* not found */ 00294 return NULL; 00295 } 00296 /* it is the current item -> return it */ 00297 return (curr); 00298 }; 00299 00300 static struct rsbac_list_item_t * lookup_lol_subitem_memcmp( 00301 struct rsbac_list_lol_reg_item_t * list, 00302 struct rsbac_list_lol_item_t * sublist, 00303 void * subdesc) 00304 { 00305 struct rsbac_list_item_t * curr; 00306 00307 if(!list || !sublist || !subdesc) 00308 return NULL; 00309 00310 curr = sublist->curr; 00311 if(!curr) 00312 { 00313 curr = sublist->head; 00314 if(!curr) 00315 return NULL; 00316 } 00317 /* if current item is not the right one, search... */ 00318 /* note: item desc is behind official struct */ 00319 if(memcmp(subdesc, 00320 &curr[1], 00321 list->info.subdesc_size)) 00322 { 00323 if(memcmp(subdesc, 00324 &curr[1], 00325 list->info.subdesc_size) > 0) 00326 { 00327 curr = curr->next; 00328 while ( curr 00329 && (memcmp(subdesc, 00330 &curr[1], 00331 list->info.subdesc_size) > 0) 00332 ) 00333 { 00334 curr = curr->next; 00335 } 00336 } 00337 else 00338 { 00339 curr = curr->prev; 00340 while ( curr 00341 && (memcmp(subdesc, 00342 &curr[1], 00343 list->info.subdesc_size) < 0) 00344 ) 00345 { 00346 curr = curr->prev; 00347 } 00348 } 00349 if (curr) 00350 { 00351 /* keep for speedup */ 00352 sublist->curr = curr; 00353 if(!memcmp(subdesc, 00354 &curr[1], 00355 list->info.subdesc_size)) 00356 { 00357 /* found */ 00358 return curr; 00359 } 00360 } 00361 /* not found */ 00362 return NULL; 00363 } 00364 /* it is the current item -> return it */ 00365 return (curr); 00366 }; 00367 00368 static struct rsbac_list_item_t * lookup_lol_subitem( 00369 struct rsbac_list_lol_reg_item_t * list, 00370 struct rsbac_list_lol_item_t * sublist, 00371 void * subdesc) 00372 { 00373 if(!list || !sublist || !subdesc) 00374 return NULL; 00375 00376 if(list->subcompare) 00377 return lookup_lol_subitem_compare(list, sublist, subdesc, list->subcompare); 00378 else 00379 return lookup_lol_subitem_memcmp(list, sublist, subdesc); 00380 } 00381 00382 static struct rsbac_list_item_t * lookup_lol_subitem_user_compare( 00383 struct rsbac_list_lol_reg_item_t * list, 00384 struct rsbac_list_lol_item_t * sublist, 00385 void * subdesc, 00386 rsbac_list_compare_function_t compare) 00387 { 00388 struct rsbac_list_item_t * curr; 00389 00390 if(!list || !sublist || !subdesc || !compare) 00391 return NULL; 00392 00393 curr = sublist->head; 00394 /* note: item desc is behind official struct */ 00395 while(curr) 00396 { 00397 if(!compare(&curr[1],subdesc)) 00398 return curr; 00399 curr = curr->next; 00400 } 00401 return (curr); 00402 }; 00403 00404 /* list of lists - items */ 00405 00406 static struct rsbac_list_lol_item_t * lookup_lol_item_compare( 00407 struct rsbac_list_lol_reg_item_t * list, 00408 void * desc) 00409 { 00410 struct rsbac_list_lol_item_t * curr; 00411 00412 if(!list || !desc || !list->compare) 00413 return NULL; 00414 00415 curr = list->curr; 00416 if(!curr) 00417 { 00418 curr = list->head; 00419 if(!curr) 00420 return NULL; 00421 } 00422 /* if current item is not the right one, search... */ 00423 /* note: item desc is behind official struct */ 00424 if(list->compare(desc, &curr[1])) 00425 { 00426 if((list->compare(desc, &curr[1]) > 0)) 00427 { 00428 curr = curr->next; 00429 while ( curr 00430 && (list->compare(desc, &curr[1]) > 0) 00431 ) 00432 { 00433 curr = curr->next; 00434 } 00435 } 00436 else 00437 { 00438 curr = curr->prev; 00439 while ( curr 00440 && (list->compare(desc, &curr[1]) < 0) 00441 ) 00442 { 00443 curr = curr->prev; 00444 } 00445 } 00446 if (curr) 00447 { 00448 /* keep for speedup */ 00449 list->curr = curr; 00450 if(!list->compare(desc, &curr[1])) 00451 { 00452 /* found */ 00453 return curr; 00454 } 00455 } 00456 /* not found */ 00457 return NULL; 00458 } 00459 /* it is the current item -> return it */ 00460 return (curr); 00461 }; 00462 00463 static struct rsbac_list_lol_item_t * lookup_lol_item_memcmp( 00464 struct rsbac_list_lol_reg_item_t * list, 00465 void * desc) 00466 { 00467 struct rsbac_list_lol_item_t * curr; 00468 00469 if(!list || !desc) 00470 return NULL; 00471 00472 curr = list->curr; 00473 if(!curr) 00474 { 00475 curr = list->head; 00476 if(!curr) 00477 return NULL; 00478 } 00479 /* if current item is not the right one, search... */ 00480 /* note: item desc is behind official struct */ 00481 if(memcmp(desc, 00482 &curr[1], 00483 list->info.desc_size)) 00484 { 00485 if(memcmp(desc, 00486 &curr[1], 00487 list->info.desc_size) > 0) 00488 { 00489 curr = curr->next; 00490 while ( curr 00491 && (memcmp(desc, 00492 &curr[1], 00493 list->info.desc_size) > 0) 00494 ) 00495 { 00496 curr = curr->next; 00497 } 00498 } 00499 else 00500 { 00501 curr = curr->prev; 00502 while ( curr 00503 && (memcmp(desc, 00504 &curr[1], 00505 list->info.desc_size) < 0) 00506 ) 00507 { 00508 curr = curr->prev; 00509 } 00510 } 00511 if (curr) 00512 { 00513 /* keep for speedup */ 00514 list->curr = curr; 00515 if(!memcmp(desc, 00516 &curr[1], 00517 list->info.desc_size)) 00518 { 00519 /* found */ 00520 return curr; 00521 } 00522 } 00523 /* not found */ 00524 return NULL; 00525 } 00526 /* it is the current item -> return it */ 00527 return (curr); 00528 }; 00529 00530 static struct rsbac_list_lol_item_t * lookup_lol_item( 00531 struct rsbac_list_lol_reg_item_t * list, 00532 void * desc) 00533 { 00534 if(!list || !desc) 00535 return NULL; 00536 00537 if(list->compare) 00538 return lookup_lol_item_compare(list, desc); 00539 else 00540 return lookup_lol_item_memcmp(list, desc); 00541 } 00542 00543 /* Registration lookup */ 00544 00545 static struct rsbac_list_reg_item_t * lookup_reg(struct rsbac_list_reg_item_t * handle) 00546 { 00547 struct rsbac_list_reg_item_t * curr = reg_head.curr; 00548 00549 if(!handle) 00550 return NULL; 00551 /* if there is no current item or it is not the right one, search... */ 00552 if(curr != handle) 00553 { 00554 curr = reg_head.head; 00555 while (curr && curr != handle) 00556 { 00557 curr = curr->next; 00558 } 00559 if (curr) 00560 reg_head.curr=curr; 00561 #ifdef CONFIG_RSBAC_DEBUG 00562 else 00563 if(rsbac_debug_lists) 00564 { 00565 #ifdef CONFIG_RSBAC_RMSG 00566 rsbac_printk(KERN_DEBUG "lookup_reg(): Lookup of unknown list handle %p\n", 00567 handle); 00568 #endif 00569 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00570 if (!rsbac_nosyslog) 00571 #endif 00572 printk(KERN_DEBUG "lookup_reg(): Lookup of unknown list handle %p\n", 00573 handle); 00574 } 00575 #endif 00576 } 00577 /* it is the current item -> return it */ 00578 return (curr); 00579 }; 00580 00581 static struct rsbac_list_reg_item_t * lookup_reg_name(char * name, kdev_t device) 00582 { 00583 struct rsbac_list_reg_item_t * curr = reg_head.curr; 00584 00585 if(!name) 00586 return NULL; 00587 /* if there is no current item or it is not the right one, search... */ 00588 if( !curr 00589 || ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME) 00590 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device)) 00591 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device)) 00592 ) 00593 ) 00594 { 00595 curr = reg_head.head; 00596 while ( curr 00597 && ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME) 00598 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device)) 00599 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device)) 00600 ) 00601 ) 00602 { 00603 curr = curr->next; 00604 } 00605 if (curr) 00606 reg_head.curr=curr; 00607 #ifdef CONFIG_RSBAC_DEBUG 00608 else 00609 if(rsbac_debug_lists) 00610 { 00611 #ifdef CONFIG_RSBAC_RMSG 00612 rsbac_printk(KERN_DEBUG "lookup_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n", 00613 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 00614 #endif 00615 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00616 if (!rsbac_nosyslog) 00617 #endif 00618 printk(KERN_DEBUG "lookup_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n", 00619 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 00620 } 00621 #endif 00622 } 00623 /* it is the current item -> return it */ 00624 return (curr); 00625 }; 00626 00627 /* List of lists registration lookup */ 00628 00629 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg(struct rsbac_list_lol_reg_item_t * handle) 00630 { 00631 struct rsbac_list_lol_reg_item_t * curr = lol_reg_head.curr; 00632 00633 if(!handle) 00634 return NULL; 00635 /* if there is no current item or it is not the right one, search... */ 00636 if(curr != handle) 00637 { 00638 curr = lol_reg_head.head; 00639 while (curr && curr != handle) 00640 { 00641 curr = curr->next; 00642 } 00643 if (curr) 00644 lol_reg_head.curr=curr; 00645 #ifdef CONFIG_RSBAC_DEBUG 00646 else 00647 if(rsbac_debug_lists) 00648 { 00649 #ifdef CONFIG_RSBAC_RMSG 00650 rsbac_printk(KERN_DEBUG "lookup_lol_reg(): Lookup of unknown list handle %p\n", 00651 handle); 00652 #endif 00653 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00654 if (!rsbac_nosyslog) 00655 #endif 00656 printk(KERN_DEBUG "lookup_lol_reg(): Lookup of unknown list handle %p\n", 00657 handle); 00658 } 00659 #endif 00660 } 00661 /* it is the current item -> return it */ 00662 return (curr); 00663 }; 00664 00665 static struct rsbac_list_lol_reg_item_t * lookup_lol_reg_name(char * name, kdev_t device) 00666 { 00667 struct rsbac_list_lol_reg_item_t * curr = lol_reg_head.curr; 00668 00669 if(!name) 00670 return NULL; 00671 /* if there is no current item or it is not the right one, search... */ 00672 if( !curr 00673 || ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME) 00674 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device)) 00675 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device)) 00676 ) 00677 ) 00678 { 00679 curr = lol_reg_head.head; 00680 while ( curr 00681 && ( strncmp(curr->name, name, RSBAC_LIST_MAX_FILENAME) 00682 || (RSBAC_MAJOR(curr->device) != RSBAC_MAJOR(device)) 00683 || (RSBAC_MINOR(curr->device) != RSBAC_MINOR(device)) 00684 ) 00685 ) 00686 { 00687 curr = curr->next; 00688 } 00689 if (curr) 00690 lol_reg_head.curr=curr; 00691 #ifdef CONFIG_RSBAC_DEBUG 00692 else 00693 if(rsbac_debug_lists) 00694 { 00695 #ifdef CONFIG_RSBAC_RMSG 00696 rsbac_printk(KERN_DEBUG "lookup_lol_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n", 00697 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 00698 #endif 00699 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00700 if (!rsbac_nosyslog) 00701 #endif 00702 printk(KERN_DEBUG "lookup_lol_reg_name(): Lookup of unknown list name %s on device %02u:%02u\n", 00703 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 00704 } 00705 #endif 00706 } 00707 /* it is the current item -> return it */ 00708 return (curr); 00709 }; 00710 00711 /*************/ 00712 /* Add items */ 00713 00714 static struct rsbac_list_item_t * insert_item_compare( 00715 struct rsbac_list_reg_item_t * list, 00716 void * desc, 00717 struct rsbac_list_item_t * new_item_p) 00718 { 00719 struct rsbac_list_item_t * curr; 00720 00721 curr = list->curr; 00722 if(!curr) 00723 curr = list->head; 00724 if((list->compare(desc, &curr[1]) > 0)) 00725 { 00726 curr = curr->next; 00727 while ( curr 00728 && (list->compare(desc, &curr[1]) > 0) 00729 ) 00730 { 00731 curr = curr->next; 00732 } 00733 if (curr) 00734 { 00735 /* insert before curr */ 00736 new_item_p->prev=curr->prev; 00737 new_item_p->next=curr; 00738 curr->prev->next=new_item_p; 00739 curr->prev=new_item_p; 00740 } 00741 else 00742 { 00743 /* insert as last item */ 00744 new_item_p->prev=list->tail; 00745 new_item_p->next=NULL; 00746 list->tail->next=new_item_p; 00747 list->tail=new_item_p; 00748 } 00749 } 00750 else 00751 { 00752 curr = curr->prev; 00753 while ( curr 00754 && (list->compare(desc, &curr[1]) < 0) 00755 ) 00756 { 00757 curr = curr->prev; 00758 } 00759 if (curr) 00760 { 00761 /* insert after curr */ 00762 new_item_p->prev=curr; 00763 new_item_p->next=curr->next; 00764 curr->next->prev=new_item_p; 00765 curr->next=new_item_p; 00766 } 00767 else 00768 { 00769 /* insert as first item */ 00770 new_item_p->prev=NULL; 00771 new_item_p->next=list->head; 00772 list->head->prev=new_item_p; 00773 list->head=new_item_p; 00774 } 00775 } 00776 list->count++; 00777 list->curr=new_item_p; 00778 return(new_item_p); 00779 } 00780 00781 static struct rsbac_list_item_t * insert_item_memcmp( 00782 struct rsbac_list_reg_item_t * list, 00783 void * desc, 00784 struct rsbac_list_item_t * new_item_p) 00785 { 00786 struct rsbac_list_item_t * curr; 00787 00788 curr = list->curr; 00789 if(!curr) 00790 curr = list->head; 00791 if(memcmp(desc, 00792 &curr[1], 00793 list->info.desc_size) > 0) 00794 { 00795 curr = curr->next; 00796 while ( curr 00797 && (memcmp(desc, 00798 &curr[1], 00799 list->info.desc_size) > 0 00800 ) 00801 ) 00802 { 00803 curr = curr->next; 00804 } 00805 if (curr) 00806 { 00807 /* insert before curr */ 00808 new_item_p->prev=curr->prev; 00809 new_item_p->next=curr; 00810 curr->prev->next=new_item_p; 00811 curr->prev=new_item_p; 00812 } 00813 else 00814 { 00815 /* insert as last item */ 00816 new_item_p->prev=list->tail; 00817 new_item_p->next=NULL; 00818 list->tail->next=new_item_p; 00819 list->tail=new_item_p; 00820 } 00821 } 00822 else 00823 { 00824 curr = curr->prev; 00825 while ( curr 00826 && (memcmp(desc, 00827 &curr[1], 00828 list->info.desc_size) < 0 00829 ) 00830 ) 00831 { 00832 curr = curr->prev; 00833 } 00834 if (curr) 00835 { 00836 /* insert after curr */ 00837 new_item_p->prev=curr; 00838 new_item_p->next=curr->next; 00839 curr->next->prev=new_item_p; 00840 curr->next=new_item_p; 00841 } 00842 else 00843 { 00844 /* insert as first item */ 00845 new_item_p->prev=NULL; 00846 new_item_p->next=list->head; 00847 list->head->prev=new_item_p; 00848 list->head=new_item_p; 00849 } 00850 } 00851 list->count++; 00852 list->curr=new_item_p; 00853 return(new_item_p); 00854 } 00855 00856 static struct rsbac_list_item_t * add_item( 00857 struct rsbac_list_reg_item_t * list, 00858 rsbac_time_t max_age, 00859 void * desc, 00860 void * data) 00861 { 00862 struct rsbac_list_item_t * new_item_p = NULL; 00863 00864 if(!list || !desc) 00865 return NULL; 00866 00867 if(!list || !desc) 00868 return NULL; 00869 if(list->info.data_size && !data) 00870 return NULL; 00871 /* item desc and data are behind official struct */ 00872 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) ) 00873 return(NULL); 00874 new_item_p->max_age = max_age; 00875 /* item desc is behind official struct */ 00876 memcpy(&new_item_p[1], 00877 desc, list->info.desc_size); 00878 /* item data is behind official struct and desc */ 00879 /* data might be empty! */ 00880 if(data && list->info.data_size) 00881 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size, 00882 data, 00883 list->info.data_size); 00884 00885 if (!list->head) 00886 { 00887 list->head=new_item_p; 00888 list->tail=new_item_p; 00889 list->curr=new_item_p; 00890 list->count = 1; 00891 new_item_p->prev=NULL; 00892 new_item_p->next=NULL; 00893 return new_item_p; 00894 } 00895 if(list->compare) 00896 return insert_item_compare(list, desc, new_item_p); 00897 else 00898 return insert_item_memcmp(list, desc, new_item_p); 00899 } 00900 00901 00902 static struct rsbac_list_item_t * insert_lol_subitem_compare( 00903 struct rsbac_list_lol_reg_item_t * list, 00904 struct rsbac_list_lol_item_t * sublist, 00905 void * subdesc, 00906 struct rsbac_list_item_t * new_item_p) 00907 { 00908 struct rsbac_list_item_t * curr; 00909 00910 curr = sublist->curr; 00911 if(!curr) 00912 curr = sublist->head; 00913 if((list->subcompare(subdesc, &curr[1]) > 0)) 00914 { 00915 curr = curr->next; 00916 while ( curr 00917 && (list->subcompare(subdesc, &curr[1]) > 0) 00918 ) 00919 { 00920 curr = curr->next; 00921 } 00922 if (curr) 00923 { 00924 /* insert before curr */ 00925 new_item_p->prev=curr->prev; 00926 new_item_p->next=curr; 00927 curr->prev->next=new_item_p; 00928 curr->prev=new_item_p; 00929 } 00930 else 00931 { 00932 /* insert as last item */ 00933 new_item_p->prev=sublist->tail; 00934 new_item_p->next=NULL; 00935 sublist->tail->next=new_item_p; 00936 sublist->tail=new_item_p; 00937 } 00938 } 00939 else 00940 { 00941 curr = curr->prev; 00942 while ( curr 00943 && (list->subcompare(subdesc, &curr[1]) < 0) 00944 ) 00945 { 00946 curr = curr->prev; 00947 } 00948 if (curr) 00949 { 00950 /* insert after curr */ 00951 new_item_p->prev=curr; 00952 new_item_p->next=curr->next; 00953 curr->next->prev=new_item_p; 00954 curr->next=new_item_p; 00955 } 00956 else 00957 { 00958 /* insert as first item */ 00959 new_item_p->prev=NULL; 00960 new_item_p->next=sublist->head; 00961 sublist->head->prev=new_item_p; 00962 sublist->head=new_item_p; 00963 } 00964 } 00965 sublist->count++; 00966 sublist->curr=new_item_p; 00967 return(new_item_p); 00968 } 00969 00970 static struct rsbac_list_item_t * insert_lol_subitem_memcmp( 00971 struct rsbac_list_lol_reg_item_t * list, 00972 struct rsbac_list_lol_item_t * sublist, 00973 void * subdesc, 00974 struct rsbac_list_item_t * new_item_p) 00975 { 00976 struct rsbac_list_item_t * curr; 00977 00978 curr = sublist->curr; 00979 if(!curr) 00980 curr = sublist->head; 00981 if(memcmp(subdesc, 00982 &curr[1], 00983 list->info.subdesc_size) > 0) 00984 { 00985 curr = curr->next; 00986 while ( curr 00987 && (memcmp(subdesc, 00988 &curr[1], 00989 list->info.subdesc_size) > 0 00990 ) 00991 ) 00992 { 00993 curr = curr->next; 00994 } 00995 if (curr) 00996 { 00997 /* insert before curr */ 00998 new_item_p->prev=curr->prev; 00999 new_item_p->next=curr; 01000 curr->prev->next=new_item_p; 01001 curr->prev=new_item_p; 01002 } 01003 else 01004 { 01005 /* insert as last item */ 01006 new_item_p->prev=sublist->tail; 01007 new_item_p->next=NULL; 01008 sublist->tail->next=new_item_p; 01009 sublist->tail=new_item_p; 01010 } 01011 } 01012 else 01013 { 01014 curr = curr->prev; 01015 while ( curr 01016 && (memcmp(subdesc, 01017 &curr[1], 01018 list->info.subdesc_size) < 0 01019 ) 01020 ) 01021 { 01022 curr = curr->prev; 01023 } 01024 if (curr) 01025 { 01026 /* insert after curr */ 01027 new_item_p->prev=curr; 01028 new_item_p->next=curr->next; 01029 curr->next->prev=new_item_p; 01030 curr->next=new_item_p; 01031 } 01032 else 01033 { 01034 /* insert as first item */ 01035 new_item_p->prev=NULL; 01036 new_item_p->next=sublist->head; 01037 sublist->head->prev=new_item_p; 01038 sublist->head=new_item_p; 01039 } 01040 } 01041 sublist->count++; 01042 sublist->curr=new_item_p; 01043 return(new_item_p); 01044 } 01045 01046 static struct rsbac_list_item_t * add_lol_subitem( 01047 struct rsbac_list_lol_reg_item_t * list, 01048 struct rsbac_list_lol_item_t * sublist, 01049 rsbac_time_t max_age, 01050 void * subdesc, 01051 void * subdata) 01052 { 01053 struct rsbac_list_item_t * new_item_p = NULL; 01054 01055 if(!list || !sublist || !subdesc) 01056 return NULL; 01057 if(list->info.subdata_size && !subdata) 01058 return NULL; 01059 /* item desc and data are behind official struct */ 01060 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.subdesc_size + list->info.subdata_size)) ) 01061 return(NULL); 01062 new_item_p->max_age = max_age; 01063 /* item desc is behind official struct */ 01064 memcpy(&new_item_p[1], 01065 subdesc, 01066 list->info.subdesc_size); 01067 /* item data is behind official struct and desc */ 01068 /* subdata might be empty! */ 01069 if(subdata && list->info.subdata_size) 01070 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.subdesc_size, 01071 subdata, 01072 list->info.subdata_size); 01073 01074 if (!sublist->head) 01075 { 01076 sublist->head=new_item_p; 01077 sublist->tail=new_item_p; 01078 sublist->curr=new_item_p; 01079 sublist->count = 1; 01080 new_item_p->prev=NULL; 01081 new_item_p->next=NULL; 01082 return(new_item_p); 01083 } 01084 if(list->subcompare) 01085 return insert_lol_subitem_compare(list, sublist, subdesc, new_item_p); 01086 else 01087 return insert_lol_subitem_memcmp(list, sublist, subdesc, new_item_p); 01088 } 01089 01090 static struct rsbac_list_lol_item_t * insert_lol_item_compare( 01091 struct rsbac_list_lol_reg_item_t * list, 01092 void * desc, 01093 struct rsbac_list_lol_item_t * new_item_p) 01094 { 01095 struct rsbac_list_lol_item_t * curr; 01096 01097 curr = list->curr; 01098 if(!curr) 01099 curr = list->head; 01100 if((list->compare(desc, &curr[1]) > 0)) 01101 { 01102 curr = curr->next; 01103 while ( curr 01104 && (list->compare(desc, &curr[1]) > 0) 01105 ) 01106 { 01107 curr = curr->next; 01108 } 01109 if (curr) 01110 { 01111 /* insert before curr */ 01112 new_item_p->prev=curr->prev; 01113 new_item_p->next=curr; 01114 curr->prev->next=new_item_p; 01115 curr->prev=new_item_p; 01116 } 01117 else 01118 { 01119 /* insert as last item */ 01120 new_item_p->prev=list->tail; 01121 new_item_p->next=NULL; 01122 list->tail->next=new_item_p; 01123 list->tail=new_item_p; 01124 } 01125 } 01126 else 01127 { 01128 curr = curr->prev; 01129 while ( curr 01130 && (list->compare(desc, &curr[1]) < 0) 01131 ) 01132 { 01133 curr = curr->prev; 01134 } 01135 if (curr) 01136 { 01137 /* insert after curr */ 01138 new_item_p->prev=curr; 01139 new_item_p->next=curr->next; 01140 curr->next->prev=new_item_p; 01141 curr->next=new_item_p; 01142 } 01143 else 01144 { 01145 /* insert as first item */ 01146 new_item_p->prev=NULL; 01147 new_item_p->next=list->head; 01148 list->head->prev=new_item_p; 01149 list->head=new_item_p; 01150 } 01151 } 01152 list->count++; 01153 list->curr=new_item_p; 01154 return(new_item_p); 01155 } 01156 01157 static struct rsbac_list_lol_item_t * insert_lol_item_memcmp( 01158 struct rsbac_list_lol_reg_item_t * list, 01159 void * desc, 01160 struct rsbac_list_lol_item_t * new_item_p) 01161 { 01162 struct rsbac_list_lol_item_t * curr; 01163 01164 curr = list->curr; 01165 if(!curr) 01166 curr = list->head; 01167 if(memcmp(desc, 01168 &curr[1], 01169 list->info.desc_size) > 0) 01170 { 01171 curr = curr->next; 01172 while ( curr 01173 && (memcmp(desc, 01174 &curr[1], 01175 list->info.desc_size) > 0 01176 ) 01177 ) 01178 { 01179 curr = curr->next; 01180 } 01181 if (curr) 01182 { 01183 /* insert before curr */ 01184 new_item_p->prev=curr->prev; 01185 new_item_p->next=curr; 01186 curr->prev->next=new_item_p; 01187 curr->prev=new_item_p; 01188 } 01189 else 01190 { 01191 /* insert as last item */ 01192 new_item_p->prev=list->tail; 01193 new_item_p->next=NULL; 01194 list->tail->next=new_item_p; 01195 list->tail=new_item_p; 01196 } 01197 } 01198 else 01199 { 01200 curr = curr->prev; 01201 while ( curr 01202 && (memcmp(desc, 01203 &curr[1], 01204 list->info.desc_size) < 0 01205 ) 01206 ) 01207 { 01208 curr = curr->prev; 01209 } 01210 if (curr) 01211 { 01212 /* insert after curr */ 01213 new_item_p->prev=curr; 01214 new_item_p->next=curr->next; 01215 curr->next->prev=new_item_p; 01216 curr->next=new_item_p; 01217 } 01218 else 01219 { 01220 /* insert as first item */ 01221 new_item_p->prev=NULL; 01222 new_item_p->next=list->head; 01223 list->head->prev=new_item_p; 01224 list->head=new_item_p; 01225 } 01226 } 01227 list->count++; 01228 list->curr=new_item_p; 01229 return(new_item_p); 01230 } 01231 01232 static struct rsbac_list_lol_item_t * add_lol_item( 01233 struct rsbac_list_lol_reg_item_t * list, 01234 rsbac_time_t max_age, 01235 void * desc, 01236 void * data) 01237 { 01238 struct rsbac_list_lol_item_t * new_item_p = NULL; 01239 01240 if(!list || !desc) 01241 return NULL; 01242 if(list->info.data_size && !data) 01243 return NULL; 01244 /* item desc and data are behind official struct */ 01245 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p) + list->info.desc_size + list->info.data_size)) ) 01246 return(NULL); 01247 /* Init sublist */ 01248 new_item_p->head = NULL; 01249 new_item_p->tail = NULL; 01250 new_item_p->curr = NULL; 01251 new_item_p->count = 0; 01252 new_item_p->max_age = max_age; 01253 /* item desc is behind official struct */ 01254 memcpy(&new_item_p[1], 01255 desc, 01256 list->info.desc_size); 01257 /* item data is behind official struct and desc */ 01258 /* data might be empty! */ 01259 if(data && list->info.data_size) 01260 memcpy(((__u8 *) new_item_p) + sizeof(*new_item_p) + list->info.desc_size, 01261 data, 01262 list->info.data_size); 01263 01264 if (!list->head) 01265 { 01266 list->head=new_item_p; 01267 list->tail=new_item_p; 01268 list->curr=new_item_p; 01269 list->count = 1; 01270 new_item_p->prev=NULL; 01271 new_item_p->next=NULL; 01272 return(new_item_p); 01273 } 01274 if(list->compare) 01275 return insert_lol_item_compare(list, desc, new_item_p); 01276 else 01277 return insert_lol_item_memcmp(list, desc, new_item_p); 01278 } 01279 01280 /* Add registration items */ 01281 01282 /* no locking needed */ 01283 static struct rsbac_list_reg_item_t* 01284 create_reg(struct rsbac_list_info_t * info_p, 01285 u_int flags, 01286 rsbac_list_compare_function_t * compare, 01287 rsbac_list_get_conv_t * get_conv, 01288 void * def_data, 01289 char * name, 01290 kdev_t device) 01291 { 01292 struct rsbac_list_reg_item_t * new_item_p = NULL; 01293 01294 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) ) 01295 return(NULL); 01296 new_item_p->info = *info_p; 01297 if(!def_data) 01298 flags &= ~RSBAC_LIST_DEF_DATA; 01299 new_item_p->flags = flags; 01300 new_item_p->compare = compare; 01301 new_item_p->get_conv = get_conv; 01302 if(flags & RSBAC_LIST_DEF_DATA) 01303 { 01304 new_item_p->def_data = rsbac_kmalloc(info_p->data_size); 01305 if(new_item_p->def_data) 01306 memcpy(new_item_p->def_data, def_data, info_p->data_size); 01307 else 01308 { 01309 rsbac_kfree(new_item_p); 01310 return NULL; 01311 } 01312 } 01313 else 01314 new_item_p->def_data = NULL; 01315 if(name) 01316 { 01317 strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME); 01318 new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0; 01319 } 01320 else 01321 { 01322 strcpy(new_item_p->name, RSBAC_LIST_NONAME); 01323 } 01324 new_item_p->device = device; 01325 new_item_p->head = NULL; 01326 new_item_p->tail = NULL; 01327 new_item_p->curr = NULL; 01328 new_item_p->lock = RW_LOCK_UNLOCKED; 01329 new_item_p->count = 0; 01330 new_item_p->dirty = FALSE; 01331 if(flags & RSBAC_LIST_NO_WRITE) 01332 new_item_p->no_write = TRUE; 01333 else 01334 new_item_p->no_write = FALSE; 01335 new_item_p->self = new_item_p; 01336 return(new_item_p); 01337 }; 01338 01339 /* locking needed */ 01340 static struct rsbac_list_reg_item_t* 01341 add_reg(struct rsbac_list_reg_item_t* new_item_p) 01342 { 01343 if (!reg_head.head) 01344 { 01345 reg_head.head=new_item_p; 01346 reg_head.tail=new_item_p; 01347 reg_head.curr=new_item_p; 01348 reg_head.count = 1; 01349 new_item_p->prev=NULL; 01350 new_item_p->next=NULL; 01351 } 01352 else 01353 { 01354 new_item_p->prev=reg_head.tail; 01355 new_item_p->next=NULL; 01356 reg_head.tail->next=new_item_p; 01357 reg_head.tail=new_item_p; 01358 reg_head.curr=new_item_p; 01359 reg_head.count++; 01360 }; 01361 return(new_item_p); 01362 }; 01363 01364 /* no locking needed */ 01365 static struct rsbac_list_lol_reg_item_t* 01366 create_lol_reg(struct rsbac_list_lol_info_t * info_p, 01367 u_int flags, 01368 rsbac_list_compare_function_t * compare, 01369 rsbac_list_compare_function_t * subcompare, 01370 rsbac_list_get_conv_t * get_conv, 01371 rsbac_list_get_conv_t * get_subconv, 01372 void * def_data, 01373 void * def_subdata, 01374 char * name, 01375 kdev_t device) 01376 { 01377 struct rsbac_list_lol_reg_item_t * new_item_p = NULL; 01378 01379 if ( !(new_item_p = rsbac_kmalloc(sizeof(*new_item_p))) ) 01380 return(NULL); 01381 new_item_p->info = *info_p; 01382 if(info_p->data_size && !def_data) 01383 flags &= ~RSBAC_LIST_DEF_DATA; 01384 if(!def_subdata) 01385 flags &= ~RSBAC_LIST_DEF_SUBDATA; 01386 new_item_p->flags = flags; 01387 new_item_p->compare = compare; 01388 new_item_p->subcompare = subcompare; 01389 new_item_p->get_conv = get_conv; 01390 new_item_p->get_subconv = get_subconv; 01391 if( (flags & RSBAC_LIST_DEF_DATA) 01392 && (info_p->data_size) 01393 ) 01394 { 01395 new_item_p->def_data = rsbac_kmalloc(info_p->data_size); 01396 if(new_item_p->def_data) 01397 memcpy(new_item_p->def_data, def_data, info_p->data_size); 01398 else 01399 { 01400 rsbac_kfree(new_item_p); 01401 return NULL; 01402 } 01403 } 01404 else 01405 new_item_p->def_data = NULL; 01406 if(flags & RSBAC_LIST_DEF_SUBDATA) 01407 { 01408 new_item_p->def_subdata = rsbac_kmalloc(info_p->subdata_size); 01409 if(new_item_p->def_subdata) 01410 memcpy(new_item_p->def_subdata, def_subdata, info_p->subdata_size); 01411 else 01412 { 01413 if(new_item_p->def_data) 01414 rsbac_kfree(new_item_p->def_data); 01415 rsbac_kfree(new_item_p); 01416 return NULL; 01417 } 01418 } 01419 else 01420 new_item_p->def_subdata = NULL; 01421 if(name) 01422 { 01423 strncpy(new_item_p->name, name, RSBAC_LIST_MAX_FILENAME); 01424 new_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0; 01425 } 01426 else 01427 { 01428 strcpy(new_item_p->name, RSBAC_LIST_NONAME); 01429 } 01430 new_item_p->device = device; 01431 new_item_p->head = NULL; 01432 new_item_p->tail = NULL; 01433 new_item_p->curr = NULL; 01434 new_item_p->lock = RW_LOCK_UNLOCKED; 01435 new_item_p->count = 0; 01436 new_item_p->dirty = FALSE; 01437 if(flags & RSBAC_LIST_NO_WRITE) 01438 new_item_p->no_write = TRUE; 01439 else 01440 new_item_p->no_write = FALSE; 01441 new_item_p->self = new_item_p; 01442 return(new_item_p); 01443 }; 01444 01445 /* locking needed */ 01446 static struct rsbac_list_lol_reg_item_t* 01447 add_lol_reg(struct rsbac_list_lol_reg_item_t * new_item_p) 01448 { 01449 if (!lol_reg_head.head) 01450 { 01451 lol_reg_head.head=new_item_p; 01452 lol_reg_head.tail=new_item_p; 01453 lol_reg_head.curr=new_item_p; 01454 lol_reg_head.count = 1; 01455 new_item_p->prev=NULL; 01456 new_item_p->next=NULL; 01457 } 01458 else 01459 { 01460 new_item_p->prev=lol_reg_head.tail; 01461 new_item_p->next=NULL; 01462 lol_reg_head.tail->next=new_item_p; 01463 lol_reg_head.tail=new_item_p; 01464 lol_reg_head.curr=new_item_p; 01465 lol_reg_head.count++; 01466 }; 01467 return(new_item_p); 01468 }; 01469 01470 /* Removing items */ 01471 01472 static void do_remove_item( 01473 struct rsbac_list_reg_item_t * list, 01474 struct rsbac_list_item_t * item_p) 01475 { 01476 if(!list || !item_p) 01477 return; 01478 01479 if ( (list->head == item_p) ) 01480 { /* item is head */ 01481 if ( (list->tail == item_p) ) 01482 { /* item is head and tail = only item -> list will be empty*/ 01483 list->head = NULL; 01484 list->tail = NULL; 01485 } 01486 else 01487 { /* item is head, but not tail -> next item becomes head */ 01488 item_p->next->prev = NULL; 01489 list->head = item_p->next; 01490 }; 01491 } 01492 else 01493 { /* item is not head */ 01494 if ( (list->tail == item_p) ) 01495 { /*item is not head, but tail -> previous item becomes tail*/ 01496 item_p->prev->next = NULL; 01497 list->tail = item_p->prev; 01498 } 01499 else 01500 { /* item is neither head nor tail -> item is cut out */ 01501 item_p->prev->next = item_p->next; 01502 item_p->next->prev = item_p->prev; 01503 }; 01504 }; 01505 /* curr is no longer valid -> reset */ 01506 list->curr=NULL; 01507 /* adjust counter */ 01508 list->count--; 01509 /* now we can remove the item from memory */ 01510 rsbac_kfree(item_p); 01511 }; /* end of do_remove_item() */ 01512 01513 static void remove_item( 01514 struct rsbac_list_reg_item_t * list, 01515 void * desc) 01516 { 01517 struct rsbac_list_item_t * item_p; 01518 01519 if(!list || !desc) 01520 return; 01521 /* first we must locate the item. */ 01522 if ( (item_p = lookup_item(list, desc)) ) 01523 { 01524 do_remove_item(list, item_p); 01525 } 01526 }; /* end of remove_item() */ 01527 01528 static void remove_all_items(struct rsbac_list_reg_item_t * list) 01529 { 01530 struct rsbac_list_item_t * item_p; 01531 struct rsbac_list_item_t * next_item_p; 01532 01533 /* cleanup all items */ 01534 item_p = list->head; 01535 while(item_p) 01536 { 01537 next_item_p = item_p->next; 01538 rsbac_kfree(item_p); 01539 item_p = next_item_p; 01540 } 01541 list->head = NULL; 01542 list->tail = NULL; 01543 list->curr = NULL; 01544 list->count = 0; 01545 }; /* end of remove_all_items() */ 01546 01547 01548 static void do_remove_lol_subitem( 01549 struct rsbac_list_lol_item_t * sublist, 01550 struct rsbac_list_item_t * item_p) 01551 { 01552 if(!sublist || !item_p) 01553 return; 01554 01555 if ( (sublist->head == item_p) ) 01556 { /* item is head */ 01557 if ( (sublist->tail == item_p) ) 01558 { /* item is head and tail = only item -> list will be empty*/ 01559 sublist->head = NULL; 01560 sublist->tail = NULL; 01561 } 01562 else 01563 { /* item is head, but not tail -> next item becomes head */ 01564 item_p->next->prev = NULL; 01565 sublist->head = item_p->next; 01566 }; 01567 } 01568 else 01569 { /* item is not head */ 01570 if ( (sublist->tail == item_p) ) 01571 { /*item is not head, but tail -> previous item becomes tail*/ 01572 item_p->prev->next = NULL; 01573 sublist->tail = item_p->prev; 01574 } 01575 else 01576 { /* item is neither head nor tail -> item is cut out */ 01577 item_p->prev->next = item_p->next; 01578 item_p->next->prev = item_p->prev; 01579 } 01580 } 01581 /* curr is no longer valid -> reset */ 01582 sublist->curr=NULL; 01583 /* adjust counter */ 01584 sublist->count--; 01585 /* now we can remove the item from memory */ 01586 rsbac_kfree(item_p); 01587 }; /* end of do_remove_lol_subitem() */ 01588 01589 static void remove_lol_subitem( 01590 struct rsbac_list_lol_reg_item_t * list, 01591 struct rsbac_list_lol_item_t * sublist, 01592 void * subdesc) 01593 { 01594 struct rsbac_list_item_t * item_p; 01595 01596 if(!list || !sublist || !subdesc) 01597 return; 01598 01599 /* first we must locate the item. */ 01600 if ( (item_p = lookup_lol_subitem(list, sublist, subdesc)) ) 01601 { 01602 do_remove_lol_subitem(sublist, item_p); 01603 } 01604 }; /* end of remove_lol_subitem() */ 01605 01606 01607 static void do_remove_lol_item( 01608 struct rsbac_list_lol_reg_item_t * list, 01609 struct rsbac_list_lol_item_t * item_p) 01610 { 01611 struct rsbac_list_item_t * subitem_p; 01612 struct rsbac_list_item_t * next_subitem_p; 01613 01614 if(!list || !item_p) 01615 return; 01616 01617 if ( (list->head == item_p) ) 01618 { /* item is head */ 01619 if ( (list->tail == item_p) ) 01620 { /* item is head and tail = only item -> list will be empty*/ 01621 list->head = NULL; 01622 list->tail = NULL; 01623 } 01624 else 01625 { /* item is head, but not tail -> next item becomes head */ 01626 item_p->next->prev = NULL; 01627 list->head = item_p->next; 01628 }; 01629 } 01630 else 01631 { /* item is not head */ 01632 if ( (list->tail == item_p) ) 01633 { /*item is not head, but tail -> previous item becomes tail*/ 01634 item_p->prev->next = NULL; 01635 list->tail = item_p->prev; 01636 } 01637 else 01638 { /* item is neither head nor tail -> item is cut out */ 01639 item_p->prev->next = item_p->next; 01640 item_p->next->prev = item_p->prev; 01641 }; 01642 }; 01643 /* curr is no longer valid -> reset */ 01644 list->curr=NULL; 01645 /* adjust counter */ 01646 list->count--; 01647 /* first remove subitems */ 01648 subitem_p = item_p->head; 01649 while(subitem_p) 01650 { 01651 next_subitem_p = subitem_p->next; 01652 rsbac_kfree(subitem_p); 01653 subitem_p = next_subitem_p; 01654 } 01655 /* now we can remove the item from memory */ 01656 rsbac_kfree(item_p); 01657 }; 01658 01659 static void remove_lol_item( 01660 struct rsbac_list_lol_reg_item_t * list, 01661 void * desc) 01662 { 01663 struct rsbac_list_lol_item_t * item_p; 01664 01665 if(!list || !desc) 01666 return; 01667 01668 /* first we must locate the item. */ 01669 if ( (item_p = lookup_lol_item(list, desc)) ) 01670 { 01671 do_remove_lol_item(list, item_p); 01672 } 01673 } 01674 01675 static void remove_all_lol_subitems( 01676 struct rsbac_list_lol_item_t * sublist) 01677 { 01678 struct rsbac_list_item_t * subitem_p; 01679 struct rsbac_list_item_t * next_subitem_p; 01680 01681 /* cleanup all items */ 01682 subitem_p = sublist->head; 01683 while(subitem_p) 01684 { 01685 next_subitem_p = subitem_p->next; 01686 rsbac_kfree(subitem_p); 01687 subitem_p = next_subitem_p; 01688 } 01689 sublist->head = NULL; 01690 sublist->tail = NULL; 01691 sublist->curr = NULL; 01692 sublist->count = 0; 01693 }; /* end of remove_all_items() */ 01694 01695 static void remove_all_lol_items(struct rsbac_list_lol_reg_item_t * list) 01696 { 01697 struct rsbac_list_lol_item_t * item_p; 01698 struct rsbac_list_lol_item_t * next_item_p; 01699 struct rsbac_list_item_t * subitem_p; 01700 struct rsbac_list_item_t * next_subitem_p; 01701 01702 /* cleanup all items */ 01703 item_p = list->head; 01704 while(item_p) 01705 { 01706 /* first remove subitems */ 01707 subitem_p = item_p->head; 01708 while(subitem_p) 01709 { 01710 next_subitem_p = subitem_p->next; 01711 rsbac_kfree(subitem_p); 01712 subitem_p = next_subitem_p; 01713 } 01714 next_item_p = item_p->next; 01715 rsbac_kfree(item_p); 01716 item_p = next_item_p; 01717 } 01718 list->head = NULL; 01719 list->tail = NULL; 01720 list->curr = NULL; 01721 list->count = 0; 01722 }; /* end of remove_all_items() */ 01723 01724 /* Remove registration items */ 01725 01726 /* no locking needed */ 01727 static void clear_reg(struct rsbac_list_reg_item_t * item_p) 01728 { 01729 if(item_p) 01730 { 01731 /* now we can remove the item from memory */ 01732 remove_all_items(item_p); 01733 if(item_p->def_data) 01734 rsbac_kfree(item_p->def_data); 01735 rsbac_kfree(item_p); 01736 } 01737 }; 01738 01739 /* locking needed */ 01740 static void remove_reg(struct rsbac_list_reg_item_t * handle) 01741 { 01742 struct rsbac_list_reg_item_t * item_p; 01743 01744 /* first we must locate the item. */ 01745 if ( (item_p = lookup_reg(handle)) ) 01746 { /* ok, item was found */ 01747 /* protect against reuse */ 01748 item_p->self = NULL; 01749 if ( (reg_head.head == item_p) ) 01750 { /* item is head */ 01751 if ( (reg_head.tail == item_p) ) 01752 { /* item is head and tail = only item -> list will be empty*/ 01753 reg_head.head = NULL; 01754 reg_head.tail = NULL; 01755 } 01756 else 01757 { /* item is head, but not tail -> next item becomes head */ 01758 item_p->next->prev = NULL; 01759 reg_head.head = item_p->next; 01760 }; 01761 } 01762 else 01763 { /* item is not head */ 01764 if ( (reg_head.tail == item_p) ) 01765 { /*item is not head, but tail -> previous item becomes tail*/ 01766 item_p->prev->next = NULL; 01767 reg_head.tail = item_p->prev; 01768 } 01769 else 01770 { /* item is neither head nor tail -> item is cut out */ 01771 item_p->prev->next = item_p->next; 01772 item_p->next->prev = item_p->prev; 01773 }; 01774 }; 01775 01776 /* curr is no longer valid -> reset */ 01777 reg_head.curr=NULL; 01778 /* adjust counter */ 01779 reg_head.count--; 01780 /* now we can remove the item from memory */ 01781 clear_reg(item_p); 01782 }; /* end of if: item was found */ 01783 }; /* end of remove_reg() */ 01784 01785 /* no locking needed */ 01786 static void clear_lol_reg(struct rsbac_list_lol_reg_item_t * item_p) 01787 { 01788 if(item_p) 01789 { 01790 /* now we can remove the item from memory */ 01791 remove_all_lol_items(item_p); 01792 if(item_p->def_data) 01793 rsbac_kfree(item_p->def_data); 01794 if(item_p->def_subdata) 01795 rsbac_kfree(item_p->def_subdata); 01796 rsbac_kfree(item_p); 01797 }; 01798 }; 01799 01800 /* locking needed */ 01801 static void remove_lol_reg(struct rsbac_list_lol_reg_item_t * handle) 01802 { 01803 struct rsbac_list_lol_reg_item_t * item_p; 01804 01805 /* first we must locate the item. */ 01806 if ( (item_p = lookup_lol_reg(handle)) ) 01807 { /* ok, item was found */ 01808 /* protect against reuse */ 01809 item_p->self = NULL; 01810 if ( (lol_reg_head.head == item_p) ) 01811 { /* item is head */ 01812 if ( (lol_reg_head.tail == item_p) ) 01813 { /* item is head and tail = only item -> list will be empty*/ 01814 lol_reg_head.head = NULL; 01815 lol_reg_head.tail = NULL; 01816 } 01817 else 01818 { /* item is head, but not tail -> next item becomes head */ 01819 item_p->next->prev = NULL; 01820 lol_reg_head.head = item_p->next; 01821 }; 01822 } 01823 else 01824 { /* item is not head */ 01825 if ( (lol_reg_head.tail == item_p) ) 01826 { /*item is not head, but tail -> previous item becomes tail*/ 01827 item_p->prev->next = NULL; 01828 lol_reg_head.tail = item_p->prev; 01829 } 01830 else 01831 { /* item is neither head nor tail -> item is cut out */ 01832 item_p->prev->next = item_p->next; 01833 item_p->next->prev = item_p->prev; 01834 }; 01835 }; 01836 01837 /* curr is no longer valid -> reset */ 01838 lol_reg_head.curr=NULL; 01839 /* adjust counter */ 01840 lol_reg_head.count--; 01841 /* now we can remove the item from memory */ 01842 clear_lol_reg(item_p); 01843 }; /* end of if: item was found */ 01844 }; /* end of remove_lol_reg() */ 01845 01846 01847 /********************/ 01848 /* Read/Write */ 01849 /********************/ 01850 01851 static int read_list(struct rsbac_list_reg_item_t * list) 01852 { 01853 struct file * file_p; 01854 int err = 0; 01855 int tmperr; 01856 int converr; 01857 rsbac_version_t list_version; 01858 u_long read_count = 0; 01859 u_long flags; 01860 char * old_buf; 01861 char * new_buf; 01862 char * old_data; 01863 char * new_data; 01864 struct rsbac_list_info_t * list_info_p; 01865 rsbac_list_count_t list_count; 01866 rsbac_time_t timestamp; 01867 rsbac_time_t max_age = 0; 01868 rsbac_list_conv_function_t * conv = NULL; 01869 boolean timeout = FALSE; 01870 mm_segment_t oldfs; 01871 01872 list_info_p = rsbac_kmalloc(sizeof(*list_info_p)); 01873 if(!list_info_p) 01874 return -RSBAC_ENOMEM; 01875 file_p = rsbac_kmalloc(sizeof(*file_p)); 01876 if(!file_p) 01877 { 01878 rsbac_kfree(list_info_p); 01879 return -RSBAC_ENOMEM; 01880 } 01881 /* open file */ 01882 if ((err = rsbac_read_open(list->name, 01883 file_p, 01884 list->device) )) 01885 { 01886 rsbac_kfree(list_info_p); 01887 rsbac_kfree(file_p); 01888 return(err); 01889 } 01890 01891 /* OK, now we can start reading */ 01892 /* There is a read function for this file, so check info and read as 01893 * many items as possible. A positive return value means a read success, 01894 * 0 end of file and a negative value an error. */ 01895 01896 /* Set current user space to kernel space, because read() writes */ 01897 /* to user space */ 01898 oldfs = get_fs(); 01899 set_fs(KERNEL_DS); 01900 01901 /* check gen-list on-disk version */ 01902 tmperr = file_p->f_op->read(file_p, 01903 (__u8 *) &list_version, 01904 sizeof(list_version), 01905 &file_p->f_pos); 01906 /* error? */ 01907 if (tmperr < sizeof(list_version)) 01908 { 01909 printk(KERN_WARNING 01910 "read_list(): read error from file!\n"); 01911 err = -RSBAC_EREADFAILED; 01912 goto end_read; 01913 } 01914 /* if wrong list on-disk version, fail */ 01915 switch(list_version) 01916 { 01917 case RSBAC_LIST_DISK_VERSION: 01918 case RSBAC_LIST_DISK_OLD_VERSION: 01919 break; 01920 default: 01921 printk(KERN_WARNING 01922 "read_list(): wrong on-disk list version %u in file %s, expected %u - error!\n", 01923 list_version, 01924 list->name, 01925 RSBAC_LIST_DISK_VERSION); 01926 err = -RSBAC_EREADFAILED; 01927 goto end_read; 01928 } 01929 01930 /* get timestamp */ 01931 tmperr = file_p->f_op->read(file_p, 01932 (__u8 *) &timestamp, 01933 sizeof(timestamp), 01934 &file_p->f_pos); 01935 /* error? */ 01936 if (tmperr < sizeof(timestamp)) 01937 { 01938 printk(KERN_WARNING 01939 "read_list(): timestamp read error from file %s!\n", 01940 list->name); 01941 err = -RSBAC_EREADFAILED; 01942 goto end_read; 01943 } 01944 01945 /* get list info */ 01946 tmperr = file_p->f_op->read(file_p, 01947 (__u8 *) list_info_p, 01948 sizeof(*list_info_p), 01949 &file_p->f_pos); 01950 /* error? */ 01951 if (tmperr < sizeof(*list_info_p)) 01952 { 01953 printk(KERN_WARNING 01954 "read_list(): list info read error from file %s!\n", 01955 list->name); 01956 err = -RSBAC_EREADFAILED; 01957 goto end_read; 01958 } 01959 01960 /* list timed out? System time is measured in seconds. */ 01961 if( list_info_p->max_age 01962 && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME) 01963 timeout = TRUE; 01964 01965 /* Valid key? */ 01966 if (list_info_p->key != list->info.key) 01967 { 01968 if(timeout) 01969 { 01970 printk(KERN_WARNING 01971 "read_list(): accessing timed out list %s with wrong key, ignoring old contents!\n", 01972 list->name); 01973 goto end_read; 01974 } 01975 else 01976 { 01977 printk(KERN_WARNING 01978 "read_list(): try to access list %s with wrong key!\n", 01979 list->name); 01980 err = -EPERM; 01981 goto end_read; 01982 } 01983 } 01984 01985 /* skip the rest, it ignore is requested */ 01986 if(list->flags & RSBAC_LIST_IGNORE_OLD) 01987 goto end_read; 01988 01989 /* if wrong list version, try to get_conv */ 01990 if(list_info_p->version != list->info.version) 01991 { 01992 if(list->get_conv) 01993 conv = list->get_conv(list_info_p->version); 01994 if(!conv) 01995 { 01996 if(timeout) 01997 { 01998 printk(KERN_WARNING 01999 "read_list(): accessing timed out list %s without conversion function, ignoring old contents!\n", 02000 list->name); 02001 goto end_read; 02002 } 02003 else 02004 { 02005 /* complain and set error, if ignore is not requested */ 02006 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION)) 02007 { 02008 printk(KERN_WARNING 02009 "read_list(): cannot convert list version %u of file %s to version %u!\n", 02010 list_info_p->version, 02011 list->name, 02012 list->info.version); 02013 err = -RSBAC_EINVALIDVERSION; 02014 } 02015 goto end_read; 02016 } 02017 } 02018 else 02019 { 02020 printk(KERN_WARNING 02021 "read_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n", 02022 list_info_p->version, 02023 list->name, 02024 RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), 02025 list->info.version); 02026 } 02027 } 02028 else /* same version needs same sizes */ 02029 { 02030 if( (list_info_p->desc_size != list->info.desc_size) 02031 || (list_info_p->data_size != list->info.data_size) 02032 ) 02033 { 02034 if(timeout) 02035 { 02036 printk(KERN_WARNING 02037 "read_list(): accessing timed out list %s with wrong desc or data size, ignoring old contents!\n", 02038 list->name); 02039 goto end_read; 02040 } 02041 else 02042 { 02043 printk(KERN_WARNING 02044 "read_list(): desc or data size mismatch on list %s!\n", 02045 list->name); 02046 err = -RSBAC_EINVALIDVALUE; 02047 goto end_read; 02048 } 02049 } 02050 } 02051 02052 /* get list count */ 02053 tmperr = file_p->f_op->read(file_p, 02054 (__u8 *) &list_count, 02055 sizeof(list_count), 02056 &file_p->f_pos); 02057 /* error? */ 02058 if (tmperr < sizeof(list_count)) 02059 { 02060 printk(KERN_WARNING 02061 "read_list(): list count read error from file %s!\n", 02062 list->name); 02063 err = -RSBAC_EREADFAILED; 02064 goto end_read; 02065 } 02066 02067 /* alloc mem for old and converted item */ 02068 old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size); 02069 if(!old_buf) 02070 { 02071 printk(KERN_WARNING 02072 "read_list(): cannot allocate memory!\n"); 02073 err = -RSBAC_ENOMEM; 02074 goto end_read; 02075 } 02076 new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size); 02077 if(!new_buf) 02078 { 02079 printk(KERN_WARNING 02080 "read_list(): cannot allocate memory!\n"); 02081 rsbac_kfree(old_buf); 02082 err = -RSBAC_ENOMEM; 02083 goto end_read; 02084 } 02085 /* calculate data pointers */ 02086 if(list_info_p->data_size) 02087 old_data = old_buf + list_info_p->desc_size; 02088 else 02089 old_data = NULL; 02090 if(list->info.data_size) 02091 new_data = new_buf + list->info.desc_size; 02092 else 02093 new_data = NULL; 02094 02095 /* actual reading */ 02096 do 02097 { 02098 switch(list_version) 02099 { 02100 case RSBAC_LIST_DISK_VERSION: 02101 tmperr = file_p->f_op->read(file_p, 02102 (char *) &max_age, 02103 sizeof(max_age), 02104 &file_p->f_pos); 02105 break; 02106 case RSBAC_LIST_DISK_OLD_VERSION: 02107 break; 02108 default: 02109 printk(KERN_WARNING 02110 "read_list(): wrong on-disk list version %u in file %s, expected %u - error!\n", 02111 list_version, 02112 list->name, 02113 RSBAC_LIST_DISK_VERSION); 02114 err = -RSBAC_EREADFAILED; 02115 goto end_read; 02116 } 02117 if(conv) 02118 { 02119 tmperr = file_p->f_op->read(file_p, 02120 old_buf, 02121 list_info_p->desc_size + list_info_p->data_size, 02122 &file_p->f_pos); 02123 if(tmperr > 0) 02124 { /* convert */ 02125 converr = conv(old_buf, old_data, 02126 new_buf, new_data); 02127 if(converr) 02128 tmperr = converr; 02129 } 02130 } 02131 else 02132 { 02133 tmperr = file_p->f_op->read(file_p, 02134 new_buf, 02135 list->info.desc_size + list->info.data_size, 02136 &file_p->f_pos); 02137 } 02138 /* if successful, add item */ 02139 if (tmperr > 0) 02140 { 02141 /* wait for write access to list */ 02142 rsbac_write_lock(&list->lock, &flags); 02143 add_item(list, max_age, new_buf, new_data); 02144 /* allow access */ 02145 rsbac_write_unlock(&list->lock, &flags); 02146 read_count++; 02147 /* 02148 #ifdef CONFIG_RSBAC_DEBUG 02149 if (rsbac_debug_lists) printk(KERN_DEBUG "read_list(): read item %i\n", 02150 user_aci.id); 02151 #endif 02152 */ 02153 } 02154 } 02155 while (tmperr > 0); /* end of do */ 02156 02157 if (tmperr < 0) 02158 { 02159 printk(KERN_WARNING "read_list(): read error from file %s!\n", 02160 list->name); 02161 err = -RSBAC_EREADFAILED; 02162 } 02163 rsbac_kfree(old_buf); 02164 rsbac_kfree(new_buf); 02165 02166 if (read_count != list_count) 02167 { 02168 printk(KERN_WARNING "read_list(): read %lu, expected %u items from file %s!\n", 02169 read_count, 02170 list_count, 02171 list->name); 02172 err = -RSBAC_EREADFAILED; 02173 } 02174 02175 end_read: 02176 /* Set current user space back to user space, because read() writes */ 02177 /* to user space */ 02178 set_fs(oldfs); 02179 02180 #ifdef CONFIG_RSBAC_DEBUG 02181 if (rsbac_debug_lists) 02182 { 02183 #ifdef CONFIG_RSBAC_RMSG 02184 rsbac_printk(KERN_DEBUG "read_list(): %lu entries read.\n", 02185 read_count); 02186 #endif 02187 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02188 if (!rsbac_nosyslog) 02189 #endif 02190 printk(KERN_DEBUG "read_list(): %lu entries read.\n", 02191 read_count); 02192 } 02193 #endif 02194 /* We do not need this file any more */ 02195 rsbac_read_close(file_p); 02196 rsbac_kfree(list_info_p); 02197 rsbac_kfree(file_p); 02198 return(err); 02199 }; /* end of read_list() */ 02200 02201 02202 static int read_lol_list(struct rsbac_list_lol_reg_item_t * list) 02203 { 02204 struct file * file_p; 02205 int err = 0; 02206 int tmperr; 02207 int converr; 02208 rsbac_version_t list_version; 02209 u_long read_count = 0; 02210 u_long flags; 02211 u_long sublen; 02212 u_long i; 02213 char * old_buf; 02214 char * new_buf; 02215 char * old_data; 02216 char * new_data; 02217 char * old_subbuf; 02218 char * new_subbuf; 02219 char * old_subdata; 02220 char * new_subdata; 02221 struct rsbac_list_lol_info_t * list_info_p; 02222 rsbac_list_count_t list_count; 02223 rsbac_time_t timestamp; 02224 rsbac_time_t max_age = 0; 02225 rsbac_list_conv_function_t * conv = NULL; 02226 rsbac_list_conv_function_t * subconv = NULL; 02227 boolean timeout = FALSE; 02228 struct rsbac_list_lol_item_t * item_p; 02229 mm_segment_t oldfs; 02230 02231 list_info_p = rsbac_kmalloc(sizeof(*list_info_p)); 02232 if(!list_info_p) 02233 return -RSBAC_ENOMEM; 02234 file_p = rsbac_kmalloc(sizeof(*file_p)); 02235 if(!file_p) 02236 { 02237 rsbac_kfree(list_info_p); 02238 return -RSBAC_ENOMEM; 02239 } 02240 /* open file */ 02241 if ((err = rsbac_read_open(list->name, 02242 file_p, 02243 list->device) )) 02244 { 02245 rsbac_kfree(list_info_p); 02246 rsbac_kfree(file_p); 02247 return(err); 02248 } 02249 02250 /* OK, now we can start reading */ 02251 /* There is a read function for this file, so check info and read as 02252 * many items as possible. A positive return value means a read success, 02253 * 0 end of file and a negative value an error. */ 02254 02255 /* Set current user space to kernel space, because read() writes */ 02256 /* to user space */ 02257 oldfs = get_fs(); 02258 set_fs(KERNEL_DS); 02259 02260 /* check gen-list on-disk version */ 02261 tmperr = file_p->f_op->read(file_p, 02262 (__u8 *) &list_version, 02263 sizeof(list_version), 02264 &file_p->f_pos); 02265 /* error? */ 02266 if (tmperr < sizeof(list_version)) 02267 { 02268 printk(KERN_WARNING 02269 "read_lol_list(): read error from file!\n"); 02270 err = -RSBAC_EREADFAILED; 02271 goto end_read; 02272 } 02273 /* if wrong list on-disk version, fail */ 02274 switch(list_version) 02275 { 02276 case RSBAC_LIST_DISK_VERSION: 02277 break; 02278 case RSBAC_LIST_DISK_OLD_VERSION: 02279 break; 02280 default: 02281 printk(KERN_WARNING 02282 "read_lol_list(): wrong on-disk list version %u in file %s, expected %u - error!\n", 02283 list_version, 02284 list->name, 02285 RSBAC_LIST_DISK_VERSION); 02286 err = -RSBAC_EREADFAILED; 02287 goto end_read; 02288 } 02289 02290 /* get timestamp */ 02291 tmperr = file_p->f_op->read(file_p, 02292 (__u8 *) &timestamp, 02293 sizeof(timestamp), 02294 &file_p->f_pos); 02295 /* error? */ 02296 if (tmperr < sizeof(timestamp)) 02297 { 02298 printk(KERN_WARNING 02299 "read_lol_list(): timestamp read error from file %s!\n", 02300 list->name); 02301 err = -RSBAC_EREADFAILED; 02302 goto end_read; 02303 } 02304 02305 /* get list info */ 02306 tmperr = file_p->f_op->read(file_p, 02307 (__u8 *) list_info_p, 02308 sizeof(*list_info_p), 02309 &file_p->f_pos); 02310 /* error? */ 02311 if (tmperr < sizeof(*list_info_p)) 02312 { 02313 printk(KERN_WARNING 02314 "read_lol_list(): list info read error from file %s!\n", 02315 list->name); 02316 err = -RSBAC_EREADFAILED; 02317 goto end_read; 02318 } 02319 02320 /* list timed out? System time is measured in seconds. */ 02321 if( list_info_p->max_age 02322 && (timestamp + list_info_p->max_age) <= RSBAC_CURRENT_TIME) 02323 timeout = TRUE; 02324 02325 /* Valid key? */ 02326 if (list_info_p->key != list->info.key) 02327 { 02328 if(timeout) 02329 { 02330 printk(KERN_WARNING 02331 "read_lol_list(): accessing timed out list %s with wrong key, ignoring old contents!\n", 02332 list->name); 02333 goto end_read; 02334 } 02335 else 02336 { 02337 printk(KERN_WARNING 02338 "read_lol_list(): try to access list %s with wrong key!\n", 02339 list->name); 02340 err = -EPERM; 02341 goto end_read; 02342 } 02343 } 02344 02345 /* skip the rest, it ignore is requested */ 02346 if(list->flags & RSBAC_LIST_IGNORE_OLD) 02347 goto end_read; 02348 02349 /* if wrong list version, try to get_conv */ 02350 if(list_info_p->version != list->info.version) 02351 { 02352 if(list->get_conv) 02353 conv = list->get_conv(list_info_p->version); 02354 if(list->get_subconv) 02355 subconv = list->get_subconv(list_info_p->version); 02356 if(!conv || !subconv) 02357 { 02358 if(timeout) 02359 { 02360 printk(KERN_WARNING 02361 "read_lol_list(): accessing timed out list %s without both conversion functions, ignoring old contents!\n", 02362 list->name); 02363 goto end_read; 02364 } 02365 else 02366 { 02367 /* complain and set error, if ignore is not requested */ 02368 if(!(list->flags & RSBAC_LIST_IGNORE_UNSUPP_VERSION)) 02369 { 02370 printk(KERN_WARNING 02371 "read_lol_list(): cannot convert list version %u of file %s to version %u!\n", 02372 list_info_p->version, 02373 list->name, 02374 list->info.version); 02375 err = -RSBAC_EINVALIDVERSION; 02376 } 02377 goto end_read; 02378 } 02379 } 02380 else 02381 { 02382 printk(KERN_WARNING 02383 "read_lol_list(): converting list version %u of file %s on device %02u:%02u to version %u!\n", 02384 list_info_p->version, 02385 list->name, 02386 RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), 02387 list->info.version); 02388 } 02389 } 02390 else /* same version needs same sizes */ 02391 { 02392 if( (list_info_p->desc_size != list->info.desc_size) 02393 || (list_info_p->data_size != list->info.data_size) 02394 || (list_info_p->subdesc_size != list->info.subdesc_size) 02395 || (list_info_p->subdata_size != list->info.subdata_size) 02396 ) 02397 { 02398 if(timeout) 02399 { 02400 printk(KERN_WARNING 02401 "read_lol_list(): accessing timed out list %s with wrong desc or data size(s), ignoring old contents!\n", 02402 list->name); 02403 goto end_read; 02404 } 02405 else 02406 { 02407 printk(KERN_WARNING 02408 "read_lol_list(): desc or data size mismatch on list %s!\n", 02409 list->name); 02410 err = -RSBAC_EINVALIDVALUE; 02411 goto end_read; 02412 } 02413 } 02414 } 02415 02416 /* get list count */ 02417 tmperr = file_p->f_op->read(file_p, 02418 (__u8 *) &list_count, 02419 sizeof(list_count), 02420 &file_p->f_pos); 02421 /* error? */ 02422 if (tmperr < sizeof(list_count)) 02423 { 02424 printk(KERN_WARNING 02425 "read_lol_list(): list count read error from file %s!\n", 02426 list->name); 02427 err = -RSBAC_EREADFAILED; 02428 goto end_read; 02429 } 02430 02431 /* alloc mem for old and converted items */ 02432 old_buf = rsbac_kmalloc(list_info_p->desc_size + list_info_p->data_size); 02433 if(!old_buf) 02434 { 02435 printk(KERN_WARNING 02436 "read_lol_list(): cannot allocate memory!\n"); 02437 err = -RSBAC_ENOMEM; 02438 goto end_read; 02439 } 02440 new_buf = rsbac_kmalloc(list->info.desc_size + list->info.data_size); 02441 if(!new_buf) 02442 { 02443 printk(KERN_WARNING 02444 "read_lol_list(): cannot allocate memory!\n"); 02445 rsbac_kfree(old_buf); 02446 err = -RSBAC_ENOMEM; 02447 goto end_read; 02448 } 02449 old_subbuf = rsbac_kmalloc(list_info_p->subdesc_size + list_info_p->subdata_size); 02450 if(!old_subbuf) 02451 { 02452 printk(KERN_WARNING 02453 "read_lol_list(): cannot allocate memory!\n"); 02454 rsbac_kfree(old_buf); 02455 rsbac_kfree(new_buf); 02456 err = -RSBAC_ENOMEM; 02457 goto end_read; 02458 } 02459 new_subbuf = rsbac_kmalloc(list->info.subdesc_size + list->info.subdata_size); 02460 if(!new_subbuf) 02461 { 02462 printk(KERN_WARNING 02463 "read_lol_list(): cannot allocate memory!\n"); 02464 rsbac_kfree(old_buf); 02465 rsbac_kfree(new_buf); 02466 rsbac_kfree(old_subbuf); 02467 err = -RSBAC_ENOMEM; 02468 goto end_read; 02469 } 02470 /* calculate data pointers */ 02471 if(list_info_p->data_size) 02472 old_data = old_buf + list_info_p->desc_size; 02473 else 02474 old_data = NULL; 02475 if(list->info.data_size) 02476 new_data = new_buf + list->info.desc_size; 02477 else 02478 new_data = NULL; 02479 if(list_info_p->subdata_size) 02480 old_subdata = old_subbuf + list_info_p->subdesc_size; 02481 else 02482 old_subdata = NULL; 02483 if(list->info.subdata_size) 02484 new_subdata = new_subbuf + list->info.subdesc_size; 02485 else 02486 new_subdata = NULL; 02487 02488 /* actual reading */ 02489 do 02490 { 02491 switch(list_version) 02492 { 02493 case RSBAC_LIST_DISK_VERSION: 02494 tmperr = file_p->f_op->read(file_p, 02495 (char *) &max_age, 02496 sizeof(max_age), 02497 &file_p->f_pos); 02498 break; 02499 case RSBAC_LIST_DISK_OLD_VERSION: 02500 break; 02501 default: 02502 printk(KERN_WARNING 02503 "read_lol_list(): wrong on-disk list version %u in file %s, expected %u - error!\n", 02504 list_version, 02505 list->name, 02506 RSBAC_LIST_DISK_VERSION); 02507 err = -RSBAC_EREADFAILED; 02508 goto end_read; 02509 } 02510 if(conv) 02511 { 02512 tmperr = file_p->f_op->read(file_p, 02513 old_buf, 02514 list_info_p->desc_size + list_info_p->data_size, 02515 &file_p->f_pos); 02516 if(tmperr > 0) 02517 { /* convert */ 02518 converr = conv(old_buf, old_data, 02519 new_buf, new_data); 02520 if(converr) 02521 tmperr = converr; 02522 } 02523 } 02524 else 02525 { 02526 tmperr = file_p->f_op->read(file_p, 02527 new_buf, 02528 list->info.desc_size + list->info.data_size, 02529 &file_p->f_pos); 02530 } 02531 /* if successful, add item */ 02532 if (tmperr > 0) 02533 { 02534 /* wait for write access to list */ 02535 rsbac_write_lock(&list->lock, &flags); 02536 item_p = add_lol_item(list, max_age, new_buf, new_data); 02537 /* allow access */ 02538 rsbac_write_unlock(&list->lock, &flags); 02539 if(!item_p) 02540 { 02541 err = -RSBAC_ENOMEM; 02542 goto end_read_free; 02543 } 02544 read_count++; 02545 /* 02546 #ifdef CONFIG_RSBAC_DEBUG 02547 if (rsbac_debug_lists) printk(KERN_DEBUG "read_lol_list(): read item %i\n", 02548 user_aci.id); 02549 #endif 02550 */ 02551 tmperr = file_p->f_op->read(file_p, 02552 (__u8 *) &sublen, 02553 sizeof(sublen), 02554 &file_p->f_pos); 02555 /* if successful, read and add sublen subitems */ 02556 if (tmperr > 0) 02557 { 02558 for(i=0;i<sublen;i++) 02559 { 02560 switch(list_version) 02561 { 02562 case RSBAC_LIST_DISK_VERSION: 02563 tmperr = file_p->f_op->read(file_p, 02564 (char *) &max_age, 02565 sizeof(max_age), 02566 &file_p->f_pos); 02567 break; 02568 case RSBAC_LIST_DISK_OLD_VERSION: 02569 break; 02570 default: 02571 printk(KERN_WARNING 02572 "read_lol_list(): wrong on-disk list version %u in file %s, expected %u - error!\n", 02573 list_version, 02574 list->name, 02575 RSBAC_LIST_DISK_VERSION); 02576 err = -RSBAC_EREADFAILED; 02577 goto end_read; 02578 } 02579 if(subconv) 02580 { 02581 tmperr = file_p->f_op->read(file_p, 02582 old_subbuf, 02583 list_info_p->subdesc_size + list_info_p->subdata_size, 02584 &file_p->f_pos); 02585 if(tmperr > 0) 02586 { /* convert */ 02587 converr = subconv(old_subbuf, old_subdata, 02588 new_subbuf, new_subdata); 02589 if(converr) 02590 tmperr = converr; 02591 } 02592 } 02593 else 02594 { 02595 tmperr = file_p->f_op->read(file_p, 02596 new_subbuf, 02597 list->info.subdesc_size + list->info.subdata_size, 02598 &file_p->f_pos); 02599 } 02600 if(tmperr > 0) 02601 { 02602 /* wait for write access to list */ 02603 rsbac_write_lock(&list->lock, &flags); 02604 if (!add_lol_subitem(list, 02605 item_p, 02606 max_age, 02607 new_subbuf, 02608 new_subdata)) 02609 { 02610 printk(KERN_WARNING 02611 "read_lol_list(): could not add subitem!\n"); 02612 i = sublen; 02613 tmperr = -1; 02614 } 02615 /* allow access */ 02616 rsbac_write_unlock(&list->lock, &flags); 02617 } 02618 else 02619 { 02620 i = sublen; 02621 tmperr = -1; 02622 } 02623 } 02624 } 02625 } 02626 } 02627 while (tmperr > 0); /* end of do */ 02628 02629 if (tmperr < 0) 02630 { 02631 printk(KERN_WARNING "read_lol_list(): read error from file %s!\n", 02632 list->name); 02633 err = -RSBAC_EREADFAILED; 02634 } 02635 02636 if (read_count != list_count) 02637 { 02638 printk(KERN_WARNING "read_lol_list(): read %lu, expected %u items from file %s!\n", 02639 read_count, 02640 list_count, 02641 list->name); 02642 err = -RSBAC_EREADFAILED; 02643 } 02644 02645 end_read_free: 02646 rsbac_kfree(old_buf); 02647 rsbac_kfree(new_buf); 02648 rsbac_kfree(old_subbuf); 02649 rsbac_kfree(new_subbuf); 02650 02651 end_read: 02652 /* Set current user space back to user space, because read() writes */ 02653 /* to user space */ 02654 set_fs(oldfs); 02655 02656 #ifdef CONFIG_RSBAC_DEBUG 02657 if (rsbac_debug_lists) 02658 { 02659 #ifdef CONFIG_RSBAC_RMSG 02660 rsbac_printk(KERN_DEBUG "read_lol_list(): %lu entries read.\n", 02661 read_count); 02662 #endif 02663 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02664 if (!rsbac_nosyslog) 02665 #endif 02666 printk(KERN_DEBUG "read_lol_list(): %lu entries read.\n", 02667 read_count); 02668 } 02669 #endif 02670 /* We do not need this file any more */ 02671 rsbac_read_close(file_p); 02672 rsbac_kfree(list_info_p); 02673 rsbac_kfree(file_p); 02674 return(err); 02675 }; /* end of read_lol_list() */ 02676 02677 02678 #ifndef CONFIG_RSBAC_NO_WRITE 02679 static int fill_buffer(struct rsbac_list_reg_item_t * list, 02680 struct rsbac_list_write_item_t ** write_item_pp) 02681 { 02682 struct rsbac_list_write_item_t * write_item_p; 02683 struct rsbac_list_item_t * current_p; 02684 u_long flags; 02685 char * buffer = NULL; 02686 u_long buflen; 02687 u_long write_count = 0; 02688 boolean vmalloc_used = FALSE; 02689 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION; 02690 rsbac_time_t timestamp = RSBAC_CURRENT_TIME; 02691 02692 write_item_p = rsbac_kmalloc(sizeof(*write_item_p)); 02693 if(!write_item_p) 02694 { 02695 *write_item_pp = NULL; 02696 return(-RSBAC_ENOMEM); 02697 } 02698 02699 /* protect this list */ 02700 rsbac_read_lock(&list->lock, &flags); 02701 /* allocate mem */ 02702 buflen = sizeof(list_version) 02703 + sizeof(timestamp) 02704 + sizeof(list->info) 02705 + sizeof(list->count) 02706 + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size); 02707 /* try to rsbac_vkmalloc */ 02708 buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used); 02709 if(!buffer) 02710 { 02711 /* unprotect this list */ 02712 rsbac_read_unlock(&list->lock, &flags); 02713 rsbac_kfree(write_item_p); 02714 *write_item_pp = NULL; 02715 return(-RSBAC_ENOMEM); 02716 } 02717 /* copy version */ 02718 memcpy(buffer, 02719 (char *) &list_version, 02720 sizeof(list_version)); 02721 write_count = sizeof(list_version); 02722 /* copy version */ 02723 memcpy(buffer+write_count, 02724 (char *) &timestamp, 02725 sizeof(timestamp)); 02726 write_count += sizeof(timestamp); 02727 /* copy info */ 02728 memcpy(buffer+write_count, 02729 (char *) &list->info, 02730 sizeof(list->info)); 02731 write_count += sizeof(list->info); 02732 /* copy count */ 02733 memcpy(buffer+write_count, 02734 (char *) &list->count, 02735 sizeof(list->count)); 02736 write_count += sizeof(list->count); 02737 /* copy list */ 02738 current_p = list->head; 02739 while (current_p) 02740 { 02741 memcpy(buffer+write_count, 02742 &current_p->max_age, 02743 sizeof(current_p->max_age)); 02744 write_count += sizeof(current_p->max_age); 02745 memcpy(buffer+write_count, 02746 ((char *) current_p) + sizeof(*current_p), 02747 list->info.desc_size + list->info.data_size); 02748 write_count += list->info.desc_size + list->info.data_size; 02749 current_p = current_p->next; 02750 } 02751 02752 /* fill write_item */ 02753 write_item_p->prev = NULL; 02754 write_item_p->next = NULL; 02755 write_item_p->list = list; 02756 write_item_p->buflen = write_count; 02757 write_item_p->buf = buffer; 02758 write_item_p->vmalloc_used = vmalloc_used; 02759 strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME); 02760 write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0; 02761 write_item_p->device = list->device; 02762 02763 *write_item_pp = write_item_p; 02764 02765 /* unprotect this list */ 02766 rsbac_read_unlock(&list->lock, &flags); 02767 02768 return 0; 02769 } 02770 02771 static int rsbac_list_write_buffers(struct rsbac_list_write_head_t write_head, 02772 boolean need_lock) 02773 { 02774 struct file * file_p; 02775 int count = 0; 02776 mm_segment_t oldfs; 02777 u_long written; 02778 u_long bytes; 02779 int tmperr = 0; 02780 struct rsbac_list_write_item_t * write_item_p; 02781 struct rsbac_list_write_item_t * next_item_p; 02782 02783 file_p = rsbac_kmalloc(sizeof(*file_p)); 02784 if(!file_p) 02785 { 02786 return -RSBAC_ENOMEM; 02787 } 02788 write_item_p = write_head.head; 02789 while(write_item_p) 02790 { 02791 #ifdef CONFIG_RSBAC_DEBUG 02792 if (rsbac_debug_write) 02793 { 02794 #ifdef CONFIG_RSBAC_RMSG 02795 rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): write list %s on device %02u:%02u.\n", 02796 write_item_p->name, 02797 RSBAC_MAJOR(write_item_p->device), 02798 RSBAC_MINOR(write_item_p->device)); 02799 #endif 02800 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02801 if (!rsbac_nosyslog) 02802 #endif 02803 printk(KERN_DEBUG "rsbac_list_write_buffers(): write list %s on device %02u:%02u.\n", 02804 write_item_p->name, 02805 RSBAC_MAJOR(write_item_p->device), 02806 RSBAC_MINOR(write_item_p->device)); 02807 } 02808 #endif 02809 if(need_lock) 02810 lock_kernel(); 02811 /* open file */ 02812 if ((tmperr = rsbac_write_open(write_item_p->name, 02813 file_p, 02814 write_item_p->device) )) 02815 { 02816 if(tmperr != -RSBAC_ENOTWRITABLE) 02817 { 02818 #ifdef CONFIG_RSBAC_RMSG 02819 rsbac_printk(KERN_WARNING 02820 "rsbac_list_write_buffers(): opening file %s on device %02u:%02u failed with error %i!\n", 02821 write_item_p->name, 02822 RSBAC_MAJOR(write_item_p->device), 02823 RSBAC_MINOR(write_item_p->device), 02824 tmperr); 02825 #endif 02826 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02827 if (!rsbac_nosyslog) 02828 #endif 02829 printk(KERN_WARNING 02830 "rsbac_list_write_buffers(): opening file %s on device %02u:%02u failed with error %i!\n", 02831 write_item_p->name, 02832 RSBAC_MAJOR(write_item_p->device), 02833 RSBAC_MINOR(write_item_p->device), 02834 tmperr); 02835 } 02836 count = tmperr; 02837 goto free_item; 02838 } 02839 02840 /* OK, now we can start writing the buffer. */ 02841 /* Set current user space to kernel space, because write() reads */ 02842 /* from user space */ 02843 oldfs = get_fs(); 02844 set_fs(KERNEL_DS); 02845 02846 written = 0; 02847 while ((written < write_item_p->buflen) && (tmperr >= 0)) 02848 { 02849 bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK); 02850 tmperr = file_p->f_op->write(file_p, 02851 write_item_p->buf + written, 02852 bytes, 02853 &file_p->f_pos); 02854 if(tmperr > 0) 02855 { 02856 written += tmperr; 02857 } 02858 } 02859 if (tmperr < 0) 02860 { 02861 #ifdef CONFIG_RSBAC_RMSG 02862 rsbac_printk(KERN_WARNING 02863 "rsbac_list_write_buffers(): write error %i on device %02u:%02u file %s!\n", 02864 tmperr, 02865 RSBAC_MAJOR(write_item_p->device), 02866 RSBAC_MINOR(write_item_p->device), 02867 write_item_p->name); 02868 #endif 02869 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02870 if (!rsbac_nosyslog) 02871 #endif 02872 printk(KERN_WARNING 02873 "rsbac_list_write_buffers(): write error %i on device %02u:%02u file %s!\n", 02874 tmperr, 02875 RSBAC_MAJOR(write_item_p->device), 02876 RSBAC_MINOR(write_item_p->device), 02877 write_item_p->name); 02878 if(write_item_p->list->self == write_item_p->list) 02879 write_item_p->list->dirty = TRUE; 02880 } 02881 else 02882 count++; 02883 02884 /* Set current user space back to user space, because write() reads */ 02885 /* from user space */ 02886 set_fs(oldfs); 02887 02888 #ifdef CONFIG_RSBAC_DEBUG 02889 if (rsbac_debug_write) 02890 { 02891 #ifdef CONFIG_RSBAC_RMSG 02892 rsbac_printk(KERN_DEBUG "rsbac_list_write_buffers(): %lu bytes written.\n", 02893 written); 02894 #endif 02895 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02896 if (!rsbac_nosyslog) 02897 #endif 02898 printk(KERN_DEBUG "rsbac_list_write_buffers(): %lu bytes written.\n", 02899 written); 02900 } 02901 #endif 02902 /* End of write access */ 02903 rsbac_write_close(file_p); 02904 02905 free_item: 02906 if(need_lock) 02907 unlock_kernel(); 02908 /* free buffer */ 02909 rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used); 02910 next_item_p = write_item_p->next; 02911 rsbac_kfree(write_item_p); 02912 write_item_p = next_item_p; 02913 } 02914 /* Ready. */ 02915 rsbac_kfree(file_p); 02916 return(count); 02917 } 02918 02919 static int fill_lol_buffer(struct rsbac_list_lol_reg_item_t * list, 02920 struct rsbac_list_lol_write_item_t ** write_item_pp) 02921 { 02922 struct rsbac_list_lol_write_item_t * write_item_p; 02923 struct rsbac_list_lol_item_t * current_p; 02924 struct rsbac_list_item_t * sub_p; 02925 u_long flags; 02926 char * buffer = NULL; 02927 u_long buflen; 02928 u_long write_count = 0; 02929 boolean vmalloc_used = FALSE; 02930 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION; 02931 rsbac_time_t timestamp = RSBAC_CURRENT_TIME; 02932 02933 write_item_p = rsbac_kmalloc(sizeof(*write_item_p)); 02934 if(!write_item_p) 02935 { 02936 *write_item_pp = NULL; 02937 return(-RSBAC_ENOMEM); 02938 } 02939 02940 /* protect this list */ 02941 rsbac_read_lock(&list->lock, &flags); 02942 02943 /* allocate mem */ 02944 buflen = sizeof(list_version) 02945 + sizeof(timestamp) 02946 + sizeof(list->info) 02947 + sizeof(list->count) 02948 + list->count * (sizeof(current_p->max_age) + list->info.desc_size + list->info.data_size); 02949 current_p = list->head; 02950 while(current_p) 02951 { 02952 buflen += sizeof(current_p->count); 02953 buflen += current_p->count * (sizeof(current_p->max_age) + list->info.subdesc_size + list->info.subdata_size); 02954 current_p = current_p->next; 02955 } 02956 /* try to rsbac_vkmalloc */ 02957 buffer = (char *) rsbac_vkmalloc(buflen, &vmalloc_used); 02958 if(!buffer) 02959 { 02960 /* unprotect this list */ 02961 rsbac_read_unlock(&list->lock, &flags); 02962 rsbac_kfree(write_item_p); 02963 *write_item_pp = NULL; 02964 return(-RSBAC_ENOMEM); 02965 } 02966 /* copy version */ 02967 memcpy(buffer, 02968 (char *) &list_version, 02969 sizeof(list_version)); 02970 write_count = sizeof(list_version); 02971 /* copy version */ 02972 memcpy(buffer+write_count, 02973 (char *) &timestamp, 02974 sizeof(timestamp)); 02975 write_count += sizeof(timestamp); 02976 /* copy info */ 02977 memcpy(buffer+write_count, 02978 (char *) &list->info, 02979 sizeof(list->info)); 02980 write_count += sizeof(list->info); 02981 /* copy count */ 02982 memcpy(buffer+write_count, 02983 (char *) &list->count, 02984 sizeof(list->count)); 02985 write_count += sizeof(list->count); 02986 /* copy list */ 02987 current_p = list->head; 02988 while (current_p) 02989 { 02990 memcpy(buffer+write_count, 02991 &current_p->max_age, 02992 sizeof(current_p->max_age)); 02993 write_count += sizeof(current_p->max_age); 02994 memcpy(buffer+write_count, 02995 ((char *) current_p) + sizeof(*current_p), 02996 list->info.desc_size + list->info.data_size); 02997 write_count += list->info.desc_size + list->info.data_size; 02998 memcpy(buffer+write_count, 02999 &current_p->count, 03000 sizeof(current_p->count)); 03001 write_count += sizeof(current_p->count); 03002 /* copy subitems */ 03003 sub_p = current_p->head; 03004 while (sub_p) 03005 { 03006 memcpy(buffer+write_count, 03007 &sub_p->max_age, 03008 sizeof(sub_p->max_age)); 03009 write_count += sizeof(sub_p->max_age); 03010 memcpy(buffer+write_count, 03011 ((char *) sub_p) + sizeof(*sub_p), 03012 list->info.subdesc_size + list->info.subdata_size); 03013 write_count += list->info.subdesc_size + list->info.subdata_size; 03014 sub_p = sub_p->next; 03015 } 03016 current_p = current_p->next; 03017 } 03018 03019 /* fill write_item */ 03020 write_item_p->prev = NULL; 03021 write_item_p->next = NULL; 03022 write_item_p->list = list; 03023 write_item_p->buflen = write_count; 03024 write_item_p->buf = buffer; 03025 write_item_p->vmalloc_used = vmalloc_used; 03026 strncpy(write_item_p->name, list->name, RSBAC_LIST_MAX_FILENAME); 03027 write_item_p->name[RSBAC_LIST_MAX_FILENAME] = 0; 03028 write_item_p->device = list->device; 03029 *write_item_pp = write_item_p; 03030 03031 /* unprotect this list */ 03032 rsbac_read_unlock(&list->lock, &flags); 03033 03034 return 0; 03035 } 03036 03037 static int rsbac_list_write_lol_buffers(struct rsbac_list_lol_write_head_t write_head, 03038 boolean need_lock) 03039 { 03040 struct file * file_p; 03041 int count = 0; 03042 mm_segment_t oldfs; 03043 u_long written; 03044 u_long bytes; 03045 int tmperr = 0; 03046 struct rsbac_list_lol_write_item_t * write_item_p; 03047 struct rsbac_list_lol_write_item_t * next_item_p; 03048 03049 file_p = rsbac_kmalloc(sizeof(*file_p)); 03050 if(!file_p) 03051 { 03052 return -RSBAC_ENOMEM; 03053 } 03054 write_item_p = write_head.head; 03055 while(write_item_p) 03056 { 03057 #ifdef CONFIG_RSBAC_DEBUG 03058 if (rsbac_debug_write) 03059 { 03060 #ifdef CONFIG_RSBAC_RMSG 03061 rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): write list %s on device %02u:%02u.\n", 03062 write_item_p->name, 03063 RSBAC_MAJOR(write_item_p->device), 03064 RSBAC_MINOR(write_item_p->device)); 03065 #endif 03066 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03067 if (!rsbac_nosyslog) 03068 #endif 03069 printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): write list %s on device %02u:%02u.\n", 03070 write_item_p->name, 03071 RSBAC_MAJOR(write_item_p->device), 03072 RSBAC_MINOR(write_item_p->device)); 03073 } 03074 #endif 03075 if(need_lock) 03076 lock_kernel(); 03077 /* open file */ 03078 if ((tmperr = rsbac_write_open(write_item_p->name, 03079 file_p, 03080 write_item_p->device) )) 03081 { 03082 if(tmperr != -RSBAC_ENOTWRITABLE) 03083 { 03084 #ifdef CONFIG_RSBAC_RMSG 03085 rsbac_printk(KERN_WARNING 03086 "rsbac_list_write_lol_buffers(): opening file %s on device %02u:%02u failed with error %i!\n", 03087 write_item_p->name, 03088 RSBAC_MAJOR(write_item_p->device), 03089 RSBAC_MINOR(write_item_p->device), 03090 tmperr); 03091 #endif 03092 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03093 if (!rsbac_nosyslog) 03094 #endif 03095 printk(KERN_WARNING 03096 "rsbac_list_write_lol_buffers(): opening file %s on device %02u:%02u failed with error %i!\n", 03097 write_item_p->name, 03098 RSBAC_MAJOR(write_item_p->device), 03099 RSBAC_MINOR(write_item_p->device), 03100 tmperr); 03101 } 03102 goto free_item; 03103 } 03104 03105 /* OK, now we can start writing the buffer. */ 03106 /* Set current user space to kernel space, because write() reads */ 03107 /* from user space */ 03108 oldfs = get_fs(); 03109 set_fs(KERNEL_DS); 03110 03111 written = 0; 03112 while ((written < write_item_p->buflen) && (tmperr >= 0)) 03113 { 03114 bytes = rsbac_min(write_item_p->buflen - written, RSBAC_MAX_WRITE_CHUNK); 03115 tmperr = file_p->f_op->write(file_p, 03116 write_item_p->buf + written, 03117 bytes, 03118 &file_p->f_pos); 03119 if(tmperr > 0) 03120 { 03121 written += tmperr; 03122 } 03123 } 03124 if (tmperr < 0) 03125 { 03126 #ifdef CONFIG_RSBAC_RMSG 03127 rsbac_printk(KERN_WARNING 03128 "rsbac_list_write_lol_buffers(): write error %i on device %02u:%02u file %s!\n", 03129 tmperr, 03130 RSBAC_MAJOR(write_item_p->device), 03131 RSBAC_MINOR(write_item_p->device), 03132 write_item_p->name); 03133 #endif 03134 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03135 if (!rsbac_nosyslog) 03136 #endif 03137 printk(KERN_WARNING 03138 "rsbac_list_write_lol_buffers(): write error %i on device %02u:%02u file %s!\n", 03139 tmperr, 03140 RSBAC_MAJOR(write_item_p->device), 03141 RSBAC_MINOR(write_item_p->device), 03142 write_item_p->name); 03143 if(write_item_p->list->self == write_item_p->list) 03144 write_item_p->list->dirty = TRUE; 03145 } 03146 else 03147 count++; 03148 03149 /* Set current user space back to user space, because write() reads */ 03150 /* from user space */ 03151 set_fs(oldfs); 03152 03153 #ifdef CONFIG_RSBAC_DEBUG 03154 if (rsbac_debug_write) 03155 { 03156 #ifdef CONFIG_RSBAC_RMSG 03157 rsbac_printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): %lu bytes written.\n", 03158 written); 03159 #endif 03160 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03161 if (!rsbac_nosyslog) 03162 #endif 03163 printk(KERN_DEBUG "rsbac_list_write_lol_buffers(): %lu bytes written.\n", 03164 written); 03165 } 03166 #endif 03167 /* End of write access */ 03168 rsbac_write_close(file_p); 03169 03170 free_item: 03171 if(need_lock) 03172 unlock_kernel(); 03173 /* free buffer */ 03174 rsbac_vkfree(write_item_p->buf, write_item_p->vmalloc_used); 03175 next_item_p = write_item_p->next; 03176 rsbac_kfree(write_item_p); 03177 write_item_p = next_item_p; 03178 } 03179 /* Ready. */ 03180 rsbac_kfree(file_p); 03181 return(count); 03182 } 03183 #endif /* ifndef CONFIG_RSBAC_NO_WRITE */ 03184 03185 03186 /************************************************* */ 03187 /* PROC support */ 03188 /************************************************* */ 03189 03190 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 03191 static int 03192 lists_proc_info(char *buffer, char **start, off_t offset, int length) 03193 { 03194 int len = 0; 03195 off_t pos = 0; 03196 off_t begin = 0; 03197 03198 union rsbac_target_id_t rsbac_target_id; 03199 union rsbac_attribute_value_t rsbac_attribute_value; 03200 struct rsbac_list_reg_item_t * item_p; 03201 struct rsbac_list_lol_reg_item_t * lol_item_p; 03202 u_long flags; 03203 03204 if (!rsbac_is_initialized()) 03205 return (-ENOSYS); 03206 03207 #ifdef CONFIG_RSBAC_DEBUG 03208 if (rsbac_debug_aef) 03209 { 03210 #ifdef CONFIG_RSBAC_RMSG 03211 rsbac_printk(KERN_DEBUG "lists_proc_info(): calling ADF\n"); 03212 #endif 03213 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03214 if (!rsbac_nosyslog) 03215 #endif 03216 printk(KERN_DEBUG "lists_proc_info(): calling ADF\n"); 03217 } 03218 #endif 03219 rsbac_target_id.scd = ST_rsbac; 03220 rsbac_attribute_value.dummy = 0; 03221 if (!rsbac_adf_request(R_GET_STATUS_DATA, 03222 current->pid, 03223 T_SCD, 03224 rsbac_target_id, 03225 A_none, 03226 rsbac_attribute_value)) 03227 { 03228 return -EPERM; 03229 } 03230 03231 len += sprintf(buffer, "Registered Generic Lists\n------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n"); 03232 pos = begin + len; 03233 if (pos < offset) 03234 { 03235 len = 0; 03236 begin = pos; 03237 } 03238 if (pos > offset+length) 03239 goto out; 03240 03241 rsbac_read_lock(&reg_head.lock, &flags); 03242 item_p=reg_head.head; 03243 while(item_p) 03244 { 03245 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n", 03246 item_p->name, 03247 RSBAC_MAJOR(item_p->device), RSBAC_MINOR(item_p->device), 03248 item_p->count, 03249 item_p->info.desc_size, 03250 item_p->info.data_size, 03251 item_p->flags & RSBAC_LIST_PERSIST, 03252 item_p->no_write, 03253 item_p->flags, 03254 item_p->dirty & (item_p->flags & RSBAC_LIST_PERSIST)); 03255 pos = begin + len; 03256 if (pos < offset) 03257 { 03258 len = 0; 03259 begin = pos; 03260 } 03261 if (pos > offset+length) 03262 { 03263 rsbac_read_unlock(&reg_head.lock, &flags); 03264 goto out; 03265 } 03266 item_p = item_p->next; 03267 } 03268 rsbac_read_unlock(&reg_head.lock, &flags); 03269 03270 len += sprintf(buffer + len, "\n %u lists registered.\n\n", 03271 reg_head.count); 03272 pos = begin + len; 03273 if (pos < offset) 03274 { 03275 len = 0; 03276 begin = pos; 03277 } 03278 if (pos > offset+length) 03279 goto out; 03280 03281 len += sprintf(buffer + len, "Registered Generic Lists of Lists\n---------------------------------\nName\t\tdevice\tcount\tdesc\tdata\tpersist\tnowrite\tflags\tdirty\n"); 03282 pos = begin + len; 03283 if (pos < offset) 03284 { 03285 len = 0; 03286 begin = pos; 03287 } 03288 if (pos > offset+length) 03289 goto out; 03290 03291 rsbac_read_lock(&lol_reg_head.lock, &flags); 03292 lol_item_p=lol_reg_head.head; 03293 while(lol_item_p) 03294 { 03295 len += sprintf(buffer + len, "%-16s%02u:%02u\t%u\t%u+%u\t%u+%u\t%u\t%u\t%u\t%u\n", 03296 lol_item_p->name, 03297 RSBAC_MAJOR(lol_item_p->device), RSBAC_MINOR(lol_item_p->device), 03298 lol_item_p->count, 03299 lol_item_p->info.desc_size, 03300 lol_item_p->info.subdesc_size, 03301 lol_item_p->info.data_size, 03302 lol_item_p->info.subdata_size, 03303 lol_item_p->flags & RSBAC_LIST_PERSIST, 03304 lol_item_p->no_write, 03305 lol_item_p->flags, 03306 lol_item_p->dirty & (lol_item_p->flags & RSBAC_LIST_PERSIST)); 03307 pos = begin + len; 03308 if (pos < offset) 03309 { 03310 len = 0; 03311 begin = pos; 03312 } 03313 if (pos > offset+length) 03314 { 03315 rsbac_read_unlock(&lol_reg_head.lock, &flags); 03316 goto out; 03317 } 03318 lol_item_p = lol_item_p->next; 03319 } 03320 rsbac_read_unlock(&lol_reg_head.lock, &flags); 03321 03322 len += sprintf(buffer + len, "\n %u lists of lists registered.\n", 03323 lol_reg_head.count); 03324 pos = begin + len; 03325 if (pos < offset) 03326 { 03327 len = 0; 03328 begin = pos; 03329 } 03330 if (pos > offset+length) 03331 goto out; 03332 03333 out: 03334 *start = buffer + (offset - begin); 03335 len -= (offset - begin); 03336 03337 if (len > length) 03338 len = length; 03339 return len; 03340 } 03341 03342 /* Generic backup generation function */ 03343 static int backup_proc_read(char *page, char **start, off_t off, 03344 int count, int *eof, void *data) 03345 { 03346 int len = 0; 03347 off_t pos = 0; 03348 off_t begin = 0; 03349 03350 union rsbac_target_id_t rsbac_target_id; 03351 union rsbac_attribute_value_t rsbac_attribute_value; 03352 struct rsbac_list_reg_item_t * list; 03353 struct rsbac_list_item_t * current_p; 03354 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION; 03355 rsbac_time_t timestamp = RSBAC_CURRENT_TIME; 03356 u_long rflags, flags; 03357 03358 if (!rsbac_is_initialized()) 03359 return (-ENOSYS); 03360 03361 #ifdef CONFIG_RSBAC_DEBUG 03362 if (rsbac_debug_aef) 03363 { 03364 #ifdef CONFIG_RSBAC_RMSG 03365 rsbac_printk(KERN_DEBUG "backup_proc_read(): calling ADF\n"); 03366 #endif 03367 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03368 if (!rsbac_nosyslog) 03369 #endif 03370 printk(KERN_DEBUG "backup_proc_read(): calling ADF\n"); 03371 } 03372 #endif 03373 rsbac_target_id.scd = ST_rsbac; 03374 rsbac_attribute_value.dummy = 0; 03375 if (!rsbac_adf_request(R_GET_STATUS_DATA, 03376 current->pid, 03377 T_SCD, 03378 rsbac_target_id, 03379 A_none, 03380 rsbac_attribute_value)) 03381 { 03382 return -EPERM; 03383 } 03384 03385 rsbac_read_lock(&reg_head.lock, &rflags); 03386 list=lookup_reg(data); 03387 if(!list) 03388 { 03389 rsbac_read_unlock(&reg_head.lock, &rflags); 03390 return -ENOSYS; 03391 } 03392 /* lock list */ 03393 rsbac_read_lock(&list->lock, &flags); 03394 /* copy version */ 03395 memcpy(page, 03396 (char *) &list_version, 03397 sizeof(list_version)); 03398 len = sizeof(list_version); 03399 /* copy version */ 03400 memcpy(page+len, 03401 (char *) &timestamp, 03402 sizeof(timestamp)); 03403 len += sizeof(timestamp); 03404 /* copy info */ 03405 memcpy(page+len, 03406 (char *) &list->info, 03407 sizeof(list->info)); 03408 len += sizeof(list->info); 03409 pos = begin + len; 03410 if (pos < off) 03411 { 03412 len = 0; 03413 begin = pos; 03414 } 03415 if (pos > off+count) 03416 { 03417 goto out; 03418 } 03419 03420 /* copy list */ 03421 current_p = list->head; 03422 while (current_p) 03423 { 03424 memcpy(page+len, 03425 ((char *) current_p) + sizeof(*current_p), 03426 list->info.desc_size + list->info.data_size); 03427 len += list->info.desc_size + list->info.data_size; 03428 pos = begin + len; 03429 if (pos < off) 03430 { 03431 len = 0; 03432 begin = pos; 03433 } 03434 if (pos > off+count) 03435 { 03436 goto out; 03437 } 03438 current_p = current_p->next; 03439 } 03440 03441 out: 03442 /* unprotect this list */ 03443 rsbac_read_unlock(&list->lock, &flags); 03444 rsbac_read_unlock(&reg_head.lock, &rflags); 03445 if(len <= off+count) 03446 *eof=1; 03447 *start = page + (off - begin); 03448 len -= (off - begin); 03449 03450 if (len > count) 03451 len = count; 03452 return len; 03453 } 03454 03455 /* Generic lists of lists backup generation function */ 03456 static int lol_backup_proc_read(char *page, char **start, off_t off, 03457 int count, int *eof, void *data) 03458 { 03459 int len = 0; 03460 off_t pos = 0; 03461 off_t begin = 0; 03462 03463 union rsbac_target_id_t rsbac_target_id; 03464 union rsbac_attribute_value_t rsbac_attribute_value; 03465 struct rsbac_list_lol_reg_item_t * list; 03466 struct rsbac_list_lol_item_t * current_p; 03467 struct rsbac_list_item_t * sub_p; 03468 rsbac_version_t list_version = RSBAC_LIST_DISK_VERSION; 03469 rsbac_time_t timestamp = RSBAC_CURRENT_TIME; 03470 u_long rflags, flags; 03471 03472 if (!rsbac_is_initialized()) 03473 return (-ENOSYS); 03474 03475 #ifdef CONFIG_RSBAC_DEBUG 03476 if (rsbac_debug_aef) 03477 { 03478 #ifdef CONFIG_RSBAC_RMSG 03479 rsbac_printk(KERN_DEBUG "lol_backup_proc_read(): calling ADF\n"); 03480 #endif 03481 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03482 if (!rsbac_nosyslog) 03483 #endif 03484 printk(KERN_DEBUG "lol_backup_proc_read(): calling ADF\n"); 03485 } 03486 #endif 03487 rsbac_target_id.scd = ST_rsbac; 03488 rsbac_attribute_value.dummy = 0; 03489 if (!rsbac_adf_request(R_GET_STATUS_DATA, 03490 current->pid, 03491 T_SCD, 03492 rsbac_target_id, 03493 A_none, 03494 rsbac_attribute_value)) 03495 { 03496 return -EPERM; 03497 } 03498 03499 rsbac_read_lock(&lol_reg_head.lock, &rflags); 03500 list=lookup_lol_reg(data); 03501 if(!list) 03502 { 03503 rsbac_read_unlock(&lol_reg_head.lock, &rflags); 03504 return -ENOSYS; 03505 } 03506 /* lock list */ 03507 rsbac_read_lock(&list->lock, &flags); 03508 /* copy version */ 03509 memcpy(page, 03510 (char *) &list_version, 03511 sizeof(list_version)); 03512 len = sizeof(list_version); 03513 /* copy version */ 03514 memcpy(page+len, 03515 (char *) &timestamp, 03516 sizeof(timestamp)); 03517 len += sizeof(timestamp); 03518 /* copy info */ 03519 memcpy(page+len, 03520 (char *) &list->info, 03521 sizeof(list->info)); 03522 len += sizeof(list->info); 03523 pos = begin + len; 03524 if (pos < off) 03525 { 03526 len = 0; 03527 begin = pos; 03528 } 03529 if (pos > off+count) 03530 { 03531 goto out; 03532 } 03533 03534 /* copy list */ 03535 current_p = list->head; 03536 while (current_p) 03537 { 03538 memcpy(page+len, 03539 ((char *) current_p) + sizeof(*current_p), 03540 list->info.desc_size + list->info.data_size); 03541 len += list->info.desc_size + list->info.data_size; 03542 memcpy(page+len, 03543 &current_p->count, 03544 sizeof(current_p->count)); 03545 len += sizeof(current_p->count); 03546 pos = begin + len; 03547 if (pos < off) 03548 { 03549 len = 0; 03550 begin = pos; 03551 } 03552 if (pos > off+count) 03553 { 03554 goto out; 03555 } 03556 /* copy sublist */ 03557 sub_p = current_p->head; 03558 while (sub_p) 03559 { 03560 memcpy(page+len, 03561 ((char *) sub_p) + sizeof(*sub_p), 03562 list->info.subdesc_size + list->info.subdata_size); 03563 len += list->info.subdesc_size + list->info.subdata_size; 03564 pos = begin + len; 03565 if (pos < off) 03566 { 03567 len = 0; 03568 begin = pos; 03569 } 03570 if (pos > off+count) 03571 { 03572 goto out; 03573 } 03574 sub_p = sub_p->next; 03575 } 03576 current_p = current_p->next; 03577 } 03578 03579 out: 03580 /* unprotect this list */ 03581 rsbac_read_unlock(&list->lock, &flags); 03582 rsbac_read_unlock(&lol_reg_head.lock, &rflags); 03583 if(len <= off+count) 03584 *eof=1; 03585 *start = page + (off - begin); 03586 len -= (off - begin); 03587 03588 if (len > count) 03589 len = count; 03590 return len; 03591 } 03592 #endif /* PROC */ 03593 03594 03595 /********************/ 03596 /* Init and general */ 03597 /********************/ 03598 03599 int rsbac_list_compare_u32(void * desc1, void * desc2) 03600 { 03601 if( *((__u32*) desc1) < *((__u32*) desc2)) 03602 return -1; 03603 return( *((__u32*) desc1) != *((__u32*) desc2)); 03604 } 03605 03606 #ifdef CONFIG_RSBAC_INIT_DELAY 03607 void rsbac_list_init(void) 03608 #else 03609 void __init rsbac_list_init(void) 03610 #endif 03611 { 03612 reg_head.head = NULL; 03613 reg_head.tail = NULL; 03614 reg_head.curr = NULL; 03615 reg_head.lock = RW_LOCK_UNLOCKED; 03616 reg_head.count = 0; 03617 03618 lol_reg_head.head = NULL; 03619 lol_reg_head.tail = NULL; 03620 lol_reg_head.curr = NULL; 03621 lol_reg_head.lock = RW_LOCK_UNLOCKED; 03622 lol_reg_head.count = 0; 03623 03624 list_initialized = TRUE; 03625 03626 /* init proc entry */ 03627 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 03628 { 03629 struct proc_dir_entry * tmp_entry_p; 03630 03631 tmp_entry_p = create_proc_entry(RSBAC_LIST_PROC_NAME, 03632 S_IFREG | S_IRUGO, 03633 proc_rsbac_root_p); 03634 if(tmp_entry_p) 03635 { 03636 tmp_entry_p->get_info = lists_proc_info; 03637 } 03638 } 03639 #endif 03640 } 03641 03642 int rsbac_list_mount(kdev_t kdev) 03643 { 03644 return 0; 03645 } 03646 03647 int rsbac_list_umount(kdev_t kdev) 03648 { 03649 return 0; 03650 } 03651 03652 #ifdef CONFIG_RSBAC_AUTO_WRITE 03653 int rsbac_write_lists(boolean need_lock) 03654 { 03655 int count = 0; 03656 int subcount = 0; 03657 int error = 0; 03658 struct rsbac_list_reg_item_t * item_p; 03659 struct rsbac_list_lol_reg_item_t * lol_item_p; 03660 u_long lock_flags; 03661 struct rsbac_list_write_head_t write_head; 03662 struct rsbac_list_write_item_t * write_item_p; 03663 struct rsbac_list_lol_write_head_t write_lol_head; 03664 struct rsbac_list_lol_write_item_t * write_lol_item_p; 03665 03666 /* 03667 #ifdef CONFIG_RSBAC_DEBUG 03668 if(rsbac_debug_lists) 03669 printk(KERN_DEBUG "rsbac_write_lists() called.\n"); 03670 #endif 03671 */ 03672 if(!list_initialized) 03673 return -RSBAC_ENOTINITIALIZED; 03674 03675 /* Init buffer list */ 03676 write_head.head=NULL; 03677 write_head.tail=NULL; 03678 write_head.total=0; 03679 write_head.count=0; 03680 03681 rsbac_read_lock(&reg_head.lock, &lock_flags); 03682 item_p=reg_head.head; 03683 while(item_p) 03684 { 03685 if( (item_p->flags & RSBAC_LIST_PERSIST) 03686 && item_p->dirty 03687 && !item_p->no_write 03688 ) 03689 { 03690 item_p->dirty = FALSE; 03691 /* list locking is done in fill_buffer */ 03692 error = fill_buffer(item_p, &write_item_p); 03693 if(!error) 03694 { 03695 if(!write_head.head) 03696 { 03697 write_head.head = write_item_p; 03698 write_head.tail = write_item_p; 03699 write_head.total = write_item_p->buflen; 03700 write_head.count = 1; 03701 } 03702 else 03703 { 03704 write_head.tail->next = write_item_p; 03705 write_item_p->prev = write_head.tail; 03706 write_head.tail = write_item_p; 03707 write_head.total += write_item_p->buflen; 03708 write_head.count++; 03709 } 03710 } 03711 else 03712 { 03713 if( (error != -RSBAC_ENOTWRITABLE) 03714 && (error != -RSBAC_ENOMEM) 03715 ) 03716 { 03717 #ifdef CONFIG_RSBAC_RMSG 03718 rsbac_printk(KERN_WARNING 03719 "rsbac_write_lists(): fill_buffer() for list %s returned error %i\n", 03720 item_p->name, error); 03721 #endif 03722 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03723 if (!rsbac_nosyslog) 03724 #endif 03725 printk(KERN_WARNING 03726 "rsbac_write_lists(): fill_buffer() for list %s returned error %i\n", 03727 item_p->name, error); 03728 } 03729 } 03730 } 03731 item_p=item_p->next; 03732 } 03733 rsbac_read_unlock(&reg_head.lock, &lock_flags); 03734 03735 #ifdef CONFIG_RSBAC_DEBUG 03736 if( rsbac_debug_write 03737 && (write_head.count > 0) 03738 ) 03739 { 03740 #ifdef CONFIG_RSBAC_RMSG 03741 rsbac_printk(KERN_DEBUG 03742 "rsbac_write_lists(): %u lists copied to buffers, total of %lu bytes\n", 03743 write_head.count, 03744 write_head.total); 03745 #endif 03746 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03747 if (!rsbac_nosyslog) 03748 #endif 03749 printk(KERN_DEBUG 03750 "rsbac_write_lists(): %u lists copied to buffers, total of %lu bytes\n", 03751 write_head.count, 03752 write_head.total); 03753 } 03754 #endif 03755 03756 /* write all buffers */ 03757 if(write_head.count) 03758 { 03759 count = rsbac_list_write_buffers(write_head, need_lock); 03760 #ifdef CONFIG_RSBAC_DEBUG 03761 if(rsbac_debug_write) 03762 { 03763 #ifdef CONFIG_RSBAC_RMSG 03764 rsbac_printk(KERN_DEBUG 03765 "rsbac_write_lists(): %u lists written to disk\n", 03766 count); 03767 #endif 03768 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03769 if (!rsbac_nosyslog) 03770 #endif 03771 printk(KERN_DEBUG 03772 "rsbac_write_lists(): %u lists written to disk\n", 03773 count); 03774 } 03775 #endif 03776 } 03777 03778 /* LOL */ 03779 /* Init buffer list */ 03780 write_lol_head.head=NULL; 03781 write_lol_head.tail=NULL; 03782 write_lol_head.total=0; 03783 write_lol_head.count=0; 03784 03785 rsbac_read_lock(&lol_reg_head.lock, &lock_flags); 03786 lol_item_p=lol_reg_head.head; 03787 while(lol_item_p) 03788 { 03789 if( (lol_item_p->flags & RSBAC_LIST_PERSIST) 03790 && lol_item_p->dirty 03791 && !lol_item_p->no_write 03792 ) 03793 { 03794 lol_item_p->dirty = FALSE; 03795 /* list locking is done in fill_buffer */ 03796 error = fill_lol_buffer(lol_item_p, &write_lol_item_p); 03797 if(!error) 03798 { 03799 if(!write_lol_head.head) 03800 { 03801 write_lol_head.head = write_lol_item_p; 03802 write_lol_head.tail = write_lol_item_p; 03803 write_lol_head.total = write_lol_item_p->buflen; 03804 write_lol_head.count = 1; 03805 } 03806 else 03807 { 03808 write_lol_head.tail->next = write_lol_item_p; 03809 write_lol_item_p->prev = write_lol_head.tail; 03810 write_lol_head.tail = write_lol_item_p; 03811 write_lol_head.total += write_lol_item_p->buflen; 03812 write_lol_head.count++; 03813 } 03814 } 03815 else 03816 { 03817 if( (error != -RSBAC_ENOTWRITABLE) 03818 && (error != -RSBAC_ENOMEM) 03819 ) 03820 { 03821 #ifdef CONFIG_RSBAC_RMSG 03822 rsbac_printk(KERN_WARNING 03823 "rsbac_write_lists(): fill_lol_buffer() for list %s returned error %i\n", 03824 lol_item_p->name, error); 03825 #endif 03826 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03827 if (!rsbac_nosyslog) 03828 #endif 03829 printk(KERN_WARNING 03830 "rsbac_write_lists(): fill_lol_buffer() for list %s returned error %i\n", 03831 lol_item_p->name, error); 03832 } 03833 } 03834 } 03835 lol_item_p=lol_item_p->next; 03836 } 03837 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 03838 03839 #ifdef CONFIG_RSBAC_DEBUG 03840 if( rsbac_debug_write 03841 && (write_lol_head.count > 0) 03842 ) 03843 { 03844 #ifdef CONFIG_RSBAC_RMSG 03845 rsbac_printk(KERN_DEBUG 03846 "rsbac_write_lists(): %u lists of lists copied to buffers, total of %lu bytes\n", 03847 write_lol_head.count, 03848 write_lol_head.total); 03849 #endif 03850 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03851 if (!rsbac_nosyslog) 03852 #endif 03853 printk(KERN_DEBUG 03854 "rsbac_write_lists(): %u lists of lists copied to buffers, total of %lu bytes\n", 03855 write_lol_head.count, 03856 write_lol_head.total); 03857 } 03858 #endif 03859 03860 /* write all buffers */ 03861 if(write_lol_head.count) 03862 { 03863 subcount = rsbac_list_write_lol_buffers(write_lol_head, need_lock); 03864 count += subcount; 03865 #ifdef CONFIG_RSBAC_DEBUG 03866 if(rsbac_debug_write) 03867 { 03868 #ifdef CONFIG_RSBAC_RMSG 03869 rsbac_printk(KERN_DEBUG 03870 "rsbac_write_lists(): %u lists of lists written to disk\n", 03871 subcount); 03872 #endif 03873 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03874 if (!rsbac_nosyslog) 03875 #endif 03876 printk(KERN_DEBUG 03877 "rsbac_write_lists(): %u lists of lists written to disk\n", 03878 subcount); 03879 } 03880 #endif 03881 } 03882 03883 #ifdef CONFIG_RSBAC_DEBUG 03884 if (rsbac_debug_write) 03885 { 03886 #ifdef CONFIG_RSBAC_RMSG 03887 rsbac_printk(KERN_DEBUG "rsbac_write_lists(): %u lists with a total of %lu bytes written.\n", 03888 count, write_head.total + write_lol_head.total); 03889 #endif 03890 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03891 if (!rsbac_nosyslog) 03892 #endif 03893 printk(KERN_DEBUG "rsbac_write_lists(): %u lists with a total of %lu bytes written.\n", 03894 count, write_head.total + write_lol_head.total); 03895 } 03896 #endif 03897 return count; 03898 } 03899 #endif /* CONFIG_RSBAC_AUTO_WRITE */ 03900 03901 /* Status checking */ 03902 int rsbac_check_lists(int correct) 03903 { 03904 struct rsbac_list_reg_item_t * list; 03905 struct rsbac_list_lol_reg_item_t * lol_list; 03906 struct rsbac_list_item_t * item_p; 03907 struct rsbac_list_item_t * next_item_p; 03908 struct rsbac_list_lol_item_t * lol_item_p; 03909 struct rsbac_list_lol_item_t * next_lol_item_p; 03910 struct rsbac_list_item_t * lol_subitem_p; 03911 struct rsbac_list_item_t * next_lol_subitem_p; 03912 u_long lock_flags, rlock_flags; 03913 u_long tmp_count; 03914 u_long tmp_subcount; 03915 u_long subitem_count; 03916 u_long dirty = 0; 03917 03918 #ifdef CONFIG_RSBAC_DEBUG 03919 if(rsbac_debug_lists) 03920 { 03921 #ifdef CONFIG_RSBAC_RMSG 03922 rsbac_printk(KERN_DEBUG "rsbac_check_lists() called.\n"); 03923 #endif 03924 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03925 if (!rsbac_nosyslog) 03926 #endif 03927 printk(KERN_DEBUG "rsbac_check_lists() called.\n"); 03928 } 03929 #endif 03930 if(!list_initialized) 03931 return -RSBAC_ENOTINITIALIZED; 03932 rsbac_read_lock(&reg_head.lock, &rlock_flags); 03933 list = reg_head.head; 03934 while(list) 03935 { 03936 /* check list */ 03937 rsbac_write_lock(&list->lock, &lock_flags); 03938 tmp_count = 0; 03939 item_p = list->head; 03940 while(item_p) 03941 { 03942 if( ( item_p->max_age 03943 && (item_p->max_age <= RSBAC_CURRENT_TIME) 03944 ) 03945 || ( list->def_data 03946 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 03947 list->def_data, 03948 list->info.data_size) 03949 ) 03950 ) 03951 { 03952 next_item_p = item_p->next; 03953 do_remove_item(list, item_p); 03954 item_p = next_item_p; 03955 } 03956 else 03957 { 03958 tmp_count++; 03959 item_p = item_p->next; 03960 } 03961 } 03962 if(tmp_count != list->count) 03963 { 03964 if(correct) 03965 { 03966 #ifdef CONFIG_RSBAC_RMSG 03967 rsbac_printk(KERN_WARNING 03968 "rsbac_check_lists(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n", 03969 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 03970 #endif 03971 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03972 if (!rsbac_nosyslog) 03973 #endif 03974 printk(KERN_WARNING 03975 "rsbac_check_lists(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n", 03976 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 03977 list->count = tmp_count; 03978 } 03979 else 03980 { 03981 #ifdef CONFIG_RSBAC_RMSG 03982 rsbac_printk(KERN_WARNING 03983 "rsbac_check_lists(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n", 03984 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 03985 #endif 03986 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03987 if (!rsbac_nosyslog) 03988 #endif 03989 printk(KERN_WARNING 03990 "rsbac_check_lists(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n", 03991 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 03992 } 03993 } 03994 rsbac_write_unlock(&list->lock, &lock_flags); 03995 if(list->dirty && (list->flags & RSBAC_LIST_PERSIST)) 03996 { 03997 dirty++; 03998 #ifdef CONFIG_RSBAC_DEBUG 03999 if(rsbac_debug_lists) 04000 { 04001 #ifdef CONFIG_RSBAC_RMSG 04002 rsbac_printk(KERN_DEBUG 04003 "rsbac_check_lists(): %s on %02u:%02u has %u items (list is dirty)\n", 04004 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count); 04005 #endif 04006 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04007 if (!rsbac_nosyslog) 04008 #endif 04009 printk(KERN_DEBUG 04010 "rsbac_check_lists(): %s on %02u:%02u has %u items (list is dirty)\n", 04011 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count); 04012 } 04013 #endif 04014 } 04015 #ifdef CONFIG_RSBAC_DEBUG 04016 else 04017 { 04018 if(rsbac_debug_lists) 04019 { 04020 #ifdef CONFIG_RSBAC_RMSG 04021 rsbac_printk(KERN_DEBUG 04022 "rsbac_check_lists(): %s on %02u:%02u has %u items\n", 04023 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count); 04024 #endif 04025 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04026 if (!rsbac_nosyslog) 04027 #endif 04028 printk(KERN_DEBUG 04029 "rsbac_check_lists(): %s on %02u:%02u has %u items\n", 04030 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count); 04031 } 04032 } 04033 #endif 04034 list = list->next; 04035 } 04036 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 04037 04038 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 04039 lol_list = lol_reg_head.head; 04040 while(lol_list) 04041 { 04042 /* check list */ 04043 rsbac_write_lock(&lol_list->lock, &lock_flags); 04044 tmp_count = 0; 04045 subitem_count = 0; 04046 lol_item_p = lol_list->head; 04047 while(lol_item_p) 04048 { 04049 if( ( lol_item_p->max_age 04050 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME) 04051 ) 04052 || ( lol_list->def_data 04053 && !lol_item_p->count 04054 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size, 04055 lol_list->def_data, 04056 lol_list->info.data_size) 04057 ) 04058 || ( !lol_list->info.data_size 04059 && (lol_list->flags & RSBAC_LIST_DEF_DATA) 04060 && !lol_item_p->count 04061 ) 04062 ) 04063 { 04064 next_lol_item_p = lol_item_p->next; 04065 do_remove_lol_item(lol_list, lol_item_p); 04066 lol_item_p = next_lol_item_p; 04067 } 04068 else 04069 { 04070 tmp_count++; 04071 tmp_subcount = 0; 04072 lol_subitem_p = lol_item_p->head; 04073 while(lol_subitem_p) 04074 { 04075 if( ( lol_subitem_p->max_age 04076 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME) 04077 ) 04078 || ( lol_list->def_subdata 04079 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size, 04080 lol_list->def_subdata, 04081 lol_list->info.subdata_size) 04082 ) 04083 ) 04084 { 04085 next_lol_subitem_p = lol_subitem_p->next; 04086 do_remove_lol_subitem(lol_item_p, lol_subitem_p); 04087 lol_subitem_p = next_lol_subitem_p; 04088 } 04089 else 04090 { 04091 tmp_subcount++; 04092 lol_subitem_p = lol_subitem_p->next; 04093 } 04094 } 04095 if(tmp_subcount != lol_item_p->count) 04096 { 04097 if(correct) 04098 { 04099 #ifdef CONFIG_RSBAC_RMSG 04100 rsbac_printk(KERN_WARNING 04101 "rsbac_check_lists(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n", 04102 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04103 #endif 04104 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04105 if (!rsbac_nosyslog) 04106 #endif 04107 printk(KERN_WARNING 04108 "rsbac_check_lists(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n", 04109 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04110 lol_item_p->count = tmp_subcount; 04111 } 04112 else 04113 { 04114 #ifdef CONFIG_RSBAC_RMSG 04115 rsbac_printk(KERN_WARNING 04116 "rsbac_check_lists(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n", 04117 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04118 #endif 04119 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04120 if (!rsbac_nosyslog) 04121 #endif 04122 printk(KERN_WARNING 04123 "rsbac_check_lists(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n", 04124 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04125 } 04126 } 04127 subitem_count += lol_item_p->count; 04128 lol_item_p = lol_item_p->next; 04129 } 04130 } 04131 if(tmp_count != lol_list->count) 04132 { 04133 if(correct) 04134 { 04135 #ifdef CONFIG_RSBAC_RMSG 04136 rsbac_printk(KERN_WARNING 04137 "rsbac_check_lists(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n", 04138 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04139 #endif 04140 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04141 if (!rsbac_nosyslog) 04142 #endif 04143 printk(KERN_WARNING 04144 "rsbac_check_lists(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n", 04145 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04146 lol_list->count = tmp_count; 04147 } 04148 else 04149 { 04150 #ifdef CONFIG_RSBAC_RMSG 04151 rsbac_printk(KERN_WARNING 04152 "rsbac_check_lists(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n", 04153 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04154 #endif 04155 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04156 if (!rsbac_nosyslog) 04157 #endif 04158 printk(KERN_WARNING 04159 "rsbac_check_lists(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n", 04160 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04161 } 04162 } 04163 rsbac_write_unlock(&lol_list->lock, &lock_flags); 04164 if(lol_list->dirty && (lol_list->flags & RSBAC_LIST_PERSIST)) 04165 { 04166 dirty++; 04167 #ifdef CONFIG_RSBAC_DEBUG 04168 if(rsbac_debug_lists) 04169 { 04170 #ifdef CONFIG_RSBAC_RMSG 04171 rsbac_printk(KERN_DEBUG 04172 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems (list is dirty)\n", 04173 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count); 04174 #endif 04175 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04176 if (!rsbac_nosyslog) 04177 #endif 04178 printk(KERN_DEBUG 04179 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems (list is dirty)\n", 04180 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count); 04181 } 04182 #endif 04183 } 04184 #ifdef CONFIG_RSBAC_DEBUG 04185 else 04186 { 04187 if(rsbac_debug_lists) 04188 { 04189 #ifdef CONFIG_RSBAC_RMSG 04190 rsbac_printk(KERN_DEBUG 04191 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems\n", 04192 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count); 04193 #endif 04194 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04195 if (!rsbac_nosyslog) 04196 #endif 04197 printk(KERN_DEBUG 04198 "rsbac_check_lists(): %s on %02u:%02u has %u items and %lu subitems\n", 04199 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, subitem_count); 04200 } 04201 } 04202 #endif 04203 lol_list = lol_list->next; 04204 } 04205 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 04206 return 0; 04207 } 04208 04209 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 04210 EXPORT_SYMBOL(rsbac_list_check); 04211 #endif 04212 int rsbac_list_check( 04213 rsbac_list_handle_t handle, 04214 int correct) 04215 { 04216 struct rsbac_list_reg_item_t * list; 04217 struct rsbac_list_item_t * item_p; 04218 struct rsbac_list_item_t * next_item_p; 04219 u_long lock_flags; 04220 u_long rlock_flags; 04221 u_long tmp_count; 04222 04223 if(!handle) 04224 return -RSBAC_EINVALIDVALUE; 04225 if(!list_initialized) 04226 return -RSBAC_ENOTINITIALIZED; 04227 04228 list = (struct rsbac_list_reg_item_t *) handle; 04229 if(!list || (list->self != list)) 04230 return -RSBAC_EINVALIDVALUE; 04231 04232 rsbac_read_lock(&reg_head.lock, &rlock_flags); 04233 #ifdef CONFIG_RSBAC_DEBUG 04234 if(rsbac_debug_lists) 04235 printk(KERN_DEBUG "rsbac_list_check: checking list %s.\n", 04236 list->name); 04237 #endif 04238 rsbac_write_lock(&list->lock, &lock_flags); 04239 tmp_count = 0; 04240 item_p = list->head; 04241 while(item_p) 04242 { 04243 if( ( item_p->max_age 04244 && (item_p->max_age <= RSBAC_CURRENT_TIME) 04245 ) 04246 || ( list->def_data 04247 && !memcmp(((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 04248 list->def_data, 04249 list->info.data_size) 04250 ) 04251 ) 04252 { 04253 next_item_p = item_p->next; 04254 do_remove_item(list, item_p); 04255 item_p = next_item_p; 04256 list->dirty = TRUE; 04257 } 04258 else 04259 { 04260 tmp_count++; 04261 item_p = item_p->next; 04262 } 04263 } 04264 if(tmp_count != list->count) 04265 { 04266 if(correct) 04267 { 04268 #ifdef CONFIG_RSBAC_RMSG 04269 rsbac_printk(KERN_WARNING 04270 "rsbac_list_check(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n", 04271 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 04272 #endif 04273 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04274 if (!rsbac_nosyslog) 04275 #endif 04276 printk(KERN_WARNING 04277 "rsbac_list_check(): correcting count mismatch for list %s on device %02u:%02u - was %u, counted %lu!\n", 04278 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 04279 list->count = tmp_count; 04280 list->dirty = TRUE; 04281 } 04282 else 04283 { 04284 #ifdef CONFIG_RSBAC_RMSG 04285 rsbac_printk(KERN_WARNING 04286 "rsbac_list_check(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n", 04287 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 04288 #endif 04289 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04290 if (!rsbac_nosyslog) 04291 #endif 04292 printk(KERN_WARNING 04293 "rsbac_list_check(): count mismatch for list %s on device %02u:%02u - is %u, counted %lu!\n", 04294 list->name, RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device), list->count, tmp_count); 04295 } 04296 } 04297 rsbac_write_unlock(&list->lock, &lock_flags); 04298 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 04299 return 0; 04300 } 04301 04302 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 04303 EXPORT_SYMBOL(rsbac_list_lol_check); 04304 #endif 04305 int rsbac_list_lol_check( 04306 rsbac_list_handle_t handle, 04307 int correct) 04308 { 04309 struct rsbac_list_lol_reg_item_t * lol_list; 04310 struct rsbac_list_lol_item_t * lol_item_p; 04311 struct rsbac_list_lol_item_t * next_lol_item_p; 04312 struct rsbac_list_item_t * lol_subitem_p; 04313 struct rsbac_list_item_t * next_lol_subitem_p; 04314 u_long lock_flags; 04315 u_long rlock_flags; 04316 u_long tmp_count; 04317 u_long tmp_subcount; 04318 04319 if(!handle) 04320 return -RSBAC_EINVALIDVALUE; 04321 if(!list_initialized) 04322 return -RSBAC_ENOTINITIALIZED; 04323 04324 lol_list = (struct rsbac_list_lol_reg_item_t *) handle; 04325 if(!lol_list || (lol_list->self != lol_list)) 04326 return -RSBAC_EINVALIDVALUE; 04327 04328 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 04329 #ifdef CONFIG_RSBAC_DEBUG 04330 if(rsbac_debug_lists) 04331 printk(KERN_DEBUG "rsbac_list_lol_check: checking list %s.\n", 04332 lol_list->name); 04333 #endif 04334 rsbac_write_lock(&lol_list->lock, &lock_flags); 04335 tmp_count = 0; 04336 lol_item_p = lol_list->head; 04337 while(lol_item_p) 04338 { 04339 if( ( lol_item_p->max_age 04340 && (lol_item_p->max_age <= RSBAC_CURRENT_TIME) 04341 ) 04342 || ( lol_list->def_data 04343 && !lol_item_p->count 04344 && !memcmp(((char *) lol_item_p) + sizeof(*lol_item_p) + lol_list->info.desc_size, 04345 lol_list->def_data, 04346 lol_list->info.data_size) 04347 ) 04348 || ( !lol_list->info.data_size 04349 && (lol_list->flags & RSBAC_LIST_DEF_DATA) 04350 && !lol_item_p->count 04351 ) 04352 ) 04353 { 04354 next_lol_item_p = lol_item_p->next; 04355 do_remove_lol_item(lol_list, lol_item_p); 04356 lol_item_p = next_lol_item_p; 04357 } 04358 else 04359 { 04360 tmp_count++; 04361 tmp_subcount = 0; 04362 lol_subitem_p = lol_item_p->head; 04363 while(lol_subitem_p) 04364 { 04365 if( ( lol_subitem_p->max_age 04366 && (lol_subitem_p->max_age <= RSBAC_CURRENT_TIME) 04367 ) 04368 || ( lol_list->def_subdata 04369 && !memcmp(((char *) lol_subitem_p) + sizeof(*lol_subitem_p) + lol_list->info.subdesc_size, 04370 lol_list->def_subdata, 04371 lol_list->info.subdata_size) 04372 ) 04373 ) 04374 { 04375 next_lol_subitem_p = lol_subitem_p->next; 04376 do_remove_lol_subitem(lol_item_p, lol_subitem_p); 04377 lol_subitem_p = next_lol_subitem_p; 04378 } 04379 else 04380 { 04381 tmp_subcount++; 04382 lol_subitem_p = lol_subitem_p->next; 04383 } 04384 } 04385 if(tmp_subcount != lol_item_p->count) 04386 { 04387 if(correct) 04388 { 04389 #ifdef CONFIG_RSBAC_RMSG 04390 rsbac_printk(KERN_WARNING 04391 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n", 04392 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04393 #endif 04394 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04395 if (!rsbac_nosyslog) 04396 #endif 04397 printk(KERN_WARNING 04398 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s sublist on %02u:%02u - was %lu, counted %lu!\n", 04399 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04400 lol_item_p->count = tmp_subcount; 04401 } 04402 else 04403 { 04404 #ifdef CONFIG_RSBAC_RMSG 04405 rsbac_printk(KERN_WARNING 04406 "rsbac_list_lol_check(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n", 04407 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04408 #endif 04409 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04410 if (!rsbac_nosyslog) 04411 #endif 04412 printk(KERN_WARNING 04413 "rsbac_list_lol_check(): count mismatch for list of lists %s sublist on %02u:%02u - is %lu, counted %lu!\n", 04414 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_item_p->count, tmp_subcount); 04415 } 04416 } 04417 lol_item_p = lol_item_p->next; 04418 } 04419 } 04420 if(tmp_count != lol_list->count) 04421 { 04422 if(correct) 04423 { 04424 #ifdef CONFIG_RSBAC_RMSG 04425 rsbac_printk(KERN_WARNING 04426 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n", 04427 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04428 #endif 04429 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04430 if (!rsbac_nosyslog) 04431 #endif 04432 printk(KERN_WARNING 04433 "rsbac_list_lol_check(): correcting count mismatch for list of lists %s on %02u:%02u - was %u, counted %lu!\n", 04434 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04435 lol_list->count = tmp_count; 04436 } 04437 else 04438 { 04439 #ifdef CONFIG_RSBAC_RMSG 04440 rsbac_printk(KERN_WARNING 04441 "rsbac_list_lol_check(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n", 04442 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04443 #endif 04444 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04445 if (!rsbac_nosyslog) 04446 #endif 04447 printk(KERN_WARNING 04448 "rsbac_list_lol_check(): count mismatch for list of lists %s on %02u:%02u - is %u, counted %lu!\n", 04449 lol_list->name, RSBAC_MAJOR(lol_list->device), RSBAC_MINOR(lol_list->device), lol_list->count, tmp_count); 04450 } 04451 } 04452 rsbac_write_unlock(&lol_list->lock, &lock_flags); 04453 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 04454 return 0; 04455 } 04456 04457 04458 /********************/ 04459 /* Registration */ 04460 /********************/ 04461 04462 /* get generic list registration version */ 04463 rsbac_version_t rsbac_list_version(void) 04464 { 04465 return RSBAC_LIST_VERSION; 04466 } 04467 04468 /* register a new list */ 04469 /* 04470 * If list with same name exists in memory, error -RSBAC_EEXISTS is returned. 04471 * If list with same name and key exists on device, it is restored depending on the flags. 04472 * If list with same name, but different key exists, access is denied (error -EPERM). 04473 * 04474 * ds_version: for binary modules, must be RSBAC_LIST_VERSION. If version differs, return error. 04475 * handle_p: for all list accesses, an opaque handle is put into *handle_p. 04476 * key: positive, secret __u32 key, which must be the same as in on-disk version, if persistent 04477 * list_version: positive __u32 version number for the list. If old on-disk version is 04478 different, upconversion is tried (depending on flags and get_conv function) 04479 * flags: see flag values 04480 * desc_size: size of the descriptor (error is returned, if value is 0 or list exists and value differs) 04481 * data_size: size of data (error is returned, if list exists and value differs). Can be 0 for sets. 04482 * compare: for lookup and list optimization, can be NULL, then 04483 memcmp(desc1, desc2, desc_size) is used 04484 * def_data: default data value for flag RSBAC_LIST_DEF_DATA 04485 (if NULL, flag is cleared) 04486 * name: the on-disk name, must be distinct and max. 7 or 8.2 chars 04487 (only used for statistics, if non-persistent) 04488 * device: the device to read list from or to save list to - use 0 for root dev 04489 (ignored, if non-persistent) 04490 */ 04491 04492 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 04493 EXPORT_SYMBOL(rsbac_list_register); 04494 #endif 04495 int rsbac_list_register( 04496 rsbac_version_t ds_version, 04497 rsbac_list_handle_t *handle_p, 04498 struct rsbac_list_info_t * info_p, 04499 u_int flags, 04500 rsbac_list_compare_function_t * compare, 04501 rsbac_list_get_conv_t * get_conv, 04502 void * def_data, 04503 char * name, 04504 kdev_t device) 04505 { 04506 struct rsbac_list_reg_item_t * reg_item_p; 04507 struct rsbac_list_reg_item_t * new_reg_item_p; 04508 u_long lock_flags; 04509 int err = 0; 04510 04511 if(ds_version != RSBAC_LIST_VERSION) 04512 { 04513 if(name) 04514 { 04515 #ifdef CONFIG_RSBAC_RMSG 04516 rsbac_printk(KERN_WARNING 04517 "rsbac_list_register: wrong ds_version %u for list %s, expected %u!\n", 04518 ds_version, 04519 name, 04520 RSBAC_LIST_VERSION); 04521 #endif 04522 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04523 if (!rsbac_nosyslog) 04524 #endif 04525 printk(KERN_WARNING 04526 "rsbac_list_register: wrong ds_version %u for list %s, expected %u!\n", 04527 ds_version, 04528 name, 04529 RSBAC_LIST_VERSION); 04530 } 04531 return -RSBAC_EINVALIDVERSION; 04532 } 04533 if(!handle_p || !info_p) 04534 return -RSBAC_EINVALIDPOINTER; 04535 *handle_p = NULL; 04536 if(!info_p->key || !info_p->version || !info_p->desc_size) 04537 return -RSBAC_EINVALIDVALUE; 04538 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT) 04539 return -RSBAC_EINVALIDVALUE; 04540 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE) 04541 return -RSBAC_EINVALIDVALUE; 04542 if(!list_initialized) 04543 return -RSBAC_ENOTINITIALIZED; 04544 if(name) 04545 { 04546 struct rsbac_list_lol_reg_item_t * lol_reg_item_p; 04547 04548 rsbac_read_lock(&reg_head.lock, &lock_flags); 04549 reg_item_p = lookup_reg_name(name, device); 04550 rsbac_read_unlock(&reg_head.lock, &lock_flags); 04551 if(reg_item_p) 04552 { 04553 #ifdef CONFIG_RSBAC_DEBUG 04554 if(rsbac_debug_lists) 04555 { 04556 #ifdef CONFIG_RSBAC_RMSG 04557 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04558 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04559 #endif 04560 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04561 if (!rsbac_nosyslog) 04562 #endif 04563 printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04564 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04565 } 04566 #endif 04567 return -RSBAC_EEXISTS; 04568 } 04569 rsbac_read_lock(&lol_reg_head.lock, &lock_flags); 04570 lol_reg_item_p = lookup_lol_reg_name(name, device); 04571 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 04572 if(lol_reg_item_p) 04573 { 04574 #ifdef CONFIG_RSBAC_DEBUG 04575 if(rsbac_debug_lists) 04576 { 04577 #ifdef CONFIG_RSBAC_RMSG 04578 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04579 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04580 #endif 04581 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04582 if (!rsbac_nosyslog) 04583 #endif 04584 printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04585 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04586 } 04587 #endif 04588 return -RSBAC_EEXISTS; 04589 } 04590 } 04591 else 04592 if(flags & RSBAC_LIST_PERSIST) 04593 { 04594 #ifdef CONFIG_RSBAC_RMSG 04595 rsbac_printk(KERN_WARNING 04596 "rsbac_list_register: trial to register persistent list without name.\n"); 04597 #endif 04598 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04599 if (!rsbac_nosyslog) 04600 #endif 04601 printk(KERN_WARNING 04602 "rsbac_list_register: trial to register persistent list without name.\n"); 04603 return -RSBAC_EINVALIDVALUE; 04604 } 04605 04606 if(flags & RSBAC_LIST_PERSIST) 04607 { 04608 if(RSBAC_IS_AUTO_DEV(device)) 04609 device = rsbac_root_dev; 04610 if(!RSBAC_MAJOR(device)) 04611 flags &= ~RSBAC_LIST_PERSIST; 04612 } 04613 04614 #ifdef CONFIG_RSBAC_DEBUG 04615 if(rsbac_debug_lists) 04616 { 04617 #ifdef CONFIG_RSBAC_RMSG 04618 rsbac_printk(KERN_DEBUG "rsbac_list_register: registering list %s for device %02u:%02u.\n", 04619 name, RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04620 #endif 04621 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04622 if (!rsbac_nosyslog) 04623 #endif 04624 printk(KERN_DEBUG "rsbac_list_register: registering list %s for device %02u:%02u.\n", 04625 name, RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04626 } 04627 #endif 04628 new_reg_item_p = create_reg(info_p, flags, compare, get_conv, def_data, name, device); 04629 if(!new_reg_item_p) 04630 { 04631 return -RSBAC_ECOULDNOTADDITEM; 04632 } 04633 /* Restore from disk, but only for real device mounts */ 04634 if( (flags & RSBAC_LIST_PERSIST) 04635 && RSBAC_MAJOR(device) 04636 ) 04637 { 04638 #ifdef CONFIG_RSBAC_DEBUG 04639 if(rsbac_debug_lists) 04640 { 04641 #ifdef CONFIG_RSBAC_RMSG 04642 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u.\n", 04643 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04644 #endif 04645 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04646 if (!rsbac_nosyslog) 04647 #endif 04648 printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u.\n", 04649 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04650 } 04651 #endif 04652 err = read_list(new_reg_item_p); 04653 /* not found is no error */ 04654 if(err == -RSBAC_ENOTFOUND) 04655 err = 0; 04656 else 04657 if(err) 04658 { 04659 #ifdef CONFIG_RSBAC_DEBUG 04660 if(rsbac_debug_lists) 04661 { 04662 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 04663 04664 if(tmp) 04665 { 04666 get_error_name(tmp, err); 04667 #ifdef CONFIG_RSBAC_RMSG 04668 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n", 04669 name, 04670 RSBAC_MAJOR(device),RSBAC_MINOR(device), 04671 tmp); 04672 #endif 04673 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04674 if (!rsbac_nosyslog) 04675 #endif 04676 printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n", 04677 name, 04678 RSBAC_MAJOR(device),RSBAC_MINOR(device), 04679 tmp); 04680 rsbac_kfree(tmp); 04681 } 04682 } 04683 #endif 04684 clear_reg(new_reg_item_p); 04685 return err; 04686 } 04687 #ifdef CONFIG_RSBAC_DEBUG 04688 else 04689 { 04690 if(rsbac_debug_lists) 04691 { 04692 #ifdef CONFIG_RSBAC_RMSG 04693 rsbac_printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u was successful.\n", 04694 name, 04695 RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04696 #endif 04697 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04698 if (!rsbac_nosyslog) 04699 #endif 04700 printk(KERN_DEBUG "rsbac_list_register: restoring list %s from device %02u:%02u was successful.\n", 04701 name, 04702 RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04703 } 04704 } 04705 #endif 04706 } 04707 04708 rsbac_write_lock(&reg_head.lock, &lock_flags); 04709 reg_item_p = add_reg(new_reg_item_p); 04710 rsbac_write_unlock(&reg_head.lock, &lock_flags); 04711 if(!reg_item_p) 04712 { 04713 #ifdef CONFIG_RSBAC_RMSG 04714 rsbac_printk(KERN_WARNING 04715 "rsbac_list_register: inserting list %s failed!\n", 04716 name); 04717 #endif 04718 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04719 if (!rsbac_nosyslog) 04720 #endif 04721 printk(KERN_WARNING 04722 "rsbac_list_register: inserting list %s failed!\n", 04723 name); 04724 /* cleanup */ 04725 clear_reg(new_reg_item_p); 04726 return -RSBAC_ECOULDNOTADDITEM; 04727 } 04728 04729 /* finish */ 04730 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 04731 /* create proc entry, if requested */ 04732 if(flags & RSBAC_LIST_BACKUP) 04733 { 04734 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name, 04735 S_IFREG | S_IRUGO, 04736 proc_rsbac_backup_p); 04737 if(reg_item_p->proc_entry_p) 04738 { 04739 reg_item_p->proc_entry_p->read_proc = backup_proc_read; 04740 reg_item_p->proc_entry_p->data = reg_item_p; 04741 } 04742 } 04743 else 04744 { 04745 reg_item_p->proc_entry_p = NULL; 04746 } 04747 #endif 04748 *handle_p = reg_item_p; 04749 return err; 04750 } 04751 04752 /* register a new list of lists */ 04753 /* 04754 * If list with same name exists in memory, error -RSBAC_EEXISTS is returned. 04755 * If list with same name and key exists on device, it is restored depending on the flags. 04756 * If list with same name, but different key exists, access is denied (error -EPERM). 04757 * 04758 * ds_version: for binary modules, must be RSBAC_LIST_VERSION. If version differs, return error. 04759 * handle_p: for all list accesses, an opaque handle is put into *handle_p. 04760 * key: positive, secret __u32 key, which must be the same as in on-disk version, if persistent 04761 * list_version: positive __u32 version number for the list. If old on-disk version is 04762 different, upconversion is tried (depending on flags and get_conv function) 04763 * flags: see flag values 04764 * desc_size: size of the descriptor (error is returned, if value is 0 or list exists and value differs) 04765 * subdesc_size: size of the sublist descriptor (error is returned, if value is 0 or list exists 04766 and value differs) 04767 * data_size: size of data (error is returned, if list exists and value differs). Can be 0 for sets. 04768 * subdata_size: size of sublist data (error is returned, if list exists and value differs). 04769 Can be 0 for sets. 04770 * compare: for lookup and list optimization, can be NULL, then 04771 memcmp(desc1, desc2, desc_size) is used 04772 * subcompare: for item lookup and optimization of sublist, can be NULL, then 04773 memcmp(desc1, desc2, desc_size) is used 04774 * def_data: default data value for flag RSBAC_LIST_DEF_DATA 04775 (if NULL, flag is cleared) 04776 * def_subdata: default subdata value for flag RSBAC_LIST_DEF_SUBDATA 04777 (if NULL, flag is cleared) 04778 * name: the on-disk name, must be distinct and max. 7 or 8.2 chars 04779 (only used for info, if non-persistent) 04780 * device: the device to read list from or to save list to - use 0 for root dev 04781 (ignored, if non-persistent) 04782 */ 04783 04784 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 04785 EXPORT_SYMBOL(rsbac_list_lol_register); 04786 #endif 04787 int rsbac_list_lol_register( 04788 rsbac_version_t ds_version, 04789 rsbac_list_handle_t *handle_p, 04790 struct rsbac_list_lol_info_t * info_p, 04791 u_int flags, 04792 rsbac_list_compare_function_t * compare, 04793 rsbac_list_compare_function_t * subcompare, 04794 rsbac_list_get_conv_t * get_conv, 04795 rsbac_list_get_conv_t * get_subconv, 04796 void * def_data, 04797 void * def_subdata, 04798 char * name, 04799 kdev_t device) 04800 { 04801 struct rsbac_list_lol_reg_item_t * reg_item_p; 04802 struct rsbac_list_lol_reg_item_t * new_reg_item_p; 04803 u_long lock_flags; 04804 int err = 0; 04805 04806 if(ds_version != RSBAC_LIST_VERSION) 04807 return -RSBAC_EINVALIDVERSION; 04808 if(!handle_p) 04809 return -RSBAC_EINVALIDPOINTER; 04810 *handle_p = NULL; 04811 if(!info_p->key || !info_p->version || !info_p->desc_size) 04812 return -RSBAC_EINVALIDVALUE; 04813 if(info_p->max_age > RSBAC_LIST_MAX_AGE_LIMIT) 04814 return -RSBAC_EINVALIDVALUE; 04815 if(info_p->desc_size + info_p->data_size > RSBAC_LIST_MAX_ITEM_SIZE) 04816 return -RSBAC_EINVALIDVALUE; 04817 if(info_p->subdesc_size + info_p->subdata_size > RSBAC_LIST_MAX_ITEM_SIZE) 04818 return -RSBAC_EINVALIDVALUE; 04819 if(!list_initialized) 04820 return -RSBAC_ENOTINITIALIZED; 04821 if(name) 04822 { 04823 struct rsbac_list_reg_item_t * std_reg_item_p; 04824 04825 rsbac_read_lock(&lol_reg_head.lock, &lock_flags); 04826 reg_item_p = lookup_lol_reg_name(name, device); 04827 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 04828 if(reg_item_p) 04829 { 04830 #ifdef CONFIG_RSBAC_DEBUG 04831 if(rsbac_debug_lists) 04832 { 04833 #ifdef CONFIG_RSBAC_RMSG 04834 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: list name %s already exists on device %02u:%02u!\n", 04835 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04836 #endif 04837 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04838 if (!rsbac_nosyslog) 04839 #endif 04840 printk(KERN_DEBUG "rsbac_list_lol_register: list name %s already exists on device %02u:%02u!\n", 04841 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04842 } 04843 #endif 04844 return -RSBAC_EEXISTS; 04845 } 04846 rsbac_read_lock(&reg_head.lock, &lock_flags); 04847 std_reg_item_p = lookup_reg_name(name, device); 04848 rsbac_read_unlock(&reg_head.lock, &lock_flags); 04849 if(std_reg_item_p) 04850 { 04851 #ifdef CONFIG_RSBAC_DEBUG 04852 if(rsbac_debug_lists) 04853 { 04854 #ifdef CONFIG_RSBAC_RMSG 04855 rsbac_printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04856 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04857 #endif 04858 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04859 if (!rsbac_nosyslog) 04860 #endif 04861 printk(KERN_DEBUG "rsbac_list_register: list name %s already exists on device %02u:%02u!\n", 04862 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04863 } 04864 #endif 04865 return -RSBAC_EEXISTS; 04866 } 04867 } 04868 else 04869 if(flags & RSBAC_LIST_PERSIST) 04870 { 04871 #ifdef CONFIG_RSBAC_RMSG 04872 rsbac_printk(KERN_WARNING 04873 "rsbac_list_lol_register: trial to register persistent list of lists without name.\n"); 04874 #endif 04875 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04876 if (!rsbac_nosyslog) 04877 #endif 04878 printk(KERN_WARNING 04879 "rsbac_list_lol_register: trial to register persistent list of lists without name.\n"); 04880 return -RSBAC_EINVALIDVALUE; 04881 } 04882 04883 if(flags & RSBAC_LIST_PERSIST) 04884 { 04885 if(RSBAC_IS_AUTO_DEV(device)) 04886 device = rsbac_root_dev; 04887 if(!RSBAC_MAJOR(device)) 04888 flags &= ~RSBAC_LIST_PERSIST; 04889 } 04890 04891 #ifdef CONFIG_RSBAC_DEBUG 04892 if(rsbac_debug_lists) 04893 { 04894 #ifdef CONFIG_RSBAC_RMSG 04895 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: registering list of lists %s.\n", 04896 name); 04897 #endif 04898 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04899 if (!rsbac_nosyslog) 04900 #endif 04901 printk(KERN_DEBUG "rsbac_list_lol_register: registering list of lists %s.\n", 04902 name); 04903 } 04904 #endif 04905 new_reg_item_p = create_lol_reg(info_p, flags, compare, subcompare, 04906 get_conv, get_subconv, 04907 def_data, def_subdata, 04908 name, device); 04909 if(!new_reg_item_p) 04910 { 04911 return -RSBAC_ECOULDNOTADDITEM; 04912 } 04913 /* Restore from disk */ 04914 if(flags & RSBAC_LIST_PERSIST) 04915 { 04916 #ifdef CONFIG_RSBAC_DEBUG 04917 if(rsbac_debug_lists) 04918 { 04919 #ifdef CONFIG_RSBAC_RMSG 04920 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u.\n", 04921 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04922 #endif 04923 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04924 if (!rsbac_nosyslog) 04925 #endif 04926 printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u.\n", 04927 name, RSBAC_MAJOR(device), RSBAC_MINOR(device)); 04928 } 04929 #endif 04930 err = read_lol_list(new_reg_item_p); 04931 /* not found is no error */ 04932 if(err == -RSBAC_ENOTFOUND) 04933 err = 0; 04934 else 04935 if(err) 04936 { 04937 #ifdef CONFIG_RSBAC_DEBUG 04938 if(rsbac_debug_lists) 04939 { 04940 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 04941 04942 if(tmp) 04943 { 04944 get_error_name(tmp, err); 04945 #ifdef CONFIG_RSBAC_RMSG 04946 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n", 04947 name, 04948 RSBAC_MAJOR(device),RSBAC_MINOR(device), 04949 tmp); 04950 #endif 04951 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04952 if (!rsbac_nosyslog) 04953 #endif 04954 printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u failed with error %s, unregistering list.\n", 04955 name, 04956 RSBAC_MAJOR(device),RSBAC_MINOR(device), 04957 tmp); 04958 rsbac_kfree(tmp); 04959 } 04960 } 04961 #endif 04962 clear_lol_reg(new_reg_item_p); 04963 return err; 04964 } 04965 #ifdef CONFIG_RSBAC_DEBUG 04966 else 04967 { 04968 if(rsbac_debug_lists) 04969 { 04970 #ifdef CONFIG_RSBAC_RMSG 04971 rsbac_printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u was successful.\n", 04972 name, 04973 RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04974 #endif 04975 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04976 if (!rsbac_nosyslog) 04977 #endif 04978 printk(KERN_DEBUG "rsbac_list_lol_register: restoring list %s from device %02u:%02u was successful.\n", 04979 name, 04980 RSBAC_MAJOR(device),RSBAC_MINOR(device)); 04981 } 04982 } 04983 #endif 04984 } 04985 04986 rsbac_write_lock(&lol_reg_head.lock, &lock_flags); 04987 reg_item_p = add_lol_reg(new_reg_item_p); 04988 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags); 04989 if(!reg_item_p) 04990 { 04991 #ifdef CONFIG_RSBAC_RMSG 04992 rsbac_printk(KERN_WARNING 04993 "rsbac_list_lol_register: inserting list %s failed!\n", 04994 name); 04995 #endif 04996 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 04997 if (!rsbac_nosyslog) 04998 #endif 04999 printk(KERN_WARNING 05000 "rsbac_list_lol_register: inserting list %s failed!\n", 05001 name); 05002 /* cleanup */ 05003 clear_lol_reg(new_reg_item_p); 05004 return -RSBAC_ECOULDNOTADDITEM; 05005 } 05006 05007 /* finish */ 05008 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 05009 /* create proc entry, if requested */ 05010 if(flags & RSBAC_LIST_BACKUP) 05011 { 05012 reg_item_p->proc_entry_p = create_proc_entry(reg_item_p->name, 05013 S_IFREG | S_IRUGO, 05014 proc_rsbac_backup_p); 05015 if(reg_item_p->proc_entry_p) 05016 { 05017 reg_item_p->proc_entry_p->read_proc = lol_backup_proc_read; 05018 reg_item_p->proc_entry_p->data = reg_item_p; 05019 } 05020 } 05021 else 05022 { 05023 reg_item_p->proc_entry_p = NULL; 05024 } 05025 #endif 05026 *handle_p = reg_item_p; 05027 return err; 05028 } 05029 05030 /* destroy list */ 05031 /* list is destroyed, disk file is deleted */ 05032 /* list must have been opened with register */ 05033 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05034 EXPORT_SYMBOL(rsbac_list_destroy); 05035 #endif 05036 int rsbac_list_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key) 05037 { 05038 struct rsbac_list_reg_item_t * reg_item_p; 05039 u_long lock_flags; 05040 int err = 0; 05041 05042 if(!handle_p) 05043 return -RSBAC_EINVALIDPOINTER; 05044 if(!*handle_p) 05045 return -RSBAC_EINVALIDVALUE; 05046 if(!list_initialized) 05047 return -RSBAC_ENOTINITIALIZED; 05048 05049 rsbac_write_lock(&reg_head.lock, &lock_flags); 05050 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p); 05051 if(!reg_item_p) 05052 { 05053 rsbac_write_unlock(&reg_head.lock, &lock_flags); 05054 #ifdef CONFIG_RSBAC_RMSG 05055 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list failed due to invalid handle!\n"); 05056 #endif 05057 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05058 if (!rsbac_nosyslog) 05059 #endif 05060 printk(KERN_WARNING "rsbac_list_destroy: destroying list failed due to invalid handle!\n"); 05061 return -RSBAC_EINVALIDVALUE; 05062 } 05063 if(reg_item_p->info.key != key) 05064 { 05065 rsbac_write_unlock(&reg_head.lock, &lock_flags); 05066 #ifdef CONFIG_RSBAC_RMSG 05067 rsbac_printk(KERN_WARNING "rsbac_list_destroy: destroying list %s denied due to invalid key!\n", 05068 reg_item_p->name); 05069 #endif 05070 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05071 if (!rsbac_nosyslog) 05072 #endif 05073 printk(KERN_WARNING "rsbac_list_destroy: destroying list %s denied due to invalid key!\n", 05074 reg_item_p->name); 05075 return -EPERM; 05076 } 05077 #ifdef CONFIG_RSBAC_DEBUG 05078 if(rsbac_debug_lists) 05079 { 05080 #ifdef CONFIG_RSBAC_RMSG 05081 rsbac_printk(KERN_DEBUG "rsbac_list_destroy: destroying list %s.\n", 05082 reg_item_p->name); 05083 #endif 05084 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05085 if (!rsbac_nosyslog) 05086 #endif 05087 printk(KERN_DEBUG "rsbac_list_destroy: destroying list %s.\n", 05088 reg_item_p->name); 05089 } 05090 #endif 05091 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 05092 /* delete proc entry, if it exists */ 05093 if( (reg_item_p->flags & RSBAC_LIST_BACKUP) 05094 && reg_item_p->proc_entry_p 05095 ) 05096 { 05097 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p); 05098 reg_item_p->proc_entry_p = NULL; 05099 } 05100 #endif 05101 05102 #if 0 05103 if(reg_item_p->flags & RSBAC_LIST_PERSIST) 05104 err = unlink_list(reg_item_p); 05105 #endif 05106 05107 remove_reg(reg_item_p); 05108 *handle_p = NULL; 05109 rsbac_write_unlock(&reg_head.lock, &lock_flags); 05110 return err; 05111 } 05112 05113 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05114 EXPORT_SYMBOL(rsbac_list_lol_destroy); 05115 #endif 05116 int rsbac_list_lol_destroy(rsbac_list_handle_t * handle_p, rsbac_list_key_t key) 05117 { 05118 struct rsbac_list_lol_reg_item_t * reg_item_p; 05119 u_long lock_flags; 05120 int err = 0; 05121 05122 if(!handle_p) 05123 return -RSBAC_EINVALIDPOINTER; 05124 if(!*handle_p) 05125 return -RSBAC_EINVALIDVALUE; 05126 if(!list_initialized) 05127 return -RSBAC_ENOTINITIALIZED; 05128 05129 rsbac_write_lock(&lol_reg_head.lock, &lock_flags); 05130 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p); 05131 if(!reg_item_p) 05132 { 05133 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags); 05134 #ifdef CONFIG_RSBAC_RMSG 05135 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list failed due to invalid handle!\n"); 05136 #endif 05137 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05138 if (!rsbac_nosyslog) 05139 #endif 05140 printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list failed due to invalid handle!\n"); 05141 return -RSBAC_EINVALIDVALUE; 05142 } 05143 if(reg_item_p->info.key != key) 05144 { 05145 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags); 05146 #ifdef CONFIG_RSBAC_RMSG 05147 rsbac_printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list %s denied due to invalid key %u!\n", 05148 reg_item_p->name, 05149 key); 05150 #endif 05151 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05152 if (!rsbac_nosyslog) 05153 #endif 05154 printk(KERN_WARNING "rsbac_list_lol_destroy: destroying list %s denied due to invalid key %u!\n", 05155 reg_item_p->name, 05156 key); 05157 return -EPERM; 05158 } 05159 #ifdef CONFIG_RSBAC_DEBUG 05160 if(rsbac_debug_lists) 05161 { 05162 #ifdef CONFIG_RSBAC_RMSG 05163 rsbac_printk(KERN_DEBUG "rsbac_list_lol_destroy: destroying list %s.\n", 05164 reg_item_p->name); 05165 #endif 05166 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05167 if (!rsbac_nosyslog) 05168 #endif 05169 printk(KERN_DEBUG "rsbac_list_lol_destroy: destroying list %s.\n", 05170 reg_item_p->name); 05171 } 05172 #endif 05173 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 05174 /* delete proc entry, if it exists */ 05175 if( (reg_item_p->flags & RSBAC_LIST_BACKUP) 05176 && reg_item_p->proc_entry_p 05177 ) 05178 { 05179 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p); 05180 reg_item_p->proc_entry_p = NULL; 05181 } 05182 #endif 05183 #if 0 05184 if(reg_item_p->flags & RSBAC_LIST_PERSIST) 05185 err = unlink_lol_list(reg_item_p); 05186 #endif 05187 05188 remove_lol_reg(reg_item_p); 05189 *handle_p = NULL; 05190 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags); 05191 return err; 05192 } 05193 05194 /* detach from list */ 05195 /* list is saved and removed from memory. Call register for new access. */ 05196 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05197 EXPORT_SYMBOL(rsbac_list_detach); 05198 #endif 05199 int rsbac_list_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key) 05200 { 05201 struct rsbac_list_reg_item_t * reg_item_p; 05202 u_long lock_flags; 05203 int err = 0; 05204 05205 if(!handle_p) 05206 return -RSBAC_EINVALIDPOINTER; 05207 if(!*handle_p) 05208 return -RSBAC_EINVALIDVALUE; 05209 if(!list_initialized) 05210 return -RSBAC_ENOTINITIALIZED; 05211 05212 rsbac_read_lock(&reg_head.lock, &lock_flags); 05213 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) *handle_p); 05214 if(!reg_item_p) 05215 { 05216 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05217 #ifdef CONFIG_RSBAC_RMSG 05218 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list failed due to invalid handle!\n"); 05219 #endif 05220 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05221 if (!rsbac_nosyslog) 05222 #endif 05223 printk(KERN_WARNING "rsbac_list_detach: detaching list failed due to invalid handle!\n"); 05224 return -RSBAC_EINVALIDVALUE; 05225 } 05226 if(reg_item_p->info.key != key) 05227 { 05228 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05229 #ifdef CONFIG_RSBAC_RMSG 05230 rsbac_printk(KERN_WARNING "rsbac_list_detach: detaching list %s denied due to invalid key %u!\n", 05231 reg_item_p->name, 05232 key); 05233 #endif 05234 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05235 if (!rsbac_nosyslog) 05236 #endif 05237 printk(KERN_WARNING "rsbac_list_detach: detaching list %s denied due to invalid key %u!\n", 05238 reg_item_p->name, 05239 key); 05240 return -EPERM; 05241 } 05242 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 05243 /* delete proc entry, if it exists */ 05244 if( (reg_item_p->flags & RSBAC_LIST_BACKUP) 05245 && reg_item_p->proc_entry_p 05246 ) 05247 { 05248 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p); 05249 reg_item_p->proc_entry_p = NULL; 05250 } 05251 #endif 05252 #ifndef CONFIG_RSBAC_NO_WRITE 05253 /* final write, if dirty etc. */ 05254 if( (reg_item_p->flags & RSBAC_LIST_PERSIST) 05255 && reg_item_p->dirty 05256 && !reg_item_p->no_write 05257 ) 05258 { 05259 struct rsbac_list_write_head_t write_head; 05260 struct rsbac_list_write_item_t * write_item_p; 05261 05262 reg_item_p->dirty = FALSE; 05263 err = fill_buffer(reg_item_p, &write_item_p); 05264 if(!err) 05265 { 05266 write_head.head = write_item_p; 05267 write_head.tail = write_item_p; 05268 write_head.total = write_item_p->buflen; 05269 write_head.count = 1; 05270 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05271 rsbac_list_write_buffers(write_head, TRUE); 05272 } 05273 else 05274 { 05275 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05276 if(err != -RSBAC_ENOTWRITABLE) 05277 { 05278 #ifdef CONFIG_RSBAC_RMSG 05279 rsbac_printk(KERN_WARNING 05280 "rsbac_list_detach(): fill_buffer() for list %s returned error %i\n", 05281 reg_item_p->name, err); 05282 #endif 05283 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05284 if (!rsbac_nosyslog) 05285 #endif 05286 printk(KERN_WARNING 05287 "rsbac_list_detach(): fill_buffer() for list %s returned error %i\n", 05288 reg_item_p->name, err); 05289 } 05290 } 05291 } 05292 else 05293 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05294 #else 05295 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05296 #endif 05297 /* disable handle */ 05298 *handle_p = NULL; 05299 /* too bad that the list might have been changed again - we do not care anymore */ 05300 rsbac_write_lock(&reg_head.lock, &lock_flags); 05301 remove_reg(reg_item_p); 05302 rsbac_write_unlock(&reg_head.lock, &lock_flags); 05303 return err; 05304 } 05305 05306 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05307 EXPORT_SYMBOL(rsbac_list_lol_detach); 05308 #endif 05309 int rsbac_list_lol_detach(rsbac_list_handle_t * handle_p, rsbac_list_key_t key) 05310 { 05311 struct rsbac_list_lol_reg_item_t * reg_item_p; 05312 u_long lock_flags; 05313 int err = 0; 05314 05315 if(!handle_p) 05316 return -RSBAC_EINVALIDPOINTER; 05317 if(!*handle_p) 05318 return -RSBAC_EINVALIDVALUE; 05319 if(!list_initialized) 05320 return -RSBAC_ENOTINITIALIZED; 05321 05322 rsbac_read_lock(&lol_reg_head.lock, &lock_flags); 05323 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) *handle_p); 05324 if(!reg_item_p) 05325 { 05326 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05327 #ifdef CONFIG_RSBAC_RMSG 05328 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list failed due to invalid handle!\n"); 05329 #endif 05330 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05331 if (!rsbac_nosyslog) 05332 #endif 05333 printk(KERN_WARNING "rsbac_list_lol_detach: detaching list failed due to invalid handle!\n"); 05334 return -RSBAC_EINVALIDVALUE; 05335 } 05336 if(reg_item_p->info.key != key) 05337 { 05338 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05339 #ifdef CONFIG_RSBAC_RMSG 05340 rsbac_printk(KERN_WARNING "rsbac_list_lol_detach: detaching list %s denied due to invalid key %u!\n", 05341 reg_item_p->name, 05342 key); 05343 #endif 05344 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05345 if (!rsbac_nosyslog) 05346 #endif 05347 printk(KERN_WARNING "rsbac_list_lol_detach: detaching list %s denied due to invalid key %u!\n", 05348 reg_item_p->name, 05349 key); 05350 return -EPERM; 05351 } 05352 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 05353 /* delete proc entry, if it exists */ 05354 if( (reg_item_p->flags & RSBAC_LIST_BACKUP) 05355 && reg_item_p->proc_entry_p 05356 ) 05357 { 05358 remove_proc_entry(reg_item_p->name, proc_rsbac_backup_p); 05359 reg_item_p->proc_entry_p = NULL; 05360 } 05361 #endif 05362 #ifndef CONFIG_RSBAC_NO_WRITE 05363 /* final write, if dirty etc. */ 05364 if( (reg_item_p->flags & RSBAC_LIST_PERSIST) 05365 && reg_item_p->dirty 05366 && !reg_item_p->no_write 05367 ) 05368 { 05369 struct rsbac_list_lol_write_head_t write_head; 05370 struct rsbac_list_lol_write_item_t * write_item_p; 05371 05372 reg_item_p->dirty = FALSE; 05373 err = fill_lol_buffer(reg_item_p, &write_item_p); 05374 if(!err) 05375 { 05376 write_head.head = write_item_p; 05377 write_head.tail = write_item_p; 05378 write_head.total = write_item_p->buflen; 05379 write_head.count = 1; 05380 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05381 rsbac_list_write_lol_buffers(write_head, TRUE); 05382 } 05383 else 05384 { 05385 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05386 if(err != -RSBAC_ENOTWRITABLE) 05387 { 05388 #ifdef CONFIG_RSBAC_RMSG 05389 rsbac_printk(KERN_WARNING 05390 "rsbac_list_lol_detach(): fill_buffer() for list %s returned error %i\n", 05391 reg_item_p->name, err); 05392 #endif 05393 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05394 if (!rsbac_nosyslog) 05395 #endif 05396 printk(KERN_WARNING 05397 "rsbac_list_lol_detach(): fill_buffer() for list %s returned error %i\n", 05398 reg_item_p->name, err); 05399 } 05400 } 05401 } 05402 else 05403 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05404 #else 05405 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05406 #endif 05407 /* disable handle */ 05408 *handle_p = NULL; 05409 /* too bad that the list might have been changed again - we do not care anymore */ 05410 rsbac_write_lock(&lol_reg_head.lock, &lock_flags); 05411 remove_lol_reg(reg_item_p); 05412 rsbac_write_unlock(&lol_reg_head.lock, &lock_flags); 05413 return err; 05414 } 05415 05416 /* set list's no_write flag */ 05417 /* TRUE: do not write to disk, FALSE: writing allowed */ 05418 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05419 EXPORT_SYMBOL(rsbac_list_no_write); 05420 #endif 05421 int rsbac_list_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, boolean no_write) 05422 { 05423 struct rsbac_list_reg_item_t * reg_item_p; 05424 u_long lock_flags; 05425 05426 if( !handle 05427 || ( (no_write != FALSE ) 05428 && (no_write != TRUE ) 05429 ) 05430 ) 05431 return -RSBAC_EINVALIDVALUE; 05432 if(!list_initialized) 05433 return -RSBAC_ENOTINITIALIZED; 05434 05435 rsbac_read_lock(&reg_head.lock, &lock_flags); 05436 reg_item_p = lookup_reg((struct rsbac_list_reg_item_t *) handle); 05437 if(!reg_item_p) 05438 { 05439 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05440 #ifdef CONFIG_RSBAC_RMSG 05441 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list denied due to invalid handle!\n"); 05442 #endif 05443 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05444 if (!rsbac_nosyslog) 05445 #endif 05446 printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list denied due to invalid handle!\n"); 05447 return -RSBAC_EINVALIDVALUE; 05448 } 05449 if(reg_item_p->info.key != key) 05450 { 05451 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05452 #ifdef CONFIG_RSBAC_RMSG 05453 rsbac_printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list %s denied due to invalid key %u!\n", 05454 reg_item_p->name, 05455 key); 05456 #endif 05457 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05458 if (!rsbac_nosyslog) 05459 #endif 05460 printk(KERN_WARNING "rsbac_list_no_write: setting no_write for list %s denied due to invalid key %u!\n", 05461 reg_item_p->name, 05462 key); 05463 return -EPERM; 05464 } 05465 reg_item_p->no_write = no_write; 05466 rsbac_read_unlock(&reg_head.lock, &lock_flags); 05467 return 0; 05468 } 05469 05470 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05471 EXPORT_SYMBOL(rsbac_list_lol_no_write); 05472 #endif 05473 int rsbac_list_lol_no_write(rsbac_list_handle_t handle, rsbac_list_key_t key, boolean no_write) 05474 { 05475 struct rsbac_list_lol_reg_item_t * reg_item_p; 05476 u_long lock_flags; 05477 05478 if( !handle 05479 || ( (no_write != FALSE ) 05480 && (no_write != TRUE ) 05481 ) 05482 ) 05483 return -RSBAC_EINVALIDVALUE; 05484 if(!list_initialized) 05485 return -RSBAC_ENOTINITIALIZED; 05486 05487 rsbac_read_lock(&lol_reg_head.lock, &lock_flags); 05488 reg_item_p = lookup_lol_reg((struct rsbac_list_lol_reg_item_t *) handle); 05489 if(!reg_item_p) 05490 { 05491 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05492 #ifdef CONFIG_RSBAC_RMSG 05493 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list denied due to invalid handle!\n"); 05494 #endif 05495 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05496 if (!rsbac_nosyslog) 05497 #endif 05498 printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list denied due to invalid handle!\n"); 05499 return -RSBAC_EINVALIDVALUE; 05500 } 05501 if(reg_item_p->info.key != key) 05502 { 05503 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05504 #ifdef CONFIG_RSBAC_RMSG 05505 rsbac_printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list %s denied due to invalid key %u!\n", 05506 reg_item_p->name, 05507 key); 05508 #endif 05509 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 05510 if (!rsbac_nosyslog) 05511 #endif 05512 printk(KERN_WARNING "rsbac_list_lol_no_write: setting no_write for list %s denied due to invalid key %u!\n", 05513 reg_item_p->name, 05514 key); 05515 return -EPERM; 05516 } 05517 reg_item_p->no_write = no_write; 05518 rsbac_read_unlock(&lol_reg_head.lock, &lock_flags); 05519 return 0; 05520 } 05521 05522 05523 /********************/ 05524 /* List Access */ 05525 /********************/ 05526 05527 /* add item */ 05528 /* if item for desc exists, the data is updated */ 05529 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05530 EXPORT_SYMBOL(rsbac_list_add_ttl); 05531 #endif 05532 int rsbac_list_add_ttl( 05533 rsbac_list_handle_t handle, 05534 rsbac_time_t ttl, 05535 void * desc, 05536 void * data) 05537 { 05538 struct rsbac_list_reg_item_t * list; 05539 struct rsbac_list_item_t * item_p; 05540 u_long lock_flags, rlock_flags; 05541 05542 if(!handle || !desc) 05543 return -RSBAC_EINVALIDVALUE; 05544 if(!list_initialized) 05545 return -RSBAC_ENOTINITIALIZED; 05546 05547 list = (struct rsbac_list_reg_item_t *) handle; 05548 if(!list || (list->self != list)) 05549 return -RSBAC_EINVALIDVALUE; 05550 05551 rsbac_read_lock(&reg_head.lock, &rlock_flags); 05552 if(list->info.data_size && !data) 05553 { 05554 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 05555 return -RSBAC_EINVALIDVALUE; 05556 } 05557 05558 /* 05559 #ifdef CONFIG_RSBAC_DEBUG 05560 if(rsbac_debug_lists) 05561 printk(KERN_DEBUG "rsbac_list_add: adding to list %s.\n", 05562 list->name); 05563 #endif 05564 */ 05565 rsbac_write_lock(&list->lock, &lock_flags); 05566 05567 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP)) 05568 { 05569 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT) 05570 ttl = RSBAC_LIST_MAX_AGE_LIMIT; 05571 ttl += RSBAC_CURRENT_TIME; 05572 } 05573 item_p = lookup_item(list, desc); 05574 if(item_p) 05575 { /* exists -> update data, if any */ 05576 if(ttl != RSBAC_LIST_TTL_KEEP) 05577 item_p->max_age = ttl; 05578 if(data && list->info.data_size) 05579 { 05580 if( list->def_data 05581 && !item_p->max_age 05582 && !memcmp(list->def_data, data, list->info.data_size) 05583 ) 05584 do_remove_item(list, item_p); 05585 else 05586 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 05587 data, list->info.data_size); 05588 } 05589 } 05590 else 05591 { 05592 if(ttl == RSBAC_LIST_TTL_KEEP) 05593 ttl = 0; 05594 if( !list->def_data 05595 || memcmp(list->def_data, data, list->info.data_size) 05596 ) 05597 add_item(list, ttl, desc, data); 05598 } 05599 list->dirty = TRUE; 05600 rsbac_write_unlock(&list->lock, &lock_flags); 05601 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 05602 return 0; 05603 } 05604 05605 /* simple wrapper for 32Bit desc to allow using const values */ 05606 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05607 EXPORT_SYMBOL(rsbac_list_add_ttl_u32); 05608 #endif 05609 int rsbac_list_add_ttl_u32(rsbac_list_handle_t handle, rsbac_time_t ttl, __u32 desc, void * data) 05610 { 05611 return rsbac_list_add_ttl(handle, ttl, &desc, data); 05612 } 05613 05614 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05615 EXPORT_SYMBOL(rsbac_list_add); 05616 #endif 05617 int rsbac_list_add( 05618 rsbac_list_handle_t handle, 05619 void * desc, 05620 void * data) 05621 { 05622 return rsbac_list_add_ttl(handle, RSBAC_LIST_TTL_KEEP, desc, data); 05623 } 05624 05625 /* simple wrapper for 32Bit desc to allow using const values */ 05626 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05627 EXPORT_SYMBOL(rsbac_list_add_u32); 05628 #endif 05629 int rsbac_list_add_u32(rsbac_list_handle_t handle, __u32 desc, void * data) 05630 { 05631 return rsbac_list_add_ttl(handle, RSBAC_LIST_TTL_KEEP, &desc, data); 05632 } 05633 05634 /* add list of lists sublist item */ 05635 /* if item for desc exists, the data is updated */ 05636 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05637 EXPORT_SYMBOL(rsbac_list_lol_subadd_ttl); 05638 #endif 05639 int rsbac_list_lol_subadd_ttl( 05640 rsbac_list_handle_t handle, 05641 rsbac_time_t ttl, 05642 void * desc, 05643 void * subdesc, 05644 void * subdata) 05645 { 05646 struct rsbac_list_lol_reg_item_t * list; 05647 struct rsbac_list_lol_item_t * sublist; 05648 struct rsbac_list_item_t * item_p; 05649 u_long lock_flags, rlock_flags; 05650 int err = 0; 05651 05652 if(!handle || !desc || !subdesc) 05653 return -RSBAC_EINVALIDVALUE; 05654 if(!list_initialized) 05655 return -RSBAC_ENOTINITIALIZED; 05656 05657 list = (struct rsbac_list_lol_reg_item_t *) handle; 05658 if(!list || (list->self != list)) 05659 return -RSBAC_EINVALIDVALUE; 05660 05661 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 05662 if(list->info.subdata_size && !subdata) 05663 { 05664 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 05665 return -RSBAC_EINVALIDVALUE; 05666 } 05667 05668 /* 05669 #ifdef CONFIG_RSBAC_DEBUG 05670 if(rsbac_debug_lists) 05671 printk(KERN_DEBUG "rsbac_list_lol_subadd: adding to list %s.\n", 05672 list->name); 05673 #endif 05674 */ 05675 rsbac_write_lock(&list->lock, &lock_flags); 05676 05677 sublist = lookup_lol_item(list, desc); 05678 if( !sublist 05679 && (list->flags & RSBAC_LIST_DEF_DATA) 05680 ) 05681 sublist = add_lol_item(list, 0, desc, list->def_data); 05682 if(sublist) 05683 { 05684 if( sublist->max_age 05685 && (sublist->max_age <= RSBAC_CURRENT_TIME) 05686 ) 05687 { 05688 remove_lol_item(list, desc); 05689 err = -RSBAC_EINVALIDTARGET; 05690 } 05691 else 05692 { 05693 /* exists -> lookup subitem */ 05694 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP)) 05695 { 05696 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT) 05697 ttl = RSBAC_LIST_MAX_AGE_LIMIT; 05698 ttl += RSBAC_CURRENT_TIME; 05699 } 05700 item_p = lookup_lol_subitem(list, sublist, subdesc); 05701 if(item_p) 05702 { /* exists -> update data, if any */ 05703 if(ttl != RSBAC_LIST_TTL_KEEP) 05704 item_p->max_age = ttl; 05705 if(subdata && list->info.subdata_size) 05706 { 05707 if( list->def_subdata 05708 && !item_p->max_age 05709 && !memcmp(list->def_subdata, subdata, list->info.subdata_size) 05710 ) 05711 do_remove_lol_subitem(sublist, item_p); 05712 else 05713 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size, 05714 subdata, 05715 list->info.subdata_size); 05716 } 05717 } 05718 else 05719 { 05720 if(ttl == RSBAC_LIST_TTL_KEEP) 05721 ttl = 0; 05722 if( !list->def_subdata 05723 || memcmp(list->def_subdata, subdata, list->info.subdata_size) 05724 ) 05725 add_lol_subitem(list, sublist, ttl, subdesc, subdata); 05726 } 05727 list->dirty = TRUE; 05728 } 05729 } 05730 else 05731 { 05732 err = -RSBAC_EINVALIDTARGET; 05733 } 05734 rsbac_write_unlock(&list->lock, &lock_flags); 05735 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 05736 return err; 05737 } 05738 05739 /* simple wrapper for 32Bit desc to allow using const values */ 05740 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05741 EXPORT_SYMBOL(rsbac_list_lol_subadd_ttl_u32); 05742 #endif 05743 int rsbac_list_lol_subadd_ttl_u32(rsbac_list_handle_t handle, 05744 rsbac_time_t ttl, 05745 __u32 desc, 05746 __u32 subdesc, 05747 void * subdata) 05748 { 05749 return rsbac_list_lol_subadd_ttl(handle, ttl, &desc, &subdesc, subdata); 05750 } 05751 05752 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05753 EXPORT_SYMBOL(rsbac_list_lol_subadd); 05754 #endif 05755 int rsbac_list_lol_subadd( 05756 rsbac_list_handle_t handle, 05757 void * desc, 05758 void * subdesc, 05759 void * subdata) 05760 { 05761 return rsbac_list_lol_subadd_ttl(handle, RSBAC_LIST_TTL_KEEP, desc, subdesc, subdata); 05762 } 05763 05764 /* simple wrapper for 32Bit desc to allow using const values */ 05765 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05766 EXPORT_SYMBOL(rsbac_list_lol_subadd_u32); 05767 #endif 05768 int rsbac_list_lol_subadd_u32(rsbac_list_handle_t handle, 05769 __u32 desc, 05770 __u32 subdesc, 05771 void * subdata) 05772 { 05773 return rsbac_list_lol_subadd_ttl(handle, RSBAC_LIST_TTL_KEEP, &desc, &subdesc, subdata); 05774 } 05775 05776 05777 /* add list of lists item */ 05778 /* if item for desc exists, the data is updated */ 05779 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05780 EXPORT_SYMBOL(rsbac_list_lol_add_ttl); 05781 #endif 05782 int rsbac_list_lol_add_ttl( 05783 rsbac_list_handle_t handle, 05784 rsbac_time_t ttl, 05785 void * desc, 05786 void * data) 05787 { 05788 struct rsbac_list_lol_reg_item_t * list; 05789 struct rsbac_list_lol_item_t * item_p; 05790 u_long lock_flags, rlock_flags; 05791 05792 if(!handle || !desc) 05793 return -RSBAC_EINVALIDVALUE; 05794 if(!list_initialized) 05795 return -RSBAC_ENOTINITIALIZED; 05796 05797 list = (struct rsbac_list_lol_reg_item_t *) handle; 05798 if(!list || (list->self != list)) 05799 return -RSBAC_EINVALIDVALUE; 05800 05801 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 05802 if(list->info.data_size && !data) 05803 { 05804 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 05805 return -RSBAC_EINVALIDVALUE; 05806 } 05807 05808 /* 05809 #ifdef CONFIG_RSBAC_DEBUG 05810 if(rsbac_debug_lists) 05811 printk(KERN_DEBUG "rsbac_list_lol_add: adding to list %s.\n", 05812 list->name); 05813 #endif 05814 */ 05815 rsbac_write_lock(&list->lock, &lock_flags); 05816 05817 if(ttl && (ttl != RSBAC_LIST_TTL_KEEP)) 05818 { 05819 if(ttl > RSBAC_LIST_MAX_AGE_LIMIT) 05820 ttl = RSBAC_LIST_MAX_AGE_LIMIT; 05821 ttl += RSBAC_CURRENT_TIME; 05822 } 05823 item_p = lookup_lol_item(list, desc); 05824 if(item_p) 05825 { /* exists -> update data, if any */ 05826 if(ttl != RSBAC_LIST_TTL_KEEP) 05827 item_p->max_age = ttl; 05828 if(data && list->info.data_size) 05829 { 05830 if( list->def_data 05831 && !item_p->max_age 05832 && !memcmp(list->def_data, data, list->info.data_size) 05833 && !item_p->count 05834 ) 05835 do_remove_lol_item(list, item_p); 05836 else 05837 memcpy(((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 05838 data, list->info.data_size); 05839 } 05840 } 05841 else 05842 { 05843 if(ttl == RSBAC_LIST_TTL_KEEP) 05844 ttl = 0; 05845 if( !list->def_data 05846 || memcmp(list->def_data, data, list->info.data_size) 05847 ) 05848 add_lol_item(list, ttl, desc, data); 05849 } 05850 list->dirty = TRUE; 05851 rsbac_write_unlock(&list->lock, &lock_flags); 05852 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 05853 return 0; 05854 } 05855 05856 /* simple wrapper for 32Bit desc to allow using const values */ 05857 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05858 EXPORT_SYMBOL(rsbac_list_lol_add_ttl_u32); 05859 #endif 05860 int rsbac_list_lol_add_ttl_u32(rsbac_list_handle_t handle, 05861 rsbac_time_t ttl, 05862 __u32 desc, 05863 void * data) 05864 { 05865 return rsbac_list_lol_add_ttl(handle, ttl, &desc, data); 05866 } 05867 05868 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05869 EXPORT_SYMBOL(rsbac_list_lol_add); 05870 #endif 05871 int rsbac_list_lol_add( 05872 rsbac_list_handle_t handle, 05873 void * desc, 05874 void * data) 05875 { 05876 return rsbac_list_lol_add_ttl(handle, RSBAC_LIST_TTL_KEEP, desc, data); 05877 } 05878 05879 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05880 EXPORT_SYMBOL(rsbac_list_lol_add_u32); 05881 #endif 05882 int rsbac_list_lol_add_u32(rsbac_list_handle_t handle, __u32 desc, void * data) 05883 { 05884 return rsbac_list_lol_add_ttl(handle, RSBAC_LIST_TTL_KEEP, &desc, data); 05885 } 05886 05887 05888 /* remove item */ 05889 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05890 EXPORT_SYMBOL(rsbac_list_remove); 05891 #endif 05892 int rsbac_list_remove( 05893 rsbac_list_handle_t handle, 05894 void * desc) 05895 { 05896 struct rsbac_list_reg_item_t * list; 05897 u_long lock_flags, rlock_flags; 05898 05899 if(!handle || !desc) 05900 return -RSBAC_EINVALIDVALUE; 05901 if(!list_initialized) 05902 return -RSBAC_ENOTINITIALIZED; 05903 05904 list = (struct rsbac_list_reg_item_t *) handle; 05905 if(!list || (list->self != list)) 05906 return -RSBAC_EINVALIDVALUE; 05907 05908 rsbac_read_lock(&reg_head.lock, &rlock_flags); 05909 /* 05910 #ifdef CONFIG_RSBAC_DEBUG 05911 if(rsbac_debug_lists) 05912 printk(KERN_DEBUG "rsbac_list_remove: removing from list %s.\n", 05913 list->name); 05914 #endif 05915 */ 05916 rsbac_write_lock(&list->lock, &lock_flags); 05917 if(lookup_item(list, desc)) 05918 { /* exists -> remove */ 05919 remove_item(list, desc); 05920 list->dirty = TRUE; 05921 } 05922 rsbac_write_unlock(&list->lock, &lock_flags); 05923 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 05924 return 0; 05925 } 05926 05927 /* simple wrapper for 32Bit desc to allow using const values */ 05928 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05929 EXPORT_SYMBOL(rsbac_list_remove_u32); 05930 #endif 05931 int rsbac_list_remove_u32(rsbac_list_handle_t handle, __u32 desc) 05932 { 05933 return rsbac_list_remove(handle, &desc); 05934 } 05935 05936 05937 /* remove all items */ 05938 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05939 EXPORT_SYMBOL(rsbac_list_remove_all); 05940 #endif 05941 int rsbac_list_remove_all(rsbac_list_handle_t handle) 05942 { 05943 struct rsbac_list_reg_item_t * list; 05944 u_long lock_flags, rlock_flags; 05945 05946 if(!handle) 05947 return -RSBAC_EINVALIDVALUE; 05948 if(!list_initialized) 05949 return -RSBAC_ENOTINITIALIZED; 05950 05951 list = (struct rsbac_list_reg_item_t *) handle; 05952 if(list->self != list) 05953 return -RSBAC_EINVALIDVALUE; 05954 05955 rsbac_read_lock(&reg_head.lock, &rlock_flags); 05956 /* 05957 #ifdef CONFIG_RSBAC_DEBUG 05958 if(rsbac_debug_lists) 05959 printk(KERN_DEBUG "rsbac_list_remove_all: removing all items from list %s.\n", 05960 list->name); 05961 #endif 05962 */ 05963 rsbac_write_lock(&list->lock, &lock_flags); 05964 if(list->head) 05965 { 05966 remove_all_items(list); 05967 list->dirty = TRUE; 05968 } 05969 rsbac_write_unlock(&list->lock, &lock_flags); 05970 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 05971 return 0; 05972 } 05973 05974 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 05975 EXPORT_SYMBOL(rsbac_list_lol_subremove); 05976 #endif 05977 int rsbac_list_lol_subremove( 05978 rsbac_list_handle_t handle, 05979 void * desc, 05980 void * subdesc) 05981 { 05982 struct rsbac_list_lol_reg_item_t * list; 05983 struct rsbac_list_lol_item_t * sublist; 05984 u_long lock_flags, rlock_flags; 05985 05986 if(!handle || !desc || !subdesc) 05987 return -RSBAC_EINVALIDVALUE; 05988 if(!list_initialized) 05989 return -RSBAC_ENOTINITIALIZED; 05990 05991 list = (struct rsbac_list_lol_reg_item_t *) handle; 05992 if(list->self != list) 05993 return -RSBAC_EINVALIDVALUE; 05994 05995 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 05996 /* 05997 #ifdef CONFIG_RSBAC_DEBUG 05998 if(rsbac_debug_lists) 05999 printk(KERN_DEBUG "rsbac_list_lol_subremove: removing from list of lists %s, device %02u:%02u.\n", 06000 list->name, 06001 RSBAC_MAJOR(list->device), RSBAC_MINOR(list->device)); 06002 #endif 06003 */ 06004 rsbac_write_lock(&list->lock, &lock_flags); 06005 sublist = lookup_lol_item(list, desc); 06006 if(sublist) 06007 { 06008 if( sublist->max_age 06009 && (sublist->max_age <= RSBAC_CURRENT_TIME) 06010 ) 06011 { 06012 do_remove_lol_item(list, sublist); 06013 } 06014 else 06015 { 06016 if(lookup_lol_subitem(list, sublist, subdesc)) 06017 { /* exists -> remove and set dirty */ 06018 remove_lol_subitem(list, sublist, subdesc); 06019 list->dirty = TRUE; 06020 } 06021 if( !sublist->count 06022 && ( ( list->def_data 06023 && !memcmp(((char *) sublist) + sizeof(*sublist) + list->info.desc_size, 06024 list->def_data, 06025 list->info.data_size) 06026 ) 06027 || ( !list->info.data_size 06028 && (list->flags & RSBAC_LIST_DEF_DATA) 06029 ) 06030 ) 06031 ) 06032 do_remove_lol_item(list, sublist); 06033 } 06034 } 06035 rsbac_write_unlock(&list->lock, &lock_flags); 06036 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06037 return 0; 06038 } 06039 06040 /* simple wrapper for 32Bit desc to allow using const values */ 06041 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06042 EXPORT_SYMBOL(rsbac_list_lol_subremove_u32); 06043 #endif 06044 int rsbac_list_lol_subremove_u32(rsbac_list_handle_t handle, __u32 desc, __u32 subdesc) 06045 { 06046 return rsbac_list_lol_subremove(handle, &desc, &subdesc); 06047 } 06048 06049 06050 /* remove same subitem from all items */ 06051 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06052 EXPORT_SYMBOL(rsbac_list_lol_subremove_from_all); 06053 #endif 06054 int rsbac_list_lol_subremove_from_all( 06055 rsbac_list_handle_t handle, 06056 void * subdesc) 06057 { 06058 struct rsbac_list_lol_reg_item_t * list; 06059 struct rsbac_list_lol_item_t * sublist; 06060 u_long lock_flags, rlock_flags; 06061 06062 if(!handle || !subdesc) 06063 return -RSBAC_EINVALIDVALUE; 06064 if(!list_initialized) 06065 return -RSBAC_ENOTINITIALIZED; 06066 06067 list = (struct rsbac_list_lol_reg_item_t *) handle; 06068 if(list->self != list) 06069 return -RSBAC_EINVALIDVALUE; 06070 06071 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06072 /* 06073 #ifdef CONFIG_RSBAC_DEBUG 06074 if(rsbac_debug_lists) 06075 printk(KERN_DEBUG "rsbac_list_lol_subremove: removing from list of lists %s.\n", 06076 list->name); 06077 #endif 06078 */ 06079 rsbac_write_lock(&list->lock, &lock_flags); 06080 06081 sublist = list->head; 06082 while(sublist) 06083 { 06084 if(lookup_lol_subitem(list, sublist, subdesc)) 06085 { /* exists -> remove and set dirty */ 06086 remove_lol_subitem(list, sublist, subdesc); 06087 list->dirty = TRUE; 06088 } 06089 sublist = sublist->next; 06090 } 06091 rsbac_write_unlock(&list->lock, &lock_flags); 06092 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06093 return 0; 06094 } 06095 06096 /* simple wrapper for 32Bit desc to allow using const values */ 06097 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06098 EXPORT_SYMBOL(rsbac_list_lol_subremove_from_all_u32); 06099 #endif 06100 int rsbac_list_lol_subremove_from_all_u32(rsbac_list_handle_t handle, __u32 subdesc) 06101 { 06102 return rsbac_list_lol_subremove_from_all(handle, &subdesc); 06103 } 06104 06105 06106 /* remove all subitems */ 06107 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06108 EXPORT_SYMBOL(rsbac_list_lol_subremove_all); 06109 #endif 06110 int rsbac_list_lol_subremove_all(rsbac_list_handle_t handle, void * desc) 06111 { 06112 struct rsbac_list_lol_reg_item_t * list; 06113 struct rsbac_list_lol_item_t * sublist; 06114 u_long lock_flags, rlock_flags; 06115 06116 if(!handle) 06117 return -RSBAC_EINVALIDVALUE; 06118 if(!list_initialized) 06119 return -RSBAC_ENOTINITIALIZED; 06120 06121 list = (struct rsbac_list_lol_reg_item_t *) handle; 06122 if(list->self != list) 06123 return -RSBAC_EINVALIDVALUE; 06124 06125 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06126 /* 06127 #ifdef CONFIG_RSBAC_DEBUG 06128 if(rsbac_debug_lists) 06129 printk(KERN_DEBUG "rsbac_list_lol_subremove_all: removing all subitems from list of lists %s.\n", 06130 list->name); 06131 #endif 06132 */ 06133 rsbac_write_lock(&list->lock, &lock_flags); 06134 sublist = lookup_lol_item(list, desc); 06135 if(sublist && sublist->head) 06136 { 06137 remove_all_lol_subitems(sublist); 06138 list->dirty = TRUE; 06139 } 06140 rsbac_write_unlock(&list->lock, &lock_flags); 06141 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06142 return 0; 06143 } 06144 06145 /* simple wrapper for 32Bit desc to allow using const values */ 06146 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06147 EXPORT_SYMBOL(rsbac_list_lol_subremove_all_u32); 06148 #endif 06149 int rsbac_list_lol_subremove_all_u32(rsbac_list_handle_t handle, __u32 desc) 06150 { 06151 return rsbac_list_lol_subremove_all(handle, &desc); 06152 } 06153 06154 06155 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06156 EXPORT_SYMBOL(rsbac_list_lol_remove); 06157 #endif 06158 int rsbac_list_lol_remove( 06159 rsbac_list_handle_t handle, 06160 void * desc) 06161 { 06162 struct rsbac_list_lol_reg_item_t * list; 06163 u_long lock_flags, rlock_flags; 06164 06165 if(!handle || !desc) 06166 return -RSBAC_EINVALIDVALUE; 06167 if(!list_initialized) 06168 return -RSBAC_ENOTINITIALIZED; 06169 06170 list = (struct rsbac_list_lol_reg_item_t *) handle; 06171 if(list->self != list) 06172 return -RSBAC_EINVALIDVALUE; 06173 06174 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06175 /* 06176 #ifdef CONFIG_RSBAC_DEBUG 06177 if(rsbac_debug_lists) 06178 printk(KERN_DEBUG "rsbac_list_lol_remove: removing from list of lists %s.\n", 06179 list->name); 06180 #endif 06181 */ 06182 rsbac_write_lock(&list->lock, &lock_flags); 06183 if(lookup_lol_item(list, desc)) 06184 { /* exists -> remove */ 06185 remove_lol_item(list, desc); 06186 list->dirty = TRUE; 06187 } 06188 rsbac_write_unlock(&list->lock, &lock_flags); 06189 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06190 return 0; 06191 } 06192 06193 /* simple wrapper for 32Bit desc to allow using const values */ 06194 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06195 EXPORT_SYMBOL(rsbac_list_lol_remove_u32); 06196 #endif 06197 int rsbac_list_lol_remove_u32(rsbac_list_handle_t handle, __u32 desc) 06198 { 06199 return rsbac_list_lol_remove(handle, &desc); 06200 } 06201 06202 06203 /* remove all items */ 06204 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06205 EXPORT_SYMBOL(rsbac_list_lol_remove_all); 06206 #endif 06207 int rsbac_list_lol_remove_all(rsbac_list_handle_t handle) 06208 { 06209 struct rsbac_list_lol_reg_item_t * list; 06210 u_long lock_flags, rlock_flags; 06211 06212 if(!handle) 06213 return -RSBAC_EINVALIDVALUE; 06214 if(!list_initialized) 06215 return -RSBAC_ENOTINITIALIZED; 06216 06217 list = (struct rsbac_list_lol_reg_item_t *) handle; 06218 if(list->self != list) 06219 return -RSBAC_EINVALIDVALUE; 06220 06221 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06222 /* 06223 #ifdef CONFIG_RSBAC_DEBUG 06224 if(rsbac_debug_lists) 06225 printk(KERN_DEBUG "rsbac_list_lol_remove_all: removing all items from list of lists %s.\n", 06226 list->name); 06227 #endif 06228 */ 06229 rsbac_write_lock(&list->lock, &lock_flags); 06230 if(list->head) 06231 { 06232 remove_all_lol_items(list); 06233 list->dirty = TRUE; 06234 } 06235 rsbac_write_unlock(&list->lock, &lock_flags); 06236 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06237 return 0; 06238 } 06239 06240 06241 /* get item data */ 06242 /* Item data is copied - we cannot give a pointer, because item could be 06243 * removed */ 06244 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06245 EXPORT_SYMBOL(rsbac_list_get_data_ttl); 06246 #endif 06247 int rsbac_list_get_data_ttl(rsbac_list_handle_t handle, 06248 rsbac_time_t * ttl_p, 06249 void * desc, 06250 void * data) 06251 { 06252 struct rsbac_list_reg_item_t * list; 06253 struct rsbac_list_item_t * item_p; 06254 u_long lock_flags, rlock_flags; 06255 int err = 0; 06256 06257 if(!handle || !desc) 06258 return -RSBAC_EINVALIDVALUE; 06259 if(!list_initialized) 06260 return -RSBAC_ENOTINITIALIZED; 06261 06262 list = (struct rsbac_list_reg_item_t *) handle; 06263 if(list->self != list) 06264 return -RSBAC_EINVALIDVALUE; 06265 06266 rsbac_read_lock(&reg_head.lock, &rlock_flags); 06267 /* 06268 #ifdef CONFIG_RSBAC_DEBUG 06269 if(rsbac_debug_lists) 06270 printk(KERN_DEBUG "rsbac_list_get_data: getting data from list %s.\n", 06271 list->name); 06272 #endif 06273 */ 06274 if(data && !list->info.data_size) 06275 { 06276 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06277 return -RSBAC_EINVALIDREQUEST; 06278 } 06279 06280 rsbac_read_lock(&list->lock, &lock_flags); 06281 06282 item_p = lookup_item(list, desc); 06283 if( item_p 06284 && ( !item_p->max_age 06285 || (item_p->max_age > RSBAC_CURRENT_TIME) 06286 ) 06287 ) 06288 { /* exists -> copy data, if any */ 06289 if(ttl_p) 06290 { 06291 if(item_p->max_age) 06292 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME; 06293 else 06294 *ttl_p = 0; 06295 } 06296 if(data) 06297 { 06298 memcpy(data, 06299 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 06300 list->info.data_size); 06301 } 06302 } 06303 else 06304 { 06305 if(!list->def_data) 06306 err = -RSBAC_ENOTFOUND; 06307 else 06308 { 06309 if(ttl_p) 06310 *ttl_p = 0; 06311 if(data) 06312 memcpy(data, 06313 list->def_data, 06314 list->info.data_size); 06315 } 06316 } 06317 rsbac_read_unlock(&list->lock, &lock_flags); 06318 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06319 return err; 06320 } 06321 06322 /* simple wrapper for 32Bit desc to allow using const values */ 06323 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06324 EXPORT_SYMBOL(rsbac_list_get_data_ttl_u32); 06325 #endif 06326 int rsbac_list_get_data_ttl_u32(rsbac_list_handle_t handle, 06327 rsbac_time_t * ttl_p, 06328 __u32 desc, 06329 void * data) 06330 { 06331 return rsbac_list_get_data_ttl(handle, ttl_p, &desc, data); 06332 } 06333 06334 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06335 EXPORT_SYMBOL(rsbac_list_get_data); 06336 #endif 06337 int rsbac_list_get_data(rsbac_list_handle_t handle, void * desc, void * data) 06338 { 06339 return rsbac_list_get_data_ttl(handle, NULL, desc, data); 06340 } 06341 06342 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06343 EXPORT_SYMBOL(rsbac_list_get_data_u32); 06344 #endif 06345 int rsbac_list_get_data_u32(rsbac_list_handle_t handle, __u32 desc, void * data) 06346 { 06347 return rsbac_list_get_data_ttl(handle, NULL, &desc, data); 06348 } 06349 06350 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06351 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_ttl); 06352 #endif 06353 int rsbac_list_lol_get_subdata_ttl( 06354 rsbac_list_handle_t handle, 06355 rsbac_time_t * ttl_p, 06356 void * desc, 06357 void * subdesc, 06358 void * subdata) 06359 { 06360 struct rsbac_list_lol_reg_item_t * list; 06361 struct rsbac_list_lol_item_t * sublist; 06362 struct rsbac_list_item_t * item_p; 06363 u_long lock_flags, rlock_flags; 06364 int err = 0; 06365 06366 if(!handle || !desc || !subdesc) 06367 return -RSBAC_EINVALIDVALUE; 06368 if(!list_initialized) 06369 return -RSBAC_ENOTINITIALIZED; 06370 06371 list = (struct rsbac_list_lol_reg_item_t *) handle; 06372 if(list->self != list) 06373 return -RSBAC_EINVALIDVALUE; 06374 06375 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06376 /* 06377 #ifdef CONFIG_RSBAC_DEBUG 06378 if(rsbac_debug_lists) 06379 printk(KERN_DEBUG "rsbac_list_lol_get_subdata: getting data from list %s.\n", 06380 list->name); 06381 #endif 06382 */ 06383 if(subdata && !list->info.subdata_size) 06384 { 06385 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06386 return -RSBAC_EINVALIDREQUEST; 06387 } 06388 06389 rsbac_read_lock(&list->lock, &lock_flags); 06390 06391 sublist = lookup_lol_item(list, desc); 06392 if(sublist) 06393 { /* exists -> lookup subitem */ 06394 item_p = lookup_lol_subitem(list, sublist, subdesc); 06395 if( item_p 06396 && ( !item_p->max_age 06397 || (item_p->max_age > RSBAC_CURRENT_TIME) 06398 ) 06399 ) 06400 { /* exists -> copy data, if any */ 06401 if(ttl_p) 06402 { 06403 if(item_p->max_age) 06404 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME; 06405 else 06406 *ttl_p = 0; 06407 } 06408 if(subdata) 06409 { 06410 memcpy(subdata, 06411 ((char *) item_p) + sizeof(*item_p) + list->info.subdesc_size, 06412 list->info.subdata_size); 06413 } 06414 } 06415 else 06416 { 06417 if(!list->def_subdata) 06418 err = -RSBAC_ENOTFOUND; 06419 else 06420 { 06421 if(ttl_p) 06422 *ttl_p = 0; 06423 if(subdata) 06424 memcpy(subdata, 06425 list->def_subdata, 06426 list->info.subdata_size); 06427 } 06428 } 06429 } 06430 else 06431 { 06432 if(!list->def_subdata) 06433 err = -RSBAC_ENOTFOUND; 06434 else 06435 { 06436 if(ttl_p) 06437 *ttl_p = 0; 06438 if(subdata) 06439 memcpy(subdata, 06440 list->def_subdata, 06441 list->info.subdata_size); 06442 } 06443 } 06444 rsbac_read_unlock(&list->lock, &lock_flags); 06445 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06446 return err; 06447 } 06448 06449 /* simple wrapper for 32Bit desc to allow using const values */ 06450 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06451 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_ttl_u32); 06452 #endif 06453 int rsbac_list_lol_get_subdata_ttl_u32(rsbac_list_handle_t handle, 06454 rsbac_time_t * ttl_p, 06455 __u32 desc, 06456 __u32 subdesc, 06457 void * data) 06458 { 06459 return rsbac_list_lol_get_subdata_ttl(handle, ttl_p, &desc, &subdesc, data); 06460 } 06461 06462 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06463 EXPORT_SYMBOL(rsbac_list_lol_get_subdata); 06464 #endif 06465 int rsbac_list_lol_get_subdata( 06466 rsbac_list_handle_t handle, 06467 void * desc, 06468 void * subdesc, 06469 void * subdata) 06470 { 06471 return rsbac_list_lol_get_subdata_ttl(handle, NULL, desc, subdesc, subdata); 06472 } 06473 06474 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06475 EXPORT_SYMBOL(rsbac_list_lol_get_subdata_u32); 06476 #endif 06477 int rsbac_list_lol_get_subdata_u32(rsbac_list_handle_t handle, __u32 desc, __u32 subdesc, void * data) 06478 { 06479 return rsbac_list_lol_get_subdata_ttl(handle, NULL, &desc, &subdesc, data); 06480 } 06481 06482 06483 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06484 EXPORT_SYMBOL(rsbac_list_lol_get_data_ttl); 06485 #endif 06486 int rsbac_list_lol_get_data_ttl(rsbac_list_handle_t handle, 06487 rsbac_time_t * ttl_p, 06488 void * desc, 06489 void * data) 06490 { 06491 struct rsbac_list_lol_reg_item_t * list; 06492 struct rsbac_list_lol_item_t * item_p; 06493 u_long lock_flags, rlock_flags; 06494 int err = 0; 06495 06496 if(!handle || !desc) 06497 return -RSBAC_EINVALIDVALUE; 06498 if(!list_initialized) 06499 return -RSBAC_ENOTINITIALIZED; 06500 06501 list = (struct rsbac_list_lol_reg_item_t *) handle; 06502 if(list->self != list) 06503 return -RSBAC_EINVALIDVALUE; 06504 06505 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06506 /* 06507 #ifdef CONFIG_RSBAC_DEBUG 06508 if(rsbac_debug_lists) 06509 printk(KERN_DEBUG "rsbac_list_lol_get_data: getting data from list %s.\n", 06510 list->name); 06511 #endif 06512 */ 06513 if(data && !list->info.data_size) 06514 { 06515 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06516 return -RSBAC_EINVALIDREQUEST; 06517 } 06518 06519 rsbac_read_lock(&list->lock, &lock_flags); 06520 06521 item_p = lookup_lol_item(list, desc); 06522 if( item_p 06523 && ( !item_p->max_age 06524 || (item_p->max_age > RSBAC_CURRENT_TIME) 06525 ) 06526 ) 06527 { /* exists -> copy data, if any */ 06528 if(ttl_p) 06529 { 06530 if(item_p->max_age) 06531 *ttl_p = item_p->max_age - RSBAC_CURRENT_TIME; 06532 else 06533 *ttl_p = 0; 06534 } 06535 if(data) 06536 { 06537 memcpy(data, 06538 ((char *) item_p) + sizeof(*item_p) + list->info.desc_size, 06539 list->info.data_size); 06540 } 06541 } 06542 else 06543 { 06544 if(!list->def_data) 06545 err = -RSBAC_ENOTFOUND; 06546 else 06547 { 06548 if(ttl_p) 06549 *ttl_p = 0; 06550 if(data) 06551 memcpy(data, 06552 list->def_data, 06553 list->info.data_size); 06554 } 06555 } 06556 rsbac_read_unlock(&list->lock, &lock_flags); 06557 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06558 return err; 06559 } 06560 06561 /* simple wrapper for 32Bit desc to allow using const values */ 06562 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06563 EXPORT_SYMBOL(rsbac_list_lol_get_data_ttl_u32); 06564 #endif 06565 int rsbac_list_lol_get_data_ttl_u32(rsbac_list_handle_t handle, 06566 rsbac_time_t * ttl_p, 06567 __u32 desc, 06568 void * data) 06569 { 06570 return rsbac_list_lol_get_data_ttl(handle, ttl_p, &desc, data); 06571 } 06572 06573 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06574 EXPORT_SYMBOL(rsbac_list_lol_get_data); 06575 #endif 06576 int rsbac_list_lol_get_data(rsbac_list_handle_t handle, 06577 void * desc, 06578 void * data) 06579 { 06580 return rsbac_list_lol_get_data_ttl(handle, NULL, desc, data); 06581 } 06582 06583 /* simple wrapper for 32Bit desc to allow using const values */ 06584 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06585 EXPORT_SYMBOL(rsbac_list_lol_get_data_u32); 06586 #endif 06587 int rsbac_list_lol_get_data_u32(rsbac_list_handle_t handle, __u32 desc, void * data) 06588 { 06589 return rsbac_list_lol_get_data_ttl(handle, NULL, &desc, data); 06590 } 06591 06592 06593 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06594 EXPORT_SYMBOL(rsbac_list_get_max_desc); 06595 #endif 06596 int rsbac_list_get_max_desc(rsbac_list_handle_t handle, void * desc) 06597 { 06598 struct rsbac_list_reg_item_t * list; 06599 struct rsbac_list_item_t * item_p; 06600 u_long lock_flags, rlock_flags; 06601 06602 if(!handle) 06603 return -RSBAC_EINVALIDVALUE; 06604 if(!list_initialized) 06605 return -RSBAC_ENOTINITIALIZED; 06606 06607 list = (struct rsbac_list_reg_item_t *) handle; 06608 if(list->self != list) 06609 return -RSBAC_EINVALIDVALUE; 06610 06611 rsbac_read_lock(&reg_head.lock, &rlock_flags); 06612 /* 06613 #ifdef CONFIG_RSBAC_DEBUG 06614 if(rsbac_debug_lists) 06615 printk(KERN_DEBUG "rsbac_list_get_max_desc: list %s.\n", 06616 list->name); 06617 #endif 06618 */ 06619 rsbac_read_lock(&list->lock, &lock_flags); 06620 item_p = list->tail; 06621 while( item_p 06622 && item_p->max_age 06623 && (item_p->max_age > RSBAC_CURRENT_TIME) 06624 ) 06625 item_p = item_p->prev; 06626 if(item_p) 06627 memcpy(desc, (char *)item_p + sizeof(*item_p), list->info.desc_size); 06628 else 06629 memset(desc, 0, list->info.desc_size); 06630 rsbac_read_unlock(&list->lock, &lock_flags); 06631 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06632 return 0; 06633 } 06634 06635 /* get item desc by data */ 06636 /* Item desc is copied - we cannot give a pointer, because item could be 06637 * removed. 06638 * If no compare function is provided (NULL value), memcmp is used. 06639 * Note: The data value given here is always used as second parameter to the 06640 * compare function, so you can use different types for storage and 06641 * lookup. 06642 */ 06643 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06644 EXPORT_SYMBOL(rsbac_list_get_desc); 06645 #endif 06646 int rsbac_list_get_desc(rsbac_list_handle_t handle, 06647 void * desc, 06648 void * data, 06649 rsbac_list_data_compare_function_t compare) 06650 { 06651 struct rsbac_list_reg_item_t * list; 06652 struct rsbac_list_item_t * item_p; 06653 u_long lock_flags, rlock_flags; 06654 int err = 0; 06655 06656 if(!handle || !desc || !data) 06657 return -RSBAC_EINVALIDVALUE; 06658 if(!list_initialized) 06659 return -RSBAC_ENOTINITIALIZED; 06660 06661 list = (struct rsbac_list_reg_item_t *) handle; 06662 if(list->self != list) 06663 return -RSBAC_EINVALIDVALUE; 06664 06665 rsbac_read_lock(&reg_head.lock, &rlock_flags); 06666 /* 06667 #ifdef CONFIG_RSBAC_DEBUG 06668 if(rsbac_debug_lists) 06669 printk(KERN_DEBUG "rsbac_list_get_desc: getting desc from list %s.\n", 06670 list->name); 06671 #endif 06672 */ 06673 if(!list->info.data_size) 06674 { 06675 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06676 return -RSBAC_EINVALIDREQUEST; 06677 } 06678 06679 rsbac_read_lock(&list->lock, &lock_flags); 06680 06681 item_p = lookup_item_data(list, data, compare); 06682 if(item_p) 06683 { /* exists -> copy desc */ 06684 memcpy(desc, 06685 ((char *) item_p) + sizeof(*item_p), 06686 list->info.desc_size); 06687 } 06688 else 06689 { 06690 err = -RSBAC_ENOTFOUND; 06691 } 06692 rsbac_read_unlock(&list->lock, &lock_flags); 06693 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06694 return err; 06695 } 06696 06697 06698 /* returns TRUE, if item exists or def_data is defined, FALSE, if not */ 06699 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06700 EXPORT_SYMBOL(rsbac_list_exist); 06701 #endif 06702 int rsbac_list_exist( 06703 rsbac_list_handle_t handle, 06704 void * desc) 06705 { 06706 struct rsbac_list_reg_item_t * list; 06707 u_long lock_flags, rlock_flags; 06708 struct rsbac_list_item_t * item_p; 06709 int result; 06710 06711 if(!handle || !desc) 06712 return FALSE; 06713 if(!list_initialized) 06714 return FALSE; 06715 06716 list = (struct rsbac_list_reg_item_t *) handle; 06717 if(list->self != list) 06718 return -RSBAC_EINVALIDVALUE; 06719 06720 rsbac_read_lock(&reg_head.lock, &rlock_flags); 06721 /* 06722 #ifdef CONFIG_RSBAC_DEBUG 06723 if(rsbac_debug_lists) 06724 printk(KERN_DEBUG "rsbac_list_exist: testing on list %s.\n", 06725 list->name); 06726 #endif 06727 */ 06728 rsbac_read_lock(&list->lock, &lock_flags); 06729 06730 item_p = lookup_item(list, desc); 06731 if( item_p 06732 && ( !item_p->max_age 06733 || (item_p->max_age > RSBAC_CURRENT_TIME) 06734 ) 06735 ) 06736 { /* exists -> TRUE */ 06737 result = TRUE; 06738 } 06739 else 06740 { 06741 result = FALSE; 06742 } 06743 rsbac_read_unlock(&list->lock, &lock_flags); 06744 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 06745 return result; 06746 } 06747 06748 /* simple wrapper for 32Bit desc to allow using const values */ 06749 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06750 EXPORT_SYMBOL(rsbac_list_exist_u32); 06751 #endif 06752 int rsbac_list_exist_u32(rsbac_list_handle_t handle, __u32 desc) 06753 { 06754 return rsbac_list_exist(handle, &desc); 06755 } 06756 06757 /* does item exist? */ 06758 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06759 EXPORT_SYMBOL(rsbac_list_lol_subexist); 06760 #endif 06761 int rsbac_list_lol_subexist( 06762 rsbac_list_handle_t handle, 06763 void * desc, 06764 void * subdesc) 06765 { 06766 struct rsbac_list_lol_reg_item_t * list; 06767 struct rsbac_list_lol_item_t * sublist; 06768 u_long lock_flags, rlock_flags; 06769 struct rsbac_list_item_t * item_p; 06770 int result; 06771 06772 if(!handle || !desc || !subdesc) 06773 return FALSE; 06774 if(!list_initialized) 06775 return FALSE; 06776 06777 list = (struct rsbac_list_lol_reg_item_t *) handle; 06778 if(list->self != list) 06779 return -RSBAC_EINVALIDVALUE; 06780 06781 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06782 /* 06783 #ifdef CONFIG_RSBAC_DEBUG 06784 if(rsbac_debug_lists) 06785 printk(KERN_DEBUG "rsbac_list_lol_subexist: testing on list %s.\n", 06786 list->name); 06787 #endif 06788 */ 06789 rsbac_read_lock(&list->lock, &lock_flags); 06790 06791 sublist = lookup_lol_item(list, desc); 06792 if(sublist) 06793 { /* exists -> lookup subitem */ 06794 item_p = lookup_lol_subitem(list, sublist, subdesc); 06795 if( item_p 06796 && ( !item_p->max_age 06797 || (item_p->max_age > RSBAC_CURRENT_TIME) 06798 ) 06799 ) 06800 { /* exists -> TRUE */ 06801 result = TRUE; 06802 } 06803 else 06804 { 06805 result = FALSE; 06806 } 06807 } 06808 else 06809 { 06810 result = FALSE; 06811 } 06812 rsbac_read_unlock(&list->lock, &lock_flags); 06813 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06814 return result; 06815 } 06816 06817 /* simple wrapper for 32Bit desc to allow using const values */ 06818 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06819 EXPORT_SYMBOL(rsbac_list_lol_subexist_u32); 06820 #endif 06821 int rsbac_list_lol_subexist_u32(rsbac_list_handle_t handle, __u32 desc, __u32 subdesc) 06822 { 06823 return rsbac_list_lol_subexist(handle, &desc, &subdesc); 06824 } 06825 06826 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06827 EXPORT_SYMBOL(rsbac_list_lol_subexist_compare); 06828 #endif 06829 int rsbac_list_lol_subexist_compare( 06830 rsbac_list_handle_t handle, 06831 void * desc, 06832 void * subdesc, 06833 rsbac_list_compare_function_t compare) 06834 { 06835 struct rsbac_list_lol_reg_item_t * list; 06836 struct rsbac_list_lol_item_t * sublist; 06837 u_long lock_flags, rlock_flags; 06838 struct rsbac_list_item_t * item_p; 06839 int result; 06840 06841 if(!handle || !desc || !subdesc) 06842 return FALSE; 06843 if(!list_initialized) 06844 return FALSE; 06845 /* Use standard function, if compare is not provided. */ 06846 if(!compare) 06847 return rsbac_list_lol_subexist(handle, desc, subdesc); 06848 06849 list = (struct rsbac_list_lol_reg_item_t *) handle; 06850 if(list->self != list) 06851 return -RSBAC_EINVALIDVALUE; 06852 06853 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06854 /* 06855 #ifdef CONFIG_RSBAC_DEBUG 06856 if(rsbac_debug_lists) 06857 printk(KERN_DEBUG "rsbac_list_lol_subexist_compare: testing on list %s.\n", 06858 list->name); 06859 #endif 06860 */ 06861 rsbac_read_lock(&list->lock, &lock_flags); 06862 06863 sublist = lookup_lol_item(list, desc); 06864 if(sublist) 06865 { /* exists -> lookup subitem */ 06866 item_p = lookup_lol_subitem_user_compare(list, sublist, subdesc, compare); 06867 if( item_p 06868 && ( !item_p->max_age 06869 || (item_p->max_age > RSBAC_CURRENT_TIME) 06870 ) 06871 ) 06872 { /* exists -> TRUE */ 06873 result = TRUE; 06874 } 06875 else 06876 { 06877 result = FALSE; 06878 } 06879 } 06880 else 06881 { 06882 result = FALSE; 06883 } 06884 rsbac_read_unlock(&list->lock, &lock_flags); 06885 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06886 return result; 06887 } 06888 06889 /* simple wrapper for 32Bit desc to allow using const values */ 06890 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06891 EXPORT_SYMBOL(rsbac_list_lol_subexist_compare_u32); 06892 #endif 06893 int rsbac_list_lol_subexist_compare_u32(rsbac_list_handle_t handle, 06894 __u32 desc, 06895 __u32 subdesc, 06896 rsbac_list_compare_function_t compare) 06897 { 06898 return rsbac_list_lol_subexist(handle, &desc, &subdesc); 06899 } 06900 06901 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06902 EXPORT_SYMBOL(rsbac_list_lol_exist); 06903 #endif 06904 int rsbac_list_lol_exist( 06905 rsbac_list_handle_t handle, 06906 void * desc) 06907 { 06908 struct rsbac_list_lol_reg_item_t * list; 06909 u_long lock_flags, rlock_flags; 06910 struct rsbac_list_lol_item_t * item_p; 06911 int result; 06912 06913 if(!handle || !desc) 06914 return FALSE; 06915 if(!list_initialized) 06916 return FALSE; 06917 06918 list = (struct rsbac_list_lol_reg_item_t *) handle; 06919 if(list->self != list) 06920 return -RSBAC_EINVALIDVALUE; 06921 06922 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06923 /* 06924 #ifdef CONFIG_RSBAC_DEBUG 06925 if(rsbac_debug_lists) 06926 printk(KERN_DEBUG "rsbac_list_lol_exist: testing on list %s.\n", 06927 list->name); 06928 #endif 06929 */ 06930 rsbac_read_lock(&list->lock, &lock_flags); 06931 06932 item_p = lookup_lol_item(list, desc); 06933 if( item_p 06934 && ( !item_p->max_age 06935 || (item_p->max_age > RSBAC_CURRENT_TIME) 06936 ) 06937 ) 06938 { /* exists -> TRUE */ 06939 result = TRUE; 06940 } 06941 else 06942 { 06943 result = FALSE; 06944 } 06945 rsbac_read_unlock(&list->lock, &lock_flags); 06946 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 06947 return result; 06948 } 06949 06950 /* simple wrapper for 32Bit desc to allow using const values */ 06951 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06952 EXPORT_SYMBOL(rsbac_list_lol_exist_u32); 06953 #endif 06954 int rsbac_list_lol_exist_u32(rsbac_list_handle_t handle, __u32 desc) 06955 { 06956 return rsbac_list_lol_exist(handle, &desc); 06957 } 06958 06959 06960 /* count number of elements */ 06961 /* returns number of elements or negative error code */ 06962 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 06963 EXPORT_SYMBOL(rsbac_list_lol_subcount); 06964 #endif 06965 long rsbac_list_lol_subcount(rsbac_list_handle_t handle, void * desc) 06966 { 06967 struct rsbac_list_lol_reg_item_t * list; 06968 struct rsbac_list_lol_item_t * sublist; 06969 u_long lock_flags, rlock_flags; 06970 long result; 06971 06972 if(!handle) 06973 return -RSBAC_EINVALIDVALUE; 06974 if(!list_initialized) 06975 return -RSBAC_ENOTINITIALIZED; 06976 06977 list = (struct rsbac_list_lol_reg_item_t *) handle; 06978 if(list->self != list) 06979 return -RSBAC_EINVALIDVALUE; 06980 06981 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 06982 /* 06983 #ifdef CONFIG_RSBAC_DEBUG 06984 if(rsbac_debug_lists) 06985 printk(KERN_DEBUG "rsbac_list_lol_subcount: list %s.\n", 06986 list->name); 06987 #endif 06988 */ 06989 rsbac_read_lock(&list->lock, &lock_flags); 06990 06991 sublist = lookup_lol_item(list, desc); 06992 if(sublist) 06993 { 06994 result = sublist->count; 06995 } 06996 else 06997 { 06998 result = -RSBAC_ENOTFOUND; 06999 } 07000 rsbac_read_unlock(&list->lock, &lock_flags); 07001 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07002 return result; 07003 } 07004 07005 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07006 EXPORT_SYMBOL(rsbac_list_lol_all_subcount); 07007 #endif 07008 long rsbac_list_lol_all_subcount(rsbac_list_handle_t handle) 07009 { 07010 struct rsbac_list_lol_reg_item_t * list; 07011 struct rsbac_list_lol_item_t * sublist; 07012 u_long lock_flags, rlock_flags; 07013 long result = 0; 07014 07015 if(!handle) 07016 return -RSBAC_EINVALIDVALUE; 07017 if(!list_initialized) 07018 return -RSBAC_ENOTINITIALIZED; 07019 07020 list = (struct rsbac_list_lol_reg_item_t *) handle; 07021 if(list->self != list) 07022 return -RSBAC_EINVALIDVALUE; 07023 07024 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07025 /* 07026 #ifdef CONFIG_RSBAC_DEBUG 07027 if(rsbac_debug_lists) 07028 printk(KERN_DEBUG "rsbac_list_lol_subcount: list %s.\n", 07029 list->name); 07030 #endif 07031 */ 07032 rsbac_read_lock(&list->lock, &lock_flags); 07033 07034 sublist = list->head; 07035 while(sublist) 07036 { 07037 result += sublist->count; 07038 sublist = sublist->next; 07039 } 07040 rsbac_read_unlock(&list->lock, &lock_flags); 07041 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07042 return result; 07043 } 07044 07045 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07046 EXPORT_SYMBOL(rsbac_list_lol_count); 07047 #endif 07048 long rsbac_list_lol_count(rsbac_list_handle_t handle) 07049 { 07050 struct rsbac_list_lol_reg_item_t * list; 07051 07052 if(!handle) 07053 return -RSBAC_EINVALIDVALUE; 07054 if(!list_initialized) 07055 return -RSBAC_ENOTINITIALIZED; 07056 07057 list = (struct rsbac_list_lol_reg_item_t *) handle; 07058 if(list->self != list) 07059 return -RSBAC_EINVALIDVALUE; 07060 07061 /* 07062 #ifdef CONFIG_RSBAC_DEBUG 07063 if(rsbac_debug_lists) 07064 printk(KERN_DEBUG "rsbac_list_lol_count: list %s.\n", 07065 list->name); 07066 #endif 07067 */ 07068 return list->count; 07069 } 07070 07071 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07072 EXPORT_SYMBOL(rsbac_list_count); 07073 #endif 07074 long rsbac_list_count(rsbac_list_handle_t handle) 07075 { 07076 struct rsbac_list_reg_item_t * list; 07077 07078 if(!handle) 07079 return -RSBAC_EINVALIDVALUE; 07080 if(!list_initialized) 07081 return -RSBAC_ENOTINITIALIZED; 07082 07083 list = (struct rsbac_list_reg_item_t *) handle; 07084 if(list->self != list) 07085 return -RSBAC_EINVALIDVALUE; 07086 07087 /* 07088 #ifdef CONFIG_RSBAC_DEBUG 07089 if(rsbac_debug_lists) 07090 printk(KERN_DEBUG "rsbac_list_count: list %s.\n", 07091 list->name); 07092 #endif 07093 */ 07094 return list->count; 07095 } 07096 07097 07098 /* Get array of all descriptors */ 07099 /* Returns number of elements or negative error code */ 07100 /* If return value > 0, *array_p contains a pointer to a vmalloc'd array of descs, 07101 otherwise *array_p is set to NULL. If *array_p has been set, caller must call 07102 rsbac_vfree(*array_p) after use! */ 07103 07104 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07105 EXPORT_SYMBOL(rsbac_list_get_all_desc); 07106 #endif 07107 long rsbac_list_get_all_desc(rsbac_list_handle_t handle, void ** array_p) 07108 { 07109 struct rsbac_list_reg_item_t * list; 07110 struct rsbac_list_item_t * item_p; 07111 char * buffer; 07112 u_long lock_flags, rlock_flags; 07113 u_long offset = 0; 07114 long result = 0; 07115 u_int item_size; 07116 07117 if(!handle) 07118 return -RSBAC_EINVALIDVALUE; 07119 if(!array_p) 07120 return -RSBAC_EINVALIDVALUE; 07121 if(!list_initialized) 07122 return -RSBAC_ENOTINITIALIZED; 07123 07124 list = (struct rsbac_list_reg_item_t *) handle; 07125 if(list->self != list) 07126 return -RSBAC_EINVALIDVALUE; 07127 *array_p = NULL; 07128 07129 rsbac_read_lock(&reg_head.lock, &rlock_flags); 07130 /* 07131 #ifdef CONFIG_RSBAC_DEBUG 07132 if(rsbac_debug_lists) 07133 printk(KERN_DEBUG "rsbac_list_get_all_desc: list %s.\n", 07134 list->name); 07135 #endif 07136 */ 07137 rsbac_read_lock(&list->lock, &lock_flags); 07138 if(list->count) 07139 { 07140 item_size = list->info.desc_size; 07141 buffer = rsbac_vmalloc(item_size * list->count); 07142 if(buffer) 07143 { 07144 item_p = list->head; 07145 while(item_p) 07146 { 07147 if( !item_p->max_age 07148 || (item_p->max_age > RSBAC_CURRENT_TIME) 07149 ) 07150 { 07151 memcpy(buffer + offset, 07152 ((char *) item_p) + sizeof(*item_p), 07153 item_size); 07154 offset += item_size; 07155 result++; 07156 } 07157 item_p = item_p->next; 07158 } 07159 *array_p = buffer; 07160 } 07161 else 07162 { 07163 result = -RSBAC_ENOMEM; 07164 } 07165 } 07166 rsbac_read_unlock(&list->lock, &lock_flags); 07167 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 07168 return result; 07169 } 07170 07171 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07172 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc_ttl); 07173 #endif 07174 long rsbac_list_lol_get_all_subdesc_ttl(rsbac_list_handle_t handle, 07175 void * desc, 07176 void ** array_p, 07177 rsbac_time_t ** ttl_array_p) 07178 { 07179 struct rsbac_list_lol_reg_item_t * list; 07180 struct rsbac_list_lol_item_t * sublist; 07181 struct rsbac_list_item_t * item_p; 07182 char * buffer; 07183 rsbac_time_t * ttl_p = NULL; 07184 u_long lock_flags, rlock_flags; 07185 u_long offset = 0; 07186 long result = 0; 07187 u_int item_size; 07188 07189 if(!handle) 07190 return -RSBAC_EINVALIDVALUE; 07191 if(!array_p) 07192 return -RSBAC_EINVALIDVALUE; 07193 if(!list_initialized) 07194 return -RSBAC_ENOTINITIALIZED; 07195 07196 list = (struct rsbac_list_lol_reg_item_t *) handle; 07197 if(list->self != list) 07198 return -RSBAC_EINVALIDVALUE; 07199 *array_p = NULL; 07200 07201 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07202 /* 07203 #ifdef CONFIG_RSBAC_DEBUG 07204 if(rsbac_debug_lists) 07205 printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n", 07206 list->name); 07207 #endif 07208 */ 07209 rsbac_read_lock(&list->lock, &lock_flags); 07210 sublist = lookup_lol_item(list, desc); 07211 if(sublist && sublist->count) 07212 { 07213 item_size = list->info.subdesc_size; 07214 buffer = rsbac_vmalloc(item_size * sublist->count); 07215 if(buffer) 07216 { 07217 if(ttl_array_p) 07218 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count); 07219 item_p = sublist->head; 07220 while(item_p) 07221 { 07222 if( !item_p->max_age 07223 || (item_p->max_age > RSBAC_CURRENT_TIME) 07224 ) 07225 { 07226 memcpy(buffer + offset, 07227 ((char *) item_p) + sizeof(*item_p), 07228 item_size); 07229 if(ttl_p) 07230 { 07231 if(item_p->max_age) 07232 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME; 07233 else 07234 ttl_p[result] = 0; 07235 } 07236 offset += item_size; 07237 result++; 07238 } 07239 item_p = item_p->next; 07240 } 07241 *array_p = buffer; 07242 if(ttl_array_p) 07243 *ttl_array_p = ttl_p; 07244 } 07245 else 07246 { 07247 result = -RSBAC_ENOMEM; 07248 } 07249 } 07250 rsbac_read_unlock(&list->lock, &lock_flags); 07251 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07252 return result; 07253 } 07254 07255 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07256 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdesc); 07257 #endif 07258 long rsbac_list_lol_get_all_subdesc(rsbac_list_handle_t handle, void * desc, void ** array_p) 07259 { 07260 return rsbac_list_lol_get_all_subdesc_ttl(handle, desc, array_p, NULL); 07261 } 07262 07263 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07264 EXPORT_SYMBOL(rsbac_list_lol_get_all_desc); 07265 #endif 07266 long rsbac_list_lol_get_all_desc(rsbac_list_handle_t handle, void ** array_p) 07267 { 07268 struct rsbac_list_lol_reg_item_t * list; 07269 struct rsbac_list_lol_item_t * item_p; 07270 char * buffer; 07271 u_long lock_flags, rlock_flags; 07272 u_long offset = 0; 07273 long result = 0; 07274 u_int item_size; 07275 07276 if(!handle) 07277 return -RSBAC_EINVALIDVALUE; 07278 if(!array_p) 07279 return -RSBAC_EINVALIDVALUE; 07280 if(!list_initialized) 07281 return -RSBAC_ENOTINITIALIZED; 07282 07283 list = (struct rsbac_list_lol_reg_item_t *) handle; 07284 if(list->self != list) 07285 return -RSBAC_EINVALIDVALUE; 07286 *array_p = NULL; 07287 07288 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07289 /* 07290 #ifdef CONFIG_RSBAC_DEBUG 07291 if(rsbac_debug_lists) 07292 printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n", 07293 list->name); 07294 #endif 07295 */ 07296 rsbac_read_lock(&list->lock, &lock_flags); 07297 if(list->count) 07298 { 07299 item_size = list->info.desc_size; 07300 buffer = rsbac_vmalloc(item_size * list->count); 07301 if(buffer) 07302 { 07303 item_p = list->head; 07304 while(item_p) 07305 { 07306 if( !item_p->max_age 07307 || (item_p->max_age > RSBAC_CURRENT_TIME) 07308 ) 07309 { 07310 memcpy(buffer + offset, 07311 ((char *) item_p) + sizeof(*item_p), 07312 item_size); 07313 offset += item_size; 07314 result++; 07315 } 07316 item_p = item_p->next; 07317 } 07318 *array_p = buffer; 07319 } 07320 else 07321 { 07322 result = -RSBAC_ENOMEM; 07323 } 07324 } 07325 rsbac_read_unlock(&list->lock, &lock_flags); 07326 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07327 return result; 07328 } 07329 07330 /* Get array of all data */ 07331 /* Returns number of elements or negative error code */ 07332 /* If return value > 0, *array_p contains a pointer to a vmalloc'd array of datas, 07333 otherwise *array_p is set to NULL. If *array_p has been set, caller must call 07334 rsbac_vfree(*array_p) after use! */ 07335 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07336 EXPORT_SYMBOL(rsbac_list_get_all_data); 07337 #endif 07338 long rsbac_list_get_all_data(rsbac_list_handle_t handle, void ** array_p) 07339 { 07340 struct rsbac_list_reg_item_t * list; 07341 struct rsbac_list_item_t * item_p; 07342 char * buffer; 07343 u_long lock_flags, rlock_flags; 07344 u_long offset = 0; 07345 long result = 0; 07346 u_int item_size; 07347 u_int item_offset; 07348 07349 if(!handle) 07350 return -RSBAC_EINVALIDVALUE; 07351 if(!array_p) 07352 return -RSBAC_EINVALIDVALUE; 07353 if(!list_initialized) 07354 return -RSBAC_ENOTINITIALIZED; 07355 07356 list = (struct rsbac_list_reg_item_t *) handle; 07357 if(list->self != list) 07358 return -RSBAC_EINVALIDVALUE; 07359 *array_p = NULL; 07360 07361 rsbac_read_lock(&reg_head.lock, &rlock_flags); 07362 /* 07363 #ifdef CONFIG_RSBAC_DEBUG 07364 if(rsbac_debug_lists) 07365 printk(KERN_DEBUG "rsbac_list_get_all_data: list %s.\n", 07366 list->name); 07367 #endif 07368 */ 07369 rsbac_read_lock(&list->lock, &lock_flags); 07370 if(!list->info.data_size) 07371 { 07372 rsbac_read_unlock(&list->lock, &lock_flags); 07373 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 07374 return -RSBAC_EINVALIDREQUEST; 07375 } 07376 if(list->count) 07377 { 07378 item_size = list->info.data_size; 07379 item_offset = list->info.desc_size; 07380 buffer = rsbac_vmalloc(item_size * list->count); 07381 if(buffer) 07382 { 07383 item_p = list->head; 07384 while(item_p) 07385 { 07386 if( !item_p->max_age 07387 || (item_p->max_age > RSBAC_CURRENT_TIME) 07388 ) 07389 { 07390 memcpy(buffer + offset, 07391 ((char *) item_p) + sizeof(*item_p) + item_offset, 07392 item_size); 07393 offset += item_size; 07394 result++; 07395 } 07396 item_p = item_p->next; 07397 } 07398 *array_p = buffer; 07399 } 07400 else 07401 { 07402 result = -RSBAC_ENOMEM; 07403 } 07404 } 07405 rsbac_read_unlock(&list->lock, &lock_flags); 07406 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 07407 return result; 07408 } 07409 07410 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07411 EXPORT_SYMBOL(rsbac_list_lol_get_all_subdata); 07412 #endif 07413 long rsbac_list_lol_get_all_subdata(rsbac_list_handle_t handle, void * desc, void ** array_p) 07414 { 07415 struct rsbac_list_lol_reg_item_t * list; 07416 struct rsbac_list_lol_item_t * sublist; 07417 struct rsbac_list_item_t * item_p; 07418 char * buffer; 07419 u_long lock_flags, rlock_flags; 07420 u_long offset = 0; 07421 long result = 0; 07422 u_int item_size; 07423 u_int item_offset; 07424 07425 if(!handle) 07426 return -RSBAC_EINVALIDVALUE; 07427 if(!array_p) 07428 return -RSBAC_EINVALIDVALUE; 07429 if(!list_initialized) 07430 return -RSBAC_ENOTINITIALIZED; 07431 07432 list = (struct rsbac_list_lol_reg_item_t *) handle; 07433 if(list->self != list) 07434 return -RSBAC_EINVALIDVALUE; 07435 *array_p = NULL; 07436 07437 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07438 /* 07439 #ifdef CONFIG_RSBAC_DEBUG 07440 if(rsbac_debug_lists) 07441 printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n", 07442 list->name); 07443 #endif 07444 */ 07445 rsbac_read_lock(&list->lock, &lock_flags); 07446 if(!list->info.subdata_size) 07447 { 07448 rsbac_read_unlock(&list->lock, &lock_flags); 07449 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07450 return -RSBAC_EINVALIDREQUEST; 07451 } 07452 sublist = lookup_lol_item(list, desc); 07453 if(sublist && sublist->count) 07454 { 07455 item_size = list->info.subdata_size; 07456 item_offset = list->info.subdesc_size; 07457 buffer = rsbac_vmalloc(item_size * sublist->count); 07458 if(buffer) 07459 { 07460 item_p = sublist->head; 07461 while(item_p) 07462 { 07463 if( !item_p->max_age 07464 || (item_p->max_age > RSBAC_CURRENT_TIME) 07465 ) 07466 { 07467 memcpy(buffer + offset, 07468 ((char *) item_p) + sizeof(*item_p) + item_offset, 07469 item_size); 07470 offset += item_size; 07471 result++; 07472 } 07473 item_p = item_p->next; 07474 } 07475 *array_p = buffer; 07476 } 07477 else 07478 { 07479 result = -RSBAC_ENOMEM; 07480 } 07481 } 07482 rsbac_read_unlock(&list->lock, &lock_flags); 07483 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07484 return result; 07485 } 07486 07487 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07488 EXPORT_SYMBOL(rsbac_list_lol_get_all_data); 07489 #endif 07490 long rsbac_list_lol_get_all_data(rsbac_list_handle_t handle, void ** array_p) 07491 { 07492 struct rsbac_list_lol_reg_item_t * list; 07493 struct rsbac_list_lol_item_t * item_p; 07494 char * buffer; 07495 u_long lock_flags, rlock_flags; 07496 u_long offset = 0; 07497 long result = 0; 07498 u_int item_size; 07499 u_int item_offset; 07500 07501 if(!handle) 07502 return -RSBAC_EINVALIDVALUE; 07503 if(!array_p) 07504 return -RSBAC_EINVALIDVALUE; 07505 if(!list_initialized) 07506 return -RSBAC_ENOTINITIALIZED; 07507 07508 list = (struct rsbac_list_lol_reg_item_t *) handle; 07509 if(list->self != list) 07510 return -RSBAC_EINVALIDVALUE; 07511 *array_p = NULL; 07512 07513 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07514 /* 07515 #ifdef CONFIG_RSBAC_DEBUG 07516 if(rsbac_debug_lists) 07517 printk(KERN_DEBUG "rsbac_list_lol_get_all_desc: list %s.\n", 07518 list->name); 07519 #endif 07520 */ 07521 rsbac_read_lock(&list->lock, &lock_flags); 07522 if(!list->info.data_size) 07523 { 07524 rsbac_read_unlock(&list->lock, &lock_flags); 07525 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07526 return -RSBAC_EINVALIDREQUEST; 07527 } 07528 if(list->count) 07529 { 07530 item_size = list->info.data_size; 07531 item_offset = list->info.desc_size; 07532 buffer = rsbac_vmalloc(item_size * list->count); 07533 if(buffer) 07534 { 07535 item_p = list->head; 07536 while(item_p) 07537 { 07538 if( !item_p->max_age 07539 || (item_p->max_age > RSBAC_CURRENT_TIME) 07540 ) 07541 { 07542 memcpy(buffer + offset, 07543 ((char *) item_p) + sizeof(*item_p) + item_offset, 07544 item_size); 07545 offset += item_size; 07546 result++; 07547 } 07548 item_p = item_p->next; 07549 } 07550 *array_p = buffer; 07551 } 07552 else 07553 { 07554 result = -RSBAC_ENOMEM; 07555 } 07556 } 07557 rsbac_read_unlock(&list->lock, &lock_flags); 07558 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07559 return result; 07560 } 07561 07562 07563 /* Get item size */ 07564 07565 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07566 EXPORT_SYMBOL(rsbac_list_get_item_size); 07567 #endif 07568 int rsbac_list_get_item_size(rsbac_list_handle_t handle) 07569 { 07570 struct rsbac_list_reg_item_t * list; 07571 07572 if(!handle) 07573 return -RSBAC_EINVALIDVALUE; 07574 if(!list_initialized) 07575 return -RSBAC_ENOTINITIALIZED; 07576 07577 list = (struct rsbac_list_reg_item_t *) handle; 07578 if(list->self != list) 07579 return -RSBAC_EINVALIDVALUE; 07580 return list->info.desc_size + list->info.data_size; 07581 } 07582 07583 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07584 EXPORT_SYMBOL(rsbac_list_lol_get_subitem_size); 07585 #endif 07586 int rsbac_list_lol_get_subitem_size(rsbac_list_handle_t handle) 07587 { 07588 struct rsbac_list_lol_reg_item_t * list; 07589 07590 if(!handle) 07591 return -RSBAC_EINVALIDVALUE; 07592 if(!list_initialized) 07593 return -RSBAC_ENOTINITIALIZED; 07594 07595 list = (struct rsbac_list_lol_reg_item_t *) handle; 07596 if(list->self != list) 07597 return -RSBAC_EINVALIDVALUE; 07598 return list->info.subdesc_size + list->info.subdata_size; 07599 } 07600 07601 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07602 EXPORT_SYMBOL(rsbac_list_lol_get_item_size); 07603 #endif 07604 int rsbac_list_lol_get_item_size(rsbac_list_handle_t handle) 07605 { 07606 struct rsbac_list_lol_reg_item_t * list; 07607 07608 if(!handle) 07609 return -RSBAC_EINVALIDVALUE; 07610 if(!list_initialized) 07611 return -RSBAC_ENOTINITIALIZED; 07612 07613 list = (struct rsbac_list_lol_reg_item_t *) handle; 07614 if(list->self != list) 07615 return -RSBAC_EINVALIDVALUE; 07616 return list->info.desc_size + list->info.data_size; 07617 } 07618 07619 /* Get array of all items */ 07620 /* Returns number of items or negative error code */ 07621 /* If return value > 0, *array_p contains a pointer to a rsbac_vmalloc'd array of items, 07622 where desc and data are placed directly behind each other. 07623 If *array_p has been set (return value > 0), caller must call rsbac_vfree(*array_p) after use! */ 07624 07625 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07626 EXPORT_SYMBOL(rsbac_list_get_all_items_ttl); 07627 #endif 07628 long rsbac_list_get_all_items_ttl(rsbac_list_handle_t handle, 07629 void ** array_p, 07630 rsbac_time_t ** ttl_array_p) 07631 { 07632 struct rsbac_list_reg_item_t * list; 07633 struct rsbac_list_item_t * item_p; 07634 char * buffer; 07635 rsbac_time_t * ttl_p = NULL; 07636 u_long lock_flags, rlock_flags; 07637 u_long offset = 0; 07638 long result = 0; 07639 u_int item_size; 07640 07641 if(!handle) 07642 return -RSBAC_EINVALIDVALUE; 07643 if(!array_p) 07644 return -RSBAC_EINVALIDPOINTER; 07645 if(!list_initialized) 07646 return -RSBAC_ENOTINITIALIZED; 07647 07648 list = (struct rsbac_list_reg_item_t *) handle; 07649 if(list->self != list) 07650 return -RSBAC_EINVALIDVALUE; 07651 *array_p = NULL; 07652 07653 rsbac_read_lock(&reg_head.lock, &rlock_flags); 07654 /* 07655 #ifdef CONFIG_RSBAC_DEBUG 07656 if(rsbac_debug_lists) 07657 printk(KERN_DEBUG "rsbac_list_get_all_items: list %s.\n", 07658 list->name); 07659 #endif 07660 */ 07661 rsbac_read_lock(&list->lock, &lock_flags); 07662 if(list->count) 07663 { 07664 item_size = list->info.desc_size + list->info.data_size; 07665 buffer = rsbac_vmalloc(item_size * list->count); 07666 if(buffer) 07667 { 07668 if(ttl_array_p) 07669 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * list->count); 07670 item_p = list->head; 07671 while(item_p) 07672 { 07673 if( !item_p->max_age 07674 || (item_p->max_age > RSBAC_CURRENT_TIME) 07675 ) 07676 { 07677 memcpy(buffer + offset, 07678 ((char *) item_p) + sizeof(*item_p), 07679 item_size); 07680 if(ttl_p) 07681 { 07682 if(item_p->max_age) 07683 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME; 07684 else 07685 ttl_p[result] = 0; 07686 } 07687 offset += item_size; 07688 result++; 07689 } 07690 item_p = item_p->next; 07691 } 07692 *array_p = buffer; 07693 if(ttl_array_p) 07694 *ttl_array_p = ttl_p; 07695 } 07696 else 07697 { 07698 result = -RSBAC_ENOMEM; 07699 } 07700 } 07701 rsbac_read_unlock(&list->lock, &lock_flags); 07702 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 07703 return result; 07704 } 07705 07706 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07707 EXPORT_SYMBOL(rsbac_list_get_all_items); 07708 #endif 07709 long rsbac_list_get_all_items(rsbac_list_handle_t handle, void ** array_p) 07710 { 07711 return rsbac_list_get_all_items_ttl(handle, array_p, NULL); 07712 } 07713 07714 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07715 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems_ttl); 07716 #endif 07717 long rsbac_list_lol_get_all_subitems_ttl(rsbac_list_handle_t handle, 07718 void * desc, 07719 void ** array_p, 07720 rsbac_time_t ** ttl_array_p) 07721 { 07722 struct rsbac_list_lol_reg_item_t * list; 07723 struct rsbac_list_lol_item_t * sublist; 07724 struct rsbac_list_item_t * item_p; 07725 char * buffer; 07726 rsbac_time_t * ttl_p = NULL; 07727 u_long lock_flags, rlock_flags; 07728 u_long offset = 0; 07729 long result = 0; 07730 u_int item_size; 07731 07732 if(!handle) 07733 return -RSBAC_EINVALIDVALUE; 07734 if(!array_p) 07735 return -RSBAC_EINVALIDVALUE; 07736 if(!list_initialized) 07737 return -RSBAC_ENOTINITIALIZED; 07738 07739 list = (struct rsbac_list_lol_reg_item_t *) handle; 07740 if(list->self != list) 07741 return -RSBAC_EINVALIDVALUE; 07742 *array_p = NULL; 07743 07744 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07745 /* 07746 #ifdef CONFIG_RSBAC_DEBUG 07747 if(rsbac_debug_lists) 07748 printk(KERN_DEBUG "rsbac_list_lol_get_all_subitems: list %s.\n", 07749 list->name); 07750 #endif 07751 */ 07752 rsbac_read_lock(&list->lock, &lock_flags); 07753 sublist = lookup_lol_item(list, desc); 07754 if(sublist && sublist->count) 07755 { 07756 item_size = list->info.subdesc_size + list->info.subdata_size; 07757 buffer = rsbac_vmalloc(item_size * sublist->count); 07758 if(buffer) 07759 { 07760 if(ttl_array_p) 07761 ttl_p = rsbac_vmalloc(sizeof(**ttl_array_p) * sublist->count); 07762 item_p = sublist->head; 07763 while(item_p) 07764 { 07765 if( !item_p->max_age 07766 || (item_p->max_age > RSBAC_CURRENT_TIME) 07767 ) 07768 { 07769 memcpy(buffer + offset, 07770 ((char *) item_p) + sizeof(*item_p), 07771 item_size); 07772 if(ttl_p) 07773 { 07774 if(item_p->max_age) 07775 ttl_p[result] = item_p->max_age - RSBAC_CURRENT_TIME; 07776 else 07777 ttl_p[result] = 0; 07778 } 07779 offset += item_size; 07780 result++; 07781 } 07782 item_p = item_p->next; 07783 } 07784 *array_p = buffer; 07785 if(ttl_array_p) 07786 *ttl_array_p = ttl_p; 07787 } 07788 else 07789 { 07790 result = -RSBAC_ENOMEM; 07791 } 07792 } 07793 rsbac_read_unlock(&list->lock, &lock_flags); 07794 rsbac_read_unlock(&lol_reg_head.lock, &rlock_flags); 07795 return result; 07796 } 07797 07798 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07799 EXPORT_SYMBOL(rsbac_list_lol_get_all_subitems); 07800 #endif 07801 long rsbac_list_lol_get_all_subitems(rsbac_list_handle_t handle, void * desc, void ** array_p) 07802 { 07803 return rsbac_list_lol_get_all_subitems_ttl(handle, desc, array_p, NULL); 07804 } 07805 07806 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT) 07807 EXPORT_SYMBOL(rsbac_list_lol_get_all_items); 07808 #endif 07809 long rsbac_list_lol_get_all_items(rsbac_list_handle_t handle, void ** array_p) 07810 { 07811 struct rsbac_list_lol_reg_item_t * list; 07812 struct rsbac_list_lol_item_t * item_p; 07813 char * buffer; 07814 u_long lock_flags, rlock_flags; 07815 u_long offset = 0; 07816 long result = 0; 07817 u_int item_size; 07818 07819 if(!handle) 07820 return -RSBAC_EINVALIDVALUE; 07821 if(!array_p) 07822 return -RSBAC_EINVALIDVALUE; 07823 if(!list_initialized) 07824 return -RSBAC_ENOTINITIALIZED; 07825 07826 list = (struct rsbac_list_lol_reg_item_t *) handle; 07827 if(list->self != list) 07828 return -RSBAC_EINVALIDVALUE; 07829 *array_p = NULL; 07830 07831 rsbac_read_lock(&lol_reg_head.lock, &rlock_flags); 07832 /* 07833 #ifdef CONFIG_RSBAC_DEBUG 07834 if(rsbac_debug_lists) 07835 printk(KERN_DEBUG "rsbac_list_lol_get_all_items: list %s.\n", 07836 list->name); 07837 #endif 07838 */ 07839 rsbac_read_lock(&list->lock, &lock_flags); 07840 if(list->count) 07841 { 07842 item_size = list->info.desc_size + list->info.data_size; 07843 buffer = rsbac_vmalloc(item_size * list->count); 07844 if(buffer) 07845 { 07846 item_p = list->head; 07847 while(item_p) 07848 { 07849 if( !item_p->max_age 07850 || (item_p->max_age > RSBAC_CURRENT_TIME) 07851 ) 07852 { 07853 memcpy(buffer + offset, 07854 ((char *) item_p) + sizeof(*item_p), 07855 item_size); 07856 offset += item_size; 07857 result++; 07858 } 07859 item_p = item_p->next; 07860 } 07861 *array_p = buffer; 07862 } 07863 else 07864 { 07865 result = -RSBAC_ENOMEM; 07866 } 07867 } 07868 rsbac_read_unlock(&list->lock, &lock_flags); 07869 rsbac_read_unlock(&reg_head.lock, &rlock_flags); 07870 return result; 07871 } 07872 07873 07874 /* end of gen_lists.c */

Generated on Tue Aug 31 10:05:26 2004 for RSBAC by doxygen 1.3.8