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: 18/Jul/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_desc_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_FILE:
00811                 case T_DEV:
00812                 case T_NONE:
00813                   /* test owner's pm_role */
00814                   i_tid.user = owner;
00815                   if (rsbac_get_attr(PM,
00816                        T_USER,
00817                                      i_tid,
00818                                      A_pm_role,
00819                                      &i_attr_val1,
00820                                      TRUE))
00821                     {
00822                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00823                       return(NOT_GRANTED);
00824                     }
00825                   /* only administrators are allowed to do this */
00826                   if (i_attr_val1.pm_role != PR_system_admin)
00827                     return(NOT_GRANTED);
00828                   else
00829                     return(GRANTED);
00830 
00831                 /* all other cases */
00832                 default:
00833                   return(DO_NOT_CARE);
00834               }
00835 
00836         case R_APPEND_OPEN:
00837             switch(target)
00838               {
00839                 case T_FILE:
00840                 case T_FIFO:
00841                   /* get pm_object_type of target */
00842                   if (rsbac_get_attr(PM,
00843                        target,
00844                                      tid,
00845                                      A_pm_object_type,
00846                                      &i_attr_val1,
00847                                      FALSE))
00848                     {
00849                       printk(KERN_WARNING
00850                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00851                       return(NOT_GRANTED);
00852                     }
00853                   /* no append_open on TPs */
00854                   if(i_attr_val1.pm_object_type == PO_TP)
00855                     return(NOT_GRANTED);
00856                   /* TPs must not write on other than personal_data */
00857                   if(i_attr_val1.pm_object_type != PO_personal_data)
00858                     return(tp_check(caller_pid));
00859                   
00860                   /* only personal_data left -> */
00861                   /* check necessary && (purpose_bind || consent) */
00862                   return(na_and_pp_or_cs(caller_pid,
00863                                          tid.file,
00864                                          RSBAC_PM_A_APPEND));
00865                   break;
00866 
00867                 /* Appending to devices is no problem here */
00868                 case T_DEV:
00869                   return(DO_NOT_CARE);
00870 
00871                 case T_IPC:
00872                   /* get IPC-purpose */
00873                   i_pm_pp = get_ipc_purpose(tid.ipc);
00874                   /* if IPC-pp is NIL -> process type must be NIL */
00875                   if(!i_pm_pp)
00876                     {
00877                       /* get process-type of caller-process */
00878                       i_tid.process = caller_pid;
00879                       if (rsbac_get_attr(PM,
00880                        T_PROCESS,
00881                                          i_tid,
00882                                          A_pm_process_type,
00883                                          &i_attr_val1,
00884                                          FALSE))
00885                         { 
00886                           printk(KERN_WARNING
00887                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00888                           return(NOT_GRANTED);
00889                         }
00890                       if(i_attr_val1.pm_process_type == PP_TP)
00891                         return(NOT_GRANTED);
00892                       else
00893                         return(GRANTED);
00894                     }
00895                   /* OK, we do have an IPC-purpose */                  
00896                   /* get current_task of caller-process */
00897                   i_tid.process = caller_pid;
00898                   if (rsbac_get_attr(PM,
00899                        T_PROCESS,
00900                                      i_tid,
00901                                      A_pm_current_task,
00902                                      &i_attr_val1,
00903                                      FALSE))
00904                     {
00905                       printk(KERN_WARNING
00906                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00907                       return(NOT_GRANTED);
00908                     }
00909                   /* if current_task = NIL -> do not grant */
00910                   if(!i_attr_val1.pm_current_task)
00911                     {
00912                         return(NOT_GRANTED);
00913                     }
00914                   /* check necessary && purpose_bind */
00915                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
00916                                        caller_pid,
00917                                        RSBAC_PM_A_APPEND,
00918                                        tid.ipc));
00919                   break;
00920 
00921                 /* all other cases are undefined */
00922                 default: return(DO_NOT_CARE);
00923               }
00924 
00925         case R_CHANGE_GROUP:
00926             switch(target)
00927               {
00928                 /* We do not care about process or user groups */
00929                 /* all other cases */
00930                 default: return(DO_NOT_CARE);
00931               }
00932 
00933         case R_CHANGE_OWNER:
00934             switch(target)
00935               {
00936                 case T_FILE:
00937                 case T_FIFO:
00938                 case T_SYMLINK:
00939                   /* get pm_object_type of target */
00940                   if (rsbac_get_attr(PM,
00941                                      target,
00942                                      tid,
00943                                      A_pm_object_type,
00944                                      &i_attr_val1,
00945                                      FALSE))
00946                     {
00947                       printk(KERN_WARNING
00948                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00949                       return(NOT_GRANTED);
00950                     }
00951                   /* no access on TPs and personal_data*/
00952                   if(   (i_attr_val1.pm_object_type == PO_TP)
00953                      || (i_attr_val1.pm_object_type == PO_personal_data))
00954                     return(NOT_GRANTED);
00955                   else
00956                     return(GRANTED);
00957                   break;
00958 
00959                 /*  processes may only be given to other user, if    */
00960                 /*  current_task is authorized for him.              */
00961                 /*  If CONFIG_RSBAC_PM_ROLE_PROT is set, only changing  */
00962                 /*  to or from pm_role general_user is allowed.      */
00963                 case T_PROCESS:
00964                   /* get current_task of caller-process */
00965                   i_tid.process = caller_pid;
00966                   if (rsbac_get_attr(PM,
00967                        T_PROCESS,
00968                                      i_tid,
00969                                      A_pm_current_task,
00970                                      &i_attr_val1,
00971                                      FALSE))
00972                     {
00973                       printk(KERN_WARNING
00974                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00975                       return(NOT_GRANTED);
00976                     }
00977                   /* if task = NIL: no problem, grant */
00978                   if(!i_attr_val1.pm_current_task)
00979                     return(GRANTED);
00980 
00981                   /* get task_set_id of process-owner */
00982                   i_tid.user = owner;
00983                   if (rsbac_get_attr(PM,
00984                        T_USER,
00985                                      i_tid,
00986                                      A_pm_task_set,
00987                                      &i_attr_val2,
00988                                      FALSE))
00989                     {
00990                       printk(KERN_WARNING
00991                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
00992                       return(NOT_GRANTED);
00993                     }
00994                   /* if user has no set of authorized tasks -> do not grant */
00995                   if(!i_attr_val2.pm_task_set)
00996                     return(NOT_GRANTED);
00997 
00998                   /* grant, if task is in owner's authorized task_set */
00999                   i_pm_set_id.task_set = i_attr_val2.pm_task_set;
01000                   i_pm_set_member.task = i_attr_val1.pm_current_task;
01001                   if (rsbac_pm_set_member(0,PS_TASK,i_pm_set_id,i_pm_set_member))
01002                     return(GRANTED);
01003                   /* else: don't... */
01004                   else
01005                     return(NOT_GRANTED);
01006 
01007                 /* Change-owner without or for other target: do not care */
01008                 case T_DIR:
01009                 case T_IPC:
01010                 case T_NONE:
01011                   return(DO_NOT_CARE);
01012                 /* all other cases are undefined */
01013                 default:
01014                   return(DO_NOT_CARE);
01015               }
01016 
01017         case R_CLONE:
01018             if (target == T_PROCESS)
01019               {
01020                 /* get process_type of caller-process */
01021                 i_tid.process = caller_pid;
01022                 if (rsbac_get_attr(PM,
01023                        T_PROCESS,
01024                                    i_tid,
01025                                    A_pm_process_type,
01026                                    &i_attr_val1,
01027                                    FALSE))
01028                   {
01029                     printk(KERN_WARNING
01030                            "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01031                     return(NOT_GRANTED);
01032                   }
01033                 /* cloning is only allowed for normal processes */
01034                 if(i_attr_val1.pm_process_type == PP_none)
01035                   return(GRANTED);
01036                 else
01037                   return(NOT_GRANTED);
01038               }
01039             else
01040               return(DO_NOT_CARE);
01041 
01042         case R_CREATE:
01043             switch(target)
01044               {
01045                 /* Creating dir or (pseudo) file IN target dir! */
01046                 case T_DIR: 
01047                   /* get process_type of caller-process */
01048                   i_tid.process = caller_pid;
01049                   if (rsbac_get_attr(PM,
01050                        T_PROCESS,
01051                                      i_tid,
01052                                      A_pm_process_type,
01053                                      &i_attr_val1,
01054                                      FALSE))
01055                     {
01056                       printk(KERN_WARNING
01057                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01058                       return(NOT_GRANTED);
01059                     }
01060                   /* we only care for TPs here */
01061                   if(i_attr_val1.pm_process_type != PP_TP)
01062                     return(DO_NOT_CARE);
01063 
01064                   /* get current_task of caller-process */
01065                   i_tid.process = caller_pid;
01066                   if (rsbac_get_attr(PM,
01067                        T_PROCESS,
01068                                      i_tid,
01069                                      A_pm_current_task,
01070                                      &i_attr_val1,
01071                                      FALSE))
01072                     {
01073                       printk(KERN_WARNING
01074                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01075                              return(NOT_GRANTED);
01076                     }
01077                   if(!i_attr_val1.pm_current_task)
01078                     {
01079 #ifdef CONFIG_RSBAC_DEBUG
01080                       if(rsbac_debug_adf_pm)
01081                         printk(KERN_DEBUG
01082                                "rsbac_adf_request_pm(): no current_task for calling process trying to access personal_data\n");
01083 #endif
01084                       return(NOT_GRANTED);
01085                     }
01086 
01087                   /* get pm_tp of caller-process */
01088                   if (rsbac_get_attr(PM,
01089                        T_PROCESS,
01090                                      i_tid,
01091                                      A_pm_tp,
01092                                      &i_attr_val2,
01093                                      FALSE))
01094                     {
01095                       printk(KERN_WARNING
01096                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01097                       return(NOT_GRANTED);
01098                     }
01099                   if(!i_attr_val2.pm_tp)
01100                     {
01101 #ifdef CONFIG_RSBAC_DEBUG
01102                       if(rsbac_debug_adf_pm)
01103                         printk(KERN_DEBUG
01104                                "rsbac_adf_request_pm(): calling process trying to access personal_data has no TP-id\n");
01105 #endif
01106                       return(NOT_GRANTED);
01107                     }
01108 
01109                   /* get necessary accesses for NIL class */
01110                   i_pm_tid.na.task = i_attr_val1.pm_current_task;
01111                   i_pm_tid.na.object_class = 0;
01112                   i_pm_tid.na.tp = i_attr_val2.pm_tp;
01113                   if ((error = rsbac_pm_get_data(0,
01114                                                  PMT_NA,
01115                                                  i_pm_tid,
01116                                                  PD_accesses,
01117                                                  &i_data_val1)))
01118                     {
01119                       if(error != -RSBAC_EINVALIDTARGET)
01120                         printk(KERN_WARNING
01121                                "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
01122                                error);
01123                       return(NOT_GRANTED);
01124                     }
01125                   /* is requested access mode included in access mask? */
01126                   if(!(RSBAC_PM_A_CREATE & i_data_val1.accesses))
01127                     {
01128 #ifdef CONFIG_RSBAC_DEBUG
01129                       if(rsbac_debug_adf_pm)
01130                         printk(KERN_DEBUG
01131                                "rsbac_adf_request_pm(): requested access mode CREATE for class NIL is not necessary\n");
01132 #endif
01133                       return(NOT_GRANTED);
01134                     }
01135 
01136                   /* OK, create is necessary -> grant */
01137                   return(GRANTED);
01138                   break;
01139                   
01140                 case T_IPC:
01141                   /* get current_task of caller-process */
01142                   i_tid.process = caller_pid;
01143                   if (rsbac_get_attr(PM,
01144                        T_PROCESS,
01145                                      i_tid,
01146                                      A_pm_current_task,
01147                                      &i_attr_val1,
01148                                      FALSE))
01149                     {
01150                       printk(KERN_WARNING
01151                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01152                       return(NOT_GRANTED);
01153                     }
01154                   /* if current_task = NIL, do not care */
01155                   if(!i_attr_val1.pm_current_task)
01156                     return(DO_NOT_CARE);
01157 
01158                   /* check necessary */
01159                   return(na_ipc(i_attr_val1.pm_current_task,
01160                                 caller_pid,
01161                                 RSBAC_PM_A_CREATE));
01162                   break;
01163 
01164                 /* all other cases are undefined */
01165                 default: return(DO_NOT_CARE);
01166               }
01167 
01168         case R_DELETE:
01169             switch(target)
01170               {
01171                 case T_FILE:
01172                 case T_FIFO:
01173                 case T_SYMLINK:
01174                   /* get pm_object_type of target */
01175                   if (rsbac_get_attr(PM,
01176                        target,
01177                                      tid,
01178                                      A_pm_object_type,
01179                                      &i_attr_val1,
01180                                      FALSE))
01181                     {
01182                       printk(KERN_WARNING
01183                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01184                       return(NOT_GRANTED);
01185                     }
01186                   /* if TP: only TP_Manager */
01187                   if(i_attr_val1.pm_object_type == PO_TP)
01188                     {
01189                       /* test owner's pm_role */
01190                       i_tid.user = owner;
01191                       if (rsbac_get_attr(PM,
01192                        T_USER,
01193                                          i_tid,
01194                                          A_pm_role,
01195                                          &i_attr_val1,
01196                                          TRUE))
01197                         {
01198                           printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01199                           return(NOT_GRANTED);
01200                         }
01201                       if(i_attr_val1.pm_role == PR_tp_manager)
01202                         return(GRANTED);
01203                       else
01204                         return(NOT_GRANTED);
01205                     }
01206                   /* do not care for other than personal_data */
01207                   if(i_attr_val1.pm_object_type != PO_personal_data)
01208                     return(DO_NOT_CARE);
01209                   
01210                   /* check necessary && (purpose_bind || consent) */
01211                   /* (in fact, necessary means allowed here) */
01212                   return(na_and_pp_or_cs(caller_pid,
01213                                          tid.file,
01214                                          RSBAC_PM_A_DELETE));
01215                   break;
01216 
01217                 case T_IPC:
01218                   /* get current_task of caller-process */
01219                   i_tid.process = caller_pid;
01220                   if (rsbac_get_attr(PM,
01221                        T_PROCESS,
01222                                      i_tid,
01223                                      A_pm_current_task,
01224                                      &i_attr_val1,
01225                                      FALSE))
01226                     {
01227                       printk(KERN_WARNING
01228                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01229                       return(NOT_GRANTED);
01230                     }
01231                   /* if current_task = NIL, ipc_purpose must be NIL */
01232                   if(!i_attr_val1.pm_current_task)
01233                     {
01234                       if(!get_ipc_purpose(tid.ipc))
01235                         return(GRANTED);
01236                       else
01237                         return(NOT_GRANTED);
01238                     }
01239                   /* check necessary && purpose_bind */
01240                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01241                                        caller_pid,
01242                                        RSBAC_PM_A_DELETE,
01243                                        tid.ipc));
01244                   break;
01245 
01246                 case T_DIR:
01247                       return(DO_NOT_CARE);
01248                   break;
01249                 /* all other cases are undefined */
01250                 default: return(DO_NOT_CARE);
01251               }
01252 
01253         case R_EXECUTE:
01254         case R_MAP_EXEC:
01255             switch(target)
01256               {
01257                 case T_FILE:
01258                   /* get pm_object_type of target */
01259                   if (rsbac_get_attr(PM,
01260                        T_FILE,
01261                                      tid,
01262                                      A_pm_object_type,
01263                                      &i_attr_val1,
01264                                      FALSE))
01265                     {
01266                       printk(KERN_WARNING
01267                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01268                       return(NOT_GRANTED);
01269                     }
01270                   /* if not TP: do not care */
01271                   if(i_attr_val1.pm_object_type != PO_TP)
01272                     return(DO_NOT_CARE);
01273 
01274                   /* get pm_tp of target */
01275                   if (rsbac_get_attr(PM,
01276                        T_FILE,
01277                                      tid,
01278                                      A_pm_tp,
01279                                      &i_attr_val1,
01280                                      FALSE))
01281                     {
01282                       printk(KERN_WARNING
01283                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01284                       return(NOT_GRANTED);
01285                     }
01286                   /* if no tp: error! */
01287                   if(!i_attr_val1.pm_tp)
01288                     {
01289                       printk(KERN_WARNING
01290                              "rsbac_adf_request_pm(): file with object_type TP has no tp_id!\n");
01291                       return(NOT_GRANTED);
01292                     }
01293                   /* get current_task of caller-process */
01294                   i_tid.process = caller_pid;
01295                   if (rsbac_get_attr(PM,
01296                        T_PROCESS,
01297                                      i_tid,
01298                                      A_pm_current_task,
01299                                      &i_attr_val2,
01300                                      FALSE))
01301                     {
01302                       printk(KERN_WARNING
01303                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01304                       return(NOT_GRANTED);
01305                     }
01306                   /* if there is no current task, do not grant */
01307                   if(!i_attr_val2.pm_current_task)
01308                     {
01309 #ifdef CONFIG_RSBAC_DEBUG
01310                       if(rsbac_debug_adf_pm)
01311                         printk(KERN_DEBUG
01312                                "rsbac_adf_request_pm(): no current_task for process trying to execute TP\n");
01313 #endif
01314                       return(NOT_GRANTED);
01315                     }
01316                   /* get tp_set_id of current_task */
01317                   i_pm_tid.task = i_attr_val2.pm_current_task;
01318                   if ((error = rsbac_pm_get_data(0,
01319                                                  PMT_TASK,
01320                                                  i_pm_tid,
01321                                                  PD_tp_set,
01322                                                  &i_data_val1)))
01323                     {
01324                       if(error != -RSBAC_EINVALIDTARGET)
01325                         printk(KERN_WARNING
01326                                "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
01327                                error);
01328                       return(NOT_GRANTED);
01329                     }
01330                   /* if there is no tp set, do not grant */
01331                   if(!i_data_val1.tp_set)
01332                     {
01333 #ifdef CONFIG_RSBAC_DEBUG
01334                       if(rsbac_debug_adf_pm)
01335                         printk(KERN_DEBUG
01336                                "rsbac_adf_request_pm(): no tp_set for current_task of process trying to execute TP\n");
01337 #endif
01338                       return(NOT_GRANTED);
01339                     }
01340                   
01341                   /* grant, if file's tp is in process-current-task's */
01342                   /* authorized tp_set */
01343                   i_pm_set_id.tp_set = i_data_val1.tp_set;
01344                   i_pm_set_member.tp = i_attr_val1.pm_tp;
01345                   if (rsbac_pm_set_member(0,PS_TP,i_pm_set_id,i_pm_set_member))
01346                     return(GRANTED);
01347                   /* else: don't... */
01348                   else
01349                     {
01350 #ifdef CONFIG_RSBAC_DEBUG
01351                       if(rsbac_debug_adf_pm)
01352                         printk(KERN_DEBUG
01353                                "rsbac_adf_request_pm(): tp %i of file is not in tp_set %i of current_task %i of process\n",
01354                                i_attr_val1.pm_tp, i_data_val1.tp_set, i_attr_val2.pm_current_task);
01355 #endif
01356                       return(NOT_GRANTED);
01357                     }
01358 
01359                 /* all other cases are undefined */
01360                 default:
01361                   return(DO_NOT_CARE);
01362               }
01363 
01364         case R_GET_STATUS_DATA:
01365             switch(target)
01366               {
01367                 case T_SCD:
01368                   /* target rsbaclog? only for secoff and dataprot */
01369                   if (tid.scd != ST_rsbaclog)
01370                     return(GRANTED);
01371                   /* Secoff or dataprot? */
01372                   i_tid.user = owner;
01373                   if ((error=rsbac_get_attr(PM,
01374                        T_USER,
01375                                      i_tid,
01376                                      A_pm_role,
01377                                      &i_attr_val1,
01378                                      TRUE)))
01379                     {
01380                       printk(KERN_WARNING
01381                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error %i!\n",
01382                              error);
01383                       return(NOT_GRANTED);
01384                     }
01385                   /* grant only for secoff and dataprot */
01386                   if (   (i_attr_val1.pm_role == PR_security_officer)
01387                       || (i_attr_val1.pm_role == PR_data_protection_officer)
01388                      )
01389                     return(GRANTED);
01390                   else
01391                     return(NOT_GRANTED);
01392                 default:
01393                   return(DO_NOT_CARE);
01394                };
01395 
01396         case R_LINK_HARD:
01397             switch(target)
01398               {
01399                 case T_FILE:
01400                 case T_FIFO:
01401                 case T_SYMLINK:
01402                   /* get pm_object_type of target */
01403                   if (rsbac_get_attr(PM,
01404                        target,
01405                                      tid,
01406                                      A_pm_object_type,
01407                                      &i_attr_val1,
01408                                      FALSE))
01409                     {
01410                       printk(KERN_WARNING
01411                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01412                       return(NOT_GRANTED);
01413                     }
01414                   /* if OT = TP or OT = personal_data -> do not grant, else do */
01415                   if(   (i_attr_val1.pm_object_type == PO_TP)
01416                      || (i_attr_val1.pm_object_type == PO_personal_data))
01417                     return(NOT_GRANTED);
01418                   else
01419                     return(GRANTED);
01420                   break;
01421                 /* all other cases are undefined */
01422                 default: return(DO_NOT_CARE);
01423               }
01424 
01425         case R_MODIFY_ACCESS_DATA:
01426         case R_RENAME:
01427             switch(target)
01428               {
01429                 case T_FILE:
01430                 case T_FIFO:
01431                 case T_SYMLINK:
01432                   /* get pm_object_type of target */
01433                   if (rsbac_get_attr(PM,
01434                        target,
01435                                      tid,
01436                                      A_pm_object_type,
01437                                      &i_attr_val1,
01438                                      FALSE))
01439                     {
01440                       printk(KERN_WARNING
01441                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01442                       return(NOT_GRANTED);
01443                     }
01444 
01445                   /* if personal_data -> do not grant */
01446                   if(i_attr_val1.pm_object_type == PO_personal_data)
01447                     return(NOT_GRANTED);
01448                   /* alternative: check necessary && (purpose_bind || consent) */
01449                   /* return(na_and_pp_or_cs(caller_pid,
01450                                          tid.file,
01451                                          RSBAC_PM_A_WRITE)); */
01452 
01453                   /* if TP: only TP_Manager, else: do not care */
01454                   if(i_attr_val1.pm_object_type != PO_TP)
01455                     return(DO_NOT_CARE);
01456                   /* test owner's pm_role */
01457                   i_tid.user = owner;
01458                   if (rsbac_get_attr(PM,
01459                        T_USER,
01460                                      i_tid,
01461                                      A_pm_role,
01462                                      &i_attr_val1,
01463                                      TRUE))
01464                     {
01465                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01466                       return(NOT_GRANTED);
01467                     }
01468                   if(i_attr_val1.pm_role == PR_tp_manager)
01469                     return(GRANTED);
01470                   else
01471                     return(NOT_GRANTED);
01472                   break;
01473 
01474                 case T_DIR:
01475                   return(DO_NOT_CARE);
01476                   break;
01477                 /* all other cases are undefined */
01478                 default: return(DO_NOT_CARE);
01479               }
01480 
01481         case R_MODIFY_ATTRIBUTE:
01482             switch(attr)
01483               {
01484                 /* all pm relevant attributes are changed via sys_rsbac_pm */
01485                 /* using tickets in most cases -> deny here */
01486                 case A_pm_object_type:
01487                 case A_pm_tp:
01488                 case A_pm_role:
01489                 case A_pm_process_type:
01490                 case A_pm_current_task:
01491                 case A_pm_object_class:
01492                 case A_pm_ipc_purpose:
01493                 case A_pm_program_type:
01494                 case A_pm_task_set:
01495                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01496                 case A_owner:
01497                 case A_pseudo:
01498                 #endif
01499                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01500                 case A_auth_may_setuid:
01501                 case A_auth_may_set_cap:
01502                 case A_auth_start_uid:
01503                 case A_auth_start_euid:
01504                 case A_auth_start_gid:
01505                 case A_auth_start_egid:
01506                 case A_auth_program_file:
01507                 case A_auth_last_auth:
01508                 #endif
01509                   return(NOT_GRANTED);
01510                 /* All attributes (remove target!) */
01511                 case A_none:
01512                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01513                 case A_auth_add_f_cap:
01514                 case A_auth_remove_f_cap:
01515                 case A_auth_learn:
01516                 #endif
01517                   switch(target)
01518                     { /* special care for pm-relevant files and devs*/
01519                       case T_FILE:
01520                       case T_FIFO:
01521                       case T_DEV:
01522                         /* get object_type */
01523                         if (rsbac_get_attr(PM,
01524                        target,
01525                                            tid,
01526                                            A_pm_object_type,
01527                                            &i_attr_val1,
01528                                            FALSE))
01529                           {
01530                             printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01531                             return(NOT_GRANTED);
01532                           }
01533                         /* if OT is PM-relevant -> do not grant */
01534                         if(   (i_attr_val1.pm_object_type != PO_none)
01535                            && (i_attr_val1.pm_object_type != PO_non_personal_data))
01536                           return(NOT_GRANTED);
01537                         else
01538                           return(GRANTED);
01539 
01540                       /* we do not care for dirs or symlinks */
01541                       case T_DIR:
01542                       case T_SYMLINK:
01543                         return(DO_NOT_CARE);
01544                       
01545                       /* we do care for users, and if PM is active, we use  */
01546                       /* tickets to delete user attributes, so do not grant.*/ 
01547                       /* take care: if other models are active, their       */
01548                       /* additional restrictions are not met!               */
01549                       case T_USER:
01550                         return(NOT_GRANTED);
01551 
01552                       /* no removing of process attributes */
01553                       case T_PROCESS:
01554                         return(NOT_GRANTED);
01555 
01556                       case T_IPC:
01557                         /* get ipc_purpose */
01558                         if (rsbac_get_attr(PM,
01559                        T_IPC,
01560                                            tid,
01561                                            A_pm_ipc_purpose,
01562                                            &i_attr_val1,
01563                                            FALSE))
01564                           {
01565                             printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01566                             return(NOT_GRANTED);
01567                           }
01568                         /* if a purpose is set -> do not grant, else: who cares? */
01569                         if(i_attr_val1.pm_ipc_purpose)
01570                           return(NOT_GRANTED);
01571                         else
01572                           return(GRANTED);
01573 
01574                       default:
01575                         return(DO_NOT_CARE);
01576                     }
01577 
01578                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01579                 case A_log_array_low:
01580                 case A_log_array_high:
01581                 case A_log_program_based:
01582                 case A_log_user_based:
01583                 case A_symlink_add_uid:
01584                 case A_symlink_add_remote_ip:
01585                 case A_fake_root_uid:
01586                 case A_audit_uid:
01587                 case A_auid_exempt:
01588                   /* test owner's pm_role */
01589                   i_tid.user = owner;
01590                   if (rsbac_get_attr(PM,
01591                                      T_USER,
01592                                      i_tid,
01593                                      A_pm_role,
01594                                      &i_attr_val1,
01595                                      TRUE))
01596                     {
01597                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01598                       return(NOT_GRANTED);
01599                     }
01600                   /* security officer? -> grant  */
01601                   if (i_attr_val1.pm_role == PR_security_officer)
01602                     return(GRANTED);
01603                   else
01604                     return(NOT_GRANTED);
01605                 #endif
01606 
01607                 default:
01608                   return(DO_NOT_CARE);
01609               }
01610 
01611         case R_MODIFY_PERMISSIONS_DATA:
01612             switch(target)
01613               {
01614                 case T_FILE:
01615                 case T_FIFO:
01616                   /* get pm_object_type of target */
01617                   if (rsbac_get_attr(PM,
01618                        target,
01619                                      tid,
01620                                      A_pm_object_type,
01621                                      &i_attr_val1,
01622                                      FALSE))
01623                     {
01624                       printk(KERN_WARNING
01625                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01626                       return(NOT_GRANTED);
01627                     }
01628                   /* if TP: only TP_Manager, else: do not care */
01629                   if(i_attr_val1.pm_object_type != PO_TP)
01630                     return(DO_NOT_CARE);
01631                   /* test owner's pm_role */
01632                   i_tid.user = owner;
01633                   if (rsbac_get_attr(PM,
01634                        T_USER,
01635                                      i_tid,
01636                                      A_pm_role,
01637                                      &i_attr_val1,
01638                                      TRUE))
01639                     {
01640                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01641                       return(NOT_GRANTED);
01642                     }
01643                   if(i_attr_val1.pm_role == PR_tp_manager)
01644                     return(GRANTED);
01645                   else
01646                     return(NOT_GRANTED);
01647                   break;
01648 
01649                 /* all other cases are undefined */
01650                 default: return(DO_NOT_CARE);
01651               }
01652 
01653         case R_MODIFY_SYSTEM_DATA:
01654             switch(target)
01655               {
01656                 case T_SCD:
01657                   /* target rlimit? no problem, but needed -> grant */
01658                   if (tid.scd == ST_rlimit)
01659                     return(GRANTED);
01660                   /* Administrator? */
01661                   i_tid.user = owner;
01662                   if (rsbac_get_attr(PM,
01663                        T_USER,
01664                                      i_tid,
01665                                      A_pm_role,
01666                                      &i_attr_val1,
01667                                      TRUE))
01668                     {
01669                       printk(KERN_WARNING
01670                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01671                       return(NOT_GRANTED);
01672                     }
01673                   /* if rsbaclog: grant only for secoff and dataprot */
01674                   if(tid.scd == ST_rsbaclog)
01675                     {
01676                       if (   (i_attr_val1.pm_role == PR_security_officer)
01677                           || (i_attr_val1.pm_role == PR_data_protection_officer)
01678                          )
01679                         return(GRANTED);
01680                       else
01681                         return(NOT_GRANTED);
01682                     }
01683                   /* if rsbac_log_remote: grant only for secoff */
01684                   if(tid.scd == ST_rsbac_remote_log)
01685                     {
01686                       if (   (i_attr_val1.pm_role == PR_security_officer)
01687                           || (i_attr_val1.pm_role == PR_data_protection_officer)
01688                          )
01689                         return(GRANTED);
01690                       else
01691                         return(NOT_GRANTED);
01692                     }
01693                   /* other scds: if administrator, then grant */
01694                   if (i_attr_val1.pm_role == PR_system_admin)
01695                     return(GRANTED);
01696                   else
01697                     return(NOT_GRANTED);
01698                   
01699                 /* all other cases are undefined */
01700                 default: return(DO_NOT_CARE);
01701               }
01702 
01703         case R_MOUNT:
01704             switch(target)
01705               {
01706                 case T_FILE:
01707                 case T_DIR:
01708                 case T_DEV:
01709                   /* Administrator? */
01710                   i_tid.user = owner;
01711                   if (rsbac_get_attr(PM,
01712                        T_USER,
01713                                      i_tid,
01714                                      A_pm_role,
01715                                      &i_attr_val1,
01716                                      TRUE))
01717                     {
01718                       printk(KERN_WARNING
01719                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01720                       return(NOT_GRANTED);
01721                     }
01722                   /* if administrator, then grant */
01723                   if (i_attr_val1.pm_role == PR_system_admin)
01724                     return(GRANTED);
01725                   else
01726                     return(NOT_GRANTED);
01727 
01728                 /* all other cases are undefined */
01729                 default: return(DO_NOT_CARE);
01730               }
01731 
01732         case R_READ:
01733             switch(target)
01734               {
01735 #ifdef CONFIG_RSBAC_RW
01736                 case T_FILE:
01737                 case T_FIFO:
01738                   /* get pm_object_type of target */
01739                   if (rsbac_get_attr(PM,
01740                        target,
01741                                      tid,
01742                                      A_pm_object_type,
01743                                      &i_attr_val1,
01744                                      FALSE))
01745                     {
01746                       printk(KERN_WARNING
01747                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01748                       return(NOT_GRANTED);
01749                     }
01750                   /* no read_open on TPs */
01751                   if(i_attr_val1.pm_object_type == PO_TP)
01752                     return(NOT_GRANTED);
01753                   /* do not care for other than personal_data */
01754                   if(i_attr_val1.pm_object_type != PO_personal_data)
01755                     return(DO_NOT_CARE);
01756                   
01757                   /* check necessary && (purpose_bind || consent) */
01758                   return(na_and_pp_or_cs(caller_pid,
01759                                          tid.file,
01760                                          RSBAC_PM_A_READ));
01761                   break;
01762 
01763                 case T_DEV:
01764                   /* get pm_object_type of target */
01765                   if (rsbac_get_attr(PM,
01766                        T_DEV,
01767                                      tid,
01768                                      A_pm_object_type,
01769                                      &i_attr_val1,
01770                                      FALSE))
01771                     {
01772                       printk(KERN_WARNING
01773                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01774                       return(NOT_GRANTED);
01775                     }
01776                   /* check read_open only on devs containing personal_data */
01777                   if(i_attr_val1.pm_object_type != PO_personal_data)
01778                     return(DO_NOT_CARE);
01779                   /* check necessary && purpose_bind */
01780                   return(na_dev(caller_pid,
01781                                 RSBAC_PM_A_READ,
01782                                 tid.dev));
01783 
01784 #ifdef CONFIG_RSBAC_RW_SOCK
01785                 case T_IPC:
01786                   /* get current_task of caller-process */
01787                   i_tid.process = caller_pid;
01788                   if (rsbac_get_attr(PM,
01789                        T_PROCESS,
01790                                      i_tid,
01791                                      A_pm_current_task,
01792                                      &i_attr_val1,
01793                                      FALSE))
01794                     {
01795                       printk(KERN_WARNING
01796                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01797                       return(NOT_GRANTED);
01798                     }
01799                   /* if current_task = NIL, ipc_purpose must be NIL */
01800                   if(!i_attr_val1.pm_current_task)
01801                     {
01802                       if(!get_ipc_purpose(tid.ipc))
01803                         return(GRANTED);
01804                       else
01805                         return(NOT_GRANTED);
01806                     }
01807                   /* check necessary && purpose_bind */
01808                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01809                                        caller_pid,
01810                                        RSBAC_PM_A_READ,
01811                                        tid.ipc));
01812                   break;
01813 #endif /* RW_SOCK */
01814 #endif /* RW */
01815 
01816                 /* all other cases are undefined */
01817                 default: return(DO_NOT_CARE);
01818               }
01819 
01820         case R_READ_ATTRIBUTE:
01821             switch(attr)
01822               {
01823                 case A_pm_object_type:
01824                 case A_pm_tp:
01825                 case A_pm_role:
01826                 case A_pm_process_type:
01827                 case A_pm_current_task:
01828                 case A_pm_object_class:
01829                 case A_pm_ipc_purpose:
01830                 case A_pm_program_type:
01831                 case A_pm_task_set:
01832                 #ifdef CONFIG_RSBAC_PM_GEN_PROT
01833                 case A_owner:
01834                 case A_pseudo:
01835                 case A_log_array_low:
01836                 case A_log_array_high:
01837                 case A_log_program_based:
01838                 case A_log_user_based:
01839                 case A_symlink_add_remote_ip:
01840                 case A_symlink_add_uid:
01841                 case A_fake_root_uid:
01842                 case A_audit_uid:
01843                 case A_auid_exempt:
01844                 #endif
01845                 #ifdef CONFIG_RSBAC_PM_AUTH_PROT
01846                 case A_auth_may_setuid:
01847                 case A_auth_may_set_cap:
01848                 case A_auth_start_uid:
01849                 case A_auth_start_euid:
01850                 case A_auth_start_gid:
01851                 case A_auth_start_egid:
01852                 case A_auth_program_file:
01853                 case A_auth_learn:
01854                 case A_auth_last_auth:
01855                 #endif
01856                   /* Security Officer or Data Protection Officer? */
01857                   i_tid.user = owner;
01858                   if (rsbac_get_attr(PM,
01859                                      T_USER,
01860                                      i_tid,
01861                                      A_pm_role,
01862                                      &i_attr_val1,
01863                                      TRUE))
01864                     {
01865                       printk(KERN_WARNING
01866                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01867                       return(NOT_GRANTED);
01868                     }
01869                   /* if sec_officer or data_prot_off, then grant */
01870                   if(   (i_attr_val1.pm_role == PR_security_officer)
01871                      || (i_attr_val1.pm_role == PR_data_protection_officer))
01872                     return(GRANTED);
01873                   else
01874                     return(NOT_GRANTED);
01875 
01876                 default:
01877                   return(DO_NOT_CARE);
01878               }
01879 
01880         case R_READ_OPEN:
01881             switch(target)
01882               {
01883                 case T_FILE:
01884                 case T_FIFO:
01885                   /* get pm_object_type of target */
01886                   if (rsbac_get_attr(PM,
01887                        target,
01888                                      tid,
01889                                      A_pm_object_type,
01890                                      &i_attr_val1,
01891                                      FALSE))
01892                     {
01893                       printk(KERN_WARNING
01894                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01895                       return(NOT_GRANTED);
01896                     }
01897                   /* no read_open on TPs */
01898                   if(i_attr_val1.pm_object_type == PO_TP)
01899                     return(NOT_GRANTED);
01900                   /* do not care for other than personal_data */
01901                   if(i_attr_val1.pm_object_type != PO_personal_data)
01902                     return(DO_NOT_CARE);
01903                   
01904                   /* check necessary && (purpose_bind || consent) */
01905                   return(na_and_pp_or_cs(caller_pid,
01906                                          tid.file,
01907                                          RSBAC_PM_A_READ));
01908                   break;
01909 
01910                 case T_DEV:
01911                   /* get pm_object_type of target */
01912                   if (rsbac_get_attr(PM,
01913                        T_DEV,
01914                                      tid,
01915                                      A_pm_object_type,
01916                                      &i_attr_val1,
01917                                      FALSE))
01918                     {
01919                       printk(KERN_WARNING
01920                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01921                       return(NOT_GRANTED);
01922                     }
01923                   /* check read_open only on devs containing personal_data */
01924                   if(i_attr_val1.pm_object_type != PO_personal_data)
01925                     return(DO_NOT_CARE);
01926                   /* check necessary && purpose_bind */
01927                   return(na_dev(caller_pid,
01928                                 RSBAC_PM_A_READ,
01929                                 tid.dev));
01930 
01931                 case T_IPC:
01932                   /* get current_task of caller-process */
01933                   i_tid.process = caller_pid;
01934                   if (rsbac_get_attr(PM,
01935                        T_PROCESS,
01936                                      i_tid,
01937                                      A_pm_current_task,
01938                                      &i_attr_val1,
01939                                      FALSE))
01940                     {
01941                       printk(KERN_WARNING
01942                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01943                       return(NOT_GRANTED);
01944                     }
01945                   /* if current_task = NIL, ipc_purpose must be NIL */
01946                   if(!i_attr_val1.pm_current_task)
01947                     {
01948                       if(!get_ipc_purpose(tid.ipc))
01949                         return(GRANTED);
01950                       else
01951                         return(NOT_GRANTED);
01952                     }
01953                   /* check necessary && purpose_bind */
01954                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
01955                                        caller_pid,
01956                                        RSBAC_PM_A_READ,
01957                                        tid.ipc));
01958                   break;
01959 
01960                 /* all other cases are undefined */
01961                 default: return(DO_NOT_CARE);
01962               }
01963 
01964         case R_READ_WRITE_OPEN:
01965             switch(target)
01966               {
01967                 case T_FILE:
01968                 case T_FIFO:
01969                   /* get pm_object_type of target */
01970                   if (rsbac_get_attr(PM,
01971                        target,
01972                                      tid,
01973                                      A_pm_object_type,
01974                                      &i_attr_val1,
01975                                      FALSE))
01976                     {
01977                       printk(KERN_WARNING
01978                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
01979                       return(NOT_GRANTED);
01980                     }
01981                   /* no read_write_open on TPs */
01982                   if(i_attr_val1.pm_object_type == PO_TP)
01983                     return(NOT_GRANTED);
01984                   /* TPs must not write on other than personal_data */
01985                   if(i_attr_val1.pm_object_type != PO_personal_data)
01986                     return(tp_check(caller_pid));
01987                   
01988                   /* check necessary && (purpose_bind || consent) */
01989                   return(na_and_pp_or_cs(caller_pid,
01990                                          tid.file,
01991                                          RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
01992                   break;
01993 
01994                 case T_DEV:
01995                   /* get pm_object_type of target */
01996                   if (rsbac_get_attr(PM,
01997                        T_DEV,
01998                                      tid,
01999                                      A_pm_object_type,
02000                                      &i_attr_val1,
02001                                      FALSE))
02002                     {
02003                       printk(KERN_WARNING
02004                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02005                       return(NOT_GRANTED);
02006                     }
02007                   /* check read_write_open only on devs containing personal_data or TPs*/
02008                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02009                      && (i_attr_val1.pm_object_type != PO_TP) )
02010                     return(DO_NOT_CARE);
02011                   /* check necessary && purpose_bind */
02012                   return(na_dev(caller_pid,
02013                                 RSBAC_PM_A_READ | RSBAC_PM_A_WRITE,
02014                                 tid.dev));
02015 
02016                 case T_IPC:
02017                   /* get IPC-purpose */
02018                   i_pm_pp = get_ipc_purpose(tid.ipc);
02019                   /* if IPC-pp is NIL -> process type must be NIL */
02020                   if(!i_pm_pp)
02021                     {
02022                       /* get process-type of caller-process */
02023                       i_tid.process = caller_pid;
02024                       if (rsbac_get_attr(PM,
02025                        T_PROCESS,
02026                                          i_tid,
02027                                          A_pm_process_type,
02028                                          &i_attr_val1,
02029                                          FALSE))
02030                         { 
02031                           printk(KERN_WARNING
02032                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02033                           return(NOT_GRANTED);
02034                         }
02035                       if(i_attr_val1.pm_process_type == PP_TP)
02036                         return(NOT_GRANTED);
02037                       else
02038                         return(GRANTED);
02039                     }
02040                   /* OK, we do have an IPC-purpose */                  
02041                   /* get current_task of caller-process */
02042                   i_tid.process = caller_pid;
02043                   if (rsbac_get_attr(PM,
02044                        T_PROCESS,
02045                                      i_tid,
02046                                      A_pm_current_task,
02047                                      &i_attr_val1,
02048                                      FALSE))
02049                     {
02050                       printk(KERN_WARNING
02051                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02052                       return(NOT_GRANTED);
02053                     }
02054                   /* if current_task = NIL -> do not grant */
02055                   if(!i_attr_val1.pm_current_task)
02056                     {
02057                         return(NOT_GRANTED);
02058                     }
02059                   /* check necessary && purpose_bind */
02060                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02061                                        caller_pid,
02062                                        RSBAC_PM_A_READ | RSBAC_PM_A_WRITE,
02063                                        tid.ipc));
02064                   break;
02065 
02066                 /* all other cases are undefined */
02067                 default: return(DO_NOT_CARE);
02068               }
02069 
02070         case R_REMOVE_FROM_KERNEL:
02071             switch(target)
02072               {
02073                 case T_FILE:
02074                 case T_DEV:
02075                 case T_NONE:
02076                   /* test owner's pm_role */
02077                   i_tid.user = owner;
02078                   if (rsbac_get_attr(PM,
02079                        T_USER,
02080                                      i_tid,
02081                                      A_pm_role,
02082                                      &i_attr_val1,
02083                                      TRUE))
02084                     {
02085                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02086                       return(NOT_GRANTED);
02087                     }
02088                   /* only administrators are allowed to do this */
02089                   if (i_attr_val1.pm_role != PR_system_admin)
02090                     return(NOT_GRANTED);
02091                   /* That's it */
02092                   return(GRANTED);
02093 
02094                 /* all other cases are undefined */
02095                 default: return(DO_NOT_CARE);
02096               }
02097 
02098 /*      case R_RENAME: see R_MODIFY_ACCESS_DATA */
02099 
02100         case R_SEND_SIGNAL:
02101             switch(target)
02102               {
02103                 case T_PROCESS:
02104                   /* TPs are not allowed to send signals */
02105                   /* get process_type of caller-process */
02106                   i_tid.process = caller_pid;
02107                   if (rsbac_get_attr(PM,
02108                        T_PROCESS,
02109                                      i_tid,
02110                                      A_pm_process_type,
02111                                      &i_attr_val1,
02112                                      FALSE))
02113                     {
02114                       printk(KERN_WARNING
02115                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02116                       return(NOT_GRANTED);
02117                     }
02118                   /* we do not allow TPs here */
02119                   if(i_attr_val1.pm_process_type == PP_TP)
02120                     return(NOT_GRANTED);
02121 
02122                   /* SIGKILL to TPs is restricted to tp_managers to prevent */
02123                   /* inconsistencies */
02124                   /* get process_type of target-process */
02125                   if (rsbac_get_attr(PM,
02126                        T_PROCESS,
02127                                      tid,
02128                                      A_pm_process_type,
02129                                      &i_attr_val1,
02130                                      FALSE))
02131                     {
02132                       printk(KERN_WARNING
02133                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02134                       return(NOT_GRANTED);
02135                     }
02136                   /* we only care for TPs here */
02137                   if(i_attr_val1.pm_process_type != PP_TP)
02138                     return(DO_NOT_CARE);
02139   
02140                   /* test owner's pm_role */
02141                   i_tid.user = owner;
02142                   if (rsbac_get_attr(PM,
02143                        T_USER,
02144                                      i_tid,
02145                                      A_pm_role,
02146                                      &i_attr_val1,
02147                                      TRUE))
02148                     {
02149                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02150                       return(NOT_GRANTED);
02151                     }
02152                   /* only tp_managers are allowed to do this */
02153                   if (i_attr_val1.pm_role != PR_tp_manager)
02154                     return(NOT_GRANTED);
02155                   /* That's it */
02156                   return(GRANTED);
02157 
02158                 /* all other cases are undefined */
02159                 default:
02160                   return(DO_NOT_CARE);
02161               }
02162 
02163         case R_SHUTDOWN:
02164             switch(target)
02165               {
02166                 case T_NONE:
02167                   /* test owner's pm_role */
02168                   i_tid.user = owner;
02169                   if (rsbac_get_attr(PM,
02170                        T_USER,
02171                                      i_tid,
02172                                      A_pm_role,
02173                                      &i_attr_val1,
02174                                      TRUE))
02175                     {
02176                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02177                       return(NOT_GRANTED);
02178                     }
02179                   /* only administrators are allowed to do this */
02180                   if (i_attr_val1.pm_role != PR_system_admin)
02181                     return(NOT_GRANTED);
02182                   /* That's it */
02183                   return(GRANTED);
02184 
02185                 /* all other cases are undefined */
02186                 default: return(DO_NOT_CARE);
02187               }
02188 
02189         case R_SWITCH_LOG:
02190             switch(target)
02191               {
02192                 case T_NONE:
02193                   /* test owner's pm_role */
02194                   i_tid.user = owner;
02195                   if (rsbac_get_attr(PM,
02196                        T_USER,
02197                                      i_tid,
02198                                      A_pm_role,
02199                                      &i_attr_val1,
02200                                      FALSE))
02201                     {
02202                       printk(KERN_WARNING "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02203                       return(NOT_GRANTED);
02204                     }
02205                   /* security officer? -> grant  */
02206                   if (i_attr_val1.pm_role == PR_security_officer)
02207                     return(GRANTED);
02208                   else
02209                     return(NOT_GRANTED);
02210 
02211                 /* all other cases are undefined */
02212                 default: return(DO_NOT_CARE);
02213               }
02214               
02215         case R_SWITCH_MODULE:
02216             switch(target)
02217               {
02218                 case T_NONE:
02219                   /* we need the switch_target */
02220                   if(attr != A_switch_target)
02221                     return(UNDEFINED);
02222                   /* deny PM to be switched, do not care for others */
02223                   if(   (attr_val.switch_target == PM)
02224                      #ifdef CONFIG_RSBAC_PM_AUTH_PROT
02225                      || (attr_val.switch_target == AUTH)
02226                      #endif
02227                      #ifdef CONFIG_RSBAC_SOFTMODE
02228                      || (attr_val.switch_target == SOFTMODE)
02229                      #endif
02230                      #ifdef CONFIG_RSBAC_FREEZE
02231                      || (attr_val.switch_target == FREEZE)
02232                      #endif
02233                     )
02234                     return(NOT_GRANTED);
02235                   else
02236                     return(DO_NOT_CARE);
02237 
02238                 /* all other cases are undefined */
02239                 default: return(DO_NOT_CARE);
02240               }
02241               
02242         /* notify only, handled by adf-dispatcher */
02243         case R_TERMINATE:
02244             if (target == T_PROCESS)
02245               { /* Remove input and output purpose set of process */
02246                 i_pm_set_id.in_pp_set = tid.process;
02247                 rsbac_pm_remove_set(0, PS_IN_PP, i_pm_set_id);
02248                 i_pm_set_id.out_pp_set = tid.process;
02249                 rsbac_pm_remove_set(0, PS_OUT_PP, i_pm_set_id);
02250                 return(GRANTED);
02251               }
02252             else
02253               return(DO_NOT_CARE);
02254 
02255         case R_TRACE:
02256             switch(target)
02257               {
02258                 case T_PROCESS:
02259                   /* get process_type of calling process */
02260                   i_tid.process = caller_pid;
02261                   if (rsbac_get_attr(PM,
02262                        T_PROCESS,
02263                                      i_tid,
02264                                      A_pm_process_type,
02265                                      &i_attr_val1,
02266                                      FALSE))
02267                     {
02268                       printk(KERN_WARNING
02269                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02270                       return(NOT_GRANTED);
02271                     }
02272                   /* do not grant for TPs */
02273                   if(i_attr_val1.pm_process_type == PP_TP)
02274                     return(NOT_GRANTED);
02275 
02276                   /* get process_type of target-process */
02277                   if (rsbac_get_attr(PM,
02278                        T_PROCESS,
02279                                      tid,
02280                                      A_pm_process_type,
02281                                      &i_attr_val1,
02282                                      FALSE))
02283                     {
02284                       printk(KERN_WARNING
02285                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02286                       return(NOT_GRANTED);
02287                     }
02288                   /* do not grant for TPs */
02289                   if(i_attr_val1.pm_process_type == PP_TP)
02290                     return(NOT_GRANTED);
02291 
02292                   /* neither P1 nor P2 is TP -> grant */
02293                   return(GRANTED);
02294 
02295                 /* all other cases are undefined */
02296                 default:
02297                   return(DO_NOT_CARE);
02298               }
02299 
02300         case R_TRUNCATE:
02301             switch(target)
02302               {
02303                 case T_FILE:
02304                   /* get pm_object_type of target */
02305                   if (rsbac_get_attr(PM,
02306                        T_FILE,
02307                                      tid,
02308                                      A_pm_object_type,
02309                                      &i_attr_val1,
02310                                      FALSE))
02311                     {
02312                       printk(KERN_WARNING
02313                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02314                       return(NOT_GRANTED);
02315                     }
02316                   /* no append_open on TPs */
02317                   if(i_attr_val1.pm_object_type == PO_TP)
02318                     return(NOT_GRANTED);
02319                   /* TPs must not write on other than personal_data */
02320                   if(i_attr_val1.pm_object_type != PO_personal_data)
02321                     return(tp_check(caller_pid));
02322                   
02323                   /* check necessary && (purpose_bind || consent) */
02324                   return(na_and_pp_or_cs(caller_pid,
02325                                          tid.file,
02326                                          RSBAC_PM_A_WRITE));
02327                   break;
02328 
02329                 /* all other cases are undefined */
02330                 default: return(DO_NOT_CARE);
02331               }
02332 
02333         case R_UMOUNT:
02334             switch(target)
02335               {
02336                 case T_FILE:
02337                 case T_DIR:
02338                 case T_DEV:
02339                   /* Administrator? */
02340                   i_tid.user = owner;
02341                   if (rsbac_get_attr(PM,
02342                        T_USER,
02343                                      i_tid,
02344                                      A_pm_role,
02345                                      &i_attr_val1,
02346                                      TRUE))
02347                     {
02348                       printk(KERN_WARNING
02349                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02350                       return(NOT_GRANTED);
02351                     }
02352                   /* if administrator, then grant */
02353                   if (i_attr_val1.pm_role == PR_system_admin)
02354                     return(GRANTED);
02355                   else
02356                     return(NOT_GRANTED);
02357 
02358                 /* all other cases are undefined */
02359                 default: return(DO_NOT_CARE);
02360               }
02361 
02362         case R_WRITE:
02363             switch(target)
02364               {
02365 #ifdef CONFIG_RSBAC_RW
02366                 case T_FILE:
02367                 case T_FIFO:
02368                   /* get pm_object_type of target */
02369                   if (rsbac_get_attr(PM,
02370                        target,
02371                                      tid,
02372                                      A_pm_object_type,
02373                                      &i_attr_val1,
02374                                      FALSE))
02375                     {
02376                       printk(KERN_WARNING
02377                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02378                       return(NOT_GRANTED);
02379                     }
02380                   /* no append_open on TPs */
02381                   if(i_attr_val1.pm_object_type == PO_TP)
02382                     return(NOT_GRANTED);
02383                   /* TPs must not write on other than personal_data */
02384                   if(i_attr_val1.pm_object_type != PO_personal_data)
02385                     return(tp_check(caller_pid));
02386                   
02387                   /* check necessary && (purpose_bind || consent) */
02388                   return(na_and_pp_or_cs(caller_pid,
02389                                          tid.file,
02390                                          RSBAC_PM_A_WRITE));
02391                   break;
02392 
02393                 case T_DEV:
02394                   /* get pm_object_type of target */
02395                   if (rsbac_get_attr(PM,
02396                        T_DEV,
02397                                      tid,
02398                                      A_pm_object_type,
02399                                      &i_attr_val1,
02400                                      FALSE))
02401                     {
02402                       printk(KERN_WARNING
02403                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02404                       return(NOT_GRANTED);
02405                     }
02406                   /* check write_open only on devs containing personal_data or TPs*/
02407                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02408                      && (i_attr_val1.pm_object_type != PO_TP) )
02409                     return(DO_NOT_CARE);
02410                   /* check necessary && purpose_bind */
02411                   return(na_dev(caller_pid,
02412                                 RSBAC_PM_A_WRITE,
02413                                 tid.dev));
02414 
02415 #ifdef CONFIG_RSBAC_RW_SOCK
02416                 case T_IPC:
02417                   /* get IPC-purpose */
02418                   i_pm_pp = get_ipc_purpose(tid.ipc);
02419                   /* if IPC-pp is NIL -> process type must be NIL */
02420                   if(!i_pm_pp)
02421                     {
02422                       /* get process-type of caller-process */
02423                       i_tid.process = caller_pid;
02424                       if (rsbac_get_attr(PM,
02425                        T_PROCESS,
02426                                          i_tid,
02427                                          A_pm_process_type,
02428                                          &i_attr_val1,
02429                                          FALSE))
02430                         { 
02431                           printk(KERN_WARNING
02432                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02433                           return(NOT_GRANTED);
02434                         }
02435                       if(i_attr_val1.pm_process_type == PP_TP)
02436                         return(NOT_GRANTED);
02437                       else
02438                         return(GRANTED);
02439                     }
02440                   /* OK, we do have an IPC-purpose */                  
02441                   /* get current_task of caller-process */
02442                   i_tid.process = caller_pid;
02443                   if (rsbac_get_attr(PM,
02444                        T_PROCESS,
02445                                      i_tid,
02446                                      A_pm_current_task,
02447                                      &i_attr_val1,
02448                                      FALSE))
02449                     {
02450                       printk(KERN_WARNING
02451                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02452                       return(NOT_GRANTED);
02453                     }
02454                   /* if current_task = NIL -> do not grant */
02455                   if(!i_attr_val1.pm_current_task)
02456                     {
02457                         return(NOT_GRANTED);
02458                     }
02459                   /* check necessary && purpose_bind */
02460                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02461                                        caller_pid,
02462                                        RSBAC_PM_A_WRITE,
02463                                        tid.ipc));
02464                   break;
02465 #endif
02466 #endif
02467 
02468                 /* all other cases are undefined */
02469                 default: return(DO_NOT_CARE);
02470               }
02471 
02472         case R_WRITE_OPEN:
02473             switch(target)
02474               {
02475                 case T_FILE:
02476                 case T_FIFO:
02477                   /* get pm_object_type of target */
02478                   if (rsbac_get_attr(PM,
02479                        target,
02480                                      tid,
02481                                      A_pm_object_type,
02482                                      &i_attr_val1,
02483                                      FALSE))
02484                     {
02485                       printk(KERN_WARNING
02486                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02487                       return(NOT_GRANTED);
02488                     }
02489                   /* no append_open on TPs */
02490                   if(i_attr_val1.pm_object_type == PO_TP)
02491                     return(NOT_GRANTED);
02492                   /* TPs must not write on other than personal_data */
02493                   if(i_attr_val1.pm_object_type != PO_personal_data)
02494                     return(tp_check(caller_pid));
02495                   
02496                   /* check necessary && (purpose_bind || consent) */
02497                   return(na_and_pp_or_cs(caller_pid,
02498                                          tid.file,
02499                                          RSBAC_PM_A_WRITE));
02500                   break;
02501 
02502                 case T_DEV:
02503                   /* get pm_object_type of target */
02504                   if (rsbac_get_attr(PM,
02505                        T_DEV,
02506                                      tid,
02507                                      A_pm_object_type,
02508                                      &i_attr_val1,
02509                                      FALSE))
02510                     {
02511                       printk(KERN_WARNING
02512                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02513                       return(NOT_GRANTED);
02514                     }
02515                   /* check write_open only on devs containing personal_data or TPs*/
02516                   if(   (i_attr_val1.pm_object_type != PO_personal_data)
02517                      && (i_attr_val1.pm_object_type != PO_TP) )
02518                     return(DO_NOT_CARE);
02519                   /* check necessary && purpose_bind */
02520                   return(na_dev(caller_pid,
02521                                 RSBAC_PM_A_WRITE,
02522                                 tid.dev));
02523 
02524                 case T_IPC:
02525                   /* get IPC-purpose */
02526                   i_pm_pp = get_ipc_purpose(tid.ipc);
02527                   /* if IPC-pp is NIL -> process type must be NIL */
02528                   if(!i_pm_pp)
02529                     {
02530                       /* get process-type of caller-process */
02531                       i_tid.process = caller_pid;
02532                       if (rsbac_get_attr(PM,
02533                        T_PROCESS,
02534                                          i_tid,
02535                                          A_pm_process_type,
02536                                          &i_attr_val1,
02537                                          FALSE))
02538                         { 
02539                           printk(KERN_WARNING
02540                                  "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02541                           return(NOT_GRANTED);
02542                         }
02543                       if(i_attr_val1.pm_process_type == PP_TP)
02544                         return(NOT_GRANTED);
02545                       else
02546                         return(GRANTED);
02547                     }
02548                   /* OK, we do have an IPC-purpose */                  
02549                   /* get current_task of caller-process */
02550                   i_tid.process = caller_pid;
02551                   if (rsbac_get_attr(PM,
02552                        T_PROCESS,
02553                                      i_tid,
02554                                      A_pm_current_task,
02555                                      &i_attr_val1,
02556                                      FALSE))
02557                     {
02558                       printk(KERN_WARNING
02559                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02560                       return(NOT_GRANTED);
02561                     }
02562                   /* if current_task = NIL -> do not grant */
02563                   if(!i_attr_val1.pm_current_task)
02564                     {
02565                         return(NOT_GRANTED);
02566                     }
02567                   /* check necessary && purpose_bind */
02568                   return(na_and_pp_ipc(i_attr_val1.pm_current_task,
02569                                        caller_pid,
02570                                        RSBAC_PM_A_WRITE,
02571                                        tid.ipc));
02572                   break;
02573 
02574                 /* all other cases are undefined */
02575                 default: return(DO_NOT_CARE);
02576               }
02577 
02578 
02579 /*********************/
02580         default: return DO_NOT_CARE;
02581       }
02582 
02583     return(result);
02584   } /* end of rsbac_adf_request_pm() */
02585 
02586 
02587 /*****************************************************************************/
02588 /* If the request returned granted and the operation is performed,           */
02589 /* the following function can be called by the AEF to get all aci set        */
02590 /* correctly. For write accesses that are performed fully within the kernel, */
02591 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
02592 /* cleaning up.                                                              */
02593 /* The second instance of target specification is the new target, if one has */
02594 /* been created, otherwise its values are ignored.                           */
02595 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
02596 
02597 int  rsbac_adf_set_attr_pm(
02598                       enum  rsbac_adf_request_t     request,
02599                             rsbac_pid_t             caller_pid,
02600                       enum  rsbac_target_t          target,
02601                       union rsbac_target_id_t       tid,
02602                       enum  rsbac_target_t          new_target,
02603                       union rsbac_target_id_t       new_tid,
02604                       enum  rsbac_attribute_t       attr,
02605                       union rsbac_attribute_value_t attr_val,
02606                             rsbac_uid_t             owner)
02607   {
02608     union rsbac_target_id_t       i_tid;
02609     union rsbac_attribute_value_t i_attr_val1;
02610     union rsbac_attribute_value_t i_attr_val2;
02611     union rsbac_attribute_value_t i_attr_val3;
02612     union rsbac_attribute_value_t i_attr_val4;
02613     union rsbac_pm_target_id_t    i_pm_tid;
02614     union rsbac_pm_data_value_t   i_data_val1;
02615           int                     error;
02616 
02617     switch (request)
02618       {
02619         case R_APPEND_OPEN:
02620             switch(target)
02621               {
02622                 case T_FILE:
02623                 case T_FIFO:
02624                   return(adjust_in_out_pp(caller_pid,
02625                                           target,
02626                                           tid.file,
02627                                           RSBAC_PM_A_APPEND));
02628                 case T_IPC:
02629                   return(adjust_in_out_pp_ipc(caller_pid,
02630                                               tid.ipc,
02631                                               RSBAC_PM_A_APPEND));
02632                 case T_DEV:
02633                   return(0);
02634                 default:
02635                   return(0);
02636               }
02637 #ifdef CONFIG_RSBAC_RW
02638         case R_READ:
02639             switch(target)
02640               {
02641                 case T_FILE:
02642                 case T_FIFO:
02643                   return(adjust_in_out_pp(caller_pid,
02644                                           target,
02645                                           tid.file,
02646                                           RSBAC_PM_A_READ));
02647 #ifdef CONFIG_RSBAC_RW_SOCK
02648                 case T_IPC:
02649                   return(adjust_in_out_pp_ipc(caller_pid,
02650                                               tid.ipc,
02651                                               RSBAC_PM_A_READ));
02652 #endif
02653                 default:
02654                   return(0);
02655               }
02656 #endif
02657         case R_READ_OPEN:
02658             switch(target)
02659               {
02660                 case T_FILE:
02661                 case T_FIFO:
02662                   return(adjust_in_out_pp(caller_pid,
02663                                           target,
02664                                           tid.file,
02665                                           RSBAC_PM_A_READ));
02666                 case T_IPC:
02667                   return(adjust_in_out_pp_ipc(caller_pid,
02668                                               tid.ipc,
02669                                               RSBAC_PM_A_READ));
02670                 case T_DIR:
02671                 case T_DEV:
02672                   return(0);
02673                 default:
02674                   return(0);
02675               }
02676         case R_READ_WRITE_OPEN:
02677             switch(target)
02678               {
02679                 case T_FILE:
02680                 case T_FIFO:
02681                   return(adjust_in_out_pp(caller_pid,
02682                                           target,
02683                                           tid.file,
02684                                           RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
02685                 case T_IPC:
02686                   return(adjust_in_out_pp_ipc(caller_pid,
02687                                               tid.ipc,
02688                                               RSBAC_PM_A_READ | RSBAC_PM_A_WRITE));
02689                 case T_DEV:
02690                   return(0);
02691                 default:
02692                   return(0);
02693               }
02694 
02695 #ifdef CONFIG_RSBAC_RW
02696         case R_WRITE:
02697             switch(target)
02698               {
02699                 case T_FILE:
02700                 case T_FIFO:
02701                   return(adjust_in_out_pp(caller_pid,
02702                                           target,
02703                                           tid.file,
02704                                           RSBAC_PM_A_WRITE));
02705 #ifdef CONFIG_RSBAC_RW_SOCK
02706                 case T_IPC:
02707                   return(adjust_in_out_pp_ipc(caller_pid,
02708                                               tid.ipc,
02709                                               RSBAC_PM_A_WRITE));
02710 #endif
02711                 default:
02712                   return(0);
02713               }
02714 #endif
02715 
02716         case R_WRITE_OPEN:
02717             switch(target)
02718               {
02719                 case T_FILE:
02720                 case T_FIFO:
02721                   return(adjust_in_out_pp(caller_pid,
02722                                           target,
02723                                           tid.file,
02724                                           RSBAC_PM_A_WRITE));
02725                 case T_DEV:
02726                   return(0);
02727 
02728                 case T_IPC:
02729                   return(adjust_in_out_pp_ipc(caller_pid,
02730                                               tid.ipc,
02731                                               RSBAC_PM_A_WRITE));
02732                 default:
02733                   return(0);
02734               }
02735 
02736         case R_CLONE:
02737             if (target == T_PROCESS)
02738               {
02739                   /* Get owner from first process (provided on call) */
02740                   i_attr_val1.owner = owner;
02741                   /* Get pm_tp from first process */
02742                   if (rsbac_get_attr(PM,
02743                        T_PROCESS,
02744                                      tid,
02745                                      A_pm_tp,
02746                                      &i_attr_val2,
02747                                      FALSE))
02748                     {
02749                       printk(KERN_WARNING
02750                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02751                       return(-RSBAC_EREADFAILED);
02752                     }
02753                   /* Get pm_current_task from first process... */
02754                   if (rsbac_get_attr(PM,
02755                        T_PROCESS,
02756                                      tid,
02757                                      A_pm_current_task,
02758                                      &i_attr_val3,
02759                                      FALSE))
02760                     {
02761                       printk(KERN_WARNING
02762                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02763                       return(-RSBAC_EREADFAILED);
02764                     }
02765                   /* Get pm_process_type from first process */
02766                   if (rsbac_get_attr(PM,
02767                        T_PROCESS,
02768                                      tid,
02769                                      A_pm_process_type,
02770                                      &i_attr_val4,
02771                                      FALSE))
02772                     {
02773                       printk(KERN_WARNING
02774                              "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02775                       return(-RSBAC_EREADFAILED);
02776                     }
02777                   /* Set pm_tp for new process */
02778                   if (rsbac_set_attr(PM,
02779                        T_PROCESS,
02780                                      new_tid,
02781                                      A_pm_tp,
02782                                      i_attr_val2))
02783                     {
02784                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02785                       return(-RSBAC_EWRITEFAILED);
02786                     }
02787                   /* Set pm_current_task for new process */
02788                   if (rsbac_set_attr(PM,
02789                        T_PROCESS,
02790                                      new_tid,
02791                                      A_pm_current_task,
02792                                      i_attr_val3))
02793                     {
02794                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02795                       return(-RSBAC_EWRITEFAILED);
02796                     }
02797                   /* Set pm_process_type for new process */
02798                   if (rsbac_set_attr(PM,
02799                        T_PROCESS,
02800                                      new_tid,
02801                                      A_pm_process_type,
02802                                      i_attr_val4))
02803                     {
02804                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02805                       return(-RSBAC_EWRITEFAILED);
02806                     }
02807                   return(0);
02808               }
02809             else
02810               return(0);
02811 
02812         case R_CREATE:
02813             switch(target)
02814               {
02815                 /* Creating dir or (pseudo) file IN target dir! */
02816                 case T_DIR:
02817                   /* Mode of created item is ignored! */
02818 
02819                   /* Is calling process a TP? */
02820                   /* get process_type of caller-process */
02821                   i_tid.process = caller_pid;
02822                   if (rsbac_get_attr(PM,
02823                                      T_PROCESS,
02824                                      i_tid,
02825                                      A_pm_process_type,
02826                                      &i_attr_val1,
02827                                      FALSE))
02828                     {
02829                       printk(KERN_WARNING
02830                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02831                       return(NOT_GRANTED);
02832                     }
02833                   /* if TP: Set pm_object_class to purpose default class for new item */
02834                   if(i_attr_val1.pm_process_type == PP_TP)
02835                     {
02836                       /* get current_task of caller-process */
02837                       i_tid.process = caller_pid;
02838                       if (rsbac_get_attr(PM,
02839                        T_PROCESS,
02840                                          i_tid,
02841                                          A_pm_current_task,
02842                                          &i_attr_val1,
02843                                          FALSE))
02844                         {
02845                           printk(KERN_WARNING
02846                                  "rsbac_adf_set_attr_pm(): rsbac_get_attr() returned error!\n");
02847                                  return(RSBAC_EREADFAILED);
02848                         }
02849                       if(!i_attr_val1.pm_current_task)
02850                         {
02851 #ifdef CONFIG_RSBAC_DEBUG
02852                           if(rsbac_debug_adf_pm)
02853                             printk(KERN_DEBUG
02854                                    "rsbac_adf_set_attr_pm(): no current_task for calling process trying to access personal_data\n");
02855 #endif
02856                           return(RSBAC_EREADFAILED);
02857                         }
02858                       /* get purpose of current_task */
02859                       i_pm_tid.task = i_attr_val1.pm_current_task;
02860                       if ((error = rsbac_pm_get_data(0,
02861                                                      PMT_TASK,
02862                                                      i_pm_tid,
02863                                                      PD_purpose,
02864                                                      &i_data_val1)))
02865                         {
02866                           if(error != -RSBAC_EINVALIDTARGET)
02867                             printk(KERN_WARNING
02868                                    "rsbac_adf_set_attr_pm(): rsbac_pm_get_data() returned error %i!\n",
02869                                    error);
02870                           return(error);
02871                         }
02872                       /* if there is no purpose, return error */
02873                       if(!i_data_val1.purpose)
02874                         {
02875 #ifdef CONFIG_RSBAC_DEBUG
02876                           if(rsbac_debug_adf_pm)
02877                             printk(KERN_DEBUG
02878                                    "rsbac_adf_set_attr_pm(): no purpose for current_task of process trying to execute TP\n");
02879 #endif
02880                           return(RSBAC_EREADFAILED);
02881                         }
02882                       /* get def_class of purpose of current_task */
02883                       i_pm_tid.pp = i_data_val1.purpose;
02884                       if ((error = rsbac_pm_get_data(0,
02885                                                      PMT_PP,
02886                                                      i_pm_tid,
02887                                                      PD_def_class,
02888                                                      &i_data_val1)))
02889                         {
02890                           if(error != -RSBAC_EINVALIDTARGET)
02891                             printk(KERN_WARNING
02892                                    "rsbac_adf_set_attr_pm(): rsbac_pm_get_data() returned error %i!\n",
02893                                    error);
02894                           return(error);
02895                         }
02896                       i_attr_val1.pm_object_class = i_data_val1.def_class;
02897                     }
02898                   else /* calling process is no TP */
02899                     /* set class to NIL */
02900                     i_attr_val1.pm_object_class = 0;
02901                   
02902                   if (rsbac_get_attr(PM,
02903                                      new_target,
02904                                      new_tid,
02905                                      A_pm_object_class,
02906                                      &i_attr_val2,
02907                                      FALSE))
02908                     {
02909                       printk(KERN_WARNING
02910                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02911                       return(-RSBAC_EREADFAILED);
02912                     }
02913                   if(i_attr_val1.pm_object_class != i_attr_val2.pm_object_class)
02914                     {
02915                       if (rsbac_set_attr(PM,
02916                                          new_target,
02917                                          new_tid,
02918                                          A_pm_object_class,
02919                                          i_attr_val1))
02920                         {
02921                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02922                           return(-RSBAC_EWRITEFAILED);
02923                         }
02924                     }
02925                   /* Set pm_tp for new item */
02926                   i_attr_val1.pm_tp = 0;
02927                   if (rsbac_get_attr(PM,
02928                                      new_target,
02929                                      new_tid,
02930                                      A_pm_tp,
02931                                      &i_attr_val2,
02932                                      FALSE))
02933                     {
02934                       printk(KERN_WARNING
02935                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02936                       return(-RSBAC_EREADFAILED);
02937                     }
02938                   if(i_attr_val1.pm_tp != i_attr_val2.pm_tp)
02939                     {
02940                       if (rsbac_set_attr(PM,
02941                                          new_target,
02942                                          new_tid,
02943                                          A_pm_tp,
02944                                          i_attr_val1))
02945                         {
02946                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02947                           return(-RSBAC_EWRITEFAILED);
02948                         }
02949                     }
02950 
02951                   /* get process_type of caller-process */
02952                   i_tid.process = caller_pid;
02953                   if (rsbac_get_attr(PM,
02954                                      T_PROCESS,
02955                                      i_tid,
02956                                      A_pm_process_type,
02957                                      &i_attr_val1,
02958                                      FALSE))
02959                     {
02960                       printk(KERN_WARNING
02961                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02962                       return(-RSBAC_EREADFAILED);
02963                     }
02964                   /* Set pm_object_type for new item */
02965                   if(new_target == T_DIR)
02966                     i_attr_val1.pm_object_type = PO_dir;
02967                   else
02968                     /* files: if process is TP, set to personal_data */
02969                     /* to prevent unrestricted access */
02970                     if(i_attr_val1.pm_process_type == PP_TP)
02971                       i_attr_val1.pm_object_type = PO_personal_data;
02972                     else
02973                       i_attr_val1.pm_object_type = PO_none;
02974                   if (rsbac_get_attr(PM,
02975                                      new_target,
02976                                      new_tid,
02977                                      A_pm_object_type,
02978                                      &i_attr_val2,
02979                                      FALSE))
02980                     {
02981                       printk(KERN_WARNING
02982                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
02983                       return(-RSBAC_EREADFAILED);
02984                     }
02985                   if(i_attr_val1.pm_object_type != i_attr_val2.pm_object_type)
02986                     {
02987                       if (rsbac_set_attr(PM,
02988                                          new_target,
02989                                          new_tid,
02990                                          A_pm_object_type,
02991                                          i_attr_val1))
02992                         {
02993                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
02994                           return(-RSBAC_EWRITEFAILED);
02995                         }
02996                     }
02997                   return(0);
02998                   break;
02999 
03000                 case T_IPC: 
03001                   /* Set pm_ipc_purpose for new item */
03002                   /* get current_task of caller-process */
03003                   i_tid.process = caller_pid;
03004                   if (rsbac_get_attr(PM,
03005                                      T_PROCESS,
03006                                      i_tid,
03007                                      A_pm_current_task,
03008                                      &i_attr_val1,
03009                                      FALSE))
03010                     {
03011                       printk(KERN_WARNING
03012                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03013                       return(-RSBAC_EREADFAILED);
03014                     }
03015                   /* if current_task = NIL, ipc_purpose must be NIL */
03016                   if(!i_attr_val1.pm_current_task)
03017                     i_attr_val1.pm_ipc_purpose = 0;
03018                   else
03019                     {
03020                       /* get purpose of current_task */
03021                       i_pm_tid.task = i_attr_val1.pm_current_task;
03022                       if ((error = rsbac_pm_get_data(0,
03023                                                      PMT_TASK,
03024                                                      i_pm_tid,
03025                                                      PD_purpose,
03026                                                      &i_data_val1)))
03027                         {
03028                           if(error == -RSBAC_EINVALIDTARGET)
03029                             printk(KERN_WARNING
03030                                    "rsbac_adf_request_pm(): pm_current_task of calling process is invalid!\n");
03031                           else
03032                             printk(KERN_WARNING
03033                                    "rsbac_adf_request_pm(): rsbac_pm_get_data() returned error %i!\n",
03034                                    error);
03035                           return(-RSBAC_EREADFAILED);
03036                         }
03037                       i_attr_val1.pm_ipc_purpose = i_data_val1.purpose;
03038                     }
03039                   if (rsbac_get_attr(PM,
03040                                      target,
03041                                      tid,
03042                                      A_pm_ipc_purpose,
03043                                      &i_attr_val2,
03044                                      FALSE))
03045                     {
03046                       printk(KERN_WARNING
03047                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03048                       return(-RSBAC_EREADFAILED);
03049                     }
03050                   if(i_attr_val1.pm_ipc_purpose != i_attr_val2.pm_ipc_purpose)
03051                     {
03052                       if (rsbac_set_attr(PM,
03053                                          target,
03054                                          tid,
03055                                          A_pm_ipc_purpose,
03056                                          i_attr_val1))
03057                         {
03058                           printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03059                           return(-RSBAC_EWRITEFAILED);
03060                         }
03061                     }
03062                   return(0);
03063                   break;
03064 
03065                 /* all other cases are undefined */
03066                 default:
03067                   return(0);
03068               }
03069 
03070         case R_EXECUTE:
03071             switch(target)
03072               {
03073                 case T_FILE:
03074                   /* get pm_object_type of target */
03075                   if (rsbac_get_attr(PM,
03076                                      T_FILE,
03077                                      tid,
03078                                      A_pm_object_type,
03079                                      &i_attr_val1,
03080                                      FALSE))
03081                     {
03082                       printk(KERN_WARNING
03083                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03084                       return(-RSBAC_EREADFAILED);
03085                     }
03086                   /* if not TP: do nothing */
03087                   if(i_attr_val1.pm_object_type != PO_TP)
03088                     return(0);
03089 
03090                   /* get pm_tp of target */
03091                   if (rsbac_get_attr(PM,
03092                        T_FILE,
03093                                      tid,
03094                                      A_pm_tp,
03095                                      &i_attr_val1,
03096                                      FALSE))
03097                     {
03098                       printk(KERN_WARNING
03099                              "rsbac_adf_request_pm(): rsbac_get_attr() returned error!\n");
03100                       return(-RSBAC_EREADFAILED);
03101                     }
03102                   /* if no tp: error! */
03103                   if(!i_attr_val1.pm_tp)
03104                     {
03105                       printk(KERN_WARNING
03106                              "rsbac_adf_request_pm(): file with object_type TP has no tp_id!\n");
03107                       return(-RSBAC_EINVALIDVALUE);
03108                     }
03109                   /* Set pm_tp for this process */
03110                   i_tid.process = caller_pid;
03111                   if (rsbac_set_attr(PM,
03112                                      T_PROCESS,
03113                                      i_tid,
03114                                      A_pm_tp,
03115                                      i_attr_val1))
03116                     {
03117                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03118                       return(-RSBAC_EWRITEFAILED);
03119                     }
03120                   /* Set pm_process_type for this process */
03121                   i_attr_val1.pm_process_type = PP_TP;
03122                   if (rsbac_set_attr(PM,
03123                                      T_PROCESS,
03124                                      i_tid,
03125                                      A_pm_process_type,
03126                                      i_attr_val1))
03127                     {
03128                       printk(KERN_WARNING "rsbac_adf_set_attr_pm(): rsbac_set_attr() returned error!\n");
03129                       return(-RSBAC_EWRITEFAILED);
03130                     }
03131                   return(0);
03132 
03133                 /* all other cases are undefined */
03134                 default:
03135                   return(0);
03136               }
03137 
03138 /*********************/
03139 
03140         default: return(0);
03141       }
03142 
03143     return(0);
03144   }; /* end of rsbac_adf_set_attr_pm() */
03145 
03146 /******************************************/
03147 #ifdef CONFIG_RSBAC_SECDEL
03148 rsbac_boolean_t rsbac_need_overwrite_pm(struct dentry * dentry_p)
03149   {
03150     union rsbac_target_id_t       i_tid;
03151     union rsbac_attribute_value_t i_attr_val1;
03152 
03153     if(   !dentry_p
03154        || !dentry_p->d_inode)
03155       return FALSE;
03156 
03157     i_tid.file.device = dentry_p->d_sb->s_dev;
03158     i_tid.file.inode = dentry_p->d_inode->i_ino;
03159     i_tid.file.dentry_p = dentry_p;
03160     /* get target's file flags */
03161     if (rsbac_get_attr(PM,
03162                        T_FILE,
03163                        i_tid,
03164                        A_pm_object_type,
03165                        &i_attr_val1,
03166                        TRUE))
03167       {
03168         printk(KERN_WARNING "rsbac_need_overwrite_pm(): rsbac_get_attr() returned error!\n");
03169         return FALSE;
03170       }
03171 
03172     /* overwrite, if personal data */
03173     if (i_attr_val1.pm_object_type == PO_personal_data)
03174       return TRUE;
03175     else
03176       return FALSE;
03177   }
03178 #endif
03179 
03180 /* end of rsbac/adf/pm/main.c */

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