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

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