2 * Transparently handle the upgrading of server data formats.
4 * Copyright (c) 1987-2012 by the citadel.org team
6 * This program is open source software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
23 #include <sys/types.h>
25 #if TIME_WITH_SYS_TIME
26 # include <sys/time.h>
30 # include <sys/time.h>
39 #include <libcitadel.h>
42 #include "citserver.h"
49 #include "serv_upgrade.h"
50 #include "euidindex.h"
53 #include "ctdl_module.h"
58 * Fix up the name for Citadel user 0 and try to remove any extra users with number 0
60 void fix_sys_user_name(void)
62 struct ctdluser usbuf;
63 char usernamekey[USERNAME_SIZE];
65 /** If we have a user called Citadel rename them to SYS_Citadel */
66 if (CtdlGetUser(&usbuf, "Citadel") == 0)
68 rename_user("Citadel", "SYS_Citadel");
71 while (CtdlGetUserByNumber(&usbuf, 0) == 0)
73 /* delete user with number 0 and no name */
74 if (IsEmptyStr(usbuf.fullname)) {
75 cdb_delete(CDB_USERS, "", 0);
78 /* temporarily set this user to -1 */
84 /* Make sure user SYS_* is user 0 */
85 while (CtdlGetUserByNumber(&usbuf, -1) == 0)
87 if (strncmp(usbuf.fullname, "SYS_", 4))
88 { /* Delete any user 0 that doesn't start with SYS_ */
89 makeuserkey(usernamekey, usbuf.fullname, cutuserkey(usbuf.fullname));
90 cdb_delete(CDB_USERS, usernamekey, strlen(usernamekey));
101 * Back end processing function for cmd_bmbx
103 void cmd_bmbx_backend(struct ctdlroom *qrbuf, void *data) {
104 static struct RoomProcList *rplist = NULL;
105 struct RoomProcList *ptr;
108 /* Lazy programming here. Call this function as a CtdlForEachRoom backend
109 * in order to queue up the room names, or call it with a null room
110 * to make it do the processing.
113 ptr = (struct RoomProcList *) malloc(sizeof (struct RoomProcList));
114 if (ptr == NULL) return;
116 safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
122 while (rplist != NULL) {
124 if (CtdlGetRoomLock(&qr, rplist->name) == 0) {
125 syslog(LOG_DEBUG, "Processing <%s>...", rplist->name);
126 if ( (qr.QRflags & QR_MAILBOX) == 0) {
127 syslog(LOG_DEBUG, " -- not a mailbox");
131 qr.QRgen = time(NULL);
132 syslog(LOG_DEBUG, " -- fixed!");
134 CtdlPutRoomLock(&qr);
138 rplist = rplist->next;
144 * quick fix to bump mailbox generation numbers
146 void bump_mailbox_generation_numbers(void) {
147 syslog(LOG_WARNING, "Applying security fix to mailbox rooms");
148 CtdlForEachRoom(cmd_bmbx_backend, NULL);
149 cmd_bmbx_backend(NULL, NULL);
155 * Back end processing function for convert_ctdluid_to_minusone()
157 void cbtm_backend(struct ctdluser *usbuf, void *data) {
158 static struct UserProcList *uplist = NULL;
159 struct UserProcList *ptr;
162 /* Lazy programming here. Call this function as a ForEachUser backend
163 * in order to queue up the room names, or call it with a null user
164 * to make it do the processing.
167 ptr = (struct UserProcList *)
168 malloc(sizeof (struct UserProcList));
169 if (ptr == NULL) return;
171 safestrncpy(ptr->user, usbuf->fullname, sizeof ptr->user);
177 while (uplist != NULL) {
179 if (CtdlGetUserLock(&us, uplist->user) == 0) {
180 syslog(LOG_DEBUG, "Processing <%s>...", uplist->user);
181 if (us.uid == CTDLUID) {
184 CtdlPutUserLock(&us);
188 uplist = uplist->next;
194 * quick fix to change all CTDLUID users to (-1)
196 void convert_ctdluid_to_minusone(void) {
197 syslog(LOG_WARNING, "Applying uid changes");
198 ForEachUser(cbtm_backend, NULL);
199 cbtm_backend(NULL, NULL);
206 * These accounts may have been created by code that ran between mid 2008 and early 2011.
207 * If present they are no longer in use and may be deleted.
209 void remove_thread_users(void) {
210 char *deleteusers[] = {
219 "SYS_select_on_master",
224 struct ctdluser usbuf;
225 for (i=0; i<(sizeof(deleteusers)/sizeof(char *)); ++i) {
226 if (CtdlGetUser(&usbuf, deleteusers[i]) == 0) {
228 strcpy(usbuf.password, "deleteme");
231 "System user account <%s> is no longer in use and will be deleted.",
240 * Attempt to guess the name of the time zone currently in use
241 * on the underlying host system.
243 void guess_time_zone(void) {
247 fp = popen(file_guesstimezone, "r");
249 if (fgets(buf, sizeof buf, fp) && (strlen(buf) > 2)) {
250 buf[strlen(buf)-1] = 0;
251 safestrncpy(config.c_default_cal_zone, buf, sizeof config.c_default_cal_zone);
252 syslog(LOG_INFO, "Configuring timezone: %s", config.c_default_cal_zone);
260 * Perform any upgrades that can be done automatically based on our knowledge of the previous
261 * version of Citadel server that was running here.
263 * Note that if the previous version was 0 then this is a new installation running for the first time.
265 void update_config(void) {
268 if (CitControl.version < 606) {
269 config.c_rfc822_strict_from = 0;
272 if (CitControl.version < 609) {
273 config.c_purge_hour = 3;
276 if (CitControl.version < 615) {
277 config.c_ldap_port = 389;
280 if (CitControl.version < 623) {
281 strcpy(config.c_ip_addr, "*");
284 if (CitControl.version < 650) {
285 config.c_enable_fulltext = 1;
288 if (CitControl.version < 652) {
289 config.c_auto_cull = 1;
292 if (CitControl.version < 725) {
293 config.c_xmpp_c2s_port = 5222;
294 config.c_xmpp_s2s_port = 5269;
297 if (IsEmptyStr(config.c_default_cal_zone)) {
307 * Based on the server version number reported by the existing database,
308 * run in-place data format upgrades until everything is up to date.
310 void check_server_upgrades(void) {
313 syslog(LOG_INFO, "Existing database version on disk is %d.%02d",
314 (CitControl.version / 100),
315 (CitControl.version % 100)
318 if (CitControl.version < REV_LEVEL) {
320 "Server hosted updates need to be processed at this time. Please wait..."
329 if ((CitControl.version > 000) && (CitControl.version < 555)) {
330 syslog(LOG_EMERG, "This database is too old to be upgraded. Citadel server will exit.");
333 if ((CitControl.version > 000) && (CitControl.version < 591)) {
334 bump_mailbox_generation_numbers();
336 if ((CitControl.version > 000) && (CitControl.version < 608)) {
337 convert_ctdluid_to_minusone();
339 if ((CitControl.version > 000) && (CitControl.version < 659)) {
340 rebuild_euid_index();
342 if (CitControl.version < 735) {
345 if (CitControl.version < 736) {
346 rebuild_usersbynumber();
348 if (CitControl.version < 790) {
349 remove_thread_users();
351 CitControl.version = REV_LEVEL;
356 CTDL_MODULE_UPGRADE(upgrade)
358 check_server_upgrades();
360 /* return our module id for the Log */