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
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
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
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
00108
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
00141
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
00196
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
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
00296
#else
00297
target_id_name =
rsbac_kmalloc(2 *
RSBAC_MAXNAMELEN);
00298
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
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
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
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 {
00441
case A_owner:
00442
if(request ==
R_READ_ATTRIBUTE)
00443
return(
GRANTED);
00444
else
00445
return(
NOT_GRANTED);
00446
00447
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
00482
if(
rsbac_acl_check_super(target,
00483 tid,
00484 owner))
00485
return(
GRANTED);
00486
else
00487
return(
NOT_GRANTED);
00488
#endif
00489
00490
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
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 };
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
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
00564
return(0);
00565 };
00566
00567