/linux-2.6.21.1-rsbac-1.3.4/rsbac/adf/acl/acl_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) - Access Control Lists (ACL)        */
00005 /* File: rsbac/adf/acl/acl_main.c                     */
00006 /*                                                    */
00007 /* Author and (c) 1999-2006: Amon Ott <ao@rsbac.org>  */
00008 /*                                                    */
00009 /* Last modified: 14/Jun/2006                         */
00010 /**************************************************** */
00011 
00012 #include <linux/string.h>
00013 #include <linux/vmalloc.h>
00014 #include <rsbac/aci.h>
00015 #include <rsbac/acl.h>
00016 #include <rsbac/adf_main.h>
00017 #include <rsbac/adf_syshelpers.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/helpers.h>
00020 #include <rsbac/getname.h>
00021 #include <rsbac/rkmem.h>
00022 #include <rsbac/debug.h>
00023 
00024 /************************************************* */
00025 /*           Global Variables                      */
00026 /************************************************* */
00027 
00028 /************************************************* */
00029 /*          Internal Help functions                */
00030 /************************************************* */
00031 
00032 /* in acl_syscalls.c */
00033 rsbac_boolean_t rsbac_acl_check_super(enum  rsbac_target_t target,
00034                               union rsbac_target_id_t tid,
00035                                     rsbac_uid_t user);
00036 
00037 rsbac_boolean_t rsbac_acl_check_right(enum  rsbac_target_t target,
00038                               union rsbac_target_id_t tid,
00039                                     rsbac_uid_t user,
00040                                     rsbac_pid_t caller_pid,
00041                               enum  rsbac_adf_request_t request)
00042   {
00043     rsbac_boolean_t                   result = FALSE;
00044     int                       err=0, tmperr;
00045     int                       i;
00046     rsbac_acl_group_id_t    * group_p;
00047     #if defined(CONFIG_RSBAC_RC)
00048     union rsbac_target_id_t       i_tid;
00049     union rsbac_attribute_value_t i_attr_val1;
00050     #endif
00051 
00052     /* Only check implemented targets */
00053     switch(target)
00054       {
00055         case T_FILE:
00056         case T_DIR:
00057         case T_FIFO:
00058         case T_SYMLINK:
00059         case T_UNIXSOCK:
00060         case T_DEV:
00061         case T_IPC:
00062         case T_SCD:
00063         case T_USER:
00064         case T_PROCESS:
00065 #ifdef CONFIG_RSBAC_ACL_UM_PROT
00066         case T_GROUP:
00067 #endif
00068 #ifdef CONFIG_RSBAC_ACL_NET_DEV_PROT
00069         case T_NETDEV:
00070 #endif
00071 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00072         case T_NETTEMP_NT:
00073         case T_NETTEMP:
00074         case T_NETOBJ:
00075 #endif
00076           break;
00077         default:
00078           return TRUE;
00079       }
00080     /* inherited own rights */
00081     err = rsbac_acl_get_single_right(target,
00082                                      tid,
00083                                      ACLS_USER,
00084                                      (rsbac_acl_subject_id_t) user,
00085                                      request,
00086                                      &result);
00087     if(err)
00088       {
00089         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00090 
00091         if(tmp)
00092           {
00093             rsbac_printk(KERN_WARNING
00094                    "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n",
00095                    get_error_name(tmp,err));
00096             rsbac_kfree(tmp);
00097           }
00098         return FALSE;
00099       }
00100     if(result)
00101       return(TRUE);
00102 
00103     /* add group and role rights */
00104     /* group everyone */
00105     err = rsbac_acl_get_single_right(target,
00106                                      tid,
00107                                      ACLS_GROUP,
00108                                      RSBAC_ACL_GROUP_EVERYONE,
00109                                      request,
00110                                      &result);
00111     if(err)
00112       {
00113         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00114 
00115         if(tmp)
00116           {
00117             rsbac_printk(KERN_WARNING
00118                    "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n",
00119                    get_error_name(tmp,err));
00120             rsbac_kfree(tmp);
00121           }
00122         return FALSE;
00123       }
00124     if(result)
00125       return(TRUE);
00126 
00127     #if defined(CONFIG_RSBAC_RC)
00128     /* use process role */
00129     /* first get role */
00130     i_tid.process = caller_pid;
00131     if (rsbac_get_attr(SW_RC,
00132                        T_PROCESS,
00133                        i_tid,
00134                        A_rc_role,
00135                        &i_attr_val1,
00136                        FALSE))
00137       {
00138         rsbac_printk(KERN_WARNING
00139                "rsbac_acl_check_right(): rsbac_get_attr() for process rc_role returned error!\n");
00140       }
00141     else
00142       {
00143         err = rsbac_acl_get_single_right(target,
00144                                          tid,
00145                                          ACLS_ROLE,
00146                                          i_attr_val1.rc_role,
00147                                          request,
00148                                          &result);
00149         if(err)
00150           {
00151             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00152 
00153             if(tmp)
00154               {
00155                 get_error_name(tmp,err);
00156                 rsbac_printk(KERN_WARNING
00157                        "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n",
00158                        tmp);
00159                 rsbac_kfree(tmp);
00160               }
00161             return FALSE;
00162           }
00163         if(result)
00164           return(TRUE);
00165       }
00166     #endif
00167 
00168     /* other groups */
00169     /* first get user groups */
00170     group_p = NULL;
00171     err = rsbac_acl_get_user_groups(0, user, &group_p, NULL);
00172     if(err<0)
00173       {
00174         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00175 
00176         if(tmp)
00177           {
00178             rsbac_printk(KERN_WARNING
00179                    "rsbac_acl_check_right(): rsbac_acl_get_user_groups() returned error %s!\n",
00180                    get_error_name(tmp,err));
00181             rsbac_kfree(tmp);
00182           }
00183         return err;
00184       }
00185     for(i=0; i<err; i++)
00186       {
00187         tmperr = rsbac_acl_get_single_right(target,
00188                                             tid,
00189                                             ACLS_GROUP,
00190                                             group_p[i],
00191                                             request,
00192                                             &result);
00193         if(tmperr)
00194           {
00195             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00196 
00197             if(tmp)
00198               {
00199                 rsbac_printk(KERN_WARNING
00200                        "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n",
00201                        get_error_name(tmp, tmperr));
00202                 rsbac_kfree(tmp);
00203               }
00204             if(group_p)
00205               rsbac_vfree(group_p);
00206             return FALSE;
00207           }
00208         if(result)
00209           {
00210             if(group_p)
00211               rsbac_vfree(group_p);
00212             return(TRUE);
00213           }
00214       }
00215     if(group_p)
00216       rsbac_vfree(group_p);
00217 
00218     /* SUPERVISOR? */
00219 #ifdef CONFIG_RSBAC_ACL_LEARN
00220     result = rsbac_acl_check_super(target, tid, user);
00221     if(   !result
00222        && (request < R_NONE)
00223       )
00224       {
00225         switch(target)
00226           {
00227             case T_FILE:
00228             case T_DIR:
00229             case T_FIFO:
00230             case T_SYMLINK:
00231             case T_UNIXSOCK:
00232               if(rsbac_acl_learn_fd)
00233                 {
00234                   char * tmp;
00235                   enum rsbac_acl_subject_type_t  subj_type;
00236                        rsbac_acl_subject_id_t    subj_id;
00237                        rsbac_acl_rights_vector_t rights;
00238                        rsbac_time_t              ttl;
00239 
00240                   tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00241                   if(tmp)
00242                     {
00243                       char * target_type_name;
00244 
00245                       target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00246                       if(target_type_name)
00247                         {
00248                           char * target_id_name;
00249 
00250                           #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00251                           target_id_name
00252                            = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00253                           /* max. path name len + some extra */
00254                           #else
00255                           target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00256                           /* max. file name len + some extra */
00257                           #endif
00258                           if(target_id_name)
00259                             {
00260                               get_request_name(tmp,request);
00261                               get_target_name(target_type_name, target, target_id_name, tid);
00262                               rsbac_printk(KERN_INFO
00263                                            "rsbac_acl_check_right(): auto_learn_fd: granting right %s for user %u to target_type %s, tid %s!\n",
00264                                            tmp,
00265                                            user,
00266                                            target_type_name,
00267                                            target_id_name);
00268                               rsbac_kfree(target_id_name);
00269                             }
00270                           rsbac_kfree(target_type_name);
00271                         }
00272                     }
00273                   subj_type = ACLS_USER;
00274                   subj_id = user;
00275                   rights = RSBAC_REQUEST_VECTOR(request);
00276                   ttl = 0;
00277                   err = rsbac_acl_add_to_acl_entry(0, target, tid, subj_type, subj_id, rights, ttl);
00278                   if(tmp)
00279                     {
00280                       if(err)
00281                         {
00282                           rsbac_printk(KERN_WARNING
00283                                        "rsbac_acl_check_right(): rsbac_acl_add_to_acl_entry() returned error %s!\n",
00284                                        get_error_name(tmp,err));
00285                         }
00286                       rsbac_kfree(tmp);
00287                     }
00288                   result = TRUE;
00289                 }
00290               break;
00291 
00292             default:
00293               break;
00294           }
00295       }
00296     return result;
00297 #else
00298     return rsbac_acl_check_super(target, tid, user);
00299 #endif
00300   }
00301 
00302 rsbac_boolean_t rsbac_acl_check_forward(enum  rsbac_target_t target,
00303                                 union rsbac_target_id_t tid,
00304                                       rsbac_uid_t user,
00305                                       rsbac_acl_rights_vector_t rights)
00306   {
00307     rsbac_acl_rights_vector_t i_rights = 0;
00308     rsbac_acl_rights_vector_t i_rvec = ((rsbac_acl_rights_vector_t) 1 << ACLR_FORWARD) | rights;
00309     int                       err=0;
00310 
00311 
00312     /* Only check implemented targets */
00313     switch(target)
00314       {
00315         case T_FILE:
00316         case T_DIR:
00317         case T_FIFO:
00318         case T_SYMLINK:
00319         case T_UNIXSOCK:
00320         case T_DEV:
00321         case T_IPC:
00322         case T_SCD:
00323         case T_USER:
00324         case T_PROCESS:
00325 #ifdef CONFIG_RSBAC_ACL_UM_PROT
00326         case T_GROUP:
00327 #endif
00328 #ifdef CONFIG_RSBAC_ACL_NET_DEV_PROT
00329         case T_NETDEV:
00330 #endif
00331 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00332         case T_NETTEMP_NT:
00333         case T_NETTEMP:
00334         case T_NETOBJ:
00335 #endif
00336           break;
00337         default:
00338           return TRUE;
00339       }
00340     /* get effective rights */
00341     err = rsbac_acl_sys_get_rights(0, target, tid, ACLS_USER, (rsbac_acl_subject_id_t) user, &i_rights, TRUE);
00342     if(err)
00343       {
00344         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00345 
00346         if(tmp)
00347           {
00348             rsbac_printk(KERN_WARNING
00349                    "rsbac_acl_check_forward(): rsbac_acl_sys_get_rights() returned error %s!\n",
00350                    get_error_name(tmp,err));
00351             rsbac_kfree(tmp);
00352           }
00353         return FALSE;
00354       }
00355     if((i_rights & i_rvec) == i_rvec)
00356       return(TRUE);
00357     else
00358       return(FALSE);
00359   }
00360 
00361 /************************************************* */
00362 /*          Externally visible functions           */
00363 /************************************************* */
00364 
00365 inline enum rsbac_adf_req_ret_t
00366    rsbac_adf_request_acl (enum  rsbac_adf_request_t     request,
00367                                 rsbac_pid_t             caller_pid,
00368                           enum  rsbac_target_t          target,
00369                           union rsbac_target_id_t       tid,
00370                           enum  rsbac_attribute_t       attr,
00371                           union rsbac_attribute_value_t attr_val,
00372                                 rsbac_uid_t             owner)
00373   {
00374     switch (request)
00375       {
00376         case R_READ_ATTRIBUTE:
00377         case R_MODIFY_ATTRIBUTE:
00378             switch(attr)
00379               { /* owner must be changed by other request to prevent inconsistency */
00380                 case A_owner:
00381                   if(request == R_READ_ATTRIBUTE)
00382                     return(GRANTED);
00383                   else
00384                     return(NOT_GRANTED);
00385 
00386                 /* Only protect AUTH, if asked to by configuration */
00387                 #ifdef CONFIG_RSBAC_ACL_AUTH_PROT
00388                 case A_auth_may_setuid:
00389                 case A_auth_may_set_cap:
00390                 case A_auth_start_uid:
00391                 case A_auth_start_euid:
00392                 case A_auth_start_gid:
00393                 case A_auth_start_egid:
00394                 case A_auth_learn:
00395                 case A_auth_program_file:
00396                 case A_auth_add_f_cap:
00397                 case A_auth_remove_f_cap:
00398                   tid.scd = AST_auth_administration;
00399                   if (rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request))
00400                     return(GRANTED);
00401                   else
00402                     return(NOT_GRANTED);
00403                 #endif
00404 
00405                 #ifdef CONFIG_RSBAC_ACL_GEN_PROT
00406                 case A_pseudo:
00407                 case A_log_array_low:
00408                 case A_log_array_high:
00409                 case A_log_program_based:
00410                 case A_log_user_based:
00411                 case A_symlink_add_remote_ip:
00412                 case A_symlink_add_uid:
00413                 case A_symlink_add_rc_role:
00414                 case A_linux_dac_disable:
00415                 case A_fake_root_uid:
00416                 case A_audit_uid:
00417                 case A_auid_exempt:
00418                 case A_remote_ip:
00419                   if (!rsbac_acl_check_right(target, tid, owner, caller_pid, request))
00420                     return(NOT_GRANTED);
00421                   else
00422                     return(GRANTED);
00423                 #endif
00424 
00425                 #ifdef CONFIG_RSBAC_ACL_LEARN
00426                 case A_acl_learn:
00427                   /* check supervisor on target */
00428                   if(rsbac_acl_check_super(target,
00429                                            tid,
00430                                            owner))
00431                     return(GRANTED);
00432                   else
00433                     return(NOT_GRANTED);
00434                 #endif
00435 
00436                 /* All attributes (remove target!) */
00437                 case A_none:
00438                   if (!rsbac_acl_check_right(target, tid, owner, caller_pid, request))
00439                     return(NOT_GRANTED);
00440                   #ifdef CONFIG_RSBAC_ACL_AUTH_PROT
00441                   tid.scd = AST_auth_administration;
00442                   if (!rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request))
00443                     return(NOT_GRANTED);
00444                   #endif
00445                   return(GRANTED);
00446 
00447                 default:
00448                   return(DO_NOT_CARE);
00449               }
00450 
00451         case R_SWITCH_MODULE:
00452             switch(target)
00453               {
00454                 case T_NONE:
00455                     if(   (attr_val.switch_target != SW_ACL)
00456                        #ifdef CONFIG_RSBAC_SOFTMODE
00457                        && (attr_val.switch_target != SW_SOFTMODE)
00458                        #endif
00459                        #ifdef CONFIG_RSBAC_FREEZE
00460                        && (attr_val.switch_target != SW_FREEZE)
00461                        #endif
00462                        #ifdef CONFIG_RSBAC_ACL_AUTH_PROT
00463                        && (attr_val.switch_target != SW_AUTH)
00464                        #endif
00465                       )
00466                       return(DO_NOT_CARE);
00467 
00468                     tid.scd = ST_other;
00469                     if (rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request))
00470                       return(GRANTED);
00471                     else
00472                       return(NOT_GRANTED);
00473 
00474                 /* all other cases are unknown */
00475                 default:
00476                   return(DO_NOT_CARE);
00477               }
00478 
00479 /*********************/
00480         default:
00481           if(target == T_NONE)
00482             {
00483               target = T_SCD;
00484               tid.scd = ST_other;
00485             }
00486           if (rsbac_acl_check_right(target, tid, owner, caller_pid, request))
00487             return(GRANTED);
00488           else
00489             return(NOT_GRANTED);
00490       }
00491   } /* end of rsbac_adf_request_acl() */
00492 
00493 /* end of rsbac/adf/acl/main.c */

Generated on Wed May 16 11:53:29 2007 for RSBAC by  doxygen 1.5.1