res_main.c

Go to the documentation of this file.
00001 /**************************************************** */
00002 /* Rule Set Based Access Control                      */
00003 /* Implementation of the Access Control Decision      */
00004 /* Facility (ADF) - System Resources (RES)            */
00005 /* File: rsbac/adf/res/main.c                         */
00006 /*                                                    */
00007 /* Author and (c) 2002-2005: Amon Ott <ao@rsbac.org>  */
00008 /*                                                    */
00009 /* Last modified: 18/Jul/2005                         */
00010 /**************************************************** */
00011 
00012 #include <linux/string.h>
00013 #include <linux/version.h>
00014 #include <rsbac/types.h>
00015 #include <rsbac/aci.h>
00016 #include <rsbac/adf_main.h>
00017 #include <rsbac/error.h>
00018 #include <rsbac/helpers.h>
00019 #include <rsbac/getname.h>
00020 #include <rsbac/debug.h>
00021 
00022 /************************************************* */
00023 /*           Global Variables                      */
00024 /************************************************* */
00025 
00026 /************************************************* */
00027 /*          Internal Help functions                */
00028 /************************************************* */
00029 
00030 /************************************************* */
00031 /*          Externally visible functions           */
00032 /************************************************* */
00033 
00034 enum rsbac_adf_req_ret_t
00035    rsbac_adf_request_res (enum  rsbac_adf_request_t     request,
00036                                 rsbac_pid_t             caller_pid,
00037                           enum  rsbac_target_t          target,
00038                           union rsbac_target_id_t       tid,
00039                           enum  rsbac_attribute_t       attr,
00040                           union rsbac_attribute_value_t attr_val,
00041                                 rsbac_uid_t             owner)
00042   {
00043     union rsbac_target_id_t       i_tid;
00044     union rsbac_attribute_value_t i_attr_val1;
00045 
00046     switch (request)
00047       {
00048         case R_MODIFY_ATTRIBUTE:
00049             switch(attr)
00050               {
00051                 case A_system_role:
00052                 case A_res_role:
00053                 case A_res_min:
00054                 case A_res_max:
00055                 /* All attributes (remove target!) */
00056                 case A_none:
00057                   /* Security Officer? */
00058                   i_tid.user = owner;
00059                   if (rsbac_get_attr(RES,
00060                                      T_USER,
00061                                      i_tid,
00062                                      A_res_role,
00063                                      &i_attr_val1,
00064                                      TRUE))
00065                     {
00066                       rsbac_ds_get_error("rsbac_adf_request_res()", A_res_role);
00067                       return(NOT_GRANTED);
00068                     }
00069                   /* if sec_officer, then grant */
00070                   if (i_attr_val1.system_role == SR_security_officer)
00071                     return(GRANTED);
00072                   else
00073                     return(NOT_GRANTED);
00074 
00075                 default:
00076                   return(DO_NOT_CARE);
00077               }
00078 
00079         case R_READ_ATTRIBUTE:
00080             switch(attr)
00081               {
00082                 case A_system_role:
00083                 case A_res_role:
00084                 case A_res_min:
00085                 case A_res_max:
00086                 /* All attributes (remove target!) */
00087                 case A_none:
00088                   /* Security Officer or Admin? */
00089                   i_tid.user = owner;
00090                   if (rsbac_get_attr(RES,
00091                                      T_USER,
00092                                      i_tid,
00093                                      A_res_role,
00094                                      &i_attr_val1,
00095                                      TRUE))
00096                     {
00097                       rsbac_ds_get_error("rsbac_adf_request_res()", A_res_role);
00098                       return(NOT_GRANTED);
00099                     }
00100                   /* if sec_officer, then grant */
00101                   if(   (i_attr_val1.system_role == SR_security_officer)
00102                      || (i_attr_val1.system_role == SR_administrator)
00103                     )
00104                     return(GRANTED);
00105                   else
00106                     return(NOT_GRANTED);
00107 
00108                 default:
00109                   return(DO_NOT_CARE);
00110               }
00111 
00112         case R_SWITCH_LOG:
00113             switch(target)
00114               {
00115                 case T_NONE:
00116                   /* test owner's res_role */
00117                   i_tid.user = owner;
00118                   if (rsbac_get_attr(RES,
00119                                      T_USER,
00120                                      i_tid,
00121                                      A_res_role,
00122                                      &i_attr_val1,
00123                                      TRUE))
00124                     {
00125                       rsbac_ds_get_error("rsbac_adf_request_res()", A_res_role);
00126                       return(NOT_GRANTED);
00127                     }
00128                   /* security officer? -> grant  */
00129                   if (i_attr_val1.system_role == SR_security_officer)
00130                     return(GRANTED);
00131                   else
00132                     return(NOT_GRANTED);
00133 
00134                 /* all other cases are unknown */
00135                 default: return(DO_NOT_CARE);
00136               }
00137 
00138         case R_SWITCH_MODULE:
00139             switch(target)
00140               {
00141                 case T_NONE:
00142                   /* we need the switch_target */
00143                   if(attr != A_switch_target)
00144                     return(UNDEFINED);
00145                   /* do not care for other modules */
00146                   if(   (attr_val.switch_target != RES)
00147                      #ifdef CONFIG_RSBAC_SOFTMODE
00148                      && (attr_val.switch_target != SOFTMODE)
00149                      #endif
00150                      #ifdef CONFIG_RSBAC_FREEZE
00151                      && (attr_val.switch_target != FREEZE)
00152                      #endif
00153                     )
00154                     return(DO_NOT_CARE);
00155                   /* test owner's res_role */
00156                   i_tid.user = owner;
00157                   if (rsbac_get_attr(RES,
00158                                      T_USER,
00159                                      i_tid,
00160                                      A_res_role,
00161                                      &i_attr_val1,
00162                                      TRUE))
00163                     {
00164                       rsbac_ds_get_error("rsbac_adf_request_res()", A_res_role);
00165                       return(NOT_GRANTED);
00166                     }
00167                   /* security officer? -> grant  */
00168                   if (i_attr_val1.system_role == SR_security_officer)
00169                     return(GRANTED);
00170                   else
00171                     return(NOT_GRANTED);
00172 
00173                 /* all other cases are unknown */
00174                 default: return(DO_NOT_CARE);
00175               }
00176 
00177 
00178 /*********************/
00179         default: return DO_NOT_CARE;
00180       }
00181 
00182     return(DO_NOT_CARE);
00183   } /* end of rsbac_adf_request_res() */
00184 
00185 
00186 /*****************************************************************************/
00187 /* If the request returned granted and the operation is performed,           */
00188 /* the following function can be called by the AEF to get all aci set        */
00189 /* correctly. For write accesses that are performed fully within the kernel, */
00190 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
00191 /* cleaning up.                                                              */
00192 /* The second instance of target specification is the new target, if one has */
00193 /* been created, otherwise its values are ignored.                           */
00194 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
00195 
00196 int  rsbac_adf_set_attr_res(
00197                       enum  rsbac_adf_request_t     request,
00198                             rsbac_pid_t             caller_pid,
00199                       enum  rsbac_target_t          target,
00200                       union rsbac_target_id_t       tid,
00201                       enum  rsbac_target_t          new_target,
00202                       union rsbac_target_id_t       new_tid,
00203                       enum  rsbac_attribute_t       attr,
00204                       union rsbac_attribute_value_t attr_val,
00205                             rsbac_uid_t             owner)
00206   {
00207     union rsbac_target_id_t       i_tid;
00208     union rsbac_attribute_value_t i_attr_val1;
00209 
00210     switch (request)
00211       {
00212         case R_CHANGE_OWNER:
00213             switch(target)
00214               {
00215                 case T_PROCESS:
00216                   if(attr != A_owner)
00217                     return(-RSBAC_EINVALIDATTR);
00218                   /* Adjust Linux resources */
00219                   i_tid.user = attr_val.owner;
00220                   #ifdef CONFIG_RSBAC_SOFTMODE
00221                   if(!rsbac_softmode)
00222                   #endif
00223                     {
00224                       int maxval = rsbac_min(RLIM_NLIMITS - 1, RSBAC_RES_MAX);
00225                       int i;
00226 
00227                       if (rsbac_get_attr(RES,
00228                                          T_USER,
00229                                          i_tid,
00230                                          A_res_max,
00231                                          &i_attr_val1,
00232                                          FALSE))
00233                         {
00234                           rsbac_ds_get_error("rsbac_adf_set_attr_res()", A_res_max);
00235                           return -RSBAC_EREADFAILED;
00236                         }
00237                       for(i = 0; i <= maxval ; i++)
00238                         {
00239                           if(i_attr_val1.res_array[i])
00240                             {
00241 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
00242                               if(current->signal->rlim[i].rlim_max > i_attr_val1.res_array[i])
00243                                 current->signal->rlim[i].rlim_max = i_attr_val1.res_array[i];
00244                               if(current->signal->rlim[i].rlim_cur > i_attr_val1.res_array[i])
00245                                 current->signal->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00246 #else
00247                               if(current->rlim[i].rlim_max > i_attr_val1.res_array[i])
00248                                 current->rlim[i].rlim_max = i_attr_val1.res_array[i];
00249                               if(current->rlim[i].rlim_cur > i_attr_val1.res_array[i])
00250                                 current->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00251 #endif
00252                             }
00253                         }
00254                       if (rsbac_get_attr(RES,
00255                                          T_USER,
00256                                          i_tid,
00257                                          A_res_min,
00258                                          &i_attr_val1,
00259                                          FALSE))
00260                         {
00261                           rsbac_ds_get_error("rsbac_adf_set_attr_res()", A_res_min);
00262                           return -RSBAC_EREADFAILED;
00263                         }
00264                       if(i_attr_val1.res_array[RLIMIT_NOFILE] > NR_OPEN)
00265                         i_attr_val1.res_array[RLIMIT_NOFILE] = NR_OPEN;
00266                       for(i = 0; i <= maxval ; i++)
00267                         {
00268                           if(i_attr_val1.res_array[i])
00269                             {
00270 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
00271                               if(current->signal->rlim[i].rlim_max < i_attr_val1.res_array[i])
00272                                 current->signal->rlim[i].rlim_max = i_attr_val1.res_array[i];
00273                               if(current->signal->rlim[i].rlim_cur < i_attr_val1.res_array[i])
00274                                 current->signal->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00275 #else
00276                               if(current->rlim[i].rlim_max < i_attr_val1.res_array[i])
00277                                 current->rlim[i].rlim_max = i_attr_val1.res_array[i];
00278                               if(current->rlim[i].rlim_cur < i_attr_val1.res_array[i])
00279                                 current->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00280 #endif
00281                             }
00282                         }
00283                     }
00284                   return 0;
00285 
00286                 /* all other cases are unknown */
00287                 default:
00288                   return(0);
00289               }
00290             break;
00291 
00292         case R_EXECUTE:
00293             switch(target)
00294               {
00295                 case T_FILE:
00296                   #ifdef CONFIG_RSBAC_SOFTMODE
00297                   if(!rsbac_softmode)
00298                   #endif
00299                     {
00300                       int maxval = rsbac_min(RLIM_NLIMITS - 1, RSBAC_RES_MAX);
00301                       int i;
00302 
00303                       if (rsbac_get_attr(RES,
00304                                          target,
00305                                          tid,
00306                                          A_res_max,
00307                                          &i_attr_val1,
00308                                          FALSE))
00309                         {
00310                           rsbac_ds_get_error("rsbac_adf_set_attr_res()", A_res_max);
00311                           return -RSBAC_EREADFAILED;
00312                         }
00313                       for(i = 0; i <= maxval ; i++)
00314                         {
00315                           if(i_attr_val1.res_array[i])
00316                             {
00317 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
00318                               if(current->signal->rlim[i].rlim_max > i_attr_val1.res_array[i])
00319                                 current->signal->rlim[i].rlim_max = i_attr_val1.res_array[i];
00320                               if(current->signal->rlim[i].rlim_cur > i_attr_val1.res_array[i])
00321                                 current->signal->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00322 #else
00323                               if(current->rlim[i].rlim_max > i_attr_val1.res_array[i])
00324                                 current->rlim[i].rlim_max = i_attr_val1.res_array[i];
00325                               if(current->rlim[i].rlim_cur > i_attr_val1.res_array[i])
00326                                 current->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00327 #endif
00328                             }
00329                         }
00330                       if (rsbac_get_attr(RES,
00331                                          target,
00332                                          tid,
00333                                          A_res_min,
00334                                          &i_attr_val1,
00335                                          FALSE))
00336                         {
00337                           rsbac_ds_get_error("rsbac_adf_set_attr_res()", A_res_min);
00338                           return -RSBAC_EREADFAILED;
00339                         }
00340                       for(i = 0; i <= maxval ; i++)
00341                         {
00342                           if(i_attr_val1.res_array[i])
00343                             {
00344 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
00345                               if(current->signal->rlim[i].rlim_max < i_attr_val1.res_array[i])
00346                                 current->signal->rlim[i].rlim_max = i_attr_val1.res_array[i];
00347                               if(current->signal->rlim[i].rlim_cur < i_attr_val1.res_array[i])
00348                                 current->signal->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00349 #else
00350                               if(current->rlim[i].rlim_max < i_attr_val1.res_array[i])
00351                                 current->rlim[i].rlim_max = i_attr_val1.res_array[i];
00352                               if(current->rlim[i].rlim_cur < i_attr_val1.res_array[i])
00353                                 current->rlim[i].rlim_cur = i_attr_val1.res_array[i];
00354 #endif
00355                             }
00356                         }
00357                     }
00358                   return 0;
00359 
00360                 /* all other cases are unknown */
00361                 default:
00362                   return(0);
00363               }
00364             break;
00365 
00366 /*********************/
00367         default: return(0);
00368       }
00369 
00370     return(0);
00371   } /* end of rsbac_adf_set_attr_res() */
00372 
00373 /* end of rsbac/adf/res/main.c */

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