/daten/src/linux-2.4.27-rsbac-v1.2.3/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-2004: Amon Ott <ao@rsbac.org> */ 00008 /* */ 00009 /* Last modified: 29/Apr/2004 */ 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 boolean rsbac_acl_check_super(enum rsbac_target_t target, 00034 union rsbac_target_id_t tid, 00035 rsbac_uid_t user); 00036 00037 boolean 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 boolean 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_DEV: 00060 case T_IPC: 00061 case T_SCD: 00062 case T_USER: 00063 case T_PROCESS: 00064 #ifdef CONFIG_RSBAC_ACL_NET_DEV_PROT 00065 case T_NETDEV: 00066 #endif 00067 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT 00068 case T_NETTEMP_NT: 00069 case T_NETTEMP: 00070 case T_NETOBJ: 00071 #endif 00072 break; 00073 default: 00074 return TRUE; 00075 } 00076 /* inherited own rights */ 00077 err = rsbac_acl_get_single_right(target, 00078 tid, 00079 ACLS_USER, 00080 (rsbac_acl_subject_id_t) user, 00081 request, 00082 &result); 00083 if(err) 00084 { 00085 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00086 00087 if(tmp) 00088 { 00089 #ifdef CONFIG_RSBAC_RMSG 00090 rsbac_printk(KERN_WARNING 00091 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00092 get_error_name(tmp,err)); 00093 #endif 00094 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00095 if (!rsbac_nosyslog) 00096 #endif 00097 printk(KERN_WARNING 00098 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00099 get_error_name(tmp,err)); 00100 rsbac_kfree(tmp); 00101 } 00102 return FALSE; 00103 } 00104 if(result) 00105 return(TRUE); 00106 00107 /* add group and role rights */ 00108 /* group everyone */ 00109 err = rsbac_acl_get_single_right(target, 00110 tid, 00111 ACLS_GROUP, 00112 RSBAC_ACL_GROUP_EVERYONE, 00113 request, 00114 &result); 00115 if(err) 00116 { 00117 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00118 00119 if(tmp) 00120 { 00121 #ifdef CONFIG_RSBAC_RMSG 00122 rsbac_printk(KERN_WARNING 00123 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00124 get_error_name(tmp,err)); 00125 #endif 00126 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00127 if (!rsbac_nosyslog) 00128 #endif 00129 printk(KERN_WARNING 00130 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00131 get_error_name(tmp,err)); 00132 rsbac_kfree(tmp); 00133 } 00134 return FALSE; 00135 } 00136 if(result) 00137 return(TRUE); 00138 00139 #if defined(CONFIG_RSBAC_RC) 00140 /* use process role */ 00141 /* first get role */ 00142 i_tid.process = caller_pid; 00143 if (rsbac_get_attr(RC, 00144 T_PROCESS, 00145 i_tid, 00146 A_rc_role, 00147 &i_attr_val1, 00148 FALSE)) 00149 { 00150 #ifdef CONFIG_RSBAC_RMSG 00151 rsbac_printk(KERN_WARNING 00152 "rsbac_acl_check_right(): rsbac_get_attr() for process rc_role returned error!\n"); 00153 #endif 00154 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00155 if (!rsbac_nosyslog) 00156 #endif 00157 printk(KERN_WARNING 00158 "rsbac_acl_check_right(): rsbac_get_attr() for process rc_role returned error!\n"); 00159 } 00160 else 00161 { 00162 err = rsbac_acl_get_single_right(target, 00163 tid, 00164 ACLS_ROLE, 00165 i_attr_val1.rc_role, 00166 request, 00167 &result); 00168 if(err) 00169 { 00170 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00171 00172 if(tmp) 00173 { 00174 get_error_name(tmp,err); 00175 #ifdef CONFIG_RSBAC_RMSG 00176 rsbac_printk(KERN_WARNING 00177 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00178 tmp); 00179 #endif 00180 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00181 if (!rsbac_nosyslog) 00182 #endif 00183 printk(KERN_WARNING 00184 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00185 tmp); 00186 rsbac_kfree(tmp); 00187 } 00188 return FALSE; 00189 } 00190 if(result) 00191 return(TRUE); 00192 } 00193 #endif 00194 00195 /* other groups */ 00196 /* first get user groups */ 00197 group_p = NULL; 00198 err = rsbac_acl_get_user_groups(user, &group_p, NULL); 00199 if(err<0) 00200 { 00201 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00202 00203 if(tmp) 00204 { 00205 #ifdef CONFIG_RSBAC_RMSG 00206 rsbac_printk(KERN_WARNING 00207 "rsbac_acl_check_right(): rsbac_acl_get_user_groups() returned error %s!\n", 00208 get_error_name(tmp,err)); 00209 #endif 00210 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00211 if (!rsbac_nosyslog) 00212 #endif 00213 printk(KERN_WARNING 00214 "rsbac_acl_check_right(): rsbac_acl_get_user_groups() returned error %s!\n", 00215 get_error_name(tmp,err)); 00216 rsbac_kfree(tmp); 00217 } 00218 return err; 00219 } 00220 for(i=0; i<err; i++) 00221 { 00222 tmperr = rsbac_acl_get_single_right(target, 00223 tid, 00224 ACLS_GROUP, 00225 group_p[i], 00226 request, 00227 &result); 00228 if(tmperr) 00229 { 00230 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00231 00232 if(tmp) 00233 { 00234 #ifdef CONFIG_RSBAC_RMSG 00235 rsbac_printk(KERN_WARNING 00236 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00237 get_error_name(tmp, tmperr)); 00238 #endif 00239 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00240 if (!rsbac_nosyslog) 00241 #endif 00242 printk(KERN_WARNING 00243 "rsbac_acl_check_right(): rsbac_acl_get_single_right() returned error %s!\n", 00244 get_error_name(tmp, tmperr)); 00245 rsbac_kfree(tmp); 00246 } 00247 if(group_p) 00248 rsbac_vfree(group_p); 00249 return FALSE; 00250 } 00251 if(result) 00252 { 00253 if(group_p) 00254 rsbac_vfree(group_p); 00255 return(TRUE); 00256 } 00257 } 00258 if(group_p) 00259 rsbac_vfree(group_p); 00260 00261 /* SUPERVISOR? */ 00262 #ifdef CONFIG_RSBAC_ACL_LEARN 00263 result = rsbac_acl_check_super(target, tid, user); 00264 if( !result 00265 && (request < R_NONE) 00266 ) 00267 { 00268 switch(target) 00269 { 00270 case T_FILE: 00271 case T_DIR: 00272 case T_FIFO: 00273 case T_SYMLINK: 00274 if(rsbac_acl_learn_fd) 00275 { 00276 char * tmp; 00277 enum rsbac_acl_subject_type_t subj_type; 00278 rsbac_acl_subject_id_t subj_id; 00279 rsbac_acl_rights_vector_t rights; 00280 rsbac_time_t ttl; 00281 00282 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00283 if(tmp) 00284 { 00285 char * target_type_name; 00286 00287 target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00288 if(target_type_name) 00289 { 00290 char * target_id_name; 00291 00292 #ifdef CONFIG_RSBAC_LOG_FULL_PATH 00293 target_id_name 00294 = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN); 00295 /* max. path name len + some extra */ 00296 #else 00297 target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN); 00298 /* max. file name len + some extra */ 00299 #endif 00300 if(target_id_name) 00301 { 00302 get_request_name(tmp,request); 00303 get_target_name(target_type_name, target, target_id_name, tid); 00304 #ifdef CONFIG_RSBAC_RMSG 00305 rsbac_printk(KERN_INFO 00306 "rsbac_acl_check_right(): auto_learn_fd: granting right %s for user %u to target_type %s, tid %s!\n", 00307 tmp, 00308 user, 00309 target_type_name, 00310 target_id_name); 00311 #endif 00312 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00313 if (!rsbac_nosyslog) 00314 #endif 00315 printk(KERN_INFO 00316 "rsbac_acl_check_right(): auto_learn_fd: granting right %s for user %u to target_type %s, tid %s!\n", 00317 tmp, 00318 user, 00319 target_type_name, 00320 target_id_name); 00321 rsbac_kfree(target_id_name); 00322 } 00323 rsbac_kfree(target_type_name); 00324 } 00325 } 00326 subj_type = ACLS_USER; 00327 subj_id = user; 00328 rights = RSBAC_REQUEST_VECTOR(request); 00329 ttl = 0; 00330 err = rsbac_acl_add_to_acl_entry(target, tid, subj_type, subj_id, rights, ttl); 00331 if(tmp) 00332 { 00333 if(err) 00334 { 00335 #ifdef CONFIG_RSBAC_RMSG 00336 rsbac_printk(KERN_WARNING 00337 "rsbac_acl_check_right(): rsbac_acl_add_to_acl_entry() returned error %s!\n", 00338 get_error_name(tmp,err)); 00339 #endif 00340 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00341 if (!rsbac_nosyslog) 00342 #endif 00343 printk(KERN_WARNING 00344 "rsbac_acl_check_right(): rsbac_acl_add_to_acl_entry() returned error %s!\n", 00345 get_error_name(tmp,err)); 00346 } 00347 rsbac_kfree(tmp); 00348 } 00349 result = TRUE; 00350 } 00351 break; 00352 00353 default: 00354 break; 00355 } 00356 } 00357 return result; 00358 #else 00359 return rsbac_acl_check_super(target, tid, user); 00360 #endif 00361 }; 00362 00363 boolean rsbac_acl_check_forward(enum rsbac_target_t target, 00364 union rsbac_target_id_t tid, 00365 rsbac_uid_t user, 00366 rsbac_acl_rights_vector_t rights) 00367 { 00368 rsbac_acl_rights_vector_t i_rights = 0; 00369 rsbac_acl_rights_vector_t i_rvec = ((rsbac_acl_rights_vector_t) 1 << ACLR_FORWARD) | rights; 00370 int err=0; 00371 00372 00373 /* Only check implemented targets */ 00374 switch(target) 00375 { 00376 case T_FILE: 00377 case T_DIR: 00378 case T_FIFO: 00379 case T_SYMLINK: 00380 case T_DEV: 00381 case T_IPC: 00382 case T_SCD: 00383 case T_USER: 00384 case T_PROCESS: 00385 case T_NETDEV: 00386 case T_NETTEMP_NT: 00387 case T_NETTEMP: 00388 case T_NETOBJ: 00389 break; 00390 default: 00391 return TRUE; 00392 } 00393 /* get effective rights */ 00394 err = rsbac_acl_sys_get_rights(target, tid, ACLS_USER, (rsbac_acl_subject_id_t) user, &i_rights, TRUE); 00395 if(err) 00396 { 00397 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN); 00398 00399 if(tmp) 00400 { 00401 #ifdef CONFIG_RSBAC_RMSG 00402 rsbac_printk(KERN_WARNING 00403 "rsbac_acl_check_forward(): rsbac_acl_sys_get_rights() returned error %s!\n", 00404 get_error_name(tmp,err)); 00405 #endif 00406 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00407 if (!rsbac_nosyslog) 00408 #endif 00409 printk(KERN_WARNING 00410 "rsbac_acl_check_forward(): rsbac_acl_sys_get_rights() returned error %s!\n", 00411 get_error_name(tmp,err)); 00412 rsbac_kfree(tmp); 00413 } 00414 return FALSE; 00415 } 00416 if((i_rights & i_rvec) == i_rvec) 00417 return(TRUE); 00418 else 00419 return(FALSE); 00420 }; 00421 00422 /************************************************* */ 00423 /* Externally visible functions */ 00424 /************************************************* */ 00425 00426 enum rsbac_adf_req_ret_t 00427 rsbac_adf_request_acl (enum rsbac_adf_request_t request, 00428 rsbac_pid_t caller_pid, 00429 enum rsbac_target_t target, 00430 union rsbac_target_id_t tid, 00431 enum rsbac_attribute_t attr, 00432 union rsbac_attribute_value_t attr_val, 00433 rsbac_uid_t owner) 00434 { 00435 switch (request) 00436 { 00437 case R_READ_ATTRIBUTE: 00438 case R_MODIFY_ATTRIBUTE: 00439 switch(attr) 00440 { /* owner must be changed by other request to prevent inconsistency */ 00441 case A_owner: 00442 if(request == R_READ_ATTRIBUTE) 00443 return(GRANTED); 00444 else 00445 return(NOT_GRANTED); 00446 00447 /* Only protect AUTH, if asked to by configuration */ 00448 #ifdef CONFIG_RSBAC_ACL_AUTH_PROT 00449 case A_auth_may_setuid: 00450 case A_auth_may_set_cap: 00451 case A_auth_start_uid: 00452 case A_auth_learn: 00453 case A_auth_program_file: 00454 case A_auth_add_f_cap: 00455 case A_auth_remove_f_cap: 00456 tid.scd = AST_auth_administration; 00457 if (rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request)) 00458 return(GRANTED); 00459 else 00460 return(NOT_GRANTED); 00461 #endif 00462 00463 #ifdef CONFIG_RSBAC_ACL_GEN_PROT 00464 case A_pseudo: 00465 case A_log_array_low: 00466 case A_log_array_high: 00467 case A_log_program_based: 00468 case A_log_user_based: 00469 case A_symlink_add_uid: 00470 case A_symlink_add_rc_role: 00471 case A_linux_dac_disable: 00472 case A_fake_root_uid: 00473 if (!rsbac_acl_check_right(target, tid, owner, caller_pid, request)) 00474 return(NOT_GRANTED); 00475 else 00476 return(GRANTED); 00477 #endif 00478 00479 #ifdef CONFIG_RSBAC_ACL_LEARN 00480 case A_acl_learn: 00481 /* check supervisor on target */ 00482 if(rsbac_acl_check_super(target, 00483 tid, 00484 owner)) 00485 return(GRANTED); 00486 else 00487 return(NOT_GRANTED); 00488 #endif 00489 00490 /* All attributes (remove target!) */ 00491 case A_none: 00492 if (!rsbac_acl_check_right(target, tid, owner, caller_pid, request)) 00493 return(NOT_GRANTED); 00494 #ifdef CONFIG_RSBAC_ACL_AUTH_PROT 00495 tid.scd = AST_auth_administration; 00496 if (!rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request)) 00497 return(NOT_GRANTED); 00498 #endif 00499 return(GRANTED); 00500 00501 default: 00502 return(DO_NOT_CARE); 00503 } 00504 00505 case R_SWITCH_MODULE: 00506 switch(target) 00507 { 00508 case T_NONE: 00509 if( (attr_val.switch_target != ACL) 00510 #ifdef CONFIG_RSBAC_SOFTMODE 00511 && (attr_val.switch_target != SOFTMODE) 00512 #endif 00513 ) 00514 return(DO_NOT_CARE); 00515 00516 tid.scd = ST_other; 00517 if (rsbac_acl_check_right(T_SCD, tid, owner, caller_pid, request)) 00518 return(GRANTED); 00519 else 00520 return(NOT_GRANTED); 00521 00522 /* all other cases are unknown */ 00523 default: 00524 return(DO_NOT_CARE); 00525 } 00526 00527 /*********************/ 00528 default: 00529 if(target == T_NONE) 00530 { 00531 target = T_SCD; 00532 tid.scd = ST_other; 00533 } 00534 if (rsbac_acl_check_right(target, tid, owner, caller_pid, request)) 00535 return(GRANTED); 00536 else 00537 return(NOT_GRANTED); 00538 } 00539 }; /* end of rsbac_adf_request_acl() */ 00540 00541 00542 /*****************************************************************************/ 00543 /* If the request returned granted and the operation is performed, */ 00544 /* the following function can be called by the AEF to get all aci set */ 00545 /* correctly. For write accesses that are performed fully within the kernel, */ 00546 /* this is usually not done to prevent extra calls, including R_CLOSE for */ 00547 /* cleaning up. */ 00548 /* The second instance of target specification is the new target, if one has */ 00549 /* been created, otherwise its values are ignored. */ 00550 /* On success, 0 is returned, and an error from rsbac/error.h otherwise. */ 00551 00552 inline int rsbac_adf_set_attr_acl( 00553 enum rsbac_adf_request_t request, 00554 rsbac_pid_t caller_pid, 00555 enum rsbac_target_t target, 00556 union rsbac_target_id_t tid, 00557 enum rsbac_target_t new_target, 00558 union rsbac_target_id_t new_tid, 00559 enum rsbac_attribute_t attr, 00560 union rsbac_attribute_value_t attr_val, 00561 rsbac_uid_t owner) 00562 { 00563 /* Nothing to be done here */ 00564 return(0); 00565 }; /* end of rsbac_adf_set_attr_acl() */ 00566 00567 /* end of rsbac/adf/acl/main.c */

Generated on Tue Aug 31 10:05:23 2004 for RSBAC by doxygen 1.3.8