/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/adf/reg/reg_main.c

Go to the documentation of this file.
00001 /*************************************************** */ 00002 /* Rule Set Based Access Control */ 00003 /* Implementation of the Access Control Decision */ 00004 /* Facility (ADF) - REG / Decision Module Registration */ 00005 /* File: rsbac/adf/reg/main.c */ 00006 /* */ 00007 /* Author and (c) 1999-2004: Amon Ott <ao@rsbac.org> */ 00008 /* */ 00009 /* Last modified: 11/Mar/2004 */ 00010 /*************************************************** */ 00011 00012 #include <linux/types.h> 00013 #include <linux/string.h> 00014 #include <linux/init.h> 00015 #include <linux/kernel.h> 00016 #include <linux/config.h> 00017 #include <linux/module.h> 00018 #include <asm/uaccess.h> 00019 #include <linux/smp_lock.h> 00020 #include <rsbac/types.h> 00021 #include <rsbac/reg.h> 00022 #include <rsbac/reg_main.h> 00023 #include <rsbac/aci.h> 00024 #include <rsbac/aci_data_structures.h> 00025 #include <rsbac/adf.h> 00026 #include <rsbac/adf_main.h> 00027 #include <rsbac/error.h> 00028 #include <rsbac/helpers.h> 00029 #include <rsbac/getname.h> 00030 #include <rsbac/proc_fs.h> 00031 #include <rsbac/rkmem.h> 00032 00033 /************************************************* */ 00034 /* Global Variables */ 00035 /************************************************* */ 00036 00037 static struct rsbac_reg_list_head_t list_head; 00038 static struct rsbac_reg_sc_list_head_t sc_list_head; 00039 00040 /************************************************* */ 00041 /* Internal functions */ 00042 /************************************************* */ 00043 00044 /* lookup_item() */ 00045 static struct rsbac_reg_list_item_t * lookup_item(rsbac_reg_handle_t handle) 00046 { 00047 struct rsbac_reg_list_item_t * curr = list_head.curr; 00048 00049 /* is the current item the one we look for? yes -> return, else search */ 00050 if (curr && (curr->entry.handle == handle)) 00051 return (curr); 00052 00053 curr = list_head.head; 00054 while (curr && (curr->entry.handle != handle)) 00055 curr = curr->next; 00056 if (curr) 00057 list_head.curr=curr; 00058 return (curr); 00059 }; 00060 00061 /* lookup_sc_item_reg() */ 00062 static struct rsbac_reg_sc_list_item_t * lookup_sc_item_reg(rsbac_reg_handle_t handle) 00063 { 00064 struct rsbac_reg_sc_list_item_t * curr = sc_list_head.curr; 00065 00066 /* is the current item the one we look for? yes -> return, else search */ 00067 if (curr && (curr->entry.registration_handle == handle)) 00068 return (curr); 00069 00070 curr = sc_list_head.head; 00071 while (curr && (curr->entry.registration_handle != handle)) 00072 curr = curr->next; 00073 if (curr) 00074 sc_list_head.curr=curr; 00075 return (curr); 00076 }; 00077 00078 /* lookup_sc_item_dis() */ 00079 static struct rsbac_reg_sc_list_item_t * lookup_sc_item_dis(rsbac_reg_handle_t handle) 00080 { 00081 struct rsbac_reg_sc_list_item_t * curr = sc_list_head.curr; 00082 00083 /* is the current item the one we look for? yes -> return, else search */ 00084 if (curr && (curr->entry.dispatcher_handle == handle)) 00085 return (curr); 00086 00087 curr = sc_list_head.head; 00088 while (curr && (curr->entry.dispatcher_handle != handle)) 00089 curr = curr->next; 00090 if (curr) 00091 sc_list_head.curr=curr; 00092 return (curr); 00093 }; 00094 00095 static struct rsbac_reg_list_item_t* 00096 add_item(struct rsbac_reg_entry_t entry) 00097 { 00098 struct rsbac_reg_list_item_t * new_item_p = NULL; 00099 00100 if ( !(new_item_p = (struct rsbac_reg_list_item_t *) 00101 rsbac_kmalloc(sizeof(*new_item_p))) ) 00102 return(NULL); 00103 new_item_p->entry.handle = entry.handle; 00104 strncpy(new_item_p->entry.name, entry.name, RSBAC_REG_NAME_LEN); 00105 new_item_p->entry.name[RSBAC_REG_NAME_LEN] = 0; 00106 new_item_p->entry.request_func = entry.request_func; 00107 new_item_p->entry.set_attr_func = entry.set_attr_func; 00108 new_item_p->entry.need_overwrite_func = entry.need_overwrite_func; 00109 new_item_p->entry.write_func = entry.write_func; 00110 new_item_p->entry.mount_func = entry.mount_func; 00111 new_item_p->entry.umount_func = entry.umount_func; 00112 new_item_p->entry.check_func = entry.check_func; 00113 new_item_p->entry.switch_on = entry.switch_on; 00114 00115 if (!list_head.head) 00116 { 00117 list_head.head=new_item_p; 00118 list_head.tail=new_item_p; 00119 list_head.curr=new_item_p; 00120 list_head.count = 1; 00121 new_item_p->prev=NULL; 00122 new_item_p->next=NULL; 00123 } 00124 else 00125 { 00126 new_item_p->prev=list_head.tail; 00127 new_item_p->next=NULL; 00128 list_head.tail->next=new_item_p; 00129 list_head.tail=new_item_p; 00130 list_head.curr=new_item_p; 00131 list_head.count++; 00132 }; 00133 return(new_item_p); 00134 }; 00135 00136 static struct rsbac_reg_sc_list_item_t* 00137 add_sc_item(struct rsbac_reg_syscall_entry_t entry) 00138 { 00139 struct rsbac_reg_sc_list_item_t * new_item_p = NULL; 00140 00141 if ( !(new_item_p = (struct rsbac_reg_sc_list_item_t *) 00142 rsbac_kmalloc(sizeof(*new_item_p))) ) 00143 return(NULL); 00144 new_item_p->entry.registration_handle = entry.registration_handle; 00145 new_item_p->entry.dispatcher_handle = entry.dispatcher_handle; 00146 strncpy(new_item_p->entry.name, entry.name, RSBAC_REG_NAME_LEN); 00147 new_item_p->entry.name[RSBAC_REG_NAME_LEN] = 0; 00148 new_item_p->entry.syscall_func = entry.syscall_func; 00149 00150 if (!sc_list_head.head) 00151 { 00152 sc_list_head.head=new_item_p; 00153 sc_list_head.tail=new_item_p; 00154 sc_list_head.curr=new_item_p; 00155 sc_list_head.count = 1; 00156 new_item_p->prev=NULL; 00157 new_item_p->next=NULL; 00158 } 00159 else 00160 { 00161 new_item_p->prev=sc_list_head.tail; 00162 new_item_p->next=NULL; 00163 sc_list_head.tail->next=new_item_p; 00164 sc_list_head.tail=new_item_p; 00165 sc_list_head.curr=new_item_p; 00166 sc_list_head.count++; 00167 }; 00168 return(new_item_p); 00169 }; 00170 00171 static void remove_item(rsbac_reg_handle_t handle) 00172 { 00173 struct rsbac_reg_list_item_t * item_p; 00174 00175 /* first we must locate the item. */ 00176 if ( (item_p = lookup_item(handle)) ) 00177 { /* ok, item was found */ 00178 if ( (list_head.head == item_p) ) 00179 { /* item is head */ 00180 if ( (list_head.tail == item_p) ) 00181 { /* item is head and tail = only item -> list will be empty*/ 00182 list_head.head = NULL; 00183 list_head.tail = NULL; 00184 } 00185 else 00186 { /* item is head, but not tail -> next item becomes head */ 00187 item_p->next->prev = NULL; 00188 list_head.head = item_p->next; 00189 }; 00190 } 00191 else 00192 { /* item is not head */ 00193 if ( (list_head.tail == item_p) ) 00194 { /*item is not head, but tail -> previous item becomes tail*/ 00195 item_p->prev->next = NULL; 00196 list_head.tail = item_p->prev; 00197 } 00198 else 00199 { /* item is neither head nor tail -> item is cut out */ 00200 item_p->prev->next = item_p->next; 00201 item_p->next->prev = item_p->prev; 00202 }; 00203 }; 00204 00205 /* curr is no longer valid -> reset */ 00206 list_head.curr=NULL; 00207 /* adjust counter */ 00208 list_head.count--; 00209 /* now we can remove the item from memory */ 00210 rsbac_kfree(item_p); 00211 }; /* end of if: item was found */ 00212 }; /* end of remove_item() */ 00213 00214 static void remove_sc_item(rsbac_reg_handle_t handle) 00215 { 00216 struct rsbac_reg_sc_list_item_t * item_p; 00217 00218 /* first we must locate the item. */ 00219 if ( (item_p = lookup_sc_item_reg(handle)) ) 00220 { /* ok, item was found */ 00221 if ( (sc_list_head.head == item_p) ) 00222 { /* item is head */ 00223 if ( (sc_list_head.tail == item_p) ) 00224 { /* item is head and tail = only item -> sc_list will be empty*/ 00225 sc_list_head.head = NULL; 00226 sc_list_head.tail = NULL; 00227 } 00228 else 00229 { /* item is head, but not tail -> next item becomes head */ 00230 item_p->next->prev = NULL; 00231 sc_list_head.head = item_p->next; 00232 }; 00233 } 00234 else 00235 { /* item is not head */ 00236 if ( (sc_list_head.tail == item_p) ) 00237 { /*item is not head, but tail -> previous item becomes tail*/ 00238 item_p->prev->next = NULL; 00239 sc_list_head.tail = item_p->prev; 00240 } 00241 else 00242 { /* item is neither head nor tail -> item is cut out */ 00243 item_p->prev->next = item_p->next; 00244 item_p->next->prev = item_p->prev; 00245 }; 00246 }; 00247 00248 /* curr is no longer valid -> reset */ 00249 sc_list_head.curr=NULL; 00250 /* adjust counter */ 00251 sc_list_head.count--; 00252 /* now we can remove the item from memory */ 00253 rsbac_kfree(item_p); 00254 }; /* end of if: item was found */ 00255 }; /* end of remove_item() */ 00256 00257 00258 /************************************************* */ 00259 /* PROC support */ 00260 /************************************************* */ 00261 00262 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 00263 static int 00264 reg_modules_proc_info(char *buffer, char **start, off_t offset, int length) 00265 { 00266 int len = 0; 00267 off_t pos = 0; 00268 off_t begin = 0; 00269 00270 union rsbac_target_id_t rsbac_target_id; 00271 union rsbac_attribute_value_t rsbac_attribute_value; 00272 struct rsbac_reg_list_item_t * item_p; 00273 struct rsbac_reg_sc_list_item_t * sc_item_p; 00274 u_long flags; 00275 00276 if (!rsbac_is_initialized()) 00277 return (-ENOSYS); 00278 00279 #ifdef CONFIG_RSBAC_DEBUG 00280 if (rsbac_debug_aef) 00281 { 00282 #ifdef CONFIG_RSBAC_RMSG 00283 rsbac_printk(KERN_DEBUG "reg_modules_proc_info(): calling ADF\n"); 00284 #endif 00285 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00286 if (!rsbac_nosyslog) 00287 #endif 00288 printk(KERN_DEBUG "reg_modules_proc_info(): calling ADF\n"); 00289 } 00290 #endif 00291 rsbac_target_id.scd = ST_rsbac; 00292 rsbac_attribute_value.dummy = 0; 00293 if (!rsbac_adf_request(R_GET_STATUS_DATA, 00294 current->pid, 00295 T_SCD, 00296 rsbac_target_id, 00297 A_none, 00298 rsbac_attribute_value)) 00299 { 00300 return -EPERM; 00301 } 00302 00303 len += sprintf(buffer, "RSBAC REG registered decision modules\n-------------------------------------\n"); 00304 pos = begin + len; 00305 if (pos < offset) 00306 { 00307 len = 0; 00308 begin = pos; 00309 } 00310 if (pos > offset+length) 00311 goto out; 00312 00313 rsbac_read_lock(&list_head.lock, &flags); 00314 item_p=list_head.head; 00315 while(item_p) 00316 { 00317 if(item_p->entry.name[0] == 0) 00318 len += sprintf(buffer + len, "(no name)\n"); 00319 else 00320 len += sprintf(buffer + len, "%s\n", 00321 item_p->entry.name); 00322 pos = begin + len; 00323 if (pos < offset) 00324 { 00325 len = 0; 00326 begin = pos; 00327 } 00328 if (pos > offset+length) 00329 { 00330 rsbac_read_unlock(&list_head.lock, &flags); 00331 goto out; 00332 } 00333 item_p = item_p->next; 00334 } 00335 rsbac_read_unlock(&list_head.lock, &flags); 00336 00337 len += sprintf(buffer + len, "\n %i module entries used.\n", 00338 list_head.count); 00339 pos = begin + len; 00340 if (pos < offset) 00341 { 00342 len = 0; 00343 begin = pos; 00344 } 00345 if (pos > offset+length) 00346 goto out; 00347 00348 len += sprintf(buffer+len, "\nRSBAC REG registered system calls\n---------------------------------\n"); 00349 pos = begin + len; 00350 if (pos < offset) 00351 { 00352 len = 0; 00353 begin = pos; 00354 } 00355 if (pos > offset+length) 00356 goto out; 00357 00358 rsbac_read_lock(&sc_list_head.lock, &flags); 00359 sc_item_p=sc_list_head.head; 00360 while(sc_item_p) 00361 { 00362 if(sc_item_p->entry.name[0] == 0) 00363 len += sprintf(buffer + len, "%u: (no name)\n", 00364 sc_item_p->entry.dispatcher_handle); 00365 else 00366 len += sprintf(buffer + len, "%u: %s\n", 00367 sc_item_p->entry.dispatcher_handle, 00368 sc_item_p->entry.name); 00369 pos = begin + len; 00370 if (pos < offset) 00371 { 00372 len = 0; 00373 begin = pos; 00374 } 00375 if (pos > offset+length) 00376 { 00377 rsbac_read_unlock(&sc_list_head.lock, &flags); 00378 goto out; 00379 } 00380 sc_item_p = sc_item_p->next; 00381 } 00382 rsbac_read_unlock(&sc_list_head.lock, &flags); 00383 00384 len += sprintf(buffer + len, "\n %i syscall entries used.\n", 00385 sc_list_head.count); 00386 pos = begin + len; 00387 if (pos < offset) 00388 { 00389 len = 0; 00390 begin = pos; 00391 } 00392 if (pos > offset+length) 00393 goto out; 00394 00395 out: 00396 *start = buffer + (offset - begin); 00397 len -= (offset - begin); 00398 00399 if (len > length) 00400 len = length; 00401 return len; 00402 } 00403 #endif /* PROC */ 00404 00405 /************************************************* */ 00406 /* Externally visible functions */ 00407 /************************************************* */ 00408 00409 #ifdef CONFIG_RSBAC_INIT_DELAY 00410 void rsbac_reg_init(void) 00411 #else 00412 void __init rsbac_reg_init(void) 00413 #endif 00414 { 00415 if (rsbac_is_initialized()) 00416 { 00417 #ifdef CONFIG_RSBAC_RMSG 00418 rsbac_printk(KERN_WARNING "rsbac_reg_init(): RSBAC already initialized\n"); 00419 #endif 00420 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00421 if (!rsbac_nosyslog) 00422 #endif 00423 printk(KERN_WARNING "rsbac_reg_init(): RSBAC already initialized\n"); 00424 return; 00425 } 00426 /* init data structures */ 00427 #ifdef CONFIG_RSBAC_RMSG 00428 rsbac_printk(KERN_INFO "rsbac_reg_init(): Initializing RSBAC: REG module and syscall registration\n"); 00429 #endif 00430 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00431 if (!rsbac_nosyslog) 00432 #endif 00433 printk(KERN_INFO "rsbac_reg_init(): Initializing RSBAC: REG module and syscall registration\n"); 00434 00435 list_head.lock = RW_LOCK_UNLOCKED; 00436 list_head.head = NULL; 00437 list_head.tail = NULL; 00438 list_head.curr = NULL; 00439 list_head.count = 0; 00440 sc_list_head.lock = RW_LOCK_UNLOCKED; 00441 sc_list_head.head = NULL; 00442 sc_list_head.tail = NULL; 00443 sc_list_head.curr = NULL; 00444 sc_list_head.count = 0; 00445 00446 /* init proc entry */ 00447 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS) 00448 { 00449 struct proc_dir_entry * tmp_entry_p; 00450 00451 tmp_entry_p = create_proc_entry(RSBAC_REG_PROC_NAME, 00452 S_IFREG | S_IRUGO, 00453 proc_rsbac_root_p); 00454 if(tmp_entry_p) 00455 { 00456 tmp_entry_p->get_info = reg_modules_proc_info; 00457 } 00458 } 00459 #endif 00460 } 00461 00462 00463 enum rsbac_adf_req_ret_t 00464 rsbac_adf_request_reg (enum rsbac_adf_request_t request, 00465 rsbac_pid_t caller_pid, 00466 enum rsbac_target_t target, 00467 union rsbac_target_id_t tid, 00468 enum rsbac_attribute_t attr, 00469 union rsbac_attribute_value_t attr_val, 00470 rsbac_uid_t owner) 00471 { 00472 enum rsbac_adf_req_ret_t result = DO_NOT_CARE; 00473 struct rsbac_reg_list_item_t * item_p; 00474 u_long flags; 00475 00476 rsbac_read_lock(&list_head.lock, &flags); 00477 item_p=list_head.head; 00478 while(item_p) 00479 { 00480 if( item_p->entry.request_func 00481 #ifdef CONFIG_RSBAC_SWITCH 00482 && item_p->entry.switch_on 00483 #endif 00484 ) 00485 result = adf_and_plus(result, 00486 item_p->entry.request_func (request, 00487 caller_pid, 00488 target, 00489 tid, 00490 attr, 00491 attr_val, 00492 owner) ); 00493 item_p=item_p->next; 00494 } 00495 rsbac_read_unlock(&list_head.lock, &flags); 00496 return result; 00497 } 00498 00499 int rsbac_adf_set_attr_reg( 00500 enum rsbac_adf_request_t request, 00501 rsbac_pid_t caller_pid, 00502 enum rsbac_target_t target, 00503 union rsbac_target_id_t tid, 00504 enum rsbac_target_t new_target, 00505 union rsbac_target_id_t new_tid, 00506 enum rsbac_attribute_t attr, 00507 union rsbac_attribute_value_t attr_val, 00508 rsbac_uid_t owner) 00509 { 00510 int error = 0; 00511 int suberror; 00512 struct rsbac_reg_list_item_t * item_p; 00513 u_long flags; 00514 00515 rsbac_read_lock(&list_head.lock, &flags); 00516 item_p=list_head.head; 00517 while(item_p) 00518 { 00519 if( item_p->entry.set_attr_func 00520 #ifdef CONFIG_RSBAC_SWITCH 00521 && item_p->entry.switch_on 00522 #endif 00523 ) 00524 { 00525 suberror = item_p->entry.set_attr_func (request, 00526 caller_pid, 00527 target, 00528 tid, 00529 new_target, 00530 new_tid, 00531 attr, 00532 attr_val, 00533 owner); 00534 if(suberror) 00535 error = suberror; 00536 } 00537 item_p = item_p->next; 00538 } 00539 rsbac_read_unlock(&list_head.lock, &flags); 00540 return error; 00541 } 00542 00543 00544 #ifdef CONFIG_RSBAC_SECDEL 00545 boolean rsbac_need_overwrite_reg(struct dentry * dentry_p) 00546 { 00547 boolean need_overwrite = FALSE; 00548 struct rsbac_reg_list_item_t * item_p; 00549 u_long flags; 00550 00551 rsbac_read_lock(&list_head.lock, &flags); 00552 item_p=list_head.head; 00553 while(item_p) 00554 { 00555 if( item_p->entry.need_overwrite_func 00556 #ifdef CONFIG_RSBAC_SWITCH 00557 && item_p->entry.switch_on 00558 #endif 00559 ) 00560 if(!need_overwrite) 00561 need_overwrite = item_p->entry.need_overwrite_func(dentry_p); 00562 item_p=item_p->next; 00563 } 00564 rsbac_read_unlock(&list_head.lock, &flags); 00565 return need_overwrite; 00566 } 00567 #endif 00568 00569 /* mounting and umounting */ 00570 int rsbac_mount_reg(kdev_t kdev) 00571 { 00572 int error = 0; 00573 int suberror; 00574 struct rsbac_reg_list_item_t * item_p; 00575 u_long flags; 00576 00577 rsbac_read_lock(&list_head.lock, &flags); 00578 item_p=list_head.head; 00579 while(item_p) 00580 { 00581 if( item_p->entry.mount_func 00582 ) 00583 { 00584 suberror = item_p->entry.mount_func(kdev); 00585 if(suberror < 0) 00586 error = suberror; 00587 } 00588 item_p=item_p->next; 00589 } 00590 rsbac_read_unlock(&list_head.lock, &flags); 00591 return error; 00592 } 00593 00594 int rsbac_umount_reg(kdev_t kdev) 00595 { 00596 int error = 0; 00597 int suberror; 00598 struct rsbac_reg_list_item_t * item_p; 00599 u_long flags; 00600 00601 rsbac_read_lock(&list_head.lock, &flags); 00602 item_p=list_head.head; 00603 while(item_p) 00604 { 00605 if( item_p->entry.umount_func 00606 ) 00607 { 00608 suberror = item_p->entry.umount_func(kdev); 00609 if(suberror < 0) 00610 error = suberror; 00611 } 00612 item_p=item_p->next; 00613 } 00614 rsbac_read_unlock(&list_head.lock, &flags); 00615 return error; 00616 } 00617 00618 #if defined(CONFIG_RSBAC_AUTO_WRITE) 00619 int rsbac_write_reg(boolean need_lock) 00620 { 00621 int count = 0; 00622 int subcount = 0; 00623 struct rsbac_reg_list_item_t * item_p; 00624 u_long flags; 00625 00626 rsbac_read_lock(&list_head.lock, &flags); 00627 item_p=list_head.head; 00628 while(item_p) 00629 { 00630 if(item_p->entry.write_func) 00631 { 00632 subcount = item_p->entry.write_func(need_lock); 00633 if(subcount > 0) 00634 { 00635 count += subcount; 00636 } 00637 else 00638 if(subcount < 0) 00639 { 00640 if(subcount != -RSBAC_ENOTWRITABLE) 00641 { 00642 #ifdef CONFIG_RSBAC_RMSG 00643 rsbac_printk(KERN_WARNING 00644 "rsbac_write_reg(): write_func() for REG module %s returned error %i\n", 00645 item_p->entry.name, subcount); 00646 #endif 00647 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00648 if (!rsbac_nosyslog) 00649 #endif 00650 printk(KERN_WARNING 00651 "rsbac_write_reg(): write_func() for REG module %s returned error %i\n", 00652 item_p->entry.name, subcount); 00653 } 00654 } 00655 } 00656 item_p=item_p->next; 00657 } 00658 rsbac_read_unlock(&list_head.lock, &flags); 00659 #ifdef CONFIG_RSBAC_DEBUG 00660 if (rsbac_debug_write) 00661 { 00662 #ifdef CONFIG_RSBAC_RMSG 00663 rsbac_printk(KERN_DEBUG "rsbac_write_reg(): %u lists written.\n", 00664 count); 00665 #endif 00666 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00667 if (!rsbac_nosyslog) 00668 #endif 00669 printk(KERN_DEBUG "rsbac_write_reg(): %u lists written.\n", 00670 count); 00671 } 00672 #endif 00673 return count; 00674 } 00675 #endif /* CONFIG_RSBAC_AUTO_WRITE */ 00676 00677 /* Status checking */ 00678 int rsbac_check_reg(int correct, int check_inode) 00679 { 00680 int error = 0; 00681 int suberror; 00682 struct rsbac_reg_list_item_t * item_p; 00683 u_long flags; 00684 00685 rsbac_read_lock(&list_head.lock, &flags); 00686 item_p=list_head.head; 00687 while(item_p) 00688 { 00689 if( item_p->entry.check_func 00690 ) 00691 { 00692 suberror = item_p->entry.check_func(correct, check_inode); 00693 if(suberror < 0) 00694 error = suberror; 00695 } 00696 item_p=item_p->next; 00697 } 00698 rsbac_read_unlock(&list_head.lock, &flags); 00699 return error; 00700 } 00701 00702 00703 /* 00704 * Register an ADF decision module 00705 * Returns given positive handle or negative error code 00706 */ 00707 00708 EXPORT_SYMBOL(rsbac_reg_register); 00709 00710 rsbac_reg_handle_t rsbac_reg_register( rsbac_version_t version, 00711 struct rsbac_reg_entry_t entry) 00712 { 00713 u_long flags; 00714 00715 if(version != RSBAC_REG_VERSION) 00716 return(-RSBAC_EINVALIDVERSION); 00717 00718 /* check entry */ 00719 if( ( !entry.request_func 00720 && !entry.set_attr_func 00721 && !entry.need_overwrite_func 00722 && !entry.write_func 00723 && !entry.mount_func 00724 && !entry.umount_func 00725 ) 00726 || (entry.handle <= 0) 00727 ) 00728 return -RSBAC_EINVALIDVALUE; 00729 00730 rsbac_write_lock(&list_head.lock, &flags); 00731 if(lookup_item(entry.handle)) 00732 { 00733 #ifdef CONFIG_RSBAC_RMSG 00734 rsbac_printk(KERN_INFO "rsbac_reg_register: Handle in use, registering failed: %s.\n", 00735 entry.name); 00736 #endif 00737 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00738 if (!rsbac_nosyslog) 00739 #endif 00740 printk(KERN_INFO "rsbac_reg_register: Handle in use, registering failed: %s.\n", 00741 entry.name); 00742 entry.handle = -RSBAC_EEXISTS; 00743 } 00744 else 00745 { 00746 if(!add_item(entry)) 00747 { 00748 entry.name[RSBAC_REG_NAME_LEN] = 0; 00749 #ifdef CONFIG_RSBAC_RMSG 00750 rsbac_printk(KERN_INFO "rsbac_reg_register: registering failed for %s.\n", 00751 entry.name); 00752 #endif 00753 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00754 if (!rsbac_nosyslog) 00755 #endif 00756 printk(KERN_INFO "rsbac_reg_register: registering failed for %s.\n", 00757 entry.name); 00758 entry.handle = -RSBAC_ECOULDNOTADDITEM; 00759 } 00760 #ifdef CONFIG_RSBAC_DEBUG 00761 else 00762 if(rsbac_debug_reg) 00763 { 00764 #ifdef CONFIG_RSBAC_RMSG 00765 rsbac_printk(KERN_DEBUG "rsbac_reg_register: module %s registered.\n", 00766 entry.name); 00767 #endif 00768 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00769 if (!rsbac_nosyslog) 00770 #endif 00771 printk(KERN_DEBUG "rsbac_reg_register: module %s registered.\n", 00772 entry.name); 00773 } 00774 #endif 00775 } 00776 rsbac_write_unlock(&list_head.lock, &flags); 00777 return entry.handle; 00778 }; 00779 00780 /* 00781 * Switch module on or off - for 'normal' modules this is done by general 00782 * function. This is a dummy, if module switching is disabled. 00783 */ 00784 00785 EXPORT_SYMBOL(rsbac_reg_switch); 00786 00787 int rsbac_reg_switch (rsbac_reg_handle_t handle, boolean value) 00788 { 00789 #ifdef CONFIG_RSBAC_SWITCH 00790 struct rsbac_reg_list_item_t * item_p; 00791 u_long flags; 00792 int err=0; 00793 00794 if((value != FALSE) && (value != TRUE)) 00795 return -RSBAC_EINVALIDVALUE; 00796 rsbac_read_lock(&list_head.lock, &flags); 00797 item_p = lookup_item(handle); 00798 if(item_p) 00799 { 00800 item_p->entry.switch_on = value; 00801 #ifdef CONFIG_RSBAC_DEBUG 00802 if(rsbac_debug_reg) 00803 { 00804 #ifdef CONFIG_RSBAC_RMSG 00805 rsbac_printk(KERN_DEBUG "rsbac_reg_switch: module %s switched to %i.\n", 00806 item_p->entry.name, 00807 value); 00808 #endif 00809 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00810 if (!rsbac_nosyslog) 00811 #endif 00812 printk(KERN_DEBUG "rsbac_reg_switch: module %s switched to %i.\n", 00813 item_p->entry.name, 00814 value); 00815 } 00816 #endif 00817 } 00818 else 00819 err = -RSBAC_EINVALIDTARGET; 00820 rsbac_read_unlock(&list_head.lock, &flags); 00821 return err; 00822 #else 00823 return(-RSBAC_EINVALIDTARGET); 00824 #endif 00825 }; 00826 00827 /* 00828 * Unregister an ADF decision module 00829 * Returns 0 on success or negative error code. Be careful not to unregister 00830 * modules you did not register yourself. 00831 */ 00832 00833 EXPORT_SYMBOL(rsbac_reg_unregister); 00834 00835 int rsbac_reg_unregister(rsbac_reg_handle_t handle) 00836 { 00837 u_long flags; 00838 int err=0; 00839 00840 if(handle <= 0) 00841 return -RSBAC_EINVALIDVALUE; 00842 00843 rsbac_write_lock(&list_head.lock, &flags); 00844 if(lookup_item(handle)) 00845 { 00846 remove_item(handle); 00847 #ifdef CONFIG_RSBAC_DEBUG 00848 if(rsbac_debug_reg) 00849 { 00850 #ifdef CONFIG_RSBAC_RMSG 00851 rsbac_printk(KERN_DEBUG "rsbac_reg_unregister: module unregistered.\n"); 00852 #endif 00853 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00854 if (!rsbac_nosyslog) 00855 #endif 00856 printk(KERN_DEBUG "rsbac_reg_unregister: module unregistered.\n"); 00857 } 00858 #endif 00859 } 00860 else 00861 { 00862 err = -RSBAC_EINVALIDTARGET; 00863 #ifdef CONFIG_RSBAC_DEBUG 00864 if(rsbac_debug_reg) 00865 { 00866 #ifdef CONFIG_RSBAC_RMSG 00867 rsbac_printk(KERN_DEBUG "rsbac_reg_unregister: module unregistering failed.\n"); 00868 #endif 00869 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00870 if (!rsbac_nosyslog) 00871 #endif 00872 printk(KERN_DEBUG "rsbac_reg_unregister: module unregistering failed.\n"); 00873 } 00874 #endif 00875 } 00876 rsbac_write_unlock(&list_head.lock, &flags); 00877 return err; 00878 }; 00879 00880 00881 /* 00882 * Register a system call 00883 * Returns given positive handle or negative error code 00884 */ 00885 00886 EXPORT_SYMBOL(rsbac_reg_register_syscall); 00887 00888 rsbac_reg_handle_t rsbac_reg_register_syscall( rsbac_version_t version, 00889 struct rsbac_reg_syscall_entry_t entry) 00890 { 00891 u_long flags; 00892 00893 if(version != RSBAC_REG_VERSION) 00894 return(-RSBAC_EINVALIDVERSION); 00895 00896 /* check entry */ 00897 if( !entry.syscall_func 00898 || (entry.registration_handle <= 0) 00899 || (entry.dispatcher_handle <= 0) 00900 ) 00901 return -RSBAC_EINVALIDVALUE; 00902 00903 rsbac_write_lock(&sc_list_head.lock, &flags); 00904 if(lookup_sc_item_reg(entry.registration_handle)) 00905 { 00906 #ifdef CONFIG_RSBAC_RMSG 00907 rsbac_printk(KERN_INFO "rsbac_reg_register_syscall: Registration handle in use, registering failed: %s.\n", 00908 entry.name); 00909 #endif 00910 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00911 if (!rsbac_nosyslog) 00912 #endif 00913 printk(KERN_INFO "rsbac_reg_register_syscall: Registration handle in use, registering failed: %s.\n", 00914 entry.name); 00915 entry.registration_handle = -RSBAC_EEXISTS; 00916 } 00917 else 00918 if(lookup_sc_item_dis(entry.dispatcher_handle)) 00919 { 00920 #ifdef CONFIG_RSBAC_RMSG 00921 rsbac_printk(KERN_INFO "rsbac_reg_register_syscall: Dispatcher handle in use, registering failed: %s.\n", 00922 entry.name); 00923 #endif 00924 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00925 if (!rsbac_nosyslog) 00926 #endif 00927 printk(KERN_INFO "rsbac_reg_register_syscall: Dispatcher handle in use, registering failed: %s.\n", 00928 entry.name); 00929 entry.registration_handle = -RSBAC_EEXISTS; 00930 } 00931 else 00932 { 00933 entry.name[RSBAC_REG_NAME_LEN] = 0; 00934 if(!add_sc_item(entry)) 00935 { 00936 #ifdef CONFIG_RSBAC_RMSG 00937 rsbac_printk(KERN_INFO "rsbac_reg_register_syscall: registering failed for %s.\n", 00938 entry.name); 00939 #endif 00940 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00941 if (!rsbac_nosyslog) 00942 #endif 00943 printk(KERN_INFO "rsbac_reg_register_syscall: registering failed for %s.\n", 00944 entry.name); 00945 entry.registration_handle = -RSBAC_ECOULDNOTADDITEM; 00946 } 00947 #ifdef CONFIG_RSBAC_DEBUG 00948 else 00949 if(rsbac_debug_reg) 00950 { 00951 #ifdef CONFIG_RSBAC_RMSG 00952 rsbac_printk(KERN_DEBUG "rsbac_reg_register_syscall: syscall %s registered.\n", 00953 entry.name); 00954 #endif 00955 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00956 if (!rsbac_nosyslog) 00957 #endif 00958 printk(KERN_DEBUG "rsbac_reg_register_syscall: syscall %s registered.\n", 00959 entry.name); 00960 } 00961 #endif 00962 } 00963 rsbac_write_unlock(&sc_list_head.lock, &flags); 00964 return entry.registration_handle; 00965 }; 00966 00967 /* 00968 * Unregister a system call 00969 * Returns 0 on success or negative error code. Be careful not to unregister 00970 * syscalls you did not register yourself. 00971 */ 00972 00973 EXPORT_SYMBOL(rsbac_reg_unregister_syscall); 00974 00975 int rsbac_reg_unregister_syscall(rsbac_reg_handle_t handle) 00976 { 00977 u_long flags; 00978 int err=0; 00979 00980 if(handle <= 0) 00981 return -RSBAC_EINVALIDVALUE; 00982 00983 rsbac_write_lock(&sc_list_head.lock, &flags); 00984 if(lookup_sc_item_reg(handle)) 00985 { 00986 remove_sc_item(handle); 00987 #ifdef CONFIG_RSBAC_DEBUG 00988 if(rsbac_debug_reg) 00989 { 00990 #ifdef CONFIG_RSBAC_RMSG 00991 rsbac_printk(KERN_DEBUG "rsbac_reg_unregister_syscall: syscall unregistered.\n"); 00992 #endif 00993 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00994 if (!rsbac_nosyslog) 00995 #endif 00996 printk(KERN_DEBUG "rsbac_reg_unregister_syscall: syscall unregistered.\n"); 00997 } 00998 #endif 00999 } 01000 else 01001 { 01002 err = -RSBAC_EINVALIDTARGET; 01003 #ifdef CONFIG_RSBAC_RMSG 01004 rsbac_printk(KERN_INFO "rsbac_reg_unregister_syscall: syscall unregistering failed for invalid handle!\n"); 01005 #endif 01006 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01007 if (!rsbac_nosyslog) 01008 #endif 01009 printk(KERN_INFO "rsbac_reg_unregister_syscall: syscall unregistering failed for invalid handle!\n"); 01010 } 01011 rsbac_write_unlock(&sc_list_head.lock, &flags); 01012 return err; 01013 }; 01014 01015 int rsbac_reg_syscall(rsbac_reg_handle_t handle, 01016 void * arg) 01017 { 01018 int err = 0; 01019 struct rsbac_reg_sc_list_item_t * item_p; 01020 u_long flags; 01021 01022 rsbac_read_lock(&sc_list_head.lock, &flags); 01023 item_p=lookup_sc_item_dis(handle); 01024 if(item_p && item_p->entry.syscall_func) 01025 { 01026 err = item_p->entry.syscall_func(arg); 01027 } 01028 else 01029 { 01030 err = -RSBAC_EINVALIDTARGET; 01031 } 01032 rsbac_read_unlock(&sc_list_head.lock, &flags); 01033 return err; 01034 } 01035 01036 /* end of rsbac/adf/reg/reg_main.c */

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