Ticket #43: jabberd-sqlite.patch

File jabberd-sqlite.patch, 17.0 KB (added by smoku, 20 months ago)

Patch by Reinhard Max <max@…>

  • c2s/Makefile.am

     
    22 
    33bin_PROGRAMS = c2s 
    44 
    5 c2s_SOURCES = authreg.c authreg_anon.c authreg_db.c authreg_ldap.c authreg_mysql.c authreg_pam.c authreg_pgsql.c authreg_pipe.c bind.c c2s.c main.c sm.c 
     5c2s_SOURCES = authreg.c authreg_anon.c authreg_db.c authreg_ldap.c authreg_mysql.c authreg_pam.c authreg_pgsql.c authreg_pipe.c authreg_sqlite.c bind.c c2s.c main.c sm.c 
    66noinst_HEADERS = c2s.h 
    77 
    88c2s_LDADD = $(top_builddir)/sx/libsx.la \ 
  • c2s/authreg.c

     
    4949#ifdef STORAGE_ANON 
    5050extern int ar_anon_init(authreg_t); 
    5151#endif 
     52#ifdef STORAGE_SQLITE 
     53extern int ar_sqlite_init(authreg_t); 
     54#endif 
    5255 
    5356char *module_names[] = { 
    5457#ifdef STORAGE_MYSQL 
     
    7275#ifdef STORAGE_ANON 
    7376    "anon", 
    7477#endif 
     78#ifdef STORAGE_SQLITE 
     79    "sqlite", 
     80#endif 
    7581    NULL 
    7682}; 
    7783 
     
    97103#ifdef STORAGE_ANON 
    98104    ar_anon_init, 
    99105#endif 
     106#ifdef STORAGE_SQLITE 
     107    ar_sqlite_init, 
     108#endif 
    100109    NULL 
    101110}; 
    102111 
  • c2s/authreg_sqlite.c

     
     1/* 
     2 * jabberd - Jabber Open Source Server 
     3 * Copyright (c) 2002-2003 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/** 
     22 * @file authreg_sqlite.c 
     23 * @brief sqlite 3 authentication code for jabberd2 
     24 * @author Christopher Parker 
     25 * @bug no known bugs 
     26 */ 
     27 
     28/* Released under the GPL by Christopher Parker <parkerc@i-vsn.com>, IVSN 
     29 * to the Jabberd project. 
     30 */ 
     31 
     32#include "c2s.h" 
     33 
     34#ifdef STORAGE_SQLITE 
     35 
     36#include <sqlite3.h> 
     37 
     38typedef struct moddata_st { 
     39    sqlite3 *db; 
     40    int txn; 
     41    sqlite3_stmt *user_exists_stmt; 
     42    sqlite3_stmt *get_password_stmt; 
     43    sqlite3_stmt *check_password_stmt; 
     44    sqlite3_stmt *set_password_stmt; 
     45    sqlite3_stmt *get_zerok_stmt; 
     46    sqlite3_stmt *set_zerok_stmt; 
     47    sqlite3_stmt *create_user_stmt; 
     48    sqlite3_stmt *delete_user_stmt; 
     49} *moddata_t; 
     50 
     51static sqlite3_stmt* 
     52_get_stmt(authreg_t ar, sqlite3 *db, sqlite3_stmt **stmt, char *sql) 
     53{ 
     54    int res; 
     55    if (*stmt == NULL) { 
     56        res = sqlite3_prepare(db, sql, -1, stmt, 0); 
     57        if (res != SQLITE_OK) { 
     58            log_write(ar->c2s->log, LOG_ERR, "sqlite (authreg): %s", sqlite3_errmsg(db)); 
     59            return NULL; 
     60        } 
     61    } 
     62    return *stmt; 
     63} 
     64 
     65/** 
     66 * @return 1 if the user exists, 0 if not  
     67 */ 
     68static int 
     69_ar_sqlite_user_exists(authreg_t ar, char *username, char *realm) 
     70{ 
     71 
     72    sqlite3_stmt *stmt; 
     73    char *sql = 
     74        "SELECT username FROM authreg WHERE username = ? AND realm = ?"; 
     75    moddata_t data = (moddata_t) ar->private; 
     76    int res, ret = 0; 
     77     
     78    log_debug(ZONE, "sqlite (authreg): user exists"); 
     79     
     80    stmt = _get_stmt(ar, data->db, &data->user_exists_stmt, sql); 
     81    if (stmt == NULL) { 
     82        return 0; 
     83    } 
     84 
     85    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     86    sqlite3_bind_text(stmt, 2, realm, -1, SQLITE_STATIC); 
     87 
     88    res = sqlite3_step(stmt); 
     89    if (res == SQLITE_ROW) { 
     90        log_debug(ZONE, "sqlite (authreg): user exists : yes"); 
     91        ret = 1; 
     92    } else { 
     93        log_debug(ZONE, "sqlite (authreg): user exists : no"); 
     94    } 
     95    sqlite3_reset(stmt); 
     96    return ret; 
     97} 
     98 
     99/** 
     100 * @return 0 is password is populated, 1 if not  
     101 */ 
     102static int 
     103_ar_sqlite_get_password(authreg_t ar, char *username, char *realm, 
     104                        char password[257]) 
     105{ 
     106 
     107    sqlite3_stmt *stmt; 
     108    char *sql = 
     109        "SELECT password FROM authreg WHERE username = ? and realm = ?"; 
     110    moddata_t data = (moddata_t) ar->private; 
     111    int res, ret=1; 
     112     
     113    log_debug(ZONE, "sqlite (authreg): get password"); 
     114     
     115    stmt = _get_stmt (ar, data->db, &data->get_password_stmt, sql); 
     116    if (stmt == NULL) { 
     117        return 1; 
     118    } 
     119 
     120    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     121    sqlite3_bind_text(stmt, 2, realm, -1, SQLITE_STATIC); 
     122     
     123    res = sqlite3_step(stmt); 
     124    if (res == SQLITE_ROW) { 
     125        strcpy(password, (char *) sqlite3_column_text(stmt, 0)); 
     126        ret = 0; 
     127    } 
     128    sqlite3_reset(stmt); 
     129    return ret; 
     130} 
     131 
     132/** 
     133 * @return 0 if the given password matches the password stored in the database, !0 if not 
     134 */ 
     135static int 
     136_ar_sqlite_check_password(authreg_t ar, char *username, char *realm, 
     137                          char password[257]) 
     138{ 
     139 
     140    sqlite3_stmt *stmt; 
     141    moddata_t data = (moddata_t) ar->private; 
     142    int res, ret=1; 
     143    char *sql = 
     144        "SELECT username FROM authreg WHERE username = ? AND password = ? AND realm = ?"; 
     145 
     146    log_debug(ZONE, "sqlite (authreg): check password"); 
     147 
     148    stmt = _get_stmt(ar, data->db, &data->check_password_stmt, sql); 
     149    if (stmt == NULL) { 
     150        return 1; 
     151    } 
     152 
     153    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     154    sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC); 
     155    sqlite3_bind_text(stmt, 3, realm, -1, SQLITE_STATIC); 
     156     
     157    res = sqlite3_step(stmt); 
     158    if (res == SQLITE_ROW) { 
     159        ret = 0; 
     160    } 
     161    sqlite3_reset(stmt); 
     162    return ret; 
     163} 
     164 
     165/** 
     166 * @return 0 if password is stored, 1 if not 
     167 */ 
     168static int 
     169_ar_sqlite_set_password(authreg_t ar, char *username, char *realm, 
     170                        char password[257]) 
     171{ 
     172 
     173    sqlite3_stmt *stmt; 
     174    moddata_t data = (moddata_t) ar->private; 
     175    int res, ret = 0; 
     176 
     177    char *sql = 
     178        "UPDATE authreg SET password = ? WHERE username = ? AND realm = ?"; 
     179     
     180    log_debug(ZONE, "sqlite (authreg): set password"); 
     181     
     182    stmt = _get_stmt(ar, data->db, &data->set_password_stmt, sql); 
     183    if (stmt == NULL) { 
     184        return 1; 
     185    } 
     186 
     187    sqlite3_bind_text(stmt, 1, password, -1, SQLITE_STATIC); 
     188    sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC); 
     189    sqlite3_bind_text(stmt, 3, realm, -1, SQLITE_STATIC); 
     190     
     191    res = sqlite3_step(stmt); 
     192    if (res != SQLITE_DONE) { 
     193        log_write(ar->c2s->log, LOG_ERR, "sqlite (authreg): %s", sqlite3_errmsg (data->db)); 
     194        ret = 1; 
     195    } 
     196    sqlite3_reset(stmt); 
     197    return ret; 
     198} 
     199 
     200/** 
     201 * @return 0 if zerok is returned, 1 if not 
     202 */ 
     203static int 
     204_ar_sqlite_get_zerok(authreg_t ar, char *username, char *realm, 
     205                     char hash[41], char token[11], int *sequence) 
     206{ 
     207    sqlite3_stmt *stmt; 
     208    moddata_t data = (moddata_t) ar->private; 
     209    int res, ret = 1; 
     210     
     211    char *sql = 
     212        "SELECT hash, token, sequence FROM authreg WHERE username = ? AND realm = ?"; 
     213     
     214    log_debug(ZONE, "sqlite (authreg): getzerok"); 
     215 
     216    stmt = _get_stmt(ar, data->db, &data->get_zerok_stmt, sql); 
     217    if (stmt == NULL) { 
     218        return 1; 
     219    } 
     220 
     221    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     222    sqlite3_bind_text(stmt, 2, realm, -1, SQLITE_STATIC); 
     223     
     224    res = sqlite3_step(stmt); 
     225    if (res == SQLITE_ROW) { 
     226        strncpy(hash, (char *) sqlite3_column_text(stmt, 0), 41); 
     227        strncpy(token, (char *) sqlite3_column_text(stmt, 1), 11); 
     228        *sequence = sqlite3_column_int(stmt, 2); 
     229         
     230        ret = 0; 
     231    } 
     232    sqlite3_reset(stmt); 
     233    return ret; 
     234} 
     235 
     236/** 
     237 * @return 0 if zerok is set, 1 if not 
     238 */ 
     239static int 
     240_ar_sqlite_set_zerok(authreg_t ar, char *username, char *realm, 
     241                     char hash[41], char token[11], int sequence) 
     242{ 
     243    sqlite3_stmt *stmt; 
     244    moddata_t data = (moddata_t) ar->private; 
     245    int res, ret = 0; 
     246 
     247    char *sql = 
     248        "UPDATE authreg SET hash = ?, token = ?, sequence = ? WHERE username = ? AND realm = ?"; 
     249     
     250    log_debug(ZONE, "sqlite (authreg): set zerok"); 
     251     
     252    stmt = _get_stmt(ar, data->db, &data->set_zerok_stmt, sql); 
     253    if (stmt == NULL) { 
     254        return 1; 
     255    } 
     256     
     257    sqlite3_bind_text(stmt, 1, hash, -1, SQLITE_STATIC); 
     258    sqlite3_bind_text(stmt, 2, token, -1, SQLITE_STATIC); 
     259    sqlite3_bind_int(stmt, 3, sequence); 
     260    sqlite3_bind_text(stmt, 4, username, -1, SQLITE_STATIC); 
     261    sqlite3_bind_text(stmt, 5, realm, -1, SQLITE_STATIC); 
     262 
     263    res = sqlite3_step(stmt); 
     264    if (res != SQLITE_DONE) { 
     265        log_write(ar->c2s->log, LOG_ERR, "sqlite (authreg): %s", sqlite3_errmsg (data->db)); 
     266        ret = 1; 
     267    } 
     268    sqlite3_reset(stmt); 
     269    return ret; 
     270} 
     271 
     272/** 
     273 * @return 0 if user is created, 1 if not 
     274 */ 
     275static int 
     276_ar_sqlite_create_user(authreg_t ar, char *username, char *realm) 
     277{ 
     278    sqlite3_stmt *stmt; 
     279    moddata_t data = data = (moddata_t) ar->private; 
     280    int res, ret = 0; 
     281 
     282    char *sql = 
     283        "INSERT INTO authreg ( username, realm ) VALUES ( ?, ? )"; 
     284     
     285    log_debug(ZONE, "sqlite (authreg): create user"); 
     286     
     287    stmt = _get_stmt(ar, data->db, &data->create_user_stmt, sql); 
     288    if (stmt == NULL) { 
     289        return 1; 
     290    } 
     291 
     292    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     293    sqlite3_bind_text(stmt, 2, realm, -1, SQLITE_STATIC); 
     294     
     295    res = sqlite3_step(stmt); 
     296    if (res != SQLITE_DONE) { 
     297        log_write(ar->c2s->log, LOG_ERR, "sqlite (authreg): %s", sqlite3_errmsg (data->db)); 
     298        ret = 1; 
     299    } 
     300    sqlite3_reset(stmt); 
     301    return 0; 
     302} 
     303 
     304/** 
     305 * @return 0 if user is deleted, 1 if not 
     306 */ 
     307static int 
     308_ar_sqlite_delete_user(authreg_t ar, char *username, char *realm) 
     309{ 
     310    sqlite3_stmt *stmt; 
     311    moddata_t data = (moddata_t) ar->private; 
     312    int res, ret = 0; 
     313 
     314    char *sql = "DELETE FROM authreg WHERE username = ? AND realm = ?"; 
     315     
     316    log_debug(ZONE, "sqlite (authreg): delete user"); 
     317     
     318    stmt = _get_stmt(ar, data->db, &data->delete_user_stmt, sql); 
     319    if (stmt == NULL) { 
     320        return 1; 
     321    } 
     322 
     323    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); 
     324    sqlite3_bind_text(stmt, 2, realm, -1, SQLITE_STATIC); 
     325     
     326    res = sqlite3_step(stmt); 
     327    if (res != SQLITE_DONE) { 
     328        log_write(ar->c2s->log, LOG_ERR, "sqlite (authreg): %s", sqlite3_errmsg (data->db)); 
     329        ret = 1; 
     330    } 
     331    sqlite3_reset(stmt); 
     332     
     333    return ret; 
     334} 
     335 
     336/** 
     337 * @return does not return 
     338 */ 
     339static void 
     340_ar_sqlite_free(authreg_t ar) 
     341{ 
     342    log_debug(ZONE, "sqlite (authreg): free"); 
     343     
     344    moddata_t data = (moddata_t) ar->private; 
     345 
     346    sqlite3_finalize(data->user_exists_stmt); 
     347    sqlite3_finalize(data->get_password_stmt); 
     348    sqlite3_finalize(data->check_password_stmt); 
     349    sqlite3_finalize(data->set_password_stmt); 
     350    sqlite3_finalize(data->get_zerok_stmt); 
     351    sqlite3_finalize(data->set_zerok_stmt); 
     352    sqlite3_finalize(data->create_user_stmt); 
     353    sqlite3_finalize(data->delete_user_stmt); 
     354 
     355    sqlite3_close(data->db); 
     356     
     357    free(data); 
     358} 
     359 
     360int 
     361ar_sqlite_init(authreg_t ar) 
     362{ 
     363 
     364    int ret; 
     365    sqlite3 *db; 
     366    moddata_t data; 
     367    char *busy_timeout; 
     368 
     369    log_debug(ZONE, "sqlite (authreg): start init"); 
     370 
     371    char *dbname = 
     372        config_get_one(ar->c2s->config, "authreg.sqlite.dbname", 0); 
     373    if (dbname == NULL) { 
     374        log_write(ar->c2s->log, LOG_ERR, 
     375                  "sqlite (authreg): invalid driver config."); 
     376        return 1; 
     377    } 
     378 
     379    ret = sqlite3_open(dbname, &db); 
     380    if (ret != SQLITE_OK) { 
     381        log_write(ar->c2s->log, LOG_ERR, 
     382                  "sqlite (authreg): can't open database."); 
     383        return 1; 
     384    } 
     385 
     386    data = (moddata_t) malloc(sizeof(struct moddata_st)); 
     387    if (!data) { 
     388        log_write(ar->c2s->log, LOG_ERR, 
     389                  "sqlite (authreg): memory error."); 
     390        return 1; 
     391    } 
     392    memset(data, 0, sizeof(struct moddata_st)); 
     393 
     394    data->db = db; 
     395 
     396    if (config_get_one(ar->c2s->config, 
     397                       "authreg.sqlite.transactions", 0) != NULL) { 
     398        data->txn = 1; 
     399    } else { 
     400        log_write(ar->c2s->log, LOG_WARNING, 
     401                  "sqlite (authreg): transactions disabled"); 
     402        data->txn = 0; 
     403    } 
     404 
     405    busy_timeout = config_get_one(ar->c2s->config, 
     406                                  "authreg.sqlite.busy-timeout", 0); 
     407 
     408    if (busy_timeout != NULL) { 
     409        sqlite3_busy_timeout(db, atoi(busy_timeout)); 
     410    } 
     411 
     412    ar->private = data; 
     413 
     414    ar->user_exists = _ar_sqlite_user_exists; 
     415    ar->get_password = _ar_sqlite_get_password; 
     416    ar->check_password = _ar_sqlite_check_password; 
     417    ar->set_password = _ar_sqlite_set_password; 
     418    ar->get_zerok = _ar_sqlite_get_zerok; 
     419    ar->set_zerok = _ar_sqlite_set_zerok; 
     420    ar->create_user = _ar_sqlite_create_user; 
     421    ar->delete_user = _ar_sqlite_delete_user; 
     422    ar->free = _ar_sqlite_free; 
     423 
     424    log_debug(ZONE, "sqlite (authreg): finish init"); 
     425 
     426    return 0; 
     427} 
     428 
     429#endif 
  • etc/c2s.xml.dist.in

     
    351351      <exec>@bindir@/pipe-auth.pl</exec> 
    352352    </pipe> 
    353353 
     354    <!-- SQLite module configuration --> 
     355    <sqlite> 
     356      <dbname>@localstatedir@/jabberd/db/sqlite.db</dbname> 
     357      <busy-timeout>0</busy-timeout> 
     358      <transactions/> 
     359    </sqlite> 
     360 
    354361  </authreg> 
    355362 
    356363</c2s> 
  • etc/sm.xml.dist.in

     
    141141      <user>jabberd2</user> 
    142142      <pass>secret</pass> 
    143143    </oracle> 
     144 
     145    <!-- SQLite driver configuration --> 
     146    <sqlite> 
     147      <dbname>@localstatedir@/jabberd/db/sqlite.db</dbname> 
     148      <busy-timeout>0</busy-timeout> 
     149      <transactions/> 
     150    </sqlite> 
    144151  </storage> 
    145152   
    146153  <!-- Access control information --> 
  • tools/Makefile.am

     
    11bin_SCRIPTS = jabberd 
    2 EXTRA_DIST = db-setup.mysql db-setup.pgsql jabberd.in jabberd.rc pipe-auth.pl migrate.pl db-update.mysql db-setup.oracle 
     2EXTRA_DIST = db-setup.mysql db-setup.pgsql jabberd.in jabberd.rc pipe-auth.pl migrate.pl db-update.mysql db-setup.oracle db-setup.sqlite 
    33 
    44edit = sed \ 
    55        -e 's,@sysconfdir\@,$(sysconfdir),g' \ 
  • tools/db-setup.sqlite

     
     1-- 
     2-- This is the required schema for sqlite. 
     3-- 
     4--     sqlite jabberd2.db <  db-setup.sqlite 
     5-- 
     6 
     7-- 
     8-- c2s authentication/registration table 
     9-- 
     10CREATE TABLE 'authreg' ( 
     11    'username' TEXT, 
     12    'realm' TEXT, 
     13    'password' TEXT, 
     14    'token' VARCHAR(10), 
     15    'sequence' INTEGER, 
     16    'hash' VARCHAR(40) ); 
     17 
     18-- 
     19-- Session manager tables  
     20-- 
     21 
     22-- 
     23-- Active (seen) users 
     24-- Used by: core 
     25-- 
     26CREATE TABLE 'active' ( 
     27    'collection-owner' TEXT NOT NULL, 
     28    'object-sequence' INTEGER PRIMARY KEY, 
     29    'time' INT ); 
     30 
     31-- 
     32-- Logout times 
     33-- Used by: mod_iq_last 
     34-- 
     35CREATE TABLE 'logout' ( 
     36    'collection-owner' TEXT NOT NULL, 
     37    'object-sequence' INTEGER PRIMARY KEY, 
     38    'time' INT ); 
     39 
     40-- 
     41-- Roster items 
     42-- Used by: mod_roster 
     43-- 
     44CREATE TABLE 'roster-items' ( 
     45    'collection-owner' TEXT NOT NULL, 
     46    'object-sequence' INTEGER PRIMARY KEY, 
     47    'jid' TEXT, 
     48    'name' TEXT, 
     49    'to' BOOL, 
     50    'from' BOOL, 
     51    'ask' INTEGER ); 
     52 
     53-- 
     54-- Roster groups 
     55-- Used by: mod_roster 
     56-- 
     57CREATE TABLE 'roster-groups' ( 
     58    'collection-owner' TEXT NOT NULL, 
     59    'object-sequence' INTEGER PRIMARY KEY, 
     60    'jid' TEXT, 
     61    'group' TEXT ); 
     62 
     63-- 
     64-- vCard (user profile information) 
     65-- Used by: mod_iq_vcard 
     66-- 
     67CREATE TABLE 'vcard' ( 
     68    'collection-owner' TEXT NOT NULL, 
     69    'object-sequence' INTEGER PRIMARY KEY, 
     70    'fn' TEXT, 
     71    'nickname' TEXT, 
     72    'url' TEXT, 
     73    'tel' TEXT, 
     74    'email' TEXT, 
     75    'title' TEXT, 
     76    'role' TEXT, 
     77    'bday' TEXT, 
     78    'desc' TEXT, 
     79    'n-given' TEXT, 
     80    'n-family' TEXT, 
     81    'adr-street' TEXT, 
     82    'adr-extadd' TEXT, 
     83    'adr-locality' TEXT, 
     84    'adr-region' TEXT, 
     85    'adr-pcode' TEXT, 
     86    'adr-country' TEXT, 
     87    'org-orgname' TEXT, 
     88    'org-orgunit' TEXT ); 
     89 
     90-- 
     91-- Offline message queue 
     92-- Used by: mod_offline 
     93-- 
     94CREATE TABLE 'queue' ( 
     95    'collection-owner' TEXT NOT NULL, 
     96    'object-sequence' INTEGER PRIMARY KEY, 
     97    'xml' TEXT ); 
     98 
     99-- 
     100-- Private XML storage 
     101-- Used by: mod_iq_private 
     102-- 
     103CREATE TABLE 'private' ( 
     104    'collection-owner' TEXT NOT NULL, 
     105    'object-sequence' INTEGER PRIMARY KEY, 
     106    'ns' TEXT, 
     107    'xml' TEXT ); 
     108 
     109-- 
     110-- Message Of The Day (MOTD) messages (announcements) 
     111-- Used by: mod_announce 
     112-- 
     113CREATE TABLE 'motd-message' ( 
     114    'collection-owner' TEXT NOT NULL, 
     115    'object-sequence' INTEGER PRIMARY KEY, 
     116    'xml' TEXT ); 
     117 
     118-- 
     119-- Times of last MOTD message for each user 
     120-- Used by: mod_announce 
     121-- 
     122CREATE TABLE 'motd-times' ( 
     123    'collection-owner' TEXT NOT NULL, 
     124    'object-sequence' INTEGER PRIMARY KEY, 
     125    'time' INTEGER ); 
     126 
     127-- 
     128-- User-published discovery items 
     129-- Used by: mod_disco_publish 
     130-- 
     131CREATE TABLE 'disco-items' ( 
     132    'collection-owner' TEXT NOT NULL, 
     133    'object-sequence' INTEGER PRIMARY KEY, 
     134    'jid' TEXT, 
     135    'name' TEXT, 
     136    'node' TEXT ); 
     137 
     138-- 
     139-- Default privacy list 
     140-- Used by: mod_privacy 
     141-- 
     142CREATE TABLE 'privacy-default' ( 
     143    'collection-owner' TEXT NOT NULL, 
     144    'object-sequence' INTEGER PRIMARY KEY, 
     145    'default' TEXT ); 
     146 
     147-- 
     148-- Privacy lists 
     149-- Used by: mod_privacy 
     150-- 
     151CREATE TABLE 'privacy-items' ( 
     152    'collection-owner' TEXT NOT NULL, 
     153    'object-sequence' INTEGER PRIMARY KEY, 
     154    'list' TEXT, 
     155    'type' TEXT, 
     156    'value' TEXT, 
     157    'deny' BOOL, 
     158    'order' INTEGER, 
     159    'block' INTEGER ); 
     160 
     161-- 
     162-- Vacation settings 
     163-- Used by: mod_vacation 
     164-- 
     165CREATE TABLE 'vacation-settings' ( 
     166    'collection-owner' TEXT NOT NULL, 
     167    'object-sequence' INTEGER PRIMARY KEY, 
     168    'start' INTEGER, 
     169    'end' INTEGER, 
     170    'message' TEXT );