ff_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) - File Flags                       */
00005 /* File: rsbac/adf/ff/main.c                         */
00006 /*                                                   */
00007 /* Author and (c) 1999-2005: Amon Ott <ao@rsbac.org> */
00008 /*                                                   */
00009 /* Last modified: 09/Feb/2005                        */
00010 /*************************************************** */
00011 
00012 #include <linux/types.h>
00013 #include <linux/string.h>
00014 #include <linux/fs.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 
00021 #include <asm/uaccess.h>
00022 
00023 /************************************************* */
00024 /*           Global Variables                      */
00025 /************************************************* */
00026 
00027 /************************************************* */
00028 /*          Internal Help functions                */
00029 /************************************************* */
00030 
00031 
00032 enum rsbac_adf_req_ret_t
00033   check_flags_ff(enum rsbac_target_t target,
00034                  union rsbac_target_id_t tid,
00035                  rsbac_ff_flags_t flags)
00036   {
00037     union rsbac_attribute_value_t i_attr_val1;
00038 
00039     /* get target's file flags */
00040     if (rsbac_get_attr(FF, target,
00041                        tid,
00042                        A_ff_flags,
00043                        &i_attr_val1,
00044                        TRUE))
00045       {
00046         printk(KERN_WARNING "check_flags_ff(): rsbac_get_attr() returned error!\n");
00047         return(NOT_GRANTED);
00048       }
00049       
00050     /* Access is granted, if none of the flags in argument flags is set */
00051     if (i_attr_val1.ff_flags & flags)
00052       return(NOT_GRANTED);
00053     else
00054       return(GRANTED);
00055   }
00056 
00057 /************************************************* */
00058 /*          Externally visible functions           */
00059 /************************************************* */
00060 
00061 enum rsbac_adf_req_ret_t
00062    rsbac_adf_request_ff (enum  rsbac_adf_request_t     request,
00063                                 rsbac_pid_t             caller_pid,
00064                           enum  rsbac_target_t          target,
00065                           union rsbac_target_id_t       tid,
00066                           enum  rsbac_attribute_t       attr,
00067                           union rsbac_attribute_value_t attr_val,
00068                                 rsbac_uid_t             owner)
00069   {
00070     enum  rsbac_adf_req_ret_t result = DO_NOT_CARE;
00071     union rsbac_target_id_t       i_tid;
00072     union rsbac_attribute_value_t i_attr_val1;
00073     int err=0;
00074 
00075     switch (request)
00076       {
00077         case R_APPEND_OPEN:
00078             switch(target)
00079               {
00080                 case T_FILE:
00081                 case T_FIFO:
00082                   return(check_flags_ff(target,tid,
00083                                         FF_read_only | FF_execute_only));
00084 
00085                 /* all other cases are undefined */
00086                 default: return(DO_NOT_CARE);
00087               }
00088 
00089         case R_CHANGE_GROUP:
00090         case R_MODIFY_PERMISSIONS_DATA:
00091             switch(target)
00092               {
00093                 case T_FILE:
00094                 case T_FIFO:
00095                 case T_SYMLINK:
00096                   return(check_flags_ff(target,tid,
00097                                         FF_read_only | FF_execute_only | FF_append_only));
00098                 case T_DIR:
00099                   return(check_flags_ff(target,tid,
00100                                         FF_read_only | FF_search_only));
00101 
00102 #if defined(CONFIG_RSBAC_FF_UM_PROT)
00103                 case T_USER:
00104                 case T_GROUP:
00105                   /* Security Officer? */
00106                   i_tid.user = owner;
00107                   if (rsbac_get_attr(FF,
00108                                      T_USER,
00109                                      i_tid,
00110                                      A_ff_role,
00111                                      &i_attr_val1,
00112                                      TRUE))
00113                     {
00114                       rsbac_ds_get_error("rsbac_adf_request_ff()", A_ff_role);
00115                       return(NOT_GRANTED);
00116                     }
00117                   /* if sec_officer, then grant */
00118                   if (i_attr_val1.system_role == SR_security_officer)
00119                     return(GRANTED);
00120                   else
00121                     return(NOT_GRANTED);
00122 #endif
00123 
00124                 /* all other cases are undefined */
00125                 default:
00126                   return(DO_NOT_CARE);
00127               }
00128 
00129         case R_CHANGE_OWNER:
00130             switch(target)
00131               {
00132                 case T_FILE:
00133                 case T_FIFO:
00134                 case T_SYMLINK:
00135                   return(check_flags_ff(target,tid,
00136                                         FF_read_only | FF_execute_only | FF_append_only));
00137                 case T_DIR:
00138                   return(check_flags_ff(target,tid,
00139                                         FF_read_only | FF_search_only));
00140                 /* all other cases are undefined */
00141                 default:
00142                   return(DO_NOT_CARE);
00143               }
00144 
00145         case R_CHDIR:
00146             switch(target)
00147               {
00148                 case T_DIR: 
00149                   return(check_flags_ff(target,tid,
00150                                         FF_search_only));
00151 
00152                 /* all other cases are undefined */
00153                 default: return(DO_NOT_CARE);
00154               }
00155 
00156         /* Creating dir or (pseudo) file IN target dir! */
00157         case R_CREATE:
00158             switch(target)
00159               {
00160                 case T_DIR: 
00161                   return(check_flags_ff(target,tid,
00162                                         FF_read_only | FF_search_only));
00163 
00164 #if defined(CONFIG_RSBAC_FF_UM_PROT)
00165                 case T_USER:
00166                 case T_GROUP:
00167                   /* Security Officer? */
00168                   i_tid.user = owner;
00169                   if (rsbac_get_attr(FF,
00170                                      T_USER,
00171                                      i_tid,
00172                                      A_ff_role,
00173                                      &i_attr_val1,
00174                                      TRUE))
00175                     {
00176                       rsbac_ds_get_error("rsbac_adf_request_ff()", A_ff_role);
00177                       return(NOT_GRANTED);
00178                     }
00179                   /* if sec_officer, then grant */
00180                   if (i_attr_val1.system_role == SR_security_officer)
00181                     return(GRANTED);
00182                   else
00183                     return(NOT_GRANTED);
00184 #endif
00185 
00186                 /* all other cases are undefined */
00187                 default: return(DO_NOT_CARE);
00188               }
00189 
00190         case R_DELETE:
00191         case R_RENAME:
00192             switch(target)
00193               {
00194                 case T_FILE: 
00195                 case T_FIFO:
00196                 case T_SYMLINK:
00197                   return(check_flags_ff(target,tid,
00198                                         FF_read_only | FF_execute_only | FF_no_delete_or_rename
00199                                          | FF_append_only));
00200                 case T_DIR: 
00201                   return(check_flags_ff(target,tid,
00202                                         FF_read_only | FF_search_only | FF_no_delete_or_rename));
00203 
00204 #if defined(CONFIG_RSBAC_FF_UM_PROT)
00205                 case T_USER:
00206                 case T_GROUP:
00207                   /* Security Officer? */
00208                   i_tid.user = owner;
00209                   if (rsbac_get_attr(FF,
00210                                      T_USER,
00211                                      i_tid,
00212                                      A_ff_role,
00213                                      &i_attr_val1,
00214                                      TRUE))
00215                     {
00216                       rsbac_ds_get_error("rsbac_adf_request_ff()", A_ff_role);
00217                       return(NOT_GRANTED);
00218                     }
00219                   /* if sec_officer, then grant */
00220                   if (i_attr_val1.system_role == SR_security_officer)
00221                     return(GRANTED);
00222                   else
00223                     return(NOT_GRANTED);
00224 #endif
00225 
00226                 /* all other cases are undefined */
00227                 default: return(DO_NOT_CARE);
00228               }
00229 
00230         case R_EXECUTE:
00231         case R_MAP_EXEC:
00232             switch(target)
00233               {
00234                 case T_FILE:
00235                   return(check_flags_ff(target,tid,
00236                                         FF_write_only | FF_no_execute | FF_append_only));
00237 
00238                 /* all other cases are undefined */
00239                 default: return(DO_NOT_CARE);
00240               }
00241 
00242 #if defined(CONFIG_RSBAC_FF_UM_PROT)
00243         case R_GET_PERMISSIONS_DATA:
00244             switch(target)
00245               {
00246                 case T_USER:
00247                 case T_GROUP:
00248                   /* Security Officer? */
00249                   i_tid.user = owner;
00250                   if (rsbac_get_attr(FF,
00251                                      T_USER,
00252                                      i_tid,
00253                                      A_ff_role,
00254                                      &i_attr_val1,
00255                                      TRUE))
00256                     {
00257                       rsbac_ds_get_error("rsbac_adf_request_ff()", A_ff_role);
00258                       return(NOT_GRANTED);
00259                     }
00260                   /* if sec_officer, then grant */
00261                   if (i_attr_val1.system_role == SR_security_officer)
00262                     return(GRANTED);
00263                   else
00264                     return(NOT_GRANTED);
00265 
00266                 /* We do not care about */
00267                 /* all other cases */
00268                 default: return(DO_NOT_CARE);
00269               }
00270 #endif
00271 
00272         case R_GET_STATUS_DATA:
00273             switch(target)
00274               {
00275                 case T_SCD:
00276                   /* target rsbaclog? only for secoff */
00277                   if (tid.scd != ST_rsbaclog)
00278                     return(GRANTED);
00279                   /* Secoff? */
00280                   i_tid.user = owner;
00281                   if ((err=rsbac_get_attr(FF, T_USER,
00282                                      i_tid,
00283                                      A_ff_role,
00284                                      &i_attr_val1,
00285                                      TRUE)))
00286                     {
00287                       printk(KERN_WARNING
00288                              "rsbac_adf_request_ff(): rsbac_get_attr() returned error %i!\n",err);
00289                       return(NOT_GRANTED);
00290                     }
00291                   /* grant only for secoff */
00292                   if (   (i_attr_val1.system_role == SR_security_officer)
00293                       || (i_attr_val1.system_role == SR_auditor)
00294                      )
00295                     return(GRANTED);
00296                   else
00297                     return(NOT_GRANTED);
00298                 default:
00299                   return(DO_NOT_CARE);
00300                };
00301 
00302         case R_LINK_HARD:
00303             switch(target)
00304               {
00305                 case T_FILE:
00306                 case T_FIFO:
00307                 case T_SYMLINK:
00308                   return(check_flags_ff(target,tid,
00309                                         FF_read_only | FF_execute_only));
00310 
00311                 /* all other cases are undefined */
00312                 default: return(DO_NOT_CARE);
00313               }
00314 
00315         case R_MODIFY_ACCESS_DATA:
00316             switch(target)
00317               {
00318                 case T_FILE:
00319                 case T_FIFO:
00320                 case T_SYMLINK:
00321                   return(check_flags_ff(target,tid,
00322                                         FF_read_only | FF_execute_only | FF_append_only));
00323                 case T_DIR:
00324                   return(check_flags_ff(target,tid,
00325                                         FF_read_only | FF_search_only));
00326 
00327                 /* all other cases are undefined */
00328                 default:
00329                   return(DO_NOT_CARE);
00330               }
00331 
00332         case R_MODIFY_ATTRIBUTE:
00333             switch(attr)
00334               {
00335                 case A_ff_flags:
00336                 case A_system_role:
00337                 case A_ff_role:
00338                 #ifdef CONFIG_RSBAC_FF_AUTH_PROT
00339                 case A_auth_may_setuid:
00340                 case A_auth_may_set_cap:
00341                 case A_auth_start_uid:
00342                 case A_auth_program_file:
00343                 case A_auth_learn:
00344                 case A_auth_add_f_cap:
00345                 case A_auth_remove_f_cap:
00346                 #endif
00347                 #ifdef CONFIG_RSBAC_FF_GEN_PROT
00348                 case A_log_array_low:
00349                 case A_log_array_high:
00350                 case A_log_program_based:
00351                 case A_log_user_based:
00352                 case A_symlink_add_uid:
00353                 case A_symlink_add_rc_role:
00354                 case A_linux_dac_disable:
00355                 case A_pseudo:
00356                 case A_fake_root_uid:
00357                 case A_audit_uid:
00358                 case A_auid_exempt:
00359                 #endif
00360                 /* All attributes (remove target!) */
00361                 case A_none:
00362                   /* Security Officer? */
00363                   i_tid.user = owner;
00364                   if (rsbac_get_attr(FF, T_USER,
00365                                      i_tid,
00366                                      A_ff_role,
00367                                      &i_attr_val1,
00368                                      TRUE))
00369                     {
00370                       printk(KERN_WARNING
00371                              "rsbac_adf_request_ff(): rsbac_get_attr() returned error!\n");
00372                       return(NOT_GRANTED);
00373                     }
00374                   /* if sec_officer, then grant */
00375                   if (i_attr_val1.system_role == SR_security_officer)
00376                     return(GRANTED);
00377                   else
00378                     return(NOT_GRANTED);
00379 
00380                 default:
00381                   return(DO_NOT_CARE);
00382               }
00383 
00384         case R_MODIFY_SYSTEM_DATA:
00385             switch(target)
00386               {
00387                 case T_SCD:
00388                   /* target not rsbaclog? no problem -> grant */
00389                   if (tid.scd != ST_rsbaclog)
00390                     return(GRANTED);
00391                   /* Get role */
00392                   i_tid.user = owner;
00393                   if (rsbac_get_attr(FF, T_USER,
00394                                      i_tid,
00395                                      A_ff_role,
00396                                      &i_attr_val1,
00397                                      TRUE))
00398                     {
00399                       printk(KERN_WARNING
00400                              "rsbac_adf_request_ff(): rsbac_get_attr() returned error!\n");
00401                       return(NOT_GRANTED);
00402                     }
00403                   /* grant only for secoff */
00404                   if (   (i_attr_val1.system_role == SR_security_officer)
00405                       || (i_attr_val1.system_role == SR_auditor)
00406                      )
00407                     return(GRANTED);
00408                   else
00409                     return(NOT_GRANTED);
00410                   
00411                 /* all other cases are undefined */
00412                 default: return(DO_NOT_CARE);
00413               }
00414 
00415         case R_MOUNT:
00416         case R_UMOUNT:
00417             switch(target)
00418               {
00419                 case T_FILE: 
00420                   return(check_flags_ff(target,tid,
00421                                         FF_read_only | FF_execute_only
00422                                          | FF_write_only | FF_append_only | FF_no_mount));
00423                 case T_DIR: 
00424                   return(check_flags_ff(target,tid,
00425                                         FF_read_only | FF_search_only | FF_no_mount));
00426 
00427                 /* all other cases are undefined */
00428                 default: return(DO_NOT_CARE);
00429               }
00430 
00431         case R_READ:
00432             switch(target)
00433               {
00434                 case T_DIR: 
00435                   return(check_flags_ff(target,tid,
00436                                         FF_search_only));
00437 
00438 #ifdef CONFIG_RSBAC_RW
00439                 case T_FILE:
00440                 case T_FIFO:
00441                   return(check_flags_ff(target,tid,
00442                                         FF_execute_only | FF_write_only));
00443 #endif
00444 
00445                 /* all other cases are undefined */
00446                 default: return(DO_NOT_CARE);
00447               }
00448 
00449         case R_READ_OPEN:
00450             switch(target)
00451               {
00452                 case T_FILE:
00453                 case T_FIFO:
00454                   return(check_flags_ff(target,tid,
00455                                         FF_execute_only | FF_write_only));
00456                 case T_DIR:
00457                   return(check_flags_ff(target,tid,
00458                                         FF_search_only));
00459 
00460                 /* all other cases are undefined */
00461                 default: return(DO_NOT_CARE);
00462               }
00463 
00464         case R_READ_WRITE_OPEN:
00465             switch(target)
00466               {
00467                 case T_FILE:
00468                 case T_FIFO:
00469                   return(check_flags_ff(target,tid,
00470                                         FF_read_only | FF_execute_only
00471                                          | FF_write_only | FF_append_only));
00472 
00473                 /* all other cases are undefined */
00474                 default: return(DO_NOT_CARE);
00475               }
00476 
00477         case R_SWITCH_LOG:
00478             switch(target)
00479               {
00480                 case T_NONE:
00481                   /* test owner's ff_role */
00482                   i_tid.user = owner;
00483                   if (rsbac_get_attr(FF, T_USER,
00484                                      i_tid,
00485                                      A_ff_role,
00486                                      &i_attr_val1,
00487                                      TRUE))
00488                     {
00489                       printk(KERN_WARNING "rsbac_adf_request_ff(): rsbac_get_attr() returned error!\n");
00490                       return(NOT_GRANTED);
00491                     }
00492                   /* security officer? -> grant  */
00493                   if (i_attr_val1.system_role == SR_security_officer)
00494                     return(GRANTED);
00495                   else
00496                     return(NOT_GRANTED);
00497 
00498                 /* all other cases are undefined */
00499                 default: return(DO_NOT_CARE);
00500               }
00501 
00502         case R_SWITCH_MODULE:
00503             switch(target)
00504               {
00505                 case T_NONE:
00506                   /* we need the switch_target */
00507                   if(attr != A_switch_target)
00508                     return(UNDEFINED);
00509                   /* do not care for other modules */
00510                   if(   (attr_val.switch_target != FF)
00511                      #ifdef CONFIG_RSBAC_SOFTMODE
00512                      && (attr_val.switch_target != SOFTMODE)
00513                      #endif
00514                      #ifdef CONFIG_RSBAC_FREEZE
00515                      && (attr_val.switch_target != FREEZE)
00516                      #endif
00517                      #ifdef CONFIG_RSBAC_FF_AUTH_PROT
00518                      && (attr_val.switch_target != AUTH)
00519                      #endif
00520                     )
00521                     return(DO_NOT_CARE);
00522                   /* test owner's ff_role */
00523                   i_tid.user = owner;
00524                   if (rsbac_get_attr(FF, T_USER,
00525                                      i_tid,
00526                                      A_ff_role,
00527                                      &i_attr_val1,
00528                                      TRUE))
00529                     {
00530                       printk(KERN_WARNING "rsbac_adf_request_ff(): rsbac_get_attr() returned error!\n");
00531                       return(NOT_GRANTED);
00532                     }
00533                   /* security officer? -> grant  */
00534                   if (i_attr_val1.system_role == SR_security_officer)
00535                     return(GRANTED);
00536                   else
00537                     return(NOT_GRANTED);
00538 
00539                 /* all other cases are undefined */
00540                 default: return(DO_NOT_CARE);
00541               }
00542 
00543         case R_TRUNCATE:
00544         case R_WRITE_OPEN:
00545             switch(target)
00546               {
00547                 case T_FILE:
00548                 case T_FIFO:
00549                   return(check_flags_ff(target,tid,
00550                                         FF_read_only | FF_execute_only | FF_append_only));
00551 
00552                 /* all other cases are undefined */
00553                 default: return(DO_NOT_CARE);
00554               }
00555 
00556         case R_WRITE:
00557             switch(target)
00558               {
00559                 case T_DIR: 
00560                   return(check_flags_ff(target,tid,
00561                                         FF_read_only | FF_search_only));
00562 
00563 #ifdef CONFIG_RSBAC_RW
00564                 case T_FILE:
00565                 case T_FIFO:
00566                   return(check_flags_ff(target,tid,
00567                                         FF_read_only | FF_execute_only));
00568 #endif
00569 #if defined(CONFIG_RSBAC_FF_UM_PROT)
00570                 case T_USER:
00571                 case T_GROUP:
00572                   /* Security Officer? */
00573                   i_tid.user = owner;
00574                   if (rsbac_get_attr(FF,
00575                                      T_USER,
00576                                      i_tid,
00577                                      A_ff_role,
00578                                      &i_attr_val1,
00579                                      TRUE))
00580                     {
00581                       rsbac_ds_get_error("rsbac_adf_request_ff()", A_ff_role);
00582                       return(NOT_GRANTED);
00583                     }
00584                   /* if sec_officer, then grant */
00585                   if (i_attr_val1.system_role == SR_security_officer)
00586                     return(GRANTED);
00587                   else
00588                     return(NOT_GRANTED);
00589 #endif
00590 
00591                 /* all other cases are undefined */
00592                 default: return(DO_NOT_CARE);
00593               }
00594 
00595 
00596 /*********************/
00597         default: return DO_NOT_CARE;
00598       }
00599 
00600     return(result);
00601   }; /* end of rsbac_adf_request_ff() */
00602 
00603 
00604 /*****************************************************************************/
00605 /* If the request returned granted and the operation is performed,           */
00606 /* the following function can be called by the AEF to get all aci set        */
00607 /* correctly. For write accesses that are performed fully within the kernel, */
00608 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
00609 /* cleaning up.                                                              */
00610 /* The second instance of target specification is the new target, if one has */
00611 /* been created, otherwise its values are ignored.                           */
00612 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
00613 
00614 int  rsbac_adf_set_attr_ff(
00615                       enum  rsbac_adf_request_t     request,
00616                             rsbac_pid_t             caller_pid,
00617                       enum  rsbac_target_t          target,
00618                       union rsbac_target_id_t       tid,
00619                       enum  rsbac_target_t          new_target,
00620                       union rsbac_target_id_t       new_tid,
00621                       enum  rsbac_attribute_t       attr,
00622                       union rsbac_attribute_value_t attr_val,
00623                             rsbac_uid_t             owner)
00624   {
00625 /*    union rsbac_target_id_t       i_tid;
00626     union rsbac_attribute_value_t i_attr_val1;
00627     union rsbac_attribute_value_t i_attr_val2; */
00628 
00629 /*
00630     switch (request)
00631       {
00632         default: return(0);
00633       }
00634 */
00635     return(0);
00636   } /* end of rsbac_adf_set_attr_ff() */
00637 
00638 /******************************************/
00639 #ifdef CONFIG_RSBAC_SECDEL
00640 rsbac_boolean_t rsbac_need_overwrite_ff(struct dentry * dentry_p)
00641   {
00642     union rsbac_target_id_t       i_tid;
00643     union rsbac_attribute_value_t i_attr_val1;
00644 
00645     if(   !dentry_p
00646        || !dentry_p->d_inode)
00647       return FALSE;
00648 
00649     i_tid.file.device = dentry_p->d_sb->s_dev;
00650     i_tid.file.inode = dentry_p->d_inode->i_ino;
00651     i_tid.file.dentry_p = dentry_p;
00652     /* get target's file flags */
00653     if (rsbac_get_attr(FF, T_FILE,
00654                        i_tid,
00655                        A_ff_flags,
00656                        &i_attr_val1,
00657                        TRUE))
00658       {
00659         printk(KERN_WARNING "rsbac_need_overwrite_ff(): rsbac_get_attr() returned error!\n");
00660         return FALSE;
00661       }
00662 
00663     /* overwrite, if secure_delete is set */
00664     if (i_attr_val1.ff_flags & FF_secure_delete)
00665       return TRUE;
00666     else
00667       return FALSE;
00668   }
00669 #endif
00670 
00671 /* end of rsbac/adf/ff/main.c */

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