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-2005: Amon Ott <ao@rsbac.org> */
00008 /*                                                   */
00009 /* Last modified: 22/Jul/2005                        */
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 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 /* lookup_item() */
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     /* is the current item the one we look for? yes -> return, else search */
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 /* lookup_sc_item_reg() */
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     /* is the current item the one we look for? yes -> return, else search */
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 /* lookup_sc_item_dis() */
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     /* is the current item the one we look for? yes -> return, else search */
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       /* first we must locate the item. */
00252       if ( (item_p = lookup_item(handle)) )
00253         { /* ok, item was found */
00254           if ( (list_head.head == item_p) )
00255              { /* item is head */
00256                if ( (list_head.tail == item_p) )
00257                  { /* item is head and tail = only item -> list will be empty*/
00258                    list_head.head = NULL;
00259                    list_head.tail = NULL;
00260                  }
00261                else
00262                  { /* item is head, but not tail -> next item becomes head */
00263                    item_p->next->prev = NULL;
00264                    list_head.head = item_p->next;
00265                  };
00266              }
00267           else
00268              { /* item is not head */
00269                if ( (list_head.tail == item_p) )
00270                  { /*item is not head, but tail -> previous item becomes tail*/
00271                    item_p->prev->next = NULL;
00272                    list_head.tail = item_p->prev;
00273                  }
00274                else
00275                  { /* item is neither head nor tail -> item is cut out */
00276                    item_p->prev->next = item_p->next;
00277                    item_p->next->prev = item_p->prev;
00278                  };
00279              };
00280              
00281           /* curr is no longer valid -> reset */
00282           list_head.curr=NULL;
00283           /* adjust counter */
00284           list_head.count--;
00285           /* now we can remove the item from memory */
00286           rsbac_kfree(item_p);    
00287         };  /* end of if: item was found */
00288     }; /* end of remove_item() */
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       /* first we must locate the item. */
00295       if ( (item_p = lookup_sc_item_reg(handle)) )
00296         { /* ok, item was found */
00297           if ( (sc_list_head.head == item_p) )
00298              { /* item is head */
00299                if ( (sc_list_head.tail == item_p) )
00300                  { /* item is head and tail = only item -> sc_list will be empty*/
00301                    sc_list_head.head = NULL;
00302                    sc_list_head.tail = NULL;
00303                  }
00304                else
00305                  { /* item is head, but not tail -> next item becomes head */
00306                    item_p->next->prev = NULL;
00307                    sc_list_head.head = item_p->next;
00308                  };
00309              }
00310           else
00311              { /* item is not head */
00312                if ( (sc_list_head.tail == item_p) )
00313                  { /*item is not head, but tail -> previous item becomes tail*/
00314                    item_p->prev->next = NULL;
00315                    sc_list_head.tail = item_p->prev;
00316                  }
00317                else
00318                  { /* item is neither head nor tail -> item is cut out */
00319                    item_p->prev->next = item_p->next;
00320                    item_p->next->prev = item_p->prev;
00321                  };
00322              };
00323              
00324           /* curr is no longer valid -> reset */
00325           sc_list_head.curr=NULL;
00326           /* adjust counter */
00327           sc_list_head.count--;
00328           /* now we can remove the item from memory */
00329           rsbac_kfree(item_p);    
00330         };  /* end of if: item was found */
00331     }; /* end of remove_item() */
00332 
00333 
00334 /************************************************* */
00335 /*           PROC support                          */
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 /* PROC */
00473 
00474 /************************************************* */
00475 /*          Externally visible functions           */
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     /* init data structures */
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     /* init proc entry */
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 /* mounting and umounting */
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 /* CONFIG_RSBAC_AUTO_WRITE */
00714 
00715 /* Status checking */
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  * Register an ADF decision module
00742  * Returns given positive handle or negative error code
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     /* check entry */
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  * Switch module on or off - for 'normal' modules this is done by general
00796  * function. This is a dummy, if module switching is disabled.
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  * Unregister an ADF decision module
00834  * Returns 0 on success or negative error code. Be careful not to unregister
00835  * modules you did not register yourself.
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  * Register a system call
00875  * Returns given positive handle or negative error code
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     /* check entry */
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  * Unregister a system call
00931  * Returns 0 on success or negative error code. Be careful not to unregister
00932  * syscalls you did not register yourself.
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 /* end of rsbac/adf/reg/reg_main.c */

Generated on Sun May 21 14:30:50 2006 for RSBAC by  doxygen 1.4.2