dazuko_xp.c File Reference

#include "dazuko_platform.h"
#include "dazuko_xp.h"
#include "dazukoio.h"
#include "dazuko_call.h"

Go to the source code of this file.

Data Structures

struct  path
struct  daemon_id
struct  slot
struct  slot_list
struct  slot_list_container
struct  one_slot_state_not_condition_param
struct  two_slot_state_not_condition_param
struct  get_ready_slot_condition_param

Defines

#define NUM_SLOT_LISTS   5
#define NUM_SLOTS   25
#define SCAN_ON_OPEN   (access_mask & DAZUKO_ON_OPEN)
#define SCAN_ON_CLOSE   (access_mask & DAZUKO_ON_CLOSE)
#define SCAN_ON_EXEC   (access_mask & DAZUKO_ON_EXEC)
#define SCAN_ON_CLOSE_MODIFIED   (access_mask & DAZUKO_ON_CLOSE_MODIFIED)
#define DAZUKO_VSNPRINTF_PRINTSTRING
#define DAZUKO_VSNPRINT(type, name)   dazuko_snprintf(request->reply_buffer + request->reply_buffer_size_used, (request->reply_buffer_size - request->reply_buffer_size_used) - 1, "%s%" #type , key, *((name *)value))

Functions

int dazuko_vsnprintf (char *str, size_t size, const char *format, va_list ap)
int dazuko_snprintf (char *str, size_t size, const char *format,...)
void dazuko_bzero (void *p, int len)
static int dazuko_get_new_unique (void)
static int dazuko_slot_state (struct slot *s)
static int one_slot_state_not_condition (void *param)
static int two_slot_state_not_condition (void *param)
static int __dazuko_change_slot_state (struct slot *s, int from_state, int to_state)
static int dazuko_change_slot_state (struct slot *s, int from_state, int to_state, int release)
static struct slot_dazuko_find_slot (struct daemon_id *did, int release, struct slot_list *sl)
static struct slotdazuko_find_slot_and_slotlist (struct daemon_id *did, int release, struct slot_list *slist, struct slot_list **sl_result)
static struct slotdazuko_find_slot (struct daemon_id *did, int release, struct slot_list *slist)
static int dazuko_insert_path_fs (struct path **list, char *fs_path, int fs_len)
static void dazuko_remove_all_hash (void)
static void dazuko_remove_all_paths (void)
static int _dazuko_unregister_daemon (struct daemon_id *did)
int dazuko_unregister_daemon (struct xp_daemon_id *xp_id)
static int dazuko_state_error (struct slot *s, int current_state)
static int dazuko_register_daemon (struct daemon_id *did, const char *reg_name, int string_length, int write_mode)
static struct slotdazuko_get_an_access (struct daemon_id *did)
static int dazuko_return_access (struct daemon_id *did, int response, struct slot *s)
static int dazuko_isdigit (const char c)
static long dazuko_strtol (const char *string)
static int dazuko_strlen (const char *string)
static const char * dazuko_strchr (const char *haystack, char needle)
static const char * dazuko_strstr (const char *haystack, const char *needle)
int dazuko_get_value (const char *key, const char *string, char **value)
static void dazuko_clear_replybuffer (struct dazuko_request *request)
static void dazuko_close_replybuffer (struct dazuko_request *request)
static void dazuko_add_keyvalue_to_replybuffer (struct dazuko_request *request, const char *key, void *value, char vtype)
static int dazuko_printable (char c)
static void dazuko_add_esc_to_replybuffer (struct dazuko_request *request, const char *key, char **filename)
static int dazuko_set_option (struct daemon_id *did, int opt, void *param, int len)
static int dazuko_handle_request (struct dazuko_request *request, struct xp_daemon_id *xp_id)
int dazuko_handle_user_request (struct dazuko_request *user_request, struct xp_daemon_id *xp_id)
int dazuko_handle_user_request_compat12 (void *ptr, int cmd, struct xp_daemon_id *xp_id)
static struct slotdazuko_get_and_hold_ready_slot (struct slot_list *sl)
static int get_ready_slot_condition (void *param)
static int dazuko_run_daemon_on_slotlist (int event, char *filename, int filenamelength, struct event_properties *event_p, struct file_properties *file_p, int prev_response, struct slot_list *sl)
static int dazuko_run_daemon (int event, char *filename, int filenamelength, struct event_properties *event_p, struct file_properties *file_p)
int dazuko_is_our_daemon (struct xp_daemon_id *xp_id)
static int dazuko_is_selected (struct dazuko_file_struct *kfs)
static int dazuko_add_hash (struct xp_file *file, char *filename, int len)
static void dazuko_mark_hash_dirty (struct xp_file *file)
static struct hashdazuko_get_hash (struct xp_file *file)
int dazuko_get_filename_length (char *filename)
static int dazuko_should_scan (struct dazuko_file_struct *kfs)
int dazuko_sys_check (unsigned long event, int daemon_is_allowed, struct xp_daemon_id *xp_id)
int dazuko_sys_pre (unsigned long event, struct dazuko_file_struct *kfs, struct xp_file *file, struct event_properties *event_p)
int dazuko_sys_post (unsigned long event, struct dazuko_file_struct *kfs, struct xp_file *file, struct event_properties *event_p)
int dazuko_init (void)
int dazuko_exit (void)

Variables

static int unique_count = 1
static char access_mask = 7
static struct slot_list_container slot_lists [NUM_SLOT_LISTS]
static struct pathincl_paths = NULL
static struct pathexcl_paths = NULL
static struct hashhash = NULL
static struct xp_rwlock lock_hash
static struct xp_rwlock lock_lists
static struct xp_atomic active
static struct xp_mutex mutex_unique_count
static struct xp_queue wait_kernel_waiting_for_free_slot
static struct xp_queue wait_daemon_waiting_for_work
static struct xp_queue wait_kernel_waiting_while_daemon_works
static struct xp_queue wait_daemon_waiting_for_free


Define Documentation

#define DAZUKO_VSNPRINT type,
name   )     dazuko_snprintf(request->reply_buffer + request->reply_buffer_size_used, (request->reply_buffer_size - request->reply_buffer_size_used) - 1, "%s%" #type , key, *((name *)value))
 

#define DAZUKO_VSNPRINTF_PRINTSTRING
 

Value:

for ( ; *s ; s++) \
        { \
                if (target == end) \
                { \
                        overflow = 1; \
                        goto dazuko_vsnprintf_out; \
                } \
                *target = *s; \
                target++; \
        }

#define NUM_SLOT_LISTS   5
 

Definition at line 42 of file dazuko_xp.c.

#define NUM_SLOTS   25
 

Definition at line 43 of file dazuko_xp.c.

#define SCAN_ON_CLOSE   (access_mask & DAZUKO_ON_CLOSE)
 

Definition at line 46 of file dazuko_xp.c.

Referenced by dazuko_sys_check(), and dazuko_sys_post().

#define SCAN_ON_CLOSE_MODIFIED   (access_mask & DAZUKO_ON_CLOSE_MODIFIED)
 

Definition at line 48 of file dazuko_xp.c.

Referenced by dazuko_sys_check(), and dazuko_sys_post().

#define SCAN_ON_EXEC   (access_mask & DAZUKO_ON_EXEC)
 

Definition at line 47 of file dazuko_xp.c.

#define SCAN_ON_OPEN   (access_mask & DAZUKO_ON_OPEN)
 

Definition at line 45 of file dazuko_xp.c.

Referenced by dazuko_sys_check(), dazuko_sys_post(), and dazuko_sys_pre().


Function Documentation

static int __dazuko_change_slot_state struct slot s,
int  from_state,
int  to_state
[inline, static]
 

Definition at line 329 of file dazuko_xp.c.

References call_xp_notify(), DAZUKO_FREE, and DAZUKO_READY.

00330 {
00331         /* Make a predicted state transition. We fail if it
00332          * is an unpredicted change. We can ALWAYS go to the
00333          * to_state if it is the same as from_state. Not SMP safe! */
00334 
00335         if (to_state != from_state)
00336         {
00337                 /* make sure this is a predicted transition and there
00338                  * is a daemon on this slot (unique != 0)*/
00339                 if (s->state != from_state || s->did.unique == 0)
00340                         return 0;
00341         }
00342 
00343         s->state = to_state;
00344 
00345         /* handle appropriate wake_up's for basic
00346          * state changes */
00347 
00348         if (to_state == DAZUKO_READY)
00349         {
00350                 call_xp_notify(&wait_kernel_waiting_for_free_slot);
00351         }
00352         else if (to_state == DAZUKO_FREE)
00353         {
00354                 call_xp_notify(&wait_kernel_waiting_while_daemon_works);
00355                 call_xp_notify(&wait_daemon_waiting_for_free);
00356         }
00357 
00358         return 1;
00359 }

static struct slot* _dazuko_find_slot struct daemon_id did,
int  release,
struct slot_list sl
[static]
 

Definition at line 387 of file dazuko_xp.c.

References call_xp_down(), call_xp_id_compare(), call_xp_print, call_xp_up(), slot::did, slot::mutex, NULL, NUM_SLOTS, slot_list::slots, daemon_id::unique, and daemon_id::xp_id.

00388 {
00389         /* Find the first slot with the same given
00390          * pid number. SMP safe. Use this function
00391          * with CAUTION, since the mutex may or may not
00392          * be released depending on the return value AND
00393          * on the value of the "release" argument. */
00394 
00395         int     i;
00396         struct slot     *s = NULL;
00397 
00398         if (sl == NULL)
00399         {
00400                 call_xp_print("dazuko: invalid slot_list given (bug!)\n");
00401                 return NULL;
00402         }
00403 
00404         for (i=0 ; i<NUM_SLOTS ; i++)
00405         {
00406                 s = &(sl->slots[i]);
00407 /* DOWN */
00408                 /* if we are interrupted, we say that no
00409                  * slot was found */
00410                 if (call_xp_down(&(s->mutex)) != 0)
00411                         return NULL;
00412 
00413                 if (did == NULL)
00414                 {
00415                         /* we are looking for an empty slot */
00416                         if (s->did.unique == 0 && s->did.xp_id == NULL)
00417                         {
00418                                 /* we release the mutex only if the
00419                                 * called wanted us to */
00420                                 if (release)
00421                                         call_xp_up(&(s->mutex));
00422 /* UP */
00423                                 return s;
00424                         }
00425                 }
00426                 else if (s->did.unique == 0 && s->did.xp_id == NULL)
00427                 {
00428                         /* this slot is emtpy, so it can't match */
00429 
00430                         /* do nothing */
00431                 }
00432                 /* xp_id's must match! */
00433                 else if (call_xp_id_compare(s->did.xp_id, did->xp_id) == 0)
00434                 {
00435                         /* unique's must also match (unless unique is negative,
00436                          * in which case we will trust xp_id) */
00437                         if (did->unique < 0 || (s->did.unique == did->unique))
00438                         {
00439                                 /* we release the mutex only if the
00440                                  * called wanted us to */
00441                                 if (release)
00442                                         call_xp_up(&(s->mutex));
00443 /* UP */
00444                                 return s;
00445                         }
00446                 }
00447 
00448                 call_xp_up(&(s->mutex));
00449 /* UP */
00450         }
00451 
00452         return NULL;
00453 }

static int _dazuko_unregister_daemon struct daemon_id did  )  [static]
 

Definition at line 632 of file dazuko_xp.c.

References __dazuko_change_slot_state(), call_xp_atomic_dec(), call_xp_atomic_read(), call_xp_id_free(), call_xp_notify(), call_xp_print, call_xp_up(), dazuko_find_slot_and_slotlist(), DAZUKO_FREE, dazuko_remove_all_hash(), dazuko_remove_all_paths(), slot::did, DPRINT, slot::mutex, NULL, daemon_id::unique, slot_list::use_count, and daemon_id::xp_id.

00633 {
00634         /* We unregister the daemon by finding the
00635          * slot with the same slot->pid as the the
00636          * current process id, the daemon. */
00637 
00638         struct slot             *s;
00639         struct slot_list        *sl;
00640 
00641         DPRINT(("dazuko: dazuko_unregister_daemon() [%d]\n", did->unique));
00642 
00643         /* find our slot and hold the mutex
00644          * if we find it */
00645 /* DOWN? */
00646         s = dazuko_find_slot_and_slotlist(did, 0, NULL, &sl);
00647 
00648         if (s == NULL)
00649         {
00650                 /* this daemon was not registered */
00651                 return 0;
00652         }
00653 
00654 /* DOWN */
00655 
00656         /* clearing the unique and pid makes the slot available */
00657         s->did.unique = 0;
00658         call_xp_id_free(s->did.xp_id);
00659         s->did.xp_id = NULL;
00660 
00661         /* reset slot state */
00662         __dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE);
00663 
00664         call_xp_atomic_dec(&(sl->use_count));
00665 
00666         call_xp_up(&(s->mutex));
00667 /* UP */
00668 
00669         /* active should always be positive here, but
00670          * let's check just to be sure. ;) */
00671         if (call_xp_atomic_read(&active) > 0)
00672         {
00673                 /* active and the kernel usage counter
00674                  * should always reflect how many daemons
00675                  * are active */
00676 
00677                 call_xp_atomic_dec(&active);
00678         }
00679         else
00680         {
00681                 call_xp_print("dazuko: active count error (possible bug)\n");
00682         }
00683 
00684         /* Wake up any kernel processes that are
00685          * waiting for an available slot. Remove
00686          * all the include and exclude paths
00687          * if there are no more daemons */
00688 
00689         if (call_xp_atomic_read(&active) == 0)
00690         {
00691                 /* clear out include and exclude paths */
00692                 /* are we sure we want to do this? */
00693                 dazuko_remove_all_paths();
00694 
00695                 /* clear out hash nodes */
00696                 dazuko_remove_all_hash();
00697         }
00698 
00699         call_xp_notify(&wait_kernel_waiting_for_free_slot);
00700         call_xp_notify(&wait_kernel_waiting_while_daemon_works);
00701 
00702         return 0;
00703 }

static void dazuko_add_esc_to_replybuffer struct dazuko_request request,
const char *  key,
char **  filename
[inline, static]
 

Definition at line 1223 of file dazuko_xp.c.

References dazuko_add_keyvalue_to_replybuffer(), dazuko_printable(), dazuko_snprintf(), dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, and dazuko_request::reply_buffer_size_used.

01224 {
01225         int             found = 0;
01226         char            *p_rq;
01227         const char      *limit;
01228         const char      *p_fn;
01229         unsigned char   c;
01230 
01231         /* check for escape characters in filename */
01232         for (p_fn=*filename ; *p_fn ; p_fn++)
01233         {
01234                 if (!dazuko_printable(*p_fn))
01235                 {
01236                         found = 1;
01237                         break;
01238                 }
01239         }
01240 
01241         if (found)
01242         {
01243                 /* this is expensive, but it will also almost never occur */
01244 
01245                 p_rq = request->reply_buffer + request->reply_buffer_size_used;
01246                 limit = request->reply_buffer + request->reply_buffer_size - 1;
01247 
01248                 dazuko_snprintf(p_rq, limit - p_rq, "%s", key);
01249                 p_rq += strlen(p_rq);
01250 
01251                 for (p_fn=*filename ; *p_fn && (p_rq<limit) ; p_fn++)
01252                 {
01253                         if (dazuko_printable(*p_fn))
01254                         {
01255                                 *p_rq = *p_fn;
01256                                 p_rq++;
01257                         }
01258                         else
01259                         {
01260                                 c = *p_fn & 0xFF;
01261                                 dazuko_snprintf(p_rq, limit - p_rq, "\\x%02x", c);
01262                                 p_rq += strlen(p_rq);
01263                         }
01264                 }
01265 
01266                 request->reply_buffer_size_used += strlen(request->reply_buffer + request->reply_buffer_size_used);
01267         }
01268         else
01269         {
01270                 /* no escape characters found */
01271 
01272                 dazuko_add_keyvalue_to_replybuffer(request, key, filename, 's');
01273         }
01274 }

static int dazuko_add_hash struct xp_file file,
char *  filename,
int  len
[static]
 

Definition at line 2341 of file dazuko_xp.c.

References call_xp_copy_file(), call_xp_malloc(), call_xp_write_lock(), call_xp_write_unlock(), hash::dirty, hash::file, hash::name, hash::namelen, hash::next, NULL, and XP_ERROR_FAULT.

Referenced by dazuko_sys_post().

02342 {
02343         /* Add the given file and filename to the linked list
02344          * of files to scan once they are closed. */
02345 
02346         struct hash     *h;
02347 
02348         /* create a new struct hash structure making room for name also */
02349         h = (struct hash *)call_xp_malloc(sizeof(struct hash) + len);
02350         if (h == NULL)
02351                 return XP_ERROR_FAULT;
02352 
02353         /* fill in structure items */
02354 
02355         call_xp_copy_file(&(h->file), file);
02356         h->dirty = 0;
02357         h->namelen = len;
02358         memcpy(h->name, filename, len);
02359         h->name[len] = 0;
02360 
02361         /* add the new struct hash item to the head of the
02362          * struct hash linked list */
02363 
02364 /* LOCK */
02365         call_xp_write_lock(&lock_hash);
02366         h->next = hash;
02367         hash = h;
02368         call_xp_write_unlock(&lock_hash);
02369 /* UNLOCK */
02370         return 0;
02371 }

static void dazuko_add_keyvalue_to_replybuffer struct dazuko_request request,
const char *  key,
void *  value,
char  vtype
[inline, static]
 

Definition at line 1187 of file dazuko_xp.c.

References DAZUKO_VSNPRINT, dazuko_request::reply_buffer, and dazuko_request::reply_buffer_size_used.

01188 {
01189 
01190 #define DAZUKO_VSNPRINT(type, name) dazuko_snprintf(request->reply_buffer + request->reply_buffer_size_used, (request->reply_buffer_size - request->reply_buffer_size_used) - 1, "%s%" #type , key, *((name *)value))
01191 
01192         switch (vtype)
01193         {
01194                 case 'd':
01195                         DAZUKO_VSNPRINT(d, const int);
01196                         break;
01197 
01198                 case 's':
01199                         DAZUKO_VSNPRINT(s, const char *);
01200                         break;
01201 
01202                 case 'l':
01203                         DAZUKO_VSNPRINT(lu, const unsigned long);
01204                         break;
01205 
01206                 default:
01207                         /* all other types treated as chars */
01208                         DAZUKO_VSNPRINT(c, const char);
01209                         break;
01210         }
01211 
01212         /* update how much buffer we have used */
01213         request->reply_buffer_size_used += strlen(request->reply_buffer + request->reply_buffer_size_used);
01214 }

void dazuko_bzero void *  p,
int  len
[inline]
 

Definition at line 273 of file dazuko_xp.c.

00274 {
00275         /* "zero out" len bytes starting with p */
00276 
00277         char    *ptr = (char *)p;
00278 
00279         while (len--)
00280                 *ptr++ = 0;
00281 }

static int dazuko_change_slot_state struct slot s,
int  from_state,
int  to_state,
int  release
[static]
 

Definition at line 361 of file dazuko_xp.c.

References __dazuko_change_slot_state(), call_xp_down(), call_xp_up(), and slot::mutex.

00362 {
00363         /* SMP safe version of __dazuko_change_slot_state().
00364          * This should only be used if we haven't
00365          * already aquired slot.mutex. Use this function
00366          * with CAUTION, since the mutex may or may not
00367          * be released depending on the return value AND
00368          * on the value of the "release" argument. */
00369 
00370         int     success;
00371 
00372         /* if we are interrupted, report the state as unpredicted */
00373 /* DOWN */
00374         if (call_xp_down(&(s->mutex)) != 0)
00375                 return 0;
00376 
00377         success = __dazuko_change_slot_state(s, from_state, to_state);
00378 
00379         /* the mutex is released if the state change was
00380          * unpredicted or if the called wants it released */
00381         if (!success || release)
00382                 call_xp_up(&(s->mutex));
00383 /* UP */
00384         return success;
00385 }

static void dazuko_clear_replybuffer struct dazuko_request request  )  [inline, static]
 

Definition at line 1175 of file dazuko_xp.c.

References dazuko_bzero(), dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, and dazuko_request::reply_buffer_size_used.

01176 {
01177         dazuko_bzero(request->reply_buffer, request->reply_buffer_size);
01178         request->reply_buffer_size_used = 0;
01179 }

static void dazuko_close_replybuffer struct dazuko_request request  )  [inline, static]
 

Definition at line 1181 of file dazuko_xp.c.

References dazuko_request::reply_buffer, and dazuko_request::reply_buffer_size_used.

01182 {
01183         request->reply_buffer[request->reply_buffer_size_used] = 0;
01184         request->reply_buffer_size_used++;
01185 }

int dazuko_exit void   )  [inline]
 

Definition at line 2838 of file dazuko_xp.c.

References call_xp_atomic_read(), call_xp_destroy_mutex(), call_xp_destroy_queue(), call_xp_destroy_rwlock(), call_xp_free(), call_xp_print, call_xp_sys_unhook, dazuko_remove_all_hash(), dazuko_remove_all_paths(), dazuko_remove_all_trusted(), slot_list_container::mutex, NULL, NUM_SLOTS, slot_list::reg_name, slot_list_container::slot_list, VERSION, and VERSION_STRING.

02839 {
02840         int     error;
02841         int     i;
02842         int     j;
02843 
02844         i = call_xp_atomic_read(&active);
02845 
02846         if (i != 0)
02847         {
02848                 call_xp_print("dazuko: warning: trying to remove Dazuko with %d process%s still registered\n", i, i==1 ? "" : "es");
02849                 return -1;
02850         }
02851 
02852         dazuko_remove_all_paths();
02853         dazuko_remove_all_hash();
02854 
02855         error = call_xp_sys_unhook();
02856 
02857         if (error == 0)
02858         {
02859                 call_xp_destroy_mutex(&mutex_unique_count);
02860 
02861                 call_xp_destroy_rwlock(&lock_hash);
02862                 call_xp_destroy_rwlock(&lock_lists);
02863 
02864                 call_xp_destroy_queue(&wait_kernel_waiting_for_free_slot);
02865                 call_xp_destroy_queue(&wait_daemon_waiting_for_work);
02866                 call_xp_destroy_queue(&wait_kernel_waiting_while_daemon_works);
02867                 call_xp_destroy_queue(&wait_daemon_waiting_for_free);
02868 
02869                 for (i=0 ; i<NUM_SLOT_LISTS ; i++)
02870                 {
02871                         if (slot_lists[i].slot_list != NULL)
02872                         {
02873                                 if (call_xp_atomic_read(&(slot_lists[i].slot_list->use_count)) != 0)
02874                                         call_xp_print("dazuko: slot_list count was not 0 (possible bug)\n");
02875 
02876                                 for (j=0 ; j<NUM_SLOTS ; j++)
02877                                 {
02878                                         call_xp_destroy_mutex(&(slot_lists[i].slot_list->slots[j].mutex));
02879                                 }
02880 
02881                                 call_xp_free(slot_lists[i].slot_list);
02882                                 slot_lists[i].slot_list = NULL;
02883                         }
02884 
02885                         call_xp_destroy_mutex(&(slot_lists[i].mutex));
02886                 }
02887 
02888                 call_xp_print("dazuko: unloaded, version=%s\n", VERSION);
02889         }
02890 
02891         return error;
02892 }

static struct slot* dazuko_find_slot struct daemon_id did,
int  release,
struct slot_list slist
[inline, static]
 

Definition at line 498 of file dazuko_xp.c.

References dazuko_find_slot_and_slotlist(), and NULL.

00499 {
00500         return dazuko_find_slot_and_slotlist(did, release, slist, NULL);
00501 }

static struct slot* dazuko_find_slot_and_slotlist struct daemon_id did,
int  release,
struct slot_list slist,
struct slot_list **  sl_result
[static]
 

Definition at line 455 of file dazuko_xp.c.

References _dazuko_find_slot(), call_xp_down(), call_xp_up(), NULL, and slot_list_container::slot_list.

00456 {
00457         struct slot             *s;
00458         int             i;
00459         struct slot_list        *sl;
00460 
00461         if (slist == NULL)
00462         {
00463                 for (i=0 ; i<NUM_SLOT_LISTS ; i++)
00464                 {
00465 /* DOWN */
00466                         /* if we are interrupted, we say that no
00467                         * slot was found */
00468                         if (call_xp_down(&(slot_lists[i].mutex)) != 0)
00469                                 return NULL;
00470 
00471                         sl = slot_lists[i].slot_list;
00472 
00473                         call_xp_up(&(slot_lists[i].mutex));
00474 /* UP */
00475 
00476                         if (sl != NULL)
00477                         {
00478                                 s = _dazuko_find_slot(did, release, sl);
00479                                 if (s != NULL)
00480                                 {
00481                                         /* set the current slot_list */
00482                                         if (sl_result != NULL)
00483                                                 *sl_result = sl;
00484 
00485                                         return s;
00486                                 }
00487                         }
00488                 }
00489         }
00490         else
00491         {
00492                 return _dazuko_find_slot(did, release, slist);
00493         }
00494 
00495         return NULL;
00496 }

static struct slot* dazuko_get_an_access struct daemon_id did  )  [static]
 

Definition at line 894 of file dazuko_xp.c.

References call_xp_notify(), call_xp_print, call_xp_wait_until_condition(), DAZUKO_BROKEN, dazuko_change_slot_state(), dazuko_find_slot(), DAZUKO_READY, dazuko_register_daemon(), DAZUKO_WAITING, DAZUKO_WORKING, DPRINT, NULL, one_slot_state_not_condition(), one_slot_state_not_condition_param::slot, one_slot_state_not_condition_param::state, and daemon_id::unique.

00895 {
00896         /* The daemon is requesting a filename of a file
00897          * to scan. This code will wait until a filename
00898          * is available, or until we should be killed.
00899          * (killing is done if any errors occur as well
00900          * as when the user kills us) */
00901 
00902         /* If a slot is returned, it will be already locked! */
00903 
00904         int                                     i;
00905         struct slot                                     *s;
00906         struct one_slot_state_not_condition_param       cond_p;
00907 
00908 tryagain:
00909         /* find our slot */
00910         s = dazuko_find_slot(did, 1, NULL);
00911 
00912         if (s == NULL)
00913         {
00914                 i = dazuko_register_daemon(did, "_COMPAT", 7, 1);
00915                 if (i != 0)
00916                 {
00917                         call_xp_print("dazuko: unregistered daemon %d attempted to get access\n", did->unique);
00918                         return NULL;
00919                 }
00920 
00921                 s = dazuko_find_slot(did, 1, NULL);
00922                 if (s == NULL)
00923                 {
00924                         call_xp_print("dazuko: unregistered daemon %d attempted to get access\n", did->unique);
00925                         return NULL;
00926                 }
00927 
00928                 call_xp_print("dazuko: warning: daemon %d is using a deprecated protocol\n", did->unique);
00929         }
00930 
00931         /* the daemon is now ready to receive a file */
00932         dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_READY, 1);
00933 
00934         cond_p.slot = s;
00935         cond_p.state = DAZUKO_READY;
00936         if (call_xp_wait_until_condition(&wait_daemon_waiting_for_work, one_slot_state_not_condition, &cond_p, 1) != 0)
00937         {
00938                 /* The user has issued an interrupt.
00939                  * Return an error. The daemon should
00940                  * unregister itself. */
00941 
00942                 DPRINT(("dazuko: daemon %d killed while waiting for work\n", did->unique));
00943 
00944                 if (dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_BROKEN, 1) || dazuko_change_slot_state(s, DAZUKO_WAITING, DAZUKO_BROKEN, 1))
00945                 {
00946                         call_xp_notify(&wait_kernel_waiting_for_free_slot);
00947                         call_xp_notify(&wait_kernel_waiting_while_daemon_works);
00948                 }
00949 
00950                 return NULL;
00951         }
00952 
00953         /* slot SHOULD now be in DAZUKO_WAITING state */
00954 
00955         /* we will be working with the slot, so
00956          * we need to lock it */
00957 
00958 /* DOWN? */
00959         if (!dazuko_change_slot_state(s, DAZUKO_WAITING, DAZUKO_WORKING, 0))
00960         {
00961                 /* State transition error. Try again., */
00962 
00963                 goto tryagain;
00964         }
00965 
00966 /* DOWN */
00967 
00968         /* Slot IS in DAZUKO_WORKING state. Copy all the
00969          * necessary information to userspace structure. */
00970 
00971         /* IMPORTANT: slot is still locked! */
00972 
00973         return s;  /* access is available */
00974 }

static struct slot* dazuko_get_and_hold_ready_slot struct slot_list sl  )  [static]
 

Definition at line 1991 of file dazuko_xp.c.

References dazuko_change_slot_state(), DAZUKO_READY, DAZUKO_WAITING, NULL, NUM_SLOTS, and slot_list::slots.

01992 {
01993         /* This is a simple search to find a
01994          * slot whose state is DAZUKO_READY. This means
01995          * it is able to accept work. If a slot
01996          * is found, the slot.mutex is held so
01997          * it can be filled with work by the caller.
01998          * It is the responsibility of the caller
01999          * to RELEASE THE MUTEX. */
02000 
02001         int             i;
02002         struct slot     *s;
02003 
02004         for (i=0 ; i<NUM_SLOTS ; i++)
02005         {
02006                 s = &(sl->slots[i]);
02007 /* DOWN? */
02008                 if (dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_WAITING, 0))
02009                 {
02010 /* DOWN */
02011                         return s;
02012                 }
02013         }
02014 
02015         /* we didn't find a slot that is ready for work */
02016 
02017         return NULL;
02018 }

int dazuko_get_filename_length char *  filename  )  [inline]
 

Definition at line 2499 of file dazuko_xp.c.

02500 {
02501         int len;
02502 
02503         for (len=0 ; filename[len] ; len++);
02504 
02505         return len;
02506 }

static struct hash* dazuko_get_hash struct xp_file file  )  [static]
 

Definition at line 2461 of file dazuko_xp.c.

References call_xp_compare_file(), call_xp_write_lock(), call_xp_write_unlock(), hash::file, hash::next, and NULL.

Referenced by dazuko_sys_post().

02462 {
02463         /* Find the given file within our list
02464          * and then remove it from the list and
02465          * return it. */
02466 
02467         struct hash     *prev;
02468         struct hash     *cur;
02469 
02470 /* LOCK */
02471         call_xp_write_lock(&lock_hash);
02472 
02473         prev = NULL;
02474         cur = hash;
02475         while (cur)
02476         {
02477                 if (call_xp_compare_file(&(cur->file), file) == 0)
02478                 {
02479                         /* we found the entry */
02480 
02481                         /* remove the item from the list */
02482                         if (!prev)
02483                                 hash = cur->next;
02484                         else
02485                                 prev->next = cur->next;
02486                         break;
02487                 }
02488 
02489                 prev = cur;
02490                 cur = cur->next;
02491         }
02492 
02493         call_xp_write_unlock(&lock_hash);
02494 /* UNLOCK */
02495 
02496         return cur;
02497 }

static int dazuko_get_new_unique void   )  [inline, static]
 

Definition at line 283 of file dazuko_xp.c.

References call_xp_down(), call_xp_up(), and unique_count.

00284 {
00285         int     unique;
00286 
00287 /* DOWN */
00288         call_xp_down(&mutex_unique_count);
00289 
00290         unique = unique_count;
00291         unique_count++;
00292 
00293         call_xp_up(&mutex_unique_count);
00294 /* UP */
00295 
00296         return unique;
00297 }

int dazuko_get_value const char *  key,
const char *  string,
char **  value
 

Definition at line 1141 of file dazuko_xp.c.

References call_xp_malloc(), dazuko_strlen(), dazuko_strstr(), and NULL.

01142 {
01143         const char      *p1;
01144         const char      *p2;
01145         int             size;
01146 
01147         if (value == NULL)
01148                 return -1;
01149 
01150         *value = NULL;
01151 
01152         if (key == NULL || string == NULL)
01153                 return -1;
01154 
01155         p1 = dazuko_strstr(string, key);
01156         if (p1 == NULL)
01157                 return -1;
01158 
01159         p1 += dazuko_strlen(key);
01160 
01161         for (p2=p1 ; *p2 && *p2!='\n' ; p2++)
01162                 continue;
01163 
01164         size = (p2 - p1) + 1;
01165         *value = call_xp_malloc(size);
01166         if (*value == NULL)
01167                 return -1;
01168 
01169         memcpy(*value, p1, size - 1);
01170         (*value)[size - 1] = 0;
01171 
01172         return 0;
01173 }

static int dazuko_handle_request struct dazuko_request request,
struct xp_daemon_id xp_id
[static]
 

Definition at line 1368 of file dazuko_xp.c.

References access_mask, ADD_EXCLUDE_PATH, ADD_INCLUDE_PATH, dazuko_request::buffer, dazuko_request::buffer_size, call_xp_free(), call_xp_id_copy(), call_xp_id_free(), call_xp_print, call_xp_up(), dazuko_add_esc_to_replybuffer(), dazuko_add_keyvalue_to_replybuffer(), dazuko_clear_replybuffer(), dazuko_close_replybuffer(), dazuko_get_an_access(), dazuko_get_value(), dazuko_register_daemon(), dazuko_return_access(), dazuko_set_option(), dazuko_strchr(), dazuko_strlen(), dazuko_strtol(), file_properties::device_type, slot::event, slot::event_p, slot::file_p, slot::filename, event_properties::flags, GET_AN_ACCESS, file_properties::gid, file_properties::mode, event_properties::mode, slot::mutex, NULL, event_properties::pid, REGISTER, REMOVE_ALL_PATHS, dazuko_request::reply_buffer_size, RETURN_AN_ACCESS, SET_ACCESS_MASK, file_properties::set_device_type, event_properties::set_flags, file_properties::set_gid, file_properties::set_mode, event_properties::set_mode, event_properties::set_pid, file_properties::set_size, file_properties::set_uid, event_properties::set_uid, file_properties::size, dazuko_request::type, file_properties::uid, event_properties::uid, daemon_id::unique, UNREGISTER, slot::write_mode, XP_ERROR_INTERRUPT, and daemon_id::xp_id.

01369 {
01370         char                    *value1;
01371         char                    *value2;
01372         int                     error = 0;
01373         int                     type;
01374         struct slot             *s;
01375         struct daemon_id        did;
01376 
01377         if (request == NULL || xp_id == NULL)
01378                 return -1;
01379 
01380         type = request->type[0] + (256 * request->type[1]);
01381 
01382         switch (type)
01383         {
01384                 case REGISTER:
01385                         /* read "\nRM=regmode\nGN=group" */
01386                         /* send "\nID=id" */
01387 
01388                         if (request->buffer_size <= 0)
01389                                 return -1;
01390 
01391                         if (request->reply_buffer_size <= 0)
01392                                 return -1;
01393 
01394                         if (dazuko_get_value("\nGN=", request->buffer, &value1) != 0)
01395                                 return -1;
01396 
01397                         if (dazuko_get_value("\nRM=", request->buffer, &value2) != 0)
01398                         {
01399                                 call_xp_free(value1);
01400                                 return -1;
01401                         }
01402 
01403                         did.xp_id = call_xp_id_copy(xp_id);
01404                         did.unique = 0; /* a unique is not yet assigned */
01405 
01406                         error = dazuko_register_daemon(&did, value1, dazuko_strlen(value1), dazuko_strchr(value2, 'W') != NULL);
01407 
01408                         dazuko_clear_replybuffer(request);
01409                         dazuko_add_keyvalue_to_replybuffer(request, "\nID=", &(did.unique), 'd');
01410                         dazuko_close_replybuffer(request);
01411 
01412                         call_xp_free(value1);
01413                         call_xp_free(value2);
01414                         call_xp_id_free(did.xp_id);
01415 
01416                         break;
01417 
01418                 case UNREGISTER:
01419                         /* read "\nID=id" */
01420 
01421                         if (request->buffer_size <= 0)
01422                                 return -1;
01423 
01424                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01425                                 return -1;
01426 
01427                         did.xp_id = call_xp_id_copy(xp_id);
01428                         did.unique = dazuko_strtol(value1);
01429 
01430                         error = dazuko_set_option(&did, UNREGISTER, NULL, 0);
01431 
01432                         call_xp_free(value1);
01433                         call_xp_id_free(did.xp_id);
01434 
01435                         break;
01436 
01437                 case SET_ACCESS_MASK:
01438                         /* read "\nID=id\nAM=mask" */
01439 
01440                         if (request->buffer_size <= 0)
01441                                 return -1;
01442 
01443                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01444                                 return -1;
01445 
01446                         if (dazuko_get_value("\nAM=", request->buffer, &value2) != 0)
01447                         {
01448                                 call_xp_free(value1);
01449                                 return -1;
01450                         }
01451 
01452                         access_mask = (char)dazuko_strtol(value2);
01453 
01454                         call_xp_free(value1);
01455                         call_xp_free(value2);
01456 
01457                         break;
01458 
01459                 case ADD_INCLUDE_PATH:
01460                         /* read "\nID=id\nPT=path" */
01461 
01462                         if (request->buffer_size <= 0)
01463                                 return -1;
01464 
01465                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01466                                 return -1;
01467 
01468                         if (dazuko_get_value("\nPT=", request->buffer, &value2) != 0)
01469                         {
01470                                 call_xp_free(value1);
01471                                 return -1;
01472                         }
01473 
01474                         did.xp_id = call_xp_id_copy(xp_id);
01475                         did.unique = dazuko_strtol(value1);
01476 
01477                         error = dazuko_set_option(&did, ADD_INCLUDE_PATH, value2, dazuko_strlen(value2));
01478 
01479                         call_xp_free(value1);
01480                         call_xp_free(value2);
01481                         call_xp_id_free(did.xp_id);
01482 
01483                         break;
01484 
01485                 case ADD_EXCLUDE_PATH:
01486                         /* read "\nID=id\nPT=path" */
01487 
01488                         if (request->buffer_size <= 0)
01489                                 return -1;
01490 
01491                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01492                                 return -1;
01493 
01494                         if (dazuko_get_value("\nPT=", request->buffer, &value2) != 0)
01495                         {
01496                                 call_xp_free(value1);
01497                                 return -1;
01498                         }
01499 
01500                         did.xp_id = call_xp_id_copy(xp_id);
01501                         did.unique = dazuko_strtol(value1);
01502 
01503                         error = dazuko_set_option(&did, ADD_EXCLUDE_PATH, value2, dazuko_strlen(value2));
01504 
01505                         call_xp_free(value1);
01506                         call_xp_free(value2);
01507                         call_xp_id_free(did.xp_id);
01508 
01509                         break;
01510 
01511                 case REMOVE_ALL_PATHS:
01512                         /* read "\nID=id" */
01513 
01514                         if (request->buffer_size <= 0)
01515                                 return -1;
01516 
01517                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01518                                 return -1;
01519 
01520                         did.xp_id = call_xp_id_copy(xp_id);
01521                         did.unique = dazuko_strtol(value1);
01522 
01523                         error = dazuko_set_option(&did, REMOVE_ALL_PATHS, NULL, 0);
01524 
01525                         call_xp_free(value1);
01526                         call_xp_id_free(did.xp_id);
01527 
01528                         break;
01529 
01530                 case GET_AN_ACCESS:
01531                         /* read "\nID=id" */
01532                         /* send "\nFN=file\nFL=flags\nMD=mode\nUI=uid\nPI=pid" */
01533 
01534                         if (request->buffer_size <= 0)
01535                                 return -1;
01536 
01537                         if (request->reply_buffer_size <= 0)
01538                                 return -1;
01539 
01540                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01541                                 return -1;
01542 
01543                         did.xp_id = call_xp_id_copy(xp_id);
01544                         did.unique = dazuko_strtol(value1);
01545 
01546                         call_xp_free(value1);
01547 
01548 /* DOWN? */
01549                         s = dazuko_get_an_access(&did);
01550 
01551                         if (s == NULL)
01552                         {
01553                                 call_xp_id_free(did.xp_id);
01554                                 return XP_ERROR_INTERRUPT;
01555                         }
01556 /* DOWN */
01557 
01558                         /* Slot IS in DAZUKO_WORKING state. Copy all the
01559                          * necessary information to userspace structure. */
01560 
01561                         dazuko_clear_replybuffer(request);
01562                         dazuko_add_keyvalue_to_replybuffer(request, "\nEV=", &(s->event), 'd');
01563                         dazuko_add_esc_to_replybuffer(request, "\nFN=", &(s->filename));
01564 
01565                         if (s->event_p.set_uid)
01566                                 dazuko_add_keyvalue_to_replybuffer(request, "\nUI=", &(s->event_p.uid), 'd');
01567 
01568                         if (s->event_p.set_pid)
01569                                 dazuko_add_keyvalue_to_replybuffer(request, "\nPI=", &(s->event_p.pid), 'd');
01570 
01571                         if (s->event_p.set_flags)
01572                                 dazuko_add_keyvalue_to_replybuffer(request, "\nFL=", &(s->event_p.flags), 'd');
01573 
01574                         if (s->event_p.set_mode)
01575                                 dazuko_add_keyvalue_to_replybuffer(request, "\nMD=", &(s->event_p.mode), 'd');
01576 
01577                         if (s->file_p.set_size)
01578                                 dazuko_add_keyvalue_to_replybuffer(request, "\nFS=", &(s->file_p.size), 'l');
01579 
01580                         if (s->file_p.set_uid)
01581                                 dazuko_add_keyvalue_to_replybuffer(request, "\nFU=", &(s->file_p.uid), 'd');
01582 
01583                         if (s->file_p.set_gid)
01584                                 dazuko_add_keyvalue_to_replybuffer(request, "\nFG=", &(s->file_p.gid), 'd');
01585 
01586                         if (s->file_p.set_mode)
01587                                 dazuko_add_keyvalue_to_replybuffer(request, "\nFM=", &(s->file_p.mode), 'd');
01588 
01589                         if (s->file_p.set_device_type)
01590                                 dazuko_add_keyvalue_to_replybuffer(request, "\nDT=", &(s->file_p.device_type), 'd');
01591 
01592                         dazuko_close_replybuffer(request);
01593 
01594 /* XXX: What do we do if there is a problem copying back to userspace?! */
01595 /* dazuko_state_error(s, DAZUKO_WORKING); */
01596 
01597                         /* are we in read_only mode? */
01598                         if (!(s->write_mode))
01599                         {
01600                                 /* the access is immediately (and at the kernel level)
01601                                  * returned */
01602 
01603                                 call_xp_up(&(s->mutex));
01604 /* UP */
01605 
01606                                 dazuko_return_access(&did, 0, s);
01607                         }
01608                         else
01609                         {
01610                                 call_xp_up(&(s->mutex));
01611 /* UP */
01612                         }
01613 
01614                         call_xp_id_free(did.xp_id);
01615 
01616                         break;
01617 
01618                 case RETURN_AN_ACCESS:
01619                         /* read "\nID=id\nDN=deny" */
01620 
01621                         if (request->buffer_size <= 0)
01622                                 return -1;
01623 
01624                         if (dazuko_get_value("\nID=", request->buffer, &value1) != 0)
01625                                 return -1;
01626 
01627                         if (dazuko_get_value("\nDN=", request->buffer, &value2) != 0)
01628                         {
01629                                 call_xp_free(value1);
01630                                 return -1;
01631                         }
01632 
01633                         did.xp_id = call_xp_id_copy(xp_id);
01634                         did.unique = dazuko_strtol(value1);
01635 
01636                         error = dazuko_return_access(&did, dazuko_strtol(value2), NULL);
01637 
01638                         call_xp_free(value1);
01639                         call_xp_free(value2);
01640                         call_xp_id_free(did.xp_id);
01641 
01642                         break;
01643 
01644                 default:
01645                         call_xp_print("dazuko: daemon made unknown request %d (possible bug)\n", type);
01646 
01647                         break;
01648         }
01649 
01650         return error;
01651 }

int dazuko_handle_user_request struct dazuko_request user_request,
struct xp_daemon_id xp_id
 

Definition at line 1653 of file dazuko_xp.c.

References dazuko_request::buffer, dazuko_request::buffer_size, call_xp_copyin(), call_xp_copyout(), call_xp_free(), call_xp_malloc(), dazuko_handle_request(), NULL, dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, dazuko_request::reply_buffer_size_used, dazuko_request::type, XP_ERROR_FAULT, and XP_ERROR_PERMISSION.

01654 {
01655         int                     error = 0;
01656         struct dazuko_request   *request;
01657         struct dazuko_request   *temp_request;
01658 
01659         if (user_request == NULL || xp_id == NULL)
01660                 return XP_ERROR_FAULT;
01661 
01662         /* allocate kernel request */
01663         request = (struct dazuko_request *)call_xp_malloc(sizeof(struct dazuko_request));
01664         if (request == NULL)
01665                 return XP_ERROR_FAULT;
01666 
01667 /* use out0 now */
01668 
01669         /* allocate temp kernel request */
01670         temp_request = (struct dazuko_request *)call_xp_malloc(sizeof(struct dazuko_request));
01671         if (temp_request == NULL)
01672         {
01673                 error = XP_ERROR_FAULT;
01674                 goto dazuko_handle_user_request_out0;
01675         }
01676 
01677 /* use out1 now */
01678 
01679         /* copy in the request */
01680         if (call_xp_copyin(user_request, temp_request, sizeof(struct dazuko_request)) != 0)
01681         {
01682                 error = XP_ERROR_FAULT;
01683                 goto dazuko_handle_user_request_out1;
01684         }
01685 
01686         memcpy(request->type, temp_request->type, sizeof(char[2]));
01687         request->buffer_size = temp_request->buffer_size;
01688 
01689         /* sanity check */
01690         if (request->buffer_size < 0 || request->buffer_size > 8192)
01691         {
01692                 error = XP_ERROR_FAULT;
01693                 goto dazuko_handle_user_request_out1;
01694         }
01695 
01696         request->reply_buffer_size = temp_request->reply_buffer_size;
01697 
01698         /* sanity check */
01699         if (request->reply_buffer_size < 0 || request->reply_buffer_size > 8192)
01700         {
01701                 error = XP_ERROR_PERMISSION;
01702                 goto dazuko_handle_user_request_out1;
01703         }
01704 
01705         /* allocate buffer */
01706         request->buffer = (char *)call_xp_malloc(request->buffer_size + 1);
01707         if (request->buffer == NULL)
01708         {
01709                 error = XP_ERROR_FAULT;
01710                 goto dazuko_handle_user_request_out1;
01711         }
01712 
01713 /* use out2 now */
01714 
01715         if (request->reply_buffer_size > 0)
01716         {
01717                 /* allocate reply buffer */
01718                 request->reply_buffer = (char *)call_xp_malloc(request->reply_buffer_size + 1);
01719                 if (request->reply_buffer == NULL)
01720                 {
01721                         error = XP_ERROR_FAULT;
01722                         goto dazuko_handle_user_request_out2;
01723                 }
01724 
01725 /* use out3 now */
01726 
01727                 request->reply_buffer_size_used = 0;
01728         }
01729 
01730         /* copy the buffer from userspace to kernelspace */
01731         if (call_xp_copyin(temp_request->buffer, request->buffer, request->buffer_size) != 0)
01732         {
01733                 error = XP_ERROR_FAULT;
01734                 goto dazuko_handle_user_request_out3;
01735         }
01736 
01737         request->buffer[request->buffer_size] = 0;
01738 
01739         error = dazuko_handle_request(request, xp_id);
01740 
01741         if (error == 0 && request->reply_buffer_size > 0)
01742         {
01743                 request->reply_buffer[request->reply_buffer_size] = 0;
01744 
01745                 temp_request->reply_buffer_size_used = request->reply_buffer_size_used;
01746 
01747                 if (call_xp_copyout(temp_request, user_request, sizeof(struct dazuko_request)) != 0)
01748                 {
01749                         error = XP_ERROR_FAULT;
01750                         goto dazuko_handle_user_request_out3;
01751                 }
01752 
01753                 if (request->reply_buffer_size_used > 0)
01754                 {
01755                         if (call_xp_copyout(request->reply_buffer, temp_request->reply_buffer, request->reply_buffer_size_used) != 0)
01756                         {
01757                                 error = XP_ERROR_FAULT;
01758                                 goto dazuko_handle_user_request_out3;
01759                         }
01760                 }
01761         }
01762 
01763 dazuko_handle_user_request_out3:
01764         if (request->reply_buffer_size > 0)
01765                 call_xp_free(request->reply_buffer);
01766 dazuko_handle_user_request_out2:
01767         call_xp_free(request->buffer);
01768 dazuko_handle_user_request_out1:
01769         call_xp_free(temp_request);
01770 dazuko_handle_user_request_out0:
01771         call_xp_free(request);
01772 
01773         return error;
01774 }

int dazuko_handle_user_request_compat12 void *  ptr,
int  cmd,
struct xp_daemon_id xp_id
 

Definition at line 1776 of file dazuko_xp.c.

References call_xp_copyin(), call_xp_copyout(), call_xp_free(), call_xp_id_copy(), call_xp_id_free(), call_xp_malloc(), call_xp_print, call_xp_up(), call_xp_verify_user_readable(), call_xp_verify_user_writable(), DAZUKO_FILENAME_MAX_LENGTH_COMPAT12, dazuko_get_an_access(), dazuko_register_daemon(), dazuko_return_access(), dazuko_set_option(), dazuko_state_error(), DAZUKO_WORKING, access_compat12::deny, access_compat12::event, slot::event, slot::event_p, slot::filename, access_compat12::filename, slot::filenamelength, event_properties::flags, IOCTL_GET_AN_ACCESS, IOCTL_RETURN_ACCESS, IOCTL_SET_OPTION, event_properties::mode, slot::mutex, NULL, access_compat12::o_flags, access_compat12::o_mode, access_compat12::pid, event_properties::pid, REGISTER, access_compat12::uid, event_properties::uid, daemon_id::unique, XP_ERROR_FAULT, XP_ERROR_INTERRUPT, XP_ERROR_INVALID, and daemon_id::xp_id.

Referenced by linux_dazuko_device_ioctl().

01777 {
01778         struct access_compat12  *user_request12;
01779         struct access_compat12  *temp_request12;
01780         int                     error = 0;
01781         struct slot             *s;
01782         char                    *k_param;
01783         struct daemon_id        did;
01784         int                     temp_length;
01785         int                     temp_int;
01786 
01787         if (ptr == NULL || xp_id == NULL)
01788                 return XP_ERROR_FAULT;
01789 
01790         did.xp_id = call_xp_id_copy(xp_id);
01791         did.unique = -1;
01792 
01793         switch (cmd)
01794         {
01795                 case IOCTL_GET_AN_ACCESS:
01796                         /* The daemon is requesting a filename of a file
01797                          * to scan. This code will wait until a filename
01798                          * is available, or until we should be killed.
01799                          * (killing is done if any errors occur as well
01800                          * as when the user kills us) */
01801 
01802                         user_request12 = (struct access_compat12 *)ptr;
01803 
01804                         error = call_xp_verify_user_writable(user_request12, sizeof(struct access_compat12));
01805                         if (error)
01806                         {
01807                                 error = XP_ERROR_FAULT;
01808                                 break;
01809                         }
01810 
01811 /* DOWN? */
01812                         s = dazuko_get_an_access(&did);
01813 
01814                         if (s == NULL)
01815                         {
01816                                 error = XP_ERROR_INTERRUPT;
01817                                 break;
01818                         }
01819 
01820 /* DOWN */
01821 
01822                         /* Slot IS in WORKING state. Copy all the
01823                          * necessary information to userspace structure. */
01824 
01825                         if (s->filenamelength >= DAZUKO_FILENAME_MAX_LENGTH_COMPAT12)
01826                         {
01827                                 /* filename length overflow :( */
01828 
01829                                 s->filename[DAZUKO_FILENAME_MAX_LENGTH_COMPAT12 - 1] = 0;
01830                                 temp_length = DAZUKO_FILENAME_MAX_LENGTH_COMPAT12;
01831                         }
01832                         else
01833                         {
01834                                 temp_length = s->filenamelength + 1;
01835                         }
01836 
01837                         temp_request12 = (struct access_compat12 *)call_xp_malloc(sizeof(struct access_compat12));
01838                         if (temp_request12 == NULL)
01839                         {
01840                                 error = XP_ERROR_FAULT;
01841                         }
01842                         else if (call_xp_copyin(user_request12, temp_request12, sizeof(struct access_compat12)) != 0)
01843                         {
01844                                 error = XP_ERROR_FAULT;
01845                         }
01846 
01847                         if (error == 0)
01848                         {
01849                                 temp_request12->event = s->event;
01850                                 temp_request12->o_flags = s->event_p.flags;
01851                                 temp_request12->o_mode = s->event_p.mode;
01852                                 temp_request12->uid = s->event_p.uid;
01853                                 temp_request12->pid = s->event_p.pid;
01854                                 memcpy(temp_request12->filename, s->filename, temp_length);
01855 
01856                                 if (call_xp_copyout(temp_request12, user_request12, sizeof(struct access_compat12)) != 0)
01857                                 {
01858                                         error = XP_ERROR_FAULT;
01859                                 }
01860                         }
01861 
01862                         call_xp_up(&(s->mutex));
01863 /* UP */
01864 
01865                         if (error)
01866                         {
01867                                 dazuko_state_error(s, DAZUKO_WORKING);
01868                         }
01869 
01870                         if (temp_request12 != NULL)
01871                         {
01872                                 call_xp_free(temp_request12);
01873                         }
01874 
01875                         break;
01876 
01877                 case IOCTL_RETURN_ACCESS:
01878                         /* The daemon has finished scanning a file
01879                          * and has the response to give. The daemon's
01880                          * slot should be in the WORKING state. */
01881 
01882                         user_request12 = (struct access_compat12 *)ptr;
01883 
01884                         error = call_xp_verify_user_readable(user_request12, sizeof(struct access_compat12));
01885                         if (error)
01886                         {
01887                                 error = XP_ERROR_FAULT;
01888                                 break;
01889                         }
01890 
01891                         temp_request12 = (struct access_compat12 *)call_xp_malloc(sizeof(struct access_compat12));
01892                         if (temp_request12 == NULL)
01893                         {
01894                                 error = XP_ERROR_FAULT;
01895                                 break;
01896                         }
01897 
01898                         if (call_xp_copyin(user_request12, temp_request12, sizeof(struct access_compat12)) != 0)
01899                         {
01900                                 error = XP_ERROR_FAULT;
01901                         }
01902 
01903                         temp_int = temp_request12->deny;
01904 
01905                         call_xp_free(temp_request12);
01906 
01907                         error = dazuko_return_access(&did, temp_int, NULL);
01908                         break;
01909 
01910                 case IOCTL_SET_OPTION:
01911                         /* The daemon wants to set a configuration
01912                          * option in the kernel. */
01913 
01914                         error = call_xp_verify_user_readable(ptr, 2*sizeof(int));
01915                         if (error)
01916                         {
01917                                 error = XP_ERROR_FAULT;
01918                                 break;
01919                         }
01920 
01921                         /* copy option type from userspace */
01922                         if (call_xp_copyin(ptr, &temp_int, sizeof(int)) != 0)
01923                         {
01924                                 error = XP_ERROR_FAULT;
01925                                 break;
01926                         }
01927 
01928                         ptr = ((char *)ptr + sizeof(int));
01929 
01930                         /* copy path length from userspace */
01931                         if (call_xp_copyin(ptr, &temp_length, sizeof(int)) != 0)
01932                         {
01933                                 error = XP_ERROR_FAULT;
01934                                 break;
01935                         }
01936 
01937                         /* sanity check */
01938                         if (temp_length < 0 || temp_length > 4096)
01939                         {
01940                                 error = XP_ERROR_INVALID;
01941                                 break;
01942                         }
01943 
01944                         ptr = ((char *)ptr + sizeof(int));
01945 
01946                         error = call_xp_verify_user_readable(ptr, temp_length);
01947                         if (error)
01948                         {
01949                                 error = XP_ERROR_FAULT;
01950                                 break;
01951                         }
01952 
01953                         k_param = (char *)call_xp_malloc(temp_length + 1);
01954                         if (k_param == NULL)
01955                         {
01956                                 error = XP_ERROR_FAULT;
01957                                 break;
01958                         }
01959 
01960                         /* We must copy the param from userspace to kernelspace. */
01961 
01962                         if (call_xp_copyin(ptr, k_param, temp_length) != 0)
01963                         {
01964                                 call_xp_free(k_param);
01965                                 error = XP_ERROR_FAULT;
01966                                 break;
01967                         }
01968 
01969                         k_param[temp_length] = 0;
01970 
01971                         if (temp_int == REGISTER)
01972                                 error = dazuko_register_daemon(&did, k_param, temp_length, 1);
01973                         else
01974                                 error = dazuko_set_option(&did, temp_int, k_param, temp_length);
01975 
01976                         call_xp_free(k_param);
01977 
01978                         break;
01979 
01980                 default:
01981                         call_xp_print("dazuko: daemon requested unknown device_ioctl %d (possible bug)\n", cmd);
01982 
01983                         break;
01984         }
01985 
01986         call_xp_id_free(did.xp_id);
01987 
01988         return error;
01989 }

int dazuko_init void   )  [inline]
 

Definition at line 2808 of file dazuko_xp.c.

References access_mask_cache, AMC_UNSET, call_xp_atomic_set(), call_xp_init_mutex(), call_xp_init_queue(), call_xp_init_rwlock(), call_xp_print, call_xp_sys_hook, dazuko_bzero(), VERSION, and VERSION_STRING.

02809 {
02810         int     i;
02811         int     error;
02812 
02813         call_xp_init_mutex(&mutex_unique_count);
02814 
02815         call_xp_init_rwlock(&lock_hash);
02816         call_xp_init_rwlock(&lock_lists);
02817 
02818         call_xp_init_queue(&wait_kernel_waiting_for_free_slot);
02819         call_xp_init_queue(&wait_daemon_waiting_for_work);
02820         call_xp_init_queue(&wait_kernel_waiting_while_daemon_works);
02821         call_xp_init_queue(&wait_daemon_waiting_for_free);
02822 
02823         dazuko_bzero(&slot_lists, sizeof(slot_lists));
02824 
02825         for (i=0 ; i<NUM_SLOT_LISTS ; i++)
02826                 call_xp_init_mutex(&(slot_lists[i].mutex));
02827 
02828         call_xp_atomic_set(&active, 0);
02829 
02830         error = call_xp_sys_hook();
02831 
02832         if (error == 0)
02833                 call_xp_print("dazuko: loaded, version=%s\n", VERSION);
02834 
02835         return error;
02836 }

static int dazuko_insert_path_fs struct path **  list,
char *  fs_path,
int  fs_len
[static]
 

Definition at line 503 of file dazuko_xp.c.

References call_xp_free(), call_xp_is_absolute_path(), call_xp_malloc(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, path::len, path::next, NULL, path::path, XP_ERROR_FAULT, and XP_ERROR_INVALID.

00504 {
00505         /* Create a new struct path structure and insert it
00506          * into the linked list given (list argument).
00507          * The fs_len argument is to help speed things
00508          * up so we don't have to calculate the length
00509          * of fs_path. */
00510 
00511         struct path     *newitem;
00512         struct path     *tmp;
00513 
00514         if (fs_path == NULL || fs_len < 1)
00515                 return XP_ERROR_INVALID;
00516 
00517         /* we want only absolute paths */
00518         if (!call_xp_is_absolute_path(fs_path))
00519                 return XP_ERROR_INVALID;
00520 
00521         /* create a new struct path structure making room for path also */
00522         newitem = (struct path *)call_xp_malloc(sizeof(struct path) + fs_len);
00523         if (newitem == NULL)
00524                 return XP_ERROR_FAULT;
00525 
00526         /* fs_path is already in kernelspace */
00527         memcpy(newitem->path, fs_path, fs_len);
00528 
00529         newitem->path[fs_len] = 0;
00530 
00531         while (newitem->path[fs_len-1] == 0)
00532         {
00533                 fs_len--;
00534                 if (fs_len == 0)
00535                         break;
00536         }
00537 
00538         if (fs_len < 1)
00539         {
00540                 call_xp_free(newitem);
00541                 return XP_ERROR_INVALID;
00542         }
00543 
00544         newitem->len = fs_len;
00545 
00546         /* check if this path already exists in the list */
00547         for (tmp=*list ; tmp ; tmp=tmp->next)
00548         {
00549                 if (newitem->len == tmp->len)
00550                 {
00551                         if (memcmp(newitem->path, tmp->path, tmp->len) == 0)
00552                         {
00553                                 /* we already have this path */
00554 
00555                                 call_xp_free(newitem);
00556 
00557                                 return 0;
00558                         }
00559                 }
00560         }
00561 
00562         DPRINT(("dazuko: adding %s %s\n", (list == &incl_paths) ? "incl" : "excl", newitem->path));
00563 
00564         /* add struct path to head of linked list */
00565 /* LOCK */
00566         call_xp_write_lock(&lock_lists);
00567         newitem->next = *list;
00568         *list = newitem;
00569         call_xp_write_unlock(&lock_lists);
00570 /* UNLOCK */
00571 
00572         return 0;
00573 }

int dazuko_is_our_daemon struct xp_daemon_id xp_id  )  [inline]
 

Definition at line 2218 of file dazuko_xp.c.

References call_xp_id_copy(), call_xp_id_free(), dazuko_find_slot(), NULL, daemon_id::unique, and daemon_id::xp_id.

02219 {
02220         /* Check if the current process is one
02221          * of the daemons. */
02222 
02223         struct daemon_id        did;
02224         int                     ret;
02225 
02226         did.xp_id = call_xp_id_copy(xp_id);
02227         did.unique = -1;
02228 
02229         ret = (dazuko_find_slot(&did, 1, NULL) != NULL);
02230 
02231         call_xp_id_free(did.xp_id);
02232 
02233         return ret;
02234 }

static int dazuko_is_selected struct dazuko_file_struct kfs  )  [static]
 

Definition at line 2236 of file dazuko_xp.c.

References dazuko_file_struct::aliases, call_xp_print, call_xp_read_lock(), call_xp_read_unlock(), dazuko_bzero(), dazuko_file_listnode::filename, dazuko_file_struct::filename, dazuko_file_struct::filename_length, dazuko_file_listnode::filename_length, path::len, path::next, dazuko_file_listnode::next, NULL, path::path, xp_free(), and xp_malloc().

02237 {
02238         /* Check if the given filename (with path) is
02239          * under our include directories but not under
02240          * the exclude directories. */
02241 
02242         struct dazuko_file_listnode     *cur;
02243         struct path                     *path;
02244         int                             selected = 0;
02245         int                             use_aliases = 1;
02246 
02247         if (kfs == NULL)
02248                 return 0;
02249 
02250         /* If we are interrupted here, we will report that
02251          * this file is not selected. This will make the
02252          * kernel allow normal access. Is this dangerous? */
02253 /* LOCK */
02254         call_xp_read_lock(&lock_lists);
02255 
02256         if (kfs->aliases == NULL && kfs->filename != NULL)
02257         {
02258                 /* extension is not using aliases */
02259 
02260                 use_aliases = 0;
02261 
02262                 kfs->aliases = (struct dazuko_file_listnode *)xp_malloc(sizeof(struct dazuko_file_listnode));
02263                 if (kfs->aliases == NULL)
02264                 {
02265                         call_xp_print("dazuko: warning: access not controlled (%s)\n", kfs->filename);
02266                         return 0;
02267                 }
02268 
02269                 dazuko_bzero(kfs->aliases, sizeof(struct dazuko_file_listnode));
02270 
02271                 kfs->aliases->filename = kfs->filename;
02272                 kfs->aliases->filename_length = kfs->filename_length;
02273         }
02274 
02275         for (cur=kfs->aliases ; cur ; cur=cur->next)
02276         {
02277                 if (cur->filename != NULL && cur->filename_length > 0)
02278                 {
02279                         /* check if filename is under our include paths */
02280                         for (path=incl_paths ; path ; path=path->next)
02281                         {
02282                                 /* the include item must be at least as long as the given filename */
02283                                 if (path->len <= cur->filename_length)
02284                                 {
02285                                         /* the include item should match the beginning of the given filename */
02286                                         if (memcmp(path->path, cur->filename, path->len) == 0)
02287                                         {
02288                                                 kfs->filename = cur->filename;
02289                                                 kfs->filename_length = cur->filename_length;
02290 
02291                                                 selected = 1;
02292                                                 break;
02293                                         }
02294                                 }
02295                         }
02296 
02297                         /* If we didn't find a path, it isn't in our
02298                          * include directories. It can't be one of
02299                          * the selected files to scan. */
02300                         if (!selected)
02301                         {
02302                                 continue;
02303                         }
02304 
02305                         /* check if filename is under our exclude paths */
02306                         for (path=excl_paths ; path ; path=path->next)
02307                         {
02308                                 /* the exclude item must be at least as long as the given filename */
02309                                 if (path->len <= cur->filename_length)
02310                                 {
02311                                         /* the exclude item should match the beginning of the given filename */
02312                                         if (memcmp(path->path, cur->filename, path->len) == 0)
02313                                         {
02314                                                 kfs->filename = NULL;
02315                                                 kfs->filename_length = 0;
02316 
02317                                                 selected = 0;
02318                                                 break;
02319                                         }
02320                                 }
02321                         }
02322 
02323                         /* If we are still selected, then we can stop. */
02324                         if (selected)
02325                                 break;
02326                 }
02327         }
02328 
02329         call_xp_read_unlock(&lock_lists);
02330 /* UNLOCK */
02331 
02332         if (!use_aliases)
02333         {
02334                 xp_free(kfs->aliases);
02335                 kfs->aliases = NULL;
02336         }
02337 
02338         return selected;
02339 }

static int dazuko_isdigit const char  c  )  [inline, static]
 

Definition at line 1043 of file dazuko_xp.c.

01044 {
01045         return (c >= '0' && c <= '9');
01046 }

static void dazuko_mark_hash_dirty struct xp_file file  )  [static]
 

Definition at line 2374 of file dazuko_xp.c.

References call_xp_compare_file(), call_xp_write_lock(), call_xp_write_unlock(), hash::dirty, hash::file, hash::next, and NULL.

Referenced by dazuko_sys_post().

02375 {
02376         struct hash     *h = NULL;
02377         struct hash     *entry = NULL;
02378         struct hash     *prev = NULL;
02379         struct hash     *prev_entry = NULL;
02380 
02381 /* LOCK */
02382         call_xp_write_lock(&lock_hash);
02383 
02384         for (h=hash ; h ; h=h->next)
02385         {
02386                 /* not found if hit first dirty entry */
02387                 if (h->dirty)
02388                 {
02389                         entry = NULL;
02390                         break;
02391                 }
02392 
02393                 if (call_xp_compare_file(&(h->file), file) == 0)
02394                 {
02395                         /* we found the entry */
02396 
02397                         prev_entry = prev;
02398                         entry = h;
02399                         break;
02400                 }
02401 
02402                 prev = h;
02403         } 
02404 
02405         if (entry)
02406         {
02407                 if (!entry->dirty)
02408                 {
02409                         /* mark as dirty */
02410                         entry->dirty = 1;
02411 
02412                         /* If we already are last entry or next
02413                          * entry dirty, we don't need to move */
02414 
02415                         if (entry->next)
02416                         {
02417                                 if (!entry->next->dirty)
02418                                 {
02419                                         for (h=entry->next ; h ; h=h->next)
02420                                         {
02421                                                 if (h->dirty)
02422                                                         break;
02423 
02424                                                 prev = h;
02425                                         }
02426 
02427                                         /* remove from current position */
02428                                         if (prev_entry)
02429                                                 prev_entry->next = entry->next;
02430                                         else
02431                                                 hash = entry->next;
02432 
02433                                         if (prev == NULL)
02434                                         {
02435                                                 /* insert as first item */
02436                                                 entry->next = hash;
02437                                                 hash = entry;
02438                                         }
02439                                         else if (h)
02440                                         {
02441                                                 /* insert before h (after prev) */
02442                                                 entry->next = prev->next;
02443                                                 prev->next = entry;
02444                                         }
02445                                         else
02446                                         {
02447                                                 /* insert as last item (after prev) */
02448                                                 entry->next = NULL;
02449                                                 prev->next = entry;
02450                                         }
02451                                 }
02452                         }
02453                 }
02454         }
02455 
02456         call_xp_write_unlock(&lock_hash);
02457 /* UNLOCK */
02458 
02459 }

static int dazuko_printable char  c  )  [inline, static]
 

Definition at line 1216 of file dazuko_xp.c.

01217 {
01218         /* hopefully this counts for all operating systems! */
01219 
01220         return ((c >= ' ') && (c <= '~') && (c != '\\'));
01221 }

static int dazuko_register_daemon struct daemon_id did,
const char *  reg_name,
int  string_length,
int  write_mode
[static]
 

Definition at line 734 of file dazuko_xp.c.

References __dazuko_change_slot_state(), call_xp_atomic_inc(), call_xp_atomic_set(), call_xp_down(), call_xp_free(), call_xp_id_copy(), call_xp_init_mutex(), call_xp_malloc(), call_xp_print, call_xp_up(), dazuko_bzero(), dazuko_find_slot(), DAZUKO_FREE, dazuko_get_new_unique(), slot::did, DPRINT, slot::id, slot::mutex, NULL, NUM_SLOTS, slot_list::reg_name, slot_list_container::slot_list, daemon_id::unique, slot_list::use_count, slot::write_mode, XP_ERROR_BUSY, XP_ERROR_FAULT, XP_ERROR_INTERRUPT, XP_ERROR_PERMISSION, and daemon_id::xp_id.

00735 {
00736         const char      *p1;
00737         char            *p2;
00738         struct slot             *s;
00739         struct slot_list        *sl;
00740         int             i;
00741 
00742         DPRINT(("dazuko: dazuko_register_daemon() [%d]\n", did->unique));
00743 
00744         if (did == NULL || reg_name == NULL)
00745                 return XP_ERROR_PERMISSION;
00746 
00747         s = dazuko_find_slot(did, 1, NULL);
00748 
00749         if (s != NULL)
00750         {
00751                 /* We are already registered! */
00752 
00753                 call_xp_print("dazuko: daemon %d already assigned to slot[%d]\n", did->unique, s->id);
00754 
00755                 return XP_ERROR_PERMISSION;
00756         }
00757 
00758         /* Find the slot_list with the matching name. */
00759 
00760         for (i=0 ; i<NUM_SLOT_LISTS ; i++)
00761         {
00762 /* DOWN */
00763                 /* if we are interrupted, we say that it
00764                 * was interrupted */
00765                 if (call_xp_down(&(slot_lists[i].mutex)) != 0)
00766                         return XP_ERROR_INTERRUPT;
00767 
00768                 sl = slot_lists[i].slot_list;
00769 
00770                 call_xp_up(&(slot_lists[i].mutex));
00771 /* UP */
00772 
00773                 if (sl != NULL)
00774                 {
00775                         p1 = reg_name;
00776                         p2 = sl->reg_name;
00777 
00778                         while (*p1 == *p2)
00779                         {
00780                                 if (*p1 == 0)
00781                                         break;
00782 
00783                                 p1++;
00784                                 p2++;
00785                         }
00786 
00787                         if (*p1 == *p2)
00788                                 break;
00789                 }
00790         }
00791 
00792         if (i == NUM_SLOT_LISTS)
00793         {
00794                 /* There is no slot_list with this name. We
00795                  * need to make one. */
00796 
00797                 sl = (struct slot_list *)call_xp_malloc(sizeof(struct slot_list) + string_length);
00798                 if (sl == NULL)
00799                         return XP_ERROR_FAULT;
00800 
00801                 dazuko_bzero(sl, sizeof(struct slot_list) + string_length);
00802                 call_xp_atomic_set(&(sl->use_count), 0);
00803 
00804                 p1 = reg_name;
00805                 p2 = sl->reg_name;
00806 
00807                 while (*p1)
00808                 {
00809                         *p2 = *p1;
00810 
00811                         p1++;
00812                         p2++;
00813                 }
00814                 *p2 = 0;
00815 
00816                 /* give each slot a unique id */
00817                 for (i=0 ; i<NUM_SLOTS ; i++)
00818                 {
00819                         sl->slots[i].id = i;
00820                         call_xp_init_mutex(&(sl->slots[i].mutex));
00821                 }
00822 
00823                 /* we need to find an empty slot */
00824                 for (i=0 ; i<NUM_SLOT_LISTS ; i++)
00825                 {
00826 /* DOWN */
00827                         /* if we are interrupted, we need to cleanup
00828                         * and return error */
00829                         if (call_xp_down(&(slot_lists[i].mutex)) != 0)
00830                         {
00831                                 call_xp_free(sl);
00832                                 return XP_ERROR_INTERRUPT;
00833                         }
00834 
00835                         if (slot_lists[i].slot_list == NULL)
00836                         {
00837                                 slot_lists[i].slot_list = sl;
00838 
00839                                 call_xp_up(&(slot_lists[i].mutex));
00840 /* UP */
00841                                 break;
00842                         }
00843 
00844                         call_xp_up(&(slot_lists[i].mutex));
00845 /* UP */
00846                 }
00847 
00848                 if (i == NUM_SLOT_LISTS)
00849                 {
00850                         /* no empty slot :( */
00851                         call_xp_free(sl);
00852                         return XP_ERROR_BUSY;
00853                 }
00854         }
00855 
00856         /* find an available slot and hold the mutex
00857          * if we find one */
00858 /* DOWN? */
00859         s = dazuko_find_slot(NULL, 0, sl);
00860 
00861         if (s == NULL)
00862                 return XP_ERROR_BUSY;
00863 
00864 /* DOWN */
00865 
00866         /* We have found a slot, so increment the active
00867          * variable and the kernel module use counter.
00868          * The module counter will always reflect the
00869          * number of daemons. */
00870 
00871         call_xp_atomic_inc(&active);
00872 
00873         /* get new unique id for this process */
00874         did->unique = dazuko_get_new_unique();
00875 
00876         s->did.unique = did->unique;
00877         s->did.xp_id = call_xp_id_copy(did->xp_id);
00878         s->write_mode = write_mode;
00879 
00880         call_xp_atomic_inc(&(sl->use_count));
00881 
00882         /* the daemon is registered, but not yet
00883          * ready to receive files */
00884         __dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE);
00885 
00886         DPRINT(("dazuko: slot[%d] assigned to daemon %d\n", s->id, s->did.unique));
00887 
00888         call_xp_up(&(s->mutex));
00889 /* UP */
00890 
00891         return 0;
00892 }

static void dazuko_remove_all_hash void   )  [static]
 

Definition at line 575 of file dazuko_xp.c.

References call_xp_free(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, hash::name, and hash::next.

Referenced by _dazuko_unregister_daemon(), and dazuko_exit().

00576 {
00577         /* Empty the hash linked list. */
00578 
00579         struct hash     *tmp;
00580 
00581 /* LOCK */
00582         call_xp_write_lock(&lock_hash);
00583         while (hash)
00584         {
00585                 tmp = hash;
00586                 hash = hash->next;
00587 
00588                 DPRINT(("dazuko: removing hash %s\n", tmp->name));
00589 
00590                 call_xp_free(tmp);
00591         }
00592         call_xp_write_unlock(&lock_hash);
00593 /* UNLOCK */
00594 }

static void dazuko_remove_all_paths void   )  [static]
 

Definition at line 596 of file dazuko_xp.c.

References call_xp_free(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, path::next, and path::path.

00597 {
00598         /* Empty both include and exclude struct path
00599          * linked lists. */
00600 
00601         struct path     *tmp;
00602 
00603 /* LOCK */
00604         call_xp_write_lock(&lock_lists);
00605 
00606         /* empty include paths list */
00607         while (incl_paths)
00608         {
00609                 tmp = incl_paths;
00610                 incl_paths = incl_paths->next;
00611 
00612                 DPRINT(("dazuko: removing incl %s\n", tmp->path));
00613 
00614                 call_xp_free(tmp);
00615         }
00616 
00617         /* empty exclude paths list */
00618         while (excl_paths)
00619         {
00620                 tmp = excl_paths;
00621                 excl_paths = excl_paths->next;
00622 
00623                 DPRINT(("dazuko: removing excl %s\n", tmp->path));
00624 
00625                 call_xp_free(tmp);
00626         }
00627 
00628         call_xp_write_unlock(&lock_lists);
00629 /* UNLOCK */
00630 }

static int dazuko_return_access struct daemon_id did,
int  response,
struct slot s
[static]
 

Definition at line 976 of file dazuko_xp.c.

References call_xp_notify(), call_xp_up(), call_xp_wait_until_condition(), dazuko_change_slot_state(), DAZUKO_DONE, dazuko_find_slot(), DAZUKO_WORKING, DPRINT, slot::id, slot::mutex, NULL, one_slot_state_not_condition(), slot::response, one_slot_state_not_condition_param::slot, one_slot_state_not_condition_param::state, daemon_id::unique, XP_ERROR_INTERRUPT, and XP_ERROR_PERMISSION.

00977 {
00978         /* The daemon has finished scanning a file
00979          * and has the response to give. The daemon's
00980          * slot should be in the DAZUKO_WORKING state. */
00981 
00982         struct one_slot_state_not_condition_param       cond_p;
00983 
00984         /* do we already have a slot? */
00985         if (s == NULL)
00986         {
00987                 /* find our slot */
00988                 s = dazuko_find_slot(did, 1, NULL);
00989 
00990                 if (s == NULL)
00991                 {
00992                         /* It appears the kernel isn't interested
00993                          * in us or our response. It gave our slot away! */
00994 
00995                         DPRINT(("dazuko: daemon %d unexpectedly lost slot\n", did->unique));
00996 
00997                         return XP_ERROR_PERMISSION;
00998                 }
00999         }
01000 
01001         /* we will be writing into the slot, so we
01002          * need to lock it */
01003 
01004 /* DOWN? */
01005         if (!dazuko_change_slot_state(s, DAZUKO_WORKING, DAZUKO_DONE, 0))
01006         {
01007                 /* The slot is in the wrong state. We will
01008                  * assume the kernel has cancelled the file
01009                  * access. */
01010 
01011                 DPRINT(("dazuko: response from daemon %d on slot[%d] not needed\n", did->unique, s->id));
01012 
01013                 return 0;
01014         }
01015 
01016 /* DOWN */
01017 
01018         s->response = response;
01019 
01020         call_xp_up(&(s->mutex));
01021 /* UP */
01022 
01023         /* wake up any kernel processes that are
01024          * waiting for responses */
01025         call_xp_notify(&wait_kernel_waiting_while_daemon_works);
01026 
01027         cond_p.slot = s;
01028         cond_p.state = DAZUKO_DONE;
01029         if (call_xp_wait_until_condition(&wait_daemon_waiting_for_free, one_slot_state_not_condition, &cond_p, 1) != 0)
01030         {
01031                 /* The user has issued an interrupt.
01032                  * Return an error. The daemon should
01033                  * unregister itself. */
01034 
01035                 DPRINT(("dazuko: daemon %d killed while waiting for response acknowledgement\n", did->unique));
01036 
01037                 return XP_ERROR_INTERRUPT;
01038         }
01039 
01040         return 0;
01041 }

static int dazuko_run_daemon int  event,
char *  filename,
int  filenamelength,
struct event_properties event_p,
struct file_properties file_p
[static]
 

Definition at line 2170 of file dazuko_xp.c.

References call_xp_down(), call_xp_up(), dazuko_run_daemon_on_slotlist(), NULL, slot_list_container::slot_list, event_properties::thrown, and XP_ERROR_INTERRUPT.

02171 {
02172         struct slot_list        *sl;
02173         int                     i;
02174         int                     rc = 0;
02175         int                     error;
02176 
02177         if (event_p != NULL)
02178         {
02179                 /* we don't want to throw the same event twice */
02180                 if (event_p->thrown)
02181                         return 0;
02182                 event_p->thrown = 1;
02183         }
02184 
02185         for (i=0 ; i<NUM_SLOT_LISTS ; i++)
02186         {
02187 /* DOWN */
02188                 /* if we are interrupted, we report error */
02189                 if (call_xp_down(&(slot_lists[i].mutex)) != 0)
02190                         return XP_ERROR_INTERRUPT;
02191 
02192                 sl = slot_lists[i].slot_list;
02193 
02194                 call_xp_up(&(slot_lists[i].mutex));
02195 /* UP */
02196 
02197                 if (sl != NULL)
02198                 {
02199                         error = dazuko_run_daemon_on_slotlist(event, filename, filenamelength, event_p, file_p, rc, sl);
02200 
02201                         if (error < 0)
02202                         {
02203                                 /* most likely user interrupt */
02204                                 rc = error;
02205                                 break;
02206                         }
02207                         else if (error > 0)
02208                         {
02209                                 /* this daemon wants access blocked */
02210                                 rc = 1;
02211                         }
02212                 }
02213         }
02214 
02215         return rc;
02216 }

static int dazuko_run_daemon_on_slotlist int  event,
char *  filename,
int  filenamelength,
struct event_properties event_p,
struct file_properties file_p,
int  prev_response,
struct slot_list sl
[static]
 

Definition at line 2027 of file dazuko_xp.c.

References __dazuko_change_slot_state(), call_xp_down(), call_xp_notify(), call_xp_up(), call_xp_wait_until_condition(), dazuko_bzero(), dazuko_change_slot_state(), DAZUKO_DONE, DAZUKO_FREE, DAZUKO_WAITING, DAZUKO_WORKING, slot::did, DPRINT, slot::event, slot::event_p, slot::file_p, slot::filename, slot::filenamelength, get_ready_slot_condition(), slot::mutex, NULL, event_properties::pid, slot::response, get_ready_slot_condition_param::slot, two_slot_state_not_condition_param::slot1, two_slot_state_not_condition_param::slot2, get_ready_slot_condition_param::slotlist, two_slot_state_not_condition_param::state1, two_slot_state_not_condition_param::state2, two_slot_state_not_condition(), and daemon_id::unique.

02028 {
02029         /* This is the main function called by the kernel
02030          * to work with a daemon. */
02031 
02032         int                                             rc;
02033         int                                             unique;
02034         struct slot                                     *s;
02035         struct get_ready_slot_condition_param           cond_p1;
02036         struct two_slot_state_not_condition_param       cond_p2;
02037 
02038 begin:
02039         /* we initialize the slot value because
02040          * we cannot guarentee that it will be
02041          * assigned a new value BEFORE !active
02042          * is checked */
02043         s = NULL;
02044 
02045         /* wait for a slot to become ready */
02046         cond_p1.slotlist = sl;
02047         cond_p1.slot = s;
02048         if (call_xp_wait_until_condition(&wait_kernel_waiting_for_free_slot, get_ready_slot_condition, &cond_p1, 0) != 0)
02049         {
02050                 /* The kernel process was killed while
02051                  * waiting for a slot to become ready.
02052                  * This is fine. */
02053 
02054                 DPRINT(("dazuko: kernel process %d killed while waiting for free slot\n", event_p->pid));
02055 
02056                 return -1;  /* user interrupted */
02057         }
02058 
02059         /* Make sure we have a slot. We may have
02060          * gotten past the last wait because we
02061          * are no longer active. */
02062 
02063         s = cond_p1.slot;
02064 
02065         if (s == NULL)
02066         {
02067                 /* We were no longer active. We don't
02068                  * need to initiate a daemon. This also
02069                  * means we never acquired the lock. */
02070 
02071                 return 0;  /* allow access */
02072         }
02073 
02074 /* DOWN */
02075 
02076         /* the slot is already locked at this point */
02077 
02078         /* grab the daemon's unique */
02079         unique = s->did.unique;
02080 
02081         /* At this point we have a locked slot. It IS
02082          * sitting in the DAZUKO_WAITING state, waiting for
02083          * us to give it some work. */
02084         
02085         /* set up the slot to do work */
02086         s->filename = filename;
02087         s->event = event;
02088         s->response = prev_response;
02089         s->filenamelength = filenamelength;
02090 
02091         if (event_p == NULL)
02092                 dazuko_bzero(&(s->event_p), sizeof(struct event_properties));
02093         else
02094                 memcpy(&(s->event_p), event_p, sizeof(struct event_properties));
02095 
02096         if (file_p == NULL)
02097                 dazuko_bzero(&(s->file_p), sizeof(struct file_properties));
02098         else
02099                 memcpy(&(s->file_p), file_p, sizeof(struct file_properties));
02100 
02101         /* we are done modifying the slot */
02102         call_xp_up(&(s->mutex));
02103 /* UP */
02104 
02105         /* wake up any daemons waiting for work */
02106         call_xp_notify(&wait_daemon_waiting_for_work);
02107 
02108         /* wait until the daemon is finished with the slot */
02109         cond_p2.slot1 = s;
02110         cond_p2.state1 = DAZUKO_WAITING;
02111         cond_p2.slot2 = s;
02112         cond_p2.state2 = DAZUKO_WORKING;
02113         if (call_xp_wait_until_condition(&wait_kernel_waiting_while_daemon_works, two_slot_state_not_condition, &cond_p2, 0) != 0)
02114         {
02115                 /* The kernel process was killed while
02116                  * waiting for a daemon to process the file.
02117                  * This is fine. */
02118 
02119                 DPRINT(("dazuko: kernel process %d killed while waiting for daemon response\n", event_p->pid));
02120 
02121                 /* change the slot's state to let the
02122                  * daemon know we are not interested
02123                  * in a response */
02124                 dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE, 1);
02125 
02126                 return -1;  /* user interrupted */
02127         }
02128 
02129         /* we are working with the slot, so
02130          * we need to lock it */
02131 /* DOWN */
02132         if (call_xp_down(&(s->mutex)) != 0)
02133         {
02134                 return -1;  /* user interrupted */
02135         }
02136 
02137         /* make sure this is the right daemon */
02138         if (s->did.unique != unique)
02139         {
02140                 /* This is a different daemon than
02141                  * the one we assigned work to.
02142                  * We need to scan again. */
02143                 call_xp_up(&(s->mutex));
02144 /* UP */
02145                 goto begin;
02146         }
02147 
02148         /* The slot should now be in the DAZUKO_DONE state. */
02149         if (!__dazuko_change_slot_state(s, DAZUKO_DONE, DAZUKO_FREE))
02150         {
02151                 /* The daemon was killed while scanning.
02152                  * We need to scan again. */
02153 
02154                 call_xp_up(&(s->mutex));
02155 /* UP */
02156                 goto begin;
02157         }
02158 
02159         /* grab the response */
02160         rc = s->response;
02161 
02162         call_xp_up(&(s->mutex));
02163 /* UP */
02164 
02165         /* CONGRATULATIONS! You successfully completed a full state cycle! */
02166 
02167         return rc;
02168 }

static int dazuko_set_option struct daemon_id did,
int  opt,
void *  param,
int  len
[static]
 

Definition at line 1276 of file dazuko_xp.c.

References _dazuko_unregister_daemon(), access_mask, ADD_EXCLUDE_PATH, ADD_INCLUDE_PATH, call_xp_print, dazuko_find_slot(), dazuko_insert_path_fs(), dazuko_register_daemon(), dazuko_remove_all_paths(), NULL, REGISTER, REMOVE_ALL_PATHS, SET_ACCESS_MASK, UNREGISTER, and XP_ERROR_PERMISSION.

01277 {
01278         /* The daemon wants to set a configuration
01279          * option in the kernel. */
01280 
01281         struct slot     *s;
01282         int             error;
01283 
01284         /* sanity check */
01285         if (len < 0 || len > 8192)
01286                 return XP_ERROR_PERMISSION;
01287 
01288         /* make sure we are already registered
01289          * (or that we don't register twice) */
01290 
01291         /* find our slot */
01292         s = dazuko_find_slot(did, 1, NULL);
01293 
01294         switch (opt)
01295         {
01296                 case REGISTER:
01297                         call_xp_print("dazuko: dazuko_set_option does not support REGISTER (bug!)\n");
01298                         return XP_ERROR_PERMISSION;
01299 
01300                 case UNREGISTER:
01301                         if (s == NULL)
01302                         {
01303                                 /* We are not registered! */
01304 
01305                                 return 0;
01306                         }
01307                         break;
01308 
01309                 default:
01310                         if (s == NULL)
01311                         {
01312                                 error = dazuko_register_daemon(did, "_COMPAT", 7, 1);
01313                                 if (error)
01314                                 {
01315                                         call_xp_print("dazuko: unregistered daemon %d attempted access\n", did->unique);
01316                                         return XP_ERROR_PERMISSION;
01317                                 }
01318 
01319                                 s = dazuko_find_slot(did, 1, NULL);
01320                                 if (s == NULL)
01321                                 {
01322                                         call_xp_print("dazuko: unregistered daemon %d attempted access\n", did->unique);
01323                                         return XP_ERROR_PERMISSION;
01324                                 }
01325 
01326                                 call_xp_print("dazuko: warning: daemon %d is using a deprecated protocol\n", did->unique);
01327                         }
01328                         break;
01329         }
01330 
01331         /* check option type and take the appropriate action */
01332         switch (opt)
01333         {
01334                 case UNREGISTER:
01335                         error = _dazuko_unregister_daemon(did);
01336                         if (error)
01337                                 return error;
01338                         break;
01339 
01340                 case SET_ACCESS_MASK:
01341                         memcpy(&access_mask, (char *)param, sizeof(char));
01342                         break;
01343 
01344                 case ADD_INCLUDE_PATH:
01345                         error = dazuko_insert_path_fs(&incl_paths, (char *)param, len);
01346                         if (error)
01347                                 return error;
01348                         break;
01349 
01350                 case ADD_EXCLUDE_PATH:
01351                         error = dazuko_insert_path_fs(&excl_paths, (char *)param, len);
01352                         if (error)
01353                                 return error;
01354                         break;
01355 
01356                 case REMOVE_ALL_PATHS:
01357                         dazuko_remove_all_paths();
01358                         break;
01359 
01360                 default:
01361                         call_xp_print("dazuko: daemon %d requested unknown set %d (possible bug)\n", did->unique, opt);
01362                         break;
01363         }
01364 
01365         return 0;
01366 }

static int dazuko_should_scan struct dazuko_file_struct kfs  )  [static]
 

Definition at line 2508 of file dazuko_xp.c.

References call_xp_fill_file_struct(), dazuko_is_selected(), and dazuko_file_struct::should_scan.

02509 {
02510         /* Check if we are supposed to scan this file.
02511          * This checks for all the correct file types,
02512          * permissions, and if it is within the desired
02513          * paths to scan. */
02514 
02515         int result = 0;
02516 
02517         /* check if we already know if we scan this file */
02518         switch (kfs->should_scan)
02519         {
02520                 /* case 0 means that we do not know yet. This is a little
02521                  * confusing, because 0 represents uninitialized. However,
02522                  * the should_scan variable is used in this function ONLY
02523                  * so this optimization shouldn't cause any problems. */
02524 
02525                 case 1:
02526                         /* we already know it should be scanned */
02527                         return 1;
02528 
02529                 case 2:
02530                         /* we already know it should not be scanned */
02531                         return 2;
02532         }
02533 
02534         /* make necessary platform-dependent checks */
02535         if (call_xp_fill_file_struct(kfs) == 0)
02536         {
02537                 if (dazuko_is_selected(kfs))
02538                 {
02539                         /* If we made it this far, we are supposed
02540                          * to scan this file. We mark it so that
02541                          * any further immediate inquiries don't have
02542                          * to do all this work all over again. */
02543  
02544                         /* yes, should be scanned */
02545                         kfs->should_scan = 1;
02546 
02547                         result = 1;
02548                 }
02549                 else
02550                 {
02551                         /* We will still mark it so that any further
02552                          * immediate inquiries don't have to do all
02553                          * this work all over again. */
02554 
02555                         /* no, should not be scanned */
02556                         kfs->should_scan = 2;
02557                 }
02558         }
02559 
02560         return result;
02561 }

static int dazuko_slot_state struct slot s  )  [inline, static]
 

Definition at line 299 of file dazuko_xp.c.

References call_xp_down(), call_xp_up(), slot::mutex, slot::state, and XP_ERROR_INTERRUPT.

00300 {
00301         int state;
00302 
00303 /* DOWN */
00304         if (call_xp_down(&(s->mutex)) != 0)
00305                 return XP_ERROR_INTERRUPT;
00306 
00307         state = s->state;
00308 
00309         call_xp_up(&(s->mutex));
00310 /* UP */
00311 
00312         return state;
00313 }

int dazuko_snprintf char *  str,
size_t  size,
const char *  format,
  ...
 

Definition at line 261 of file dazuko_xp.c.

References dazuko_vsnprintf().

00262 {
00263         va_list ap;
00264         int     ret;
00265 
00266         va_start(ap, format);
00267         ret = dazuko_vsnprintf(str, size, format, ap);
00268         va_end(ap);
00269 
00270         return ret;
00271 }

static int dazuko_state_error struct slot s,
int  current_state
[inline, static]
 

Definition at line 723 of file dazuko_xp.c.

References call_xp_notify(), DAZUKO_BROKEN, and dazuko_change_slot_state().

Referenced by dazuko_handle_user_request_compat12().

00724 {
00725         if (dazuko_change_slot_state(s, current_state, DAZUKO_BROKEN, 1))
00726         {
00727                 call_xp_notify(&wait_kernel_waiting_for_free_slot);
00728                 call_xp_notify(&wait_kernel_waiting_while_daemon_works);
00729         }
00730 
00731         return 0;
00732 }

static const char* dazuko_strchr const char *  haystack,
char  needle
[inline, static]
 

Definition at line 1101 of file dazuko_xp.c.

References NULL.

01102 {
01103         const char      *p;
01104 
01105         if (haystack == NULL)
01106                 return NULL;
01107 
01108         for (p=haystack ; *p ; p++)
01109         {
01110                 if (*p == needle)
01111                         return p;
01112         }
01113 
01114         return NULL;
01115 }

static int dazuko_strlen const char *  string  )  [inline, static]
 

Definition at line 1088 of file dazuko_xp.c.

References NULL.

01089 {
01090         const char      *p;
01091 
01092         if (string == NULL)
01093                 return -1;
01094 
01095         for (p=string ; *p ; p++)
01096                 continue;
01097 
01098         return (p - string);
01099 }

static const char* dazuko_strstr const char *  haystack,
const char *  needle
[inline, static]
 

Definition at line 1117 of file dazuko_xp.c.

References NULL.

01118 {
01119         const char      *p1;
01120         const char      *p2;
01121         const char      *p3;
01122 
01123         if (haystack == NULL || needle == NULL)
01124                 return NULL;
01125 
01126         for (p1=haystack ; *p1 ; p1++)
01127         {
01128                 for (p2=needle,p3=p1 ; *p2&&*p3 ; p2++,p3++)
01129                 {
01130                         if (*p2 != *p3)
01131                                 break;
01132                 }
01133 
01134                 if (*p2 == 0)
01135                         return p1;
01136         }
01137 
01138         return NULL;
01139 }

static long dazuko_strtol const char *  string  )  [inline, static]
 

Definition at line 1048 of file dazuko_xp.c.

References dazuko_isdigit(), and NULL.

01049 {
01050         long            num = 1;
01051         const char      *p = string;
01052 
01053         if (string == NULL)
01054                 return 0;
01055 
01056         switch (*p)
01057         {
01058                 case '-':
01059                         num = -1;
01060                         p++;
01061                         break;
01062 
01063                 case '+':
01064                         p++;
01065                         break;
01066         }
01067 
01068         if (dazuko_isdigit(*p))
01069         {
01070                 num *= *p - '0';
01071                 p++;
01072         }
01073         else
01074         {
01075                 return 0;
01076         }
01077 
01078         while (dazuko_isdigit(*p))
01079         {
01080                 num *= 10;
01081                 num += *p - '0';
01082                 p++;
01083         }
01084 
01085         return num;
01086 }

int dazuko_sys_check unsigned long  event,
int  daemon_is_allowed,
struct xp_daemon_id xp_id
[inline]
 

Definition at line 2563 of file dazuko_xp.c.

References access_mask, call_xp_atomic_read(), dazuko_is_our_daemon(), DAZUKO_ON_CLOSE, DAZUKO_ON_OPEN, SCAN_ON_CLOSE, SCAN_ON_CLOSE_MODIFIED, and SCAN_ON_OPEN.

Referenced by rsbac_adf_request_daz(), and rsbac_adf_set_attr_daz().

02564 {
02565         /* is this event in our mask? */
02566         switch (event)
02567         {
02568                 case DAZUKO_ON_OPEN:
02569                         /* this is a special case because the on_close information needs
02570                          * to be saved during the on_open event */
02571 
02572                         if ((SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) == 0)
02573                                 return -1;
02574                         break;
02575 
02576                 case DAZUKO_ON_CLOSE:
02577                         /* will need to scan if ON_CLOSE_MODIFIED is in the mask too */
02578 
02579                         if ((SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) == 0)
02580                                 return -1;
02581                         break;
02582 
02583                 default:
02584                         if ((access_mask & event) == 0)
02585                                 return -1;
02586                         break;
02587         }
02588 
02589         /* do we have any daemons? */
02590         if (call_xp_atomic_read(&active) <= 0)
02591                 return -1;
02592 
02593         /* should daemons be allowed this event without a scan? */
02594         if (daemon_is_allowed)
02595         {
02596                 if (dazuko_is_our_daemon(xp_id))
02597                 {
02598                         /* this is one of our daemons, so we will report as
02599                          * as if this event was not in the mask */
02600 
02601                         return -1;
02602                 }
02603         }
02604 
02605         return 0;
02606 }

int dazuko_sys_post unsigned long  event,
struct dazuko_file_struct kfs,
struct xp_file file,
struct event_properties event_p
[inline]
 

Definition at line 2727 of file dazuko_xp.c.

References call_xp_atomic_read(), call_xp_free(), dazuko_add_hash(), dazuko_get_hash(), dazuko_mark_hash_dirty(), DAZUKO_ON_CLOSE, DAZUKO_ON_CLOSE_MODIFIED, DAZUKO_ON_OPEN, dazuko_run_daemon(), dazuko_should_scan(), hash::dirty, hash::name, hash::namelen, NULL, SCAN_ON_CLOSE, SCAN_ON_CLOSE_MODIFIED, and SCAN_ON_OPEN.

Referenced by rsbac_adf_set_attr_daz().

02728 {
02729         struct hash     *h = NULL;
02730 
02731         switch (event)
02732         {
02733                 case DAZUKO_ON_OPEN: /* kfs,file required */
02734                         /* if the file was opened and we are interested
02735                          * in scanning on close, add this file to our struct hash list */
02736 
02737                         if ((call_xp_atomic_read(&active) > 0) && file != NULL && kfs != NULL)
02738                         {
02739                                 if (SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED)
02740                                 {
02741                                         /* make sure we should scan this file */
02742                                         if (dazuko_should_scan(kfs))
02743                                         {
02744                                                 /* hash is added if we were given an xp_file */
02745                                                 if (file != NULL)
02746                                                         dazuko_add_hash(file, kfs->filename, kfs->filename_length);
02747 
02748                                                 /* this is a fallback in case we didn't process the event in "sys_pre" */
02749                                                 dazuko_run_daemon(event, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p));
02750                                         }
02751                                 }
02752                         }
02753                         break;
02754 
02755                 case DAZUKO_ON_CLOSE: /* file,o_flags,o_mode,pid,uid required */
02756                         if (file != NULL)
02757                         {
02758                                 /* find hash entry and remove it from list */
02759                                 h = dazuko_get_hash(file);
02760 
02761                                 /* if we found the file in our list and the file was
02762                                 * successfully closed, we need to scan it */
02763                                 if (h != NULL)
02764                                 {
02765                                         /* determine if we are scanning on close or close_modified */
02766 
02767                                         /* note that close_modified has priority over just close */
02768 
02769                                         if (SCAN_ON_CLOSE_MODIFIED && h->dirty)
02770                                                 dazuko_run_daemon(DAZUKO_ON_CLOSE_MODIFIED, h->name, h->namelen, event_p, NULL);
02771                                         else if (SCAN_ON_CLOSE)
02772                                                 dazuko_run_daemon(DAZUKO_ON_CLOSE, h->name, h->namelen, event_p, NULL);
02773 
02774                                         /* clean up the struct hash structure */
02775                                         call_xp_free(h);
02776                                 }
02777                         }
02778                         else
02779                         {
02780                                 if (SCAN_ON_CLOSE)
02781                                 {
02782                                         if (dazuko_should_scan(kfs))
02783                                         {
02784                                                 dazuko_run_daemon(DAZUKO_ON_CLOSE, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p));
02785                                         }
02786                                 }
02787                         }
02788                         break;
02789 
02790                 case DAZUKO_ON_CLOSE_MODIFIED: /* file required */
02791                         if (file != NULL)
02792                         {
02793                                 /* if we actually wrote something and we found the
02794                                  * file in our list, set it as dirty */
02795 
02796                                 /* Swade 4/24/02: Move to end of clean list */
02797                                 dazuko_mark_hash_dirty(file);
02798                         }
02799                         break;
02800 
02801                 default:
02802                         break;
02803         }
02804 
02805         return 0;
02806 }

int dazuko_sys_pre unsigned long  event,
struct dazuko_file_struct kfs,
struct xp_file file,
struct event_properties event_p
[inline]
 

Definition at line 2608 of file dazuko_xp.c.

References call_xp_compare_file(), call_xp_malloc(), call_xp_print, call_xp_read_lock(), call_xp_read_unlock(), DAZUKO_ON_CLOSE, DAZUKO_ON_CLOSE_MODIFIED, DAZUKO_ON_OPEN, dazuko_run_daemon(), dazuko_should_scan(), dazuko_file_struct::extra_data, hash::file, dazuko_file_struct::filename, dazuko_file_struct::filename_length, hash::name, hash::namelen, hash::next, NULL, SCAN_ON_OPEN, dazuko_file_struct::should_scan, XP_ERROR_INTERRUPT, and XP_ERROR_PERMISSION.

Referenced by rsbac_adf_request_daz().

02609 {
02610         /* return codes:
02611          *   >0 -> access should be blocked
02612          *   <0 -> access should be blocked (because user interrupted)
02613          *    0 -> access is allowed
02614          *   -2 -> unscanned access should not be taken care of
02615          */
02616 
02617         int             error = 0;
02618         struct hash     *h = NULL;
02619 
02620         switch (event)
02621         {
02622                 case DAZUKO_ON_OPEN:
02623                         /* special case, because this pre may be called
02624                          * in order to record ON_CLOSE events (in post) */
02625 
02626                         if (!SCAN_ON_OPEN)
02627                                 return 2;
02628                         break;
02629 
02630                 case DAZUKO_ON_CLOSE:
02631                         /* handled in post */
02632 
02633                         return 2;
02634 
02635                 case DAZUKO_ON_CLOSE_MODIFIED:
02636                         /* (this is really sys_write) always permitted */
02637 
02638                         return 2;
02639 
02640                 default:
02641                         break;
02642         }
02643 
02644         if (kfs == NULL)
02645         {
02646                 /* kfs is required */
02647 
02648                 call_xp_print("dazuko: kfs=NULL (possible bug)\n");
02649 
02650                 return XP_ERROR_PERMISSION;
02651         }
02652 
02653         if (file != NULL)
02654         {
02655                 /* we search for the file descriptor first */
02656 
02657 /* LOCK */
02658                 call_xp_read_lock(&lock_hash);
02659 
02660                 for (h=hash ; h ; h=h->next)
02661                 {
02662                         if (call_xp_compare_file(&(h->file), file) == 0)
02663                         {
02664                                 /* we found the file descriptor */
02665 
02666                                 kfs->filename = (char*)call_xp_malloc(h->namelen + 1);
02667                                 if (kfs->filename != NULL)
02668                                 {
02669                                         memcpy(kfs->filename, h->name, h->namelen);
02670                                         kfs->filename[h->namelen] = 0;
02671                                         kfs->filename_length = h->namelen;
02672                                         kfs->should_scan = 1;
02673                                 }
02674                                 else
02675                                 {
02676                                         /* error allocating, so we get out */
02677                                         h = NULL;
02678                                 }
02679                                 break;
02680                         }
02681                 }
02682 
02683                 call_xp_read_unlock(&lock_hash);
02684 /* UNLOCK */
02685 
02686                 if (h == NULL && kfs->extra_data == NULL)
02687                 {
02688                         /* we don't know this file descriptor
02689                          * and we cannot fallback on name lookups
02690                          */
02691 
02692                         /* we should not scan this file */
02693                         kfs->should_scan = 2;
02694 
02695                         return 0;
02696                 }
02697         }
02698 
02699         /* make sure we should scan this file */
02700         if (dazuko_should_scan(kfs))
02701                 error = dazuko_run_daemon(event, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p));
02702         else
02703                 return 2;
02704 
02705         if (error > 0)
02706         {
02707                 /* access will be blocked */
02708 
02709                 /* dazuko_sys_post should NOT be called! */
02710 
02711                 return XP_ERROR_PERMISSION;
02712         }
02713         else if (error < 0)
02714         {
02715                 /* user interrupted */
02716 
02717                 /* dazuko_sys_post should NOT be called! */
02718 
02719                 return XP_ERROR_INTERRUPT;
02720         }
02721 
02722         /* access allowed */
02723 
02724         return 0;
02725 }

int dazuko_unregister_daemon struct xp_daemon_id xp_id  ) 
 

Definition at line 705 of file dazuko_xp.c.

References _dazuko_unregister_daemon(), call_xp_id_copy(), call_xp_id_free(), NULL, daemon_id::unique, and daemon_id::xp_id.

00706 {
00707         struct daemon_id        did;
00708         int                     ret;
00709 
00710         if (xp_id == NULL)
00711                 return 0;
00712 
00713         did.unique = -1;
00714         did.xp_id = call_xp_id_copy(xp_id);
00715 
00716         ret = _dazuko_unregister_daemon(&did);
00717 
00718         call_xp_id_free(did.xp_id);
00719 
00720         return ret;
00721 }

int dazuko_vsnprintf char *  str,
size_t  size,
const char *  format,
va_list  ap
 

Definition at line 149 of file dazuko_xp.c.

References DAZUKO_VSNPRINTF_PRINTSTRING, and NULL.

00150 {
00151         char            *target;
00152         const char      *end;
00153         int             overflow = 0;
00154         char            number_buffer[32]; /* 32 should be enough to hold any number, right? */
00155         const char      *s;
00156 
00157         if (str == NULL || size < 1 || format == NULL)
00158                 return -1;
00159 
00160         target = str;
00161         end = (target + size) - 1;
00162 
00163 #define DAZUKO_VSNPRINTF_PRINTSTRING \
00164         for ( ; *s ; s++) \
00165         { \
00166                 if (target == end) \
00167                 { \
00168                         overflow = 1; \
00169                         goto dazuko_vsnprintf_out; \
00170                 } \
00171                 *target = *s; \
00172                 target++; \
00173         }
00174 
00175         for ( ; *format ; format++)
00176         {
00177                 if (target == end)
00178                 {
00179                         overflow = 1;
00180                         goto dazuko_vsnprintf_out;
00181                 }
00182 
00183                 if (*format == '%')
00184                 {
00185                         format++;
00186 
00187                         switch (*format)
00188                         {
00189                                 case 's': /* %s */
00190                                         s = va_arg(ap, char *);
00191                                         if (s == NULL)
00192                                                 s = "(null)";
00193                                         DAZUKO_VSNPRINTF_PRINTSTRING
00194                                         break;
00195 
00196                                 case 'd': /* %d */
00197                                         sprintf(number_buffer, "%d", va_arg(ap, int));
00198                                         s = number_buffer;
00199                                         DAZUKO_VSNPRINTF_PRINTSTRING
00200                                         break;
00201 
00202                                 case 'c': /* %c */
00203                                         *target = va_arg(ap, int);
00204                                         target++;
00205                                         break;
00206 
00207                                 case 'l': /* %lu */
00208                                         format++;
00209                                         if (*format != 'u')
00210                                         {
00211                                                 /* print error message */
00212                                                 goto dazuko_vsnprintf_out;
00213                                         }
00214                                         sprintf(number_buffer, "%lu", va_arg(ap, unsigned long));
00215                                         s = number_buffer;
00216                                         DAZUKO_VSNPRINTF_PRINTSTRING
00217                                         break;
00218 
00219                                 case '0': /* %02x */
00220                                         format++;
00221                                         if (*format != '2')
00222                                         {
00223                                                 /* print error message */
00224                                                 goto dazuko_vsnprintf_out;
00225                                         }
00226                                         format++;
00227                                         if (*format != 'x')
00228                                         {
00229                                                 /* print error message */
00230                                                 goto dazuko_vsnprintf_out;
00231                                         }
00232                                         sprintf(number_buffer, "%02x", va_arg(ap, int));
00233                                         s = number_buffer;
00234                                         DAZUKO_VSNPRINTF_PRINTSTRING
00235                                         break;
00236 
00237                                 default:
00238                                         /* print error message */
00239                                         goto dazuko_vsnprintf_out;
00240                         }
00241                 }
00242                 else
00243                 {
00244                         *target = *format;
00245                         target++;
00246                 }
00247         }
00248 
00249 dazuko_vsnprintf_out:
00250 
00251         *target = 0;
00252 
00253         /* We are returning what we've written. If there was an
00254          * overflow, the returned value will match "size" rather
00255          * than being less than "size"
00256          */
00257 
00258         return ((target - str) + overflow);
00259 }

static int get_ready_slot_condition void *  param  )  [static]
 

Definition at line 2020 of file dazuko_xp.c.

References call_xp_atomic_read(), dazuko_get_and_hold_ready_slot(), and NULL.

02021 {
02022         return ((((struct get_ready_slot_condition_param *)param)->slot = dazuko_get_and_hold_ready_slot(((struct get_ready_slot_condition_param *)param)->slotlist)) != NULL
02023                 || call_xp_atomic_read(&active) == 0
02024                 || call_xp_atomic_read(&(((struct get_ready_slot_condition_param *)param)->slotlist->use_count)) == 0);
02025 }

static int one_slot_state_not_condition void *  param  )  [static]
 

Definition at line 315 of file dazuko_xp.c.

References dazuko_slot_state().

00316 {
00317         return (dazuko_slot_state(((struct one_slot_state_not_condition_param *)param)->slot)
00318                 != ((struct one_slot_state_not_condition_param *)param)->state);
00319 }

static int two_slot_state_not_condition void *  param  )  [static]
 

Definition at line 321 of file dazuko_xp.c.

References dazuko_slot_state().

00322 {
00323         return (dazuko_slot_state(((struct two_slot_state_not_condition_param *)param)->slot1)
00324                 != ((struct two_slot_state_not_condition_param *)param)->state1
00325                 && dazuko_slot_state(((struct two_slot_state_not_condition_param *)param)->slot2)
00326                 != ((struct two_slot_state_not_condition_param *)param)->state2);
00327 }


Variable Documentation

char access_mask = 7 [static]
 

Definition at line 133 of file dazuko_xp.c.

Referenced by dazuko_handle_request(), dazuko_set_option(), and dazuko_sys_check().

struct xp_atomic active [static]
 

Definition at line 140 of file dazuko_xp.c.

struct path* excl_paths = NULL [static]
 

Definition at line 136 of file dazuko_xp.c.

struct hash* hash = NULL [static]
 

Definition at line 137 of file dazuko_xp.c.

struct path* incl_paths = NULL [static]
 

Definition at line 135 of file dazuko_xp.c.

struct xp_rwlock lock_hash [static]
 

Definition at line 138 of file dazuko_xp.c.

struct xp_rwlock lock_lists [static]
 

Definition at line 139 of file dazuko_xp.c.

struct xp_mutex mutex_unique_count [static]
 

Definition at line 141 of file dazuko_xp.c.

struct slot_list_container slot_lists[NUM_SLOT_LISTS] [static]
 

Definition at line 134 of file dazuko_xp.c.

int unique_count = 1 [static]
 

Definition at line 132 of file dazuko_xp.c.

struct xp_queue wait_daemon_waiting_for_free [static]
 

Definition at line 146 of file dazuko_xp.c.

struct xp_queue wait_daemon_waiting_for_work [static]
 

Definition at line 144 of file dazuko_xp.c.

struct xp_queue wait_kernel_waiting_for_free_slot [static]
 

Definition at line 143 of file dazuko_xp.c.

struct xp_queue wait_kernel_waiting_while_daemon_works [static]
 

Definition at line 145 of file dazuko_xp.c.


Generated on Sun May 21 14:31:01 2006 for RSBAC by  doxygen 1.4.2