1 /*  Open DC Hub - A Linux/Unix version of the Direct Connect hub.
2  *  Copyright (C) 2002,2003  Jonatan Nilsson
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
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.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 
20 
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24 
25 #include <sys/types.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #if HAVE_MALLOC_H
30 # include <malloc.h>
31 #endif
32 #include <ctype.h>
33 #include <netdb.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #if HAVE_CRYPT_H
38 # include <crypt.h>
39 #endif
40 #if HAVE_UNISTD_H
41 # include <unistd.h>
42 #endif
43 #if HAVE_FCNTL_H
44 # include <fcntl.h>
45 #endif
46 #include <sys/stat.h>
47 #include <sys/types.h>
48 #include <stdarg.h>
49 #if TIME_WITH_SYS_TIME
50 # include <sys/time.h>
51 # include <time.h>
52 #else
53 # if HAVE_SYS_TIME_H
54 #  include <sys/time.h>
55 # else
56 #  include <time.h>
57 # endif
58 #endif
59 #include <errno.h>
60 #include <dirent.h>
61 #ifdef HAVE_SYSLOG_H
62 # include <syslog.h>
63 #endif
64 #ifdef SWITCH_USER
65 # include <pwd.h>
66 #endif
67 
68 #include "main.h"
69 #include "utils.h"
70 #include "fileio.h"
71 #include "network.h"
72 #ifdef HAVE_PERL
73 # include "perl_utils.h"
74 #endif
75 
76 #ifndef HAVE_STRTOLL
77 # ifdef HAVE_STRTOQ
78 #  define strtoll(X, Y, Z) (long long)strtoq(X, Y, Z)
79 # endif
80 #endif
81 
82 /* Reads config file */
read_config(void)83 int read_config(void)
84 {
85    int i, j;
86    int fd;
87    int erret;
88    FILE *fp;
89    char path[MAX_FDP_LEN+1];
90    char line[1024];
91 
92    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, CONFIG_FILE);
93 
94    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
95      logprintf(1, "Error - In read_config()/open(): Interrupted system call. Trying again.\n");
96 
97    if(fd < 0)
98      {
99 	logprintf(1, "Error - In read_config()/open(): ");
100 	logerror(1, errno);
101 	return -1;
102      }
103 
104    /* Set the lock */
105    if(set_lock(fd, F_RDLCK) == 0)
106      {
107 	logprintf(1, "Error - In read_config(): Couldn't set file lock\n");
108 	close(fd);
109 	return -1;
110      }
111 
112 
113    if((fp = fdopen(fd, "r")) == NULL)
114      {
115 	logprintf(1, "Error - In read_config()/fdopen(): ");
116 	logerror(1, errno);
117 	set_lock(fd, F_UNLCK);
118 	close(fd);
119 	return -1;
120      }
121 
122    while(fgets(line, 1023, fp) != NULL)
123      {
124 	trim_string(line);
125 
126 	j = strlen(line);
127 	if(j != 0)
128 	  {
129 	     /* Jump to next char which isn't a space */
130 	     i = 0;
131 	     while(line[i] == ' ')
132 	       i++;
133 
134 	     /* Name of the hub */
135 	     if(strncmp(line + i, "hub_name", 8) == 0)
136 	       {
137 		  if(strchr(line + i, '"') == NULL)
138 		    {
139 		       set_lock(fd, F_UNLCK);
140 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
141 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
142 
143 		       if(erret != 0)
144 			 {
145 			    logprintf(1, "Error - In read_config()/fclose(): ");
146 			    logerror(1, errno);
147 			    return -1;
148 			 }
149 
150 		       return -1;
151 		    }
152 		  strncpy(hub_name, strchr(line + i, '"') + 1, MAX_HUB_NAME);
153 		  if(*(hub_name + strlen(hub_name) - 1) == '"')
154 		    *(hub_name + strlen(hub_name) - 1) = '\0';
155 	       }
156 
157 	     /* Maximum hub users */
158 	     else if(strncmp(line + i, "max_users", 9) == 0)
159 	       {
160 		  while(!isdigit((int)line[i]))
161 		    i++;
162 		  max_users = atoi(line + i);
163 	       }
164 	     /* Number of users when fork occurs */
165 	     else if(strncmp(line + i, "users_per_fork", 14) == 0)
166 	       {
167 		  while(!isdigit((int)line[i]))
168 		    i++;
169 		  users_per_fork = atoi(line + i);
170 	       }
171 
172 	     /* The message displayed if hub is full */
173 	     else if(strncmp(line + i, "hub_full_mess", 13) == 0)
174 	       {
175 		  /* The string has to begin with a '"' at the same line */
176 		  if(strchr(line + i, '"') == NULL)
177 		    {
178 		       set_lock(fd, F_UNLCK);
179 
180 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
181 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
182 
183 		       if(erret != 0)
184 			 {
185 			    logprintf(1, "Error - In read_config()/fclose(): ");
186 			    logerror(1, errno);
187 			    return -1;
188 			 }
189 
190 		       return -1;
191 		    }
192 		  if((hub_full_mess = malloc(sizeof(char)
193 		       * (strlen(line+i+1) + 1))) == NULL)
194 		    {
195 		       logprintf(1, "Error - In read_config()/malloc(): ");
196 		       logerror(1, errno);
197 		       quit = 1;
198 		       set_lock(fd, F_UNLCK);
199 		       fclose(fp);
200 		       return -1;
201 		    }
202 		  strcpy(hub_full_mess, strchr(line + i, '"') + 1);
203 		  while((line[strlen(line) - 1] != '"') && (fgets(line, 1023, fp) != NULL))
204 		    {
205 		       trim_string(line);
206 		       if((hub_full_mess = realloc(hub_full_mess, sizeof(char)
207 			* (strlen(hub_full_mess) + strlen(line) + 3))) == NULL)
208 			 {
209 			    logprintf(1, "Error - In read_config()/realloc(): ");
210 			    logerror(1, errno);
211 			    quit = 1;
212 			    set_lock(fd, F_UNLCK);
213 			    fclose(fp);
214 			    return -1;
215 			 }
216 		       sprintfa(hub_full_mess, "\r\n%s", line);
217 		    }
218 		  if(*(hub_full_mess + strlen(hub_full_mess) - 1) == '"')
219 		     *(hub_full_mess + strlen(hub_full_mess) - 1) = '\0';
220 	       }
221 
222 	     /* Description of hub. Sent to public hub list */
223 	     else if(strncmp(line + i, "hub_description", 15) == 0)
224 	       {
225 		  if(strchr(line + i, '"') == NULL)
226 		    {
227 		       set_lock(fd, F_UNLCK);
228 
229 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
230 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
231 
232 		       if(erret != 0)
233 			 {
234 			    logprintf(1, "Error - In read_config()/fclose(): ");
235 			    logerror(1, errno);
236 			    return -1;
237 			 }
238 
239 		       return -1;
240 		    }
241 		  strncpy(hub_description, strchr(line + i, '"') + 1, MAX_HUB_DESC);
242 		  if(*(hub_description + strlen(hub_description) - 1) == '"')
243 		    *(hub_description + strlen(hub_description) - 1) = '\0';
244 	       }
245 
246 	     /* Minimum share to allow a user access */
247 	     else if(strncmp(line + i, "min_share", 9) == 0)
248 	       {
249 		  while(!isdigit((int)line[i]))
250 		    i++;
251 		  min_share = strtoll(line + i, (char **)NULL, 10);
252 	       }
253 
254              /* Minimum upload slots for a user */
255 	     else if(strncmp(line + i, "min_upload_slots", 16) == 0)
256 	       {
257 		  while(!isdigit((int)line[i]))
258 		    i++;
259 		  min_upload_slots = atoi(line + i);
260 	       }
261 
262 	     /* Password for admin to log in via telnet */
263 	     else if(strncmp(line + i, "admin_pass", 10) == 0)
264 	       {
265 		  if(strchr(line + i, '"') == NULL)
266 		    {
267 		       set_lock(fd, F_UNLCK);
268 		         while(((erret = fclose(fp)) != 0) && (errno == EINTR))
269 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
270 
271 		       if(erret != 0)
272 			 {
273 			    logprintf(1, "Error - In read_config()/fclose(): ");
274 			    logerror(1, errno);
275 			    return -1;
276 			 }
277 
278 		       return -1;
279 		    }
280 		  strncpy(admin_pass, strchr(line + i, '"') + 1, MAX_ADMIN_PASS_LEN);
281 		  if(*(admin_pass + strlen(admin_pass) - 1) == '"')
282 		    *(admin_pass + strlen(admin_pass) - 1) = '\0';
283 	       }
284 
285              /* Password for admin to log in via telnet */
286              else if(strncmp(line + i, "default_pass", 12) == 0)
287                {
288                   if(strchr(line + i, '"') == NULL)
289                     {
290                        set_lock(fd, F_UNLCK);
291                          while(((erret = fclose(fp)) != 0) && (errno == EINTR))
292                          logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
293 
294                        if(erret != 0)
295                          {
296                             logprintf(1, "Error - In read_config()/fclose(): ");
297                             logerror(1, errno);
298                             return -1;
299                          }
300 
301                        return -1;
302                     }
303                   strncpy(default_pass, strchr(line + i, '"') + 1, MAX_ADMIN_PASS_LEN);
304                   if(*(default_pass + strlen(default_pass) - 1) == '"')
305                     *(default_pass + strlen(default_pass) - 1) = '\0';
306                }
307 
308 	     /* Password for hub linking */
309 	     else if(strncmp(line + i, "link_pass", 9) == 0)
310 	       {
311 		  if(strchr(line + i, '"') == NULL)
312 		    {
313 		       set_lock(fd, F_UNLCK);
314 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
315 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
316 
317 		       if(erret != 0)
318 			 {
319 			    logprintf(1, "Error - In read_config()/fclose(): ");
320 			    logerror(1, errno);
321 			    return -1;
322 			 }
323 
324 		       return -1;
325 		    }
326 		  strncpy(link_pass, strchr(line + i, '"') + 1, MAX_ADMIN_PASS_LEN);
327 		  if(*(link_pass + strlen(link_pass) - 1) == '"')
328 		    *(link_pass + strlen(link_pass) - 1) = '\0';
329 	       }
330 
331 	     /* The port the hub is listening on */
332 	     else if(strncmp(line + i, "listening_port", 14) == 0)
333 	       {
334 		  while(!isdigit((int)line[i]))
335 		    i++;
336 		  listening_port = (unsigned int)(atoi(line + i));
337 	       }
338 
339 	     /* Listening port for admin connections */
340 	      else if(strncmp(line + i, "admin_port", 10) == 0)
341 	       {
342 		  while(!isdigit((int)line[i]))
343 		    i++;
344 		  admin_port = atoi(line + i);
345 	       }
346 
347 	     /* Listening host for admin connections on localhost */
348 	     else if (strncmp(line + i, "admin_localhost", 15) == 0)
349 	       {
350 	          while(!isdigit((int)line[i]))
351 		    i++;
352 		  admin_localhost = atoi(line + i);
353 	       }
354 
355 	     /* Public hub list host */
356 	     else if(strncmp(line + i, "public_hub_host", 15) == 0)
357 	       {
358 		  if(strchr(line + i, '"') == NULL)
359 		    {
360 		       set_lock(fd, F_UNLCK);
361 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
362 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
363 
364 		       if(erret != 0)
365 			 {
366 			    logprintf(1, "Error - In read_config()/fclose(): ");
367 			    logerror(1, errno);
368 			    return -1;
369 			 }
370 
371 		       return -1;
372 		    }
373 		  strncpy(public_hub_host, strchr(line + i, '"') + 1, 121);
374 		  if(*(public_hub_host + strlen(public_hub_host) - 1) == '"')
375 		    *(public_hub_host + strlen(public_hub_host) - 1) = '\0';
376 	       }
377 
378 	     /* Hostname to upload to public hublist */
379 	     else if(strncmp(line + i, "hub_hostname", 12) == 0)
380 	       {
381 		  if(strchr(line + i, '"') == NULL)
382 		    {
383 		       set_lock(fd, F_UNLCK);
384 
385 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
386 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
387 
388 		       if(erret != 0)
389 			 {
390 			    logprintf(1, "Error - In read_config()/fclose(): ");
391 			    logerror(1, errno);
392 			    return -1;
393 			 }
394 
395 		       return -1;
396 		    }
397 		  strncpy(hub_hostname, strchr(line + i, '"') + 1, 121);
398 		  if(*(hub_hostname + strlen(hub_hostname) - 1) == '"')
399 		    *(hub_hostname + strlen(hub_hostname) - 1) = '\0';
400 	       }
401 
402 	     /* Minimum client version */
403 	     else if(strncmp(line + i, "min_version", 11) == 0)
404 	       {
405 		  if(strchr(line + i, '"') == NULL)
406 		    {
407 		       set_lock(fd, F_UNLCK);
408 
409 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
410 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
411 
412 		       if(erret != 0)
413 			 {
414 			    logprintf(1, "Error - In read_config()/fclose(): ");
415 			    logerror(1, errno);
416 			    return -1;
417 			 }
418 
419 		       return -1;
420 		    }
421 		  strncpy(min_version, strchr(line + i, '"') + 1, 30);
422 		  if(*(min_version + strlen(min_version) - 1) == '"')
423 		    *(min_version + strlen(min_version) - 1) = '\0';
424 	       }
425 
426 	     /* 1 if hub should upload description to public hublist */
427 	      else if(strncmp(line + i, "hublist_upload", 14) == 0)
428 	       {
429 		  while(!isdigit((int)line[i]))
430 		    i++;
431 		  hublist_upload = atoi(line + i);
432 	       }
433 
434 	     /*  Host to redirect users if hub is full */
435 	     else if(strncmp(line + i, "redirect_host", 13) == 0)
436 	       {
437 		  if(strchr(line + i, '"') == NULL)
438 		    {
439 		       redirect_host[0] = '\0';
440 		       set_lock(fd, F_UNLCK);
441 
442 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
443 			 logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
444 
445 		       if(erret != 0)
446 			 {
447 			    logprintf(1, "Error - In read_config()/fclose(): ");
448 			    logerror(1, errno);
449 			    return -1;
450 			 }
451 
452 		       return 1;
453 		    }
454 		  strncpy(redirect_host, strchr(line + i, '"') + 1, 121);
455 		  if(*(redirect_host + strlen(redirect_host) - 1) == '"')
456 		    *(redirect_host + strlen(redirect_host) - 1) = '\0';
457 	       }
458 
459 	     /* 1 for registered only mode */
460 	     else if(strncmp(line + i, "registered_only", 15) == 0)
461 	       {
462 		  while(!isdigit((int)line[i]))
463 		    i++;
464 		  registered_only = atoi(line + i);
465 	       }
466 
467 	      /* 1 for ban to override allow */
468 	     else if(strncmp(line + i, "ban_overrides_allow", 19) == 0)
469 	       {
470 		  while(!isdigit((int)line[i]))
471 		    i++;
472 		  ban_overrides_allow = atoi(line + i);
473 	       }
474 
475 	     /* 1 for validation of clients Keys */
476 	     else if(strncmp(line + i, "check_key", 9) == 0)
477 	       {
478 		  while(!isdigit((int)line[i]))
479 		    i++;
480 		  check_key = atoi(line + i);
481 	       }
482 
483 	       /* 1 for Reverse DNS lookups */
484 	     else if(strncmp(line + i, "reverse_dns", 11) == 0)
485 	       {
486 		  while(!isdigit((int)line[i]))
487 		    i++;
488 		  reverse_dns = atoi(line + i);
489 	       }
490 
491 	     /* 5 for all possible logging, 0 for no logging at all */
492 	     else if(strncmp(line + i, "verbosity", 9) == 0)
493 	       {
494 		  while(!isdigit((int)line[i]))
495 		    i++;
496 		  verbosity = atoi(line + i);
497 	       }
498 	     /* 1 if user should be redirected if he doesn't share enough */
499 	     else if(strncmp(line + i, "redir_on_min_share", 18) == 0)
500 	       {
501 		  while(!isdigit((int)line[i]))
502 		    i++;
503 		  redir_on_min_share = atoi(line + i);
504 	       }
505 	     /* 1 if logging should go to syslog instead */
506 	     else if(strncmp(line + i, "syslog_enable", 13) == 0)
507 	       {
508 		  while(!isdigit((int)line[i]))
509 		    i++;
510 		  syslog_enable = atoi(line + i);
511 	       }
512 	     /* 1 if search IP check should ignore internal IP addresses */
513 	     else if(strncmp(line + i, "searchcheck_exclude_internal", 28) == 0)
514 	       {
515 		  while(!isdigit((int)line[i]))
516 		    i++;
517 		  searchcheck_exclude_internal = atoi(line + i);
518 	       }
519 	     /* 1 if search IP check should be skipped altogether */
520 	     else if(strncmp(line + i, "searchcheck_exclude_all", 23) == 0)
521 	       {
522 		  while(!isdigit((int)line[i]))
523 		    i++;
524 		  searchcheck_exclude_all = atoi(line + i);
525 	       }
526 	     /* Number of minutes user should be banned for when kicked */
527 	     else if(strncmp(line + i, "kick_bantime", 12) == 0)
528 	       {
529 		  while(!isdigit((int)line[i]))
530 		    i++;
531 		  kick_bantime = atoi(line + i);
532 	       }
533 	     /* Min number of seconds between searches */
534 	     else if(strncmp(line + i, "searchspam_time", 15) == 0)
535 	       {
536 		  while(!isdigit((int)line[i]))
537 		    i++;
538 		  searchspam_time = atoi(line + i);
539 	       }
540 	     /* Max length of email addresses */
541 	     else if(strncmp(line + i, "max_email_len", 13) == 0)
542 	       {
543 		  while(!isdigit((int)line[i]))
544 		    i++;
545 		  max_email_len = atoi(line + i);
546 	       }
547 	     /* Max length of user descriptions */
548 	     else if(strncmp(line + i, "max_desc_len", 12) == 0)
549 	       {
550 		  while(!isdigit((int)line[i]))
551 		    i++;
552 		  max_desc_len = atoi(line + i);
553 	       }
554 	     /* Enable encrypted passwords? */
555 	     else if(strncmp(line + i, "crypt_enable", 12) == 0)
556 	       {
557 		  while(!isdigit((int)line[i]))
558 		    i++;
559 		 crypt_enable = atoi(line + i);
560 	       }
561 	  }
562      }
563    set_lock(fd, F_UNLCK);
564 
565    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
566      logprintf(1, "Error - In read_config()/fclose(): Interrupted system call. Trying again.\n");
567 
568    if(erret != 0)
569      {
570 	logprintf(1, "Error - In read_config()/fclose(): ");
571 	logerror(1, errno);
572 	return -1;
573      }
574 
575    return 1;
576 }
577 
578 /* Creates banlist if it does not exist */
create_banlist(void)579 void create_banlist(void)
580 {
581    FILE *fp;
582    int fd;
583    int erret;
584    char path[MAX_FDP_LEN+1];
585 
586    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, BAN_FILE);
587 
588    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
589      logprintf(1, "Error - In create_banlist()/open(): Interrupted system call. Trying again.\n");
590 
591    if(fd >= 0)
592      {
593 	/* Banlist already exists */
594 	close(fd);
595 	return;
596      }
597 
598    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
599      logprintf(1, "Error - In create_banlist()/open(): Interrupted system call. Trying again.\n");
600 
601    if(fd < 0)
602      {
603 	logprintf(1, "Error - In create_banlist()/open(): ");
604 	logerror(1, errno);
605 	return;
606      }
607 
608    /* Set the lock */
609    if(set_lock(fd, F_WRLCK) == 0)
610      {
611 	logprintf(1, "Error - In create_ban_list(): Couldn't set lock\n");
612 	close(fd);
613 	return;
614      }
615 
616    if((fp = fdopen(fd, "a")) == NULL)
617      {
618 	logprintf(1, "Error - In create_ban_list()/fdopen(): ");
619 	logerror(1, errno);
620 	set_lock(fd, F_UNLCK);
621 	close(fd);
622 	return;
623      }
624 
625    logprintf(1, "Created banlist\n");
626    set_lock(fd, F_UNLCK);
627 
628    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
629      logprintf(1, "Error - In create_banlist()/fclose(): Interrupted system call. Trying again.\n");
630 
631    if(erret != 0)
632      {
633 	logprintf(1, "Error - In create_banlist()/fclose(): ");
634 	logerror(1, errno);
635      }
636 }
637 
638 /* Creates nickbanlist if it does not exist */
create_nickbanlist(void)639 void create_nickbanlist(void)
640 {
641    FILE *fp;
642    int fd;
643    int erret;
644    char path[MAX_FDP_LEN+1];
645 
646    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
647 
648    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
649      logprintf(1, "Error - In create_nickbanlist()/open(): Interrupted system call. Trying again.\n");
650 
651    if(fd >= 0)
652      {
653 	/* Nickbanlist already exists */
654 	close(fd);
655 	return;
656      }
657 
658    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
659      logprintf(1, "Error - In create_nickbanlist()/open(): Interrupted system call. Trying again.\n");
660 
661    if(fd < 0)
662      {
663 	logprintf(1, "Error - In create_nickbanlist()/open(): ");
664 	logerror(1, errno);
665 	return;
666      }
667 
668    /* Set the lock */
669    if(set_lock(fd, F_WRLCK) == 0)
670      {
671 	logprintf(1, "Error - In create_nickbanlist(): Couldn't set lock\n");
672 	close(fd);
673 	return;
674      }
675 
676    if((fp = fdopen(fd, "a")) == NULL)
677      {
678 	logprintf(1, "Error - In create_nickbanlist()/fdopen(): ");
679 	logerror(1, errno);
680 	set_lock(fd, F_UNLCK);
681 	close(fd);
682 	return;
683      }
684 
685    logprintf(1, "Created nickbanlist\n");
686    set_lock(fd, F_UNLCK);
687 
688    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
689      logprintf(1, "Error - In create_nickbanlist()/fclose(): Interrupted system call. Trying again.\n");
690 
691    if(erret != 0)
692      {
693 	logprintf(1, "Error - In create_nickbanlist()/fclose(): ");
694 	logerror(1, errno);
695      }
696 }
697 
698 /* Creates allowlist if it does not exist */
create_allowlist(void)699 void create_allowlist(void)
700 {
701    FILE *fp;
702    int fd;
703    int erret;
704    char path[MAX_FDP_LEN+1];
705 
706    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, ALLOW_FILE);
707 
708    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
709      logprintf(1, "Error - In create_allowlist()/open(): Interrupted system call. Trying again.\n");
710 
711    if(fd >= 0)
712      {
713 	/* Allowlist already exists */
714 	close(fd);
715 	return;
716      }
717 
718    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
719      logprintf(1, "Error - In create_allowlist()/open(): Interrupted system call. Trying again.\n");
720 
721    if(fd < 0)
722      {
723 	logprintf(1, "Error - In create_allowlist()/open(): ");
724 	logerror(1, errno);
725 	return;
726      }
727 
728    /* Set the lock */
729    if(set_lock(fd, F_WRLCK) == 0)
730      {
731 	logprintf(1, "Error - In create_allowlist(): Couldn't set file lock\n");
732 	close(fd);
733 	return;
734      }
735 
736    if((fp = fdopen(fd, "a")) == NULL)
737      {
738 	logprintf(1, "Error - In create_allowlist()/fdopen(): ");
739 	logerror(1, errno);
740 	set_lock(fd, F_UNLCK);
741 	close(fd);
742 	return;
743      }
744 
745    logprintf(1, "Created allowlist\n");
746    set_lock(fd, F_UNLCK);
747    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
748      logprintf(1, "Error - In create_allowlist()/fclose(): Interrupted system call. Trying again.\n");
749 
750    if(erret != 0)
751      {
752 	logprintf(1, "Error - In create_allowlist()/fclose(): ");
753 	logerror(1, errno);
754      }
755 }
756 
757 /* Creates reglist if it does not exist */
create_reglist(void)758 void create_reglist(void)
759 {
760    FILE *fp;
761    int fd;
762    int erret;
763    char path[MAX_FDP_LEN+1];
764 
765    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, REG_FILE);
766 
767    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
768      logprintf(1, "Error - In create_reglist()/open(): Interrupted system call. Trying again.\n");
769 
770    if(fd >= 0)
771      {
772 	/* Reglist already exists */
773 	close(fd);
774 	return;
775      }
776 
777    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
778      logprintf(1, "Error - In create_reglist()/open(): Interrupted system call. Trying again.\n");
779 
780    if(fd < 0)
781      {
782 	logprintf(1, "Error - In create_reglist()/open(): ");
783 	logerror(1, errno);
784 	return;
785      }
786 
787    /* Set the lock */
788    if(set_lock(fd, F_WRLCK) == 0)
789      {
790 	logprintf(1, "Error - In create_reglist(): Couldn't set file lock\n");
791 	close(fd);
792 	return;
793      }
794 
795    if((fp = fdopen(fd, "a")) == NULL)
796      {
797 	logprintf(1, "Error - In create_reglist()/fdopen(): ");
798 	logerror(1, errno);
799 	set_lock(fd, F_UNLCK);
800 	close(fd);
801 	return;
802      }
803 
804    logprintf(1, "Created reg list\n");
805    set_lock(fd, F_UNLCK);
806    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
807      logprintf(1, "Error - In create_reglist()/fclose(): Interrupted system call. Trying again.\n");
808 
809    if(erret != 0)
810      {
811 	logprintf(1, "Error - In create_reglist()/fclose(): ");
812 	logerror(1, errno);
813      }
814 }
815 
816 /* Creates op_permlist if it does not exist */
create_op_permlist(void)817 void create_op_permlist(void)
818 {
819    FILE *fp;
820    int fd;
821    int erret;
822    char path[MAX_FDP_LEN+1];
823 
824    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, OP_PERM_FILE);
825 
826    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
827      logprintf(1, "Error - In create_op_permlist()/open(): Interrupted system call. Trying again.\n");
828 
829    if(fd >= 0)
830      {
831 	/* Op permlist already exists */
832 	close(fd);
833 	return;
834      }
835 
836    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
837      logprintf(1, "Error - In create_op_permlist()/open(): Interrupted system call. Trying again.\n");
838 
839    if(fd < 0)
840      {
841 	logprintf(1, "Error - In create_op_permlist()/open(): ");
842 	logerror(1, errno);
843 	return;
844      }
845 
846    /* Set the lock */
847    if(set_lock(fd, F_WRLCK) == 0)
848      {
849 	logprintf(1, "Error - In create_op_permlist(): Couldn't set file lock\n");
850 	close(fd);
851 	return;
852      }
853 
854    if((fp = fdopen(fd, "a")) == NULL)
855      {
856 	logprintf(1, "Error - In create_op_permlist()/fdopen(): ");
857 	logerror(1, errno);
858 	set_lock(fd, F_UNLCK);
859 	close(fd);
860 	return;
861      }
862 
863    logprintf(1, "Created op perm list\n");
864    set_lock(fd, F_UNLCK);
865 
866    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
867      logprintf(1, "Error - In create_op_permlist()/fclose(): Interrupted system call. Trying again.\n");
868 
869    if(erret != 0)
870      {
871 	logprintf(1, "Error - In create_op_permlist()/fclose(): ");
872 	logerror(1, errno);
873      }
874 }
875 
876 /* Creates linklist if it does not exist */
create_linklist(void)877 void create_linklist(void)
878 {
879    FILE *fp;
880    int fd;
881    int erret;
882    char path[MAX_FDP_LEN+1];
883 
884    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LINK_FILE);
885 
886    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
887      logprintf(1, "Error - In create_linklist()/open(): Interrupted system call. Trying again.\n");
888 
889    if(fd >= 0)
890      {
891 	/* Linklist already exists */
892 	close(fd);
893 	return;
894      }
895 
896    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
897      logprintf(1, "Error - In create_linklist()/open(): Interrupted system call. Trying again.\n");
898 
899    if(fd < 0)
900      {
901 	logprintf(1, "Error - In create_linklist()/open(): ");
902 	logerror(1, errno);
903 	return;
904      }
905 
906    /* Set the lock */
907    if(set_lock(fd, F_WRLCK) == 0)
908      {
909 	logprintf(1, "Error - In create_linklist(): Couldn't set file lock\n");
910 	close(fd);
911 	return;
912      }
913 
914    if((fp = fdopen(fd, "a")) == NULL)
915      {
916 	logprintf(1, "Error - In create_linklist()/fdopen(): ");
917 	logerror(1, errno);
918 	set_lock(fd, F_UNLCK);
919 	close(fd);
920 	return;
921      }
922 
923    logprintf(1, "Created link list\n");
924    set_lock(fd, F_UNLCK);
925 
926    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
927      logprintf(1, "Error - In create_linklist()/fclose(): Interrupted system call. Trying again.\n");
928 
929    if(erret != 0)
930      {
931 	logprintf(1, "Error - In create_linklist()/fclose(): ");
932 	logerror(1, errno);
933      }
934 }
935 
936 /* Returns 1 if user is on the banlist.  */
check_if_banned(struct user_t * user,int type)937 int check_if_banned(struct user_t *user, int type)
938 {
939    int i, j;
940    int fd;
941    int erret;
942    FILE *fp;
943    char path[MAX_FDP_LEN+1];
944    char line[1024];
945    char ban_host[MAX_HOST_LEN+1];
946    char *string_ip = NULL;
947    unsigned long userip = 0;
948    unsigned long fileip = 0;
949    int byte1, byte2, byte3, byte4, mask;
950    time_t ban_time;
951    time_t now_time;
952 
953    if(type == BAN)
954 	snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, BAN_FILE);
955    else if(type == NICKBAN)
956 	snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
957    else
958 	return -1;
959 
960    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
961      logprintf(1, "Error - In check_if_banned()/open(): Interrupted system call. Trying again.\n");
962 
963    if(fd < 0)
964      {
965 	logprintf(1, "Error - In check_if_banned()/open(): ");
966 	logerror(1, errno);
967 	return -1;
968      }
969 
970    /* Set the lock */
971    if(set_lock(fd, F_RDLCK) == 0)
972      {
973 	logprintf(1, "Error - In check_if_banned(): Couldn't set file lock\n");
974 	close(fd);
975 	return -1;
976      }
977 
978    if((fp = fdopen(fd, "r")) == NULL)
979      {
980 	logprintf(1, "Error - In check_if_banned()/fdopen(): ");
981 	logerror(1, errno);
982 	set_lock(fd, F_UNLCK);
983 	close(fd);
984 	return -1;
985      }
986 
987    now_time = time(NULL);
988 
989    if(type == BAN)
990      {
991 	if((string_ip = ip_to_string(user->ip)) == NULL)
992 	  {
993 	     set_lock(fd, F_UNLCK);
994 
995 	     while(((erret = fclose(fp)) != 0) && (errno == EINTR))
996 	       logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
997 
998 	     if(erret != 0)
999 	       {
1000 		  logprintf(1, "Error - In check_if_banned()/fclose(): ");
1001 		  logerror(1, errno);
1002 		  return -1;
1003 	       }
1004 
1005 	     return 0;
1006 	  }
1007 	userip = ntohl(user->ip);
1008      }
1009 
1010    while(fgets(line, 1023, fp) != NULL)
1011      {
1012 	trim_string(line);
1013 	ban_time = 0;
1014 
1015 	j = strlen(line);
1016 	if(j != 0)
1017 	  {
1018 	     /* Jump to next char which isn't a space */
1019 	     i = 0;
1020 	     while(line[i] == ' ')
1021 	       i++;
1022 
1023 	     sscanf(line+i, "%120s %lu", ban_host, &ban_time);
1024 	     if(type == BAN)
1025 	       {
1026 		  /* Check if it's part of user's ip */
1027 		  /* First, check if it's a subnet.  */
1028 		  if((sscanf(ban_host, "%d.%d.%d.%d/%d",
1029 			     &byte1, &byte2, &byte3, &byte4, &mask) == 5)
1030 		     && (mask > 0) && (mask <= 32))
1031 		    {
1032 		       fileip = (byte1<<24) | (byte2<<16) | (byte3<<8) | byte4;
1033 		       if((((0xFFFF << (32-mask)) & userip)
1034 			   == ((0xFFFF << (32-mask)) & fileip))
1035 			  && ((ban_time == 0) || (ban_time > now_time)))
1036 			 {
1037 			    set_lock(fd, F_UNLCK);
1038 
1039 			    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1040 			      logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
1041 
1042 			    if(erret != 0)
1043 			      {
1044 				 logprintf(1, "Error - In check_if_banned()/fclose(): ");
1045 				 logerror(1, errno);
1046 				 return -1;
1047 			      }
1048 
1049 			    return 1;
1050 			 }
1051 		    }
1052 		  /* If not, it has to be an exact match.  */
1053 		  else if((strncmp(string_ip, ban_host, strlen(ban_host)) == 0)
1054 			  && (strlen(ban_host) == strlen(string_ip))
1055 			  && ((ban_time == 0) || (ban_time > now_time)))
1056 		    {
1057 		       set_lock(fd, F_UNLCK);
1058 
1059 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1060 			 logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
1061 
1062 		       if(erret != 0)
1063 			 {
1064 			    logprintf(1, "Error - In check_if_banned()/fclose(): ");
1065 			    logerror(1, errno);
1066 			    return -1;
1067 			 }
1068 
1069 		       return 1;
1070 	            }
1071 
1072 		  /* Check if users hostname is banned.  */
1073 		  if((user->hostname != NULL)
1074 		     && (strncmp(user->hostname, string_ip, strlen(string_ip)) != 0))
1075 		    {
1076 		       if(match_with_wildcards(user->hostname, ban_host) != 0)
1077 			 {
1078 			    set_lock(fd, F_UNLCK);
1079 
1080 			    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1081 			      logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
1082 
1083 			    if(erret != 0)
1084 			      {
1085 				 logprintf(1, "Error - In check_if_banned()/fclose(): ");
1086 				 logerror(1, errno);
1087 				 return -1;
1088 			      }
1089 
1090 			    return 1;
1091 			 }
1092 		    }
1093 	       }
1094 	     else
1095 	       {
1096 		  /* Check if a nickname is banned.  */
1097 		  if(((ban_time == 0) || (ban_time > now_time))
1098 		     && (match_with_wildcards(user->nick, ban_host) != 0))
1099 		    {
1100 		       set_lock(fd, F_UNLCK);
1101 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1102 			 logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
1103 
1104 		       if(erret != 0)
1105 			 {
1106 			    logprintf(1, "Error - In check_if_banned()/fclose(): ");
1107 			    logerror(1, errno);
1108 			    return -1;
1109 			 }
1110 
1111 		       return 1;
1112 		    }
1113 	       }
1114           }
1115      }
1116    set_lock(fd, F_UNLCK);
1117 
1118    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1119      logprintf(1, "Error - In check_if_banned()/fclose(): Interrupted system call. Trying again.\n");
1120 
1121    if(erret != 0)
1122      {
1123 	logprintf(1, "Error - In check_if_banned()/fclose(): ");
1124 	logerror(1, errno);
1125 	return -1;
1126      }
1127 
1128    return 0;
1129 }
1130 
1131 /* Returns 1 if user is on the allowlist.  */
check_if_allowed(struct user_t * user)1132 int check_if_allowed(struct user_t *user)
1133 {
1134    int i, j;
1135    int fd;
1136    int erret;
1137    FILE *fp;
1138    char path[MAX_FDP_LEN+1];
1139    char line[1024];
1140    char allow_host[MAX_HOST_LEN+1];
1141    char *string_ip = NULL;
1142    unsigned long userip = 0;
1143    unsigned long fileip = 0;
1144    int byte1, byte2, byte3, byte4, mask;
1145    time_t allow_time;
1146    time_t now_time;
1147 
1148    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, ALLOW_FILE);
1149 
1150    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
1151      logprintf(1, "Error - In check_if_allowed()/open(): Interrupted system call. Trying again.\n");
1152 
1153    if(fd < 0)
1154      {
1155 	logprintf(1, "Error - In check_if_allowed()/open(): ");
1156 	logerror(1, errno);
1157 	return -1;
1158      }
1159 
1160    /* Set the lock */
1161    if(set_lock(fd, F_RDLCK) == 0)
1162      {
1163 	logprintf(1, "Error - In check_if_allowed(): Couldn't set file lock\n");
1164 	close(fd);
1165 	return -1;
1166      }
1167 
1168    if((fp = fdopen(fd, "r")) == NULL)
1169      {
1170 	logprintf(1, "Error - In check_if_allowed()/fdopen(): ");
1171 	logerror(1, errno);
1172 	set_lock(fd, F_UNLCK);
1173 	close(fd);
1174 	return -1;
1175      }
1176 
1177    now_time = time(NULL);
1178 
1179    if((string_ip = ip_to_string(user->ip)) == NULL)
1180      {
1181 	set_lock(fd, F_UNLCK);
1182 
1183 	while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1184 	  logprintf(1, "Error - In check_if_allowed()/fclose(): Interrupted system call. Trying again.\n");
1185 
1186 	if(erret != 0)
1187 	  {
1188 	     logprintf(1, "Error - In check_if_allowed()/fclose(): ");
1189 	     logerror(1, errno);
1190 	     return -1;
1191 	  }
1192 
1193 	return 0;
1194      }
1195    userip = ntohl(user->ip);
1196 
1197    while(fgets(line, 1023, fp) != NULL)
1198      {
1199 	trim_string(line);
1200 	allow_time = 0;
1201 
1202 	j = strlen(line);
1203 	if(j != 0)
1204 	  {
1205 	     /* Jump to next char which isn't a space */
1206 	     i = 0;
1207 	     while(line[i] == ' ')
1208 	       i++;
1209 
1210 	     sscanf(line+i, "%120s %lu", allow_host, &allow_time);
1211 
1212 	     /* Check if it's part of user's ip */
1213 	     /* First, check if it's a subnet.  */
1214 	     if((sscanf(allow_host, "%d.%d.%d.%d/%d",
1215 			&byte1, &byte2, &byte3, &byte4, &mask) == 5)
1216 		&& (mask > 0) && (mask <= 32))
1217 	       {
1218 		  fileip = (byte1<<24) | (byte2<<16) | (byte3<<8) | byte4;
1219 		  if((((0xFFFF << (32-mask)) & userip)
1220 		      == ((0xFFFF << (32-mask)) & fileip))
1221 		     && ((allow_time == 0) || (allow_time > now_time)))
1222 		    {
1223 		       set_lock(fd, F_UNLCK);
1224 
1225 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1226 			 logprintf(1, "Error - In check_if_allowed()/fclose(): Interrupted system call. Trying again.\n");
1227 
1228 		       if(erret != 0)
1229 			 {
1230 			    logprintf(1, "Error - In check_if_allowed()/fclose(): ");
1231 			    logerror(1, errno);
1232 			    return -1;
1233 			 }
1234 
1235 		       return 1;
1236 		    }
1237 	       }
1238 
1239 	     /* If not, it has to be an exact match.  */
1240 	     else if((strncmp(string_ip, allow_host, strlen(allow_host)) == 0)
1241 		     && (strlen(allow_host) == strlen(string_ip))
1242 		     &&((allow_time == 0) || (allow_time > now_time)))
1243 	       {
1244 		  set_lock(fd, F_UNLCK);
1245 
1246 		  while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1247 		    logprintf(1, "Error - In check_if_allowed()/fclose(): Interrupted system call. Trying again.\n");
1248 
1249 		  if(erret != 0)
1250 		    {
1251 		       logprintf(1, "Error - In check_if_allowed()/fclose(): ");
1252 		       logerror(1, errno);
1253 		       return -1;
1254 		    }
1255 
1256 		  return 1;
1257 	       }
1258 
1259 	     /* Check users hostname is allowed.  */
1260 	     if((user->hostname != NULL)
1261 		&& (strncmp(user->hostname, string_ip, strlen(string_ip)) != 0))
1262 	       {
1263 		  if(match_with_wildcards(user->hostname, allow_host) != 0)
1264 		    {
1265 		       set_lock(fd, F_UNLCK);
1266 
1267 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1268 			 logprintf(1, "Error - In check_if_allowed()/fclose(): Interrupted system call. Trying again.\n");
1269 
1270 		       if(erret != 0)
1271 			 {
1272 			    logprintf(1, "Error - In check_if_allowed()/fclose(): ");
1273 			    logerror(1, errno);
1274 			    return -1;
1275 			 }
1276 
1277 		       return 1;
1278 		    }
1279 	       }
1280 	  }
1281      }
1282 
1283    set_lock(fd, F_UNLCK);
1284    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1285      logprintf(1, "Error - In check_if_allowed()/fclose(): Interrupted system call. Trying again.\n");
1286 
1287    if(erret != 0)
1288      {
1289 	logprintf(1, "Error - In check_if_allowed()/fclose(): ");
1290 	logerror(1, errno);
1291 	return -1;
1292      }
1293 
1294    return 0;
1295 }
1296 
1297 /* Returns 1 if a nick is on the registered list, 2 if nick is op and 3 if
1298  * user is op_admin.  */
check_if_registered(char * user_nick)1299 int check_if_registered(char *user_nick)
1300 {
1301    int i, j;
1302    int fd;
1303    int erret;
1304    FILE *fp;
1305    char path[MAX_FDP_LEN+1];
1306    char line[1024];
1307 
1308    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, REG_FILE);
1309 
1310    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
1311      logprintf(1, "Error - In check_if_registered()/open(): Interrupted system call. Trying again.\n");
1312 
1313    if(fd < 0)
1314      {
1315 	logprintf(1, "Error - In check_if_registered()/open(): ");
1316 	logerror(1, errno);
1317 	return -1;
1318      }
1319 
1320    /* Set the lock */
1321    if(set_lock(fd, F_RDLCK) == 0)
1322      {
1323 	logprintf(1, "Error - In check_if_registered(): Couldn't set lock\n");
1324 	close(fd);
1325 	return -1;
1326      }
1327 
1328 
1329    if((fp = fdopen(fd, "r")) == NULL)
1330      {
1331 	logprintf(1, "Error - In check_if_registered()/fdopen(): ");
1332 	logerror(1, errno);
1333 	set_lock(fd, F_UNLCK);
1334 	close(fd);
1335 	return -1;
1336      }
1337 
1338    while(fgets(line, 1023, fp) != NULL)
1339      {
1340 	trim_string(line);
1341 
1342 	j = strlen(line);
1343 	if(j != 0)
1344 	  {
1345 	     /* Jump to next char which isn't a space */
1346 	     i = 0;
1347 	     while(line[i] == ' ')
1348 	       i++;
1349 
1350 	     if((strncasecmp(line + i, user_nick, cut_string(line + i, ' ')) == 0)
1351 		&& (cut_string(line + i, ' ') == strlen(user_nick)))
1352 	       {
1353 		  set_lock(fd, F_UNLCK);
1354 
1355 		  while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1356 		    logprintf(1, "Error - In check_if_registered()/fclose(): Interrupted system call. Trying again.\n");
1357 
1358 		  if(erret != 0)
1359 		    {
1360 		       logprintf(1, "Error - In check_if_registered()/fclose(): ");
1361 		       logerror(1, errno);
1362 		       return -1;
1363 		    }
1364 
1365 		  /* Return 3 if user is op admin */
1366 		  if(line[j-1] == '2')
1367 		    return 3;
1368 
1369 		  /* Return 2 if user is op */
1370 		  if(line[j-1] == '1')
1371 		    return 2;
1372 		  return 1;
1373 	       }
1374 	  }
1375      }
1376    set_lock(fd, F_UNLCK);
1377 
1378    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1379      logprintf(1, "Error - In check_if_registered()/fclose(): Interrupted system call. Trying again.\n");
1380 
1381    if(erret != 0)
1382      {
1383 	logprintf(1, "Error - In check_if_registered()/fclose(): ");
1384 	logerror(1, errno);
1385 	return -1;
1386      }
1387 
1388    return 0;
1389 }
1390 
1391 /* Returns 0 if user is not on the list, 2 if user is registered, 3 if user
1392  * is OP, 4 if user is Op Admin and -1 if error */
check_pass(char * buf,struct user_t * user)1393 int check_pass(char *buf, struct user_t *user)
1394 {
1395    int i, j;
1396    int fd;
1397    int erret;
1398    FILE *fp;
1399    char path[MAX_FDP_LEN+1];
1400    char line[1024];
1401    char reg_passwd[51];
1402    char this_passwd[51];
1403    char* tmp;
1404 
1405    strncpy(this_passwd,buf,50);
1406    this_passwd[strlen(this_passwd)-1] = '\0';
1407 
1408    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, REG_FILE);
1409 
1410    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
1411      logprintf(1, "Error - In check_pass()/open(): Interrupted system call. Trying again.\n");
1412 
1413    if(fd < 0)
1414      {
1415 	logprintf(1, "Error - In check_pass()/open(): ");
1416 	logerror(1, errno);
1417 	return -1;
1418      }
1419 
1420    /* Set the lock */
1421    if(set_lock(fd, F_RDLCK) == 0)
1422      {
1423 	logprintf(1, "Error - In check_pass(): Couldn't set file lock\n");
1424 	close(fd);
1425 	return -1;
1426      }
1427 
1428    if((fp = fdopen(fd, "r")) == NULL)
1429      {
1430 	logprintf(1, "Error - In check_pass()/fdopen(): ");
1431 	logerror(1, errno);
1432 	set_lock(fd, F_UNLCK);
1433 	close(fd);
1434 	return -1;
1435      }
1436 
1437    while(fgets(line, 1023, fp) != NULL)
1438      {
1439 	trim_string(line);
1440 
1441 	j = strlen(line);
1442 	if(j != 0)
1443 	  {
1444 	     /* Jump to next char which isn't a space */
1445 	     i = 0;
1446 	     while(line[i] == ' ')
1447 	       i++;
1448 
1449 	     if((strncasecmp(line + i, user->nick, cut_string(line + i, ' ')) == 0)
1450 		&& (cut_string(line + i, ' ') == strlen(user->nick)))
1451 	       {
1452 		  /* User is on the list */
1453 		  if((i = cut_string(line + i, ' ')) == -1)
1454 		    {
1455 		       logprintf(1, "Error - In check_pass(): Erroneous line in file\n");
1456 		       set_lock(fd, F_UNLCK);
1457 
1458 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1459 			 logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1460 
1461 		       if(erret != 0)
1462 			 {
1463 			    logprintf(1, "Error - In check_pass()/fclose(): ");
1464 			    logerror(1, errno);
1465 			    return -1;
1466 			 }
1467 
1468 		       return -1;
1469 		    }
1470 
1471 		  while(line[i] == ' ')
1472 		    i++;
1473 		  if(line[i] == '\0')
1474 		    {
1475 		       logprintf(1, "Error - In check_pass(): Erroneous line in file\n");
1476 		       set_lock(fd, F_UNLCK);
1477 
1478 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1479 			 logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1480 
1481 		       if(erret != 0)
1482 			 {
1483 			    logprintf(1, "Error - In check_pass()/fclose(): ");
1484 			    logerror(1, errno);
1485 			    return -1;
1486 			 }
1487 
1488 		       return -1;
1489 		    }
1490 		  if((j = i + cut_string(line + i, ' ')) == -1)
1491 		    {
1492 		       logprintf(1, "Error - In check_pass(): Erroneous line in file\n");
1493 		       set_lock(fd, F_UNLCK);
1494 
1495 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1496 			 logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1497 
1498 		       if(erret != 0)
1499 			 {
1500 			    logprintf(1, "Error - In check_pass()/fclose(): ");
1501 			    logerror(1, errno);
1502 			    return -1;
1503 			 }
1504 
1505 		       return -1;
1506 		    }
1507 
1508 		  /* The password check. */
1509 
1510 		  strncpy(reg_passwd,line+i,50);
1511 		  reg_passwd[strlen(reg_passwd)-2] = '\0';
1512 
1513 		  if(crypt_enable != 0)
1514 		    tmp = crypt(this_passwd,reg_passwd);
1515 		  else
1516 		    tmp = this_passwd;
1517 
1518 		  if(strcmp(tmp,reg_passwd) == 0)
1519 		    {
1520 		       /* Users password is correct */
1521 
1522 		       set_lock(fd, F_UNLCK);
1523 
1524 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1525 			 logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1526 
1527 		       if(erret != 0)
1528 			 {
1529 			    logprintf(1, "Error - In check_pass()/fclose(): ");
1530 			    logerror(1, errno);
1531 			    return -1;
1532 			 }
1533 
1534 		       while(line[j] == ' ')
1535 			 j++;
1536 		       if(line[j] == '2')
1537 			 {
1538 			    /* User is OP Admin */
1539 			    return 4;
1540 			 }
1541 		       else if(line[j] == '1')
1542 			 {
1543 			    /* User is OP */
1544 			    return 3;
1545 			 }
1546 		       else if(line[j] == '0')
1547 			 {
1548 			    /* User is registered */
1549 			    return 2;
1550 			 }
1551 		       else
1552 			 {
1553 			    logprintf(1, "Error - In check_pass(): Erroneous line in file\n");
1554 			    return -1;
1555 			 }
1556 		    }
1557 		  else
1558 		    {
1559 		       logprintf(1, "User at %s provided bad password for %s\n", user->hostname, user->nick);
1560 		       set_lock(fd, F_UNLCK);
1561 
1562 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1563 			 logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1564 
1565 		       if(erret != 0)
1566 			 {
1567 			    logprintf(1, "Error - In check_pass()/fclose(): ");
1568 			    logerror(1, errno);
1569 			    return -1;
1570 			 }
1571 
1572 		       return 0;
1573 		    }
1574 	       }
1575 	  }
1576      }
1577 
1578    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1579      logprintf(1, "Error - In check_pass()/fclose(): Interrupted system call. Trying again.\n");
1580 
1581    if(erret != 0)
1582      {
1583 	logprintf(1, "Error - In check_pass()/fclose(): ");
1584 	logerror(1, errno);
1585 	return -1;
1586      }
1587 
1588    if(strlen(default_pass) > 0)
1589      {
1590         if(strcmp(this_passwd,default_pass) == 0)
1591           {
1592             /* User is regular but default pass required */
1593             return 1;
1594           }
1595         else
1596 	  {
1597             return 0;
1598           }
1599      }
1600 
1601    return -1;
1602 }
1603 
get_permissions(char * user_nick)1604 int get_permissions(char *user_nick)
1605 {
1606    FILE *fp;
1607    int fd;
1608    int erret;
1609    int perms = 0;
1610    char path[MAX_FDP_LEN+1];
1611    char line[1024];
1612    int i,j;
1613 
1614    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, OP_PERM_FILE);
1615 
1616    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
1617      logprintf(1, "Error - In get_permissions()/open(): Interrupted system call. Trying again.\n");
1618 
1619    if(fd < 0)
1620      {
1621 	logprintf(1, "Error - In get_permissions()/open(): ");
1622 	logerror(1, errno);
1623 	return -1;
1624      }
1625 
1626    /* Set the lock */
1627    if(set_lock(fd, F_RDLCK) == 0)
1628      {
1629 	logprintf(1, "Error - In get_permissions(): Couldn't set file lock\n");
1630 	close(fd);
1631 	return -1;
1632      }
1633 
1634    if((fp = fdopen(fd, "r")) == NULL)
1635      {
1636 	logprintf(1, "Error - In get_permissions()/fdopen(): ");
1637 	logerror(1, errno);
1638 	set_lock(fd, F_UNLCK);
1639 	close(fd);
1640 	return -1;
1641      }
1642 
1643    while(fgets(line, 1023, fp) != NULL)
1644      {
1645 	trim_string(line);
1646 
1647 	j = strlen(line);
1648 	if(j != 0)
1649 	  {
1650 	     /* Jump to next char which isn't a space */
1651 	     i = 0;
1652 	     while(line[i] == ' ')
1653 	       i++;
1654 
1655 	     if((strncasecmp(line + i, user_nick, cut_string(line + i, ' ')) == 0)
1656 		&& (cut_string(line + i, ' ') == strlen(user_nick)))
1657 	       {
1658 		  /* User is on the list */
1659 		  if((i = cut_string(line + i, ' ')) == -1)
1660 		    {
1661 		       logprintf(1, "Error - In get_permissions(): Erroneous line in file\n");
1662 		       set_lock(fd, F_UNLCK);
1663 
1664 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1665 			 logprintf(1, "Error - In get_permissions()/fclose(): Interrupted system call. Trying again.\n");
1666 
1667 		       if(erret != 0)
1668 			 {
1669 			    logprintf(1, "Error - In get_permissions()/fclose(): ");
1670 			    logerror(1, errno);
1671 			    return -1;
1672 			 }
1673 
1674 		       return -1;
1675 		    }
1676 
1677 		  while(line[i] == ' ')
1678 		    i++;
1679 		  if(line[i] == '\0')
1680 		    {
1681 		       logprintf(1, "Error - In get_permissions(): Erroneous line in file\n");
1682 		       set_lock(fd, F_UNLCK);
1683 
1684 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1685 			 logprintf(1, "Error - In get_permissions()/fclose(): Interrupted system call. Trying again.\n");
1686 
1687 		       if(erret != 0)
1688 			 {
1689 			    logprintf(1, "Error - In get_permissions()/fclose(): ");
1690 			    logerror(1, errno);
1691 			    return -1;
1692 			 }
1693 
1694 		       return -1;
1695 		    }
1696 		  if((j = i + cut_string(line + i, ' ')) == -1)
1697 		    {
1698 		       logprintf(1, "Error - In get_permissions(): Erroneous line in file\n");
1699 		       set_lock(fd, F_UNLCK);
1700 
1701 		       while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1702 			 logprintf(1, "Error - In get_permissions()/fclose(): Interrupted system call. Trying again.\n");
1703 
1704 		       if(erret != 0)
1705 			 {
1706 			    logprintf(1, "Error - In get_permissions()/fclose(): ");
1707 			    logerror(1, errno);
1708 			    return -1;
1709 			 }
1710 
1711 		       return -1;
1712 		    }
1713 
1714 		  perms = atoi(line + i);
1715 	       }
1716 	  }
1717      }
1718    set_lock(fd, F_UNLCK);
1719 
1720    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1721      logprintf(1, "Error - In get_permissions()/fclose(): Interrupted system call. Trying again.\n");
1722 
1723    if(erret != 0)
1724      {
1725 	logprintf(1, "Error - In get_permissions()/fclose(): ");
1726 	logerror(1, errno);
1727 	return -1;
1728      }
1729 
1730    return perms;
1731 }
1732 
1733 /* Write config file */
write_config_file(void)1734 int write_config_file(void)
1735 {
1736    FILE *fp;
1737    int fd;
1738    int erret;
1739    char path[MAX_FDP_LEN+1];
1740 
1741    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, CONFIG_FILE);
1742 
1743    /* Remove existing config file */
1744    unlink(path);
1745 
1746    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
1747      logprintf(1, "Error - In write_config_file()/open(): Interrupted system call. Trying again.\n");
1748 
1749    if(fd < 0)
1750      {
1751 	logprintf(1, "Error - In write_config_file()/open(): ");
1752 	logerror(1, errno);
1753 	return -1;
1754      }
1755 
1756    /* Set the lock */
1757    if(set_lock(fd, F_WRLCK) == 0)
1758      {
1759 	logprintf(1, "Error - In write_config_file(): Couldn't set file lock\n");
1760 	close(fd);
1761 	return -1;
1762      }
1763 
1764    if((fp = fdopen(fd, "w")) == NULL)
1765      {
1766 	logprintf(1, "Error - In write_config_file()/fdopen(): ");
1767 	logerror(1, errno);
1768 	set_lock(fd, F_UNLCK);
1769 	close(fd);
1770 	return -1;
1771      }
1772 
1773    fprintf(fp, "hub_name = \"%s\"\n\n", hub_name);
1774 
1775    fprintf(fp, "max_users = %d\n\n", max_users);
1776 
1777    fprintf(fp, "hub_full_mess = \"%s\"\n\n", hub_full_mess);
1778 
1779    fprintf(fp, "hub_description = \"%s\"\n\n", hub_description);
1780 
1781    fprintf(fp, "min_share = %llu\n\n", min_share);
1782 
1783    fprintf(fp, "min_upload_slots = %d\n\n", min_upload_slots);
1784 
1785    fprintf(fp, "admin_pass = \"%s\"\n\n", admin_pass);
1786 
1787    fprintf(fp, "default_pass = \"%s\"\n\n", default_pass);
1788 
1789    fprintf(fp, "link_pass = \"%s\"\n\n", link_pass);
1790 
1791    fprintf(fp, "users_per_fork = %d\n\n", users_per_fork);
1792 
1793    fprintf(fp, "listening_port = %u\n\n", listening_port);
1794 
1795    fprintf(fp, "admin_port = %u\n\n", admin_port);
1796 
1797    fprintf(fp, "admin_localhost = %u\n\n", admin_localhost);
1798 
1799    fprintf(fp, "hublist_upload = %d\n\n", hublist_upload);
1800 
1801    fprintf(fp, "public_hub_host = \"%s\"\n\n", public_hub_host);
1802 
1803    fprintf(fp, "hub_hostname = \"%s\"\n\n", hub_hostname);
1804 
1805    fprintf(fp, "min_version = \"%s\"\n\n", min_version);
1806 
1807    fprintf(fp, "redirect_host = \"%s\"\n\n", redirect_host);
1808 
1809    fprintf(fp, "registered_only = %d\n\n", registered_only);
1810 
1811    fprintf(fp, "check_key = %d\n\n", check_key);
1812 
1813    fprintf(fp, "reverse_dns = %d\n\n", reverse_dns);
1814 
1815    fprintf(fp, "ban_overrides_allow = %d\n\n", ban_overrides_allow);
1816 
1817    fprintf(fp, "verbosity = %d\n\n", verbosity);
1818 
1819    fprintf(fp, "redir_on_min_share = %d\n\n", redir_on_min_share);
1820 
1821    fprintf(fp, "syslog_enable = %d\n\n", syslog_enable);
1822 
1823    fprintf(fp, "searchcheck_exclude_internal = %d\n\n", searchcheck_exclude_internal);
1824 
1825    fprintf(fp, "searchcheck_exclude_all = %d\n\n", searchcheck_exclude_all);
1826 
1827    fprintf(fp, "kick_bantime = %d\n\n", kick_bantime);
1828 
1829    fprintf(fp, "searchspam_time = %d\n\n", searchspam_time);
1830 
1831    fprintf(fp, "max_email_len = %d\n\n", max_email_len);
1832 
1833    fprintf(fp, "max_desc_len = %d\n\n", max_desc_len);
1834 
1835    fprintf(fp, "crypt_enable = %d\n\n", crypt_enable);
1836 
1837    set_lock(fd, F_UNLCK);
1838 
1839    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
1840      logprintf(1, "Error - In write_config_file()/fclose(): Interrupted system call. Trying again.\n");
1841 
1842    if(erret != 0)
1843      {
1844 	logprintf(1, "Error - In write_config_file()/fclose(): ");
1845 	logerror(1, errno);
1846 	return -1;
1847      }
1848 
1849    return 1;
1850 }
1851 
1852 /* Set lock on file */
set_lock(int fd,int type)1853 int set_lock(int fd, int type)
1854 {
1855    int ret;
1856    struct flock lock;
1857 
1858    memset(&lock, 0, sizeof(struct flock));
1859    lock.l_whence = SEEK_SET;
1860    lock.l_start = 0;
1861    lock.l_len = 0;
1862 
1863    lock.l_type = type;
1864 
1865    while(((ret = fcntl(fd, F_SETLKW, &lock)) < 0) && (errno == EINTR))
1866      logprintf(1, "Error - In set_lock()/fcntl(): Interrupted system call. Trying again.\n");
1867 
1868    if(ret < 0)
1869      {
1870 	logprintf(1, "Error - In set_lock()/fcntl(): ");
1871 	logerror(1, errno);
1872 	quit = 1;
1873 	return 0;
1874      }
1875 
1876    return 1;
1877 }
1878 
1879 /* Removes a user from the reglist */
remove_reg_user(char * buf,struct user_t * user)1880 int remove_reg_user(char *buf, struct user_t *user)
1881 {
1882    int nick_len;
1883    char *temp;
1884    char nick[MAX_NICK_LEN+1];
1885    char path[MAX_FDP_LEN+1];
1886    int line_nbr;
1887 
1888    line_nbr = 0;
1889    temp = NULL;
1890 
1891    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, REG_FILE);
1892 
1893    if(buf[strlen(buf)-1] == '|')
1894      nick_len = strlen(buf)-1;
1895    else
1896      nick_len = strlen(buf);
1897 
1898    snprintf(nick, (nick_len>MAX_NICK_LEN)?MAX_NICK_LEN+1:nick_len+1, "%s", buf);
1899 
1900    if((user->type != ADMIN) &&
1901       (check_if_registered(nick) > check_if_registered(user->nick)))
1902      return -1;
1903 
1904    return remove_line_from_file(nick, path, 0);
1905 }
1906 
1907 
1908 /* Adds a user to the reglist. Returns 2 if the command had bad format and 3
1909  * if it's already registered Format is: $AddRegUser <nick> <pass> <opstatus> */
add_reg_user(char * buf,struct user_t * user)1910 int add_reg_user(char *buf, struct user_t *user)
1911 {
1912    int ret;
1913    char command[21];
1914    char nick[MAX_NICK_LEN+1];
1915    char pass[51];
1916    char path[MAX_FDP_LEN+1];
1917    char line[51 + MAX_NICK_LEN + 2];
1918    int  type;
1919 
1920    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, REG_FILE);
1921 
1922    if(sscanf(buf, "%20s %50s %50s %d|", command, nick, pass, &type) != 4)
1923      return 2;
1924 
1925    if((pass[0] == '\0') || ((type != 0) && (type != 1) && (type != 2)))
1926      return 2;
1927 
1928    if ((user != NULL) && (user->type != ADMIN)
1929        && (type >= check_if_registered(user->nick)))
1930      return -1;
1931 
1932    /* If the user already is there, then remove the user first */
1933    if(check_if_registered(nick) != 0)
1934      return 3;
1935 
1936    encrypt_pass(pass);
1937 
1938    sprintf(line, "%s %s %d", nick, pass, type);
1939 
1940    ret = add_line_to_file(line, path);
1941 
1942    /* Send the event to script */
1943 #ifdef HAVE_PERL
1944    if(ret == 1)
1945      {
1946 	command_to_scripts("$Script added_registered_user %c%c", '\005', '\005');
1947 	non_format_to_scripts(nick);
1948 	command_to_scripts("|");
1949      }
1950 #endif
1951    return ret;
1952 }
1953 
1954 /* Adds a hub to the linklist. Returns 2 if the command had bad format */
1955 /* Format is: $AddLinkedHub hub_ip port */
add_linked_hub(char * buf)1956 int add_linked_hub(char *buf)
1957 {
1958    char command[21];
1959    char ip[MAX_HOST_LEN+1];
1960    char path[MAX_FDP_LEN+1];
1961    int  port;
1962    int ret;
1963    char line[MAX_HOST_LEN + 6];
1964    int checkret;
1965 
1966    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LINK_FILE);
1967 
1968    if(sscanf(buf, "%20s %121s %d|", command, ip, &port) != 3)
1969      return 2;
1970 
1971    if((ip[0] == '\0') || (port < 1) || (port > 65536))
1972      return 2;
1973 
1974    if((checkret = check_if_on_linklist(ip, port)) == 1)
1975      return 3;
1976    else if(checkret == -1)
1977      return -1;
1978 
1979    /* And add the hub */
1980    sprintf(line, "%s %d", ip, port);
1981 
1982    ret = add_line_to_file(line, path);
1983 
1984    /* Send to scripts */
1985 #ifdef HAVE_PERL
1986    if(ret == 1)
1987      {
1988 	command_to_scripts("$Script added_multi_hub %c%c", '\005', '\005', ip);
1989 	non_format_to_scripts(ip);
1990 	command_to_scripts("%c%c%d|", '\005', '\005', port);
1991      }
1992 #endif
1993    return ret;
1994 }
1995 
1996 /* Removes a hub from the linklist */
remove_linked_hub(char * buf)1997 int remove_linked_hub(char *buf)
1998 {
1999    int ip_len;
2000    char line[1024];
2001    char ip[MAX_HOST_LEN+1];
2002    int port;
2003    char path[MAX_FDP_LEN+1];
2004 
2005    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LINK_FILE);
2006 
2007    if(sscanf(buf, "%121s %d|", ip, &port) != 2)
2008      return 2;
2009 
2010    if((ip[0] == '\0') || (port < 1) || (port > 65536))
2011      return 2;
2012 
2013    ip_len = strlen(ip);
2014 
2015    sprintf(line, "%s %d", ip, port);
2016 
2017    return remove_line_from_file(line, path, port);
2018 }
2019 
2020 /* Set the directories used */
init_dirs(void)2021 int init_dirs(void)
2022 {
2023    char path[MAX_FDP_LEN+1];
2024    char script_dir[MAX_FDP_LEN+1];
2025 
2026    if(strlen(working_dir) == 0)
2027      {
2028 #ifdef __CYGWIN__
2029 	getcwd(working_dir, MAX_FDP_LEN);
2030 #else
2031 #ifdef SWITCH_USER
2032 	struct passwd *user = getpwuid(dchub_user);
2033 	snprintf( working_dir, MAX_FDP_LEN, "%s", user->pw_dir );
2034 #else
2035 	if( getenv( "HOME" ) == NULL )
2036 	   return 0;
2037 
2038 	snprintf( working_dir, MAX_FDP_LEN, "%s", getenv( "HOME" ) );
2039 #endif
2040 #endif
2041      }
2042    strncpy(path, working_dir, MAX_FDP_LEN);
2043    snprintf( config_dir, MAX_FDP_LEN, "%s/.opendchub", path );
2044 
2045    sprintfa(path, "/tmp");
2046    sprintf(un_sock_path, "%s/%s", path, UN_SOCK_NAME);
2047    sprintf(script_dir, "%s/%s", config_dir, SCRIPT_DIR);
2048    mkdir(config_dir, 0700);
2049    mkdir(path, 0700);
2050    mkdir(script_dir, 0700);
2051    return 1;
2052 }
2053 
2054 /* Print to log file */
logprintf(int verb,const char * format,...)2055 void logprintf(int verb, const char *format, ...)
2056 {
2057    static char buf[4096];
2058    char path[MAX_FDP_LEN+1];
2059    FILE *fp = NULL;
2060    int fd=0;
2061    int erret;
2062    char *localtime;
2063    char *temp;
2064    time_t current_time;
2065    int priority;
2066 
2067    if(verb > verbosity)
2068      return;
2069 
2070    if ((syslog_enable == 0) && (syslog_switch == 0))
2071      {
2072 	if (strlen(logfile) > 1)
2073 	  strncpy(path, logfile, MAX_FDP_LEN);
2074 	else									/* If no preset logfile. */
2075 	  snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LOG_FILE);
2076      }
2077 
2078    if(format)
2079      {
2080 	va_list args;
2081 	va_start(args, format);
2082 	vsnprintf(buf, 4095, format, args);
2083 	va_end(args);
2084 
2085 	if((syslog_enable == 0) && (syslog_switch == 0))
2086 	  {
2087 	     while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
2088 	       {
2089 	       }
2090 
2091 	     if(fd < 0)
2092 	       return;
2093 
2094 	     /* Set the lock */
2095 	     if(set_lock(fd, F_WRLCK) == 0)
2096 	       {
2097 		  close(fd);
2098 		  return;
2099 	       }
2100 
2101 	     if((fp = fdopen(fd, "a")) == NULL)
2102 	       {
2103 		  set_lock(fd, F_UNLCK);
2104 		  close(fd);
2105 		 return;
2106 	      }
2107 	  }
2108 
2109 	current_time = time(NULL);
2110 	localtime = ctime(&current_time);
2111 	temp = localtime;
2112 	temp += 4;
2113 	localtime[strlen(localtime)-6] = 0;
2114 	if(debug != 0)
2115 	  printf("%s %s", temp, buf);
2116 #ifdef HAVE_SYSLOG_H
2117 	else if((syslog_enable != 0) || (syslog_switch != 0))
2118 	  {
2119 	     if(verb > 1)
2120 		priority = LOG_DEBUG;
2121 	     else if (strncmp(buf, "Error - ", 8))
2122 		priority = LOG_ERR;
2123 	     else
2124 		priority = LOG_WARNING;
2125 	     syslog(priority, "%s", buf);
2126 	  }
2127 #endif
2128 	else
2129 	  fprintf(fp, "%s %s", temp, buf);
2130 
2131 	if((syslog_enable == 0) && (syslog_switch == 0))
2132 	  {
2133 	     set_lock(fd, F_UNLCK);
2134 	     while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2135 	       {
2136 	       }
2137 	  }
2138      }
2139 }
2140 
2141 /* Write the motd. Creates the motd file if it doesn't exist. Overwrites
2142    current motd if overwrite is set to 1. Returns 1 on created file and
2143    0 if it already exists. */
write_motd(char * buf,int overwrite)2144 int write_motd(char *buf, int overwrite)
2145 {
2146    FILE *fp;
2147    int fd;
2148    int erret;
2149    char path[MAX_FDP_LEN+1];
2150 
2151    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, MOTD_FILE);
2152 
2153    if(overwrite == 0)
2154      {
2155 	while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
2156 	  logprintf(1, "Error - In write_motd()/open(): Interrupted system call. Trying again.\n");
2157 
2158 	if(fd >= 0)
2159 	  {
2160 	     /* MOTD already exists */
2161 	     close(fd);
2162 	     return 0;
2163 	  }
2164      }
2165 
2166    if(overwrite != 0)
2167      unlink(path);
2168 
2169    while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
2170      logprintf(1, "Error - In write_motd()/open(): Interrupted system call. Trying again.\n");
2171 
2172    if(fd < 0)
2173      {
2174 	logprintf(1, "Error - In write_motd()/open(): ");
2175 	logerror(1, errno);
2176 	return -1;
2177      }
2178 
2179    /* Set the lock */
2180    if(set_lock(fd, F_WRLCK) == 0)
2181      {
2182 	close(fd);
2183 	return -1;
2184      }
2185 
2186    if((fp = fdopen(fd, "w")) == NULL)
2187      {
2188 	logprintf(1, "Error - In write_motd()/fdopen(): ");
2189 	logerror(1, errno);
2190 	set_lock(fd, F_UNLCK);
2191 	close(fd);
2192 	return -1;
2193      }
2194    fprintf(fp, "%s", buf);
2195    set_lock(fd, F_UNLCK);
2196 
2197    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2198      logprintf(1, "Error - In write_motd()/fclose(): Interrupted system call. Trying again.\n");
2199 
2200    if(erret != 0)
2201      {
2202 	logprintf(1, "Error - In write_motd()/fclose(): ");
2203 	logerror(1, errno);
2204 	return -1;
2205      }
2206 
2207    if(overwrite != 0)
2208      return 0;
2209    else
2210      return 1;
2211 }
2212 
2213 /* Sends the motd to the particular user. */
send_motd(struct user_t * user)2214 int send_motd(struct user_t *user)
2215 {
2216    FILE *fp;
2217    int fd;
2218    int erret;
2219    char line[4095];
2220    char path[MAX_FDP_LEN+1];
2221 
2222    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, MOTD_FILE);
2223 
2224    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
2225      logprintf(1, "Error - In send_motd()/open(): Interrupted system call. Trying again.\n");
2226 
2227    if(fd < 0)
2228      {
2229 	logprintf(1, "Error - In send_motd()/open(): ");
2230 	logerror(1, errno);
2231 	return -1;
2232      }
2233 
2234    /* Set the lock */
2235    if(set_lock(fd, F_RDLCK) == 0)
2236      {
2237 	logprintf(1, "Error - In send_motd(): Couldn't set file lock\n");
2238 	close(fd);
2239 	return -1;
2240      }
2241 
2242    if((fp = fdopen(fd, "r")) == NULL)
2243      {
2244 	logprintf(1, "Error - In send_motd()/fdopen(): ");
2245 	logerror(1, errno);
2246 	set_lock(fd, F_UNLCK);
2247 	close(fd);
2248 	return -1;
2249      }
2250 
2251    if(fgets(line, 4094, fp) != NULL)
2252      {
2253 	trim_string(line);
2254 	uprintf(user, "%s", line);
2255 	while(fgets(line, 4094, fp) != NULL)
2256 	  {
2257 	     trim_string(line);
2258 	     uprintf(user, "\r\n%s", line);
2259 	  }
2260      }
2261    set_lock(fd, F_UNLCK);
2262 
2263    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2264      logprintf(1, "Error - In send_motd()/fclose(): Interrupted system call. Trying again.\n");
2265 
2266    if(erret != 0)
2267      {
2268 	logprintf(1, "Error - In send_motd()/fclose(): ");
2269 	logerror(1, errno);
2270 	return -1;
2271      }
2272 
2273    return 1;
2274 }
2275 
2276 /* Sends the welcome message to a newly connected user. */
welcome_mess(struct user_t * user)2277 int welcome_mess(struct user_t *user)
2278 {
2279    int ret;
2280    //uprintf(user, "$To: %s From: Hub $", user->nick);   //This did not let motd to be sent when new user connects.
2281    ret = send_motd(user);
2282    send_to_user("|", user);
2283    return ret;
2284 }
2285 
2286 /* Prints the error to the log file */
logerror(int verb,int error)2287 void logerror(int verb, int error)
2288 {
2289    char path[MAX_FDP_LEN+1];
2290    FILE *fp=NULL;
2291    int fd=0;
2292    int erret;
2293    int priority;
2294 
2295    if(verb > verbosity)
2296      return;
2297 
2298    if((syslog_enable == 0) && (syslog_switch == 0))
2299      {
2300 	snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LOG_FILE);
2301 
2302 	while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
2303 	  {
2304 	  }
2305 
2306 	if(fd < 0)
2307 	  return;
2308 
2309 	/* Set the lock */
2310 	if(set_lock(fd, F_WRLCK) == 0)
2311 	  {
2312 	     close(fd);
2313 	     return;
2314 	  }
2315 
2316 	if((fp = fdopen(fd, "a")) == NULL)
2317 	  {
2318 	     set_lock(fd, F_UNLCK);
2319 	     close(fd);
2320 	     return;
2321 	  }
2322      }
2323 
2324    if(debug != 0)
2325      printf("%s\n", strerror(error));
2326 #ifdef HAVE_SYSLOG_H
2327    else if((syslog_enable != 0) || (syslog_switch != 0))
2328      {
2329 	if(verb > 1)
2330 	   priority = LOG_DEBUG;
2331 	else
2332 	   priority = LOG_ERR;
2333 	syslog(priority, "%s", strerror(error));
2334      }
2335 #endif
2336    else
2337      fprintf(fp, "%s\n", strerror(error));
2338 
2339    if((syslog_enable == 0) && (syslog_switch == 0))
2340      {
2341 	set_lock(fd, F_UNLCK);
2342 
2343 	while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2344 	  {
2345 	  }
2346      }
2347 }
2348 
2349 /* Adds line to end of a file */
add_line_to_file(char * line,char * file)2350 int add_line_to_file(char *line, char *file)
2351 {
2352    FILE *fp;
2353    int fd;
2354    int erret;
2355 
2356    /* Open the file */
2357    while(((fd = open(file, O_RDWR)) < 0) && (errno == EINTR))
2358      logprintf(1, "Error - In add_line_to_file()/open(): Interrupted system call. Trying again.\n");
2359 
2360    if(fd < 0)
2361      {
2362 	logprintf(1, "Error - In add_line_to_file()/open(), file = %s: ", file);
2363 	logerror(1, errno);
2364 	return -1;
2365      }
2366 
2367    /* Set the lock */
2368    if(set_lock(fd, F_WRLCK) == 0)
2369      {
2370 	logprintf(1, "Error - In add_line_to_file(): Couldn't set file lock, file = %s\n", file);
2371 	close(fd);
2372 	return -1;
2373      }
2374 
2375    if((fp = fdopen(fd, "a")) == NULL)
2376      {
2377 	logprintf(1, "Error - In add_line_to_file()/fdopen(), file = %s: ", file);
2378 	logerror(1, errno);
2379 	set_lock(fd, F_UNLCK);
2380 	close(fd);
2381 	return -1;
2382      }
2383 
2384    fprintf(fp, "%s\n", line);
2385 
2386    set_lock(fd, F_UNLCK);
2387 
2388    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2389      logprintf(1, "Error - In add_line_to_file()/fclose(): Interrupted system call. Trying again.\n");
2390 
2391    if(erret != 0)
2392      {
2393 	logprintf(1, "Error - In add_line_to_file()/fclose(): ");
2394 	logerror(1, errno);
2395 	return -1;
2396      }
2397 
2398    return 1;
2399 }
2400 
2401 /* Removes line from file. Word has to match first word in the line in
2402  * the file. If port is set to anything else than zero, it assumes it's the
2403  * linklist file and then the port must match as well. Returns 1 on success,
2404  * 0 if pattern wasn't found and -1 on error.  */
remove_line_from_file(char * line,char * file,int port)2405 int remove_line_from_file(char *line, char *file, int port)
2406 {
2407    FILE *fp;
2408    int fd;
2409    int erret;
2410    char *temp;
2411    char word[201];
2412    char fileline[1024];
2413    char fileword[201];
2414    int i, len;
2415    int fileport;
2416    int line_nbr = 0;
2417 
2418    if((temp = malloc(sizeof(char) * 2)) == NULL)
2419      {
2420 	logprintf(1, "Error - In remove_line_from_file()/malloc(): ");
2421 	logerror(1, errno);
2422 	quit = 1;
2423 	return -1;
2424      }
2425 
2426    sscanf(line, "%200s", word);
2427 
2428    sprintf(temp, "%c", '\0');
2429 
2430    while(((fd = open(file, O_RDWR)) < 0) && (errno == EINTR))
2431      logprintf(1, "Error - In remove_line_from_file()/open(): Interrupted system call. Trying again.\n");
2432 
2433    if(fd < 0)
2434      {
2435 	logprintf(1, "Error - In remove_line_from_file()/open(), file = %s: ", file);	logprintf(1, "Error - In remove_line_from_file()/open(), file = %s: ", file);	logprintf(1, "Error - In remove_line_from_file()/open(), file = %s: ", file);
2436 	logerror(1, errno);
2437 	free(temp);
2438 	return -1;
2439      }
2440 
2441    /* Set the lock */
2442    if(set_lock(fd, F_WRLCK) == 0)
2443      {
2444 	logprintf(1, "Error - In remove_line_from_file(): Couldn't set file lock, file = %s\n", file);
2445 	close(fd);
2446 	free(temp);
2447 	return -1;
2448      }
2449 
2450    if((fp = fdopen(fd, "r")) == NULL)
2451      {
2452 	logprintf(1, "Error - In remove_line_from_file()/fdopen(), file = %s: ", file);
2453 	logerror(1, errno);
2454 	set_lock(fd, F_UNLCK);
2455 	close(fd);
2456 	free(temp);
2457 	return -1;
2458      }
2459 
2460    while(fgets(fileline, 1023, fp) != NULL)
2461      {
2462 	line_nbr++;
2463 	if(port != 0)
2464 	  sscanf(fileline, "%200s %d", fileword, &fileport);
2465 	else
2466 	  {
2467 	     sscanf(fileline, "%200s", fileword);
2468 	     fileport = 0;
2469 	  }
2470 
2471 	if(((strncasecmp(word, fileword, strlen(word)) == 0)
2472 	   && (strlen(word) == strlen(fileword))
2473 	   && (port == fileport)))
2474 	  {
2475 	     /* Put the rest of the file in the temporary string */
2476 	     while(fgets(fileline, 1023, fp) != NULL)
2477 	       {
2478 		  if((temp = realloc(temp, sizeof(char)
2479 				     * (strlen(temp) + strlen(fileline) + 1))) == NULL)
2480 		    {
2481 		       logprintf(1, "Error - In remove_line_from_file()/realloc(): ");
2482 		       logerror(1, errno);
2483 		       quit = 1;
2484 		       set_lock(fd, F_UNLCK);
2485 		       fclose(fp);
2486 		       return -1;
2487 		    }
2488 		  strcat(temp, fileline);
2489 	       }
2490 	     rewind(fp);
2491 
2492 	     /* Go to the position where the user name is */
2493 	     for(i = 1; i<= (line_nbr-1); i++)
2494 	       fgets(fileline, 1023, fp);
2495 
2496 	     /* Truncate the file */
2497 	     len = ftell(fp);
2498 
2499 	     while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2500 	       logprintf(1, "Error - In remove_line_from_file()/fclose(): Interrupted system call. Trying again.\n");
2501 
2502 	     if(erret != 0)
2503 	       {
2504 		  logprintf(1, "Error - In remove_line_from_file()/fclose(): ");
2505 		  logerror(1, errno);
2506 		  return -1;
2507 	       }
2508 
2509 	     truncate(file, len);
2510 
2511 	     while(((fd = open(file, O_RDWR)) < 0) && (errno == EINTR))
2512 	       logprintf(1, "Error - In remove_line_from_file()/open(): Interrupted system call. Trying again.\n");
2513 
2514 	     if(fd < 0)
2515 	       {
2516 		  logprintf(1, "Error - In remove_line_from_file()/open(), file = %s: ", file);
2517 		  logerror(1, errno);
2518 		  free(temp);
2519 		  return -1;
2520 	       }
2521 
2522 	     if((fp = fdopen(fd, "a")) == NULL)
2523 	       {
2524 		  logprintf(1, "Error - In remove_line_from_file()/fdopen(), file = %s: ", file);
2525 		  logerror(1, errno);
2526 		  set_lock(fd, F_UNLCK);
2527 		  close(fd);
2528 		  free(temp);
2529 		  return -1;
2530 	       }
2531 	     fwrite(temp, strlen(temp), 1, fp);
2532 
2533 	     set_lock(fd, F_UNLCK);
2534 
2535 	     while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2536 	       logprintf(1, "Error - In remove_line_from_file()/fclose(): Interrupted system call. Trying again.\n");
2537 
2538 	     if(erret != 0)
2539 	       {
2540 		  logprintf(1, "Error - In remove_line_from_file()/fclose(): ");
2541 		  logerror(1, errno);
2542 		  free(temp);
2543 		  return -1;
2544 	       }
2545 
2546 	     free(temp);
2547 	     return 1;
2548 	  }
2549      }
2550    set_lock(fd, F_UNLCK);
2551 
2552    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2553      logprintf(1, "Error - In remove_line_from_file()/fclose(): Interrupted system call. Trying again.\n");
2554 
2555    if(erret != 0)
2556      {
2557 	logprintf(1, "Error - In remove_line_from_file()/fclose(): ");
2558 	logerror(1, errno);
2559 	free(temp);
2560 	return -1;
2561      }
2562 
2563    free(temp);
2564    return 0;
2565 }
2566 
2567 /* Remove an expired ban/allow line from a file.  */
remove_exp_from_file(time_t now_time,char * file)2568 int remove_exp_from_file(time_t now_time, char *file)
2569 {
2570    FILE *fp;
2571    FILE *newfp;
2572    int fd;
2573    int erret;
2574    int newfd;
2575    char *newfile;
2576    char fileline[1024];
2577    char fileword[201];
2578    time_t exp_time;
2579 
2580    if((newfile = malloc(strlen(file) + 2)) == NULL)
2581      {
2582 	logprintf(1, "Error - In remove_exp_from_file()/malloc(): ");
2583 	logerror(1, errno);
2584 	quit = 1;
2585 	return -1;
2586      }
2587 
2588    strcpy(newfile, file);
2589    strcat(newfile, "1");
2590 
2591    while(((fd = open(file, O_RDWR)) < 0) && (errno == EINTR))
2592      logprintf(1, "Error - In remove_exp_from_file()/open(): Interrupted system call. Trying again.\n");
2593 
2594    if(fd < 0)
2595      {
2596 	logprintf(1, "Error - In remove_exp_from_file()/open(), file = %s: ", file);
2597 	logerror(1, errno);
2598 	free(newfile);
2599 	return -1;
2600      }
2601 
2602    /* Set the lock */
2603    if(set_lock(fd, F_WRLCK) == 0)
2604      {
2605 	logprintf(1, "Error - In remove_exp_from_file(): Couldn't set file lock, file = %s\n", file);
2606 	close(fd);
2607 	free(newfile);
2608 	return -1;
2609      }
2610 
2611    if((fp = fdopen(fd, "r")) == NULL)
2612      {
2613 	logprintf(1, "Error - In remove_exp_from_file()/fdopen(), file = %s: ", file);
2614 	logerror(1, errno);
2615 	set_lock(fd, F_UNLCK);
2616 	close(fd);
2617 	free(newfile);
2618 	return -1;
2619      }
2620 
2621    unlink(newfile);
2622 
2623    while(((newfd = open(newfile, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
2624      logprintf(1, "Error - In remove_exp_from_file()/open(): Interrupted system call. Trying again.\n");
2625 
2626    if(newfd < 0)
2627      {
2628 	logprintf(1, "Error - In remove_exp_from_file()/open(), file = %s: ", newfile);
2629 	logerror(1, errno);
2630 	set_lock(fd, F_UNLCK);
2631 	while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2632 	  logprintf(1, "Error - In remove_exp_from_file()/fclose(): Interrupted system call. Trying again.\n");
2633 
2634 	if(erret != 0)
2635 	  {
2636 	     logprintf(1, "Error - In remove_exp_from_file()/fclose(): ");
2637 	     logerror(1, errno);
2638 	     free(newfile);
2639 	     return -1;
2640 	  }
2641 
2642 	free(newfile);
2643 	return -1;
2644      }
2645 
2646    if(set_lock(newfd, F_WRLCK) == 0)
2647      {
2648 	logprintf(1, "Error - In remove_exp_from_file(): Couldn't set file lock, file = %s\n", newfile);
2649 	set_lock(fd, F_UNLCK);
2650 	fclose(fp);
2651 	close(newfd);
2652 	free(newfile);
2653 	return -1;
2654      }
2655 
2656    if((newfp = fdopen(newfd, "w")) == NULL)
2657      {
2658 	logprintf(1, "Error - In remove_exp_from_file()/fdopen(), file = %s: ", newfile);
2659 	logerror(1, errno);
2660 	set_lock(fd, F_UNLCK);
2661 	fclose(fp);
2662 	set_lock(newfd, F_UNLCK);
2663 	close(newfd);
2664 	free(newfile);
2665 	return -1;
2666      }
2667 
2668    while(fgets(fileline, 1023, fp) != NULL)
2669      {
2670 	exp_time = 0;
2671 	sscanf(fileline, "%200s %lu", fileword, &exp_time);
2672 
2673 	if((exp_time == 0) || (exp_time > now_time))
2674 	  fprintf(newfp, "%s", fileline);
2675      }
2676    set_lock(newfd, F_UNLCK);
2677    set_lock(fd, F_UNLCK);
2678 
2679    while(((erret = fclose(newfp)) != 0) && (errno == EINTR))
2680      logprintf(1, "Error - In remove_exp_from_file()/fclose(): Interrupted system call. Trying again.\n");
2681 
2682    if(erret != 0)
2683      {
2684 	logprintf(1, "Error - In remove_exp_from_file()/fclose(): ");
2685 	logerror(1, errno);
2686 	free(newfile);
2687 	return -1;
2688      }
2689 
2690    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2691      logprintf(1, "Error - In remove_exp_from_file()/fclose(): Interrupted system call. Trying again.\n");
2692 
2693    if(erret != 0)
2694      {
2695 	logprintf(1, "Error - In remove_exp_from_file()/fclose(): ");
2696 	logerror(1, errno);
2697 	free(newfile);
2698 	return -1;
2699      }
2700 
2701    rename(newfile, file);
2702    free(newfile);
2703    return 0;
2704 }
2705 
2706 /* This puts a list of all files in directory dirname that ends with '.pl'
2707  * in namelist. It returns the number of matching entries.  */
my_scandir(char * dirname,char * namelist[])2708 int my_scandir(char *dirname, char *namelist[])
2709 {
2710    DIR *dp;
2711    struct dirent *dent;
2712    int i = 0;
2713 
2714    if((dp = opendir(dirname)) == NULL)
2715      return -1;
2716 
2717    while((dent = readdir(dp)) != NULL)
2718      i++;
2719 
2720    if(i == 0)
2721      return 0;
2722 
2723    rewinddir(dp);
2724 
2725    i = 0;
2726 
2727    while((dent = readdir(dp)) != NULL)
2728      {
2729 
2730 	/* Only parse files with filenames ending with .pl  */
2731 	if(!((strlen( (strrchr(dent->d_name, 'l') == NULL)
2732 		      ? "" : strrchr(dent->d_name, 'l')) == 1)
2733 	     && (strlen( (strrchr(dent->d_name, 'p') == NULL)
2734 			 ? "" : strrchr(dent->d_name, 'p')) == 2)
2735 	     && (strlen( (strrchr(dent->d_name, '.') == NULL)
2736 			 ? "" : strrchr(dent->d_name, '.')) == 3)))
2737 	  continue;
2738 	if((namelist[i] = (char *)malloc(sizeof(char)
2739 				    * (strlen(dirname) + strlen(dent->d_name) + 2))) == NULL)
2740 	  {
2741 	     logprintf(1, "Error - In my_scandir()/malloc(): ");
2742 	     logerror(1, errno);
2743 	     quit = 1;
2744 	     return 0;
2745 	  }
2746 	sprintf(namelist[i], "%s/%s", dirname, dent->d_name);
2747 	i++;
2748      }
2749    closedir(dp);
2750    return i;
2751 }
2752 
2753 /* Adds a permission to an op. Returns 2 if the command had bad format, 3
2754  * if the op already has that permission and 4 if the user is not an op.
2755  * Format is: $AddPerm <nick> <permission> */
add_perm(char * buf,struct user_t * user)2756 int add_perm(char *buf, struct user_t *user)
2757 {
2758    int ret;
2759    char command[21];
2760    char nick[MAX_NICK_LEN+1];
2761    char perm[15];
2762    int new_perm, old_perm;
2763    char path[MAX_FDP_LEN+1];
2764    char line[51 + MAX_NICK_LEN + 2];
2765    struct user_t *targ_user;
2766 
2767    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, OP_PERM_FILE);
2768 
2769    if(sscanf(buf, "%20s %50s %15[^|]", command, nick, perm) != 3)
2770      return 2;
2771 
2772    if(perm[0] == '\0')
2773      return 2;
2774 
2775    if(check_if_registered(nick) != 2)
2776      return 4;
2777 
2778    if((targ_user = get_human_user(nick)) == NULL)
2779      {
2780 	if(*buf == '!')
2781 	  {
2782 	     *buf = '$';
2783 	     send_to_non_humans(buf, FORKED, user);
2784 	     *buf = '!';
2785 	  }
2786 	else
2787 	  send_to_non_humans(buf, FORKED, user);
2788 	return 1;
2789      }
2790    else
2791      {
2792 	if(!(strcasecmp(perm, "BAN_ALLOW")))
2793 	  new_perm = BAN_ALLOW;
2794 	else if(!(strcasecmp(perm, "USER_INFO")))
2795 	  new_perm = USER_INFO;
2796 	else if(!(strcasecmp(perm, "MASSMESSAGE")))
2797 	  new_perm = MASSMESSAGE;
2798 	else if(!(strcasecmp(perm, "USER_ADMIN")))
2799 	  new_perm = USER_ADMIN;
2800 	else
2801 	  return 2;
2802 
2803 	old_perm = get_permissions(nick);
2804 	if((old_perm & new_perm) != 0)
2805 	  return 3;
2806 
2807 	if(old_perm > 0)
2808 	  {
2809 	     sprintf(line, "%s", nick);
2810 	     ret = remove_line_from_file(line, path, 0);
2811 	     if(ret != 1)
2812 	       return ret;
2813 	  }
2814 
2815 	old_perm = old_perm | new_perm;
2816 
2817 	sprintf(line, "%s %d", nick, old_perm);
2818 
2819 	ret = add_line_to_file(line, path);
2820 
2821 	targ_user->permissions = old_perm;
2822 
2823 	return ret;
2824      }
2825 }
2826 
2827 /* Removes a permission from an op. Returns 2 if the command had bad format,
2828  * 3 if the op does not have that permission and 4 if the user is not an op.
2829  * Format is: $RemovePerm <nick> <permission> */
remove_perm(char * buf,struct user_t * user)2830 int remove_perm(char *buf, struct user_t *user)
2831 {
2832    int ret;
2833    char command[21];
2834    char nick[MAX_NICK_LEN+1];
2835    char perm[15];
2836    int old_perm, del_perm;
2837    char path[MAX_FDP_LEN+1];
2838    char line[51 + MAX_NICK_LEN + 2];
2839    struct user_t *targ_user;
2840 
2841    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, OP_PERM_FILE);
2842 
2843    if(sscanf(buf, "%20s %50s %15[^|]", command, nick, perm) != 3)
2844      return 2;
2845 
2846    if(perm[0] == '\0')
2847      return 2;
2848 
2849    if(check_if_registered(nick) != 2)
2850      return 4;
2851 
2852    if((targ_user = get_human_user(nick)) == NULL)
2853      {
2854 	if(*buf == '!')
2855 	  {
2856 	     *buf = '$';
2857 	     send_to_non_humans(buf, FORKED, user);
2858 	     *buf = '!';
2859 	  }
2860 	else
2861 	  send_to_non_humans(buf, FORKED, user);
2862 	return 1;
2863      }
2864    else
2865      {
2866 	if(!(strcasecmp(perm, "BAN_ALLOW")))
2867 	  del_perm = BAN_ALLOW;
2868 	else if(!(strcasecmp(perm, "USER_INFO")))
2869 	  del_perm = USER_INFO;
2870 	else if(!(strcasecmp(perm, "MASSMESSAGE")))
2871 	  del_perm = MASSMESSAGE;
2872 	else if(!(strcasecmp(perm, "USER_ADMIN")))
2873 	  del_perm = USER_ADMIN;
2874 	else
2875 	  return 2;
2876 
2877 	old_perm = get_permissions(nick);
2878 	if((old_perm & del_perm) == 0)
2879 	  return 3;
2880 
2881 	sprintf(line, "%s", nick);
2882 	ret = remove_line_from_file(line, path, 0);
2883 	if(ret != 1)
2884 	  return ret;
2885 
2886 	old_perm = (old_perm ^ del_perm);
2887 
2888 	if(old_perm > 0)
2889 	  {
2890 	     sprintf(line, "%s %d", nick, old_perm);
2891 	     ret = add_line_to_file(line, path);
2892 	  }
2893 
2894 	targ_user->permissions = old_perm;
2895 
2896 	return ret;
2897      }
2898 }
2899 
2900 /* Checks if an entry exists in the linklist. Returns 1 if user exists,
2901  * otherwise 0.  */
check_if_on_linklist(char * ip,int port)2902 int check_if_on_linklist(char *ip, int port)
2903 {
2904    int fd;
2905    int erret;
2906    FILE *fp;
2907    char path[MAX_FDP_LEN+1];
2908    char line[1024];
2909    char fileip[MAX_HOST_LEN+1];
2910    int fileport;
2911 
2912    snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LINK_FILE);
2913 
2914    while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
2915      logprintf(1, "Error - In check_if_on_linklist()/open(): Interrupted system call. Trying again.\n");
2916 
2917    if(fd < 0)
2918      {
2919 	logprintf(1, "Error - In check_if_on_linklist()/open(): ");
2920 	logerror(1, errno);
2921 	return -1;
2922      }
2923 
2924    /* Set the lock */
2925    if(set_lock(fd, F_RDLCK) == 0)
2926      {
2927 	logprintf(1, "Error - In check_if_on_linklist): Couldn't set lock\n");
2928 	close(fd);
2929 	return -1;
2930      }
2931 
2932    if((fp = fdopen(fd, "r")) == NULL)
2933      {
2934 	logprintf(1, "Error - In check_if_on_linklist()/fdopen(): ");
2935 	logerror(1, errno);
2936 	set_lock(fd, F_UNLCK);
2937 	close(fd);
2938 	return -1;
2939      }
2940 
2941    while(fgets(line, 1023, fp) != NULL)
2942      {
2943 	trim_string(line);
2944 	sscanf(line, "%121s %d", fileip, &fileport);
2945 	if((strncmp(ip, fileip, strlen(fileip)) == 0)
2946 	   && (port == fileport) && (strlen(ip) == strlen(fileip)))
2947 	  {
2948 	     while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2949 	       logprintf(1, "Error - In check_if_on_linklist()/fclose(): Interrupted system call. Trying again.\n");
2950 	     return 1;
2951 	  }
2952      }
2953 
2954    while(((erret = fclose(fp)) != 0) && (errno == EINTR))
2955      logprintf(1, "Error - In check_if_on_linklist()/fclose(): Interrupted system call. Trying again.\n");
2956 
2957    return 0;
2958 }
2959 
2960