Cherry-picks the code from 0.1.x branch
[rahunas] / src / rh-server.c
1 /**
2  * RahuNAS server
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2009-03-24
5  */
6 #include <stdio.h>
7 #include <string.h>
8 #include "rahunasd.h"
9 #include "rh-server.h"
10 #include "rh-utils.h"
11
12 RHVServer *
13 vserver_exists (GList *vserver_list, int vserver_id, const char *vserver_name)
14 {
15   GList *runner = g_list_first(vserver_list);
16   RHVServer *lvserver = NULL;
17
18   while (runner != NULL) {
19     lvserver = (RHVServer *)runner->data;
20    
21     if (lvserver->vserver_config->vserver_id == vserver_id)
22       return lvserver; 
23
24     if (strcmp(lvserver->vserver_config->vserver_name, vserver_name) == 0)
25       return lvserver;
26
27     runner = g_list_next(runner); 
28   } 
29   return NULL;
30 }
31
32 RHVServer *vserver_get_by_id(RHMainServer *ms, int search_id)
33 {
34   GList *runner = g_list_first(ms->vserver_list);
35   RHVServer *lvserver = NULL;
36
37   while (runner != NULL) {
38     lvserver = (RHVServer *)runner->data;
39    
40     if (lvserver->vserver_config->vserver_id == search_id) {
41       return lvserver;
42     }
43
44     runner = g_list_next(runner); 
45   } 
46   return NULL;
47 }
48
49 int vserver_cleanup(RHVServer *vs)
50 {
51   if (vs == NULL)
52     return 0;
53
54   if (vs->vserver_config != NULL)
55     cleanup_vserver_config(vs->vserver_config);  
56
57   return 0;
58 }
59
60 int mainserver_cleanup(RHMainServer *ms)
61 {
62   if (ms == NULL)
63     return 0;
64
65   if (ms->main_config != NULL)
66     cleanup_mainserver_config(ms->main_config);  
67
68   return 0;
69 }
70
71 int register_vserver(RHMainServer *ms, const char *vserver_cfg_file)
72 {
73   GList *vserver_list = ms->vserver_list;
74   GList *chk = NULL;
75   GList *node = NULL;
76   FILE  *cfg_file = NULL;
77   
78   union rahunas_config *cfg_get = NULL;
79   struct rahunas_vserver_config *vserver_config = NULL;
80   RHVServer *new_vserver = NULL;
81   RHVServer *old_vserver = NULL;
82
83   union rahunas_config config = {
84     .rh_vserver.vserver_name = NULL,
85     .rh_vserver.vserver_id = VSERVER_ID,
86     .rh_vserver.init_flag = VS_INIT,
87     .rh_vserver.dev_external = NULL,
88     .rh_vserver.dev_internal = NULL,
89     .rh_vserver.vlan = NULL,
90     .rh_vserver.vlan_raw_dev_external = NULL,
91     .rh_vserver.vlan_raw_dev_internal = NULL,
92     .rh_vserver.bridge = NULL,
93     .rh_vserver.masquerade = NULL,
94     .rh_vserver.ignore_mac = NULL,
95     .rh_vserver.vserver_ip = NULL, 
96     .rh_vserver.vserver_fqdn = NULL,
97     .rh_vserver.vserver_ports_allow = NULL,
98     .rh_vserver.vserver_ports_intercept = NULL,
99     .rh_vserver.clients = NULL,
100     .rh_vserver.excluded = NULL,
101     .rh_vserver.idle_timeout = IDLE_TIMEOUT,
102     .rh_vserver.dns = NULL,
103     .rh_vserver.ssh = NULL,
104     .rh_vserver.proxy = NULL,
105     .rh_vserver.proxy_host = NULL,
106     .rh_vserver.proxy_port = NULL,
107     .rh_vserver.bittorrent = NULL,
108     .rh_vserver.bittorrent_allow = NULL,
109     .rh_vserver.radius_host = NULL,
110     .rh_vserver.radius_secret = NULL,
111     .rh_vserver.radius_encrypt = NULL,
112     .rh_vserver.radius_auth_port = NULL,
113     .rh_vserver.radius_account_port = NULL,
114     .rh_vserver.nas_identifier = NULL,
115     .rh_vserver.nas_port = NULL,
116     .rh_vserver.nas_login_title = NULL,
117     .rh_vserver.nas_default_redirect = NULL,
118     .rh_vserver.nas_default_language = NULL,
119     .rh_vserver.nas_weblogin_template = NULL,
120   };
121
122   cfg_file = fopen(vserver_cfg_file, "r");
123   if (cfg_file == NULL)
124     return -1;
125
126   if (get_config(vserver_cfg_file, &config) == 0) {
127     old_vserver = vserver_exists(vserver_list, config.rh_vserver.vserver_id, 
128                     config.rh_vserver.vserver_name);
129
130     if (old_vserver != NULL) {
131       if (old_vserver->dummy_config != NULL) {
132         DP("Cleanup old dummy config");
133         rh_free((void **) &old_vserver->dummy_config);
134       }
135
136       old_vserver->dummy_config = 
137         (struct rahunas_vserver_config *) rh_malloc(sizeof(struct rahunas_vserver_config));
138
139       if (old_vserver->dummy_config == NULL)
140         return -1;
141
142       memset(old_vserver->dummy_config, 0, 
143         sizeof(struct rahunas_vserver_config));
144       memcpy(old_vserver->dummy_config, &config, 
145         sizeof(struct rahunas_vserver_config));
146
147       if (strncmp(config.rh_vserver.vserver_name, 
148             old_vserver->vserver_config->vserver_name, 32) != 0 || 
149           strncmp(config.rh_vserver.clients, 
150             old_vserver->vserver_config->clients, 18) != 0) {
151         old_vserver->vserver_config->init_flag = VS_RESET;
152       } else {
153         old_vserver->vserver_config->init_flag = VS_RELOAD;  
154       }
155       return 1;
156     }
157   } else {
158     return -1;
159   }
160
161   vserver_config = (struct rahunas_vserver_config *) rh_malloc(sizeof(struct rahunas_vserver_config));
162
163   if (vserver_config == NULL)
164     return -1;
165
166   memset(vserver_config, 0, sizeof(struct rahunas_vserver_config));
167
168   memcpy(vserver_config, &config, sizeof(struct rahunas_vserver_config));
169
170   new_vserver = (RHVServer *) rh_malloc(sizeof(RHVServer));
171
172   if (new_vserver == NULL)
173     return -1;
174
175   memset(new_vserver, 0, sizeof(RHVServer));
176
177   new_vserver->vserver_config = vserver_config;
178
179   new_vserver->main_server = ms;
180   new_vserver->vserver_config->init_flag = VS_INIT;
181   ms->vserver_list = g_list_append(ms->vserver_list, new_vserver);
182   return 0; 
183 }
184
185 int unregister_vserver(RHMainServer *ms, int vserver_id)
186 {
187   GList *vserver_list = ms->vserver_list;
188   GList *runner = g_list_first(vserver_list);
189   RHVServer *lvserver = NULL;
190
191   while (runner != NULL) {
192     lvserver = (RHVServer *)runner->data;
193     if (lvserver->vserver_config->vserver_id == vserver_id) {
194       vserver_cleanup(lvserver);
195
196       ms->vserver_list = g_list_delete_link(ms->vserver_list, runner);
197       break;
198     } else {
199       runner = g_list_next(runner);
200     }
201   }
202   return 0;
203 }
204
205 int unregister_vserver_all(RHMainServer *ms)
206 {
207   GList *vserver_list = ms->vserver_list;
208   GList *runner = g_list_first(vserver_list);
209   GList *deleting = NULL;
210   RHVServer *lvserver = NULL;
211
212   while (runner != NULL) {
213     lvserver = (RHVServer *)runner->data;
214     vserver_cleanup(lvserver);
215     deleting = runner;
216     runner = g_list_next(runner);
217
218     cleanup_vserver_config(lvserver->vserver_config);
219     ms->vserver_list = g_list_delete_link(ms->vserver_list, deleting);
220   }
221   
222   return 0;
223 }
224
225 int walk_through_vserver(int (*callback)(RHMainServer *, RHVServer*),
226                          RHMainServer *ms)
227 {
228   GList *vserver_list = ms->vserver_list;
229   GList *runner = g_list_first(vserver_list);
230   RHVServer *vs = NULL;
231
232   while (runner != NULL) {
233     vs = (RHVServer *)runner->data;
234
235     (*callback)(ms, vs);
236
237     runner = g_list_next(runner); 
238   } 
239
240   return 0;
241 }
242
243 void vserver_init_done(RHMainServer *ms, RHVServer *vs)
244 {
245   if (vs != NULL) {
246     vs->vserver_config->init_flag = VS_DONE;
247     DP("Virtual Sever (%s) - Configured", vs->vserver_config->vserver_name);
248   }
249 }
250
251 void vserver_reload(RHMainServer *ms, RHVServer *vs)
252 {
253   if (vs->vserver_config->init_flag == VS_DONE) {
254     // Indicate the unused virtual server
255     vs->vserver_config->init_flag = VS_NONE;
256     return;
257   }
258
259   while (vs->vserver_config->init_flag != VS_DONE) {
260     if (vs->vserver_config->init_flag == VS_INIT) {
261       logmsg(RH_LOG_NORMAL, "[%s] - Config init",
262              vs->vserver_config->vserver_name);
263
264       rh_task_init(ms, vs); 
265       vs->vserver_config->init_flag = VS_DONE;
266     } else if (vs->vserver_config->init_flag == VS_RELOAD) {
267       logmsg(RH_LOG_NORMAL, "[%s] - Config reload",
268              vs->vserver_config->vserver_name);
269
270       rh_task_cleanup(ms, vs);
271
272       if (vs->dummy_config != NULL) {
273         cleanup_vserver_config(vs->vserver_config);
274         memcpy(vs->vserver_config, vs->dummy_config, 
275           sizeof(struct rahunas_vserver_config));
276       }
277
278       vs->vserver_config->init_flag = VS_RELOAD;
279       rh_task_init(ms, vs); 
280       vs->vserver_config->init_flag = VS_DONE;
281     } else if (vs->vserver_config->init_flag == VS_RESET) {
282       logmsg(RH_LOG_NORMAL, "[%s] - Config reset",
283              vs->vserver_config->vserver_name);
284
285       rh_task_cleanup(ms, vs);
286
287       if (vs->dummy_config != NULL) {
288         cleanup_vserver_config(vs->vserver_config);
289         memcpy(vs->vserver_config, vs->dummy_config, 
290           sizeof(struct rahunas_vserver_config));
291         rh_free((void **) &vs->dummy_config);
292       }
293
294       vs->vserver_config->init_flag = VS_INIT;
295     } else {
296       /* Prevent infinite loop */
297       vs->vserver_config->init_flag = VS_DONE;
298     }
299   } 
300 }
301
302
303 void vserver_unused_cleanup(RHMainServer *ms)
304 {
305   GList *vserver_list = ms->vserver_list;
306   GList *runner = g_list_first(vserver_list);
307   RHVServer *lvserver = NULL;
308
309   while (runner != NULL) {
310     lvserver = (RHVServer *)runner->data;
311     if (lvserver->vserver_config->init_flag == VS_NONE) {
312       logmsg(RH_LOG_NORMAL, "[%s] - Config removed",
313              lvserver->vserver_config->vserver_name);
314       rh_task_cleanup(ms, lvserver);
315       unregister_vserver(ms, lvserver->vserver_config->vserver_id);
316
317       // Set runner to the first of list due to unregister may delete head
318       runner = g_list_first(ms->vserver_list);
319     } else {
320       runner = g_list_next(runner);
321     }
322   }
323 }