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