~ubuntu-branches/ubuntu/oneiric/jabberd2/oneiric-security

« back to all changes in this revision

Viewing changes to sm/mm.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolai Spohrer
  • Date: 2008-08-12 16:13:43 UTC
  • mfrom: (1.1.3 upstream) (0.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20080812161343-6trz3r97dtevxd17
Tags: 2.2.1-1ubuntu1
* Merge with Debian unstable (LP: #257130), remaining changes:
  - debian/control:
    + Modify Maintainer field as per spec
    + Depend on libdb4.6-dev instead of libdb4.4-dev
    + Added Conflicts and Replaces: ..., jabber for jabberd2
  - debian/rules: Added libtoolize call (jabberd2 ships with
     an older ltmain.sh version that conflicts with the
     current libtool version)
  - debian/init: create /var/run/jabber directory with correct
     permissions
* Dropped changes:
  - Debian already depends on libpq-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "sm.h"
22
22
 
 
23
#ifdef _WIN32
 
24
# define LIBRARY_DIR "."
 
25
# include <windows.h>
 
26
#else
 
27
# include <dlfcn.h>
 
28
#endif /* _WIN32 */
 
29
 
23
30
/** @file sm/mm.c
24
31
  * @brief module manager
25
32
  * @author Robert Norris
26
 
  * $Date: 2005/01/19 18:29:38 $
27
 
  * $Revision: 1.32.2.2 $
 
33
  * $Date: 2005/08/17 07:48:28 $
 
34
  * $Revision: 1.40 $
28
35
  */
29
36
 
30
37
/* these functions implement a multiplexor to get calls to the correct module
31
38
 * for the given type */
32
39
 
33
 
 
34
 
/* if you add a module, you'll need to update these arrays */
35
 
 
36
 
extern int active_init(mod_instance_t);
37
 
extern int announce_init(mod_instance_t);
38
 
extern int deliver_init(mod_instance_t);
39
 
extern int disco_init(mod_instance_t);
40
 
extern int disco_publish_init(mod_instance_t);
41
 
extern int echo_init(mod_instance_t);
42
 
extern int help_init(mod_instance_t);
43
 
extern int offline_init(mod_instance_t);
44
 
extern int presence_init(mod_instance_t);
45
 
extern int privacy_init(mod_instance_t);
46
 
extern int roster_init(mod_instance_t);
47
 
extern int session_init(mod_instance_t);
48
 
extern int vacation_init(mod_instance_t);
49
 
extern int validate_init(mod_instance_t);
50
 
extern int iq_last_init(mod_instance_t);
51
 
extern int iq_private_init(mod_instance_t);
52
 
extern int iq_time_init(mod_instance_t);
53
 
extern int iq_vcard_init(mod_instance_t);
54
 
extern int iq_version_init(mod_instance_t);
55
 
extern int template_roster_init(mod_instance_t);
56
 
 
57
 
char *module_names[] = {
58
 
    "active",
59
 
    "announce",
60
 
    "deliver",
61
 
    "disco",
62
 
    "disco-publish",
63
 
    "echo",
64
 
    "help",
65
 
    "offline",
66
 
    "presence",
67
 
    "privacy",
68
 
    "roster",
69
 
    "session",
70
 
    "vacation",
71
 
    "validate",
72
 
    "iq-last",
73
 
    "iq-private",
74
 
    "iq-time",
75
 
    "iq-vcard",
76
 
    "iq-version",
77
 
    "template-roster",
78
 
    NULL
79
 
};
80
 
 
81
 
module_init_fn module_inits[] = {
82
 
    active_init,
83
 
    announce_init,
84
 
    deliver_init,
85
 
    disco_init,
86
 
    disco_publish_init,
87
 
    echo_init,
88
 
    help_init,
89
 
    offline_init,
90
 
    presence_init,
91
 
    privacy_init,
92
 
    roster_init,
93
 
    session_init,
94
 
    vacation_init,
95
 
    validate_init,
96
 
    iq_last_init,
97
 
    iq_private_init,
98
 
    iq_time_init,
99
 
    iq_vcard_init,
100
 
    iq_version_init,
101
 
    template_roster_init,
102
 
    NULL
103
 
};
 
40
/* Notes on dynamic modules (cedricv@) :
 
41
   Modules are searched by name mod_[modulename].so or mod_[modulename].dll
 
42
   depending platform.
 
43
   You have to set <path>[full_path]</path> within <modules> in sm.xml config,
 
44
   else it will only search in LD_LIBRARY_PATH or c:\windows\system32
 
45
 */
104
46
 
105
47
mm_t mm_new(sm_t sm) {
106
48
    mm_t mm;
107
 
    int celem, melem, attr, i, *nlist = NULL;
108
 
    char id[13], name[32], arg[1024];
 
49
    int celem, melem, attr, *nlist = NULL;
 
50
    char id[13], name[32], mod_fullpath[PATH_MAX], arg[1024], *modules_path;
109
51
    mod_chain_t chain = (mod_chain_t) NULL;
110
52
    mod_instance_t **list = NULL, mi;
111
53
    module_t mod;
112
54
 
113
 
    mm = (mm_t) malloc(sizeof(struct mm_st));
114
 
    memset(mm, 0, sizeof(struct mm_st));
 
55
    mm = (mm_t) calloc(1, sizeof(struct mm_st));
115
56
 
116
57
    mm->sm = sm;
117
58
    mm->modules = xhash_new(101);
119
60
    if((celem = nad_find_elem(sm->config->nad, 0, -1, "modules", 1)) < 0)
120
61
        return mm;
121
62
 
 
63
    modules_path = config_get_one(sm->config, "modules.path", 0);
 
64
    if (modules_path != NULL)
 
65
        log_write(sm->log, LOG_NOTICE, "modules search path: %s", modules_path);
 
66
    else
 
67
        log_write(sm->log, LOG_NOTICE, "modules search path undefined, using deafult: "LIBRARY_DIR);
 
68
 
122
69
    celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 1);
123
70
    while(celem >= 0) {
124
71
        if((attr = nad_find_attr(sm->config->nad, celem, -1, "id", NULL)) < 0) {
192
139
            list = &mm->user_delete;
193
140
            nlist = &mm->nuser_delete;
194
141
        }
 
142
        else if(strcmp(id, "disco-extend") == 0) {
 
143
            chain = chain_DISCO_EXTEND;
 
144
            list = &mm->disco_extend;
 
145
            nlist = &mm->ndisco_extend;
 
146
        }
195
147
 
196
148
        if(list == NULL) {
197
 
            log_write(sm->log, LOG_ERR, "unknwon chain type '%s'", id);
 
149
            log_write(sm->log, LOG_ERR, "unknown chain type '%s'", id);
198
150
 
199
151
            celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 0);
200
152
            continue;
207
159
                continue;
208
160
            }
209
161
 
 
162
            arg[0] = '\0';
 
163
            attr = nad_find_attr(sm->config->nad, melem, -1, "arg", NULL);
 
164
            if(attr >= 0) {
 
165
                snprintf(arg, 1024, "%.*s", NAD_AVAL_L(sm->config->nad, attr), NAD_AVAL(sm->config->nad, attr));
 
166
                log_debug(ZONE, "module arg: %s", arg);
 
167
            }
 
168
 
210
169
            snprintf(name, 32, "%.*s", NAD_CDATA_L(sm->config->nad, melem), NAD_CDATA(sm->config->nad, melem));
211
170
 
212
 
            for(i = 0; module_names[i] != NULL; i++) {
213
 
                if(strcmp(name, module_names[i]) == 0) {
214
 
                    log_debug(ZONE, "adding module '%s' to chain '%s'", name, id);
215
 
 
216
 
                    arg[0] = '\0';
217
 
                    attr = nad_find_attr(sm->config->nad, melem, -1, "arg", NULL);
218
 
                    if(attr >= 0) {
219
 
                        snprintf(arg, 1024, "%.*s", NAD_AVAL_L(sm->config->nad, attr), NAD_AVAL(sm->config->nad, attr));
220
 
                        log_debug(ZONE, "module arg: %s", arg);
221
 
                    }
222
 
 
223
 
                    mod = xhash_get(mm->modules, name);
224
 
                    if(mod == NULL) {
225
 
                        mod = (module_t) malloc(sizeof(struct module_st));
226
 
                        memset(mod, 0, sizeof(struct module_st));
227
 
 
228
 
                        mod->mm = mm;
229
 
                        mod->index = mm->nindex;
230
 
                        mod->name = strdup(name);
231
 
 
 
171
            mod = xhash_get(mm->modules, name);
 
172
            if(mod == NULL) {
 
173
                mod = (module_t) calloc(1, sizeof(struct module_st));
 
174
 
 
175
                mod->mm = mm;
 
176
                mod->index = mm->nindex;
 
177
                mod->name = strdup(name);
 
178
                #ifndef _WIN32
 
179
                  if (modules_path != NULL)
 
180
                      snprintf(mod_fullpath, PATH_MAX, "%s/mod_%s.so", modules_path, name);
 
181
                  else
 
182
                      snprintf(mod_fullpath, PATH_MAX, "%s/mod_%s.so", LIBRARY_DIR, name);
 
183
                  mod->handle = dlopen(mod_fullpath, RTLD_LAZY);
 
184
                  if (mod->handle != NULL)
 
185
                      mod->module_init_fn = dlsym(mod->handle, "module_init");
 
186
                #else
 
187
                  if (modules_path != NULL)
 
188
                      snprintf(mod_fullpath, PATH_MAX, "%s\\mod_%s.dll", modules_path, name);
 
189
                  else
 
190
                      snprintf(mod_fullpath, PATH_MAX, "mod_%s.dll", name);
 
191
                  mod->handle = (void*) LoadLibrary(mod_fullpath);
 
192
                  if (mod->handle != NULL)
 
193
                      mod->module_init_fn = (int (*)(mod_instance_t))GetProcAddress((HMODULE) mod->handle, "module_init");
 
194
                #endif
 
195
 
 
196
                if (mod->handle != NULL && mod->module_init_fn != NULL) {
 
197
                    log_debug(ZONE, "preloaded module '%s' to chain '%s' (not added yet)", name, id);
232
198
                        xhash_put(mm->modules, mod->name, (void *) mod);
233
 
 
234
199
                        mm->nindex++;
235
 
                    }
236
 
 
237
 
                    mi = (mod_instance_t) malloc(sizeof(struct mod_instance_st));
238
 
                    memset(mi, 0, sizeof(struct mod_instance_st));
239
 
 
240
 
                    mi->sm = sm;
241
 
                    mi->mod = mod;
242
 
                    mi->chain = chain;
243
 
                    mi->arg = (arg[0] == '\0') ? NULL : strdup(arg);
244
 
                    mi->seq = mod->init;
245
 
 
246
 
                    if((module_inits[i])(mi) != 0) {
247
 
                        log_debug(ZONE, "init for module '%s' (seq %d) failed", name, mi->seq);
248
 
 
249
 
                        free(mi);
250
 
 
251
 
                        if(mod->init == 0) {
252
 
                            xhash_zap(mm->modules, mod->name);
253
 
                            free(mod->name);
254
 
                            free(mod);
255
 
 
256
 
                            mm->nindex--;
257
 
 
258
 
                            melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0);
259
 
                            continue;
260
 
                        }
261
 
                    }
262
 
 
263
 
                    mod->init++;
264
 
 
265
 
                    *list = (mod_instance_t *) realloc(*list, sizeof(mod_instance_t) * (*nlist + 1));
266
 
                    (*list)[*nlist] = mi;
267
 
 
268
 
                    log_debug(ZONE, "module '%s' added to chain '%s' (order %d index %d seq %d)", mod->name, id, *nlist, mod->index, mi->seq);
269
 
 
270
 
                    (*nlist)++;
271
 
                }
272
 
            }
 
200
                } else {
 
201
                    #ifndef _WIN32
 
202
                      log_write(sm->log, LOG_ERR, "failed loading module '%s' to chain '%s' (%s)", name, id, dlerror());
 
203
                      if (mod->handle != NULL)
 
204
                          dlclose(mod->handle);
 
205
                    #else
 
206
                      log_write(sm->log, LOG_ERR, "failed loading module '%s' to chain '%s' (errcode: %x)", name, id, GetLastError());
 
207
                      if (mod->handle != NULL)
 
208
                          FreeLibrary((HMODULE) mod->handle);
 
209
                    #endif
 
210
 
 
211
                    melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0);
 
212
                    continue;
 
213
                }
 
214
            }
 
215
 
 
216
            mi = (mod_instance_t) calloc(1, sizeof(struct mod_instance_st));
 
217
 
 
218
            mi->sm = sm;
 
219
            mi->mod = mod;
 
220
            mi->chain = chain;
 
221
            mi->arg = (arg[0] == '\0') ? NULL : strdup(arg);
 
222
            mi->seq = mod->init;
 
223
 
 
224
            if(mod->module_init_fn(mi) != 0) {
 
225
                log_write(sm->log, LOG_ERR, "init for module '%s' (seq %d) failed", name, mi->seq);
 
226
                free(mi);
 
227
 
 
228
                if(mod->init == 0) {
 
229
                    xhash_zap(mm->modules, mod->name);
 
230
 
 
231
                    #ifndef _WIN32
 
232
                      if (mod->handle != NULL)
 
233
                          dlclose(mod->handle);
 
234
                    #else
 
235
                      if (mod->handle != NULL)
 
236
                          FreeLibrary((HMODULE) mod->handle);
 
237
                    #endif
 
238
 
 
239
                    free(mod->name);
 
240
                    free(mod);
 
241
 
 
242
                    mm->nindex--;
 
243
 
 
244
                    melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0);
 
245
                    continue;
 
246
                }
 
247
            }
 
248
 
 
249
            mod->init++;
 
250
 
 
251
            *list = (mod_instance_t *) realloc(*list, sizeof(mod_instance_t) * (*nlist + 1));
 
252
            (*list)[*nlist] = mi;
 
253
 
 
254
            log_write(sm->log, LOG_NOTICE, "module '%s' added to chain '%s' (order %d index %d seq %d)", mod->name, id, *nlist, mod->index, mi->seq);
 
255
 
 
256
            (*nlist)++;
273
257
 
274
258
            melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0);
275
259
        }
286
270
    if(mod->free != NULL)
287
271
        (mod->free)(mod);
288
272
 
 
273
    #ifndef _WIN32
 
274
        if (mod->handle != NULL)
 
275
            dlclose(mod->handle);
 
276
    #else
 
277
        if (mod->handle != NULL)
 
278
            FreeLibrary((HMODULE) mod->handle);
 
279
    #endif
 
280
 
289
281
    free(mod->name);
290
282
    free(mod);
291
283
}
387
379
    ret = 0;
388
380
    for(n = 0; n < mm->nsess_start; n++) {
389
381
        mi = mm->sess_start[n];
390
 
        if(mi == NULL || mi->mod->sess_start == NULL) {
 
382
        if(mi == NULL) {
 
383
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
384
            continue;
 
385
        }
 
386
        if(mi->mod->sess_start == NULL) {
391
387
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
392
388
            continue;
393
389
        }
413
409
 
414
410
    for(n = 0; n < mm->nsess_end; n++) {
415
411
        mi = mm->sess_end[n];
416
 
        if(mi == NULL || mi->mod->sess_end == NULL) {
 
412
        if(mi == NULL) {
 
413
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
414
            continue;
 
415
        }
 
416
        if(mi->mod->sess_end == NULL) {
417
417
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
418
418
            continue;
419
419
        }
437
437
    ret = mod_PASS;
438
438
    for(n = 0; n < mm->nin_sess; n++) {
439
439
        mi = mm->in_sess[n];
440
 
        if(mi == NULL || mi->mod->in_sess == NULL) {
 
440
        if(mi == NULL) {
 
441
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
442
            continue;
 
443
        }
 
444
        if(mi->mod->in_sess == NULL) {
441
445
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
442
446
            continue;
443
447
        }
462
466
 
463
467
    log_debug(ZONE, "dispatching in-router chain");
464
468
 
 
469
    if (mm != NULL && pkt != NULL )
465
470
    for(n = 0; n < mm->nin_router; n++) {
466
471
        mi = mm->in_router[n];
467
 
        if(mi == NULL || mi->mod->in_router == NULL) {
 
472
        if(mi == NULL) {
 
473
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
474
            continue;
 
475
        }
 
476
        if(mi->mod == NULL || mi->mod->in_router == NULL) {
468
477
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
469
478
            continue;
470
479
        }
491
500
 
492
501
    for(n = 0; n < mm->nout_sess; n++) {
493
502
        mi = mm->out_sess[n];
494
 
        if(mi == NULL || mi->mod->out_sess == NULL) {
 
503
        if(mi == NULL) {
 
504
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
505
            continue;
 
506
        }
 
507
        if(mi->mod->out_sess == NULL) {
495
508
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
496
509
            continue;
497
510
        }
518
531
 
519
532
    for(n = 0; n < mm->nout_router; n++) {
520
533
        mi = mm->out_router[n];
521
 
        if(mi == NULL || mi->mod->out_router == NULL) {
 
534
        if(mi == NULL) {
 
535
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
536
            continue;
 
537
        }
 
538
        if(mi->mod->out_router == NULL) {
522
539
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
523
540
            continue;
524
541
        }
544
561
 
545
562
    for(n = 0; n < mm->npkt_sm; n++) {
546
563
        mi = mm->pkt_sm[n];
547
 
        if(mi == NULL || mi->mod->pkt_sm == NULL) {
 
564
        if(mi == NULL) {
 
565
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
566
            continue;
 
567
        }
 
568
        if(mi->mod->pkt_sm == NULL) {
548
569
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
549
570
            continue;
550
571
        }
571
592
 
572
593
    for(n = 0; n < mm->npkt_user; n++) {
573
594
        mi = mm->pkt_user[n];
574
 
        if(mi == NULL || mi->mod->pkt_user == NULL) {
 
595
        if(mi == NULL) {
 
596
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
597
            continue;
 
598
        }
 
599
        if(mi->mod->pkt_user == NULL) {
575
600
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
576
601
            continue;
577
602
        }
598
623
 
599
624
    for(n = 0; n < mm->npkt_router; n++) {
600
625
        mi = mm->pkt_router[n];
601
 
        if(mi == NULL || mi->mod->pkt_router == NULL) {
 
626
        if(mi == NULL) {
 
627
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
628
            continue;
 
629
        }
 
630
        if(mi->mod->pkt_router == NULL) {
602
631
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
603
632
            continue;
604
633
        }
625
654
 
626
655
    for(n = 0; n < mm->nuser_load; n++) {
627
656
        mi = mm->user_load[n];
628
 
        if(mi == NULL || mi->mod->user_load == NULL) {
 
657
        if(mi == NULL) {
 
658
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
659
            continue;
 
660
        }
 
661
        if(mi->mod->user_load == NULL) {
629
662
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
630
663
            continue;
631
664
        }
652
685
 
653
686
    for(n = 0; n < mm->nuser_create; n++) {
654
687
        mi = mm->user_create[n];
655
 
        if(mi == NULL || mi->mod->user_create == NULL) {
 
688
        if(mi == NULL) {
 
689
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
690
            continue;
 
691
        }
 
692
        if(mi->mod->user_create == NULL) {
656
693
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
657
694
            continue;
658
695
        }
678
715
 
679
716
    for(n = 0; n < mm->nuser_delete; n++) {
680
717
        mi = mm->user_delete[n];
681
 
        if(mi == NULL || mi->mod->user_delete == NULL) {
 
718
        if(mi == NULL) {
 
719
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
720
            continue;
 
721
        }
 
722
        if(mi->mod->user_delete == NULL) {
682
723
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
683
724
            continue;
684
725
        }
690
731
 
691
732
    log_debug(ZONE, "user-delete chain returning");
692
733
}
 
734
 
 
735
/** disco extend */
 
736
void mm_disco_extend(mm_t mm, pkt_t pkt) {
 
737
    int n;
 
738
    mod_instance_t mi;
 
739
 
 
740
    log_debug(ZONE, "dispatching disco-extend chain");
 
741
 
 
742
    for(n = 0; n < mm->ndisco_extend; n++) {
 
743
        mi = mm->disco_extend[n];
 
744
        if(mi == NULL) {
 
745
            log_debug(ZONE, "module at index %d is not loaded yet", n);
 
746
            continue;
 
747
        }
 
748
        if(mi->mod->disco_extend == NULL) {
 
749
            log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name);
 
750
            continue;
 
751
        }
 
752
 
 
753
        log_debug(ZONE, "calling module %s", mi->mod->name);
 
754
 
 
755
        (mi->mod->disco_extend)(mi, pkt);
 
756
    }
 
757
 
 
758
    log_debug(ZONE, "disco-extend chain returning");
 
759
}