00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "dazuko_rsbac.h"
00021
#include "dazuko_xp.h"
00022
#include "dazukoio.h"
00023
00024
#include <linux/init.h>
00025
#include <linux/unistd.h>
00026
#include <linux/fs.h>
00027
#include <linux/slab.h>
00028
#include <asm/uaccess.h>
00029
#include <linux/random.h>
00030
00031
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00032
#include <linux/vermagic.h>
00033
#endif
00034
00035
#include <rsbac/types.h>
00036
#include <rsbac/reg.h>
00037
#include <rsbac/adf.h>
00038
#include <rsbac/aci.h>
00039
#include <rsbac/getname.h>
00040
#include <rsbac/error.h>
00041
#include <rsbac/proc_fs.h>
00042
#include <rsbac/debug.h>
00043
00044
00045
#if defined(DEVFS_SUPPORT) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00046
#include <linux/devfs_fs_kernel.h>
00047
#endif
00048
00049
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00050
int linux_dazuko_device_read(
struct file *file,
char *buffer, size_t length, loff_t *pos);
00051
int linux_dazuko_device_write(
struct file *file,
const char *buffer, size_t length, loff_t *pos);
00052
#else
00053
ssize_t
linux_dazuko_device_read(
struct file *file,
char *buffer, size_t length, loff_t *pos);
00054 ssize_t
linux_dazuko_device_write(
struct file *file,
const char *buffer, size_t length, loff_t *pos);
00055
#endif
00056
int linux_dazuko_device_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long param);
00057
int linux_dazuko_device_open(
struct inode *inode,
struct file *file);
00058
int linux_dazuko_device_release(
struct inode *inode,
struct file *file);
00059
00060
extern struct xp_atomic active;
00061
00062 static int dev_major = -1;
00063 static rsbac_reg_handle_t handle = -1;
00064
00065 static struct file_operations
fops = {
00066 read:
linux_dazuko_device_read,
00067 write:
linux_dazuko_device_write,
00068 ioctl:
linux_dazuko_device_ioctl,
00069 open:
linux_dazuko_device_open,
00070 release:
linux_dazuko_device_release,
00071 };
00072
00073
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00074
00075
00076
00077
00078
#ifndef __wait_event_interruptible
00079 #define __wait_event_interruptible(wq, condition, ret) \
00080
do { \
00081
struct wait_queue __wait; \
00082
\
00083
__wait.task = current; \
00084
add_wait_queue(&wq, &__wait); \
00085
for (;;) { \
00086
current->state = TASK_INTERRUPTIBLE; \
00087
mb(); \
00088
if (condition) \
00089
break; \
00090
if (!signal_pending(current)) { \
00091
schedule(); \
00092
continue; \
00093
} \
00094
ret = -ERESTARTSYS; \
00095
break; \
00096
} \
00097
current->state = TASK_RUNNING; \
00098
remove_wait_queue(&wq, &__wait); \
00099
} while (0)
00100
#endif
00101
00102
#ifndef wait_event_interruptible
00103 #define wait_event_interruptible(wq, condition) \
00104
({ \
00105
int __ret = 0; \
00106
if (!(condition)) \
00107
__wait_event_interruptible(wq, condition, __ret);\
00108
__ret; \
00109
})
00110 #define wait_event(wq, condition) \
00111
({ \
00112
int __ret = 0; \
00113
if (!(condition)) \
00114
__wait_event_interruptible(wq, condition, __ret);\
00115
__ret; \
00116
})
00117
#endif
00118
00119
#endif
00120
00121
00122
00123
00124 inline int xp_init_mutex(
struct xp_mutex *mutex)
00125 {
00126
#ifdef init_MUTEX
00127
init_MUTEX(&(mutex->
mutex));
00128
#else
00129
sema_init(&(mutex->
mutex), 1);
00130
#endif
00131
00132
return 0;
00133 }
00134
00135 inline int xp_down(
struct xp_mutex *mutex)
00136 {
00137 down(&(mutex->
mutex));
00138
return 0;
00139 }
00140
00141 inline int xp_up(
struct xp_mutex *mutex)
00142 {
00143 up(&(mutex->
mutex));
00144
return 0;
00145 }
00146
00147 inline int xp_destroy_mutex(
struct xp_mutex *mutex)
00148 {
00149
return 0;
00150 }
00151
00152
00153
00154
00155 inline int xp_init_rwlock(
struct xp_rwlock *rwlock)
00156 {
00157
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00158
rwlock_init(&(rwlock->
rwlock));
00159
#else
00160
rwlock->
rwlock = RW_LOCK_UNLOCKED;
00161
#endif
00162
return 0;
00163 }
00164
00165 inline int xp_write_lock(
struct xp_rwlock *rwlock)
00166 {
00167 write_lock(&(rwlock->
rwlock));
00168
return 0;
00169 }
00170
00171 inline int xp_write_unlock(
struct xp_rwlock *rwlock)
00172 {
00173 write_unlock(&(rwlock->
rwlock));
00174
return 0;
00175 }
00176
00177 inline int xp_read_lock(
struct xp_rwlock *rlock)
00178 {
00179 read_lock(&(rlock->
rwlock));
00180
return 0;
00181 }
00182
00183 inline int xp_read_unlock(
struct xp_rwlock *rlock)
00184 {
00185 read_unlock(&(rlock->
rwlock));
00186
return 0;
00187 }
00188
00189 inline int xp_destroy_rwlock(
struct xp_rwlock *rwlock)
00190 {
00191
return 0;
00192 }
00193
00194
00195
00196
00197 inline int xp_init_queue(
struct xp_queue *queue)
00198 {
00199
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00200
init_waitqueue_head(&(queue->
queue));
00201
#else
00202
queue =
NULL;
00203
#endif
00204
00205
return 0;
00206 }
00207
00208 inline int xp_wait_until_condition(
struct xp_queue *queue,
int (*cfunction)(
void *),
void *cparam,
int allow_interrupt)
00209 {
00210
00211
00212
if (allow_interrupt)
00213 {
00214
return wait_event_interruptible(queue->
queue, cfunction(cparam) != 0);
00215 }
00216
else
00217 {
00218
wait_event(queue->
queue, cfunction(cparam) != 0);
00219 }
00220
00221
return 0;
00222 }
00223
00224 inline int xp_notify(
struct xp_queue *queue)
00225 {
00226 wake_up(&(queue->
queue));
00227
return 0;
00228 }
00229
00230 inline int xp_destroy_queue(
struct xp_queue *queue)
00231 {
00232
return 0;
00233 }
00234
00235
00236
00237
00238 inline void*
xp_malloc(size_t size)
00239 {
00240
return kmalloc(size, GFP_KERNEL);
00241 }
00242
00243 inline int xp_free(
void *ptr)
00244 {
00245 kfree(ptr);
00246
return 0;
00247 }
00248
00249 inline int xp_copyin(
const void *user_src,
void *kernel_dest, size_t size)
00250 {
00251
return copy_from_user(kernel_dest, user_src, size);
00252 }
00253
00254 inline int xp_copyout(
const void *kernel_src,
void *user_dest, size_t size)
00255 {
00256
return copy_to_user(user_dest, kernel_src, size);
00257 }
00258
00259 inline int xp_verify_user_writable(
const void *user_ptr, size_t size)
00260 {
00261
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00262
return verify_area(VERIFY_WRITE, user_ptr, size);
00263
#else
00264
return 0;
00265
#endif
00266
}
00267
00268 inline int xp_verify_user_readable(
const void *user_ptr, size_t size)
00269 {
00270
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00271
return verify_area(VERIFY_READ, user_ptr, size);
00272
#else
00273
return 0;
00274
#endif
00275
}
00276
00277
00278
00279
00280 inline int xp_is_absolute_path(
const char *
path)
00281 {
00282
return (path[0] ==
'/');
00283 }
00284
00285
00286
00287
00288 inline int xp_atomic_set(
struct xp_atomic *atomic,
int value)
00289 {
00290 atomic_set(&(atomic->
atomic), value);
00291
return 0;
00292 }
00293
00294 inline int xp_atomic_inc(
struct xp_atomic *atomic)
00295 {
00296
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00297
#ifdef MODULE
00298
if (atomic == &
active)
00299 MOD_INC_USE_COUNT;
00300
#endif
00301
#endif
00302
00303 atomic_inc(&(atomic->
atomic));
00304
return 0;
00305 }
00306
00307 inline int xp_atomic_dec(
struct xp_atomic *atomic)
00308 {
00309
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00310
#ifdef MODULE
00311
if (atomic == &
active)
00312 MOD_DEC_USE_COUNT;
00313
#endif
00314
#endif
00315
00316 atomic_dec(&(atomic->
atomic));
00317
return 0;
00318 }
00319
00320 inline int xp_atomic_read(
struct xp_atomic *atomic)
00321 {
00322
return atomic_read(&(atomic->
atomic));
00323 }
00324
00325
00326
00327
00328 inline int xp_copy_file(
struct xp_file *dest,
struct xp_file *src)
00329 {
00330
return 0;
00331 }
00332
00333 inline int xp_compare_file(
struct xp_file *file1,
struct xp_file *file2)
00334 {
00335
return 0;
00336 }
00337
00338 inline int xp_file_struct_check(
struct dazuko_file_struct *dfs)
00339 {
00340
int length;
00341
00342
00343
00344
if (dfs ==
NULL)
00345
return -1;
00346
00347
if (dfs->
extra_data ==
NULL)
00348
return -1;
00349
00350
if (dfs->
extra_data->
dentry ==
NULL)
00351
return -1;
00352
00353
if (dfs->
extra_data->
dentry->d_inode ==
NULL)
00354
return -1;
00355
00356
00357
00358 length =
rsbac_get_full_path_length(dfs->
extra_data->
dentry);
00359
if (length < 1)
00360
return -1;
00361
00362 dfs->
extra_data->
full_filename =
xp_malloc(length + 1);
00363
if (dfs->
extra_data->
full_filename ==
NULL)
00364
return -1;
00365
00366
00367 dfs->
extra_data->
free_full_filename = 1;
00368
00369
if (
rsbac_get_full_path(dfs->
extra_data->
dentry, dfs->
extra_data->
full_filename, length + 1) < 1)
00370
return -1;
00371
00372
00373 dfs->
extra_data->
full_filename_length =
dazuko_get_filename_length(dfs->
extra_data->
full_filename);
00374
00375
00376 dfs->
filename = dfs->
extra_data->
full_filename;
00377
00378 dfs->
filename_length = dfs->
extra_data->
full_filename_length;
00379
00380 dfs->
file_p.
size = dfs->
extra_data->
dentry->d_inode->i_size;
00381 dfs->
file_p.
set_size = 1;
00382 dfs->
file_p.
uid = dfs->
extra_data->
dentry->d_inode->i_uid;
00383 dfs->
file_p.
set_uid = 1;
00384 dfs->
file_p.
gid = dfs->
extra_data->
dentry->d_inode->i_gid;
00385 dfs->
file_p.
set_gid = 1;
00386 dfs->
file_p.
mode = dfs->
extra_data->
dentry->d_inode->i_mode;
00387 dfs->
file_p.
set_mode = 1;
00388
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00389
dfs->
file_p.
device_type = dfs->
extra_data->
dentry->d_inode->i_dev;
00390
#else
00391
dfs->
file_p.
device_type = dfs->
extra_data->
dentry->d_inode->i_rdev;
00392
#endif
00393
dfs->
file_p.
set_device_type = 1;
00394
00395
return 0;
00396 }
00397
00398 int xp_file_struct_check_cleanup(
struct dazuko_file_struct *dfs)
00399 {
00400
return 0;
00401 }
00402
00403 static int dazuko_file_struct_cleanup(
struct dazuko_file_struct **dfs)
00404 {
00405
if (dfs ==
NULL)
00406
return 0;
00407
00408
if (*dfs ==
NULL)
00409
return 0;
00410
00411
xp_file_struct_check_cleanup(*dfs);
00412
00413
if ((*dfs)->extra_data !=
NULL)
00414 {
00415
if ((*dfs)->extra_data->free_full_filename)
00416
xp_free((*dfs)->extra_data->full_filename);
00417
00418
xp_free((*dfs)->extra_data);
00419 }
00420
00421
xp_free(*dfs);
00422
00423 *dfs =
NULL;
00424
00425
return 0;
00426 }
00427
00428
00429
00430
00431 int xp_id_compare(
struct xp_daemon_id *id1,
struct xp_daemon_id *id2)
00432 {
00433
if (id1 ==
NULL || id2 ==
NULL)
00434
return -1;
00435
00436
00437
00438
if (id1->
file !=
NULL && id1->
file == id2->
file)
00439
return 0;
00440
00441
if (id1->
pid == id2->
pid)
00442
return 0;
00443
00444
return 1;
00445 }
00446
00447 int xp_id_free(
struct xp_daemon_id *
id)
00448 {
00449
xp_free(
id);
00450
00451
return 0;
00452 }
00453
00454 struct xp_daemon_id*
xp_id_copy(
struct xp_daemon_id *
id)
00455 {
00456
struct xp_daemon_id *ptr;
00457
00458
if (
id ==
NULL)
00459
return NULL;
00460
00461 ptr = (
struct xp_daemon_id *)
xp_malloc(
sizeof(
struct xp_daemon_id));
00462
00463
if (ptr !=
NULL)
00464 {
00465 ptr->pid =
id->pid;
00466 ptr->file =
id->file;
00467 }
00468
00469
return ptr;
00470 }
00471
00472
00473
00474
00475 static inline int dazuko_rsbac_process(
enum rsbac_adf_request_t request,
00476
enum rsbac_target_t target,
00477
union rsbac_target_id_t tid,
00478
int is_pre)
00479 {
00480
struct dazuko_file_struct *dfs =
NULL;
00481
struct xp_daemon_id xp_id;
00482
int error = 0;
00483
int check_error = 0;
00484
struct event_properties event_p;
00485
int event;
00486
int daemon_allowed;
00487
00488
switch (request)
00489 {
00490
case R_DELETE:
00491
if (target ==
T_FILE)
00492 {
00493 event =
DAZUKO_ON_UNLINK;
00494 daemon_allowed = 1;
00495 }
00496
else if (target ==
T_DIR)
00497 {
00498 event =
DAZUKO_ON_RMDIR;
00499 daemon_allowed = 1;
00500 }
00501
else
00502 {
00503
goto dazuko_rsbac_process_quickout;
00504 }
00505
break;
00506
00507
case R_CLOSE:
00508
if (target ==
T_FILE)
00509 {
00510 event =
DAZUKO_ON_CLOSE;
00511 daemon_allowed = 1;
00512 }
00513
else
00514 {
00515
goto dazuko_rsbac_process_quickout;
00516 }
00517
break;
00518
00519
case R_EXECUTE:
00520
if (target ==
T_FILE)
00521 {
00522 event =
DAZUKO_ON_EXEC;
00523 daemon_allowed = 0;
00524 }
00525
else
00526 {
00527
goto dazuko_rsbac_process_quickout;
00528 }
00529
break;
00530
00531
case R_APPEND_OPEN:
00532
case R_READ_WRITE_OPEN:
00533
case R_READ_OPEN:
00534
case R_WRITE_OPEN:
00535
if (target ==
T_FILE)
00536 {
00537 event =
DAZUKO_ON_OPEN;
00538 daemon_allowed = 1;
00539 }
00540
else
00541 {
00542
goto dazuko_rsbac_process_quickout;
00543 }
00544
break;
00545
00546
default:
00547
goto dazuko_rsbac_process_quickout;
00548 }
00549
00550 xp_id.
pid = current->pid;
00551 xp_id.
file =
NULL;
00552
00553 check_error =
dazuko_sys_check(event, daemon_allowed, &xp_id);
00554
00555
if (!check_error)
00556 {
00557
dazuko_bzero(&event_p,
sizeof(event_p));
00558
00559
00560
00561
00562
00563
00564 event_p.pid = current->pid;
00565 event_p.set_pid = 1;
00566 event_p.uid = current->uid;
00567 event_p.set_uid = 1;
00568
00569 dfs = (
struct dazuko_file_struct *)
xp_malloc(
sizeof(
struct dazuko_file_struct));
00570
if (dfs !=
NULL)
00571 {
00572
dazuko_bzero(dfs,
sizeof(
struct dazuko_file_struct));
00573
00574 dfs->extra_data = (
struct xp_file_struct *)
xp_malloc(
sizeof(
struct xp_file_struct));
00575
if (dfs->extra_data !=
NULL)
00576 {
00577
dazuko_bzero(dfs->extra_data,
sizeof(
struct xp_file_struct));
00578
00579 dfs->extra_data->dentry = tid.file.dentry_p;
00580
00581
if (is_pre)
00582 error =
dazuko_sys_pre(event, dfs, &event_p);
00583
else
00584
dazuko_sys_post(event, dfs,
NULL, &event_p);
00585 }
00586
else
00587 {
00588
xp_free(dfs);
00589 dfs =
NULL;
00590 }
00591
00592
dazuko_file_struct_cleanup(&dfs);
00593 }
00594 }
00595
00596
if (!is_pre)
00597
return 0;
00598
00599
if (error)
00600
return NOT_GRANTED;
00601
00602
return GRANTED;
00603
00604 dazuko_rsbac_process_quickout:
00605
if (is_pre)
00606
return DO_NOT_CARE;
00607
00608
return 0;
00609 }
00610
00611 static inline int dazuko_rsbac_pre(
enum rsbac_adf_request_t request,
00612
rsbac_pid_t owner_pid,
00613
enum rsbac_target_t target,
00614
union rsbac_target_id_t tid,
00615
enum rsbac_attribute_t attr,
00616
union rsbac_attribute_value_t attr_val,
00617
rsbac_uid_t owner)
00618 {
00619
return dazuko_rsbac_process(request, target, tid, 1);
00620 }
00621
00622
00623 static int dazuko_rsbac_post(
enum rsbac_adf_request_t request,
00624
rsbac_pid_t owner_pid,
00625
enum rsbac_target_t target,
00626
union rsbac_target_id_t tid,
00627
enum rsbac_target_t new_target,
00628
union rsbac_target_id_t new_tid,
00629
enum rsbac_attribute_t attr,
00630
union rsbac_attribute_value_t attr_val,
00631
rsbac_uid_t owner)
00632 {
00633
return dazuko_rsbac_process(request, target, tid, 0);
00634 }
00635
00636
00637
00638
00639 inline int xp_sys_hook()
00640 {
00641
#define RSBAC_REG_REGISTER_RETRIES 1024
00642
00643
00644
int retries;
00645
00646
00647
00648
struct rsbac_reg_entry_t entry;
00649
00650
00651 memset(&entry, 0,
sizeof(entry));
00652
00653 strcpy(entry.name,
"Dazuko");
00654 entry.request_func =
dazuko_rsbac_pre;
00655 entry.set_attr_func =
dazuko_rsbac_post;
00656 entry.switch_on =
TRUE;
00657
00658
for (retries=0 ; retries<
RSBAC_REG_REGISTER_RETRIES ; retries++)
00659 {
00660
00661 get_random_bytes(&
handle,
sizeof(
handle));
00662
00663
00664
if (
handle < 0)
00665
handle *= -1;
00666
00667 entry.handle =
handle;
00668
00669
handle =
rsbac_reg_register(
RSBAC_REG_VERSION, entry);
00670
00671
if (
handle != -
RSBAC_EEXISTS)
00672 {
00673
00674
break;
00675 }
00676 }
00677
00678
if (
handle < 0)
00679 {
00680
xp_print(
"dazuko: failed to register with RSBAC\n");
00681
return -ENOEXEC;
00682 }
00683
00684
00685
#ifdef DEVFS_SUPPORT
00686
dev_major = devfs_register_chrdev(0,
DEVICE_NAME, &
fops);
00687 devfs_register(
NULL,
DEVICE_NAME, DEVFS_FL_DEFAULT,
00688
dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
00689 &
fops,
NULL);
00690
#else
00691
dev_major = register_chrdev(0,
DEVICE_NAME, &
fops);
00692
#endif
00693
if (
dev_major < 0)
00694 {
00695
xp_print(
"dazuko: unable to register device chrdev, err=%d\n",
dev_major);
00696
return dev_major;
00697 }
00698
00699
00700
00701
return 0;
00702 }
00703
00704 inline int xp_sys_unhook()
00705 {
00706
00707
00708
int error;
00709
00710
#ifdef DEVFS_SUPPORT
00711
error = devfs_unregister_chrdev(
dev_major,
DEVICE_NAME);
00712 devfs_unregister(devfs_find_handle(
NULL,
DEVICE_NAME,
dev_major, 0, DEVFS_SPECIAL_CHR, 0));
00713
#else
00714
error = unregister_chrdev(
dev_major,
DEVICE_NAME);
00715
#endif
00716
if (error < 0)
00717 {
00718
xp_print(
"dazuko: error unregistering chrdev, err=%d\n", error);
00719 }
00720
00721
if (
rsbac_reg_unregister(
handle) != 0)
00722 {
00723
xp_print(
"dazuko: failed to unregister with RSBAC (system may be left in an unstable state!)\n");
00724 }
00725
00726
return 0;
00727 }
00728
00729
00730
00731
00732 int xp_print(
const char *fmt, ...)
00733 {
00734 va_list args;
00735
char *p;
00736 size_t size = 1024;
00737
00738 p = (
char *)
xp_malloc(size);
00739
if (!p)
00740
return -1;
00741
00742 va_start(args, fmt);
00743
dazuko_vsnprintf(p, size-1, fmt, args);
00744 va_end(args);
00745
00746 p[size-1] = 0;
00747
00748 printk(p);
00749 rsbac_printk(p);
00750
00751
xp_free(p);
00752
00753
return 0;
00754 }
00755
00756
00757
00758
00759
int linux_dazuko_device_open(
struct inode *inode,
struct file *file)
00760 {
00761
DPRINT((
"dazuko: linux_dazuko_device_open() [%d]\n", current->pid));
00762
00763
return 0;
00764 }
00765
00766
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00767
int linux_dazuko_device_read(
struct file *file,
char *buffer, size_t length, loff_t *pos)
00768 #
else
00769 ssize_t
linux_dazuko_device_read(
struct file *file,
char *buffer, size_t length, loff_t *pos)
00770 #endif
00771 {
00772
00773
00774
00775
00776
char tmp[20];
00777 size_t dev_major_len;
00778
00779
DPRINT((
"dazuko: linux_dazuko_device_read() [%d]\n", current->pid));
00780
00781
00782
if (current->uid != 0)
00783
return 0;
00784
00785
00786
if (*pos != 0)
00787
return 0;
00788
00789
if (
dev_major < 0)
00790
return -ENODEV;
00791
00792
00793
00794
dazuko_bzero(tmp,
sizeof(tmp));
00795
00796 dev_major_len =
dazuko_snprintf(tmp,
sizeof(tmp),
"%d", dev_major) + 1;
00797
00798
if (tmp[
sizeof(tmp)-1] != 0)
00799 {
00800
xp_print(
"dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major);
00801
return -EFAULT;
00802 }
00803
00804
if (length < dev_major_len)
00805
return -EINVAL;
00806
00807
00808
if (
xp_copyout(tmp, buffer, dev_major_len) != 0)
00809
return -EFAULT;
00810
00811 *pos = dev_major_len;
00812
00813
return dev_major_len;
00814 }
00815
00816
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00817
int linux_dazuko_device_write(
struct file *file,
const char *buffer, size_t length, loff_t *pos)
00818 #
else
00819 ssize_t
linux_dazuko_device_write(
struct file *file,
const char *buffer, size_t length, loff_t *pos)
00820 #endif
00821 {
00822
struct dazuko_request *u_request;
00823
struct xp_daemon_id xp_id;
00824
char tmpbuffer[32];
00825
char *value;
00826
int size;
00827
00828
00829
if (current->uid != 0)
00830
return length;
00831
00832 size = length;
00833
if (length >=
sizeof(tmpbuffer))
00834 size =
sizeof(tmpbuffer) -1;
00835
00836
00837
if (
xp_copyin(buffer, tmpbuffer, size) != 0)
00838
return -EFAULT;
00839
00840 tmpbuffer[size] = 0;
00841
00842
if (
dazuko_get_value(
"\nRA=", buffer, &value) != 0)
00843 {
00844
xp_print(
"dazuko: error: linux_dazuko_device_write.RA missing\n");
00845
return -EFAULT;
00846 }
00847
00848 u_request = (
struct dazuko_request *)simple_strtoul(value, NULL, 10);
00849
00850
xp_free(value);
00851
00852 xp_id.
pid = current->pid;
00853 xp_id.
file = file;
00854
00855
if (
dazuko_handle_user_request(u_request, &xp_id) == 0)
00856
return length;
00857
else
00858
return -EINTR;
00859 }
00860
00861
int linux_dazuko_device_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long param)
00862 {
00863
00864
00865
00866
00867
struct xp_daemon_id xp_id;
00868
int error = 0;
00869
00870
00871
if (current->uid != 0)
00872
return 0;
00873
00874
if (param == 0)
00875 {
00876
xp_print(
"dazuko: error: linux_dazuko_device_ioctl(..., 0)\n");
00877
return -EFAULT;
00878 }
00879
00880 xp_id.
pid = current->pid;
00881 xp_id.
file = file;
00882
00883 error =
dazuko_handle_user_request_compat12((
void *)param, _IOC_NR(cmd), &xp_id);
00884
00885
if (error != 0)
00886 {
00887
00888
00889
return -EPERM;
00890 }
00891
00892
return error;
00893 }
00894
00895
int linux_dazuko_device_release(
struct inode *inode,
struct file *file)
00896 {
00897
struct xp_daemon_id xp_id;
00898
00899
DPRINT((
"dazuko: dazuko_device_release() [%d]\n", current->pid));
00900
00901
00902
if (current->uid != 0)
00903
return 0;
00904
00905 xp_id.
pid = current->pid;
00906 xp_id.
file = file;
00907
00908
return dazuko_unregister_daemon(&xp_id);
00909 }
00910
00911
00912
00913
00914 int __init
linux_dazuko_init(
void)
00915 {
00916
return dazuko_init();
00917 }
00918
00919
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00920
void __exit
linux_dazuko_exit(
void)
00921 #
else
00922 void linux_dazuko_exit(
void)
00923 #endif
00924 {
00925
dazuko_exit();
00926 }
00927
00928
00929
#ifdef MODULE
00930
00931
int init_module(
void)
00932 {
00933
return linux_dazuko_init();
00934 }
00935
00936
void cleanup_module(
void)
00937 {
00938
linux_dazuko_exit();
00939 }
00940
00941
MODULE_AUTHOR(
"H+BEDV Datentechnik GmbH <linux_support@antivir.de>");
00942
MODULE_DESCRIPTION(
"allow 3rd-party file access control");
00943
#ifdef MODULE_LICENSE
00944
MODULE_LICENSE(
"GPL");
00945
#else
00946
static const char __module_license[]
__attribute__((section(
".modinfo"))) =
"license=GPL";
00947
#endif
00948
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00949
MODULE_INFO(vermagic, VERMAGIC_STRING);
00950
#endif
00951
00952
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00953
EXPORT_NO_SYMBOLS;
00954
#endif
00955
00956
#else
00957
00958
module_init(linux_dazuko_init);
00959
module_exit(linux_dazuko_exit);
00960
00961
00962
00963
#endif
00964