/daten/src/linux-2.4.27-rsbac-v1.2.3/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-2004: Amon Ott <ao@rsbac.org> */ 00005 /* */ 00006 /* Last modified: 10/Mar/2004 */ 00007 /*************************************************** */ 00008 00009 #include <linux/types.h> 00010 #include <linux/sched.h> 00011 #include <linux/mm.h> 00012 #include <linux/init.h> 00013 #include <linux/ext2_fs.h> 00014 #include <asm/uaccess.h> 00015 #include <rsbac/types.h> 00016 #include <rsbac/aci_data_structures.h> 00017 #include <rsbac/auth_data_structures.h> 00018 #include <rsbac/error.h> 00019 #include <rsbac/helpers.h> 00020 #include <rsbac/adf.h> 00021 #include <rsbac/aci.h> 00022 #include <rsbac/auth.h> 00023 #include <rsbac/lists.h> 00024 #include <rsbac/proc_fs.h> 00025 #include <rsbac/rkmem.h> 00026 #include <rsbac/getname.h> 00027 #include <linux/string.h> 00028 #include <linux/smp_lock.h> 00029 00030 /************************************************************************** */ 00031 /* Global Variables */ 00032 /************************************************************************** */ 00033 00034 /* The following global variables are needed for access to PM data. */ 00035 00036 static struct rsbac_auth_device_list_head_t device_list_head; 00037 00038 static rsbac_list_handle_t process_handle = NULL; 00039 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00040 static rsbac_list_handle_t process_eff_handle = NULL; 00041 static rsbac_list_handle_t process_fs_handle = NULL; 00042 #endif 00043 00044 /**************************************************/ 00045 /* Declarations of external functions */ 00046 /**************************************************/ 00047 00048 boolean writable(struct super_block * sb_p); 00049 00050 /**************************************************/ 00051 /* Declarations of internal functions */ 00052 /**************************************************/ 00053 00054 /************************************************* */ 00055 /* Internal Help functions */ 00056 /************************************************* */ 00057 00058 static inline int fd_hash(rsbac_inode_nr_t inode) 00059 { 00060 return(inode % RSBAC_AUTH_NR_CAP_FD_LISTS); 00061 } 00062 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00063 static inline int eff_fd_hash(rsbac_inode_nr_t inode) 00064 { 00065 return(inode % RSBAC_AUTH_NR_CAP_EFF_FD_LISTS); 00066 } 00067 static inline int fs_fd_hash(rsbac_inode_nr_t inode) 00068 { 00069 return(inode % RSBAC_AUTH_NR_CAP_FS_FD_LISTS); 00070 } 00071 #endif 00072 00073 static int cap_compare(void * desc1, void * desc2) 00074 { 00075 struct rsbac_auth_cap_range_t * range1 = desc1; 00076 struct rsbac_auth_cap_range_t * range2 = desc2; 00077 00078 if(!desc1 || !desc2) 00079 return 0; 00080 if(range1->first < range2->first) 00081 return -1; 00082 if(range1->first > range2->first) 00083 return 1; 00084 if(range1->last < range2->last) 00085 return -1; 00086 if(range1->last > range2->last) 00087 return 1; 00088 return 0; 00089 }; 00090 00091 static int single_cap_compare(void * desc1, void * desc2) 00092 { 00093 struct rsbac_auth_cap_range_t * range = desc1; 00094 rsbac_uid_t * uid = desc2; 00095 00096 if(!desc1 || !desc2) 00097 return 0; 00098 if( (*uid < range->first) 00099 || (*uid > range->last) 00100 ) 00101 return 1; 00102 else 00103 return 0; 00104 }; 00105 00106 /* auth_register_fd_lists() */ 00107 /* register fd ACL lists for device */ 00108 00109 static int auth_register_fd_lists(struct rsbac_auth_device_list_item_t * device_p, 00110 kdev_t kdev) 00111 { 00112 char * name; 00113 int err = 0; 00114 int tmperr; 00115 char number[10]; 00116 u_int file_no; 00117 struct rsbac_list_lol_info_t lol_info; 00118 00119 if(!device_p) 00120 return(-RSBAC_EINVALIDPOINTER); 00121 name = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00122 if(!name) 00123 return -RSBAC_ENOMEM; 00124 00125 /* register all the AUTH lists of lists */ 00126 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FD_LISTS; file_no++) 00127 { 00128 /* construct name from base name + number */ 00129 strcpy(name, RSBAC_AUTH_FD_FILENAME); 00130 strcat(name, inttostr(number,file_no) ); 00131 00132 lol_info.version = RSBAC_AUTH_FD_LIST_VERSION; 00133 lol_info.key = RSBAC_AUTH_LIST_KEY; 00134 lol_info.desc_size = sizeof(rsbac_inode_nr_t); 00135 lol_info.data_size = 0; 00136 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 00137 lol_info.subdata_size = 0; /* rights */ 00138 lol_info.max_age = 0; 00139 tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION, 00140 &(device_p->handles[file_no]), 00141 &lol_info, 00142 RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA, 00143 rsbac_list_compare_u32, 00144 cap_compare, 00145 NULL, 00146 NULL, 00147 NULL, 00148 NULL, 00149 name, 00150 kdev); 00151 if(tmperr) 00152 { 00153 char * tmp; 00154 00155 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00156 if(tmp) 00157 { 00158 printk(KERN_WARNING 00159 "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n", 00160 name, 00161 RSBAC_MAJOR(kdev), 00162 RSBAC_MINOR(kdev), 00163 get_error_name(tmp, tmperr)); 00164 rsbac_kfree(tmp); 00165 } 00166 err = tmperr; 00167 } 00168 } 00169 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00170 /* register all the AUTH DAC lists of lists */ 00171 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; file_no++) 00172 { 00173 /* construct name from base name + number */ 00174 strcpy(name, RSBAC_AUTH_FD_EFF_FILENAME); 00175 strcat(name, inttostr(number,file_no) ); 00176 00177 lol_info.version = RSBAC_AUTH_FD_EFF_LIST_VERSION; 00178 lol_info.key = RSBAC_AUTH_LIST_KEY; 00179 lol_info.desc_size = sizeof(rsbac_inode_nr_t); 00180 lol_info.data_size = 0; 00181 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 00182 lol_info.subdata_size = 0; /* rights */ 00183 lol_info.max_age = 0; 00184 tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION, 00185 &(device_p->eff_handles[file_no]), 00186 &lol_info, 00187 RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA, 00188 rsbac_list_compare_u32, 00189 cap_compare, 00190 NULL, 00191 NULL, 00192 NULL, 00193 NULL, 00194 name, 00195 kdev); 00196 if(tmperr) 00197 { 00198 char * tmp; 00199 00200 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00201 if(tmp) 00202 { 00203 printk(KERN_WARNING 00204 "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n", 00205 name, 00206 RSBAC_MAJOR(kdev), 00207 RSBAC_MINOR(kdev), 00208 get_error_name(tmp, tmperr)); 00209 rsbac_kfree(tmp); 00210 } 00211 err = tmperr; 00212 } 00213 } 00214 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; file_no++) 00215 { 00216 /* construct name from base name + number */ 00217 strcpy(name, RSBAC_AUTH_FD_FS_FILENAME); 00218 strcat(name, inttostr(number,file_no) ); 00219 00220 lol_info.version = RSBAC_AUTH_FD_FS_LIST_VERSION; 00221 lol_info.key = RSBAC_AUTH_LIST_KEY; 00222 lol_info.desc_size = sizeof(rsbac_inode_nr_t); 00223 lol_info.data_size = 0; 00224 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 00225 lol_info.subdata_size = 0; /* rights */ 00226 lol_info.max_age = 0; 00227 tmperr = rsbac_list_lol_register(RSBAC_LIST_VERSION, 00228 &(device_p->fs_handles[file_no]), 00229 &lol_info, 00230 RSBAC_LIST_PERSIST | RSBAC_LIST_DEF_DATA, 00231 rsbac_list_compare_u32, 00232 cap_compare, 00233 NULL, 00234 NULL, 00235 NULL, 00236 NULL, 00237 name, 00238 kdev); 00239 if(tmperr) 00240 { 00241 char * tmp; 00242 00243 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00244 if(tmp) 00245 { 00246 printk(KERN_WARNING 00247 "auth_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n", 00248 name, 00249 RSBAC_MAJOR(kdev), 00250 RSBAC_MINOR(kdev), 00251 get_error_name(tmp, tmperr)); 00252 rsbac_kfree(tmp); 00253 } 00254 err = tmperr; 00255 } 00256 } 00257 #endif 00258 return err; 00259 } 00260 00261 /* auth_detach_fd_lists() */ 00262 /* detach from fd AUTH lists for device */ 00263 00264 static int auth_detach_fd_lists(struct rsbac_auth_device_list_item_t * device_p) 00265 { 00266 char * name; 00267 int err = 0; 00268 int tmperr; 00269 char number[10]; 00270 u_int file_no; 00271 00272 if(!device_p) 00273 return(-RSBAC_EINVALIDPOINTER); 00274 name = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00275 if(!name) 00276 return -RSBAC_ENOMEM; 00277 00278 /* detach all the AUTH lists of lists */ 00279 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FD_LISTS; file_no++) 00280 { 00281 /* construct name from base name + number */ 00282 strcpy(name, RSBAC_AUTH_FD_FILENAME); 00283 strcat(name, inttostr(number,file_no) ); 00284 00285 tmperr = rsbac_list_lol_detach(&device_p->handles[file_no], 00286 RSBAC_AUTH_LIST_KEY); 00287 if(tmperr) 00288 { 00289 char * tmp; 00290 00291 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00292 if(tmp) 00293 { 00294 printk(KERN_WARNING 00295 "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n", 00296 name, 00297 RSBAC_MAJOR(device_p->id), 00298 RSBAC_MINOR(device_p->id), 00299 get_error_name(tmp, tmperr)); 00300 rsbac_kfree(tmp); 00301 } 00302 err = tmperr; 00303 } 00304 } 00305 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00306 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; file_no++) 00307 { 00308 /* construct name from base name + number */ 00309 strcpy(name, RSBAC_AUTH_FD_EFF_FILENAME); 00310 strcat(name, inttostr(number,file_no) ); 00311 00312 tmperr = rsbac_list_lol_detach(&device_p->eff_handles[file_no], 00313 RSBAC_AUTH_LIST_KEY); 00314 if(tmperr) 00315 { 00316 char * tmp; 00317 00318 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00319 if(tmp) 00320 { 00321 printk(KERN_WARNING 00322 "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n", 00323 name, 00324 RSBAC_MAJOR(device_p->id), 00325 RSBAC_MINOR(device_p->id), 00326 get_error_name(tmp, tmperr)); 00327 rsbac_kfree(tmp); 00328 } 00329 err = tmperr; 00330 } 00331 } 00332 for (file_no = 0; file_no < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; file_no++) 00333 { 00334 /* construct name from base name + number */ 00335 strcpy(name, RSBAC_AUTH_FD_FS_FILENAME); 00336 strcat(name, inttostr(number,file_no) ); 00337 00338 tmperr = rsbac_list_lol_detach(&device_p->fs_handles[file_no], 00339 RSBAC_AUTH_LIST_KEY); 00340 if(tmperr) 00341 { 00342 char * tmp; 00343 00344 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00345 if(tmp) 00346 { 00347 printk(KERN_WARNING 00348 "auth_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n", 00349 name, 00350 RSBAC_MAJOR(device_p->id), 00351 RSBAC_MINOR(device_p->id), 00352 get_error_name(tmp, tmperr)); 00353 rsbac_kfree(tmp); 00354 } 00355 err = tmperr; 00356 } 00357 } 00358 #endif 00359 00360 return err; 00361 } 00362 00363 /************************************************************************** */ 00364 /* The lookup functions return NULL, if the item is not found, and a */ 00365 /* pointer to the item otherwise. */ 00366 00367 /* first the device item lookup */ 00368 static struct rsbac_auth_device_list_item_t * lookup_device(kdev_t kdev) 00369 { 00370 struct rsbac_auth_device_list_item_t * curr = device_list_head.curr; 00371 00372 /* if there is no current item or it is not the right one, search... */ 00373 if(! ( curr 00374 && (RSBAC_MAJOR(curr->id) == RSBAC_MAJOR(kdev)) 00375 && (RSBAC_MINOR(curr->id) == RSBAC_MINOR(kdev)) 00376 ) 00377 ) 00378 { 00379 curr = device_list_head.head; 00380 while( curr 00381 && ( (RSBAC_MAJOR(curr->id) != RSBAC_MAJOR(kdev)) 00382 || (RSBAC_MINOR(curr->id) != RSBAC_MINOR(kdev)) 00383 ) 00384 ) 00385 { 00386 curr = curr->next; 00387 } 00388 if (curr) 00389 device_list_head.curr=curr; 00390 } 00391 /* it is the current item -> return it */ 00392 return (curr); 00393 }; 00394 00395 /************************************************************************** */ 00396 /* The add_item() functions add an item to the list, set head.curr to it, */ 00397 /* and return a pointer to the item. */ 00398 /* These functions will NOT check, if there is already an item under the */ 00399 /* same ID! If this happens, the lookup functions will return the old item! */ 00400 /* All list manipulation is protected by rw-spinlocks to prevent inconsistency */ 00401 /* and undefined behaviour in other concurrent functions. */ 00402 00403 /* Create a device item without adding to list. No locking needed. */ 00404 static struct rsbac_auth_device_list_item_t 00405 * create_device_item(kdev_t kdev) 00406 { 00407 struct rsbac_auth_device_list_item_t * new_item_p; 00408 int i; 00409 00410 /* allocate memory for new device, return NULL, if failed */ 00411 if ( !(new_item_p = (struct rsbac_auth_device_list_item_t *) 00412 rsbac_kmalloc(sizeof(*new_item_p)) ) ) 00413 return(NULL); 00414 00415 new_item_p->id = kdev; 00416 new_item_p->mount_count = 1; 00417 00418 /* init file/dir sublists */ 00419 for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS ; i++) 00420 new_item_p->handles[i] = NULL; 00421 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00422 for(i=0 ; i < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS ; i++) 00423 new_item_p->eff_handles[i] = NULL; 00424 for(i=0 ; i < RSBAC_AUTH_NR_CAP_FS_FD_LISTS ; i++) 00425 new_item_p->fs_handles[i] = NULL; 00426 #endif 00427 return(new_item_p); 00428 }; 00429 00430 /* Add an existing device item to list. Locking needed. */ 00431 static struct rsbac_auth_device_list_item_t 00432 * add_device_item(struct rsbac_auth_device_list_item_t * device_p) 00433 { 00434 if (!device_p) 00435 return(NULL); 00436 00437 /* add new device to device list */ 00438 if (!device_list_head.head) 00439 { /* first device */ 00440 device_list_head.head=device_p; 00441 device_list_head.tail=device_p; 00442 device_list_head.curr=device_p; 00443 device_list_head.count=1; 00444 device_p->prev=NULL; 00445 device_p->next=NULL; 00446 } 00447 else 00448 { /* there is another device -> hang to tail */ 00449 device_p->prev=device_list_head.tail; 00450 device_p->next=NULL; 00451 device_list_head.tail->next=device_p; 00452 device_list_head.tail=device_p; 00453 device_list_head.curr=device_p; 00454 device_list_head.count++; 00455 }; 00456 return(device_p); 00457 }; 00458 00459 /************************************************************************** */ 00460 /* The remove_item() functions remove an item from the list. If this item */ 00461 /* is head, tail or curr, these pointers are set accordingly. */ 00462 /* To speed up removing several subsequent items, curr is set to the next */ 00463 /* item, if possible. */ 00464 /* If the item is not found, nothing is done. */ 00465 00466 static void clear_device_item(struct rsbac_auth_device_list_item_t * item_p) 00467 { 00468 if(!item_p) 00469 return; 00470 00471 /* First deregister lists... */ 00472 auth_detach_fd_lists(item_p); 00473 /* OK, lets remove the device item itself */ 00474 rsbac_kfree(item_p); 00475 }; /* end of clear_device_item() */ 00476 00477 static void remove_device_item(kdev_t kdev) 00478 { 00479 struct rsbac_auth_device_list_item_t * item_p; 00480 00481 /* first we must locate the item. */ 00482 if ( (item_p = lookup_device(kdev)) ) 00483 { /* ok, item was found */ 00484 if (device_list_head.head == item_p) 00485 { /* item is head */ 00486 if (device_list_head.tail == item_p) 00487 { /* item is head and tail = only item -> list will be empty*/ 00488 device_list_head.head = NULL; 00489 device_list_head.tail = NULL; 00490 } 00491 else 00492 { /* item is head, but not tail -> next item becomes head */ 00493 item_p->next->prev = NULL; 00494 device_list_head.head = item_p->next; 00495 }; 00496 } 00497 else 00498 { /* item is not head */ 00499 if (device_list_head.tail == item_p) 00500 { /*item is not head, but tail -> previous item becomes tail*/ 00501 item_p->prev->next = NULL; 00502 device_list_head.tail = item_p->prev; 00503 } 00504 else 00505 { /* item is neither head nor tail -> item is cut out */ 00506 item_p->prev->next = item_p->next; 00507 item_p->next->prev = item_p->prev; 00508 }; 00509 }; 00510 00511 /* curr is no longer valid -> reset. */ 00512 device_list_head.curr=NULL; 00513 /* adjust counter */ 00514 device_list_head.count--; 00515 00516 /* now we can remove the item from memory. This means cleaning up */ 00517 /* everything below. */ 00518 clear_device_item(item_p); 00519 }; /* end of if: item was found */ 00520 00521 }; /* end of remove_device_item() */ 00522 00523 /************************************************************************** */ 00524 /* The copy_fp_cap_set_item() function copies a file cap set to a process */ 00525 /* cap set */ 00526 00527 static int copy_fp_cap_set_item(struct rsbac_auth_device_list_item_t * device_p, 00528 rsbac_auth_file_t file, 00529 rsbac_pid_t pid) 00530 { 00531 struct rsbac_auth_cap_range_t * cap_item_p; 00532 rsbac_time_t * ttl_p; 00533 int i; 00534 long count; 00535 enum rsbac_target_t target = T_FILE; 00536 union rsbac_target_id_t tid; 00537 00538 rsbac_list_lol_remove(process_handle, &pid); 00539 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handles[fd_hash(file.inode)], 00540 &file.inode, 00541 (void **) &cap_item_p, 00542 &ttl_p); 00543 if( !count 00544 || (count == -RSBAC_ENOTFOUND) 00545 ) 00546 { 00547 tid.file = file; 00548 if(!rsbac_get_parent(target, tid, &target, &tid)) 00549 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handles[fd_hash(tid.file.inode)], 00550 &tid.file.inode, 00551 (void **) &cap_item_p, 00552 &ttl_p); 00553 } 00554 if(count > 0) 00555 { 00556 for(i=0; i < count ; i++) 00557 { 00558 rsbac_list_lol_subadd_ttl(process_handle, 00559 ttl_p[i], 00560 &pid, 00561 &cap_item_p[i], 00562 NULL); 00563 } 00564 rsbac_vfree(cap_item_p); 00565 rsbac_vfree(ttl_p); 00566 } 00567 else 00568 { 00569 if( (count < 0) 00570 && (count != -RSBAC_ENOTFOUND) 00571 ) 00572 return count; 00573 } 00574 00575 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00576 rsbac_list_lol_remove(process_eff_handle, &pid); 00577 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->eff_handles[eff_fd_hash(file.inode)], 00578 &file.inode, 00579 (void **) &cap_item_p, 00580 &ttl_p); 00581 if( !count 00582 || (count == -RSBAC_ENOTFOUND) 00583 ) 00584 { 00585 tid.file = file; 00586 if(!rsbac_get_parent(target, tid, &target, &tid)) 00587 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->eff_handles[eff_fd_hash(tid.file.inode)], 00588 &tid.file.inode, 00589 (void **) &cap_item_p, 00590 &ttl_p); 00591 } 00592 if(count > 0) 00593 { 00594 for(i=0; i < count ; i++) 00595 { 00596 rsbac_list_lol_subadd_ttl(process_eff_handle, 00597 ttl_p[i], 00598 &pid, 00599 &cap_item_p[i], 00600 NULL); 00601 } 00602 rsbac_vfree(cap_item_p); 00603 rsbac_vfree(ttl_p); 00604 } 00605 else 00606 { 00607 if( (count < 0) 00608 && (count != -RSBAC_ENOTFOUND) 00609 ) 00610 return count; 00611 } 00612 rsbac_list_lol_remove(process_fs_handle, &pid); 00613 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->fs_handles[fs_fd_hash(file.inode)], 00614 &file.inode, 00615 (void **) &cap_item_p, 00616 &ttl_p); 00617 if( !count 00618 || (count == -RSBAC_ENOTFOUND) 00619 ) 00620 { 00621 tid.file = file; 00622 if(!rsbac_get_parent(target, tid, &target, &tid)) 00623 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->fs_handles[fs_fd_hash(tid.file.inode)], 00624 &tid.file.inode, 00625 (void **) &cap_item_p, 00626 &ttl_p); 00627 } 00628 if(count > 0) 00629 { 00630 for(i=0; i < count ; i++) 00631 { 00632 rsbac_list_lol_subadd_ttl(process_fs_handle, 00633 ttl_p[i], 00634 &pid, 00635 &cap_item_p[i], 00636 NULL); 00637 } 00638 rsbac_vfree(cap_item_p); 00639 rsbac_vfree(ttl_p); 00640 } 00641 else 00642 { 00643 if( (count < 0) 00644 && (count != -RSBAC_ENOTFOUND) 00645 ) 00646 return count; 00647 } 00648 #endif 00649 00650 return 0; 00651 }; /* end of copy_fp_cap_set_item() */ 00652 00653 /************************************************************************** */ 00654 /* The copy_pp_cap_set_item() function copies a process cap set to another */ 00655 00656 static int copy_pp_cap_set_item_handle(rsbac_list_handle_t handle, 00657 rsbac_pid_t old_pid, 00658 rsbac_pid_t new_pid) 00659 { 00660 struct rsbac_auth_cap_range_t * cap_item_p; 00661 rsbac_time_t * ttl_p; 00662 int i; 00663 long count; 00664 00665 rsbac_list_lol_remove(handle, &new_pid); 00666 count = rsbac_list_lol_get_all_subdesc_ttl(handle, 00667 &old_pid, 00668 (void **) &cap_item_p, 00669 &ttl_p); 00670 if(count > 0) 00671 { 00672 for(i=0; i < count ; i++) 00673 { 00674 rsbac_list_lol_subadd_ttl(handle, 00675 ttl_p[i], 00676 &new_pid, 00677 &cap_item_p[i], 00678 NULL); 00679 } 00680 rsbac_vfree(cap_item_p); 00681 rsbac_vfree(ttl_p); 00682 } 00683 else 00684 { 00685 if(count < 0) 00686 return count; 00687 } 00688 return 0; 00689 } 00690 00691 static int copy_pp_cap_set_item(rsbac_pid_t old_pid, 00692 rsbac_pid_t new_pid) 00693 { 00694 int res; 00695 00696 res = copy_pp_cap_set_item_handle(process_handle, old_pid, new_pid); 00697 00698 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00699 if(res) 00700 return res; 00701 res = copy_pp_cap_set_item_handle(process_eff_handle, old_pid, new_pid); 00702 if(res) 00703 return res; 00704 res = copy_pp_cap_set_item_handle(process_fs_handle, old_pid, new_pid); 00705 #endif 00706 return(res); 00707 }; /* end of copy_pp_cap_set_item() */ 00708 00709 /************************************************* */ 00710 /* proc functions */ 00711 /************************************************* */ 00712 00713 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 00714 static int 00715 auth_devices_proc_info(char *buffer, char **start, off_t offset, int length) 00716 { 00717 int len = 0; 00718 off_t pos = 0; 00719 off_t begin = 0; 00720 struct rsbac_auth_device_list_item_t * device_p; 00721 u_long dflags; 00722 00723 if (!rsbac_is_initialized()) return (-ENOSYS); 00724 00725 len += sprintf(buffer, "%u RSBAC AUTH Devices\n--------------------\n", 00726 device_list_head.count); 00727 00728 /* wait for read access to device_list_head */ 00729 rsbac_read_lock(&device_list_head.lock, &dflags); 00730 /* OK, go on */ 00731 for (device_p = device_list_head.head; device_p; device_p = device_p->next) 00732 { 00733 len += sprintf(buffer + len, "%02u:%02u with mount_count = %u\n", 00734 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), 00735 device_p->mount_count); 00736 pos = begin + len; 00737 if (pos < offset) 00738 { 00739 len = 0; 00740 begin = pos; 00741 } 00742 if (pos > offset+length) 00743 break; 00744 } 00745 00746 /* free access to device_list_head */ 00747 rsbac_read_unlock(&device_list_head.lock, &dflags); 00748 00749 *start = buffer + (offset - begin); 00750 len -= (offset - begin); 00751 00752 if (len > length) 00753 len = length; 00754 return len; 00755 } 00756 00757 static int 00758 stats_auth_proc_info(char *buffer, char **start, off_t offset, int length) 00759 { 00760 u_int len = 0; 00761 off_t pos = 0; 00762 off_t begin = 0; 00763 00764 u_int cap_set_count = 0; 00765 u_int member_count = 0; 00766 u_long dflags; 00767 struct rsbac_auth_device_list_item_t * device_p; 00768 int i; 00769 00770 union rsbac_target_id_t rsbac_target_id; 00771 union rsbac_attribute_value_t rsbac_attribute_value; 00772 00773 if (!rsbac_is_initialized) 00774 { 00775 printk(KERN_WARNING "stats_auth_proc_info(): RSBAC not initialized\n"); 00776 return(-RSBAC_ENOTINITIALIZED); 00777 } 00778 #ifdef CONFIG_RSBAC_DEBUG 00779 if (rsbac_debug_aef_auth) 00780 { 00781 #ifdef CONFIG_RSBAC_RMSG 00782 rsbac_printk(KERN_DEBUG "stats_auth_proc_info(): calling ADF\n"); 00783 #endif 00784 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00785 if (!rsbac_nosyslog) 00786 #endif 00787 printk(KERN_DEBUG "stats_auth_proc_info(): calling ADF\n"); 00788 } 00789 #endif 00790 rsbac_target_id.scd = ST_rsbac; 00791 rsbac_attribute_value.dummy = 0; 00792 if (!rsbac_adf_request(R_GET_STATUS_DATA, 00793 current->pid, 00794 T_SCD, 00795 rsbac_target_id, 00796 A_none, 00797 rsbac_attribute_value)) 00798 { 00799 return -EPERM; 00800 } 00801 00802 len += sprintf(buffer, "AUTH Status\n-----------\n"); 00803 00804 len += sprintf(buffer + len, "%lu process cap set items, sum of %lu members\n", 00805 rsbac_list_lol_count(process_handle), 00806 rsbac_list_lol_all_subcount(process_handle)); 00807 pos = begin + len; 00808 if (pos < offset) 00809 { 00810 len = 0; 00811 begin = pos; 00812 } 00813 if (pos > offset+length) 00814 goto out; 00815 00816 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00817 len += sprintf(buffer + len, "%lu process eff cap set items, sum of %lu members\n", 00818 rsbac_list_lol_count(process_eff_handle), 00819 rsbac_list_lol_all_subcount(process_eff_handle)); 00820 pos = begin + len; 00821 if (pos < offset) 00822 { 00823 len = 0; 00824 begin = pos; 00825 } 00826 if (pos > offset+length) 00827 goto out; 00828 len += sprintf(buffer + len, "%lu process fs cap set items, sum of %lu members\n", 00829 rsbac_list_lol_count(process_fs_handle), 00830 rsbac_list_lol_all_subcount(process_fs_handle)); 00831 pos = begin + len; 00832 if (pos < offset) 00833 { 00834 len = 0; 00835 begin = pos; 00836 } 00837 if (pos > offset+length) 00838 goto out; 00839 #endif 00840 00841 /* protect device list */ 00842 rsbac_read_lock(&device_list_head.lock, &dflags); 00843 device_p = device_list_head.head; 00844 while(device_p) 00845 { 00846 /* reset counters */ 00847 cap_set_count = 0; 00848 member_count = 0; 00849 for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++) 00850 { 00851 cap_set_count += rsbac_list_lol_count(device_p->handles[i]); 00852 member_count += rsbac_list_lol_all_subcount(device_p->handles[i]); 00853 } 00854 len += sprintf(buffer + len, "device %02u:%02u has %u file cap set items, sum of %u members\n", 00855 RSBAC_MAJOR(device_p->id), 00856 RSBAC_MINOR(device_p->id), 00857 cap_set_count,member_count); 00858 pos = begin + len; 00859 if (pos < offset) 00860 { 00861 len = 0; 00862 begin = pos; 00863 } 00864 if (pos > offset+length) 00865 goto out_unlock; 00866 00867 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 00868 cap_set_count = 0; 00869 member_count = 0; 00870 for(i=0 ; i < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; i++) 00871 { 00872 cap_set_count += rsbac_list_lol_count(device_p->eff_handles[i]); 00873 member_count += rsbac_list_lol_all_subcount(device_p->eff_handles[i]); 00874 } 00875 len += sprintf(buffer + len, "device %02u:%02u has %u file eff cap set items, sum of %u members\n", 00876 RSBAC_MAJOR(device_p->id), 00877 RSBAC_MINOR(device_p->id), 00878 cap_set_count,member_count); 00879 pos = begin + len; 00880 if (pos < offset) 00881 { 00882 len = 0; 00883 begin = pos; 00884 } 00885 if (pos > offset+length) 00886 goto out_unlock; 00887 cap_set_count = 0; 00888 member_count = 0; 00889 for(i=0 ; i < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; i++) 00890 { 00891 cap_set_count += rsbac_list_lol_count(device_p->fs_handles[i]); 00892 member_count += rsbac_list_lol_all_subcount(device_p->fs_handles[i]); 00893 } 00894 len += sprintf(buffer + len, "device %02u:%02u has %u file fs cap set items, sum of %u members\n", 00895 RSBAC_MAJOR(device_p->id), 00896 RSBAC_MINOR(device_p->id), 00897 cap_set_count,member_count); 00898 pos = begin + len; 00899 if (pos < offset) 00900 { 00901 len = 0; 00902 begin = pos; 00903 } 00904 if (pos > offset+length) 00905 goto out_unlock; 00906 #endif 00907 00908 device_p = device_p->next; 00909 } 00910 out_unlock: 00911 /* unprotect device list */ 00912 rsbac_read_unlock(&device_list_head.lock, &dflags); 00913 00914 out: 00915 *start = buffer + (offset - begin); 00916 len -= (offset - begin); 00917 00918 if (len > length) 00919 len = length; 00920 return len; 00921 } 00922 00923 static int 00924 auth_caplist_proc_info(char *buffer, char **start, off_t offset, int length) 00925 { 00926 u_int len = 0; 00927 off_t pos = 0; 00928 off_t begin = 0; 00929 00930 u_int count = 0; 00931 u_int member_count = 0; 00932 u_long all_member_count; 00933 u_long dflags; 00934 int i,j,list; 00935 struct rsbac_auth_device_list_item_t * device_p; 00936 rsbac_pid_t * p_list; 00937 rsbac_inode_nr_t * f_list; 00938 struct rsbac_auth_cap_range_t * cap_list; 00939 00940 union rsbac_target_id_t rsbac_target_id; 00941 union rsbac_attribute_value_t rsbac_attribute_value; 00942 00943 if (!rsbac_is_initialized) 00944 { 00945 printk(KERN_WARNING "auth_caplist_proc_info(): RSBAC not initialized\n"); 00946 return(-RSBAC_ENOTINITIALIZED); 00947 } 00948 #ifdef CONFIG_RSBAC_DEBUG 00949 if (rsbac_debug_aef_auth) 00950 { 00951 #ifdef CONFIG_RSBAC_RMSG 00952 rsbac_printk(KERN_DEBUG "auth_caplist_proc_info(): calling ADF\n"); 00953 #endif 00954 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00955 if (!rsbac_nosyslog) 00956 #endif 00957 printk(KERN_DEBUG "auth_caplist_proc_info(): calling ADF\n"); 00958 } 00959 #endif 00960 rsbac_target_id.scd = ST_rsbac; 00961 rsbac_attribute_value.dummy = 0; 00962 if (!rsbac_adf_request(R_GET_STATUS_DATA, 00963 current->pid, 00964 T_SCD, 00965 rsbac_target_id, 00966 A_none, 00967 rsbac_attribute_value)) 00968 { 00969 return -EPERM; 00970 } 00971 00972 len += sprintf(buffer, "AUTH Cap Lists\n--------------\n"); 00973 00974 /* protect process cap set list */ 00975 len += sprintf(buffer + len, "Process capabilities:\nset-id count cap-members"); 00976 pos = begin + len; 00977 if (pos < offset) 00978 { 00979 len = 0; 00980 begin = pos; 00981 } 00982 if (pos > offset+length) 00983 goto out; 00984 00985 all_member_count = 0; 00986 count = rsbac_list_lol_get_all_desc(process_handle, 00987 (void **) &p_list); 00988 if(count > 0) 00989 { 00990 for(i=0; i<count; i++) 00991 { 00992 member_count = rsbac_list_lol_get_all_subdesc(process_handle, 00993 &p_list[i], 00994 (void **) &cap_list); 00995 len += sprintf(buffer + len, "\n %u\t%u\t", 00996 p_list[i], 00997 member_count); 00998 if(member_count > 0) 00999 { 01000 for(j=0; j<member_count; j++) 01001 { 01002 if(cap_list[j].first != cap_list[j].last) 01003 len += sprintf(buffer + len, "%u:%u ", 01004 cap_list[j].first, 01005 cap_list[j].last); 01006 else 01007 len += sprintf(buffer + len, "%u ", 01008 cap_list[j].first); 01009 pos = begin + len; 01010 if (pos < offset) 01011 { 01012 len = 0; 01013 begin = pos; 01014 } 01015 if (pos > offset+length) 01016 { 01017 rsbac_vfree(cap_list); 01018 rsbac_vfree(p_list); 01019 goto out; 01020 } 01021 } 01022 rsbac_vfree(cap_list); 01023 all_member_count += member_count; 01024 } 01025 pos = begin + len; 01026 if (pos < offset) 01027 { 01028 len = 0; 01029 begin = pos; 01030 } 01031 if (pos > offset+length) 01032 { 01033 rsbac_vfree(p_list); 01034 goto out; 01035 } 01036 } 01037 rsbac_vfree(p_list); 01038 } 01039 len += sprintf(buffer + len, "\n%u process cap set items, sum of %lu members\n", 01040 count,all_member_count); 01041 pos = begin + len; 01042 if (pos < offset) 01043 { 01044 len = 0; 01045 begin = pos; 01046 } 01047 if (pos > offset+length) 01048 goto out; 01049 01050 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 01051 len += sprintf(buffer + len, "\nProcess eff capabilities:\nset-id count cap-members"); 01052 pos = begin + len; 01053 if (pos < offset) 01054 { 01055 len = 0; 01056 begin = pos; 01057 } 01058 if (pos > offset+length) 01059 goto out; 01060 01061 all_member_count = 0; 01062 count = rsbac_list_lol_get_all_desc(process_eff_handle, 01063 (void **) &p_list); 01064 if(count > 0) 01065 { 01066 for(i=0; i<count; i++) 01067 { 01068 member_count = rsbac_list_lol_get_all_subdesc(process_eff_handle, 01069 &p_list[i], 01070 (void **) &cap_list); 01071 len += sprintf(buffer + len, "\n %u\t%u\t", 01072 p_list[i], 01073 member_count); 01074 if(member_count > 0) 01075 { 01076 for(j=0; j<member_count; j++) 01077 { 01078 if(cap_list[j].first != cap_list[j].last) 01079 len += sprintf(buffer + len, "%u:%u ", 01080 cap_list[j].first, 01081 cap_list[j].last); 01082 else 01083 len += sprintf(buffer + len, "%u ", 01084 cap_list[j].first); 01085 pos = begin + len; 01086 if (pos < offset) 01087 { 01088 len = 0; 01089 begin = pos; 01090 } 01091 if (pos > offset+length) 01092 { 01093 rsbac_vfree(cap_list); 01094 rsbac_vfree(p_list); 01095 goto out; 01096 } 01097 } 01098 rsbac_vfree(cap_list); 01099 all_member_count += member_count; 01100 } 01101 pos = begin + len; 01102 if (pos < offset) 01103 { 01104 len = 0; 01105 begin = pos; 01106 } 01107 if (pos > offset+length) 01108 { 01109 rsbac_vfree(p_list); 01110 goto out; 01111 } 01112 } 01113 rsbac_vfree(p_list); 01114 } 01115 len += sprintf(buffer + len, "\n%u process eff cap set items, sum of %lu members\n", 01116 count,all_member_count); 01117 pos = begin + len; 01118 if (pos < offset) 01119 { 01120 len = 0; 01121 begin = pos; 01122 } 01123 if (pos > offset+length) 01124 goto out; 01125 len += sprintf(buffer + len, "\nProcess fs capabilities:\nset-id count cap-members"); 01126 pos = begin + len; 01127 if (pos < offset) 01128 { 01129 len = 0; 01130 begin = pos; 01131 } 01132 if (pos > offset+length) 01133 goto out; 01134 01135 all_member_count = 0; 01136 count = rsbac_list_lol_get_all_desc(process_fs_handle, 01137 (void **) &p_list); 01138 if(count > 0) 01139 { 01140 for(i=0; i<count; i++) 01141 { 01142 member_count = rsbac_list_lol_get_all_subdesc(process_fs_handle, 01143 &p_list[i], 01144 (void **) &cap_list); 01145 len += sprintf(buffer + len, "\n %u\t%u\t", 01146 p_list[i], 01147 member_count); 01148 if(member_count > 0) 01149 { 01150 for(j=0; j<member_count; j++) 01151 { 01152 if(cap_list[j].first != cap_list[j].last) 01153 len += sprintf(buffer + len, "%u:%u ", 01154 cap_list[j].first, 01155 cap_list[j].last); 01156 else 01157 len += sprintf(buffer + len, "%u ", 01158 cap_list[j].first); 01159 pos = begin + len; 01160 if (pos < offset) 01161 { 01162 len = 0; 01163 begin = pos; 01164 } 01165 if (pos > offset+length) 01166 { 01167 rsbac_vfree(cap_list); 01168 rsbac_vfree(p_list); 01169 goto out; 01170 } 01171 } 01172 rsbac_vfree(cap_list); 01173 all_member_count += member_count; 01174 } 01175 pos = begin + len; 01176 if (pos < offset) 01177 { 01178 len = 0; 01179 begin = pos; 01180 } 01181 if (pos > offset+length) 01182 { 01183 rsbac_vfree(p_list); 01184 goto out; 01185 } 01186 } 01187 rsbac_vfree(p_list); 01188 } 01189 len += sprintf(buffer + len, "\n\n%u process fs cap set items, sum of %lu members\n", 01190 count,all_member_count); 01191 pos = begin + len; 01192 if (pos < offset) 01193 { 01194 len = 0; 01195 begin = pos; 01196 } 01197 if (pos > offset+length) 01198 goto out; 01199 #endif 01200 01201 len += sprintf(buffer + len, "\nFile capabilities:\nset-id count cap-members"); 01202 pos = begin + len; 01203 if (pos < offset) 01204 { 01205 len = 0; 01206 begin = pos; 01207 } 01208 if (pos > offset+length) 01209 goto out; 01210 01211 /* protect device list */ 01212 rsbac_read_lock(&device_list_head.lock, &dflags); 01213 device_p = device_list_head.head; 01214 while(device_p) 01215 { 01216 /* reset counters */ 01217 all_member_count = 0; 01218 for(list=0 ; list < RSBAC_AUTH_NR_CAP_FD_LISTS; list++) 01219 { 01220 count = rsbac_list_lol_get_all_desc(device_p->handles[list], 01221 (void **) &f_list); 01222 if(count > 0) 01223 { 01224 for(i=0; i<count; i++) 01225 { 01226 member_count = rsbac_list_lol_get_all_subdesc(device_p->handles[list], 01227 &f_list[i], 01228 (void **) &cap_list); 01229 len += sprintf(buffer + len, "\n %u\t%u\t", 01230 f_list[i], 01231 member_count); 01232 if(member_count > 0) 01233 { 01234 for(j=0; j<member_count; j++) 01235 { 01236 if(cap_list[j].first != cap_list[j].last) 01237 len += sprintf(buffer + len, "%u:%u ", 01238 cap_list[j].first, 01239 cap_list[j].last); 01240 else 01241 len += sprintf(buffer + len, "%u ", 01242 cap_list[j].first); 01243 pos = begin + len; 01244 if (pos < offset) 01245 { 01246 len = 0; 01247 begin = pos; 01248 } 01249 if (pos > offset+length) 01250 { 01251 rsbac_vfree(cap_list); 01252 rsbac_vfree(f_list); 01253 goto out_unlock; 01254 } 01255 } 01256 rsbac_vfree(cap_list); 01257 all_member_count += member_count; 01258 } 01259 pos = begin + len; 01260 if (pos < offset) 01261 { 01262 len = 0; 01263 begin = pos; 01264 } 01265 if (pos > offset+length) 01266 { 01267 rsbac_vfree(f_list); 01268 goto out_unlock; 01269 } 01270 } 01271 rsbac_vfree(f_list); 01272 } 01273 } 01274 len += sprintf(buffer + len, "\ndevice %02u:%02u has %u file cap set items, sum of %lu members, list is clean\n", 01275 RSBAC_MAJOR(device_p->id), 01276 RSBAC_MINOR(device_p->id), 01277 count, all_member_count); 01278 pos = begin + len; 01279 if (pos < offset) 01280 { 01281 len = 0; 01282 begin = pos; 01283 } 01284 if (pos > offset+length) 01285 goto out_unlock; 01286 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 01287 all_member_count = 0; 01288 for(list=0 ; list < RSBAC_AUTH_NR_CAP_EFF_FD_LISTS; list++) 01289 { 01290 count = rsbac_list_lol_get_all_desc(device_p->eff_handles[list], 01291 (void **) &f_list); 01292 if(count > 0) 01293 { 01294 for(i=0; i<count; i++) 01295 { 01296 member_count = rsbac_list_lol_get_all_subdesc(device_p->eff_handles[list], 01297 &f_list[i], 01298 (void **) &cap_list); 01299 len += sprintf(buffer + len, "\n %u\t%u\t", 01300 f_list[i], 01301 member_count); 01302 if(member_count > 0) 01303 { 01304 for(j=0; j<member_count; j++) 01305 { 01306 if(cap_list[j].first != cap_list[j].last) 01307 len += sprintf(buffer + len, "%u:%u ", 01308 cap_list[j].first, 01309 cap_list[j].last); 01310 else 01311 len += sprintf(buffer + len, "%u ", 01312 cap_list[j].first); 01313 pos = begin + len; 01314 if (pos < offset) 01315 { 01316 len = 0; 01317 begin = pos; 01318 } 01319 if (pos > offset+length) 01320 { 01321 rsbac_vfree(cap_list); 01322 rsbac_vfree(f_list); 01323 goto out_unlock; 01324 } 01325 } 01326 rsbac_vfree(cap_list); 01327 all_member_count += member_count; 01328 } 01329 pos = begin + len; 01330 if (pos < offset) 01331 { 01332 len = 0; 01333 begin = pos; 01334 } 01335 if (pos > offset+length) 01336 { 01337 rsbac_vfree(f_list); 01338 goto out_unlock; 01339 } 01340 } 01341 rsbac_vfree(f_list); 01342 } 01343 } 01344 len += sprintf(buffer + len, "\ndevice %02u:%02u has %u file eff cap set items, sum of %lu members, list is clean\n", 01345 RSBAC_MAJOR(device_p->id), 01346 RSBAC_MINOR(device_p->id), 01347 count, all_member_count); 01348 pos = begin + len; 01349 if (pos < offset) 01350 { 01351 len = 0; 01352 begin = pos; 01353 } 01354 if (pos > offset+length) 01355 goto out_unlock; 01356 01357 all_member_count = 0; 01358 for(list=0 ; list < RSBAC_AUTH_NR_CAP_FS_FD_LISTS; list++) 01359 { 01360 count = rsbac_list_lol_get_all_desc(device_p->fs_handles[list], 01361 (void **) &f_list); 01362 if(count > 0) 01363 { 01364 for(i=0; i<count; i++) 01365 { 01366 member_count = rsbac_list_lol_get_all_subdesc(device_p->fs_handles[list], 01367 &f_list[i], 01368 (void **) &cap_list); 01369 len += sprintf(buffer + len, "\n %u\t%u\t", 01370 f_list[i], 01371 member_count); 01372 if(member_count > 0) 01373 { 01374 for(j=0; j<member_count; j++) 01375 { 01376 if(cap_list[j].first != cap_list[j].last) 01377 len += sprintf(buffer + len, "%u:%u ", 01378 cap_list[j].first, 01379 cap_list[j].last); 01380 else 01381 len += sprintf(buffer + len, "%u ", 01382 cap_list[j].first); 01383 pos = begin + len; 01384 if (pos < offset) 01385 { 01386 len = 0; 01387 begin = pos; 01388 } 01389 if (pos > offset+length) 01390 { 01391 rsbac_vfree(cap_list); 01392 rsbac_vfree(f_list); 01393 goto out_unlock; 01394 } 01395 } 01396 rsbac_vfree(cap_list); 01397 all_member_count += member_count; 01398 } 01399 pos = begin + len; 01400 if (pos < offset) 01401 { 01402 len = 0; 01403 begin = pos; 01404 } 01405 if (pos > offset+length) 01406 { 01407 rsbac_vfree(f_list); 01408 goto out_unlock; 01409 } 01410 } 01411 rsbac_vfree(f_list); 01412 } 01413 } 01414 len += sprintf(buffer + len, "\ndevice %02u:%02u has %u file fs cap set items, sum of %lu members, list is clean\n", 01415 RSBAC_MAJOR(device_p->id), 01416 RSBAC_MINOR(device_p->id), 01417 count, all_member_count); 01418 pos = begin + len; 01419 if (pos < offset) 01420 { 01421 len = 0; 01422 begin = pos; 01423 } 01424 if (pos > offset+length) 01425 goto out_unlock; 01426 #endif 01427 device_p = device_p->next; 01428 } 01429 out_unlock: 01430 /* unprotect device list */ 01431 rsbac_read_unlock(&device_list_head.lock, &dflags); 01432 01433 out: 01434 *start = buffer + (offset - begin); 01435 len -= (offset - begin); 01436 01437 if (len > length) 01438 len = length; 01439 return len; 01440 } 01441 #endif /* CONFIG_PROC_FS && CONFIG_RSBAC_PROC */ 01442 01443 /************************************************* */ 01444 /* Init functions */ 01445 /************************************************* */ 01446 01447 /* All functions return 0, if no error occurred, and a negative error code */ 01448 /* otherwise. The error codes are defined in rsbac/error.h. */ 01449 01450 /************************************************************************** */ 01451 /* Initialization of all AUTH data structures. After this call, all AUTH */ 01452 /* data is kept in memory for performance reasons, but is written to disk */ 01453 /* on every change. */ 01454 01455 /* Because there can be no access to aci data structures before init, */ 01456 /* rsbac_init_auth() will initialize all rw-spinlocks to unlocked. */ 01457 01458 #ifdef CONFIG_RSBAC_INIT_DELAY 01459 int rsbac_init_auth(void) 01460 #else 01461 int __init rsbac_init_auth(void) 01462 #endif 01463 { 01464 int err = 0; 01465 struct rsbac_auth_device_list_item_t * device_p = NULL; 01466 u_long dflags; 01467 struct proc_dir_entry * tmp_entry_p; 01468 struct rsbac_list_lol_info_t lol_info; 01469 01470 if (rsbac_is_initialized()) 01471 { 01472 #ifdef CONFIG_RSBAC_RMSG 01473 rsbac_printk(KERN_WARNING "rsbac_init_auth(): RSBAC already initialized\n"); 01474 #endif 01475 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01476 if (!rsbac_nosyslog) 01477 #endif 01478 printk(KERN_WARNING "rsbac_init_auth(): RSBAC already initialized\n"); 01479 return(-RSBAC_EREINIT); 01480 } 01481 01482 /* set rw-spinlocks to unlocked status and init data structures */ 01483 #ifdef CONFIG_RSBAC_RMSG 01484 rsbac_printk(KERN_INFO "rsbac_init_auth(): Initializing RSBAC: AUTH subsystem\n"); 01485 #endif 01486 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01487 if (!rsbac_nosyslog) 01488 #endif 01489 printk(KERN_INFO "rsbac_init_auth(): Initializing RSBAC: AUTH subsystem\n"); 01490 01491 lol_info.version = RSBAC_AUTH_P_LIST_VERSION; 01492 lol_info.key = RSBAC_AUTH_LIST_KEY; 01493 lol_info.desc_size = sizeof(rsbac_pid_t); 01494 lol_info.data_size = 0; 01495 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 01496 lol_info.subdata_size = 0; 01497 lol_info.max_age = 0; 01498 err = rsbac_list_lol_register(RSBAC_LIST_VERSION, 01499 &process_handle, 01500 &lol_info, 01501 RSBAC_LIST_DEF_DATA, 01502 NULL, 01503 cap_compare, 01504 NULL, 01505 NULL, 01506 NULL, 01507 NULL, 01508 RSBAC_AUTH_P_LIST_NAME, 01509 RSBAC_AUTO_DEV); 01510 if(err) 01511 { 01512 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 01513 01514 if(tmp) 01515 { 01516 #ifdef CONFIG_RSBAC_RMSG 01517 rsbac_printk(KERN_WARNING 01518 "rsbac_init_auth(): Registering AUTH process cap list failed with error %s\n", 01519 get_error_name(tmp, err)); 01520 #endif 01521 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01522 if (!rsbac_nosyslog) 01523 #endif 01524 printk(KERN_WARNING 01525 "rsbac_init_auth(): Registering AUTH process cap list failed with error %s\n", 01526 get_error_name(tmp, err)); 01527 rsbac_kfree(tmp); 01528 } 01529 } 01530 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 01531 lol_info.version = RSBAC_AUTH_P_LIST_VERSION; 01532 lol_info.key = RSBAC_AUTH_LIST_KEY; 01533 lol_info.desc_size = sizeof(rsbac_pid_t); 01534 lol_info.data_size = 0; 01535 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 01536 lol_info.subdata_size = 0; 01537 lol_info.max_age = 0; 01538 err = rsbac_list_lol_register(RSBAC_LIST_VERSION, 01539 &process_eff_handle, 01540 &lol_info, 01541 RSBAC_LIST_DEF_DATA, 01542 NULL, 01543 cap_compare, 01544 NULL, 01545 NULL, 01546 NULL, 01547 NULL, 01548 RSBAC_AUTH_P_EFF_LIST_NAME, 01549 RSBAC_AUTO_DEV); 01550 if(err) 01551 { 01552 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 01553 01554 if(tmp) 01555 { 01556 #ifdef CONFIG_RSBAC_RMSG 01557 rsbac_printk(KERN_WARNING 01558 "rsbac_init_auth(): Registering AUTH process eff cap list failed with error %s\n", 01559 get_error_name(tmp, err)); 01560 #endif 01561 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01562 if (!rsbac_nosyslog) 01563 #endif 01564 printk(KERN_WARNING 01565 "rsbac_init_auth(): Registering AUTH process eff cap list failed with error %s\n", 01566 get_error_name(tmp, err)); 01567 rsbac_kfree(tmp); 01568 } 01569 } 01570 lol_info.version = RSBAC_AUTH_P_LIST_VERSION; 01571 lol_info.key = RSBAC_AUTH_LIST_KEY; 01572 lol_info.desc_size = sizeof(rsbac_pid_t); 01573 lol_info.data_size = 0; 01574 lol_info.subdesc_size = sizeof(struct rsbac_auth_cap_range_t); 01575 lol_info.subdata_size = 0; 01576 lol_info.max_age = 0; 01577 err = rsbac_list_lol_register(RSBAC_LIST_VERSION, 01578 &process_fs_handle, 01579 &lol_info, 01580 RSBAC_LIST_DEF_DATA, 01581 NULL, 01582 cap_compare, 01583 NULL, 01584 NULL, 01585 NULL, 01586 NULL, 01587 RSBAC_AUTH_P_FS_LIST_NAME, 01588 RSBAC_AUTO_DEV); 01589 if(err) 01590 { 01591 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 01592 01593 if(tmp) 01594 { 01595 #ifdef CONFIG_RSBAC_RMSG 01596 rsbac_printk(KERN_WARNING 01597 "rsbac_init_auth(): Registering AUTH process fs cap list failed with error %s\n", 01598 get_error_name(tmp, err)); 01599 #endif 01600 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01601 if (!rsbac_nosyslog) 01602 #endif 01603 printk(KERN_WARNING 01604 "rsbac_init_auth(): Registering AUTH process fs cap list failed with error %s\n", 01605 get_error_name(tmp, err)); 01606 rsbac_kfree(tmp); 01607 } 01608 } 01609 #endif 01610 01611 /* Init FD lists */ 01612 device_list_head.lock = RW_LOCK_UNLOCKED; 01613 device_list_head.head = NULL; 01614 device_list_head.tail = NULL; 01615 device_list_head.curr = NULL; 01616 device_list_head.count = 0; 01617 01618 /* read all data */ 01619 #ifdef CONFIG_RSBAC_DEBUG 01620 if (rsbac_debug_ds_auth) 01621 { 01622 #ifdef CONFIG_RSBAC_RMSG 01623 rsbac_printk(KERN_INFO "rsbac_init_auth(): Registering FD lists\n"); 01624 #endif 01625 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01626 if (!rsbac_nosyslog) 01627 #endif 01628 printk(KERN_INFO "rsbac_init_auth(): Registering FD lists\n"); 01629 } 01630 #endif 01631 device_p = create_device_item(rsbac_root_dev); 01632 if (!device_p) 01633 { 01634 #ifdef CONFIG_RSBAC_RMSG 01635 rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n"); 01636 #endif 01637 printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n"); 01638 return(-RSBAC_ECOULDNOTADDDEVICE); 01639 } 01640 if((err = auth_register_fd_lists(device_p,rsbac_root_dev))) 01641 { 01642 char tmp[RSBAC_MAXNAMELEN]; 01643 01644 #ifdef CONFIG_RSBAC_RMSG 01645 rsbac_printk(KERN_WARNING 01646 "rsbac_init_auth(): File/Dir cap set registration failed for dev %02u:%02u, err %s!\n", 01647 RSBAC_MAJOR(rsbac_root_dev), RSBAC_MINOR(rsbac_root_dev), get_error_name(tmp,err)); 01648 #endif 01649 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01650 if (!rsbac_nosyslog) 01651 #endif 01652 printk(KERN_WARNING 01653 "rsbac_init_auth(): File/Dir cap set registration failed for dev %02u:%02u, err %s!\n", 01654 RSBAC_MAJOR(rsbac_root_dev), RSBAC_MINOR(rsbac_root_dev), get_error_name(tmp,err)); 01655 } 01656 /* wait for write access to device_list_head */ 01657 rsbac_write_lock_irq(&device_list_head.lock, &dflags); 01658 device_p = add_device_item(device_p); 01659 /* device was added, allow access */ 01660 rsbac_write_unlock_irq(&device_list_head.lock, &dflags); 01661 if (!device_p) 01662 { 01663 #ifdef CONFIG_RSBAC_RMSG 01664 rsbac_printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n"); 01665 #endif 01666 printk(KERN_CRIT "rsbac_init_auth(): Could not add device!\n"); 01667 return(-RSBAC_ECOULDNOTADDDEVICE); 01668 } 01669 01670 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 01671 tmp_entry_p = create_proc_entry("auth_devices", 01672 S_IFREG | S_IRUGO | S_IWUGO, 01673 proc_rsbac_root_p); 01674 if(tmp_entry_p) 01675 { 01676 tmp_entry_p->get_info = auth_devices_proc_info; 01677 } 01678 tmp_entry_p = create_proc_entry("stats_auth", 01679 S_IFREG | S_IRUGO, 01680 proc_rsbac_root_p); 01681 if(tmp_entry_p) 01682 { 01683 tmp_entry_p->get_info = stats_auth_proc_info; 01684 } 01685 tmp_entry_p = create_proc_entry("auth_caplist", 01686 S_IFREG | S_IRUGO, 01687 proc_rsbac_root_p); 01688 if(tmp_entry_p) 01689 { 01690 tmp_entry_p->get_info = auth_caplist_proc_info; 01691 } 01692 #endif 01693 01694 #ifdef CONFIG_RSBAC_DEBUG 01695 if (rsbac_debug_ds_auth) 01696 { 01697 #ifdef CONFIG_RSBAC_RMSG 01698 rsbac_printk(KERN_DEBUG "rsbac_init_auth(): Ready.\n"); 01699 #endif 01700 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01701 if (!rsbac_nosyslog) 01702 #endif 01703 printk(KERN_DEBUG "rsbac_init_auth(): Ready.\n"); 01704 } 01705 #endif 01706 return(err); 01707 }; 01708 01709 int rsbac_mount_auth(kdev_t kdev) 01710 { 01711 int err = 0; 01712 struct rsbac_auth_device_list_item_t * device_p; 01713 struct rsbac_auth_device_list_item_t * new_device_p; 01714 u_long dflags; 01715 01716 if (!rsbac_is_initialized()) 01717 { 01718 #ifdef CONFIG_RSBAC_RMSG 01719 rsbac_printk(KERN_WARNING "rsbac_mount_auth(): RSBAC not initialized\n"); 01720 #endif 01721 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01722 if (!rsbac_nosyslog) 01723 #endif 01724 printk(KERN_WARNING "rsbac_mount_auth(): RSBAC not initialized\n"); 01725 return(-RSBAC_ENOTINITIALIZED); 01726 } 01727 #ifdef CONFIG_RSBAC_DEBUG 01728 if (rsbac_debug_ds_auth) 01729 { 01730 #ifdef CONFIG_RSBAC_RMSG 01731 rsbac_printk(KERN_DEBUG "rsbac_mount_auth(): mounting device %02u:%02u\n", 01732 RSBAC_MAJOR(kdev),RSBAC_MINOR(kdev)); 01733 #endif 01734 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01735 if (!rsbac_nosyslog) 01736 #endif 01737 printk(KERN_DEBUG "rsbac_mount_auth(): mounting device %02u:%02u\n", 01738 RSBAC_MAJOR(kdev),RSBAC_MINOR(kdev)); 01739 } 01740 #endif 01741 /* wait for write access to device_list_head */ 01742 rsbac_read_lock(&device_list_head.lock, &dflags); 01743 device_p = lookup_device(kdev); 01744 /* repeated mount? */ 01745 if(device_p) 01746 { 01747 #ifdef CONFIG_RSBAC_RMSG 01748 rsbac_printk(KERN_WARNING "rsbac_mount_auth: repeated mount %u of device %02u:%02u\n", 01749 device_p->mount_count, RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01750 #endif 01751 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01752 if (!rsbac_nosyslog) 01753 #endif 01754 printk(KERN_WARNING "rsbac_mount_auth: repeated mount %u of device %02u:%02u\n", 01755 device_p->mount_count, RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01756 device_p->mount_count++; 01757 rsbac_read_unlock(&device_list_head.lock, &dflags); 01758 return 0; 01759 } 01760 rsbac_read_unlock(&device_list_head.lock, &dflags); 01761 01762 new_device_p = create_device_item(kdev); 01763 if(!new_device_p) 01764 return -RSBAC_ECOULDNOTADDDEVICE; 01765 01766 /* register lists */ 01767 if((err = auth_register_fd_lists(new_device_p, kdev))) 01768 { 01769 char tmp[RSBAC_MAXNAMELEN]; 01770 01771 #ifdef CONFIG_RSBAC_RMSG 01772 rsbac_printk(KERN_WARNING 01773 "rsbac_mount_auth(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n", 01774 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev), get_error_name(tmp,err)); 01775 #endif 01776 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01777 if (!rsbac_nosyslog) 01778 #endif 01779 printk(KERN_WARNING 01780 "rsbac_mount_auth(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n", 01781 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev), get_error_name(tmp,err)); 01782 } 01783 01784 /* wait for read access to device_list_head */ 01785 rsbac_read_lock(&device_list_head.lock, &dflags); 01786 /* make sure to only add, if this device item has not been added in the meantime */ 01787 device_p = lookup_device(kdev); 01788 if(device_p) 01789 { 01790 #ifdef CONFIG_RSBAC_RMSG 01791 rsbac_printk(KERN_WARNING 01792 "rsbac_mount_auth(): mount race for device %02u:%02u detected!\n", 01793 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01794 #endif 01795 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01796 if (!rsbac_nosyslog) 01797 #endif 01798 printk(KERN_WARNING 01799 "rsbac_mount_auth(): mount race for device %02u:%02u detected!\n", 01800 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01801 device_p->mount_count++; 01802 rsbac_read_unlock(&device_list_head.lock, &dflags); 01803 clear_device_item(new_device_p); 01804 } 01805 else 01806 { 01807 rsbac_read_unlock(&device_list_head.lock, &dflags); 01808 rsbac_write_lock_irq(&device_list_head.lock, &dflags); 01809 device_p = add_device_item(new_device_p); 01810 rsbac_write_unlock_irq(&device_list_head.lock, &dflags); 01811 if(!device_p) 01812 { 01813 #ifdef CONFIG_RSBAC_RMSG 01814 rsbac_printk(KERN_WARNING "rsbac_mount_auth: adding device %02u:%02u failed!\n", 01815 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01816 #endif 01817 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01818 if (!rsbac_nosyslog) 01819 #endif 01820 printk(KERN_WARNING "rsbac_mount_auth: adding device %02u:%02u failed!\n", 01821 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01822 clear_device_item(new_device_p); 01823 err = -RSBAC_ECOULDNOTADDDEVICE; 01824 } 01825 } 01826 return(err); 01827 }; 01828 01829 /* When umounting a device, its file cap set list must be removed. */ 01830 01831 int rsbac_umount_auth(kdev_t kdev) 01832 { 01833 u_long flags; 01834 struct rsbac_auth_device_list_item_t * device_p; 01835 01836 if (!rsbac_is_initialized()) 01837 { 01838 #ifdef CONFIG_RSBAC_RMSG 01839 rsbac_printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n"); 01840 #endif 01841 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01842 if (!rsbac_nosyslog) 01843 #endif 01844 printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n"); 01845 return(-RSBAC_ENOTINITIALIZED); 01846 } 01847 01848 #ifdef CONFIG_RSBAC_DEBUG 01849 if (rsbac_debug_ds_auth) 01850 { 01851 #ifdef CONFIG_RSBAC_RMSG 01852 rsbac_printk(KERN_DEBUG "rsbac_umount_auth(): umounting device %02u:%02u\n", 01853 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01854 #endif 01855 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01856 if (!rsbac_nosyslog) 01857 #endif 01858 printk(KERN_DEBUG "rsbac_umount_auth(): umounting device %02u:%02u\n", 01859 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01860 } 01861 #endif 01862 /* sync of attribute lists was done in rsbac_umount */ 01863 /* wait for write access to device_list_head */ 01864 rsbac_write_lock(&device_list_head.lock, &flags); 01865 /* OK, nobody else is working on it... */ 01866 device_p = lookup_device(kdev); 01867 if(device_p) 01868 { 01869 if(device_p->mount_count == 1) 01870 remove_device_item(kdev); 01871 else 01872 { 01873 if(device_p->mount_count > 1) 01874 { 01875 device_p->mount_count--; 01876 } 01877 else 01878 { 01879 #ifdef CONFIG_RSBAC_RMSG 01880 rsbac_printk(KERN_WARNING "rsbac_mount_auth: device %02u:%02u has mount_count < 1!\n", 01881 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01882 #endif 01883 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01884 if (!rsbac_nosyslog) 01885 #endif 01886 printk(KERN_WARNING "rsbac_mount_auth: device %02u:%02u has mount_count < 1!\n", 01887 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev)); 01888 } 01889 } 01890 } 01891 01892 /* allow access */ 01893 rsbac_write_unlock(&device_list_head.lock, &flags); 01894 return(0); 01895 }; 01896 01897 /***************************************************/ 01898 /* We also need some status information... */ 01899 01900 int rsbac_stats_auth(void) 01901 { 01902 u_int cap_set_count = 0; 01903 u_int member_count = 0; 01904 u_long dflags; 01905 struct rsbac_auth_device_list_item_t * device_p; 01906 int i; 01907 01908 union rsbac_target_id_t rsbac_target_id; 01909 union rsbac_attribute_value_t rsbac_attribute_value; 01910 01911 if (!rsbac_is_initialized) 01912 { 01913 #ifdef CONFIG_RSBAC_RMSG 01914 rsbac_printk(KERN_WARNING "rsbac_stats_auth(): RSBAC not initialized\n"); 01915 #endif 01916 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01917 if (!rsbac_nosyslog) 01918 #endif 01919 printk(KERN_WARNING "rsbac_stats_auth(): RSBAC not initialized\n"); 01920 return(-RSBAC_ENOTINITIALIZED); 01921 } 01922 #ifdef CONFIG_RSBAC_DEBUG 01923 if (rsbac_debug_aef_auth) 01924 { 01925 #ifdef CONFIG_RSBAC_RMSG 01926 rsbac_printk(KERN_DEBUG "rsbac_stats_auth(): calling ADF\n"); 01927 #endif 01928 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01929 if (!rsbac_nosyslog) 01930 #endif 01931 printk(KERN_DEBUG "rsbac_stats_auth(): calling ADF\n"); 01932 } 01933 #endif 01934 rsbac_target_id.scd = ST_rsbac; 01935 rsbac_attribute_value.dummy = 0; 01936 if (!rsbac_adf_request(R_GET_STATUS_DATA, 01937 current->pid, 01938 T_SCD, 01939 rsbac_target_id, 01940 A_none, 01941 rsbac_attribute_value)) 01942 { 01943 return -EPERM; 01944 } 01945 01946 printk(KERN_INFO "AUTH Status\n-----------\n"); 01947 01948 printk(KERN_INFO "%lu process cap set items, sum of %lu members\n", 01949 rsbac_list_lol_count(process_handle), 01950 rsbac_list_lol_all_subcount(process_handle)); 01951 01952 /* protect device list */ 01953 rsbac_read_lock(&device_list_head.lock, &dflags); 01954 device_p = device_list_head.head; 01955 while(device_p) 01956 { 01957 /* reset counters */ 01958 cap_set_count = 0; 01959 member_count = 0; 01960 for(i=0 ; i < RSBAC_AUTH_NR_CAP_FD_LISTS; i++) 01961 { 01962 cap_set_count += rsbac_list_lol_count(device_p->handles[i]); 01963 member_count += rsbac_list_lol_all_subcount(device_p->handles[i]); 01964 } 01965 printk(KERN_INFO "device %02u:%02u has %u file cap set items, sum of %u members\n", 01966 RSBAC_MAJOR(device_p->id), 01967 RSBAC_MINOR(device_p->id), 01968 cap_set_count,member_count); 01969 device_p = device_p->next; 01970 } 01971 /* unprotect device list */ 01972 rsbac_read_unlock(&device_list_head.lock, &dflags); 01973 return(0); 01974 }; 01975 01976 /***************************************************/ 01977 /* consistency checking (as far as possible) */ 01978 01979 int rsbac_check_auth(int correct, int check_inode) 01980 { 01981 struct rsbac_auth_device_list_item_t * device_p; 01982 u_long f_count = 0, f_sum = 0, tmp_count, 01983 r_count, u_count, b_count, no_member_count; 01984 long desc_count; 01985 u_int i,list_no; 01986 u_long dflags; 01987 struct super_block * sb_p; 01988 struct inode * inode_p; 01989 rsbac_inode_nr_t * fd_desc_p; 01990 01991 if (!rsbac_is_initialized()) 01992 { 01993 #ifdef CONFIG_RSBAC_RMSG 01994 rsbac_printk(KERN_WARNING "rsbac_check_auth(): RSBAC not initialized\n"); 01995 #endif 01996 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01997 if (!rsbac_nosyslog) 01998 #endif 01999 printk(KERN_WARNING "rsbac_check_auth(): RSBAC not initialized\n"); 02000 return(-RSBAC_ENOTINITIALIZED); 02001 } 02002 02003 /* wait for read access to device_list_head */ 02004 rsbac_read_lock(&device_list_head.lock, &dflags); 02005 /* OK, go on */ 02006 /* printk(KERN_INFO "rsbac_check_auth(): currently %u processes working on file/dir aci\n", 02007 device_list_head.lock.lock); */ 02008 device_p = device_list_head.head; 02009 while (device_p) 02010 { /* for all sublists */ 02011 f_count = 0; 02012 r_count = 0; 02013 u_count = 0; 02014 b_count = 0; 02015 no_member_count = 0; 02016 if(check_inode) 02017 { 02018 sb_p = rsbac_get_super_block(device_p->id); 02019 if(!sb_p) 02020 { 02021 #ifdef CONFIG_RSBAC_RMSG 02022 rsbac_printk(KERN_WARNING "rsbac_check_auth(): no super block for device %02u:%02u!\n", 02023 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id)); 02024 #endif 02025 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02026 if (!rsbac_nosyslog) 02027 #endif 02028 printk(KERN_WARNING "rsbac_check_auth(): no super block for device %02u:%02u!\n", 02029 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id)); 02030 } 02031 } 02032 else 02033 sb_p = NULL; 02034 02035 /* OK, go ahead */ 02036 for(list_no = 0; list_no < RSBAC_AUTH_NR_CAP_FD_LISTS; list_no++) 02037 { 02038 /* printk(KERN_INFO "rsbac_check_auth(): list %u\n", 02039 list_no); */ 02040 tmp_count = 0; 02041 desc_count = rsbac_list_lol_get_all_desc(device_p->handles[list_no], (void **) &fd_desc_p); 02042 if(desc_count > 0) 02043 { 02044 for(i=0; i<desc_count; i++) 02045 { 02046 /* check for inode on disk (but not for reiserfs, because of 64bit inode numbers) */ 02047 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 02048 if(sb_p) 02049 #else 02050 if(sb_p && !sb_p->s_op->read_inode2) 02051 #endif 02052 { 02053 inode_p = iget(sb_p, fd_desc_p[i]); 02054 if(is_bad_inode(inode_p)) 02055 { /* inode is bad -> remove */ 02056 b_count++; 02057 if(correct) 02058 { 02059 #ifdef CONFIG_RSBAC_RMSG 02060 rsbac_printk(KERN_INFO 02061 "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u, removing!\n", 02062 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02063 #endif 02064 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02065 if (!rsbac_nosyslog) 02066 #endif 02067 printk(KERN_INFO 02068 "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u, removing!\n", 02069 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02070 rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]); 02071 continue; 02072 } 02073 else 02074 { 02075 #ifdef CONFIG_RSBAC_RMSG 02076 rsbac_printk(KERN_INFO 02077 "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u!\n", 02078 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02079 #endif 02080 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02081 if (!rsbac_nosyslog) 02082 #endif 02083 printk(KERN_INFO 02084 "rsbac_check_auth(): fd_item for bad inode %u on device %02u:%02u, list %u!\n", 02085 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02086 } 02087 } /* end of bad_inode */ 02088 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 02089 else 02090 { /* good inode */ 02091 /* currently only deletion checking of ext2 inodes is possible */ 02092 if(sb_p->s_magic == EXT2_SUPER_MAGIC) 02093 { 02094 if(inode_p->u.ext2_i.i_dtime) 02095 { /* inode has been deleted -> remove */ 02096 r_count++; 02097 if(correct) 02098 { 02099 #ifdef CONFIG_RSBAC_RMSG 02100 rsbac_printk(KERN_INFO 02101 "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u, removing!\n", 02102 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02103 #endif 02104 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02105 if (!rsbac_nosyslog) 02106 #endif 02107 printk(KERN_INFO 02108 "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u, removing!\n", 02109 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02110 rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]); 02111 continue; 02112 } 02113 else 02114 { 02115 #ifdef CONFIG_RSBAC_RMSG 02116 rsbac_printk(KERN_INFO 02117 "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u!\n", 02118 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02119 #endif 02120 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02121 if (!rsbac_nosyslog) 02122 #endif 02123 printk(KERN_INFO 02124 "rsbac_check_auth(): fd_item for deleted inode %u on device %02u:%02u, list %u!\n", 02125 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02126 } 02127 } 02128 else 02129 { 02130 if(inode_p->i_nlink <= 0) 02131 { /* inode has been unlinked, but no dtime is set -> warn */ 02132 u_count++; 02133 if(correct >= 2) 02134 { 02135 #ifdef CONFIG_RSBAC_RMSG 02136 rsbac_printk(KERN_INFO 02137 "rsbac_check_auth(): fd_item for inode %u with nlink <= 0 on device %02u:%02u, list %u, removing!\n", 02138 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02139 #endif 02140 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02141 if (!rsbac_nosyslog) 02142 #endif 02143 printk(KERN_INFO 02144 "rsbac_check_auth(): fd_item for inode %u with nlink <= 0 on device %02u:%02u, list %u, removing!\n", 02145 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02146 rsbac_list_lol_remove(device_p->handles[list_no], &fd_desc_p[i]); 02147 continue; 02148 } 02149 else 02150 { 02151 #ifdef CONFIG_RSBAC_RMSG 02152 rsbac_printk(KERN_INFO 02153 "rsbac_check_auth(): deleted inode %u on device %02u:%02u, list %u, has no dtime!\n", 02154 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02155 #endif 02156 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02157 if (!rsbac_nosyslog) 02158 #endif 02159 printk(KERN_INFO 02160 "rsbac_check_auth(): deleted inode %u on device %02u:%02u, list %u, has no dtime!\n", 02161 fd_desc_p[i], RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), list_no); 02162 } 02163 } 02164 } 02165 } 02166 } /* end of is_good_inode */ 02167 #endif /* VERSION < 2.6.0 */ 02168 iput(inode_p); 02169 } /* end of sb_p */ 02170 } 02171 tmp_count++; 02172 rsbac_vfree(fd_desc_p); 02173 f_count += desc_count; 02174 } 02175 } /* end of for-fd-list-array */ 02176 02177 switch(correct) 02178 { 02179 case 2: 02180 #ifdef CONFIG_RSBAC_RMSG 02181 rsbac_printk(KERN_INFO 02182 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu unlinked inodes, %lu had no members and default mask))\n", 02183 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + u_count + no_member_count, 02184 b_count, r_count, u_count, no_member_count); 02185 #endif 02186 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02187 if (!rsbac_nosyslog) 02188 #endif 02189 printk(KERN_INFO 02190 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu unlinked inodes, %lu had no members and default mask))\n", 02191 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + u_count + no_member_count, 02192 b_count, r_count, u_count, no_member_count); 02193 break; 02194 case 1: 02195 #ifdef CONFIG_RSBAC_RMSG 02196 rsbac_printk(KERN_INFO 02197 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu had no members and default mask), %lu unlinked inodes)\n", 02198 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + no_member_count, 02199 b_count, r_count, no_member_count, u_count); 02200 #endif 02201 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02202 if (!rsbac_nosyslog) 02203 #endif 02204 printk(KERN_INFO 02205 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu removed (%lu bad inodes, %lu dtimed inodes, %lu had no members and default mask), %lu unlinked inodes)\n", 02206 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, b_count + r_count + no_member_count, 02207 b_count, r_count, no_member_count, u_count); 02208 break; 02209 default: 02210 #ifdef CONFIG_RSBAC_RMSG 02211 rsbac_printk(KERN_INFO 02212 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu with bad inodes, %lu with dtimed inodes, %lu unlinked inodes, %lu without members and with default mask)\n", 02213 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, 02214 b_count, r_count, u_count, no_member_count); 02215 #endif 02216 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02217 if (!rsbac_nosyslog) 02218 #endif 02219 printk(KERN_INFO 02220 "rsbac_check_auth(): Device %02u:%02u has %lu file/dir AUTHs (%lu with bad inodes, %lu with dtimed inodes, %lu unlinked inodes, %lu without members and with default mask)\n", 02221 RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id), f_count, 02222 b_count, r_count, u_count, no_member_count); 02223 } 02224 f_sum += f_count; 02225 /* go on */ 02226 device_p = device_p->next; 02227 } 02228 #ifdef CONFIG_RSBAC_RMSG 02229 rsbac_printk(KERN_INFO "rsbac_check_auth(): Sum of %u Devices with %lu file/dir AUTHs\n", 02230 device_list_head.count, f_sum); 02231 #endif 02232 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02233 if (!rsbac_nosyslog) 02234 #endif 02235 printk(KERN_INFO "rsbac_check_auth(): Sum of %u Devices with %lu file/dir AUTHs\n", 02236 device_list_head.count, f_sum); 02237 /* free access to device_list_head */ 02238 rsbac_read_unlock(&device_list_head.lock, &dflags); 02239 02240 #ifdef CONFIG_RSBAC_RMSG 02241 rsbac_printk(KERN_INFO 02242 "rsbac_check_auth(): Total of %lu registered auth items\n", 02243 f_sum); 02244 #endif 02245 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02246 if (!rsbac_nosyslog) 02247 #endif 02248 printk(KERN_INFO 02249 "rsbac_check_auth(): Total of %lu registered auth items\n", 02250 f_sum); 02251 return(0); 02252 }; 02253 02254 /************************************************* */ 02255 /* Access functions */ 02256 /************************************************* */ 02257 02258 /* All these procedures handle the rw-spinlocks to protect the targets during */ 02259 /* access. */ 02260 /* Trying to access a never created or removed set returns an error! */ 02261 02262 /* rsbac_auth_add_to_capset */ 02263 /* Add a set member to a set sublist. Set behaviour: also returns success, */ 02264 /* if member was already in set! */ 02265 02266 int rsbac_auth_add_to_p_capset(rsbac_pid_t pid, 02267 enum rsbac_auth_cap_type_t cap_type, 02268 struct rsbac_auth_cap_range_t cap_range, 02269 rsbac_time_t ttl) 02270 { 02271 if (!rsbac_is_initialized()) 02272 { 02273 printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): RSBAC not initialized\n"); 02274 return(-RSBAC_ENOTINITIALIZED); 02275 } 02276 if (in_interrupt()) 02277 { 02278 printk(KERN_WARNING "rsbac_auth_add_to_p_capset(): called from interrupt!\n"); 02279 } 02280 if(cap_range.first > cap_range.last) 02281 return(-RSBAC_EINVALIDVALUE); 02282 switch(cap_type) 02283 { 02284 case ACT_real: 02285 return rsbac_list_lol_subadd_ttl(process_handle, ttl, &pid, &cap_range, NULL); 02286 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02287 case ACT_eff: 02288 return rsbac_list_lol_subadd_ttl(process_eff_handle, ttl, &pid, &cap_range, NULL); 02289 case ACT_fs: 02290 return rsbac_list_lol_subadd_ttl(process_fs_handle, ttl, &pid, &cap_range, NULL); 02291 #endif 02292 default: 02293 return -RSBAC_EINVALIDTARGET; 02294 } 02295 } 02296 02297 int rsbac_auth_add_to_f_capset(rsbac_auth_file_t file, 02298 enum rsbac_auth_cap_type_t cap_type, 02299 struct rsbac_auth_cap_range_t cap_range, 02300 rsbac_time_t ttl) 02301 { 02302 int err=0; 02303 u_long dflags; 02304 struct rsbac_auth_device_list_item_t * device_p; 02305 02306 if (!rsbac_is_initialized()) 02307 { 02308 printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): RSBAC not initialized\n"); 02309 return(-RSBAC_ENOTINITIALIZED); 02310 } 02311 if (in_interrupt()) 02312 { 02313 printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): called from interrupt!\n"); 02314 } 02315 if(cap_range.first > cap_range.last) 02316 return(-RSBAC_EINVALIDVALUE); 02317 02318 /* protect device list */ 02319 rsbac_read_lock(&device_list_head.lock, &dflags); 02320 device_p = lookup_device(file.device); 02321 if(!device_p) 02322 { 02323 /* trigger rsbac_mount() */ 02324 rsbac_read_unlock(&device_list_head.lock, &dflags); 02325 rsbac_get_super_block(file.device); 02326 /* retry */ 02327 rsbac_read_lock(&device_list_head.lock, &dflags); 02328 device_p = lookup_device(file.device); 02329 if(!device_p) 02330 { 02331 #ifdef CONFIG_RSBAC_RMSG 02332 rsbac_printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): invalid device %02u:%02u!\n", 02333 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02334 #endif 02335 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02336 if (!rsbac_nosyslog) 02337 #endif 02338 printk(KERN_WARNING "rsbac_auth_add_to_f_capset(): invalid device %02u:%02u!\n", 02339 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02340 rsbac_read_unlock(&device_list_head.lock, &dflags); 02341 return(-RSBAC_EINVALIDDEV); 02342 } 02343 } 02344 02345 switch(cap_type) 02346 { 02347 case ACT_real: 02348 err = rsbac_list_lol_subadd_ttl(device_p->handles[fd_hash(file.inode)], 02349 ttl, &file.inode, &cap_range, NULL); 02350 break; 02351 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02352 case ACT_eff: 02353 err = rsbac_list_lol_subadd_ttl(device_p->eff_handles[eff_fd_hash(file.inode)], 02354 ttl, &file.inode, &cap_range, NULL); 02355 break; 02356 case ACT_fs: 02357 err = rsbac_list_lol_subadd_ttl(device_p->fs_handles[fs_fd_hash(file.inode)], 02358 ttl, &file.inode, &cap_range, NULL); 02359 break; 02360 #endif 02361 default: 02362 err = -RSBAC_EINVALIDTARGET; 02363 } 02364 rsbac_read_unlock(&device_list_head.lock, &dflags); 02365 return(err); 02366 } 02367 02368 /* rsbac_auth_remove_from_capset */ 02369 /* Remove a set member from a sublist. Set behaviour: Returns no error, if */ 02370 /* member is not in list. */ 02371 02372 int rsbac_auth_remove_from_p_capset(rsbac_pid_t pid, 02373 enum rsbac_auth_cap_type_t cap_type, 02374 struct rsbac_auth_cap_range_t cap_range) 02375 { 02376 if (!rsbac_is_initialized()) 02377 { 02378 printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): RSBAC not initialized\n"); 02379 return(-RSBAC_ENOTINITIALIZED); 02380 } 02381 if (in_interrupt()) 02382 { 02383 printk(KERN_WARNING "rsbac_auth_remove_from_p_capset(): called from interrupt!\n"); 02384 } 02385 if(cap_range.first > cap_range.last) 02386 return(-RSBAC_EINVALIDVALUE); 02387 switch(cap_type) 02388 { 02389 case ACT_real: 02390 return rsbac_list_lol_subremove(process_handle, &pid, &cap_range); 02391 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02392 case ACT_eff: 02393 return rsbac_list_lol_subremove(process_eff_handle, &pid, &cap_range); 02394 case ACT_fs: 02395 return rsbac_list_lol_subremove(process_fs_handle, &pid, &cap_range); 02396 #endif 02397 default: 02398 return -RSBAC_EINVALIDTARGET; 02399 } 02400 } 02401 02402 int rsbac_auth_remove_from_f_capset(rsbac_auth_file_t file, 02403 enum rsbac_auth_cap_type_t cap_type, 02404 struct rsbac_auth_cap_range_t cap_range) 02405 { 02406 int err=0; 02407 u_long dflags; 02408 struct rsbac_auth_device_list_item_t * device_p; 02409 02410 if (!rsbac_is_initialized()) 02411 { 02412 printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): RSBAC not initialized\n"); 02413 return(-RSBAC_ENOTINITIALIZED); 02414 } 02415 if (in_interrupt()) 02416 { 02417 printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): called from interrupt!\n"); 02418 } 02419 if(cap_range.first > cap_range.last) 02420 return(-RSBAC_EINVALIDVALUE); 02421 02422 /* protect device list */ 02423 rsbac_read_lock(&device_list_head.lock, &dflags); 02424 device_p = lookup_device(file.device); 02425 if(!device_p) 02426 { 02427 /* trigger rsbac_mount() */ 02428 rsbac_read_unlock(&device_list_head.lock, &dflags); 02429 rsbac_get_super_block(file.device); 02430 /* retry */ 02431 rsbac_read_lock(&device_list_head.lock, &dflags); 02432 device_p = lookup_device(file.device); 02433 if(!device_p) 02434 { 02435 #ifdef CONFIG_RSBAC_RMSG 02436 rsbac_printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): invalid device %02u:%02u!\n", 02437 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02438 #endif 02439 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02440 if (!rsbac_nosyslog) 02441 #endif 02442 printk(KERN_WARNING "rsbac_auth_remove_from_f_capset(): invalid device %02u:%02u!\n", 02443 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02444 rsbac_read_unlock(&device_list_head.lock, &dflags); 02445 return(-RSBAC_EINVALIDDEV); 02446 } 02447 } 02448 switch(cap_type) 02449 { 02450 case ACT_real: 02451 err = rsbac_list_lol_subremove(device_p->handles[fd_hash(file.inode)], &file.inode, &cap_range); 02452 break; 02453 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02454 case ACT_eff: 02455 err = rsbac_list_lol_subremove(device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode, &cap_range); 02456 break; 02457 case ACT_fs: 02458 err = rsbac_list_lol_subremove(device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode, &cap_range); 02459 break; 02460 #endif 02461 default: 02462 err = -RSBAC_EINVALIDTARGET; 02463 } 02464 rsbac_read_unlock(&device_list_head.lock, &dflags); 02465 return(err); 02466 } 02467 02468 /* rsbac_auth_clear_capset */ 02469 /* Remove all set members from a sublist. Set behaviour: Returns no error, */ 02470 /* if list is empty. */ 02471 02472 int rsbac_auth_clear_p_capset(rsbac_pid_t pid, 02473 enum rsbac_auth_cap_type_t cap_type) 02474 { 02475 if (!rsbac_is_initialized()) 02476 { 02477 printk(KERN_WARNING "rsbac_auth_clear_p_capset(): RSBAC not initialized\n"); 02478 return(-RSBAC_ENOTINITIALIZED); 02479 } 02480 if (in_interrupt()) 02481 { 02482 printk(KERN_WARNING "rsbac_auth_clear_p_capset(): called from interrupt!\n"); 02483 } 02484 switch(cap_type) 02485 { 02486 case ACT_real: 02487 return rsbac_list_lol_remove(process_handle, &pid); 02488 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02489 case ACT_eff: 02490 return rsbac_list_lol_remove(process_handle, &pid); 02491 case ACT_fs: 02492 return rsbac_list_lol_remove(process_handle, &pid); 02493 #endif 02494 default: 02495 return -RSBAC_EINVALIDTARGET; 02496 } 02497 } 02498 02499 int rsbac_auth_clear_f_capset(rsbac_auth_file_t file, 02500 enum rsbac_auth_cap_type_t cap_type) 02501 { 02502 int err=0; 02503 u_long dflags; 02504 struct rsbac_auth_device_list_item_t * device_p; 02505 02506 if (!rsbac_is_initialized()) 02507 { 02508 printk(KERN_WARNING "rsbac_auth_clear_f_capset(): RSBAC not initialized\n"); 02509 return(-RSBAC_ENOTINITIALIZED); 02510 } 02511 if (in_interrupt()) 02512 { 02513 printk(KERN_WARNING "rsbac_auth_clear_f_capset(): called from interrupt!\n"); 02514 } 02515 /* protect device list */ 02516 rsbac_read_lock(&device_list_head.lock, &dflags); 02517 device_p = lookup_device(file.device); 02518 if(!device_p) 02519 { 02520 /* trigger rsbac_mount() */ 02521 rsbac_read_unlock(&device_list_head.lock, &dflags); 02522 rsbac_get_super_block(file.device); 02523 /* retry */ 02524 rsbac_read_lock(&device_list_head.lock, &dflags); 02525 device_p = lookup_device(file.device); 02526 if(!device_p) 02527 { 02528 #ifdef CONFIG_RSBAC_RMSG 02529 rsbac_printk(KERN_WARNING "rsbac_auth_clear_f_capset(): invalid device %02u:%02u!\n", 02530 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02531 #endif 02532 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02533 if (!rsbac_nosyslog) 02534 #endif 02535 printk(KERN_WARNING "rsbac_auth_clear_f_capset(): invalid device %02u:%02u!\n", 02536 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02537 rsbac_read_unlock(&device_list_head.lock, &dflags); 02538 return(-RSBAC_EINVALIDDEV); 02539 } 02540 } 02541 switch(cap_type) 02542 { 02543 case ACT_real: 02544 err = rsbac_list_lol_remove(device_p->handles[fd_hash(file.inode)], &file.inode); 02545 break; 02546 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02547 case ACT_eff: 02548 err = rsbac_list_lol_remove(device_p->eff_handles[eff_fd_hash(file.inode)], &file.inode); 02549 break; 02550 case ACT_fs: 02551 err = rsbac_list_lol_remove(device_p->fs_handles[fs_fd_hash(file.inode)], &file.inode); 02552 break; 02553 #endif 02554 default: 02555 err = -RSBAC_EINVALIDTARGET; 02556 } 02557 rsbac_read_unlock(&device_list_head.lock, &dflags); 02558 return(err); 02559 } 02560 02561 /* rsbac_auth_capset_member */ 02562 /* Return truth value, whether member is in set */ 02563 02564 boolean rsbac_auth_p_capset_member(rsbac_pid_t pid, 02565 enum rsbac_auth_cap_type_t cap_type, 02566 rsbac_uid_t member) 02567 { 02568 boolean result; 02569 02570 if (!rsbac_is_initialized()) 02571 { 02572 printk(KERN_WARNING "rsbac_auth_p_capset_member(): RSBAC not initialized\n"); 02573 return FALSE; 02574 } 02575 if (in_interrupt()) 02576 { 02577 printk(KERN_WARNING "rsbac_auth_p_capset_member(): called from interrupt!\n"); 02578 } 02579 switch(cap_type) 02580 { 02581 case ACT_real: 02582 result = rsbac_list_lol_subexist_compare(process_handle, &pid, &member, single_cap_compare); 02583 02584 #if defined(CONFIG_RSBAC_AUTH_LEARN) 02585 if( !result 02586 && (member <= RSBAC_AUTH_MAX_RANGE_UID) 02587 ) 02588 { 02589 union rsbac_target_id_t tid; 02590 union rsbac_attribute_value_t attr_val; 02591 boolean learn; 02592 02593 learn = rsbac_auth_learn; 02594 if(!learn) 02595 { 02596 tid.process = pid; 02597 /* check learn on process */ 02598 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE)) 02599 learn = attr_val.auth_learn; 02600 } 02601 if(learn) 02602 { 02603 struct rsbac_auth_cap_range_t range; 02604 02605 #ifdef CONFIG_RSBAC_RMSG 02606 rsbac_printk(KERN_INFO 02607 "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to process %u (%.15s)!\n", 02608 member, 02609 pid, 02610 current->comm); 02611 #endif 02612 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02613 if (!rsbac_nosyslog) 02614 #endif 02615 printk(KERN_INFO 02616 "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to process %u (%.15s)!\n", 02617 member, 02618 pid, 02619 current->comm); 02620 range.first = member; 02621 range.last = member; 02622 rsbac_list_lol_subadd(process_handle, &pid, &range, NULL); 02623 02624 tid.process = pid; 02625 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE)) 02626 { 02627 struct rsbac_auth_device_list_item_t * device_p; 02628 union rsbac_attribute_value_t attr_val2; 02629 u_long dflags; 02630 02631 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)) 02632 { 02633 if(range.first == attr_val2.auth_start_uid) 02634 { 02635 range.first = RSBAC_AUTH_OWNER_F_CAP; 02636 range.last = range.first; 02637 } 02638 } 02639 #ifdef CONFIG_RSBAC_RMSG 02640 rsbac_printk(KERN_INFO 02641 "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to file %u on device %02u:%02u!\n", 02642 range.first, 02643 attr_val.auth_program_file.inode, 02644 MAJOR(attr_val.auth_program_file.device), 02645 MINOR(attr_val.auth_program_file.device)); 02646 #endif 02647 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02648 if (!rsbac_nosyslog) 02649 #endif 02650 printk(KERN_INFO 02651 "rsbac_auth_p_capset_member(): adding AUTH capability for uid %u to file %u on device %02u:%02u!\n", 02652 range.first, 02653 attr_val.auth_program_file.inode, 02654 MAJOR(attr_val.auth_program_file.device), 02655 MINOR(attr_val.auth_program_file.device)); 02656 rsbac_read_lock(&device_list_head.lock, &dflags); 02657 device_p = lookup_device(attr_val.auth_program_file.device); 02658 if(device_p) 02659 { 02660 rsbac_list_lol_subadd(device_p->handles[fd_hash(attr_val.auth_program_file.inode)], 02661 &attr_val.auth_program_file.inode, &range, NULL); 02662 } 02663 else 02664 { 02665 #ifdef CONFIG_RSBAC_RMSG 02666 rsbac_printk(KERN_INFO 02667 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02668 MAJOR(attr_val.auth_program_file.device), 02669 MINOR(attr_val.auth_program_file.device)); 02670 #endif 02671 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02672 if (!rsbac_nosyslog) 02673 #endif 02674 printk(KERN_INFO 02675 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02676 MAJOR(attr_val.auth_program_file.device), 02677 MINOR(attr_val.auth_program_file.device)); 02678 } 02679 rsbac_read_unlock(&device_list_head.lock, &dflags); 02680 } 02681 result = TRUE; 02682 } 02683 } 02684 #endif 02685 break; 02686 02687 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02688 case ACT_eff: 02689 result = rsbac_list_lol_subexist_compare(process_eff_handle, &pid, &member, single_cap_compare); 02690 02691 #if defined(CONFIG_RSBAC_AUTH_LEARN) 02692 if( !result 02693 && (member <= RSBAC_AUTH_MAX_RANGE_UID) 02694 ) 02695 { 02696 union rsbac_target_id_t tid; 02697 union rsbac_attribute_value_t attr_val; 02698 boolean learn; 02699 02700 learn = rsbac_auth_learn; 02701 if(!learn) 02702 { 02703 tid.process = pid; 02704 /* check learn on process */ 02705 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE)) 02706 learn = attr_val.auth_learn; 02707 } 02708 if(learn) 02709 { 02710 struct rsbac_auth_cap_range_t range; 02711 02712 #ifdef CONFIG_RSBAC_RMSG 02713 rsbac_printk(KERN_INFO 02714 "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to process %u (%.15s)!\n", 02715 member, 02716 pid, 02717 current->comm); 02718 #endif 02719 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02720 if (!rsbac_nosyslog) 02721 #endif 02722 printk(KERN_INFO 02723 "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to process %u (%.15s)!\n", 02724 member, 02725 pid, 02726 current->comm); 02727 range.first = member; 02728 range.last = member; 02729 rsbac_list_lol_subadd(process_eff_handle, &pid, &range, NULL); 02730 02731 tid.process = pid; 02732 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE)) 02733 { 02734 struct rsbac_auth_device_list_item_t * device_p; 02735 union rsbac_attribute_value_t attr_val2; 02736 u_long dflags; 02737 02738 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)) 02739 { 02740 if(range.first == attr_val2.auth_start_uid) 02741 { 02742 range.first = RSBAC_AUTH_OWNER_F_CAP; 02743 range.last = range.first; 02744 } 02745 } 02746 #ifdef CONFIG_RSBAC_RMSG 02747 rsbac_printk(KERN_INFO 02748 "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to file %u on device %02u:%02u!\n", 02749 range.first, 02750 attr_val.auth_program_file.inode, 02751 MAJOR(attr_val.auth_program_file.device), 02752 MINOR(attr_val.auth_program_file.device)); 02753 #endif 02754 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02755 if (!rsbac_nosyslog) 02756 #endif 02757 printk(KERN_INFO 02758 "rsbac_auth_p_capset_member(): adding AUTH eff capability for uid %u to file %u on device %02u:%02u!\n", 02759 range.first, 02760 attr_val.auth_program_file.inode, 02761 MAJOR(attr_val.auth_program_file.device), 02762 MINOR(attr_val.auth_program_file.device)); 02763 rsbac_read_lock(&device_list_head.lock, &dflags); 02764 device_p = lookup_device(attr_val.auth_program_file.device); 02765 if(device_p) 02766 { 02767 rsbac_list_lol_subadd(device_p->eff_handles[eff_fd_hash(attr_val.auth_program_file.inode)], 02768 &attr_val.auth_program_file.inode, &range, NULL); 02769 } 02770 else 02771 { 02772 #ifdef CONFIG_RSBAC_RMSG 02773 rsbac_printk(KERN_INFO 02774 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02775 MAJOR(attr_val.auth_program_file.device), 02776 MINOR(attr_val.auth_program_file.device)); 02777 #endif 02778 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02779 if (!rsbac_nosyslog) 02780 #endif 02781 printk(KERN_INFO 02782 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02783 MAJOR(attr_val.auth_program_file.device), 02784 MINOR(attr_val.auth_program_file.device)); 02785 } 02786 rsbac_read_unlock(&device_list_head.lock, &dflags); 02787 } 02788 result = TRUE; 02789 } 02790 } 02791 #endif 02792 break; 02793 02794 case ACT_fs: 02795 result = rsbac_list_lol_subexist_compare(process_fs_handle, &pid, &member, single_cap_compare); 02796 02797 #if defined(CONFIG_RSBAC_AUTH_LEARN) 02798 if( !result 02799 && (member <= RSBAC_AUTH_MAX_RANGE_UID) 02800 ) 02801 { 02802 union rsbac_target_id_t tid; 02803 union rsbac_attribute_value_t attr_val; 02804 boolean learn; 02805 02806 learn = rsbac_auth_learn; 02807 if(!learn) 02808 { 02809 tid.process = pid; 02810 /* check learn on process */ 02811 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_learn, &attr_val, FALSE)) 02812 learn = attr_val.auth_learn; 02813 } 02814 if(learn) 02815 { 02816 struct rsbac_auth_cap_range_t range; 02817 02818 #ifdef CONFIG_RSBAC_RMSG 02819 rsbac_printk(KERN_INFO 02820 "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to process %u (%.15s)!\n", 02821 member, 02822 pid, 02823 current->comm); 02824 #endif 02825 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02826 if (!rsbac_nosyslog) 02827 #endif 02828 printk(KERN_INFO 02829 "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to process %u (%.15s)!\n", 02830 member, 02831 pid, 02832 current->comm); 02833 range.first = member; 02834 range.last = member; 02835 rsbac_list_lol_subadd(process_fs_handle, &pid, &range, NULL); 02836 02837 tid.process = pid; 02838 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_program_file, &attr_val, FALSE)) 02839 { 02840 struct rsbac_auth_device_list_item_t * device_p; 02841 union rsbac_attribute_value_t attr_val2; 02842 u_long dflags; 02843 02844 if(!rsbac_get_attr(AUTH, T_PROCESS, tid, A_auth_start_uid, &attr_val2, FALSE)) 02845 { 02846 if(range.first == attr_val2.auth_start_uid) 02847 { 02848 range.first = RSBAC_AUTH_OWNER_F_CAP; 02849 range.last = range.first; 02850 } 02851 } 02852 #ifdef CONFIG_RSBAC_RMSG 02853 rsbac_printk(KERN_INFO 02854 "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to file %u on device %02u:%02u!\n", 02855 range.first, 02856 attr_val.auth_program_file.inode, 02857 MAJOR(attr_val.auth_program_file.device), 02858 MINOR(attr_val.auth_program_file.device)); 02859 #endif 02860 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02861 if (!rsbac_nosyslog) 02862 #endif 02863 printk(KERN_INFO 02864 "rsbac_auth_p_capset_member(): adding AUTH fs capability for uid %u to file %u on device %02u:%02u!\n", 02865 range.first, 02866 attr_val.auth_program_file.inode, 02867 MAJOR(attr_val.auth_program_file.device), 02868 MINOR(attr_val.auth_program_file.device)); 02869 rsbac_read_lock(&device_list_head.lock, &dflags); 02870 device_p = lookup_device(attr_val.auth_program_file.device); 02871 if(device_p) 02872 { 02873 rsbac_list_lol_subadd(device_p->fs_handles[fs_fd_hash(attr_val.auth_program_file.inode)], 02874 &attr_val.auth_program_file.inode, &range, NULL); 02875 } 02876 else 02877 { 02878 #ifdef CONFIG_RSBAC_RMSG 02879 rsbac_printk(KERN_INFO 02880 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02881 MAJOR(attr_val.auth_program_file.device), 02882 MINOR(attr_val.auth_program_file.device)); 02883 #endif 02884 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02885 if (!rsbac_nosyslog) 02886 #endif 02887 printk(KERN_INFO 02888 "rsbac_auth_p_capset_member(): unknown device %02u:%02u!\n", 02889 MAJOR(attr_val.auth_program_file.device), 02890 MINOR(attr_val.auth_program_file.device)); 02891 } 02892 rsbac_read_unlock(&device_list_head.lock, &dflags); 02893 } 02894 result = TRUE; 02895 } 02896 } 02897 #endif 02898 break; 02899 #endif 02900 default: 02901 return FALSE; 02902 } 02903 return result; 02904 } 02905 02906 /* rsbac_auth_remove_capset */ 02907 /* Remove a full set. For cleanup, if object is deleted. */ 02908 /* To empty an existing set use rsbac_auth_clear_capset. */ 02909 02910 int rsbac_auth_remove_p_capsets(rsbac_pid_t pid) 02911 { 02912 int err; 02913 02914 err = rsbac_auth_clear_p_capset(pid, ACT_real); 02915 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02916 err = rsbac_auth_clear_p_capset(pid, ACT_eff); 02917 err = rsbac_auth_clear_p_capset(pid, ACT_fs); 02918 #endif 02919 return err; 02920 } 02921 02922 int rsbac_auth_remove_f_capsets(rsbac_auth_file_t file) 02923 { 02924 int err; 02925 02926 err = rsbac_auth_clear_f_capset(file, ACT_real); 02927 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 02928 if(!err) 02929 err = rsbac_auth_clear_f_capset(file, ACT_eff); 02930 if(!err) 02931 err = rsbac_auth_clear_f_capset(file, ACT_fs); 02932 #endif 02933 return err; 02934 } 02935 02936 int rsbac_auth_copy_fp_capset(rsbac_auth_file_t file, 02937 rsbac_pid_t p_cap_set_id) 02938 { 02939 u_long dflags; 02940 struct rsbac_auth_device_list_item_t * device_p; 02941 int err=0; 02942 02943 if (!rsbac_is_initialized) 02944 { 02945 printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): RSBAC not initialized\n"); 02946 return(-RSBAC_ENOTINITIALIZED); 02947 } 02948 if (in_interrupt()) 02949 { 02950 printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): called from interrupt!\n"); 02951 } 02952 /* 02953 #ifdef CONFIG_RSBAC_DEBUG 02954 if (rsbac_debug_ds_auth) 02955 printk(KERN_DEBUG 02956 "rsbac_auth_copy_fp_capset(): Copying file cap set data to process cap set\n"); 02957 #endif 02958 */ 02959 /* protect device list */ 02960 rsbac_read_lock(&device_list_head.lock, &dflags); 02961 device_p = lookup_device(file.device); 02962 if(!device_p) 02963 { 02964 /* trigger rsbac_mount() */ 02965 rsbac_read_unlock(&device_list_head.lock, &dflags); 02966 rsbac_get_super_block(file.device); 02967 /* retry */ 02968 rsbac_read_lock(&device_list_head.lock, &dflags); 02969 device_p = lookup_device(file.device); 02970 if(!device_p) 02971 { 02972 #ifdef CONFIG_RSBAC_RMSG 02973 rsbac_printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): invalid device %02u:%02u!\n", 02974 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02975 #endif 02976 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 02977 if (!rsbac_nosyslog) 02978 #endif 02979 printk(KERN_WARNING "rsbac_auth_copy_fp_capset(): invalid device %02u:%02u!\n", 02980 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 02981 rsbac_read_unlock(&device_list_head.lock, &dflags); 02982 return(-RSBAC_EINVALIDDEV); 02983 } 02984 } 02985 /* call the copy function */ 02986 err = copy_fp_cap_set_item(device_p,file,p_cap_set_id); 02987 rsbac_read_unlock(&device_list_head.lock, &dflags); 02988 return(err); 02989 } 02990 02991 int rsbac_auth_copy_pp_capset(rsbac_pid_t old_p_set_id, 02992 rsbac_pid_t new_p_set_id) 02993 { 02994 if (!rsbac_is_initialized) 02995 { 02996 printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): RSBAC not initialized\n"); 02997 return(-RSBAC_ENOTINITIALIZED); 02998 } 02999 if (in_interrupt()) 03000 { 03001 printk(KERN_WARNING "rsbac_auth_copy_pp_capset(): called from interrupt!\n"); 03002 } 03003 /* 03004 #ifdef CONFIG_RSBAC_DEBUG 03005 if (rsbac_debug_ds_auth) 03006 printk(KERN_DEBUG 03007 "rsbac_auth_copy_pp_capset(): Copying process cap set data to process cap set\n"); 03008 #endif 03009 */ 03010 /* call the copy function */ 03011 return copy_pp_cap_set_item(old_p_set_id,new_p_set_id); 03012 } 03013 03014 int rsbac_auth_get_f_caplist(rsbac_auth_file_t file, 03015 enum rsbac_auth_cap_type_t cap_type, 03016 struct rsbac_auth_cap_range_t **caplist_p, 03017 rsbac_time_t **ttllist_p) 03018 { 03019 u_long dflags; 03020 struct rsbac_auth_device_list_item_t * device_p; 03021 long count; 03022 03023 if (!rsbac_is_initialized) 03024 { 03025 printk(KERN_WARNING "rsbac_auth_get_f_caplist(): RSBAC not initialized\n"); 03026 return(-RSBAC_ENOTINITIALIZED); 03027 } 03028 if (in_interrupt()) 03029 { 03030 printk(KERN_WARNING "rsbac_auth_get_f_caplist(): called from interrupt!\n"); 03031 } 03032 /* 03033 #ifdef CONFIG_RSBAC_DEBUG 03034 if (rsbac_debug_ds_auth) 03035 printk(KERN_DEBUG 03036 "rsbac_auth_get_f_caplist(): Getting file/dir cap set list\n"); 03037 #endif 03038 */ 03039 /* protect device list */ 03040 rsbac_read_lock(&device_list_head.lock, &dflags); 03041 device_p = lookup_device(file.device); 03042 if(!device_p) 03043 { 03044 /* trigger rsbac_mount() */ 03045 rsbac_read_unlock(&device_list_head.lock, &dflags); 03046 rsbac_get_super_block(file.device); 03047 /* retry */ 03048 rsbac_read_lock(&device_list_head.lock, &dflags); 03049 device_p = lookup_device(file.device); 03050 if(!device_p) 03051 { 03052 #ifdef CONFIG_RSBAC_RMSG 03053 rsbac_printk(KERN_WARNING "rsbac_auth_get_f_caplist(): invalid device %02u:%02u!\n", 03054 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 03055 #endif 03056 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 03057 if (!rsbac_nosyslog) 03058 #endif 03059 printk(KERN_WARNING "rsbac_auth_get_f_caplist(): invalid device %02u:%02u!\n", 03060 RSBAC_MAJOR(file.device),RSBAC_MINOR(file.device)); 03061 rsbac_read_unlock(&device_list_head.lock, &dflags); 03062 return(-RSBAC_EINVALIDDEV); 03063 } 03064 } 03065 switch(cap_type) 03066 { 03067 case ACT_real: 03068 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handles[fd_hash(file.inode)], 03069 &file.inode, 03070 (void **) caplist_p, 03071 ttllist_p); 03072 break; 03073 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 03074 case ACT_eff: 03075 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->eff_handles[eff_fd_hash(file.inode)], 03076 &file.inode, 03077 (void **) caplist_p, 03078 ttllist_p); 03079 break; 03080 case ACT_fs: 03081 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->fs_handles[fs_fd_hash(file.inode)], 03082 &file.inode, 03083 (void **) caplist_p, 03084 ttllist_p); 03085 break; 03086 #endif 03087 default: 03088 count = -RSBAC_EINVALIDTARGET; 03089 } 03090 rsbac_read_unlock(&device_list_head.lock, &dflags); 03091 return(count); 03092 } 03093 03094 int rsbac_auth_get_p_caplist(rsbac_pid_t pid, 03095 enum rsbac_auth_cap_type_t cap_type, 03096 struct rsbac_auth_cap_range_t **caplist_p, 03097 rsbac_time_t **ttllist_p) 03098 { 03099 long count; 03100 03101 if (!rsbac_is_initialized) 03102 { 03103 printk(KERN_WARNING "rsbac_auth_get_p_caplist(): RSBAC not initialized\n"); 03104 return(-RSBAC_ENOTINITIALIZED); 03105 } 03106 if (in_interrupt()) 03107 { 03108 printk(KERN_WARNING "rsbac_auth_get_p_caplist(): called from interrupt!\n"); 03109 } 03110 /* 03111 #ifdef CONFIG_RSBAC_DEBUG 03112 if (rsbac_debug_ds_auth) 03113 printk(KERN_DEBUG 03114 "rsbac_auth_get_p_caplist(): Getting process cap set list\n"); 03115 #endif 03116 */ 03117 switch(cap_type) 03118 { 03119 case ACT_real: 03120 count = rsbac_list_lol_get_all_subdesc_ttl(process_handle, 03121 &pid, 03122 (void **) caplist_p, 03123 ttllist_p); 03124 break; 03125 #ifdef CONFIG_RSBAC_AUTH_DAC_OWNER 03126 case ACT_eff: 03127 count = rsbac_list_lol_get_all_subdesc_ttl(process_eff_handle, 03128 &pid, 03129 (void **) caplist_p, 03130 ttllist_p); 03131 break; 03132 case ACT_fs: 03133 count = rsbac_list_lol_get_all_subdesc_ttl(process_fs_handle, 03134 &pid, 03135 (void **) caplist_p, 03136 ttllist_p); 03137 break; 03138 #endif 03139 default: 03140 count = -RSBAC_EINVALIDTARGET; 03141 } 03142 return(count); 03143 } 03144 03145 /* end of auth_data_structures.c */

Generated on Tue Aug 31 10:05:25 2004 for RSBAC by doxygen 1.3.8