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: 09/Feb/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 /* 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 rsbac_boolean_t rsbac_need_overwrite_reg(struct dentry * dentry_p)
00546   {
00547     rsbac_boolean_t 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(rsbac_boolean_t 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, rsbac_boolean_t 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 Fri Jun 17 09:45:20 2005 for RSBAC by  doxygen 1.4.2