/linux-2.6.21.1-rsbac-1.3.4/rsbac/adf/mac/mac_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) - Mandatory Access Control         */
00005 /* File: rsbac/adf/mac/main.c                        */
00006 /*                                                   */
00007 /* Author and (c) 1999-2006: Amon Ott <ao@rsbac.org> */
00008 /* MAC_LIGHT Modifications (c) 2000 Stanislav Ievlev */
00009 /*                     and (c) 2001 Amon Ott         */
00010 /*                                                   */
00011 /* Last modified: 11/Dec/2006                        */
00012 /*************************************************** */
00013 
00014 #include <linux/string.h>
00015 #include <rsbac/aci.h>
00016 #include <rsbac/mac.h>
00017 #include <rsbac/adf_main.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/helpers.h>
00020 #include <rsbac/getname.h>
00021 #include <rsbac/debug.h>
00022 #include <rsbac/rkmem.h>
00023 
00024 /************************************************* */
00025 /*           Global Variables                      */
00026 /************************************************* */
00027 
00028 /************************************************* */
00029 /*          Internal Help functions                */
00030 /************************************************* */
00031 
00032 static enum rsbac_adf_req_ret_t
00033 mac_check_role(rsbac_uid_t owner,
00034                 enum rsbac_system_role_t role)
00035 {
00036         union rsbac_target_id_t i_tid;
00037         union rsbac_attribute_value_t i_attr_val1;
00038 
00039         i_tid.user = owner;
00040         if (rsbac_get_attr(SW_MAC,
00041                            T_USER,
00042                            i_tid, A_mac_role, &i_attr_val1, TRUE)) {
00043                 rsbac_ds_get_error("mac_check_role", A_mac_role);
00044                 return (NOT_GRANTED);
00045         }
00046         /* if correct role, then grant */
00047         if (i_attr_val1.system_role == role)
00048                 return (GRANTED);
00049         else {
00050                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: wrong mac_role %u -> NOT_GRANTED!\n",
00051                                current->pid, current->comm,
00052                                i_attr_val1.system_role);
00053                 return (NOT_GRANTED);
00054         }
00055 }
00056 
00057 /* auto_write() */
00058 /* This function builds a decision for write-only access based on      */
00059 /* ss-property and *-property. The Subject is given by process-id pid, */
00060 /* its attributes are taken from the data structures module. */
00061 /* For the object, only security_level is given to become independent  */
00062 /* from different object/target types.                                 */
00063 /* If attribute mac_auto is set, the current_security_level is changed */
00064 /* within min_write and max_read boundaries to allow for more accesses.*/
00065 /* If set_level is TRUE, the current_security_level and read/write     */
00066 /* boundaries are set to appropiate values, otherwise they are only    */
00067 /* checked. This provides only one function for decision and attribute */
00068 /* setting.                                                            */
00069 /* Trusted processes (attr. mac_trusted set) are always granted write  */
00070 /* access.                                                             */
00071 
00072 static enum rsbac_adf_req_ret_t
00073 auto_write_attr(rsbac_pid_t pid,
00074                 enum rsbac_target_t target,
00075                 union rsbac_target_id_t tid,
00076                 enum rsbac_attribute_t t_level_attr,
00077                 enum rsbac_attribute_t t_cat_attr,
00078                 rsbac_boolean_t set_level)
00079 {
00080         rsbac_security_level_t curr_level;
00081         rsbac_mac_category_vector_t curr_categories;
00082         rsbac_security_level_t target_sec_level;
00083         rsbac_mac_category_vector_t target_categories;
00084         union rsbac_target_id_t i_tid;
00085         union rsbac_attribute_value_t attr_val1;
00086         union rsbac_attribute_value_t attr_val2;
00087         rsbac_mac_process_flags_t flags;
00088         rsbac_boolean_t mac_auto_used_level = FALSE;
00089         rsbac_boolean_t mac_auto_used_cat = FALSE;
00090         rsbac_boolean_t raise_object_level = FALSE;
00091         rsbac_boolean_t raise_object_cat = FALSE;
00092 
00093         /* first check for mac_override, which allows everything */
00094         i_tid.process = pid;
00095         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_process_flags, &attr_val1, FALSE)) { /* failed! */
00096                 rsbac_ds_get_error("mac_auto_write", A_none);
00097                 return (NOT_GRANTED);
00098         }
00099         flags = attr_val1.mac_process_flags;
00100         if (flags & MAC_override)
00101                 return GRANTED;
00102 
00103         /* Get current security level */
00104         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, &attr_val1, FALSE)) { /* failed! */
00105                 rsbac_ds_get_error("mac_auto_write", A_none);
00106                 return (NOT_GRANTED);
00107         }
00108         curr_level = attr_val1.security_level;
00109         /* Get current categories */
00110         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, &attr_val1, FALSE)) {       /* failed! */
00111                 rsbac_ds_get_error("mac_auto_write", A_none);
00112                 return (NOT_GRANTED);
00113         }
00114         curr_categories = attr_val1.mac_categories;
00115         /* Get target security level */
00116         if (rsbac_get_attr(SW_MAC, target, tid, t_level_attr, &attr_val1, TRUE)) {      /* failed! */
00117                 rsbac_ds_get_error("mac_auto_write", A_none);
00118                 return (NOT_GRANTED);
00119         }
00120         target_sec_level = attr_val1.security_level;
00121         /* Get target categories */
00122         if (rsbac_get_attr(SW_MAC, target, tid, t_cat_attr, &attr_val1, TRUE)) {        /* failed! */
00123                 rsbac_ds_get_error("mac_auto_write", A_none);
00124                 return (NOT_GRANTED);
00125         }
00126         target_categories = attr_val1.mac_categories;
00127 
00128         if (target_sec_level > curr_level) {
00129                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_security_level, &attr_val1, FALSE)) {    /* failed! */
00130                         rsbac_ds_get_error("mac_auto_write", A_none);
00131                         return (NOT_GRANTED);
00132                 }
00133                 if (attr_val1.security_level < target_sec_level) {
00134                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: security_level %u under target_sec_level %u, no override -> NOT_GRANTED!\n",
00135                                        current->pid, current->comm,
00136                                        attr_val1.security_level,
00137                                        target_sec_level);
00138                         return (NOT_GRANTED);
00139                 }
00140                 /* curr_level < target_level <= max_level -> need mac_auto,
00141                  * write_up, trusted (at process)
00142                  * or shared (at object) */
00143                 if (flags & MAC_auto)
00144                         mac_auto_used_level = TRUE;
00145                 else {
00146                         if (!(flags & MAC_write_up)
00147                             && !(flags & MAC_trusted)
00148                             ) {
00149                                 /* Try mac_file_flags on the target,
00150                                  * if FD object */
00151                                 switch (target) {
00152                                 case T_FILE:
00153                                 case T_DIR:
00154                                 case T_FIFO:
00155                                 case T_SYMLINK:
00156                                 case T_UNIXSOCK:
00157                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00158                                                 rsbac_ds_get_error
00159                                                     ("mac_auto_write",
00160                                                      A_none);
00161                                                 return (NOT_GRANTED);
00162                                         }
00163                                         if ((attr_val1.
00164                                              mac_file_flags & MAC_write_up)
00165                                             || (attr_val1.
00166                                                 mac_file_flags &
00167                                                 MAC_trusted)
00168                                             ) {
00169                                                 break;
00170                                         }
00171                                         /* fall through */
00172 
00173                                 default:
00174                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: current security_level %u under target_sec_level %u, no auto, write_up, trusted -> NOT_GRANTED!\n",
00175                                                        current->pid,
00176                                                        current->comm,
00177                                                        curr_level,
00178                                                        target_sec_level);
00179                                         return (NOT_GRANTED);
00180                                 }
00181                         }
00182                 }
00183         } else if (target_sec_level < curr_level) {
00184                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_security_level, &attr_val1, FALSE)) {        /* failed! */
00185                         rsbac_ds_get_error("mac_auto_write", A_none);
00186                         return (NOT_GRANTED);
00187                 }
00188                 if (attr_val1.security_level > target_sec_level) {
00189                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_security_level %u over target_sec_level %u, no override -> NOT_GRANTED!\n",
00190                                        current->pid,
00191                                        current->comm, attr_val1.security_level,
00192                                        target_sec_level);
00193                         return (NOT_GRANTED);
00194                 }
00195                 /* min_level <= target_level < curr_level -> need mac_auto,
00196                  * write_down or trusted */
00197                 if (flags & MAC_auto) {
00198                         /* check max_read boundary */
00199                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, &attr_val1, FALSE)) {     /* failed! */
00200                                 rsbac_ds_get_error("mac_auto_write",
00201                                                    A_none);
00202                                 return (NOT_GRANTED);
00203                         }
00204                         if (attr_val1.security_level > target_sec_level) {
00205                                 if (!(flags & MAC_write_down)
00206                                     && !(flags & MAC_trusted)
00207                                     ) {
00208                                         /* Try mac_file_flags on the target,
00209                                          * if FD object */
00210                                         switch (target) {
00211                                         case T_FILE:
00212                                         case T_DIR:
00213                                         case T_FIFO:
00214                                         case T_SYMLINK:
00215                                         case T_UNIXSOCK:
00216                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00217                                                         rsbac_ds_get_error
00218                                                             ("mac_auto_write",
00219                                                              A_none);
00220                                                         return
00221                                                             (NOT_GRANTED);
00222                                                 }
00223                                                 if ((attr_val1.
00224                                                      mac_file_flags &
00225                                                      MAC_write_down)
00226                                                     || (attr_val1.
00227                                                         mac_file_flags &
00228                                                         MAC_trusted)
00229                                                     ) {
00230                                                         if (attr_val1.
00231                                                             mac_file_flags
00232                                                             & MAC_auto) {
00233                                                                 raise_object_level
00234                                                                     = TRUE;
00235                                                         }
00236                                                         break;
00237                                                 }
00238                                                 /* fall through */
00239 
00240                                         default:
00241                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_read_open %u over target_sec_level %u, no write_down or trusted -> NOT_GRANTED!\n",
00242                                                              current->pid,
00243                                                              current->comm,
00244                                                              attr_val1.
00245                                                              security_level,
00246                                                              target_sec_level);
00247                                                 return (NOT_GRANTED);
00248                                         }
00249                                 }
00250                         } else
00251                                 mac_auto_used_level = TRUE;
00252                 } else {
00253                         if (!(flags & MAC_write_down)
00254                             && !(flags & MAC_trusted)
00255                             ) {
00256                                 /* Try mac_file_flags on the target,
00257                                  * if FD object */
00258                                 switch (target) {
00259                                 case T_FILE:
00260                                 case T_DIR:
00261                                 case T_FIFO:
00262                                 case T_SYMLINK:
00263                                 case T_UNIXSOCK:
00264                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00265                                                 rsbac_ds_get_error
00266                                                     ("mac_auto_write",
00267                                                      A_none);
00268                                                 return (NOT_GRANTED);
00269                                         }
00270                                         if ((attr_val1.
00271                                              mac_file_flags &
00272                                              MAC_write_down)
00273                                             || (attr_val1.
00274                                                 mac_file_flags &
00275                                                 MAC_trusted)
00276                                             ) {
00277                                                 if (attr_val1.
00278                                                     mac_file_flags &
00279                                                     MAC_auto) {
00280                                                         raise_object_level
00281                                                             = TRUE;
00282                                                 }
00283                                                 break;
00284                                         }
00285                                         /* fall through */
00286 
00287                                 default:
00288                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: current security_level %u over target_sec_level %u, no auto, write_down or trusted -> NOT_GRANTED!\n",
00289                                                        current->pid,
00290                                                        current->comm,
00291                                                        curr_level,
00292                                                        target_sec_level);
00293                                         return (NOT_GRANTED);
00294                                 }
00295                         }
00296                 }
00297         }
00298 
00299         if ((target_categories & curr_categories) != target_categories) {
00300                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_categories, &attr_val1, FALSE)) {    /* failed! */
00301                         rsbac_ds_get_error("mac_auto_write", A_none);
00302                         return (NOT_GRANTED);
00303                 }
00304                 if ((target_categories & attr_val1.mac_categories) !=
00305                     target_categories) {
00306 #ifdef CONFIG_RSBAC_DEBUG
00307                         if (rsbac_debug_adf_mac) {
00308                                 char *tmp =
00309                                     rsbac_kmalloc(RSBAC_MAXNAMELEN);
00310 
00311                                 if (tmp) {
00312                                         char *tmp2 =
00313                                             rsbac_kmalloc
00314                                             (RSBAC_MAXNAMELEN);
00315 
00316                                         if (tmp2) {
00317                                                 u64tostrmac(tmp,
00318                                                             attr_val1.
00319                                                             mac_categories);
00320                                                 u64tostrmac(tmp2,
00321                                                             target_categories);
00322                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_categories %s under target categories %s, no override -> NOT_GRANTED!\n",
00323                                                              current->pid,
00324                                                              current->comm,
00325                                                              tmp, tmp2);
00326                                                 rsbac_kfree(tmp2);
00327                                         }
00328                                         rsbac_kfree(tmp);
00329                                 }
00330                         }
00331 #endif
00332                         return (NOT_GRANTED);
00333                 }
00334                 /* curr_categories < target_categories <= max_categories -> need mac_auto,
00335                  * write_up or trusted */
00336                 if (flags & MAC_auto)
00337                         mac_auto_used_cat = TRUE;
00338                 else {
00339                         if (!(flags & MAC_write_up)
00340                             && !(flags & MAC_trusted)
00341                             ) {
00342                                 /* Try mac_file_flags on the target,
00343                                  * if FD object */
00344                                 switch (target) {
00345                                 case T_FILE:
00346                                 case T_DIR:
00347                                 case T_FIFO:
00348                                 case T_SYMLINK:
00349                                 case T_UNIXSOCK:
00350                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00351                                                 rsbac_ds_get_error
00352                                                     ("mac_auto_write",
00353                                                      A_none);
00354                                                 return (NOT_GRANTED);
00355                                         }
00356                                         if ((attr_val1.
00357                                              mac_file_flags & MAC_write_up)
00358                                             || (attr_val1.
00359                                                 mac_file_flags &
00360                                                 MAC_trusted)
00361                                             )
00362                                                 break;
00363                                         /* fall through */
00364 
00365                                 default:
00366 #ifdef CONFIG_RSBAC_DEBUG
00367                                         if (rsbac_debug_adf_mac) {
00368                                                 char *tmp =
00369                                                     rsbac_kmalloc
00370                                                     (RSBAC_MAXNAMELEN);
00371 
00372                                                 if (tmp) {
00373                                                         char *tmp2 =
00374                                                             rsbac_kmalloc
00375                                                             (RSBAC_MAXNAMELEN);
00376 
00377                                                         if (tmp2) {
00378                                                                 u64tostrmac
00379                                                                     (tmp,
00380                                                                      curr_categories);
00381                                                                 u64tostrmac
00382                                                                     (tmp2,
00383                                                                      target_categories);
00384                                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: curr_categories %s under target categories %s, no auto, write_up or trusted -> NOT_GRANTED!\n",
00385                                                                      current->
00386                                                                      pid,
00387                                                                      current->
00388                                                                      comm,
00389                                                                      tmp,
00390                                                                      tmp2);
00391                                                                 rsbac_kfree
00392                                                                     (tmp2);
00393                                                         }
00394                                                         rsbac_kfree(tmp);
00395                                                 }
00396                                         }
00397 #endif
00398                                         return (NOT_GRANTED);
00399                                 }
00400                         }
00401                 }
00402         } else
00403             if ((target_categories & curr_categories) != curr_categories) {
00404                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_min_categories, &attr_val1, FALSE)) {        /* failed! */
00405                         rsbac_ds_get_error("mac_auto_write", A_none);
00406                         return (NOT_GRANTED);
00407                 }
00408                 if ((target_categories & attr_val1.mac_categories) !=
00409                     attr_val1.mac_categories) {
00410 #ifdef CONFIG_RSBAC_DEBUG
00411                         if (rsbac_debug_adf_mac) {
00412                                 char *tmp =
00413                                     rsbac_kmalloc(RSBAC_MAXNAMELEN);
00414 
00415                                 if (tmp) {
00416                                         char *tmp2 =
00417                                             rsbac_kmalloc
00418                                             (RSBAC_MAXNAMELEN);
00419 
00420                                         if (tmp2) {
00421                                                 u64tostrmac(tmp,
00422                                                             attr_val1.
00423                                                             mac_categories);
00424                                                 u64tostrmac(tmp2,
00425                                                             target_categories);
00426                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_categories %s over target categories %s, no override -> NOT_GRANTED!\n",
00427                                                              current->pid,
00428                                                              current->comm,
00429                                                              tmp, tmp2);
00430                                                 rsbac_kfree(tmp2);
00431                                         }
00432                                         rsbac_kfree(tmp);
00433                                 }
00434                         }
00435 #endif
00436                         return (NOT_GRANTED);
00437                 }
00438                 /* min_level <= target_level < curr_level -> need mac_auto,
00439                  * write_down or trusted */
00440                 if (flags & MAC_auto) {
00441                         /* check max_read boundary */
00442                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, &attr_val1, FALSE)) {       /* failed! */
00443                                 rsbac_ds_get_error("mac_auto_write",
00444                                                    A_none);
00445                                 return (NOT_GRANTED);
00446                         }
00447                         if ((target_categories & attr_val1.
00448                              mac_categories) != attr_val1.mac_categories) {
00449                                 if (!(flags & MAC_write_down)
00450                                     && !(flags & MAC_trusted)
00451                                     ) {
00452                                         /* Try mac_file_flags on the target,
00453                                          * if FD object */
00454                                         switch (target) {
00455                                         case T_FILE:
00456                                         case T_DIR:
00457                                         case T_FIFO:
00458                                         case T_SYMLINK:
00459                                         case T_UNIXSOCK:
00460                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00461                                                         rsbac_ds_get_error
00462                                                             ("mac_auto_write",
00463                                                              A_none);
00464                                                         return
00465                                                             (NOT_GRANTED);
00466                                                 }
00467                                                 if ((attr_val1.
00468                                                      mac_file_flags &
00469                                                      MAC_write_down)
00470                                                     || (attr_val1.
00471                                                         mac_file_flags &
00472                                                         MAC_trusted)
00473                                                     ) {
00474                                                         if (attr_val1.
00475                                                             mac_file_flags
00476                                                             & MAC_auto) {
00477                                                                 raise_object_cat
00478                                                                     = TRUE;
00479                                                         }
00480                                                         break;
00481                                                 }
00482                                                 /* fall through */
00483 
00484                                         default:
00485 #ifdef CONFIG_RSBAC_DEBUG
00486                                                 if (rsbac_debug_adf_mac) {
00487                                                         char *tmp =
00488                                                             rsbac_kmalloc
00489                                                             (RSBAC_MAXNAMELEN);
00490 
00491                                                         if (tmp) {
00492                                                                 char *tmp2
00493                                                                     =
00494                                                                     rsbac_kmalloc
00495                                                                     (RSBAC_MAXNAMELEN);
00496 
00497                                                                 if (tmp2) {
00498                                                                         u64tostrmac
00499                                                                             (tmp,
00500                                                                              attr_val1.
00501                                                                              mac_categories);
00502                                                                         u64tostrmac
00503                                                                             (tmp2,
00504                                                                              target_categories);
00505                                                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_read_categories %s over target categories %s, no write_down or trusted -> NOT_GRANTED!\n",
00506                                                                              current->
00507                                                                              pid,
00508                                                                              current->
00509                                                                              comm,
00510                                                                              tmp,
00511                                                                              tmp2);
00512                                                                         rsbac_kfree
00513                                                                             (tmp2);
00514                                                                 }
00515                                                                 rsbac_kfree
00516                                                                     (tmp);
00517                                                         }
00518                                                 }
00519 #endif
00520                                                 return (NOT_GRANTED);
00521                                         }
00522                                 }
00523                         } else
00524                                 mac_auto_used_cat = TRUE;
00525                 } else {
00526                         if (!(flags & MAC_write_down)
00527                             && !(flags & MAC_trusted)
00528                             ) {
00529                                 /* Try mac_file_flags on the target, if FD object */
00530                                 switch (target) {
00531                                 case T_FILE:
00532                                 case T_DIR:
00533                                 case T_FIFO:
00534                                 case T_SYMLINK:
00535                                 case T_UNIXSOCK:
00536                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00537                                                 rsbac_ds_get_error
00538                                                     ("mac_auto_write",
00539                                                      A_none);
00540                                                 return (NOT_GRANTED);
00541                                         }
00542                                         if ((attr_val1.
00543                                              mac_file_flags &
00544                                              MAC_write_down)
00545                                             || (attr_val1.
00546                                                 mac_file_flags &
00547                                                 MAC_trusted)
00548                                             ) {
00549                                                 if (attr_val1.
00550                                                     mac_file_flags &
00551                                                     MAC_auto) {
00552                                                         raise_object_cat =
00553                                                             TRUE;
00554                                                 }
00555                                                 break;
00556                                         }
00557                                         /* fall through */
00558 
00559                                 default:
00560 #ifdef CONFIG_RSBAC_DEBUG
00561                                         if (rsbac_debug_adf_mac) {
00562                                                 char *tmp =
00563                                                     rsbac_kmalloc
00564                                                     (RSBAC_MAXNAMELEN);
00565 
00566                                                 if (tmp) {
00567                                                         char *tmp2 =
00568                                                             rsbac_kmalloc
00569                                                             (RSBAC_MAXNAMELEN);
00570 
00571                                                         if (tmp2) {
00572                                                                 u64tostrmac
00573                                                                     (tmp,
00574                                                                      curr_categories);
00575                                                                 u64tostrmac
00576                                                                     (tmp2,
00577                                                                      target_categories);
00578                                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: curr_categories %s over target categories %s, no auto, write_down or trusted -> NOT_GRANTED!\n",
00579                                                                      current->
00580                                                                      pid,
00581                                                                      current->
00582                                                                      comm,
00583                                                                      tmp,
00584                                                                      tmp2);
00585                                                                 rsbac_kfree
00586                                                                     (tmp2);
00587                                                         }
00588                                                         rsbac_kfree(tmp);
00589                                                 }
00590                                         }
00591 #endif
00592                                         return (NOT_GRANTED);
00593                                 }
00594                         }
00595                 }
00596         }
00597 
00598         /* grant area */
00599 
00600         /* adjust current_sec_level and min_write_level, */
00601         /* if set_level is true and mac_auto has been used */
00602         if (set_level && (mac_auto_used_level || raise_object_level)
00603             ) {
00604 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
00605                 {
00606                         char *target_type_name;
00607                         char *target_id_name;
00608 
00609                         target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00610                         if (target_type_name) {
00611 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00612                                 target_id_name
00613                                     =
00614                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
00615                                                   + RSBAC_MAXNAMELEN);
00616                                 /* max. path name len + some extra */
00617 #else
00618                                 target_id_name =
00619                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00620                                 /* max. file name len + some extra */
00621 #endif
00622                                 if (target_id_name) {
00623                                         get_target_name(target_type_name,
00624                                                         target,
00625                                                         target_id_name,
00626                                                         tid);
00627 
00628                                         if (mac_auto_used_level) {
00629                                                 rsbac_printk(KERN_INFO "mac_auto_write(): Changing process %u (%.15s, owner %u) current level from %u to %u for %s %s\n",
00630                                                              pid,
00631                                                              current->comm,
00632                                                              current->uid,
00633                                                              curr_level,
00634                                                              target_sec_level,
00635                                                              target_type_name,
00636                                                              target_id_name);
00637                                         } else {
00638                                                 rsbac_printk(KERN_INFO "mac_auto_write(): Process %u (%.15s, owner %u): Raising object level from %u to %u for %s %s\n",
00639                                                              pid,
00640                                                              current->comm,
00641                                                              current->uid,
00642                                                              target_sec_level,
00643                                                              curr_level,
00644                                                              target_type_name,
00645                                                              target_id_name);
00646                                         }
00647                                         rsbac_kfree(target_id_name);
00648                                 }
00649                                 rsbac_kfree(target_type_name);
00650                         }
00651                 }
00652 #endif
00653                 if (mac_auto_used_level) {
00654                         i_tid.process = pid;
00655                         attr_val1.current_sec_level = target_sec_level;
00656                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, &attr_val2, TRUE)) {     /* failed! */
00657                                 rsbac_ds_get_error("mac_auto_write",
00658                                                    A_none);
00659                                 return (NOT_GRANTED);
00660                         }
00661                         if (attr_val1.min_write_open <
00662                             attr_val2.min_write_open) {
00663                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, attr_val1)) {    /* failed! */
00664                                         rsbac_ds_set_error
00665                                             ("mac_auto_write", A_none);
00666                                         return (NOT_GRANTED);
00667                                 }
00668                         }
00669                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, attr_val1)) { /* failed! */
00670                                 rsbac_ds_set_error("mac_auto_write",
00671                                                    A_none);
00672                                 return (NOT_GRANTED);
00673                         }
00674                 } else {
00675                         attr_val1.security_level = curr_level;
00676                         if (rsbac_set_attr(SW_MAC, target, tid, A_security_level, attr_val1)) { /* failed! */
00677                                 rsbac_ds_set_error("mac_auto_write",
00678                                                    A_none);
00679                                 return (NOT_GRANTED);
00680                         }
00681                 }
00682         }
00683         /* adjust current_categories and min_write_categories, */
00684         /* if set_level is true and mac_auto has been used */
00685         if (set_level && (mac_auto_used_cat || raise_object_cat)
00686             ) {
00687 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
00688                 {
00689                         char *target_type_name =
00690                             rsbac_kmalloc(RSBAC_MAXNAMELEN);
00691                         if (target_type_name) {
00692                                 char *target_id_name;
00693 
00694 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00695                                 target_id_name
00696                                     =
00697                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
00698                                                   + RSBAC_MAXNAMELEN);
00699                                 /* max. path name len + some extra */
00700 #else
00701                                 target_id_name =
00702                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00703                                 /* max. file name len + some extra */
00704 #endif
00705                                 if (target_id_name) {
00706                                         char *tmp1 =
00707                                             rsbac_kmalloc
00708                                             (RSBAC_MAXNAMELEN);
00709                                         if (tmp1) {
00710                                                 char *tmp2 =
00711                                                     rsbac_kmalloc
00712                                                     (RSBAC_MAXNAMELEN);
00713                                                 if (tmp2) {
00714                                                         get_target_name
00715                                                             (target_type_name,
00716                                                              target,
00717                                                              target_id_name,
00718                                                              tid);
00719 
00720                                                         if (mac_auto_used_cat) {
00721                                                                 rsbac_printk
00722                                                                     (KERN_INFO "mac_auto_write(): Changing process %u (%.15s, owner %u) current categories from %s to %s for %s %s\n",
00723                                                                      pid,
00724                                                                      current->
00725                                                                      comm,
00726                                                                      current->
00727                                                                      uid,
00728                                                                      u64tostrmac
00729                                                                      (tmp1,
00730                                                                       curr_categories),
00731                                                                      u64tostrmac
00732                                                                      (tmp2,
00733                                                                       target_categories),
00734                                                                      target_type_name,
00735                                                                      target_id_name);
00736                                                         } else {
00737                                                                 rsbac_printk
00738                                                                     (KERN_INFO "mac_auto_write(): Process %u (%.15s, owner %u): raising current categories from %s to %s for %s %s\n",
00739                                                                      pid,
00740                                                                      current->
00741                                                                      comm,
00742                                                                      current->
00743                                                                      uid,
00744                                                                      u64tostrmac
00745                                                                      (tmp2,
00746                                                                       target_categories),
00747                                                                      u64tostrmac
00748                                                                      (tmp1,
00749                                                                       curr_categories),
00750                                                                      target_type_name,
00751                                                                      target_id_name);
00752                                                         }
00753                                                         rsbac_kfree(tmp2);
00754                                                 }
00755                                                 rsbac_kfree(tmp1);
00756                                         }
00757                                         rsbac_kfree(target_id_name);
00758                                 }
00759                                 rsbac_kfree(target_type_name);
00760                         }
00761                 }
00762 #endif
00763                 if (mac_auto_used_cat) {
00764                         i_tid.process = pid;
00765                         attr_val1.mac_categories = target_categories;
00766                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, &attr_val2, TRUE)) {       /* failed! */
00767                                 rsbac_ds_get_error("mac_auto_write",
00768                                                    A_none);
00769                                 return (NOT_GRANTED);
00770                         }
00771                         if ((attr_val1.mac_categories & attr_val2.
00772                              mac_categories)
00773                             != attr_val2.mac_categories) {
00774                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, attr_val1)) {      /* failed! */
00775                                         rsbac_ds_set_error
00776                                             ("mac_auto_write", A_none);
00777                                         return (NOT_GRANTED);
00778                                 }
00779                         }
00780                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, attr_val1)) {       /* failed! */
00781                                 rsbac_ds_set_error("mac_auto_write",
00782                                                    A_none);
00783                                 return (NOT_GRANTED);
00784                         }
00785                 } else {
00786                         attr_val1.mac_categories = curr_categories;
00787                         if (rsbac_set_attr(SW_MAC, target, tid, A_mac_categories, attr_val1)) { /* failed! */
00788                                 rsbac_ds_set_error("mac_auto_write",
00789                                                    A_none);
00790                                 return (NOT_GRANTED);
00791                         }
00792                 }
00793         }
00794 
00795         /* Everything done, so return */
00796         return (GRANTED);
00797 }
00798 
00799 static enum rsbac_adf_req_ret_t
00800 auto_write(rsbac_pid_t pid,
00801            enum rsbac_target_t target,
00802            union rsbac_target_id_t tid, rsbac_boolean_t set_level)
00803 {
00804         return auto_write_attr(pid,
00805                                target,
00806                                tid,
00807                                A_security_level,
00808                                A_mac_categories, set_level);
00809 }
00810 
00811 /* auto_read() */
00812 /* This function works similar to auto_write() */
00813 
00814 static enum rsbac_adf_req_ret_t
00815 auto_read_attr(rsbac_pid_t pid,
00816                enum rsbac_target_t target,
00817                union rsbac_target_id_t tid,
00818                enum rsbac_attribute_t t_level_attr,
00819                enum rsbac_attribute_t t_cat_attr,
00820                rsbac_boolean_t set_level)
00821 {
00822         rsbac_security_level_t curr_level;
00823         rsbac_mac_category_vector_t curr_categories;
00824         rsbac_security_level_t target_sec_level;
00825         rsbac_mac_category_vector_t target_categories;
00826         union rsbac_target_id_t i_tid;
00827         union rsbac_attribute_value_t attr_val1;
00828         union rsbac_attribute_value_t attr_val2;
00829         rsbac_mac_process_flags_t flags;
00830         rsbac_boolean_t mac_auto_used_level = FALSE;
00831         rsbac_boolean_t mac_auto_used_cat = FALSE;
00832         rsbac_boolean_t set_level_level = FALSE;
00833         rsbac_boolean_t set_level_cat = FALSE;
00834 
00835         /* first check for mac_override, which allows everything */
00836         i_tid.process = pid;
00837         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_process_flags, &attr_val1, FALSE)) { /* failed! */
00838                 rsbac_ds_get_error("mac_auto_read", A_none);
00839                 return (NOT_GRANTED);
00840         }
00841         flags = attr_val1.mac_process_flags;
00842         if (flags & MAC_override)
00843                 return GRANTED;
00844 
00845         /* Get current security level */
00846         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, &attr_val1, FALSE)) { /* failed! */
00847                 rsbac_ds_get_error("mac_auto_read", A_none);
00848                 return (NOT_GRANTED);
00849         }
00850         curr_level = attr_val1.security_level;
00851         /* Get current categories */
00852         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, &attr_val1, FALSE)) {       /* failed! */
00853                 rsbac_ds_get_error("mac_auto_read", A_none);
00854                 return (NOT_GRANTED);
00855         }
00856         curr_categories = attr_val1.mac_categories;
00857         /* Get target security level */
00858         if (rsbac_get_attr(SW_MAC, target, tid, t_level_attr, &attr_val1, TRUE)) {      /* failed! */
00859                 rsbac_ds_get_error("mac_auto_read", A_none);
00860                 return (NOT_GRANTED);
00861         }
00862         target_sec_level = attr_val1.security_level;
00863         /* Get target categories */
00864         if (rsbac_get_attr(SW_MAC, target, tid, t_cat_attr, &attr_val1, TRUE)) {        /* failed! */
00865                 rsbac_ds_get_error("mac_auto_read", A_none);
00866                 return (NOT_GRANTED);
00867         }
00868         target_categories = attr_val1.mac_categories;
00869 
00870         if (target_sec_level > curr_level) {
00871                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_security_level, &attr_val1, FALSE)) {    /* failed! */
00872                         rsbac_ds_get_error("mac_auto_read", A_none);
00873                         return (NOT_GRANTED);
00874                 }
00875                 if (attr_val1.security_level < target_sec_level) {
00876                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: security_level %u under target_sec_level %u, no override -> NOT_GRANTED!\n",
00877                                        current->pid, current->comm,
00878                                        attr_val1.security_level,
00879                                        target_sec_level);
00880                         return (NOT_GRANTED);
00881                 }
00882                 /* curr_level < target_level <= max_level -> need mac_auto, read_up or trusted (with read option) */
00883                 if (flags & MAC_auto) {
00884                         /* check min_write boundary */
00885                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, &attr_val1, FALSE)) {    /* failed! */
00886                                 rsbac_ds_get_error("mac_auto_read",
00887                                                    A_none);
00888                                 return (NOT_GRANTED);
00889                         }
00890                         if (attr_val1.security_level < target_sec_level) {
00891                                 if (!(flags & MAC_read_up)
00892 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
00893                                     && !(flags & MAC_trusted)
00894 #endif
00895                                     ) {
00896                                         /* Try mac_file_flags on the target, if FD object */
00897                                         switch (target) {
00898                                         case T_FILE:
00899                                         case T_DIR:
00900                                         case T_FIFO:
00901                                         case T_SYMLINK:
00902                                         case T_UNIXSOCK:
00903                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00904                                                         rsbac_ds_get_error
00905                                                             ("mac_auto_read",
00906                                                              A_none);
00907                                                         return
00908                                                             (NOT_GRANTED);
00909                                                 }
00910                                                 if ((attr_val1.
00911                                                      mac_file_flags &
00912                                                      MAC_read_up)
00913 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
00914                                                     || (attr_val1.
00915                                                         mac_file_flags &
00916                                                         MAC_trusted)
00917 #endif
00918                                                     ) {
00919                                                         break;
00920                                                 }
00921                                                 /* fall through */
00922 
00923                                         default:
00924                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_write_open %u under target_sec_level %u, no read_up or trusted -> NOT_GRANTED!\n",
00925                                                              current->pid,
00926                                                              current->comm,
00927                                                              attr_val1.
00928                                                              security_level,
00929                                                              target_sec_level);
00930                                                 return (NOT_GRANTED);
00931                                         }
00932                                 }
00933                         } else {
00934                                 mac_auto_used_level = TRUE;
00935                                 set_level_level = TRUE;
00936                         }
00937                 } else {
00938                         if (!(flags & MAC_read_up)
00939 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
00940                             && !(flags & MAC_trusted)
00941 #endif
00942                             ) {
00943                                 /* Try mac_file_flags on the target, if FD object */
00944                                 switch (target) {
00945                                 case T_FILE:
00946                                 case T_DIR:
00947                                 case T_FIFO:
00948                                 case T_SYMLINK:
00949                                 case T_UNIXSOCK:
00950                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
00951                                                 rsbac_ds_get_error
00952                                                     ("mac_auto_read",
00953                                                      A_none);
00954                                                 return (NOT_GRANTED);
00955                                         }
00956                                         if ((attr_val1.
00957                                              mac_file_flags & MAC_read_up)
00958 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
00959                                             || (attr_val1.
00960                                                 mac_file_flags &
00961                                                 MAC_trusted)
00962 #endif
00963                                             ) {
00964                                                 break;
00965                                         }
00966                                         /* fall through */
00967 
00968                                 default:
00969                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: current level %u under target_sec_level %u, no auto, read_up or trusted -> NOT_GRANTED!\n",
00970                                                        current->pid,
00971                                                        current->comm,
00972                                                        curr_level,
00973                                                        target_sec_level);
00974                                         return (NOT_GRANTED);
00975                                 }
00976                         }
00977                 }
00978         } else if (target_sec_level < curr_level) {
00979                 if (flags & MAC_auto) {
00980                         mac_auto_used_level = TRUE;
00981                 }
00982         }
00983         if ((target_categories & curr_categories) != target_categories) {
00984                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_categories, &attr_val1, FALSE)) {    /* failed! */
00985                         rsbac_ds_get_error("mac_auto_read", A_none);
00986                         return (NOT_GRANTED);
00987                 }
00988                 if ((target_categories & attr_val1.mac_categories) !=
00989                     target_categories) {
00990 #ifdef CONFIG_RSBAC_DEBUG
00991                         if (rsbac_debug_adf_mac) {
00992                                 char *tmp =
00993                                     rsbac_kmalloc(RSBAC_MAXNAMELEN);
00994 
00995                                 if (tmp) {
00996                                         char *tmp2 =
00997                                             rsbac_kmalloc
00998                                             (RSBAC_MAXNAMELEN);
00999 
01000                                         if (tmp2) {
01001                                                 u64tostrmac(tmp,
01002                                                             attr_val1.
01003                                                             mac_categories);
01004                                                 u64tostrmac(tmp2,
01005                                                             target_categories);
01006                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_categories %s under target categories %s, no override -> NOT_GRANTED!\n",
01007                                                              current->pid,
01008                                                              current->comm,
01009                                                              tmp, tmp2);
01010                                                 rsbac_kfree(tmp2);
01011                                         }
01012                                         rsbac_kfree(tmp);
01013                                 }
01014                         }
01015 #endif
01016                         return (NOT_GRANTED);
01017                 }
01018                 /* curr_categories < target_categories <= max_categories -> need mac_auto,
01019                  * read_up or trusted */
01020                 if (flags & MAC_auto) {
01021                         /* check min_write boundary */
01022                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, &attr_val1, FALSE)) {      /* failed! */
01023                                 rsbac_ds_get_error("mac_auto_read",
01024                                                    A_none);
01025                                 return (NOT_GRANTED);
01026                         }
01027                         if ((target_categories & attr_val1.
01028                              mac_categories) != target_categories) {
01029                                 if (!(flags & MAC_read_up)
01030 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01031                                     && !(flags & MAC_trusted)
01032 #endif
01033                                     ) {
01034                                         /* Try mac_file_flags on the target,
01035                                          * if FD object */
01036                                         switch (target) {
01037                                         case T_FILE:
01038                                         case T_DIR:
01039                                         case T_FIFO:
01040                                         case T_SYMLINK:
01041                                         case T_UNIXSOCK:
01042                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01043                                                         rsbac_ds_get_error
01044                                                             ("mac_auto_read",
01045                                                              A_none);
01046                                                         return
01047                                                             (NOT_GRANTED);
01048                                                 }
01049                                                 if ((attr_val1.
01050                                                      mac_file_flags &
01051                                                      MAC_read_up)
01052 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01053                                                     || (attr_val1.
01054                                                         mac_file_flags &
01055                                                         MAC_trusted)
01056 #endif
01057                                                     ) {
01058                                                         break;
01059                                                 }
01060                                                 /* fall through */
01061 
01062                                         default:
01063 #ifdef CONFIG_RSBAC_DEBUG
01064                                                 if (rsbac_debug_adf_mac) {
01065                                                         char *tmp =
01066                                                             rsbac_kmalloc
01067                                                             (RSBAC_MAXNAMELEN);
01068 
01069                                                         if (tmp) {
01070                                                                 char *tmp2
01071                                                                     =
01072                                                                     rsbac_kmalloc
01073                                                                     (RSBAC_MAXNAMELEN);
01074 
01075                                                                 if (tmp2) {
01076                                                                         u64tostrmac
01077                                                                             (tmp,
01078                                                                              attr_val1.
01079                                                                              mac_categories);
01080                                                                         u64tostrmac
01081                                                                             (tmp2,
01082                                                                              target_categories);
01083                                                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_write_categories %s under target categories %s, no read_up or trusted with read option -> NOT_GRANTED!\n",
01084                                                                              current->
01085                                                                              pid,
01086                                                                              current->
01087                                                                              comm,
01088                                                                              tmp,
01089                                                                              tmp2);
01090                                                                         rsbac_kfree
01091                                                                             (tmp2);
01092                                                                 }
01093                                                                 rsbac_kfree
01094                                                                     (tmp);
01095                                                         }
01096                                                 }
01097 #endif
01098                                                 return (NOT_GRANTED);
01099                                         }
01100                                 }
01101                         } else {
01102                                 mac_auto_used_cat = TRUE;
01103                                 set_level_cat = TRUE;
01104                         }
01105                 } else {
01106                         if (!(flags & MAC_read_up)
01107 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01108                             && !(flags & MAC_trusted)
01109 #endif
01110                             ) {
01111                                 /* Try mac_file_flags on the target,
01112                                  * if FD object */
01113                                 switch (target) {
01114                                 case T_FILE:
01115                                 case T_DIR:
01116                                 case T_FIFO:
01117                                 case T_SYMLINK:
01118                                 case T_UNIXSOCK:
01119                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01120                                                 rsbac_ds_get_error
01121                                                     ("mac_auto_read",
01122                                                      A_none);
01123                                                 return (NOT_GRANTED);
01124                                         }
01125                                         if ((attr_val1.
01126                                              mac_file_flags & MAC_read_up)
01127 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01128                                             || (attr_val1.
01129                                                 mac_file_flags &
01130                                                 MAC_trusted)
01131 #endif
01132                                             ) {
01133                                                 break;
01134                                         }
01135                                         /* fall through */
01136 
01137                                 default:
01138 #ifdef CONFIG_RSBAC_DEBUG
01139                                         if (rsbac_debug_adf_mac) {
01140                                                 char *tmp =
01141                                                     rsbac_kmalloc
01142                                                     (RSBAC_MAXNAMELEN);
01143 
01144                                                 if (tmp) {
01145                                                         char *tmp2 =
01146                                                             rsbac_kmalloc
01147                                                             (RSBAC_MAXNAMELEN);
01148 
01149                                                         if (tmp2) {
01150                                                                 u64tostrmac
01151                                                                     (tmp,
01152                                                                      curr_categories);
01153                                                                 u64tostrmac
01154                                                                     (tmp2,
01155                                                                      target_categories);
01156                                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: curr_categories %s under target categories %s, no auto, read_up or trusted with read option -> NOT_GRANTED!\n",
01157                                                                      current->
01158                                                                      pid,
01159                                                                      current->
01160                                                                      comm,
01161                                                                      tmp,
01162                                                                      tmp2);
01163                                                                 rsbac_kfree
01164                                                                     (tmp2);
01165                                                         }
01166                                                         rsbac_kfree(tmp);
01167                                                 }
01168                                         }
01169 #endif
01170                                         return (NOT_GRANTED);
01171                                 }
01172                         }
01173                 }
01174         } else
01175             if ((target_categories & curr_categories) != curr_categories) {
01176                 if (flags & MAC_auto) {
01177                         mac_auto_used_level = TRUE;
01178                 }
01179         }
01180 
01181         /* grant area */
01182 
01183         /* adjust current_sec_level and max_read_level, */
01184         /* if set_level is true and mac_auto has been used */
01185         if (set_level && mac_auto_used_level) {
01186                 i_tid.process = pid;
01187                 attr_val1.current_sec_level = target_sec_level;
01188                 if (set_level_level) {
01189 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
01190                         char *target_type_name;
01191                         char *target_id_name;
01192 
01193                         target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01194                         if (target_type_name) {
01195 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
01196                                 target_id_name
01197                                     =
01198                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
01199                                                   + RSBAC_MAXNAMELEN);
01200                                 /* max. path name len + some extra */
01201 #else
01202                                 target_id_name =
01203                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
01204                                 /* max. file name len + some extra */
01205 #endif
01206                                 if (target_id_name) {
01207                                         get_target_name(target_type_name,
01208                                                         target,
01209                                                         target_id_name,
01210                                                         tid);
01211 
01212                                         rsbac_printk(KERN_INFO "mac_auto_read(): Changing process %u (%.15s, owner %u) current level from %u to %u for %s %s\n",
01213                                                      pid,
01214                                                      current->comm,
01215                                                      current->uid,
01216                                                      curr_level,
01217                                                      target_sec_level,
01218                                                      target_type_name,
01219                                                      target_id_name);
01220                                         rsbac_kfree(target_id_name);
01221                                 }
01222                                 rsbac_kfree(target_type_name);
01223                         }
01224 #endif
01225                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, attr_val1)) { /* failed! */
01226                                 rsbac_ds_set_error("mac_auto_read",
01227                                                    A_none);
01228                                 return (NOT_GRANTED);
01229                         }
01230                 }
01231                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, &attr_val2, TRUE)) {      /* failed! */
01232                         rsbac_ds_get_error("mac_auto_read", A_none);
01233                         return (NOT_GRANTED);
01234                 }
01235                 if (attr_val1.max_read_open > attr_val2.max_read_open) {
01236                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, attr_val1)) {     /* failed! */
01237                                 rsbac_ds_set_error("mac_auto_read",
01238                                                    A_none);
01239                                 return (NOT_GRANTED);
01240                         }
01241                 }
01242         }
01243         /* adjust current_categories and max_read_categories, */
01244         /* if set_level is true and mac_auto has been used */
01245         if (set_level && mac_auto_used_cat) {
01246                 i_tid.process = pid;
01247                 attr_val1.mac_categories = target_categories;
01248                 if (set_level_cat) {
01249 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
01250                         char *target_type_name =
01251                             rsbac_kmalloc(RSBAC_MAXNAMELEN);
01252                         if (target_type_name) {
01253                                 char *target_id_name;
01254 
01255 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
01256                                 target_id_name
01257                                     =
01258                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
01259                                                   + RSBAC_MAXNAMELEN);
01260                                 /* max. path name len + some extra */
01261 #else
01262                                 target_id_name =
01263                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
01264                                 /* max. file name len + some extra */
01265 #endif
01266                                 if (target_id_name) {
01267                                         char *tmp1 =
01268                                             rsbac_kmalloc
01269                                             (RSBAC_MAXNAMELEN);
01270                                         if (tmp1) {
01271                                                 char *tmp2 =
01272                                                     rsbac_kmalloc
01273                                                     (RSBAC_MAXNAMELEN);
01274                                                 if (tmp2) {
01275                                                         get_target_name
01276                                                             (target_type_name,
01277                                                              target,
01278                                                              target_id_name,
01279                                                              tid);
01280 
01281                                                         rsbac_printk
01282                                                             (KERN_INFO "mac_auto_read(): Changing process %u (15%s, owner %u) current categories from %s to %s for %s %s\n",
01283                                                              pid,
01284                                                              current->comm,
01285                                                              current->uid,
01286                                                              u64tostrmac
01287                                                              (tmp1,
01288                                                               curr_categories),
01289                                                              u64tostrmac
01290                                                              (tmp2,
01291                                                               target_categories),
01292                                                              target_type_name,
01293                                                              target_id_name);
01294                                                         rsbac_kfree(tmp2);
01295                                                 }
01296                                                 rsbac_kfree(tmp1);
01297                                         }
01298                                         rsbac_kfree(target_id_name);
01299                                 }
01300                                 rsbac_kfree(target_type_name);
01301                         }
01302 #endif
01303                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, attr_val1)) {       /* failed! */
01304                                 rsbac_ds_set_error("mac_auto_read",
01305                                                    A_none);
01306                                 return (NOT_GRANTED);
01307                         }
01308                 }
01309                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, &attr_val2, TRUE)) {        /* failed! */
01310                         rsbac_ds_get_error("mac_auto_read", A_none);
01311                         return (NOT_GRANTED);
01312                 }
01313                 if ((attr_val1.mac_categories & attr_val2.mac_categories)
01314                     != attr_val1.mac_categories) {
01315                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, attr_val1)) {       /* failed! */
01316                                 rsbac_ds_set_error("mac_auto_read",
01317                                                    A_none);
01318                                 return (NOT_GRANTED);
01319                         }
01320                 }
01321         }
01322 
01323         /* Everything done, so return */
01324         return (GRANTED);
01325 }
01326 
01327 static enum rsbac_adf_req_ret_t
01328 auto_read(rsbac_pid_t pid,
01329           enum rsbac_target_t target,
01330           union rsbac_target_id_t tid, rsbac_boolean_t set_level)
01331 {
01332         return auto_read_attr(pid,
01333                               target,
01334                               tid,
01335                               A_security_level,
01336                               A_mac_categories, set_level);
01337 }
01338 
01339 
01340 /* auto-read-write() */
01341 /* combines auto-read and auto-write */
01342 
01343 static enum rsbac_adf_req_ret_t
01344 auto_read_write_attr(rsbac_pid_t pid,
01345                      enum rsbac_target_t target,
01346                      union rsbac_target_id_t tid,
01347                      enum rsbac_attribute_t t_level_attr,
01348                      enum rsbac_attribute_t t_cat_attr,
01349                      rsbac_boolean_t set_level)
01350 {
01351         rsbac_security_level_t curr_level;
01352         rsbac_mac_category_vector_t curr_categories;
01353         rsbac_security_level_t target_sec_level;
01354         rsbac_mac_category_vector_t target_categories;
01355         union rsbac_target_id_t i_tid;
01356         union rsbac_attribute_value_t attr_val1;
01357         union rsbac_attribute_value_t attr_val2;
01358         rsbac_mac_process_flags_t flags;
01359         rsbac_boolean_t mac_auto_used_level = FALSE;
01360         rsbac_boolean_t mac_auto_used_cat = FALSE;
01361         rsbac_boolean_t raise_object_level = FALSE;
01362         rsbac_boolean_t raise_object_cat = FALSE;
01363 
01364         /* first check for mac_override, which allows everything */
01365         i_tid.process = pid;
01366         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_process_flags, &attr_val1, FALSE)) { /* failed! */
01367                 rsbac_ds_get_error("mac_auto_read_write", A_none);
01368                 return (NOT_GRANTED);
01369         }
01370         flags = attr_val1.mac_process_flags;
01371         if (flags & MAC_override)
01372                 return GRANTED;
01373 
01374         /* Get current security level */
01375         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, &attr_val1, FALSE)) { /* failed! */
01376                 rsbac_ds_get_error("mac_auto_read_write", A_none);
01377                 return (NOT_GRANTED);
01378         }
01379         curr_level = attr_val1.security_level;
01380         /* Get current categories */
01381         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, &attr_val1, FALSE)) {       /* failed! */
01382                 rsbac_ds_get_error("mac_auto_read_write", A_none);
01383                 return (NOT_GRANTED);
01384         }
01385         curr_categories = attr_val1.mac_categories;
01386         /* Get target security level */
01387         if (rsbac_get_attr(SW_MAC, target, tid, t_level_attr, &attr_val1, TRUE)) {      /* failed! */
01388                 rsbac_ds_get_error("mac_auto_read_write", A_none);
01389                 return (NOT_GRANTED);
01390         }
01391         target_sec_level = attr_val1.security_level;
01392         /* Get target categories */
01393         if (rsbac_get_attr(SW_MAC, target, tid, t_cat_attr, &attr_val1, TRUE)) {        /* failed! */
01394                 rsbac_ds_get_error("mac_auto_read_write", A_none);
01395                 return (NOT_GRANTED);
01396         }
01397         target_categories = attr_val1.mac_categories;
01398 
01399         if (target_sec_level > curr_level) {
01400                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_security_level, &attr_val1, FALSE)) {    /* failed! */
01401                         rsbac_ds_get_error("mac_auto_read_write", A_none);
01402                         return (NOT_GRANTED);
01403                 }
01404                 if (attr_val1.security_level < target_sec_level) {
01405                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: security_level %u under target_sec_level %u, no override -> NOT_GRANTED!\n",
01406                                        current->pid, current->comm,
01407                                        attr_val1.security_level,
01408                                        target_sec_level);
01409                         return (NOT_GRANTED);
01410                 }
01411                 /* curr_level < target_level <= max_level */
01412                 /* -> need mac_auto, (write_up && read_up)
01413                  * or trusted (with read option) */
01414                 if (flags & MAC_auto) {
01415                         /* check min_write boundary */
01416                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, &attr_val1, FALSE)) {    /* failed! */
01417                                 rsbac_ds_get_error("mac_auto_read_write",
01418                                                    A_none);
01419                                 return (NOT_GRANTED);
01420                         }
01421                         if (attr_val1.security_level < target_sec_level) {
01422                                 if (!
01423                                     ((flags & MAC_write_up)
01424                                      && (flags & MAC_read_up))
01425 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01426 && !(flags & MAC_trusted)
01427 #endif
01428                                     ) {
01429                                         /* Try mac_file_flags on the target, if FD object */
01430                                         switch (target) {
01431                                         case T_FILE:
01432                                         case T_DIR:
01433                                         case T_FIFO:
01434                                         case T_SYMLINK:
01435                                         case T_UNIXSOCK:
01436                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01437                                                         rsbac_ds_get_error
01438                                                             ("mac_auto_read_write",
01439                                                              A_none);
01440                                                         return
01441                                                             (NOT_GRANTED);
01442                                                 }
01443                                                 if (((attr_val1.
01444                                                       mac_file_flags &
01445                                                       MAC_write_up)
01446                                                      && (attr_val1.
01447                                                          mac_file_flags &
01448                                                          MAC_read_up)
01449                                                     )
01450 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01451                                                     || (flags &
01452                                                         MAC_trusted)
01453 #endif
01454                                                     ) {
01455                                                         break;
01456                                                 }
01457                                                 /* fall through */
01458 
01459                                         default:
01460                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_write_open %u under target_sec_level %u, no read_up or trusted -> NOT_GRANTED!\n",
01461                                                              current->pid,
01462                                                              current->comm,
01463                                                              attr_val1.
01464                                                              security_level,
01465                                                              target_sec_level);
01466                                                 return (NOT_GRANTED);
01467                                         }
01468                                 }
01469                         } else
01470                                 mac_auto_used_level = TRUE;
01471                 } else {
01472                         if (!
01473                             ((flags & MAC_write_up)
01474                              && (flags & MAC_read_up))
01475 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01476 && !(flags & MAC_trusted)
01477 #endif
01478                             ) {
01479                                 /* Try mac_file_flags on the target, if FD object */
01480                                 switch (target) {
01481                                 case T_FILE:
01482                                 case T_DIR:
01483                                 case T_FIFO:
01484                                 case T_SYMLINK:
01485                                 case T_UNIXSOCK:
01486                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01487                                                 rsbac_ds_get_error
01488                                                     ("mac_auto_read_write",
01489                                                      A_none);
01490                                                 return (NOT_GRANTED);
01491                                         }
01492                                         if (((attr_val1.
01493                                               mac_file_flags &
01494                                               MAC_write_up)
01495                                              && (attr_val1.
01496                                                  mac_file_flags &
01497                                                  MAC_read_up)
01498                                             )
01499 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01500                                             || (flags & MAC_trusted)
01501 #endif
01502                                             ) {
01503                                                 break;
01504                                         }
01505                                         /* fall through */
01506 
01507                                 default:
01508                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: current level %u under target_sec_level %u, no auto, (write_up && read_up) or trusted -> NOT_GRANTED!\n",
01509                                                        current->pid,
01510                                                        current->comm,
01511                                                        curr_level,
01512                                                        target_sec_level);
01513                                         return (NOT_GRANTED);
01514                                 }
01515                         }
01516                 }
01517         } else if (target_sec_level < curr_level) {
01518                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_security_level, &attr_val1, FALSE)) {        /* failed! */
01519                         rsbac_ds_get_error("mac_auto_read_write", A_none);
01520                         return (NOT_GRANTED);
01521                 }
01522                 if (attr_val1.security_level > target_sec_level) {
01523                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_security_level %u over target_sec_level %u, no override -> NOT_GRANTED!\n",
01524                                        current->pid,
01525                                        current->comm, attr_val1.security_level,
01526                                        target_sec_level);
01527                         return (NOT_GRANTED);
01528                 }
01529                 /* min_level <= target_level < curr_level -> need mac_auto,
01530                  * write_down or trusted */
01531                 if (flags & MAC_auto) {
01532                         /* check max_read boundary */
01533                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, &attr_val1, FALSE)) {     /* failed! */
01534                                 rsbac_ds_get_error("mac_auto_read_write",
01535                                                    A_none);
01536                                 return (NOT_GRANTED);
01537                         }
01538                         if (attr_val1.security_level > target_sec_level) {
01539                                 if (!(flags & MAC_write_down)
01540                                     && !(flags & MAC_trusted)
01541                                     ) {
01542                                         /* Try mac_file_flags on the target,
01543                                          * if FD object */
01544                                         switch (target) {
01545                                         case T_FILE:
01546                                         case T_DIR:
01547                                         case T_FIFO:
01548                                         case T_SYMLINK:
01549                                         case T_UNIXSOCK:
01550                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01551                                                         rsbac_ds_get_error
01552                                                             ("mac_auto_read_write",
01553                                                              A_none);
01554                                                         return
01555                                                             (NOT_GRANTED);
01556                                                 }
01557                                                 if ((attr_val1.
01558                                                      mac_file_flags &
01559                                                      MAC_write_down)
01560                                                     || (attr_val1.
01561                                                         mac_file_flags &
01562                                                         MAC_trusted)
01563                                                     ) {
01564                                                         if (attr_val1.
01565                                                             mac_file_flags
01566                                                             & MAC_auto) {
01567                                                                 raise_object_level
01568                                                                     = TRUE;
01569                                                         }
01570                                                         break;
01571                                                 }
01572                                                 /* fall through */
01573 
01574                                         default:
01575                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_read_open %u over target_sec_level %u, no write_down or trusted -> NOT_GRANTED!\n",
01576                                                              current->pid,
01577                                                              current->comm,
01578                                                              attr_val1.
01579                                                              security_level,
01580                                                              target_sec_level);
01581                                                 return (NOT_GRANTED);
01582                                         }
01583                                 }
01584                         } else
01585                                 mac_auto_used_level = TRUE;
01586                 } else {
01587                         if (!(flags & MAC_write_down)
01588                             && !(flags & MAC_trusted)
01589                             ) {
01590                                 /* Try mac_file_flags on the target,
01591                                  * if FD object */
01592                                 switch (target) {
01593                                 case T_FILE:
01594                                 case T_DIR:
01595                                 case T_FIFO:
01596                                 case T_SYMLINK:
01597                                 case T_UNIXSOCK:
01598                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01599                                                 rsbac_ds_get_error
01600                                                     ("mac_auto_read_write",
01601                                                      A_none);
01602                                                 return (NOT_GRANTED);
01603                                         }
01604                                         if ((attr_val1.
01605                                              mac_file_flags &
01606                                              MAC_write_down)
01607                                             || (attr_val1.
01608                                                 mac_file_flags &
01609                                                 MAC_trusted)
01610                                             ) {
01611                                                 if (attr_val1.
01612                                                     mac_file_flags &
01613                                                     MAC_auto) {
01614                                                         raise_object_level
01615                                                             = TRUE;
01616                                                 }
01617                                                 break;
01618                                         }
01619                                         /* fall through */
01620 
01621                                 default:
01622                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: current security_level %u over target_sec_level %u, no auto, write_down or trusted -> NOT_GRANTED!\n",
01623                                                        current->pid,
01624                                                        current->comm,
01625                                                        curr_level,
01626                                                        target_sec_level);
01627                                         return (NOT_GRANTED);
01628                                 }
01629                         }
01630                 }
01631         }
01632         if ((target_categories & curr_categories) != target_categories) {
01633                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_categories, &attr_val1, FALSE)) {    /* failed! */
01634                         rsbac_ds_get_error("mac_auto_read_write", A_none);
01635                         return (NOT_GRANTED);
01636                 }
01637                 if ((target_categories & attr_val1.mac_categories) !=
01638                     target_categories) {
01639 #ifdef CONFIG_RSBAC_DEBUG
01640                         if (rsbac_debug_adf_mac) {
01641                                 char *tmp =
01642                                     rsbac_kmalloc(RSBAC_MAXNAMELEN);
01643 
01644                                 if (tmp) {
01645                                         char *tmp2 =
01646                                             rsbac_kmalloc
01647                                             (RSBAC_MAXNAMELEN);
01648 
01649                                         if (tmp2) {
01650                                                 u64tostrmac(tmp,
01651                                                             attr_val1.
01652                                                             mac_categories);
01653                                                 u64tostrmac(tmp2,
01654                                                             target_categories);
01655                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_categories %s under target categories %s, no override -> NOT_GRANTED!\n",
01656                                                              current->pid,
01657                                                              current->comm,
01658                                                              tmp, tmp2);
01659                                                 rsbac_kfree(tmp2);
01660                                         }
01661                                         rsbac_kfree(tmp);
01662                                 }
01663                         }
01664 #endif
01665                         return (NOT_GRANTED);
01666                 }
01667                 /* curr_categories < target_categories <= max_categories */
01668                 /* -> need mac_auto, (read_up && write_up) or 
01669                  * trusted (with read option) */
01670                 if (flags & MAC_auto) {
01671                         /* check min_write boundary */
01672                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, &attr_val1, FALSE)) {      /* failed! */
01673                                 rsbac_ds_get_error("mac_auto_read_write",
01674                                                    A_none);
01675                                 return (NOT_GRANTED);
01676                         }
01677                         if ((target_categories & attr_val1.
01678                              mac_categories) != target_categories) {
01679                                 if (!
01680                                     ((flags & MAC_write_up)
01681                                      && (flags & MAC_read_up))
01682 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01683 && !(flags & MAC_trusted)
01684 #endif
01685                                     ) {
01686                                         /* Try mac_file_flags on the target,
01687                                          * if FD object */
01688                                         switch (target) {
01689                                         case T_FILE:
01690                                         case T_DIR:
01691                                         case T_FIFO:
01692                                         case T_SYMLINK:
01693                                         case T_UNIXSOCK:
01694                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01695                                                         rsbac_ds_get_error
01696                                                             ("mac_auto_read_write",
01697                                                              A_none);
01698                                                         return
01699                                                             (NOT_GRANTED);
01700                                                 }
01701                                                 if (((attr_val1.
01702                                                       mac_file_flags &
01703                                                       MAC_write_up)
01704                                                      && (attr_val1.
01705                                                          mac_file_flags &
01706                                                          MAC_read_up)
01707                                                     )
01708 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01709                                                     || (flags &
01710                                                         MAC_trusted)
01711 #endif
01712                                                     ) {
01713                                                         break;
01714                                                 }
01715                                                 /* fall through */
01716 
01717                                         default:
01718 #ifdef CONFIG_RSBAC_DEBUG
01719                                                 if (rsbac_debug_adf_mac) {
01720                                                         char *tmp =
01721                                                             rsbac_kmalloc
01722                                                             (RSBAC_MAXNAMELEN);
01723 
01724                                                         if (tmp) {
01725                                                                 char *tmp2
01726                                                                     =
01727                                                                     rsbac_kmalloc
01728                                                                     (RSBAC_MAXNAMELEN);
01729 
01730                                                                 if (tmp2) {
01731                                                                         u64tostrmac
01732                                                                             (tmp,
01733                                                                              attr_val1.
01734                                                                              mac_categories);
01735                                                                         u64tostrmac
01736                                                                             (tmp2,
01737                                                                              target_categories);
01738                                                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_write_categories %s under target categories %s, no (read_up and write_up) or trusted with read option -> NOT_GRANTED!\n",
01739                                                                              current->
01740                                                                              pid,
01741                                                                              current->
01742                                                                              comm,
01743                                                                              tmp,
01744                                                                              tmp2);
01745                                                                         rsbac_kfree
01746                                                                             (tmp2);
01747                                                                 }
01748                                                                 rsbac_kfree
01749                                                                     (tmp);
01750                                                         }
01751                                                 }
01752 #endif
01753                                                 return (NOT_GRANTED);
01754                                         }
01755                                 }
01756                         } else
01757                                 mac_auto_used_cat = TRUE;
01758                 } else {
01759                         if (!
01760                             ((flags & MAC_write_up)
01761                              && (flags & MAC_read_up))
01762 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01763 && !(flags & MAC_trusted)
01764 #endif
01765                             ) {
01766                                 /* Try mac_file_flags on the target,
01767                                  * if FD object */
01768                                 switch (target) {
01769                                 case T_FILE:
01770                                 case T_DIR:
01771                                 case T_FIFO:
01772                                 case T_SYMLINK:
01773                                 case T_UNIXSOCK:
01774                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01775                                                 rsbac_ds_get_error
01776                                                     ("mac_auto_read_write",
01777                                                      A_none);
01778                                                 return (NOT_GRANTED);
01779                                         }
01780                                         if (((attr_val1.
01781                                               mac_file_flags &
01782                                               MAC_write_up)
01783                                              && (attr_val1.
01784                                                  mac_file_flags &
01785                                                  MAC_read_up)
01786                                             )
01787 #ifdef CONFIG_RSBAC_MAC_TRUSTED_READ
01788                                             || (flags & MAC_trusted)
01789 #endif
01790                                             ) {
01791                                                 break;
01792                                         }
01793                                         /* fall through */
01794 
01795                                 default:
01796 #ifdef CONFIG_RSBAC_DEBUG
01797                                         if (rsbac_debug_adf_mac) {
01798                                                 char *tmp =
01799                                                     rsbac_kmalloc
01800                                                     (RSBAC_MAXNAMELEN);
01801 
01802                                                 if (tmp) {
01803                                                         char *tmp2 =
01804                                                             rsbac_kmalloc
01805                                                             (RSBAC_MAXNAMELEN);
01806 
01807                                                         if (tmp2) {
01808                                                                 u64tostrmac
01809                                                                     (tmp,
01810                                                                      curr_categories);
01811                                                                 u64tostrmac
01812                                                                     (tmp2,
01813                                                                      target_categories);
01814                                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: curr_categories %s under target categories %s, no auto, (read_up and write_up) or trusted -> NOT_GRANTED!\n",
01815                                                                      current->
01816                                                                      pid,
01817                                                                      current->
01818                                                                      comm,
01819                                                                      tmp,
01820                                                                      tmp2);
01821                                                                 rsbac_kfree
01822                                                                     (tmp2);
01823                                                         }
01824                                                         rsbac_kfree(tmp);
01825                                                 }
01826                                         }
01827 #endif
01828                                         return (NOT_GRANTED);
01829                                 }
01830                         }
01831                 }
01832         } else
01833             if ((target_categories & curr_categories) != curr_categories) {
01834                 if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_mac_min_categories, &attr_val1, FALSE)) {        /* failed! */
01835                         rsbac_ds_get_error("mac_auto_read_write", A_none);
01836                         return (NOT_GRANTED);
01837                 }
01838                 if ((target_categories & attr_val1.mac_categories) !=
01839                     attr_val1.mac_categories) {
01840 #ifdef CONFIG_RSBAC_DEBUG
01841                         if (rsbac_debug_adf_mac) {
01842                                 char *tmp =
01843                                     rsbac_kmalloc(RSBAC_MAXNAMELEN);
01844 
01845                                 if (tmp) {
01846                                         char *tmp2 =
01847                                             rsbac_kmalloc
01848                                             (RSBAC_MAXNAMELEN);
01849 
01850                                         if (tmp2) {
01851                                                 u64tostrmac(tmp,
01852                                                             attr_val1.
01853                                                             mac_categories);
01854                                                 u64tostrmac(tmp2,
01855                                                             target_categories);
01856                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: min_categories %s over target categories %s, no override -> NOT_GRANTED!\n",
01857                                                              current->pid,
01858                                                              current->comm,
01859                                                              tmp, tmp2);
01860                                                 rsbac_kfree(tmp2);
01861                                         }
01862                                         rsbac_kfree(tmp);
01863                                 }
01864                         }
01865 #endif
01866                         return (NOT_GRANTED);
01867                 }
01868                 /* min_level <= target_level < curr_level -> need mac_auto,
01869                  * write_down or trusted */
01870                 if (flags & MAC_auto) {
01871                         /* check max_read boundary */
01872                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, &attr_val1, FALSE)) {       /* failed! */
01873                                 rsbac_ds_get_error("mac_auto_read_write",
01874                                                    A_none);
01875                                 return (NOT_GRANTED);
01876                         }
01877                         if ((target_categories & attr_val1.
01878                              mac_categories) != attr_val1.mac_categories) {
01879                                 if (!(flags & MAC_write_down)
01880                                     && !(flags & MAC_trusted)
01881                                     ) {
01882                                         /* Try mac_file_flags on the target,
01883                                          * if FD object */
01884                                         switch (target) {
01885                                         case T_FILE:
01886                                         case T_DIR:
01887                                         case T_FIFO:
01888                                         case T_SYMLINK:
01889                                         case T_UNIXSOCK:
01890                                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01891                                                         rsbac_ds_get_error
01892                                                             ("mac_auto_read_write",
01893                                                              A_none);
01894                                                         return
01895                                                             (NOT_GRANTED);
01896                                                 }
01897                                                 if ((attr_val1.
01898                                                      mac_file_flags &
01899                                                      MAC_write_down)
01900                                                     || (attr_val1.
01901                                                         mac_file_flags &
01902                                                         MAC_trusted)
01903                                                     ) {
01904                                                         if (attr_val1.
01905                                                             mac_file_flags
01906                                                             & MAC_auto) {
01907                                                                 raise_object_cat
01908                                                                     = TRUE;
01909                                                         }
01910                                                         break;
01911                                                 }
01912                                                 /* fall through */
01913 
01914                                         default:
01915 #ifdef CONFIG_RSBAC_DEBUG
01916                                                 if (rsbac_debug_adf_mac) {
01917                                                         char *tmp =
01918                                                             rsbac_kmalloc
01919                                                             (RSBAC_MAXNAMELEN);
01920 
01921                                                         if (tmp) {
01922                                                                 char *tmp2
01923                                                                     =
01924                                                                     rsbac_kmalloc
01925                                                                     (RSBAC_MAXNAMELEN);
01926 
01927                                                                 if (tmp2) {
01928                                                                         u64tostrmac
01929                                                                             (tmp,
01930                                                                              attr_val1.
01931                                                                              mac_categories);
01932                                                                         u64tostrmac
01933                                                                             (tmp2,
01934                                                                              target_categories);
01935                                                                         rsbac_pr_debug(adf_mac, "pid %u/%.15s: max_read_categories %s over target categories %s, no write_down or trusted -> NOT_GRANTED!\n",
01936                                                                              current->
01937                                                                              pid,
01938                                                                              current->
01939                                                                              comm,
01940                                                                              tmp,
01941                                                                              tmp2);
01942                                                                         rsbac_kfree
01943                                                                             (tmp2);
01944                                                                 }
01945                                                                 rsbac_kfree
01946                                                                     (tmp);
01947                                                         }
01948                                                 }
01949 #endif
01950                                                 return (NOT_GRANTED);
01951                                         }
01952                                 }
01953                         } else
01954                                 mac_auto_used_cat = TRUE;
01955                 } else {
01956                         if (!(flags & MAC_write_down)
01957                             && !(flags & MAC_trusted)
01958                             ) {
01959                                 /* Try mac_file_flags on the target,
01960                                  * if FD object */
01961                                 switch (target) {
01962                                 case T_FILE:
01963                                 case T_DIR:
01964                                 case T_FIFO:
01965                                 case T_SYMLINK:
01966                                 case T_UNIXSOCK:
01967                                         if (rsbac_get_attr(SW_MAC, target, tid, A_mac_file_flags, &attr_val1, TRUE)) {  /* failed! */
01968                                                 rsbac_ds_get_error
01969                                                     ("mac_auto_read_write",
01970                                                      A_none);
01971                                                 return (NOT_GRANTED);
01972                                         }
01973                                         if ((attr_val1.
01974                                              mac_file_flags &
01975                                              MAC_write_down)
01976                                             || (attr_val1.
01977                                                 mac_file_flags &
01978                                                 MAC_trusted)
01979                                             ) {
01980                                                 if (attr_val1.
01981                                                     mac_file_flags &
01982                                                     MAC_auto) {
01983                                                         raise_object_cat =
01984                                                             TRUE;
01985                                                 }
01986                                                 break;
01987                                         }
01988                                         /* fall through */
01989 
01990                                 default:
01991 #ifdef CONFIG_RSBAC_DEBUG
01992                                         if (rsbac_debug_adf_mac) {
01993                                                 char *tmp =
01994                                                     rsbac_kmalloc
01995                                                     (RSBAC_MAXNAMELEN);
01996 
01997                                                 if (tmp) {
01998                                                         char *tmp2 =
01999                                                             rsbac_kmalloc
02000                                                             (RSBAC_MAXNAMELEN);
02001 
02002                                                         if (tmp2) {
02003                                                                 u64tostrmac
02004                                                                     (tmp,
02005                                                                      curr_categories);
02006                                                                 u64tostrmac
02007                                                                     (tmp2,
02008                                                                      target_categories);
02009                                                                 rsbac_pr_debug(adf_mac, "pid %u/%.15s: curr_categories %s over target categories %s, no auto, write_down or trusted -> NOT_GRANTED!\n",
02010                                                                      current->
02011                                                                      pid,
02012                                                                      current->
02013                                                                      comm,
02014                                                                      tmp,
02015                                                                      tmp2);
02016                                                                 rsbac_kfree
02017                                                                     (tmp2);
02018                                                         }
02019                                                         rsbac_kfree(tmp);
02020                                                 }
02021                                         }
02022 #endif
02023                                         return (NOT_GRANTED);
02024                                 }
02025                         }
02026                 }
02027         }
02028 
02029         /* grant area */
02030 
02031         /* adjust current_sec_level and min_write_level, */
02032         /* if set_level is true and mac_auto has been used */
02033         if (set_level && (mac_auto_used_level || raise_object_level)
02034             ) {
02035 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
02036                 {
02037                         char *target_type_name;
02038                         char *target_id_name;
02039 
02040                         target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
02041                         if (target_type_name) {
02042 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
02043                                 target_id_name
02044                                     =
02045                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
02046                                                   + RSBAC_MAXNAMELEN);
02047                                 /* max. path name len + some extra */
02048 #else
02049                                 target_id_name =
02050                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
02051                                 /* max. file name len + some extra */
02052 #endif
02053                                 if (target_id_name) {
02054                                         get_target_name(target_type_name,
02055                                                         target,
02056                                                         target_id_name,
02057                                                         tid);
02058 
02059                                         if (mac_auto_used_level) {
02060                                                 rsbac_printk(KERN_INFO "mac_auto_read_write(): Changing process %u (%.15s, owner %u) current level from %u to %u for %s %s\n",
02061                                                              pid,
02062                                                              current->comm,
02063                                                              current->uid,
02064                                                              curr_level,
02065                                                              target_sec_level,
02066                                                              target_type_name,
02067                                                              target_id_name);
02068                                         } else {
02069                                                 rsbac_printk(KERN_INFO "mac_auto_read_write(): Process %u (%.15s, owner %u): Raising object level from %u to %u for %s %s\n",
02070                                                              pid,
02071                                                              current->comm,
02072                                                              current->uid,
02073                                                              target_sec_level,
02074                                                              curr_level,
02075                                                              target_type_name,
02076                                                              target_id_name);
02077                                         }
02078                                         rsbac_kfree(target_id_name);
02079                                 }
02080                                 rsbac_kfree(target_type_name);
02081                         }
02082                 }
02083 #endif
02084                 if (mac_auto_used_level) {
02085                         i_tid.process = pid;
02086                         attr_val1.current_sec_level = target_sec_level;
02087                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, &attr_val2, TRUE)) {     /* failed! */
02088                                 rsbac_ds_get_error("mac_auto_read_write",
02089                                                    A_none);
02090                                 return (NOT_GRANTED);
02091                         }
02092                         if (attr_val1.min_write_open <
02093                             attr_val2.min_write_open) {
02094                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_open, attr_val1)) {    /* failed! */
02095                                         rsbac_ds_set_error
02096                                             ("mac_auto_read_write",
02097                                              A_none);
02098                                         return (NOT_GRANTED);
02099                                 }
02100                         }
02101                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, &attr_val2, TRUE)) {      /* failed! */
02102                                 rsbac_ds_get_error("mac_auto_read_write",
02103                                                    A_none);
02104                                 return (NOT_GRANTED);
02105                         }
02106                         if (attr_val1.max_read_open >
02107                             attr_val2.max_read_open) {
02108                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_open, attr_val1)) {     /* failed! */
02109                                         rsbac_ds_set_error
02110                                             ("mac_auto_read_write",
02111                                              A_none);
02112                                         return (NOT_GRANTED);
02113                                 }
02114                         }
02115                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_current_sec_level, attr_val1)) { /* failed! */
02116                                 rsbac_ds_set_error("mac_auto_read_write",
02117                                                    A_none);
02118                                 return (NOT_GRANTED);
02119                         }
02120                 } else {
02121                         attr_val1.security_level = curr_level;
02122                         if (rsbac_set_attr(SW_MAC, target, tid, A_security_level, attr_val1)) { /* failed! */
02123                                 rsbac_ds_set_error("mac_auto_read_write",
02124                                                    A_none);
02125                                 return (NOT_GRANTED);
02126                         }
02127                 }
02128         }
02129         /* adjust current_categories and min_write_categories, */
02130         /* if set_level is true and mac_auto has been used */
02131         if (set_level && (mac_auto_used_cat || raise_object_cat)
02132             ) {
02133 #ifdef CONFIG_RSBAC_MAC_LOG_LEVEL_CHANGE
02134                 {
02135                         char *target_type_name =
02136                             rsbac_kmalloc(RSBAC_MAXNAMELEN);
02137                         if (target_type_name) {
02138                                 char *target_id_name;
02139 
02140 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
02141                                 target_id_name
02142                                     =
02143                                     rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN
02144                                                   + RSBAC_MAXNAMELEN);
02145                                 /* max. path name len + some extra */
02146 #else
02147                                 target_id_name =
02148                                     rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
02149                                 /* max. file name len + some extra */
02150 #endif
02151                                 if (target_id_name) {
02152                                         char *tmp1 =
02153                                             rsbac_kmalloc
02154                                             (RSBAC_MAXNAMELEN);
02155                                         if (tmp1) {
02156                                                 char *tmp2 =
02157                                                     rsbac_kmalloc
02158                                                     (RSBAC_MAXNAMELEN);
02159                                                 if (tmp2) {
02160                                                         get_target_name
02161                                                             (target_type_name,
02162                                                              target,
02163                                                              target_id_name,
02164                                                              tid);
02165 
02166                                                         if (mac_auto_used_cat) {
02167                                                                 rsbac_printk
02168                                                                     (KERN_INFO "mac_auto_read_write(): Changing process %u (%.15s, owner %u) current categories from %s to %s for %s %s\n",
02169                                                                      pid,
02170                                                                      current->
02171                                                                      comm,
02172                                                                      current->
02173                                                                      uid,
02174                                                                      u64tostrmac
02175                                                                      (tmp1,
02176                                                                       curr_categories),
02177                                                                      u64tostrmac
02178                                                                      (tmp2,
02179                                                                       target_categories),
02180                                                                      target_type_name,
02181                                                                      target_id_name);
02182                                                         } else {
02183                                                                 rsbac_printk
02184                                                                     (KERN_INFO "mac_auto_read_write(): Process %u (%.15s, owner %u): raising current categories from %s to %s for %s %s\n",
02185                                                                      pid,
02186                                                                      current->
02187                                                                      comm,
02188                                                                      current->
02189                                                                      uid,
02190                                                                      u64tostrmac
02191                                                                      (tmp2,
02192                                                                       target_categories),
02193                                                                      u64tostrmac
02194                                                                      (tmp1,
02195                                                                       curr_categories),
02196                                                                      target_type_name,
02197                                                                      target_id_name);
02198                                                         }
02199                                                         rsbac_kfree(tmp2);
02200                                                 }
02201                                                 rsbac_kfree(tmp1);
02202                                         }
02203                                         rsbac_kfree(target_id_name);
02204                                 }
02205                                 rsbac_kfree(target_type_name);
02206                         }
02207                 }
02208 #endif
02209                 if (mac_auto_used_cat) {
02210                         i_tid.process = pid;
02211                         attr_val1.mac_categories = target_categories;
02212                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, &attr_val2, TRUE)) {       /* failed! */
02213                                 rsbac_ds_set_error("mac_auto_read_write",
02214                                                    A_none);
02215                                 return (NOT_GRANTED);
02216                         }
02217                         if ((attr_val1.mac_categories & attr_val2.
02218                              mac_categories)
02219                             != attr_val2.mac_categories) {
02220                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_min_write_categories, attr_val1)) {      /* failed! */
02221                                         rsbac_ds_set_error
02222                                             ("mac_auto_read_write",
02223                                              A_none);
02224                                         return (NOT_GRANTED);
02225                                 }
02226                         }
02227                         if (rsbac_get_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, &attr_val2, TRUE)) {        /* failed! */
02228                                 rsbac_ds_get_error("mac_auto_read_write",
02229                                                    A_none);
02230                                 return (NOT_GRANTED);
02231                         }
02232                         if ((attr_val1.mac_categories & attr_val2.
02233                              mac_categories)
02234                             != attr_val1.mac_categories) {
02235                                 if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_max_read_categories, attr_val1)) {       /* failed! */
02236                                         rsbac_ds_set_error
02237                                             ("mac_auto_read_write",
02238                                              A_none);
02239                                         return (NOT_GRANTED);
02240                                 }
02241                         }
02242                         if (rsbac_set_attr(SW_MAC, T_PROCESS, i_tid, A_mac_curr_categories, attr_val1)) {       /* failed! */
02243                                 rsbac_ds_set_error("mac_auto_read_write",
02244                                                    A_none);
02245                                 return (NOT_GRANTED);
02246                         }
02247                 } else {
02248                         attr_val1.mac_categories = curr_categories;
02249                         if (rsbac_set_attr(SW_MAC, target, tid, A_mac_categories, attr_val1)) { /* failed! */
02250                                 rsbac_ds_set_error("mac_auto_read_write",
02251                                                    A_none);
02252                                 return (NOT_GRANTED);
02253                         }
02254                 }
02255         }
02256 
02257         /* Everything done, so return */
02258         return (GRANTED);
02259 }
02260 
02261 static enum rsbac_adf_req_ret_t
02262 auto_read_write(rsbac_pid_t pid,
02263                 enum rsbac_target_t target,
02264                 union rsbac_target_id_t tid, rsbac_boolean_t set_level)
02265 {
02266         return auto_read_write_attr(pid,
02267                                     target,
02268                                     tid,
02269                                     A_security_level,
02270                                     A_mac_categories, set_level);
02271 }
02272 
02273 /************************************************* */
02274 /*          Externally visible functions           */
02275 /************************************************* */
02276 
02277 inline enum rsbac_adf_req_ret_t
02278 rsbac_adf_request_mac(enum rsbac_adf_request_t request,
02279                       rsbac_pid_t caller_pid,
02280                       enum rsbac_target_t target,
02281                       union rsbac_target_id_t tid,
02282                       enum rsbac_attribute_t attr,
02283                       union rsbac_attribute_value_t attr_val,
02284                       rsbac_uid_t owner)
02285 {
02286         enum rsbac_adf_req_ret_t result = DO_NOT_CARE;
02287         union rsbac_target_id_t i_tid;
02288         union rsbac_attribute_value_t i_attr_val1;
02289 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
02290         union rsbac_attribute_value_t i_attr_val2;
02291 #endif
02292 
02293         switch (request) {
02294         case R_ADD_TO_KERNEL:
02295                 switch (target) {
02296                 case T_FILE:
02297                 case T_DEV:
02298                 case T_NONE:
02299                         /* test owner's mac_role */
02300                         return mac_check_role(owner, SR_administrator);
02301 
02302                         /* all other cases are unknown */
02303                 default:
02304                         return (DO_NOT_CARE);
02305                 }
02306 
02307         case R_ALTER:
02308                 /* only for IPC */
02309                 if (target == T_IPC) {
02310                         /* and perform auto-write without setting attributes */
02311                         return (auto_write(caller_pid,
02312                                            target, tid, FALSE));
02313                 } else
02314                         /* all other targets are unknown */
02315                         return (DO_NOT_CARE);
02316                 break;
02317 
02318         case R_APPEND_OPEN:
02319                 switch (target) {
02320                 case T_FILE:
02321                 case T_FIFO:
02322                 case T_UNIXSOCK:
02323                         /* and perform auto-write without setting attributes */
02324                         return (auto_write(caller_pid,
02325                                            target, tid, FALSE));
02326                         break;
02327                 case T_IPC:
02328                         /* and perform auto-write without setting attributes */
02329                         return (auto_write(caller_pid,
02330                                            target, tid, FALSE));
02331                         break;
02332                 case T_DEV:
02333                         /* Only check for devices with mac_check set */
02334                         if (rsbac_get_attr(SW_MAC,
02335                                            T_DEV,
02336                                            tid,
02337                                            A_mac_check,
02338                                            &i_attr_val1, FALSE)) {
02339                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02340                                                    A_none);
02341                                 return (NOT_GRANTED);
02342                         }
02343                         if (!i_attr_val1.mac_check)
02344                                 return (DO_NOT_CARE);
02345                         /* and perform auto-write without setting attributes */
02346                         return (auto_write(caller_pid,
02347                                            target, tid, FALSE));
02348                         break;
02349                         /* all other cases are unknown */
02350                 default:
02351                         return (DO_NOT_CARE);
02352                 }
02353 
02354         case R_CHANGE_GROUP:
02355                 switch (target) {
02356                 case T_FILE:
02357                 case T_DIR:
02358                 case T_FIFO:
02359                 case T_SYMLINK:
02360                 case T_UNIXSOCK:
02361                         /* and perform auto-write without setting attributes */
02362                         return (auto_write(caller_pid,
02363                                            target, tid, FALSE));
02364                 case T_IPC:
02365                         /* and perform auto-write without setting attributes */
02366                         return (auto_write(caller_pid,
02367                                            target, tid, FALSE));
02368 
02369 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02370                 case T_USER:
02371                         /* Security Officer? */
02372                         return mac_check_role(owner, SR_security_officer);
02373 #endif
02374                         /* We do not care about */
02375                         /* all other cases */
02376                 default:
02377                         return (DO_NOT_CARE);
02378                 }
02379 
02380         case R_CHANGE_OWNER:
02381                 switch (target) {
02382                 case T_FILE:
02383                 case T_DIR:
02384                 case T_FIFO:
02385                 case T_SYMLINK:
02386                 case T_UNIXSOCK:
02387                         /* and perform auto-write without setting attributes */
02388                         return (auto_write(caller_pid,
02389                                            target, tid, FALSE));
02390 
02391                 case T_IPC:
02392                         return (auto_write(caller_pid,
02393                                            target, tid, FALSE));
02394 
02395                         /* all other cases are unknown */
02396                 default:
02397                         return (DO_NOT_CARE);
02398                 }
02399 
02400         case R_CHDIR:
02401                 switch (target) {
02402                 case T_DIR:
02403                         /* and perform auto-read without setting attributes */
02404                         return (auto_read(caller_pid, target, tid, FALSE));
02405                         break;
02406                         /* all other cases are unknown */
02407                 default:
02408                         return (DO_NOT_CARE);
02409                 }
02410 
02411         case R_CREATE:
02412                 switch (target) {
02413                         /* Creating dir or (pseudo) file IN target dir! */
02414                 case T_DIR:
02415 #ifdef CONFIG_RSBAC_MAC_LIGHT
02416                         return GRANTED;
02417 #else
02418                         /* Mode of created item is ignored! */
02419                         /* and perform auto-write without setting attributes */
02420                         return (auto_write(caller_pid,
02421                                            target, tid, FALSE));
02422 #endif
02423                         break;
02424 
02425 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02426                 case T_NETTEMP:
02427                         return mac_check_role(owner, SR_security_officer);
02428 
02429                 case T_NETOBJ:
02430                         /* and perform auto-write without setting attributes */
02431                         return (auto_write_attr(caller_pid,
02432                                                 target,
02433                                                 tid,
02434                                                 A_local_sec_level,
02435                                                 A_local_mac_categories,
02436                                                 FALSE));
02437 #endif
02438 
02439 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02440                 case T_USER:
02441                 case T_GROUP:
02442                         /* Security Officer? */
02443                         return mac_check_role(owner, SR_security_officer);
02444 #endif
02445                         /* all other cases are unknown */
02446                 default:
02447                         return (DO_NOT_CARE);
02448                 }
02449 
02450         case R_DELETE:
02451                 switch (target) {
02452                 case T_FILE:
02453                 case T_DIR:
02454                 case T_FIFO:
02455                 case T_SYMLINK:
02456                 case T_UNIXSOCK:
02457                         /* and perform auto-write without setting attributes */
02458                         return (auto_write(caller_pid,
02459                                            target, tid, FALSE));
02460                         break;
02461                 case T_IPC:
02462                         /* and perform auto-write without setting attributes */
02463                         return (auto_write(caller_pid,
02464                                            target, tid, FALSE));
02465                         break;
02466 
02467 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02468                 case T_NETTEMP:
02469                         return mac_check_role(owner, SR_security_officer);
02470 #endif
02471 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02472                 case T_USER:
02473                 case T_GROUP:
02474                         /* Security Officer? */
02475                         return mac_check_role(owner, SR_security_officer);
02476 #endif
02477 
02478                         /* all other cases are unknown */
02479                 default:
02480                         return (DO_NOT_CARE);
02481                 }
02482 
02483         case R_EXECUTE:
02484         case R_MAP_EXEC:
02485                 switch (target) {
02486                 case T_FILE:
02487                         /* and perform auto-read without setting attributes */
02488                         return (auto_read(caller_pid, target, tid, FALSE));
02489 
02490                         /* all other cases are unknown */
02491                 default:
02492                         return (DO_NOT_CARE);
02493                 }
02494 
02495         case R_GET_PERMISSIONS_DATA:
02496                 switch (target) {
02497 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02498                 case T_USER:
02499                 case T_GROUP:
02500                         /* Security Officer? */
02501                         return mac_check_role(owner, SR_security_officer);
02502 #endif
02503 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02504                 case T_NETOBJ:
02505                         /* and perform auto-read without setting attributes */
02506                         return (auto_read_attr(caller_pid,
02507                                                target,
02508                                                tid,
02509                                                A_local_sec_level,
02510                                                A_local_mac_categories,
02511                                                FALSE));
02512 #endif
02513 
02514                 default:
02515                         return (DO_NOT_CARE);
02516                 }
02517 
02518         case R_GET_STATUS_DATA:
02519                 switch (target) {
02520                 case T_SCD:
02521                         /* target rsbaclog? only for secoff */
02522                         if (tid.scd != ST_rsbac_log)
02523                                 return (GRANTED);
02524                         /* Secoff? */
02525                         if (mac_check_role(owner, SR_security_officer) ==
02526                             NOT_GRANTED)
02527                                 return mac_check_role(owner, SR_auditor);
02528                         else
02529                                 return GRANTED;
02530 
02531                 case T_PROCESS:
02532                         /* perform auto-read without setting attributes */
02533                         return (auto_read_attr(caller_pid,
02534                                                target,
02535                                                tid,
02536                                                A_current_sec_level,
02537                                                A_mac_curr_categories,
02538                                                FALSE));
02539 
02540 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02541                 case T_NETOBJ:
02542                         /* and perform auto-read without setting attributes */
02543                         return (auto_read_attr(caller_pid,
02544                                                target,
02545                                                tid,
02546                                                A_local_sec_level,
02547                                                A_local_mac_categories,
02548                                                FALSE));
02549 #endif
02550 
02551                 default:
02552                         return (DO_NOT_CARE);
02553                 }
02554 
02555         case R_LINK_HARD:
02556                 switch (target) {
02557                 case T_FILE:
02558                 case T_FIFO:
02559                 case T_SYMLINK:
02560                         /* and perform auto-write without setting attributes */
02561                         return (auto_write(caller_pid,
02562                                            target, tid, FALSE));
02563                         break;
02564                         /* all other cases are unknown */
02565                 default:
02566                         return (DO_NOT_CARE);
02567                 }
02568 
02569         case R_MODIFY_ACCESS_DATA:
02570                 switch (target) {
02571                 case T_FILE:
02572                 case T_DIR:
02573                 case T_FIFO:
02574                 case T_SYMLINK:
02575                 case T_UNIXSOCK:
02576                         /* and perform auto-write without setting attributes */
02577                         return (auto_write(caller_pid,
02578                                            target, tid, FALSE));
02579                         break;
02580                         /* all other cases are unknown */
02581                 default:
02582                         return (DO_NOT_CARE);
02583                 }
02584 
02585         case R_MODIFY_ATTRIBUTE:
02586                 switch (attr) {
02587                 case A_security_level:
02588                 case A_initial_security_level:
02589                 case A_local_sec_level:
02590                 case A_remote_sec_level:
02591                 case A_min_security_level:
02592                 case A_mac_categories:
02593                 case A_mac_initial_categories:
02594                 case A_local_mac_categories:
02595                 case A_remote_mac_categories:
02596                 case A_mac_min_categories:
02597                 case A_mac_user_flags:
02598                 case A_mac_process_flags:
02599                 case A_mac_file_flags:
02600                 case A_system_role:
02601                 case A_mac_role:
02602                 case A_current_sec_level:
02603                 case A_mac_curr_categories:
02604                 case A_min_write_open:
02605                 case A_max_read_open:
02606                 case A_min_write_categories:
02607                 case A_max_read_categories:
02608                 case A_mac_check:
02609                 case A_mac_auto:
02610                 case A_mac_prop_trusted:
02611                 case A_symlink_add_mac_level:
02612 #ifdef CONFIG_RSBAC_MAC_GEN_PROT
02613                 case A_pseudo:
02614                 case A_log_array_low:
02615                 case A_log_array_high:
02616                 case A_local_log_array_low:
02617                 case A_local_log_array_high:
02618                 case A_remote_log_array_low:
02619                 case A_remote_log_array_high:
02620                 case A_log_program_based:
02621                 case A_log_user_based:
02622                 case A_symlink_add_remote_ip:
02623                 case A_symlink_add_uid:
02624                 case A_linux_dac_disable:
02625                 case A_fake_root_uid:
02626                 case A_audit_uid:
02627                 case A_auid_exempt:
02628                 case A_remote_ip:
02629                 case A_kernel_thread:
02630 #endif
02631 #ifdef CONFIG_RSBAC_MAC_AUTH_PROT
02632                 case A_auth_may_setuid:
02633                 case A_auth_may_set_cap:
02634                 case A_auth_start_uid:
02635                 case A_auth_start_euid:
02636                 case A_auth_start_gid:
02637                 case A_auth_start_egid:
02638                 case A_auth_program_file:
02639                 case A_auth_learn:
02640                 case A_auth_add_f_cap:
02641                 case A_auth_remove_f_cap:
02642                 case A_auth_last_auth:
02643 #endif
02644                         /* All attributes (remove target!) */
02645                 case A_none:
02646                         /* Security Officer? */
02647                         return mac_check_role(owner, SR_security_officer);
02648 
02649                 default:
02650                         return (DO_NOT_CARE);
02651                 }
02652 
02653         case R_MODIFY_PERMISSIONS_DATA:
02654                 switch (target) {
02655                 case T_FILE:
02656                 case T_DIR:
02657                 case T_FIFO:
02658                 case T_SYMLINK:
02659                 case T_UNIXSOCK:
02660                 case T_IPC:
02661                         /* and perform auto-write without setting attributes */
02662                         return (auto_write(caller_pid,
02663                                            target, tid, FALSE));
02664                         break;
02665 
02666                 case T_SCD:
02667 #ifdef CONFIG_RSBAC_USER_MOD_IOPERM
02668                         if (tid.scd == ST_ioports)
02669                                 return GRANTED;
02670 #endif
02671                         /* Security Officer? */
02672                         i_tid.user = owner;
02673                         if (rsbac_get_attr(SW_MAC,
02674                                            T_USER,
02675                                            i_tid,
02676                                            A_mac_role,
02677                                            &i_attr_val1, TRUE)) {
02678                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02679                                                    A_none);
02680                                 return (NOT_GRANTED);
02681                         }
02682                         /* if sec_officer, then grant */
02683                         if (i_attr_val1.system_role == SR_security_officer)
02684                                 return (GRANTED);
02685                         /* For booting: if administrator and ioports, then grant */
02686                         if ((i_attr_val1.system_role == SR_administrator)
02687                             && (tid.scd == ST_ioports))
02688                                 return (GRANTED);
02689                         else
02690                                 return (NOT_GRANTED);
02691 
02692 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02693                 case T_NETOBJ:
02694                         /* and perform auto-write without setting attributes */
02695                         return (auto_write_attr(caller_pid,
02696                                                 target,
02697                                                 tid,
02698                                                 A_local_sec_level,
02699                                                 A_local_mac_categories,
02700                                                 FALSE));
02701 #endif
02702 
02703 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02704                 case T_USER:
02705                 case T_GROUP:
02706                         /* Security Officer? */
02707                         return mac_check_role(owner, SR_security_officer);
02708 #endif
02709 #ifdef CONFIG_RSBAC_ALLOW_DAC_DISABLE
02710                         /* switching Linux DAC */
02711                 case T_NONE:
02712                         /* Security Officer? */
02713                         i_tid.user = owner;
02714                         if (rsbac_get_attr(SW_MAC,
02715                                            T_USER,
02716                                            i_tid,
02717                                            A_mac_role,
02718                                            &i_attr_val1, TRUE)) {
02719                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02720                                                    A_none);
02721                                 return (NOT_GRANTED);
02722                         }
02723                         /* if sec_officer, then grant */
02724                         if (i_attr_val1.system_role == SR_security_officer)
02725                                 return (GRANTED);
02726                         else
02727                                 return (NOT_GRANTED);
02728 #endif
02729 
02730                         /* all other cases are unknown */
02731                 default:
02732                         return (DO_NOT_CARE);
02733                 }
02734 
02735         case R_MODIFY_SYSTEM_DATA:
02736                 switch (target) {
02737                 case T_SCD:
02738                         /* target rlimit? no problem, but needed -> grant */
02739                         if (tid.scd == ST_rlimit)
02740                                 return (GRANTED);
02741                         /* Get role */
02742                         i_tid.user = owner;
02743                         if (rsbac_get_attr(SW_MAC,
02744                                            T_USER,
02745                                            i_tid,
02746                                            A_mac_role,
02747                                            &i_attr_val1, TRUE)) {
02748                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02749                                                    A_none);
02750                                 return NOT_GRANTED;
02751                         }
02752                         /* if rsbaclog: grant only for secoff and auditor */
02753                         if (tid.scd == ST_rsbac_log) {
02754                                 if ((i_attr_val1.system_role ==
02755                                      SR_security_officer)
02756                                     || (i_attr_val1.system_role ==
02757                                         SR_auditor)
02758                                     )
02759                                         return (GRANTED);
02760                                 else
02761                                         return (NOT_GRANTED);
02762                         }
02763                         /* if rsbac_log_remote: grant only for secoff */
02764                         if (tid.scd == ST_rsbac_remote_log) {
02765                                 if ((i_attr_val1.system_role ==
02766                                      SR_security_officer)
02767                                     )
02768                                         return (GRANTED);
02769                                 else
02770                                         return (NOT_GRANTED);
02771                         }
02772                         /* if rsbac: grant for secoff and adminr */
02773                         if (tid.scd == ST_rsbac) {
02774                                 if ((i_attr_val1.system_role ==
02775                                      SR_security_officer)
02776                                     || (i_attr_val1.system_role ==
02777                                         SR_administrator)
02778                                     )
02779                                         return (GRANTED);
02780                                 else
02781                                         return (NOT_GRANTED);
02782                         }
02783                         /* if administrator, then grant */
02784                         if (i_attr_val1.system_role == SR_administrator)
02785                                 return (GRANTED);
02786                         else
02787                                 return (NOT_GRANTED);
02788 
02789                 case T_DEV:
02790                         if (tid.dev.type == D_block)
02791                                 return mac_check_role(owner,
02792                                                       SR_administrator);
02793                         else
02794                                 return DO_NOT_CARE;
02795 
02796                 case T_PROCESS:
02797                         /* and perform auto-write without setting attributes */
02798                         return (auto_write_attr(caller_pid,
02799                                                 target,
02800                                                 tid,
02801                                                 A_current_sec_level,
02802                                                 A_mac_curr_categories,
02803                                                 FALSE));
02804 
02805 #ifdef CONFIG_RSBAC_MAC_NET_DEV_PROT
02806                 case T_NETDEV:
02807                         return mac_check_role(owner, SR_administrator);
02808 #endif
02809 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
02810                 case T_NETOBJ:
02811                         /* and perform auto-write without setting attributes */
02812                         return (auto_write_attr(caller_pid,
02813                                                 target,
02814                                                 tid,
02815                                                 A_local_sec_level,
02816                                                 A_local_mac_categories,
02817                                                 FALSE));
02818 #endif
02819 
02820                         /* all other cases are unknown */
02821                 default:
02822                         return (DO_NOT_CARE);
02823                 }
02824 
02825         case R_MOUNT:
02826                 switch (target) {
02827                 case T_FILE:
02828                 case T_DIR:
02829                 case T_DEV:
02830                         /* test owner's mac_role: Administrator? */
02831 #ifndef CONFIG_RSBAC_MAC_LIGHT
02832                         if (mac_check_role(owner, SR_administrator) ==
02833                             NOT_GRANTED)
02834                                 return (NOT_GRANTED);
02835 #endif
02836                         /* test read-write access to mount dir / dev: */
02837                         /* and perform auto-read(-write) without setting of attributes */
02838                         if ((target == T_DEV)
02839                             && (attr == A_mode)
02840                             && (attr_val.mode & MS_RDONLY))
02841                                 return (auto_read(caller_pid,
02842                                                   target, tid, FALSE));
02843                         else
02844                                 return (auto_read_write(caller_pid,
02845                                                         target,
02846                                                         tid, FALSE));
02847 
02848                         /* all other cases are unknown */
02849                 default:
02850                         return (DO_NOT_CARE);
02851                 }
02852 
02853         case R_READ:
02854                 switch (target) {
02855                 case T_DIR:
02856 #ifdef CONFIG_RSBAC_RW
02857                 case T_IPC:
02858                 case T_FILE:
02859                 case T_FIFO:
02860                 case T_UNIXSOCK:
02861 #endif
02862                         /* and perform auto-read without setting attributes */
02863                         return (auto_read(caller_pid, target, tid, FALSE));
02864                         break;
02865 
02866 #ifdef CONFIG_RSBAC_RW
02867                 case T_DEV:
02868                         /* Only check for devices with mac_check set */
02869                         if (rsbac_get_attr(SW_MAC,
02870                                            T_DEV,
02871                                            tid,
02872                                            A_mac_check,
02873                                            &i_attr_val1, FALSE)) {
02874                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02875                                                    A_none);
02876                                 return (NOT_GRANTED);
02877                         }
02878                         if (!i_attr_val1.mac_check)
02879                                 return (DO_NOT_CARE);
02880                         /* and perform auto-read without setting attributes */
02881                         return (auto_read(caller_pid, target, tid, FALSE));
02882                         break;
02883 #endif
02884 
02885 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
02886                 case T_NETTEMP:
02887                         if (mac_check_role(owner, SR_security_officer) ==
02888                             GRANTED)
02889                                 return GRANTED;
02890                         return mac_check_role(owner, SR_administrator);
02891 
02892                 case T_NETOBJ:
02893                         /* and perform auto-read without setting attributes */
02894                         return (auto_read_attr(caller_pid,
02895                                                target,
02896                                                tid,
02897                                                A_remote_sec_level,
02898                                                A_remote_mac_categories,
02899                                                FALSE));
02900 #endif
02901 
02902 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
02903                 case T_USER:
02904                         /* Security Officer or Admin? */
02905                         if (mac_check_role(owner, SR_security_officer) ==
02906                             GRANTED)
02907                                 return GRANTED;
02908                         else
02909                                 return mac_check_role(owner,
02910                                                       SR_administrator);
02911 #endif
02912                         /* all other cases are unknown */
02913                 default:
02914                         return (DO_NOT_CARE);
02915                 }
02916 
02917 
02918         case R_READ_ATTRIBUTE:
02919                 switch (attr) {
02920                 case A_owner:
02921                 case A_security_level:
02922                 case A_local_sec_level:
02923                 case A_remote_sec_level:
02924                 case A_min_security_level:
02925                 case A_mac_categories:
02926                 case A_local_mac_categories:
02927                 case A_remote_mac_categories:
02928                 case A_mac_min_categories:
02929                 case A_pseudo:
02930                 case A_system_role:
02931                 case A_mac_role:
02932                 case A_current_sec_level:
02933                 case A_min_write_open:
02934                 case A_max_read_open:
02935                 case A_mac_user_flags:
02936                 case A_mac_process_flags:
02937                 case A_mac_check:
02938                 case A_mac_auto:
02939                 case A_mac_prop_trusted:
02940                 case A_mac_file_flags:
02941                 case A_initial_security_level:
02942                 case A_mac_initial_categories:
02943                 case A_symlink_add_mac_level:
02944 #ifdef CONFIG_RSBAC_MAC_GEN_PROT
02945                 case A_log_array_low:
02946                 case A_log_array_high:
02947                 case A_log_program_based:
02948                 case A_log_user_based:
02949                 case A_symlink_add_remote_ip:
02950                 case A_symlink_add_uid:
02951                 case A_fake_root_uid:
02952                 case A_audit_uid:
02953                 case A_auid_exempt:
02954                 case A_remote_ip:
02955                 case A_kernel_thread:
02956 #endif
02957 #ifdef CONFIG_RSBAC_MAC_AUTH_PROT
02958                 case A_auth_may_setuid:
02959                 case A_auth_may_set_cap:
02960                 case A_auth_start_uid:
02961                 case A_auth_start_euid:
02962                 case A_auth_start_gid:
02963                 case A_auth_start_egid:
02964                 case A_auth_program_file:
02965                 case A_auth_learn:
02966                 case A_auth_last_auth:
02967 #endif
02968                         /* Security Officer ot Admin? */
02969                         if (mac_check_role(owner, SR_security_officer) ==
02970                             GRANTED)
02971                                 return GRANTED;
02972                         else
02973                                 return mac_check_role(owner,
02974                                                       SR_administrator);
02975 
02976                 default:
02977                         return (DO_NOT_CARE);
02978                 }
02979 
02980         case R_READ_OPEN:
02981                 switch (target) {
02982                 case T_FILE:
02983                 case T_DIR:
02984                 case T_FIFO:
02985                 case T_UNIXSOCK:
02986                 case T_IPC:
02987                         /* and perform auto-read without setting attributes */
02988                         return (auto_read(caller_pid, target, tid, FALSE));
02989                         break;
02990                 case T_DEV:
02991                         /* Only check for devices with mac_check set */
02992                         if (rsbac_get_attr(SW_MAC,
02993                                            T_DEV,
02994                                            tid,
02995                                            A_mac_check,
02996                                            &i_attr_val1, FALSE)) {
02997                                 rsbac_ds_get_error("rsbac_adf_request_mac",
02998                                                    A_none);
02999                                 return (NOT_GRANTED);
03000                         }
03001                         if (!i_attr_val1.mac_check)
03002                                 return (DO_NOT_CARE);
03003                         /* and perform auto-read without setting attributes */
03004                         return (auto_read(caller_pid, target, tid, FALSE));
03005                         break;
03006                         /* all other cases are unknown */
03007                 default:
03008                         return (DO_NOT_CARE);
03009                 }
03010 
03011         case R_READ_WRITE_OPEN:
03012                 switch (target) {
03013                 case T_FILE:
03014                 case T_FIFO:
03015                 case T_UNIXSOCK:
03016                 case T_IPC:
03017                         /* and perform auto-read-write without setting attributes */
03018                         return (auto_read_write(caller_pid,
03019                                                 target, tid, FALSE));
03020 
03021                 case T_DEV:
03022                         /* Only check for devices with mac_check set */
03023                         if (rsbac_get_attr(SW_MAC,
03024                                            T_DEV,
03025                                            tid,
03026                                            A_mac_check,
03027                                            &i_attr_val1, FALSE)) {
03028                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03029                                                    A_none);
03030                                 return (NOT_GRANTED);
03031                         }
03032                         if (!i_attr_val1.mac_check)
03033                                 return (DO_NOT_CARE);
03034                         /* and perform auto-read-write without setting attributes */
03035                         return (auto_read_write(caller_pid,
03036                                                 target, tid, FALSE));
03037 
03038                         /* all other cases are unknown */
03039                 default:
03040                         return (DO_NOT_CARE);
03041                 }
03042 
03043         case R_REMOVE_FROM_KERNEL:
03044                 switch (target) {
03045                 case T_FILE:
03046                 case T_DEV:
03047                 case T_NONE:
03048                         /* test owner's mac_role */
03049                         return mac_check_role(owner, SR_administrator);
03050 
03051                         /* all other cases are unknown */
03052                 default:
03053                         return (DO_NOT_CARE);
03054                 }
03055 
03056         case R_SHUTDOWN:
03057                 switch (target) {
03058                 case T_NONE:
03059                         /* test owner's mac_role */
03060                         return mac_check_role(owner, SR_administrator);
03061 
03062                         /* all other cases are unknown */
03063                 default:
03064                         return (DO_NOT_CARE);
03065                 }
03066 
03067         case R_RENAME:
03068                 switch (target) {
03069                 case T_FILE:
03070                 case T_DIR:
03071                 case T_FIFO:
03072                 case T_SYMLINK:
03073                 case T_UNIXSOCK:
03074                         /* and perform auto-write without setting attributes */
03075                         result = auto_write(caller_pid,
03076                                             target, tid, FALSE);
03077                         /* if parent dir might change, convert inherit to explicit level/cat:
03078                            get and set effective value */
03079                         if (((result == GRANTED)
03080                              || (result == DO_NOT_CARE)
03081                             )
03082                             && ((attr != A_new_dir_dentry_p)
03083                                 || (attr_val.new_dir_dentry_p !=
03084                                     tid.file.dentry_p->d_parent)
03085                             )
03086                             ) {
03087                                 if (rsbac_get_attr(SW_MAC, target, tid, A_security_level, &i_attr_val1, TRUE)) {        /* failed! */
03088                                         rsbac_ds_get_error
03089                                             ("rsbac_adf_request_mac",
03090                                              A_none);
03091                                         return (NOT_GRANTED);
03092                                 }
03093                                 if (rsbac_set_attr(SW_MAC, target, tid, A_security_level, i_attr_val1)) {       /* failed! */
03094                                         rsbac_ds_set_error
03095                                             ("rsbac_adf_request_mac",
03096                                              A_none);
03097                                         return (NOT_GRANTED);
03098                                 }
03099                                 if (rsbac_get_attr(SW_MAC, target, tid, A_mac_categories, &i_attr_val1, TRUE)) {        /* failed! */
03100                                         rsbac_ds_get_error
03101                                             ("rsbac_adf_request_mac",
03102                                              A_none);
03103                                         return (NOT_GRANTED);
03104                                 }
03105                                 if (rsbac_set_attr(SW_MAC, target, tid, A_mac_categories, i_attr_val1)) {       /* failed! */
03106                                         rsbac_ds_set_error
03107                                             ("rsbac_adf_request_mac",
03108                                              A_none);
03109                                         return (NOT_GRANTED);
03110                                 }
03111                         }
03112                         return result;
03113                         break;
03114 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
03115                 case T_USER:
03116                 case T_GROUP:
03117                         /* Security Officer? */
03118                         return mac_check_role(owner, SR_security_officer);
03119 #endif
03120                         /* all other cases are unknown */
03121                 default:
03122                         return (DO_NOT_CARE);
03123                 }
03124 
03125 
03126         case R_SEARCH:
03127                 switch (target) {
03128                 case T_DIR:
03129                 case T_SYMLINK:
03130                 case T_UNIXSOCK:
03131                         /* and perform auto-read without setting attributes */
03132                         return (auto_read(caller_pid, target, tid, FALSE));
03133                         break;
03134                         /* all other cases are unknown */
03135                 default:
03136                         return (DO_NOT_CARE);
03137                 }
03138 
03139         case R_SEND_SIGNAL:
03140                 switch (target) {
03141                 case T_PROCESS:
03142                         /* and perform auto-write without setting attributes */
03143                         return (auto_write_attr(caller_pid,
03144                                                 target,
03145                                                 tid,
03146                                                 A_current_sec_level,
03147                                                 A_mac_curr_categories,
03148                                                 FALSE));
03149 
03150                         /* all other cases are unknown */
03151                 default:
03152                         return (DO_NOT_CARE);
03153                 }
03154 
03155         case R_SWITCH_LOG:
03156                 switch (target) {
03157                 case T_NONE:
03158                         /* test owner's mac_role */
03159                         return mac_check_role(owner, SR_security_officer);
03160 
03161                         /* all other cases are unknown */
03162                 default:
03163                         return (DO_NOT_CARE);
03164                 }
03165 
03166         case R_SWITCH_MODULE:
03167                 switch (target) {
03168                 case T_NONE:
03169                         /* we need the switch_target */
03170                         if (attr != A_switch_target)
03171                                 return (UNDEFINED);
03172                         /* do not care for other modules */
03173                         if ((attr_val.switch_target != SW_MAC)
03174 #ifdef CONFIG_RSBAC_MAC_AUTH_PROT
03175                             && (attr_val.switch_target != SW_AUTH)
03176 #endif
03177 #ifdef CONFIG_RSBAC_SOFTMODE
03178                             && (attr_val.switch_target != SW_SOFTMODE)
03179 #endif
03180 #ifdef CONFIG_RSBAC_FREEZE
03181                             && (attr_val.switch_target != SW_FREEZE)
03182 #endif
03183                             )
03184                                 return (DO_NOT_CARE);
03185                         /* test owner's mac_role */
03186                         return mac_check_role(owner, SR_security_officer);
03187 
03188                         /* all other cases are unknown */
03189                 default:
03190                         return (DO_NOT_CARE);
03191                 }
03192 
03193         case R_TRACE:
03194                 switch (target) {
03195                 case T_PROCESS:
03196                         /* and perform auto-read-write without setting attributes */
03197                         return (auto_read_write_attr(caller_pid,
03198                                                      target,
03199                                                      tid,
03200                                                      A_current_sec_level,
03201                                                      A_mac_curr_categories,
03202                                                      FALSE));
03203 
03204                         /* all other cases are unknown */
03205                 default:
03206                         return (DO_NOT_CARE);
03207                 }
03208 
03209         case R_TRUNCATE:
03210                 switch (target) {
03211                 case T_FILE:
03212                         /* and perform auto-write without setting attributes */
03213                         return (auto_write(caller_pid,
03214                                            target, tid, FALSE));
03215                         break;
03216                         /* all other cases are unknown */
03217                 default:
03218                         return (DO_NOT_CARE);
03219                 }
03220 
03221         case R_UMOUNT:
03222                 switch (target) {
03223                 case T_FILE:
03224                 case T_DIR:
03225                 case T_DEV:
03226 #ifdef CONFIG_RSBAC_MAC_LIGHT
03227                         return (GRANTED);
03228 #else
03229                         return mac_check_role(owner, SR_administrator);
03230 #endif
03231                         /* all other cases are unknown */
03232                 default:
03233                         return (DO_NOT_CARE);
03234                 }
03235 
03236         case R_WRITE:
03237                 switch (target) {
03238                 case T_DIR:
03239                 case T_IPC:
03240 #ifdef CONFIG_RSBAC_RW
03241                 case T_FILE:
03242                 case T_FIFO:
03243                 case T_UNIXSOCK:
03244 #endif
03245                         /* Mode of created item is ignored! */
03246                         /* and perform auto-write without setting attributes */
03247                         return (auto_write(caller_pid,
03248                                            target, tid, FALSE));
03249 
03250 
03251 #ifdef CONFIG_RSBAC_RW
03252                 case T_DEV:
03253                         /* Only check for devices with mac_check set */
03254                         if (rsbac_get_attr(SW_MAC,
03255                                            T_DEV,
03256                                            tid,
03257                                            A_mac_check,
03258                                            &i_attr_val1, FALSE)) {
03259                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03260                                                    A_none);
03261                                 return (NOT_GRANTED);
03262                         }
03263                         if (!i_attr_val1.mac_check)
03264                                 return (DO_NOT_CARE);
03265                         /* and perform auto-write without setting attributes */
03266                         return (auto_write(caller_pid,
03267                                            target, tid, FALSE));
03268                         break;
03269 #endif
03270 
03271 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
03272                 case T_NETTEMP:
03273                         return mac_check_role(owner, SR_security_officer);
03274 
03275                 case T_NETOBJ:
03276                         /* test write access to target: get its sec_level */
03277                         if (rsbac_get_attr(SW_MAC,
03278                                            target,
03279                                            tid,
03280                                            A_remote_sec_level,
03281                                            &i_attr_val1, TRUE)) {
03282                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03283                                                    A_none);
03284                                 return (NOT_GRANTED);
03285                         }
03286                         if (rsbac_get_attr(SW_MAC,
03287                                            target,
03288                                            tid,
03289                                            A_remote_mac_categories,
03290                                            &i_attr_val2, TRUE)) {
03291                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03292                                                    A_none);
03293                                 return (NOT_GRANTED);
03294                         }
03295                         /* and perform auto-write without setting attributes */
03296                         return (auto_write_attr(caller_pid,
03297                                                 target,
03298                                                 tid,
03299                                                 A_remote_sec_level,
03300                                                 A_remote_mac_categories,
03301                                                 FALSE));
03302 #endif
03303 
03304 #if defined(CONFIG_RSBAC_MAC_UM_PROT)
03305                 case T_USER:
03306                 case T_GROUP:
03307                         /* Security Officer? */
03308                         return mac_check_role(owner, SR_security_officer);
03309 #endif
03310                         /* all other cases are unknown */
03311                 default:
03312                         return (DO_NOT_CARE);
03313                 }
03314 
03315         case R_WRITE_OPEN:
03316                 switch (target) {
03317                 case T_FILE:
03318                 case T_FIFO:
03319                 case T_UNIXSOCK:
03320                 case T_IPC:
03321                         /* and perform auto-write without setting attributes */
03322                         return (auto_write(caller_pid,
03323                                            target, tid, FALSE));
03324                         break;
03325                 case T_DEV:
03326                         /* Only check for devices with mac_check set */
03327                         if (rsbac_get_attr(SW_MAC,
03328                                            T_DEV,
03329                                            tid,
03330                                            A_mac_check,
03331                                            &i_attr_val1, FALSE)) {
03332                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03333                                                    A_none);
03334                                 return (NOT_GRANTED);
03335                         }
03336                         if (!i_attr_val1.mac_check)
03337                                 return (DO_NOT_CARE);
03338                         /* and perform auto-write without setting attributes */
03339                         return (auto_write(caller_pid,
03340                                            target, tid, FALSE));
03341 
03342                         /* all other cases are unknown */
03343                 default:
03344                         return (DO_NOT_CARE);
03345                 }
03346 
03347         case R_SEND:
03348                 switch (target) {
03349                 case T_DEV:
03350                         /* Only check for devices with mac_check set */
03351                         if (rsbac_get_attr(SW_MAC,
03352                                            T_DEV,
03353                                            tid,
03354                                            A_mac_check,
03355                                            &i_attr_val1, FALSE)) {
03356                                 rsbac_ds_get_error("rsbac_adf_request_mac",
03357                                                    A_none);
03358                                 return (NOT_GRANTED);
03359                         }
03360                         if (!i_attr_val1.mac_check)
03361                                 return (DO_NOT_CARE);
03362                         /* and perform auto-write without setting attributes */
03363                         return (auto_write(caller_pid,
03364                                            target, tid, FALSE));
03365 
03366                 case T_UNIXSOCK:
03367                         return (auto_write(caller_pid,
03368                                            target, tid, FALSE));
03369 
03370 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
03371                 case T_NETOBJ:
03372                         /* and perform auto-read-write without setting attributes */
03373                         return (auto_read_write_attr(caller_pid,
03374                                                      target,
03375                                                      tid,
03376                                                      A_remote_sec_level,
03377                                                      A_remote_mac_categories,
03378                                                      FALSE));
03379 
03380 #endif
03381                         /* all other cases are unknown */
03382                 default:
03383                         return (DO_NOT_CARE);
03384                 }
03385 
03386         case R_BIND:
03387         case R_LISTEN:
03388                 switch (target) {
03389                 case T_UNIXSOCK:
03390                         return (auto_read(caller_pid,
03391                                            target, tid, FALSE));
03392 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
03393                 case T_NETOBJ:
03394                         /* and perform auto-read-write without setting attributes */
03395                         return (auto_read_write_attr(caller_pid,
03396                                                      target,
03397                                                      tid,
03398                                                      A_local_sec_level,
03399                                                      A_local_mac_categories,
03400                                                      FALSE));
03401 
03402                         /* all other cases are unknown */
03403 #endif
03404                 default:
03405                         return (DO_NOT_CARE);
03406                 }
03407 
03408         case R_ACCEPT:
03409         case R_CONNECT:
03410         case R_RECEIVE:
03411                 switch (target) {
03412                 case T_UNIXSOCK:
03413                         return (auto_read_write(caller_pid,
03414                                            target, tid, FALSE));
03415 #if defined(CONFIG_RSBAC_MAC_NET_OBJ_PROT)
03416                 case T_NETOBJ:
03417                         /* and perform auto-read-write without setting attributes */
03418                         return (auto_read_write_attr(caller_pid,
03419                                                      target,
03420                                                      tid,
03421                                                      A_remote_sec_level,
03422                                                      A_remote_mac_categories,
03423                                                      FALSE));
03424 #endif
03425                         /* all other cases are unknown */
03426                 default:
03427                         return (DO_NOT_CARE);
03428                 }
03429 
03430         default:
03431                 return DO_NOT_CARE;
03432         }
03433 
03434         return result;
03435 }
03436 
03437 
03438 /*****************************************************************************/
03439 /* If the request returned granted and the operation is performed,           */
03440 /* the following function can be called by the AEF to get all aci set        */
03441 /* correctly. For write accesses that are performed fully within the kernel, */
03442 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
03443 /* cleaning up. Because of this, the write boundary is not adjusted - there  */
03444 /* is no user-level writing anyway...                                        */
03445 /* The second instance of target specification is the new target, if one has */
03446 /* been created, otherwise its values are ignored.                           */
03447 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
03448 
03449 inline int rsbac_adf_set_attr_mac(enum rsbac_adf_request_t request,
03450                            rsbac_pid_t caller_pid,
03451                            enum rsbac_target_t target,
03452                            union rsbac_target_id_t tid,
03453                            enum rsbac_target_t new_target,
03454                            union rsbac_target_id_t new_tid,
03455                            enum rsbac_attribute_t attr,
03456                            union rsbac_attribute_value_t attr_val,
03457                            rsbac_uid_t owner)
03458 {
03459         enum rsbac_adf_req_ret_t result = DO_NOT_CARE;
03460         union rsbac_target_id_t i_tid;
03461         union rsbac_attribute_value_t i_attr_val1;
03462         union rsbac_attribute_value_t i_attr_val2;
03463         union rsbac_attribute_value_t i_attr_val3;
03464         union rsbac_attribute_value_t i_attr_val4;
03465         union rsbac_attribute_value_t i_attr_val5;
03466         union rsbac_attribute_value_t i_attr_val6;
03467         union rsbac_attribute_value_t i_attr_val7;
03468         union rsbac_attribute_value_t i_attr_val8;
03469         union rsbac_attribute_value_t i_attr_val9;
03470         rsbac_boolean_t inherit;
03471 
03472         switch (request) {
03473         case R_APPEND_OPEN:
03474                 switch (target) {
03475                 case T_FILE:
03476                 case T_FIFO:
03477                 case T_UNIXSOCK:
03478                 case T_IPC:
03479                         /* test write access to target: get its sec_level */
03480                         if ((target == T_FILE)
03481                             || (target == T_FIFO)
03482                             )
03483                                 inherit = TRUE;
03484                         else
03485                                 inherit = FALSE;
03486                         if (rsbac_get_attr(SW_MAC,
03487                                            target,
03488                                            tid,
03489                                            A_security_level,
03490                                            &i_attr_val1, inherit)) {
03491                                 rsbac_ds_get_error
03492                                     ("rsbac_adf_set_attr_mac", A_none);
03493                                 return (-RSBAC_EREADFAILED);
03494                         }
03495                         if (rsbac_get_attr(SW_MAC,
03496                                            target,
03497                                            tid,
03498                                            A_mac_categories,
03499                                            &i_attr_val2, inherit)) {
03500                                 rsbac_ds_get_error
03501                                     ("rsbac_adf_set_attr_mac", A_none);
03502                                 return (-RSBAC_EREADFAILED);
03503                         }
03504                         /* and perform auto-write with setting attributes */
03505                         result = auto_write(caller_pid, target, tid, TRUE);
03506                         if ((result == GRANTED) || (result == DO_NOT_CARE))
03507                                 return 0;
03508                         else
03509                                 return (-RSBAC_EDECISIONMISMATCH);
03510                         break;
03511                 case T_DEV:
03512                         /* Only check for devices with mac_check set */
03513                         if (rsbac_get_attr(SW_MAC,
03514                                            T_DEV,
03515                                            tid,
03516                                            A_mac_check,
03517                                            &i_attr_val1, FALSE)) {
03518                                 rsbac_ds_get_error
03519                                     ("rsbac_adf_set_attr_mac", A_none);
03520                                 return (-RSBAC_EREADFAILED);
03521                         }
03522                         if (!i_attr_val1.mac_check)
03523                                 return 0;
03524                         /* and perform auto-write with setting attributes */
03525                         result = auto_write(caller_pid, target, tid, TRUE);
03526                         if ((result == GRANTED) || (result == DO_NOT_CARE))
03527                                 return 0;
03528                         else
03529                                 return (-RSBAC_EDECISIONMISMATCH);
03530                         break;
03531                         /* all other cases are unknown */
03532                 default:
03533                         return 0;
03534                 }
03535 
03536         case R_CHANGE_OWNER:
03537                 switch (target) {
03538                         /*  Changing process owner affects access decisions, */
03539                         /*  so attributes have to be adjusted.               */
03540                 case T_PROCESS:
03541                         /* For target process there MUST be a new owner specified */
03542                         if (attr != A_owner)
03543                                 return (-RSBAC_EINVALIDATTR);
03544 
03545                         /* Get owner-sec-level and mac_categories for new owner */
03546                         i_tid.user = attr_val.owner;
03547                         if (rsbac_get_attr(SW_MAC,
03548                                            T_USER,
03549                                            i_tid,
03550                                            A_security_level,
03551                                            &i_attr_val2, TRUE)) {
03552                                 rsbac_ds_get_error
03553                                     ("rsbac_adf_set_attr_mac", A_none);
03554                                 return (-RSBAC_EREADFAILED);
03555                         }
03556                         if (rsbac_get_attr(SW_MAC,
03557                                            T_USER,
03558                                            i_tid,
03559                                            A_mac_categories,
03560                                            &i_attr_val3, TRUE)) {
03561                                 rsbac_ds_get_error
03562                                     ("rsbac_adf_set_attr_mac", A_none);
03563                                 return (-RSBAC_EREADFAILED);
03564                         }
03565                         /* set owner-sec-level and mac_categories for process to new values */
03566                         if (rsbac_set_attr(SW_MAC,
03567                                            T_PROCESS,
03568                                            tid,
03569                                            A_security_level,
03570                                            i_attr_val2)) {
03571                                 rsbac_ds_set_error
03572                                     ("rsbac_adf_set_attr_mac", A_none);
03573                                 return (-RSBAC_EWRITEFAILED);
03574                         }
03575                         if (rsbac_set_attr(SW_MAC,
03576                                            T_PROCESS,
03577                                            tid,
03578                                            A_mac_categories,
03579                                            i_attr_val3)) {
03580                                 rsbac_ds_set_error
03581                                     ("rsbac_adf_set_attr_mac", A_none);
03582                                 return (-RSBAC_EWRITEFAILED);
03583                         }
03584                         /* Get min_write_open and min_write_categories of process */
03585                         if (rsbac_get_attr(SW_MAC,
03586                                            T_PROCESS,
03587                                            tid,
03588                                            A_min_write_open,
03589                                            &i_attr_val4, TRUE)) {
03590                                 rsbac_ds_get_error
03591                                     ("rsbac_adf_set_attr_mac", A_none);
03592                                 return (-RSBAC_EREADFAILED);
03593                         }
03594                         if (rsbac_get_attr(SW_MAC,
03595                                            T_PROCESS,
03596                                            tid,
03597                                            A_min_write_categories,
03598                                            &i_attr_val5, TRUE)) {
03599                                 rsbac_ds_get_error
03600                                     ("rsbac_adf_set_attr_mac", A_none);
03601                                 return (-RSBAC_EREADFAILED);
03602                         }
03603                         /* adjust min_write_open and min_write_categories, if too high */
03604                         if (i_attr_val2.security_level <
03605                             i_attr_val4.min_write_open) {
03606                                 i_attr_val4.min_write_open =
03607                                     i_attr_val2.security_level;
03608                                 if (rsbac_set_attr
03609                                     (SW_MAC, T_PROCESS, tid, A_min_write_open,
03610                                      i_attr_val4)) {
03611                                         rsbac_ds_set_error
03612                                             ("rsbac_adf_set_attr_mac",
03613                                              A_none);
03614                                         return (-RSBAC_EWRITEFAILED);
03615                                 }
03616                         }
03617                         /* does process have categories in min_write
03618                          * that the new owner has not? */
03619                         /* If yes, throw them out. */
03620                         if ((i_attr_val3.mac_categories & i_attr_val5.
03621                              mac_categories)
03622                             != i_attr_val5.mac_categories) {
03623                                 i_attr_val5.mac_categories &=
03624                                     i_attr_val3.mac_categories;
03625                                 if (rsbac_set_attr
03626                                     (SW_MAC, T_PROCESS, tid,
03627                                      A_min_write_categories,
03628                                      i_attr_val5)) {
03629                                         rsbac_ds_set_error
03630                                             ("rsbac_adf_set_attr_mac",
03631                                              A_none);
03632                                         return (-RSBAC_EWRITEFAILED);
03633                                 }
03634                         }
03635                         /* Get owner-initial-sec-level and
03636                          * mac_initial_categories for new owner */
03637                         /* These values will be adjusted by 
03638                          * max_read / min_write and then used as */
03639                         /* new current level/categories. */
03640                         i_tid.user = owner;
03641                         if (rsbac_get_attr(SW_MAC,
03642                                            T_USER,
03643                                            i_tid,
03644                                            A_initial_security_level,
03645                                            &i_attr_val6, TRUE)) {
03646                                 rsbac_ds_get_error
03647                                     ("rsbac_adf_set_attr_mac", A_none);
03648                                 return (-RSBAC_EREADFAILED);
03649                         }
03650                         if (rsbac_set_attr(SW_MAC,
03651                                            T_PROCESS,
03652                                            tid,
03653                                            A_initial_security_level,
03654                                            i_attr_val6)) {
03655                                 rsbac_ds_set_error
03656                                     ("rsbac_adf_set_attr_mac", A_none);
03657                                 return (-RSBAC_EWRITEFAILED);
03658                         }
03659 #if 0
03660                         /* restrict current_level to be a maximum of min_write */
03661                         if (i_attr_val6.security_level >
03662                             i_attr_val4.min_write_open)
03663                                 i_attr_val6.security_level =
03664                                     i_attr_val4.min_write_open;
03665 #endif
03666                         if (rsbac_get_attr(SW_MAC,
03667                                            T_USER,
03668                                            i_tid,
03669                                            A_mac_initial_categories,
03670                                            &i_attr_val7, TRUE)) {
03671                                 rsbac_ds_get_error
03672                                     ("rsbac_adf_set_attr_mac", A_none);
03673                                 return (-RSBAC_EREADFAILED);
03674                         }
03675                         if (rsbac_set_attr(SW_MAC,
03676                                            T_PROCESS,
03677                                            tid,
03678                                            A_mac_initial_categories,
03679                                            i_attr_val7)) {
03680                                 rsbac_ds_set_error
03681                                     ("rsbac_adf_set_attr_mac", A_none);
03682                                 return (-RSBAC_EWRITEFAILED);
03683                         }
03684 #if 0
03685                         /* restrict current_categories to be a maximum of min_write */
03686                         if ((i_attr_val7.mac_categories & i_attr_val5.
03687                              mac_categories) != i_attr_val7.mac_categories)
03688                                 i_attr_val7.mac_categories &=
03689                                     i_attr_val5.mac_categories;
03690 #endif
03691                         /* Get owner-min-sec-level and mac_min_categories for new owner */
03692                         i_tid.user = owner;
03693                         if (rsbac_get_attr(SW_MAC,
03694                                            T_USER,
03695                                            i_tid,
03696                                            A_min_security_level,
03697                                            &i_attr_val8, TRUE)) {
03698                                 rsbac_ds_get_error
03699                                     ("rsbac_adf_set_attr_mac", A_none);
03700                                 return (-RSBAC_EREADFAILED);
03701                         }
03702                         if (rsbac_get_attr(SW_MAC,
03703                                            T_USER,
03704                                            i_tid,
03705                                            A_mac_min_categories,
03706                                            &i_attr_val9, TRUE)) {
03707                                 rsbac_ds_get_error
03708                                     ("rsbac_adf_set_attr_mac", A_none);
03709                                 return (-RSBAC_EREADFAILED);
03710                         }
03711                         /* set owner-sec-level and mac_categories for process to new values */
03712                         /* owner is set by main dispatcher! */
03713                         if (rsbac_set_attr(SW_MAC,
03714                                            T_PROCESS,
03715                                            tid,
03716                                            A_min_security_level,
03717                                            i_attr_val8)) {
03718                                 rsbac_ds_set_error
03719                                     ("rsbac_adf_set_attr_mac", A_none);
03720                                 return (-RSBAC_EWRITEFAILED);
03721                         }
03722                         if (rsbac_set_attr(SW_MAC,
03723                                            T_PROCESS,
03724                                            tid,
03725                                            A_mac_min_categories,
03726                                            i_attr_val9)) {
03727                                 rsbac_ds_set_error
03728                                     ("rsbac_adf_set_attr_mac", A_none);
03729                                 return (-RSBAC_EWRITEFAILED);
03730                         }
03731                         /* Get max_read_open and max_read_categories of process */
03732                         if (rsbac_get_attr(SW_MAC,
03733                                            T_PROCESS,
03734                                            tid,
03735                                            A_max_read_open,
03736                                            &i_attr_val4, TRUE)) {
03737                                 rsbac_ds_get_error
03738                                     ("rsbac_adf_set_attr_mac", A_none);
03739                                 return (-RSBAC_EREADFAILED);
03740                         }
03741                         if (rsbac_get_attr(SW_MAC,
03742                                            T_PROCESS,
03743                                            tid,
03744                                            A_max_read_categories,
03745                                            &i_attr_val5, TRUE)) {
03746                                 rsbac_ds_get_error
03747                                     ("rsbac_adf_set_attr_mac", A_none);
03748                                 return (-RSBAC_EREADFAILED);
03749                         }
03750                         /* adjust max_read_open and max_read_categories, if too low */
03751                         if (i_attr_val8.security_level >
03752                             i_attr_val4.max_read_open) {
03753                                 i_attr_val4.max_read_open =
03754                                     i_attr_val8.security_level;
03755                                 if (rsbac_set_attr
03756                                     (SW_MAC, T_PROCESS, tid, A_max_read_open,
03757                                      i_attr_val4)) {
03758                                         rsbac_ds_set_error
03759                                             ("rsbac_adf_set_attr_mac",
03760                                              A_none);
03761                                         return (-RSBAC_EWRITEFAILED);
03762                                 }
03763                         }
03764 #if 0
03765                         /* adjust current sec level to a minimum of max_read */
03766                         if (i_attr_val6.security_level <
03767                             i_attr_val4.max_read_open)
03768                                 i_attr_val6.security_level =
03769                                     i_attr_val4.max_read_open;
03770 #endif
03771                         /* but never set it over new max_level or under new min_level */
03772                         if (i_attr_val6.security_level >
03773                             i_attr_val2.security_level)
03774                                 i_attr_val6.security_level =
03775                                     i_attr_val2.security_level;
03776                         else if (i_attr_val6.security_level <
03777                                  i_attr_val8.security_level)
03778                                 i_attr_val6.security_level =
03779                                     i_attr_val8.security_level;
03780                         if (rsbac_set_attr
03781                             (SW_MAC, T_PROCESS, tid, A_current_sec_level,
03782                              i_attr_val6)) {
03783                                 rsbac_ds_set_error
03784                                     ("rsbac_adf_set_attr_mac", A_none);
03785                                 return (-RSBAC_EWRITEFAILED);
03786                         }
03787 
03788                         /* does new owner have categories in min_categories that the process max_read 
03789                            has not? */
03790                         /* If yes, add them. */
03791                         if ((i_attr_val9.mac_categories & i_attr_val5.
03792                              mac_categories)
03793                             != i_attr_val9.mac_categories) {
03794                                 i_attr_val5.mac_categories |=
03795                                     i_attr_val9.mac_categories;
03796                                 if (rsbac_set_attr
03797                                     (SW_MAC, T_PROCESS, tid,
03798                                      A_max_read_categories, i_attr_val5)) {
03799                                         rsbac_ds_set_error
03800                                             ("rsbac_adf_set_attr_mac",
03801                                              A_none);
03802                                         return (-RSBAC_EWRITEFAILED);
03803                                 }
03804                         }
03805 #if 0
03806                         /* adjust current categories to include all from max_read (from initial) */
03807                         if ((i_attr_val7.mac_categories & i_attr_val5.
03808                              mac_categories) != i_attr_val5.mac_categories)
03809                                 i_attr_val7.mac_categories |=
03810                                     i_attr_val5.mac_categories;
03811 #endif
03812                         /* but never set it over new max_cats or under new min_cats */
03813                         if ((i_attr_val7.mac_categories & i_attr_val3.
03814                              mac_categories) != i_attr_val7.mac_categories)
03815                                 i_attr_val7.mac_categories &=
03816                                     i_attr_val3.mac_categories;
03817                         else if ((i_attr_val7.mac_categories & i_attr_val9.
03818                                   mac_categories) !=
03819                                  i_attr_val9.mac_categories)
03820                                 i_attr_val7.mac_categories |=
03821                                     i_attr_val9.mac_categories;
03822                         if (rsbac_set_attr
03823                             (SW_MAC, T_PROCESS, tid, A_mac_curr_categories,
03824                              i_attr_val7)) {
03825                                 rsbac_ds_set_error
03826                                     ("rsbac_adf_set_attr_mac", A_none);
03827                                 return (-RSBAC_EWRITEFAILED);
03828                         }
03829 
03830                         /* Get mac_user_flags from user */
03831                         i_tid.user = attr_val.owner;
03832                         if (rsbac_get_attr(SW_MAC,
03833                                            T_USER,
03834                                            i_tid,
03835                                            A_mac_user_flags,
03836                                            &i_attr_val3, TRUE)) {
03837                                 rsbac_ds_get_error
03838                                     ("rsbac_adf_set_attr_mac", A_none);
03839                                 return (-RSBAC_EREADFAILED);
03840                         }
03841                         i_attr_val1.mac_process_flags =
03842                             i_attr_val3.mac_user_flags;
03843                         /* adjust flags - first get old process flags */
03844                         if (rsbac_get_attr(SW_MAC,
03845                                            T_PROCESS,
03846                                            tid,
03847                                            A_mac_process_flags,
03848                                            &i_attr_val2, TRUE)) {
03849                                 rsbac_ds_get_error
03850                                     ("rsbac_adf_set_attr_mac", A_none);
03851                                 return (-RSBAC_EREADFAILED);
03852                         }
03853                         if ((i_attr_val2.
03854                              mac_process_flags & MAC_program_auto)
03855                             && (i_attr_val3.
03856                                 mac_user_flags & MAC_allow_auto)
03857                             )
03858                                 i_attr_val1.mac_process_flags |= MAC_auto;
03859 
03860                         i_attr_val1.mac_process_flags &= RSBAC_MAC_P_FLAGS;
03861 
03862                         if (!(i_attr_val1.mac_process_flags & MAC_trusted)) {
03863                                 if (rsbac_mac_p_truset_member
03864                                     (caller_pid, owner))
03865                                         i_attr_val1.mac_process_flags |=
03866                                             MAC_trusted;
03867                         }
03868                         /* Set mac_process_flags on process */
03869                         if (rsbac_set_attr(SW_MAC,
03870                                            T_PROCESS,
03871                                            tid,
03872                                            A_mac_process_flags,
03873                                            i_attr_val1)) {
03874                                 rsbac_ds_set_error
03875                                     ("rsbac_adf_set_attr_mac", A_none);
03876                                 return (-RSBAC_EWRITEFAILED);
03877                         }
03878                         /* OK, we are ready */
03879                         return 0;
03880 
03881                         /* We do not care about other cases here */
03882                 default:
03883                         return 0;
03884                 }
03885 
03886         case R_CLONE:
03887                 if (target == T_PROCESS) {
03888                         /* Get owner-sec-level from first process */
03889                         if (rsbac_get_attr(SW_MAC,
03890                                            T_PROCESS,
03891                                            tid,
03892                                            A_security_level,
03893                                            &i_attr_val2, FALSE)) {
03894                                 rsbac_ds_get_error
03895                                     ("rsbac_adf_set_attr_mac", A_none);
03896                                 return (-RSBAC_EREADFAILED);
03897                         }
03898                         /* Get current-sec-level from first process... */
03899                         if (rsbac_get_attr(SW_MAC,
03900                                            T_PROCESS,
03901                                            tid,
03902                                            A_current_sec_level,
03903                                            &i_attr_val3, FALSE)) {
03904                                 rsbac_ds_get_error
03905                                     ("rsbac_adf_set_attr_mac", A_none);
03906                                 return (-RSBAC_EREADFAILED);
03907                         }
03908                         /* Get min_write_open from first process */
03909                         if (rsbac_get_attr(SW_MAC,
03910                                            T_PROCESS,
03911                                            tid,
03912                                            A_min_write_open,
03913                                            &i_attr_val4, FALSE)) {
03914                                 rsbac_ds_get_error
03915                                     ("rsbac_adf_set_attr_mac", A_none);
03916                                 return (-RSBAC_EREADFAILED);
03917                         }
03918                         /* Get max_read_open from first process */
03919                         if (rsbac_get_attr(SW_MAC,
03920                                            T_PROCESS,
03921                                            tid,
03922                                            A_max_read_open,
03923                                            &i_attr_val5, FALSE)) {
03924                                 rsbac_ds_get_error
03925                                     ("rsbac_adf_set_attr_mac", A_none);
03926                                 return (-RSBAC_EREADFAILED);
03927                         }
03928                         /* Get mac_process_flags from first process */
03929                         if (rsbac_get_attr(SW_MAC,
03930                                            T_PROCESS,
03931                                            tid,
03932                                            A_mac_process_flags,
03933                                            &i_attr_val7, FALSE)) {
03934                                 rsbac_ds_get_error
03935                                     ("rsbac_adf_set_attr_mac", A_none);
03936                                 return (-RSBAC_EREADFAILED);
03937                         }
03938                         /* Set owner_sec_level for new process */
03939                         if (rsbac_set_attr(SW_MAC,
03940                                            T_PROCESS,
03941                                            new_tid,
03942                                            A_security_level,
03943                                            i_attr_val2)) {
03944                                 rsbac_ds_set_error
03945                                     ("rsbac_adf_set_attr_mac", A_none);
03946                                 return (-RSBAC_EWRITEFAILED);
03947                         }
03948                         /* Set current_sec_level for new process */
03949                         if (rsbac_set_attr(SW_MAC,
03950                                            T_PROCESS,
03951                                            new_tid,
03952                                            A_current_sec_level,
03953                                            i_attr_val3)) {
03954                                 rsbac_ds_set_error
03955                                     ("rsbac_adf_set_attr_mac", A_none);
03956                                 return (-RSBAC_EWRITEFAILED);
03957                         }
03958                         /* Set min_write_open for new process */
03959                         if (rsbac_set_attr(SW_MAC,
03960                                            T_PROCESS,
03961                                            new_tid,
03962                                            A_min_write_open,
03963                                            i_attr_val4)) {
03964                                 rsbac_ds_set_error
03965                                     ("rsbac_adf_set_attr_mac", A_none);
03966                                 return (-RSBAC_EWRITEFAILED);
03967                         }
03968                         /* Set max_read_open for new process */
03969                         if (rsbac_set_attr(SW_MAC,
03970                                            T_PROCESS,
03971                                            new_tid,
03972                                            A_max_read_open, i_attr_val5)) {
03973                                 rsbac_ds_set_error
03974                                     ("rsbac_adf_set_attr_mac", A_none);
03975                                 return (-RSBAC_EWRITEFAILED);
03976                         }
03977                         /* Set mac_process_flags for new process */
03978                         if (rsbac_set_attr(SW_MAC,
03979                                            T_PROCESS,
03980                                            new_tid,
03981                                            A_mac_process_flags,
03982                                            i_attr_val7)) {
03983                                 rsbac_ds_set_error
03984                                     ("rsbac_adf_set_attr_mac", A_none);
03985                                 return (-RSBAC_EWRITEFAILED);
03986                         }
03987 
03988                         /* Get mac_categories from first process */
03989                         if (rsbac_get_attr(SW_MAC,
03990                                            T_PROCESS,
03991                                            tid,
03992                                            A_mac_categories,
03993                                            &i_attr_val2, FALSE)) {
03994                                 rsbac_ds_get_error
03995                                     ("rsbac_adf_set_attr_mac", A_none);
03996                                 return (-RSBAC_EREADFAILED);
03997                         }
03998                         /* Get mac_curr_categories from first process... */
03999                         if (rsbac_get_attr(SW_MAC,
04000                                            T_PROCESS,
04001                                            tid,
04002                                            A_mac_curr_categories,
04003                                            &i_attr_val3, FALSE)) {
04004                                 rsbac_ds_get_error
04005                                     ("rsbac_adf_set_attr_mac", A_none);
04006                                 return (-RSBAC_EREADFAILED);
04007                         }
04008                         /* Get min_write_categories from first process */
04009                         if (rsbac_get_attr(SW_MAC,
04010                                            T_PROCESS,
04011                                            tid,
04012                                            A_min_write_categories,
04013                                            &i_attr_val4, FALSE)) {
04014                                 rsbac_ds_get_error
04015                                     ("rsbac_adf_set_attr_mac", A_none);
04016                                 return (-RSBAC_EREADFAILED);
04017                         }
04018                         /* Get max_read_categories from first process */
04019                         if (rsbac_get_attr(SW_MAC,
04020                                            T_PROCESS,
04021                                            tid,
04022                                            A_max_read_categories,
04023                                            &i_attr_val5, FALSE)) {
04024                                 rsbac_ds_get_error
04025                                     ("rsbac_adf_set_attr_mac", A_none);
04026                                 return (-RSBAC_EREADFAILED);
04027                         }
04028                         /* Get initial_sec_level from first process */
04029                         if (rsbac_get_attr(SW_MAC,
04030                                            T_PROCESS,
04031                                            tid,
04032                                            A_initial_security_level,
04033                                            &i_attr_val6, FALSE)) {
04034                                 rsbac_ds_get_error
04035                                     ("rsbac_adf_set_attr_mac", A_none);
04036                                 return (-RSBAC_EREADFAILED);
04037                         }
04038                         /* Get initial_categories from first process */
04039                         if (rsbac_get_attr(SW_MAC,
04040                                            T_PROCESS,
04041                                            tid,
04042                                            A_mac_initial_categories,
04043                                            &i_attr_val7, FALSE)) {
04044                                 rsbac_ds_get_error
04045                                     ("rsbac_adf_set_attr_mac", A_none);
04046                                 return (-RSBAC_EREADFAILED);
04047                         }
04048                         /* Set mac_categories for new process */
04049                         if (rsbac_set_attr(SW_MAC,
04050                                            T_PROCESS,
04051                                            new_tid,
04052                                            A_mac_categories,
04053                                            i_attr_val2)) {
04054                                 rsbac_ds_set_error
04055                                     ("rsbac_adf_set_attr_mac", A_none);
04056                                 return (-RSBAC_EWRITEFAILED);
04057                         }
04058                         /* Set mac_curr_categories for new process */
04059                         if (rsbac_set_attr(SW_MAC,
04060                                            T_PROCESS,
04061                                            new_tid,
04062                                            A_mac_curr_categories,
04063                                            i_attr_val3)) {
04064                                 rsbac_ds_set_error
04065                                     ("rsbac_adf_set_attr_mac", A_none);
04066                                 return (-RSBAC_EWRITEFAILED);
04067                         }
04068                         /* Set min_write_categories for new process */
04069                         if (rsbac_set_attr(SW_MAC,
04070                                            T_PROCESS,
04071                                            new_tid,
04072                                            A_min_write_categories,
04073                                            i_attr_val4)) {
04074                                 rsbac_ds_set_error
04075                                     ("rsbac_adf_set_attr_mac", A_none);
04076                                 return (-RSBAC_EWRITEFAILED);
04077                         }
04078                         /* Set max_read_categories for new process */
04079                         if (rsbac_set_attr(SW_MAC,
04080                                            T_PROCESS,
04081                                            new_tid,
04082                                            A_max_read_categories,
04083                                            i_attr_val5)) {
04084                                 rsbac_ds_set_error
04085                                     ("rsbac_adf_set_attr_mac", A_none);
04086                                 return (-RSBAC_EWRITEFAILED);
04087                         }
04088                         /* Set initial_security_level for new process */
04089                         if (rsbac_set_attr(SW_MAC,
04090                                            T_PROCESS,
04091                                            new_tid,
04092                                            A_initial_security_level,
04093                                            i_attr_val6)) {
04094                                 rsbac_ds_set_error
04095                                     ("rsbac_adf_set_attr_mac", A_none);
04096                                 return (-RSBAC_EWRITEFAILED);
04097                         }
04098                         /* Set initial_categories for new process */
04099                         if (rsbac_set_attr(SW_MAC,
04100                                            T_PROCESS,
04101                                            new_tid,
04102                                            A_mac_initial_categories,
04103                                            i_attr_val7)) {
04104                                 rsbac_ds_set_error
04105                                     ("rsbac_adf_set_attr_mac", A_none);
04106                                 return (-RSBAC_EWRITEFAILED);
04107                         }
04108                         /* Get owner-min_sec-level/cat from first process */
04109                         if (rsbac_get_attr(SW_MAC,
04110                                            T_PROCESS,
04111                                            tid,
04112                                            A_min_security_level,
04113                                            &i_attr_val2, FALSE)) {
04114                                 rsbac_ds_get_error
04115                                     ("rsbac_adf_set_attr_mac", A_none);
04116                                 return (-RSBAC_EREADFAILED);
04117                         }
04118                         if (rsbac_get_attr(SW_MAC,
04119                                            T_PROCESS,
04120                                            tid,
04121                                            A_mac_min_categories,
04122                                            &i_attr_val3, FALSE)) {
04123                                 rsbac_ds_get_error
04124                                     ("rsbac_adf_set_attr_mac", A_none);
04125                                 return (-RSBAC_EREADFAILED);
04126                         }
04127                         /* Set min_security_level for new process */
04128                         if (rsbac_set_attr(SW_MAC,
04129                                            T_PROCESS,
04130                                            new_tid,
04131                                            A_min_security_level,
04132                                            i_attr_val2)) {
04133                                 rsbac_ds_set_error
04134                                     ("rsbac_adf_set_attr_mac", A_none);
04135                                 return (-RSBAC_EWRITEFAILED);
04136                         }
04137                         /* Set min_categories for new process */
04138                         if (rsbac_set_attr(SW_MAC,
04139                                            T_PROCESS,
04140                                            new_tid,
04141                                            A_mac_min_categories,
04142                                            i_attr_val3)) {
04143                                 rsbac_ds_set_error
04144                                     ("rsbac_adf_set_attr_mac", A_none);
04145                                 return (-RSBAC_EWRITEFAILED);
04146                         }
04147                         if (rsbac_mac_copy_pp_truset
04148                             (tid.process, new_tid.process)) {
04149                                 rsbac_printk(KERN_WARNING
04150                                              "rsbac_adf_set_attr_mac(): rsbac_mac_copy_pp_truset() returned error!\n");
04151                                 return (-RSBAC_EWRITEFAILED);
04152                         }
04153                         return 0;
04154                 } else
04155                         return 0;
04156 
04157         case R_CREATE:
04158                 switch (target) {
04159                         /* Creating dir or (pseudo) file IN target dir! */
04160                 case T_DIR:
04161                         /* Mode of created item is ignored! */
04162                         /* and perform auto-write without(!) 
04163                          * setting of attributes - no need */
04164                         /* -> decision consistency check only */
04165                         /* only check, if not MAC_LIGHT */
04166 #ifndef CONFIG_RSBAC_MAC_LIGHT
04167                         result = auto_write(caller_pid,
04168                                             target, tid, FALSE);
04169                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04170                                 return (-RSBAC_EDECISIONMISMATCH);
04171 #endif
04172                         /* test write access to target: get its sec_level */
04173                         if (rsbac_get_attr(SW_MAC,
04174                                            T_DIR,
04175                                            tid,
04176                                            A_security_level,
04177                                            &i_attr_val1, TRUE)) {
04178                                 rsbac_ds_get_error
04179                                     ("rsbac_adf_set_attr_mac", A_none);
04180                                 return (-RSBAC_EREADFAILED);
04181                         }
04182                         if (rsbac_get_attr(SW_MAC,
04183                                            T_DIR,
04184                                            tid,
04185                                            A_mac_categories,
04186                                            &i_attr_val2, TRUE)) {
04187                                 rsbac_ds_get_error
04188                                     ("rsbac_adf_set_attr_mac", A_none);
04189                                 return (-RSBAC_EREADFAILED);
04190                         }
04191                         /* Get current_sec_level from process (initialized to owner_sec_level)... */
04192                         i_tid.process = caller_pid;
04193                         if (rsbac_get_attr(SW_MAC,
04194                                            T_PROCESS,
04195                                            i_tid,
04196                                            A_current_sec_level,
04197                                            &i_attr_val3, FALSE)) {
04198                                 rsbac_ds_get_error
04199                                     ("rsbac_adf_set_attr_mac", A_none);
04200                                 return (-RSBAC_EREADFAILED);
04201                         }
04202 #ifdef CONFIG_RSBAC_MAC_SMART_INHERIT
04203                         /* Only set, if different than inherited value */
04204                         if (i_attr_val3.security_level !=
04205                             i_attr_val1.security_level)
04206 #endif
04207                                 /* Set security-level for new item */
04208                                 if (rsbac_set_attr(SW_MAC,
04209                                                    new_target,
04210                                                    new_tid,
04211                                                    A_security_level,
04212                                                    i_attr_val3)) {
04213                                         rsbac_ds_set_error
04214                                             ("rsbac_adf_set_attr_mac",
04215                                              A_none);
04216                                         return (-RSBAC_EWRITEFAILED);
04217                                 }
04218                         /* Get current_categories from process (initialized to owner_categories)... */
04219                         if (rsbac_get_attr(SW_MAC,
04220                                            T_PROCESS,
04221                                            i_tid,
04222                                            A_mac_curr_categories,
04223                                            &i_attr_val3, FALSE)) {
04224                                 rsbac_ds_get_error
04225                                     ("rsbac_adf_set_attr_mac", A_none);
04226                                 return (-RSBAC_EREADFAILED);
04227                         }
04228 #ifdef CONFIG_RSBAC_MAC_SMART_INHERIT
04229                         /* Only set, if different than inherited value */
04230                         if (i_attr_val3.mac_categories !=
04231                             i_attr_val2.mac_categories)
04232 #endif
04233                                 /* Set mac_categories for new item */
04234                                 if (rsbac_set_attr(SW_MAC,
04235                                                    new_target,
04236                                                    new_tid,
04237                                                    A_mac_categories,
04238                                                    i_attr_val3)) {
04239                                         rsbac_ds_set_error
04240                                             ("rsbac_adf_set_attr_mac",
04241                                              A_none);
04242                                         return (-RSBAC_EWRITEFAILED);
04243                                 }
04244                         return 0;
04245                         break;
04246 
04247                 case T_IPC:
04248                         i_tid.process = caller_pid;
04249                         /* Get current-sec-level from process... */
04250                         if (rsbac_get_attr(SW_MAC,
04251                                            T_PROCESS,
04252                                            i_tid,
04253                                            A_current_sec_level,
04254                                            &i_attr_val1, FALSE)) {
04255                                 rsbac_ds_get_error
04256                                     ("rsbac_adf_set_attr_mac", A_none);
04257                                 return (-RSBAC_EREADFAILED);
04258                         }
04259                         /* Set security-level for this ipc item */
04260                         if (rsbac_set_attr(SW_MAC,
04261                                            T_IPC,
04262                                            tid,
04263                                            A_security_level,
04264                                            i_attr_val1)) {
04265                                 rsbac_ds_get_error
04266                                     ("rsbac_adf_set_attr_mac", A_none);
04267                                 return (-RSBAC_EWRITEFAILED);
04268                         }
04269                         /* Get mac_curr_categories from process... */
04270                         if (rsbac_get_attr(SW_MAC,
04271                                            T_PROCESS,
04272                                            i_tid,
04273                                            A_mac_curr_categories,
04274                                            &i_attr_val1, FALSE)) {
04275                                 rsbac_ds_get_error
04276                                     ("rsbac_adf_set_attr_mac", A_none);
04277                                 return (-RSBAC_EREADFAILED);
04278                         }
04279                         /* Set curr_categories for new item */
04280                         if (rsbac_set_attr(SW_MAC,
04281                                            T_IPC,
04282                                            tid,
04283                                            A_mac_categories,
04284                                            i_attr_val1)) {
04285                                 rsbac_ds_set_error
04286                                     ("rsbac_adf_set_attr_mac", A_none);
04287                                 return (-RSBAC_EWRITEFAILED);
04288                         }
04289                         return 0;
04290                         break;
04291 
04292 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
04293                 case T_NETOBJ:
04294                         i_tid.process = caller_pid;
04295                         /* Get current-sec-level from process... */
04296                         if (rsbac_get_attr(SW_MAC,
04297                                            T_PROCESS,
04298                                            i_tid,
04299                                            A_current_sec_level,
04300                                            &i_attr_val1, FALSE)) {
04301                                 rsbac_ds_get_error
04302                                     ("rsbac_adf_set_attr_mac", A_none);
04303                                 return (-RSBAC_EREADFAILED);
04304                         }
04305                         /* Set local security-level for this netobj item */
04306                         if (rsbac_set_attr(SW_MAC,
04307                                            target,
04308                                            tid,
04309                                            A_local_sec_level,
04310                                            i_attr_val1)) {
04311                                 rsbac_ds_set_error
04312                                     ("rsbac_adf_set_attr_mac", A_none);
04313                                 return (-RSBAC_EWRITEFAILED);
04314                         }
04315                         /* Get mac_curr_categories from process... */
04316                         if (rsbac_get_attr(SW_MAC,
04317                                            T_PROCESS,
04318                                            i_tid,
04319                                            A_mac_curr_categories,
04320                                            &i_attr_val1, FALSE)) {
04321                                 rsbac_ds_get_error
04322                                     ("rsbac_adf_set_attr_mac", A_none);
04323                                 return (-RSBAC_EREADFAILED);
04324                         }
04325                         /* Set local curr_categories for new item */
04326                         if (rsbac_set_attr(SW_MAC,
04327                                            target,
04328                                            tid,
04329                                            A_local_mac_categories,
04330                                            i_attr_val1)) {
04331                                 rsbac_ds_set_error
04332                                     ("rsbac_adf_set_attr_mac", A_none);
04333                                 return (-RSBAC_EWRITEFAILED);
04334                         }
04335                         return 0;
04336                         break;
04337 #endif
04338 
04339                         /* all other cases are unknown */
04340                 default:
04341                         return 0;
04342                 }
04343 
04344                 /* removal of targets is done in main adf dispatcher! */
04345         case R_DELETE:
04346                 switch (target) {
04347                 case T_FILE:
04348                 case T_DIR:
04349                 case T_FIFO:
04350                 case T_SYMLINK:
04351                 case T_UNIXSOCK:
04352                 case T_IPC:
04353                         /* and perform auto-write without(!) setting of attributes */
04354                         /* - no information flow apart from missing file */
04355                         /* -> decision consistency check only */
04356                         result = auto_write(caller_pid,
04357                                             target, tid, FALSE);
04358                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04359                                 return (-RSBAC_EDECISIONMISMATCH);
04360                         else
04361                                 return 0;
04362                         /* all other cases are unknown */
04363                 default:
04364                         return 0;
04365                 }
04366 
04367         case R_EXECUTE:
04368                 switch (target) {
04369                 case T_FILE:
04370                         /* copy trusted user list from file to process */
04371                         if (rsbac_mac_copy_fp_truset(tid.file, caller_pid)) {
04372                                 rsbac_printk(KERN_WARNING
04373                                              "rsbac_adf_set_attr_mac(): rsbac_mac_copy_fp_truset() returned error!\n");
04374                                 return (-RSBAC_EWRITEFAILED);
04375                         }
04376                         /* perform auto-read with setting of attributes */
04377                         result = auto_read(caller_pid, target, tid, TRUE);
04378                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04379                                 return (-RSBAC_EDECISIONMISMATCH);
04380 
04381                         /* reset current_sec_level, mac_auto, min_write_open */
04382                         /* and max_read_open for process */
04383                         i_tid.process = caller_pid;
04384 
04385 #ifdef CONFIG_RSBAC_MAC_RESET_CURR
04386                         /* First, set current_sec_level and min_write_open to process owner's initial and seclevel */
04387                         if (rsbac_get_attr(SW_MAC,
04388                                            T_PROCESS,
04389                                            i_tid,
04390                                            A_initial_security_level,
04391                                            &i_attr_val1, TRUE)) {
04392                                 rsbac_ds_get_error
04393                                     ("rsbac_adf_set_attr_mac", A_none);
04394                                 return (-RSBAC_EREADFAILED);
04395                         }
04396                         if (rsbac_get_attr(SW_MAC,
04397                                            T_PROCESS,
04398                                            i_tid,
04399                                            A_mac_initial_categories,
04400                                            &i_attr_val2, TRUE)) {
04401                                 rsbac_ds_get_error
04402                                     ("rsbac_adf_set_attr_mac", A_none);
04403                                 return (-RSBAC_EREADFAILED);
04404                         }
04405                         if (rsbac_set_attr(SW_MAC,
04406                                            T_PROCESS,
04407                                            i_tid,
04408                                            A_current_sec_level,
04409                                            i_attr_val1)) {
04410                                 rsbac_ds_set_error
04411                                     ("rsbac_adf_set_attr_mac", A_none);
04412                                 return (-RSBAC_EWRITEFAILED);
04413                         }
04414                         if (rsbac_set_attr(SW_MAC,
04415                                            T_PROCESS,
04416                                            i_tid,
04417                                            A_mac_curr_categories,
04418                                            i_attr_val2)) {
04419                                 rsbac_ds_set_error
04420                                     ("rsbac_adf_set_attr_mac", A_none);
04421                                 return (-RSBAC_EWRITEFAILED);
04422                         }
04423 #endif
04424 #if 0
04425                         /* Now, set min_write_open to process owner's seclevel */
04426                         if (rsbac_get_attr(SW_MAC,
04427                                            T_PROCESS,
04428                                            i_tid,
04429                                            A_security_level,
04430                                            &i_attr_val1, TRUE)) {
04431                                 rsbac_ds_get_error
04432                                     ("rsbac_adf_set_attr_mac", A_none);
04433                                 return (-RSBAC_EREADFAILED);
04434                         }
04435 #endif
04436                         i_attr_val1.min_write_open = SL_max;
04437                         if (rsbac_set_attr(SW_MAC,
04438                                            T_PROCESS,
04439                                            i_tid,
04440                                            A_min_write_open,
04441                                            i_attr_val1)) {
04442                                 rsbac_ds_set_error
04443                                     ("rsbac_adf_set_attr_mac", A_none);
04444                                 return (-RSBAC_EWRITEFAILED);
04445                         }
04446 #if 0
04447                         /* Next, set min_write_categories to process owner's mac_categories */
04448                         if (rsbac_get_attr(SW_MAC,
04449                                            T_PROCESS,
04450                                            i_tid,
04451                                            A_mac_categories,
04452                                            &i_attr_val2, TRUE)) {
04453                                 rsbac_ds_get_error
04454                                     ("rsbac_adf_set_attr_mac", A_none);
04455                                 return (-RSBAC_EREADFAILED);
04456                         }
04457 #endif
04458                         i_attr_val2.mac_categories =
04459                             RSBAC_MAC_MAX_CAT_VECTOR;
04460                         if (rsbac_set_attr
04461                             (SW_MAC, T_PROCESS, i_tid, A_min_write_categories,
04462                              i_attr_val2)) {
04463                                 rsbac_ds_set_error
04464                                     ("rsbac_adf_set_attr_mac", A_none);
04465                                 return (-RSBAC_EWRITEFAILED);
04466                         }
04467                         /* reset max_read boundary */
04468 #if 0
04469                         /* Get owner-min-sec-level and mac_min_categories for owner */
04470                         if (rsbac_get_attr(SW_MAC,
04471                                            T_PROCESS,
04472                                            i_tid,
04473                                            A_min_security_level,
04474                                            &i_attr_val1, TRUE)) {
04475                                 rsbac_ds_get_error
04476                                     ("rsbac_adf_set_attr_mac", A_none);
04477                                 return (-RSBAC_EREADFAILED);
04478                         }
04479                         if (rsbac_get_attr(SW_MAC,
04480                                            T_PROCESS,
04481                                            i_tid,
04482                                            A_mac_min_categories,
04483                                            &i_attr_val2, TRUE)) {
04484                                 rsbac_ds_get_error
04485                                     ("rsbac_adf_set_attr_mac", A_none);
04486                                 return (-RSBAC_EREADFAILED);
04487                         }
04488 #endif
04489                         i_attr_val1.max_read_open = SL_min;
04490                         i_attr_val2.mac_categories =
04491                             RSBAC_MAC_MIN_CAT_VECTOR;
04492                         if (rsbac_set_attr
04493                             (SW_MAC, T_PROCESS, i_tid, A_max_read_open,
04494                              i_attr_val1)) {
04495                                 rsbac_ds_set_error
04496                                     ("rsbac_adf_set_attr_mac", A_none);
04497                                 return (-RSBAC_EWRITEFAILED);
04498                         }
04499                         /* reset category max_read boundary */
04500                         if (rsbac_set_attr(SW_MAC,
04501                                            T_PROCESS,
04502                                            i_tid,
04503                                            A_max_read_categories,
04504                                            i_attr_val2)) {
04505                                 rsbac_ds_set_error
04506                                     ("rsbac_adf_set_attr_mac", A_none);
04507                                 return (-RSBAC_EWRITEFAILED);
04508                         }
04509                         /* set flags */
04510                         if (rsbac_get_attr(SW_MAC,
04511                                            T_PROCESS,
04512                                            i_tid,
04513                                            A_mac_process_flags,
04514                                            &i_attr_val1, TRUE)) {
04515                                 rsbac_ds_get_error
04516                                     ("rsbac_adf_set_attr_mac", A_none);
04517                                 return (-RSBAC_EREADFAILED);
04518                         }
04519                         if (rsbac_get_attr(SW_MAC,
04520                                            target,
04521                                            tid,
04522                                            A_mac_auto,
04523                                            &i_attr_val2, TRUE)) {
04524                                 rsbac_ds_get_error
04525                                     ("rsbac_adf_set_attr_mac", A_none);
04526                                 return (-RSBAC_EREADFAILED);
04527                         }
04528                         if (i_attr_val2.mac_auto) {
04529                                 i_attr_val1.mac_process_flags |=
04530                                     MAC_program_auto;
04531                                 i_tid.user = owner;
04532                                 if (rsbac_get_attr(SW_MAC,
04533                                                    T_USER,
04534                                                    i_tid,
04535                                                    A_mac_user_flags,
04536                                                    &i_attr_val2, TRUE)) {
04537                                         rsbac_ds_get_error
04538                                             ("rsbac_adf_set_attr_mac",
04539                                              A_none);
04540                                         return (-RSBAC_EREADFAILED);
04541                                 }
04542                                 if (i_attr_val2.
04543                                     mac_user_flags & MAC_allow_auto)
04544                                         i_attr_val1.mac_process_flags |=
04545                                             MAC_auto;
04546                                 else
04547                                         i_attr_val1.mac_process_flags &=
04548                                             ~MAC_auto;
04549                                 i_tid.process = caller_pid;
04550                         } else {
04551                                 i_attr_val1.mac_process_flags &=
04552                                     ~MAC_program_auto;
04553                                 i_attr_val1.mac_process_flags &= ~MAC_auto;
04554                         }
04555                         if (rsbac_get_attr(SW_MAC,
04556                                            T_FILE,
04557                                            tid,
04558                                            A_mac_prop_trusted,
04559                                            &i_attr_val3, TRUE)) {
04560                                 rsbac_ds_get_error
04561                                     ("rsbac_adf_set_attr_mac", A_none);
04562                                 return (-RSBAC_EREADFAILED);
04563                         }
04564                         if (!(i_attr_val3.mac_prop_trusted)
04565                             || !(i_attr_val1.
04566                                  mac_process_flags & MAC_trusted)
04567                             ) {
04568                                 if (rsbac_mac_p_truset_member
04569                                     (caller_pid, owner))
04570                                         i_attr_val1.mac_process_flags |=
04571                                             MAC_trusted;
04572                                 else {
04573                                         i_tid.user = owner;
04574                                         if (rsbac_get_attr(SW_MAC,
04575                                                            T_USER,
04576                                                            i_tid,
04577                                                            A_mac_user_flags,
04578                                                            &i_attr_val2,
04579                                                            TRUE)) {
04580                                                 rsbac_ds_get_error
04581                                                     ("rsbac_adf_set_attr_mac",
04582                                                      A_none);
04583                                                 return
04584                                                     (-RSBAC_EREADFAILED);
04585                                         }
04586                                         if (i_attr_val2.
04587                                             mac_user_flags & MAC_trusted)
04588                                                 i_attr_val1.
04589                                                     mac_process_flags |=
04590                                                     MAC_trusted;
04591                                         else
04592                                                 i_attr_val1.
04593                                                     mac_process_flags &=
04594                                                     ~MAC_trusted;
04595                                         i_tid.process = caller_pid;
04596                                 }
04597                         }
04598                         if (rsbac_set_attr(SW_MAC,
04599                                            T_PROCESS,
04600                                            i_tid,
04601                                            A_mac_process_flags,
04602                                            i_attr_val1)) {
04603                                 rsbac_ds_set_error
04604                                     ("rsbac_adf_set_attr_mac", A_none);
04605                                 return (-RSBAC_EWRITEFAILED);
04606                         }
04607                         return 0;
04608 
04609                         /* all other cases */
04610                 default:
04611                         return 0;
04612                 }
04613 
04614         case R_MOUNT:
04615                 switch (target) {
04616                 case T_DIR:
04617                 case T_DEV:
04618                         /* and perform auto-read(-write) with setting of attributes */
04619                         if ((target == T_DEV)
04620                             && (attr == A_mode)
04621                             && (attr_val.mode & MS_RDONLY))
04622                                 result = auto_read(caller_pid,
04623                                                    target, tid, TRUE);
04624                         else
04625                                 result = auto_read_write(caller_pid,
04626                                                          target,
04627                                                          tid, TRUE);
04628                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04629                                 return (-RSBAC_EDECISIONMISMATCH);
04630                         else
04631                                 return 0;
04632 
04633                         /* all other cases are unknown */
04634                 default:
04635                         return 0;
04636                 }
04637 
04638         case R_READ:
04639                 switch (target) {
04640                 case T_DIR:
04641 #ifdef CONFIG_RSBAC_RW
04642                 case T_FILE:
04643                 case T_FIFO:
04644                 case T_UNIXSOCK:
04645                 case T_IPC:
04646 #endif
04647                         /* and perform auto-read with setting of attributes */
04648                         result = auto_read(caller_pid, target, tid, TRUE);
04649                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04650                                 return (-RSBAC_EDECISIONMISMATCH);
04651                         return 0;
04652 
04653 #ifdef CONFIG_RSBAC_RW
04654                 case T_DEV:
04655                         /* Only check for devices with mac_check set */
04656                         if (rsbac_get_attr(SW_MAC,
04657                                            T_DEV,
04658                                            tid,
04659                                            A_mac_check,
04660                                            &i_attr_val1, FALSE)) {
04661                                 rsbac_ds_get_error
04662                                     ("rsbac_adf_set_attr_mac", A_none);
04663                                 return (-RSBAC_EREADFAILED);
04664                         }
04665                         if (!i_attr_val1.mac_check)
04666                                 return 0;
04667                         /* and perform auto-read with setting of attributes */
04668                         result = auto_read(caller_pid, target, tid, TRUE);
04669                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04670                                 return (-RSBAC_EDECISIONMISMATCH);
04671                         return 0;
04672 #endif
04673 
04674 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
04675                 case T_NETOBJ:
04676                         /* and perform auto-read with setting of attributes */
04677                         result = auto_read_attr(caller_pid,
04678                                                 target,
04679                                                 tid,
04680                                                 A_remote_sec_level,
04681                                                 A_remote_mac_categories,
04682                                                 TRUE);
04683                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04684                                 return (-RSBAC_EDECISIONMISMATCH);
04685                         return 0;
04686 #endif
04687 
04688                         /* all other cases are unknown */
04689                 default:
04690                         return 0;
04691                 }
04692 
04693         case R_READ_OPEN:
04694                 switch (target) {
04695                 case T_FILE:
04696                 case T_DIR:
04697                 case T_FIFO:
04698                 case T_UNIXSOCK:
04699                 case T_IPC:
04700                         /* and perform auto-read with setting attributes */
04701                         result = auto_read(caller_pid, target, tid, TRUE);
04702                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04703                                 return (-RSBAC_EDECISIONMISMATCH);
04704                         return 0;
04705 
04706                 case T_DEV:
04707                         /* Only check for devices with mac_check set */
04708                         if (rsbac_get_attr(SW_MAC,
04709                                            T_DEV,
04710                                            tid,
04711                                            A_mac_check,
04712                                            &i_attr_val1, FALSE)) {
04713                                 rsbac_ds_get_error
04714                                     ("rsbac_adf_set_attr_mac", A_none);
04715                                 return (-RSBAC_EREADFAILED);
04716                         }
04717                         if (!i_attr_val1.mac_check)
04718                                 return 0;
04719                         /* and perform auto-read with setting attributes */
04720                         result = auto_read(caller_pid, target, tid, TRUE);
04721                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04722                                 return (-RSBAC_EDECISIONMISMATCH);
04723                         return 0;
04724 
04725                         /* all other cases are unknown */
04726                 default:
04727                         return 0;
04728                 }
04729 
04730         case R_READ_WRITE_OPEN:
04731                 switch (target) {
04732                 case T_FILE:
04733                 case T_FIFO:
04734                 case T_UNIXSOCK:
04735                 case T_IPC:
04736                         /* and perform auto-read-write without setting attributes */
04737                         result = auto_read_write(caller_pid,
04738                                                  target, tid, TRUE);
04739                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04740                                 return (-RSBAC_EDECISIONMISMATCH);
04741                         return 0;
04742 
04743                 case T_DEV:
04744                         /* Only check for devices with mac_check set */
04745                         if (rsbac_get_attr(SW_MAC,
04746                                            T_DEV,
04747                                            tid,
04748                                            A_mac_check,
04749                                            &i_attr_val1, FALSE)) {
04750                                 rsbac_ds_get_error
04751                                     ("rsbac_adf_set_attr_mac", A_none);
04752                                 return (-RSBAC_EREADFAILED);
04753                         }
04754                         if (!i_attr_val1.mac_check)
04755                                 return 0;
04756                         /* and perform auto-read-write with setting of attributes */
04757                         result = auto_read_write(caller_pid,
04758                                                  target, tid, TRUE);
04759                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04760                                 return (-RSBAC_EDECISIONMISMATCH);
04761                         return 0;
04762                         /* all other cases are unknown */
04763                 default:
04764                         return 0;
04765                 }
04766 
04767         case R_SEARCH:
04768                 switch (target) {
04769                 case T_DIR:
04770                 case T_SYMLINK:
04771                         /* and perform auto-read with setting of attributes */
04772                         result = auto_read(caller_pid, target, tid, TRUE);
04773                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04774                                 return (-RSBAC_EDECISIONMISMATCH);
04775                         return 0;
04776                         /* all other cases are unknown */
04777                 default:
04778                         return 0;
04779                 }
04780 
04781         case R_TRACE:
04782                 switch (target) {
04783                 case T_PROCESS:
04784                         /* and perform auto-read-write with setting attributes */
04785                         result = auto_read_write_attr(caller_pid,
04786                                                       target,
04787                                                       tid,
04788                                                       A_current_sec_level,
04789                                                       A_mac_curr_categories,
04790                                                       TRUE);
04791                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04792                                 return (-RSBAC_EDECISIONMISMATCH);
04793                         return 0;
04794 
04795                         /* all other cases are unknown */
04796                 default:
04797                         return 0;
04798                 }
04799 
04800         case R_WRITE:
04801         case R_WRITE_OPEN:
04802                 switch (target) {
04803                 case T_FILE:
04804                 case T_FIFO:
04805                 case T_UNIXSOCK:
04806                 case T_IPC:
04807                         /* and perform auto-write with setting attributes */
04808                         result = auto_write(caller_pid, target, tid, TRUE);
04809                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04810                                 return (-RSBAC_EDECISIONMISMATCH);
04811                         return 0;
04812 
04813                 case T_DEV:
04814                         /* Only check for devices with mac_check set */
04815                         if (rsbac_get_attr(SW_MAC,
04816                                            T_DEV,
04817                                            tid,
04818                                            A_mac_check,
04819                                            &i_attr_val1, FALSE)) {
04820                                 rsbac_ds_get_error
04821                                     ("rsbac_adf_set_attr_mac", A_none);
04822                                 return (-RSBAC_EREADFAILED);
04823                         }
04824                         if (!i_attr_val1.mac_check)
04825                                 return 0;
04826                         /* and perform auto-write with setting attributes */
04827                         result = auto_write(caller_pid, target, tid, TRUE);
04828                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04829                                 return (-RSBAC_EDECISIONMISMATCH);
04830                         return 0;
04831 
04832 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
04833                 case T_NETOBJ:
04834                         /* and perform auto-write with setting attributes */
04835                         result = auto_write_attr(caller_pid,
04836                                                  target,
04837                                                  tid,
04838                                                  A_remote_sec_level,
04839                                                  A_remote_mac_categories,
04840                                                  TRUE);
04841                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04842                                 return (-RSBAC_EDECISIONMISMATCH);
04843                         return 0;
04844 #endif
04845 
04846                         /* all other cases are unknown */
04847                 default:
04848                         return 0;
04849                 }
04850 
04851 #ifdef CONFIG_RSBAC_MAC_NET_OBJ_PROT
04852         case R_BIND:
04853         case R_LISTEN:
04854                 switch (target) {
04855                 case T_NETOBJ:
04856                         /* and perform auto-write with setting attributes */
04857                         result = auto_write_attr(caller_pid,
04858                                                  target,
04859                                                  tid,
04860                                                  A_local_sec_level,
04861                                                  A_local_mac_categories,
04862                                                  TRUE);
04863                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04864                                 return (-RSBAC_EDECISIONMISMATCH);
04865                         return 0;
04866 
04867                         /* all other cases are unknown */
04868                 default:
04869                         return 0;
04870                 }
04871 
04872         case R_ACCEPT:
04873         case R_CONNECT:
04874         case R_SEND:
04875         case R_RECEIVE:
04876                 switch (target) {
04877                 case T_NETOBJ:
04878                         /* and perform auto-write with setting attributes */
04879                         result = auto_write_attr(caller_pid,
04880                                                  target,
04881                                                  tid,
04882                                                  A_remote_sec_level,
04883                                                  A_remote_mac_categories,
04884                                                  TRUE);
04885                         if ((result != GRANTED) && (result != DO_NOT_CARE))
04886                                 return (-RSBAC_EDECISIONMISMATCH);
04887                         return 0;
04888 
04889                         /* all other cases are unknown */
04890                 default:
04891                         return 0;
04892                 }
04893 #endif
04894         default:
04895                 return 0;
04896         }
04897 
04898         return 0;
04899 }

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