/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/adf/cap/cap_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) - Linux Capabilities (CAP) */ 00005 /* File: rsbac/adf/cap/main.c */ 00006 /* */ 00007 /* Author and (c) 1999-2004: Amon Ott <ao@rsbac.org> */ 00008 /* */ 00009 /* Last modified: 11/Mar/2004 */ 00010 /**************************************************** */ 00011 00012 #include <linux/string.h> 00013 #include <rsbac/types.h> 00014 #include <rsbac/aci.h> 00015 #include <rsbac/adf_main.h> 00016 #include <rsbac/error.h> 00017 #include <rsbac/helpers.h> 00018 #include <rsbac/getname.h> 00019 #include <rsbac/debug.h> 00020 00021 /************************************************* */ 00022 /* Global Variables */ 00023 /************************************************* */ 00024 00025 /************************************************* */ 00026 /* Internal Help functions */ 00027 /************************************************* */ 00028 00029 /************************************************* */ 00030 /* Externally visible functions */ 00031 /************************************************* */ 00032 00033 enum rsbac_adf_req_ret_t 00034 rsbac_adf_request_cap (enum rsbac_adf_request_t request, 00035 rsbac_pid_t caller_pid, 00036 enum rsbac_target_t target, 00037 union rsbac_target_id_t tid, 00038 enum rsbac_attribute_t attr, 00039 union rsbac_attribute_value_t attr_val, 00040 rsbac_uid_t owner) 00041 { 00042 union rsbac_target_id_t i_tid; 00043 union rsbac_attribute_value_t i_attr_val1; 00044 00045 switch (request) 00046 { 00047 case R_MODIFY_ATTRIBUTE: 00048 switch(attr) 00049 { 00050 case A_system_role: 00051 case A_cap_role: 00052 case A_min_caps: 00053 case A_max_caps: 00054 case A_cap_process_hiding: 00055 #ifdef CONFIG_RSBAC_CAP_AUTH_PROT 00056 case A_auth_may_setuid: 00057 case A_auth_may_set_cap: 00058 case A_auth_start_uid: 00059 case A_auth_program_file: 00060 case A_auth_learn: 00061 case A_auth_add_f_cap: 00062 case A_auth_remove_f_cap: 00063 #endif 00064 /* All attributes (remove target!) */ 00065 case A_none: 00066 /* Security Officer? */ 00067 i_tid.user = owner; 00068 if (rsbac_get_attr(CAP, 00069 T_USER, 00070 i_tid, 00071 A_cap_role, 00072 &i_attr_val1, 00073 TRUE)) 00074 { 00075 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_role); 00076 return(NOT_GRANTED); 00077 } 00078 /* if sec_officer, then grant */ 00079 if (i_attr_val1.system_role == SR_security_officer) 00080 return(GRANTED); 00081 else 00082 return(NOT_GRANTED); 00083 00084 default: 00085 return(DO_NOT_CARE); 00086 } 00087 00088 case R_READ_ATTRIBUTE: 00089 switch(attr) 00090 { 00091 case A_system_role: 00092 case A_cap_role: 00093 case A_min_caps: 00094 case A_max_caps: 00095 case A_cap_process_hiding: 00096 /* All attributes (remove target!) */ 00097 case A_none: 00098 /* Security Officer or Admin? */ 00099 i_tid.user = owner; 00100 if (rsbac_get_attr(CAP, 00101 T_USER, 00102 i_tid, 00103 A_cap_role, 00104 &i_attr_val1, 00105 TRUE)) 00106 { 00107 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_role); 00108 return(NOT_GRANTED); 00109 } 00110 /* if sec_officer, then grant */ 00111 if( (i_attr_val1.system_role == SR_security_officer) 00112 || (i_attr_val1.system_role == SR_administrator) 00113 ) 00114 return(GRANTED); 00115 else 00116 return(NOT_GRANTED); 00117 00118 default: 00119 return(DO_NOT_CARE); 00120 } 00121 00122 case R_SWITCH_LOG: 00123 switch(target) 00124 { 00125 case T_NONE: 00126 /* test owner's cap_role */ 00127 i_tid.user = owner; 00128 if (rsbac_get_attr(CAP, 00129 T_USER, 00130 i_tid, 00131 A_cap_role, 00132 &i_attr_val1, 00133 TRUE)) 00134 { 00135 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_role); 00136 return(NOT_GRANTED); 00137 } 00138 /* security officer? -> grant */ 00139 if (i_attr_val1.system_role == SR_security_officer) 00140 return(GRANTED); 00141 else 00142 return(NOT_GRANTED); 00143 00144 /* all other cases are unknown */ 00145 default: return(DO_NOT_CARE); 00146 } 00147 00148 case R_SWITCH_MODULE: 00149 switch(target) 00150 { 00151 case T_NONE: 00152 /* we need the switch_target */ 00153 if(attr != A_switch_target) 00154 return(UNDEFINED); 00155 /* do not care for other modules */ 00156 if( (attr_val.switch_target != CAP) 00157 #ifdef CONFIG_RSBAC_CAP_AUTH_PROT 00158 && (attr_val.switch_target != AUTH) 00159 #endif 00160 #ifdef CONFIG_RSBAC_SOFTMODE 00161 && (attr_val.switch_target != SOFTMODE) 00162 #endif 00163 ) 00164 return(DO_NOT_CARE); 00165 /* test owner's cap_role */ 00166 i_tid.user = owner; 00167 if (rsbac_get_attr(CAP, 00168 T_USER, 00169 i_tid, 00170 A_cap_role, 00171 &i_attr_val1, 00172 TRUE)) 00173 { 00174 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_role); 00175 return(NOT_GRANTED); 00176 } 00177 /* security officer? -> grant */ 00178 if (i_attr_val1.system_role == SR_security_officer) 00179 return(GRANTED); 00180 else 00181 return(NOT_GRANTED); 00182 00183 /* all other cases are unknown */ 00184 default: return(DO_NOT_CARE); 00185 } 00186 00187 #ifdef CONFIG_RSBAC_CAP_PROC_HIDE 00188 case R_GET_STATUS_DATA: 00189 switch(target) 00190 { 00191 case T_PROCESS: 00192 if (rsbac_get_attr(CAP, 00193 target, 00194 tid, 00195 A_cap_process_hiding, 00196 &i_attr_val1, 00197 TRUE)) 00198 { 00199 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_process_hiding); 00200 return(NOT_GRANTED); /* something weird happened */ 00201 } 00202 switch(i_attr_val1.cap_process_hiding) 00203 { 00204 case PH_full: 00205 if(current->pid == tid.process) 00206 return GRANTED; 00207 else 00208 /* Security Officer or Admin? */ 00209 i_tid.user = owner; 00210 if (rsbac_get_attr(CAP, 00211 T_USER, 00212 i_tid, 00213 A_cap_role, 00214 &i_attr_val1, 00215 TRUE)) 00216 { 00217 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_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 case PH_from_other_users: 00226 { 00227 struct task_struct * task_p; 00228 enum rsbac_adf_req_ret_t result; 00229 00230 read_lock(&tasklist_lock); 00231 task_p = find_task_by_pid(tid.process); 00232 if( task_p 00233 && (task_p->uid != owner) 00234 ) 00235 result = NOT_GRANTED; 00236 else 00237 result = GRANTED; 00238 read_unlock(&tasklist_lock); 00239 if(result == GRANTED) 00240 return GRANTED; 00241 /* Security Officer or Admin? */ 00242 i_tid.user = owner; 00243 if (rsbac_get_attr(CAP, 00244 T_USER, 00245 i_tid, 00246 A_cap_role, 00247 &i_attr_val1, 00248 TRUE)) 00249 { 00250 rsbac_ds_get_error("rsbac_adf_request_cap()", A_cap_role); 00251 return(NOT_GRANTED); 00252 } 00253 /* if sec_officer or admin, then grant */ 00254 if( (i_attr_val1.system_role == SR_security_officer) 00255 || (i_attr_val1.system_role == SR_administrator) 00256 ) 00257 return(GRANTED); 00258 else 00259 return(NOT_GRANTED); 00260 } 00261 default: 00262 return DO_NOT_CARE; 00263 } 00264 00265 default: 00266 return DO_NOT_CARE; 00267 } 00268 #endif 00269 00270 /*********************/ 00271 default: return DO_NOT_CARE; 00272 } 00273 00274 return(DO_NOT_CARE); 00275 }; /* end of rsbac_adf_request_cap() */ 00276 00277 00278 /*****************************************************************************/ 00279 /* If the request returned granted and the operation is performed, */ 00280 /* the following function can be called by the AEF to get all aci set */ 00281 /* correctly. For write accesses that are performed fully within the kernel, */ 00282 /* this is usually not done to prevent extra calls, including R_CLOSE for */ 00283 /* cleaning up. */ 00284 /* The second instance of target specification is the new target, if one has */ 00285 /* been created, otherwise its values are ignored. */ 00286 /* On success, 0 is returned, and an error from rsbac/error.h otherwise. */ 00287 00288 int rsbac_adf_set_attr_cap( 00289 enum rsbac_adf_request_t request, 00290 rsbac_pid_t caller_pid, 00291 enum rsbac_target_t target, 00292 union rsbac_target_id_t tid, 00293 enum rsbac_target_t new_target, 00294 union rsbac_target_id_t new_tid, 00295 enum rsbac_attribute_t attr, 00296 union rsbac_attribute_value_t attr_val, 00297 rsbac_uid_t owner) 00298 { 00299 union rsbac_target_id_t i_tid; 00300 union rsbac_attribute_value_t i_attr_val1; 00301 00302 switch (request) 00303 { 00304 case R_CHANGE_OWNER: 00305 switch(target) 00306 { 00307 case T_PROCESS: 00308 if(attr != A_owner) 00309 return(-RSBAC_EINVALIDATTR); 00310 /* Adjust Linux caps */ 00311 i_tid.user = attr_val.owner; 00312 #ifdef CONFIG_RSBAC_SOFTMODE 00313 if(!rsbac_softmode) 00314 #endif 00315 { 00316 if (rsbac_get_attr(CAP, 00317 T_USER, 00318 i_tid, 00319 A_max_caps, 00320 &i_attr_val1, 00321 FALSE)) 00322 { 00323 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_max_caps); 00324 } 00325 else 00326 { 00327 extern spinlock_t task_capability_lock; 00328 00329 /* set caps for process */ 00330 spin_lock(&task_capability_lock); 00331 current->cap_permitted &= i_attr_val1.max_caps; 00332 current->cap_effective &= i_attr_val1.max_caps; 00333 current->cap_inheritable &= i_attr_val1.max_caps; 00334 spin_unlock(&task_capability_lock); 00335 } 00336 } 00337 if (rsbac_get_attr(CAP, 00338 T_USER, 00339 i_tid, 00340 A_min_caps, 00341 &i_attr_val1, 00342 FALSE)) 00343 { 00344 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_min_caps); 00345 } 00346 else 00347 { 00348 extern spinlock_t task_capability_lock; 00349 00350 /* set caps for process */ 00351 spin_lock(&task_capability_lock); 00352 current->cap_permitted |= i_attr_val1.min_caps; 00353 current->cap_effective |= i_attr_val1.min_caps; 00354 current->cap_inheritable |= i_attr_val1.min_caps; 00355 spin_unlock(&task_capability_lock); 00356 } 00357 return 0; 00358 00359 /* all other cases are unknown */ 00360 default: 00361 return(0); 00362 } 00363 break; 00364 00365 #if defined (CONFIG_RSBAC_CAP_PROC_HIDE) 00366 case R_CLONE: 00367 switch(target) 00368 { 00369 case T_PROCESS: 00370 /* get process hiding from old process */ 00371 if (rsbac_get_attr(CAP, 00372 target, 00373 tid, 00374 A_cap_process_hiding, 00375 &i_attr_val1, 00376 FALSE)) 00377 { 00378 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_cap_process_hiding); 00379 } 00380 else 00381 { /* only set, of not default value 0 */ 00382 if(i_attr_val1.cap_process_hiding) 00383 { 00384 /* set program based log for new process */ 00385 if (rsbac_set_attr(CAP, 00386 new_target, 00387 new_tid, 00388 A_cap_process_hiding, 00389 i_attr_val1)) 00390 { 00391 rsbac_ds_set_error("rsbac_adf_set_attr_cap()", A_cap_process_hiding); 00392 } 00393 } 00394 } 00395 return 0; 00396 00397 /* all other cases are unknown */ 00398 default: 00399 return(0); 00400 } 00401 #endif /* PROC_HIDE */ 00402 00403 case R_EXECUTE: 00404 switch(target) 00405 { 00406 case T_FILE: 00407 /* Adjust Linux caps - first user, then program based */ 00408 /* User must be redone, because caps are cleared by Linux kernel */ 00409 i_tid.user = owner; 00410 #ifdef CONFIG_RSBAC_SOFTMODE 00411 if(!rsbac_softmode) 00412 #endif 00413 { 00414 if (rsbac_get_attr(CAP, 00415 T_USER, 00416 i_tid, 00417 A_max_caps, 00418 &i_attr_val1, 00419 FALSE)) 00420 { 00421 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_max_caps); 00422 } 00423 else 00424 { 00425 extern spinlock_t task_capability_lock; 00426 00427 /* set caps for process */ 00428 spin_lock(&task_capability_lock); 00429 current->cap_permitted &= i_attr_val1.max_caps; 00430 current->cap_effective &= i_attr_val1.max_caps; 00431 current->cap_inheritable &= i_attr_val1.max_caps; 00432 spin_unlock(&task_capability_lock); 00433 } 00434 } 00435 if (rsbac_get_attr(CAP, 00436 T_USER, 00437 i_tid, 00438 A_min_caps, 00439 &i_attr_val1, 00440 FALSE)) 00441 { 00442 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_min_caps); 00443 } 00444 else 00445 { 00446 extern spinlock_t task_capability_lock; 00447 00448 /* set caps for process */ 00449 spin_lock(&task_capability_lock); 00450 current->cap_permitted |= i_attr_val1.min_caps; 00451 current->cap_effective |= i_attr_val1.min_caps; 00452 current->cap_inheritable |= i_attr_val1.min_caps; 00453 spin_unlock(&task_capability_lock); 00454 } 00455 #ifdef CONFIG_RSBAC_SOFTMODE 00456 if(!rsbac_softmode) 00457 #endif 00458 { 00459 if (rsbac_get_attr(CAP, 00460 target, 00461 tid, 00462 A_max_caps, 00463 &i_attr_val1, 00464 FALSE)) 00465 { 00466 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_max_caps); 00467 } 00468 else 00469 { 00470 extern spinlock_t task_capability_lock; 00471 00472 /* set caps for process */ 00473 spin_lock(&task_capability_lock); 00474 current->cap_permitted &= i_attr_val1.max_caps; 00475 current->cap_effective &= i_attr_val1.max_caps; 00476 current->cap_inheritable &= i_attr_val1.max_caps; 00477 spin_unlock(&task_capability_lock); 00478 } 00479 } 00480 if (rsbac_get_attr(CAP, 00481 target, 00482 tid, 00483 A_min_caps, 00484 &i_attr_val1, 00485 FALSE)) 00486 { 00487 rsbac_ds_get_error("rsbac_adf_set_attr_cap()", A_min_caps); 00488 } 00489 else 00490 { 00491 extern spinlock_t task_capability_lock; 00492 00493 /* set caps for process */ 00494 spin_lock(&task_capability_lock); 00495 current->cap_permitted |= i_attr_val1.min_caps; 00496 current->cap_effective |= i_attr_val1.min_caps; 00497 current->cap_inheritable |= i_attr_val1.min_caps; 00498 spin_unlock(&task_capability_lock); 00499 } 00500 return 0; 00501 00502 /* all other cases are unknown */ 00503 default: 00504 return(0); 00505 } 00506 break; 00507 00508 /*********************/ 00509 default: return(0); 00510 } 00511 00512 return(0); 00513 }; /* end of rsbac_adf_set_attr_cap() */ 00514 00515 /* end of rsbac/adf/cap/main.c */

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