gen_lists.c

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

Generated on Fri Jun 17 09:45:24 2005 for RSBAC by  doxygen 1.4.2