dazuko_rsbac.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) - Dazuko Malware Scan              */
00005 /* File: rsbac/adf/daz/daz_main.c                    */
00006 /*                                                   */
00007 /* Author and (c) 1999-2004: Amon Ott <ao@rsbac.org> */
00008 /* Copyright (c) 2004 H+BEDV Datentechnik GmbH       */
00009 /* Written by John Ogness <jogness@antivir.de>       */
00010 /*                                                   */
00011 /* Last modified: 30/Sep/2004                        */
00012 /*************************************************** */
00013 
00014 /* Dazuko RSBAC. Allow RSBAC Linux file access control for 3rd-party applications.
00015 
00016    This program is free software; you can redistribute it and/or
00017    modify it under the terms of the GNU General Public License
00018    as published by the Free Software Foundation; either version 2
00019    of the License, or (at your option) any later version.
00020 
00021    This program is distributed in the hope that it will be useful,
00022    but WITHOUT ANY WARRANTY; without even the implied warranty of
00023    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024    GNU General Public License for more details.
00025 
00026    You should have received a copy of the GNU General Public License
00027    along with this program; if not, write to the Free Software
00028    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00029 */
00030 
00031 #include "dazuko_rsbac.h"
00032 #include "dazuko_xp.h"
00033 #include "dazukoio.h"
00034 
00035 #include <linux/init.h>
00036 #include <linux/unistd.h>
00037 #include <linux/fs.h>
00038 #include <linux/slab.h>
00039 #include <linux/random.h>
00040 
00041 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00042 #include <linux/vermagic.h>
00043 #endif
00044 
00045 #include <linux/string.h>
00046 #include <linux/module.h>
00047 #include <linux/types.h>
00048 #include <linux/version.h>
00049 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00050 #include <linux/syscalls.h>
00051 #endif
00052 #include <asm/uaccess.h>
00053 #include <rsbac/types.h>
00054 #include <rsbac/aci.h>
00055 #include <rsbac/adf.h>
00056 #include <rsbac/adf_main.h>
00057 #include <rsbac/debug.h>
00058 #include <rsbac/error.h>
00059 #include <rsbac/helpers.h>
00060 #include <rsbac/getname.h>
00061 #include <rsbac/net_getname.h>
00062 #include <rsbac/rkmem.h>
00063 #include <rsbac/proc_fs.h>
00064 
00065 /************************************************* */
00066 /*           Global Variables                      */
00067 /************************************************* */
00068 
00069 #if defined(CONFIG_DEVFS_FS) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00070 #include <linux/devfs_fs_kernel.h>
00071 #endif
00072 
00073 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos);
00074 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos);
00075 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param);
00076 int linux_dazuko_device_open(struct inode *inode, struct file *file);
00077 int linux_dazuko_device_release(struct inode *inode, struct file *file);
00078 
00079 extern struct xp_atomic active;
00080 
00081 static int                      dev_major = -1;
00082 
00083 static struct file_operations   fops = {
00084                                         read: linux_dazuko_device_read,         /* read */
00085                                         write: linux_dazuko_device_write,       /* write */
00086                                         ioctl: linux_dazuko_device_ioctl,       /* ioctl */
00087                                         open: linux_dazuko_device_open,         /* open */
00088                                         release: linux_dazuko_device_release,   /* release */
00089                                 };
00090 
00091 /************************************************* */
00092 /*          Internal Help functions                */
00093 /************************************************* */
00094 
00095 #if defined(CONFIG_RSBAC_DAZ_CACHE)
00096 static int reset_scanned(struct rsbac_fs_file_t file)
00097   {
00098     union rsbac_attribute_value_t i_attr_val1;
00099     union rsbac_target_id_t       i_tid;
00100 
00101     /* reset scanned status for file */
00102     i_tid.file=file;
00103     i_attr_val1.daz_scanned = DAZ_unscanned;
00104     if(rsbac_set_attr(DAZ,
00105                       T_FILE,
00106                       i_tid,
00107                       A_daz_scanned,
00108                       i_attr_val1))
00109       {
00110         rsbac_printk(KERN_WARNING "reset_scanned(): rsbac_set_attr() returned error!\n");
00111         return(-RSBAC_EWRITEFAILED);
00112       }
00113     /* reset scanner flag for file */
00114     i_attr_val1.daz_scanner = FALSE;
00115     if(rsbac_set_attr(DAZ,
00116                       T_FILE,
00117                       i_tid,
00118                       A_daz_scanner,
00119                       i_attr_val1))
00120       {
00121         rsbac_printk(KERN_WARNING "reset_scanned(): rsbac_set_attr() returned error!\n");
00122         return(-RSBAC_EWRITEFAILED);
00123       }
00124     return(0);
00125   }
00126 #else
00127 static inline int reset_scanned(struct rsbac_fs_file_t file)
00128   {
00129     return 0;
00130   }
00131 #endif
00132 
00133 
00134 /* mutex */
00135 
00136 inline int xp_init_mutex(struct xp_mutex *mutex)
00137 {
00138         #ifdef init_MUTEX
00139                 init_MUTEX(&(mutex->mutex));
00140         #else
00141                 sema_init(&(mutex->mutex), 1);
00142         #endif
00143 
00144         return 0;
00145 }
00146 
00147 inline int xp_down(struct xp_mutex *mutex)
00148 {
00149         down(&(mutex->mutex));
00150         return 0;
00151 }
00152 
00153 inline int xp_up(struct xp_mutex *mutex)
00154 {
00155         up(&(mutex->mutex));
00156         return 0;
00157 }
00158 
00159 inline int xp_destroy_mutex(struct xp_mutex *mutex)
00160 {
00161         return 0;
00162 }
00163 
00164 
00165 /* read-write lock */
00166 
00167 inline int xp_init_rwlock(struct xp_rwlock *rwlock)
00168 {
00169         rwlock_init(&(rwlock->rwlock));
00170         return 0;
00171 }
00172 
00173 inline int xp_write_lock(struct xp_rwlock *rwlock)
00174 {
00175         write_lock(&(rwlock->rwlock));
00176         return 0;
00177 }
00178 
00179 inline int xp_write_unlock(struct xp_rwlock *rwlock)
00180 {
00181         write_unlock(&(rwlock->rwlock));
00182         return 0;
00183 }
00184 
00185 inline int xp_read_lock(struct xp_rwlock *rlock)
00186 {
00187         read_lock(&(rlock->rwlock));
00188         return 0;
00189 }
00190 
00191 inline int xp_read_unlock(struct xp_rwlock *rlock)
00192 {
00193         read_unlock(&(rlock->rwlock));
00194         return 0;
00195 }
00196 
00197 inline int xp_destroy_rwlock(struct xp_rwlock *rwlock)
00198 {
00199         return 0;
00200 }
00201 
00202 
00203 /* wait-notify queue */
00204 
00205 inline int xp_init_queue(struct xp_queue *queue)
00206 {
00207         init_waitqueue_head(&(queue->queue));
00208         return 0;
00209 }
00210 
00211 inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt)
00212 {
00213         /* wait until cfunction(cparam) != 0 (condition is true) */
00214 
00215         if (allow_interrupt)
00216         {
00217                 return wait_event_interruptible(queue->queue, cfunction(cparam) != 0);
00218         }
00219         else
00220         {
00221                 wait_event(queue->queue, cfunction(cparam) != 0);
00222         }
00223 
00224         return 0;
00225 }
00226 
00227 inline int xp_notify(struct xp_queue *queue)
00228 {
00229         wake_up(&(queue->queue));
00230         return 0;
00231 }
00232 
00233 inline int xp_destroy_queue(struct xp_queue *queue)
00234 {
00235         return 0;
00236 }
00237 
00238 
00239 /* memory */
00240 
00241 inline void* xp_malloc(size_t size)
00242 {
00243         return rsbac_kmalloc(size);
00244 }
00245 
00246 inline int xp_free(void *ptr)
00247 {
00248         kfree(ptr);
00249         return 0;
00250 }
00251 
00252 inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size)
00253 {
00254         return copy_from_user(kernel_dest, user_src, size);
00255 }
00256 
00257 inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size)
00258 {
00259         return copy_to_user(user_dest, kernel_src, size);
00260 }
00261 
00262 inline int xp_verify_user_writable(const void *user_ptr, size_t size)
00263 {
00264         return 0;
00265 }
00266 
00267 inline int xp_verify_user_readable(const void *user_ptr, size_t size)
00268 {
00269         return 0;
00270 }
00271 
00272 
00273 /* path attribute */
00274 
00275 inline int xp_is_absolute_path(const char *path)
00276 {
00277         return (path[0] == '/');
00278 }
00279 
00280 
00281 /* atomic */
00282 
00283 inline int xp_atomic_set(struct xp_atomic *atomic, int value)
00284 {
00285         atomic_set(&(atomic->atomic), value);
00286         return 0;
00287 }
00288 
00289 inline int xp_atomic_inc(struct xp_atomic *atomic)
00290 {
00291         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00292                 #ifdef MODULE
00293                         if (atomic == &active)
00294                                 MOD_INC_USE_COUNT;
00295                 #endif
00296         #endif
00297 
00298         atomic_inc(&(atomic->atomic));
00299         return 0;
00300 }
00301 
00302 inline int xp_atomic_dec(struct xp_atomic *atomic)
00303 {
00304         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00305                 #ifdef MODULE
00306                         if (atomic == &active)
00307                                 MOD_DEC_USE_COUNT;
00308                 #endif
00309         #endif
00310 
00311         atomic_dec(&(atomic->atomic));
00312         return 0;
00313 }
00314 
00315 inline int xp_atomic_read(struct xp_atomic *atomic)
00316 {
00317         return atomic_read(&(atomic->atomic));
00318 }
00319 
00320 
00321 /* file descriptor */
00322 
00323 inline int xp_copy_file(struct xp_file *dest, struct xp_file *src)
00324 {
00325         return 0;
00326 }
00327 
00328 inline int xp_compare_file(struct xp_file *file1, struct xp_file *file2)
00329 {
00330         return 0;
00331 }
00332 
00333 inline int xp_fill_file_struct(struct dazuko_file_struct *dfs)
00334 {
00335         int     length;
00336 
00337         /* make sure we have access to everything */
00338 
00339         if (dfs == NULL)
00340                 return -1;
00341 
00342         if (dfs->extra_data == NULL)
00343                 return -1;
00344 
00345         if (dfs->extra_data->dentry == NULL)
00346                 return -1;
00347 
00348         if (dfs->extra_data->dentry->d_inode == NULL)
00349                 return -1;
00350 
00351         /* ok, we have everything we need */
00352 
00353         length = rsbac_get_full_path_length(dfs->extra_data->dentry);
00354         if (length < 1)
00355                 return -1;
00356 
00357         dfs->extra_data->full_filename = xp_malloc(length + 1);
00358         if (dfs->extra_data->full_filename == NULL)
00359                 return -1;
00360 
00361         /* the full_filename will need to be deleted later */
00362         dfs->extra_data->free_full_filename = 1;
00363 
00364         if (rsbac_get_full_path(dfs->extra_data->dentry, dfs->extra_data->full_filename, length + 1) < 1)
00365                 return -1;
00366 
00367         /* find the actual value of the length */
00368         dfs->extra_data->full_filename_length = dazuko_get_filename_length(dfs->extra_data->full_filename);
00369 
00370         /* reference copy of full path */
00371         dfs->filename = dfs->extra_data->full_filename;
00372 
00373         dfs->filename_length = dfs->extra_data->full_filename_length;
00374 
00375         dfs->file_p.size = dfs->extra_data->dentry->d_inode->i_size;
00376         dfs->file_p.set_size = 1;
00377         dfs->file_p.uid = dfs->extra_data->dentry->d_inode->i_uid;
00378         dfs->file_p.set_uid = 1;
00379         dfs->file_p.gid = dfs->extra_data->dentry->d_inode->i_gid;
00380         dfs->file_p.set_gid = 1;
00381         dfs->file_p.mode = dfs->extra_data->dentry->d_inode->i_mode;
00382         dfs->file_p.set_mode = 1;
00383 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00384         dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_dev;
00385 #else
00386         dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_rdev;
00387 #endif
00388         dfs->file_p.set_device_type = 1;
00389 
00390         return 0;
00391 }
00392 
00393 static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs)
00394 {
00395         if (dfs == NULL)
00396                 return 0;
00397 
00398         if (*dfs == NULL)
00399                 return 0;
00400 
00401         if ((*dfs)->extra_data != NULL)
00402         {
00403                 if ((*dfs)->extra_data->free_full_filename)
00404                         xp_free((*dfs)->extra_data->full_filename);
00405 
00406                 xp_free((*dfs)->extra_data);
00407         }
00408 
00409         xp_free(*dfs);
00410 
00411         *dfs = NULL;
00412 
00413         return 0;
00414 }
00415 
00416 
00417 /* daemon id */
00418 
00419 int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2)
00420 {
00421         if (id1 == NULL || id2 == NULL)
00422                 return -1;
00423 
00424         /* if file's are available and they match,
00425          * then we say that the id's match */
00426         if (id1->file != NULL && id1->file == id2->file)
00427                 return 0;
00428 
00429         if (id1->pid == id2->pid)
00430                 return 0;
00431 
00432         return 1;
00433 }
00434 
00435 int xp_id_free(struct xp_daemon_id *id)
00436 {
00437         xp_free(id);
00438 
00439         return 0;
00440 }
00441 
00442 struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id)
00443 {
00444         struct xp_daemon_id     *ptr;
00445 
00446         if (id == NULL)
00447                 return NULL;
00448 
00449         ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id));
00450 
00451         if (ptr != NULL)
00452         {
00453                 ptr->pid = id->pid;
00454                 ptr->file = id->file;
00455         }
00456 
00457         return ptr;
00458 }
00459 
00460 
00461 /* system hook */
00462 
00463 inline int xp_sys_hook()
00464 {
00465         /* Called insmod when inserting the module. */
00466 
00467         /* register the dazuko device */
00468 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00469         dev_major = register_chrdev(CONFIG_RSBAC_DAZ_DEV_MAJOR, DEVICE_NAME, &fops);
00470 
00471         devfs_mk_cdev(MKDEV(dev_major, CONFIG_RSBAC_DAZ_DEV_MAJOR), S_IFCHR | S_IRUSR | S_IWUSR, DEVICE_NAME);
00472 #else
00473         #ifdef CONFIG_DEVFS_FS
00474                 dev_major = devfs_register_chrdev(CONFIG_RSBAC_DAZ_DEV_MAJOR, DEVICE_NAME, &fops);
00475                 devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT,
00476                         dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
00477                         &fops, NULL);
00478         #else
00479                 dev_major = register_chrdev(CONFIG_RSBAC_DAZ_DEV_MAJOR, DEVICE_NAME, &fops);
00480         #endif
00481 #endif
00482         if (dev_major < 0)
00483         {
00484                 xp_print("dazuko: unable to register device chrdev, err=%d\n", dev_major);
00485                 return dev_major;
00486         }
00487 
00488         /* initialization complete */
00489 
00490         return 0;
00491 }
00492 
00493 inline int xp_sys_unhook()
00494 {
00495         /* Called by rmmod when removing the module. */
00496 
00497         int     error;
00498 
00499 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00500         error = unregister_chrdev(dev_major, DEVICE_NAME);
00501 
00502         devfs_remove(DEVICE_NAME);
00503 #else
00504         #ifdef CONFIG_DEVFS_FS
00505                 error = devfs_unregister_chrdev(dev_major, DEVICE_NAME);
00506                 devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0));
00507         #else
00508                 error = unregister_chrdev(dev_major, DEVICE_NAME);
00509         #endif
00510 #endif
00511         if (error < 0)
00512         {
00513                 xp_print("dazuko: error unregistering chrdev, err=%d\n", error);
00514         }
00515 
00516         return 0;
00517 }
00518 
00519 
00520 /* output */
00521 
00522 int xp_print(const char *fmt, ...)
00523 {
00524         va_list args;
00525         char *p;
00526         size_t size = 1024;
00527 
00528         p = (char *)xp_malloc(size);
00529         if (!p)
00530                 return -1;
00531 
00532         va_start(args, fmt);
00533         dazuko_vsnprintf(p, size-1, fmt, args);
00534         va_end(args);
00535 
00536         p[size-1] = 0;
00537 
00538         rsbac_printk(p);
00539 
00540         xp_free(p);
00541 
00542         return 0;
00543 }
00544 
00545 
00546 /* ioctl's */
00547 
00548 int linux_dazuko_device_open(struct inode *inode, struct file *file)
00549 {
00550         DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid));
00551 
00552         return 0;
00553 }
00554 
00555 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos)
00556 {
00557         /* Reading from the dazuko device simply
00558          * returns the device number. This is to
00559          * help out the daemon. */
00560 
00561         char    tmp[20];
00562         size_t  dev_major_len;
00563 
00564         DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid));
00565 
00566         /* only one read is allowed */
00567         if (*pos != 0)
00568                 return 0;
00569 
00570         if (dev_major < 0)
00571                 return -ENODEV;
00572 
00573         /* print dev_major to a string
00574          * and get length (with terminator) */
00575         dazuko_bzero(tmp, sizeof(tmp));
00576 
00577         dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1;
00578 
00579         if (tmp[sizeof(tmp)-1] != 0)
00580         {
00581                 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major);
00582                 return -EFAULT;
00583         }
00584 
00585         if (length < dev_major_len)
00586                 return -EINVAL;
00587 
00588         /* copy dev_major string to userspace */
00589         if (xp_copyout(tmp, buffer, dev_major_len) != 0)
00590                 return -EFAULT;
00591 
00592         *pos = dev_major_len;
00593 
00594         return dev_major_len;
00595 }
00596 
00597 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos)
00598 {
00599         struct dazuko_request   *u_request;
00600         struct xp_daemon_id     xp_id;
00601         char                    tmpbuffer[32];
00602         char                    *value;
00603         int                     size;
00604 
00605         size = length;
00606         if (length >= sizeof(tmpbuffer))
00607                 size = sizeof(tmpbuffer) -1;
00608 
00609         /* copy request pointer string to kernelspace */
00610         if (xp_copyin(buffer, tmpbuffer, size) != 0)
00611                 return -EFAULT;
00612 
00613         tmpbuffer[size] = 0;
00614 
00615         if (dazuko_get_value("\nRA=", buffer, &value) != 0)
00616         {
00617                 xp_print("dazuko: error: linux_dazuko_device_write.RA missing\n");
00618                 return -EFAULT;
00619         }
00620 
00621         u_request = (struct dazuko_request *)simple_strtoul(value, NULL, 10);
00622 
00623         xp_free(value);
00624 
00625         xp_id.pid = current->pid;
00626         xp_id.file = file;
00627 
00628         if (dazuko_handle_user_request(u_request, &xp_id) == 0)
00629                 return length;
00630         else
00631                 return -EINTR;
00632 }
00633 
00634 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
00635 {
00636         /* A daemon uses this function to interact with
00637          * the kernel. A daemon can set scanning parameters,
00638          * give scanning response, and get filenames to scan. */
00639 
00640         struct xp_daemon_id     xp_id;
00641         int                     error = 0;
00642 
00643         if (param == 0)
00644         {
00645                 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n");
00646                 return -EFAULT;
00647         }
00648 
00649         xp_id.pid = current->pid;
00650         xp_id.file = file;
00651 
00652         error = dazuko_handle_user_request_compat12((void *)param, _IOC_NR(cmd), &xp_id);
00653 
00654         if (error != 0)
00655         {
00656                 /* general error occurred */
00657 
00658                 return -EPERM;
00659         }
00660 
00661         return error;
00662 }
00663 
00664 int linux_dazuko_device_release(struct inode *inode, struct file *file)
00665 {
00666         struct xp_daemon_id     xp_id;
00667 
00668         DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid));
00669 
00670         xp_id.pid = current->pid;
00671         xp_id.file = file;
00672 
00673         return dazuko_unregister_daemon(&xp_id);
00674 }
00675 
00676 
00677 /************************************************* */
00678 /*          Externally visible functions           */
00679 /************************************************* */
00680 
00681 #ifdef CONFIG_RSBAC_INIT_DELAY
00682 int rsbac_init_daz(void)
00683 #else
00684 int __init rsbac_init_daz(void)
00685 #endif
00686   {
00687     if (rsbac_is_initialized())
00688       {
00689         rsbac_printk(KERN_WARNING "rsbac_init_daz(): RSBAC already initialized\n");
00690         return(-RSBAC_EREINIT);
00691       }
00692 
00693     /* init data structures */
00694     rsbac_printk(KERN_INFO "rsbac_init_daz(): Initializing RSBAC: DAZuko subsystem\n");
00695 
00696     return dazuko_init();
00697   }
00698 
00699 
00700 enum rsbac_adf_req_ret_t
00701    rsbac_adf_request_daz (enum  rsbac_adf_request_t     request,
00702                                 rsbac_pid_t             caller_pid,
00703                           enum  rsbac_target_t          target,
00704                           union rsbac_target_id_t       tid,
00705                           enum  rsbac_attribute_t       attr,
00706                           union rsbac_attribute_value_t attr_val,
00707                                 rsbac_uid_t             owner)
00708   {
00709     struct dazuko_file_struct *dfs = NULL;
00710     struct xp_daemon_id xp_id;
00711     int error = 0;
00712     int check_error = 0;
00713     struct event_properties event_p;
00714     int event;
00715     int daemon_allowed;
00716 
00717     union rsbac_target_id_t       i_tid;
00718     union rsbac_attribute_value_t i_attr_val1;
00719 
00720     switch (request)
00721       {
00722                 case R_DELETE:
00723                         if (target == T_FILE)
00724                         {
00725                                 event = DAZUKO_ON_UNLINK;
00726                                 daemon_allowed = 1;
00727                         }
00728                         else if (target == T_DIR)
00729                         {
00730                                 event = DAZUKO_ON_RMDIR;
00731                                 daemon_allowed = 1;
00732                         }
00733                         else
00734                         {
00735                           return DO_NOT_CARE;
00736                         }
00737                         break;
00738                 case R_CLOSE:
00739                         if (target == T_FILE)
00740                         {
00741                                 event = DAZUKO_ON_CLOSE;
00742                                 daemon_allowed = 1;
00743                         }
00744                         else
00745                         {
00746                           return DO_NOT_CARE;
00747                         }
00748                         break;
00749 
00750                 case R_EXECUTE:
00751                         if (target == T_FILE)
00752                         {
00753                                 event = DAZUKO_ON_EXEC;
00754                                 daemon_allowed = 0;
00755                         }
00756                         else
00757                         {
00758                           return DO_NOT_CARE;
00759                         }
00760                         break;
00761 
00762                 case R_APPEND_OPEN:
00763                 case R_READ_WRITE_OPEN:
00764                 case R_READ_OPEN:
00765                 case R_WRITE_OPEN:
00766                         if (target == T_FILE)
00767                         {
00768                                 event = DAZUKO_ON_OPEN;
00769                                 daemon_allowed = 1;
00770                         }
00771                         else
00772                         if (target == T_DEV)
00773                         {
00774                           if(   (tid.dev.type == D_char)
00775                              && (MAJOR(tid.dev.id) == CONFIG_RSBAC_DAZ_DEV_MAJOR)
00776                             )
00777                             {
00778                               i_tid.process = caller_pid;
00779                               if (rsbac_get_attr(DAZ,
00780                                                  T_PROCESS,
00781                                                  i_tid,
00782                                                  A_daz_scanner,
00783                                                  &i_attr_val1,
00784                                                  TRUE))
00785                                 {
00786                                   rsbac_printk(KERN_WARNING
00787                                                "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00788                                   return(NOT_GRANTED);
00789                                 }
00790                               /* if scanner, then grant */
00791                               if (i_attr_val1.daz_scanner)
00792                                 return(GRANTED);
00793                               else
00794                                 return(NOT_GRANTED);
00795                             }
00796                           else
00797                             return DO_NOT_CARE;
00798                         }
00799                         else
00800                         {
00801                           return DO_NOT_CARE;
00802                         }
00803                         break;
00804 
00805         case R_MODIFY_ATTRIBUTE:
00806             switch(attr)
00807               {
00808                 case A_daz_scanned:
00809                 case A_daz_scanner:
00810                 case A_system_role:
00811                 case A_daz_role:
00812                 /* All attributes (remove target!) */
00813                 case A_none:
00814                   /* Security Officer? */
00815                   i_tid.user = owner;
00816                   if (rsbac_get_attr(DAZ,
00817                                      T_USER,
00818                                      i_tid,
00819                                      A_daz_role,
00820                                      &i_attr_val1,
00821                                      TRUE))
00822                     {
00823                       rsbac_printk(KERN_WARNING
00824                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00825                       return(NOT_GRANTED);
00826                     }
00827                   /* if sec_officer, then grant */
00828                   if (i_attr_val1.system_role == SR_security_officer)
00829                     return(GRANTED);
00830                   else
00831                     return(NOT_GRANTED);
00832 
00833                 default:
00834                   return(DO_NOT_CARE);
00835               }
00836 
00837         case R_READ_ATTRIBUTE:
00838             switch(attr)
00839               {
00840                 /* every user may see scan status of files */
00841                 case A_daz_scanned:
00842                   return(GRANTED);
00843                 /* ...but only security officers may see other attributes */
00844                 case A_system_role:
00845                 case A_daz_role:
00846                 case A_daz_scanner:
00847                   /* Security Officer? */
00848                   i_tid.user = owner;
00849                   if (rsbac_get_attr(DAZ,
00850                                      T_USER,
00851                                      i_tid,
00852                                      A_daz_role,
00853                                      &i_attr_val1,
00854                                      TRUE))
00855                     {
00856                       rsbac_printk(KERN_WARNING
00857                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00858                       return(NOT_GRANTED);
00859                     }
00860                   /* if sec_officer, then grant */
00861                   if (i_attr_val1.system_role == SR_security_officer)
00862                     return(GRANTED);
00863                   else
00864                     return(NOT_GRANTED);
00865 
00866                 default:
00867                   return(DO_NOT_CARE);
00868               }
00869 
00870         case R_SWITCH_MODULE:
00871             switch(target)
00872               {
00873                 case T_NONE:
00874                   /* we need the switch_target */
00875                   if(attr != A_switch_target)
00876                     return(UNDEFINED);
00877                   /* do not care for other modules */
00878                   if(   (attr_val.switch_target != DAZ)
00879                      #ifdef CONFIG_RSBAC_SOFTMODE
00880                      && (attr_val.switch_target != SOFTMODE)
00881                      #endif
00882                      #ifdef CONFIG_RSBAC_FREEZE
00883                      && (attr_val.switch_target != FREEZE)
00884                      #endif
00885                     )
00886                     return(DO_NOT_CARE);
00887                   /* test owner's daz_role */
00888                   i_tid.user = owner;
00889                   if (rsbac_get_attr(DAZ,
00890                                      T_USER,
00891                                      i_tid,
00892                                      A_daz_role,
00893                                      &i_attr_val1,
00894                                      TRUE))
00895                     {
00896                       rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00897                       return(NOT_GRANTED);
00898                     }
00899                   /* security officer? -> grant  */
00900                   if (i_attr_val1.system_role == SR_security_officer)
00901                     return(GRANTED);
00902                   else
00903                     return(NOT_GRANTED);
00904 
00905                 /* all other cases are undefined */
00906                 default: return(DO_NOT_CARE);
00907               }
00908               
00909 /*********************/
00910         default: return DO_NOT_CARE;
00911       }
00912 
00913 #if defined(CONFIG_RSBAC_DAZ_CACHE)
00914     /* get daz_scanned for file */
00915     if (rsbac_get_attr(DAZ,
00916                        T_FILE,
00917                        tid,
00918                        A_daz_scanned,
00919                        &i_attr_val1,
00920                        TRUE))
00921       {
00922         rsbac_printk(KERN_WARNING
00923                      "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00924         return(-RSBAC_EREADFAILED);
00925       }
00926     if(i_attr_val1.daz_scanned == DAZ_clean)
00927       return GRANTED;
00928 #endif
00929 
00930         xp_id.pid = current->pid;
00931         xp_id.file = NULL;
00932 
00933         check_error = dazuko_sys_check(event, daemon_allowed, &xp_id);
00934 
00935         if (!check_error)
00936         {
00937                 dazuko_bzero(&event_p, sizeof(event_p));
00938 /*
00939                 event_p.flags = flags;
00940                 event_p.set_flags = 1;
00941                 event_p.mode = mode;
00942                 event_p.set_mode = 1;
00943 */
00944                 event_p.pid = current->pid;
00945                 event_p.set_pid = 1;
00946                 event_p.uid = current->uid;
00947                 event_p.set_uid = 1;
00948 
00949                 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
00950                 if (dfs != NULL)
00951                 {
00952                         dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
00953 
00954                         dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
00955                         if (dfs->extra_data != NULL)
00956                         {
00957                                 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
00958 
00959                                 dfs->extra_data->dentry = tid.file.dentry_p;
00960 
00961                                 error = dazuko_sys_pre(event, dfs, NULL, &event_p);
00962 
00963 #if defined(CONFIG_RSBAC_DAZ_CACHE)
00964                                 if(!error)
00965                                   i_attr_val1.daz_scanned = DAZ_clean;
00966                                 else
00967                                   i_attr_val1.daz_scanned = DAZ_infected;
00968 
00969                                 if (rsbac_set_attr(DAZ,
00970                                     target,
00971                                     tid,
00972                                     A_daz_scanned,
00973                                     i_attr_val1))
00974                                   {
00975                                     rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_set_attr() returned error!\n");
00976                                     return NOT_GRANTED;
00977                                   }
00978 #endif
00979                         }
00980                         else
00981                         {
00982                                 xp_free(dfs);
00983                                 dfs = NULL;
00984                         }
00985 
00986                         dazuko_file_struct_cleanup(&dfs);
00987                 }
00988         }
00989 
00990         if(!error)
00991           return GRANTED;
00992         else
00993           return NOT_GRANTED;
00994   }; /* end of rsbac_adf_request_daz() */
00995 
00996 
00997 /*****************************************************************************/
00998 /* If the request returned granted and the operation is performed,           */
00999 /* the following function can be called by the AEF to get all aci set        */
01000 /* correctly. For write accesses that are performed fully within the kernel, */
01001 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
01002 /* cleaning up. Because of this, the write boundary is not adjusted - there  */
01003 /* is no user-level writing anyway...                                        */
01004 /* The second instance of target specification is the new target, if one has */
01005 /* been created, otherwise its values are ignored.                           */
01006 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
01007 
01008 int  rsbac_adf_set_attr_daz(
01009                       enum  rsbac_adf_request_t     request,
01010                             rsbac_pid_t             caller_pid,
01011                       enum  rsbac_target_t          target,
01012                       union rsbac_target_id_t       tid,
01013                       enum  rsbac_target_t          new_target,
01014                       union rsbac_target_id_t       new_tid,
01015                       enum  rsbac_attribute_t       attr,
01016                       union rsbac_attribute_value_t attr_val,
01017                             rsbac_uid_t             owner)
01018   {
01019     struct dazuko_file_struct *dfs = NULL;
01020     struct xp_daemon_id xp_id;
01021     int check_error = 0;
01022     struct event_properties event_p;
01023     int event;
01024     int daemon_allowed;
01025     union rsbac_target_id_t       i_tid;
01026     union rsbac_attribute_value_t i_attr_val1;
01027     union rsbac_attribute_value_t i_attr_val2;
01028 
01029     switch (request)
01030       {
01031                 case R_DELETE:
01032                         if (target == T_FILE)
01033                         {
01034                                 reset_scanned(tid.file);
01035                                 event = DAZUKO_ON_UNLINK;
01036                                 daemon_allowed = 1;
01037                         }
01038                         else if (target == T_DIR)
01039                         {
01040                                 event = DAZUKO_ON_RMDIR;
01041                                 daemon_allowed = 1;
01042                         }
01043                         else
01044                         {
01045                           return(0);
01046                         }
01047                         break;
01048                 case R_CLOSE:
01049                         if (target == T_FILE)
01050                         {
01051                                 event = DAZUKO_ON_CLOSE;
01052                                 daemon_allowed = 1;
01053                         }
01054                         else
01055                         {
01056                           return(0);
01057                         }
01058                         break;
01059 
01060                 case R_EXECUTE:
01061                         if (target == T_FILE)
01062                         {
01063                   /* get daz_scanner for file */
01064                   if (rsbac_get_attr(DAZ,
01065                                      T_FILE,
01066                                      tid,
01067                                      A_daz_scanner,
01068                                      &i_attr_val1,
01069                                      TRUE))
01070                     {
01071                       rsbac_printk(KERN_WARNING
01072                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01073                       return(-RSBAC_EREADFAILED);
01074                     }
01075                   /* get for process */
01076                   i_tid.process = caller_pid;
01077                   if (rsbac_get_attr(DAZ,
01078                                      T_PROCESS,
01079                                      i_tid,
01080                                      A_daz_scanner,
01081                                      &i_attr_val2,
01082                                      FALSE))
01083                     {
01084                       rsbac_printk(KERN_WARNING
01085                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01086                       return(-RSBAC_EREADFAILED);
01087                     }
01088                   /* and set for process, if different */
01089                   if(i_attr_val1.daz_scanner != i_attr_val2.daz_scanner)
01090                     if (rsbac_set_attr(DAZ,
01091                                        T_PROCESS,
01092                                        i_tid,
01093                                        A_daz_scanner,
01094                                        i_attr_val1))
01095                       {
01096                         rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01097                         return(-RSBAC_EWRITEFAILED);
01098                       }
01099                                 event = DAZUKO_ON_EXEC;
01100                                 daemon_allowed = 0;
01101                         }
01102                         else
01103                         {
01104                           return(0);
01105                         }
01106                         break;
01107 
01108                 case R_APPEND_OPEN:
01109                 case R_READ_WRITE_OPEN:
01110                 case R_WRITE_OPEN:
01111                         if (target == T_FILE)
01112                         {
01113                                 reset_scanned(tid.file);
01114                                 event = DAZUKO_ON_OPEN;
01115                                 daemon_allowed = 1;
01116                         }
01117                         else
01118                         {
01119                           return(0);
01120                         }
01121                         break;
01122 
01123                 case R_READ_OPEN:
01124                         if (target == T_FILE)
01125                         {
01126                                 event = DAZUKO_ON_OPEN;
01127                                 daemon_allowed = 1;
01128                         }
01129                         else
01130                         {
01131                           return(0);
01132                         }
01133                         break;
01134 
01135         case R_CLONE:
01136             if (target == T_PROCESS)
01137               {
01138                 /* Get daz_scanner from first process */
01139                 if (rsbac_get_attr(DAZ,
01140                                    T_PROCESS,
01141                                    tid,
01142                                    A_daz_scanner,
01143                                    &i_attr_val1,
01144                                    FALSE))
01145                   {
01146                     rsbac_printk(KERN_WARNING
01147                            "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01148                     return(-RSBAC_EREADFAILED);
01149                   }
01150                 /* Set daz_scanner for new process, if set for first */
01151                 if (   i_attr_val1.daz_scanner
01152                     && (rsbac_set_attr(DAZ,
01153                                        T_PROCESS,
01154                                        new_tid,
01155                                        A_daz_scanner,
01156                                        i_attr_val1)) )
01157                   {
01158                     rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01159                     return(-RSBAC_EWRITEFAILED);
01160                   }
01161                 return(0);
01162               }
01163             else
01164               return(0);
01165 
01166 /*********************/
01167         default: return(0);
01168       }
01169 
01170 #if defined(CONFIG_RSBAC_DAZ_CACHE)
01171     /* get daz_scanned for file */
01172     if (rsbac_get_attr(DAZ,
01173                        T_FILE,
01174                        tid,
01175                        A_daz_scanned,
01176                        &i_attr_val1,
01177                        TRUE))
01178       {
01179         rsbac_printk(KERN_WARNING
01180                      "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01181         return(-RSBAC_EREADFAILED);
01182       }
01183     if(i_attr_val1.daz_scanned == DAZ_clean)
01184       return 0;
01185 #endif
01186 
01187         xp_id.pid = current->pid;
01188         xp_id.file = NULL;
01189 
01190         check_error = dazuko_sys_check(event, daemon_allowed, &xp_id);
01191 
01192         if (!check_error)
01193         {
01194                 dazuko_bzero(&event_p, sizeof(event_p));
01195 /*
01196                 event_p.flags = flags;
01197                 event_p.set_flags = 1;
01198                 event_p.mode = mode;
01199                 event_p.set_mode = 1;
01200 */
01201                 event_p.pid = current->pid;
01202                 event_p.set_pid = 1;
01203                 event_p.uid = current->uid;
01204                 event_p.set_uid = 1;
01205 
01206                 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01207                 if (dfs != NULL)
01208                 {
01209                         dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01210 
01211                         dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01212                         if (dfs->extra_data != NULL)
01213                         {
01214                                 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01215 
01216                                 dfs->extra_data->dentry = tid.file.dentry_p;
01217 
01218                                 dazuko_sys_post(event, dfs, NULL, &event_p);
01219                         }
01220                         else
01221                         {
01222                                 xp_free(dfs);
01223                                 dfs = NULL;
01224                         }
01225 
01226                         dazuko_file_struct_cleanup(&dfs);
01227                 }
01228         }
01229 
01230     return(0);
01231   }; /* end of rsbac_adf_set_attr_daz() */
01232 
01233 /* end of rsbac/adf/daz/daz_main.c */
01234 

Generated on Sun May 21 14:30:50 2006 for RSBAC by  doxygen 1.4.2