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

« back to all changes in this revision

Viewing changes to sm/mod_roster_publish.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:
 
1
/*
 
2
 * jabberd - Jabber Open Source Server
 
3
 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
 
4
 *                    Ryan Eatmon, Robert Norris
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
 
19
 */
 
20
 
 
21
#include "sm.h"
 
22
 
 
23
/** @file sm/mod_roster_publish.c
 
24
  * @brief roster publishing
 
25
  * @author Nikita Smirnov
 
26
  */
 
27
 
 
28
#ifndef NO_SM_CACHE
 
29
typedef struct _roster_publish_active_cache_st *_roster_publish_active_cache_t;
 
30
struct _roster_publish_active_cache_st {
 
31
    time_t time; // when cache was updated
 
32
    time_t active;
 
33
    char *jid_user;
 
34
};
 
35
typedef struct _roster_publish_group_cache_st *_roster_publish_group_cache_t;
 
36
struct _roster_publish_group_cache_st {
 
37
    time_t time; // when cache was updated
 
38
    char *groupid;
 
39
    char *groupname;
 
40
};
 
41
#endif
 
42
 
 
43
typedef struct _roster_publish_st {
 
44
    int publish, forcegroups, fixsubs, overridenames, mappedgroups;
 
45
    char *groupprefix, *groupsuffix, *removedomain;
 
46
    int groupprefixlen, groupsuffixlen;
 
47
    time_t active_cache_ttl;
 
48
    time_t group_cache_ttl;
 
49
#ifndef NO_SM_CACHE
 
50
    xht active_cache; // cache of values from 'active' storage,
 
51
                      // used to check that user exists in sm database
 
52
    xht group_cache; // cache of values from published-roster-groups storage
 
53
                     // used to map group id to group name
 
54
#endif
 
55
} *roster_publish_t;
 
56
 
 
57
#ifndef NO_SM_CACHE
 
58
/* free single item of active cache */
 
59
static void _roster_publish_free_active_cache_walker(xht cache, const char *key, void *val, void *arg) {
 
60
    _roster_publish_active_cache_t item = (_roster_publish_active_cache_t)val;
 
61
    free(item->jid_user);
 
62
    free(item);
 
63
}
 
64
/* free single item of group cache */
 
65
static void _roster_publish_free_group_cache_walker(xht cache, const char *key, void *val, void *arg) {
 
66
    _roster_publish_group_cache_t item = (_roster_publish_group_cache_t)val;
 
67
    free(item->groupid);
 
68
    free(item->groupname);
 
69
    free(item);
 
70
}
 
71
#endif
 
72
 
 
73
/*
 
74
 * get group's descriptive name by it's text id
 
75
 * returned value needs to be freed by caller
 
76
 */
 
77
static char *_roster_publish_get_group_name(sm_t sm, roster_publish_t rp, const char *groupid)
 
78
{
 
79
    os_t os;
 
80
    os_object_t o;
 
81
    char *str;
 
82
    char *group;
 
83
 
 
84
#ifndef NO_SM_CACHE
 
85
    _roster_publish_group_cache_t group_cached;
 
86
 
 
87
    /* check for remembered group value in cache */
 
88
    if( rp->group_cache_ttl ) {
 
89
        if( rp->group_cache ) {
 
90
            group_cached = xhash_get(rp->group_cache, groupid);
 
91
            if( group_cached != NULL ) {
 
92
                if( (time(NULL) - group_cached->time) >= rp->group_cache_ttl ) {
 
93
                    log_debug(ZONE,"group cache: expiring cached value for %s",groupid);
 
94
                    xhash_zap(rp->group_cache, groupid);
 
95
                    free(group_cached);
 
96
                } else {
 
97
                    log_debug(ZONE,"group cache: returning cached value for %s",groupid);
 
98
                    return strdup(group_cached->groupname);
 
99
                }
 
100
            }
 
101
        } else {
 
102
            log_debug(ZONE,"group cache: creating cache");
 
103
            rp->group_cache = xhash_new(401);
 
104
        }
 
105
    }
 
106
#endif
 
107
 
 
108
    if(storage_get(sm->st, "published-roster-groups", groupid, NULL, &os) == st_SUCCESS && os_iter_first(os)) {
 
109
        o = os_iter_object(os);
 
110
        os_object_get_str(os, o, "groupname", &str);
 
111
        if( str ) {
 
112
            group=strdup(str);
 
113
        } else {
 
114
            group=NULL;
 
115
        }
 
116
        os_free(os);
 
117
#ifndef NO_SM_CACHE
 
118
        if( rp->group_cache_ttl && group ) {
 
119
            log_debug(ZONE,"group cache: updating cache value for %s",groupid);
 
120
            group_cached = calloc(1, sizeof(struct _roster_publish_group_cache_st));
 
121
            group_cached->time = time(NULL);
 
122
            group_cached->groupid = strdup(groupid);
 
123
            group_cached->groupname = strdup(group);
 
124
            xhash_put(rp->group_cache, group_cached->groupid, group_cached);
 
125
        }
 
126
#endif
 
127
        return group;
 
128
    } else {
 
129
        return NULL;
 
130
    }
 
131
}
 
132
 
 
133
/* free a single roster item */
 
134
static void _roster_publish_free_walker(xht roster, const char *key, void *val, void *arg)
 
135
{
 
136
    item_t item = (item_t) val;
 
137
    int i;
 
138
 
 
139
    jid_free(item->jid);
 
140
    
 
141
    if(item->name != NULL)
 
142
        free(item->name);
 
143
 
 
144
    for(i = 0; i < item->ngroups; i++)
 
145
        free(item->groups[i]);
 
146
    free(item->groups);
 
147
 
 
148
    free(item);
 
149
}
 
150
 
 
151
static void _roster_publish_save_item(user_t user, item_t item) {
 
152
    os_t os;
 
153
    os_object_t o;
 
154
    char filter[4096];
 
155
    int i;
 
156
 
 
157
    log_debug(ZONE, "saving roster item %s for %s", jid_full(item->jid), jid_user(user->jid));
 
158
 
 
159
    os = os_new();
 
160
    o = os_object_new(os);
 
161
 
 
162
    os_object_put(o, "jid", jid_full(item->jid), os_type_STRING);
 
163
 
 
164
    if(item->name != NULL)
 
165
        os_object_put(o, "name", item->name, os_type_STRING);
 
166
 
 
167
    os_object_put(o, "to", &item->to, os_type_BOOLEAN);
 
168
    os_object_put(o, "from", &item->from, os_type_BOOLEAN);
 
169
    os_object_put(o, "ask", &item->ask, os_type_INTEGER);
 
170
 
 
171
    snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid));
 
172
 
 
173
    storage_replace(user->sm->st, "roster-items", jid_user(user->jid), filter, os);
 
174
 
 
175
    os_free(os);
 
176
 
 
177
    snprintf(filter, 4096, "(jid=%s)", jid_full(item->jid));
 
178
 
 
179
    if(item->ngroups == 0) {
 
180
        storage_delete(user->sm->st, "roster-groups", jid_user(user->jid), filter);
 
181
        return;
 
182
    }
 
183
 
 
184
    os = os_new();
 
185
    
 
186
    for(i = 0; i < item->ngroups; i++) {
 
187
        o = os_object_new(os);
 
188
 
 
189
        os_object_put(o, "jid", jid_full(item->jid), os_type_STRING);
 
190
        os_object_put(o, "group", item->groups[i], os_type_STRING);
 
191
    }
 
192
 
 
193
    storage_replace(user->sm->st, "roster-groups", jid_user(user->jid), filter, os);
 
194
 
 
195
    os_free(os);
 
196
}
 
197
 
 
198
/** publish the roster from the database */
 
199
static int _roster_publish_user_load(mod_instance_t mi, user_t user) {
 
200
    roster_publish_t roster_publish = (roster_publish_t) mi->mod->private;
 
201
    os_t os, os_active;
 
202
    os_object_t o, o_active;
 
203
    os_type_t ot, ot_active;
 
204
    char *str, *group, filter[4096];
 
205
    int i,j,gpos,found,delete,checksm,userinsm,tmp_to,tmp_from,tmp_do_change;
 
206
    item_t item;
 
207
    jid_t jid;
 
208
#ifndef NO_SM_CACHE
 
209
    _roster_publish_active_cache_t active_cached;
 
210
#endif
 
211
 
 
212
    /* update roster to match published roster */
 
213
    if( roster_publish->publish) {
 
214
        /* free if necessary */
 
215
        if(user->roster == NULL) {
 
216
            log_write(user->sm->log, LOG_NOTICE, "roster_publish: no roster for %s",jid_user(user->jid));
 
217
            return 0;
 
218
        }
 
219
 
 
220
        log_debug(ZONE, "publishing roster for %s",jid_user(user->jid));
 
221
        /* get published roster */
 
222
        if( storage_get(user->sm->st, "published-roster", "", NULL, &os) == st_SUCCESS ) {
 
223
            if(os_iter_first(os)) {
 
224
                /* iterate on published roster */
 
225
                jid = NULL;
 
226
                do {
 
227
                    o = os_iter_object(os);
 
228
                    if(os_object_get_str(os, o, "jid", &str)) {
 
229
                        if( strcmp(str,jid_user(user->jid)) == 0 ) {
 
230
                            /* not adding self */
 
231
                            continue; /* do { } while( os_iter_next ) */
 
232
                        }
 
233
                        /* check that published item exists in sm database */
 
234
                        checksm=0;
 
235
                        if( jid ) jid_free(jid);
 
236
                        jid = jid_new(str, -1);
 
237
                        if( roster_publish->removedomain ) {
 
238
                            if( strcmp(jid->domain,roster_publish->removedomain) == 0 ) {
 
239
                                checksm = 1;
 
240
                            }
 
241
                        }
 
242
                        if( checksm ) {
 
243
                            /* is this a hack? but i want to know was the user activated in sm or no? */
 
244
#ifndef NO_SM_CACHE
 
245
                            /* check for remembered active value in cache */
 
246
                            userinsm = -1;
 
247
                            if( roster_publish->active_cache_ttl ) {
 
248
                                if( roster_publish->active_cache ) {
 
249
                                    active_cached = xhash_get(roster_publish->active_cache, jid_user(jid));
 
250
                                    if( active_cached != NULL ) {
 
251
                                        if( (time(NULL) - active_cached->time) >= roster_publish->active_cache_ttl ) {
 
252
                                            xhash_zap(roster_publish->active_cache, jid_user(jid));
 
253
                                            free(active_cached);
 
254
                                        } else {
 
255
                                            if( active_cached->active ) {
 
256
                                                userinsm = 1;
 
257
                                            } else {
 
258
                                                userinsm = 0;
 
259
                                            }
 
260
                                        }
 
261
                                    }
 
262
                                } else {
 
263
                                    roster_publish->active_cache = xhash_new(401);
 
264
                                }
 
265
                            }
 
266
                            if( userinsm == -1 ) {
 
267
                                if( roster_publish->active_cache_ttl ) {
 
268
                                    active_cached = calloc(1, sizeof(struct _roster_publish_active_cache_st));
 
269
                                    active_cached->time = time(NULL);
 
270
                                }
 
271
#endif
 
272
                                if(storage_get(user->sm->st, "active", jid_user(jid), NULL, &os_active) == st_SUCCESS
 
273
                                        && os_iter_first(os_active)) {
 
274
#ifndef NO_SM_CACHE
 
275
                                    if( roster_publish->active_cache_ttl ) {
 
276
                                        o_active = os_iter_object(os_active);
 
277
                                        os_object_get_time(os_active, o_active, "time", &active_cached->active);
 
278
                                    }
 
279
#endif
 
280
                                    os_free(os_active);
 
281
                                    userinsm = 1;
 
282
                                } else {
 
283
#ifndef NO_SM_CACHE
 
284
                                    if( roster_publish->active_cache_ttl ) {
 
285
                                        active_cached->active = 0;
 
286
                                    }
 
287
#endif
 
288
                                    userinsm = 0;
 
289
                                }
 
290
#ifndef NO_SM_CACHE
 
291
                                if( roster_publish->active_cache_ttl ) {
 
292
                                    active_cached->jid_user = strdup(jid_user(jid));
 
293
                                    xhash_put(roster_publish->active_cache, active_cached->jid_user, active_cached);
 
294
                                }
 
295
                            } // if( userinsm == -1 )
 
296
#endif
 
297
                        } // if( checksm )
 
298
                        item = xhash_get(user->roster,jid_user(jid));
 
299
                        if( item == NULL ) {
 
300
                            /* user has no this jid in his roster */
 
301
                            /* if we checking sm database and user is not in it, not adding */
 
302
                            if( checksm && !userinsm ) {
 
303
                                log_debug(ZONE, "published user %s has no record in sm, not adding", jid_user(jid));
 
304
                                continue; /* do { } while( os_iter_next ) */
 
305
                            }
 
306
                            log_debug(ZONE, "user has no %s in roster, adding", jid_user(jid));
 
307
                            item = (item_t) calloc(1, sizeof(struct item_st));
 
308
 
 
309
                            item->jid = jid_new(jid_user(jid), -1);
 
310
                            if(item->jid == NULL) {
 
311
                                log_debug(ZONE, "eek! invalid jid %s, skipping it", jid_user(jid));
 
312
                                log_write(user->sm->log, LOG_ERR, "roster_publish: eek! invalid jid %s, skipping it", jid_user(jid));
 
313
                                /* nvs: is it needed? */
 
314
                                free(item);
 
315
                                /* nvs: is it needed? */
 
316
                            } else {
 
317
                                os_object_get_str(os, o, "group", &str);
 
318
                                if( roster_publish->mappedgroups ) {
 
319
                                    group = _roster_publish_get_group_name(user->sm, roster_publish, str); // don't forget to free group
 
320
                                } else {
 
321
                                    group = strdup(str);
 
322
                                }
 
323
                                if( group ) {
 
324
                                    item->groups = realloc(item->groups, sizeof(char *) * (item->ngroups + 1));
 
325
                                    item->groups[item->ngroups] = group;
 
326
                                    item->ngroups++;
 
327
 
 
328
                                    if(os_object_get_str(os, o, "name", &str))
 
329
                                        item->name = strdup(str);
 
330
 
 
331
                                    os_object_get_bool(os, o, "to", &item->to);
 
332
                                    os_object_get_bool(os, o, "from", &item->from);
 
333
                                    os_object_get_int(os, o, "ask", &item->ask);
 
334
 
 
335
                                    log_debug(ZONE, "adding %s to roster from template (to %d from %d ask %d name %s)", jid_full(item->jid), item->to, item->from, item->ask, item->name);
 
336
 
 
337
                                    /* its good */
 
338
                                    xhash_put(user->roster, jid_full(item->jid), (void *) item);
 
339
                                    _roster_publish_save_item(user,item);
 
340
                                } else {
 
341
                                    log_write(user->sm->log, LOG_ERR, "roster_publish: unknown published group id '%s' for %s",str,jid_full(item->jid));
 
342
                                    free(item);
 
343
                                }
 
344
                            }
 
345
                        }
 
346
                        else /* if( item == NULL ) else ... : here item != NULL : user has this jid in his roster */
 
347
                        {
 
348
                            /* if we checking sm database and user is not in it, remove it from roster */
 
349
                            if( checksm && !userinsm ) {
 
350
                                log_debug(ZONE, "published user %s has no record in sm, deleting from roster", jid_user(jid));
 
351
                                snprintf(filter, 4096, "(jid=%s)", jid_full(jid));
 
352
                                storage_delete(user->sm->st, "roster-items", jid_user(user->jid), filter);
 
353
                                snprintf(filter, 4096, "(jid=%s)", jid_full(jid));
 
354
                                storage_delete(user->sm->st, "roster-groups", jid_user(user->jid), filter);
 
355
 
 
356
                                xhash_zap(user->roster, jid_full(jid));
 
357
                                _roster_publish_free_walker(NULL, (const char *) jid_full(jid), (void *) item, NULL);
 
358
                                continue; /* do { } while( os_iter_next ) */
 
359
                            }
 
360
                            if( roster_publish->fixsubs ) {
 
361
                                /* check subscriptions and correct if needed */
 
362
                                os_object_get_bool(os, o, "to", &tmp_to);
 
363
                                os_object_get_bool(os, o, "from", &tmp_from);
 
364
                                if( item->to != tmp_to || item->from != tmp_from ) {
 
365
                                    item->to = tmp_to;
 
366
                                    item->from = tmp_from;
 
367
                                    log_debug(ZONE, "fixsubs in roster %s, item %s",jid_user(user->jid),jid_user(item->jid));
 
368
                                    xhash_put(user->roster, jid_full(item->jid), (void *) item);
 
369
                                    _roster_publish_save_item(user,item);
 
370
                                }
 
371
                            }
 
372
                            if( roster_publish->overridenames ) {
 
373
                                /* override display name if it differs */
 
374
                                if(os_object_get_str(os, o, "name", &str)) {
 
375
                                    if( str ) {
 
376
                                        tmp_do_change = 0;
 
377
                                        if( ! item->name ) {
 
378
                                            tmp_do_change = 1;
 
379
                                        } else {
 
380
                                            if( strcmp(item->name,str) != 0 ) {
 
381
                                                tmp_do_change = 1;
 
382
                                            }
 
383
                                        }
 
384
                                        if( tmp_do_change ) {
 
385
                                            log_debug(ZONE, "replacing name for %s in roster of %s", jid_full(item->jid),jid_user(user->jid));
 
386
                                            item->name = strdup(str);
 
387
                                            xhash_put(user->roster, jid_full(item->jid), (void *) item);
 
388
                                            _roster_publish_save_item(user,item);
 
389
                                        }
 
390
                                    } else {
 
391
                                        log_debug(ZONE,"warning: name is null in published roster for item %s",jid_full(item->jid));
 
392
                                    }
 
393
                                }
 
394
                            }
 
395
                            if( roster_publish->forcegroups ) {
 
396
                                /* item already in roster, check groups if needed */
 
397
                                os_object_get_str(os, o, "group", &str);
 
398
                                if( roster_publish->mappedgroups ) {
 
399
                                    group = _roster_publish_get_group_name(user->sm, roster_publish, str); // don't forget to free group
 
400
                                    if( !group ) {
 
401
                                        log_write(user->sm->log, LOG_ERR, "roster_publish: unknown published group id '%s' for %s",str, jid_full(item->jid));
 
402
                                        continue; /* do { } while( os_iter_next ) */
 
403
                                    }
 
404
                                } else {
 
405
                                    group = strdup(str);
 
406
                                }
 
407
                                /* find published roster item's group in user's roster */
 
408
                                found = 0;
 
409
                                for(i = 0; i < item->ngroups; i++) {
 
410
                                    if( strcmp(item->groups[i],group) == 0 ) {
 
411
                                        found = 1;
 
412
                                        /* do not break loop, give groups that matches
 
413
                                         * prefix and suffix to be deleted
 
414
                                         */
 
415
                                    } else {
 
416
                                        /* check if user's roster group matches
 
417
                                         * prefix or suffix given in config
 
418
                                         * and delete such groups (and thus they will be replaced)
 
419
                                         */
 
420
                                        delete = 0;
 
421
                                        if( roster_publish->groupprefix ) {
 
422
                                            if( strncmp(item->groups[i],roster_publish->groupprefix,roster_publish->groupprefixlen) == 0 ) {
 
423
                                                delete = 1;
 
424
                                            }
 
425
                                        }
 
426
                                        if( !delete && roster_publish->groupsuffix ) {
 
427
                                            gpos=strlen(item->groups[i])-roster_publish->groupsuffixlen;
 
428
                                            if( gpos > 0 ) {
 
429
                                                if( strcmp(item->groups[i]+gpos,roster_publish->groupsuffix) == 0 ) {
 
430
                                                    delete = 1;
 
431
                                                }
 
432
                                            }
 
433
                                        }
 
434
                                        /* remove group from roster item */
 
435
                                        if( delete ) {
 
436
                                            free(item->groups[i]);
 
437
                                            for(j = i; j < item->ngroups-1; j++) {
 
438
                                                item->groups[j]=item->groups[j+1];
 
439
                                            }
 
440
                                            item->ngroups--;
 
441
                                            item->groups = realloc(item->groups, sizeof(char *) * (item->ngroups));
 
442
                                        }
 
443
                                    }
 
444
                                } /* for(i... */
 
445
                                if( !found ) {
 
446
                                    log_debug(ZONE, "adding group %s to item %s for user %s",group,jid_user(item->jid),jid_user(user->jid));
 
447
                                    item->groups = realloc(item->groups, sizeof(char *) * (item->ngroups + 1));
 
448
                                    item->groups[item->ngroups] = group; // will be freed
 
449
                                    item->ngroups++;
 
450
                                    /* replace item */
 
451
                                    xhash_put(user->roster, jid_full(item->jid), (void *) item);
 
452
                                    _roster_publish_save_item(user,item);
 
453
                                } else {
 
454
                                    free(group);
 
455
                                }
 
456
                            } /* else if( roster_publish->forcegroups ) */
 
457
                        } /* end of if if( item == NULL ) */
 
458
                    } /* if( os_object_get(...) */
 
459
                } while(os_iter_next(os));
 
460
                if( jid ) jid_free(jid);
 
461
            }
 
462
            os_free(os);
 
463
        }
 
464
    }
 
465
    return 0;
 
466
}
 
467
 
 
468
static void _roster_publish_free(module_t mod) {
 
469
    roster_publish_t roster_publish = (roster_publish_t) mod->private;
 
470
 
 
471
#ifndef NO_SM_CACHE
 
472
    if( roster_publish->active_cache ) {
 
473
        xhash_walk(roster_publish->active_cache,_roster_publish_free_active_cache_walker,NULL);
 
474
        xhash_free(roster_publish->active_cache);
 
475
    }
 
476
    if( roster_publish->group_cache ) {
 
477
        xhash_walk(roster_publish->group_cache,_roster_publish_free_group_cache_walker,NULL);
 
478
        xhash_free(roster_publish->group_cache);
 
479
    }
 
480
#endif
 
481
    free(roster_publish);
 
482
}
 
483
 
 
484
DLLEXPORT int module_init(mod_instance_t mi, char *arg) {
 
485
    module_t mod = mi->mod;
 
486
    roster_publish_t roster_publish;
 
487
 
 
488
    if(mod->init) return 0;
 
489
 
 
490
    roster_publish = (roster_publish_t) calloc(1, sizeof(struct _roster_publish_st));
 
491
 
 
492
    if( config_get_one(mod->mm->sm->config, "user.template.publish", 0) ) {
 
493
        roster_publish->publish = 1;
 
494
        roster_publish->removedomain = config_get_one(mod->mm->sm->config, "user.template.publish.check-remove-domain", 0);
 
495
        roster_publish->fixsubs = j_atoi(config_get_one(mod->mm->sm->config, "user.template.publish.fix-subscriptions", 0), 0);
 
496
        roster_publish->overridenames = j_atoi(config_get_one(mod->mm->sm->config, "user.template.publish.override-names", 0), 0);
 
497
        roster_publish->mappedgroups = j_atoi(config_get_one(mod->mm->sm->config, "user.template.publish.mapped-groups.map-groups", 0), 0);
 
498
#ifndef NO_SM_CACHE
 
499
        roster_publish->active_cache_ttl = j_atoi(config_get_one(mod->mm->sm->config, "user.template.publish.active-cache-ttl", 0), 0);
 
500
        roster_publish->group_cache_ttl = j_atoi(config_get_one(mod->mm->sm->config, "user.template.publish.mapped-groups.group-cache-ttl", 0), 0);
 
501
#endif
 
502
        if( config_get_one(mod->mm->sm->config, "user.template.publish.force-groups", 0) ) {
 
503
            roster_publish->forcegroups = 1;
 
504
            if( roster_publish->groupprefix = config_get_one(mod->mm->sm->config, "user.template.publish.force-groups.prefix", 0) ) {
 
505
                roster_publish->groupprefixlen = strlen(roster_publish->groupprefix);
 
506
            }
 
507
            if( roster_publish->groupsuffix = config_get_one(mod->mm->sm->config, "user.template.publish.force-groups.suffix", 0) ) {
 
508
                roster_publish->groupsuffixlen = strlen(roster_publish->groupsuffix);
 
509
            }
 
510
        } else {
 
511
            roster_publish->forcegroups = 0;
 
512
        }
 
513
    } else {
 
514
        roster_publish->publish = 0;
 
515
    }
 
516
    mod->private = roster_publish;
 
517
 
 
518
    mod->user_load = _roster_publish_user_load;
 
519
    mod->free = _roster_publish_free;
 
520
 
 
521
    return 0;
 
522
}
 
523
 
 
524
// vim: shiftwidth=4