7188365563bbdaa095180af15dff312ba519c90f
[citadel.git] / citadel / modules / upgrade / serv_upgrade.c
1 /*
2  * $Id$
3  *
4  * Transparently handle the upgrading of server data formats.
5  *
6  */
7
8 #include "sysdep.h"
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <signal.h>
14 #include <pwd.h>
15 #include <errno.h>
16 #include <sys/types.h>
17
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # if HAVE_SYS_TIME_H
23 #  include <sys/time.h>
24 # else
25 #  include <time.h>
26 # endif
27 #endif
28
29 #include <sys/wait.h>
30 #include <string.h>
31 #include <limits.h>
32 #include <libcitadel.h>
33 #include "citadel.h"
34 #include "server.h"
35 #include "citserver.h"
36 #include "support.h"
37 #include "config.h"
38 #include "control.h"
39 #include "database.h"
40 #include "room_ops.h"
41 #include "user_ops.h"
42 #include "msgbase.h"
43 #include "serv_upgrade.h"
44 #include "euidindex.h"
45
46
47 #include "ctdl_module.h"
48
49
50 /* 
51  * Back end processing function for cmd_bmbx
52  */
53 void cmd_bmbx_backend(struct ctdlroom *qrbuf, void *data) {
54         static struct RoomProcList *rplist = NULL;
55         struct RoomProcList *ptr;
56         struct ctdlroom qr;
57
58         /* Lazy programming here.  Call this function as a ForEachRoom backend
59          * in order to queue up the room names, or call it with a null room
60          * to make it do the processing.
61          */
62         if (qrbuf != NULL) {
63                 ptr = (struct RoomProcList *)
64                         malloc(sizeof (struct RoomProcList));
65                 if (ptr == NULL) return;
66
67                 safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
68                 ptr->next = rplist;
69                 rplist = ptr;
70                 return;
71         }
72
73         while (rplist != NULL) {
74
75                 if (lgetroom(&qr, rplist->name) == 0) {
76                         lprintf(CTDL_DEBUG, "Processing <%s>...\n", rplist->name);
77                         if ( (qr.QRflags & QR_MAILBOX) == 0) {
78                                 lprintf(CTDL_DEBUG, "  -- not a mailbox\n");
79                         }
80                         else {
81
82                                 qr.QRgen = time(NULL);
83                                 lprintf(CTDL_DEBUG, "  -- fixed!\n");
84                         }
85                         lputroom(&qr);
86                 }
87
88                 ptr = rplist;
89                 rplist = rplist->next;
90                 free(ptr);
91         }
92 }
93
94 /*
95  * quick fix to bump mailbox generation numbers
96  */
97 void bump_mailbox_generation_numbers(void) {
98         lprintf(CTDL_WARNING, "Applying security fix to mailbox rooms\n");
99         ForEachRoom(cmd_bmbx_backend, NULL);
100         cmd_bmbx_backend(NULL, NULL);
101         return;
102 }
103
104
105 /* 
106  * Back end processing function for convert_ctdluid_to_minusone()
107  */
108 void cbtm_backend(struct ctdluser *usbuf, void *data) {
109         static struct UserProcList *uplist = NULL;
110         struct UserProcList *ptr;
111         struct ctdluser us;
112
113         /* Lazy programming here.  Call this function as a ForEachUser backend
114          * in order to queue up the room names, or call it with a null user
115          * to make it do the processing.
116          */
117         if (usbuf != NULL) {
118                 ptr = (struct UserProcList *)
119                         malloc(sizeof (struct UserProcList));
120                 if (ptr == NULL) return;
121
122                 safestrncpy(ptr->user, usbuf->fullname, sizeof ptr->user);
123                 ptr->next = uplist;
124                 uplist = ptr;
125                 return;
126         }
127
128         while (uplist != NULL) {
129
130                 if (lgetuser(&us, uplist->user) == 0) {
131                         lprintf(CTDL_DEBUG, "Processing <%s>...\n", uplist->user);
132                         if (us.uid == CTDLUID) {
133                                 us.uid = (-1);
134                         }
135                         lputuser(&us);
136                 }
137
138                 ptr = uplist;
139                 uplist = uplist->next;
140                 free(ptr);
141         }
142 }
143
144 /*
145  * quick fix to change all CTDLUID users to (-1)
146  */
147 void convert_ctdluid_to_minusone(void) {
148         lprintf(CTDL_WARNING, "Applying uid changes\n");
149         ForEachUser(cbtm_backend, NULL);
150         cbtm_backend(NULL, NULL);
151         return;
152 }
153
154 /*
155  * Do various things to our configuration file
156  */
157 void update_config(void) {
158         get_config();
159
160         if (CitControl.version < 606) {
161                 config.c_rfc822_strict_from = 0;
162         }
163
164         if (CitControl.version < 609) {
165                 config.c_purge_hour = 3;
166         }
167
168         if (CitControl.version < 615) {
169                 config.c_ldap_port = 389;
170         }
171
172         if (CitControl.version < 623) {
173                 strcpy(config.c_ip_addr, "0.0.0.0");
174         }
175
176         if (CitControl.version < 650) {
177                 config.c_enable_fulltext = 0;
178         }
179
180         if (CitControl.version < 652) {
181                 config.c_auto_cull = 1;
182         }
183
184         put_config();
185 }
186
187
188
189
190 void check_server_upgrades(void) {
191
192         get_control();
193         lprintf(CTDL_INFO, "Server-hosted upgrade level is %d.%02d\n",
194                 (CitControl.version / 100),
195                 (CitControl.version % 100) );
196
197         if (CitControl.version < REV_LEVEL) {
198                 lprintf(CTDL_WARNING,
199                         "Server hosted updates need to be processed at "
200                         "this time.  Please wait...\n");
201         }
202         else {
203                 return;
204         }
205
206         update_config();
207
208         if ((CitControl.version > 000) && (CitControl.version < 555)) {
209                 lprintf(CTDL_EMERG,
210                         "Your data files are from a version of Citadel\n"
211                         "that is too old to be upgraded.  Sorry.\n");
212                 exit(EXIT_FAILURE);
213         }
214         if ((CitControl.version > 000) && (CitControl.version < 591)) {
215                 bump_mailbox_generation_numbers();
216         }
217         if ((CitControl.version > 000) && (CitControl.version < 608)) {
218                 convert_ctdluid_to_minusone();
219         }
220         if ((CitControl.version > 000) && (CitControl.version < 659)) {
221                 rebuild_euid_index();
222         }
223
224         CitControl.version = REV_LEVEL;
225         put_control();
226 }
227
228
229 CTDL_MODULE_INIT(upgrade)
230 {
231         if (!threading)
232         {
233                 check_server_upgrades();
234         }
235         
236         /* return our Subversion id for the Log */
237         return "$Id$";
238 }