pm_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) - Privacy Model                    */
00005 /* File: rsbac/adf/pm/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/string.h>
00013 #include <rsbac/types.h>
00014 #include <rsbac/aci.h>
00015 #include <rsbac/adf_main.h>
00016 #include <rsbac/error.h>
00017 #include <rsbac/debug.h>
00018 #include <rsbac/helpers.h>
00019 #include <rsbac/getname.h>
00020 #include <rsbac/pm.h>
00021 
00022 /************************************************* */
00023 /*           Global Variables                      */
00024 /************************************************* */
00025 
00026 /************************************************* */
00027 /*          Internal Help functions                */
00028 /************************************************* */
00029 
00030 static rsbac_pm_purpose_id_t
00031   get_ipc_purpose(struct rsbac_ipc_t ipc_id)
00032   {
00033     union rsbac_target_id_t       i_tid;
00034     union rsbac_attribute_value_t i_attr_val1;
00035 
00036     /* get pm_ipc_purpose of given ipc */
00037     i_tid.ipc = ipc_id;
00038     if (rsbac_get_attr(PM,
00039                        T_IPC,
00040                        i_tid,
00041                        A_pm_ipc_purpose,
00042                        &i_attr_val1,
00043                        FALSE))
00044       {
00045         printk(KERN_WARNING
00046                "get_ipc_purpose(): rsbac_get_attr() returned error!\n");
00047         return(0);
00048       }
00049     return(i_attr_val1.pm_ipc_purpose);
00050   }
00051 
00052 static enum rsbac_adf_req_ret_t
00053   tp_check(rsbac_pid_t caller_pid)
00054   {
00055     union rsbac_target_id_t       i_tid;
00056     union rsbac_attribute_value_t i_attr_val1;
00057 
00058     /* get pm_process_type of caller-process */
00059     i_tid.process = caller_pid;
00060     if (rsbac_get_attr(PM,
00061                        T_PROCESS,
00062                        i_tid,
00063                        A_pm_process_type,
00064                        &i_attr_val1,
00065                        FALSE))
00066       {
00067         printk(KERN_WARNING
00068                "tp_check(): rsbac_get_attr() returned error!\n");
00069         return(NOT_GRANTED);
00070       }
00071     if(i_attr_val1.pm_process_type == PP_TP)
00072       return(NOT_GRANTED);
00073     else
00074       return(DO_NOT_CARE);
00075   };
00076 
00077 /* This function does the actual checking for */
00078 /* necessary(access) and (purpose-binding or consent). */
00079 /* Additionally, information flow checking is done via input and output */
00080 /* purpose sets. */
00081 static enum rsbac_adf_req_ret_t
00082   na_and_pp_or_cs(       rsbac_pid_t          caller_pid,
00083                   struct rsbac_fs_file_t      file,
00084                          rsbac_pm_accesses_t  acc)
00085   {
00086     rsbac_pm_task_id_t            task;
00087     rsbac_pm_object_class_id_t    object_class;
00088     rsbac_pm_tp_id_t              tp;
00089     union rsbac_target_id_t       i_tid;
00090     union rsbac_attribute_value_t i_attr_val1;
00091     union rsbac_pm_target_id_t    i_pm_tid;
00092     union rsbac_pm_data_value_t   i_data_val1;
00093     union rsbac_pm_data_value_t   i_data_val2;
00094     union rsbac_pm_set_id_t       i_pm_set_id;
00095     union rsbac_pm_set_member_t   i_pm_set_member;
00096           int                     error;
00097     
00098     /* get object_class of file */
00099     i_tid.file = file;
00100     if (rsbac_get_attr(PM,
00101                        T_FILE,
00102                        i_tid,
00103                        A_pm_object_class,
00104                        &i_attr_val1,
00105                        FALSE))
00106       {
00107         printk(KERN_WARNING
00108                "na_and_pp_or_cs(): rsbac_get_attr() returned error!\n");
00109                return(NOT_GRANTED);
00110       }
00111     object_class = i_attr_val1.pm_object_class;
00112     /* if there is no class for this file, this is an error!   */
00113     /* (all personal data must have a class assigned, and this */
00114     /* function must never be called for anything else)        */
00115     if(!object_class)
00116       {
00117 #ifdef CONFIG_RSBAC_DEBUG
00118         if(rsbac_debug_adf_pm)
00119           printk(KERN_WARNING
00120                  "na_and_pp_or_cs(): personal_data with NIL class!\n");
00121 #endif
00122         return(NOT_GRANTED);
00123       }
00124 
00125     /* get current_task of caller-process */
00126     i_tid.process = caller_pid;
00127     if (rsbac_get_attr(PM,
00128                        T_PROCESS,
00129                        i_tid,
00130                        A_pm_current_task,
00131                        &i_attr_val1,
00132                        FALSE))
00133       {
00134         printk(KERN_WARNING
00135                "na_and_pp_or_cs(): rsbac_get_attr() returned error!\n");
00136                return(NOT_GRANTED);
00137       }
00138     task = i_attr_val1.pm_current_task;
00139     if(!task)
00140       {
00141 #ifdef CONFIG_RSBAC_DEBUG
00142         if(rsbac_debug_adf_pm)
00143           printk(KERN_DEBUG
00144                  "na_and_pp_or_cs(): no current_task for calling process trying to access personal_data\n");
00145 #endif
00146         return(NOT_GRANTED);
00147       }
00148 
00149     /* get pm_tp of caller-process */
00150     if (rsbac_get_attr(PM,
00151                        T_PROCESS,
00152                        i_tid,
00153                        A_pm_tp,
00154                        &i_attr_val1,
00155                        FALSE))
00156       {
00157         printk(KERN_WARNING
00158                "na_and_pp_or_cs(): rsbac_get_attr() returned error!\n");
00159         return(NOT_GRANTED);
00160       }
00161     tp = i_attr_val1.pm_tp;
00162     if(!tp)
00163       {
00164 #ifdef CONFIG_RSBAC_DEBUG
00165         if(rsbac_debug_adf_pm)
00166           printk(KERN_DEBUG
00167                  "na_and_pp_or_cs(): calling process trying to access personal_data has no TP-id\n");
00168 #endif
00169         return(NOT_GRANTED);
00170       }
00171 
00172     /* get necessary accesses */
00173     i_pm_tid.na.task = task;
00174     i_pm_tid.na.object_class = object_class;
00175     i_pm_tid.na.tp = tp;
00176     if ((error = rsbac_pm_get_data(0,
00177                                    PMT_NA,
00178                                    i_pm_tid,
00179                                    PD_accesses,
00180                                    &i_data_val1)))
00181       {
00182         if(error != -RSBAC_EINVALIDTARGET)
00183           printk(KERN_WARNING
00184                  "na_and_pp_or_cs(): rsbac_pm_get_data() returned error %i!\n",
00185                  error);
00186           return(NOT_GRANTED);
00187       }
00188     /* is requested access mode included in access mask? */
00189     if((acc & i_data_val1.accesses) != acc)
00190       {
00191 #ifdef CONFIG_RSBAC_DEBUG
00192         if(rsbac_debug_adf_pm)
00193           printk(KERN_DEBUG
00194                  "na_and_pp_or_cs(): requested access mode is not necessary\n");
00195 #endif
00196         return(NOT_GRANTED);
00197       }
00198 
00199     /* OK, access is necessary -> check (purpose-bind or consent) */
00200     /* first try purpose-binding */
00201     
00202     /* get purpose-id of current_task */
00203     i_pm_tid.task = task;
00204     if ((error = rsbac_pm_get_data(0,
00205                                    PMT_TASK,
00206                                    i_pm_tid,
00207                                    PD_purpose,
00208                                    &i_data_val1)))
00209       {
00210         printk(KERN_WARNING
00211                  "na_and_pp_or_cs(): rsbac_get_data() for current_TASK/purpose returned error %i!\n",
00212                  error);
00213         return(NOT_GRANTED);
00214       }
00215     if(!i_data_val1.purpose)
00216       {
00217         printk(KERN_WARNING
00218                "na_and_pp_or_cs(): task %i has NIL purpose!\n",task);
00219         return(NOT_GRANTED);
00220       }
00221     /* get purpose-set-id of class */
00222     i_pm_tid.object_class = object_class;
00223     if ((error = rsbac_pm_get_data(0,
00224                                    PMT_CLASS,
00225                                    i_pm_tid,
00226                                    PD_pp_set,
00227                                    &i_data_val2)))
00228       {
00229         if(error != -RSBAC_EINVALIDTARGET)
00230           printk(KERN_WARNING
00231                  "na_and_pp_or_cs(): rsbac_pm_get_data() returned error %i!\n",
00232                  error);
00233         return(NOT_GRANTED);
00234       }
00235     /* OK, if task's purpose is in class's purpose_set */
00236     i_pm_set_id.pp_set = i_data_val2.pp_set;
00237     i_pm_set_member.pp = i_data_val1.purpose;
00238     if (!rsbac_pm_set_member(0,PS_PP,i_pm_set_id,i_pm_set_member))
00239       { /* purpose binding failed -> try consent */
00240 #ifdef CONFIG_RSBAC_DEBUG
00241         if(rsbac_debug_adf_pm)
00242           printk(KERN_DEBUG
00243                  "na_and_pp_or_cs(): purpose of current_task of calling process is NOT in purpose set of class of file -> trying consent\n");
00244 #endif
00245         i_pm_tid.cs.purpose = i_data_val1.purpose;
00246         i_pm_tid.cs.file = file;
00247         if(!rsbac_pm_exists(0,PMT_CS,i_pm_tid))
00248           { /* neither pp-binding, nor consent -> do not grant */
00249 #ifdef CONFIG_RSBAC_DEBUG
00250             if(rsbac_debug_adf_pm)
00251               printk(KERN_DEBUG
00252                      "na_and_pp_or_cs(): there is no consent for this purpose for file\n");
00253 #endif
00254             return(NOT_GRANTED);
00255           }
00256       }
00257 
00258     /* information flow check */
00259 
00260     /* read access: is purpose set of class of file superset of process */
00261     /* output purpose set? If not -> do not grant access */
00262     /* (Output purpose set id is process id) */
00263     if(   (acc & RSBAC_PM_A_READ)
00264        && !rsbac_pm_pp_superset(i_pm_set_id.pp_set, caller_pid) )
00265       {
00266 #ifdef CONFIG_RSBAC_DEBUG
00267         if(rsbac_debug_adf_pm)
00268           printk(KERN_DEBUG
00269                  "na_and_pp_or_cs(): failed information flow check for read access\n");
00270 #endif
00271         return(NOT_GRANTED);
00272       }
00273 
00274     /* write access: is purpose set of class of file subset of process */
00275     /* input purpose set? If not -> do not grant access */
00276     /* (Input purpose set id is also process id) */
00277     if(   (acc & RSBAC_PM_A_WRITE_TO_FILE)
00278        && !rsbac_pm_pp_subset(i_pm_set_id.pp_set, caller_pid) )
00279       {
00280 #ifdef CONFIG_RSBAC_DEBUG
00281         if(rsbac_debug_adf_pm)
00282           printk(KERN_DEBUG
00283                  "na_and_pp_or_cs(): failed information flow check for write access\n");
00284 #endif
00285         return(NOT_GRANTED);
00286       }
00287 
00288     /* OK, all checks done. GRANT! */
00289     return(GRANTED);
00290   }
00291   
00292 /* reduced version for IPC objects */
00293 static enum rsbac_adf_req_ret_t
00294   na_and_pp_ipc(       rsbac_pm_task_id_t   task,
00295                        rsbac_pid_t          caller_pid,
00296                        rsbac_pm_accesses_t  acc,
00297                 struct rsbac_ipc_t          ipc_id)
00298   {
00299     rsbac_pm_tp_id_t              tp;
00300     union rsbac_target_id_t       i_tid;
00301     union rsbac_attribute_value_t i_attr_val1;
00302     union rsbac_pm_target_id_t    i_pm_tid;
00303     union rsbac_pm_data_value_t   i_data_val1;
00304     union rsbac_pm_set_id_t       i_pm_set_id;
00305     union rsbac_pm_set_member_t   i_pm_set_member;
00306           int                     error;
00307     
00308     if(!task)
00309       return(NOT_GRANTED);
00310 
00311     /* get pm_tp of caller-process */
00312     i_tid.process = caller_pid;
00313     if (rsbac_get_attr(PM,
00314                        T_PROCESS,
00315                        i_tid,
00316                        A_pm_tp,
00317                        &i_attr_val1,
00318                        FALSE))
00319       {
00320         printk(KERN_WARNING
00321                "na_and_pp_ipc(): rsbac_get_attr() returned error!\n");
00322         return(NOT_GRANTED);
00323       }
00324     tp = i_attr_val1.pm_tp;
00325     if(!tp)
00326       {
00327 #ifdef CONFIG_RSBAC_DEBUG
00328         if(rsbac_debug_adf_pm)
00329           printk(KERN_DEBUG
00330                  "na_and_pp_ipc(): calling process trying to access ipc has task, but no TP-id\n");
00331 #endif
00332         return(NOT_GRANTED);
00333       }
00334       return(NOT_GRANTED);
00335 
00336     /* get necessary accesses */
00337     i_pm_tid.na.task = task;
00338     i_pm_tid.na.object_class = RSBAC_PM_IPC_OBJECT_CLASS_ID;
00339     i_pm_tid.na.tp = tp;
00340     if ((error = rsbac_pm_get_data(0,
00341                                    PMT_NA,
00342                                    i_pm_tid,
00343                                    PD_accesses,
00344                                    &i_data_val1)))
00345       {
00346         if(error != -RSBAC_EINVALIDTARGET)
00347           printk(KERN_WARNING
00348                  "na_and_pp_ipc(): rsbac_pm_get_data() returned error %i!\n",
00349                  error);
00350           return(NOT_GRANTED);
00351       }
00352     /* is requested access mode included in access mask? */
00353     if((acc & i_data_val1.accesses) != acc)
00354       {
00355 #ifdef CONFIG_RSBAC_DEBUG
00356         if(rsbac_debug_adf_pm)
00357           printk(KERN_DEBUG
00358                  "na_and_pp_ipc(): requested access mode is not necessary\n");
00359 #endif
00360         return(NOT_GRANTED);
00361       }
00362 
00363     /* OK, access is necessary -> check purpose-bind */
00364     /* get purpose-id of current_task */
00365     i_pm_tid.task = task;
00366     if ((error = rsbac_pm_get_data(0,
00367                                    PMT_TASK,
00368                                    i_pm_tid,
00369                                    PD_purpose,
00370                                    &i_data_val1)))
00371       {
00372         printk(KERN_WARNING
00373                  "na_and_pp_ipc(): rsbac_get_data() for current_TASK/purpose returned error %i!\n",
00374                  error);
00375         return(NOT_GRANTED);
00376       }
00377     if(!i_data_val1.purpose)
00378       {
00379         printk(KERN_WARNING
00380                "na_and_pp_ipc(): task %i has NIL purpose!\n",task);
00381         return(NOT_GRANTED);
00382       }
00383     /* get ipc_purpose of IPC-object */
00384     i_tid.ipc = ipc_id;
00385     if (rsbac_get_attr(PM,
00386                        T_IPC,
00387                        i_tid,
00388                        A_pm_ipc_purpose,
00389                        &i_attr_val1,
00390                        FALSE))
00391       {
00392         printk(KERN_WARNING
00393                "na_and_pp_ipc(): rsbac_get_attr() returned error!\n");
00394         return(NOT_GRANTED);
00395       }
00396 
00397     /* grant, if task's purpose is ipc's ipc_purpose or if */
00398     /* IPC-pp is NIL and access is read-only */
00399     if (!(   (i_data_val1.purpose == i_attr_val1.pm_ipc_purpose)
00400           || (!i_data_val1.purpose && !(acc & RSBAC_PM_A_WRITING) ) ) )
00401       {
00402 #ifdef CONFIG_RSBAC_DEBUG
00403         if(rsbac_debug_adf_pm)
00404           printk(KERN_DEBUG
00405                  "na_and_pp_ipc(): purpose of current_task of calling process is NOT ipc_purpose\n");
00406 #endif
00407         return(NOT_GRANTED);
00408       }
00409     /* information flow check */
00410 
00411     /* read access: is purpose of ipc object NIL or no other purpose in */
00412     /* output purpose set? If not -> do not grant access */
00413     /* (Output purpose set id is process id) */
00414     if(   (acc & RSBAC_PM_A_READ)
00415        && i_attr_val1.pm_ipc_purpose
00416        && !rsbac_pm_pp_only(i_attr_val1.pm_ipc_purpose, caller_pid) )
00417       {
00418 #ifdef CONFIG_RSBAC_DEBUG
00419         if(rsbac_debug_adf_pm)
00420           printk(KERN_DEBUG
00421                  "na_and_pp_ipc(): failed information flow check for read access\n");
00422 #endif
00423         return(NOT_GRANTED);
00424       }
00425 
00426     /* write access: is purpose of ipc in */
00427     /* input purpose set? If not -> do not grant access */
00428     /* (Input purpose set id is also process id) */
00429     if(acc & RSBAC_PM_A_WRITE_TO_FILE)
00430       {
00431         i_pm_set_id.in_pp_set = caller_pid;
00432         i_pm_set_member.pp = i_attr_val1.pm_ipc_purpose;
00433         if (!rsbac_pm_set_member(0, PS_IN_PP, i_pm_set_id, i_pm_set_member) )
00434           {
00435 #ifdef CONFIG_RSBAC_DEBUG
00436             if(rsbac_debug_adf_pm)
00437               printk(KERN_DEBUG
00438                      "na_and_pp_or_cs(): failed information flow check for write access\n");
00439 #endif
00440             return(NOT_GRANTED);
00441           }
00442       }
00443     /* OK, all checks done. GRANT! */
00444     return(GRANTED);
00445   }
00446 
00447 
00448 static enum rsbac_adf_req_ret_t
00449   na_ipc(rsbac_pm_task_id_t   task,
00450          rsbac_pid_t          caller_pid,
00451          rsbac_pm_accesses_t  acc)
00452   {
00453     rsbac_pm_tp_id_t              tp;
00454     union rsbac_target_id_t       i_tid;
00455     union rsbac_attribute_value_t i_attr_val1;
00456     union rsbac_pm_target_id_t    i_pm_tid;
00457     union rsbac_pm_data_value_t   i_data_val1;
00458           int                     error;
00459     
00460     if(!task)
00461       return(NOT_GRANTED);
00462 
00463     /* get pm_tp of caller-process */
00464     i_tid.process = caller_pid;
00465     if (rsbac_get_attr(PM,
00466                        T_PROCESS,
00467                        i_tid,
00468                        A_pm_tp,
00469                        &i_attr_val1,
00470                        FALSE))
00471       {
00472         printk(KERN_WARNING
00473                "na_ipc(): rsbac_get_attr() returned error!\n");
00474         return(NOT_GRANTED);
00475       }
00476     tp = i_attr_val1.pm_tp;
00477     if(!tp)
00478       return(NOT_GRANTED);
00479 
00480     /* get necessary accesses */
00481     i_pm_tid.na.task = task;
00482     i_pm_tid.na.object_class = RSBAC_PM_IPC_OBJECT_CLASS_ID;
00483     i_pm_tid.na.tp = tp;
00484     if ((error = rsbac_pm_get_data(0,
00485                                    PMT_NA,
00486                                    i_pm_tid,
00487                                    PD_accesses,
00488                                    &i_data_val1)))
00489       {
00490         if(error != -RSBAC_EINVALIDTARGET)
00491           printk(KERN_WARNING
00492                  "na_ipc(): rsbac_pm_get_data() returned error %i!\n",
00493                  error);
00494           return(NOT_GRANTED);
00495       }
00496     /* is requested access mode included in access mask? */
00497     if((acc & i_data_val1.accesses) == acc)
00498       return(GRANTED);
00499     else
00500       return(NOT_GRANTED);
00501   }
00502 
00503 static enum rsbac_adf_req_ret_t
00504   na_dev(rsbac_pid_t          caller_pid,
00505          rsbac_pm_accesses_t  acc,
00506          struct rsbac_dev_t   dev)
00507   {
00508     rsbac_pm_tp_id_t              tp;
00509     rsbac_pm_task_id_t            task;
00510     rsbac_pm_object_class_id_t    object_class;
00511     union rsbac_target_id_t       i_tid;
00512     union rsbac_attribute_value_t i_attr_val1;
00513     union rsbac_pm_target_id_t    i_pm_tid;
00514     union rsbac_pm_data_value_t   i_data_val1;
00515           int                     error;
00516     
00517     i_tid.process = caller_pid;
00518     if (rsbac_get_attr(PM,
00519                        T_PROCESS,
00520                        i_tid,
00521                        A_pm_current_task,
00522                        &i_attr_val1,
00523                        FALSE))
00524       {
00525         printk(KERN_WARNING
00526                "na_dev(): rsbac_get_attr() returned error!\n");
00527                return(NOT_GRANTED);
00528       }
00529     task = i_attr_val1.pm_current_task;
00530     /* if current_task = NIL -> do not grant */
00531     if(!task)
00532       {
00533         return(NOT_GRANTED);
00534       }
00535 
00536     /* get pm_tp of caller-process */
00537     i_tid.process = caller_pid;
00538     if (rsbac_get_attr(PM,
00539                        T_PROCESS,
00540                        i_tid,
00541                        A_pm_tp,
00542                        &i_attr_val1,
00543                        FALSE))
00544       {
00545         printk(KERN_WARNING
00546                "na_dev(): rsbac_get_attr() returned error!\n");
00547         return(NOT_GRANTED);
00548       }
00549     tp = i_attr_val1.pm_tp;
00550     if(!tp)
00551       return(NOT_GRANTED);
00552 
00553     /* get pm_object_class of dev target */
00554     i_tid.dev = dev;
00555     if (rsbac_get_attr(PM,
00556                        T_DEV,
00557                        i_tid,
00558                        A_pm_object_class,
00559                        &i_attr_val1,
00560                        FALSE))
00561       {
00562         printk(KERN_WARNING
00563                "na_dev(): rsbac_get_attr() returned error!\n");
00564         return(NOT_GRANTED);
00565       }
00566     object_class = i_attr_val1.pm_object_class;
00567 
00568     /* get necessary accesses */
00569     i_pm_tid.na.task = task;
00570     i_pm_tid.na.object_class = object_class;
00571     i_pm_tid.na.tp = tp;
00572     if ((error = rsbac_pm_get_data(0,
00573                                    PMT_NA,
00574                                    i_pm_tid,
00575                                    PD_accesses,
00576                                    &i_data_val1)))
00577       {
00578         if(error != -RSBAC_EINVALIDTARGET)
00579           printk(KERN_WARNING
00580                  "na_dev(): rsbac_pm_get_data() returned error %i!\n",
00581                  error);
00582           return(NOT_GRANTED);
00583       }
00584     /* is requested access mode included in access mask? */
00585     if((acc & i_data_val1.accesses) == acc)
00586       return(GRANTED);
00587     else
00588       return(NOT_GRANTED);
00589   }
00590 
00591 /* This function does the adjustment of input- and output-purpose-set of */
00592 /* the calling process according to type of access and purpose set of class */
00593 /* of file. */
00594 static int
00595   adjust_in_out_pp(       rsbac_pid_t          caller_pid,
00596                    enum   rsbac_target_t       target,
00597                    struct rsbac_fs_file_t      file,
00598                           rsbac_pm_accesses_t  acc)
00599   {
00600     rsbac_pm_object_class_id_t    object_class;
00601     union rsbac_target_id_t       i_tid;
00602     union rsbac_attribute_value_t i_attr_val1;
00603     union rsbac_pm_target_id_t    i_pm_tid;
00604     union rsbac_pm_data_value_t   i_data_val1;
00605           int                     error;
00606     
00607     /* get pm_object_type of file */
00608     i_tid.file = file;
00609     if (rsbac_get_attr(PM,
00610                        target,
00611                        i_tid,
00612                        A_pm_object_type,
00613                        &i_attr_val1,
00614                        FALSE))
00615       {
00616         printk(KERN_WARNING
00617                "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00618         return(-RSBAC_EREADFAILED);
00619       }
00620     /* we only adjust for personal_data */
00621     if(i_attr_val1.pm_object_type != PO_personal_data)
00622       return(0);
00623                   
00624     /* only personal_data left -> */
00625     /* get object_class of file */
00626     i_tid.file = file;
00627     if (rsbac_get_attr(PM,
00628                        target,
00629                        i_tid,
00630                        A_pm_object_class,
00631                        &i_attr_val1,
00632                        FALSE))
00633       {
00634         printk(KERN_WARNING
00635                "adjust_in_out_pp(): rsbac_get_attr() returned error!\n");
00636         return(-RSBAC_EREADFAILED);
00637       }
00638     object_class = i_attr_val1.pm_object_class;
00639     /* if there is no class for this file, this is an error!   */
00640     /* (all personal data must have a class assigned, and here */
00641     /* must never be anything else)        */
00642     if(!object_class)
00643       {
00644 #ifdef CONFIG_RSBAC_DEBUG
00645         if(rsbac_debug_adf_pm)
00646           printk(KERN_WARNING
00647                  "adjust_in_out_pp(): personal_data with NIL class!\n");
00648 #endif
00649         return(-RSBAC_EINVALIDVALUE);
00650       }
00651 
00652     /* get pp_set-id of class */
00653     i_pm_tid.object_class = object_class;
00654     if ((error = rsbac_pm_get_data(0,
00655                                    PMT_CLASS,
00656                                    i_pm_tid,
00657                                    PD_pp_set,
00658                                    &i_data_val1)))
00659       {
00660         if(error != -RSBAC_EINVALIDTARGET)
00661           printk(KERN_WARNING
00662                  "adjust_in_out_pp(): rsbac_pm_get_data() returned error %i!\n",
00663                  error);
00664         else
00665           printk(KERN_WARNING
00666                  "adjust_in_out_pp(): class %i of file does not exist!\n",
00667                  object_class);
00668         return(-RSBAC_EREADFAILED);
00669       }
00670 
00671     /* adjust information flow check boundaries */
00672 
00673     /* read access: create intersection of input-purpose-set of process and  */
00674     /* purpose-set of class of file in input-purpose-set of process */
00675     /* (Input purpose set id is process id) */
00676     if(   (acc & RSBAC_PM_A_READ)
00677        && rsbac_pm_pp_intersec(i_data_val1.pp_set, caller_pid) )
00678       {
00679         printk(KERN_WARNING
00680                  "adjust_in_out_pp(): call to rsbac_pm_pp_intersec failed\n");
00681         error = -RSBAC_EWRITEFAILED;
00682       }
00683 
00684     /* write access: create union of output-purpose-set of process and  */
00685     /* purpose-set of class of file in output-purpose-set of process */
00686     /* (Output purpose set id is process id) */
00687     if(   (acc & RSBAC_PM_A_WRITE_TO_FILE)
00688        && rsbac_pm_pp_union(i_data_val1.pp_set, caller_pid) )
00689       {
00690         printk(KERN_WARNING
00691                  "adjust_in_out_pp(): call to rsbac_pm_pp_union failed\n");
00692         error = -RSBAC_EWRITEFAILED;
00693       }
00694 
00695     /* OK, everything is done. */
00696     return(error);
00697   }
00698 
00699 /* This function does the adjustment of input- and output-purpose-set of */
00700 /* the calling process according to type of access and ipc-purpose of ipc */
00701 /* object. */
00702 static int
00703   adjust_in_out_pp_ipc(   rsbac_pid_t          caller_pid,
00704                    struct rsbac_ipc_t          ipc,
00705                           rsbac_pm_accesses_t  acc)
00706   {
00707     union rsbac_pm_set_id_t       i_pm_set_id;
00708     union rsbac_pm_set_member_t   i_pm_set_member;
00709           rsbac_pm_purpose_id_t   i_pm_pp;
00710           int                     error = 0;
00711     
00712     /* get IPC-purpose */
00713     i_pm_pp = get_ipc_purpose(ipc);
00714     /* if ipc_purpose is 0, this cannot be a TP -> no access to personal data */
00715     /* -> no flow control */
00716     if(!i_pm_pp)
00717       return(0);
00718     
00719     /* adjust information flow check boundaries */
00720 
00721     /* read access: create intersection of input-purpose-set of process and */
00722     /* purpose-set of ipc in input-purpose-set of process -> clear set and */
00723     /* add ipc-purpose, because ipc-purpose must have been in it at decision */
00724     /* (Input purpose set id is process id) */
00725     if(acc & RSBAC_PM_A_READ)
00726       {
00727         i_pm_set_id.in_pp_set = caller_pid;
00728         /* if set does not exist, create it */
00729         if(   !rsbac_pm_set_exist(0,PS_IN_PP, i_pm_set_id) 
00730            && rsbac_pm_create_set(0,PS_IN_PP, i_pm_set_id) )
00731             {
00732               printk(KERN_WARNING
00733                      "adjust_in_out_pp_ipc(): call to rsbac_pm_create_set returned error\n");
00734               error = -RSBAC_EWRITEFAILED;
00735             }
00736         if(rsbac_pm_clear_set(0,PS_IN_PP, i_pm_set_id) )
00737           {
00738             printk(KERN_WARNING
00739                    "adjust_in_out_pp_ipc(): call to rsbac_pm_clear_set returned error\n");
00740             error = -RSBAC_EWRITEFAILED;
00741           }
00742         i_pm_set_member.pp = i_pm_pp;
00743         if(rsbac_pm_add_to_set(0,PS_IN_PP, i_pm_set_id, i_pm_set_member) )
00744           {
00745             printk(KERN_WARNING
00746                    "adjust_in_out_pp_ipc(): call to rsbac_pm_add_to_set returned error\n");
00747             error = -RSBAC_EWRITEFAILED;
00748           }
00749       }
00750 
00751     /* write access: create union of output-purpose-set of process and */
00752     /* purpose-set of ipc in output-purpose-set of process -> */
00753     /* add ipc-purpose to output-purpose-set */
00754     /* (Input purpose set id is process id) */
00755     if(acc & RSBAC_PM_A_WRITE_TO_FILE)
00756       {
00757         i_pm_set_id.out_pp_set = caller_pid;
00758         /* if set does not exist, create it */
00759         if(   !rsbac_pm_set_exist(0,PS_OUT_PP, i_pm_set_id) 
00760            && rsbac_pm_create_set(0,PS_OUT_PP, i_pm_set_id) )
00761             {
00762               printk(KERN_WARNING
00763                      "adjust_in_out_pp_ipc(): call to rsbac_pm_create_set returned error\n");
00764               error = -RSBAC_EWRITEFAILED;
00765             }
00766         /* add ipc_purpose to set */
00767         i_pm_set_member.pp = i_pm_pp;
00768         if(rsbac_pm_add_to_set(0,PS_OUT_PP, i_pm_set_id, i_pm_set_member) )
00769           {
00770             printk(KERN_WARNING
00771                    "adjust_in_out_pp_ipc(): call to rsbac_pm_add_to_set returned error\n");
00772             error = -RSBAC_EWRITEFAILED;
00773           }
00774       }
00775 
00776     /* OK, everything is done. */
00777     return(error);
00778   }
00779 
00780 
00781 /************************************************* */
00782 /*          Externally visible functions           */
00783 /************************************************* */
00784 
00785 enum rsbac_adf_req_ret_t
00786    rsbac_adf_request_pm  (enum  rsbac_adf_request_t     request,
00787                                 rsbac_pid_t             caller_pid,
00788                           enum  rsbac_target_t          target,
00789                           union rsbac_target_id_t       tid,
00790                           enum  rsbac_attribute_t       attr,
00791                           union rsbac_attribute_value_t attr_val,
00792                                 rsbac_uid_t             owner)
00793   {
00794     enum  rsbac_adf_req_ret_t result = DO_NOT_CARE;
00795     union rsbac_target_id_t       i_tid;
00796     union rsbac_attribute_value_t i_attr_val1;
00797     union rsbac_attribute_value_t i_attr_val2;
00798     union rsbac_pm_target_id_t    i_pm_tid;
00799     union rsbac_pm_data_value_t   i_data_val1;
00800     union rsbac_pm_set_id_t       i_pm_set_id;
00801     union rsbac_pm_set_member_t   i_pm_set_member;
00802           rsbac_pm_purpose_id_t   i_pm_pp;
00803           int                     error;
00804 
00805     switch (request)
00806       {
00807         case R_ADD_TO_KERNEL:
00808             switch(target)
00809               {
00810                 case T_NONE:
00811                   /* test owner's pm_role */
00812                   i_tid.user = owner;
00813                   if (rsbac_get_attr(PM,
00814                        T_USER,
00815                                      i_tid,
00816                                      A_pm_role,
00817                                      &i_attr_val1,
00818                                      TRUE))
00819                     {
00820                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00821                       return(NOT_GRANTED);
00822                     }
00823                   /* only administrators are allowed to do this */
00824                   if (i_attr_val1.pm_role != PR_system_admin)
00825                     return(NOT_GRANTED);
00826                   else
00827                     return(GRANTED);
00828 
00829                 /* all other cases */
00830                 default:
00831                   return(DO_NOT_CARE);
00832               }
00833 
00834         case R_ALTER:
00835             /* only for IPC */
00836             if (target == T_IPC)
00837               return (DO_NOT_CARE);
00838             else
00839             /* all other targets are undefined */
00840               return (DO_NOT_CARE);
00841             break;
00842 
00843         case R_APPEND_OPEN:
00844             switch(target)
00845               {
00846                 case T_FILE:
00847                 case T_FIFO:
00848                   /* get pm_object_type of target */
00849                   if (rsbac_get_attr(PM,
00850                        target,
00851                                      tid,
00852                                      A_pm_object_type,
00853                                      &i_attr_val1,
00854                                      FALSE))
00855                     {
00856                       printk(KERN_WARNING
00857                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00858                       return(NOT_GRANTED);
00859                     }
00860                   /* no append_open on TPs */
00861                   if(i_attr_val1.pm_object_type == PO_TP)
00862                     return(NOT_GRANTED);
00863                   /* TPs must not write on other than personal_data */
00864                   if(i_attr_val1.pm_object_type != PO_personal_data)
00865                     return(tp_check(caller_pid));
00866                   
00867                   /* only personal_data left -> */
00868                   /* check necessary && (purpose_bind || consent) */
00869                   return(na_and_pp_or_cs(caller_pid,
00870                                          tid.file,
00871                                          RSBAC_PM_A_APPEND));
00872                   break;
00873 
00874                 /* Appending to devices is no problem here */
00875                 case T_DEV:
00876                   return(DO_NOT_CARE);
00877 
00878                 case T_IPC:
00879                   /* get IPC-purpose */
00880                   i_pm_pp = get_ipc_purpose(tid.ipc);
00881                   /* if IPC-pp is NIL -> process type must be NIL */
00882                   if(!i_pm_pp)
00883                     {
00884                       /* get process-type of caller-process */
00885                       i_tid.process = caller_pid;
00886                       if (rsbac_get_attr(PM,
00887                        T_PROCESS,
00888                                          i_tid,
00889                                          A_pm_process_type,
00890                                          &i_attr_val1,
00891                                          FALSE))
00892                         { 
00893                           printk(KERN_WARNING
00894                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00895                           return(NOT_GRANTED);
00896                         }
00897                       if(i_attr_val1.pm_process_type == PP_TP)
00898                         return(NOT_GRANTED);
00899                       else
00900                         return(GRANTED);
00901                     }
00902                   /* OK, we do have an IPC-purpose */                  
00903                   /* get current_task of caller-process */
00904                   i_tid.process = caller_pid;
00905                   if (rsbac_get_attr(PM,
00906                        T_PROCESS,
00907                                      i_tid,
00908                                      A_pm_current_task,
00909                                      &i_attr_val1,
00910                                      FALSE))
00911                     {
00912                       printk(KERN_WARNING
00913                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00914                       return(NOT_GRANTED);
00915                     }
00916                   /* if current_task = NIL -> do not grant */
00917                   if(!i_attr_val1.pm_current_task)
00918                     {
00919                         return(NOT_GRANTED);
00920                     }
00921                   /* check necessary && purpose_bind */
00922                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
00923                                        caller_pid,
00924                                        RSBAC_PM_A_APPEND,
00925                                        tid.ipc));
00926                   break;
00927 
00928                 /* all other cases are undefined */
00929                 default: return(DO_NOT_CARE);
00930               }
00931 
00932         case R_CHANGE_GROUP:
00933             switch(target)
00934               {
00935                 /* We do not care about process or user groups */
00936                 /* all other cases */
00937                 default: return(DO_NOT_CARE);
00938               }
00939 
00940         case R_CHANGE_OWNER:
00941             switch(target)
00942               {
00943                 case T_FILE:
00944                 case T_FIFO:
00945                 case T_SYMLINK:
00946                   /* get pm_object_type of target */
00947                   if (rsbac_get_attr(PM,
00948                        target,
00949                                      tid,
00950                                      A_pm_object_type,
00951                                      &i_attr_val1,
00952                                      FALSE))
00953                     {
00954                       printk(KERN_WARNING
00955                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00956                       return(NOT_GRANTED);
00957                     }
00958                   /* no access on TPs and personal_data*/
00959                   if(   (i_attr_val1.pm_object_type == PO_TP)
00960                      || (i_attr_val1.pm_object_type == PO_personal_data))
00961                     return(NOT_GRANTED);
00962                   else
00963                     return(GRANTED);
00964                   break;
00965 
00966                 /*  processes may only be given to other user, if    */
00967                 /*  current_task is authorized for him.              */
00968                 /*  If CONFIG_RSBAC_PM_ROLE_PROT is set, only changing  */
00969                 /*  to or from pm_role general_user is allowed.      */
00970                 case T_PROCESS:
00971                   #ifdef CONFIG_RSBAC_PM_ROLE_PROT
00972                   /* For target process there MUST be a new owner specified */
00973                   if (attr != A_owner)
00974                     return(UNDEFINED);
00975                   /* general user? */
00976                   i_tid.user = owner;
00977                   if (rsbac_get_attr(PM,
00978                        T_USER,
00979                                      i_tid,
00980                                      A_pm_role,
00981                                      &i_attr_val1,
00982                                      TRUE))
00983                     {
00984                       printk(KERN_WARNING
00985                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00986                       return(NOT_GRANTED);
00987                     }
00988                   /* only check further, if not general user */
00989                   if (i_attr_val1.pm_role != PR_user)
00990                     {
00991                       /* get target user's role */
00992                       i_tid.user = attr_val.owner;
00993                       if (rsbac_get_attr(PM,
00994                        T_USER,
00995                                          i_tid,
00996                                          A_pm_role,
00997                                          &i_attr_val2,
00998                                          TRUE))
00999                         {
01000                           printk(KERN_WARNING
01001                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01002                           return(NOT_GRANTED);
01003                         }
01004                       /* target is also no general user -> deny,
01005                        * if different role */
01006                       if(   (i_attr_val2.pm_role != PR_user)
01007                          && (i_attr_val1.pm_role != i_attr_val2.pm_role)
01008                         )
01009                         return(NOT_GRANTED);
01010                     }
01011                   /* OK, role check passed */
01012                   #endif
01013 
01014                   /* get current_task of caller-process */
01015                   i_tid.process = caller_pid;
01016                   if (rsbac_get_attr(PM,
01017                        T_PROCESS,
01018                                      i_tid,
01019                                      A_pm_current_task,
01020                                      &i_attr_val1,
01021                                      FALSE))
01022                     {
01023                       printk(KERN_WARNING
01024                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01025                       return(NOT_GRANTED);
01026                     }
01027                   /* if task = NIL: no problem, grant */
01028                   if(!i_attr_val1.pm_current_task)
01029                     return(GRANTED);
01030 
01031                   /* get task_set_id of process-owner */
01032                   i_tid.user = owner;
01033                   if (rsbac_get_attr(PM,
01034                        T_USER,
01035                                      i_tid,
01036                                      A_pm_task_set,
01037                                      &i_attr_val2,
01038                                      FALSE))
01039                     {
01040                       printk(KERN_WARNING
01041                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01042                       return(NOT_GRANTED);
01043                     }
01044                   /* if user has no set of authorized tasks -> do not grant */
01045                   if(!i_attr_val2.pm_task_set)
01046                     return(NOT_GRANTED);
01047 
01048                   /* grant, if task is in owner's authorized task_set */
01049                   i_pm_set_id.task_set = i_attr_val2.pm_task_set;
01050                   i_pm_set_member.task = i_attr_val1.pm_current_task;
01051                   if (rsbac_pm_set_member(0,PS_TASK,i_pm_set_id,i_pm_set_member))
01052                     return(GRANTED);
01053                   /* else: don't... */
01054                   else
01055                     return(NOT_GRANTED);
01056 
01057                 /* Change-owner without or for other target: do not care */
01058                 case T_DIR:
01059                 case T_IPC:
01060                 case T_NONE:
01061                   return(DO_NOT_CARE);
01062                 /* all other cases are undefined */
01063                 default:
01064                   return(DO_NOT_CARE);
01065               }
01066 
01067         case R_CLONE:
01068             if (target == T_PROCESS)
01069               {
01070                 /* get process_type of caller-process */
01071                 i_tid.process = caller_pid;
01072                 if (rsbac_get_attr(PM,
01073                        T_PROCESS,
01074                                    i_tid,
01075                                    A_pm_process_type,
01076                                    &i_attr_val1,
01077                                    FALSE))
01078                   {
01079                     printk(KERN_WARNING
01080                            "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01081                     return(NOT_GRANTED);
01082                   }
01083                 /* cloning is only allowed for normal processes */
01084                 if(i_attr_val1.pm_process_type == PP_none)
01085                   return(GRANTED);
01086                 else
01087                   return(NOT_GRANTED);
01088               }
01089             else
01090               return(DO_NOT_CARE);
01091 
01092         case R_CREATE:
01093             switch(target)
01094               {
01095                 /* Creating dir or (pseudo) file IN target dir! */
01096                 case T_DIR: 
01097                   /* get process_type of caller-process */
01098                   i_tid.process = caller_pid;
01099                   if (rsbac_get_attr(PM,
01100                        T_PROCESS,
01101                                      i_tid,
01102                                      A_pm_process_type,
01103                                      &i_attr_val1,
01104                                      FALSE))
01105                     {
01106                       printk(KERN_WARNING
01107                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01108                       return(NOT_GRANTED);
01109                     }
01110                   /* we only care for TPs here */
01111                   if(i_attr_val1.pm_process_type != PP_TP)
01112                     return(DO_NOT_CARE);
01113 
01114                   /* get current_task of caller-process */
01115                   i_tid.process = caller_pid;
01116                   if (rsbac_get_attr(PM,
01117                        T_PROCESS,
01118                                      i_tid,
01119                                      A_pm_current_task,
01120                                      &i_attr_val1,
01121                                      FALSE))
01122                     {
01123                       printk(KERN_WARNING
01124                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01125                              return(NOT_GRANTED);
01126                     }
01127                   if(!i_attr_val1.pm_current_task)
01128                     {
01129 #ifdef CONFIG_RSBAC_DEBUG
01130                       if(rsbac_debug_adf_pm)
01131                         printk(KERN_DEBUG
01132                                "rsbac_adf_request_pm(): no current_task for calling process trying to access personal_data\n");
01133 #endif
01134                       return(NOT_GRANTED);
01135                     }
01136 
01137                   /* get pm_tp of caller-process */
01138                   if (rsbac_get_attr(PM,
01139                        T_PROCESS,
01140                                      i_tid,
01141                                      A_pm_tp,
01142                                      &i_attr_val2,
01143                                      FALSE))
01144                     {
01145                       printk(KERN_WARNING
01146                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01147                       return(NOT_GRANTED);
01148                     }
01149                   if(!i_attr_val2.pm_tp)
01150                     {
01151 #ifdef CONFIG_RSBAC_DEBUG
01152                       if(rsbac_debug_adf_pm)
01153                         printk(KERN_DEBUG
01154                                "rsbac_adf_request_pm(): calling process trying to access personal_data has no TP-id\n");
01155 #endif
01156                       return(NOT_GRANTED);
01157                     }
01158 
01159                   /* get necessary accesses for NIL class */
01160                   i_pm_tid.na.task = i_attr_val1.pm_current_task;
01161                   i_pm_tid.na.object_class = 0;
01162                   i_pm_tid.na.tp = i_attr_val2.pm_tp;
01163                   if ((error = rsbac_pm_get_data(0,
01164                                                  PMT_NA,
01165                                                  i_pm_tid,
01166                                                  PD_accesses,
01167                                                  &i_data_val1)))
01168                     {
01169                       if(error != -RSBAC_EINVALIDTARGET)
01170                         printk(KERN_WARNING
01171                                "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
01172                                error);
01173                       return(NOT_GRANTED);
01174                     }
01175                   /* is requested access mode included in access mask? */
01176                   if(!(RSBAC_PM_A_CREATE & i_data_val1.accesses))
01177                     {
01178 #ifdef CONFIG_RSBAC_DEBUG
01179                       if(rsbac_debug_adf_pm)
01180                         printk(KERN_DEBUG
01181                                "rsbac_adf_request_pm(): requested access mode CREATE for class NIL is not necessary\n");
01182 #endif
01183                       return(NOT_GRANTED);
01184                     }
01185 
01186                   /* OK, create is necessary -> grant */
01187                   return(GRANTED);
01188                   break;
01189                   
01190                 case T_IPC:
01191                   /* get current_task of caller-process */
01192                   i_tid.process = caller_pid;
01193                   if (rsbac_get_attr(PM,
01194                        T_PROCESS,
01195                                      i_tid,
01196                                      A_pm_current_task,
01197                                      &i_attr_val1,
01198                                      FALSE))
01199                     {
01200                       printk(KERN_WARNING
01201                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01202                       return(NOT_GRANTED);
01203                     }
01204                   /* if current_task = NIL, do not care */
01205                   if(!i_attr_val1.pm_current_task)
01206                     return(DO_NOT_CARE);
01207 
01208                   /* check necessary */
01209                   return(na_ipc(i_attr_val1.pm_current_task,
01210                                 caller_pid,
01211                                 RSBAC_PM_A_CREATE));
01212                   break;
01213 
01214                 /* all other cases are undefined */
01215                 default: return(DO_NOT_CARE);
01216               }
01217 
01218         case R_DELETE:
01219             switch(target)
01220               {
01221                 case T_FILE:
01222                 case T_FIFO:
01223                 case T_SYMLINK:
01224                   /* get pm_object_type of target */
01225                   if (rsbac_get_attr(PM,
01226                        target,
01227                                      tid,
01228                                      A_pm_object_type,
01229                                      &i_attr_val1,
01230                                      FALSE))
01231                     {
01232                       printk(KERN_WARNING
01233                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01234                       return(NOT_GRANTED);
01235                     }
01236                   /* if TP: only TP_Manager */
01237                   if(i_attr_val1.pm_object_type == PO_TP)
01238                     {
01239                       /* test owner's pm_role */
01240                       i_tid.user = owner;
01241                       if (rsbac_get_attr(PM,
01242                        T_USER,
01243                                          i_tid,
01244                                          A_pm_role,
01245                                          &i_attr_val1,
01246                                          TRUE))
01247                         {
01248                           printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01249                           return(NOT_GRANTED);
01250                         }
01251                       if(i_attr_val1.pm_role == PR_tp_manager)
01252                         return(GRANTED);
01253                       else
01254                         return(NOT_GRANTED);
01255                     }
01256                   /* do not care for other than personal_data */
01257                   if(i_attr_val1.pm_object_type != PO_personal_data)
01258                     return(DO_NOT_CARE);
01259                   
01260                   /* check necessary && (purpose_bind || consent) */
01261                   /* (in fact, necessary means allowed here) */
01262                   return(na_and_pp_or_cs(caller_pid,
01263                                          tid.file,
01264                                          RSBAC_PM_A_DELETE));
01265                   break;
01266 
01267                 case T_IPC:
01268                   /* get current_task of caller-process */
01269                   i_tid.process = caller_pid;
01270                   if (rsbac_get_attr(PM,
01271                        T_PROCESS,
01272                                      i_tid,
01273                                      A_pm_current_task,
01274                                      &i_attr_val1,
01275                                      FALSE))
01276                     {
01277                       printk(KERN_WARNING
01278                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01279                       return(NOT_GRANTED);
01280                     }
01281                   /* if current_task = NIL, ipc_purpose must be NIL */
01282                   if(!i_attr_val1.pm_current_task)
01283                     {
01284                       if(!get_ipc_purpose(tid.ipc))
01285                         return(GRANTED);
01286                       else
01287                         return(NOT_GRANTED);
01288                     }
01289                   /* check necessary && purpose_bind */
01290                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01291                                        caller_pid,
01292                                        RSBAC_PM_A_DELETE,
01293                                        tid.ipc));
01294                   break;
01295 
01296                 case T_DIR:
01297                       return(DO_NOT_CARE);
01298                   break;
01299                 /* all other cases are undefined */
01300                 default: return(DO_NOT_CARE);
01301               }
01302 
01303         case R_EXECUTE:
01304             switch(target)
01305               {
01306                 case T_FILE:
01307                   /* get pm_object_type of target */
01308                   if (rsbac_get_attr(PM,
01309                        T_FILE,
01310                                      tid,
01311                                      A_pm_object_type,
01312                                      &i_attr_val1,
01313                                      FALSE))
01314                     {
01315                       printk(KERN_WARNING
01316                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01317                       return(NOT_GRANTED);
01318                     }
01319                   /* if not TP: do not care */
01320                   if(i_attr_val1.pm_object_type != PO_TP)
01321                     return(DO_NOT_CARE);
01322 
01323                   /* get pm_tp of target */
01324                   if (rsbac_get_attr(PM,
01325                        T_FILE,
01326                                      tid,
01327                                      A_pm_tp,
01328                                      &i_attr_val1,
01329                                      FALSE))
01330                     {
01331                       printk(KERN_WARNING
01332                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01333                       return(NOT_GRANTED);
01334                     }
01335                   /* if no tp: error! */
01336                   if(!i_attr_val1.pm_tp)
01337                     {
01338                       printk(KERN_WARNING
01339                              "rsbac_adf_request_pm(): file with object_type TP has no tp_id!\n");
01340                       return(NOT_GRANTED);
01341                     }
01342                   /* get current_task of caller-process */
01343                   i_tid.process = caller_pid;
01344                   if (rsbac_get_attr(PM,
01345                        T_PROCESS,
01346                                      i_tid,
01347                                      A_pm_current_task,
01348                                      &i_attr_val2,
01349                                      FALSE))
01350                     {
01351                       printk(KERN_WARNING
01352                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01353                       return(NOT_GRANTED);
01354                     }
01355                   /* if there is no current task, do not grant */
01356                   if(!i_attr_val2.pm_current_task)
01357                     {
01358 #ifdef CONFIG_RSBAC_DEBUG
01359                       if(rsbac_debug_adf_pm)
01360                         printk(KERN_DEBUG
01361                                "rsbac_adf_request_pm(): no current_task for process trying to execute TP\n");
01362 #endif
01363                       return(NOT_GRANTED);
01364                     }
01365                   /* get tp_set_id of current_task */
01366                   i_pm_tid.task = i_attr_val2.pm_current_task;
01367                   if ((error = rsbac_pm_get_data(0,
01368                                                  PMT_TASK,
01369                                                  i_pm_tid,
01370                                                  PD_tp_set,
01371                                                  &i_data_val1)))
01372                     {
01373                       if(error != -RSBAC_EINVALIDTARGET)
01374                         printk(KERN_WARNING
01375                                "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
01376                                error);
01377                       return(NOT_GRANTED);
01378                     }
01379                   /* if there is no tp set, do not grant */
01380                   if(!i_data_val1.tp_set)
01381                     {
01382 #ifdef CONFIG_RSBAC_DEBUG
01383                       if(rsbac_debug_adf_pm)
01384                         printk(KERN_DEBUG
01385                                "rsbac_adf_request_pm(): no tp_set for current_task of process trying to execute TP\n");
01386 #endif
01387                       return(NOT_GRANTED);
01388                     }
01389                   
01390                   /* grant, if file's tp is in process-current-task's */
01391                   /* authorized tp_set */
01392                   i_pm_set_id.tp_set = i_data_val1.tp_set;
01393                   i_pm_set_member.tp = i_attr_val1.pm_tp;
01394                   if (rsbac_pm_set_member(0,PS_TP,i_pm_set_id,i_pm_set_member))
01395                     return(GRANTED);
01396                   /* else: don't... */
01397                   else
01398                     {
01399 #ifdef CONFIG_RSBAC_DEBUG
01400                       if(rsbac_debug_adf_pm)
01401                         printk(KERN_DEBUG
01402                                "rsbac_adf_request_pm(): tp %i of file is not in tp_set %i of current_task %i of process\n",
01403                                i_attr_val1.pm_tp, i_data_val1.tp_set, i_attr_val2.pm_current_task);
01404 #endif
01405                       return(NOT_GRANTED);
01406                     }
01407 
01408                 /* all other cases are undefined */
01409                 default:
01410                   return(DO_NOT_CARE);
01411               }
01412 
01413         case R_GET_STATUS_DATA:
01414             switch(target)
01415               {
01416                 case T_SCD:
01417                   /* target rsbaclog? only for secoff and dataprot */
01418                   if (tid.scd != ST_rsbaclog)
01419                     return(GRANTED);
01420                   /* Secoff or dataprot? */
01421                   i_tid.user = owner;
01422                   if ((error=rsbac_get_attr(PM,
01423                        T_USER,
01424                                      i_tid,
01425                                      A_pm_role,
01426                                      &i_attr_val1,
01427                                      TRUE)))
01428                     {
01429                       printk(KERN_WARNING
01430                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error %i!\n",
01431                              error);
01432                       return(NOT_GRANTED);
01433                     }
01434                   /* grant only for secoff and dataprot */
01435                   if (   (i_attr_val1.pm_role == PR_security_officer)
01436                       || (i_attr_val1.pm_role == PR_data_protection_officer)
01437                      )
01438                     return(GRANTED);
01439                   else
01440                     return(NOT_GRANTED);
01441                 default:
01442                   return(DO_NOT_CARE);
01443                };
01444 
01445         case R_LINK_HARD:
01446             switch(target)
01447               {
01448                 case T_FILE:
01449                 case T_FIFO:
01450                 case T_SYMLINK:
01451                   /* get pm_object_type of target */
01452                   if (rsbac_get_attr(PM,
01453                        target,
01454                                      tid,
01455                                      A_pm_object_type,
01456                                      &i_attr_val1,
01457                                      FALSE))
01458                     {
01459                       printk(KERN_WARNING
01460                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01461                       return(NOT_GRANTED);
01462                     }
01463                   /* if OT = TP or OT = personal_data -> do not grant, else do */
01464                   if(   (i_attr_val1.pm_object_type == PO_TP)
01465                      || (i_attr_val1.pm_object_type == PO_personal_data))
01466                     return(NOT_GRANTED);
01467                   else
01468                     return(GRANTED);
01469                   break;
01470                 /* all other cases are undefined */
01471                 default: return(DO_NOT_CARE);
01472               }
01473 
01474         case R_MODIFY_ACCESS_DATA:
01475         case R_RENAME:
01476             switch(target)
01477               {
01478                 case T_FILE:
01479                 case T_FIFO:
01480                 case T_SYMLINK:
01481                   /* get pm_object_type of target */
01482                   if (rsbac_get_attr(PM,
01483                        target,
01484                                      tid,
01485                                      A_pm_object_type,
01486                                      &i_attr_val1,
01487                                      FALSE))
01488                     {
01489                       printk(KERN_WARNING
01490                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01491                       return(NOT_GRANTED);
01492                     }
01493 
01494                   /* if personal_data -> do not grant */
01495                   if(i_attr_val1.pm_object_type == PO_personal_data)
01496                     return(NOT_GRANTED);
01497                   /* alternative: check necessary && (purpose_bind || consent) */
01498                   /* return(na_and_pp_or_cs(caller_pid,
01499                                          tid.file,
01500                                          RSBAC_PM_A_WRITE)); */
01501 
01502                   /* if TP: only TP_Manager, else: do not care */
01503                   if(i_attr_val1.pm_object_type != PO_TP)
01504                     return(DO_NOT_CARE);
01505                   /* test owner's pm_role */
01506                   i_tid.user = owner;
01507                   if (rsbac_get_attr(PM,
01508                        T_USER,
01509                                      i_tid,
01510                                      A_pm_role,
01511                                      &i_attr_val1,
01512                                      TRUE))
01513                     {
01514                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01515                       return(NOT_GRANTED);
01516                     }
01517                   if(i_attr_val1.pm_role == PR_tp_manager)
01518                     return(GRANTED);
01519                   else
01520                     return(NOT_GRANTED);
01521                   break;
01522 
01523                 case T_DIR:
01524                   return(DO_NOT_CARE);
01525                   break;
01526                 /* all other cases are undefined */
01527                 default: return(DO_NOT_CARE);
01528               }
01529 
01530         case R_MODIFY_ATTRIBUTE:
01531             switch(attr)
01532               {
01533                 /* all pm relevant attributes are changed via sys_rsbac_pm */
01534                 /* using tickets in most cases -> deny here */
01535                 case A_pm_object_type:
01536                 case A_pm_tp:
01537                 case A_pm_role:
01538                 case A_pm_process_type:
01539                 case A_pm_current_task:
01540                 case A_pm_object_class:
01541                 case A_pm_ipc_purpose:
01542                 case A_pm_program_type:
01543                 case A_pm_task_set:
01544                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01545                 case A_owner:
01546                 case A_pseudo:
01547                 #endif
01548                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01549                 case A_auth_may_setuid:
01550                 case A_auth_may_set_cap:
01551                 case A_auth_start_uid:
01552                 case A_auth_program_file:
01553                 #endif
01554                   return(NOT_GRANTED);
01555                 /* All attributes (remove target!) */
01556                 case A_none:
01557                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01558                 case A_auth_add_f_cap:
01559                 case A_auth_remove_f_cap:
01560                 case A_auth_learn:
01561                 #endif
01562                   switch(target)
01563                     { /* special care for pm-relevant files and devs*/
01564                       case T_FILE:
01565                       case T_FIFO:
01566                       case T_DEV:
01567                         /* get object_type */
01568                         if (rsbac_get_attr(PM,
01569                        target,
01570                                            tid,
01571                                            A_pm_object_type,
01572                                            &i_attr_val1,
01573                                            FALSE))
01574                           {
01575                             printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01576                             return(NOT_GRANTED);
01577                           }
01578                         /* if OT is PM-relevant -> do not grant */
01579                         if(   (i_attr_val1.pm_object_type != PO_none)
01580                            && (i_attr_val1.pm_object_type != PO_non_personal_data))
01581                           return(NOT_GRANTED);
01582                         else
01583                           return(GRANTED);
01584 
01585                       /* we do not care for dirs or symlinks */
01586                       case T_DIR:
01587                       case T_SYMLINK:
01588                         return(DO_NOT_CARE);
01589                       
01590                       /* we do care for users, and if PM is active, we use  */
01591                       /* tickets to delete user attributes, so do not grant.*/ 
01592                       /* take care: if other models are active, their       */
01593                       /* additional restrictions are not met!               */
01594                       case T_USER:
01595                         return(NOT_GRANTED);
01596 
01597                       /* no removing of process attributes */
01598                       case T_PROCESS:
01599                         return(NOT_GRANTED);
01600 
01601                       case T_IPC:
01602                         /* get ipc_purpose */
01603                         if (rsbac_get_attr(PM,
01604                        T_IPC,
01605                                            tid,
01606                                            A_pm_ipc_purpose,
01607                                            &i_attr_val1,
01608                                            FALSE))
01609                           {
01610                             printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01611                             return(NOT_GRANTED);
01612                           }
01613                         /* if a purpose is set -> do not grant, else: who cares? */
01614                         if(i_attr_val1.pm_ipc_purpose)
01615                           return(NOT_GRANTED);
01616                         else
01617                           return(GRANTED);
01618 
01619                       default:
01620                         return(DO_NOT_CARE);
01621                     }
01622 
01623                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01624                 case A_log_array_low:
01625                 case A_log_array_high:
01626                 case A_log_program_based:
01627                 case A_log_user_based:
01628                 case A_symlink_add_uid:
01629                 case A_fake_root_uid:
01630                 case A_audit_uid:
01631                 case A_auid_exempt:
01632                   /* test owner's pm_role */
01633                   i_tid.user = owner;
01634                   if (rsbac_get_attr(PM,
01635                                      T_USER,
01636                                      i_tid,
01637                                      A_pm_role,
01638                                      &i_attr_val1,
01639                                      TRUE))
01640                     {
01641                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01642                       return(NOT_GRANTED);
01643                     }
01644                   /* security officer? -> grant  */
01645                   if (i_attr_val1.pm_role == PR_security_officer)
01646                     return(GRANTED);
01647                   else
01648                     return(NOT_GRANTED);
01649                 #endif
01650 
01651                 default:
01652                   return(DO_NOT_CARE);
01653               }
01654 
01655         case R_MODIFY_PERMISSIONS_DATA:
01656             switch(target)
01657               {
01658                 case T_FILE:
01659                 case T_FIFO:
01660                   /* get pm_object_type of target */
01661                   if (rsbac_get_attr(PM,
01662                        target,
01663                                      tid,
01664                                      A_pm_object_type,
01665                                      &i_attr_val1,
01666                                      FALSE))
01667                     {
01668                       printk(KERN_WARNING
01669                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01670                       return(NOT_GRANTED);
01671                     }
01672                   /* if TP: only TP_Manager, else: do not care */
01673                   if(i_attr_val1.pm_object_type != PO_TP)
01674                     return(DO_NOT_CARE);
01675                   /* test owner's pm_role */
01676                   i_tid.user = owner;
01677                   if (rsbac_get_attr(PM,
01678                        T_USER,
01679                                      i_tid,
01680                                      A_pm_role,
01681                                      &i_attr_val1,
01682                                      TRUE))
01683                     {
01684                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01685                       return(NOT_GRANTED);
01686                     }
01687                   if(i_attr_val1.pm_role == PR_tp_manager)
01688                     return(GRANTED);
01689                   else
01690                     return(NOT_GRANTED);
01691                   break;
01692 
01693                 /* all other cases are undefined */
01694                 default: return(DO_NOT_CARE);
01695               }
01696 
01697         case R_MODIFY_SYSTEM_DATA:
01698             switch(target)
01699               {
01700                 case T_SCD:
01701                   /* target rlimit? no problem, but needed -> grant */
01702                   if (tid.scd == ST_rlimit)
01703                     return(GRANTED);
01704                   /* Administrator? */
01705                   i_tid.user = owner;
01706                   if (rsbac_get_attr(PM,
01707                        T_USER,
01708                                      i_tid,
01709                                      A_pm_role,
01710                                      &i_attr_val1,
01711                                      TRUE))
01712                     {
01713                       printk(KERN_WARNING
01714                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01715                       return(NOT_GRANTED);
01716                     }
01717                   /* if rsbaclog: grant only for secoff and dataprot */
01718                   if(tid.scd == ST_rsbaclog)
01719                     {
01720                       if (   (i_attr_val1.pm_role == PR_security_officer)
01721                           || (i_attr_val1.pm_role == PR_data_protection_officer)
01722                          )
01723                         return(GRANTED);
01724                       else
01725                         return(NOT_GRANTED);
01726                     }
01727                   /* if rsbac_log_remote: grant only for secoff */
01728                   if(tid.scd == ST_rsbac_remote_log)
01729                     {
01730                       if (   (i_attr_val1.pm_role == PR_security_officer)
01731                           || (i_attr_val1.pm_role == PR_data_protection_officer)
01732                          )
01733                         return(GRANTED);
01734                       else
01735                         return(NOT_GRANTED);
01736                     }
01737                   /* other scds: if administrator, then grant */
01738                   if (i_attr_val1.pm_role == PR_system_admin)
01739                     return(GRANTED);
01740                   else
01741                     return(NOT_GRANTED);
01742                   
01743                 /* all other cases are undefined */
01744                 default: return(DO_NOT_CARE);
01745               }
01746 
01747         case R_MOUNT:
01748             switch(target)
01749               {
01750                 case T_FILE:
01751                 case T_DIR:
01752                 case T_DEV:
01753                   /* Administrator? */
01754                   i_tid.user = owner;
01755                   if (rsbac_get_attr(PM,
01756                        T_USER,
01757                                      i_tid,
01758                                      A_pm_role,
01759                                      &i_attr_val1,
01760                                      TRUE))
01761                     {
01762                       printk(KERN_WARNING
01763                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01764                       return(NOT_GRANTED);
01765                     }
01766                   /* if administrator, then grant */
01767                   if (i_attr_val1.pm_role == PR_system_admin)
01768                     return(GRANTED);
01769                   else
01770                     return(NOT_GRANTED);
01771 
01772                 /* all other cases are undefined */
01773                 default: return(DO_NOT_CARE);
01774               }
01775 
01776         case R_READ:
01777             switch(target)
01778               {
01779 #ifdef CONFIG_RSBAC_RW
01780                 case T_FILE:
01781                 case T_FIFO:
01782                   /* get pm_object_type of target */
01783                   if (rsbac_get_attr(PM,
01784                        target,
01785                                      tid,
01786                                      A_pm_object_type,
01787                                      &i_attr_val1,
01788                                      FALSE))
01789                     {
01790                       printk(KERN_WARNING
01791                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01792                       return(NOT_GRANTED);
01793                     }
01794                   /* no read_open on TPs */
01795                   if(i_attr_val1.pm_object_type == PO_TP)
01796                     return(NOT_GRANTED);
01797                   /* do not care for other than personal_data */
01798                   if(i_attr_val1.pm_object_type != PO_personal_data)
01799                     return(DO_NOT_CARE);
01800                   
01801                   /* check necessary && (purpose_bind || consent) */
01802                   return(na_and_pp_or_cs(caller_pid,
01803                                          tid.file,
01804                                          RSBAC_PM_A_READ));
01805                   break;
01806 
01807                 case T_DEV:
01808                   /* get pm_object_type of target */
01809                   if (rsbac_get_attr(PM,
01810                        T_DEV,
01811                                      tid,
01812                                      A_pm_object_type,
01813                                      &i_attr_val1,
01814                                      FALSE))
01815                     {
01816                       printk(KERN_WARNING
01817                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01818                       return(NOT_GRANTED);
01819                     }
01820                   /* check read_open only on devs containing personal_data */
01821                   if(i_attr_val1.pm_object_type != PO_personal_data)
01822                     return(DO_NOT_CARE);
01823                   /* check necessary && purpose_bind */
01824                   return(na_dev(caller_pid,
01825                                 RSBAC_PM_A_READ,
01826                                 tid.dev));
01827 
01828 #ifdef CONFIG_RSBAC_RW_SOCK
01829                 case T_IPC:
01830                   /* get current_task of caller-process */
01831                   i_tid.process = caller_pid;
01832                   if (rsbac_get_attr(PM,
01833                        T_PROCESS,
01834                                      i_tid,
01835                                      A_pm_current_task,
01836                                      &i_attr_val1,
01837                                      FALSE))
01838                     {
01839                       printk(KERN_WARNING
01840                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01841                       return(NOT_GRANTED);
01842                     }
01843                   /* if current_task = NIL, ipc_purpose must be NIL */
01844                   if(!i_attr_val1.pm_current_task)
01845                     {
01846                       if(!get_ipc_purpose(tid.ipc))
01847                         return(GRANTED);
01848                       else
01849                         return(NOT_GRANTED);
01850                     }
01851                   /* check necessary && purpose_bind */
01852                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01853                                        caller_pid,
01854                                        RSBAC_PM_A_READ,
01855                                        tid.ipc));
01856                   break;
01857 #endif /* RW_SOCK */
01858 #endif /* RW */
01859 
01860                 /* all other cases are undefined */
01861                 default: return(DO_NOT_CARE);
01862               }
01863 
01864         case R_READ_ATTRIBUTE:
01865             switch(attr)
01866               {
01867                 case A_pm_object_type:
01868                 case A_pm_tp:
01869                 case A_pm_role:
01870                 case A_pm_process_type:
01871                 case A_pm_current_task:
01872                 case A_pm_object_class:
01873                 case A_pm_ipc_purpose:
01874                 case A_pm_program_type:
01875                 case A_pm_task_set:
01876                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01877                 case A_owner:
01878                 case A_pseudo:
01879                 case A_log_array_low:
01880                 case A_log_array_high:
01881                 case A_log_program_based:
01882                 case A_log_user_based:
01883                 case A_symlink_add_uid:
01884                 case A_fake_root_uid:
01885                 case A_audit_uid:
01886                 case A_auid_exempt:
01887                 #endif
01888                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01889                 case A_auth_may_setuid:
01890                 case A_auth_may_set_cap:
01891                 case A_auth_start_uid:
01892                 case A_auth_program_file:
01893                 case A_auth_learn:
01894                 #endif
01895                   /* Security Officer or Data Protection Officer? */
01896                   i_tid.user = owner;
01897                   if (rsbac_get_attr(PM,
01898                                      T_USER,
01899                                      i_tid,
01900                                      A_pm_role,
01901                                      &i_attr_val1,
01902                                      TRUE))
01903                     {
01904                       printk(KERN_WARNING
01905                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01906                       return(NOT_GRANTED);
01907                     }
01908                   /* if sec_officer or data_prot_off, then grant */
01909                   if(   (i_attr_val1.pm_role == PR_security_officer)
01910                      || (i_attr_val1.pm_role == PR_data_protection_officer))
01911                     return(GRANTED);
01912                   else
01913                     return(NOT_GRANTED);
01914 
01915                 default:
01916                   return(DO_NOT_CARE);
01917               }
01918 
01919         case R_READ_OPEN:
01920             switch(target)
01921               {
01922                 case T_FILE:
01923                 case T_FIFO:
01924                   /* get pm_object_type of target */
01925                   if (rsbac_get_attr(PM,
01926                        target,
01927                                      tid,
01928                                      A_pm_object_type,
01929                                      &i_attr_val1,
01930                                      FALSE))
01931                     {
01932                       printk(KERN_WARNING
01933                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01934                       return(NOT_GRANTED);
01935                     }
01936                   /* no read_open on TPs */
01937                   if(i_attr_val1.pm_object_type == PO_TP)
01938                     return(NOT_GRANTED);
01939                   /* do not care for other than personal_data */
01940                   if(i_attr_val1.pm_object_type != PO_personal_data)
01941                     return(DO_NOT_CARE);
01942                   
01943                   /* check necessary && (purpose_bind || consent) */
01944                   return(na_and_pp_or_cs(caller_pid,
01945                                          tid.file,
01946                                          RSBAC_PM_A_READ));
01947                   break;
01948 
01949                 case T_DEV:
01950                   /* get pm_object_type of target */
01951                   if (rsbac_get_attr(PM,
01952                        T_DEV,
01953                                      tid,
01954                                      A_pm_object_type,
01955                                      &i_attr_val1,
01956                                      FALSE))
01957                     {
01958                       printk(KERN_WARNING
01959                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01960                       return(NOT_GRANTED);
01961                     }
01962                   /* check read_open only on devs containing personal_data */
01963                   if(i_attr_val1.pm_object_type != PO_personal_data)
01964                     return(DO_NOT_CARE);
01965                   /* check necessary && purpose_bind */
01966                   return(na_dev(caller_pid,
01967                                 RSBAC_PM_A_READ,
01968                                 tid.dev));
01969 
01970                 case T_IPC:
01971                   /* get current_task of caller-process */
01972                   i_tid.process = caller_pid;
01973                   if (rsbac_get_attr(PM,
01974                        T_PROCESS,
01975                                      i_tid,
01976                                      A_pm_current_task,
01977                                      &i_attr_val1,
01978                                      FALSE))
01979                     {
01980                       printk(KERN_WARNING
01981                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01982                       return(NOT_GRANTED);
01983                     }
01984                   /* if current_task = NIL, ipc_purpose must be NIL */
01985                   if(!i_attr_val1.pm_current_task)
01986                     {
01987                       if(!get_ipc_purpose(tid.ipc))
01988                         return(GRANTED);
01989                       else
01990                         return(NOT_GRANTED);
01991                     }
01992                   /* check necessary && purpose_bind */
01993                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01994                                        caller_pid,
01995                                        RSBAC_PM_A_READ,
01996                                        tid.ipc));
01997                   break;
01998 
01999                 case T_DIR:
02000                   return(DO_NOT_CARE);
02001                   break;
02002                 /* all other cases are undefined */
02003                 default: return(DO_NOT_CARE);
02004               }
02005 
02006         case R_READ_WRITE_OPEN:
02007             switch(target)
02008               {
02009                 case T_FILE:
02010                 case T_FIFO:
02011                   /* get pm_object_type of target */
02012                   if (rsbac_get_attr(PM,
02013                        target,
02014                                      tid,
02015                                      A_pm_object_type,
02016                                      &i_attr_val1,
02017                                      FALSE))
02018                     {
02019                       printk(KERN_WARNING
02020                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02021                       return(NOT_GRANTED);
02022                     }
02023                   /* no read_write_open on TPs */
02024                   if(i_attr_val1.pm_object_type == PO_TP)
02025                     return(NOT_GRANTED);
02026                   /* TPs must not write on other than personal_data */
02027                   if(i_attr_val1.pm_object_type != PO_personal_data)
02028                     return(tp_check(caller_pid));
02029                   
02030                   /* check necessary && (purpose_bind || consent) */
02031                   return(na_and_pp_or_cs(caller_pid,
02032                                          tid.file,
02033                                          RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
02034                   break;
02035 
02036                 case T_DEV:
02037                   /* get pm_object_type of target */
02038                   if (rsbac_get_attr(PM,
02039                        T_DEV,
02040                                      tid,
02041                                      A_pm_object_type,
02042                                      &i_attr_val1,
02043                                      FALSE))
02044                     {
02045                       printk(KERN_WARNING
02046                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02047                       return(NOT_GRANTED);
02048                     }
02049                   /* check read_write_open only on devs containing personal_data or TPs*/
02050                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02051                      && (i_attr_val1.pm_object_type != PO_TP) )
02052                     return(DO_NOT_CARE);
02053                   /* check necessary && purpose_bind */
02054                   return(na_dev(caller_pid,
02055                                 RSBAC_PM_A_READ | RSBAC_PM_A_WRITE,
02056                                 tid.dev));
02057 
02058                 case T_IPC:
02059                   /* get IPC-purpose */
02060                   i_pm_pp = get_ipc_purpose(tid.ipc);
02061                   /* if IPC-pp is NIL -> process type must be NIL */
02062                   if(!i_pm_pp)
02063                     {
02064                       /* get process-type of caller-process */
02065                       i_tid.process = caller_pid;
02066                       if (rsbac_get_attr(PM,
02067                        T_PROCESS,
02068                                          i_tid,
02069                                          A_pm_process_type,
02070                                          &i_attr_val1,
02071                                          FALSE))
02072                         { 
02073                           printk(KERN_WARNING
02074                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02075                           return(NOT_GRANTED);
02076                         }
02077                       if(i_attr_val1.pm_process_type == PP_TP)
02078                         return(NOT_GRANTED);
02079                       else
02080                         return(GRANTED);
02081                     }
02082                   /* OK, we do have an IPC-purpose */                  
02083                   /* get current_task of caller-process */
02084                   i_tid.process = caller_pid;
02085                   if (rsbac_get_attr(PM,
02086                        T_PROCESS,
02087                                      i_tid,
02088                                      A_pm_current_task,
02089                                      &i_attr_val1,
02090                                      FALSE))
02091                     {
02092                       printk(KERN_WARNING
02093                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02094                       return(NOT_GRANTED);
02095                     }
02096                   /* if current_task = NIL -> do not grant */
02097                   if(!i_attr_val1.pm_current_task)
02098                     {
02099                         return(NOT_GRANTED);
02100                     }
02101                   /* check necessary && purpose_bind */
02102                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02103                                        caller_pid,
02104                                        RSBAC_PM_A_READ | RSBAC_PM_A_WRITE,
02105                                        tid.ipc));
02106                   break;
02107 
02108                 /* all other cases are undefined */
02109                 default: return(DO_NOT_CARE);
02110               }
02111 
02112         case R_REMOVE_FROM_KERNEL:
02113         case R_SHUTDOWN:
02114             switch(target)
02115               {
02116                 case T_NONE:
02117                   /* test owner's pm_role */
02118                   i_tid.user = owner;
02119                   if (rsbac_get_attr(PM,
02120                        T_USER,
02121                                      i_tid,
02122                                      A_pm_role,
02123                                      &i_attr_val1,
02124                                      TRUE))
02125                     {
02126                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02127                       return(NOT_GRANTED);
02128                     }
02129                   /* only administrators are allowed to do this */
02130                   if (i_attr_val1.pm_role != PR_system_admin)
02131                     return(NOT_GRANTED);
02132                   /* That's it */
02133                   return(GRANTED);
02134 
02135                 /* all other cases are undefined */
02136                 default: return(DO_NOT_CARE);
02137               }
02138 
02139 /*      case R_RENAME: see R_MODIFY_ACCESS_DATA */
02140 
02141         case R_SEND_SIGNAL:
02142             switch(target)
02143               {
02144                 case T_PROCESS:
02145                   /* TPs are not allowed to send signals */
02146                   /* get process_type of caller-process */
02147                   i_tid.process = caller_pid;
02148                   if (rsbac_get_attr(PM,
02149                        T_PROCESS,
02150                                      i_tid,
02151                                      A_pm_process_type,
02152                                      &i_attr_val1,
02153                                      FALSE))
02154                     {
02155                       printk(KERN_WARNING
02156                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02157                       return(NOT_GRANTED);
02158                     }
02159                   /* we do not allow TPs here */
02160                   if(i_attr_val1.pm_process_type == PP_TP)
02161                     return(NOT_GRANTED);
02162 
02163                   /* SIGKILL to TPs is restricted to tp_managers to prevent */
02164                   /* inconsistencies */
02165                   /* get process_type of target-process */
02166                   if (rsbac_get_attr(PM,
02167                        T_PROCESS,
02168                                      tid,
02169                                      A_pm_process_type,
02170                                      &i_attr_val1,
02171                                      FALSE))
02172                     {
02173                       printk(KERN_WARNING
02174                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02175                       return(NOT_GRANTED);
02176                     }
02177                   /* we only care for TPs here */
02178                   if(i_attr_val1.pm_process_type != PP_TP)
02179                     return(DO_NOT_CARE);
02180   
02181                   /* test owner's pm_role */
02182                   i_tid.user = owner;
02183                   if (rsbac_get_attr(PM,
02184                        T_USER,
02185                                      i_tid,
02186                                      A_pm_role,
02187                                      &i_attr_val1,
02188                                      TRUE))
02189                     {
02190                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02191                       return(NOT_GRANTED);
02192                     }
02193                   /* only tp_managers are allowed to do this */
02194                   if (i_attr_val1.pm_role != PR_tp_manager)
02195                     return(NOT_GRANTED);
02196                   /* That's it */
02197                   return(GRANTED);
02198 
02199                 /* all other cases are undefined */
02200                 default:
02201                   return(DO_NOT_CARE);
02202               }
02203 
02204 /*      case R_SHUTDOWN: see R_REMOVE_FROM_KERNEL */
02205 
02206         case R_SWITCH_LOG:
02207             switch(target)
02208               {
02209                 case T_NONE:
02210                   /* test owner's pm_role */
02211                   i_tid.user = owner;
02212                   if (rsbac_get_attr(PM,
02213                        T_USER,
02214                                      i_tid,
02215                                      A_pm_role,
02216                                      &i_attr_val1,
02217                                      FALSE))
02218                     {
02219                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02220                       return(NOT_GRANTED);
02221                     }
02222                   /* security officer? -> grant  */
02223                   if (i_attr_val1.pm_role == PR_security_officer)
02224                     return(GRANTED);
02225                   else
02226                     return(NOT_GRANTED);
02227 
02228                 /* all other cases are undefined */
02229                 default: return(DO_NOT_CARE);
02230               }
02231               
02232         case R_SWITCH_MODULE:
02233             switch(target)
02234               {
02235                 case T_NONE:
02236                   /* we need the switch_target */
02237                   if(attr != A_switch_target)
02238                     return(UNDEFINED);
02239                   /* deny PM to be switched, do not care for others */
02240                   if(   (attr_val.switch_target == PM)
02241                      #ifdef CONFIG_RSBAC_PM_AUTH_PROT
02242                      || (attr_val.switch_target == AUTH)
02243                      #endif
02244                      #ifdef CONFIG_RSBAC_SOFTMODE
02245                      || (attr_val.switch_target == SOFTMODE)
02246                      #endif
02247                      #ifdef CONFIG_RSBAC_FREEZE
02248                      || (attr_val.switch_target == FREEZE)
02249                      #endif
02250                     )
02251                     return(NOT_GRANTED);
02252                   else
02253                     return(DO_NOT_CARE);
02254 
02255                 /* all other cases are undefined */
02256                 default: return(DO_NOT_CARE);
02257               }
02258               
02259         /* notify only, handled by adf-dispatcher */
02260         case R_TERMINATE:
02261             if (target == T_PROCESS)
02262               { /* Remove input and output purpose set of process */
02263                 i_pm_set_id.in_pp_set = tid.process;
02264                 rsbac_pm_remove_set(0, PS_IN_PP, i_pm_set_id);
02265                 i_pm_set_id.out_pp_set = tid.process;
02266                 rsbac_pm_remove_set(0, PS_OUT_PP, i_pm_set_id);
02267                 return(GRANTED);
02268               }
02269             else
02270               return(DO_NOT_CARE);
02271 
02272         case R_TRACE:
02273             switch(target)
02274               {
02275                 case T_PROCESS:
02276                   /* get process_type of calling process */
02277                   i_tid.process = caller_pid;
02278                   if (rsbac_get_attr(PM,
02279                        T_PROCESS,
02280                                      i_tid,
02281                                      A_pm_process_type,
02282                                      &i_attr_val1,
02283                                      FALSE))
02284                     {
02285                       printk(KERN_WARNING
02286                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02287                       return(NOT_GRANTED);
02288                     }
02289                   /* do not grant for TPs */
02290                   if(i_attr_val1.pm_process_type == PP_TP)
02291                     return(NOT_GRANTED);
02292 
02293                   /* get process_type of target-process */
02294                   if (rsbac_get_attr(PM,
02295                        T_PROCESS,
02296                                      tid,
02297                                      A_pm_process_type,
02298                                      &i_attr_val1,
02299                                      FALSE))
02300                     {
02301                       printk(KERN_WARNING
02302                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02303                       return(NOT_GRANTED);
02304                     }
02305                   /* do not grant for TPs */
02306                   if(i_attr_val1.pm_process_type == PP_TP)
02307                     return(NOT_GRANTED);
02308 
02309                   /* neither P1 nor P2 is TP -> grant */
02310                   return(GRANTED);
02311 
02312                 /* all other cases are undefined */
02313                 default:
02314                   return(DO_NOT_CARE);
02315               }
02316 
02317         case R_TRUNCATE:
02318             switch(target)
02319               {
02320                 case T_FILE:
02321                   /* get pm_object_type of target */
02322                   if (rsbac_get_attr(PM,
02323                        T_FILE,
02324                                      tid,
02325                                      A_pm_object_type,
02326                                      &i_attr_val1,
02327                                      FALSE))
02328                     {
02329                       printk(KERN_WARNING
02330                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02331                       return(NOT_GRANTED);
02332                     }
02333                   /* no append_open on TPs */
02334                   if(i_attr_val1.pm_object_type == PO_TP)
02335                     return(NOT_GRANTED);
02336                   /* TPs must not write on other than personal_data */
02337                   if(i_attr_val1.pm_object_type != PO_personal_data)
02338                     return(tp_check(caller_pid));
02339                   
02340                   /* check necessary && (purpose_bind || consent) */
02341                   return(na_and_pp_or_cs(caller_pid,
02342                                          tid.file,
02343                                          RSBAC_PM_A_WRITE));
02344                   break;
02345 
02346                 /* all other cases are undefined */
02347                 default: return(DO_NOT_CARE);
02348               }
02349 
02350         case R_UMOUNT:
02351             switch(target)
02352               {
02353                 case T_FILE:
02354                 case T_DIR:
02355                 case T_DEV:
02356                   /* Administrator? */
02357                   i_tid.user = owner;
02358                   if (rsbac_get_attr(PM,
02359                        T_USER,
02360                                      i_tid,
02361                                      A_pm_role,
02362                                      &i_attr_val1,
02363                                      TRUE))
02364                     {
02365                       printk(KERN_WARNING
02366                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02367                       return(NOT_GRANTED);
02368                     }
02369                   /* if administrator, then grant */
02370                   if (i_attr_val1.pm_role == PR_system_admin)
02371                     return(GRANTED);
02372                   else
02373                     return(NOT_GRANTED);
02374 
02375                 /* all other cases are undefined */
02376                 default: return(DO_NOT_CARE);
02377               }
02378 
02379         case R_WRITE:
02380             switch(target)
02381               {
02382 #ifdef CONFIG_RSBAC_RW
02383                 case T_FILE:
02384                 case T_FIFO:
02385                   /* get pm_object_type of target */
02386                   if (rsbac_get_attr(PM,
02387                        target,
02388                                      tid,
02389                                      A_pm_object_type,
02390                                      &i_attr_val1,
02391                                      FALSE))
02392                     {
02393                       printk(KERN_WARNING
02394                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02395                       return(NOT_GRANTED);
02396                     }
02397                   /* no append_open on TPs */
02398                   if(i_attr_val1.pm_object_type == PO_TP)
02399                     return(NOT_GRANTED);
02400                   /* TPs must not write on other than personal_data */
02401                   if(i_attr_val1.pm_object_type != PO_personal_data)
02402                     return(tp_check(caller_pid));
02403                   
02404                   /* check necessary && (purpose_bind || consent) */
02405                   return(na_and_pp_or_cs(caller_pid,
02406                                          tid.file,
02407                                          RSBAC_PM_A_WRITE));
02408                   break;
02409 
02410                 case T_DEV:
02411                   /* get pm_object_type of target */
02412                   if (rsbac_get_attr(PM,
02413                        T_DEV,
02414                                      tid,
02415                                      A_pm_object_type,
02416                                      &i_attr_val1,
02417                                      FALSE))
02418                     {
02419                       printk(KERN_WARNING
02420                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02421                       return(NOT_GRANTED);
02422                     }
02423                   /* check write_open only on devs containing personal_data or TPs*/
02424                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02425                      && (i_attr_val1.pm_object_type != PO_TP) )
02426                     return(DO_NOT_CARE);
02427                   /* check necessary && purpose_bind */
02428                   return(na_dev(caller_pid,
02429                                 RSBAC_PM_A_WRITE,
02430                                 tid.dev));
02431 
02432 #ifdef CONFIG_RSBAC_RW_SOCK
02433                 case T_IPC:
02434                   /* get IPC-purpose */
02435                   i_pm_pp = get_ipc_purpose(tid.ipc);
02436                   /* if IPC-pp is NIL -> process type must be NIL */
02437                   if(!i_pm_pp)
02438                     {
02439                       /* get process-type of caller-process */
02440                       i_tid.process = caller_pid;
02441                       if (rsbac_get_attr(PM,
02442                        T_PROCESS,
02443                                          i_tid,
02444                                          A_pm_process_type,
02445                                          &i_attr_val1,
02446                                          FALSE))
02447                         { 
02448                           printk(KERN_WARNING
02449                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02450                           return(NOT_GRANTED);
02451                         }
02452                       if(i_attr_val1.pm_process_type == PP_TP)
02453                         return(NOT_GRANTED);
02454                       else
02455                         return(GRANTED);
02456                     }
02457                   /* OK, we do have an IPC-purpose */                  
02458                   /* get current_task of caller-process */
02459                   i_tid.process = caller_pid;
02460                   if (rsbac_get_attr(PM,
02461                        T_PROCESS,
02462                                      i_tid,
02463                                      A_pm_current_task,
02464                                      &i_attr_val1,
02465                                      FALSE))
02466                     {
02467                       printk(KERN_WARNING
02468                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02469                       return(NOT_GRANTED);
02470                     }
02471                   /* if current_task = NIL -> do not grant */
02472                   if(!i_attr_val1.pm_current_task)
02473                     {
02474                         return(NOT_GRANTED);
02475                     }
02476                   /* check necessary && purpose_bind */
02477                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02478                                        caller_pid,
02479                                        RSBAC_PM_A_WRITE,
02480                                        tid.ipc));
02481                   break;
02482 #endif
02483 #endif
02484 
02485                 /* all other cases are undefined */
02486                 default: return(DO_NOT_CARE);
02487               }
02488 
02489         case R_WRITE_OPEN:
02490             switch(target)
02491               {
02492                 case T_FILE:
02493                 case T_FIFO:
02494                   /* get pm_object_type of target */
02495                   if (rsbac_get_attr(PM,
02496                        target,
02497                                      tid,
02498                                      A_pm_object_type,
02499                                      &i_attr_val1,
02500                                      FALSE))
02501                     {
02502                       printk(KERN_WARNING
02503                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02504                       return(NOT_GRANTED);
02505                     }
02506                   /* no append_open on TPs */
02507                   if(i_attr_val1.pm_object_type == PO_TP)
02508                     return(NOT_GRANTED);
02509                   /* TPs must not write on other than personal_data */
02510                   if(i_attr_val1.pm_object_type != PO_personal_data)
02511                     return(tp_check(caller_pid));
02512                   
02513                   /* check necessary && (purpose_bind || consent) */
02514                   return(na_and_pp_or_cs(caller_pid,
02515                                          tid.file,
02516                                          RSBAC_PM_A_WRITE));
02517                   break;
02518 
02519                 case T_DEV:
02520                   /* get pm_object_type of target */
02521                   if (rsbac_get_attr(PM,
02522                        T_DEV,
02523                                      tid,
02524                                      A_pm_object_type,
02525                                      &i_attr_val1,
02526                                      FALSE))
02527                     {
02528                       printk(KERN_WARNING
02529                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02530                       return(NOT_GRANTED);
02531                     }
02532                   /* check write_open only on devs containing personal_data or TPs*/
02533                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02534                      && (i_attr_val1.pm_object_type != PO_TP) )
02535                     return(DO_NOT_CARE);
02536                   /* check necessary && purpose_bind */
02537                   return(na_dev(caller_pid,
02538                                 RSBAC_PM_A_WRITE,
02539                                 tid.dev));
02540 
02541                 case T_IPC:
02542                   /* get IPC-purpose */
02543                   i_pm_pp = get_ipc_purpose(tid.ipc);
02544                   /* if IPC-pp is NIL -> process type must be NIL */
02545                   if(!i_pm_pp)
02546                     {
02547                       /* get process-type of caller-process */
02548                       i_tid.process = caller_pid;
02549                       if (rsbac_get_attr(PM,
02550                        T_PROCESS,
02551                                          i_tid,
02552                                          A_pm_process_type,
02553                                          &i_attr_val1,
02554                                          FALSE))
02555                         { 
02556                           printk(KERN_WARNING
02557                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02558                           return(NOT_GRANTED);
02559                         }
02560                       if(i_attr_val1.pm_process_type == PP_TP)
02561                         return(NOT_GRANTED);
02562                       else
02563                         return(GRANTED);
02564                     }
02565                   /* OK, we do have an IPC-purpose */                  
02566                   /* get current_task of caller-process */
02567                   i_tid.process = caller_pid;
02568                   if (rsbac_get_attr(PM,
02569                        T_PROCESS,
02570                                      i_tid,
02571                                      A_pm_current_task,
02572                                      &i_attr_val1,
02573                                      FALSE))
02574                     {
02575                       printk(KERN_WARNING
02576                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02577                       return(NOT_GRANTED);
02578                     }
02579                   /* if current_task = NIL -> do not grant */
02580                   if(!i_attr_val1.pm_current_task)
02581                     {
02582                         return(NOT_GRANTED);
02583                     }
02584                   /* check necessary && purpose_bind */
02585                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02586                                        caller_pid,
02587                                        RSBAC_PM_A_WRITE,
02588                                        tid.ipc));
02589                   break;
02590 
02591                 /* all other cases are undefined */
02592                 default: return(DO_NOT_CARE);
02593               }
02594 
02595 
02596 /*********************/
02597         default: return DO_NOT_CARE;
02598       }
02599 
02600     return(result);
02601   }; /* end of rsbac_adf_request_pm() */
02602 
02603 
02604 /*****************************************************************************/
02605 /* If the request returned granted and the operation is performed,           */
02606 /* the following function can be called by the AEF to get all aci set        */
02607 /* correctly. For write accesses that are performed fully within the kernel, */
02608 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
02609 /* cleaning up.                                                              */
02610 /* The second instance of target specification is the new target, if one has */
02611 /* been created, otherwise its values are ignored.                           */
02612 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
02613 
02614 int  rsbac_adf_set_attr_pm(
02615                       enum  rsbac_adf_request_t     request,
02616                             rsbac_pid_t             caller_pid,
02617                       enum  rsbac_target_t          target,
02618                       union rsbac_target_id_t       tid,
02619                       enum  rsbac_target_t          new_target,
02620                       union rsbac_target_id_t       new_tid,
02621                       enum  rsbac_attribute_t       attr,
02622                       union rsbac_attribute_value_t attr_val,
02623                             rsbac_uid_t             owner)
02624   {
02625     union rsbac_target_id_t       i_tid;
02626     union rsbac_attribute_value_t i_attr_val1;
02627     union rsbac_attribute_value_t i_attr_val2;
02628     union rsbac_attribute_value_t i_attr_val3;
02629     union rsbac_attribute_value_t i_attr_val4;
02630     union rsbac_pm_target_id_t    i_pm_tid;
02631     union rsbac_pm_data_value_t   i_data_val1;
02632           int                     error;
02633 
02634     switch (request)
02635       {
02636         case R_APPEND_OPEN:
02637             switch(target)
02638               {
02639                 case T_FILE:
02640                 case T_FIFO:
02641                   return(adjust_in_out_pp(caller_pid,
02642                                           target,
02643                                           tid.file,
02644                                           RSBAC_PM_A_APPEND));
02645                 case T_IPC:
02646                   return(adjust_in_out_pp_ipc(caller_pid,
02647                                               tid.ipc,
02648                                               RSBAC_PM_A_APPEND));
02649                 case T_DEV:
02650                   return(0);
02651                 default:
02652                   return(0);
02653               }
02654 #ifdef CONFIG_RSBAC_RW
02655         case R_READ:
02656             switch(target)
02657               {
02658                 case T_FILE:
02659                 case T_FIFO:
02660                   return(adjust_in_out_pp(caller_pid,
02661                                           target,
02662                                           tid.file,
02663                                           RSBAC_PM_A_READ));
02664 #ifdef CONFIG_RSBAC_RW_SOCK
02665                 case T_IPC:
02666                   return(adjust_in_out_pp_ipc(caller_pid,
02667                                               tid.ipc,
02668                                               RSBAC_PM_A_READ));
02669 #endif
02670                 default:
02671                   return(0);
02672               }
02673 #endif
02674         case R_READ_OPEN:
02675             switch(target)
02676               {
02677                 case T_FILE:
02678                 case T_FIFO:
02679                   return(adjust_in_out_pp(caller_pid,
02680                                           target,
02681                                           tid.file,
02682                                           RSBAC_PM_A_READ));
02683                 case T_IPC:
02684                   return(adjust_in_out_pp_ipc(caller_pid,
02685                                               tid.ipc,
02686                                               RSBAC_PM_A_READ));
02687                 case T_DIR:
02688                 case T_DEV:
02689                   return(0);
02690                 default:
02691                   return(0);
02692               }
02693         case R_READ_WRITE_OPEN:
02694             switch(target)
02695               {
02696                 case T_FILE:
02697                 case T_FIFO:
02698                   return(adjust_in_out_pp(caller_pid,
02699                                           target,
02700                                           tid.file,
02701                                           RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
02702                 case T_IPC:
02703                   return(adjust_in_out_pp_ipc(caller_pid,
02704                                               tid.ipc,
02705                                               RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
02706                 case T_DEV:
02707                   return(0);
02708                 default:
02709                   return(0);
02710               }
02711 
02712 #ifdef CONFIG_RSBAC_RW
02713         case R_WRITE:
02714             switch(target)
02715               {
02716                 case T_FILE:
02717                 case T_FIFO:
02718                   return(adjust_in_out_pp(caller_pid,
02719                                           target,
02720                                           tid.file,
02721                                           RSBAC_PM_A_WRITE));
02722 #ifdef CONFIG_RSBAC_RW_SOCK
02723                 case T_IPC:
02724                   return(adjust_in_out_pp_ipc(caller_pid,
02725                                               tid.ipc,
02726                                               RSBAC_PM_A_WRITE));
02727 #endif
02728                 default:
02729                   return(0);
02730               }
02731 #endif
02732 
02733         case R_WRITE_OPEN:
02734             switch(target)
02735               {
02736                 case T_FILE:
02737                 case T_FIFO:
02738                   return(adjust_in_out_pp(caller_pid,
02739                                           target,
02740                                           tid.file,
02741                                           RSBAC_PM_A_WRITE));
02742                 case T_DEV:
02743                   return(0);
02744 
02745                 case T_IPC:
02746                   return(adjust_in_out_pp_ipc(caller_pid,
02747                                               tid.ipc,
02748                                               RSBAC_PM_A_WRITE));
02749                 default:
02750                   return(0);
02751               }
02752 
02753         case R_CLONE:
02754             if (target == T_PROCESS)
02755               {
02756                   /* Get owner from first process (provided on call) */
02757                   i_attr_val1.owner = owner;
02758                   /* Get pm_tp from first process */
02759                   if (rsbac_get_attr(PM,
02760                        T_PROCESS,
02761                                      tid,
02762                                      A_pm_tp,
02763                                      &i_attr_val2,
02764                                      FALSE))
02765                     {
02766                       printk(KERN_WARNING
02767                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02768                       return(-RSBAC_EREADFAILED);
02769                     }
02770                   /* Get pm_current_task from first process... */
02771                   if (rsbac_get_attr(PM,
02772                        T_PROCESS,
02773                                      tid,
02774                                      A_pm_current_task,
02775                                      &i_attr_val3,
02776                                      FALSE))
02777                     {
02778                       printk(KERN_WARNING
02779                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02780                       return(-RSBAC_EREADFAILED);
02781                     }
02782                   /* Get pm_process_type from first process */
02783                   if (rsbac_get_attr(PM,
02784                        T_PROCESS,
02785                                      tid,
02786                                      A_pm_process_type,
02787                                      &i_attr_val4,
02788                                      FALSE))
02789                     {
02790                       printk(KERN_WARNING
02791                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02792                       return(-RSBAC_EREADFAILED);
02793                     }
02794                   /* Set pm_tp for new process */
02795                   if (rsbac_set_attr(PM,
02796                        T_PROCESS,
02797                                      new_tid,
02798                                      A_pm_tp,
02799                                      i_attr_val2))
02800                     {
02801                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02802                       return(-RSBAC_EWRITEFAILED);
02803                     }
02804                   /* Set pm_current_task for new process */
02805                   if (rsbac_set_attr(PM,
02806                        T_PROCESS,
02807                                      new_tid,
02808                                      A_pm_current_task,
02809                                      i_attr_val3))
02810                     {
02811                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02812                       return(-RSBAC_EWRITEFAILED);
02813                     }
02814                   /* Set pm_process_type for new process */
02815                   if (rsbac_set_attr(PM,
02816                        T_PROCESS,
02817                                      new_tid,
02818                                      A_pm_process_type,
02819                                      i_attr_val4))
02820                     {
02821                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02822                       return(-RSBAC_EWRITEFAILED);
02823                     }
02824                   return(0);
02825               }
02826             else
02827               return(0);
02828 
02829         case R_CREATE:
02830             switch(target)
02831               {
02832                 /* Creating dir or (pseudo) file IN target dir! */
02833                 case T_DIR:
02834                   /* Mode of created item is ignored! */
02835 
02836                   /* Is calling process a TP? */
02837                   /* get process_type of caller-process */
02838                   i_tid.process = caller_pid;
02839                   if (rsbac_get_attr(PM,
02840                                      T_PROCESS,
02841                                      i_tid,
02842                                      A_pm_process_type,
02843                                      &i_attr_val1,
02844                                      FALSE))
02845                     {
02846                       printk(KERN_WARNING
02847                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02848                       return(NOT_GRANTED);
02849                     }
02850                   /* if TP: Set pm_object_class to purpose default class for new item */
02851                   if(i_attr_val1.pm_process_type == PP_TP)
02852                     {
02853                       /* get current_task of caller-process */
02854                       i_tid.process = caller_pid;
02855                       if (rsbac_get_attr(PM,
02856                        T_PROCESS,
02857                                          i_tid,
02858                                          A_pm_current_task,
02859                                          &i_attr_val1,
02860                                          FALSE))
02861                         {
02862                           printk(KERN_WARNING
02863                                  "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02864                                  return(RSBAC_EREADFAILED);
02865                         }
02866                       if(!i_attr_val1.pm_current_task)
02867                         {
02868 #ifdef CONFIG_RSBAC_DEBUG
02869                           if(rsbac_debug_adf_pm)
02870                             printk(KERN_DEBUG
02871                                    "rsbac_adf_set_attr_pm(): no current_task for calling process trying to access personal_data\n");
02872 #endif
02873                           return(RSBAC_EREADFAILED);
02874                         }
02875                       /* get purpose of current_task */
02876                       i_pm_tid.task = i_attr_val1.pm_current_task;
02877                       if ((error = rsbac_pm_get_data(0,
02878                                                      PMT_TASK,
02879                                                      i_pm_tid,
02880                                                      PD_purpose,
02881                                                      &i_data_val1)))
02882                         {
02883                           if(error != -RSBAC_EINVALIDTARGET)
02884                             printk(KERN_WARNING
02885                                    "rsbac_adf_set_attr_pm(): rsbac_pm_get_data() returned error %i!\n",
02886                                    error);
02887                           return(error);
02888                         }
02889                       /* if there is no purpose, return error */
02890                       if(!i_data_val1.purpose)
02891                         {
02892 #ifdef CONFIG_RSBAC_DEBUG
02893                           if(rsbac_debug_adf_pm)
02894                             printk(KERN_DEBUG
02895                                    "rsbac_adf_set_attr_pm(): no purpose for current_task of process trying to execute TP\n");
02896 #endif
02897                           return(RSBAC_EREADFAILED);
02898                         }
02899                       /* get def_class of purpose of current_task */
02900                       i_pm_tid.pp = i_data_val1.purpose;
02901                       if ((error = rsbac_pm_get_data(0,
02902                                                      PMT_PP,
02903                                                      i_pm_tid,
02904                                                      PD_def_class,
02905                                                      &i_data_val1)))
02906                         {
02907                           if(error != -RSBAC_EINVALIDTARGET)
02908                             printk(KERN_WARNING
02909                                    "rsbac_adf_set_attr_pm(): rsbac_pm_get_data() returned error %i!\n",
02910                                    error);
02911                           return(error);
02912                         }
02913                       i_attr_val1.pm_object_class = i_data_val1.def_class;
02914                     }
02915                   else /* calling process is no TP */
02916                     /* set class to NIL */
02917                     i_attr_val1.pm_object_class = 0;
02918                   
02919                   if (rsbac_get_attr(PM,
02920                                      new_target,
02921                                      new_tid,
02922                                      A_pm_object_class,
02923                                      &i_attr_val2,
02924                                      FALSE))
02925                     {
02926                       printk(KERN_WARNING
02927                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02928                       return(-RSBAC_EREADFAILED);
02929                     }
02930                   if(i_attr_val1.pm_object_class != i_attr_val2.pm_object_class)
02931                     {
02932                       if (rsbac_set_attr(PM,
02933                                          new_target,
02934                                          new_tid,
02935                                          A_pm_object_class,
02936                                          i_attr_val1))
02937                         {
02938                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02939                           return(-RSBAC_EWRITEFAILED);
02940                         }
02941                     }
02942                   /* Set pm_tp for new item */
02943                   i_attr_val1.pm_tp = 0;
02944                   if (rsbac_get_attr(PM,
02945                                      new_target,
02946                                      new_tid,
02947                                      A_pm_tp,
02948                                      &i_attr_val2,
02949                                      FALSE))
02950                     {
02951                       printk(KERN_WARNING
02952                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02953                       return(-RSBAC_EREADFAILED);
02954                     }
02955                   if(i_attr_val1.pm_tp != i_attr_val2.pm_tp)
02956                     {
02957                       if (rsbac_set_attr(PM,
02958                                          new_target,
02959                                          new_tid,
02960                                          A_pm_tp,
02961                                          i_attr_val1))
02962                         {
02963                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02964                           return(-RSBAC_EWRITEFAILED);
02965                         }
02966                     }
02967 
02968                   /* get process_type of caller-process */
02969                   i_tid.process = caller_pid;
02970                   if (rsbac_get_attr(PM,
02971                                      T_PROCESS,
02972                                      i_tid,
02973                                      A_pm_process_type,
02974                                      &i_attr_val1,
02975                                      FALSE))
02976                     {
02977                       printk(KERN_WARNING
02978                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02979                       return(-RSBAC_EREADFAILED);
02980                     }
02981                   /* Set pm_object_type for new item */
02982                   if(new_target == T_DIR)
02983                     i_attr_val1.pm_object_type = PO_dir;
02984                   else
02985                     /* files: if process is TP, set to personal_data */
02986                     /* to prevent unrestricted access */
02987                     if(i_attr_val1.pm_process_type == PP_TP)
02988                       i_attr_val1.pm_object_type = PO_personal_data;
02989                     else
02990                       i_attr_val1.pm_object_type = PO_none;
02991                   if (rsbac_get_attr(PM,
02992                                      new_target,
02993                                      new_tid,
02994                                      A_pm_object_type,
02995                                      &i_attr_val2,
02996                                      FALSE))
02997                     {
02998                       printk(KERN_WARNING
02999                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03000                       return(-RSBAC_EREADFAILED);
03001                     }
03002                   if(i_attr_val1.pm_object_type != i_attr_val2.pm_object_type)
03003                     {
03004                       if (rsbac_set_attr(PM,
03005                                          new_target,
03006                                          new_tid,
03007                                          A_pm_object_type,
03008                                          i_attr_val1))
03009                         {
03010                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03011                           return(-RSBAC_EWRITEFAILED);
03012                         }
03013                     }
03014                   return(0);
03015                   break;
03016 
03017                 case T_IPC: 
03018                   /* Set pm_ipc_purpose for new item */
03019                   /* get current_task of caller-process */
03020                   i_tid.process = caller_pid;
03021                   if (rsbac_get_attr(PM,
03022                                      T_PROCESS,
03023                                      i_tid,
03024                                      A_pm_current_task,
03025                                      &i_attr_val1,
03026                                      FALSE))
03027                     {
03028                       printk(KERN_WARNING
03029                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03030                       return(-RSBAC_EREADFAILED);
03031                     }
03032                   /* if current_task = NIL, ipc_purpose must be NIL */
03033                   if(!i_attr_val1.pm_current_task)
03034                     i_attr_val1.pm_ipc_purpose = 0;
03035                   else
03036                     {
03037                       /* get purpose of current_task */
03038                       i_pm_tid.task = i_attr_val1.pm_current_task;
03039                       if ((error = rsbac_pm_get_data(0,
03040                                                      PMT_TASK,
03041                                                      i_pm_tid,
03042                                                      PD_purpose,
03043                                                      &i_data_val1)))
03044                         {
03045                           if(error == -RSBAC_EINVALIDTARGET)
03046                             printk(KERN_WARNING
03047                                    "rsbac_adf_request_pm(): pm_current_task of calling process is invalid!\n");
03048                           else
03049                             printk(KERN_WARNING
03050                                    "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
03051                                    error);
03052                           return(-RSBAC_EREADFAILED);
03053                         }
03054                       i_attr_val1.pm_ipc_purpose = i_data_val1.purpose;
03055                     }
03056                   if (rsbac_get_attr(PM,
03057                                      target,
03058                                      tid,
03059                                      A_pm_ipc_purpose,
03060                                      &i_attr_val2,
03061                                      FALSE))
03062                     {
03063                       printk(KERN_WARNING
03064                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03065                       return(-RSBAC_EREADFAILED);
03066                     }
03067                   if(i_attr_val1.pm_ipc_purpose != i_attr_val2.pm_ipc_purpose)
03068                     {
03069                       if (rsbac_set_attr(PM,
03070                                          target,
03071                                          tid,
03072                                          A_pm_ipc_purpose,
03073                                          i_attr_val1))
03074                         {
03075                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03076                           return(-RSBAC_EWRITEFAILED);
03077                         }
03078                     }
03079                   return(0);
03080                   break;
03081 
03082                 /* all other cases are undefined */
03083                 default:
03084                   return(0);
03085               }
03086 
03087         case R_EXECUTE:
03088             switch(target)
03089               {
03090                 case T_FILE:
03091                   /* get pm_object_type of target */
03092                   if (rsbac_get_attr(PM,
03093                                      T_FILE,
03094                                      tid,
03095                                      A_pm_object_type,
03096                                      &i_attr_val1,
03097                                      FALSE))
03098                     {
03099                       printk(KERN_WARNING
03100                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03101                       return(-RSBAC_EREADFAILED);
03102                     }
03103                   /* if not TP: do nothing */
03104                   if(i_attr_val1.pm_object_type != PO_TP)
03105                     return(0);
03106 
03107                   /* get pm_tp of target */
03108                   if (rsbac_get_attr(PM,
03109                        T_FILE,
03110                                      tid,
03111                                      A_pm_tp,
03112                                      &i_attr_val1,
03113                                      FALSE))
03114                     {
03115                       printk(KERN_WARNING
03116                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03117                       return(-RSBAC_EREADFAILED);
03118                     }
03119                   /* if no tp: error! */
03120                   if(!i_attr_val1.pm_tp)
03121                     {
03122                       printk(KERN_WARNING
03123                              "rsbac_adf_request_pm(): file with object_type TP has no tp_id!\n");
03124                       return(-RSBAC_EINVALIDVALUE);
03125                     }
03126                   /* Set pm_tp for this process */
03127                   i_tid.process = caller_pid;
03128                   if (rsbac_set_attr(PM,
03129                                      T_PROCESS,
03130                                      i_tid,
03131                                      A_pm_tp,
03132                                      i_attr_val1))
03133                     {
03134                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03135                       return(-RSBAC_EWRITEFAILED);
03136                     }
03137                   /* Set pm_process_type for this process */
03138                   i_attr_val1.pm_process_type = PP_TP;
03139                   if (rsbac_set_attr(PM,
03140                                      T_PROCESS,
03141                                      i_tid,
03142                                      A_pm_process_type,
03143                                      i_attr_val1))
03144                     {
03145                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03146                       return(-RSBAC_EWRITEFAILED);
03147                     }
03148                   return(0);
03149 
03150                 /* all other cases are undefined */
03151                 default:
03152                   return(0);
03153               }
03154 
03155 /*********************/
03156 
03157         default: return(0);
03158       }
03159 
03160     return(0);
03161   }; /* end of rsbac_adf_set_attr_pm() */
03162 
03163 /******************************************/
03164 #ifdef CONFIG_RSBAC_SECDEL
03165 rsbac_boolean_t rsbac_need_overwrite_pm(struct dentry * dentry_p)
03166   {
03167     union rsbac_target_id_t       i_tid;
03168     union rsbac_attribute_value_t i_attr_val1;
03169 
03170     if(   !dentry_p
03171        || !dentry_p->d_inode)
03172       return FALSE;
03173 
03174     i_tid.file.device = dentry_p->d_sb->s_dev;
03175     i_tid.file.inode = dentry_p->d_inode->i_ino;
03176     i_tid.file.dentry_p = dentry_p;
03177     /* get target's file flags */
03178     if (rsbac_get_attr(PM,
03179                        T_FILE,
03180                        i_tid,
03181                        A_pm_object_type,
03182                        &i_attr_val1,
03183                        TRUE))
03184       {
03185         printk(KERN_WARNING "rsbac_need_overwrite_pm(): rsbac_get_attr() returned error!\n");
03186         return FALSE;
03187       }
03188 
03189     /* overwrite, if personal data */
03190     if (i_attr_val1.pm_object_type == PO_personal_data)
03191       return TRUE;
03192     else
03193       return FALSE;
03194   }
03195 #endif
03196 
03197 /* end of rsbac/adf/pm/main.c */

Generated on Fri Jun 17 09:45:19 2005 for RSBAC by  doxygen 1.4.2