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

Generated on Wed May 16 11:53:41 2007 for RSBAC by  doxygen 1.5.1