acl_syscalls.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) - ACL module                       */
00005 /* File: rsbac/adf/acl/syscalls.c                    */
00006 /*                                                   */
00007 /* Author and (c) 1999-2005: Amon Ott <ao@rsbac.org> */
00008 /*                                                   */
00009 /* Last modified: 15/Jul/2005                        */
00010 /*************************************************** */
00011 
00012 #include <linux/string.h>
00013 #include <linux/sched.h>
00014 #include <linux/errno.h>
00015 #include <linux/vmalloc.h>
00016 #include <rsbac/types.h>
00017 #include <rsbac/aci.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/acl.h>
00020 #include <rsbac/getname.h>
00021 #include <rsbac/acl_getname.h>
00022 #include <rsbac/helpers.h>
00023 #include <rsbac/debug.h>
00024 #include <rsbac/rkmem.h>
00025 #include <rsbac/adf_main.h>
00026 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00027 #ifdef CONFIG_RSBAC_NET_OBJ
00028 #include <net/sock.h>
00029 #endif
00030 #endif
00031 
00032 /************************************************* */
00033 /*           Global Variables                      */
00034 /************************************************* */
00035 
00036 /************************************************* */
00037 /*          Internal Help functions                */
00038 /************************************************* */
00039 
00040 rsbac_boolean_t rsbac_acl_check_super(enum  rsbac_target_t target,
00041                               union rsbac_target_id_t tid,
00042                                     rsbac_uid_t user)
00043   {
00044     rsbac_boolean_t                   i_result = FALSE;
00045     int                       err=0, tmperr;
00046     int                       i;
00047     rsbac_acl_group_id_t    * group_p;
00048     #if defined(CONFIG_RSBAC_RC)
00049     union rsbac_target_id_t       i_tid;
00050     union rsbac_attribute_value_t i_attr_val1;
00051     #endif
00052 
00053     /* Only check implemented targets */
00054     switch(target)
00055       {
00056         case T_FILE:
00057         case T_DIR:
00058         case T_FIFO:
00059         case T_SYMLINK:
00060         case T_DEV:
00061         case T_IPC:
00062         case T_SCD:
00063         case T_USER:
00064         case T_PROCESS:
00065 #ifdef CONFIG_RSBAC_ACL_UM_PROT
00066         case T_GROUP:
00067 #endif
00068         case T_NETDEV:
00069         case T_NETTEMP_NT:
00070         case T_NETTEMP:
00071         case T_NETOBJ:
00072           break;
00073         default:
00074           return TRUE;
00075       }
00076     /* own right */
00077     err = rsbac_acl_get_single_right(target,
00078                                      tid,
00079                                      ACLS_USER,
00080                                      (rsbac_acl_subject_id_t) user,
00081                                      ACLR_SUPERVISOR,
00082                                      &i_result);
00083     if(err)
00084       {
00085         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00086 
00087         if(tmp)
00088           {
00089             rsbac_printk(KERN_WARNING
00090                    "rsbac_acl_check_super(): rsbac_acl_get_single_right() returned error %s!\n",
00091                    get_error_name(tmp,err));
00092             rsbac_kfree(tmp);
00093           }
00094         return FALSE;
00095       }
00096     if(i_result)
00097       return(TRUE);
00098 
00099     /* try SUPERVISOR for group and role */
00100     /* group everyone */
00101     err = rsbac_acl_get_single_right(target,
00102                                      tid,
00103                                      ACLS_GROUP,
00104                                      RSBAC_ACL_GROUP_EVERYONE,
00105                                      ACLR_SUPERVISOR,
00106                                      &i_result);
00107     if(err)
00108       {
00109         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00110 
00111         if(tmp)
00112           {
00113             rsbac_printk(KERN_WARNING
00114                    "rsbac_acl_check_super(): rsbac_acl_get_single_right() returned error %s!\n",
00115                    get_error_name(tmp,err));
00116             rsbac_kfree(tmp);
00117           }
00118         return FALSE;
00119       }
00120     if(i_result)
00121       return(TRUE);
00122 
00123     #if defined(CONFIG_RSBAC_RC)
00124     /* use process role */
00125     /* first get role */
00126     i_tid.process = current->pid;
00127     if (rsbac_get_attr(RC,
00128                        T_PROCESS,
00129                        i_tid,
00130                        A_rc_role,
00131                        &i_attr_val1,
00132                        FALSE))
00133       {
00134         rsbac_printk(KERN_WARNING
00135                "rsbac_acl_check_super(): rsbac_get_attr() for process rc_role returned error!\n");
00136       }
00137     else
00138       {
00139         err = rsbac_acl_get_single_right(target,
00140                                          tid,
00141                                          ACLS_ROLE,
00142                                          i_attr_val1.rc_role,
00143                                          ACLR_SUPERVISOR,
00144                                          &i_result);
00145         if(err)
00146           {
00147             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00148 
00149             if(tmp)
00150               {
00151                 get_error_name(tmp,err);
00152                 rsbac_printk(KERN_WARNING
00153                        "rsbac_acl_check_super(): rsbac_acl_get_single_right() returned error %s!\n",
00154                        tmp);
00155                 rsbac_kfree(tmp);
00156               }
00157             return FALSE;
00158           }
00159         if(i_result)
00160           return(TRUE);
00161       }
00162     #endif
00163 
00164     /* other groups */
00165     /* first get user groups */
00166     group_p = NULL;
00167     err = rsbac_acl_get_user_groups(0, user, &group_p, NULL);
00168     if(err<0)
00169       {
00170         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00171 
00172         if(tmp)
00173           {
00174             rsbac_printk(KERN_WARNING
00175                    "rsbac_acl_check_super(): rsbac_acl_get_user_groups() returned error %s!\n",
00176                    get_error_name(tmp,err));
00177             rsbac_kfree(tmp);
00178           }
00179         return err;
00180       }
00181     for(i=0; i<err; i++)
00182       {
00183         tmperr = rsbac_acl_get_single_right(target,
00184                                             tid,
00185                                             ACLS_GROUP,
00186                                             group_p[i],
00187                                             ACLR_SUPERVISOR,
00188                                             &i_result);
00189         if(tmperr)
00190           {
00191             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00192 
00193             if(tmp)
00194               {
00195                 rsbac_printk(KERN_WARNING
00196                        "rsbac_acl_check_super(): rsbac_acl_get_single_right() returned error %s!\n",
00197                        get_error_name(tmp,tmperr));
00198                 rsbac_kfree(tmp);
00199               }
00200             if(group_p)
00201               rsbac_vfree(group_p);
00202             return FALSE;
00203           }
00204         if(i_result)
00205           {
00206             if(group_p)
00207               rsbac_vfree(group_p);
00208             return(TRUE);
00209           }
00210       }
00211     if(group_p)
00212       rsbac_vfree(group_p);
00213 
00214     /* give up */
00215     return FALSE;
00216   };
00217 
00218 
00219 #if !defined(CONFIG_RSBAC_MAINT)
00220 rsbac_boolean_t rsbac_acl_check_forward(enum  rsbac_target_t target,
00221                                 union rsbac_target_id_t tid,
00222                                       rsbac_uid_t user,
00223                                       rsbac_acl_rights_vector_t rights);
00224 
00225 rsbac_boolean_t rsbac_acl_check_super(enum  rsbac_target_t target,
00226                               union rsbac_target_id_t tid,
00227                                     rsbac_uid_t user);
00228 
00229 rsbac_boolean_t rsbac_acl_check_right(enum  rsbac_target_t target,
00230                               union rsbac_target_id_t tid,
00231                                     rsbac_uid_t user,
00232                                     rsbac_pid_t caller_pid,
00233                               enum  rsbac_adf_request_t request);
00234 #endif
00235 
00236 /************************************************* */
00237 /*          Externally visible functions           */
00238 /************************************************* */
00239 
00240 int rsbac_acl_sys_set_acl_entry(
00241          rsbac_list_ta_number_t      ta_number,
00242   enum   rsbac_target_t              target,
00243   union  rsbac_target_id_t           tid,
00244   enum   rsbac_acl_subject_type_t    subj_type,
00245          rsbac_acl_subject_id_t      subj_id,
00246          rsbac_acl_rights_vector_t   rights,
00247          rsbac_time_t                ttl)
00248   {
00249     int err=0;
00250 
00251 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00252       /* sanity check before using pointer */
00253       if(   (target == T_NETOBJ)
00254          && tid.netobj.sock_p
00255          && (   tid.netobj.remote_addr
00256 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00257              || !tid.netobj.sock_p->file
00258              || !tid.netobj.sock_p->file->f_dentry
00259              || !tid.netobj.sock_p->file->f_dentry->d_inode
00260              || (SOCKET_I(tid.netobj.sock_p->file->f_dentry->d_inode) != tid.netobj.sock_p)
00261 #else
00262              || !tid.netobj.sock_p->inode
00263              || (&(tid.netobj.sock_p->inode->u.socket_i) != tid.netobj.sock_p)
00264 #endif
00265             )
00266         )
00267         return -RSBAC_EINVALIDTARGET;
00268 #endif
00269 
00270 /* check only in non-maint mode */
00271 #if !defined(CONFIG_RSBAC_MAINT)
00272 #ifdef CONFIG_RSBAC_SWITCH_ACL
00273     if(rsbac_switch_acl)
00274 #endif
00275       {
00276         rsbac_uid_t user;
00277 
00278         if(rsbac_get_owner(&user))
00279           return -RSBAC_EREADFAILED;
00280         /* first try access control right (SUPERVISOR try is included) */
00281         if(!rsbac_acl_check_right(target, tid, user, current->pid, ACLR_ACCESS_CONTROL))
00282           {
00283             /* no access control -> try forward for these rights */
00284             /* but only, if no ttl requested */
00285             if(   (ttl != RSBAC_LIST_TTL_KEEP)
00286                || !rsbac_acl_check_forward(target, tid, user, rights)
00287               )
00288               {
00289                 char * rights_string = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00290                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00291                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00292                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00293                 char * target_id_name
00294                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00295                 /* max. path name len + some extra */
00296                 #else
00297                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00298                 /* max. file name len + some extra */
00299                 #endif
00300 
00301                 u64tostracl(rights_string, rights);
00302                 get_acl_subject_type_name(subject_type_name, subj_type);
00303                 get_target_name(target_type_name, target, target_id_name, tid);
00304                 rsbac_printk(KERN_INFO
00305                        "rsbac_acl_sys_set_acl_entry(): setting rights %s for %s %u to %s %s denied for user %u!\n",
00306                        rights_string,
00307                        subject_type_name,
00308                        subj_id,
00309                        target_type_name,
00310                        target_id_name,
00311                        user);
00312                 rsbac_kfree(rights_string);
00313                 rsbac_kfree(subject_type_name);
00314                 rsbac_kfree(target_type_name);
00315                 rsbac_kfree(target_id_name);
00316 
00317                 #ifdef CONFIG_RSBAC_SOFTMODE
00318                 if(   !rsbac_softmode
00319                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00320                    && !rsbac_ind_softmode[ACL]
00321                 #endif
00322                   )
00323                 #endif
00324                   return(-EPERM);
00325               }
00326           }
00327         if(rights & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR)
00328           {
00329             /* you must have SUPERVISOR to set SUPERVISOR */
00330             if(!rsbac_acl_check_super(target, tid, user))
00331               {
00332                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00333                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00334                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00335                 char * target_id_name
00336                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00337                 /* max. path name len + some extra */
00338                 #else
00339                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00340                 /* max. file name len + some extra */
00341                 #endif
00342 
00343                 get_acl_subject_type_name(subject_type_name, subj_type);
00344                 get_target_name(target_type_name, target, target_id_name, tid);
00345                 rsbac_printk(KERN_INFO
00346                        "rsbac_acl_sys_set_acl_entry(): setting SUPERVISOR for %s %u to %s %s denied for user %u!\n",
00347                        subject_type_name,
00348                        subj_id,
00349                        target_type_name,
00350                        target_id_name,
00351                        user);
00352                 rsbac_kfree(subject_type_name);
00353                 rsbac_kfree(target_type_name);
00354                 rsbac_kfree(target_id_name);
00355                 #ifdef CONFIG_RSBAC_SOFTMODE
00356                 if(   !rsbac_softmode
00357                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00358                    && !rsbac_ind_softmode[ACL]
00359                 #endif
00360                   )
00361                 #endif
00362                   return(-EPERM);
00363               }
00364           }
00365       }
00366 #endif /* !MAINT */
00367 
00368     /* OK, check passed. Set ACL. */
00369     err = rsbac_acl_set_acl_entry(ta_number, target, tid, subj_type, subj_id, rights, ttl);
00370     if(err)
00371       {
00372         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00373 
00374         if(tmp)
00375           {
00376             rsbac_printk(KERN_WARNING
00377                    "rsbac_acl_sys_set_acl_entry(): rsbac_acl_set_acl_entry() returned error %s!\n",
00378                    get_error_name(tmp,err));
00379             rsbac_kfree(tmp);
00380           }
00381       }
00382     return err;
00383   }
00384 
00385 int rsbac_acl_sys_remove_acl_entry(
00386          rsbac_list_ta_number_t      ta_number,
00387   enum   rsbac_target_t              target,
00388   union  rsbac_target_id_t           tid,
00389   enum   rsbac_acl_subject_type_t    subj_type,
00390          rsbac_acl_subject_id_t      subj_id)
00391   {
00392     int err=0;
00393 
00394 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00395       /* sanity check before using pointer */
00396       if(   (target == T_NETOBJ)
00397          && tid.netobj.sock_p
00398          && (   tid.netobj.remote_addr
00399 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00400              || !tid.netobj.sock_p->file
00401              || !tid.netobj.sock_p->file->f_dentry
00402              || !tid.netobj.sock_p->file->f_dentry->d_inode
00403              || (SOCKET_I(tid.netobj.sock_p->file->f_dentry->d_inode) != tid.netobj.sock_p)
00404 #else
00405              || !tid.netobj.sock_p->inode
00406              || (&(tid.netobj.sock_p->inode->u.socket_i) != tid.netobj.sock_p)
00407 #endif
00408             )
00409         )
00410         return -RSBAC_EINVALIDTARGET;
00411 #endif
00412 
00413 /* check only in non-maint mode */
00414 #if !defined(CONFIG_RSBAC_MAINT)
00415 #ifdef CONFIG_RSBAC_SWITCH_ACL
00416     if(rsbac_switch_acl)
00417 #endif
00418       {
00419         rsbac_uid_t user;
00420         rsbac_acl_rights_vector_t res_rights = 0;
00421 
00422         if(rsbac_get_owner(&user))
00423           return -RSBAC_EREADFAILED;
00424         /* first try access control right (SUPERVISOR is included) */
00425         if(!rsbac_acl_check_right(target, tid, user, current->pid, ACLR_ACCESS_CONTROL))
00426           {
00427             char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00428             char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00429             #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00430             char * target_id_name
00431               = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00432             /* max. path name len + some extra */
00433             #else
00434             char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00435             /* max. file name len + some extra */
00436             #endif
00437 
00438             get_acl_subject_type_name(subject_type_name, subj_type);
00439             get_target_name(target_type_name, target, target_id_name, tid);
00440             rsbac_printk(KERN_INFO
00441                    "rsbac_acl_sys_remove_acl_entry(): removing ACL entry for %s %u at %s %s denied for user %u!\n",
00442                    subject_type_name,
00443                    subj_id,
00444                    target_type_name,
00445                    target_id_name,
00446                    user);
00447             rsbac_kfree(subject_type_name);
00448             rsbac_kfree(target_type_name);
00449             rsbac_kfree(target_id_name);
00450             #ifdef CONFIG_RSBAC_SOFTMODE
00451             if(   !rsbac_softmode
00452             #ifdef CONFIG_RSBAC_SOFTMODE_IND
00453                && !rsbac_ind_softmode[ACL]
00454             #endif
00455               )
00456             #endif
00457               return(-EPERM);
00458           }
00459 
00460         err = rsbac_acl_get_rights(0, target, tid, subj_type, subj_id, &res_rights, FALSE);
00461         if(err)
00462           {
00463             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00464 
00465             if(tmp)
00466               {
00467                 rsbac_printk(KERN_WARNING
00468                        "rsbac_acl_sys_remove_acl_entry(): rsbac_acl_get_rights() returned error %s!\n",
00469                        get_error_name(tmp,err));
00470                 rsbac_kfree(tmp);
00471               }
00472             return err;
00473           }
00474         if(res_rights & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR)
00475           {
00476             /* you must have SUPERVISOR to remove an entry with SUPERVISOR */
00477             if(!rsbac_acl_check_super(target, tid, user))
00478               {
00479                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00480                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00481                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00482                 char * target_id_name
00483                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00484                 /* max. path name len + some extra */
00485                 #else
00486                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00487                 /* max. file name len + some extra */
00488                 #endif
00489 
00490                 get_acl_subject_type_name(subject_type_name, subj_type);
00491                 get_target_name(target_type_name, target, target_id_name, tid);
00492                 rsbac_printk(KERN_INFO
00493                        "rsbac_acl_sys_remove_acl_entry(): removing ACL entry with SUPERVISOR for %s %u at %s %s denied for user %u!\n",
00494                        subject_type_name,
00495                        subj_id,
00496                        target_type_name,
00497                        target_id_name,
00498                        user);
00499                 rsbac_kfree(subject_type_name);
00500                 rsbac_kfree(target_type_name);
00501                 rsbac_kfree(target_id_name);
00502                 #ifdef CONFIG_RSBAC_SOFTMODE
00503                 if(   !rsbac_softmode
00504                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00505                    && !rsbac_ind_softmode[ACL]
00506                 #endif
00507                   )
00508                 #endif
00509                   return(-EPERM);
00510                }
00511            }
00512       }
00513 #endif /* !MAINT */
00514 
00515     /* OK, check passed. Set ACL. */
00516     err = rsbac_acl_remove_acl_entry(ta_number, target, tid, subj_type, subj_id);
00517     if(err)
00518       {
00519         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00520 
00521         if(tmp)
00522           {
00523             rsbac_printk(KERN_WARNING
00524                    "rsbac_acl_sys_remove_acl_entry(): rsbac_acl_remove_acl_entry() returned error %s!\n",
00525                    get_error_name(tmp,err));
00526             rsbac_kfree(tmp);
00527           }
00528       }
00529     return err;
00530   }
00531 
00532 int rsbac_acl_sys_remove_acl(
00533          rsbac_list_ta_number_t      ta_number,
00534   enum   rsbac_target_t              target,
00535   union  rsbac_target_id_t           tid)
00536   {
00537     int err=0;
00538 
00539 /* check only in non-maint mode */
00540 #if !defined(CONFIG_RSBAC_MAINT)
00541 #ifdef CONFIG_RSBAC_SWITCH_ACL
00542     if(rsbac_switch_acl)
00543 #endif
00544       {
00545         rsbac_uid_t user;
00546 
00547         if(rsbac_get_owner(&user))
00548           return -RSBAC_EREADFAILED;
00549         /* check SUPERVISOR */
00550         if(!rsbac_acl_check_super(target, tid, user))
00551           {
00552             char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00553             #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00554             char * target_id_name
00555               = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00556             /* max. path name len + some extra */
00557             #else
00558             char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00559             /* max. file name len + some extra */
00560             #endif
00561 
00562             get_target_name(target_type_name, target, target_id_name, tid);
00563             rsbac_printk(KERN_INFO
00564                    "rsbac_acl_sys_remove_acl(): removing ACL from %s %s denied for user %u!\n",
00565                    target_type_name,
00566                    target_id_name,
00567                    user);
00568             rsbac_kfree(target_type_name);
00569             rsbac_kfree(target_id_name);
00570             #ifdef CONFIG_RSBAC_SOFTMODE
00571             if(   !rsbac_softmode
00572             #ifdef CONFIG_RSBAC_SOFTMODE_IND
00573                && !rsbac_ind_softmode[ACL]
00574             #endif
00575               )
00576             #endif
00577               return(-EPERM);
00578           }
00579       }
00580 #endif /* !MAINT */
00581 
00582     /* OK, check passed. Set ACL. */
00583     err = rsbac_acl_remove_acl(ta_number, target, tid);
00584     if(err)
00585       {
00586         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00587 
00588         if(tmp)
00589           {
00590             rsbac_printk(KERN_WARNING
00591                    "rsbac_acl_sys_remove_acl(): rsbac_acl_remove_acl() returned error %s!\n",
00592                    get_error_name(tmp,err));
00593             rsbac_kfree(tmp);
00594           }
00595       }
00596     return err;
00597   }
00598 
00599 int rsbac_acl_sys_add_to_acl_entry(
00600          rsbac_list_ta_number_t      ta_number,
00601   enum   rsbac_target_t              target,
00602   union  rsbac_target_id_t           tid,
00603   enum   rsbac_acl_subject_type_t    subj_type,
00604          rsbac_acl_subject_id_t      subj_id,
00605          rsbac_acl_rights_vector_t   rights,
00606          rsbac_time_t                ttl)
00607   {
00608     int err=0;
00609 
00610 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00611       /* sanity check before using pointer */
00612       if(   (target == T_NETOBJ)
00613          && tid.netobj.sock_p
00614          && (   tid.netobj.remote_addr
00615 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00616              || !tid.netobj.sock_p->file
00617              || !tid.netobj.sock_p->file->f_dentry
00618              || !tid.netobj.sock_p->file->f_dentry->d_inode
00619              || (SOCKET_I(tid.netobj.sock_p->file->f_dentry->d_inode) != tid.netobj.sock_p)
00620 #else
00621              || !tid.netobj.sock_p->inode
00622              || (&(tid.netobj.sock_p->inode->u.socket_i) != tid.netobj.sock_p)
00623 #endif
00624             )
00625         )
00626         return -RSBAC_EINVALIDTARGET;
00627 #endif
00628 
00629 /* check only in non-maint mode */
00630 #if !defined(CONFIG_RSBAC_MAINT)
00631 #ifdef CONFIG_RSBAC_SWITCH_ACL
00632     if(rsbac_switch_acl)
00633 #endif
00634       {
00635         rsbac_uid_t user;
00636 
00637         if(rsbac_get_owner(&user))
00638           return -RSBAC_EREADFAILED;
00639         /* first try access control right (SUPERVISOR is included) */
00640         if(!rsbac_acl_check_right(target, tid, user, current->pid, ACLR_ACCESS_CONTROL))
00641           {
00642             /* no access control -> try forward for these rights */
00643             /* but only, if no ttl requested */
00644             if(   (ttl != RSBAC_LIST_TTL_KEEP)
00645                || !rsbac_acl_check_forward(target, tid, user, rights)
00646               )
00647               {
00648                 char * rights_string = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00649                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00650                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00651                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00652                 char * target_id_name
00653                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00654                 /* max. path name len + some extra */
00655                 #else
00656                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00657                 /* max. file name len + some extra */
00658                 #endif
00659 
00660                 u64tostracl(rights_string, rights);
00661                 get_acl_subject_type_name(subject_type_name, subj_type);
00662                 get_target_name(target_type_name, target, target_id_name, tid);
00663                 rsbac_printk(KERN_INFO
00664                        "rsbac_acl_sys_add_to_acl_entry(): adding rights %s for %s %u to %s %s denied for user %u!\n",
00665                        rights_string,
00666                        subject_type_name,
00667                        subj_id,
00668                        target_type_name,
00669                        target_id_name,
00670                        user);
00671                 rsbac_kfree(rights_string);
00672                 rsbac_kfree(subject_type_name);
00673                 rsbac_kfree(target_type_name);
00674                 rsbac_kfree(target_id_name);
00675                 #ifdef CONFIG_RSBAC_SOFTMODE
00676                 if(   !rsbac_softmode
00677                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00678                    && !rsbac_ind_softmode[ACL]
00679                 #endif
00680                   )
00681                 #endif
00682                   return(-EPERM);
00683               }
00684           }
00685         if(rights & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR)
00686           {
00687             /* you must have SUPERVISOR to add SUPERVISOR */
00688             if(!rsbac_acl_check_super(target, tid, user))
00689               {
00690                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00691                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00692                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00693                 char * target_id_name
00694                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00695                 /* max. path name len + some extra */
00696                 #else
00697                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00698                 /* max. file name len + some extra */
00699                 #endif
00700 
00701                 get_acl_subject_type_name(subject_type_name, subj_type);
00702                 get_target_name(target_type_name, target, target_id_name, tid);
00703                 rsbac_printk(KERN_INFO
00704                        "rsbac_acl_sys_add_to_acl_entry(): adding SUPERVISOR for %s %u to %s %s denied for user %u!\n",
00705                        subject_type_name,
00706                        subj_id,
00707                        target_type_name,
00708                        target_id_name,
00709                        user);
00710                 rsbac_kfree(subject_type_name);
00711                 rsbac_kfree(target_type_name);
00712                 rsbac_kfree(target_id_name);
00713                 #ifdef CONFIG_RSBAC_SOFTMODE
00714                 if(   !rsbac_softmode
00715                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00716                    && !rsbac_ind_softmode[ACL]
00717                 #endif
00718                   )
00719                 #endif
00720                   return(-EPERM);
00721               }
00722           }
00723       }
00724 #endif /* !MAINT */
00725 
00726     /* OK, check passed. Set ACL. */
00727     err = rsbac_acl_add_to_acl_entry(ta_number, target, tid, subj_type, subj_id, rights, ttl);
00728     if(err)
00729       {
00730         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00731 
00732         if(tmp)
00733           {
00734             rsbac_printk(KERN_WARNING
00735                    "rsbac_acl_sys_add_to_acl_entry(): rsbac_acl_add_to_acl_entry() returned error %s!\n",
00736                    get_error_name(tmp,err));
00737             rsbac_kfree(tmp);
00738           }
00739       }
00740     return err;
00741   }
00742 
00743 int rsbac_acl_sys_remove_from_acl_entry(
00744          rsbac_list_ta_number_t      ta_number,
00745   enum   rsbac_target_t              target,
00746   union  rsbac_target_id_t           tid,
00747   enum   rsbac_acl_subject_type_t    subj_type,
00748          rsbac_acl_subject_id_t      subj_id,
00749          rsbac_acl_rights_vector_t   rights)
00750   {
00751     int err=0;
00752 
00753 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00754       /* sanity check before using pointer */
00755       if(   (target == T_NETOBJ)
00756          && tid.netobj.sock_p
00757          && (   tid.netobj.remote_addr
00758 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00759              || !tid.netobj.sock_p->file
00760              || !tid.netobj.sock_p->file->f_dentry
00761              || !tid.netobj.sock_p->file->f_dentry->d_inode
00762              || (SOCKET_I(tid.netobj.sock_p->file->f_dentry->d_inode) != tid.netobj.sock_p)
00763 #else
00764              || !tid.netobj.sock_p->inode
00765              || (&(tid.netobj.sock_p->inode->u.socket_i) != tid.netobj.sock_p)
00766 #endif
00767             )
00768         )
00769         return -RSBAC_EINVALIDTARGET;
00770 #endif
00771 
00772 /* check only in non-maint mode */
00773 #if !defined(CONFIG_RSBAC_MAINT)
00774 #ifdef CONFIG_RSBAC_SWITCH_ACL
00775     if(rsbac_switch_acl)
00776 #endif
00777       {
00778         rsbac_uid_t user;
00779 
00780         if(rsbac_get_owner(&user))
00781           return -RSBAC_EREADFAILED;
00782         /* first try access control right (SUPERVISOR is included) */
00783         if(!rsbac_acl_check_right(target, tid, user, current->pid, ACLR_ACCESS_CONTROL))
00784           {
00785             char * rights_string = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00786             char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00787             char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00788             #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00789             char * target_id_name
00790               = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00791             /* max. path name len + some extra */
00792             #else
00793             char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00794             /* max. file name len + some extra */
00795             #endif
00796 
00797             u64tostracl(rights_string, rights);
00798             get_acl_subject_type_name(subject_type_name, subj_type);
00799             get_target_name(target_type_name, target, target_id_name, tid);
00800             rsbac_printk(KERN_INFO
00801                    "rsbac_acl_sys_remove_from_acl_entry(): removing rights %s for %s %u to %s %s denied for user %u!\n",
00802                    rights_string,
00803                    subject_type_name,
00804                    subj_id,
00805                    target_type_name,
00806                    target_id_name,
00807                    user);
00808             rsbac_kfree(rights_string);
00809             rsbac_kfree(subject_type_name);
00810             rsbac_kfree(target_type_name);
00811             rsbac_kfree(target_id_name);
00812             #ifdef CONFIG_RSBAC_SOFTMODE
00813             if(   !rsbac_softmode
00814             #ifdef CONFIG_RSBAC_SOFTMODE_IND
00815                && !rsbac_ind_softmode[ACL]
00816             #endif
00817               )
00818             #endif
00819               return(-EPERM);
00820           }
00821         if(rights & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR)
00822           {
00823             /* you must have SUPERVISOR to revoke SUPERVISOR */
00824             if(!rsbac_acl_check_super(target, tid, user))
00825               {
00826                 char * subject_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00827                 char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00828                 #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00829                 char * target_id_name
00830                   = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00831                 /* max. path name len + some extra */
00832                 #else
00833                 char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00834                 /* max. file name len + some extra */
00835                 #endif
00836 
00837                 get_acl_subject_type_name(subject_type_name, subj_type);
00838                 get_target_name(target_type_name, target, target_id_name, tid);
00839                 rsbac_printk(KERN_INFO
00840                        "rsbac_acl_sys_remove_from_acl_entry(): removing SUPERVISOR for %s %u to %s %s denied for user %u!\n",
00841                        subject_type_name,
00842                        subj_id,
00843                        target_type_name,
00844                        target_id_name,
00845                        user);
00846                 rsbac_kfree(subject_type_name);
00847                 rsbac_kfree(target_type_name);
00848                 rsbac_kfree(target_id_name);
00849                 #ifdef CONFIG_RSBAC_SOFTMODE
00850                 if(   !rsbac_softmode
00851                 #ifdef CONFIG_RSBAC_SOFTMODE_IND
00852                    && !rsbac_ind_softmode[ACL]
00853                 #endif
00854                   )
00855                 #endif
00856                   return(-EPERM);
00857               }
00858           }
00859       }
00860 #endif /* !MAINT */
00861 
00862     /* OK, check passed. Remove ACL. */
00863     err = rsbac_acl_remove_from_acl_entry(ta_number, target, tid, subj_type, subj_id, rights);
00864     if(err)
00865       {
00866         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00867 
00868         if(tmp)
00869           {
00870             rsbac_printk(KERN_WARNING
00871                    "rsbac_acl_sys_remove_from_acl_entry(): rsbac_acl_remove_from_acl_entry() returned error %s!\n",
00872                    get_error_name(tmp,err));
00873             rsbac_kfree(tmp);
00874           }
00875       }
00876     return err;
00877   }
00878 
00879 int rsbac_acl_sys_set_mask(
00880          rsbac_list_ta_number_t      ta_number,
00881   enum   rsbac_target_t              target,
00882   union  rsbac_target_id_t           tid,
00883          rsbac_acl_rights_vector_t   mask)
00884   {
00885     int err=0;
00886 
00887 /* check only in non-maint mode */
00888 #if !defined(CONFIG_RSBAC_MAINT) || defined (CONFIG_RSBAC_ACL_SUPER_FILTER)
00889     rsbac_uid_t user;
00890 
00891     if(rsbac_get_owner(&user))
00892       return -RSBAC_EREADFAILED;
00893 #endif
00894 
00895 #ifdef CONFIG_RSBAC_ACL_NET_OBJ_PROT
00896       /* sanity check before using pointer */
00897       if(   (target == T_NETOBJ)
00898          && tid.netobj.sock_p
00899          && (   tid.netobj.remote_addr
00900 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00901              || !tid.netobj.sock_p->file
00902              || !tid.netobj.sock_p->file->f_dentry
00903              || !tid.netobj.sock_p->file->f_dentry->d_inode
00904              || (SOCKET_I(tid.netobj.sock_p->file->f_dentry->d_inode) != tid.netobj.sock_p)
00905 #else
00906              || !tid.netobj.sock_p->inode
00907              || (&(tid.netobj.sock_p->inode->u.socket_i) != tid.netobj.sock_p)
00908 #endif
00909             )
00910         )
00911         return -RSBAC_EINVALIDTARGET;
00912 #endif
00913 
00914 #if !defined(CONFIG_RSBAC_MAINT)
00915 #ifdef CONFIG_RSBAC_SWITCH_ACL
00916     if(rsbac_switch_acl)
00917 #endif
00918       {
00919         /* first try access control right (SUPERVISOR is included) */
00920         if(!rsbac_acl_check_right(target, tid, user, current->pid, ACLR_ACCESS_CONTROL))
00921           {
00922             char * rights_string = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00923             char * target_type_name = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00924             #ifdef CONFIG_RSBAC_LOG_FULL_PATH
00925             char * target_id_name
00926               = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + RSBAC_MAXNAMELEN);
00927             /* max. path name len + some extra */
00928             #else
00929             char * target_id_name = rsbac_kmalloc(2 * RSBAC_MAXNAMELEN);
00930             /* max. file name len + some extra */
00931             #endif
00932 
00933             u64tostracl(rights_string, mask);
00934             get_target_name(target_type_name, target, target_id_name, tid);
00935             rsbac_printk(KERN_INFO
00936                          "rsbac_acl_sys_set_mask(): setting mask %s for %s %s denied for user %u!\n",
00937                          rights_string,
00938                          target_type_name,
00939                          target_id_name,
00940                          user);
00941             rsbac_kfree(rights_string);
00942             rsbac_kfree(target_type_name);
00943             rsbac_kfree(target_id_name);
00944             #ifdef CONFIG_RSBAC_SOFTMODE
00945             if(   !rsbac_softmode
00946             #ifdef CONFIG_RSBAC_SOFTMODE_IND
00947                && !rsbac_ind_softmode[ACL]
00948             #endif
00949               )
00950             #endif
00951               return(-EPERM);
00952           }
00953       }
00954 #endif /* !MAINT */
00955 
00956 #ifdef CONFIG_RSBAC_ACL_SUPER_FILTER
00957     if(!(mask & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR))
00958       { /* trial to mask out SUPERVISOR */
00959         rsbac_acl_rights_vector_t res_rights = 0;
00960 
00961         /* you must have direct SUPERVISOR as a USER to set a mask without SUPERVISOR */
00962         /* get direct own rights (still uses default_fd_rights) */
00963         err = rsbac_acl_get_rights(0, target, tid, ACLS_USER, user, &res_rights, FALSE);
00964         if(err)
00965           return -RSBAC_EREADFAILED;
00966         if(!(res_rights & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR))
00967           mask |= RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR;
00968       }
00969 #else
00970     /* SUPERVISOR must never be masked out */
00971     mask |= RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR;
00972 #endif
00973 
00974     /* OK, checks passed. Set mask. */
00975     err = rsbac_acl_set_mask(ta_number, target, tid, mask);
00976     if(err)
00977       {
00978         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00979 
00980         if(tmp)
00981           {
00982             rsbac_printk(KERN_WARNING
00983                    "rsbac_acl_sys_set_mask(): rsbac_acl_set_mask() returned error %s!\n",
00984                    get_error_name(tmp,err));
00985             rsbac_kfree(tmp);
00986           }
00987       }
00988     return err;
00989   }
00990 
00991 int rsbac_acl_sys_remove_user(
00992   rsbac_list_ta_number_t ta_number,
00993   rsbac_uid_t uid)
00994   {
00995     int err=0;
00996 
00997 /* check only in non-maint mode */
00998 #if !defined(CONFIG_RSBAC_MAINT)
00999 #ifdef CONFIG_RSBAC_SWITCH_ACL
01000     if(rsbac_switch_acl)
01001 #endif
01002       {
01003         rsbac_uid_t user;
01004         union rsbac_target_id_t tid;
01005 
01006         if(rsbac_get_owner(&user))
01007           return -RSBAC_EREADFAILED;
01008         tid.user = uid;
01009         /* first try access control right (SUPERVISOR is included) */
01010         if(!rsbac_acl_check_right(T_USER, tid, user, current->pid, R_DELETE))
01011           {
01012             rsbac_printk(KERN_INFO
01013                          "rsbac_acl_sys_remove_user(): removing all data for user %u denied for user %u!\n",
01014                          uid,
01015                          user);
01016             #ifdef CONFIG_RSBAC_SOFTMODE
01017             if(   !rsbac_softmode
01018             #ifdef CONFIG_RSBAC_SOFTMODE_IND
01019                && !rsbac_ind_softmode[ACL]
01020             #endif
01021               )
01022             #endif
01023               return(-EPERM);
01024           }
01025       }
01026 #endif /* !MAINT */
01027 
01028     rsbac_printk(KERN_INFO
01029                  "rsbac_acl_sys_remove_user(): removing all data for user %u!\n",
01030                  uid);
01031     /* OK, checks passed. Set mask. */
01032     err = rsbac_acl_remove_user(ta_number, uid);
01033     if(err)
01034       {
01035         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01036 
01037         if(tmp)
01038           {
01039             rsbac_printk(KERN_WARNING
01040                    "rsbac_acl_sys_remove_user(): rsbac_acl_remove_user() returned error %s!\n",
01041                    get_error_name(tmp,err));
01042             rsbac_kfree(tmp);
01043           }
01044       }
01045     return err;
01046   }
01047 
01048 /*********/
01049 
01050 int rsbac_acl_sys_get_mask(
01051          rsbac_list_ta_number_t      ta_number,
01052   enum   rsbac_target_t              target,
01053   union  rsbac_target_id_t           tid,
01054          rsbac_acl_rights_vector_t * mask_p)
01055   {
01056     int err=0;
01057 
01058 /* no check */
01059 
01060     /* OK, check passed. Get mask. */
01061     err = rsbac_acl_get_mask(ta_number, target, tid, mask_p);
01062     if(err)
01063       {
01064         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01065 
01066         if(tmp)
01067           {
01068             rsbac_printk(KERN_WARNING
01069                    "rsbac_acl_sys_get_mask(): rsbac_acl_get_mask() returned error %s!\n",
01070                    get_error_name(tmp,err));
01071             rsbac_kfree(tmp);
01072           }
01073       }
01074     return err;
01075   }
01076 
01077 int rsbac_acl_sys_get_rights(
01078          rsbac_list_ta_number_t      ta_number,
01079   enum   rsbac_target_t              target,
01080   union  rsbac_target_id_t           tid,
01081   enum   rsbac_acl_subject_type_t    subj_type,
01082          rsbac_acl_subject_id_t      subj_id,
01083          rsbac_acl_rights_vector_t * rights_p,
01084          rsbac_boolean_t                     effective)
01085   {
01086     int err=0;
01087     rsbac_acl_rights_vector_t res_rights;
01088     #if defined(CONFIG_RSBAC_RC)
01089     union rsbac_target_id_t       i_tid;
01090     union rsbac_attribute_value_t i_attr_val1;
01091     #endif
01092 
01093     /* no check (Attention: rsbac_acl_check_forward depends on this to be allowed!) */
01094 
01095     if(   (subj_type == ACLS_USER)
01096        && (subj_id == RSBAC_NO_USER)
01097       )
01098       rsbac_get_owner((rsbac_uid_t *) &subj_id);
01099     /* OK, check passed. Call ACL. */
01100     if(effective)
01101       {
01102         /* inherited own rights */
01103         res_rights = 0;
01104         err = rsbac_acl_get_rights(ta_number, target, tid, subj_type, subj_id, &res_rights, TRUE);
01105         if(err)
01106           {
01107             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01108 
01109             if(tmp)
01110               {
01111                 rsbac_printk(KERN_WARNING
01112                        "rsbac_acl_sys_get_rights(): rsbac_acl_get_rights() returned error %s!\n",
01113                        get_error_name(tmp,err));
01114                 rsbac_kfree(tmp);
01115               }
01116             return err;
01117           }
01118         *rights_p = res_rights;
01119         /* add group and role rights, if normal user */
01120         if(subj_type == ACLS_USER)
01121           {
01122             rsbac_acl_group_id_t * group_p;
01123             int                    i;
01124             int                    tmperr;
01125 
01126             /* group everyone */
01127             res_rights = 0;
01128             err = rsbac_acl_get_rights(ta_number, target, tid,
01129                                        ACLS_GROUP, RSBAC_ACL_GROUP_EVERYONE,
01130                                        &res_rights, TRUE);
01131             if(err)
01132               {
01133                 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01134 
01135                 if(tmp)
01136                   {
01137                     rsbac_printk(KERN_WARNING
01138                            "rsbac_acl_sys_get_rights(): rsbac_acl_get_rights() returned error %s!\n",
01139                            get_error_name(tmp,err));
01140                     rsbac_kfree(tmp);
01141                   }
01142                 return err;
01143               }
01144             *rights_p |= res_rights;
01145 
01146             /* other groups */
01147             /* first get user groups */
01148             group_p = NULL;
01149             err = rsbac_acl_get_user_groups(ta_number, subj_id, &group_p, NULL);
01150             if(err<0)
01151               {
01152                 char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01153 
01154                 if(tmp)
01155                   {
01156                     rsbac_printk(KERN_WARNING
01157                            "rsbac_acl_sys_get_rights(): rsbac_acl_get_user_groups() returned error %s!\n",
01158                            get_error_name(tmp,err));
01159                     rsbac_kfree(tmp);
01160                   }
01161                 return err;
01162               }
01163             for(i=0; i<err; i++)
01164               {
01165                 res_rights = 0;
01166                 tmperr = rsbac_acl_get_rights(ta_number, target, tid, ACLS_GROUP, group_p[i],
01167                                               &res_rights, TRUE);
01168                 if(tmperr)
01169                   {
01170                     char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01171 
01172                     if(tmp)
01173                       {
01174                         rsbac_printk(KERN_WARNING
01175                                "rsbac_acl_sys_get_rights(): rsbac_acl_get_rights() returned error %s!\n",
01176                                get_error_name(tmp,err));
01177                         rsbac_kfree(tmp);
01178                       }
01179                     if(group_p)
01180                       rsbac_vfree(group_p);
01181                     return tmperr;
01182                   }
01183                 *rights_p |= res_rights;
01184               }
01185             err = 0;
01186             if(group_p)
01187               rsbac_vfree(group_p);
01188 
01189             #if defined(CONFIG_RSBAC_RC)
01190             /* use user role */
01191             /* first get role */
01192             i_tid.user = subj_id;
01193             if (rsbac_get_attr(RC,
01194                                T_USER,
01195                                i_tid,
01196                                A_rc_def_role,
01197                                &i_attr_val1,
01198                                FALSE))
01199               {
01200                 rsbac_printk(KERN_WARNING
01201                        "rsbac_acl_sys_get_rights(): rsbac_get_attr() for process rc_role returned error!\n");
01202               }
01203             else
01204               {
01205                 res_rights = 0;
01206                 err = rsbac_acl_get_rights(ta_number, target, tid,
01207                                            ACLS_ROLE, i_attr_val1.rc_role,
01208                                            &res_rights, TRUE);
01209                 if(err)
01210                   {
01211                     char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01212 
01213                     if(tmp)
01214                       {
01215                         get_error_name(tmp,err);
01216                         rsbac_printk(KERN_WARNING
01217                                "rsbac_acl_sys_get_rights(): rsbac_acl_get_rights() returned error %s!\n",
01218                                tmp);
01219                         rsbac_kfree(tmp);
01220                       }
01221                     return err;
01222                   }
01223                 *rights_p |= res_rights;
01224               }
01225             #endif
01226 
01227             /* check for SUPERVISOR right, if not yet there */
01228             if(   !(*rights_p & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR)
01229                && rsbac_acl_check_super(target, tid, subj_id)
01230               )
01231               *rights_p |= RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR;
01232           }
01233         else /* not ACLS_USER */
01234           {
01235             if(!(*rights_p & RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR))
01236               {
01237                 rsbac_boolean_t i_result = FALSE;
01238 
01239                 /* check for SUPERVISOR right */
01240                 /* own right */
01241                 err = rsbac_acl_get_single_right(target,
01242                                                  tid,
01243                                                  subj_type,
01244                                                  subj_id,
01245                                                  ACLR_SUPERVISOR,
01246                                                  &i_result);
01247                 if(err)
01248                   {
01249                     char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01250 
01251                     if(tmp)
01252                       {
01253                         rsbac_printk(KERN_WARNING
01254                                "rsbac_acl_sys_get_rights(): rsbac_acl_get_right() returned error %s!\n",
01255                                get_error_name(tmp,err));
01256                         rsbac_kfree(tmp);
01257                       }
01258                   }
01259                 else
01260                   if(i_result)
01261                     *rights_p |= RSBAC_ACL_SUPERVISOR_RIGHT_VECTOR;
01262               }
01263           }
01264       }
01265     else /* not effective = direct */
01266       {
01267         /* direct own rights (still uses default_fd_rights) */
01268         res_rights = 0;
01269         err = rsbac_acl_get_rights(ta_number, target, tid, subj_type, subj_id, &res_rights, FALSE);
01270         if(!err)
01271           *rights_p = res_rights;
01272       }
01273     return err;
01274   }
01275 
01276 int rsbac_acl_sys_get_tlist(
01277          rsbac_list_ta_number_t    ta_number,
01278   enum   rsbac_target_t            target,
01279   union  rsbac_target_id_t         tid,
01280   struct rsbac_acl_entry_t      ** entry_pp,
01281          rsbac_time_t           ** ttl_pp)
01282   {
01283     int err=0;
01284 
01285     /* no check */
01286 
01287     /* OK, check passed. Call ACL. */
01288     err = rsbac_acl_get_tlist(ta_number, target, tid, entry_pp, ttl_pp);
01289     if(err == -RSBAC_ENOTFOUND)
01290       err = 0;
01291     else
01292       if(err<0)
01293         {
01294           char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01295 
01296           if(tmp)
01297             {
01298               rsbac_printk(KERN_WARNING
01299                      "rsbac_acl_sys_get_tlist(): rsbac_acl_get_tlist() returned error %s!\n",
01300                      get_error_name(tmp,err));
01301               rsbac_kfree(tmp);
01302             }
01303         }
01304     return err;
01305   }
01306 
01307 /*********** Groups ***********/
01308 
01309 int rsbac_acl_sys_group(
01310         rsbac_list_ta_number_t         ta_number,
01311   enum  rsbac_acl_group_syscall_type_t call,
01312   union rsbac_acl_group_syscall_arg_t  arg)
01313   {
01314     int err = -RSBAC_EINVALIDREQUEST;
01315     char * k_name;
01316     rsbac_acl_group_id_t k_group;
01317     struct rsbac_acl_group_entry_t entry;
01318     rsbac_uid_t caller;
01319 
01320     if(call >= ACLGS_none)
01321       return -RSBAC_EINVALIDREQUEST;
01322     if(rsbac_get_owner(&caller))
01323       return -RSBAC_EREADFAILED;
01324 
01325 #ifdef CONFIG_RSBAC_DEBUG
01326     if(rsbac_debug_aef_acl)
01327       {
01328         char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
01329 
01330         if(tmp)
01331           {
01332             rsbac_printk(KERN_DEBUG
01333                    "rsbac_acl_sys_group(): %s called\n",
01334                    get_acl_group_syscall_name(tmp,call));
01335             rsbac_kfree(tmp);
01336           }
01337       }
01338 #endif
01339     
01340     switch(call)
01341       {
01342         case ACLGS_add_group:
01343           if(arg.add_group.type >= ACLG_NONE)
01344             {
01345               err = -RSBAC_EINVALIDVALUE;
01346               break;
01347             }
01348           k_name = rsbac_getname(arg.add_group.name);
01349           if(!k_name)
01350             {
01351               err = -RSBAC_EINVALIDVALUE;
01352               break;
01353             }
01354           err = rsbac_get_user((char *)&k_group, (char *)arg.add_group.group_id_p, sizeof(k_group));
01355           if(err)
01356             break;
01357           err = rsbac_acl_add_group(ta_number,
01358                                     caller,
01359                                     arg.add_group.type,
01360                                     k_name,
01361                                     &k_group);
01362           rsbac_putname(k_name);
01363           if(!err)
01364             err = rsbac_put_user((char *)&k_group, (char *) arg.add_group.group_id_p, sizeof(k_group));
01365           break;
01366 
01367         case ACLGS_change_group:
01368           if(arg.change_group.type >= ACLG_NONE)
01369             {
01370               err = -RSBAC_EINVALIDVALUE;
01371               break;
01372             }
01373           err = rsbac_acl_get_group_entry(ta_number, arg.change_group.id, &entry);
01374           if(err)
01375             break;
01376           /* check owner only, if non-maint */
01377 #if !defined(CONFIG_RSBAC_MAINT)
01378 #ifdef CONFIG_RSBAC_SWITCH_ACL
01379           if(rsbac_switch_acl)
01380 #endif
01381             {
01382               if(entry.owner != caller)
01383                 {
01384                   rsbac_printk(KERN_INFO
01385                                "rsbac_acl_group(): changing group %u denied for user %u - not owner!\n",
01386                                entry.id,
01387                                caller);
01388                   err = -EPERM;
01389                   break;
01390                 }
01391             }
01392 #endif /* !MAINT */
01393           {
01394             char * k_name;
01395 
01396             k_name = rsbac_getname(arg.change_group.name);
01397             if(k_name)
01398               {
01399                 err = rsbac_acl_change_group(ta_number,
01400                                              arg.change_group.id,
01401                                              arg.change_group.owner,
01402                                              arg.change_group.type,
01403                                              k_name);
01404                 putname(k_name);
01405               }
01406             else
01407               err = -RSBAC_EINVALIDVALUE;
01408           }
01409           break;
01410 
01411         case ACLGS_remove_group:
01412           err = rsbac_acl_get_group_entry(ta_number, arg.remove_group.id, &entry);
01413           if(err)
01414             break;
01415           /* check owner only, if non-maint */
01416 #if !defined(CONFIG_RSBAC_MAINT)
01417 #ifdef CONFIG_RSBAC_SWITCH_ACL
01418           if(rsbac_switch_acl)
01419 #endif
01420             {
01421               if(entry.owner != caller)
01422                 {
01423                   rsbac_printk(KERN_INFO
01424                                "rsbac_acl_group(): removing group %u denied for user %u - not owner!\n",
01425                                entry.id,
01426                                caller);
01427                   err = -EPERM;
01428                   break;
01429                 }
01430             }
01431 #endif /* !MAINT */
01432           err = rsbac_acl_remove_group(ta_number, arg.remove_group.id);
01433           break;
01434 
01435         case ACLGS_get_group_entry:
01436           if(!arg.get_group_entry.entry_p)
01437             {
01438               err = -RSBAC_EINVALIDPOINTER;
01439               break;
01440             }
01441           if(!arg.get_group_entry.id)
01442             { /* Everyone -> fill by hand */
01443               entry.id=0;
01444               entry.owner=RSBAC_NO_USER;
01445               entry.type=ACLG_GLOBAL;
01446               strcpy(entry.name, "Everyone");
01447               err=0;
01448             }
01449           else
01450             {
01451               err = rsbac_acl_get_group_entry(ta_number,
01452                                               arg.get_group_entry.id,
01453                                               &entry);
01454             }
01455           if(!err)
01456             {
01457               if(  (entry.owner != caller)
01458                  &&(entry.type != ACLG_GLOBAL)
01459                 )
01460                 {
01461                   rsbac_printk(KERN_INFO
01462                                "rsbac_acl_group(): getting group entry %u denied for user %u - neither owner nor global!\n",
01463                                entry.id,
01464                                caller);
01465                   err = -EPERM;
01466                 }
01467               else
01468                 err = rsbac_put_user((char *)&entry, (char *)arg.get_group_entry.entry_p, sizeof(entry));
01469             }
01470           break;
01471 
01472         case ACLGS_list_groups:
01473           if(arg.list_groups.maxnum <= 0)
01474             {
01475               err = -RSBAC_EINVALIDVALUE;
01476               break;
01477             }
01478           if(!arg.list_groups.group_entry_array)
01479             {
01480               err = -RSBAC_EINVALIDPOINTER;
01481               break;
01482             }
01483           {
01484             struct rsbac_acl_group_entry_t * entry_p;
01485             int tmperr=0;
01486 
01487             if(arg.list_groups.include_global)
01488               {
01489                 struct rsbac_acl_group_entry_t   entry_0;
01490 
01491                 entry_0.id=0;
01492                 entry_0.owner=RSBAC_NO_USER;
01493                 entry_0.type=ACLG_GLOBAL;
01494                 strcpy(entry_0.name, "Everyone");
01495                 tmperr = rsbac_put_user((char *) &entry_0,
01496                                         (char *) arg.list_groups.group_entry_array,
01497                                         sizeof(entry_0));
01498                 if(tmperr)
01499                   {
01500                     err = tmperr;
01501                     break;
01502                   }
01503                 else
01504                   err = 1;
01505                 arg.list_groups.maxnum--;
01506                 arg.list_groups.group_entry_array++;
01507               }
01508             else
01509               err = 0;
01510 
01511             if(arg.list_groups.maxnum)
01512               {
01513                 long count;
01514 
01515                 count = rsbac_acl_list_groups(ta_number,
01516                                               caller,
01517                                               arg.list_groups.include_global,
01518                                               &entry_p);
01519                 if(count>0)
01520                   {
01521                     if(count > arg.list_groups.maxnum)
01522                       count = arg.list_groups.maxnum;
01523                     err+=count;
01524                     tmperr = rsbac_put_user((char *)entry_p,
01525                                             ((char *)arg.list_groups.group_entry_array),
01526                                             count * sizeof(*entry_p));
01527                     if(tmperr)
01528                       err=tmperr;
01529                     rsbac_vfree(entry_p);
01530                   }
01531                 else
01532                   if(count < 0)
01533                     err=count;
01534               }
01535           }
01536           break;
01537 
01538         case ACLGS_add_member:
01539           /* check owner only, if non-maint */
01540 #if !defined(CONFIG_RSBAC_MAINT)
01541 #ifdef CONFIG_RSBAC_SWITCH_ACL
01542           if(rsbac_switch_acl)
01543 #endif
01544             {
01545               err = rsbac_acl_get_group_entry(ta_number, arg.add_member.group, &entry);
01546               if(err)
01547                 break;
01548               if(entry.owner != caller)
01549                 {
01550                   rsbac_printk(KERN_INFO
01551                                "rsbac_acl_group(): adding group member to group %u denied for user %u - not owner!\n",
01552                                entry.id,
01553                                caller);
01554                   err = -EPERM;
01555                   break;
01556                 }
01557             }
01558 #endif /* !MAINT */
01559           err = rsbac_acl_add_group_member(ta_number,
01560                                            arg.add_member.group,
01561                                            arg.add_member.user,
01562                                            arg.add_member.ttl);
01563           break;
01564 
01565         case ACLGS_remove_member:
01566           /* check owner only, if non-maint */
01567 #if !defined(CONFIG_RSBAC_MAINT)
01568 #ifdef CONFIG_RSBAC_SWITCH_ACL
01569           if(rsbac_switch_acl)
01570 #endif
01571             {
01572               err = rsbac_acl_get_group_entry(ta_number, arg.remove_member.group, &entry);
01573               if(err)
01574                 break;
01575               if(entry.owner != caller)
01576                 {
01577                   rsbac_printk(KERN_INFO
01578                                "rsbac_acl_group(): removing group member from group %u denied for user %u - not owner!\n",
01579                                entry.id,
01580                                caller);
01581                   err = -EPERM;
01582                   break;
01583                 }
01584             }
01585 #endif /* !MAINT */
01586           err = rsbac_acl_remove_group_member(ta_number, arg.remove_member.group, arg.remove_member.user);
01587           break;
01588 
01589         case ACLGS_get_user_groups:
01590           {
01591             rsbac_acl_group_id_t * group_p = NULL;
01592             rsbac_time_t * ttl_p = NULL;
01593 
01594             if(arg.get_user_groups.maxnum <= 0)
01595               {
01596                 err = -RSBAC_EINVALIDVALUE;
01597                 break;
01598               }
01599             if(!arg.get_user_groups.group_array)
01600               {
01601                 err = -RSBAC_EINVALIDPOINTER;
01602                 break;
01603               }
01604             if(arg.get_user_groups.user == RSBAC_NO_USER)
01605               arg.get_user_groups.user = caller;
01606 #if !defined(CONFIG_RSBAC_MAINT)
01607             else
01608 #ifdef CONFIG_RSBAC_SWITCH_ACL
01609               if(rsbac_switch_acl)
01610 #endif
01611                 {
01612                   if(arg.get_user_groups.user != caller)
01613                     {
01614                       rsbac_printk(KERN_INFO
01615                                    "rsbac_acl_group(): getting user groups for user %u denied for user %u!\n",
01616                                    arg.get_user_groups.user,
01617                                    caller);
01618                       err = -EPERM;
01619                       break;
01620                     }
01621                 }
01622 #endif /* !MAINT */
01623             err = rsbac_acl_get_user_groups(ta_number, arg.get_user_groups.user, &group_p, &ttl_p);
01624             if(err>0)
01625               {
01626                 int tmperr;
01627 
01628                 err = rsbac_min(err, arg.get_user_groups.maxnum);
01629                 tmperr = rsbac_put_user((char *)group_p,
01630                                         (char *)arg.get_user_groups.group_array,
01631                                         err * sizeof(*group_p));
01632                 if(tmperr)
01633                   err=tmperr;
01634                 if(arg.get_user_groups.ttl_array)
01635                   {
01636                     tmperr = rsbac_put_user((char *)ttl_p,
01637                                             (char *)arg.get_user_groups.ttl_array,
01638                                             err * sizeof(*ttl_p));
01639                     if(tmperr)
01640                       err=tmperr;
01641                   }
01642               }
01643             if(group_p)
01644               rsbac_vfree(group_p);
01645             if(ttl_p)
01646               rsbac_vfree(ttl_p);
01647             break;
01648           }
01649 
01650         case ACLGS_get_group_members:
01651           if(   (arg.get_group_members.maxnum <= 0)
01652              || !arg.get_group_members.group
01653             )
01654             {
01655               err = -RSBAC_EINVALIDVALUE;
01656               break;
01657             }
01658           if(arg.get_group_members.maxnum > RSBAC_ACL_MAX_MAXNUM)
01659             arg.get_group_members.maxnum = RSBAC_ACL_MAX_MAXNUM;
01660           if(!arg.get_group_members.user_array)
01661             {
01662               err = -RSBAC_EINVALIDPOINTER;
01663               break;
01664             }
01665           err = rsbac_acl_get_group_entry(ta_number,
01666                                           arg.get_group_members.group,
01667                                           &entry);
01668           if(err)
01669             break;
01670           if(  (entry.owner != caller)
01671              &&(entry.type != ACLG_GLOBAL)
01672             )
01673             {
01674               rsbac_printk(KERN_INFO
01675                            "rsbac_acl_group(): getting group members of group %u denied for user %u - neither owner nor global!\n",
01676                            entry.id,
01677                            caller);
01678               err = -EPERM;
01679               break;
01680             }
01681           {
01682             rsbac_uid_t * user_array;
01683             rsbac_time_t * ttl_array;
01684             
01685             user_array = rsbac_vmalloc(sizeof(*user_array) * arg.get_group_members.maxnum);
01686             if(!user_array)
01687               return -RSBAC_ENOMEM;
01688             ttl_array = rsbac_vmalloc(sizeof(*ttl_array) * arg.get_group_members.maxnum);
01689             if(!ttl_array)
01690               {
01691                 rsbac_vfree(user_array);
01692                 return -RSBAC_ENOMEM;
01693               }
01694 
01695             err = rsbac_acl_get_group_members(ta_number,
01696                                               arg.get_group_members.group,
01697                                               user_array,
01698                                               ttl_array,
01699                                               arg.get_group_members.maxnum);
01700             if(err>0)
01701               {
01702                 int tmperr;
01703 
01704                 tmperr = rsbac_put_user((char *)user_array,
01705                                         (char *)arg.get_group_members.user_array,
01706                                         err * sizeof(*user_array));
01707                 if(tmperr)
01708                   err=tmperr;
01709                 if(arg.get_group_members.ttl_array)
01710                   {
01711                     tmperr = rsbac_put_user((char *)ttl_array,
01712                                             (char *)arg.get_group_members.ttl_array,
01713                                             err * sizeof(*ttl_array));
01714                     if(tmperr)
01715                       err=tmperr;
01716                   }
01717               }
01718             rsbac_vfree(user_array);
01719             rsbac_vfree(ttl_array);
01720           }
01721           break;
01722 
01723         default:
01724           break;
01725       }
01726     #ifdef CONFIG_RSBAC_SOFTMODE
01727     if(   (   rsbac_softmode
01728     #ifdef CONFIG_RSBAC_SOFTMODE_IND
01729            || rsbac_ind_softmode[ACL]
01730     #endif
01731           )
01732        && (err == -EPERM)
01733       )
01734       return 0;
01735     else
01736     #endif
01737       return(err);
01738   };
01739 
01740 /* end of rsbac/adf/acl/syscalls.c */

Generated on Thu Sep 22 16:42:14 2005 for RSBAC by  doxygen 1.4.2