auth_data_structures.c

Go to the documentation of this file.
00001 /*************************************************** */
00002 /* Rule Set Based Access Control                     */
00003 /* Implementation of AUTH data structures            */
00004 /* Author and (c) 1999-2005: Amon Ott <ao@rsbac.org> */
00005 /*                                                   */
00006 /* Last modified: 11/Mar/2005                        */
00007 /*************************************************** */
00008 
00009 #include <linux/types.h>
00010 #include <linux/sched.h>
00011 #include <linux/mm.h>
00012 #include <linux/init.h>
00013 #include <linux/ext2_fs.h>
00014 #include <asm/uaccess.h>
00015 #include <rsbac/types.h>
00016 #include <rsbac/aci_data_structures.h>
00017 #include <rsbac/auth_data_structures.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/helpers.h>
00020 #include <rsbac/adf.h>
00021 #include <rsbac/aci.h>
00022 #include <rsbac/auth.h>
00023 #include <rsbac/lists.h>
00024 #include <rsbac/proc_fs.h>
00025 #include <rsbac/rkmem.h>
00026 #include <rsbac/getname.h>
00027 #include <linux/string.h>
00028 #include <linux/smp_lock.h>
00029 
00030 /************************************************************************** */
00031 /*                          Global Variables                                */
00032 /************************************************************************** */
00033 
00034 /* The following global variables are needed for access to PM data.         */
00035 
00036 static struct rsbac_auth_device_list_head_t      device_list_head;
00037 
00038 static rsbac_list_handle_t process_handle = NULL;
00039 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00040 static rsbac_list_handle_t process_eff_handle = NULL;
00041 static rsbac_list_handle_t process_fs_handle = NULL;
00042 #endif
00043 
00044 #ifdef CONFIG_RSBAC_AUTH_GROUP
00045 static rsbac_list_handle_t process_group_handle = NULL;
00046 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00047 static rsbac_list_handle_t process_group_eff_handle = NULL;
00048 static rsbac_list_handle_t process_group_fs_handle = NULL;
00049 #endif
00050 #endif
00051 
00052 /**************************************************/
00053 /*       Declarations of external functions       */
00054 /**************************************************/
00055 
00056 rsbac_boolean_t writable(struct super_block * sb_p);
00057 
00058 /**************************************************/
00059 /*       Declarations of internal functions       */
00060 /**************************************************/
00061 
00062 /************************************************* */
00063 /*               Internal Help functions           */
00064 /************************************************* */
00065 
00066 static inline int fd_hash(rsbac_inode_nr_t inode)
00067   {
00068     return(inode % RSBAC_AUTH_NR_CAP_FD_LISTS);
00069   }
00070 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00071 static inline int eff_fd_hash(rsbac_inode_nr_t inode)
00072   {
00073     return(inode % RSBAC_AUTH_NR_CAP_EFF_FD_LISTS);
00074   }
00075 static inline int fs_fd_hash(rsbac_inode_nr_t inode)
00076   {
00077     return(inode % RSBAC_AUTH_NR_CAP_FS_FD_LISTS);
00078   }
00079 #endif
00080 
00081 #ifdef CONFIG_RSBAC_AUTH_GROUP
00082 static inline int group_fd_hash(rsbac_inode_nr_t inode)
00083   {
00084     return(inode % RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS);
00085   }
00086 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00087 static inline int group_eff_fd_hash(rsbac_inode_nr_t inode)
00088   {
00089     return(inode % RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS);
00090   }
00091 static inline int group_fs_fd_hash(rsbac_inode_nr_t inode)
00092   {
00093     return(inode % RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS);
00094   }
00095 #endif
00096 #endif
00097 
00098 static int cap_compare(void * desc1, void * desc2)
00099   {
00100     struct rsbac_auth_cap_range_t * range1 = desc1;
00101     struct rsbac_auth_cap_range_t * range2 = desc2;
00102 
00103     if(!desc1 || !desc2)
00104       return 0;
00105     if(range1->first < range2->first)
00106       return -1;
00107     if(range1->first > range2->first)
00108       return 1;
00109     if(range1->last < range2->last)
00110       return -1;
00111     if(range1->last > range2->last)
00112       return 1;
00113     return 0;
00114   };
00115 
00116 static int single_cap_compare(void * desc1, void * desc2)
00117   {
00118     struct rsbac_auth_cap_range_t * range = desc1;
00119     rsbac_uid_t * uid = desc2;
00120 
00121     if(!desc1 || !desc2)
00122       return 0;
00123     if(   (*uid < range->first)
00124        || (*uid > range->last)
00125       )
00126       return 1;
00127     else
00128       return 0;
00129   };
00130 
00131 /* auth_register_fd_lists() */
00132 /* register fd ACL lists for device */
00133 
00134 static int auth_register_fd_lists(struct rsbac_auth_device_list_item_t * device_p,
00135                                   kdev_t kdev)
00136   {
00137     char                          * name;
00138     int                             err = 0;
00139     int                             tmperr;
00140     char                            number[10];
00141     u_int                           file_no;
00142     struct rsbac_list_lol_info_t lol_info;
00143 
00144     if(!device_p)
00145       return(-RSBAC_EINVALIDPOINTER);
00146     name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00147     if(!name)
00148       return -RSBAC_ENOMEM;
00149 
00150     /* register all the AUTH lists of lists */
00151     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FD_LISTS; file_no++)
00152       {
00153         /* construct name from base name + number */
00154         strcpy(name, RSBAC_AUTH_FD_FILENAME);
00155         strcat(name, inttostr(number,file_no) );
00156 
00157         lol_info.version = RSBAC_AUTH_FD_LIST_VERSION;
00158         lol_info.key = RSBAC_AUTH_LIST_KEY;
00159         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00160         lol_info.data_size = 0;
00161         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00162         lol_info.subdata_size = 0; /* rights */
00163         lol_info.max_age = 0;
00164         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00165                                          &(device_p->handles[file_no]),
00166                                          &lol_info,
00167                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00168                                          rsbac_list_compare_u32,
00169                                          cap_compare,
00170                                          NULL,
00171                                          NULL,
00172                                          NULL,
00173                                          NULL,
00174                                          name,
00175                                          kdev);
00176         if(tmperr)
00177           {
00178             char * tmp;
00179 
00180             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00181             if(tmp)
00182               {
00183                 printk(KERN_WARNING
00184                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00185                        name,
00186                        RSBAC_MAJOR(kdev),
00187                        RSBAC_MINOR(kdev),
00188                        get_error_name(tmp, tmperr));
00189                 rsbac_kfree(tmp);
00190               }
00191             err = tmperr;
00192           }
00193       }
00194 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00195     /* register all the AUTH DAC lists of lists */
00196     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; file_no++)
00197       {
00198         /* construct name from base name + number */
00199         strcpy(name, RSBAC_AUTH_FD_EFF_FILENAME);
00200         strcat(name, inttostr(number,file_no) );
00201 
00202         lol_info.version = RSBAC_AUTH_FD_EFF_LIST_VERSION;
00203         lol_info.key = RSBAC_AUTH_LIST_KEY;
00204         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00205         lol_info.data_size = 0;
00206         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00207         lol_info.subdata_size = 0; /* rights */
00208         lol_info.max_age = 0;
00209         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00210                                          &(device_p->eff_handles[file_no]),
00211                                          &lol_info,
00212                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00213                                          rsbac_list_compare_u32,
00214                                          cap_compare,
00215                                          NULL,
00216                                          NULL,
00217                                          NULL,
00218                                          NULL,
00219                                          name,
00220                                          kdev);
00221         if(tmperr)
00222           {
00223             char * tmp;
00224 
00225             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00226             if(tmp)
00227               {
00228                 printk(KERN_WARNING
00229                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00230                        name,
00231                        RSBAC_MAJOR(kdev),
00232                        RSBAC_MINOR(kdev),
00233                        get_error_name(tmp, tmperr));
00234                 rsbac_kfree(tmp);
00235               }
00236             err = tmperr;
00237           }
00238       }
00239     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; file_no++)
00240       {
00241         /* construct name from base name + number */
00242         strcpy(name, RSBAC_AUTH_FD_FS_FILENAME);
00243         strcat(name, inttostr(number,file_no) );
00244 
00245         lol_info.version = RSBAC_AUTH_FD_FS_LIST_VERSION;
00246         lol_info.key = RSBAC_AUTH_LIST_KEY;
00247         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00248         lol_info.data_size = 0;
00249         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00250         lol_info.subdata_size = 0; /* rights */
00251         lol_info.max_age = 0;
00252         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00253                                          &(device_p->fs_handles[file_no]),
00254                                          &lol_info,
00255                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00256                                          rsbac_list_compare_u32,
00257                                          cap_compare,
00258                                          NULL,
00259                                          NULL,
00260                                          NULL,
00261                                          NULL,
00262                                          name,
00263                                          kdev);
00264         if(tmperr)
00265           {
00266             char * tmp;
00267 
00268             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00269             if(tmp)
00270               {
00271                 printk(KERN_WARNING
00272                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00273                        name,
00274                        RSBAC_MAJOR(kdev),
00275                        RSBAC_MINOR(kdev),
00276                        get_error_name(tmp, tmperr));
00277                 rsbac_kfree(tmp);
00278               }
00279             err = tmperr;
00280           }
00281       }
00282 #endif
00283 
00284 #ifdef CONFIG_RSBAC_AUTH_GROUP
00285     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; file_no++)
00286       {
00287         /* construct name from base name + number */
00288         strcpy(name, RSBAC_AUTH_FD_GROUP_FILENAME);
00289         strcat(name, inttostr(number,file_no) );
00290 
00291         lol_info.version = RSBAC_AUTH_FD_GROUP_LIST_VERSION;
00292         lol_info.key = RSBAC_AUTH_LIST_KEY;
00293         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00294         lol_info.data_size = 0;
00295         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00296         lol_info.subdata_size = 0; /* rights */
00297         lol_info.max_age = 0;
00298         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00299                                          &(device_p->group_handles[file_no]),
00300                                          &lol_info,
00301                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00302                                          rsbac_list_compare_u32,
00303                                          cap_compare,
00304                                          NULL,
00305                                          NULL,
00306                                          NULL,
00307                                          NULL,
00308                                          name,
00309                                          kdev);
00310         if(tmperr)
00311           {
00312             char * tmp;
00313 
00314             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00315             if(tmp)
00316               {
00317                 printk(KERN_WARNING
00318                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00319                        name,
00320                        RSBAC_MAJOR(kdev),
00321                        RSBAC_MINOR(kdev),
00322                        get_error_name(tmp, tmperr));
00323                 rsbac_kfree(tmp);
00324               }
00325             err = tmperr;
00326           }
00327       }
00328 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00329     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; file_no++)
00330       {
00331         /* construct name from base name + number */
00332         strcpy(name, RSBAC_AUTH_FD_GROUP_EFF_FILENAME);
00333         strcat(name, inttostr(number,file_no) );
00334 
00335         lol_info.version = RSBAC_AUTH_FD_GROUP_EFF_LIST_VERSION;
00336         lol_info.key = RSBAC_AUTH_LIST_KEY;
00337         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00338         lol_info.data_size = 0;
00339         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00340         lol_info.subdata_size = 0; /* rights */
00341         lol_info.max_age = 0;
00342         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00343                                          &(device_p->group_eff_handles[file_no]),
00344                                          &lol_info,
00345                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00346                                          rsbac_list_compare_u32,
00347                                          cap_compare,
00348                                          NULL,
00349                                          NULL,
00350                                          NULL,
00351                                          NULL,
00352                                          name,
00353                                          kdev);
00354         if(tmperr)
00355           {
00356             char * tmp;
00357 
00358             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00359             if(tmp)
00360               {
00361                 printk(KERN_WARNING
00362                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00363                        name,
00364                        RSBAC_MAJOR(kdev),
00365                        RSBAC_MINOR(kdev),
00366                        get_error_name(tmp, tmperr));
00367                 rsbac_kfree(tmp);
00368               }
00369             err = tmperr;
00370           }
00371       }
00372     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; file_no++)
00373       {
00374         /* construct name from base name + number */
00375         strcpy(name, RSBAC_AUTH_FD_GROUP_FS_FILENAME);
00376         strcat(name, inttostr(number,file_no) );
00377 
00378         lol_info.version = RSBAC_AUTH_FD_GROUP_FS_LIST_VERSION;
00379         lol_info.key = RSBAC_AUTH_LIST_KEY;
00380         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00381         lol_info.data_size = 0;
00382         lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
00383         lol_info.subdata_size = 0; /* rights */
00384         lol_info.max_age = 0;
00385         tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00386                                          &(device_p->group_fs_handles[file_no]),
00387                                          &lol_info,
00388                                          RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA,
00389                                          rsbac_list_compare_u32,
00390                                          cap_compare,
00391                                          NULL,
00392                                          NULL,
00393                                          NULL,
00394                                          NULL,
00395                                          name,
00396                                          kdev);
00397         if(tmperr)
00398           {
00399             char * tmp;
00400 
00401             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00402             if(tmp)
00403               {
00404                 printk(KERN_WARNING
00405                        "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00406                        name,
00407                        RSBAC_MAJOR(kdev),
00408                        RSBAC_MINOR(kdev),
00409                        get_error_name(tmp, tmperr));
00410                 rsbac_kfree(tmp);
00411               }
00412             err = tmperr;
00413           }
00414       }
00415 #endif
00416 #endif /* AUTH_GROUP */
00417 
00418     return err;
00419   }
00420 
00421 /* auth_detach_fd_lists() */
00422 /* detach from fd AUTH lists for device */
00423 
00424 static int auth_detach_fd_lists(struct rsbac_auth_device_list_item_t * device_p)
00425   {
00426     char                          * name;
00427     int                             err = 0;
00428     int                             tmperr;
00429     char                            number[10];
00430     u_int                           file_no;
00431 
00432     if(!device_p)
00433       return(-RSBAC_EINVALIDPOINTER);
00434     name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00435     if(!name)
00436       return -RSBAC_ENOMEM;
00437 
00438     /* detach all the AUTH lists of lists */
00439     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FD_LISTS; file_no++)
00440       {
00441         /* construct name from base name + number */
00442         strcpy(name, RSBAC_AUTH_FD_FILENAME);
00443         strcat(name, inttostr(number,file_no) );
00444 
00445         tmperr = rsbac_list_lol_detach(&device_p->handles[file_no],
00446                                        RSBAC_AUTH_LIST_KEY);
00447         if(tmperr)
00448           {
00449             char * tmp;
00450 
00451             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00452             if(tmp)
00453               {
00454                 printk(KERN_WARNING
00455                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00456                        name,
00457                        RSBAC_MAJOR(device_p->id),
00458                        RSBAC_MINOR(device_p->id),
00459                        get_error_name(tmp, tmperr));
00460                 rsbac_kfree(tmp);
00461               }
00462             err = tmperr;
00463           }
00464       }
00465 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00466     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; file_no++)
00467       {
00468         /* construct name from base name + number */
00469         strcpy(name, RSBAC_AUTH_FD_EFF_FILENAME);
00470         strcat(name, inttostr(number,file_no) );
00471 
00472         tmperr = rsbac_list_lol_detach(&device_p->eff_handles[file_no],
00473                                        RSBAC_AUTH_LIST_KEY);
00474         if(tmperr)
00475           {
00476             char * tmp;
00477 
00478             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00479             if(tmp)
00480               {
00481                 printk(KERN_WARNING
00482                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00483                        name,
00484                        RSBAC_MAJOR(device_p->id),
00485                        RSBAC_MINOR(device_p->id),
00486                        get_error_name(tmp, tmperr));
00487                 rsbac_kfree(tmp);
00488               }
00489             err = tmperr;
00490           }
00491       }
00492     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; file_no++)
00493       {
00494         /* construct name from base name + number */
00495         strcpy(name, RSBAC_AUTH_FD_FS_FILENAME);
00496         strcat(name, inttostr(number,file_no) );
00497 
00498         tmperr = rsbac_list_lol_detach(&device_p->fs_handles[file_no],
00499                                        RSBAC_AUTH_LIST_KEY);
00500         if(tmperr)
00501           {
00502             char * tmp;
00503 
00504             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00505             if(tmp)
00506               {
00507                 printk(KERN_WARNING
00508                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00509                        name,
00510                        RSBAC_MAJOR(device_p->id),
00511                        RSBAC_MINOR(device_p->id),
00512                        get_error_name(tmp, tmperr));
00513                 rsbac_kfree(tmp);
00514               }
00515             err = tmperr;
00516           }
00517       }
00518 #endif
00519 
00520 #ifdef CONFIG_RSBAC_AUTH_GROUP
00521     /* detach all the AUTH lists of lists */
00522     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; file_no++)
00523       {
00524         /* construct name from base name + number */
00525         strcpy(name, RSBAC_AUTH_FD_GROUP_FILENAME);
00526         strcat(name, inttostr(number,file_no) );
00527 
00528         tmperr = rsbac_list_lol_detach(&device_p->group_handles[file_no],
00529                                        RSBAC_AUTH_LIST_KEY);
00530         if(tmperr)
00531           {
00532             char * tmp;
00533 
00534             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00535             if(tmp)
00536               {
00537                 printk(KERN_WARNING
00538                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00539                        name,
00540                        RSBAC_MAJOR(device_p->id),
00541                        RSBAC_MINOR(device_p->id),
00542                        get_error_name(tmp, tmperr));
00543                 rsbac_kfree(tmp);
00544               }
00545             err = tmperr;
00546           }
00547       }
00548 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00549     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; file_no++)
00550       {
00551         /* construct name from base name + number */
00552         strcpy(name, RSBAC_AUTH_FD_GROUP_EFF_FILENAME);
00553         strcat(name, inttostr(number,file_no) );
00554 
00555         tmperr = rsbac_list_lol_detach(&device_p->group_eff_handles[file_no],
00556                                        RSBAC_AUTH_LIST_KEY);
00557         if(tmperr)
00558           {
00559             char * tmp;
00560 
00561             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00562             if(tmp)
00563               {
00564                 printk(KERN_WARNING
00565                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00566                        name,
00567                        RSBAC_MAJOR(device_p->id),
00568                        RSBAC_MINOR(device_p->id),
00569                        get_error_name(tmp, tmperr));
00570                 rsbac_kfree(tmp);
00571               }
00572             err = tmperr;
00573           }
00574       }
00575     for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; file_no++)
00576       {
00577         /* construct name from base name + number */
00578         strcpy(name, RSBAC_AUTH_FD_GROUP_FS_FILENAME);
00579         strcat(name, inttostr(number,file_no) );
00580 
00581         tmperr = rsbac_list_lol_detach(&device_p->group_fs_handles[file_no],
00582                                        RSBAC_AUTH_LIST_KEY);
00583         if(tmperr)
00584           {
00585             char * tmp;
00586 
00587             tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00588             if(tmp)
00589               {
00590                 printk(KERN_WARNING
00591                        "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00592                        name,
00593                        RSBAC_MAJOR(device_p->id),
00594                        RSBAC_MINOR(device_p->id),
00595                        get_error_name(tmp, tmperr));
00596                 rsbac_kfree(tmp);
00597               }
00598             err = tmperr;
00599           }
00600       }
00601 #endif
00602 #endif /* AUTH_GROUP */
00603 
00604     return err;
00605   }
00606 
00607 /************************************************************************** */
00608 /* The lookup functions return NULL, if the item is not found, and a        */
00609 /* pointer to the item otherwise.                                           */
00610 
00611 /* first the device item lookup */
00612 static struct rsbac_auth_device_list_item_t * lookup_device(kdev_t kdev)
00613     {
00614       struct rsbac_auth_device_list_item_t  * curr = device_list_head.curr;
00615       
00616       /* if there is no current item or it is not the right one, search... */
00617       if(! (   curr
00618             && (RSBAC_MAJOR(curr->id) == RSBAC_MAJOR(kdev))
00619             && (RSBAC_MINOR(curr->id) == RSBAC_MINOR(kdev))
00620            )
00621         )
00622         {
00623           curr = device_list_head.head;
00624           while(   curr
00625                 && (   (RSBAC_MAJOR(curr->id) != RSBAC_MAJOR(kdev))
00626                     || (RSBAC_MINOR(curr->id) != RSBAC_MINOR(kdev))
00627                    )
00628                )
00629             {
00630               curr = curr->next;
00631             }
00632           if (curr)
00633             device_list_head.curr=curr;
00634         }
00635       /* it is the current item -> return it */
00636         return (curr);
00637     };
00638 
00639 /************************************************************************** */
00640 /* The add_item() functions add an item to the list, set head.curr to it,   */
00641 /* and return a pointer to the item.                                        */
00642 /* These functions will NOT check, if there is already an item under the    */
00643 /* same ID! If this happens, the lookup functions will return the old item! */
00644 /* All list manipulation is protected by rw-spinlocks to prevent inconsistency */
00645 /* and undefined behaviour in other concurrent functions.                   */
00646 
00647 /* Create a device item without adding to list. No locking needed. */
00648 static struct rsbac_auth_device_list_item_t 
00649           * create_device_item(kdev_t kdev)
00650     {
00651       struct rsbac_auth_device_list_item_t * new_item_p;
00652       int i;
00653 
00654       /* allocate memory for new device, return NULL, if failed */
00655       if ( !(new_item_p = (struct rsbac_auth_device_list_item_t *)
00656                     rsbac_kmalloc(sizeof(*new_item_p)) ) )
00657          return(NULL);
00658          
00659       new_item_p->id = kdev;
00660       new_item_p->mount_count = 1;
00661 
00662       /* init file/dir sublists */
00663       for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS ; i++)
00664         new_item_p->handles[i] = NULL;
00665 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00666       for(i=0 ; i < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS ; i++)
00667         new_item_p->eff_handles[i] = NULL;
00668       for(i=0 ; i < RSBAC_AUTH_NR_CAP_FS_FD_LISTS ; i++)
00669         new_item_p->fs_handles[i] = NULL;
00670 #endif
00671 #ifdef CONFIG_RSBAC_AUTH_GROUP
00672       for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS ; i++)
00673         new_item_p->group_handles[i] = NULL;
00674 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00675       for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS ; i++)
00676         new_item_p->group_eff_handles[i] = NULL;
00677       for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS ; i++)
00678         new_item_p->group_fs_handles[i] = NULL;
00679 #endif
00680 #endif
00681       return(new_item_p);
00682     };
00683 
00684 /* Add an existing device item to list. Locking needed. */
00685 static struct rsbac_auth_device_list_item_t 
00686           * add_device_item(struct rsbac_auth_device_list_item_t * device_p)
00687     {
00688       if (!device_p)
00689          return(NULL);
00690          
00691       /* add new device to device list */
00692       if (!device_list_head.head)
00693         { /* first device */
00694           device_list_head.head=device_p;
00695           device_list_head.tail=device_p;
00696           device_list_head.curr=device_p;
00697           device_list_head.count=1;
00698           device_p->prev=NULL;
00699           device_p->next=NULL;
00700         }  
00701       else
00702         { /* there is another device -> hang to tail */
00703           device_p->prev=device_list_head.tail;
00704           device_p->next=NULL;
00705           device_list_head.tail->next=device_p;
00706           device_list_head.tail=device_p;
00707           device_list_head.curr=device_p;
00708           device_list_head.count++;
00709         };
00710       return(device_p);
00711     };
00712 
00713 /************************************************************************** */
00714 /* The remove_item() functions remove an item from the list. If this item   */
00715 /* is head, tail or curr, these pointers are set accordingly.               */
00716 /* To speed up removing several subsequent items, curr is set to the next   */
00717 /* item, if possible.                                                       */
00718 /* If the item is not found, nothing is done.                               */
00719 
00720 static void clear_device_item(struct rsbac_auth_device_list_item_t * item_p)
00721     {
00722       if(!item_p)
00723         return;
00724 
00725       /* First deregister lists... */
00726       auth_detach_fd_lists(item_p);
00727       /* OK, lets remove the device item itself */
00728       rsbac_kfree(item_p);
00729     }; /* end of clear_device_item() */
00730 
00731 static void remove_device_item(kdev_t kdev)
00732     {
00733       struct rsbac_auth_device_list_item_t    * item_p;
00734 
00735       /* first we must locate the item. */
00736       if ( (item_p = lookup_device(kdev)) )
00737         { /* ok, item was found */
00738           if (device_list_head.head == item_p)  
00739              { /* item is head */
00740                if (device_list_head.tail == item_p)
00741                  { /* item is head and tail = only item -> list will be empty*/
00742                    device_list_head.head = NULL;
00743                    device_list_head.tail = NULL;
00744                  }
00745                else
00746                  { /* item is head, but not tail -> next item becomes head */
00747                    item_p->next->prev = NULL;
00748                    device_list_head.head = item_p->next;
00749                  };
00750              }
00751           else
00752              { /* item is not head */
00753                if (device_list_head.tail == item_p)
00754                  { /*item is not head, but tail -> previous item becomes tail*/
00755                    item_p->prev->next = NULL;
00756                    device_list_head.tail = item_p->prev;
00757                  }
00758                else
00759                  { /* item is neither head nor tail -> item is cut out */
00760                    item_p->prev->next = item_p->next;
00761                    item_p->next->prev = item_p->prev;
00762                  };
00763              };
00764              
00765           /* curr is no longer valid -> reset.                              */
00766           device_list_head.curr=NULL;
00767           /* adjust counter */
00768           device_list_head.count--;
00769           
00770           /* now we can remove the item from memory. This means cleaning up */
00771           /* everything below. */
00772           clear_device_item(item_p);
00773         };  /* end of if: item was found */
00774 
00775     }; /* end of remove_device_item() */
00776 
00777 /************************************************************************** */
00778 /* The copy_fp_cap_set_item() function copies a file cap set to a process   */
00779 /* cap set */
00780 
00781 static int copy_fp_cap_set_item(struct rsbac_auth_device_list_item_t * device_p,
00782                                 rsbac_auth_file_t    file,
00783                                 rsbac_pid_t pid)
00784     {
00785       struct rsbac_auth_cap_range_t  * cap_item_p;
00786       rsbac_time_t * ttl_p;
00787       int i;
00788       long count;
00789       enum  rsbac_target_t target = T_FILE;
00790       union rsbac_target_id_t tid;
00791 
00792       rsbac_list_lol_remove(process_handle, &pid);
00793       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handles[fd_hash(file.inode)],
00794                                                  &file.inode,
00795                                                  (void **) &cap_item_p,
00796                                                  &ttl_p);
00797       if(   !count
00798          || (count == -RSBAC_ENOTFOUND)
00799         )
00800         {
00801           tid.file = file;
00802           if(!rsbac_get_parent(target, tid, &target, &tid))
00803             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handles[fd_hash(tid.file.inode)],
00804                                                        &tid.file.inode,
00805                                                        (void **) &cap_item_p,
00806                                                        &ttl_p);
00807         }
00808       if(count > 0)
00809         {
00810           for(i=0; i < count ; i++)
00811             {
00812               rsbac_list_lol_subadd_ttl(process_handle,
00813                                         ttl_p[i],
00814                                         &pid,
00815                                         &cap_item_p[i],
00816                                         NULL);
00817             }
00818           rsbac_vfree(cap_item_p);
00819           rsbac_vfree(ttl_p);
00820         }
00821       else
00822         {
00823           if(   (count < 0)
00824              && (count != -RSBAC_ENOTFOUND)
00825             )
00826             return count;
00827         }
00828 
00829 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
00830       rsbac_list_lol_remove(process_eff_handle, &pid);
00831       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->eff_handles[eff_fd_hash(file.inode)],
00832                                                  &file.inode,
00833                                                  (void **) &cap_item_p,
00834                                                  &ttl_p);
00835       if(   !count
00836          || (count == -RSBAC_ENOTFOUND)
00837         )
00838         {
00839           tid.file = file;
00840           if(!rsbac_get_parent(target, tid, &target, &tid))
00841             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->eff_handles[eff_fd_hash(tid.file.inode)],
00842                                                        &tid.file.inode,
00843                                                        (void **) &cap_item_p,
00844                                                        &ttl_p);
00845         }
00846       if(count > 0)
00847         {
00848           for(i=0; i < count ; i++)
00849             {
00850               rsbac_list_lol_subadd_ttl(process_eff_handle,
00851                                         ttl_p[i],
00852                                         &pid,
00853                                         &cap_item_p[i],
00854                                         NULL);
00855             }
00856           rsbac_vfree(cap_item_p);
00857           rsbac_vfree(ttl_p);
00858         }
00859       else
00860         {
00861           if(   (count < 0)
00862              && (count != -RSBAC_ENOTFOUND)
00863             )
00864             return count;
00865         }
00866       rsbac_list_lol_remove(process_fs_handle, &pid);
00867       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->fs_handles[fs_fd_hash(file.inode)],
00868                                                  &file.inode,
00869                                                  (void **) &cap_item_p,
00870                                                  &ttl_p);
00871       if(   !count
00872          || (count == -RSBAC_ENOTFOUND)
00873         )
00874         {
00875           tid.file = file;
00876           if(!rsbac_get_parent(target, tid, &target, &tid))
00877             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->fs_handles[fs_fd_hash(tid.file.inode)],
00878                                                        &tid.file.inode,
00879                                                        (void **) &cap_item_p,
00880                                                        &ttl_p);
00881         }
00882       if(count > 0)
00883         {
00884           for(i=0; i < count ; i++)
00885             {
00886               rsbac_list_lol_subadd_ttl(process_fs_handle,
00887                                         ttl_p[i],
00888                                         &pid,
00889                                         &cap_item_p[i],
00890                                         NULL);
00891             }
00892           rsbac_vfree(cap_item_p);
00893           rsbac_vfree(ttl_p);
00894         }
00895       else
00896         {
00897           if(   (count < 0)
00898              && (count != -RSBAC_ENOTFOUND)
00899             )
00900             return count;
00901         }
00902 #endif
00903 
00904 #ifdef CONFIG_RSBAC_AUTH_GROUP
00905       rsbac_list_lol_remove(process_group_handle, &pid);
00906       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_handles[group_fd_hash(file.inode)],
00907                                                  &file.inode,
00908                                                  (void **) &cap_item_p,
00909                                                  &ttl_p);
00910       if(   !count
00911          || (count == -RSBAC_ENOTFOUND)
00912         )
00913         {
00914           tid.file = file;
00915           if(!rsbac_get_parent(target, tid, &target, &tid))
00916             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_handles[group_fd_hash(tid.file.inode)],
00917                                                        &tid.file.inode,
00918                                                        (void **) &cap_item_p,
00919                                                        &ttl_p);
00920         }
00921       if(count > 0)
00922         {
00923           for(i=0; i < count ; i++)
00924             {
00925               rsbac_list_lol_subadd_ttl(process_group_handle,
00926                                         ttl_p[i],
00927                                         &pid,
00928                                         &cap_item_p[i],
00929                                         NULL);
00930             }
00931           rsbac_vfree(cap_item_p);
00932           rsbac_vfree(ttl_p);
00933         }
00934       else
00935         {
00936           if(   (count < 0)
00937              && (count != -RSBAC_ENOTFOUND)
00938             )
00939             return count;
00940         }
00941 
00942 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
00943       rsbac_list_lol_remove(process_group_eff_handle, &pid);
00944       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_eff_handles[group_eff_fd_hash(file.inode)],
00945                                                  &file.inode,
00946                                                  (void **) &cap_item_p,
00947                                                  &ttl_p);
00948       if(   !count
00949          || (count == -RSBAC_ENOTFOUND)
00950         )
00951         {
00952           tid.file = file;
00953           if(!rsbac_get_parent(target, tid, &target, &tid))
00954             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_eff_handles[group_eff_fd_hash(tid.file.inode)],
00955                                                        &tid.file.inode,
00956                                                        (void **) &cap_item_p,
00957                                                        &ttl_p);
00958         }
00959       if(count > 0)
00960         {
00961           for(i=0; i < count ; i++)
00962             {
00963               rsbac_list_lol_subadd_ttl(process_group_eff_handle,
00964                                         ttl_p[i],
00965                                         &pid,
00966                                         &cap_item_p[i],
00967                                         NULL);
00968             }
00969           rsbac_vfree(cap_item_p);
00970           rsbac_vfree(ttl_p);
00971         }
00972       else
00973         {
00974           if(   (count < 0)
00975              && (count != -RSBAC_ENOTFOUND)
00976             )
00977             return count;
00978         }
00979       rsbac_list_lol_remove(process_group_fs_handle, &pid);
00980       count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_fs_handles[group_fs_fd_hash(file.inode)],
00981                                                  &file.inode,
00982                                                  (void **) &cap_item_p,
00983                                                  &ttl_p);
00984       if(   !count
00985          || (count == -RSBAC_ENOTFOUND)
00986         )
00987         {
00988           tid.file = file;
00989           if(!rsbac_get_parent(target, tid, &target, &tid))
00990             count = rsbac_list_lol_get_all_subdesc_ttl(device_p->group_fs_handles[group_fs_fd_hash(tid.file.inode)],
00991                                                        &tid.file.inode,
00992                                                        (void **) &cap_item_p,
00993                                                        &ttl_p);
00994         }
00995       if(count > 0)
00996         {
00997           for(i=0; i < count ; i++)
00998             {
00999               rsbac_list_lol_subadd_ttl(process_group_fs_handle,
01000                                         ttl_p[i],
01001                                         &pid,
01002                                         &cap_item_p[i],
01003                                         NULL);
01004             }
01005           rsbac_vfree(cap_item_p);
01006           rsbac_vfree(ttl_p);
01007         }
01008       else
01009         {
01010           if(   (count < 0)
01011              && (count != -RSBAC_ENOTFOUND)
01012             )
01013             return count;
01014         }
01015 #endif
01016 #endif /* AUTH_GROUP */
01017 
01018       return 0;
01019     }; /* end of copy_fp_cap_set_item() */
01020 
01021 /************************************************************************** */
01022 /* The copy_pp_cap_set_item() function copies a process cap set to another  */
01023 
01024 static int copy_pp_cap_set_item_handle(rsbac_list_handle_t handle,
01025                                        rsbac_pid_t old_pid,
01026                                        rsbac_pid_t new_pid)
01027     {
01028       struct rsbac_auth_cap_range_t  * cap_item_p;
01029       rsbac_time_t * ttl_p;
01030       int i;
01031       long count;
01032 
01033       rsbac_list_lol_remove(handle, &new_pid);
01034       count = rsbac_list_lol_get_all_subdesc_ttl(handle,
01035                                                  &old_pid,
01036                                                  (void **) &cap_item_p,
01037                                                  &ttl_p);
01038       if(count > 0)
01039         {
01040           for(i=0; i < count ; i++)
01041             {
01042               rsbac_list_lol_subadd_ttl(handle,
01043                                         ttl_p[i],
01044                                         &new_pid,
01045                                         &cap_item_p[i],
01046                                         NULL);
01047             }
01048           rsbac_vfree(cap_item_p);
01049           rsbac_vfree(ttl_p);
01050         }
01051       else
01052         {
01053           if(count < 0)
01054             return count;
01055         }
01056       return 0;
01057     }
01058 
01059 static int copy_pp_cap_set_item(rsbac_pid_t old_pid,
01060                                 rsbac_pid_t new_pid)
01061     {
01062       int res;
01063 
01064       res = copy_pp_cap_set_item_handle(process_handle, old_pid, new_pid);
01065 
01066 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01067       if(res)
01068         return res;
01069       res = copy_pp_cap_set_item_handle(process_eff_handle, old_pid, new_pid);
01070       if(res)
01071         return res;
01072       res = copy_pp_cap_set_item_handle(process_fs_handle, old_pid, new_pid);
01073 #endif
01074 
01075 #ifdef CONFIG_RSBAC_AUTH_GROUP
01076       res = copy_pp_cap_set_item_handle(process_group_handle, old_pid, new_pid);
01077 
01078 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01079       if(res)
01080         return res;
01081       res = copy_pp_cap_set_item_handle(process_group_eff_handle, old_pid, new_pid);
01082       if(res)
01083         return res;
01084       res = copy_pp_cap_set_item_handle(process_group_fs_handle, old_pid, new_pid);
01085 #endif
01086 #endif
01087 
01088       return(res);
01089     }; /* end of copy_pp_cap_set_item() */
01090 
01091 /************************************************* */
01092 /*               proc functions                    */
01093 /************************************************* */
01094 
01095 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
01096 static int
01097 auth_devices_proc_info(char *buffer, char **start, off_t offset, int length)
01098 {
01099   int len = 0;
01100   off_t pos   = 0;
01101   off_t begin = 0;
01102   struct rsbac_auth_device_list_item_t   * device_p;
01103   u_long dflags;
01104 
01105   if (!rsbac_is_initialized()) return (-ENOSYS);
01106 
01107   len += sprintf(buffer, "%u RSBAC AUTH Devices\n--------------------\n",
01108                  device_list_head.count);
01109 
01110   /* wait for read access to device_list_head */
01111   rsbac_read_lock(&device_list_head.lock, &dflags);
01112   /* OK, go on */
01113   for (device_p = device_list_head.head; device_p; device_p = device_p->next)
01114     {
01115       len += sprintf(buffer + len, "%02u:%02u with mount_count = %u\n",
01116                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id),
01117                      device_p->mount_count);
01118       pos = begin + len;
01119       if (pos < offset)
01120         {
01121           len = 0;
01122           begin = pos;
01123         }
01124       if (pos > offset+length)
01125         break;
01126     }
01127   
01128   /* free access to device_list_head */
01129   rsbac_read_unlock(&device_list_head.lock, &dflags);
01130 
01131   *start = buffer + (offset - begin);
01132   len -= (offset - begin);
01133   
01134   if (len > length)
01135     len = length;
01136   return len;
01137 }
01138 
01139 static int
01140 stats_auth_proc_info(char *buffer, char **start, off_t offset, int length)
01141 {
01142     u_int len = 0;
01143     off_t pos   = 0;
01144     off_t begin = 0;
01145 
01146     u_int                                     cap_set_count = 0;
01147     u_int                                     member_count = 0;
01148     u_long dflags;
01149     struct rsbac_auth_device_list_item_t   * device_p;
01150     int i;
01151 
01152     union rsbac_target_id_t       rsbac_target_id;
01153     union rsbac_attribute_value_t rsbac_attribute_value;
01154 
01155     if (!rsbac_is_initialized())
01156       {
01157         printk(KERN_WARNING "stats_auth_proc_info(): RSBAC not initialized\n");
01158         return(-RSBAC_ENOTINITIALIZED);
01159       }
01160 #ifdef CONFIG_RSBAC_DEBUG
01161     if (rsbac_debug_aef_auth)
01162       {
01163 #ifdef CONFIG_RSBAC_RMSG
01164         rsbac_printk(KERN_DEBUG "stats_auth_proc_info(): calling ADF\n");
01165 #endif
01166 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01167         if (!rsbac_nosyslog)
01168 #endif
01169         printk(KERN_DEBUG "stats_auth_proc_info(): calling ADF\n");
01170       }
01171 #endif
01172     rsbac_target_id.scd = ST_rsbac;
01173     rsbac_attribute_value.dummy = 0;
01174     if (!rsbac_adf_request(R_GET_STATUS_DATA,
01175                            current->pid,
01176                            T_SCD,
01177                            rsbac_target_id,
01178                            A_none,
01179                            rsbac_attribute_value))
01180       {
01181         return -EPERM;
01182       }
01183 
01184     len += sprintf(buffer, "AUTH Status\n-----------\n");
01185 
01186     len += sprintf(buffer + len, "%lu process cap set items, sum of %lu members\n",
01187                    rsbac_list_lol_count(process_handle),
01188                    rsbac_list_lol_all_subcount(process_handle));
01189     pos = begin + len;
01190     if (pos < offset)
01191       {
01192         len = 0;
01193         begin = pos;
01194       }
01195     if (pos > offset+length)
01196       goto out;
01197 
01198 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01199     len += sprintf(buffer + len, "%lu process eff cap set items, sum of %lu members\n",
01200                    rsbac_list_lol_count(process_eff_handle),
01201                    rsbac_list_lol_all_subcount(process_eff_handle));
01202     pos = begin + len;
01203     if (pos < offset)
01204       {
01205         len = 0;
01206         begin = pos;
01207       }
01208     if (pos > offset+length)
01209       goto out;
01210     len += sprintf(buffer + len, "%lu process fs cap set items, sum of %lu members\n",
01211                    rsbac_list_lol_count(process_fs_handle),
01212                    rsbac_list_lol_all_subcount(process_fs_handle));
01213     pos = begin + len;
01214     if (pos < offset)
01215       {
01216         len = 0;
01217         begin = pos;
01218       }
01219     if (pos > offset+length)
01220       goto out;
01221 #endif
01222 
01223 #ifdef CONFIG_RSBAC_AUTH_GROUP
01224     len += sprintf(buffer + len, "%lu process group cap set items, sum of %lu members\n",
01225                    rsbac_list_lol_count(process_group_handle),
01226                    rsbac_list_lol_all_subcount(process_group_handle));
01227     pos = begin + len;
01228     if (pos < offset)
01229       {
01230         len = 0;
01231         begin = pos;
01232       }
01233     if (pos > offset+length)
01234       goto out;
01235 
01236 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01237     len += sprintf(buffer + len, "%lu process group eff cap set items, sum of %lu members\n",
01238                    rsbac_list_lol_count(process_group_eff_handle),
01239                    rsbac_list_lol_all_subcount(process_group_eff_handle));
01240     pos = begin + len;
01241     if (pos < offset)
01242       {
01243         len = 0;
01244         begin = pos;
01245       }
01246     if (pos > offset+length)
01247       goto out;
01248     len += sprintf(buffer + len, "%lu process group fs cap set items, sum of %lu members\n",
01249                    rsbac_list_lol_count(process_group_fs_handle),
01250                    rsbac_list_lol_all_subcount(process_group_fs_handle));
01251     pos = begin + len;
01252     if (pos < offset)
01253       {
01254         len = 0;
01255         begin = pos;
01256       }
01257     if (pos > offset+length)
01258       goto out;
01259 #endif
01260 #endif /* AUTH_GROUP */
01261 
01262     /* protect device list */
01263     rsbac_read_lock(&device_list_head.lock, &dflags);
01264     device_p = device_list_head.head;
01265     while(device_p)
01266       {
01267         /* reset counters */
01268         cap_set_count = 0;
01269         member_count = 0;
01270         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++)
01271           {
01272             cap_set_count += rsbac_list_lol_count(device_p->handles[i]);
01273             member_count += rsbac_list_lol_all_subcount(device_p->handles[i]);
01274           }
01275         len += sprintf(buffer + len, "device %02u:%02u has %u file cap set items, sum of %u members\n",
01276                        RSBAC_MAJOR(device_p->id),
01277                        RSBAC_MINOR(device_p->id),
01278                        cap_set_count,member_count);
01279         pos = begin + len;
01280         if (pos < offset)
01281           {
01282             len = 0;
01283             begin = pos;
01284           }
01285         if (pos > offset+length)
01286           goto out_unlock;
01287 
01288 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01289         cap_set_count = 0;
01290         member_count = 0;
01291         for(i=0 ; i < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; i++)
01292           {
01293             cap_set_count += rsbac_list_lol_count(device_p->eff_handles[i]);
01294             member_count += rsbac_list_lol_all_subcount(device_p->eff_handles[i]);
01295           }
01296         len += sprintf(buffer + len, "device %02u:%02u has %u file eff cap set items, sum of %u members\n",
01297                        RSBAC_MAJOR(device_p->id),
01298                        RSBAC_MINOR(device_p->id),
01299                        cap_set_count,member_count);
01300         pos = begin + len;
01301         if (pos < offset)
01302           {
01303             len = 0;
01304             begin = pos;
01305           }
01306         if (pos > offset+length)
01307           goto out_unlock;
01308         cap_set_count = 0;
01309         member_count = 0;
01310         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; i++)
01311           {
01312             cap_set_count += rsbac_list_lol_count(device_p->fs_handles[i]);
01313             member_count += rsbac_list_lol_all_subcount(device_p->fs_handles[i]);
01314           }
01315         len += sprintf(buffer + len, "device %02u:%02u has %u file fs cap set items, sum of %u members\n",
01316                        RSBAC_MAJOR(device_p->id),
01317                        RSBAC_MINOR(device_p->id),
01318                        cap_set_count,member_count);
01319         pos = begin + len;
01320         if (pos < offset)
01321           {
01322             len = 0;
01323             begin = pos;
01324           }
01325         if (pos > offset+length)
01326           goto out_unlock;
01327 #endif
01328 
01329 #ifdef CONFIG_RSBAC_AUTH_GROUP
01330         cap_set_count = 0;
01331         member_count = 0;
01332         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; i++)
01333           {
01334             cap_set_count += rsbac_list_lol_count(device_p->group_handles[i]);
01335             member_count += rsbac_list_lol_all_subcount(device_p->group_handles[i]);
01336           }
01337         len += sprintf(buffer + len, "device %02u:%02u has %u file group cap set items, sum of %u members\n",
01338                        RSBAC_MAJOR(device_p->id),
01339                        RSBAC_MINOR(device_p->id),
01340                        cap_set_count,member_count);
01341         pos = begin + len;
01342         if (pos < offset)
01343           {
01344             len = 0;
01345             begin = pos;
01346           }
01347         if (pos > offset+length)
01348           goto out_unlock;
01349 
01350 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01351         cap_set_count = 0;
01352         member_count = 0;
01353         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; i++)
01354           {
01355             cap_set_count += rsbac_list_lol_count(device_p->group_eff_handles[i]);
01356             member_count += rsbac_list_lol_all_subcount(device_p->group_eff_handles[i]);
01357           }
01358         len += sprintf(buffer + len, "device %02u:%02u has %u file group eff cap set items, sum of %u members\n",
01359                        RSBAC_MAJOR(device_p->id),
01360                        RSBAC_MINOR(device_p->id),
01361                        cap_set_count,member_count);
01362         pos = begin + len;
01363         if (pos < offset)
01364           {
01365             len = 0;
01366             begin = pos;
01367           }
01368         if (pos > offset+length)
01369           goto out_unlock;
01370         cap_set_count = 0;
01371         member_count = 0;
01372         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; i++)
01373           {
01374             cap_set_count += rsbac_list_lol_count(device_p->group_fs_handles[i]);
01375             member_count += rsbac_list_lol_all_subcount(device_p->group_fs_handles[i]);
01376           }
01377         len += sprintf(buffer + len, "device %02u:%02u has %u file group fs cap set items, sum of %u members\n",
01378                        RSBAC_MAJOR(device_p->id),
01379                        RSBAC_MINOR(device_p->id),
01380                        cap_set_count,member_count);
01381         pos = begin + len;
01382         if (pos < offset)
01383           {
01384             len = 0;
01385             begin = pos;
01386           }
01387         if (pos > offset+length)
01388           goto out_unlock;
01389 #endif
01390 #endif /* AUTH_GROUP */
01391 
01392         device_p = device_p->next;
01393       }
01394 out_unlock:
01395     /* unprotect device list */
01396     rsbac_read_unlock(&device_list_head.lock, &dflags);
01397 
01398 out:
01399   *start = buffer + (offset - begin);
01400   len -= (offset - begin);
01401   
01402   if (len > length)
01403     len = length;
01404   return len;
01405 }
01406 
01407 static int
01408 auth_caplist_proc_info(char *buffer, char **start, off_t offset, int length)
01409 {
01410     u_int len = 0;
01411     off_t pos   = 0;
01412     off_t begin = 0;
01413 
01414     u_int                                      count = 0;
01415     u_int                                      member_count = 0;
01416     u_long                                     all_count;
01417     u_long                                     all_member_count;
01418     u_long dflags;
01419     int i,j,list;
01420     struct rsbac_auth_device_list_item_t   * device_p;
01421     rsbac_pid_t * p_list;
01422     rsbac_inode_nr_t * f_list;
01423     struct rsbac_auth_cap_range_t * cap_list;
01424 
01425     union rsbac_target_id_t       rsbac_target_id;
01426     union rsbac_attribute_value_t rsbac_attribute_value;
01427 
01428     if (!rsbac_is_initialized())
01429       {
01430         printk(KERN_WARNING "auth_caplist_proc_info(): RSBAC not initialized\n");
01431         return(-RSBAC_ENOTINITIALIZED);
01432       }
01433 #ifdef CONFIG_RSBAC_DEBUG
01434     if (rsbac_debug_aef_auth)
01435       {
01436 #ifdef CONFIG_RSBAC_RMSG
01437         rsbac_printk(KERN_DEBUG "auth_caplist_proc_info(): calling ADF\n");
01438 #endif
01439 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01440         if (!rsbac_nosyslog)
01441 #endif
01442         printk(KERN_DEBUG "auth_caplist_proc_info(): calling ADF\n");
01443       }
01444 #endif
01445     rsbac_target_id.scd = ST_rsbac;
01446     rsbac_attribute_value.dummy = 0;
01447     if (!rsbac_adf_request(R_GET_STATUS_DATA,
01448                            current->pid,
01449                            T_SCD,
01450                            rsbac_target_id,
01451                            A_none,
01452                            rsbac_attribute_value))
01453       {
01454         return -EPERM;
01455       }
01456 
01457     len += sprintf(buffer, "AUTH Cap Lists\n--------------\n");
01458 
01459     len += sprintf(buffer + len, "Process capabilities:\nset-id  count   cap-members");
01460     pos = begin + len;
01461     if (pos < offset)
01462       {
01463         len = 0;
01464         begin = pos;
01465       }
01466     if (pos > offset+length)
01467       goto out;
01468 
01469     all_member_count = 0;
01470     count = rsbac_list_lol_get_all_desc(process_handle,
01471                                         (void **) &p_list);
01472     if(count > 0)
01473       {
01474         for(i=0; i<count; i++)
01475           {
01476             member_count = rsbac_list_lol_get_all_subdesc(process_handle,
01477                                                           &p_list[i],
01478                                                           (void **) &cap_list);
01479             len += sprintf(buffer + len, "\n %u\t%u\t",
01480                            p_list[i],
01481                            member_count);
01482             if(member_count > 0)
01483               {
01484                 for(j=0; j<member_count; j++)
01485                   {
01486                     if(cap_list[j].first != cap_list[j].last)
01487                       len += sprintf(buffer + len, "%u:%u ",
01488                                      cap_list[j].first,
01489                                      cap_list[j].last);
01490                     else
01491                       len += sprintf(buffer + len, "%u ",
01492                                      cap_list[j].first);
01493                     pos = begin + len;
01494                     if (pos < offset)
01495                       {
01496                         len = 0;
01497                         begin = pos;
01498                       }
01499                     if (pos > offset+length)
01500                       {
01501                         rsbac_vfree(cap_list);
01502                         rsbac_vfree(p_list);
01503                         goto out;
01504                       }
01505                   }
01506                 rsbac_vfree(cap_list);
01507                 all_member_count += member_count;
01508               }
01509             pos = begin + len;
01510             if (pos < offset)
01511               {
01512                 len = 0;
01513                 begin = pos;
01514               }
01515             if (pos > offset+length)
01516               {
01517                 rsbac_vfree(p_list);
01518                 goto out;
01519               }
01520           }
01521         rsbac_vfree(p_list);
01522       }
01523     len += sprintf(buffer + len, "\n%u process cap set items, sum of %lu members\n",
01524                    count,all_member_count);
01525     pos = begin + len;
01526     if (pos < offset)
01527       {
01528         len = 0;
01529         begin = pos;
01530       }
01531     if (pos > offset+length)
01532       goto out;
01533 
01534 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01535     len += sprintf(buffer + len, "\nProcess eff capabilities:\nset-id  count   cap-members");
01536     pos = begin + len;
01537     if (pos < offset)
01538       {
01539         len = 0;
01540         begin = pos;
01541       }
01542     if (pos > offset+length)
01543       goto out;
01544 
01545     all_member_count = 0;
01546     count = rsbac_list_lol_get_all_desc(process_eff_handle,
01547                                         (void **) &p_list);
01548     if(count > 0)
01549       {
01550         for(i=0; i<count; i++)
01551           {
01552             member_count = rsbac_list_lol_get_all_subdesc(process_eff_handle,
01553                                                           &p_list[i],
01554                                                           (void **) &cap_list);
01555             len += sprintf(buffer + len, "\n %u\t%u\t",
01556                            p_list[i],
01557                            member_count);
01558             if(member_count > 0)
01559               {
01560                 for(j=0; j<member_count; j++)
01561                   {
01562                     if(cap_list[j].first != cap_list[j].last)
01563                       len += sprintf(buffer + len, "%u:%u ",
01564                                      cap_list[j].first,
01565                                      cap_list[j].last);
01566                     else
01567                       len += sprintf(buffer + len, "%u ",
01568                                      cap_list[j].first);
01569                     pos = begin + len;
01570                     if (pos < offset)
01571                       {
01572                         len = 0;
01573                         begin = pos;
01574                       }
01575                     if (pos > offset+length)
01576                       {
01577                         rsbac_vfree(cap_list);
01578                         rsbac_vfree(p_list);
01579                         goto out;
01580                       }
01581                   }
01582                 rsbac_vfree(cap_list);
01583                 all_member_count += member_count;
01584               }
01585             pos = begin + len;
01586             if (pos < offset)
01587               {
01588                 len = 0;
01589                 begin = pos;
01590               }
01591             if (pos > offset+length)
01592               {
01593                 rsbac_vfree(p_list);
01594                 goto out;
01595               }
01596           }
01597         rsbac_vfree(p_list);
01598       }
01599     len += sprintf(buffer + len, "\n%u process eff cap set items, sum of %lu members\n",
01600                    count,all_member_count);
01601     pos = begin + len;
01602     if (pos < offset)
01603       {
01604         len = 0;
01605         begin = pos;
01606       }
01607     if (pos > offset+length)
01608       goto out;
01609     len += sprintf(buffer + len, "\nProcess fs capabilities:\nset-id  count   cap-members");
01610     pos = begin + len;
01611     if (pos < offset)
01612       {
01613         len = 0;
01614         begin = pos;
01615       }
01616     if (pos > offset+length)
01617       goto out;
01618 
01619     all_member_count = 0;
01620     count = rsbac_list_lol_get_all_desc(process_fs_handle,
01621                                         (void **) &p_list);
01622     if(count > 0)
01623       {
01624         for(i=0; i<count; i++)
01625           {
01626             member_count = rsbac_list_lol_get_all_subdesc(process_fs_handle,
01627                                                           &p_list[i],
01628                                                           (void **) &cap_list);
01629             len += sprintf(buffer + len, "\n %u\t%u\t",
01630                            p_list[i],
01631                            member_count);
01632             if(member_count > 0)
01633               {
01634                 for(j=0; j<member_count; j++)
01635                   {
01636                     if(cap_list[j].first != cap_list[j].last)
01637                       len += sprintf(buffer + len, "%u:%u ",
01638                                      cap_list[j].first,
01639                                      cap_list[j].last);
01640                     else
01641                       len += sprintf(buffer + len, "%u ",
01642                                      cap_list[j].first);
01643                     pos = begin + len;
01644                     if (pos < offset)
01645                       {
01646                         len = 0;
01647                         begin = pos;
01648                       }
01649                     if (pos > offset+length)
01650                       {
01651                         rsbac_vfree(cap_list);
01652                         rsbac_vfree(p_list);
01653                         goto out;
01654                       }
01655                   }
01656                 rsbac_vfree(cap_list);
01657                 all_member_count += member_count;
01658               }
01659             pos = begin + len;
01660             if (pos < offset)
01661               {
01662                 len = 0;
01663                 begin = pos;
01664               }
01665             if (pos > offset+length)
01666               {
01667                 rsbac_vfree(p_list);
01668                 goto out;
01669               }
01670           }
01671         rsbac_vfree(p_list);
01672       }
01673     len += sprintf(buffer + len, "\n\n%u process fs cap set items, sum of %lu members\n",
01674                    count,all_member_count);
01675     pos = begin + len;
01676     if (pos < offset)
01677       {
01678         len = 0;
01679         begin = pos;
01680       }
01681     if (pos > offset+length)
01682       goto out;
01683 #endif
01684 
01685 #ifdef CONFIG_RSBAC_AUTH_GROUP
01686     len += sprintf(buffer + len, "\nProcess group capabilities:\nset-id  count   cap-members");
01687     pos = begin + len;
01688     if (pos < offset)
01689       {
01690         len = 0;
01691         begin = pos;
01692       }
01693     if (pos > offset+length)
01694       goto out;
01695 
01696     all_member_count = 0;
01697     count = rsbac_list_lol_get_all_desc(process_group_handle,
01698                                         (void **) &p_list);
01699     if(count > 0)
01700       {
01701         for(i=0; i<count; i++)
01702           {
01703             member_count = rsbac_list_lol_get_all_subdesc(process_group_handle,
01704                                                           &p_list[i],
01705                                                           (void **) &cap_list);
01706             len += sprintf(buffer + len, "\n %u\t%u\t",
01707                            p_list[i],
01708                            member_count);
01709             if(member_count > 0)
01710               {
01711                 for(j=0; j<member_count; j++)
01712                   {
01713                     if(cap_list[j].first != cap_list[j].last)
01714                       len += sprintf(buffer + len, "%u:%u ",
01715                                      cap_list[j].first,
01716                                      cap_list[j].last);
01717                     else
01718                       len += sprintf(buffer + len, "%u ",
01719                                      cap_list[j].first);
01720                     pos = begin + len;
01721                     if (pos < offset)
01722                       {
01723                         len = 0;
01724                         begin = pos;
01725                       }
01726                     if (pos > offset+length)
01727                       {
01728                         rsbac_vfree(cap_list);
01729                         rsbac_vfree(p_list);
01730                         goto out;
01731                       }
01732                   }
01733                 rsbac_vfree(cap_list);
01734                 all_member_count += member_count;
01735               }
01736             pos = begin + len;
01737             if (pos < offset)
01738               {
01739                 len = 0;
01740                 begin = pos;
01741               }
01742             if (pos > offset+length)
01743               {
01744                 rsbac_vfree(p_list);
01745                 goto out;
01746               }
01747           }
01748         rsbac_vfree(p_list);
01749       }
01750     len += sprintf(buffer + len, "\n%u process group cap set items, sum of %lu members\n",
01751                    count,all_member_count);
01752     pos = begin + len;
01753     if (pos < offset)
01754       {
01755         len = 0;
01756         begin = pos;
01757       }
01758     if (pos > offset+length)
01759       goto out;
01760 
01761 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01762     len += sprintf(buffer + len, "\nProcess group eff capabilities:\nset-id  count   cap-members");
01763     pos = begin + len;
01764     if (pos < offset)
01765       {
01766         len = 0;
01767         begin = pos;
01768       }
01769     if (pos > offset+length)
01770       goto out;
01771 
01772     all_member_count = 0;
01773     count = rsbac_list_lol_get_all_desc(process_group_eff_handle,
01774                                         (void **) &p_list);
01775     if(count > 0)
01776       {
01777         for(i=0; i<count; i++)
01778           {
01779             member_count = rsbac_list_lol_get_all_subdesc(process_group_eff_handle,
01780                                                           &p_list[i],
01781                                                           (void **) &cap_list);
01782             len += sprintf(buffer + len, "\n %u\t%u\t",
01783                            p_list[i],
01784                            member_count);
01785             if(member_count > 0)
01786               {
01787                 for(j=0; j<member_count; j++)
01788                   {
01789                     if(cap_list[j].first != cap_list[j].last)
01790                       len += sprintf(buffer + len, "%u:%u ",
01791                                      cap_list[j].first,
01792                                      cap_list[j].last);
01793                     else
01794                       len += sprintf(buffer + len, "%u ",
01795                                      cap_list[j].first);
01796                     pos = begin + len;
01797                     if (pos < offset)
01798                       {
01799                         len = 0;
01800                         begin = pos;
01801                       }
01802                     if (pos > offset+length)
01803                       {
01804                         rsbac_vfree(cap_list);
01805                         rsbac_vfree(p_list);
01806                         goto out;
01807                       }
01808                   }
01809                 rsbac_vfree(cap_list);
01810                 all_member_count += member_count;
01811               }
01812             pos = begin + len;
01813             if (pos < offset)
01814               {
01815                 len = 0;
01816                 begin = pos;
01817               }
01818             if (pos > offset+length)
01819               {
01820                 rsbac_vfree(p_list);
01821                 goto out;
01822               }
01823           }
01824         rsbac_vfree(p_list);
01825       }
01826     len += sprintf(buffer + len, "\n%u process group eff cap set items, sum of %lu members\n",
01827                    count,all_member_count);
01828     pos = begin + len;
01829     if (pos < offset)
01830       {
01831         len = 0;
01832         begin = pos;
01833       }
01834     if (pos > offset+length)
01835       goto out;
01836     len += sprintf(buffer + len, "\nProcess group fs capabilities:\nset-id  count   cap-members");
01837     pos = begin + len;
01838     if (pos < offset)
01839       {
01840         len = 0;
01841         begin = pos;
01842       }
01843     if (pos > offset+length)
01844       goto out;
01845 
01846     all_member_count = 0;
01847     count = rsbac_list_lol_get_all_desc(process_group_fs_handle,
01848                                         (void **) &p_list);
01849     if(count > 0)
01850       {
01851         for(i=0; i<count; i++)
01852           {
01853             member_count = rsbac_list_lol_get_all_subdesc(process_group_fs_handle,
01854                                                           &p_list[i],
01855                                                           (void **) &cap_list);
01856             len += sprintf(buffer + len, "\n %u\t%u\t",
01857                            p_list[i],
01858                            member_count);
01859             if(member_count > 0)
01860               {
01861                 for(j=0; j<member_count; j++)
01862                   {
01863                     if(cap_list[j].first != cap_list[j].last)
01864                       len += sprintf(buffer + len, "%u:%u ",
01865                                      cap_list[j].first,
01866                                      cap_list[j].last);
01867                     else
01868                       len += sprintf(buffer + len, "%u ",
01869                                      cap_list[j].first);
01870                     pos = begin + len;
01871                     if (pos < offset)
01872                       {
01873                         len = 0;
01874                         begin = pos;
01875                       }
01876                     if (pos > offset+length)
01877                       {
01878                         rsbac_vfree(cap_list);
01879                         rsbac_vfree(p_list);
01880                         goto out;
01881                       }
01882                   }
01883                 rsbac_vfree(cap_list);
01884                 all_member_count += member_count;
01885               }
01886             pos = begin + len;
01887             if (pos < offset)
01888               {
01889                 len = 0;
01890                 begin = pos;
01891               }
01892             if (pos > offset+length)
01893               {
01894                 rsbac_vfree(p_list);
01895                 goto out;
01896               }
01897           }
01898         rsbac_vfree(p_list);
01899       }
01900     len += sprintf(buffer + len, "\n\n%u process group fs cap set items, sum of %lu members\n",
01901                    count,all_member_count);
01902     pos = begin + len;
01903     if (pos < offset)
01904       {
01905         len = 0;
01906         begin = pos;
01907       }
01908     if (pos > offset+length)
01909       goto out;
01910 #endif
01911 #endif /* AUTH_GROUP */
01912 
01913     len += sprintf(buffer + len, "\nFile capabilities:\nset-id  count   cap-members");
01914     pos = begin + len;
01915     if (pos < offset)
01916       {
01917         len = 0;
01918         begin = pos;
01919       }
01920     if (pos > offset+length)
01921       goto out;
01922 
01923     /* protect device list */
01924     rsbac_read_lock(&device_list_head.lock, &dflags);
01925     device_p = device_list_head.head;
01926     while(device_p)
01927       {
01928         /* reset counters */
01929         all_member_count = 0;
01930         all_count = 0;
01931         for(list=0 ; list < RSBAC_AUTH_NR_CAP_FD_LISTS; list++)
01932           {
01933             count = rsbac_list_lol_get_all_desc(device_p->handles[list],
01934                                                 (void **) &f_list);
01935             if(count > 0)
01936               {
01937                 for(i=0; i<count; i++)
01938                   {
01939                     member_count = rsbac_list_lol_get_all_subdesc(device_p->handles[list],
01940                                                                   &f_list[i],
01941                                                                   (void **) &cap_list);
01942                     len += sprintf(buffer + len, "\n %u\t%u\t",
01943                                    f_list[i],
01944                                    member_count);
01945                     if(member_count > 0)
01946                       {
01947                         for(j=0; j<member_count; j++)
01948                           {
01949                             if(cap_list[j].first != cap_list[j].last)
01950                               len += sprintf(buffer + len, "%u:%u ",
01951                                              cap_list[j].first,
01952                                              cap_list[j].last);
01953                             else
01954                               len += sprintf(buffer + len, "%u ",
01955                                              cap_list[j].first);
01956                             pos = begin + len;
01957                             if (pos < offset)
01958                               {
01959                                 len = 0;
01960                                 begin = pos;
01961                               }
01962                             if (pos > offset+length)
01963                               {
01964                                 rsbac_vfree(cap_list);
01965                                 rsbac_vfree(f_list);
01966                                 goto out_unlock;
01967                               }
01968                           }
01969                         rsbac_vfree(cap_list);
01970                         all_member_count += member_count;
01971                       }
01972                     pos = begin + len;
01973                     if (pos < offset)
01974                       {
01975                         len = 0;
01976                         begin = pos;
01977                       }
01978                     if (pos > offset+length)
01979                       {
01980                         rsbac_vfree(f_list);
01981                         goto out_unlock;
01982                       }
01983                   }
01984                 rsbac_vfree(f_list);
01985                 all_count += count;
01986               }
01987           }
01988         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file cap set items, sum of %lu members, list is clean\n",
01989                        RSBAC_MAJOR(device_p->id),
01990                        RSBAC_MINOR(device_p->id),
01991                        all_count, all_member_count);
01992         pos = begin + len;
01993         if (pos < offset)
01994           {
01995             len = 0;
01996             begin = pos;
01997           }
01998         if (pos > offset+length)
01999           goto out_unlock;
02000 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
02001         all_member_count = 0;
02002         all_count = 0;
02003         for(list=0 ; list < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; list++)
02004           {
02005             count = rsbac_list_lol_get_all_desc(device_p->eff_handles[list],
02006                                                 (void **) &f_list);
02007             if(count > 0)
02008               {
02009                 for(i=0; i<count; i++)
02010                   {
02011                     member_count = rsbac_list_lol_get_all_subdesc(device_p->eff_handles[list],
02012                                                                   &f_list[i],
02013                                                                   (void **) &cap_list);
02014                     len += sprintf(buffer + len, "\n %u\t%u\t",
02015                                    f_list[i],
02016                                    member_count);
02017                     if(member_count > 0)
02018                       {
02019                         for(j=0; j<member_count; j++)
02020                           {
02021                             if(cap_list[j].first != cap_list[j].last)
02022                               len += sprintf(buffer + len, "%u:%u ",
02023                                              cap_list[j].first,
02024                                              cap_list[j].last);
02025                             else
02026                               len += sprintf(buffer + len, "%u ",
02027                                              cap_list[j].first);
02028                             pos = begin + len;
02029                             if (pos < offset)
02030                               {
02031                                 len = 0;
02032                                 begin = pos;
02033                               }
02034                             if (pos > offset+length)
02035                               {
02036                                 rsbac_vfree(cap_list);
02037                                 rsbac_vfree(f_list);
02038                                 goto out_unlock;
02039                               }
02040                           }
02041                         rsbac_vfree(cap_list);
02042                         all_member_count += member_count;
02043                       }
02044                     pos = begin + len;
02045                     if (pos < offset)
02046                       {
02047                         len = 0;
02048                         begin = pos;
02049                       }
02050                     if (pos > offset+length)
02051                       {
02052                         rsbac_vfree(f_list);
02053                         goto out_unlock;
02054                       }
02055                   }
02056                 rsbac_vfree(f_list);
02057                 all_count += count;
02058               }
02059           }
02060         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file eff cap set items, sum of %lu members, list is clean\n",
02061                        RSBAC_MAJOR(device_p->id),
02062                        RSBAC_MINOR(device_p->id),
02063                        all_count, all_member_count);
02064         pos = begin + len;
02065         if (pos < offset)
02066           {
02067             len = 0;
02068             begin = pos;
02069           }
02070         if (pos > offset+length)
02071           goto out_unlock;
02072 
02073         all_member_count = 0;
02074         all_count = 0;
02075         for(list=0 ; list < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; list++)
02076           {
02077             count = rsbac_list_lol_get_all_desc(device_p->fs_handles[list],
02078                                                 (void **) &f_list);
02079             if(count > 0)
02080               {
02081                 for(i=0; i<count; i++)
02082                   {
02083                     member_count = rsbac_list_lol_get_all_subdesc(device_p->fs_handles[list],
02084                                                                   &f_list[i],
02085                                                                   (void **) &cap_list);
02086                     len += sprintf(buffer + len, "\n %u\t%u\t",
02087                                    f_list[i],
02088                                    member_count);
02089                     if(member_count > 0)
02090                       {
02091                         for(j=0; j<member_count; j++)
02092                           {
02093                             if(cap_list[j].first != cap_list[j].last)
02094                               len += sprintf(buffer + len, "%u:%u ",
02095                                              cap_list[j].first,
02096                                              cap_list[j].last);
02097                             else
02098                               len += sprintf(buffer + len, "%u ",
02099                                              cap_list[j].first);
02100                             pos = begin + len;
02101                             if (pos < offset)
02102                               {
02103                                 len = 0;
02104                                 begin = pos;
02105                               }
02106                             if (pos > offset+length)
02107                               {
02108                                 rsbac_vfree(cap_list);
02109                                 rsbac_vfree(f_list);
02110                                 goto out_unlock;
02111                               }
02112                           }
02113                         rsbac_vfree(cap_list);
02114                         all_member_count += member_count;
02115                       }
02116                     pos = begin + len;
02117                     if (pos < offset)
02118                       {
02119                         len = 0;
02120                         begin = pos;
02121                       }
02122                     if (pos > offset+length)
02123                       {
02124                         rsbac_vfree(f_list);
02125                         goto out_unlock;
02126                       }
02127                   }
02128                 rsbac_vfree(f_list);
02129                 all_count += count;
02130               }
02131           }
02132         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file fs cap set items, sum of %lu members, list is clean\n",
02133                        RSBAC_MAJOR(device_p->id),
02134                        RSBAC_MINOR(device_p->id),
02135                        all_count, all_member_count);
02136         pos = begin + len;
02137         if (pos < offset)
02138           {
02139             len = 0;
02140             begin = pos;
02141           }
02142         if (pos > offset+length)
02143           goto out_unlock;
02144 #endif
02145 
02146 #ifdef CONFIG_RSBAC_AUTH_GROUP
02147         all_member_count = 0;
02148         all_count = 0;
02149         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; list++)
02150           {
02151             count = rsbac_list_lol_get_all_desc(device_p->group_handles[list],
02152                                                 (void **) &f_list);
02153             if(count > 0)
02154               {
02155                 for(i=0; i<count; i++)
02156                   {
02157                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_handles[list],
02158                                                                   &f_list[i],
02159                                                                   (void **) &cap_list);
02160                     len += sprintf(buffer + len, "\n %u\t%u\t",
02161                                    f_list[i],
02162                                    member_count);
02163                     if(member_count > 0)
02164                       {
02165                         for(j=0; j<member_count; j++)
02166                           {
02167                             if(cap_list[j].first != cap_list[j].last)
02168                               len += sprintf(buffer + len, "%u:%u ",
02169                                              cap_list[j].first,
02170                                              cap_list[j].last);
02171                             else
02172                               len += sprintf(buffer + len, "%u ",
02173                                              cap_list[j].first);
02174                             pos = begin + len;
02175                             if (pos < offset)
02176                               {
02177                                 len = 0;
02178                                 begin = pos;
02179                               }
02180                             if (pos > offset+length)
02181                               {
02182                                 rsbac_vfree(cap_list);
02183                                 rsbac_vfree(f_list);
02184                                 goto out_unlock;
02185                               }
02186                           }
02187                         rsbac_vfree(cap_list);
02188                         all_member_count += member_count;
02189                       }
02190                     pos = begin + len;
02191                     if (pos < offset)
02192                       {
02193                         len = 0;
02194                         begin = pos;
02195                       }
02196                     if (pos > offset+length)
02197                       {
02198                         rsbac_vfree(f_list);
02199                         goto out_unlock;
02200                       }
02201                   }
02202                 rsbac_vfree(f_list);
02203                 all_count += count;
02204               }
02205           }
02206         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group cap set items, sum of %lu members, list is clean\n",
02207                        RSBAC_MAJOR(device_p->id),
02208                        RSBAC_MINOR(device_p->id),
02209                        all_count, all_member_count);
02210         pos = begin + len;
02211         if (pos < offset)
02212           {
02213             len = 0;
02214             begin = pos;
02215           }
02216         if (pos > offset+length)
02217           goto out_unlock;
02218 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
02219         all_member_count = 0;
02220         all_count = 0;
02221         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; list++)
02222           {
02223             count = rsbac_list_lol_get_all_desc(device_p->group_eff_handles[list],
02224                                                 (void **) &f_list);
02225             if(count > 0)
02226               {
02227                 for(i=0; i<count; i++)
02228                   {
02229                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_eff_handles[list],
02230                                                                   &f_list[i],
02231                                                                   (void **) &cap_list);
02232                     len += sprintf(buffer + len, "\n %u\t%u\t",
02233                                    f_list[i],
02234                                    member_count);
02235                     if(member_count > 0)
02236                       {
02237                         for(j=0; j<member_count; j++)
02238                           {
02239                             if(cap_list[j].first != cap_list[j].last)
02240                               len += sprintf(buffer + len, "%u:%u ",
02241                                              cap_list[j].first,
02242                                              cap_list[j].last);
02243                             else
02244                               len += sprintf(buffer + len, "%u ",
02245                                              cap_list[j].first);
02246                             pos = begin + len;
02247                             if (pos < offset)
02248                               {
02249                                 len = 0;
02250                                 begin = pos;
02251                               }
02252                             if (pos > offset+length)
02253                               {
02254                                 rsbac_vfree(cap_list);
02255                                 rsbac_vfree(f_list);
02256                                 goto out_unlock;
02257                               }
02258                           }
02259                         rsbac_vfree(cap_list);
02260                         all_member_count += member_count;
02261                       }
02262                     pos = begin + len;
02263                     if (pos < offset)
02264                       {
02265                         len = 0;
02266                         begin = pos;
02267                       }
02268                     if (pos > offset+length)
02269                       {
02270                         rsbac_vfree(f_list);
02271                         goto out_unlock;
02272                       }
02273                   }
02274                 rsbac_vfree(f_list);
02275                 all_count += count;
02276               }
02277           }
02278         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group eff cap set items, sum of %lu members, list is clean\n",
02279                        RSBAC_MAJOR(device_p->id),
02280                        RSBAC_MINOR(device_p->id),
02281                        all_count, all_member_count);
02282         pos = begin + len;
02283         if (pos < offset)
02284           {
02285             len = 0;
02286             begin = pos;
02287           }
02288         if (pos > offset+length)
02289           goto out_unlock;
02290 
02291         all_member_count = 0;
02292         all_count = 0;
02293         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; list++)
02294           {
02295             count = rsbac_list_lol_get_all_desc(device_p->group_fs_handles[list],
02296                                                 (void **) &f_list);
02297             if(count > 0)
02298               {
02299                 for(i=0; i<count; i++)
02300                   {
02301                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_fs_handles[list],
02302                                                                   &f_list[i],
02303                                                                   (void **) &cap_list);
02304                     len += sprintf(buffer + len, "\n %u\t%u\t",
02305                                    f_list[i],
02306                                    member_count);
02307                     if(member_count > 0)
02308                       {
02309                         for(j=0; j<member_count; j++)
02310                           {
02311                             if(cap_list[j].first != cap_list[j].last)
02312                               len += sprintf(buffer + len, "%u:%u ",
02313                                              cap_list[j].first,
02314                                              cap_list[j].last);
02315                             else
02316                               len += sprintf(buffer + len, "%u ",
02317                                              cap_list[j].first);
02318                             pos = begin + len;
02319                             if (pos < offset)
02320                               {
02321                                 len = 0;
02322                                 begin = pos;
02323                               }
02324                             if (pos > offset+length)
02325                               {
02326                                 rsbac_vfree(cap_list);
02327                                 rsbac_vfree(f_list);
02328                                 goto out_unlock;
02329                               }
02330                           }
02331                         rsbac_vfree(cap_list);
02332                         all_member_count += member_count;
02333                       }
02334                     pos = begin + len;
02335                     if (pos < offset)
02336                       {
02337                         len = 0;
02338                         begin = pos;
02339                       }
02340                     if (pos > offset+length)
02341                       {
02342                         rsbac_vfree(f_list);
02343                         goto out_unlock;
02344                       }
02345                   }
02346                 rsbac_vfree(f_list);
02347                 all_count += count;
02348               }
02349           }
02350         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group fs cap set items, sum of %lu members, list is clean\n",
02351                        RSBAC_MAJOR(device_p->id),
02352                        RSBAC_MINOR(device_p->id),
02353                        all_count, all_member_count);
02354         pos = begin + len;
02355         if (pos < offset)
02356           {
02357             len = 0;
02358             begin = pos;
02359           }
02360         if (pos > offset+length)
02361           goto out_unlock;
02362 #endif
02363 #endif /* AUTH_GROUP */
02364 
02365         device_p = device_p->next;
02366       }
02367 out_unlock:
02368     /* unprotect device list */
02369     rsbac_read_unlock(&device_list_head.lock, &dflags);
02370 
02371 out:
02372   *start = buffer + (offset - begin);
02373   len -= (offset - begin);
02374   
02375   if (len > length)
02376     len = length;
02377   return len;
02378 }
02379 #endif /* CONFIG_PROC_FS && CONFIG_RSBAC_PROC */
02380 
02381 /************************************************* */
02382 /*               Init functions                    */
02383 /************************************************* */
02384 
02385 /* All functions return 0, if no error occurred, and a negative error code  */
02386 /* otherwise. The error codes are defined in rsbac/error.h.                 */
02387 
02388 /************************************************************************** */
02389 /* Initialization of all AUTH data structures. After this call, all AUTH    */
02390 /* data is kept in memory for performance reasons, but is written to disk   */
02391 /* on every change. */
02392 
02393 /* Because there can be no access to aci data structures before init,       */
02394 /* rsbac_init_auth() will initialize all rw-spinlocks to unlocked.          */
02395 
02396 #ifdef CONFIG_RSBAC_INIT_DELAY
02397 int rsbac_init_auth(void)
02398 #else
02399 int __init rsbac_init_auth(void)
02400 #endif
02401   {
02402     int  err = 0;
02403     struct rsbac_auth_device_list_item_t * device_p = NULL;
02404     u_long dflags;
02405     struct proc_dir_entry * tmp_entry_p;
02406     struct rsbac_list_lol_info_t lol_info;
02407 
02408     if (rsbac_is_initialized())
02409       {
02410 #ifdef CONFIG_RSBAC_RMSG
02411         rsbac_printk(KERN_WARNING "rsbac_init_auth(): RSBAC already initialized\n");
02412 #endif
02413 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02414         if (!rsbac_nosyslog)
02415 #endif
02416         printk(KERN_WARNING "rsbac_init_auth(): RSBAC already initialized\n");
02417         return(-RSBAC_EREINIT);
02418       }
02419 
02420     /* set rw-spinlocks to unlocked status and init data structures */
02421 #ifdef CONFIG_RSBAC_RMSG
02422     rsbac_printk(KERN_INFO "rsbac_init_auth(): Initializing RSBAC: AUTH subsystem\n");
02423 #endif
02424 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02425     if (!rsbac_nosyslog)
02426 #endif
02427     printk(KERN_INFO "rsbac_init_auth(): Initializing RSBAC: AUTH subsystem\n");
02428 
02429     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02430     lol_info.key = RSBAC_AUTH_LIST_KEY;
02431     lol_info.desc_size = sizeof(rsbac_pid_t);
02432     lol_info.data_size = 0;
02433     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02434     lol_info.subdata_size = 0;
02435     lol_info.max_age = 0;
02436     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02437                                   &process_handle,
02438                                   &lol_info,
02439                                   RSBAC_LIST_DEF_DATA,
02440                                   NULL,
02441                                   cap_compare,
02442                                   NULL,
02443                                   NULL,
02444                                   NULL,
02445                                   NULL,
02446                                   RSBAC_AUTH_P_LIST_NAME,
02447                                   RSBAC_AUTO_DEV);
02448     if(err)
02449       {
02450         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02451 
02452         if(tmp)
02453           {
02454 #ifdef CONFIG_RSBAC_RMSG
02455             rsbac_printk(KERN_WARNING
02456                    "rsbac_init_auth(): Registering AUTH process cap list failed with error %s\n",
02457                    get_error_name(tmp, err));
02458 #endif
02459 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02460             if (!rsbac_nosyslog)
02461 #endif
02462             printk(KERN_WARNING
02463                    "rsbac_init_auth(): Registering AUTH process cap list failed with error %s\n",
02464                    get_error_name(tmp, err));
02465             rsbac_kfree(tmp);
02466           }
02467       }
02468 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
02469     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02470     lol_info.key = RSBAC_AUTH_LIST_KEY;
02471     lol_info.desc_size = sizeof(rsbac_pid_t);
02472     lol_info.data_size = 0;
02473     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02474     lol_info.subdata_size = 0;
02475     lol_info.max_age = 0;
02476     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02477                                   &process_eff_handle,
02478                                   &lol_info,
02479                                   RSBAC_LIST_DEF_DATA,
02480                                   NULL,
02481                                   cap_compare,
02482                                   NULL,
02483                                   NULL,
02484                                   NULL,
02485                                   NULL,
02486                                   RSBAC_AUTH_P_EFF_LIST_NAME,
02487                                   RSBAC_AUTO_DEV);
02488     if(err)
02489       {
02490         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02491 
02492         if(tmp)
02493           {
02494 #ifdef CONFIG_RSBAC_RMSG
02495             rsbac_printk(KERN_WARNING
02496                    "rsbac_init_auth(): Registering AUTH process eff cap list failed with error %s\n",
02497                    get_error_name(tmp, err));
02498 #endif
02499 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02500             if (!rsbac_nosyslog)
02501 #endif
02502             printk(KERN_WARNING
02503                    "rsbac_init_auth(): Registering AUTH process eff cap list failed with error %s\n",
02504                    get_error_name(tmp, err));
02505             rsbac_kfree(tmp);
02506           }
02507       }
02508     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02509     lol_info.key = RSBAC_AUTH_LIST_KEY;
02510     lol_info.desc_size = sizeof(rsbac_pid_t);
02511     lol_info.data_size = 0;
02512     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02513     lol_info.subdata_size = 0;
02514     lol_info.max_age = 0;
02515     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02516                                   &process_fs_handle,
02517                                   &lol_info,
02518                                   RSBAC_LIST_DEF_DATA,
02519                                   NULL,
02520                                   cap_compare,
02521                                   NULL,
02522                                   NULL,
02523                                   NULL,
02524                                   NULL,
02525                                   RSBAC_AUTH_P_FS_LIST_NAME,
02526                                   RSBAC_AUTO_DEV);
02527     if(err)
02528       {
02529         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02530 
02531         if(tmp)
02532           {
02533 #ifdef CONFIG_RSBAC_RMSG
02534             rsbac_printk(KERN_WARNING
02535                    "rsbac_init_auth(): Registering AUTH process fs cap list failed with error %s\n",
02536                    get_error_name(tmp, err));
02537 #endif
02538 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02539             if (!rsbac_nosyslog)
02540 #endif
02541             printk(KERN_WARNING
02542                    "rsbac_init_auth(): Registering AUTH process fs cap list failed with error %s\n",
02543                    get_error_name(tmp, err));
02544             rsbac_kfree(tmp);
02545           }
02546       }
02547 #endif
02548 
02549 #ifdef CONFIG_RSBAC_AUTH_GROUP
02550     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02551     lol_info.key = RSBAC_AUTH_LIST_KEY;
02552     lol_info.desc_size = sizeof(rsbac_pid_t);
02553     lol_info.data_size = 0;
02554     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02555     lol_info.subdata_size = 0;
02556     lol_info.max_age = 0;
02557     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02558                                   &process_group_handle,
02559                                   &lol_info,
02560                                   RSBAC_LIST_DEF_DATA,
02561                                   NULL,
02562                                   cap_compare,
02563                                   NULL,
02564                                   NULL,
02565                                   NULL,
02566                                   NULL,
02567                                   RSBAC_AUTH_P_GROUP_LIST_NAME,
02568                                   RSBAC_AUTO_DEV);
02569     if(err)
02570       {
02571         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02572 
02573         if(tmp)
02574           {
02575 #ifdef CONFIG_RSBAC_RMSG
02576             rsbac_printk(KERN_WARNING
02577                    "rsbac_init_auth(): Registering AUTH process group cap list failed with error %s\n",
02578                    get_error_name(tmp, err));
02579 #endif
02580 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02581             if (!rsbac_nosyslog)
02582 #endif
02583             printk(KERN_WARNING
02584                    "rsbac_init_auth(): Registering AUTH process group cap list failed with error %s\n",
02585                    get_error_name(tmp, err));
02586             rsbac_kfree(tmp);
02587           }
02588       }
02589 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
02590     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02591     lol_info.key = RSBAC_AUTH_LIST_KEY;
02592     lol_info.desc_size = sizeof(rsbac_pid_t);
02593     lol_info.data_size = 0;
02594     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02595     lol_info.subdata_size = 0;
02596     lol_info.max_age = 0;
02597     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02598                                   &process_group_eff_handle,
02599                                   &lol_info,
02600                                   RSBAC_LIST_DEF_DATA,
02601                                   NULL,
02602                                   cap_compare,
02603                                   NULL,
02604                                   NULL,
02605                                   NULL,
02606                                   NULL,
02607                                   RSBAC_AUTH_P_GROUP_EFF_LIST_NAME,
02608                                   RSBAC_AUTO_DEV);
02609     if(err)
02610       {
02611         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02612 
02613         if(tmp)
02614           {
02615 #ifdef CONFIG_RSBAC_RMSG
02616             rsbac_printk(KERN_WARNING
02617                    "rsbac_init_auth(): Registering AUTH process group eff cap list failed with error %s\n",
02618                    get_error_name(tmp, err));
02619 #endif
02620 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02621             if (!rsbac_nosyslog)
02622 #endif
02623             printk(KERN_WARNING
02624                    "rsbac_init_auth(): Registering AUTH process group eff cap list failed with error %s\n",
02625                    get_error_name(tmp, err));
02626             rsbac_kfree(tmp);
02627           }
02628       }
02629     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02630     lol_info.key = RSBAC_AUTH_LIST_KEY;
02631     lol_info.desc_size = sizeof(rsbac_pid_t);
02632     lol_info.data_size = 0;
02633     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02634     lol_info.subdata_size = 0;
02635     lol_info.max_age = 0;
02636     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02637                                   &process_group_fs_handle,
02638                                   &lol_info,
02639                                   RSBAC_LIST_DEF_DATA,
02640                                   NULL,
02641                                   cap_compare,
02642                                   NULL,
02643                                   NULL,
02644                                   NULL,
02645                                   NULL,
02646                                   RSBAC_AUTH_P_GROUP_FS_LIST_NAME,
02647                                   RSBAC_AUTO_DEV);
02648     if(err)
02649       {
02650         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02651 
02652         if(tmp)
02653           {
02654 #ifdef CONFIG_RSBAC_RMSG
02655             rsbac_printk(KERN_WARNING
02656                    "rsbac_init_auth(): Registering AUTH process group fs cap list failed with error %s\n",
02657                    get_error_name(tmp, err));
02658 #endif
02659 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02660             if (!rsbac_nosyslog)
02661 #endif
02662             printk(KERN_WARNING
02663                    "rsbac_init_auth(): Registering AUTH process group fs cap list failed with error %s\n",
02664                    get_error_name(tmp, err));
02665             rsbac_kfree(tmp);
02666           }
02667       }
02668 #endif
02669 #endif /* AUTH_GROUP */
02670 
02671     /* Init FD lists */
02672     device_list_head.lock = RW_LOCK_UNLOCKED;
02673     device_list_head.head = NULL;
02674     device_list_head.tail = NULL;
02675     device_list_head.curr = NULL;
02676     device_list_head.count = 0;
02677 
02678     /* read all data */
02679 #ifdef CONFIG_RSBAC_DEBUG
02680     if (rsbac_debug_ds_auth)
02681       {
02682 #ifdef CONFIG_RSBAC_RMSG
02683         rsbac_printk(KERN_INFO "rsbac_init_auth(): Registering FD lists\n");
02684 #endif
02685 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02686         if (!rsbac_nosyslog)
02687 #endif
02688         printk(KERN_INFO "rsbac_init_auth(): Registering FD lists\n");
02689       }
02690 #endif
02691     device_p = create_device_item(rsbac_root_dev);
02692     if (!device_p)
02693       {
02694 #ifdef CONFIG_RSBAC_RMSG
02695         rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02696 #endif
02697         printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02698         return(-RSBAC_ECOULDNOTADDDEVICE);
02699       }
02700     if((err = auth_register_fd_lists(device_p,rsbac_root_dev)))
02701       {
02702         char tmp[RSBAC_MAXNAMELEN];
02703 
02704 #ifdef CONFIG_RSBAC_RMSG
02705         rsbac_printk(KERN_WARNING
02706                "rsbac_init_auth(): File/Dir cap set registration failed for dev %02u:%02u, err %s!\n",
02707                RSBAC_MAJOR(rsbac_root_dev), RSBAC_MINOR(rsbac_root_dev), get_error_name(tmp,err));
02708 #endif
02709 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02710         if (!rsbac_nosyslog)
02711 #endif
02712         printk(KERN_WARNING
02713                "rsbac_init_auth(): File/Dir cap set registration failed for dev %02u:%02u, err %s!\n",
02714                RSBAC_MAJOR(rsbac_root_dev), RSBAC_MINOR(rsbac_root_dev), get_error_name(tmp,err));
02715       }
02716     /* wait for write access to device_list_head */
02717     rsbac_write_lock_irq(&device_list_head.lock, &dflags);
02718     device_p = add_device_item(device_p);
02719     /* device was added, allow access */
02720     rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
02721     if (!device_p)
02722       {
02723 #ifdef CONFIG_RSBAC_RMSG
02724         rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02725 #endif
02726         printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02727         return(-RSBAC_ECOULDNOTADDDEVICE);
02728       }
02729 
02730     #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
02731     tmp_entry_p = create_proc_entry("auth_devices",
02732                                     S_IFREG | S_IRUGO,
02733                                     proc_rsbac_root_p);
02734     if(tmp_entry_p)
02735       {
02736         tmp_entry_p->get_info = auth_devices_proc_info;
02737       }
02738     tmp_entry_p = create_proc_entry("stats_auth",
02739                                     S_IFREG | S_IRUGO,
02740                                     proc_rsbac_root_p);
02741     if(tmp_entry_p)
02742       {
02743         tmp_entry_p->get_info = stats_auth_proc_info;
02744       }
02745     tmp_entry_p = create_proc_entry("auth_caplist",
02746                                     S_IFREG | S_IRUGO,
02747                                     proc_rsbac_root_p);
02748     if(tmp_entry_p)
02749       {
02750         tmp_entry_p->get_info = auth_caplist_proc_info;
02751       }
02752     #endif
02753 
02754 #ifdef CONFIG_RSBAC_DEBUG
02755     if (rsbac_debug_ds_auth)
02756       {
02757 #ifdef CONFIG_RSBAC_RMSG
02758         rsbac_printk(KERN_DEBUG "rsbac_init_auth(): Ready.\n");
02759 #endif
02760 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02761         if (!rsbac_nosyslog)
02762 #endif
02763         printk(KERN_DEBUG "rsbac_init_auth(): Ready.\n");
02764       }
02765 #endif
02766     return(err);
02767   };
02768 
02769 int rsbac_mount_auth(kdev_t kdev)
02770   {
02771     int err = 0;
02772     struct rsbac_auth_device_list_item_t * device_p;
02773     struct rsbac_auth_device_list_item_t * new_device_p;
02774     u_long dflags;
02775 
02776     if (!rsbac_is_initialized())
02777       {
02778 #ifdef CONFIG_RSBAC_RMSG
02779         rsbac_printk(KERN_WARNING "rsbac_mount_auth(): RSBAC not initialized\n");
02780 #endif
02781 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02782         if (!rsbac_nosyslog)
02783 #endif
02784         printk(KERN_WARNING "rsbac_mount_auth(): RSBAC not initialized\n");
02785           return(-RSBAC_ENOTINITIALIZED);
02786       }
02787 #ifdef CONFIG_RSBAC_DEBUG
02788     if (rsbac_debug_ds_auth)
02789       {
02790 #ifdef CONFIG_RSBAC_RMSG
02791         rsbac_printk(KERN_DEBUG "rsbac_mount_auth(): mounting device %02u:%02u\n",
02792                RSBAC_MAJOR(kdev),RSBAC_MINOR(kdev));
02793 #endif
02794 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02795         if (!rsbac_nosyslog)
02796 #endif
02797         printk(KERN_DEBUG "rsbac_mount_auth(): mounting device %02u:%02u\n",
02798                RSBAC_MAJOR(kdev),RSBAC_MINOR(kdev));
02799       }
02800 #endif
02801     /* wait for write access to device_list_head */
02802     rsbac_read_lock(&device_list_head.lock, &dflags);
02803     device_p = lookup_device(kdev);
02804     /* repeated mount? */
02805     if(device_p)
02806       {
02807 #ifdef CONFIG_RSBAC_RMSG
02808         rsbac_printk(KERN_WARNING "rsbac_mount_auth: repeated mount %u of device %02u:%02u\n",
02809                device_p->mount_count, RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02810 #endif
02811 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02812         if (!rsbac_nosyslog)
02813 #endif
02814         printk(KERN_WARNING "rsbac_mount_auth: repeated mount %u of device %02u:%02u\n",
02815                device_p->mount_count, RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02816         device_p->mount_count++;
02817         rsbac_read_unlock(&device_list_head.lock, &dflags);
02818         return 0;
02819       }
02820     rsbac_read_unlock(&device_list_head.lock, &dflags);
02821 
02822     new_device_p = create_device_item(kdev);
02823     if(!new_device_p)
02824       return -RSBAC_ECOULDNOTADDDEVICE;
02825 
02826     /* register lists */
02827     if((err = auth_register_fd_lists(new_device_p, kdev)))
02828       {
02829         char tmp[RSBAC_MAXNAMELEN];
02830 
02831 #ifdef CONFIG_RSBAC_RMSG
02832         rsbac_printk(KERN_WARNING
02833                "rsbac_mount_auth(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n",
02834                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev), get_error_name(tmp,err));
02835 #endif
02836 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02837         if (!rsbac_nosyslog)
02838 #endif
02839         printk(KERN_WARNING
02840                "rsbac_mount_auth(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n",
02841                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev), get_error_name(tmp,err));
02842       }
02843 
02844     /* wait for read access to device_list_head */
02845     rsbac_read_lock(&device_list_head.lock, &dflags);
02846     /* make sure to only add, if this device item has not been added in the meantime */
02847     device_p = lookup_device(kdev);
02848     if(device_p)
02849       {
02850 #ifdef CONFIG_RSBAC_RMSG
02851         rsbac_printk(KERN_WARNING
02852                "rsbac_mount_auth(): mount race for device %02u:%02u detected!\n",
02853                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02854 #endif
02855 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02856         if (!rsbac_nosyslog)
02857 #endif
02858         printk(KERN_WARNING
02859                "rsbac_mount_auth(): mount race for device %02u:%02u detected!\n",
02860                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02861         device_p->mount_count++;
02862         rsbac_read_unlock(&device_list_head.lock, &dflags);
02863         clear_device_item(new_device_p);
02864       }
02865     else
02866       {
02867         rsbac_read_unlock(&device_list_head.lock, &dflags);
02868         rsbac_write_lock_irq(&device_list_head.lock, &dflags);
02869         device_p = add_device_item(new_device_p);
02870         rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
02871         if(!device_p)
02872           {
02873 #ifdef CONFIG_RSBAC_RMSG
02874             rsbac_printk(KERN_WARNING "rsbac_mount_auth: adding device %02u:%02u failed!\n",
02875                    RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02876 #endif
02877 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02878             if (!rsbac_nosyslog)
02879 #endif
02880             printk(KERN_WARNING "rsbac_mount_auth: adding device %02u:%02u failed!\n",
02881                    RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02882             clear_device_item(new_device_p);
02883             err = -RSBAC_ECOULDNOTADDDEVICE;
02884           }
02885       }
02886     return(err);
02887   };
02888   
02889 /* When umounting a device, its file cap set list must be removed. */
02890 
02891 int rsbac_umount_auth(kdev_t kdev)
02892   {
02893     u_long flags;
02894     struct rsbac_auth_device_list_item_t * device_p;
02895 
02896     if (!rsbac_is_initialized())
02897       {
02898 #ifdef CONFIG_RSBAC_RMSG
02899         rsbac_printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n");
02900 #endif
02901 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02902         if (!rsbac_nosyslog)
02903 #endif
02904         printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n");
02905         return(-RSBAC_ENOTINITIALIZED);
02906       }
02907 
02908 #ifdef CONFIG_RSBAC_DEBUG
02909     if (rsbac_debug_ds_auth)
02910       {
02911 #ifdef CONFIG_RSBAC_RMSG
02912         rsbac_printk(KERN_DEBUG "rsbac_umount_auth(): umounting device %02u:%02u\n",
02913                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02914 #endif
02915 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02916         if (!rsbac_nosyslog)
02917 #endif
02918         printk(KERN_DEBUG "rsbac_umount_auth(): umounting device %02u:%02u\n",
02919                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02920       }
02921 #endif
02922     /* sync of attribute lists was done in rsbac_umount */
02923     /* wait for write access to device_list_head */
02924     rsbac_write_lock(&device_list_head.lock, &flags);
02925     /* OK, nobody else is working on it... */
02926     device_p = lookup_device(kdev);
02927     if(device_p)
02928       {
02929         if(device_p->mount_count == 1)
02930           remove_device_item(kdev);
02931         else
02932           {
02933             if(device_p->mount_count > 1)
02934               {
02935                 device_p->mount_count--;
02936               }
02937             else
02938               {
02939 #ifdef CONFIG_RSBAC_RMSG
02940                 rsbac_printk(KERN_WARNING "rsbac_mount_auth: device %02u:%02u has mount_count < 1!\n",
02941                        RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02942 #endif
02943 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02944                 if (!rsbac_nosyslog)
02945 #endif
02946                 printk(KERN_WARNING "rsbac_mount_auth: device %02u:%02u has mount_count < 1!\n",
02947                        RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02948               }
02949           }
02950       }
02951 
02952     /* allow access */
02953     rsbac_write_unlock(&device_list_head.lock, &flags);
02954     return(0);
02955   };
02956 
02957 /***************************************************/
02958 /* We also need some status information...         */
02959 
02960 int rsbac_stats_auth(void)
02961   {
02962     u_int                                     cap_set_count = 0;
02963     u_int                                     member_count = 0;
02964     u_long dflags;
02965     struct rsbac_auth_device_list_item_t   * device_p;
02966     int i;
02967   
02968     union rsbac_target_id_t       rsbac_target_id;
02969     union rsbac_attribute_value_t rsbac_attribute_value;
02970 
02971     if (!rsbac_is_initialized())
02972       {
02973 #ifdef CONFIG_RSBAC_RMSG
02974         rsbac_printk(KERN_WARNING "rsbac_stats_auth(): RSBAC not initialized\n");
02975 #endif
02976 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02977         if (!rsbac_nosyslog)
02978 #endif
02979         printk(KERN_WARNING "rsbac_stats_auth(): RSBAC not initialized\n");
02980         return(-RSBAC_ENOTINITIALIZED);
02981       }
02982 #ifdef CONFIG_RSBAC_DEBUG
02983     if (rsbac_debug_aef_auth)
02984       {
02985 #ifdef CONFIG_RSBAC_RMSG
02986         rsbac_printk(KERN_DEBUG "rsbac_stats_auth(): calling ADF\n");
02987 #endif
02988 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
02989         if (!rsbac_nosyslog)
02990 #endif
02991         printk(KERN_DEBUG "rsbac_stats_auth(): calling ADF\n");
02992       }
02993 #endif
02994     rsbac_target_id.scd = ST_rsbac;
02995     rsbac_attribute_value.dummy = 0;
02996     if (!rsbac_adf_request(R_GET_STATUS_DATA,
02997                            current->pid,
02998                            T_SCD,
02999                            rsbac_target_id,
03000                            A_none,
03001                            rsbac_attribute_value))
03002       {
03003         return -EPERM;
03004       }
03005 
03006     printk(KERN_INFO "AUTH Status\n-----------\n");
03007 
03008     printk(KERN_INFO "%lu process cap set items, sum of %lu members\n",
03009                    rsbac_list_lol_count(process_handle),
03010                    rsbac_list_lol_all_subcount(process_handle));
03011 
03012     /* protect device list */
03013     rsbac_read_lock(&device_list_head.lock, &dflags);
03014     device_p = device_list_head.head;
03015     while(device_p)
03016       {
03017         /* reset counters */
03018         cap_set_count = 0;
03019         member_count = 0;
03020         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++)
03021           {
03022             cap_set_count += rsbac_list_lol_count(device_p->handles[i]);
03023             member_count += rsbac_list_lol_all_subcount(device_p->handles[i]);
03024           }
03025         printk(KERN_INFO "device %02u:%02u has %u file cap set items, sum of %u members\n",
03026                          RSBAC_MAJOR(device_p->id),
03027                          RSBAC_MINOR(device_p->id),
03028                          cap_set_count,member_count);
03029         device_p = device_p->next;
03030       }
03031     /* unprotect device list */
03032     rsbac_read_unlock(&device_list_head.lock, &dflags);
03033     return(0);
03034   };
03035 
03036 /***************************************************/
03037 /* consistency checking (as far as possible)       */
03038 
03039 int rsbac_check_auth(int correct, int check_inode)
03040   {
03041     struct rsbac_auth_device_list_item_t * device_p;
03042     u_long                              f_count = 0, f_sum = 0, tmp_count,
03043                                         r_count, u_count, b_count, no_member_count;
03044     long                                desc_count;
03045     u_int                               i,list_no;
03046     u_long                              dflags;
03047     struct super_block                * sb_p;
03048     struct inode                      * inode_p;
03049     rsbac_inode_nr_t                  * fd_desc_p;
03050   
03051     if (!rsbac_is_initialized())
03052       {
03053 #ifdef CONFIG_RSBAC_RMSG
03054         rsbac_printk(KERN_WARNING "rsbac_check_auth(): RSBAC not initialized\n");
03055 #endif
03056 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03057         if (!rsbac_nosyslog)
03058 #endif
03059         printk(KERN_WARNING "rsbac_check_auth(): RSBAC not initialized\n");
03060         return(-RSBAC_ENOTINITIALIZED);
03061       }
03062 
03063     /* wait for read access to device_list_head */
03064     rsbac_read_lock(&device_list_head.lock, &dflags);
03065     /* OK, go on */
03066 /*    printk(KERN_INFO "rsbac_check_auth(): currently %u processes working on file/dir aci\n",
03067                      device_list_head.lock.lock); */
03068     device_p = device_list_head.head;
03069     while (device_p)
03070       { /* for all sublists */
03071         f_count = 0;
03072         r_count = 0;
03073         u_count = 0;
03074         b_count = 0;
03075         no_member_count = 0;
03076         if(check_inode)
03077           {
03078             sb_p = rsbac_get_super_block(device_p->id);
03079             if(!sb_p)
03080               {
03081 #ifdef CONFIG_RSBAC_RMSG
03082                 rsbac_printk(KERN_WARNING "rsbac_check_auth(): no super block for device %02u:%02u!\n",
03083                        RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id));
03084 #endif
03085 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03086                 if (!rsbac_nosyslog)
03087 #endif
03088                 printk(KERN_WARNING "rsbac_check_auth(): no super block for device %02u:%02u!\n",
03089                        RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id));
03090               }
03091           }
03092         else
03093           sb_p = NULL;
03094 
03095         /* OK, go ahead */
03096         for(list_no = 0; list_no < RSBAC_AUTH_NR_CAP_FD_LISTS; list_no++)
03097           {
03098 /*            printk(KERN_INFO "rsbac_check_auth(): list %u\n",
03099                    list_no); */
03100             tmp_count = 0;
03101             desc_count = rsbac_list_lol_get_all_desc(device_p->handles[list_no], (void **) &fd_desc_p);
03102             if(desc_count > 0)
03103               {
03104                 for(i=0; i<desc_count; i++)
03105                   {
03106                     /* check for inode on disk (but not for reiserfs, because of 64bit inode numbers) */
03107                     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
03108                     if(sb_p)
03109                     #else
03110                     if(sb_p && !sb_p->s_op->read_inode2)
03111                     #endif
03112                       {
03113                         inode_p = iget(sb_p, fd_desc_p[i]);
03114                         if(is_bad_inode(inode_p))
03115                           { /* inode is bad -> remove */
03116                             b_count++;
03117                             if(correct)
03118                               {
03119 #ifdef CONFIG_RSBAC_RMSG
03120                                 rsbac_printk(KERN_INFO
03121                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u, removing!\n",
03122                                         fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03123 #endif
03124 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03125                                 if (!rsbac_nosyslog)
03126 #endif
03127                                 printk(KERN_INFO
03128                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u, removing!\n",
03129                                         fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03130                                 rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
03131                                 continue;
03132                               }
03133                             else
03134                               {
03135 #ifdef CONFIG_RSBAC_RMSG
03136                                 rsbac_printk(KERN_INFO
03137                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u!\n",
03138                                        fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03139 #endif
03140 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03141                                 if (!rsbac_nosyslog)
03142 #endif
03143                                 printk(KERN_INFO
03144                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u!\n",
03145                                        fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03146                               }
03147                           } /* end of bad_inode */
03148 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
03149                         else
03150                           { /* good inode */
03151                             /* currently only deletion checking of ext2 inodes is possible */
03152                             if(sb_p->s_magic == EXT2_SUPER_MAGIC)
03153                               {
03154                                 if(inode_p->u.ext2_i.i_dtime)
03155                                   { /* inode has been deleted -> remove */
03156                                     r_count++;
03157                                     if(correct)
03158                                       {
03159 #ifdef CONFIG_RSBAC_RMSG
03160                                         rsbac_printk(KERN_INFO
03161                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u, removing!\n",
03162                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03163 #endif
03164 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03165                                         if (!rsbac_nosyslog)
03166 #endif
03167                                         printk(KERN_INFO
03168                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u, removing!\n",
03169                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03170                                         rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
03171                                         continue;
03172                                       }
03173                                     else
03174                                       {
03175 #ifdef CONFIG_RSBAC_RMSG
03176                                         rsbac_printk(KERN_INFO
03177                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u!\n",
03178                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03179 #endif
03180 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03181                                         if (!rsbac_nosyslog)
03182 #endif
03183                                         printk(KERN_INFO
03184                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u!\n",
03185                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03186                                       }
03187                                   }
03188                                 else
03189                                   {
03190                                     if(inode_p->i_nlink <= 0)
03191                                       { /* inode has been unlinked, but no dtime is set -> warn */
03192                                         u_count++;
03193                                         if(correct >= 2)
03194                                           {
03195 #ifdef CONFIG_RSBAC_RMSG
03196                                             rsbac_printk(KERN_INFO
03197                                                    "rsbac_check_auth(): fd_item for inode %u with nlink <= 0 on device %02u:%02u, list %u, removing!\n",
03198                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03199 #endif
03200 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03201                                             if (!rsbac_nosyslog)
03202 #endif
03203                                             printk(KERN_INFO
03204                                                    "rsbac_check_auth(): fd_item for inode %u with nlink <= 0 on device %02u:%02u, list %u, removing!\n",
03205                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03206                                             rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
03207                                             continue;
03208                                           }
03209                                         else
03210                                           {
03211 #ifdef CONFIG_RSBAC_RMSG
03212                                             rsbac_printk(KERN_INFO
03213                                                    "rsbac_check_auth(): deleted inode %u on device %02u:%02u, list %u, has no dtime!\n",
03214                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03215 #endif
03216 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03217                                             if (!rsbac_nosyslog)
03218 #endif
03219                                             printk(KERN_INFO
03220                                                    "rsbac_check_auth(): deleted inode %u on device %02u:%02u, list %u, has no dtime!\n",
03221                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
03222                                           }
03223                                       }
03224                                   }
03225                               }
03226                           } /* end of is_good_inode */
03227 #endif /* VERSION < 2.6.0 */
03228                         iput(inode_p);
03229                       } /* end of sb_p */
03230                   }
03231                 tmp_count++;
03232                 rsbac_vfree(fd_desc_p);
03233                 f_count += desc_count;
03234               }
03235           } /* end of for-fd-list-array */
03236 
03237         switch(correct)
03238           {
03239             case 2:
03240 #ifdef CONFIG_RSBAC_RMSG
03241               rsbac_printk(KERN_INFO
03242                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu unlinked inodes, %lu had no members and default mask))\n",
03243                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + u_count + no_member_count,
03244                      b_count, r_count, u_count, no_member_count);
03245 #endif
03246 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03247               if (!rsbac_nosyslog)
03248 #endif
03249               printk(KERN_INFO
03250                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu unlinked inodes, %lu had no members and default mask))\n",
03251                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + u_count + no_member_count,
03252                      b_count, r_count, u_count, no_member_count);
03253               break;
03254             case 1:
03255 #ifdef CONFIG_RSBAC_RMSG
03256               rsbac_printk(KERN_INFO
03257                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu had no members and default mask), %lu unlinked inodes)\n",
03258                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + no_member_count,
03259                      b_count, r_count, no_member_count, u_count);
03260 #endif
03261 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03262               if (!rsbac_nosyslog)
03263 #endif
03264               printk(KERN_INFO
03265                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu had no members and default mask), %lu unlinked inodes)\n",
03266                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + no_member_count,
03267                      b_count, r_count, no_member_count, u_count);
03268               break;
03269             default:
03270 #ifdef CONFIG_RSBAC_RMSG
03271               rsbac_printk(KERN_INFO
03272                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu with bad inodes, %lu with dtimed inodes, %lu unlinked inodes, %lu without members and with default mask)\n",
03273                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count,
03274                      b_count, r_count, u_count, no_member_count);
03275 #endif
03276 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03277               if (!rsbac_nosyslog)
03278 #endif
03279               printk(KERN_INFO
03280                      "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu with bad inodes, %lu with dtimed inodes, %lu unlinked inodes, %lu without members and with default mask)\n",
03281                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count,
03282                      b_count, r_count, u_count, no_member_count);
03283           }
03284         f_sum += f_count;
03285         /* go on */
03286         device_p = device_p->next;
03287       }
03288 #ifdef CONFIG_RSBAC_RMSG
03289     rsbac_printk(KERN_INFO "rsbac_check_auth(): Sum of %u Devices with %lu file/dir AUTHs\n",
03290                  device_list_head.count, f_sum);
03291 #endif
03292 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03293     if (!rsbac_nosyslog)
03294 #endif
03295     printk(KERN_INFO "rsbac_check_auth(): Sum of %u Devices with %lu file/dir AUTHs\n",
03296                  device_list_head.count, f_sum);
03297     /* free access to device_list_head */
03298     rsbac_read_unlock(&device_list_head.lock, &dflags);
03299     
03300 #ifdef CONFIG_RSBAC_RMSG
03301     rsbac_printk(KERN_INFO
03302            "rsbac_check_auth(): Total of %lu registered auth items\n",
03303            f_sum);
03304 #endif
03305 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03306     if (!rsbac_nosyslog)
03307 #endif
03308     printk(KERN_INFO
03309            "rsbac_check_auth(): Total of %lu registered auth items\n",
03310            f_sum);
03311     return(0);
03312   };
03313 
03314 /************************************************* */
03315 /*               Access functions                  */
03316 /************************************************* */
03317 
03318 /* All these procedures handle the rw-spinlocks to protect the targets during */
03319 /* access.                                                                  */
03320 /* Trying to access a never created or removed set returns an error! */
03321 
03322 /* rsbac_auth_add_to_capset */
03323 /* Add a set member to a set sublist. Set behaviour: also returns success, */
03324 /* if member was already in set! */
03325 
03326 int rsbac_auth_add_to_p_capset(
03327          rsbac_list_ta_number_t ta_number,
03328          rsbac_pid_t pid,
03329   enum   rsbac_auth_cap_type_t cap_type,
03330   struct rsbac_auth_cap_range_t cap_range,
03331          rsbac_time_t ttl)
03332   {
03333     if (!rsbac_is_initialized())
03334       {
03335         printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): RSBAC not initialized\n");
03336         return(-RSBAC_ENOTINITIALIZED);
03337       }
03338     if (in_interrupt())
03339       {
03340         printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): called from interrupt!\n");
03341       }
03342     if(cap_range.first > cap_range.last)
03343       return(-RSBAC_EINVALIDVALUE);
03344     switch(cap_type)
03345       {
03346         case ACT_real:
03347           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_handle, ttl, &pid, &cap_range, NULL);
03348 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03349         case ACT_eff:
03350           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_eff_handle, ttl, &pid, &cap_range, NULL);
03351         case ACT_fs:
03352           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_fs_handle, ttl, &pid, &cap_range, NULL);
03353 #endif
03354 #ifdef CONFIG_RSBAC_AUTH_GROUP
03355         case ACT_group_real:
03356           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_handle, ttl, &pid, &cap_range, NULL);
03357 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03358         case ACT_group_eff:
03359           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_eff_handle, ttl, &pid, &cap_range, NULL);
03360         case ACT_group_fs:
03361           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_fs_handle, ttl, &pid, &cap_range, NULL);
03362 #endif
03363 #endif /* AUTH_GROUP */
03364 
03365         default:
03366           return -RSBAC_EINVALIDTARGET;
03367       }
03368   }
03369 
03370 int rsbac_auth_add_to_f_capset(
03371          rsbac_list_ta_number_t ta_number,
03372          rsbac_auth_file_t file,
03373   enum   rsbac_auth_cap_type_t cap_type,
03374   struct rsbac_auth_cap_range_t cap_range,
03375          rsbac_time_t ttl)
03376   {
03377     int                                     err=0;
03378     u_long dflags;
03379     struct rsbac_auth_device_list_item_t   * device_p;
03380 
03381     if (!rsbac_is_initialized())
03382       {
03383         printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): RSBAC not initialized\n");
03384         return(-RSBAC_ENOTINITIALIZED);
03385       }
03386     if (in_interrupt())
03387       {
03388         printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): called from interrupt!\n");
03389       }
03390     if(cap_range.first > cap_range.last)
03391       return(-RSBAC_EINVALIDVALUE);
03392 
03393     /* protect device list */
03394     rsbac_read_lock(&device_list_head.lock, &dflags);
03395     device_p = lookup_device(file.device);
03396     if(!device_p)
03397       {
03398         /* trigger rsbac_mount() */
03399         rsbac_read_unlock(&device_list_head.lock, &dflags);
03400         rsbac_get_super_block(file.device);
03401         /* retry */
03402         rsbac_read_lock(&device_list_head.lock, &dflags);
03403         device_p = lookup_device(file.device);
03404         if(!device_p)
03405           {
03406 #ifdef CONFIG_RSBAC_RMSG
03407             rsbac_printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): invalid device %02u:%02u!\n",
03408                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03409 #endif
03410 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03411             if (!rsbac_nosyslog)
03412 #endif
03413             printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): invalid device %02u:%02u!\n",
03414                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03415             rsbac_read_unlock(&device_list_head.lock, &dflags);
03416             return(-RSBAC_EINVALIDDEV);
03417           }
03418       }
03419 
03420     switch(cap_type)
03421       {
03422         case ACT_real:
03423           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->handles[fd_hash(file.inode)],
03424                                           ttl, &file.inode, &cap_range, NULL);
03425           break;
03426 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03427         case ACT_eff:
03428           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)],
03429                                           ttl, &file.inode, &cap_range, NULL);
03430           break;
03431         case ACT_fs:
03432           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)],
03433                                           ttl, &file.inode, &cap_range, NULL);
03434           break;
03435 #endif
03436 #ifdef CONFIG_RSBAC_AUTH_GROUP
03437         case ACT_group_real:
03438           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_handles[group_fd_hash(file.inode)],
03439                                           ttl, &file.inode, &cap_range, NULL);
03440           break;
03441 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03442         case ACT_group_eff:
03443           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)],
03444                                           ttl, &file.inode, &cap_range, NULL);
03445           break;
03446         case ACT_group_fs:
03447           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)],
03448                                           ttl, &file.inode, &cap_range, NULL);
03449           break;
03450 #endif
03451 #endif /* AUTH_GROUP */
03452 
03453         default:
03454           err = -RSBAC_EINVALIDTARGET;
03455       }
03456     rsbac_read_unlock(&device_list_head.lock, &dflags);
03457     return(err);
03458   }
03459 
03460 /* rsbac_auth_remove_from_capset */
03461 /* Remove a set member from a sublist. Set behaviour: Returns no error, if */
03462 /* member is not in list.                                                  */
03463 
03464 int rsbac_auth_remove_from_p_capset(
03465          rsbac_list_ta_number_t ta_number,
03466          rsbac_pid_t pid,
03467   enum   rsbac_auth_cap_type_t cap_type,
03468   struct rsbac_auth_cap_range_t cap_range)
03469   {
03470     if (!rsbac_is_initialized())
03471       {
03472         printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): RSBAC not initialized\n");
03473         return(-RSBAC_ENOTINITIALIZED);
03474       }
03475     if (in_interrupt())
03476       {
03477         printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): called from interrupt!\n");
03478       }
03479     if(cap_range.first > cap_range.last)
03480       return(-RSBAC_EINVALIDVALUE);
03481     switch(cap_type)
03482       {
03483         case ACT_real:
03484           return rsbac_ta_list_lol_subremove(ta_number, process_handle, &pid, &cap_range);
03485 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03486         case ACT_eff:
03487           return rsbac_ta_list_lol_subremove(ta_number, process_eff_handle, &pid, &cap_range);
03488         case ACT_fs:
03489           return rsbac_ta_list_lol_subremove(ta_number, process_fs_handle, &pid, &cap_range);
03490 #endif
03491 #ifdef CONFIG_RSBAC_AUTH_GROUP
03492         case ACT_group_real:
03493           return rsbac_ta_list_lol_subremove(ta_number, process_group_handle, &pid, &cap_range);
03494 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03495         case ACT_group_eff:
03496           return rsbac_ta_list_lol_subremove(ta_number, process_group_eff_handle, &pid, &cap_range);
03497         case ACT_group_fs:
03498           return rsbac_ta_list_lol_subremove(ta_number, process_group_fs_handle, &pid, &cap_range);
03499 #endif
03500 #endif /* AUTH_GROUP */
03501 
03502         default:
03503           return -RSBAC_EINVALIDTARGET;
03504       }
03505   }
03506 
03507 int rsbac_auth_remove_from_f_capset(
03508         rsbac_list_ta_number_t ta_number,
03509         rsbac_auth_file_t file,
03510   enum  rsbac_auth_cap_type_t cap_type,
03511   struct rsbac_auth_cap_range_t cap_range)
03512   {
03513     int                                    err=0;
03514     u_long dflags;
03515     struct rsbac_auth_device_list_item_t   * device_p;
03516 
03517     if (!rsbac_is_initialized())
03518       {
03519         printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): RSBAC not initialized\n");
03520         return(-RSBAC_ENOTINITIALIZED);
03521       }
03522     if (in_interrupt())
03523       {
03524         printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): called from interrupt!\n");
03525       }
03526     if(cap_range.first > cap_range.last)
03527       return(-RSBAC_EINVALIDVALUE);
03528 
03529     /* protect device list */
03530     rsbac_read_lock(&device_list_head.lock, &dflags);
03531     device_p = lookup_device(file.device);
03532     if(!device_p)
03533       {
03534         /* trigger rsbac_mount() */
03535         rsbac_read_unlock(&device_list_head.lock, &dflags);
03536         rsbac_get_super_block(file.device);
03537         /* retry */
03538         rsbac_read_lock(&device_list_head.lock, &dflags);
03539         device_p = lookup_device(file.device);
03540         if(!device_p)
03541           {
03542 #ifdef CONFIG_RSBAC_RMSG
03543             rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): invalid device %02u:%02u!\n",
03544                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03545 #endif
03546 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03547             if (!rsbac_nosyslog)
03548 #endif
03549             printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): invalid device %02u:%02u!\n",
03550                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03551             rsbac_read_unlock(&device_list_head.lock, &dflags);
03552             return(-RSBAC_EINVALIDDEV);
03553           }
03554       }
03555     switch(cap_type)
03556       {
03557         case ACT_real:
03558           err = rsbac_ta_list_lol_subremove(ta_number, device_p->handles[fd_hash(file.inode)], &file.inode, &cap_range);
03559           break;
03560 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03561         case ACT_eff:
03562           err = rsbac_ta_list_lol_subremove(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode, &cap_range);
03563           break;
03564         case ACT_fs:
03565           err = rsbac_ta_list_lol_subremove(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode, &cap_range);
03566           break;
03567 #endif
03568 #ifdef CONFIG_RSBAC_AUTH_GROUP
03569         case ACT_group_real:
03570           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_handles[group_fd_hash(file.inode)], &file.inode, &cap_range);
03571           break;
03572 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03573         case ACT_group_eff:
03574           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)], &file.inode, &cap_range);
03575           break;
03576         case ACT_group_fs:
03577           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)], &file.inode, &cap_range);
03578           break;
03579 #endif
03580 #endif /* AUTH_GROUP */
03581 
03582         default:
03583           err = -RSBAC_EINVALIDTARGET;
03584       }
03585     rsbac_read_unlock(&device_list_head.lock, &dflags);
03586     return(err);
03587   }
03588 
03589 /* rsbac_auth_clear_capset */
03590 /* Remove all set members from a sublist. Set behaviour: Returns no error, */
03591 /* if list is empty.                                                       */
03592 
03593 int rsbac_auth_clear_p_capset(
03594        rsbac_list_ta_number_t ta_number,
03595        rsbac_pid_t pid,
03596   enum rsbac_auth_cap_type_t cap_type)
03597   {
03598     if (!rsbac_is_initialized())
03599       {
03600         printk(KERN_WARNING "rsbac_auth_clear_p_capset(): RSBAC not initialized\n");
03601         return(-RSBAC_ENOTINITIALIZED);
03602       }
03603     if (in_interrupt())
03604       {
03605         printk(KERN_WARNING "rsbac_auth_clear_p_capset(): called from interrupt!\n");
03606       }
03607     switch(cap_type)
03608       {
03609         case ACT_real:
03610           return rsbac_ta_list_lol_remove(ta_number, process_handle, &pid);
03611 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03612         case ACT_eff:
03613           return rsbac_ta_list_lol_remove(ta_number, process_eff_handle, &pid);
03614         case ACT_fs:
03615           return rsbac_ta_list_lol_remove(ta_number, process_fs_handle, &pid);
03616 #endif
03617 #ifdef CONFIG_RSBAC_AUTH_GROUP
03618         case ACT_group_real:
03619           return rsbac_ta_list_lol_remove(ta_number, process_group_handle, &pid);
03620 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03621         case ACT_group_eff:
03622           return rsbac_ta_list_lol_remove(ta_number, process_group_eff_handle, &pid);
03623         case ACT_group_fs:
03624           return rsbac_ta_list_lol_remove(ta_number, process_group_fs_handle, &pid);
03625 #endif
03626 #endif /* AUTH_GROUP */
03627 
03628         default:
03629           return -RSBAC_EINVALIDTARGET;
03630       }
03631   }
03632 
03633 int rsbac_auth_clear_f_capset(
03634        rsbac_list_ta_number_t ta_number,
03635        rsbac_auth_file_t file,
03636   enum rsbac_auth_cap_type_t cap_type)
03637   {
03638     int                                    err=0;
03639     u_long dflags;
03640     struct rsbac_auth_device_list_item_t   * device_p;
03641 
03642     if (!rsbac_is_initialized())
03643       {
03644         printk(KERN_WARNING "rsbac_auth_clear_f_capset(): RSBAC not initialized\n");
03645         return(-RSBAC_ENOTINITIALIZED);
03646       }
03647     if (in_interrupt())
03648       {
03649         printk(KERN_WARNING "rsbac_auth_clear_f_capset(): called from interrupt!\n");
03650       }
03651     /* protect device list */
03652     rsbac_read_lock(&device_list_head.lock, &dflags);
03653     device_p = lookup_device(file.device);
03654     if(!device_p)
03655       {
03656         /* trigger rsbac_mount() */
03657         rsbac_read_unlock(&device_list_head.lock, &dflags);
03658         rsbac_get_super_block(file.device);
03659         /* retry */
03660         rsbac_read_lock(&device_list_head.lock, &dflags);
03661         device_p = lookup_device(file.device);
03662         if(!device_p)
03663           {
03664 #ifdef CONFIG_RSBAC_RMSG
03665             rsbac_printk(KERN_WARNING "rsbac_auth_clear_f_capset(): invalid device %02u:%02u!\n",
03666                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03667 #endif
03668 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03669             if (!rsbac_nosyslog)
03670 #endif
03671             printk(KERN_WARNING "rsbac_auth_clear_f_capset(): invalid device %02u:%02u!\n",
03672                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03673             rsbac_read_unlock(&device_list_head.lock, &dflags);
03674             return(-RSBAC_EINVALIDDEV);
03675           }
03676       }
03677     switch(cap_type)
03678       {
03679         case ACT_real:
03680           err = rsbac_ta_list_lol_remove(ta_number, device_p->handles[fd_hash(file.inode)], &file.inode);
03681           break;
03682 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03683         case ACT_eff:
03684           err = rsbac_ta_list_lol_remove(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode);
03685           break;
03686         case ACT_fs:
03687           err = rsbac_ta_list_lol_remove(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode);
03688           break;
03689 #endif
03690 #ifdef CONFIG_RSBAC_AUTH_GROUP
03691         case ACT_group_real:
03692           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_handles[group_fd_hash(file.inode)], &file.inode);
03693           break;
03694 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03695         case ACT_group_eff:
03696           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)], &file.inode);
03697           break;
03698         case ACT_group_fs:
03699           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)], &file.inode);
03700           break;
03701 #endif
03702 #endif /* AUTH_GROUP */
03703 
03704         default:
03705           err = -RSBAC_EINVALIDTARGET;
03706       }
03707     rsbac_read_unlock(&device_list_head.lock, &dflags);
03708     return(err);
03709   }
03710 
03711 /* rsbac_auth_capset_member */
03712 /* Return truth value, whether member is in set */
03713 
03714 rsbac_boolean_t  rsbac_auth_p_capset_member(rsbac_pid_t pid,
03715                                     enum rsbac_auth_cap_type_t cap_type,
03716                                     rsbac_uid_t member)
03717   {
03718     rsbac_boolean_t result;
03719 
03720     if (!rsbac_is_initialized())
03721       {
03722         printk(KERN_WARNING "rsbac_auth_p_capset_member(): RSBAC not initialized\n");
03723         return FALSE;
03724       }
03725     if (in_interrupt())
03726       {
03727         printk(KERN_WARNING "rsbac_auth_p_capset_member(): called from interrupt!\n");
03728       }
03729     switch(cap_type)
03730       {
03731         case ACT_real:
03732           result = rsbac_list_lol_subexist_compare(process_handle, &pid, &member, single_cap_compare);
03733 
03734           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03735           if(   !result
03736              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03737             )
03738             {
03739               union rsbac_target_id_t tid;
03740               union rsbac_attribute_value_t attr_val;
03741               rsbac_boolean_t learn;
03742 
03743               learn = rsbac_auth_learn;
03744               if(!learn)
03745                 {
03746                   tid.process = pid;
03747                   /* check learn on process */
03748                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03749                     learn = attr_val.auth_learn;
03750                 }
03751               if(learn)
03752                 {
03753                   struct rsbac_auth_cap_range_t range;
03754 
03755 #ifdef CONFIG_RSBAC_RMSG
03756                   rsbac_printk(KERN_INFO
03757                          "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to process %u (%.15s)!\n",
03758                          member,
03759                          pid,
03760                          current->comm);
03761 #endif
03762 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03763                   if (!rsbac_nosyslog)
03764 #endif
03765                   printk(KERN_INFO
03766                          "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to process %u (%.15s)!\n",
03767                          member,
03768                          pid,
03769                          current->comm);
03770                   range.first = member;
03771                   range.last = member;
03772                   rsbac_list_lol_subadd(process_handle, &pid, &range, NULL);
03773 
03774                   tid.process = pid;
03775                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03776                     {
03777                       struct rsbac_auth_device_list_item_t * device_p;
03778                       union rsbac_attribute_value_t attr_val2;
03779                       u_long dflags;
03780 
03781                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
03782                         {
03783                           if(range.first == attr_val2.auth_start_uid)
03784                             {
03785                               range.first = RSBAC_AUTH_OWNER_F_CAP;
03786                               range.last = range.first;
03787                             }
03788                         }
03789 #ifdef CONFIG_RSBAC_RMSG
03790                       rsbac_printk(KERN_INFO
03791                              "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to file %u on device %02u:%02u!\n",
03792                              range.first,
03793                              attr_val.auth_program_file.inode,
03794                              MAJOR(attr_val.auth_program_file.device),
03795                              MINOR(attr_val.auth_program_file.device));
03796 #endif
03797 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03798                       if (!rsbac_nosyslog)
03799 #endif
03800                       printk(KERN_INFO
03801                              "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to file %u on device %02u:%02u!\n",
03802                              range.first,
03803                              attr_val.auth_program_file.inode,
03804                              MAJOR(attr_val.auth_program_file.device),
03805                              MINOR(attr_val.auth_program_file.device));
03806                       rsbac_read_lock(&device_list_head.lock, &dflags);
03807                       device_p = lookup_device(attr_val.auth_program_file.device);
03808                       if(device_p)
03809                         {
03810                           rsbac_list_lol_subadd(device_p->handles[fd_hash(attr_val.auth_program_file.inode)],
03811                                                 &attr_val.auth_program_file.inode, &range, NULL);
03812                         }
03813                       else
03814                         {
03815 #ifdef CONFIG_RSBAC_RMSG
03816                           rsbac_printk(KERN_INFO
03817                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03818                                  MAJOR(attr_val.auth_program_file.device),
03819                                  MINOR(attr_val.auth_program_file.device));
03820 #endif
03821 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03822                           if (!rsbac_nosyslog)
03823 #endif
03824                           printk(KERN_INFO
03825                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03826                                  MAJOR(attr_val.auth_program_file.device),
03827                                  MINOR(attr_val.auth_program_file.device));
03828                         }
03829                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03830                     }
03831                   result = TRUE;
03832                 }
03833             }
03834           #endif
03835           break;
03836 
03837 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03838         case ACT_eff:
03839           result = rsbac_list_lol_subexist_compare(process_eff_handle, &pid, &member, single_cap_compare);
03840 
03841           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03842           if(   !result
03843              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03844             )
03845             {
03846               union rsbac_target_id_t tid;
03847               union rsbac_attribute_value_t attr_val;
03848               rsbac_boolean_t learn;
03849 
03850               learn = rsbac_auth_learn;
03851               if(!learn)
03852                 {
03853                   tid.process = pid;
03854                   /* check learn on process */
03855                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03856                     learn = attr_val.auth_learn;
03857                 }
03858               if(learn)
03859                 {
03860                   struct rsbac_auth_cap_range_t range;
03861 
03862 #ifdef CONFIG_RSBAC_RMSG
03863                   rsbac_printk(KERN_INFO
03864                          "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to process %u (%.15s)!\n",
03865                          member,
03866                          pid,
03867                          current->comm);
03868 #endif
03869 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03870                   if (!rsbac_nosyslog)
03871 #endif
03872                   printk(KERN_INFO
03873                          "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to process %u (%.15s)!\n",
03874                          member,
03875                          pid,
03876                          current->comm);
03877                   range.first = member;
03878                   range.last = member;
03879                   rsbac_list_lol_subadd(process_eff_handle, &pid, &range, NULL);
03880 
03881                   tid.process = pid;
03882                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03883                     {
03884                       struct rsbac_auth_device_list_item_t * device_p;
03885                       union rsbac_attribute_value_t attr_val2;
03886                       u_long dflags;
03887 
03888                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
03889                         {
03890                           if(range.first == attr_val2.auth_start_uid)
03891                             {
03892                               range.first = RSBAC_AUTH_OWNER_F_CAP;
03893                               range.last = range.first;
03894                             }
03895                         }
03896 #ifdef CONFIG_RSBAC_RMSG
03897                       rsbac_printk(KERN_INFO
03898                              "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to file %u on device %02u:%02u!\n",
03899                              range.first,
03900                              attr_val.auth_program_file.inode,
03901                              MAJOR(attr_val.auth_program_file.device),
03902                              MINOR(attr_val.auth_program_file.device));
03903 #endif
03904 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03905                       if (!rsbac_nosyslog)
03906 #endif
03907                       printk(KERN_INFO
03908                              "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to file %u on device %02u:%02u!\n",
03909                              range.first,
03910                              attr_val.auth_program_file.inode,
03911                              MAJOR(attr_val.auth_program_file.device),
03912                              MINOR(attr_val.auth_program_file.device));
03913                       rsbac_read_lock(&device_list_head.lock, &dflags);
03914                       device_p = lookup_device(attr_val.auth_program_file.device);
03915                       if(device_p)
03916                         {
03917                           rsbac_list_lol_subadd(device_p->eff_handles[eff_fd_hash(attr_val.auth_program_file.inode)],
03918                                                 &attr_val.auth_program_file.inode, &range, NULL);
03919                         }
03920                       else
03921                         {
03922 #ifdef CONFIG_RSBAC_RMSG
03923                           rsbac_printk(KERN_INFO
03924                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03925                                  MAJOR(attr_val.auth_program_file.device),
03926                                  MINOR(attr_val.auth_program_file.device));
03927 #endif
03928 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03929                           if (!rsbac_nosyslog)
03930 #endif
03931                           printk(KERN_INFO
03932                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03933                                  MAJOR(attr_val.auth_program_file.device),
03934                                  MINOR(attr_val.auth_program_file.device));
03935                         }
03936                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03937                     }
03938                   result = TRUE;
03939                 }
03940             }
03941           #endif
03942           break;
03943 
03944         case ACT_fs:
03945           result = rsbac_list_lol_subexist_compare(process_fs_handle, &pid, &member, single_cap_compare);
03946 
03947           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03948           if(   !result
03949              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03950             )
03951             {
03952               union rsbac_target_id_t tid;
03953               union rsbac_attribute_value_t attr_val;
03954               rsbac_boolean_t learn;
03955 
03956               learn = rsbac_auth_learn;
03957               if(!learn)
03958                 {
03959                   tid.process = pid;
03960                   /* check learn on process */
03961                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03962                     learn = attr_val.auth_learn;
03963                 }
03964               if(learn)
03965                 {
03966                   struct rsbac_auth_cap_range_t range;
03967 
03968 #ifdef CONFIG_RSBAC_RMSG
03969                   rsbac_printk(KERN_INFO
03970                          "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to process %u (%.15s)!\n",
03971                          member,
03972                          pid,
03973                          current->comm);
03974 #endif
03975 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
03976                   if (!rsbac_nosyslog)
03977 #endif
03978                   printk(KERN_INFO
03979                          "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to process %u (%.15s)!\n",
03980                          member,
03981                          pid,
03982                          current->comm);
03983                   range.first = member;
03984                   range.last = member;
03985                   rsbac_list_lol_subadd(process_fs_handle, &pid, &range, NULL);
03986 
03987                   tid.process = pid;
03988                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03989                     {
03990                       struct rsbac_auth_device_list_item_t * device_p;
03991                       union rsbac_attribute_value_t attr_val2;
03992                       u_long dflags;
03993 
03994                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
03995                         {
03996                           if(range.first == attr_val2.auth_start_uid)
03997                             {
03998                               range.first = RSBAC_AUTH_OWNER_F_CAP;
03999                               range.last = range.first;
04000                             }
04001                         }
04002 #ifdef CONFIG_RSBAC_RMSG
04003                       rsbac_printk(KERN_INFO
04004                              "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to file %u on device %02u:%02u!\n",
04005                              range.first,
04006                              attr_val.auth_program_file.inode,
04007                              MAJOR(attr_val.auth_program_file.device),
04008                              MINOR(attr_val.auth_program_file.device));
04009 #endif
04010 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04011                       if (!rsbac_nosyslog)
04012 #endif
04013                       printk(KERN_INFO
04014                              "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to file %u on device %02u:%02u!\n",
04015                              range.first,
04016                              attr_val.auth_program_file.inode,
04017                              MAJOR(attr_val.auth_program_file.device),
04018                              MINOR(attr_val.auth_program_file.device));
04019                       rsbac_read_lock(&device_list_head.lock, &dflags);
04020                       device_p = lookup_device(attr_val.auth_program_file.device);
04021                       if(device_p)
04022                         {
04023                           rsbac_list_lol_subadd(device_p->fs_handles[fs_fd_hash(attr_val.auth_program_file.inode)],
04024                                                 &attr_val.auth_program_file.inode, &range, NULL);
04025                         }
04026                       else
04027                         {
04028 #ifdef CONFIG_RSBAC_RMSG
04029                           rsbac_printk(KERN_INFO
04030                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04031                                  MAJOR(attr_val.auth_program_file.device),
04032                                  MINOR(attr_val.auth_program_file.device));
04033 #endif
04034 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04035                           if (!rsbac_nosyslog)
04036 #endif
04037                           printk(KERN_INFO
04038                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04039                                  MAJOR(attr_val.auth_program_file.device),
04040                                  MINOR(attr_val.auth_program_file.device));
04041                         }
04042                       rsbac_read_unlock(&device_list_head.lock, &dflags);
04043                     }
04044                   result = TRUE;
04045                 }
04046             }
04047           #endif
04048           break;
04049 #endif /* AUTH_DAC_OWNER */
04050 
04051 #ifdef CONFIG_RSBAC_AUTH_GROUP
04052         case ACT_group_real:
04053           result = rsbac_list_lol_subexist_compare(process_group_handle, &pid, &member, single_cap_compare);
04054 
04055           #if defined(CONFIG_RSBAC_AUTH_LEARN)
04056           if(   !result
04057              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
04058             )
04059             {
04060               union rsbac_target_id_t tid;
04061               union rsbac_attribute_value_t attr_val;
04062               rsbac_boolean_t learn;
04063 
04064               learn = rsbac_auth_learn;
04065               if(!learn)
04066                 {
04067                   tid.process = pid;
04068                   /* check learn on process */
04069                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
04070                     learn = attr_val.auth_learn;
04071                 }
04072               if(learn)
04073                 {
04074                   struct rsbac_auth_cap_range_t range;
04075 
04076 #ifdef CONFIG_RSBAC_RMSG
04077                   rsbac_printk(KERN_INFO
04078                          "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to process %u (%.15s)!\n",
04079                          member,
04080                          pid,
04081                          current->comm);
04082 #endif
04083 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04084                   if (!rsbac_nosyslog)
04085 #endif
04086                   printk(KERN_INFO
04087                          "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to process %u (%.15s)!\n",
04088                          member,
04089                          pid,
04090                          current->comm);
04091                   range.first = member;
04092                   range.last = member;
04093                   rsbac_list_lol_subadd(process_group_handle, &pid, &range, NULL);
04094 
04095                   tid.process = pid;
04096                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
04097                     {
04098                       struct rsbac_auth_device_list_item_t * device_p;
04099                       union rsbac_attribute_value_t attr_val2;
04100                       u_long dflags;
04101 
04102                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
04103                         {
04104                           if(range.first == attr_val2.auth_start_uid)
04105                             {
04106                               range.first = RSBAC_AUTH_OWNER_F_CAP;
04107                               range.last = range.first;
04108                             }
04109                         }
04110 #ifdef CONFIG_RSBAC_RMSG
04111                       rsbac_printk(KERN_INFO
04112                              "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to file %u on device %02u:%02u!\n",
04113                              range.first,
04114                              attr_val.auth_program_file.inode,
04115                              MAJOR(attr_val.auth_program_file.device),
04116                              MINOR(attr_val.auth_program_file.device));
04117 #endif
04118 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04119                       if (!rsbac_nosyslog)
04120 #endif
04121                       printk(KERN_INFO
04122                              "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to file %u on device %02u:%02u!\n",
04123                              range.first,
04124                              attr_val.auth_program_file.inode,
04125                              MAJOR(attr_val.auth_program_file.device),
04126                              MINOR(attr_val.auth_program_file.device));
04127                       rsbac_read_lock(&device_list_head.lock, &dflags);
04128                       device_p = lookup_device(attr_val.auth_program_file.device);
04129                       if(device_p)
04130                         {
04131                           rsbac_list_lol_subadd(device_p->group_handles[group_fd_hash(attr_val.auth_program_file.inode)],
04132                                                 &attr_val.auth_program_file.inode, &range, NULL);
04133                         }
04134                       else
04135                         {
04136 #ifdef CONFIG_RSBAC_RMSG
04137                           rsbac_printk(KERN_INFO
04138                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04139                                  MAJOR(attr_val.auth_program_file.device),
04140                                  MINOR(attr_val.auth_program_file.device));
04141 #endif
04142 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04143                           if (!rsbac_nosyslog)
04144 #endif
04145                           printk(KERN_INFO
04146                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04147                                  MAJOR(attr_val.auth_program_file.device),
04148                                  MINOR(attr_val.auth_program_file.device));
04149                         }
04150                       rsbac_read_unlock(&device_list_head.lock, &dflags);
04151                     }
04152                   result = TRUE;
04153                 }
04154             }
04155           #endif
04156           break;
04157 
04158 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04159         case ACT_group_eff:
04160           result = rsbac_list_lol_subexist_compare(process_group_eff_handle, &pid, &member, single_cap_compare);
04161 
04162           #if defined(CONFIG_RSBAC_AUTH_LEARN)
04163           if(   !result
04164              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
04165             )
04166             {
04167               union rsbac_target_id_t tid;
04168               union rsbac_attribute_value_t attr_val;
04169               rsbac_boolean_t learn;
04170 
04171               learn = rsbac_auth_learn;
04172               if(!learn)
04173                 {
04174                   tid.process = pid;
04175                   /* check learn on process */
04176                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
04177                     learn = attr_val.auth_learn;
04178                 }
04179               if(learn)
04180                 {
04181                   struct rsbac_auth_cap_range_t range;
04182 
04183 #ifdef CONFIG_RSBAC_RMSG
04184                   rsbac_printk(KERN_INFO
04185                          "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to process %u (%.15s)!\n",
04186                          member,
04187                          pid,
04188                          current->comm);
04189 #endif
04190 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04191                   if (!rsbac_nosyslog)
04192 #endif
04193                   printk(KERN_INFO
04194                          "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to process %u (%.15s)!\n",
04195                          member,
04196                          pid,
04197                          current->comm);
04198                   range.first = member;
04199                   range.last = member;
04200                   rsbac_list_lol_subadd(process_group_eff_handle, &pid, &range, NULL);
04201 
04202                   tid.process = pid;
04203                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
04204                     {
04205                       struct rsbac_auth_device_list_item_t * device_p;
04206                       union rsbac_attribute_value_t attr_val2;
04207                       u_long dflags;
04208 
04209                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
04210                         {
04211                           if(range.first == attr_val2.auth_start_uid)
04212                             {
04213                               range.first = RSBAC_AUTH_OWNER_F_CAP;
04214                               range.last = range.first;
04215                             }
04216                         }
04217 #ifdef CONFIG_RSBAC_RMSG
04218                       rsbac_printk(KERN_INFO
04219                              "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to file %u on device %02u:%02u!\n",
04220                              range.first,
04221                              attr_val.auth_program_file.inode,
04222                              MAJOR(attr_val.auth_program_file.device),
04223                              MINOR(attr_val.auth_program_file.device));
04224 #endif
04225 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04226                       if (!rsbac_nosyslog)
04227 #endif
04228                       printk(KERN_INFO
04229                              "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to file %u on device %02u:%02u!\n",
04230                              range.first,
04231                              attr_val.auth_program_file.inode,
04232                              MAJOR(attr_val.auth_program_file.device),
04233                              MINOR(attr_val.auth_program_file.device));
04234                       rsbac_read_lock(&device_list_head.lock, &dflags);
04235                       device_p = lookup_device(attr_val.auth_program_file.device);
04236                       if(device_p)
04237                         {
04238                           rsbac_list_lol_subadd(device_p->group_eff_handles[group_eff_fd_hash(attr_val.auth_program_file.inode)],
04239                                                 &attr_val.auth_program_file.inode, &range, NULL);
04240                         }
04241                       else
04242                         {
04243 #ifdef CONFIG_RSBAC_RMSG
04244                           rsbac_printk(KERN_INFO
04245                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04246                                  MAJOR(attr_val.auth_program_file.device),
04247                                  MINOR(attr_val.auth_program_file.device));
04248 #endif
04249 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04250                           if (!rsbac_nosyslog)
04251 #endif
04252                           printk(KERN_INFO
04253                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04254                                  MAJOR(attr_val.auth_program_file.device),
04255                                  MINOR(attr_val.auth_program_file.device));
04256                         }
04257                       rsbac_read_unlock(&device_list_head.lock, &dflags);
04258                     }
04259                   result = TRUE;
04260                 }
04261             }
04262           #endif
04263           break;
04264 
04265         case ACT_group_fs:
04266           result = rsbac_list_lol_subexist_compare(process_group_fs_handle, &pid, &member, single_cap_compare);
04267 
04268           #if defined(CONFIG_RSBAC_AUTH_LEARN)
04269           if(   !result
04270              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
04271             )
04272             {
04273               union rsbac_target_id_t tid;
04274               union rsbac_attribute_value_t attr_val;
04275               rsbac_boolean_t learn;
04276 
04277               learn = rsbac_auth_learn;
04278               if(!learn)
04279                 {
04280                   tid.process = pid;
04281                   /* check learn on process */
04282                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
04283                     learn = attr_val.auth_learn;
04284                 }
04285               if(learn)
04286                 {
04287                   struct rsbac_auth_cap_range_t range;
04288 
04289 #ifdef CONFIG_RSBAC_RMSG
04290                   rsbac_printk(KERN_INFO
04291                          "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to process %u (%.15s)!\n",
04292                          member,
04293                          pid,
04294                          current->comm);
04295 #endif
04296 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04297                   if (!rsbac_nosyslog)
04298 #endif
04299                   printk(KERN_INFO
04300                          "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to process %u (%.15s)!\n",
04301                          member,
04302                          pid,
04303                          current->comm);
04304                   range.first = member;
04305                   range.last = member;
04306                   rsbac_list_lol_subadd(process_group_fs_handle, &pid, &range, NULL);
04307 
04308                   tid.process = pid;
04309                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
04310                     {
04311                       struct rsbac_auth_device_list_item_t * device_p;
04312                       union rsbac_attribute_value_t attr_val2;
04313                       u_long dflags;
04314 
04315                       if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE))
04316                         {
04317                           if(range.first == attr_val2.auth_start_uid)
04318                             {
04319                               range.first = RSBAC_AUTH_OWNER_F_CAP;
04320                               range.last = range.first;
04321                             }
04322                         }
04323 #ifdef CONFIG_RSBAC_RMSG
04324                       rsbac_printk(KERN_INFO
04325                              "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to file %u on device %02u:%02u!\n",
04326                              range.first,
04327                              attr_val.auth_program_file.inode,
04328                              MAJOR(attr_val.auth_program_file.device),
04329                              MINOR(attr_val.auth_program_file.device));
04330 #endif
04331 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04332                       if (!rsbac_nosyslog)
04333 #endif
04334                       printk(KERN_INFO
04335                              "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to file %u on device %02u:%02u!\n",
04336                              range.first,
04337                              attr_val.auth_program_file.inode,
04338                              MAJOR(attr_val.auth_program_file.device),
04339                              MINOR(attr_val.auth_program_file.device));
04340                       rsbac_read_lock(&device_list_head.lock, &dflags);
04341                       device_p = lookup_device(attr_val.auth_program_file.device);
04342                       if(device_p)
04343                         {
04344                           rsbac_list_lol_subadd(device_p->group_fs_handles[group_fs_fd_hash(attr_val.auth_program_file.inode)],
04345                                                 &attr_val.auth_program_file.inode, &range, NULL);
04346                         }
04347                       else
04348                         {
04349 #ifdef CONFIG_RSBAC_RMSG
04350                           rsbac_printk(KERN_INFO
04351                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04352                                  MAJOR(attr_val.auth_program_file.device),
04353                                  MINOR(attr_val.auth_program_file.device));
04354 #endif
04355 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04356                           if (!rsbac_nosyslog)
04357 #endif
04358                           printk(KERN_INFO
04359                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
04360                                  MAJOR(attr_val.auth_program_file.device),
04361                                  MINOR(attr_val.auth_program_file.device));
04362                         }
04363                       rsbac_read_unlock(&device_list_head.lock, &dflags);
04364                     }
04365                   result = TRUE;
04366                 }
04367             }
04368           #endif
04369           break;
04370 #endif /* AUTH_DAC_GROUP */
04371 #endif /* AUTH_GROUP */
04372 
04373         default:
04374           return FALSE;
04375       }
04376     return result;
04377   }
04378 
04379 /* rsbac_auth_remove_capset */
04380 /* Remove a full set. For cleanup, if object is deleted. */
04381 /* To empty an existing set use rsbac_auth_clear_capset. */
04382 
04383 int rsbac_auth_remove_p_capsets(rsbac_pid_t pid)
04384   {
04385     int err;
04386 
04387     err = rsbac_auth_clear_p_capset(0, pid, ACT_real);
04388 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04389     err = rsbac_auth_clear_p_capset(0, pid, ACT_eff);
04390     err = rsbac_auth_clear_p_capset(0, pid, ACT_fs);
04391 #endif
04392 #ifdef CONFIG_RSBAC_AUTH_GROUP
04393     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_real);
04394 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04395     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_eff);
04396     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_fs);
04397 #endif
04398 #endif /* AUTH_GROUP */
04399 
04400     return err;
04401   }
04402 
04403 int rsbac_auth_remove_f_capsets(rsbac_auth_file_t file)
04404   {
04405     int err;
04406 
04407     err = rsbac_auth_clear_f_capset(0, file, ACT_real);
04408 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04409     if(!err)
04410       err = rsbac_auth_clear_f_capset(0, file, ACT_eff);
04411     if(!err)
04412       err = rsbac_auth_clear_f_capset(0, file, ACT_fs);
04413 #endif
04414 #ifdef CONFIG_RSBAC_AUTH_GROUP
04415     err = rsbac_auth_clear_f_capset(0, file, ACT_group_real);
04416 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04417     if(!err)
04418       err = rsbac_auth_clear_f_capset(0, file, ACT_group_eff);
04419     if(!err)
04420       err = rsbac_auth_clear_f_capset(0, file, ACT_group_fs);
04421 #endif
04422 #endif /* AUTH_GROUP */
04423 
04424     return err;
04425   }
04426 
04427 int rsbac_auth_copy_fp_capset(rsbac_auth_file_t    file,
04428                               rsbac_pid_t p_cap_set_id)
04429   {
04430     u_long dflags;
04431     struct rsbac_auth_device_list_item_t * device_p;
04432     int err=0;
04433 
04434     if (!rsbac_is_initialized())
04435       {
04436         printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): RSBAC not initialized\n");
04437         return(-RSBAC_ENOTINITIALIZED);
04438       }
04439     if (in_interrupt())
04440       {
04441         printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): called from interrupt!\n");
04442       }
04443 /*
04444 #ifdef CONFIG_RSBAC_DEBUG
04445     if (rsbac_debug_ds_auth)
04446       printk(KERN_DEBUG
04447              "rsbac_auth_copy_fp_capset(): Copying file cap set data to process cap set\n");
04448 #endif
04449 */
04450     /* protect device list */
04451     rsbac_read_lock(&device_list_head.lock, &dflags);
04452     device_p = lookup_device(file.device);
04453     if(!device_p)
04454       {
04455         /* trigger rsbac_mount() */
04456         rsbac_read_unlock(&device_list_head.lock, &dflags);
04457         rsbac_get_super_block(file.device);
04458         /* retry */
04459         rsbac_read_lock(&device_list_head.lock, &dflags);
04460         device_p = lookup_device(file.device);
04461         if(!device_p)
04462           {
04463 #ifdef CONFIG_RSBAC_RMSG
04464             rsbac_printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): invalid device %02u:%02u!\n",
04465                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
04466 #endif
04467 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04468             if (!rsbac_nosyslog)
04469 #endif
04470             printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): invalid device %02u:%02u!\n",
04471                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
04472             rsbac_read_unlock(&device_list_head.lock, &dflags);
04473             return(-RSBAC_EINVALIDDEV);
04474           }
04475       }
04476     /* call the copy function */
04477     err = copy_fp_cap_set_item(device_p,file,p_cap_set_id);
04478     rsbac_read_unlock(&device_list_head.lock, &dflags);
04479     return(err);
04480   }
04481 
04482 int rsbac_auth_copy_pp_capset(rsbac_pid_t old_p_set_id,
04483                               rsbac_pid_t new_p_set_id)
04484   {
04485     if (!rsbac_is_initialized())
04486       {
04487         printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): RSBAC not initialized\n");
04488         return(-RSBAC_ENOTINITIALIZED);
04489       }
04490     if (in_interrupt())
04491       {
04492         printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): called from interrupt!\n");
04493       }
04494 /*
04495 #ifdef CONFIG_RSBAC_DEBUG
04496     if (rsbac_debug_ds_auth)
04497       printk(KERN_DEBUG
04498              "rsbac_auth_copy_pp_capset(): Copying process cap set data to process cap set\n");
04499 #endif
04500 */
04501     /* call the copy function */
04502     return copy_pp_cap_set_item(old_p_set_id,new_p_set_id);
04503   }
04504 
04505 int rsbac_auth_get_f_caplist(
04506          rsbac_list_ta_number_t ta_number,
04507          rsbac_auth_file_t file,
04508   enum   rsbac_auth_cap_type_t cap_type,
04509   struct rsbac_auth_cap_range_t **caplist_p,
04510          rsbac_time_t **ttllist_p)
04511   {
04512     u_long dflags;
04513     struct rsbac_auth_device_list_item_t * device_p;
04514     long count;
04515 
04516     if (!rsbac_is_initialized())
04517       {
04518         printk(KERN_WARNING "rsbac_auth_get_f_caplist(): RSBAC not initialized\n");
04519         return(-RSBAC_ENOTINITIALIZED);
04520       }
04521     if (in_interrupt())
04522       {
04523         printk(KERN_WARNING "rsbac_auth_get_f_caplist(): called from interrupt!\n");
04524       }
04525 /*
04526 #ifdef CONFIG_RSBAC_DEBUG
04527     if (rsbac_debug_ds_auth)
04528       printk(KERN_DEBUG
04529              "rsbac_auth_get_f_caplist(): Getting file/dir cap set list\n");
04530 #endif
04531 */
04532     /* protect device list */
04533     rsbac_read_lock(&device_list_head.lock, &dflags);
04534     device_p = lookup_device(file.device);
04535     if(!device_p)
04536       {
04537         /* trigger rsbac_mount() */
04538         rsbac_read_unlock(&device_list_head.lock, &dflags);
04539         rsbac_get_super_block(file.device);
04540         /* retry */
04541         rsbac_read_lock(&device_list_head.lock, &dflags);
04542         device_p = lookup_device(file.device);
04543         if(!device_p)
04544           {
04545 #ifdef CONFIG_RSBAC_RMSG
04546             rsbac_printk(KERN_WARNING "rsbac_auth_get_f_caplist(): invalid device %02u:%02u!\n",
04547                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
04548 #endif
04549 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
04550             if (!rsbac_nosyslog)
04551 #endif
04552             printk(KERN_WARNING "rsbac_auth_get_f_caplist(): invalid device %02u:%02u!\n",
04553                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
04554             rsbac_read_unlock(&device_list_head.lock, &dflags);
04555             return(-RSBAC_EINVALIDDEV);
04556           }
04557       }
04558     switch(cap_type)
04559       {
04560         case ACT_real:
04561           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04562                                                      device_p->handles[fd_hash(file.inode)],
04563                                                      &file.inode,
04564                                                      (void **) caplist_p,
04565                                                      ttllist_p);
04566           break;
04567 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04568         case ACT_eff:
04569           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04570                                                      device_p->eff_handles[eff_fd_hash(file.inode)],
04571                                                      &file.inode,
04572                                                      (void **) caplist_p,
04573                                                      ttllist_p);
04574           break;
04575         case ACT_fs:
04576           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04577                                                      device_p->fs_handles[fs_fd_hash(file.inode)],
04578                                                      &file.inode,
04579                                                      (void **) caplist_p,
04580                                                      ttllist_p);
04581           break;
04582 #endif
04583 #ifdef CONFIG_RSBAC_AUTH_GROUP
04584         case ACT_group_real:
04585           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04586                                                      device_p->group_handles[group_fd_hash(file.inode)],
04587                                                      &file.inode,
04588                                                      (void **) caplist_p,
04589                                                      ttllist_p);
04590           break;
04591 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04592         case ACT_group_eff:
04593           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04594                                                      device_p->group_eff_handles[group_eff_fd_hash(file.inode)],
04595                                                      &file.inode,
04596                                                      (void **) caplist_p,
04597                                                      ttllist_p);
04598           break;
04599         case ACT_group_fs:
04600           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04601                                                      device_p->group_fs_handles[group_fs_fd_hash(file.inode)],
04602                                                      &file.inode,
04603                                                      (void **) caplist_p,
04604                                                      ttllist_p);
04605           break;
04606 #endif
04607 #endif /* AUTH_GROUP */
04608 
04609         default:
04610           count = -RSBAC_EINVALIDTARGET;
04611       }
04612     rsbac_read_unlock(&device_list_head.lock, &dflags);
04613     return(count);
04614   }
04615 
04616 int rsbac_auth_get_p_caplist(
04617          rsbac_list_ta_number_t ta_number,
04618          rsbac_pid_t pid,
04619   enum   rsbac_auth_cap_type_t cap_type,
04620   struct rsbac_auth_cap_range_t **caplist_p,
04621          rsbac_time_t **ttllist_p)
04622   {
04623     long count;
04624 
04625     if (!rsbac_is_initialized())
04626       {
04627         printk(KERN_WARNING "rsbac_auth_get_p_caplist(): RSBAC not initialized\n");
04628         return(-RSBAC_ENOTINITIALIZED);
04629       }
04630     if (in_interrupt())
04631       {
04632         printk(KERN_WARNING "rsbac_auth_get_p_caplist(): called from interrupt!\n");
04633       }
04634 /*
04635 #ifdef CONFIG_RSBAC_DEBUG
04636     if (rsbac_debug_ds_auth)
04637       printk(KERN_DEBUG
04638              "rsbac_auth_get_p_caplist(): Getting process cap set list\n");
04639 #endif
04640 */
04641     switch(cap_type)
04642       {
04643         case ACT_real:
04644           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04645                                                      process_handle,
04646                                                      &pid,
04647                                                      (void **) caplist_p,
04648                                                      ttllist_p);
04649           break;
04650 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04651         case ACT_eff:
04652           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04653                                                      process_eff_handle,
04654                                                      &pid,
04655                                                      (void **) caplist_p,
04656                                                      ttllist_p);
04657           break;
04658         case ACT_fs:
04659           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04660                                                      process_fs_handle,
04661                                                      &pid,
04662                                                      (void **) caplist_p,
04663                                                      ttllist_p);
04664           break;
04665 #endif
04666 #ifdef CONFIG_RSBAC_AUTH_GROUP
04667         case ACT_group_real:
04668           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04669                                                      process_group_handle,
04670                                                      &pid,
04671                                                      (void **) caplist_p,
04672                                                      ttllist_p);
04673           break;
04674 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04675         case ACT_group_eff:
04676           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04677                                                      process_group_eff_handle,
04678                                                      &pid,
04679                                                      (void **) caplist_p,
04680                                                      ttllist_p);
04681           break;
04682         case ACT_group_fs:
04683           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04684                                                      process_group_fs_handle,
04685                                                      &pid,
04686                                                      (void **) caplist_p,
04687                                                      ttllist_p);
04688           break;
04689 #endif
04690 #endif /* AUTH_GROUP */
04691 
04692         default:
04693           count = -RSBAC_EINVALIDTARGET;
04694       }
04695     return(count);
04696   }
04697 
04698 /* end of auth_data_structures.c */

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