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

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