ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/conf.c
(Generate patch)

Comparing ircd-hybrid/branches/8.2.x/src/conf.c (file contents):
Revision 4976 by michael, Thu Dec 4 15:12:10 2014 UTC vs.
Revision 4983 by michael, Sat Dec 6 18:17:33 2014 UTC

# Line 58 | Line 58
58  
59  
60   /* general conf items link list root, other than k lines etc. */
61 < dlink_list service_items = { NULL, NULL, 0 };
62 < dlink_list server_items  = { NULL, NULL, 0 };
63 < dlink_list cluster_items = { NULL, NULL, 0 };
64 < dlink_list oconf_items   = { NULL, NULL, 0 };
65 < dlink_list uconf_items   = { NULL, NULL, 0 };
66 < dlink_list xconf_items   = { NULL, NULL, 0 };
67 < dlink_list nresv_items   = { NULL, NULL, 0 };
68 < dlink_list cresv_items   = { NULL, NULL, 0 };
61 > dlink_list service_items;
62 > dlink_list server_items;
63 > dlink_list cluster_items;
64 > dlink_list oconf_items;
65 > dlink_list uconf_items;
66 > dlink_list xconf_items;
67 > dlink_list nresv_items;
68 > dlink_list cresv_items;
69  
70   extern unsigned int lineno;
71   extern char linebuf[];
72   extern char conffilebuf[IRCD_BUFSIZE];
73   extern int yyparse(); /* defined in y.tab.c */
74  
75 /* internally defined functions */
76 static void read_conf(FILE *);
77 static void clear_out_old_conf(void);
78 static void expire_tklines(dlink_list *);
79 static int verify_access(struct Client *);
80 static int attach_iline(struct Client *, struct MaskItem *);
81 static dlink_list *map_to_list(enum maskitem_type);
82 static int find_user_host(struct Client *, char *, char *, char *, unsigned int);
83
75  
76   /* conf_dns_callback()
77   *
# Line 114 | Line 105 | conf_dns_callback(void *vptr, const stru
105   static void
106   conf_dns_lookup(struct MaskItem *conf)
107   {
108 <  if (!conf->dns_pending)
109 <  {
119 <    conf->dns_pending = 1;
108 >  if (conf->dns_pending)
109 >    return;
110  
111 <    if (conf->aftype == AF_INET)
112 <      gethost_byname_type(conf_dns_callback, conf, conf->host, T_A);
113 <    else
114 <      gethost_byname_type(conf_dns_callback, conf, conf->host, T_AAAA);
111 >  conf->dns_pending = 1;
112 >
113 >  if (conf->aftype == AF_INET)
114 >    gethost_byname_type(conf_dns_callback, conf, conf->host, T_A);
115 >  else
116 >    gethost_byname_type(conf_dns_callback, conf, conf->host, T_AAAA);
117 > }
118 >
119 > /* map_to_list()
120 > *
121 > * inputs       - ConfType conf
122 > * output       - pointer to dlink_list to use
123 > * side effects - none
124 > */
125 > static dlink_list *
126 > map_to_list(enum maskitem_type type)
127 > {
128 >  switch (type)
129 >  {
130 >    case CONF_XLINE:
131 >      return &xconf_items;
132 >      break;
133 >    case CONF_ULINE:
134 >      return &uconf_items;
135 >      break;
136 >    case CONF_NRESV:
137 >      return &nresv_items;
138 >      break;
139 >    case CONF_CRESV:
140 >      return &cresv_items;
141 >      break;
142 >    case CONF_OPER:
143 >      return &oconf_items;
144 >      break;
145 >    case CONF_SERVER:
146 >      return &server_items;
147 >      break;
148 >    case CONF_SERVICE:
149 >      return &service_items;
150 >      break;
151 >    case CONF_CLUSTER:
152 >      return &cluster_items;
153 >      break;
154 >    default:
155 >      return NULL;
156    }
157   }
158  
# Line 200 | Line 231 | conf_free(struct MaskItem *conf)
231    MyFree(conf);
232   }
233  
234 < /* check_client()
234 > /* attach_iline()
235   *
236 < * inputs       - pointer to client
237 < * output       - 0 = Success
238 < *                NOT_AUTHORIZED    (-1) = Access denied (no I line match)
239 < *                IRCD_SOCKET_ERROR (-2) = Bad socket.
209 < *                I_LINE_FULL       (-3) = I-line is full
210 < *                TOO_MANY          (-4) = Too many connections from hostname
211 < *                BANNED_CLIENT     (-5) = K-lined
212 < * side effects - Ordinary client access check.
213 < *                Look for conf lines which have the same
214 < *                status as the flags passed.
236 > * inputs       - client pointer
237 > *              - conf pointer
238 > * output       -
239 > * side effects - do actual attach
240   */
241 < int
242 < check_client(struct Client *source_p)
241 > static int
242 > attach_iline(struct Client *client_p, struct MaskItem *conf)
243   {
244 <  int i;
245 <
246 <  if ((i = verify_access(source_p)))
247 <    ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
223 <         source_p->name, source_p->sockhost);
224 <
225 <  switch (i)
226 <  {
227 <    case TOO_MANY:
228 <      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
229 <                           "Too many on IP for %s (%s).",
230 <                           get_client_name(source_p, SHOW_IP),
231 <                           source_p->sockhost);
232 <      ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
233 <           get_client_name(source_p, SHOW_IP));
234 <      ++ServerStats.is_ref;
235 <      exit_client(source_p, "No more connections allowed on that IP");
236 <      break;
244 >  const struct ClassItem *const class = conf->class;
245 >  struct ip_entry *ip_found;
246 >  int a_limit_reached = 0;
247 >  unsigned int local = 0, global = 0, ident = 0;
248  
249 <    case I_LINE_FULL:
250 <      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
251 <                           "auth{} block is full for %s (%s).",
241 <                           get_client_name(source_p, SHOW_IP),
242 <                           source_p->sockhost);
243 <      ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
244 <           get_client_name(source_p, SHOW_IP));
245 <      ++ServerStats.is_ref;
246 <      exit_client(source_p, "No more connections allowed in your connection class");
247 <      break;
249 >  ip_found = ipcache_find_or_add_address(&client_p->connection->ip);
250 >  ip_found->count++;
251 >  AddFlag(client_p, FLAGS_IPHASH);
252  
253 <    case NOT_AUTHORIZED:
254 <      ++ServerStats.is_ref;
251 <      /* jdc - lists server name & port connections are on */
252 <      /*       a purely cosmetical change */
253 <      sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
254 <                           "Unauthorized client connection from %s [%s] on [%s/%u].",
255 <                           get_client_name(source_p, SHOW_IP),
256 <                           source_p->sockhost,
257 <                           source_p->connection->listener->name,
258 <                           source_p->connection->listener->port);
259 <      ilog(LOG_TYPE_IRCD,
260 <           "Unauthorized client connection from %s on [%s/%u].",
261 <           get_client_name(source_p, SHOW_IP),
262 <           source_p->connection->listener->name,
263 <           source_p->connection->listener->port);
253 >  count_user_host(client_p->username, client_p->host,
254 >                  &global, &local, &ident);
255  
256 <      exit_client(source_p, "You are not authorized to use this server");
257 <      break;
256 >  /* XXX blah. go down checking the various silly limits
257 >   * setting a_limit_reached if any limit is reached.
258 >   * - Dianora
259 >   */
260 >  if (class->max_total && class->ref_count >= class->max_total)
261 >    a_limit_reached = 1;
262 >  else if (class->max_perip && ip_found->count > class->max_perip)
263 >    a_limit_reached = 1;
264 >  else if (class->max_local && local >= class->max_local)
265 >    a_limit_reached = 1;
266 >  else if (class->max_global && global >= class->max_global)
267 >    a_limit_reached = 1;
268 >  else if (class->max_ident && ident >= class->max_ident &&
269 >           client_p->username[0] != '~')
270 >    a_limit_reached = 1;
271  
272 <   case BANNED_CLIENT:
273 <     exit_client(source_p, "Banned");
274 <     ++ServerStats.is_ref;
275 <     break;
272 >  if (a_limit_reached)
273 >  {
274 >    if (!IsConfExemptLimits(conf))
275 >      return TOO_MANY;   /* Already at maximum allowed */
276  
277 <   case 0:
278 <   default:
275 <     break;
277 >    sendto_one_notice(client_p, &me, ":*** Your connection class is full, "
278 >                      "but you have exceed_limit = yes;");
279    }
280  
281 <  return (i < 0 ? 0 : 1);
281 >  return attach_conf(client_p, conf);
282   }
283  
284   /* verify_access()
285   *
286 < * inputs       - pointer to client to verify
287 < * output       - 0 if success -'ve if not
288 < * side effect  - find the first (best) I line to attach.
286 > * inputs       - pointer to client to verify
287 > * output       - 0 if success -'ve if not
288 > * side effect  - find the first (best) I line to attach.
289   */
290   static int
291   verify_access(struct Client *client_p)
# Line 300 | Line 303 | verify_access(struct Client *client_p)
303    else
304    {
305      strlcpy(non_ident + 1, client_p->username, sizeof(non_ident) - 1);
306 <    conf = find_address_conf(client_p->host,non_ident,
306 >    conf = find_address_conf(client_p->host, non_ident,
307                               &client_p->connection->ip,
308                               client_p->connection->aftype,
309                               client_p->connection->password);
# Line 322 | Line 325 | verify_access(struct Client *client_p)
325        if (IsConfDoSpoofIp(conf))
326        {
327          if (IsConfSpoofNotice(conf))
328 <          sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
326 <                               "%s spoofing: %s as %s",
328 >          sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE, "%s spoofing: %s as %s",
329                                 client_p->name, client_p->host, conf->name);
330 +
331          strlcpy(client_p->host, conf->name, sizeof(client_p->host));
332        }
333  
# Line 334 | Line 337 | verify_access(struct Client *client_p)
337      {
338        if (IsConfGline(conf))
339          sendto_one_notice(client_p, &me, ":*** G-lined");
340 +
341        sendto_one_notice(client_p, &me, ":*** Banned: %s", conf->reason);
342        return BANNED_CLIENT;
343      }
# Line 342 | Line 346 | verify_access(struct Client *client_p)
346    return NOT_AUTHORIZED;
347   }
348  
349 < /* attach_iline()
349 > /* check_client()
350   *
351 < * inputs       - client pointer
352 < *              - conf pointer
353 < * output       -
354 < * side effects - do actual attach
351 > * inputs       - pointer to client
352 > * output       - 0 = Success
353 > *                NOT_AUTHORIZED    (-1) = Access denied (no I line match)
354 > *                IRCD_SOCKET_ERROR (-2) = Bad socket.
355 > *                I_LINE_FULL       (-3) = I-line is full
356 > *                TOO_MANY          (-4) = Too many connections from hostname
357 > *                BANNED_CLIENT     (-5) = K-lined
358 > * side effects - Ordinary client access check.
359 > *                Look for conf lines which have the same
360 > *                status as the flags passed.
361   */
362 < static int
363 < attach_iline(struct Client *client_p, struct MaskItem *conf)
362 > int
363 > check_client(struct Client *source_p)
364   {
365 <  const struct ClassItem *const class = conf->class;
356 <  struct ip_entry *ip_found;
357 <  int a_limit_reached = 0;
358 <  unsigned int local = 0, global = 0, ident = 0;
365 >  int i;
366  
367 <  ip_found = ipcache_find_or_add_address(&client_p->connection->ip);
368 <  ip_found->count++;
369 <  AddFlag(client_p, FLAGS_IPHASH);
367 >  if ((i = verify_access(source_p)))
368 >    ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
369 >         source_p->name, source_p->sockhost);
370  
371 <  count_user_host(client_p->username, client_p->host,
372 <                  &global, &local, &ident);
371 >  switch (i)
372 >  {
373 >    case TOO_MANY:
374 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
375 >                           "Too many on IP for %s (%s).",
376 >                           get_client_name(source_p, SHOW_IP),
377 >                           source_p->sockhost);
378 >      ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
379 >           get_client_name(source_p, SHOW_IP));
380 >      ++ServerStats.is_ref;
381 >      exit_client(source_p, "No more connections allowed on that IP");
382 >      break;
383  
384 <  /* XXX blah. go down checking the various silly limits
385 <   * setting a_limit_reached if any limit is reached.
386 <   * - Dianora
387 <   */
388 <  if (class->max_total && class->ref_count >= class->max_total)
389 <    a_limit_reached = 1;
390 <  else if (class->max_perip && ip_found->count > class->max_perip)
391 <    a_limit_reached = 1;
392 <  else if (class->max_local && local >= class->max_local)
393 <    a_limit_reached = 1;
377 <  else if (class->max_global && global >= class->max_global)
378 <    a_limit_reached = 1;
379 <  else if (class->max_ident && ident >= class->max_ident &&
380 <           client_p->username[0] != '~')
381 <    a_limit_reached = 1;
384 >    case I_LINE_FULL:
385 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
386 >                           "auth {} block is full for %s (%s).",
387 >                           get_client_name(source_p, SHOW_IP),
388 >                           source_p->sockhost);
389 >      ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
390 >           get_client_name(source_p, SHOW_IP));
391 >      ++ServerStats.is_ref;
392 >      exit_client(source_p, "No more connections allowed in your connection class");
393 >      break;
394  
395 <  if (a_limit_reached)
396 <  {
397 <    if (!IsConfExemptLimits(conf))
398 <      return TOO_MANY;   /* Already at maximum allowed */
395 >    case NOT_AUTHORIZED:
396 >      /* jdc - lists server name & port connections are on */
397 >      /*       a purely cosmetical change */
398 >      sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
399 >                           "Unauthorized client connection from %s [%s] on [%s/%u].",
400 >                           get_client_name(source_p, SHOW_IP),
401 >                           source_p->sockhost,
402 >                           source_p->connection->listener->name,
403 >                           source_p->connection->listener->port);
404 >      ilog(LOG_TYPE_IRCD, "Unauthorized client connection from %s on [%s/%u].",
405 >           get_client_name(source_p, SHOW_IP),
406 >           source_p->connection->listener->name,
407 >           source_p->connection->listener->port);
408  
409 <    sendto_one_notice(client_p, &me, ":*** Your connection class is full, "
410 <                      "but you have exceed_limit = yes;");
409 >      ++ServerStats.is_ref;
410 >      exit_client(source_p, "You are not authorized to use this server");
411 >      break;
412 >
413 >    case BANNED_CLIENT:
414 >      ++ServerStats.is_ref;
415 >      exit_client(source_p, "Banned");
416 >      break;
417 >
418 >    case 0:
419 >    default:
420 >      break;
421    }
422  
423 <  return attach_conf(client_p, conf);
423 >  return !(i < 0);
424   }
425  
426   /* detach_conf()
# Line 524 | Line 555 | find_conf_name(dlink_list *list, const c
555    return NULL;
556   }
557  
527 /* map_to_list()
528 *
529 * inputs       - ConfType conf
530 * output       - pointer to dlink_list to use
531 * side effects - none
532 */
533 static dlink_list *
534 map_to_list(enum maskitem_type type)
535 {
536  switch(type)
537  {
538  case CONF_XLINE:
539    return(&xconf_items);
540    break;
541  case CONF_ULINE:
542    return(&uconf_items);
543    break;
544  case CONF_NRESV:
545    return(&nresv_items);
546    break;
547  case CONF_CRESV:
548    return(&cresv_items);
549  case CONF_OPER:
550    return(&oconf_items);
551    break;
552  case CONF_SERVER:
553    return(&server_items);
554    break;
555  case CONF_SERVICE:
556    return(&service_items);
557    break;
558  case CONF_CLUSTER:
559    return(&cluster_items);
560    break;
561  default:
562    return NULL;
563  }
564 }
565
558   /* find_matching_name_conf()
559   *
560   * inputs       - type of link list to look in
# Line 752 | Line 744 | find_exact_name_conf(enum maskitem_type
744    return NULL;
745   }
746  
755 /* rehash()
756 *
757 * Actual REHASH service routine. Called with sig == 0 if it has been called
758 * as a result of an operator issuing this command, else assume it has been
759 * called as a result of the server receiving a HUP signal.
760 */
761 int
762 rehash(int sig)
763 {
764  if (sig)
765    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
766                         "Got signal SIGHUP, reloading configuration file(s)");
767
768  restart_resolver();
769
770  /* don't close listeners until we know we can go ahead with the rehash */
771
772  read_conf_files(0);
773
774  load_conf_modules();
775  check_conf_klines();
776
777  return 0;
778 }
779
747   /* set_default_conf()
748   *
749   * inputs       - NONE
# Line 952 | Line 919 | read_conf(FILE *file)
919    class_delete_marked();  /* Delete unused classes that are marked for deletion */
920   }
921  
922 + /* conf_rehash()
923 + *
924 + * Actual REHASH service routine. Called with sig == 0 if it has been called
925 + * as a result of an operator issuing this command, else assume it has been
926 + * called as a result of the server receiving a HUP signal.
927 + */
928 + int
929 + conf_rehash(int sig)
930 + {
931 +  if (sig)
932 +    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
933 +                         "Got signal SIGHUP, reloading configuration file(s)");
934 +
935 +  restart_resolver();
936 +
937 +  /* don't close listeners until we know we can go ahead with the rehash */
938 +
939 +  read_conf_files(0);
940 +
941 +  load_conf_modules();
942 +  check_conf_klines();
943 +
944 +  return 0;
945 + }
946 +
947   /* lookup_confhost()
948   *
949   * start DNS lookups of all hostnames in the conf
# Line 1025 | Line 1017 | conf_connect_allowed(struct irc_ssaddr *
1017    return 0;
1018   }
1019  
1028 /* cleanup_tklines()
1029 *
1030 * inputs       - NONE
1031 * output       - NONE
1032 * side effects - call function to expire temporary k/d lines
1033 *                This is an event started off in ircd.c
1034 */
1035 void
1036 cleanup_tklines(void *unused)
1037 {
1038  hostmask_expire_temporary();
1039  expire_tklines(&xconf_items);
1040  expire_tklines(&nresv_items);
1041  expire_tklines(&cresv_items);
1042 }
1043
1020   /* expire_tklines()
1021   *
1022   * inputs       - tkline list pointer
# Line 1076 | Line 1052 | expire_tklines(dlink_list *list)
1052    }
1053   }
1054  
1055 + /* cleanup_tklines()
1056 + *
1057 + * inputs       - NONE
1058 + * output       - NONE
1059 + * side effects - call function to expire temporary k/d lines
1060 + *                This is an event started off in ircd.c
1061 + */
1062 + void
1063 + cleanup_tklines(void *unused)
1064 + {
1065 +  hostmask_expire_temporary();
1066 +  expire_tklines(&xconf_items);
1067 +  expire_tklines(&nresv_items);
1068 +  expire_tklines(&cresv_items);
1069 + }
1070 +
1071   /* oper_privs_as_string()
1072   *
1073   * inputs        - pointer to client_p
# Line 1166 | Line 1158 | get_oper_name(const struct Client *clien
1158    return buffer;
1159   }
1160  
1169 /* read_conf_files()
1170 *
1171 * inputs       - cold start YES or NO
1172 * output       - none
1173 * side effects - read all conf files needed, ircd.conf kline.conf etc.
1174 */
1175 void
1176 read_conf_files(int cold)
1177 {
1178  const char *filename = NULL;
1179  char chanmodes[IRCD_BUFSIZE] = "";
1180  char chanlimit[IRCD_BUFSIZE] = "";
1181
1182  conf_parser_ctx.boot = cold;
1183  filename = ConfigGeneral.configfile;
1184
1185  /* We need to know the initial filename for the yyerror() to report
1186     FIXME: The full path is in conffilenamebuf first time since we
1187             don't know anything else
1188
1189     - Gozem 2002-07-21
1190  */
1191  strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1192
1193  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1194  {
1195    if (cold)
1196    {
1197      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1198           filename, strerror(errno));
1199      exit(-1);
1200    }
1201    else
1202    {
1203      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1204                           "Unable to read configuration file '%s': %s",
1205                           filename, strerror(errno));
1206      return;
1207    }
1208  }
1209
1210  if (!cold)
1211    clear_out_old_conf();
1212
1213  read_conf(conf_parser_ctx.conf_file);
1214  fclose(conf_parser_ctx.conf_file);
1215
1216  log_reopen_all();
1217
1218  add_isupport("NICKLEN", NULL, ConfigServerInfo.max_nick_length);
1219  add_isupport("NETWORK", ConfigServerInfo.network_name, -1);
1220
1221  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1222  add_isupport("MAXLIST", chanmodes, -1);
1223  add_isupport("MAXTARGETS", NULL, ConfigGeneral.max_targets);
1224  add_isupport("CHANTYPES", "#", -1);
1225
1226  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1227           ConfigChannel.max_channels);
1228  add_isupport("CHANLIMIT", chanlimit, -1);
1229  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstMORS");
1230  add_isupport("CHANNELLEN", NULL, CHANNELLEN);
1231  add_isupport("TOPICLEN", NULL, ConfigServerInfo.max_topic_length);
1232  add_isupport("CHANMODES", chanmodes, -1);
1233
1234  /*
1235   * message_locale may have changed.  rebuild isupport since it relies
1236   * on strlen(form_str(RPL_ISUPPORT))
1237   */
1238  rebuild_isupport_message_line();
1239 }
1240
1161   /* clear_out_old_conf()
1162   *
1163   * inputs       - none
# Line 1330 | Line 1250 | clear_out_old_conf(void)
1250    close_listeners();
1251   }
1252  
1253 + /* read_conf_files()
1254 + *
1255 + * inputs       - cold start YES or NO
1256 + * output       - none
1257 + * side effects - read all conf files needed, ircd.conf kline.conf etc.
1258 + */
1259 + void
1260 + read_conf_files(int cold)
1261 + {
1262 +  const char *filename = NULL;
1263 +  char chanmodes[IRCD_BUFSIZE] = "";
1264 +  char chanlimit[IRCD_BUFSIZE] = "";
1265 +
1266 +  conf_parser_ctx.boot = cold;
1267 +  filename = ConfigGeneral.configfile;
1268 +
1269 +  /* We need to know the initial filename for the yyerror() to report
1270 +     FIXME: The full path is in conffilenamebuf first time since we
1271 +             don't know anything else
1272 +
1273 +     - Gozem 2002-07-21
1274 +  */
1275 +  strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1276 +
1277 +  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1278 +  {
1279 +    if (cold)
1280 +    {
1281 +      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1282 +           filename, strerror(errno));
1283 +      exit(-1);
1284 +    }
1285 +    else
1286 +    {
1287 +      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1288 +                           "Unable to read configuration file '%s': %s",
1289 +                           filename, strerror(errno));
1290 +      return;
1291 +    }
1292 +  }
1293 +
1294 +  if (!cold)
1295 +    clear_out_old_conf();
1296 +
1297 +  read_conf(conf_parser_ctx.conf_file);
1298 +  fclose(conf_parser_ctx.conf_file);
1299 +
1300 +  log_reopen_all();
1301 +
1302 +  add_isupport("NICKLEN", NULL, ConfigServerInfo.max_nick_length);
1303 +  add_isupport("NETWORK", ConfigServerInfo.network_name, -1);
1304 +
1305 +  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1306 +  add_isupport("MAXLIST", chanmodes, -1);
1307 +  add_isupport("MAXTARGETS", NULL, ConfigGeneral.max_targets);
1308 +  add_isupport("CHANTYPES", "#", -1);
1309 +
1310 +  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1311 +           ConfigChannel.max_channels);
1312 +  add_isupport("CHANLIMIT", chanlimit, -1);
1313 +  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstMORS");
1314 +  add_isupport("CHANNELLEN", NULL, CHANNELLEN);
1315 +  add_isupport("TOPICLEN", NULL, ConfigServerInfo.max_topic_length);
1316 +  add_isupport("CHANMODES", chanmodes, -1);
1317 +
1318 +  /*
1319 +   * message_locale may have changed.  rebuild isupport since it relies
1320 +   * on strlen(form_str(RPL_ISUPPORT))
1321 +   */
1322 +  rebuild_isupport_message_line();
1323 + }
1324 +
1325   /* conf_add_class_to_conf()
1326   *
1327   * inputs       - pointer to config item
# Line 1544 | Line 1536 | valid_wild_card(struct Client *source_p,
1536    return 0;
1537   }
1538  
1539 + /* find_user_host()
1540 + *
1541 + * inputs       - pointer to client placing kline
1542 + *              - pointer to user_host_or_nick
1543 + *              - pointer to user buffer
1544 + *              - pointer to host buffer
1545 + * output       - 0 if not ok to kline, 1 to kline i.e. if valid user host
1546 + * side effects -
1547 + */
1548 + static int
1549 + find_user_host(struct Client *source_p, char *user_host_or_nick,
1550 +               char *luser, char *lhost, unsigned int flags)
1551 + {
1552 +  struct Client *target_p = NULL;
1553 +  char *hostp = NULL;
1554 +
1555 +  if (lhost == NULL)
1556 +  {
1557 +    strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
1558 +    return 1;
1559 +  }
1560 +
1561 +  if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*')
1562 +  {
1563 +    /* Explicit user@host mask given */
1564 +    if (hostp)                            /* I'm a little user@host */
1565 +    {
1566 +      *(hostp++) = '\0';                       /* short and squat */
1567 +
1568 +      if (*user_host_or_nick)
1569 +        strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); /* here is my user */
1570 +      else
1571 +        strcpy(luser, "*");
1572 +
1573 +      if (*hostp)
1574 +        strlcpy(lhost, hostp, HOSTLEN + 1);    /* here is my host */
1575 +      else
1576 +        strcpy(lhost, "*");
1577 +    }
1578 +    else
1579 +    {
1580 +      luser[0] = '*';             /* no @ found, assume its *@somehost */
1581 +      luser[1] = '\0';
1582 +      strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1);
1583 +    }
1584 +
1585 +    return 1;
1586 +  }
1587 +  else
1588 +  {
1589 +    /* Try to find user@host mask from nick */
1590 +    /* Okay to use source_p as the first param, because source_p == client_p */
1591 +    if ((target_p =
1592 +        find_chasing(source_p, user_host_or_nick)) == NULL)
1593 +      return 0;  /* find_chasing sends ERR_NOSUCHNICK */
1594 +
1595 +    if (IsExemptKline(target_p))
1596 +    {
1597 +      if (IsClient(source_p))
1598 +        sendto_one_notice(source_p, &me, ":%s is E-lined", target_p->name);
1599 +      return 0;
1600 +    }
1601 +
1602 +    /*
1603 +     * turn the "user" bit into "*user", blow away '~'
1604 +     * if found in original user name (non-idented)
1605 +     */
1606 +    strlcpy(luser, target_p->username, USERLEN*4 + 1);
1607 +
1608 +    if (target_p->username[0] == '~')
1609 +      luser[0] = '*';
1610 +
1611 +    if (!strcmp(target_p->sockhost, "0"))
1612 +      strlcpy(lhost, target_p->host, HOSTLEN*4 + 1);
1613 +    else
1614 +      strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1);
1615 +    return 1;
1616 +  }
1617 +
1618 +  return 0;
1619 + }
1620 +
1621   /* XXX should this go into a separate file ? -Dianora */
1622   /* parse_aline
1623   *
# Line 1590 | Line 1664 | parse_aline(const char *cmd, struct Clie
1664  
1665    found_tkline_time = valid_tkline(*parv, TK_MINUTES);
1666  
1667 <  if (found_tkline_time != 0)
1667 >  if (found_tkline_time)
1668    {
1669      parv++;
1670      parc--;
1671  
1672 <    if (tkline_time != NULL)
1672 >    if (tkline_time)
1673        *tkline_time = found_tkline_time;
1674      else
1675      {
# Line 1624 | Line 1698 | parse_aline(const char *cmd, struct Clie
1698    parc--;
1699    parv++;
1700  
1701 <  if (parc != 0)
1701 >  if (parc)
1702    {
1703      if (irccmp(*parv, "ON") == 0)
1704      {
# Line 1658 | Line 1732 | parse_aline(const char *cmd, struct Clie
1732        /* Make sure target_server *is* NULL if no ON server found
1733         * caller probably NULL'd it first, but no harm to do it again -db
1734         */
1735 <      if (target_server != NULL)
1735 >      if (target_server)
1736          *target_server = NULL;
1737      }
1738    }
1739  
1740 <  if (h_p != NULL)
1740 >  if (h_p)
1741    {
1742 <    if (strchr(user, '!') != NULL)
1742 >    if (strchr(user, '!'))
1743      {
1744        sendto_one_notice(source_p, &me, ":Invalid character '!' in kline");
1745        return -1;
# Line 1678 | Line 1752 | parse_aline(const char *cmd, struct Clie
1752      if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
1753        return -1;
1754  
1755 <  if (reason != NULL)
1755 >  if (reason)
1756    {
1757 <    if (parc != 0 && !EmptyString(*parv))
1757 >    if (parc && !EmptyString(*parv))
1758      {
1759        *reason = *parv;
1760 +
1761        if (!valid_comment(source_p, *reason, 1))
1762          return -1;
1763      }
# Line 1693 | Line 1768 | parse_aline(const char *cmd, struct Clie
1768    return 1;
1769   }
1770  
1696 /* find_user_host()
1697 *
1698 * inputs       - pointer to client placing kline
1699 *              - pointer to user_host_or_nick
1700 *              - pointer to user buffer
1701 *              - pointer to host buffer
1702 * output       - 0 if not ok to kline, 1 to kline i.e. if valid user host
1703 * side effects -
1704 */
1705 static int
1706 find_user_host(struct Client *source_p, char *user_host_or_nick,
1707               char *luser, char *lhost, unsigned int flags)
1708 {
1709  struct Client *target_p = NULL;
1710  char *hostp = NULL;
1711
1712  if (lhost == NULL)
1713  {
1714    strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
1715    return 1;
1716  }
1717
1718  if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*')
1719  {
1720    /* Explicit user@host mask given */
1721
1722    if (hostp != NULL)                            /* I'm a little user@host */
1723    {
1724      *(hostp++) = '\0';                       /* short and squat */
1725      if (*user_host_or_nick)
1726        strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); /* here is my user */
1727      else
1728        strcpy(luser, "*");
1729
1730      if (*hostp)
1731        strlcpy(lhost, hostp, HOSTLEN + 1);    /* here is my host */
1732      else
1733        strcpy(lhost, "*");
1734    }
1735    else
1736    {
1737      luser[0] = '*';             /* no @ found, assume its *@somehost */
1738      luser[1] = '\0';
1739      strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1);
1740    }
1741
1742    return 1;
1743  }
1744  else
1745  {
1746    /* Try to find user@host mask from nick */
1747    /* Okay to use source_p as the first param, because source_p == client_p */
1748    if ((target_p =
1749        find_chasing(source_p, user_host_or_nick)) == NULL)
1750      return 0;  /* find_chasing sends ERR_NOSUCHNICK */
1751
1752    if (IsExemptKline(target_p))
1753    {
1754      if (IsClient(source_p))
1755        sendto_one_notice(source_p, &me, ":%s is E-lined", target_p->name);
1756      return 0;
1757    }
1758
1759    /*
1760     * turn the "user" bit into "*user", blow away '~'
1761     * if found in original user name (non-idented)
1762     */
1763    strlcpy(luser, target_p->username, USERLEN*4 + 1);
1764
1765    if (target_p->username[0] == '~')
1766      luser[0] = '*';
1767
1768    if (!strcmp(target_p->sockhost, "0"))
1769      strlcpy(lhost, target_p->host, HOSTLEN*4 + 1);
1770    else
1771      strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1);
1772    return 1;
1773  }
1774
1775  return 0;
1776 }
1777
1771   /* valid_comment()
1772   *
1773   * inputs       - pointer to client
# Line 1884 | Line 1877 | split_nuh(struct split_nuh_item *const i
1877  
1878    if (iptr->nickptr)
1879      strlcpy(iptr->nickptr, "*", iptr->nicksize);
1880 +
1881    if (iptr->userptr)
1882      strlcpy(iptr->userptr, "*", iptr->usersize);
1883 +
1884    if (iptr->hostptr)
1885      strlcpy(iptr->hostptr, "*", iptr->hostsize);
1886  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines