1 /*-
2  * Copyright (c) 1998-2008 DHIS, Dynamic Host Information System
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 #include "dhisd.h"
29 #include "qrc.h"
30 #include "ddb.h"
31 #include "misc.h"
32 
33 #include<stdio.h>
34 #include<stdlib.h>
35 #include<string.h>
36 #include<syslog.h>
37 #include<gmp.h>
38 #include<ctype.h>
39 #include<string.h>
40 #include<sys/types.h>
41 #include<sys/stat.h>
42 #include<signal.h>
43 #include<netdb.h>
44 #include<time.h>
45 #include<sys/time.h>
46 #include<sys/utsname.h>
47 #include<unistd.h>
48 #include <sys/file.h>
49 #include<fcntl.h>
50 
51 #ifdef	WITH_MYSQL
52 #include<mysql.h>
53 #endif
54 
55 int db_mode=DB_FILE;
56 
57 extern char database_file[256];
58 extern char conf_file[256];
59 
60 struct dhis_rec *dBase=NULL;
61 #ifdef WITH_MYSQL
62 char sql_server[128];
63 char sql_user[128];
64 char sql_password[128];
65 char sql_dbase[128];
66 
67 MYSQL *conn;      /* Our connection with SQL Server. */
68 MYSQL_RES *res;
69 MYSQL_ROW row;
70 int db_logged_in=0;
71 #endif
72 
new_rec(void)73 struct dhis_rec *new_rec(void) {
74 
75 	struct dhis_rec *dp;
76 	dp=(struct dhis_rec *)malloc(sizeof(struct dhis_rec));
77 	if(dp==NULL) return(NULL);
78 
79 	memset(dp,0,sizeof(struct dhis_rec));
80 
81 	dp->status=1;
82 	dp->next=NULL;
83 	return(dp);
84 }
85 
free_rec(struct dhis_rec * dp)86 void free_rec(struct dhis_rec *dp) {
87 
88 	if(dp->atype==AQRC) mpz_clear(dp->mauthn);
89 	free(dp);
90 }
91 
92 
get_rec(int rid)93 struct dhis_rec *get_rec(int rid) {
94 
95 	struct dhis_rec *r; r=dBase;
96 
97 	if(dBase==NULL) {
98 		if(!db_reload()) {
99 #ifdef WITH_MYSQL
100 			sql_logout();
101 			sql_login();
102 #endif
103 			if(!db_reload()) return NULL;
104 		}
105 		if(dBase==NULL) return NULL;
106 	}
107 
108 	while(r!=NULL) {
109 		if(r->hostid==rid) return r;
110 		r=r->next;
111 	}
112 	return NULL;
113 }
114 
db_reload(void)115 int db_reload(void) {
116 
117 #ifdef WITH_MYSQL
118 	if(db_mode==DB_MYSQL) {
119 		return (sql_db_reload());
120 	}
121 #endif
122 
123 	return (file_db_reload());
124 }
125 
db_free(void)126 void db_free(void) {
127 	struct dhis_rec *r=dBase;
128 	while(dBase!=NULL) {
129 		r=dBase;
130 		dBase=dBase->next;
131 		r->next=NULL;
132 		free_rec(r);
133 	}
134 	dBase=NULL;
135 	return;
136 }
137 
db_password(int id)138 char *db_password(int id) {
139 
140 	static char pass[32];
141 	struct dhis_rec *dp;
142 
143 	dp=get_rec(id);
144 	if(dp==NULL) return NULL;
145 	strcpy(pass,dp->hostpass);
146 	return pass;
147 }
148 
db_is_locked(int id)149 int db_is_locked(int id) {
150 
151 	struct dhis_rec *dp;
152 	dp=get_rec(id);
153 	if(dp==NULL) return 1;
154 	if(dp->status) return(0);
155 	else return(1);
156 }
157 
158 
159 
file_db_reload(void)160 int file_db_reload(void)  {
161 
162 	FILE *fp;
163 	char str[1024];
164 	struct dhis_rec *rec;
165 	char keyn[1024];
166 
167 	db_free();
168 
169 	DSYSLOG(0,(LOG_INFO,"db_reload(): Loading DHIS database %s\n",database_file));
170 
171 	fp=fopen(database_file,"r");
172 
173 	if(fp==NULL) return 0;
174 
175 	while(fgets(str,1024,fp)!=NULL) {
176 			off_nl(str);
177 			if(strchr(line_entry(1,str),';')==NULL)
178 				if(!strcmp(line_entry(2,str),"{")) {
179 					char cmd[64];
180 					char *cp;
181 					rec=new_rec();
182 					if(rec==NULL) { fclose(fp); return(0); }
183 					rec->hostid=atoi(line_entry(1,str));
184 					keyn[0]='\0';
185 					rec->refresh=NEXT_CHECK;
186 					do {
187 						if(fgets(str,1024,fp)==NULL)
188 						{
189 							fclose(fp);
190 							free_rec(rec);
191 							return(0);
192 						}
193 						off_nl(str);
194 
195 						strcpy(cmd,line_entry(1,str));
196 						strtolower(cmd);
197 
198 						if(!strcmp(cmd,"hostname")) {
199 							strcpy(rec->hostname,line_entry(2,str));
200 							if((cp=strchr(rec->hostname,';'))!=NULL)
201                                 *cp='\0';
202 						}
203 
204 						if(!strcmp(cmd,"hostpass")) {
205 							strcpy(rec->hostpass,line_entry(2,str));
206 							rec->atype=APASS;
207 
208 							if((cp=strchr(rec->hostpass,';'))!=NULL)
209                                 *cp='\0';
210 
211 						}
212 
213 						if(!strcmp(cmd,"oncmd")) {
214 							strcpy(rec->oncmd,line_ptr(2,str));
215 							if((cp=strchr(rec->oncmd,';'))!=NULL)
216                                 *cp='\0';
217 						}
218 						if(!strcmp(cmd,"offcmd")) {
219 							strcpy(rec->offcmd,line_ptr(2,str));
220 							if((cp=strchr(rec->offcmd,';'))!=NULL)
221                                 *cp='\0';
222 						}
223 
224 						if(!strcmp(cmd,"authn")) {
225 							strcat(keyn,line_entry(2,str));
226 							if((cp=strchr(keyn,';'))!=NULL)
227                                 *cp='\0';
228 							rec->atype=AQRC;
229 						}
230 
231 					} while(strcmp(line_entry(1,str),"}"));
232 
233 					if(!rec->atype)
234 						free_rec(rec);
235 					else
236 						if(rec->atype==AQRC && keyn[0]=='\0')
237 								free_rec(rec);
238 						else {
239 							if(rec->atype==AQRC) {
240 								mpz_init(rec->mauthn);
241 								mpz_set_str(rec->mauthn,keyn,10);
242 							}
243 							if(dBase==NULL) dBase=rec;
244 							else { rec->next=dBase; dBase=rec; }
245 						}
246 
247 					DSYSLOG(2,(LOG_DEBUG,"db_reload(): Read record %d\n",rec->hostid));
248 
249 				} /* End if */
250 		} /* End while */
251 		fclose(fp);
252 
253 		DSYSLOG(0,(LOG_INFO,"db_reload(): Database loaded\n"));
254 
255 		return(1);
256 }
257 
258 #ifdef WITH_MYSQL
259 
sql_login(void)260 int sql_login(void) {
261 
262 	if(db_logged_in) return 1;
263 	if(sql_server[0]=='\0' || sql_user[0]=='\0' || sql_password[0]=='\0' || sql_dbase[0]=='\0')
264 		return 0;
265 
266 	conn = mysql_init(NULL);
267 
268 	if (!mysql_real_connect(conn, sql_server,sql_user,sql_password,sql_dbase,0,NULL,0))
269         return 0;
270 
271 	db_logged_in=1;
272 	return 1;
273 }
274 
sql_logout(void)275 void sql_logout(void) {
276 
277 	if(!db_logged_in) return;
278 	db_logged_in=0;
279 	mysql_close(conn);
280 	return;
281 }
282 
283 
sql_log(char * lstr)284 int sql_log(char *lstr) {
285 
286 	char str[1024];
287 	if(!sql_login()) return 0;
288 	sprintf(str,"insert into DHISServerLog values(\"%s\")",lstr);
289 	if (mysql_query(conn,str)) return(1);
290 	res = mysql_use_result(conn);
291 	mysql_free_result(res);
292 	return(0);
293 }
294 
sql_update_lastlogin(int hostid)295 int sql_update_lastlogin(int hostid) {
296 
297 	char str[1024*8];
298 	if(!sql_login()) return 0;
299 	sprintf(str,"update DHISHost set DHISLastLogin=%ld where DHISHostID=%d",time(NULL),hostid);
300 	if (mysql_query(conn,str)) return(1);
301 	res = mysql_use_result(conn);
302 	mysql_free_result(res);
303 	return(0);
304 }
305 
sql_db_reload(void)306 int sql_db_reload(void) {
307 
308 	char str[1024];
309 	struct dhis_rec *dp=NULL;
310 
311 	db_free();
312 	if(!sql_login()) return 0;
313 
314 	DSYSLOG(0,(LOG_INFO,"db_reload(): Loading DHIS SQL database\n"));
315 
316 	sprintf(str,"select DHISHostID,DHISHostName,DHISHostPassword,DHISAuthN0,DHISAuthN1,DHISAuthN2,DHISAuthN3,DHISOnlineCmd,DHISOfflineCmd,DHISStatus from DHISHost");
317 	if (mysql_query(conn,str))
318 		return 0;
319 
320 	res = mysql_use_result(conn);
321 
322 	while((row = mysql_fetch_row(res)) != NULL) {
323 
324         	dp=new_rec();
325         	if(dp==NULL) {
326 			mysql_free_result(res);
327 			return 0;
328 		}
329 
330         	dp->hostid=atoi(row[0]);
331 
332 		dp->atype=APASS;
333 		strcpy(dp->hostname,row[1]);
334 		strcpy(dp->hostpass,row[2]);
335 		if(dp->hostpass[0]!='\0') dp->atype=APASS;
336 		strcpy(dp->authn[0],row[3]);
337 		strcpy(dp->authn[1],row[4]);
338 		strcpy(dp->authn[2],row[5]);
339 		strcpy(dp->authn[3],row[6]);
340 		if(strlen(dp->authn[0])>10)  dp->atype=AQRC;
341 		strcpy(dp->oncmd,row[7]);
342 		strcpy(dp->offcmd,row[8]);
343 		dp->status=atoi(row[9]);
344 
345 		dp->refresh=NEXT_CHECK;
346 
347         	if(dp->atype==AQRC) {
348 			char xauthn[1024];
349 			strcpy(xauthn,"");
350 			strcat(xauthn,dp->authn[0]);
351 			strcat(xauthn,dp->authn[1]);
352 			strcat(xauthn,dp->authn[2]);
353 			strcat(xauthn,dp->authn[3]);
354 			mpz_init(dp->mauthn);
355 			mpz_set_str(dp->mauthn,xauthn,10);
356 		}
357 		if(dBase==NULL) dBase=dp;
358 		else { dp->next=dBase; dBase=dp; }
359 
360 	}
361 
362 	mysql_free_result(res);
363 
364 	DSYSLOG(0,(LOG_INFO,"db_reload(): Database loaded\n"));
365 	return 1;
366 }
367 
368 #endif
369 
370