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

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