daz_main.c

Go to the documentation of this file.
00001 /*************************************************** */
00002 /* Rule Set Based Access Control                     */
00003 /* Implementation of the Access Control Decision     */
00004 /* Facility (ADF) - 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         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         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         printk(p);
00539         rsbac_printk(p);
00540 
00541         xp_free(p);
00542 
00543         return 0;
00544 }
00545 
00546 
00547 /* ioctl's */
00548 
00549 int linux_dazuko_device_open(struct inode *inode, struct file *file)
00550 {
00551         DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid));
00552 
00553         return 0;
00554 }
00555 
00556 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos)
00557 {
00558         /* Reading from the dazuko device simply
00559          * returns the device number. This is to
00560          * help out the daemon. */
00561 
00562         char    tmp[20];
00563         size_t  dev_major_len;
00564 
00565         DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid));
00566 
00567         /* only one read is allowed */
00568         if (*pos != 0)
00569                 return 0;
00570 
00571         if (dev_major < 0)
00572                 return -ENODEV;
00573 
00574         /* print dev_major to a string
00575          * and get length (with terminator) */
00576         dazuko_bzero(tmp, sizeof(tmp));
00577 
00578         dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1;
00579 
00580         if (tmp[sizeof(tmp)-1] != 0)
00581         {
00582                 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major);
00583                 return -EFAULT;
00584         }
00585 
00586         if (length < dev_major_len)
00587                 return -EINVAL;
00588 
00589         /* copy dev_major string to userspace */
00590         if (xp_copyout(tmp, buffer, dev_major_len) != 0)
00591                 return -EFAULT;
00592 
00593         *pos = dev_major_len;
00594 
00595         return dev_major_len;
00596 }
00597 
00598 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos)
00599 {
00600         struct dazuko_request   *u_request;
00601         struct xp_daemon_id     xp_id;
00602         char                    tmpbuffer[32];
00603         char                    *value;
00604         int                     size;
00605 
00606         size = length;
00607         if (length >= sizeof(tmpbuffer))
00608                 size = sizeof(tmpbuffer) -1;
00609 
00610         /* copy request pointer string to kernelspace */
00611         if (xp_copyin(buffer, tmpbuffer, size) != 0)
00612                 return -EFAULT;
00613 
00614         tmpbuffer[size] = 0;
00615 
00616         if (dazuko_get_value("\nRA=", buffer, &value) != 0)
00617         {
00618                 xp_print("dazuko: error: linux_dazuko_device_write.RA missing\n");
00619                 return -EFAULT;
00620         }
00621 
00622         u_request = (struct dazuko_request *)simple_strtoul(value, NULL, 10);
00623 
00624         xp_free(value);
00625 
00626         xp_id.pid = current->pid;
00627         xp_id.file = file;
00628 
00629         if (dazuko_handle_user_request(u_request, &xp_id) == 0)
00630                 return length;
00631         else
00632                 return -EINTR;
00633 }
00634 
00635 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
00636 {
00637         /* A daemon uses this function to interact with
00638          * the kernel. A daemon can set scanning parameters,
00639          * give scanning response, and get filenames to scan. */
00640 
00641         struct xp_daemon_id     xp_id;
00642         int                     error = 0;
00643 
00644         if (param == 0)
00645         {
00646                 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n");
00647                 return -EFAULT;
00648         }
00649 
00650         xp_id.pid = current->pid;
00651         xp_id.file = file;
00652 
00653         error = dazuko_handle_user_request_compat12((void *)param, _IOC_NR(cmd), &xp_id);
00654 
00655         if (error != 0)
00656         {
00657                 /* general error occurred */
00658 
00659                 return -EPERM;
00660         }
00661 
00662         return error;
00663 }
00664 
00665 int linux_dazuko_device_release(struct inode *inode, struct file *file)
00666 {
00667         struct xp_daemon_id     xp_id;
00668 
00669         DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid));
00670 
00671         xp_id.pid = current->pid;
00672         xp_id.file = file;
00673 
00674         return dazuko_unregister_daemon(&xp_id);
00675 }
00676 
00677 
00678 /************************************************* */
00679 /*          Externally visible functions           */
00680 /************************************************* */
00681 
00682 #ifdef CONFIG_RSBAC_INIT_DELAY
00683 int rsbac_init_daz(void)
00684 #else
00685 int __init rsbac_init_daz(void)
00686 #endif
00687   {
00688     if (rsbac_is_initialized())
00689       {
00690 #ifdef CONFIG_RSBAC_RMSG
00691         rsbac_printk(KERN_WARNING "rsbac_init_daz(): RSBAC already initialized\n");
00692 #endif
00693 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00694         if (!rsbac_nosyslog)
00695 #endif
00696         printk(KERN_WARNING "rsbac_init_daz(): RSBAC already initialized\n");
00697         return(-RSBAC_EREINIT);
00698       }
00699 
00700     /* init data structures */
00701 #ifdef CONFIG_RSBAC_RMSG
00702     rsbac_printk(KERN_INFO "rsbac_init_daz(): Initializing RSBAC: DAZuko subsystem\n");
00703 #endif
00704 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00705     if (!rsbac_nosyslog)
00706 #endif
00707     printk(KERN_INFO "rsbac_init_daz(): Initializing RSBAC: DAZuko subsystem\n");
00708 
00709     return dazuko_init();
00710   }
00711 
00712 
00713 enum rsbac_adf_req_ret_t
00714    rsbac_adf_request_daz (enum  rsbac_adf_request_t     request,
00715                                 rsbac_pid_t             caller_pid,
00716                           enum  rsbac_target_t          target,
00717                           union rsbac_target_id_t       tid,
00718                           enum  rsbac_attribute_t       attr,
00719                           union rsbac_attribute_value_t attr_val,
00720                                 rsbac_uid_t             owner)
00721   {
00722     struct dazuko_file_struct *dfs = NULL;
00723     struct xp_daemon_id xp_id;
00724     int error = 0;
00725     int check_error = 0;
00726     struct event_properties event_p;
00727     int event;
00728     int daemon_allowed;
00729 
00730     union rsbac_target_id_t       i_tid;
00731     union rsbac_attribute_value_t i_attr_val1;
00732 
00733     switch (request)
00734       {
00735                 case R_DELETE:
00736                         if (target == T_FILE)
00737                         {
00738                                 event = DAZUKO_ON_UNLINK;
00739                                 daemon_allowed = 1;
00740                         }
00741                         else if (target == T_DIR)
00742                         {
00743                                 event = DAZUKO_ON_RMDIR;
00744                                 daemon_allowed = 1;
00745                         }
00746                         else
00747                         {
00748                           return DO_NOT_CARE;
00749                         }
00750                         break;
00751                 case R_CLOSE:
00752                         if (target == T_FILE)
00753                         {
00754                                 event = DAZUKO_ON_CLOSE;
00755                                 daemon_allowed = 1;
00756                         }
00757                         else
00758                         {
00759                           return DO_NOT_CARE;
00760                         }
00761                         break;
00762 
00763                 case R_EXECUTE:
00764                         if (target == T_FILE)
00765                         {
00766                                 event = DAZUKO_ON_EXEC;
00767                                 daemon_allowed = 0;
00768                         }
00769                         else
00770                         {
00771                           return DO_NOT_CARE;
00772                         }
00773                         break;
00774 
00775                 case R_APPEND_OPEN:
00776                 case R_READ_WRITE_OPEN:
00777                 case R_READ_OPEN:
00778                 case R_WRITE_OPEN:
00779                         if (target == T_FILE)
00780                         {
00781                                 event = DAZUKO_ON_OPEN;
00782                                 daemon_allowed = 1;
00783                         }
00784                         else
00785                         if (target == T_DEV)
00786                         {
00787                           if(   (tid.dev.type == D_char)
00788                              && (MAJOR(tid.dev.id) == CONFIG_RSBAC_DAZ_DEV_MAJOR)
00789                             )
00790                             {
00791                               i_tid.process = caller_pid;
00792                               if (rsbac_get_attr(DAZ,
00793                                                  T_PROCESS,
00794                                                  i_tid,
00795                                                  A_daz_scanner,
00796                                                  &i_attr_val1,
00797                                                  TRUE))
00798                                 {
00799 #ifdef CONFIG_RSBAC_RMSG
00800                                   rsbac_printk(KERN_WARNING
00801                                                "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00802 #endif
00803 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00804                                   if (!rsbac_nosyslog)
00805 #endif
00806                                     printk(KERN_WARNING
00807                                            "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00808                                   return(NOT_GRANTED);
00809                                 }
00810                               /* if scanner, then grant */
00811                               if (i_attr_val1.daz_scanner)
00812                                 return(GRANTED);
00813                               else
00814                                 return(NOT_GRANTED);
00815                             }
00816                           else
00817                             return DO_NOT_CARE;
00818                         }
00819                         else
00820                         {
00821                           return DO_NOT_CARE;
00822                         }
00823                         break;
00824 
00825         case R_MODIFY_ATTRIBUTE:
00826             switch(attr)
00827               {
00828                 case A_daz_scanned:
00829                 case A_daz_scanner:
00830                 case A_system_role:
00831                 case A_daz_role:
00832                 /* All attributes (remove target!) */
00833                 case A_none:
00834                   /* Security Officer? */
00835                   i_tid.user = owner;
00836                   if (rsbac_get_attr(DAZ,
00837                                      T_USER,
00838                                      i_tid,
00839                                      A_daz_role,
00840                                      &i_attr_val1,
00841                                      TRUE))
00842                     {
00843 #ifdef CONFIG_RSBAC_RMSG
00844                       rsbac_printk(KERN_WARNING
00845                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00846 #endif
00847 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00848                       if (!rsbac_nosyslog)
00849 #endif
00850                       printk(KERN_WARNING
00851                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00852                       return(NOT_GRANTED);
00853                     }
00854                   /* if sec_officer, then grant */
00855                   if (i_attr_val1.system_role == SR_security_officer)
00856                     return(GRANTED);
00857                   else
00858                     return(NOT_GRANTED);
00859 
00860                 default:
00861                   return(DO_NOT_CARE);
00862               }
00863 
00864         case R_READ_ATTRIBUTE:
00865             switch(attr)
00866               {
00867                 /* every user may see scan status of files */
00868                 case A_daz_scanned:
00869                   return(GRANTED);
00870                 /* ...but only security officers may see other attributes */
00871                 case A_system_role:
00872                 case A_daz_role:
00873                 case A_daz_scanner:
00874                   /* Security Officer? */
00875                   i_tid.user = owner;
00876                   if (rsbac_get_attr(DAZ,
00877                                      T_USER,
00878                                      i_tid,
00879                                      A_daz_role,
00880                                      &i_attr_val1,
00881                                      TRUE))
00882                     {
00883 #ifdef CONFIG_RSBAC_RMSG
00884                       rsbac_printk(KERN_WARNING
00885                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00886 #endif
00887 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00888                       if (!rsbac_nosyslog)
00889 #endif
00890                       printk(KERN_WARNING
00891                              "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00892                       return(NOT_GRANTED);
00893                     }
00894                   /* if sec_officer, then grant */
00895                   if (i_attr_val1.system_role == SR_security_officer)
00896                     return(GRANTED);
00897                   else
00898                     return(NOT_GRANTED);
00899 
00900                 default:
00901                   return(DO_NOT_CARE);
00902               }
00903 
00904         case R_SWITCH_MODULE:
00905             switch(target)
00906               {
00907                 case T_NONE:
00908                   /* we need the switch_target */
00909                   if(attr != A_switch_target)
00910                     return(UNDEFINED);
00911                   /* do not care for other modules */
00912                   if(   (attr_val.switch_target != DAZ)
00913                      #ifdef CONFIG_RSBAC_SOFTMODE
00914                      && (attr_val.switch_target != SOFTMODE)
00915                      #endif
00916                      #ifdef CONFIG_RSBAC_FREEZE
00917                      && (attr_val.switch_target != FREEZE)
00918                      #endif
00919                     )
00920                     return(DO_NOT_CARE);
00921                   /* test owner's daz_role */
00922                   i_tid.user = owner;
00923                   if (rsbac_get_attr(DAZ,
00924                                      T_USER,
00925                                      i_tid,
00926                                      A_daz_role,
00927                                      &i_attr_val1,
00928                                      TRUE))
00929                     {
00930 #ifdef CONFIG_RSBAC_RMSG
00931                       rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00932 #endif
00933 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00934                       if (!rsbac_nosyslog)
00935 #endif
00936                       printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00937                       return(NOT_GRANTED);
00938                     }
00939                   /* security officer? -> grant  */
00940                   if (i_attr_val1.system_role == SR_security_officer)
00941                     return(GRANTED);
00942                   else
00943                     return(NOT_GRANTED);
00944 
00945                 /* all other cases are undefined */
00946                 default: return(DO_NOT_CARE);
00947               }
00948               
00949 /*********************/
00950         default: return DO_NOT_CARE;
00951       }
00952 
00953 #if defined(CONFIG_RSBAC_DAZ_CACHE)
00954     /* get daz_scanned for file */
00955     if (rsbac_get_attr(DAZ,
00956                        T_FILE,
00957                        tid,
00958                        A_daz_scanned,
00959                        &i_attr_val1,
00960                        TRUE))
00961       {
00962 #ifdef CONFIG_RSBAC_RMSG
00963         rsbac_printk(KERN_WARNING
00964                      "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00965 #endif
00966 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00967         if (!rsbac_nosyslog)
00968 #endif
00969           printk(KERN_WARNING
00970                  "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n");
00971         return(-RSBAC_EREADFAILED);
00972       }
00973     if(i_attr_val1.daz_scanned == DAZ_clean)
00974       return GRANTED;
00975 #endif
00976 
00977         xp_id.pid = current->pid;
00978         xp_id.file = NULL;
00979 
00980         check_error = dazuko_sys_check(event, daemon_allowed, &xp_id);
00981 
00982         if (!check_error)
00983         {
00984                 dazuko_bzero(&event_p, sizeof(event_p));
00985 /*
00986                 event_p.flags = flags;
00987                 event_p.set_flags = 1;
00988                 event_p.mode = mode;
00989                 event_p.set_mode = 1;
00990 */
00991                 event_p.pid = current->pid;
00992                 event_p.set_pid = 1;
00993                 event_p.uid = current->uid;
00994                 event_p.set_uid = 1;
00995 
00996                 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
00997                 if (dfs != NULL)
00998                 {
00999                         dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01000 
01001                         dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01002                         if (dfs->extra_data != NULL)
01003                         {
01004                                 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01005 
01006                                 dfs->extra_data->dentry = tid.file.dentry_p;
01007 
01008                                 error = dazuko_sys_pre(event, dfs, NULL, &event_p);
01009 
01010 #if defined(CONFIG_RSBAC_DAZ_CACHE)
01011                                 if(!error)
01012                                   i_attr_val1.daz_scanned = DAZ_clean;
01013                                 else
01014                                   i_attr_val1.daz_scanned = DAZ_infected;
01015 
01016                                 if (rsbac_set_attr(DAZ,
01017                                     target,
01018                                     tid,
01019                                     A_daz_scanned,
01020                                     i_attr_val1))
01021                                   {
01022 #ifdef CONFIG_RSBAC_RMSG
01023                                     rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_set_attr() returned error!\n");
01024 #endif
01025 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01026                                     if (!rsbac_nosyslog)
01027 #endif
01028                                     printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_set_attr() returned error!\n");
01029                                     return NOT_GRANTED;
01030                                   }
01031 #endif
01032                         }
01033                         else
01034                         {
01035                                 xp_free(dfs);
01036                                 dfs = NULL;
01037                         }
01038 
01039                         dazuko_file_struct_cleanup(&dfs);
01040                 }
01041         }
01042 
01043         if(!error)
01044           return GRANTED;
01045         else
01046           return NOT_GRANTED;
01047   }; /* end of rsbac_adf_request_daz() */
01048 
01049 
01050 /*****************************************************************************/
01051 /* If the request returned granted and the operation is performed,           */
01052 /* the following function can be called by the AEF to get all aci set        */
01053 /* correctly. For write accesses that are performed fully within the kernel, */
01054 /* this is usually not done to prevent extra calls, including R_CLOSE for    */
01055 /* cleaning up. Because of this, the write boundary is not adjusted - there  */
01056 /* is no user-level writing anyway...                                        */
01057 /* The second instance of target specification is the new target, if one has */
01058 /* been created, otherwise its values are ignored.                           */
01059 /* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */
01060 
01061 int  rsbac_adf_set_attr_daz(
01062                       enum  rsbac_adf_request_t     request,
01063                             rsbac_pid_t             caller_pid,
01064                       enum  rsbac_target_t          target,
01065                       union rsbac_target_id_t       tid,
01066                       enum  rsbac_target_t          new_target,
01067                       union rsbac_target_id_t       new_tid,
01068                       enum  rsbac_attribute_t       attr,
01069                       union rsbac_attribute_value_t attr_val,
01070                             rsbac_uid_t             owner)
01071   {
01072     struct dazuko_file_struct *dfs = NULL;
01073     struct xp_daemon_id xp_id;
01074     int check_error = 0;
01075     struct event_properties event_p;
01076     int event;
01077     int daemon_allowed;
01078     union rsbac_target_id_t       i_tid;
01079     union rsbac_attribute_value_t i_attr_val1;
01080     union rsbac_attribute_value_t i_attr_val2;
01081 
01082     switch (request)
01083       {
01084                 case R_DELETE:
01085                         if (target == T_FILE)
01086                         {
01087                                 reset_scanned(tid.file);
01088                                 event = DAZUKO_ON_UNLINK;
01089                                 daemon_allowed = 1;
01090                         }
01091                         else if (target == T_DIR)
01092                         {
01093                                 event = DAZUKO_ON_RMDIR;
01094                                 daemon_allowed = 1;
01095                         }
01096                         else
01097                         {
01098                           return(0);
01099                         }
01100                         break;
01101                 case R_CLOSE:
01102                         if (target == T_FILE)
01103                         {
01104                                 event = DAZUKO_ON_CLOSE;
01105                                 daemon_allowed = 1;
01106                         }
01107                         else
01108                         {
01109                           return(0);
01110                         }
01111                         break;
01112 
01113                 case R_EXECUTE:
01114                         if (target == T_FILE)
01115                         {
01116                   /* get daz_scanner for file */
01117                   if (rsbac_get_attr(DAZ,
01118                                      T_FILE,
01119                                      tid,
01120                                      A_daz_scanner,
01121                                      &i_attr_val1,
01122                                      TRUE))
01123                     {
01124 #ifdef CONFIG_RSBAC_RMSG
01125                       rsbac_printk(KERN_WARNING
01126                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01127 #endif
01128 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01129                       if (!rsbac_nosyslog)
01130 #endif
01131                       printk(KERN_WARNING
01132                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01133                       return(-RSBAC_EREADFAILED);
01134                     }
01135                   /* get for process */
01136                   i_tid.process = caller_pid;
01137                   if (rsbac_get_attr(DAZ,
01138                                      T_PROCESS,
01139                                      i_tid,
01140                                      A_daz_scanner,
01141                                      &i_attr_val2,
01142                                      FALSE))
01143                     {
01144 #ifdef CONFIG_RSBAC_RMSG
01145                       rsbac_printk(KERN_WARNING
01146                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01147 #endif
01148 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01149                       if (!rsbac_nosyslog)
01150 #endif
01151                       printk(KERN_WARNING
01152                              "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01153                       return(-RSBAC_EREADFAILED);
01154                     }
01155                   /* and set for process, if different */
01156                   if(i_attr_val1.daz_scanner != i_attr_val2.daz_scanner)
01157                     if (rsbac_set_attr(DAZ,
01158                                        T_PROCESS,
01159                                        i_tid,
01160                                        A_daz_scanner,
01161                                        i_attr_val1))
01162                       {
01163 #ifdef CONFIG_RSBAC_RMSG
01164                         rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01165 #endif
01166 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01167                         if (!rsbac_nosyslog)
01168 #endif
01169                         printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01170                         return(-RSBAC_EWRITEFAILED);
01171                       }
01172                                 event = DAZUKO_ON_EXEC;
01173                                 daemon_allowed = 0;
01174                         }
01175                         else
01176                         {
01177                           return(0);
01178                         }
01179                         break;
01180 
01181                 case R_APPEND_OPEN:
01182                 case R_READ_WRITE_OPEN:
01183                 case R_WRITE_OPEN:
01184                         if (target == T_FILE)
01185                         {
01186                                 reset_scanned(tid.file);
01187                                 event = DAZUKO_ON_OPEN;
01188                                 daemon_allowed = 1;
01189                         }
01190                         else
01191                         {
01192                           return(0);
01193                         }
01194                         break;
01195 
01196                 case R_READ_OPEN:
01197                         if (target == T_FILE)
01198                         {
01199                                 event = DAZUKO_ON_OPEN;
01200                                 daemon_allowed = 1;
01201                         }
01202                         else
01203                         {
01204                           return(0);
01205                         }
01206                         break;
01207 
01208         case R_CLONE:
01209             if (target == T_PROCESS)
01210               {
01211                 /* Get daz_scanner from first process */
01212                 if (rsbac_get_attr(DAZ,
01213                                    T_PROCESS,
01214                                    tid,
01215                                    A_daz_scanner,
01216                                    &i_attr_val1,
01217                                    FALSE))
01218                   {
01219 #ifdef CONFIG_RSBAC_RMSG
01220                     rsbac_printk(KERN_WARNING
01221                            "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01222 #endif
01223 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01224                     if (!rsbac_nosyslog)
01225 #endif
01226                     printk(KERN_WARNING
01227                            "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01228                     return(-RSBAC_EREADFAILED);
01229                   }
01230                 /* Set daz_scanner for new process, if set for first */
01231                 if (   i_attr_val1.daz_scanner
01232                     && (rsbac_set_attr(DAZ,
01233                                        T_PROCESS,
01234                                        new_tid,
01235                                        A_daz_scanner,
01236                                        i_attr_val1)) )
01237                   {
01238 #ifdef CONFIG_RSBAC_RMSG
01239                     rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01240 #endif
01241 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01242                     if (!rsbac_nosyslog)
01243 #endif
01244                     printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n");
01245                     return(-RSBAC_EWRITEFAILED);
01246                   }
01247                 return(0);
01248               }
01249             else
01250               return(0);
01251 
01252 /*********************/
01253         default: return(0);
01254       }
01255 
01256 #if defined(CONFIG_RSBAC_DAZ_CACHE)
01257     /* get daz_scanned for file */
01258     if (rsbac_get_attr(DAZ,
01259                        T_FILE,
01260                        tid,
01261                        A_daz_scanned,
01262                        &i_attr_val1,
01263                        TRUE))
01264       {
01265 #ifdef CONFIG_RSBAC_RMSG
01266         rsbac_printk(KERN_WARNING
01267                      "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01268 #endif
01269 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01270         if (!rsbac_nosyslog)
01271 #endif
01272           printk(KERN_WARNING
01273                  "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n");
01274         return(-RSBAC_EREADFAILED);
01275       }
01276     if(i_attr_val1.daz_scanned == DAZ_clean)
01277       return 0;
01278 #endif
01279 
01280         xp_id.pid = current->pid;
01281         xp_id.file = NULL;
01282 
01283         check_error = dazuko_sys_check(event, daemon_allowed, &xp_id);
01284 
01285         if (!check_error)
01286         {
01287                 dazuko_bzero(&event_p, sizeof(event_p));
01288 /*
01289                 event_p.flags = flags;
01290                 event_p.set_flags = 1;
01291                 event_p.mode = mode;
01292                 event_p.set_mode = 1;
01293 */
01294                 event_p.pid = current->pid;
01295                 event_p.set_pid = 1;
01296                 event_p.uid = current->uid;
01297                 event_p.set_uid = 1;
01298 
01299                 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01300                 if (dfs != NULL)
01301                 {
01302                         dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01303 
01304                         dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01305                         if (dfs->extra_data != NULL)
01306                         {
01307                                 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01308 
01309                                 dfs->extra_data->dentry = tid.file.dentry_p;
01310 
01311                                 dazuko_sys_post(event, dfs, NULL, &event_p);
01312                         }
01313                         else
01314                         {
01315                                 xp_free(dfs);
01316                                 dfs = NULL;
01317                         }
01318 
01319                         dazuko_file_struct_cleanup(&dfs);
01320                 }
01321         }
01322 
01323     return(0);
01324   }; /* end of rsbac_adf_set_attr_daz() */
01325 
01326 /* end of rsbac/adf/daz/daz_main.c */
01327 

Generated on Fri Jun 17 09:45:19 2005 for RSBAC by  doxygen 1.4.2