/linux-2.6.21.1-rsbac-1.3.4/rsbac/data_structures/mac_data_structures.c

Go to the documentation of this file.
00001 /*************************************************** */
00002 /* Rule Set Based Access Control                     */
00003 /* Implementation of MAC data structures            */
00004 /* Author and (c) 1999-2006: Amon Ott <ao@rsbac.org> */
00005 /*                                                   */
00006 /* Last modified: 14/Jun/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/mac_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/lists.h>
00023 #include <rsbac/proc_fs.h>
00024 #include <rsbac/rkmem.h>
00025 #include <rsbac/getname.h>
00026 #include <linux/string.h>
00027 #include <linux/smp_lock.h>
00028 
00029 /************************************************************************** */
00030 /*                          Global Variables                                */
00031 /************************************************************************** */
00032 
00033 static struct rsbac_mac_device_list_head_t device_list_head;
00034 
00035 static rsbac_list_handle_t process_handle = NULL;
00036 
00037 /**************************************************/
00038 /*       Declarations of external functions       */
00039 /**************************************************/
00040 
00041 rsbac_boolean_t writable(struct super_block *sb_p);
00042 
00043 /**************************************************/
00044 /*       Declarations of internal functions       */
00045 /**************************************************/
00046 
00047 /************************************************* */
00048 /*               Internal Help functions           */
00049 /************************************************* */
00050 
00051 static u_int nr_fd_hashes = RSBAC_MAC_NR_TRU_FD_LISTS;
00052 
00053 /* mac_register_fd_lists() */
00054 /* register fd ACL lists for device */
00055 
00056 static int mac_register_fd_lists(struct rsbac_mac_device_list_item_t
00057                                  *device_p, kdev_t kdev)
00058 {
00059         int err = 0;
00060         int tmperr;
00061         struct rsbac_list_lol_info_t lol_info;
00062 
00063         if (!device_p)
00064                 return (-RSBAC_EINVALIDPOINTER);
00065 
00066         lol_info.version = RSBAC_MAC_FD_LIST_VERSION;
00067         lol_info.key = RSBAC_MAC_LIST_KEY;
00068         lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00069         lol_info.data_size = 0;
00070         lol_info.subdesc_size = sizeof(rsbac_uid_t);
00071         lol_info.subdata_size = 0;      /* rights */
00072         lol_info.max_age = 0;
00073         tmperr = rsbac_list_lol_register_hashed(RSBAC_LIST_VERSION,
00074                                          &device_p->handle,
00075                                          &lol_info,
00076                                          RSBAC_LIST_PERSIST |
00077                                          RSBAC_LIST_DEF_DATA,
00078                                          NULL,
00079                                          NULL,
00080                                          NULL, NULL, NULL, NULL,
00081                                          RSBAC_MAC_FD_FILENAME, kdev,
00082                                          nr_fd_hashes,
00083                                          rsbac_list_hash_fd,
00084                                          RSBAC_MAC_FD_OLD_FILENAME);
00085         if (tmperr) {
00086                 char *tmp;
00087 
00088                 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00089                 if (tmp) {
00090                         rsbac_printk(KERN_WARNING "mac_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00091                                      RSBAC_MAC_FD_FILENAME,
00092                                      RSBAC_MAJOR(kdev),
00093                                      RSBAC_MINOR(kdev),
00094                                      get_error_name(tmp, tmperr));
00095                         rsbac_kfree(tmp);
00096                 }
00097                 err = tmperr;
00098         }
00099         return err;
00100 }
00101 
00102 /* mac_detach_fd_lists() */
00103 /* detach from fd MAC lists for device */
00104 
00105 static int mac_detach_fd_lists(struct rsbac_mac_device_list_item_t
00106                                *device_p)
00107 {
00108         int err = 0;
00109 
00110         if (!device_p)
00111                 return (-RSBAC_EINVALIDPOINTER);
00112 
00113         err = rsbac_list_lol_detach(&device_p->handle,
00114                                        RSBAC_MAC_LIST_KEY);
00115         if (err) {
00116                 char *tmp;
00117 
00118                 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00119                 if (tmp) {
00120                         rsbac_printk(KERN_WARNING "mac_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00121                                      RSBAC_MAC_FD_FILENAME,
00122                                      RSBAC_MAJOR(device_p->id),
00123                                      RSBAC_MINOR(device_p->id),
00124                                      get_error_name(tmp, err));
00125                         rsbac_kfree(tmp);
00126                 }
00127         }
00128         return err;
00129 }
00130 
00131 /************************************************************************** */
00132 /* The lookup functions return NULL, if the item is not found, and a        */
00133 /* pointer to the item otherwise.                                           */
00134 
00135 /* first the device item lookup */
00136 static struct rsbac_mac_device_list_item_t *lookup_device(kdev_t kdev)
00137 {
00138         struct rsbac_mac_device_list_item_t *curr = device_list_head.curr;
00139 
00140         /* if there is no current item or it is not the right one, search... */
00141         if (!(curr && (RSBAC_MAJOR(curr->id) == RSBAC_MAJOR(kdev))
00142               && (RSBAC_MINOR(curr->id) == RSBAC_MINOR(kdev))
00143             )
00144             ) {
00145                 curr = device_list_head.head;
00146                 while (curr
00147                        && ((RSBAC_MAJOR(curr->id) != RSBAC_MAJOR(kdev))
00148                            || (RSBAC_MINOR(curr->id) != RSBAC_MINOR(kdev))
00149                        )
00150                     ) {
00151                         curr = curr->next;
00152                 }
00153                 if (curr)
00154                         device_list_head.curr = curr;
00155         }
00156         /* it is the current item -> return it */
00157         return (curr);
00158 }
00159 
00160 /************************************************************************** */
00161 /* The add_item() functions add an item to the list, set head.curr to it,   */
00162 /* and return a pointer to the item.                                        */
00163 /* These functions will NOT check, if there is already an item under the    */
00164 /* same ID! If this happens, the lookup functions will return the old item! */
00165 /* All list manipulation is protected by rw-spinlocks to prevent inconsistency */
00166 /* and undefined behaviour in other concurrent functions.                   */
00167 
00168 /* Create a device item without adding to list. No locking needed. */
00169 static struct rsbac_mac_device_list_item_t
00170 *create_device_item(kdev_t kdev)
00171 {
00172         struct rsbac_mac_device_list_item_t *new_item_p;
00173 
00174         /* allocate memory for new device, return NULL, if failed */
00175         if (!(new_item_p = (struct rsbac_mac_device_list_item_t *)
00176               rsbac_kmalloc(sizeof(*new_item_p))))
00177                 return (NULL);
00178 
00179         new_item_p->id = kdev;
00180         new_item_p->mount_count = 1;
00181 
00182         /* init file/dir sublists */
00183         new_item_p->handle = NULL;
00184         return (new_item_p);
00185 }
00186 
00187 /* Add an existing device item to list. Locking needed. */
00188 static struct rsbac_mac_device_list_item_t
00189 *add_device_item(struct rsbac_mac_device_list_item_t *device_p)
00190 {
00191         if (!device_p)
00192                 return (NULL);
00193 
00194         /* add new device to device list */
00195         if (!device_list_head.head) {   /* first device */
00196                 device_list_head.head = device_p;
00197                 device_list_head.tail = device_p;
00198                 device_list_head.curr = device_p;
00199                 device_list_head.count = 1;
00200                 device_p->prev = NULL;
00201                 device_p->next = NULL;
00202         } else {                /* there is another device -> hang to tail */
00203                 device_p->prev = device_list_head.tail;
00204                 device_p->next = NULL;
00205                 device_list_head.tail->next = device_p;
00206                 device_list_head.tail = device_p;
00207                 device_list_head.curr = device_p;
00208                 device_list_head.count++;
00209         }
00210         return (device_p);
00211 }
00212 
00213 /************************************************************************** */
00214 /* The remove_item() functions remove an item from the list. If this item   */
00215 /* is head, tail or curr, these pointers are set accordingly.               */
00216 /* To speed up removing several subsequent items, curr is set to the next   */
00217 /* item, if possible.                                                       */
00218 /* If the item is not found, nothing is done.                               */
00219 
00220 static void clear_device_item(struct rsbac_mac_device_list_item_t *item_p)
00221 {
00222         if (!item_p)
00223                 return;
00224 
00225         /* First deregister lists... */
00226         mac_detach_fd_lists(item_p);
00227         /* OK, lets remove the device item itself */
00228         rsbac_kfree(item_p);
00229 }                               /* end of clear_device_item() */
00230 
00231 static void remove_device_item(kdev_t kdev)
00232 {
00233         struct rsbac_mac_device_list_item_t *item_p;
00234 
00235         /* first we must locate the item. */
00236         if ((item_p = lookup_device(kdev))) {   /* ok, item was found */
00237                 if (device_list_head.head == item_p) {  /* item is head */
00238                         if (device_list_head.tail == item_p) {  /* item is head and tail = only item -> list will be empty */
00239                                 device_list_head.head = NULL;
00240                                 device_list_head.tail = NULL;
00241                         } else {        /* item is head, but not tail -> next item becomes head */
00242                                 item_p->next->prev = NULL;
00243                                 device_list_head.head = item_p->next;
00244                         }
00245                 } else {        /* item is not head */
00246                         if (device_list_head.tail == item_p) {  /*item is not head, but tail -> previous item becomes tail */
00247                                 item_p->prev->next = NULL;
00248                                 device_list_head.tail = item_p->prev;
00249                         } else {        /* item is neither head nor tail -> item is cut out */
00250                                 item_p->prev->next = item_p->next;
00251                                 item_p->next->prev = item_p->prev;
00252                         }
00253                 }
00254 
00255                 /* curr is no longer valid -> reset.                              */
00256                 device_list_head.curr = NULL;
00257                 /* adjust counter */
00258                 device_list_head.count--;
00259 
00260                 /* now we can remove the item from memory. This means cleaning up */
00261                 /* everything below. */
00262                 clear_device_item(item_p);
00263         }                       /* end of if: item was found */
00264 
00265 }                               /* end of remove_device_item() */
00266 
00267 /************************************************************************** */
00268 /* The copy_fp_tru_set_item() function copies a file cap set to a process   */
00269 /* cap set */
00270 
00271 static int copy_fp_tru_set_item(struct rsbac_mac_device_list_item_t
00272                                 *device_p, rsbac_mac_file_t file,
00273                                 rsbac_pid_t pid)
00274 {
00275         rsbac_uid_t *tru_item_p;
00276         rsbac_time_t *ttl_p;
00277         int i;
00278         long count;
00279         enum rsbac_target_t target = T_FILE;
00280         union rsbac_target_id_t tid;
00281 
00282         rsbac_list_lol_remove(process_handle, &pid);
00283         count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handle,
00284                                                &file.inode,
00285                                                (void **) &tru_item_p,
00286                                                &ttl_p);
00287         if (!count || (count == -RSBAC_ENOTFOUND)
00288             ) {
00289                 tid.file = file;
00290                 if (!rsbac_get_parent(target, tid, &target, &tid))
00291                         count =
00292                             rsbac_list_lol_get_all_subdesc_ttl(device_p->handle,
00293                                                                &tid.file.
00294                                                                inode,
00295                                                                (void **)
00296                                                                &tru_item_p,
00297                                                                &ttl_p);
00298         }
00299         if (count > 0) {
00300                 for (i = 0; i < count; i++) {
00301                         rsbac_list_lol_subadd_ttl(process_handle,
00302                                                   ttl_p[i],
00303                                                   &pid,
00304                                                   &tru_item_p[i], NULL);
00305                 }
00306                 rsbac_vfree(tru_item_p);
00307                 rsbac_vfree(ttl_p);
00308         } else {
00309                 if ((count < 0)
00310                     && (count != -RSBAC_ENOTFOUND)
00311                     )
00312                         return count;
00313         }
00314 
00315         return 0;
00316 }                               /* end of copy_fp_tru_set_item() */
00317 
00318 /************************************************************************** */
00319 /* The copy_pp_tru_set_item() function copies a process cap set to another  */
00320 
00321 static int copy_pp_tru_set_item_handle(rsbac_list_handle_t handle,
00322                                        rsbac_pid_t old_pid,
00323                                        rsbac_pid_t new_pid)
00324 {
00325         rsbac_uid_t *tru_item_p;
00326         rsbac_time_t *ttl_p;
00327         int i;
00328         long count;
00329 
00330         rsbac_list_lol_remove(handle, &new_pid);
00331         count = rsbac_list_lol_get_all_subdesc_ttl(handle,
00332                                                    &old_pid,
00333                                                    (void **) &tru_item_p,
00334                                                    &ttl_p);
00335         if (count > 0) {
00336                 for (i = 0; i < count; i++) {
00337                         rsbac_list_lol_subadd_ttl(handle,
00338                                                   ttl_p[i],
00339                                                   &new_pid,
00340                                                   &tru_item_p[i], NULL);
00341                 }
00342                 rsbac_vfree(tru_item_p);
00343                 rsbac_vfree(ttl_p);
00344         } else {
00345                 if (count < 0)
00346                         return count;
00347         }
00348         return 0;
00349 }
00350 
00351 static int copy_pp_tru_set_item(rsbac_pid_t old_pid, rsbac_pid_t new_pid)
00352 {
00353         return copy_pp_tru_set_item_handle(process_handle, old_pid,
00354                                            new_pid);
00355 }                               /* end of copy_pp_tru_set_item() */
00356 
00357 /************************************************* */
00358 /*               proc functions                    */
00359 /************************************************* */
00360 
00361 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00362 static int
00363 mac_devices_proc_info(char *buffer, char **start, off_t offset, int length)
00364 {
00365         int len = 0;
00366         off_t pos = 0;
00367         off_t begin = 0;
00368         struct rsbac_mac_device_list_item_t *device_p;
00369         u_long dflags;
00370 
00371         if (!rsbac_is_initialized())
00372                 return (-ENOSYS);
00373 
00374         len +=
00375             sprintf(buffer, "%u RSBAC MAC Devices\n-------------------\n",
00376                     device_list_head.count);
00377 
00378         /* wait for read access to device_list_head */
00379         rsbac_read_lock(&device_list_head.lock, &dflags);
00380         /* OK, go on */
00381         for (device_p = device_list_head.head; device_p;
00382              device_p = device_p->next) {
00383                 len += sprintf(buffer + len,
00384                             "%02u:%02u with mount_count = %u\n",
00385                             RSBAC_MAJOR(device_p->id),
00386                             RSBAC_MINOR(device_p->id),
00387                             device_p->mount_count);
00388                 pos = begin + len;
00389                 if (pos < offset) {
00390                         len = 0;
00391                         begin = pos;
00392                 }
00393                 if (pos > offset + length)
00394                         break;
00395         }
00396 
00397         /* free access to device_list_head */
00398         rsbac_read_unlock(&device_list_head.lock, &dflags);
00399 
00400         *start = buffer + (offset - begin);
00401         len -= (offset - begin);
00402 
00403         if (len > length)
00404                 len = length;
00405         return len;
00406 }
00407 
00408 static int
00409 stats_mac_proc_info(char *buffer, char **start, off_t offset, int length)
00410 {
00411         u_int len = 0;
00412         off_t pos = 0;
00413         off_t begin = 0;
00414 
00415         u_long dflags;
00416         struct rsbac_mac_device_list_item_t *device_p;
00417 
00418         union rsbac_target_id_t rsbac_target_id;
00419         union rsbac_attribute_value_t rsbac_attribute_value;
00420 
00421         if (!rsbac_is_initialized()) {
00422                 rsbac_printk(KERN_WARNING "stats_mac_proc_info(): RSBAC not initialized\n");
00423                 return (-RSBAC_ENOTINITIALIZED);
00424         }
00425         rsbac_pr_debug(aef_mac, "calling ADF\n");
00426         rsbac_target_id.scd = ST_rsbac;
00427         rsbac_attribute_value.dummy = 0;
00428         if (!rsbac_adf_request(R_GET_STATUS_DATA,
00429                                current->pid,
00430                                T_SCD,
00431                                rsbac_target_id,
00432                                A_none, rsbac_attribute_value)) {
00433                 return -EPERM;
00434         }
00435 
00436         len += sprintf(buffer, "MAC Status\n----------\n");
00437 
00438         len +=
00439             sprintf(buffer + len,
00440                     "%lu process trusted user set items, sum of %lu members\n",
00441                     rsbac_list_lol_count(process_handle),
00442                     rsbac_list_lol_all_subcount(process_handle));
00443         pos = begin + len;
00444         if (pos < offset) {
00445                 len = 0;
00446                 begin = pos;
00447         }
00448         if (pos > offset + length)
00449                 goto out;
00450 
00451         /* protect device list */
00452         rsbac_read_lock(&device_list_head.lock, &dflags);
00453         device_p = device_list_head.head;
00454         while (device_p) {
00455                 /* reset counters */
00456                 len +=
00457                     sprintf(buffer + len,
00458                             "device %02u:%02u has %lu file trusted user set items, sum of %lu members\n",
00459                             RSBAC_MAJOR(device_p->id),
00460                             RSBAC_MINOR(device_p->id),
00461                             rsbac_list_lol_count(device_p->handle),
00462                             rsbac_list_lol_all_subcount(device_p->handle));
00463                 pos = begin + len;
00464                 if (pos < offset) {
00465                         len = 0;
00466                         begin = pos;
00467                 }
00468                 if (pos > offset + length)
00469                         goto out_unlock;
00470 
00471                 device_p = device_p->next;
00472         }
00473       out_unlock:
00474         /* unprotect device list */
00475         rsbac_read_unlock(&device_list_head.lock, &dflags);
00476 
00477       out:
00478         *start = buffer + (offset - begin);
00479         len -= (offset - begin);
00480 
00481         if (len > length)
00482                 len = length;
00483         return len;
00484 }
00485 
00486 static int
00487 mac_trulist_proc_info(char *buffer, char **start, off_t offset, int length)
00488 {
00489         u_int len = 0;
00490         off_t pos = 0;
00491         off_t begin = 0;
00492 
00493         u_int count = 0;
00494         u_int member_count = 0;
00495         u_long all_member_count;
00496         u_long dflags;
00497         int i, j;
00498         struct rsbac_mac_device_list_item_t *device_p;
00499         rsbac_pid_t *p_list;
00500         rsbac_inode_nr_t *f_list;
00501         rsbac_uid_t *tru_list;
00502 
00503         union rsbac_target_id_t rsbac_target_id;
00504         union rsbac_attribute_value_t rsbac_attribute_value;
00505 
00506         if (!rsbac_is_initialized()) {
00507                 rsbac_printk(KERN_WARNING "mac_trulist_proc_info(): RSBAC not initialized\n");
00508                 return (-RSBAC_ENOTINITIALIZED);
00509         }
00510         rsbac_pr_debug(aef_mac, "calling ADF\n");
00511         rsbac_target_id.scd = ST_rsbac;
00512         rsbac_attribute_value.dummy = 0;
00513         if (!rsbac_adf_request(R_GET_STATUS_DATA,
00514                                current->pid,
00515                                T_SCD,
00516                                rsbac_target_id,
00517                                A_none, rsbac_attribute_value)) {
00518                 return -EPERM;
00519         }
00520 
00521         len += sprintf(buffer,
00522                     "MAC Trusted User Lists\n---------------------\n");
00523 
00524         /* protect process cap set list */
00525         len +=
00526             sprintf(buffer + len,
00527                     "Process trusted user sets:\nset-id  count   members");
00528         pos = begin + len;
00529         if (pos < offset) {
00530                 len = 0;
00531                 begin = pos;
00532         }
00533         if (pos > offset + length)
00534                 goto out;
00535 
00536         all_member_count = 0;
00537         count = rsbac_list_lol_get_all_desc(process_handle,
00538                                             (void **) &p_list);
00539         if (count > 0) {
00540                 for (i = 0; i < count; i++) {
00541                         member_count =
00542                             rsbac_list_lol_get_all_subdesc(process_handle,
00543                                                            &p_list[i],
00544                                                            (void **)
00545                                                            &tru_list);
00546                         len +=
00547                             sprintf(buffer + len, "\n %u\t%u\t", p_list[i],
00548                                     member_count);
00549                         if (member_count > 0) {
00550                                 for (j = 0; j < member_count; j++) {
00551                                         len += sprintf(buffer + len, "%u ",
00552                                                        tru_list[j]);
00553                                         pos = begin + len;
00554                                         if (pos < offset) {
00555                                                 len = 0;
00556                                                 begin = pos;
00557                                         }
00558                                         if (pos > offset + length) {
00559                                                 rsbac_vfree(tru_list);
00560                                                 rsbac_vfree(p_list);
00561                                                 goto out;
00562                                         }
00563                                 }
00564                                 rsbac_vfree(tru_list);
00565                                 all_member_count += member_count;
00566                         }
00567                         pos = begin + len;
00568                         if (pos < offset) {
00569                                 len = 0;
00570                                 begin = pos;
00571                         }
00572                         if (pos > offset + length) {
00573                                 rsbac_vfree(p_list);
00574                                 goto out;
00575                         }
00576                 }
00577                 rsbac_vfree(p_list);
00578         }
00579         len +=
00580             sprintf(buffer + len,
00581                     "\n%u process trusted user set items, sum of %lu members\n",
00582                     count, all_member_count);
00583         pos = begin + len;
00584         if (pos < offset) {
00585                 len = 0;
00586                 begin = pos;
00587         }
00588         if (pos > offset + length)
00589                 goto out;
00590 
00591         len +=
00592             sprintf(buffer + len,
00593                     "\nFile trusted user sets:\nset-id  count   members");
00594         pos = begin + len;
00595         if (pos < offset) {
00596                 len = 0;
00597                 begin = pos;
00598         }
00599         if (pos > offset + length)
00600                 goto out;
00601 
00602         /* protect device list */
00603         rsbac_read_lock(&device_list_head.lock, &dflags);
00604         device_p = device_list_head.head;
00605         while (device_p) {
00606                 /* reset counters */
00607                 all_member_count = 0;
00608                 count = rsbac_list_lol_get_all_desc(device_p->handle,
00609                                                         (void **) &f_list);
00610                 if (count > 0) {
00611                         for (i = 0; i < count; i++) {
00612                                 member_count =
00613                                     rsbac_list_lol_get_all_subdesc
00614                                     (device_p->handle,
00615                                      &f_list[i],
00616                                      (void **) &tru_list);
00617                                 len +=
00618                                     sprintf(buffer + len,
00619                                             "\n %u\t%u\t",
00620                                             f_list[i],
00621                                             member_count);
00622                                 if (member_count > 0) {
00623                                         for (j = 0;
00624                                              j < member_count;
00625                                              j++) {
00626                                                 len +=
00627                                                     sprintf(buffer
00628                                                             + len,
00629                                                             "%u ",
00630                                                             tru_list
00631                                                             [j]);
00632                                                 pos = begin + len;
00633                                                 if (pos < offset) {
00634                                                         len = 0;
00635                                                         begin =
00636                                                             pos;
00637                                                 }
00638                                                 if (pos >
00639                                                     offset +
00640                                                     length) {
00641                                                         rsbac_vfree
00642                                                             (tru_list);
00643                                                         rsbac_vfree
00644                                                             (f_list);
00645                                                         goto out_unlock;
00646                                                 }
00647                                         }
00648                                         rsbac_vfree(tru_list);
00649                                         all_member_count +=
00650                                             member_count;
00651                                 }
00652                                 pos = begin + len;
00653                                 if (pos < offset) {
00654                                         len = 0;
00655                                         begin = pos;
00656                                 }
00657                                 if (pos > offset + length) {
00658                                         rsbac_vfree(f_list);
00659                                         goto out_unlock;
00660                                 }
00661                         }
00662                         rsbac_vfree(f_list);
00663                 }
00664                 len +=
00665                     sprintf(buffer + len,
00666                             "\ndevice %02u:%02u has %u file trusted user set items, sum of %lu members\n",
00667                             RSBAC_MAJOR(device_p->id),
00668                             RSBAC_MINOR(device_p->id), count,
00669                             all_member_count);
00670                 pos = begin + len;
00671                 if (pos < offset) {
00672                         len = 0;
00673                         begin = pos;
00674                 }
00675                 if (pos > offset + length)
00676                         goto out_unlock;
00677 
00678                 device_p = device_p->next;
00679         }
00680       out_unlock:
00681         /* unprotect device list */
00682         rsbac_read_unlock(&device_list_head.lock, &dflags);
00683 
00684       out:
00685         *start = buffer + (offset - begin);
00686         len -= (offset - begin);
00687 
00688         if (len > length)
00689                 len = length;
00690         return len;
00691 }
00692 #endif                          /* CONFIG_PROC_FS && CONFIG_RSBAC_PROC */
00693 
00694 /************************************************* */
00695 /*               Init functions                    */
00696 /************************************************* */
00697 
00698 /* All functions return 0, if no error occurred, and a negative error code  */
00699 /* otherwise. The error codes are defined in rsbac/error.h.                 */
00700 
00701 /************************************************************************** */
00702 /* Initialization of all MAC data structures. After this call, all MAC    */
00703 /* data is kept in memory for performance reasons, but is written to disk   */
00704 /* on every change. */
00705 
00706 /* Because there can be no access to aci data structures before init,       */
00707 /* rsbac_init_mac() will initialize all rw-spinlocks to unlocked.          */
00708 
00709 #ifdef CONFIG_RSBAC_INIT_DELAY
00710 int rsbac_init_mac(void)
00711 #else
00712 int __init rsbac_init_mac(void)
00713 #endif
00714 {
00715         int err = 0;
00716         struct rsbac_mac_device_list_item_t *device_p = NULL;
00717         u_long dflags;
00718         struct proc_dir_entry *tmp_entry_p;
00719         struct rsbac_list_lol_info_t lol_info;
00720 
00721         if (rsbac_is_initialized()) {
00722                 rsbac_printk(KERN_WARNING "rsbac_init_mac(): RSBAC already initialized\n");
00723                 return (-RSBAC_EREINIT);
00724         }
00725 
00726         /* set rw-spinlocks to unlocked status and init data structures */
00727         rsbac_printk(KERN_INFO "rsbac_init_mac(): Initializing RSBAC: MAC subsystem\n");
00728 
00729         lol_info.version = RSBAC_MAC_P_LIST_VERSION;
00730         lol_info.key = RSBAC_MAC_LIST_KEY;
00731         lol_info.desc_size = sizeof(rsbac_pid_t);
00732         lol_info.data_size = 0;
00733         lol_info.subdesc_size = sizeof(rsbac_uid_t);
00734         lol_info.subdata_size = 0;
00735         lol_info.max_age = 0;
00736         err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00737                                       &process_handle,
00738                                       &lol_info,
00739                                       RSBAC_LIST_DEF_DATA,
00740                                       NULL,
00741                                       NULL,
00742                                       NULL,
00743                                       NULL,
00744                                       NULL,
00745                                       NULL,
00746                                       RSBAC_MAC_P_LIST_NAME,
00747                                       RSBAC_AUTO_DEV);
00748         if (err) {
00749                 char *tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00750 
00751                 if (tmp) {
00752                         rsbac_printk(KERN_WARNING "rsbac_init_mac(): Registering MAC process trusted user list failed with error %s\n",
00753                                      get_error_name(tmp, err));
00754                         rsbac_kfree(tmp);
00755                 }
00756         }
00757 
00758         /* Init FD lists */
00759         device_list_head.lock = RW_LOCK_UNLOCKED;
00760         device_list_head.head = NULL;
00761         device_list_head.tail = NULL;
00762         device_list_head.curr = NULL;
00763         device_list_head.count = 0;
00764 
00765         /* read all data */
00766         rsbac_pr_debug(ds_mac, "rsbac_init_mac(): Registering FD lists\n");
00767         device_p = create_device_item(rsbac_root_dev);
00768         if (!device_p) {
00769                 rsbac_printk(KERN_CRIT
00770                              "rsbac_init_mac(): Could not add device!\n");
00771                 return (-RSBAC_ECOULDNOTADDDEVICE);
00772         }
00773         if ((err = mac_register_fd_lists(device_p, rsbac_root_dev))) {
00774                 char tmp[RSBAC_MAXNAMELEN];
00775 
00776                 rsbac_printk(KERN_WARNING "rsbac_init_mac(): File/Dir trusted user set registration failed for dev %02u:%02u, err %s!\n",
00777                              RSBAC_MAJOR(rsbac_root_dev),
00778                              RSBAC_MINOR(rsbac_root_dev),
00779                              get_error_name(tmp, err));
00780         }
00781         /* wait for write access to device_list_head */
00782         rsbac_write_lock_irq(&device_list_head.lock, &dflags);
00783         device_p = add_device_item(device_p);
00784         /* device was added, allow access */
00785         rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
00786         if (!device_p) {
00787                 rsbac_printk(KERN_CRIT
00788                              "rsbac_init_mac(): Could not add device!\n");
00789                 return (-RSBAC_ECOULDNOTADDDEVICE);
00790         }
00791 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00792         tmp_entry_p = create_proc_entry("mac_devices",
00793                                         S_IFREG | S_IRUGO | S_IWUGO,
00794                                         proc_rsbac_root_p);
00795         if (tmp_entry_p) {
00796                 tmp_entry_p->get_info = mac_devices_proc_info;
00797         }
00798         tmp_entry_p = create_proc_entry("stats_mac",
00799                                         S_IFREG | S_IRUGO,
00800                                         proc_rsbac_root_p);
00801         if (tmp_entry_p) {
00802                 tmp_entry_p->get_info = stats_mac_proc_info;
00803         }
00804         tmp_entry_p = create_proc_entry("mac_trusted",
00805                                         S_IFREG | S_IRUGO,
00806                                         proc_rsbac_root_p);
00807         if (tmp_entry_p) {
00808                 tmp_entry_p->get_info = mac_trulist_proc_info;
00809         }
00810 #endif
00811 
00812         rsbac_pr_debug(aef_mac, "Ready.\n");
00813         return (err);
00814 }
00815 
00816 int rsbac_mount_mac(kdev_t kdev)
00817 {
00818         int err = 0;
00819         struct rsbac_mac_device_list_item_t *device_p;
00820         struct rsbac_mac_device_list_item_t *new_device_p;
00821         u_long dflags;
00822 
00823         if (!rsbac_is_initialized()) {
00824                 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): RSBAC not initialized\n");
00825                 return (-RSBAC_ENOTINITIALIZED);
00826         }
00827         rsbac_pr_debug(aef_mac, "mounting device %02u:%02u\n",
00828                        RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00829         /* wait for write access to device_list_head */
00830         rsbac_read_lock(&device_list_head.lock, &dflags);
00831         device_p = lookup_device(kdev);
00832         /* repeated mount? */
00833         if (device_p) {
00834                 rsbac_printk(KERN_WARNING "rsbac_mount_mac: repeated mount %u of device %02u:%02u\n",
00835                              device_p->mount_count, RSBAC_MAJOR(kdev),
00836                              RSBAC_MINOR(kdev));
00837                 device_p->mount_count++;
00838                 rsbac_read_unlock(&device_list_head.lock, &dflags);
00839                 return 0;
00840         }
00841         rsbac_read_unlock(&device_list_head.lock, &dflags);
00842 
00843         new_device_p = create_device_item(kdev);
00844         if (!new_device_p)
00845                 return -RSBAC_ECOULDNOTADDDEVICE;
00846 
00847         /* register lists */
00848         if ((err = mac_register_fd_lists(new_device_p, kdev))) {
00849                 char tmp[RSBAC_MAXNAMELEN];
00850 
00851                 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n",
00852                              RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev),
00853                              get_error_name(tmp, err));
00854         }
00855 
00856         /* wait for read access to device_list_head */
00857         rsbac_read_lock(&device_list_head.lock, &dflags);
00858         /* make sure to only add, if this device item has not been added in the meantime */
00859         device_p = lookup_device(kdev);
00860         if (device_p) {
00861                 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): mount race for device %02u:%02u detected!\n",
00862                              RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00863                 device_p->mount_count++;
00864                 rsbac_read_unlock(&device_list_head.lock, &dflags);
00865                 clear_device_item(new_device_p);
00866         } else {
00867                 rsbac_read_unlock(&device_list_head.lock, &dflags);
00868                 rsbac_write_lock_irq(&device_list_head.lock, &dflags);
00869                 device_p = add_device_item(new_device_p);
00870                 rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
00871                 if (!device_p) {
00872                         rsbac_printk(KERN_WARNING "rsbac_mount_mac: adding device %02u:%02u failed!\n",
00873                                      RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00874                         clear_device_item(new_device_p);
00875                         err = -RSBAC_ECOULDNOTADDDEVICE;
00876                 }
00877         }
00878         return (err);
00879 }
00880 
00881 /* When umounting a device, its file lists must be removed. */
00882 
00883 int rsbac_umount_mac(kdev_t kdev)
00884 {
00885         u_long flags;
00886         struct rsbac_mac_device_list_item_t *device_p;
00887 
00888         if (!rsbac_is_initialized()) {
00889                 rsbac_printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n");
00890                 return (-RSBAC_ENOTINITIALIZED);
00891         }
00892         rsbac_pr_debug(aef_mac, "umounting device %02u:%02u\n",
00893                        RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00894         /* sync of attribute lists was done in rsbac_umount */
00895         /* wait for write access to device_list_head */
00896         rsbac_write_lock(&device_list_head.lock, &flags);
00897         /* OK, nobody else is working on it... */
00898         device_p = lookup_device(kdev);
00899         if (device_p) {
00900                 if (device_p->mount_count == 1)
00901                         remove_device_item(kdev);
00902                 else {
00903                         if (device_p->mount_count > 1) {
00904                                 device_p->mount_count--;
00905                         } else {
00906                                 rsbac_printk(KERN_WARNING "rsbac_mount_mac: device %02u:%02u has mount_count < 1!\n",
00907                                              RSBAC_MAJOR(kdev),
00908                                              RSBAC_MINOR(kdev));
00909                         }
00910                 }
00911         }
00912 
00913         /* allow access */
00914         rsbac_write_unlock(&device_list_head.lock, &flags);
00915         return 0;
00916 }
00917 
00918 /***************************************************/
00919 /* We also need some status information...         */
00920 
00921 int rsbac_stats_mac(void)
00922 {
00923         u_long dflags;
00924         struct rsbac_mac_device_list_item_t *device_p;
00925 
00926         union rsbac_target_id_t rsbac_target_id;
00927         union rsbac_attribute_value_t rsbac_attribute_value;
00928 
00929         if (!rsbac_is_initialized()) {
00930                 rsbac_printk(KERN_WARNING "rsbac_stats_mac(): RSBAC not initialized\n");
00931                 return (-RSBAC_ENOTINITIALIZED);
00932         }
00933         rsbac_pr_debug(aef_mac, "calling ADF\n");
00934         rsbac_target_id.scd = ST_rsbac;
00935         rsbac_attribute_value.dummy = 0;
00936         if (!rsbac_adf_request(R_GET_STATUS_DATA,
00937                                current->pid,
00938                                T_SCD,
00939                                rsbac_target_id,
00940                                A_none, rsbac_attribute_value)) {
00941                 return -EPERM;
00942         }
00943 
00944         rsbac_printk(KERN_INFO "MAC Status\n----------\n");
00945 
00946         rsbac_printk(KERN_INFO "%lu process trusted user set items, sum of %lu members\n",
00947                      rsbac_list_lol_count(process_handle),
00948                      rsbac_list_lol_all_subcount(process_handle));
00949 
00950         /* protect device list */
00951         rsbac_read_lock(&device_list_head.lock, &dflags);
00952         device_p = device_list_head.head;
00953         while (device_p) {
00954                 rsbac_printk(KERN_INFO "device %02u:%02u has %u file trusted user set items, sum of %u members\n",
00955                              RSBAC_MAJOR(device_p->id),
00956                              RSBAC_MINOR(device_p->id),
00957                              rsbac_list_lol_count(device_p->handle),
00958                              rsbac_list_lol_all_subcount(device_p->handle));
00959                 device_p = device_p->next;
00960         }
00961         /* unprotect device list */
00962         rsbac_read_unlock(&device_list_head.lock, &dflags);
00963         return 0;
00964 }
00965 
00966 /************************************************* */
00967 /*               Access functions                  */
00968 /************************************************* */
00969 
00970 /* All these procedures handle the rw-spinlocks to protect the targets during */
00971 /* access.                                                                  */
00972 /* Trying to access a never created or removed set returns an error! */
00973 
00974 /* rsbac_mac_add_to_truset */
00975 /* Add a set member to a set sublist. Set behaviour: also returns success, */
00976 /* if member was already in set! */
00977 
00978 int rsbac_mac_add_to_p_truset(rsbac_list_ta_number_t ta_number,
00979                               rsbac_pid_t pid,
00980                               rsbac_uid_t member, rsbac_time_t ttl)
00981 {
00982         if (!rsbac_is_initialized()) {
00983                 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_p_truset(): RSBAC not initialized\n");
00984                 return (-RSBAC_ENOTINITIALIZED);
00985         }
00986         if (in_interrupt()) {
00987                 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_p_truset(): called from interrupt!\n");
00988         }
00989         return rsbac_ta_list_lol_subadd_ttl(ta_number, process_handle, ttl,
00990                                             &pid, &member, NULL);
00991 }
00992 
00993 int rsbac_mac_add_to_f_truset(rsbac_list_ta_number_t ta_number,
00994                               rsbac_mac_file_t file,
00995                               rsbac_uid_t member, rsbac_time_t ttl)
00996 {
00997         int err = 0;
00998         u_long dflags;
00999         struct rsbac_mac_device_list_item_t *device_p;
01000 
01001         if (!rsbac_is_initialized()) {
01002                 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): RSBAC not initialized\n");
01003                 return (-RSBAC_ENOTINITIALIZED);
01004         }
01005         if (in_interrupt()) {
01006                 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): called from interrupt!\n");
01007         }
01008 
01009         /* protect device list */
01010         rsbac_read_lock(&device_list_head.lock, &dflags);
01011         device_p = lookup_device(file.device);
01012         if (!device_p) {
01013                 /* trigger rsbac_mount() */
01014                 rsbac_read_unlock(&device_list_head.lock, &dflags);
01015                 rsbac_get_super_block(file.device);
01016                 /* retry */
01017                 rsbac_read_lock(&device_list_head.lock, &dflags);
01018                 device_p = lookup_device(file.device);
01019                 if (!device_p) {
01020                         rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): invalid device %02u:%02u!\n",
01021                                      RSBAC_MAJOR(file.device),
01022                                      RSBAC_MINOR(file.device));
01023                         rsbac_read_unlock(&device_list_head.lock, &dflags);
01024                         return (-RSBAC_EINVALIDDEV);
01025                 }
01026         }
01027 
01028         err = rsbac_ta_list_lol_subadd_ttl(ta_number,
01029                                            device_p->handle,
01030                                            ttl, &file.inode, &member,
01031                                            NULL);
01032         rsbac_read_unlock(&device_list_head.lock, &dflags);
01033         return (err);
01034 }
01035 
01036 /* rsbac_mac_remove_from_truset */
01037 /* Remove a set member from a sublist. Set behaviour: Returns no error, if */
01038 /* member is not in list.                                                  */
01039 
01040 int rsbac_mac_remove_from_p_truset(rsbac_list_ta_number_t ta_number,
01041                                    rsbac_pid_t pid, rsbac_uid_t member)
01042 {
01043         if (!rsbac_is_initialized()) {
01044                 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_p_truset(): RSBAC not initialized\n");
01045                 return (-RSBAC_ENOTINITIALIZED);
01046         }
01047         if (in_interrupt()) {
01048                 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_p_truset(): called from interrupt!\n");
01049         }
01050         return rsbac_ta_list_lol_subremove(ta_number, process_handle, &pid,
01051                                            &member);
01052 }
01053 
01054 int rsbac_mac_remove_from_f_truset(rsbac_list_ta_number_t ta_number,
01055                                    rsbac_mac_file_t file,
01056                                    rsbac_uid_t member)
01057 {
01058         int err = 0;
01059         u_long dflags;
01060         struct rsbac_mac_device_list_item_t *device_p;
01061 
01062         if (!rsbac_is_initialized()) {
01063                 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): RSBAC not initialized\n");
01064                 return (-RSBAC_ENOTINITIALIZED);
01065         }
01066         if (in_interrupt()) {
01067                 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): called from interrupt!\n");
01068         }
01069 
01070         /* protect device list */
01071         rsbac_read_lock(&device_list_head.lock, &dflags);
01072         device_p = lookup_device(file.device);
01073         if (!device_p) {
01074                 /* trigger rsbac_mount() */
01075                 rsbac_read_unlock(&device_list_head.lock, &dflags);
01076                 rsbac_get_super_block(file.device);
01077                 /* retry */
01078                 rsbac_read_lock(&device_list_head.lock, &dflags);
01079                 device_p = lookup_device(file.device);
01080                 if (!device_p) {
01081                         rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): invalid device %02u:%02u!\n",
01082                                      RSBAC_MAJOR(file.device),
01083                                      RSBAC_MINOR(file.device));
01084                         rsbac_read_unlock(&device_list_head.lock, &dflags);
01085                         return (-RSBAC_EINVALIDDEV);
01086                 }
01087         }
01088         err = rsbac_ta_list_lol_subremove(ta_number,
01089                                           device_p->handle,
01090                                           &file.inode, &member);
01091         rsbac_read_unlock(&device_list_head.lock, &dflags);
01092         return (err);
01093 }
01094 
01095 /* rsbac_mac_clear_truset */
01096 /* Remove all set members from a sublist. Set behaviour: Returns no error, */
01097 /* if list is empty.                                                       */
01098 
01099 int rsbac_mac_clear_p_truset(rsbac_list_ta_number_t ta_number,
01100                              rsbac_pid_t pid)
01101 {
01102         if (!rsbac_is_initialized()) {
01103                 rsbac_printk(KERN_WARNING "rsbac_mac_clear_p_truset(): RSBAC not initialized\n");
01104                 return (-RSBAC_ENOTINITIALIZED);
01105         }
01106         if (in_interrupt()) {
01107                 rsbac_printk(KERN_WARNING "rsbac_mac_clear_p_truset(): called from interrupt!\n");
01108         }
01109         return rsbac_ta_list_lol_remove(ta_number, process_handle, &pid);
01110 }
01111 
01112 int rsbac_mac_clear_f_truset(rsbac_list_ta_number_t ta_number,
01113                              rsbac_mac_file_t file)
01114 {
01115         int err = 0;
01116         u_long dflags;
01117         struct rsbac_mac_device_list_item_t *device_p;
01118 
01119         if (!rsbac_is_initialized()) {
01120                 rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): RSBAC not initialized\n");
01121                 return (-RSBAC_ENOTINITIALIZED);
01122         }
01123         if (in_interrupt()) {
01124                 rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): called from interrupt!\n");
01125         }
01126         /* protect device list */
01127         rsbac_read_lock(&device_list_head.lock, &dflags);
01128         device_p = lookup_device(file.device);
01129         if (!device_p) {
01130                 /* trigger rsbac_mount() */
01131                 rsbac_read_unlock(&device_list_head.lock, &dflags);
01132                 rsbac_get_super_block(file.device);
01133                 /* retry */
01134                 rsbac_read_lock(&device_list_head.lock, &dflags);
01135                 device_p = lookup_device(file.device);
01136                 if (!device_p) {
01137                         rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): invalid device %02u:%02u!\n",
01138                                      RSBAC_MAJOR(file.device),
01139                                      RSBAC_MINOR(file.device));
01140                         rsbac_read_unlock(&device_list_head.lock, &dflags);
01141                         return (-RSBAC_EINVALIDDEV);
01142                 }
01143         }
01144         err = rsbac_ta_list_lol_remove(ta_number,
01145                                      device_p->handle,
01146                                      &file.inode);
01147         rsbac_read_unlock(&device_list_head.lock, &dflags);
01148         return (err);
01149 }
01150 
01151 /* rsbac_mac_truset_member */
01152 /* Return truth value, whether member is in set */
01153 
01154 rsbac_boolean_t rsbac_mac_p_truset_member(rsbac_pid_t pid,
01155                                           rsbac_uid_t member)
01156 {
01157         if (!rsbac_is_initialized()) {
01158                 rsbac_printk(KERN_WARNING "rsbac_mac_p_truset_member(): RSBAC not initialized\n");
01159                 return FALSE;
01160         }
01161         if (in_interrupt()) {
01162                 rsbac_printk(KERN_WARNING "rsbac_mac_p_truset_member(): called from interrupt!\n");
01163         }
01164         if (rsbac_list_lol_subexist(process_handle, &pid, &member))
01165                 return TRUE;
01166         member = RSBAC_ALL_USERS;
01167         return rsbac_list_lol_subexist(process_handle, &pid, &member);
01168 }
01169 
01170 /* rsbac_mac_remove_truset */
01171 /* Remove a full set. For cleanup, if object is deleted. */
01172 /* To empty an existing set use rsbac_mac_clear_truset. */
01173 
01174 int rsbac_mac_remove_p_trusets(rsbac_pid_t pid)
01175 {
01176         return rsbac_mac_clear_p_truset(FALSE, pid);
01177 }
01178 
01179 int rsbac_mac_remove_f_trusets(rsbac_mac_file_t file)
01180 {
01181         return rsbac_mac_clear_f_truset(FALSE, file);
01182 }
01183 
01184 int rsbac_mac_copy_fp_truset(rsbac_mac_file_t file,
01185                              rsbac_pid_t p_tru_set_id)
01186 {
01187         u_long dflags;
01188         struct rsbac_mac_device_list_item_t *device_p;
01189         int err = 0;
01190 
01191         if (!rsbac_is_initialized()) {
01192                 rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): RSBAC not initialized\n");
01193                 return (-RSBAC_ENOTINITIALIZED);
01194         }
01195         if (in_interrupt()) {
01196                 rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): called from interrupt!\n");
01197         }
01198 /*
01199         rsbac_pr_debug(ds_mac, "Copying file cap set data to process cap set\n");
01200 */
01201         /* protect device list */
01202         rsbac_read_lock(&device_list_head.lock, &dflags);
01203         device_p = lookup_device(file.device);
01204         if (!device_p) {
01205                 /* trigger rsbac_mount() */
01206                 rsbac_read_unlock(&device_list_head.lock, &dflags);
01207                 rsbac_get_super_block(file.device);
01208                 /* retry */
01209                 rsbac_read_lock(&device_list_head.lock, &dflags);
01210                 device_p = lookup_device(file.device);
01211                 if (!device_p) {
01212                         rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): invalid device %02u:%02u!\n",
01213                                      RSBAC_MAJOR(file.device),
01214                                      RSBAC_MINOR(file.device));
01215                         rsbac_read_unlock(&device_list_head.lock, &dflags);
01216                         return (-RSBAC_EINVALIDDEV);
01217                 }
01218         }
01219         /* call the copy function */
01220         err = copy_fp_tru_set_item(device_p, file, p_tru_set_id);
01221         rsbac_read_unlock(&device_list_head.lock, &dflags);
01222         return (err);
01223 }
01224 
01225 int rsbac_mac_copy_pp_truset(rsbac_pid_t old_p_set_id,
01226                              rsbac_pid_t new_p_set_id)
01227 {
01228         if (!rsbac_is_initialized()) {
01229                 rsbac_printk(KERN_WARNING "rsbac_mac_copy_pp_truset(): RSBAC not initialized\n");
01230                 return (-RSBAC_ENOTINITIALIZED);
01231         }
01232         if (in_interrupt()) {
01233                 rsbac_printk(KERN_WARNING "rsbac_mac_copy_pp_truset(): called from interrupt!\n");
01234         }
01235 /*
01236         rsbac_pr_debug(ds_mac, "Copying process cap set data to process cap set\n");
01237 */
01238         /* call the copy function */
01239         return copy_pp_tru_set_item(old_p_set_id, new_p_set_id);
01240 }
01241 
01242 int rsbac_mac_get_f_trulist(rsbac_list_ta_number_t ta_number,
01243                             rsbac_mac_file_t file,
01244                             rsbac_uid_t ** trulist_p,
01245                             rsbac_time_t ** ttllist_p)
01246 {
01247         u_long dflags;
01248         struct rsbac_mac_device_list_item_t *device_p;
01249         long count;
01250 
01251         if (!rsbac_is_initialized()) {
01252                 rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): RSBAC not initialized\n");
01253                 return (-RSBAC_ENOTINITIALIZED);
01254         }
01255         if (in_interrupt()) {
01256                 rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): called from interrupt!\n");
01257         }
01258 /*
01259         rsbac_pr_debug(ds_mac, "Getting file/dir trusted user set list\n");
01260 */
01261         /* protect device list */
01262         rsbac_read_lock(&device_list_head.lock, &dflags);
01263         device_p = lookup_device(file.device);
01264         if (!device_p) {
01265                 /* trigger rsbac_mount() */
01266                 rsbac_read_unlock(&device_list_head.lock, &dflags);
01267                 rsbac_get_super_block(file.device);
01268                 /* retry */
01269                 rsbac_read_lock(&device_list_head.lock, &dflags);
01270                 device_p = lookup_device(file.device);
01271                 if (!device_p) {
01272                         rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): invalid device %02u:%02u!\n",
01273                                      RSBAC_MAJOR(file.device),
01274                                      RSBAC_MINOR(file.device));
01275                         rsbac_read_unlock(&device_list_head.lock, &dflags);
01276                         return (-RSBAC_EINVALIDDEV);
01277                 }
01278         }
01279         count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
01280                                                       device_p->handle,
01281                                                       &file.inode,
01282                                                       (void **) trulist_p,
01283                                                       ttllist_p);
01284         rsbac_read_unlock(&device_list_head.lock, &dflags);
01285         return (count);
01286 }
01287 
01288 int rsbac_mac_get_p_trulist(rsbac_list_ta_number_t ta_number,
01289                             rsbac_pid_t pid,
01290                             rsbac_uid_t ** trulist_p,
01291                             rsbac_time_t ** ttllist_p)
01292 {
01293         if (!rsbac_is_initialized()) {
01294                 rsbac_printk(KERN_WARNING "rsbac_mac_get_p_trulist(): RSBAC not initialized\n");
01295                 return (-RSBAC_ENOTINITIALIZED);
01296         }
01297         if (in_interrupt()) {
01298                 rsbac_printk(KERN_WARNING "rsbac_mac_get_p_trulist(): called from interrupt!\n");
01299         }
01300 /*
01301         rsbac_pr_debug(ds_mac, "Getting process trusted user set list\n");
01302 */
01303         return rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
01304                                                      process_handle,
01305                                                      &pid,
01306                                                      (void **) trulist_p,
01307                                                      ttllist_p);
01308 }

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