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: 22/Apr/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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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                 rsbac_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         rsbac_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       rsbac_printk(KERN_DEBUG "stats_auth_proc_info(): calling ADF\n");
01163 #endif
01164     rsbac_target_id.scd = ST_rsbac;
01165     rsbac_attribute_value.dummy = 0;
01166     if (!rsbac_adf_request(R_GET_STATUS_DATA,
01167                            current->pid,
01168                            T_SCD,
01169                            rsbac_target_id,
01170                            A_none,
01171                            rsbac_attribute_value))
01172       {
01173         return -EPERM;
01174       }
01175 
01176     len += sprintf(buffer, "AUTH Status\n-----------\n");
01177 
01178     len += sprintf(buffer + len, "%lu process cap set items, sum of %lu members\n",
01179                    rsbac_list_lol_count(process_handle),
01180                    rsbac_list_lol_all_subcount(process_handle));
01181     pos = begin + len;
01182     if (pos < offset)
01183       {
01184         len = 0;
01185         begin = pos;
01186       }
01187     if (pos > offset+length)
01188       goto out;
01189 
01190 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01191     len += sprintf(buffer + len, "%lu process eff cap set items, sum of %lu members\n",
01192                    rsbac_list_lol_count(process_eff_handle),
01193                    rsbac_list_lol_all_subcount(process_eff_handle));
01194     pos = begin + len;
01195     if (pos < offset)
01196       {
01197         len = 0;
01198         begin = pos;
01199       }
01200     if (pos > offset+length)
01201       goto out;
01202     len += sprintf(buffer + len, "%lu process fs cap set items, sum of %lu members\n",
01203                    rsbac_list_lol_count(process_fs_handle),
01204                    rsbac_list_lol_all_subcount(process_fs_handle));
01205     pos = begin + len;
01206     if (pos < offset)
01207       {
01208         len = 0;
01209         begin = pos;
01210       }
01211     if (pos > offset+length)
01212       goto out;
01213 #endif
01214 
01215 #ifdef CONFIG_RSBAC_AUTH_GROUP
01216     len += sprintf(buffer + len, "%lu process group cap set items, sum of %lu members\n",
01217                    rsbac_list_lol_count(process_group_handle),
01218                    rsbac_list_lol_all_subcount(process_group_handle));
01219     pos = begin + len;
01220     if (pos < offset)
01221       {
01222         len = 0;
01223         begin = pos;
01224       }
01225     if (pos > offset+length)
01226       goto out;
01227 
01228 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01229     len += sprintf(buffer + len, "%lu process group eff cap set items, sum of %lu members\n",
01230                    rsbac_list_lol_count(process_group_eff_handle),
01231                    rsbac_list_lol_all_subcount(process_group_eff_handle));
01232     pos = begin + len;
01233     if (pos < offset)
01234       {
01235         len = 0;
01236         begin = pos;
01237       }
01238     if (pos > offset+length)
01239       goto out;
01240     len += sprintf(buffer + len, "%lu process group fs cap set items, sum of %lu members\n",
01241                    rsbac_list_lol_count(process_group_fs_handle),
01242                    rsbac_list_lol_all_subcount(process_group_fs_handle));
01243     pos = begin + len;
01244     if (pos < offset)
01245       {
01246         len = 0;
01247         begin = pos;
01248       }
01249     if (pos > offset+length)
01250       goto out;
01251 #endif
01252 #endif /* AUTH_GROUP */
01253 
01254     /* protect device list */
01255     rsbac_read_lock(&device_list_head.lock, &dflags);
01256     device_p = device_list_head.head;
01257     while(device_p)
01258       {
01259         /* reset counters */
01260         cap_set_count = 0;
01261         member_count = 0;
01262         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++)
01263           {
01264             cap_set_count += rsbac_list_lol_count(device_p->handles[i]);
01265             member_count += rsbac_list_lol_all_subcount(device_p->handles[i]);
01266           }
01267         len += sprintf(buffer + len, "device %02u:%02u has %u file cap set items, sum of %u members\n",
01268                        RSBAC_MAJOR(device_p->id),
01269                        RSBAC_MINOR(device_p->id),
01270                        cap_set_count,member_count);
01271         pos = begin + len;
01272         if (pos < offset)
01273           {
01274             len = 0;
01275             begin = pos;
01276           }
01277         if (pos > offset+length)
01278           goto out_unlock;
01279 
01280 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01281         cap_set_count = 0;
01282         member_count = 0;
01283         for(i=0 ; i < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; i++)
01284           {
01285             cap_set_count += rsbac_list_lol_count(device_p->eff_handles[i]);
01286             member_count += rsbac_list_lol_all_subcount(device_p->eff_handles[i]);
01287           }
01288         len += sprintf(buffer + len, "device %02u:%02u has %u file eff cap set items, sum of %u members\n",
01289                        RSBAC_MAJOR(device_p->id),
01290                        RSBAC_MINOR(device_p->id),
01291                        cap_set_count,member_count);
01292         pos = begin + len;
01293         if (pos < offset)
01294           {
01295             len = 0;
01296             begin = pos;
01297           }
01298         if (pos > offset+length)
01299           goto out_unlock;
01300         cap_set_count = 0;
01301         member_count = 0;
01302         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; i++)
01303           {
01304             cap_set_count += rsbac_list_lol_count(device_p->fs_handles[i]);
01305             member_count += rsbac_list_lol_all_subcount(device_p->fs_handles[i]);
01306           }
01307         len += sprintf(buffer + len, "device %02u:%02u has %u file fs cap set items, sum of %u members\n",
01308                        RSBAC_MAJOR(device_p->id),
01309                        RSBAC_MINOR(device_p->id),
01310                        cap_set_count,member_count);
01311         pos = begin + len;
01312         if (pos < offset)
01313           {
01314             len = 0;
01315             begin = pos;
01316           }
01317         if (pos > offset+length)
01318           goto out_unlock;
01319 #endif
01320 
01321 #ifdef CONFIG_RSBAC_AUTH_GROUP
01322         cap_set_count = 0;
01323         member_count = 0;
01324         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; i++)
01325           {
01326             cap_set_count += rsbac_list_lol_count(device_p->group_handles[i]);
01327             member_count += rsbac_list_lol_all_subcount(device_p->group_handles[i]);
01328           }
01329         len += sprintf(buffer + len, "device %02u:%02u has %u file group cap set items, sum of %u members\n",
01330                        RSBAC_MAJOR(device_p->id),
01331                        RSBAC_MINOR(device_p->id),
01332                        cap_set_count,member_count);
01333         pos = begin + len;
01334         if (pos < offset)
01335           {
01336             len = 0;
01337             begin = pos;
01338           }
01339         if (pos > offset+length)
01340           goto out_unlock;
01341 
01342 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01343         cap_set_count = 0;
01344         member_count = 0;
01345         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; i++)
01346           {
01347             cap_set_count += rsbac_list_lol_count(device_p->group_eff_handles[i]);
01348             member_count += rsbac_list_lol_all_subcount(device_p->group_eff_handles[i]);
01349           }
01350         len += sprintf(buffer + len, "device %02u:%02u has %u file group eff cap set items, sum of %u members\n",
01351                        RSBAC_MAJOR(device_p->id),
01352                        RSBAC_MINOR(device_p->id),
01353                        cap_set_count,member_count);
01354         pos = begin + len;
01355         if (pos < offset)
01356           {
01357             len = 0;
01358             begin = pos;
01359           }
01360         if (pos > offset+length)
01361           goto out_unlock;
01362         cap_set_count = 0;
01363         member_count = 0;
01364         for(i=0 ; i < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; i++)
01365           {
01366             cap_set_count += rsbac_list_lol_count(device_p->group_fs_handles[i]);
01367             member_count += rsbac_list_lol_all_subcount(device_p->group_fs_handles[i]);
01368           }
01369         len += sprintf(buffer + len, "device %02u:%02u has %u file group fs cap set items, sum of %u members\n",
01370                        RSBAC_MAJOR(device_p->id),
01371                        RSBAC_MINOR(device_p->id),
01372                        cap_set_count,member_count);
01373         pos = begin + len;
01374         if (pos < offset)
01375           {
01376             len = 0;
01377             begin = pos;
01378           }
01379         if (pos > offset+length)
01380           goto out_unlock;
01381 #endif
01382 #endif /* AUTH_GROUP */
01383 
01384         device_p = device_p->next;
01385       }
01386 out_unlock:
01387     /* unprotect device list */
01388     rsbac_read_unlock(&device_list_head.lock, &dflags);
01389 
01390 out:
01391   *start = buffer + (offset - begin);
01392   len -= (offset - begin);
01393   
01394   if (len > length)
01395     len = length;
01396   return len;
01397 }
01398 
01399 static int
01400 auth_caplist_proc_info(char *buffer, char **start, off_t offset, int length)
01401 {
01402     u_int len = 0;
01403     off_t pos   = 0;
01404     off_t begin = 0;
01405 
01406     u_int                                      count = 0;
01407     u_int                                      member_count = 0;
01408     u_long                                     all_count;
01409     u_long                                     all_member_count;
01410     u_long dflags;
01411     int i,j,list;
01412     struct rsbac_auth_device_list_item_t   * device_p;
01413     rsbac_pid_t * p_list;
01414     rsbac_inode_nr_t * f_list;
01415     struct rsbac_auth_cap_range_t * cap_list;
01416 
01417     union rsbac_target_id_t       rsbac_target_id;
01418     union rsbac_attribute_value_t rsbac_attribute_value;
01419 
01420     if (!rsbac_is_initialized())
01421       {
01422         rsbac_printk(KERN_WARNING "auth_caplist_proc_info(): RSBAC not initialized\n");
01423         return(-RSBAC_ENOTINITIALIZED);
01424       }
01425 #ifdef CONFIG_RSBAC_DEBUG
01426     if (rsbac_debug_aef_auth)
01427       rsbac_printk(KERN_DEBUG "auth_caplist_proc_info(): calling ADF\n");
01428 #endif
01429     rsbac_target_id.scd = ST_rsbac;
01430     rsbac_attribute_value.dummy = 0;
01431     if (!rsbac_adf_request(R_GET_STATUS_DATA,
01432                            current->pid,
01433                            T_SCD,
01434                            rsbac_target_id,
01435                            A_none,
01436                            rsbac_attribute_value))
01437       {
01438         return -EPERM;
01439       }
01440 
01441     len += sprintf(buffer, "AUTH Cap Lists\n--------------\n");
01442 
01443     len += sprintf(buffer + len, "Process capabilities:\nset-id  count   cap-members");
01444     pos = begin + len;
01445     if (pos < offset)
01446       {
01447         len = 0;
01448         begin = pos;
01449       }
01450     if (pos > offset+length)
01451       goto out;
01452 
01453     all_member_count = 0;
01454     count = rsbac_list_lol_get_all_desc(process_handle,
01455                                         (void **) &p_list);
01456     if(count > 0)
01457       {
01458         for(i=0; i<count; i++)
01459           {
01460             member_count = rsbac_list_lol_get_all_subdesc(process_handle,
01461                                                           &p_list[i],
01462                                                           (void **) &cap_list);
01463             len += sprintf(buffer + len, "\n %u\t%u\t",
01464                            p_list[i],
01465                            member_count);
01466             if(member_count > 0)
01467               {
01468                 for(j=0; j<member_count; j++)
01469                   {
01470                     if(cap_list[j].first != cap_list[j].last)
01471                       len += sprintf(buffer + len, "%u:%u ",
01472                                      cap_list[j].first,
01473                                      cap_list[j].last);
01474                     else
01475                       len += sprintf(buffer + len, "%u ",
01476                                      cap_list[j].first);
01477                     pos = begin + len;
01478                     if (pos < offset)
01479                       {
01480                         len = 0;
01481                         begin = pos;
01482                       }
01483                     if (pos > offset+length)
01484                       {
01485                         rsbac_vfree(cap_list);
01486                         rsbac_vfree(p_list);
01487                         goto out;
01488                       }
01489                   }
01490                 rsbac_vfree(cap_list);
01491                 all_member_count += member_count;
01492               }
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(p_list);
01502                 goto out;
01503               }
01504           }
01505         rsbac_vfree(p_list);
01506       }
01507     len += sprintf(buffer + len, "\n%u process cap set items, sum of %lu members\n",
01508                    count,all_member_count);
01509     pos = begin + len;
01510     if (pos < offset)
01511       {
01512         len = 0;
01513         begin = pos;
01514       }
01515     if (pos > offset+length)
01516       goto out;
01517 
01518 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01519     len += sprintf(buffer + len, "\nProcess eff capabilities:\nset-id  count   cap-members");
01520     pos = begin + len;
01521     if (pos < offset)
01522       {
01523         len = 0;
01524         begin = pos;
01525       }
01526     if (pos > offset+length)
01527       goto out;
01528 
01529     all_member_count = 0;
01530     count = rsbac_list_lol_get_all_desc(process_eff_handle,
01531                                         (void **) &p_list);
01532     if(count > 0)
01533       {
01534         for(i=0; i<count; i++)
01535           {
01536             member_count = rsbac_list_lol_get_all_subdesc(process_eff_handle,
01537                                                           &p_list[i],
01538                                                           (void **) &cap_list);
01539             len += sprintf(buffer + len, "\n %u\t%u\t",
01540                            p_list[i],
01541                            member_count);
01542             if(member_count > 0)
01543               {
01544                 for(j=0; j<member_count; j++)
01545                   {
01546                     if(cap_list[j].first != cap_list[j].last)
01547                       len += sprintf(buffer + len, "%u:%u ",
01548                                      cap_list[j].first,
01549                                      cap_list[j].last);
01550                     else
01551                       len += sprintf(buffer + len, "%u ",
01552                                      cap_list[j].first);
01553                     pos = begin + len;
01554                     if (pos < offset)
01555                       {
01556                         len = 0;
01557                         begin = pos;
01558                       }
01559                     if (pos > offset+length)
01560                       {
01561                         rsbac_vfree(cap_list);
01562                         rsbac_vfree(p_list);
01563                         goto out;
01564                       }
01565                   }
01566                 rsbac_vfree(cap_list);
01567                 all_member_count += member_count;
01568               }
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(p_list);
01578                 goto out;
01579               }
01580           }
01581         rsbac_vfree(p_list);
01582       }
01583     len += sprintf(buffer + len, "\n%u process eff cap set items, sum of %lu members\n",
01584                    count,all_member_count);
01585     pos = begin + len;
01586     if (pos < offset)
01587       {
01588         len = 0;
01589         begin = pos;
01590       }
01591     if (pos > offset+length)
01592       goto out;
01593     len += sprintf(buffer + len, "\nProcess fs capabilities:\nset-id  count   cap-members");
01594     pos = begin + len;
01595     if (pos < offset)
01596       {
01597         len = 0;
01598         begin = pos;
01599       }
01600     if (pos > offset+length)
01601       goto out;
01602 
01603     all_member_count = 0;
01604     count = rsbac_list_lol_get_all_desc(process_fs_handle,
01605                                         (void **) &p_list);
01606     if(count > 0)
01607       {
01608         for(i=0; i<count; i++)
01609           {
01610             member_count = rsbac_list_lol_get_all_subdesc(process_fs_handle,
01611                                                           &p_list[i],
01612                                                           (void **) &cap_list);
01613             len += sprintf(buffer + len, "\n %u\t%u\t",
01614                            p_list[i],
01615                            member_count);
01616             if(member_count > 0)
01617               {
01618                 for(j=0; j<member_count; j++)
01619                   {
01620                     if(cap_list[j].first != cap_list[j].last)
01621                       len += sprintf(buffer + len, "%u:%u ",
01622                                      cap_list[j].first,
01623                                      cap_list[j].last);
01624                     else
01625                       len += sprintf(buffer + len, "%u ",
01626                                      cap_list[j].first);
01627                     pos = begin + len;
01628                     if (pos < offset)
01629                       {
01630                         len = 0;
01631                         begin = pos;
01632                       }
01633                     if (pos > offset+length)
01634                       {
01635                         rsbac_vfree(cap_list);
01636                         rsbac_vfree(p_list);
01637                         goto out;
01638                       }
01639                   }
01640                 rsbac_vfree(cap_list);
01641                 all_member_count += member_count;
01642               }
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(p_list);
01652                 goto out;
01653               }
01654           }
01655         rsbac_vfree(p_list);
01656       }
01657     len += sprintf(buffer + len, "\n\n%u process fs cap set items, sum of %lu members\n",
01658                    count,all_member_count);
01659     pos = begin + len;
01660     if (pos < offset)
01661       {
01662         len = 0;
01663         begin = pos;
01664       }
01665     if (pos > offset+length)
01666       goto out;
01667 #endif
01668 
01669 #ifdef CONFIG_RSBAC_AUTH_GROUP
01670     len += sprintf(buffer + len, "\nProcess group capabilities:\nset-id  count   cap-members");
01671     pos = begin + len;
01672     if (pos < offset)
01673       {
01674         len = 0;
01675         begin = pos;
01676       }
01677     if (pos > offset+length)
01678       goto out;
01679 
01680     all_member_count = 0;
01681     count = rsbac_list_lol_get_all_desc(process_group_handle,
01682                                         (void **) &p_list);
01683     if(count > 0)
01684       {
01685         for(i=0; i<count; i++)
01686           {
01687             member_count = rsbac_list_lol_get_all_subdesc(process_group_handle,
01688                                                           &p_list[i],
01689                                                           (void **) &cap_list);
01690             len += sprintf(buffer + len, "\n %u\t%u\t",
01691                            p_list[i],
01692                            member_count);
01693             if(member_count > 0)
01694               {
01695                 for(j=0; j<member_count; j++)
01696                   {
01697                     if(cap_list[j].first != cap_list[j].last)
01698                       len += sprintf(buffer + len, "%u:%u ",
01699                                      cap_list[j].first,
01700                                      cap_list[j].last);
01701                     else
01702                       len += sprintf(buffer + len, "%u ",
01703                                      cap_list[j].first);
01704                     pos = begin + len;
01705                     if (pos < offset)
01706                       {
01707                         len = 0;
01708                         begin = pos;
01709                       }
01710                     if (pos > offset+length)
01711                       {
01712                         rsbac_vfree(cap_list);
01713                         rsbac_vfree(p_list);
01714                         goto out;
01715                       }
01716                   }
01717                 rsbac_vfree(cap_list);
01718                 all_member_count += member_count;
01719               }
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(p_list);
01729                 goto out;
01730               }
01731           }
01732         rsbac_vfree(p_list);
01733       }
01734     len += sprintf(buffer + len, "\n%u process group cap set items, sum of %lu members\n",
01735                    count,all_member_count);
01736     pos = begin + len;
01737     if (pos < offset)
01738       {
01739         len = 0;
01740         begin = pos;
01741       }
01742     if (pos > offset+length)
01743       goto out;
01744 
01745 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
01746     len += sprintf(buffer + len, "\nProcess group eff capabilities:\nset-id  count   cap-members");
01747     pos = begin + len;
01748     if (pos < offset)
01749       {
01750         len = 0;
01751         begin = pos;
01752       }
01753     if (pos > offset+length)
01754       goto out;
01755 
01756     all_member_count = 0;
01757     count = rsbac_list_lol_get_all_desc(process_group_eff_handle,
01758                                         (void **) &p_list);
01759     if(count > 0)
01760       {
01761         for(i=0; i<count; i++)
01762           {
01763             member_count = rsbac_list_lol_get_all_subdesc(process_group_eff_handle,
01764                                                           &p_list[i],
01765                                                           (void **) &cap_list);
01766             len += sprintf(buffer + len, "\n %u\t%u\t",
01767                            p_list[i],
01768                            member_count);
01769             if(member_count > 0)
01770               {
01771                 for(j=0; j<member_count; j++)
01772                   {
01773                     if(cap_list[j].first != cap_list[j].last)
01774                       len += sprintf(buffer + len, "%u:%u ",
01775                                      cap_list[j].first,
01776                                      cap_list[j].last);
01777                     else
01778                       len += sprintf(buffer + len, "%u ",
01779                                      cap_list[j].first);
01780                     pos = begin + len;
01781                     if (pos < offset)
01782                       {
01783                         len = 0;
01784                         begin = pos;
01785                       }
01786                     if (pos > offset+length)
01787                       {
01788                         rsbac_vfree(cap_list);
01789                         rsbac_vfree(p_list);
01790                         goto out;
01791                       }
01792                   }
01793                 rsbac_vfree(cap_list);
01794                 all_member_count += member_count;
01795               }
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(p_list);
01805                 goto out;
01806               }
01807           }
01808         rsbac_vfree(p_list);
01809       }
01810     len += sprintf(buffer + len, "\n%u process group eff cap set items, sum of %lu members\n",
01811                    count,all_member_count);
01812     pos = begin + len;
01813     if (pos < offset)
01814       {
01815         len = 0;
01816         begin = pos;
01817       }
01818     if (pos > offset+length)
01819       goto out;
01820     len += sprintf(buffer + len, "\nProcess group fs capabilities:\nset-id  count   cap-members");
01821     pos = begin + len;
01822     if (pos < offset)
01823       {
01824         len = 0;
01825         begin = pos;
01826       }
01827     if (pos > offset+length)
01828       goto out;
01829 
01830     all_member_count = 0;
01831     count = rsbac_list_lol_get_all_desc(process_group_fs_handle,
01832                                         (void **) &p_list);
01833     if(count > 0)
01834       {
01835         for(i=0; i<count; i++)
01836           {
01837             member_count = rsbac_list_lol_get_all_subdesc(process_group_fs_handle,
01838                                                           &p_list[i],
01839                                                           (void **) &cap_list);
01840             len += sprintf(buffer + len, "\n %u\t%u\t",
01841                            p_list[i],
01842                            member_count);
01843             if(member_count > 0)
01844               {
01845                 for(j=0; j<member_count; j++)
01846                   {
01847                     if(cap_list[j].first != cap_list[j].last)
01848                       len += sprintf(buffer + len, "%u:%u ",
01849                                      cap_list[j].first,
01850                                      cap_list[j].last);
01851                     else
01852                       len += sprintf(buffer + len, "%u ",
01853                                      cap_list[j].first);
01854                     pos = begin + len;
01855                     if (pos < offset)
01856                       {
01857                         len = 0;
01858                         begin = pos;
01859                       }
01860                     if (pos > offset+length)
01861                       {
01862                         rsbac_vfree(cap_list);
01863                         rsbac_vfree(p_list);
01864                         goto out;
01865                       }
01866                   }
01867                 rsbac_vfree(cap_list);
01868                 all_member_count += member_count;
01869               }
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(p_list);
01879                 goto out;
01880               }
01881           }
01882         rsbac_vfree(p_list);
01883       }
01884     len += sprintf(buffer + len, "\n\n%u process group fs cap set items, sum of %lu members\n",
01885                    count,all_member_count);
01886     pos = begin + len;
01887     if (pos < offset)
01888       {
01889         len = 0;
01890         begin = pos;
01891       }
01892     if (pos > offset+length)
01893       goto out;
01894 #endif
01895 #endif /* AUTH_GROUP */
01896 
01897     len += sprintf(buffer + len, "\nFile capabilities:\nset-id  count   cap-members");
01898     pos = begin + len;
01899     if (pos < offset)
01900       {
01901         len = 0;
01902         begin = pos;
01903       }
01904     if (pos > offset+length)
01905       goto out;
01906 
01907     /* protect device list */
01908     rsbac_read_lock(&device_list_head.lock, &dflags);
01909     device_p = device_list_head.head;
01910     while(device_p)
01911       {
01912         /* reset counters */
01913         all_member_count = 0;
01914         all_count = 0;
01915         for(list=0 ; list < RSBAC_AUTH_NR_CAP_FD_LISTS; list++)
01916           {
01917             count = rsbac_list_lol_get_all_desc(device_p->handles[list],
01918                                                 (void **) &f_list);
01919             if(count > 0)
01920               {
01921                 for(i=0; i<count; i++)
01922                   {
01923                     member_count = rsbac_list_lol_get_all_subdesc(device_p->handles[list],
01924                                                                   &f_list[i],
01925                                                                   (void **) &cap_list);
01926                     len += sprintf(buffer + len, "\n %u\t%u\t",
01927                                    f_list[i],
01928                                    member_count);
01929                     if(member_count > 0)
01930                       {
01931                         for(j=0; j<member_count; j++)
01932                           {
01933                             if(cap_list[j].first != cap_list[j].last)
01934                               len += sprintf(buffer + len, "%u:%u ",
01935                                              cap_list[j].first,
01936                                              cap_list[j].last);
01937                             else
01938                               len += sprintf(buffer + len, "%u ",
01939                                              cap_list[j].first);
01940                             pos = begin + len;
01941                             if (pos < offset)
01942                               {
01943                                 len = 0;
01944                                 begin = pos;
01945                               }
01946                             if (pos > offset+length)
01947                               {
01948                                 rsbac_vfree(cap_list);
01949                                 rsbac_vfree(f_list);
01950                                 goto out_unlock;
01951                               }
01952                           }
01953                         rsbac_vfree(cap_list);
01954                         all_member_count += member_count;
01955                       }
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(f_list);
01965                         goto out_unlock;
01966                       }
01967                   }
01968                 rsbac_vfree(f_list);
01969                 all_count += count;
01970               }
01971           }
01972         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file cap set items, sum of %lu members, list is clean\n",
01973                        RSBAC_MAJOR(device_p->id),
01974                        RSBAC_MINOR(device_p->id),
01975                        all_count, all_member_count);
01976         pos = begin + len;
01977         if (pos < offset)
01978           {
01979             len = 0;
01980             begin = pos;
01981           }
01982         if (pos > offset+length)
01983           goto out_unlock;
01984 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
01985         all_member_count = 0;
01986         all_count = 0;
01987         for(list=0 ; list < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; list++)
01988           {
01989             count = rsbac_list_lol_get_all_desc(device_p->eff_handles[list],
01990                                                 (void **) &f_list);
01991             if(count > 0)
01992               {
01993                 for(i=0; i<count; i++)
01994                   {
01995                     member_count = rsbac_list_lol_get_all_subdesc(device_p->eff_handles[list],
01996                                                                   &f_list[i],
01997                                                                   (void **) &cap_list);
01998                     len += sprintf(buffer + len, "\n %u\t%u\t",
01999                                    f_list[i],
02000                                    member_count);
02001                     if(member_count > 0)
02002                       {
02003                         for(j=0; j<member_count; j++)
02004                           {
02005                             if(cap_list[j].first != cap_list[j].last)
02006                               len += sprintf(buffer + len, "%u:%u ",
02007                                              cap_list[j].first,
02008                                              cap_list[j].last);
02009                             else
02010                               len += sprintf(buffer + len, "%u ",
02011                                              cap_list[j].first);
02012                             pos = begin + len;
02013                             if (pos < offset)
02014                               {
02015                                 len = 0;
02016                                 begin = pos;
02017                               }
02018                             if (pos > offset+length)
02019                               {
02020                                 rsbac_vfree(cap_list);
02021                                 rsbac_vfree(f_list);
02022                                 goto out_unlock;
02023                               }
02024                           }
02025                         rsbac_vfree(cap_list);
02026                         all_member_count += member_count;
02027                       }
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(f_list);
02037                         goto out_unlock;
02038                       }
02039                   }
02040                 rsbac_vfree(f_list);
02041                 all_count += count;
02042               }
02043           }
02044         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file eff cap set items, sum of %lu members, list is clean\n",
02045                        RSBAC_MAJOR(device_p->id),
02046                        RSBAC_MINOR(device_p->id),
02047                        all_count, all_member_count);
02048         pos = begin + len;
02049         if (pos < offset)
02050           {
02051             len = 0;
02052             begin = pos;
02053           }
02054         if (pos > offset+length)
02055           goto out_unlock;
02056 
02057         all_member_count = 0;
02058         all_count = 0;
02059         for(list=0 ; list < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; list++)
02060           {
02061             count = rsbac_list_lol_get_all_desc(device_p->fs_handles[list],
02062                                                 (void **) &f_list);
02063             if(count > 0)
02064               {
02065                 for(i=0; i<count; i++)
02066                   {
02067                     member_count = rsbac_list_lol_get_all_subdesc(device_p->fs_handles[list],
02068                                                                   &f_list[i],
02069                                                                   (void **) &cap_list);
02070                     len += sprintf(buffer + len, "\n %u\t%u\t",
02071                                    f_list[i],
02072                                    member_count);
02073                     if(member_count > 0)
02074                       {
02075                         for(j=0; j<member_count; j++)
02076                           {
02077                             if(cap_list[j].first != cap_list[j].last)
02078                               len += sprintf(buffer + len, "%u:%u ",
02079                                              cap_list[j].first,
02080                                              cap_list[j].last);
02081                             else
02082                               len += sprintf(buffer + len, "%u ",
02083                                              cap_list[j].first);
02084                             pos = begin + len;
02085                             if (pos < offset)
02086                               {
02087                                 len = 0;
02088                                 begin = pos;
02089                               }
02090                             if (pos > offset+length)
02091                               {
02092                                 rsbac_vfree(cap_list);
02093                                 rsbac_vfree(f_list);
02094                                 goto out_unlock;
02095                               }
02096                           }
02097                         rsbac_vfree(cap_list);
02098                         all_member_count += member_count;
02099                       }
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(f_list);
02109                         goto out_unlock;
02110                       }
02111                   }
02112                 rsbac_vfree(f_list);
02113                 all_count += count;
02114               }
02115           }
02116         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file fs cap set items, sum of %lu members, list is clean\n",
02117                        RSBAC_MAJOR(device_p->id),
02118                        RSBAC_MINOR(device_p->id),
02119                        all_count, all_member_count);
02120         pos = begin + len;
02121         if (pos < offset)
02122           {
02123             len = 0;
02124             begin = pos;
02125           }
02126         if (pos > offset+length)
02127           goto out_unlock;
02128 #endif
02129 
02130 #ifdef CONFIG_RSBAC_AUTH_GROUP
02131         all_member_count = 0;
02132         all_count = 0;
02133         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_FD_LISTS; list++)
02134           {
02135             count = rsbac_list_lol_get_all_desc(device_p->group_handles[list],
02136                                                 (void **) &f_list);
02137             if(count > 0)
02138               {
02139                 for(i=0; i<count; i++)
02140                   {
02141                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_handles[list],
02142                                                                   &f_list[i],
02143                                                                   (void **) &cap_list);
02144                     len += sprintf(buffer + len, "\n %u\t%u\t",
02145                                    f_list[i],
02146                                    member_count);
02147                     if(member_count > 0)
02148                       {
02149                         for(j=0; j<member_count; j++)
02150                           {
02151                             if(cap_list[j].first != cap_list[j].last)
02152                               len += sprintf(buffer + len, "%u:%u ",
02153                                              cap_list[j].first,
02154                                              cap_list[j].last);
02155                             else
02156                               len += sprintf(buffer + len, "%u ",
02157                                              cap_list[j].first);
02158                             pos = begin + len;
02159                             if (pos < offset)
02160                               {
02161                                 len = 0;
02162                                 begin = pos;
02163                               }
02164                             if (pos > offset+length)
02165                               {
02166                                 rsbac_vfree(cap_list);
02167                                 rsbac_vfree(f_list);
02168                                 goto out_unlock;
02169                               }
02170                           }
02171                         rsbac_vfree(cap_list);
02172                         all_member_count += member_count;
02173                       }
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(f_list);
02183                         goto out_unlock;
02184                       }
02185                   }
02186                 rsbac_vfree(f_list);
02187                 all_count += count;
02188               }
02189           }
02190         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group cap set items, sum of %lu members, list is clean\n",
02191                        RSBAC_MAJOR(device_p->id),
02192                        RSBAC_MINOR(device_p->id),
02193                        all_count, all_member_count);
02194         pos = begin + len;
02195         if (pos < offset)
02196           {
02197             len = 0;
02198             begin = pos;
02199           }
02200         if (pos > offset+length)
02201           goto out_unlock;
02202 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
02203         all_member_count = 0;
02204         all_count = 0;
02205         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_EFF_FD_LISTS; list++)
02206           {
02207             count = rsbac_list_lol_get_all_desc(device_p->group_eff_handles[list],
02208                                                 (void **) &f_list);
02209             if(count > 0)
02210               {
02211                 for(i=0; i<count; i++)
02212                   {
02213                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_eff_handles[list],
02214                                                                   &f_list[i],
02215                                                                   (void **) &cap_list);
02216                     len += sprintf(buffer + len, "\n %u\t%u\t",
02217                                    f_list[i],
02218                                    member_count);
02219                     if(member_count > 0)
02220                       {
02221                         for(j=0; j<member_count; j++)
02222                           {
02223                             if(cap_list[j].first != cap_list[j].last)
02224                               len += sprintf(buffer + len, "%u:%u ",
02225                                              cap_list[j].first,
02226                                              cap_list[j].last);
02227                             else
02228                               len += sprintf(buffer + len, "%u ",
02229                                              cap_list[j].first);
02230                             pos = begin + len;
02231                             if (pos < offset)
02232                               {
02233                                 len = 0;
02234                                 begin = pos;
02235                               }
02236                             if (pos > offset+length)
02237                               {
02238                                 rsbac_vfree(cap_list);
02239                                 rsbac_vfree(f_list);
02240                                 goto out_unlock;
02241                               }
02242                           }
02243                         rsbac_vfree(cap_list);
02244                         all_member_count += member_count;
02245                       }
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(f_list);
02255                         goto out_unlock;
02256                       }
02257                   }
02258                 rsbac_vfree(f_list);
02259                 all_count += count;
02260               }
02261           }
02262         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group eff cap set items, sum of %lu members, list is clean\n",
02263                        RSBAC_MAJOR(device_p->id),
02264                        RSBAC_MINOR(device_p->id),
02265                        all_count, all_member_count);
02266         pos = begin + len;
02267         if (pos < offset)
02268           {
02269             len = 0;
02270             begin = pos;
02271           }
02272         if (pos > offset+length)
02273           goto out_unlock;
02274 
02275         all_member_count = 0;
02276         all_count = 0;
02277         for(list=0 ; list < RSBAC_AUTH_NR_CAP_GROUP_FS_FD_LISTS; list++)
02278           {
02279             count = rsbac_list_lol_get_all_desc(device_p->group_fs_handles[list],
02280                                                 (void **) &f_list);
02281             if(count > 0)
02282               {
02283                 for(i=0; i<count; i++)
02284                   {
02285                     member_count = rsbac_list_lol_get_all_subdesc(device_p->group_fs_handles[list],
02286                                                                   &f_list[i],
02287                                                                   (void **) &cap_list);
02288                     len += sprintf(buffer + len, "\n %u\t%u\t",
02289                                    f_list[i],
02290                                    member_count);
02291                     if(member_count > 0)
02292                       {
02293                         for(j=0; j<member_count; j++)
02294                           {
02295                             if(cap_list[j].first != cap_list[j].last)
02296                               len += sprintf(buffer + len, "%u:%u ",
02297                                              cap_list[j].first,
02298                                              cap_list[j].last);
02299                             else
02300                               len += sprintf(buffer + len, "%u ",
02301                                              cap_list[j].first);
02302                             pos = begin + len;
02303                             if (pos < offset)
02304                               {
02305                                 len = 0;
02306                                 begin = pos;
02307                               }
02308                             if (pos > offset+length)
02309                               {
02310                                 rsbac_vfree(cap_list);
02311                                 rsbac_vfree(f_list);
02312                                 goto out_unlock;
02313                               }
02314                           }
02315                         rsbac_vfree(cap_list);
02316                         all_member_count += member_count;
02317                       }
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(f_list);
02327                         goto out_unlock;
02328                       }
02329                   }
02330                 rsbac_vfree(f_list);
02331                 all_count += count;
02332               }
02333           }
02334         len += sprintf(buffer + len, "\ndevice %02u:%02u has %lu file group fs cap set items, sum of %lu members, list is clean\n",
02335                        RSBAC_MAJOR(device_p->id),
02336                        RSBAC_MINOR(device_p->id),
02337                        all_count, all_member_count);
02338         pos = begin + len;
02339         if (pos < offset)
02340           {
02341             len = 0;
02342             begin = pos;
02343           }
02344         if (pos > offset+length)
02345           goto out_unlock;
02346 #endif
02347 #endif /* AUTH_GROUP */
02348 
02349         device_p = device_p->next;
02350       }
02351 out_unlock:
02352     /* unprotect device list */
02353     rsbac_read_unlock(&device_list_head.lock, &dflags);
02354 
02355 out:
02356   *start = buffer + (offset - begin);
02357   len -= (offset - begin);
02358   
02359   if (len > length)
02360     len = length;
02361   return len;
02362 }
02363 #endif /* CONFIG_PROC_FS && CONFIG_RSBAC_PROC */
02364 
02365 /************************************************* */
02366 /*               Init functions                    */
02367 /************************************************* */
02368 
02369 /* All functions return 0, if no error occurred, and a negative error code  */
02370 /* otherwise. The error codes are defined in rsbac/error.h.                 */
02371 
02372 /************************************************************************** */
02373 /* Initialization of all AUTH data structures. After this call, all AUTH    */
02374 /* data is kept in memory for performance reasons, but is written to disk   */
02375 /* on every change. */
02376 
02377 /* Because there can be no access to aci data structures before init,       */
02378 /* rsbac_init_auth() will initialize all rw-spinlocks to unlocked.          */
02379 
02380 #ifdef CONFIG_RSBAC_INIT_DELAY
02381 int rsbac_init_auth(void)
02382 #else
02383 int __init rsbac_init_auth(void)
02384 #endif
02385   {
02386     int  err = 0;
02387     struct rsbac_auth_device_list_item_t * device_p = NULL;
02388     u_long dflags;
02389     struct proc_dir_entry * tmp_entry_p;
02390     struct rsbac_list_lol_info_t lol_info;
02391 
02392     if (rsbac_is_initialized())
02393       {
02394         rsbac_printk(KERN_WARNING "rsbac_init_auth(): RSBAC already initialized\n");
02395         return(-RSBAC_EREINIT);
02396       }
02397 
02398     /* set rw-spinlocks to unlocked status and init data structures */
02399     rsbac_printk(KERN_INFO "rsbac_init_auth(): Initializing RSBAC: AUTH subsystem\n");
02400 
02401     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02402     lol_info.key = RSBAC_AUTH_LIST_KEY;
02403     lol_info.desc_size = sizeof(rsbac_pid_t);
02404     lol_info.data_size = 0;
02405     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02406     lol_info.subdata_size = 0;
02407     lol_info.max_age = 0;
02408     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02409                                   &process_handle,
02410                                   &lol_info,
02411                                   RSBAC_LIST_DEF_DATA,
02412                                   NULL,
02413                                   cap_compare,
02414                                   NULL,
02415                                   NULL,
02416                                   NULL,
02417                                   NULL,
02418                                   RSBAC_AUTH_P_LIST_NAME,
02419                                   RSBAC_AUTO_DEV);
02420     if(err)
02421       {
02422         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02423 
02424         if(tmp)
02425           {
02426             rsbac_printk(KERN_WARNING
02427                    "rsbac_init_auth(): Registering AUTH process cap list failed with error %s\n",
02428                    get_error_name(tmp, err));
02429             rsbac_kfree(tmp);
02430           }
02431       }
02432 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
02433     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02434     lol_info.key = RSBAC_AUTH_LIST_KEY;
02435     lol_info.desc_size = sizeof(rsbac_pid_t);
02436     lol_info.data_size = 0;
02437     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02438     lol_info.subdata_size = 0;
02439     lol_info.max_age = 0;
02440     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02441                                   &process_eff_handle,
02442                                   &lol_info,
02443                                   RSBAC_LIST_DEF_DATA,
02444                                   NULL,
02445                                   cap_compare,
02446                                   NULL,
02447                                   NULL,
02448                                   NULL,
02449                                   NULL,
02450                                   RSBAC_AUTH_P_EFF_LIST_NAME,
02451                                   RSBAC_AUTO_DEV);
02452     if(err)
02453       {
02454         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02455 
02456         if(tmp)
02457           {
02458             rsbac_printk(KERN_WARNING
02459                    "rsbac_init_auth(): Registering AUTH process eff cap list failed with error %s\n",
02460                    get_error_name(tmp, err));
02461             rsbac_kfree(tmp);
02462           }
02463       }
02464     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02465     lol_info.key = RSBAC_AUTH_LIST_KEY;
02466     lol_info.desc_size = sizeof(rsbac_pid_t);
02467     lol_info.data_size = 0;
02468     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02469     lol_info.subdata_size = 0;
02470     lol_info.max_age = 0;
02471     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02472                                   &process_fs_handle,
02473                                   &lol_info,
02474                                   RSBAC_LIST_DEF_DATA,
02475                                   NULL,
02476                                   cap_compare,
02477                                   NULL,
02478                                   NULL,
02479                                   NULL,
02480                                   NULL,
02481                                   RSBAC_AUTH_P_FS_LIST_NAME,
02482                                   RSBAC_AUTO_DEV);
02483     if(err)
02484       {
02485         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02486 
02487         if(tmp)
02488           {
02489             rsbac_printk(KERN_WARNING
02490                    "rsbac_init_auth(): Registering AUTH process fs cap list failed with error %s\n",
02491                    get_error_name(tmp, err));
02492             rsbac_kfree(tmp);
02493           }
02494       }
02495 #endif
02496 
02497 #ifdef CONFIG_RSBAC_AUTH_GROUP
02498     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02499     lol_info.key = RSBAC_AUTH_LIST_KEY;
02500     lol_info.desc_size = sizeof(rsbac_pid_t);
02501     lol_info.data_size = 0;
02502     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02503     lol_info.subdata_size = 0;
02504     lol_info.max_age = 0;
02505     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02506                                   &process_group_handle,
02507                                   &lol_info,
02508                                   RSBAC_LIST_DEF_DATA,
02509                                   NULL,
02510                                   cap_compare,
02511                                   NULL,
02512                                   NULL,
02513                                   NULL,
02514                                   NULL,
02515                                   RSBAC_AUTH_P_GROUP_LIST_NAME,
02516                                   RSBAC_AUTO_DEV);
02517     if(err)
02518       {
02519         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02520 
02521         if(tmp)
02522           {
02523             rsbac_printk(KERN_WARNING
02524                    "rsbac_init_auth(): Registering AUTH process group cap list failed with error %s\n",
02525                    get_error_name(tmp, err));
02526             rsbac_kfree(tmp);
02527           }
02528       }
02529 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
02530     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02531     lol_info.key = RSBAC_AUTH_LIST_KEY;
02532     lol_info.desc_size = sizeof(rsbac_pid_t);
02533     lol_info.data_size = 0;
02534     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02535     lol_info.subdata_size = 0;
02536     lol_info.max_age = 0;
02537     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02538                                   &process_group_eff_handle,
02539                                   &lol_info,
02540                                   RSBAC_LIST_DEF_DATA,
02541                                   NULL,
02542                                   cap_compare,
02543                                   NULL,
02544                                   NULL,
02545                                   NULL,
02546                                   NULL,
02547                                   RSBAC_AUTH_P_GROUP_EFF_LIST_NAME,
02548                                   RSBAC_AUTO_DEV);
02549     if(err)
02550       {
02551         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02552 
02553         if(tmp)
02554           {
02555             rsbac_printk(KERN_WARNING
02556                    "rsbac_init_auth(): Registering AUTH process group eff cap list failed with error %s\n",
02557                    get_error_name(tmp, err));
02558             rsbac_kfree(tmp);
02559           }
02560       }
02561     lol_info.version = RSBAC_AUTH_P_LIST_VERSION;
02562     lol_info.key = RSBAC_AUTH_LIST_KEY;
02563     lol_info.desc_size = sizeof(rsbac_pid_t);
02564     lol_info.data_size = 0;
02565     lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t);
02566     lol_info.subdata_size = 0;
02567     lol_info.max_age = 0;
02568     err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
02569                                   &process_group_fs_handle,
02570                                   &lol_info,
02571                                   RSBAC_LIST_DEF_DATA,
02572                                   NULL,
02573                                   cap_compare,
02574                                   NULL,
02575                                   NULL,
02576                                   NULL,
02577                                   NULL,
02578                                   RSBAC_AUTH_P_GROUP_FS_LIST_NAME,
02579                                   RSBAC_AUTO_DEV);
02580     if(err)
02581       {
02582         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02583 
02584         if(tmp)
02585           {
02586             rsbac_printk(KERN_WARNING
02587                    "rsbac_init_auth(): Registering AUTH process group fs cap list failed with error %s\n",
02588                    get_error_name(tmp, err));
02589             rsbac_kfree(tmp);
02590           }
02591       }
02592 #endif
02593 #endif /* AUTH_GROUP */
02594 
02595     /* Init FD lists */
02596     device_list_head.lock = RW_LOCK_UNLOCKED;
02597     device_list_head.head = NULL;
02598     device_list_head.tail = NULL;
02599     device_list_head.curr = NULL;
02600     device_list_head.count = 0;
02601 
02602     /* read all data */
02603 #ifdef CONFIG_RSBAC_DEBUG
02604     if (rsbac_debug_ds_auth)
02605       rsbac_printk(KERN_INFO "rsbac_init_auth(): Registering FD lists\n");
02606 #endif
02607     device_p = create_device_item(rsbac_root_dev);
02608     if (!device_p)
02609       {
02610         rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02611         return(-RSBAC_ECOULDNOTADDDEVICE);
02612       }
02613     if((err = auth_register_fd_lists(device_p,rsbac_root_dev)))
02614       {
02615         char tmp[RSBAC_MAXNAMELEN];
02616 
02617         rsbac_printk(KERN_WARNING
02618                "rsbac_init_auth(): File/Dir cap set registration failed for dev %02u:%02u, err %s!\n",
02619                RSBAC_MAJOR(rsbac_root_dev), RSBAC_MINOR(rsbac_root_dev), get_error_name(tmp,err));
02620       }
02621     /* wait for write access to device_list_head */
02622     rsbac_write_lock_irq(&device_list_head.lock, &dflags);
02623     device_p = add_device_item(device_p);
02624     /* device was added, allow access */
02625     rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
02626     if (!device_p)
02627       {
02628         rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n");
02629         return(-RSBAC_ECOULDNOTADDDEVICE);
02630       }
02631 
02632     #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
02633     tmp_entry_p = create_proc_entry("auth_devices",
02634                                     S_IFREG | S_IRUGO,
02635                                     proc_rsbac_root_p);
02636     if(tmp_entry_p)
02637       {
02638         tmp_entry_p->get_info = auth_devices_proc_info;
02639       }
02640     tmp_entry_p = create_proc_entry("stats_auth",
02641                                     S_IFREG | S_IRUGO,
02642                                     proc_rsbac_root_p);
02643     if(tmp_entry_p)
02644       {
02645         tmp_entry_p->get_info = stats_auth_proc_info;
02646       }
02647     tmp_entry_p = create_proc_entry("auth_caplist",
02648                                     S_IFREG | S_IRUGO,
02649                                     proc_rsbac_root_p);
02650     if(tmp_entry_p)
02651       {
02652         tmp_entry_p->get_info = auth_caplist_proc_info;
02653       }
02654     #endif
02655 
02656 #ifdef CONFIG_RSBAC_DEBUG
02657     if (rsbac_debug_ds_auth)
02658       rsbac_printk(KERN_DEBUG "rsbac_init_auth(): Ready.\n");
02659 #endif
02660     return(err);
02661   };
02662 
02663 int rsbac_mount_auth(kdev_t kdev)
02664   {
02665     int err = 0;
02666     struct rsbac_auth_device_list_item_t * device_p;
02667     struct rsbac_auth_device_list_item_t * new_device_p;
02668     u_long dflags;
02669 
02670     if (!rsbac_is_initialized())
02671       {
02672         rsbac_printk(KERN_WARNING "rsbac_mount_auth(): RSBAC not initialized\n");
02673         return(-RSBAC_ENOTINITIALIZED);
02674       }
02675 #ifdef CONFIG_RSBAC_DEBUG
02676     if (rsbac_debug_ds_auth)
02677       rsbac_printk(KERN_DEBUG "rsbac_mount_auth(): mounting device %02u:%02u\n",
02678                    RSBAC_MAJOR(kdev),RSBAC_MINOR(kdev));
02679 #endif
02680     /* wait for write access to device_list_head */
02681     rsbac_read_lock(&device_list_head.lock, &dflags);
02682     device_p = lookup_device(kdev);
02683     /* repeated mount? */
02684     if(device_p)
02685       {
02686         rsbac_printk(KERN_WARNING "rsbac_mount_auth: repeated mount %u of device %02u:%02u\n",
02687                device_p->mount_count, RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02688         device_p->mount_count++;
02689         rsbac_read_unlock(&device_list_head.lock, &dflags);
02690         return 0;
02691       }
02692     rsbac_read_unlock(&device_list_head.lock, &dflags);
02693 
02694     new_device_p = create_device_item(kdev);
02695     if(!new_device_p)
02696       return -RSBAC_ECOULDNOTADDDEVICE;
02697 
02698     /* register lists */
02699     if((err = auth_register_fd_lists(new_device_p, kdev)))
02700       {
02701         char tmp[RSBAC_MAXNAMELEN];
02702 
02703         rsbac_printk(KERN_WARNING
02704                "rsbac_mount_auth(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n",
02705                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev), get_error_name(tmp,err));
02706       }
02707 
02708     /* wait for read access to device_list_head */
02709     rsbac_read_lock(&device_list_head.lock, &dflags);
02710     /* make sure to only add, if this device item has not been added in the meantime */
02711     device_p = lookup_device(kdev);
02712     if(device_p)
02713       {
02714         rsbac_printk(KERN_WARNING
02715                "rsbac_mount_auth(): mount race for device %02u:%02u detected!\n",
02716                RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02717         device_p->mount_count++;
02718         rsbac_read_unlock(&device_list_head.lock, &dflags);
02719         clear_device_item(new_device_p);
02720       }
02721     else
02722       {
02723         rsbac_read_unlock(&device_list_head.lock, &dflags);
02724         rsbac_write_lock_irq(&device_list_head.lock, &dflags);
02725         device_p = add_device_item(new_device_p);
02726         rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
02727         if(!device_p)
02728           {
02729             rsbac_printk(KERN_WARNING "rsbac_mount_auth: adding device %02u:%02u failed!\n",
02730                    RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02731             clear_device_item(new_device_p);
02732             err = -RSBAC_ECOULDNOTADDDEVICE;
02733           }
02734       }
02735     return(err);
02736   };
02737   
02738 /* When umounting a device, its file cap set list must be removed. */
02739 
02740 int rsbac_umount_auth(kdev_t kdev)
02741   {
02742     u_long flags;
02743     struct rsbac_auth_device_list_item_t * device_p;
02744 
02745     if (!rsbac_is_initialized())
02746       {
02747         rsbac_printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n");
02748         return(-RSBAC_ENOTINITIALIZED);
02749       }
02750 
02751 #ifdef CONFIG_RSBAC_DEBUG
02752     if (rsbac_debug_ds_auth)
02753       rsbac_printk(KERN_DEBUG "rsbac_umount_auth(): umounting device %02u:%02u\n",
02754                    RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02755 #endif
02756     /* sync of attribute lists was done in rsbac_umount */
02757     /* wait for write access to device_list_head */
02758     rsbac_write_lock(&device_list_head.lock, &flags);
02759     /* OK, nobody else is working on it... */
02760     device_p = lookup_device(kdev);
02761     if(device_p)
02762       {
02763         if(device_p->mount_count == 1)
02764           remove_device_item(kdev);
02765         else
02766           {
02767             if(device_p->mount_count > 1)
02768               device_p->mount_count--;
02769             else
02770               rsbac_printk(KERN_WARNING "rsbac_mount_auth: device %02u:%02u has mount_count < 1!\n",
02771                            RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
02772           }
02773       }
02774 
02775     /* allow access */
02776     rsbac_write_unlock(&device_list_head.lock, &flags);
02777     return(0);
02778   }
02779 
02780 /***************************************************/
02781 /* We also need some status information...         */
02782 
02783 int rsbac_stats_auth(void)
02784   {
02785     u_int                                     cap_set_count = 0;
02786     u_int                                     member_count = 0;
02787     u_long dflags;
02788     struct rsbac_auth_device_list_item_t   * device_p;
02789     int i;
02790   
02791     union rsbac_target_id_t       rsbac_target_id;
02792     union rsbac_attribute_value_t rsbac_attribute_value;
02793 
02794     if (!rsbac_is_initialized())
02795       {
02796         rsbac_printk(KERN_WARNING "rsbac_stats_auth(): RSBAC not initialized\n");
02797         return(-RSBAC_ENOTINITIALIZED);
02798       }
02799 #ifdef CONFIG_RSBAC_DEBUG
02800     if (rsbac_debug_aef_auth)
02801       rsbac_printk(KERN_DEBUG "rsbac_stats_auth(): calling ADF\n");
02802 #endif
02803     rsbac_target_id.scd = ST_rsbac;
02804     rsbac_attribute_value.dummy = 0;
02805     if (!rsbac_adf_request(R_GET_STATUS_DATA,
02806                            current->pid,
02807                            T_SCD,
02808                            rsbac_target_id,
02809                            A_none,
02810                            rsbac_attribute_value))
02811       {
02812         return -EPERM;
02813       }
02814 
02815     rsbac_printk(KERN_INFO "AUTH Status\n-----------\n");
02816 
02817     rsbac_printk(KERN_INFO "%lu process cap set items, sum of %lu members\n",
02818                    rsbac_list_lol_count(process_handle),
02819                    rsbac_list_lol_all_subcount(process_handle));
02820 
02821     /* protect device list */
02822     rsbac_read_lock(&device_list_head.lock, &dflags);
02823     device_p = device_list_head.head;
02824     while(device_p)
02825       {
02826         /* reset counters */
02827         cap_set_count = 0;
02828         member_count = 0;
02829         for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++)
02830           {
02831             cap_set_count += rsbac_list_lol_count(device_p->handles[i]);
02832             member_count += rsbac_list_lol_all_subcount(device_p->handles[i]);
02833           }
02834         rsbac_printk(KERN_INFO "device %02u:%02u has %u file cap set items, sum of %u members\n",
02835                          RSBAC_MAJOR(device_p->id),
02836                          RSBAC_MINOR(device_p->id),
02837                          cap_set_count,member_count);
02838         device_p = device_p->next;
02839       }
02840     /* unprotect device list */
02841     rsbac_read_unlock(&device_list_head.lock, &dflags);
02842     return(0);
02843   };
02844 
02845 /***************************************************/
02846 /* consistency checking (as far as possible)       */
02847 
02848 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
02849 int rsbac_check_auth(int correct, int check_inode)
02850   {
02851     struct rsbac_auth_device_list_item_t * device_p;
02852     u_long                              f_count = 0, f_sum = 0, tmp_count,
02853                                         r_count, u_count, b_count, no_member_count;
02854     long                                desc_count;
02855     u_int                               i,list_no;
02856     u_long                              dflags;
02857     struct super_block                * sb_p;
02858     struct inode                      * inode_p;
02859     rsbac_inode_nr_t                  * fd_desc_p;
02860   
02861     if (!rsbac_is_initialized())
02862       {
02863         rsbac_printk(KERN_WARNING "rsbac_check_auth(): RSBAC not initialized\n");
02864         return(-RSBAC_ENOTINITIALIZED);
02865       }
02866 
02867     /* wait for read access to device_list_head */
02868     rsbac_read_lock(&device_list_head.lock, &dflags);
02869     /* OK, go on */
02870 /*    rsbac_printk(KERN_INFO "rsbac_check_auth(): currently %u processes working on file/dir aci\n",
02871                      device_list_head.lock.lock); */
02872     device_p = device_list_head.head;
02873     while (device_p)
02874       { /* for all sublists */
02875         f_count = 0;
02876         r_count = 0;
02877         u_count = 0;
02878         b_count = 0;
02879         no_member_count = 0;
02880         if(check_inode)
02881           {
02882             sb_p = rsbac_get_super_block(device_p->id);
02883             if(!sb_p)
02884               rsbac_printk(KERN_WARNING "rsbac_check_auth(): no super block for device %02u:%02u!\n",
02885                            RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id));
02886           }
02887         else
02888           sb_p = NULL;
02889 
02890         /* OK, go ahead */
02891         for(list_no = 0; list_no < RSBAC_AUTH_NR_CAP_FD_LISTS; list_no++)
02892           {
02893 /*            rsbac_printk(KERN_INFO "rsbac_check_auth(): list %u\n",
02894                    list_no); */
02895             tmp_count = 0;
02896             desc_count = rsbac_list_lol_get_all_desc(device_p->handles[list_no], (void **) &fd_desc_p);
02897             if(desc_count > 0)
02898               {
02899                 for(i=0; i<desc_count; i++)
02900                   {
02901                     /* check for inode on disk (but not for reiserfs, because of 64bit inode numbers) */
02902                     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
02903                     if(sb_p)
02904                     #else
02905                     if(sb_p && !sb_p->s_op->read_inode2)
02906                     #endif
02907                       {
02908                         inode_p = iget(sb_p, fd_desc_p[i]);
02909                         if(is_bad_inode(inode_p))
02910                           { /* inode is bad -> remove */
02911                             b_count++;
02912                             if(correct)
02913                               {
02914                                 rsbac_printk(KERN_INFO
02915                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u, removing!\n",
02916                                         fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02917                                 rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
02918                                 continue;
02919                               }
02920                             else
02921                               {
02922                                 rsbac_printk(KERN_INFO
02923                                        "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u!\n",
02924                                        fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02925                               }
02926                           } /* end of bad_inode */
02927                         else
02928                           { /* good inode */
02929                             /* currently only deletion checking of ext2 inodes is possible */
02930                             if(sb_p->s_magic == EXT2_SUPER_MAGIC)
02931                               {
02932                                 if(inode_p->u.ext2_i.i_dtime)
02933                                   { /* inode has been deleted -> remove */
02934                                     r_count++;
02935                                     if(correct)
02936                                       {
02937                                         rsbac_printk(KERN_INFO
02938                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u, removing!\n",
02939                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02940                                         rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
02941                                         continue;
02942                                       }
02943                                     else
02944                                       {
02945                                         rsbac_printk(KERN_INFO
02946                                                "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u!\n",
02947                                                fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02948                                       }
02949                                   }
02950                                 else
02951                                   {
02952                                     if(inode_p->i_nlink <= 0)
02953                                       { /* inode has been unlinked, but no dtime is set -> warn */
02954                                         u_count++;
02955                                         if(correct >= 2)
02956                                           {
02957                                             rsbac_printk(KERN_INFO
02958                                                    "rsbac_check_auth(): fd_item for inode %u with nlink <= 0 on device %02u:%02u, list %u, removing!\n",
02959                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02960                                             rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]);
02961                                             continue;
02962                                           }
02963                                         else
02964                                           {
02965                                             rsbac_printk(KERN_INFO
02966                                                    "rsbac_check_auth(): deleted inode %u on device %02u:%02u, list %u, has no dtime!\n",
02967                                                    fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no);
02968                                           }
02969                                       }
02970                                   }
02971                               }
02972                           } /* end of is_good_inode */
02973                         iput(inode_p);
02974                       } /* end of sb_p */
02975                   }
02976                 tmp_count++;
02977                 rsbac_vfree(fd_desc_p);
02978                 f_count += desc_count;
02979               }
02980           } /* end of for-fd-list-array */
02981 
02982         switch(correct)
02983           {
02984             case 2:
02985               rsbac_printk(KERN_INFO
02986                      "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",
02987                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + u_count + no_member_count,
02988                      b_count, r_count, u_count, no_member_count);
02989               break;
02990             case 1:
02991               rsbac_printk(KERN_INFO
02992                      "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",
02993                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + no_member_count,
02994                      b_count, r_count, no_member_count, u_count);
02995               break;
02996             default:
02997               rsbac_printk(KERN_INFO
02998                      "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",
02999                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count,
03000                      b_count, r_count, u_count, no_member_count);
03001           }
03002         f_sum += f_count;
03003         /* go on */
03004         device_p = device_p->next;
03005       }
03006     rsbac_printk(KERN_INFO "rsbac_check_auth(): Sum of %u Devices with %lu file/dir AUTHs\n",
03007                  device_list_head.count, f_sum);
03008     /* free access to device_list_head */
03009     rsbac_read_unlock(&device_list_head.lock, &dflags);
03010     
03011     rsbac_printk(KERN_INFO
03012            "rsbac_check_auth(): Total of %lu registered auth items\n",
03013            f_sum);
03014     return(0);
03015   }
03016 #endif /* VERSION < 2.6.0 */
03017 
03018 /************************************************* */
03019 /*               Access functions                  */
03020 /************************************************* */
03021 
03022 /* All these procedures handle the rw-spinlocks to protect the targets during */
03023 /* access.                                                                  */
03024 /* Trying to access a never created or removed set returns an error! */
03025 
03026 /* rsbac_auth_add_to_capset */
03027 /* Add a set member to a set sublist. Set behaviour: also returns success, */
03028 /* if member was already in set! */
03029 
03030 int rsbac_auth_add_to_p_capset(
03031          rsbac_list_ta_number_t ta_number,
03032          rsbac_pid_t pid,
03033   enum   rsbac_auth_cap_type_t cap_type,
03034   struct rsbac_auth_cap_range_t cap_range,
03035          rsbac_time_t ttl)
03036   {
03037     if (!rsbac_is_initialized())
03038       {
03039         rsbac_printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): RSBAC not initialized\n");
03040         return(-RSBAC_ENOTINITIALIZED);
03041       }
03042     if (in_interrupt())
03043       {
03044         rsbac_printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): called from interrupt!\n");
03045       }
03046     if(cap_range.first > cap_range.last)
03047       return(-RSBAC_EINVALIDVALUE);
03048     switch(cap_type)
03049       {
03050         case ACT_real:
03051           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_handle, ttl, &pid, &cap_range, NULL);
03052 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03053         case ACT_eff:
03054           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_eff_handle, ttl, &pid, &cap_range, NULL);
03055         case ACT_fs:
03056           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_fs_handle, ttl, &pid, &cap_range, NULL);
03057 #endif
03058 #ifdef CONFIG_RSBAC_AUTH_GROUP
03059         case ACT_group_real:
03060           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_handle, ttl, &pid, &cap_range, NULL);
03061 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03062         case ACT_group_eff:
03063           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_eff_handle, ttl, &pid, &cap_range, NULL);
03064         case ACT_group_fs:
03065           return rsbac_ta_list_lol_subadd_ttl(ta_number, process_group_fs_handle, ttl, &pid, &cap_range, NULL);
03066 #endif
03067 #endif /* AUTH_GROUP */
03068 
03069         default:
03070           return -RSBAC_EINVALIDTARGET;
03071       }
03072   }
03073 
03074 int rsbac_auth_add_to_f_capset(
03075          rsbac_list_ta_number_t ta_number,
03076          rsbac_auth_file_t file,
03077   enum   rsbac_auth_cap_type_t cap_type,
03078   struct rsbac_auth_cap_range_t cap_range,
03079          rsbac_time_t ttl)
03080   {
03081     int                                     err=0;
03082     u_long dflags;
03083     struct rsbac_auth_device_list_item_t   * device_p;
03084 
03085     if (!rsbac_is_initialized())
03086       {
03087         rsbac_printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): RSBAC not initialized\n");
03088         return(-RSBAC_ENOTINITIALIZED);
03089       }
03090     if (in_interrupt())
03091       {
03092         rsbac_printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): called from interrupt!\n");
03093       }
03094     if(cap_range.first > cap_range.last)
03095       return(-RSBAC_EINVALIDVALUE);
03096 
03097     /* protect device list */
03098     rsbac_read_lock(&device_list_head.lock, &dflags);
03099     device_p = lookup_device(file.device);
03100     if(!device_p)
03101       {
03102         /* trigger rsbac_mount() */
03103         rsbac_read_unlock(&device_list_head.lock, &dflags);
03104         rsbac_get_super_block(file.device);
03105         /* retry */
03106         rsbac_read_lock(&device_list_head.lock, &dflags);
03107         device_p = lookup_device(file.device);
03108         if(!device_p)
03109           {
03110             rsbac_printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): invalid device %02u:%02u!\n",
03111                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03112             rsbac_read_unlock(&device_list_head.lock, &dflags);
03113             return(-RSBAC_EINVALIDDEV);
03114           }
03115       }
03116 
03117     switch(cap_type)
03118       {
03119         case ACT_real:
03120           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->handles[fd_hash(file.inode)],
03121                                           ttl, &file.inode, &cap_range, NULL);
03122           break;
03123 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03124         case ACT_eff:
03125           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)],
03126                                           ttl, &file.inode, &cap_range, NULL);
03127           break;
03128         case ACT_fs:
03129           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)],
03130                                           ttl, &file.inode, &cap_range, NULL);
03131           break;
03132 #endif
03133 #ifdef CONFIG_RSBAC_AUTH_GROUP
03134         case ACT_group_real:
03135           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_handles[group_fd_hash(file.inode)],
03136                                           ttl, &file.inode, &cap_range, NULL);
03137           break;
03138 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03139         case ACT_group_eff:
03140           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)],
03141                                           ttl, &file.inode, &cap_range, NULL);
03142           break;
03143         case ACT_group_fs:
03144           err = rsbac_ta_list_lol_subadd_ttl(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)],
03145                                           ttl, &file.inode, &cap_range, NULL);
03146           break;
03147 #endif
03148 #endif /* AUTH_GROUP */
03149 
03150         default:
03151           err = -RSBAC_EINVALIDTARGET;
03152       }
03153     rsbac_read_unlock(&device_list_head.lock, &dflags);
03154     return(err);
03155   }
03156 
03157 /* rsbac_auth_remove_from_capset */
03158 /* Remove a set member from a sublist. Set behaviour: Returns no error, if */
03159 /* member is not in list.                                                  */
03160 
03161 int rsbac_auth_remove_from_p_capset(
03162          rsbac_list_ta_number_t ta_number,
03163          rsbac_pid_t pid,
03164   enum   rsbac_auth_cap_type_t cap_type,
03165   struct rsbac_auth_cap_range_t cap_range)
03166   {
03167     if (!rsbac_is_initialized())
03168       {
03169         rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): RSBAC not initialized\n");
03170         return(-RSBAC_ENOTINITIALIZED);
03171       }
03172     if (in_interrupt())
03173       {
03174         rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): called from interrupt!\n");
03175       }
03176     if(cap_range.first > cap_range.last)
03177       return(-RSBAC_EINVALIDVALUE);
03178     switch(cap_type)
03179       {
03180         case ACT_real:
03181           return rsbac_ta_list_lol_subremove(ta_number, process_handle, &pid, &cap_range);
03182 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03183         case ACT_eff:
03184           return rsbac_ta_list_lol_subremove(ta_number, process_eff_handle, &pid, &cap_range);
03185         case ACT_fs:
03186           return rsbac_ta_list_lol_subremove(ta_number, process_fs_handle, &pid, &cap_range);
03187 #endif
03188 #ifdef CONFIG_RSBAC_AUTH_GROUP
03189         case ACT_group_real:
03190           return rsbac_ta_list_lol_subremove(ta_number, process_group_handle, &pid, &cap_range);
03191 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03192         case ACT_group_eff:
03193           return rsbac_ta_list_lol_subremove(ta_number, process_group_eff_handle, &pid, &cap_range);
03194         case ACT_group_fs:
03195           return rsbac_ta_list_lol_subremove(ta_number, process_group_fs_handle, &pid, &cap_range);
03196 #endif
03197 #endif /* AUTH_GROUP */
03198 
03199         default:
03200           return -RSBAC_EINVALIDTARGET;
03201       }
03202   }
03203 
03204 int rsbac_auth_remove_from_f_capset(
03205         rsbac_list_ta_number_t ta_number,
03206         rsbac_auth_file_t file,
03207   enum  rsbac_auth_cap_type_t cap_type,
03208   struct rsbac_auth_cap_range_t cap_range)
03209   {
03210     int                                    err=0;
03211     u_long dflags;
03212     struct rsbac_auth_device_list_item_t   * device_p;
03213 
03214     if (!rsbac_is_initialized())
03215       {
03216         rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): RSBAC not initialized\n");
03217         return(-RSBAC_ENOTINITIALIZED);
03218       }
03219     if (in_interrupt())
03220       {
03221         rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): called from interrupt!\n");
03222       }
03223     if(cap_range.first > cap_range.last)
03224       return(-RSBAC_EINVALIDVALUE);
03225 
03226     /* protect device list */
03227     rsbac_read_lock(&device_list_head.lock, &dflags);
03228     device_p = lookup_device(file.device);
03229     if(!device_p)
03230       {
03231         /* trigger rsbac_mount() */
03232         rsbac_read_unlock(&device_list_head.lock, &dflags);
03233         rsbac_get_super_block(file.device);
03234         /* retry */
03235         rsbac_read_lock(&device_list_head.lock, &dflags);
03236         device_p = lookup_device(file.device);
03237         if(!device_p)
03238           {
03239             rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): invalid device %02u:%02u!\n",
03240                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03241             rsbac_read_unlock(&device_list_head.lock, &dflags);
03242             return(-RSBAC_EINVALIDDEV);
03243           }
03244       }
03245     switch(cap_type)
03246       {
03247         case ACT_real:
03248           err = rsbac_ta_list_lol_subremove(ta_number, device_p->handles[fd_hash(file.inode)], &file.inode, &cap_range);
03249           break;
03250 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03251         case ACT_eff:
03252           err = rsbac_ta_list_lol_subremove(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode, &cap_range);
03253           break;
03254         case ACT_fs:
03255           err = rsbac_ta_list_lol_subremove(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode, &cap_range);
03256           break;
03257 #endif
03258 #ifdef CONFIG_RSBAC_AUTH_GROUP
03259         case ACT_group_real:
03260           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_handles[group_fd_hash(file.inode)], &file.inode, &cap_range);
03261           break;
03262 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03263         case ACT_group_eff:
03264           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)], &file.inode, &cap_range);
03265           break;
03266         case ACT_group_fs:
03267           err = rsbac_ta_list_lol_subremove(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)], &file.inode, &cap_range);
03268           break;
03269 #endif
03270 #endif /* AUTH_GROUP */
03271 
03272         default:
03273           err = -RSBAC_EINVALIDTARGET;
03274       }
03275     rsbac_read_unlock(&device_list_head.lock, &dflags);
03276     return(err);
03277   }
03278 
03279 /* rsbac_auth_clear_capset */
03280 /* Remove all set members from a sublist. Set behaviour: Returns no error, */
03281 /* if list is empty.                                                       */
03282 
03283 int rsbac_auth_clear_p_capset(
03284        rsbac_list_ta_number_t ta_number,
03285        rsbac_pid_t pid,
03286   enum rsbac_auth_cap_type_t cap_type)
03287   {
03288     if (!rsbac_is_initialized())
03289       {
03290         rsbac_printk(KERN_WARNING "rsbac_auth_clear_p_capset(): RSBAC not initialized\n");
03291         return(-RSBAC_ENOTINITIALIZED);
03292       }
03293     if (in_interrupt())
03294       {
03295         rsbac_printk(KERN_WARNING "rsbac_auth_clear_p_capset(): called from interrupt!\n");
03296       }
03297     switch(cap_type)
03298       {
03299         case ACT_real:
03300           return rsbac_ta_list_lol_remove(ta_number, process_handle, &pid);
03301 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03302         case ACT_eff:
03303           return rsbac_ta_list_lol_remove(ta_number, process_eff_handle, &pid);
03304         case ACT_fs:
03305           return rsbac_ta_list_lol_remove(ta_number, process_fs_handle, &pid);
03306 #endif
03307 #ifdef CONFIG_RSBAC_AUTH_GROUP
03308         case ACT_group_real:
03309           return rsbac_ta_list_lol_remove(ta_number, process_group_handle, &pid);
03310 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03311         case ACT_group_eff:
03312           return rsbac_ta_list_lol_remove(ta_number, process_group_eff_handle, &pid);
03313         case ACT_group_fs:
03314           return rsbac_ta_list_lol_remove(ta_number, process_group_fs_handle, &pid);
03315 #endif
03316 #endif /* AUTH_GROUP */
03317 
03318         default:
03319           return -RSBAC_EINVALIDTARGET;
03320       }
03321   }
03322 
03323 int rsbac_auth_clear_f_capset(
03324        rsbac_list_ta_number_t ta_number,
03325        rsbac_auth_file_t file,
03326   enum rsbac_auth_cap_type_t cap_type)
03327   {
03328     int                                    err=0;
03329     u_long dflags;
03330     struct rsbac_auth_device_list_item_t   * device_p;
03331 
03332     if (!rsbac_is_initialized())
03333       {
03334         rsbac_printk(KERN_WARNING "rsbac_auth_clear_f_capset(): RSBAC not initialized\n");
03335         return(-RSBAC_ENOTINITIALIZED);
03336       }
03337     if (in_interrupt())
03338       {
03339         rsbac_printk(KERN_WARNING "rsbac_auth_clear_f_capset(): called from interrupt!\n");
03340       }
03341     /* protect device list */
03342     rsbac_read_lock(&device_list_head.lock, &dflags);
03343     device_p = lookup_device(file.device);
03344     if(!device_p)
03345       {
03346         /* trigger rsbac_mount() */
03347         rsbac_read_unlock(&device_list_head.lock, &dflags);
03348         rsbac_get_super_block(file.device);
03349         /* retry */
03350         rsbac_read_lock(&device_list_head.lock, &dflags);
03351         device_p = lookup_device(file.device);
03352         if(!device_p)
03353           {
03354             rsbac_printk(KERN_WARNING "rsbac_auth_clear_f_capset(): invalid device %02u:%02u!\n",
03355                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03356             rsbac_read_unlock(&device_list_head.lock, &dflags);
03357             return(-RSBAC_EINVALIDDEV);
03358           }
03359       }
03360     switch(cap_type)
03361       {
03362         case ACT_real:
03363           err = rsbac_ta_list_lol_remove(ta_number, device_p->handles[fd_hash(file.inode)], &file.inode);
03364           break;
03365 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03366         case ACT_eff:
03367           err = rsbac_ta_list_lol_remove(ta_number, device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode);
03368           break;
03369         case ACT_fs:
03370           err = rsbac_ta_list_lol_remove(ta_number, device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode);
03371           break;
03372 #endif
03373 #ifdef CONFIG_RSBAC_AUTH_GROUP
03374         case ACT_group_real:
03375           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_handles[group_fd_hash(file.inode)], &file.inode);
03376           break;
03377 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03378         case ACT_group_eff:
03379           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_eff_handles[group_eff_fd_hash(file.inode)], &file.inode);
03380           break;
03381         case ACT_group_fs:
03382           err = rsbac_ta_list_lol_remove(ta_number, device_p->group_fs_handles[group_fs_fd_hash(file.inode)], &file.inode);
03383           break;
03384 #endif
03385 #endif /* AUTH_GROUP */
03386 
03387         default:
03388           err = -RSBAC_EINVALIDTARGET;
03389       }
03390     rsbac_read_unlock(&device_list_head.lock, &dflags);
03391     return(err);
03392   }
03393 
03394 /* rsbac_auth_capset_member */
03395 /* Return truth value, whether member is in set */
03396 
03397 rsbac_boolean_t  rsbac_auth_p_capset_member(rsbac_pid_t pid,
03398                                     enum rsbac_auth_cap_type_t cap_type,
03399                                     rsbac_uid_t member)
03400   {
03401     rsbac_boolean_t result;
03402 
03403     if (!rsbac_is_initialized())
03404       {
03405         rsbac_printk(KERN_WARNING "rsbac_auth_p_capset_member(): RSBAC not initialized\n");
03406         return FALSE;
03407       }
03408     if (in_interrupt())
03409       {
03410         rsbac_printk(KERN_WARNING "rsbac_auth_p_capset_member(): called from interrupt!\n");
03411       }
03412     switch(cap_type)
03413       {
03414         case ACT_real:
03415           result = rsbac_list_lol_subexist_compare(process_handle, &pid, &member, single_cap_compare);
03416 
03417           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03418           if(   !result
03419              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03420             )
03421             {
03422               union rsbac_target_id_t tid;
03423               union rsbac_attribute_value_t attr_val;
03424               rsbac_boolean_t learn;
03425 
03426               learn = rsbac_auth_learn;
03427               if(!learn)
03428                 {
03429                   tid.process = pid;
03430                   /* check learn on process */
03431                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03432                     learn = attr_val.auth_learn;
03433                 }
03434               if(learn)
03435                 {
03436                   struct rsbac_auth_cap_range_t range;
03437 
03438                   rsbac_printk(KERN_INFO
03439                          "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to process %u (%.15s)!\n",
03440                          member,
03441                          pid,
03442                          current->comm);
03443                   range.first = member;
03444                   range.last = member;
03445                   rsbac_list_lol_subadd(process_handle, &pid, &range, NULL);
03446 
03447                   tid.process = pid;
03448                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03449                     {
03450                       struct rsbac_auth_device_list_item_t * device_p;
03451                       union rsbac_attribute_value_t attr_val2;
03452                       u_long dflags;
03453 
03454                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)
03455                          && (range.first == attr_val2.auth_start_uid)
03456                         )
03457                         {
03458                           range.first = RSBAC_AUTH_OWNER_F_CAP;
03459                           range.last = range.first;
03460                         }
03461                       rsbac_printk(KERN_INFO
03462                              "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to file %u on device %02u:%02u!\n",
03463                              range.first,
03464                              attr_val.auth_program_file.inode,
03465                              MAJOR(attr_val.auth_program_file.device),
03466                              MINOR(attr_val.auth_program_file.device));
03467                       rsbac_read_lock(&device_list_head.lock, &dflags);
03468                       device_p = lookup_device(attr_val.auth_program_file.device);
03469                       if(device_p)
03470                         {
03471                           rsbac_list_lol_subadd(device_p->handles[fd_hash(attr_val.auth_program_file.inode)],
03472                                                 &attr_val.auth_program_file.inode, &range, NULL);
03473                         }
03474                       else
03475                         {
03476                           rsbac_printk(KERN_INFO
03477                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03478                                  MAJOR(attr_val.auth_program_file.device),
03479                                  MINOR(attr_val.auth_program_file.device));
03480                         }
03481                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03482                     }
03483                   result = TRUE;
03484                 }
03485             }
03486           #endif
03487           break;
03488 
03489 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03490         case ACT_eff:
03491           result = rsbac_list_lol_subexist_compare(process_eff_handle, &pid, &member, single_cap_compare);
03492 
03493           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03494           if(   !result
03495              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03496             )
03497             {
03498               union rsbac_target_id_t tid;
03499               union rsbac_attribute_value_t attr_val;
03500               rsbac_boolean_t learn;
03501 
03502               learn = rsbac_auth_learn;
03503               if(!learn)
03504                 {
03505                   tid.process = pid;
03506                   /* check learn on process */
03507                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03508                     learn = attr_val.auth_learn;
03509                 }
03510               if(learn)
03511                 {
03512                   struct rsbac_auth_cap_range_t range;
03513 
03514                   rsbac_printk(KERN_INFO
03515                          "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to process %u (%.15s)!\n",
03516                          member,
03517                          pid,
03518                          current->comm);
03519                   range.first = member;
03520                   range.last = member;
03521                   rsbac_list_lol_subadd(process_eff_handle, &pid, &range, NULL);
03522 
03523                   tid.process = pid;
03524                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03525                     {
03526                       struct rsbac_auth_device_list_item_t * device_p;
03527                       union rsbac_attribute_value_t attr_val2;
03528                       u_long dflags;
03529 
03530                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)
03531                          && (range.first == attr_val2.auth_start_uid)
03532                         )
03533                         {
03534                           range.first = RSBAC_AUTH_OWNER_F_CAP;
03535                           range.last = range.first;
03536                         }
03537                       else
03538                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_euid, &attr_val2, FALSE)
03539                          && (range.first == attr_val2.auth_start_euid)
03540                         )
03541                         {
03542                           range.first = RSBAC_AUTH_DAC_OWNER_F_CAP;
03543                           range.last = range.first;
03544                         }
03545                       rsbac_printk(KERN_INFO
03546                              "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to file %u on device %02u:%02u!\n",
03547                              range.first,
03548                              attr_val.auth_program_file.inode,
03549                              MAJOR(attr_val.auth_program_file.device),
03550                              MINOR(attr_val.auth_program_file.device));
03551                       rsbac_read_lock(&device_list_head.lock, &dflags);
03552                       device_p = lookup_device(attr_val.auth_program_file.device);
03553                       if(device_p)
03554                         {
03555                           rsbac_list_lol_subadd(device_p->eff_handles[eff_fd_hash(attr_val.auth_program_file.inode)],
03556                                                 &attr_val.auth_program_file.inode, &range, NULL);
03557                         }
03558                       else
03559                         {
03560                           rsbac_printk(KERN_INFO
03561                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03562                                  MAJOR(attr_val.auth_program_file.device),
03563                                  MINOR(attr_val.auth_program_file.device));
03564                         }
03565                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03566                     }
03567                   result = TRUE;
03568                 }
03569             }
03570           #endif
03571           break;
03572 
03573         case ACT_fs:
03574           result = rsbac_list_lol_subexist_compare(process_fs_handle, &pid, &member, single_cap_compare);
03575 
03576           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03577           if(   !result
03578              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03579             )
03580             {
03581               union rsbac_target_id_t tid;
03582               union rsbac_attribute_value_t attr_val;
03583               rsbac_boolean_t learn;
03584 
03585               learn = rsbac_auth_learn;
03586               if(!learn)
03587                 {
03588                   tid.process = pid;
03589                   /* check learn on process */
03590                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03591                     learn = attr_val.auth_learn;
03592                 }
03593               if(learn)
03594                 {
03595                   struct rsbac_auth_cap_range_t range;
03596 
03597                   rsbac_printk(KERN_INFO
03598                          "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to process %u (%.15s)!\n",
03599                          member,
03600                          pid,
03601                          current->comm);
03602                   range.first = member;
03603                   range.last = member;
03604                   rsbac_list_lol_subadd(process_fs_handle, &pid, &range, NULL);
03605 
03606                   tid.process = pid;
03607                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03608                     {
03609                       struct rsbac_auth_device_list_item_t * device_p;
03610                       union rsbac_attribute_value_t attr_val2;
03611                       u_long dflags;
03612 
03613                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)
03614                          && (range.first == attr_val2.auth_start_uid)
03615                         )
03616                         {
03617                           range.first = RSBAC_AUTH_OWNER_F_CAP;
03618                           range.last = range.first;
03619                         }
03620                       else
03621                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_euid, &attr_val2, FALSE)
03622                          && (range.first == attr_val2.auth_start_euid)
03623                         )
03624                         {
03625                           range.first = RSBAC_AUTH_DAC_OWNER_F_CAP;
03626                           range.last = range.first;
03627                         }
03628                       rsbac_printk(KERN_INFO
03629                              "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to file %u on device %02u:%02u!\n",
03630                              range.first,
03631                              attr_val.auth_program_file.inode,
03632                              MAJOR(attr_val.auth_program_file.device),
03633                              MINOR(attr_val.auth_program_file.device));
03634                       rsbac_read_lock(&device_list_head.lock, &dflags);
03635                       device_p = lookup_device(attr_val.auth_program_file.device);
03636                       if(device_p)
03637                         {
03638                           rsbac_list_lol_subadd(device_p->fs_handles[fs_fd_hash(attr_val.auth_program_file.inode)],
03639                                                 &attr_val.auth_program_file.inode, &range, NULL);
03640                         }
03641                       else
03642                         {
03643                           rsbac_printk(KERN_INFO
03644                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03645                                  MAJOR(attr_val.auth_program_file.device),
03646                                  MINOR(attr_val.auth_program_file.device));
03647                         }
03648                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03649                     }
03650                   result = TRUE;
03651                 }
03652             }
03653           #endif
03654           break;
03655 #endif /* AUTH_DAC_OWNER */
03656 
03657 #ifdef CONFIG_RSBAC_AUTH_GROUP
03658         case ACT_group_real:
03659           result = rsbac_list_lol_subexist_compare(process_group_handle, &pid, &member, single_cap_compare);
03660 
03661           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03662           if(   !result
03663              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03664             )
03665             {
03666               union rsbac_target_id_t tid;
03667               union rsbac_attribute_value_t attr_val;
03668               rsbac_boolean_t learn;
03669 
03670               learn = rsbac_auth_learn;
03671               if(!learn)
03672                 {
03673                   tid.process = pid;
03674                   /* check learn on process */
03675                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03676                     learn = attr_val.auth_learn;
03677                 }
03678               if(learn)
03679                 {
03680                   struct rsbac_auth_cap_range_t range;
03681 
03682                   rsbac_printk(KERN_INFO
03683                          "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to process %u (%.15s)!\n",
03684                          member,
03685                          pid,
03686                          current->comm);
03687                   range.first = member;
03688                   range.last = member;
03689                   rsbac_list_lol_subadd(process_group_handle, &pid, &range, NULL);
03690 
03691                   tid.process = pid;
03692                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03693                     {
03694                       struct rsbac_auth_device_list_item_t * device_p;
03695                       union rsbac_attribute_value_t attr_val2;
03696                       u_long dflags;
03697 
03698                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_gid, &attr_val2, FALSE)
03699                          && (range.first == attr_val2.auth_start_gid)
03700                         )
03701                         {
03702                           range.first = RSBAC_AUTH_GROUP_F_CAP;
03703                           range.last = range.first;
03704                         }
03705                       rsbac_printk(KERN_INFO
03706                              "rsbac_auth_p_capset_member(): adding AUTH group capability for gid %u to file %u on device %02u:%02u!\n",
03707                              range.first,
03708                              attr_val.auth_program_file.inode,
03709                              MAJOR(attr_val.auth_program_file.device),
03710                              MINOR(attr_val.auth_program_file.device));
03711                       rsbac_read_lock(&device_list_head.lock, &dflags);
03712                       device_p = lookup_device(attr_val.auth_program_file.device);
03713                       if(device_p)
03714                         {
03715                           rsbac_list_lol_subadd(device_p->group_handles[group_fd_hash(attr_val.auth_program_file.inode)],
03716                                                 &attr_val.auth_program_file.inode, &range, NULL);
03717                         }
03718                       else
03719                         {
03720                           rsbac_printk(KERN_INFO
03721                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03722                                  MAJOR(attr_val.auth_program_file.device),
03723                                  MINOR(attr_val.auth_program_file.device));
03724                         }
03725                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03726                     }
03727                   result = TRUE;
03728                 }
03729             }
03730           #endif
03731           break;
03732 
03733 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03734         case ACT_group_eff:
03735           result = rsbac_list_lol_subexist_compare(process_group_eff_handle, &pid, &member, single_cap_compare);
03736 
03737           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03738           if(   !result
03739              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03740             )
03741             {
03742               union rsbac_target_id_t tid;
03743               union rsbac_attribute_value_t attr_val;
03744               rsbac_boolean_t learn;
03745 
03746               learn = rsbac_auth_learn;
03747               if(!learn)
03748                 {
03749                   tid.process = pid;
03750                   /* check learn on process */
03751                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03752                     learn = attr_val.auth_learn;
03753                 }
03754               if(learn)
03755                 {
03756                   struct rsbac_auth_cap_range_t range;
03757 
03758                   rsbac_printk(KERN_INFO
03759                          "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to process %u (%.15s)!\n",
03760                          member,
03761                          pid,
03762                          current->comm);
03763                   range.first = member;
03764                   range.last = member;
03765                   rsbac_list_lol_subadd(process_group_eff_handle, &pid, &range, NULL);
03766 
03767                   tid.process = pid;
03768                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03769                     {
03770                       struct rsbac_auth_device_list_item_t * device_p;
03771                       union rsbac_attribute_value_t attr_val2;
03772                       u_long dflags;
03773 
03774                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_gid, &attr_val2, FALSE)
03775                          && (range.first == attr_val2.auth_start_gid)
03776                         )
03777                         {
03778                           range.first = RSBAC_AUTH_GROUP_F_CAP;
03779                           range.last = range.first;
03780                         }
03781                       else
03782                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_egid, &attr_val2, FALSE)
03783                          && (range.first == attr_val2.auth_start_egid)
03784                         )
03785                         {
03786                           range.first = RSBAC_AUTH_DAC_GROUP_F_CAP;
03787                           range.last = range.first;
03788                         }
03789                       rsbac_printk(KERN_INFO
03790                              "rsbac_auth_p_capset_member(): adding AUTH group eff capability for gid %u to file %u on device %02u:%02u!\n",
03791                              range.first,
03792                              attr_val.auth_program_file.inode,
03793                              MAJOR(attr_val.auth_program_file.device),
03794                              MINOR(attr_val.auth_program_file.device));
03795                       rsbac_read_lock(&device_list_head.lock, &dflags);
03796                       device_p = lookup_device(attr_val.auth_program_file.device);
03797                       if(device_p)
03798                         {
03799                           rsbac_list_lol_subadd(device_p->group_eff_handles[group_eff_fd_hash(attr_val.auth_program_file.inode)],
03800                                                 &attr_val.auth_program_file.inode, &range, NULL);
03801                         }
03802                       else
03803                         {
03804                           rsbac_printk(KERN_INFO
03805                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03806                                  MAJOR(attr_val.auth_program_file.device),
03807                                  MINOR(attr_val.auth_program_file.device));
03808                         }
03809                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03810                     }
03811                   result = TRUE;
03812                 }
03813             }
03814           #endif
03815           break;
03816 
03817         case ACT_group_fs:
03818           result = rsbac_list_lol_subexist_compare(process_group_fs_handle, &pid, &member, single_cap_compare);
03819 
03820           #if defined(CONFIG_RSBAC_AUTH_LEARN)
03821           if(   !result
03822              && (member <= RSBAC_AUTH_MAX_RANGE_UID)
03823             )
03824             {
03825               union rsbac_target_id_t tid;
03826               union rsbac_attribute_value_t attr_val;
03827               rsbac_boolean_t learn;
03828 
03829               learn = rsbac_auth_learn;
03830               if(!learn)
03831                 {
03832                   tid.process = pid;
03833                   /* check learn on process */
03834                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE))
03835                     learn = attr_val.auth_learn;
03836                 }
03837               if(learn)
03838                 {
03839                   struct rsbac_auth_cap_range_t range;
03840 
03841                   rsbac_printk(KERN_INFO
03842                          "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to process %u (%.15s)!\n",
03843                          member,
03844                          pid,
03845                          current->comm);
03846                   range.first = member;
03847                   range.last = member;
03848                   rsbac_list_lol_subadd(process_group_fs_handle, &pid, &range, NULL);
03849 
03850                   tid.process = pid;
03851                   if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE))
03852                     {
03853                       struct rsbac_auth_device_list_item_t * device_p;
03854                       union rsbac_attribute_value_t attr_val2;
03855                       u_long dflags;
03856 
03857                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_gid, &attr_val2, FALSE)
03858                          && (range.first == attr_val2.auth_start_gid)
03859                         )
03860                         {
03861                           range.first = RSBAC_AUTH_GROUP_F_CAP;
03862                           range.last = range.first;
03863                         }
03864                       else
03865                       if(   !rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_egid, &attr_val2, FALSE)
03866                          && (range.first == attr_val2.auth_start_egid)
03867                         )
03868                         {
03869                           range.first = RSBAC_AUTH_DAC_GROUP_F_CAP;
03870                           range.last = range.first;
03871                         }
03872                       rsbac_printk(KERN_INFO
03873                              "rsbac_auth_p_capset_member(): adding AUTH group fs capability for gid %u to file %u on device %02u:%02u!\n",
03874                              range.first,
03875                              attr_val.auth_program_file.inode,
03876                              MAJOR(attr_val.auth_program_file.device),
03877                              MINOR(attr_val.auth_program_file.device));
03878                       rsbac_read_lock(&device_list_head.lock, &dflags);
03879                       device_p = lookup_device(attr_val.auth_program_file.device);
03880                       if(device_p)
03881                         {
03882                           rsbac_list_lol_subadd(device_p->group_fs_handles[group_fs_fd_hash(attr_val.auth_program_file.inode)],
03883                                                 &attr_val.auth_program_file.inode, &range, NULL);
03884                         }
03885                       else
03886                         {
03887                           rsbac_printk(KERN_INFO
03888                                  "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n",
03889                                  MAJOR(attr_val.auth_program_file.device),
03890                                  MINOR(attr_val.auth_program_file.device));
03891                         }
03892                       rsbac_read_unlock(&device_list_head.lock, &dflags);
03893                     }
03894                   result = TRUE;
03895                 }
03896             }
03897           #endif
03898           break;
03899 #endif /* AUTH_DAC_GROUP */
03900 #endif /* AUTH_GROUP */
03901 
03902         default:
03903           return FALSE;
03904       }
03905     return result;
03906   }
03907 
03908 /* rsbac_auth_remove_capset */
03909 /* Remove a full set. For cleanup, if object is deleted. */
03910 /* To empty an existing set use rsbac_auth_clear_capset. */
03911 
03912 int rsbac_auth_remove_p_capsets(rsbac_pid_t pid)
03913   {
03914     int err;
03915 
03916     err = rsbac_auth_clear_p_capset(0, pid, ACT_real);
03917 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03918     err = rsbac_auth_clear_p_capset(0, pid, ACT_eff);
03919     err = rsbac_auth_clear_p_capset(0, pid, ACT_fs);
03920 #endif
03921 #ifdef CONFIG_RSBAC_AUTH_GROUP
03922     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_real);
03923 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03924     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_eff);
03925     err = rsbac_auth_clear_p_capset(0, pid, ACT_group_fs);
03926 #endif
03927 #endif /* AUTH_GROUP */
03928 
03929     return err;
03930   }
03931 
03932 int rsbac_auth_remove_f_capsets(rsbac_auth_file_t file)
03933   {
03934     int err;
03935 
03936     err = rsbac_auth_clear_f_capset(0, file, ACT_real);
03937 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
03938     if(!err)
03939       err = rsbac_auth_clear_f_capset(0, file, ACT_eff);
03940     if(!err)
03941       err = rsbac_auth_clear_f_capset(0, file, ACT_fs);
03942 #endif
03943 #ifdef CONFIG_RSBAC_AUTH_GROUP
03944     err = rsbac_auth_clear_f_capset(0, file, ACT_group_real);
03945 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
03946     if(!err)
03947       err = rsbac_auth_clear_f_capset(0, file, ACT_group_eff);
03948     if(!err)
03949       err = rsbac_auth_clear_f_capset(0, file, ACT_group_fs);
03950 #endif
03951 #endif /* AUTH_GROUP */
03952 
03953     return err;
03954   }
03955 
03956 int rsbac_auth_copy_fp_capset(rsbac_auth_file_t    file,
03957                               rsbac_pid_t p_cap_set_id)
03958   {
03959     u_long dflags;
03960     struct rsbac_auth_device_list_item_t * device_p;
03961     int err=0;
03962 
03963     if (!rsbac_is_initialized())
03964       {
03965         rsbac_printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): RSBAC not initialized\n");
03966         return(-RSBAC_ENOTINITIALIZED);
03967       }
03968     if (in_interrupt())
03969       {
03970         rsbac_printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): called from interrupt!\n");
03971       }
03972 /*
03973 #ifdef CONFIG_RSBAC_DEBUG
03974     if (rsbac_debug_ds_auth)
03975       rsbac_printk(KERN_DEBUG
03976              "rsbac_auth_copy_fp_capset(): Copying file cap set data to process cap set\n");
03977 #endif
03978 */
03979     /* protect device list */
03980     rsbac_read_lock(&device_list_head.lock, &dflags);
03981     device_p = lookup_device(file.device);
03982     if(!device_p)
03983       {
03984         /* trigger rsbac_mount() */
03985         rsbac_read_unlock(&device_list_head.lock, &dflags);
03986         rsbac_get_super_block(file.device);
03987         /* retry */
03988         rsbac_read_lock(&device_list_head.lock, &dflags);
03989         device_p = lookup_device(file.device);
03990         if(!device_p)
03991           {
03992             rsbac_printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): invalid device %02u:%02u!\n",
03993                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
03994             rsbac_read_unlock(&device_list_head.lock, &dflags);
03995             return(-RSBAC_EINVALIDDEV);
03996           }
03997       }
03998     /* call the copy function */
03999     err = copy_fp_cap_set_item(device_p,file,p_cap_set_id);
04000     rsbac_read_unlock(&device_list_head.lock, &dflags);
04001     return(err);
04002   }
04003 
04004 int rsbac_auth_copy_pp_capset(rsbac_pid_t old_p_set_id,
04005                               rsbac_pid_t new_p_set_id)
04006   {
04007     if (!rsbac_is_initialized())
04008       {
04009         rsbac_printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): RSBAC not initialized\n");
04010         return(-RSBAC_ENOTINITIALIZED);
04011       }
04012     if (in_interrupt())
04013       {
04014         rsbac_printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): called from interrupt!\n");
04015       }
04016 /*
04017 #ifdef CONFIG_RSBAC_DEBUG
04018     if (rsbac_debug_ds_auth)
04019       rsbac_printk(KERN_DEBUG
04020              "rsbac_auth_copy_pp_capset(): Copying process cap set data to process cap set\n");
04021 #endif
04022 */
04023     /* call the copy function */
04024     return copy_pp_cap_set_item(old_p_set_id,new_p_set_id);
04025   }
04026 
04027 int rsbac_auth_get_f_caplist(
04028          rsbac_list_ta_number_t ta_number,
04029          rsbac_auth_file_t file,
04030   enum   rsbac_auth_cap_type_t cap_type,
04031   struct rsbac_auth_cap_range_t **caplist_p,
04032          rsbac_time_t **ttllist_p)
04033   {
04034     u_long dflags;
04035     struct rsbac_auth_device_list_item_t * device_p;
04036     long count;
04037 
04038     if (!rsbac_is_initialized())
04039       {
04040         rsbac_printk(KERN_WARNING "rsbac_auth_get_f_caplist(): RSBAC not initialized\n");
04041         return(-RSBAC_ENOTINITIALIZED);
04042       }
04043     if (in_interrupt())
04044       {
04045         rsbac_printk(KERN_WARNING "rsbac_auth_get_f_caplist(): called from interrupt!\n");
04046       }
04047 /*
04048 #ifdef CONFIG_RSBAC_DEBUG
04049     if (rsbac_debug_ds_auth)
04050       rsbac_printk(KERN_DEBUG
04051              "rsbac_auth_get_f_caplist(): Getting file/dir cap set list\n");
04052 #endif
04053 */
04054     /* protect device list */
04055     rsbac_read_lock(&device_list_head.lock, &dflags);
04056     device_p = lookup_device(file.device);
04057     if(!device_p)
04058       {
04059         /* trigger rsbac_mount() */
04060         rsbac_read_unlock(&device_list_head.lock, &dflags);
04061         rsbac_get_super_block(file.device);
04062         /* retry */
04063         rsbac_read_lock(&device_list_head.lock, &dflags);
04064         device_p = lookup_device(file.device);
04065         if(!device_p)
04066           {
04067             rsbac_printk(KERN_WARNING "rsbac_auth_get_f_caplist(): invalid device %02u:%02u!\n",
04068                    RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device));
04069             rsbac_read_unlock(&device_list_head.lock, &dflags);
04070             return(-RSBAC_EINVALIDDEV);
04071           }
04072       }
04073     switch(cap_type)
04074       {
04075         case ACT_real:
04076           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04077                                                      device_p->handles[fd_hash(file.inode)],
04078                                                      &file.inode,
04079                                                      (void **) caplist_p,
04080                                                      ttllist_p);
04081           break;
04082 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04083         case ACT_eff:
04084           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04085                                                      device_p->eff_handles[eff_fd_hash(file.inode)],
04086                                                      &file.inode,
04087                                                      (void **) caplist_p,
04088                                                      ttllist_p);
04089           break;
04090         case ACT_fs:
04091           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04092                                                      device_p->fs_handles[fs_fd_hash(file.inode)],
04093                                                      &file.inode,
04094                                                      (void **) caplist_p,
04095                                                      ttllist_p);
04096           break;
04097 #endif
04098 #ifdef CONFIG_RSBAC_AUTH_GROUP
04099         case ACT_group_real:
04100           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04101                                                      device_p->group_handles[group_fd_hash(file.inode)],
04102                                                      &file.inode,
04103                                                      (void **) caplist_p,
04104                                                      ttllist_p);
04105           break;
04106 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04107         case ACT_group_eff:
04108           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04109                                                      device_p->group_eff_handles[group_eff_fd_hash(file.inode)],
04110                                                      &file.inode,
04111                                                      (void **) caplist_p,
04112                                                      ttllist_p);
04113           break;
04114         case ACT_group_fs:
04115           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04116                                                      device_p->group_fs_handles[group_fs_fd_hash(file.inode)],
04117                                                      &file.inode,
04118                                                      (void **) caplist_p,
04119                                                      ttllist_p);
04120           break;
04121 #endif
04122 #endif /* AUTH_GROUP */
04123 
04124         default:
04125           count = -RSBAC_EINVALIDTARGET;
04126       }
04127     rsbac_read_unlock(&device_list_head.lock, &dflags);
04128     return(count);
04129   }
04130 
04131 int rsbac_auth_get_p_caplist(
04132          rsbac_list_ta_number_t ta_number,
04133          rsbac_pid_t pid,
04134   enum   rsbac_auth_cap_type_t cap_type,
04135   struct rsbac_auth_cap_range_t **caplist_p,
04136          rsbac_time_t **ttllist_p)
04137   {
04138     long count;
04139 
04140     if (!rsbac_is_initialized())
04141       {
04142         rsbac_printk(KERN_WARNING "rsbac_auth_get_p_caplist(): RSBAC not initialized\n");
04143         return(-RSBAC_ENOTINITIALIZED);
04144       }
04145     if (in_interrupt())
04146       {
04147         rsbac_printk(KERN_WARNING "rsbac_auth_get_p_caplist(): called from interrupt!\n");
04148       }
04149 /*
04150 #ifdef CONFIG_RSBAC_DEBUG
04151     if (rsbac_debug_ds_auth)
04152       rsbac_printk(KERN_DEBUG
04153              "rsbac_auth_get_p_caplist(): Getting process cap set list\n");
04154 #endif
04155 */
04156     switch(cap_type)
04157       {
04158         case ACT_real:
04159           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04160                                                      process_handle,
04161                                                      &pid,
04162                                                      (void **) caplist_p,
04163                                                      ttllist_p);
04164           break;
04165 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER
04166         case ACT_eff:
04167           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04168                                                      process_eff_handle,
04169                                                      &pid,
04170                                                      (void **) caplist_p,
04171                                                      ttllist_p);
04172           break;
04173         case ACT_fs:
04174           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04175                                                      process_fs_handle,
04176                                                      &pid,
04177                                                      (void **) caplist_p,
04178                                                      ttllist_p);
04179           break;
04180 #endif
04181 #ifdef CONFIG_RSBAC_AUTH_GROUP
04182         case ACT_group_real:
04183           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04184                                                      process_group_handle,
04185                                                      &pid,
04186                                                      (void **) caplist_p,
04187                                                      ttllist_p);
04188           break;
04189 #ifdef CONFIG_RSBAC_AUTH_DAC_GROUP
04190         case ACT_group_eff:
04191           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04192                                                      process_group_eff_handle,
04193                                                      &pid,
04194                                                      (void **) caplist_p,
04195                                                      ttllist_p);
04196           break;
04197         case ACT_group_fs:
04198           count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
04199                                                      process_group_fs_handle,
04200                                                      &pid,
04201                                                      (void **) caplist_p,
04202                                                      ttllist_p);
04203           break;
04204 #endif
04205 #endif /* AUTH_GROUP */
04206 
04207         default:
04208           count = -RSBAC_EINVALIDTARGET;
04209       }
04210     return(count);
04211   }
04212 
04213 /* end of auth_data_structures.c */

Generated on Sun May 21 14:30:53 2006 for RSBAC by  doxygen 1.4.2