1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 
5 #ifdef WIN32
6 #include <windows.h>
7 #ifndef __GNUC__
8 #pragma comment(lib, "mysqlclient.lib")
9 #endif
10 #include <mysql.h>
11 #include <mysqld_error.h>
12 #include <process.h>
13 #else
14 #include <stdio.h>
15 #include <time.h>
16 #include <mysql.h>
17 #include <mysqld_error.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20 #endif
21 
22 #define TRUE 1
23 #define FALSE 0
24 
25 MYSQL DB, DB2;
26 unsigned char Pass[50];
27 unsigned char User[50];
28 unsigned char DBName[50];
29 unsigned char PC[50];
30 MYSQL_RES *Res, *Res2, *Res3, *Res4;
31 MYSQL_ROW Row, Row2, Row3, Row4;
32 int first_connect;
33 
connect_to_db(unsigned char * U,unsigned char * P,unsigned char * S,unsigned char * D)34 void connect_to_db(unsigned char *U, unsigned char *P, unsigned char *S, unsigned char *D)
35 {
36 	if (strcmp(PC, S) != 0 || strcmp(User, U) != 0 || strcmp(Pass, P) != 0 || strcmp(DBName, D) != 0) {
37 		strcpy(PC, S);
38 		strcpy(User, U);
39 		strcpy(Pass, P);
40 		strcpy(DBName, D);
41 		if (first_connect == TRUE) {
42 			first_connect = FALSE;
43 			mysql_close(&DB2);
44 		}
45 		if (!mysql_real_connect(&DB2, PC, User, Pass, DBName, 0, NULL, 0))
46 			return;
47 	}
48 }
49 
check_if_avail(unsigned char * buf)50 int check_if_avail(unsigned char *buf)
51 {
52 	int found;
53 
54 	if (mysql_real_query(&DB, buf, strlen(buf))) {
55 		return FALSE;
56 	}
57 	if (!(Res2 = mysql_store_result(&DB))) {
58 		return FALSE;
59 	}
60 	found = TRUE;
61 	while ((Row2 = mysql_fetch_row(Res2))) {
62 		connect_to_db(Row2[4], Row2[5], Row2[6], Row2[2]);	//user,pass,pc,db
63 		if (mysql_real_query(&DB2, Row2[3], strlen(Row2[3]))) {
64 			mysql_free_result(Res2);
65 			return FALSE;
66 		}
67 		if (!(Res3 = mysql_store_result(&DB2))) {
68 			mysql_free_result(Res2);
69 			return FALSE;
70 		}
71 		Row3 = mysql_fetch_row(Res3);
72 		if (Row3 == NULL) {
73 			found = FALSE;
74 			break;
75 		}
76 //              printf("%s\n",Row2[3]);
77 	}
78 	mysql_free_result(Res2);
79 	mysql_free_result(Res3);
80 	return found;
81 }
82 
execute_one_action(unsigned char * buf3)83 void execute_one_action(unsigned char *buf3)
84 {
85 	char buf4[5000];
86 	char *b;
87 	int num, num2;
88 	char *args[10];
89 	char buffe[10][200];
90 
91 	buf4[0] = 0;
92 	b = buf3;
93 	num = 0;
94 	buffe[0][0] = 0;
95 	while (b[0] != 0) {
96 		if (strstr(buf3, "daemon_run_program") != NULL) {
97 			if (b[0] == '<') {
98 				if (num != 0)
99 					args[num - 1] = buffe[num];
100 				num++;
101 				buffe[num][0] = 0;
102 				b++;
103 			} else {
104 				if (strstr(b, "daemon_column") == b) {
105 					b += 13;
106 					num2 = atoi(b);
107 					while (b[0] >= '0' && b[0] <= '9')
108 						b++;
109 					strcat(buffe[num], Row3[num2 - 1]);
110 				} else if (strstr(b, "daemon2_column") == b) {
111 					b += 14;
112 					num2 = atoi(b);
113 					while (b[0] >= '0' && b[0] <= '9')
114 						b++;
115 					strcat(buffe[num], Row4[num2 - 1]);
116 				} else {
117 					buffe[num][strlen(buffe[num]) + 1] = 0;
118 					buffe[num][strlen(buffe[num])] = b[0];
119 					b++;
120 				}
121 			}
122 		} else {
123 			if (strstr(b, "daemon_column") == b) {
124 				b += 13;
125 				num2 = atoi(b);
126 				while (b[0] >= '0' && b[0] <= '9')
127 					b++;
128 				strcat(buf4, Row3[num2 - 1]);
129 			} else if (strstr(b, "daemon2_column") == b) {
130 				b += 14;
131 				num2 = atoi(b);
132 				while (b[0] >= '0' && b[0] <= '9')
133 					b++;
134 				strcat(buf4, Row4[num2 - 1]);
135 			} else {
136 				buf4[strlen(buf4) + 1] = 0;
137 				buf4[strlen(buf4)] = b[0];
138 			}
139 		}
140 	}
141 	if (strstr(buf3, "daemon_run_program") != NULL) {
142 		args[num - 1] = NULL;
143 //              for (i=0;i<num-1;i++) {
144 //                      printf("arg %i \"%s\"\n",i,args[i]);
145 //              }
146 //              if (num >= 0) {
147 #ifdef WIN32
148 # ifdef SPAWNV_ARGUMENT_IS_CONST
149 		spawnv(_P_NOWAIT, buffe[1], (const char * const*)args);
150 # else
151 		spawnv(_P_NOWAIT, buffe[1], (char * const*)args);
152 #endif
153 #else
154 		if (fork() == 0)
155 			execve(buffe[1], args, NULL);
156 #endif
157 //              }
158 	} else {
159 		connect_to_db(Row2[11], Row2[12], Row2[14], Row2[13]);	//user,pass,pc,db
160 		mysql_query(&DB2, buf4);
161 	}
162 }
163 
execute_all_actions(unsigned char * buf)164 void execute_all_actions(unsigned char *buf)
165 {
166 	size_t i;
167 	char buf3[5000];
168 
169 	buf3[0] = 0;
170 	for (i = 0; i < strlen(buf); i++) {
171 		if (buf[i] == '{') {
172 			execute_one_action(buf3);
173 			buf3[0] = 0;
174 		} else {
175 			buf3[strlen(buf3) + 1] = 0;
176 			buf3[strlen(buf3)] = buf[i];
177 		}
178 	}
179 	if (buf3[0] != 0)
180 		execute_one_action(buf3);
181 }
182 
execute_actions(void)183 void execute_actions(void)
184 {
185 	int first, j = 0;
186 	size_t i;
187 	char buf3[5000], buf4[5000];
188 
189 	//we search for select part
190 	first = 0;
191 	buf3[0] = 0;
192 	buf4[0] = 0;
193 	for (i = 0; i < strlen(Row2[10]); i++) {
194 		if (Row2[10][i] == '{') {
195 			if (first == 0)
196 				j = i;
197 			if (first == 1)
198 				break;
199 			first++;
200 		} else {
201 			if (first == 0) {
202 				buf3[strlen(buf3) + 1] = 0;
203 				buf3[strlen(buf3)] = Row2[10][i];
204 			} else if (first == 1) {
205 				buf4[strlen(buf4) + 1] = 0;
206 				buf4[strlen(buf4)] = Row2[10][i];
207 			}
208 		}
209 	}
210 	if (buf4[0] != 0) {
211 		if (strstr(buf4, "select") == NULL || strstr(buf4, "from") == NULL || strstr(buf4, "where") == NULL) {
212 			buf4[0] = 0;
213 			i = j;
214 		}
215 	}
216 	connect_to_db(Row2[2], Row2[4], Row2[8], Row2[6]);	//user,pass,pc,db
217 	if (mysql_real_query(&DB2, buf3, strlen(buf3))) {
218 		return;
219 	}
220 	if (!(Res3 = mysql_store_result(&DB2))) {
221 		return;
222 	}
223 	while ((Row3 = mysql_fetch_row(Res3))) {
224 		//for each value we execute actions
225 		if (buf4[0] != 0) {
226 			connect_to_db(Row2[3], Row2[5], Row2[9], Row2[7]);	//user,pass,pc,db
227 			if (mysql_real_query(&DB2, buf4, strlen(buf4))) {
228 				return;
229 			}
230 			if (!(Res4 = mysql_store_result(&DB2))) {
231 				return;
232 			}
233 			while ((Row4 = mysql_fetch_row(Res4))) {
234 				execute_all_actions(Row2[10] + i + 1);
235 			}
236 			mysql_free_result(Res4);
237 		} else {
238 			execute_all_actions(Row2[10] + i + 1);
239 		}
240 	}
241 	mysql_free_result(Res3);
242 }
243 
main(int argc,char * argv[])244 int main(int argc, char *argv[])
245 {
246 	char buf[5000];
247 
248 	first_connect = TRUE;
249 	DBName[0] = 0;
250 	Pass[0] = 0;
251 	User[0] = 0;
252 	PC[0] = 0;
253 	mysql_init(&DB);
254 	mysql_init(&DB2);
255 
256 	if (argc < 4) {
257 		printf("Usage: PC User Password Database\n");
258 		return 2;
259 	}
260 	//connect
261 	if (!mysql_real_connect(&DB, argv[1], argv[2], argv[3], argv[4], 0, NULL, 0)) {
262 		printf("I can't read rules & actions database");
263 		return 2;
264 	}
265 
266 	while (TRUE) {
267 		//search for rules ID
268 		sprintf(buf, "select ID from rules group by ID");
269 		if (mysql_real_query(&DB, buf, strlen(buf))) {
270 			return 1;
271 		}
272 		if (!(Res = mysql_store_result(&DB))) {
273 			return 1;
274 		}
275 		while ((Row = mysql_fetch_row(Res))) {
276 			//search for all rules with some ID and check them inside
277 			sprintf(buf, "SELECT ID,RuleID,DB,SQL,User,Pass,PC FROM `rules` WHERE ID='%s'", Row[0]);
278 			if (check_if_avail(buf) == FALSE)
279 				continue;
280 
281 			//yes, we execute actions
282 			sprintf(buf, "SELECT ID,ActionID,User,User2,Pass,Pass2,DB,DB2,PC,PC2,SQL,User3,Pass3,DB3,PC3 FROM `actions` WHERE ID='%s'", Row[0]);
283 			if (mysql_real_query(&DB, buf, strlen(buf))) {
284 				return 1;
285 			}
286 			if (!(Res2 = mysql_store_result(&DB))) {
287 				return 1;
288 			}
289 			while ((Row2 = mysql_fetch_row(Res2))) {
290 				//we don't have two parts
291 				if (strstr(Row2[10], "{") == NULL)
292 					continue;
293 
294 				execute_actions();
295 			}
296 			mysql_free_result(Res2);
297 		}
298 		mysql_free_result(Res);
299 #ifdef WIN32
300 		Sleep(500);
301 #else
302 		usleep(2000);
303 #endif
304 	}
305 
306 	return 0;
307 }
308 
309 /* How should editor hadle tabs in this file? Add editor commands here.
310  * vim: noexpandtab sw=8 ts=8 sts=8:
311  */
312