00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00026
00027
00028
00029
00030
00031
00032
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
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
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
00104
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
00129
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
00169
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
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
00254 #else
00255 target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00256
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
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
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
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 {
00380 case A_owner:
00381 if(request == R_READ_ATTRIBUTE)
00382 return(GRANTED);
00383 else
00384 return(NOT_GRANTED);
00385
00386
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
00428 if(rsbac_acl_check_super(target,
00429 tid,
00430 owner))
00431 return(GRANTED);
00432 else
00433 return(NOT_GRANTED);
00434 #endif
00435
00436
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
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 }
00492
00493