Import new (much simpler) resolver code from Hybrid.
[ircu2.10.12-pk.git] / ircd / s_conf.c
index d09dfd8c8b8b29d8b1168c4058c06ffd83983607..8d6d6b299b2839565aacacd2648feef59e2e052d 100644 (file)
@@ -32,6 +32,7 @@
 #include "hash.h"
 #include "ircd.h"
 #include "ircd_alloc.h"
+#include "ircd_auth.h"
 #include "ircd_chattr.h"
 #include "ircd_log.h"
 #include "ircd_reply.h"
@@ -71,6 +72,7 @@
 
 struct ConfItem  *GlobalConfList  = 0;
 int              GlobalConfCount = 0;
+struct s_map     *GlobalServiceMapList = 0;
 struct qline     *GlobalQuarantineList = 0;
 
 void yyparse(void);
@@ -202,12 +204,16 @@ static void detach_conf(struct Client* cptr, struct ConfItem* aconf)
  * a non-null pointer, otherwise hp will be null.
  * if successful save hp in the conf item it was called with
  */
-static void conf_dns_callback(void* vptr, struct DNSReply* reply)
+static void conf_dns_callback(void* vptr, struct DNSReply* hp)
 {
   struct ConfItem* aconf = (struct ConfItem*) vptr;
+  assert(aconf);
   aconf->dns_pending = 0;
-  if (reply)
-    memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+  if (hp) {
+    struct sockaddr_in *sin = (struct sockaddr_in*)&hp->addr;
+    memcpy(&aconf->ipnum, &sin->sin_addr, sizeof(struct in_addr));
+    MyFree(hp);
+  }
 }
 
 /*
@@ -215,9 +221,8 @@ static void conf_dns_callback(void* vptr, struct DNSReply* reply)
  * if the conf entry is currently doing a ns lookup do nothing, otherwise
  * if the lookup returns a null pointer, set the conf dns_pending flag
  */
-static struct DNSReply* conf_dns_lookup(struct ConfItem* aconf)
+static void conf_dns_lookup(struct ConfItem* aconf)
 {
-  struct DNSReply* dns_reply = 0;
   if (!aconf->dns_pending) {
     char            buf[HOSTLEN + 1];
     struct DNSQuery query;
@@ -226,10 +231,9 @@ static struct DNSReply* conf_dns_lookup(struct ConfItem* aconf)
     host_from_uh(buf, aconf->host, HOSTLEN);
     buf[HOSTLEN] = '\0';
 
-    if (0 == (dns_reply = gethost_byname(buf, &query)))
-      aconf->dns_pending = 1;
+    gethost_byname(buf, &query);
+    aconf->dns_pending = 1;
   }
-  return dns_reply;
 }
 
 
@@ -242,8 +246,6 @@ static struct DNSReply* conf_dns_lookup(struct ConfItem* aconf)
 void
 lookup_confhost(struct ConfItem *aconf)
 {
-  struct DNSReply* reply;
-
   if (EmptyString(aconf->host) || EmptyString(aconf->name)) {
     Debug((DEBUG_ERROR, "Host/server name error: (%s) (%s)",
            aconf->host, aconf->name));
@@ -264,8 +266,8 @@ lookup_confhost(struct ConfItem *aconf)
             aconf->host, aconf->name));
     }
   }
-  else if ((reply = conf_dns_lookup(aconf)))
-    memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+  else 
+    conf_dns_lookup(aconf);
 }
 
 /*
@@ -366,16 +368,14 @@ check_limit_and_attach(struct Client* cptr, struct ConfItem* aconf)
 enum AuthorizationCheckResult attach_iline(struct Client*  cptr)
 {
   struct ConfItem* aconf;
-  const char*      hname;
-  int              i;
   static char      uhost[HOSTLEN + USERLEN + 3];
   static char      fullname[HOSTLEN + 1];
-  struct hostent*  hp = 0;
+  struct DNSReply* hp = 0;
 
   assert(0 != cptr);
 
   if (cli_dns_reply(cptr))
-    hp = cli_dns_reply(cptr)->hp;
+    hp = cli_dns_reply(cptr);
 
   for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
     if (aconf->status != CONF_CLIENT)
@@ -385,25 +385,23 @@ enum AuthorizationCheckResult attach_iline(struct Client*  cptr)
     if (!aconf->host || !aconf->name)
       continue;
     if (hp) {
-      for (i = 0, hname = hp->h_name; hname; hname = hp->h_aliases[i++]) {
-        ircd_strncpy(fullname, hname, HOSTLEN);
-        fullname[HOSTLEN] = '\0';
-
-        Debug((DEBUG_DNS, "a_il: %s->%s", cli_sockhost(cptr), fullname));
-
-        if (strchr(aconf->name, '@')) {
-          strcpy(uhost, cli_username(cptr));
-          strcat(uhost, "@");
-        }
-        else
-          *uhost = '\0';
-        strncat(uhost, fullname, sizeof(uhost) - 1 - strlen(uhost));
-        uhost[sizeof(uhost) - 1] = 0;
-        if (0 == match(aconf->name, uhost)) {
-          if (strchr(uhost, '@'))
-            SetFlag(cptr, FLAG_DOID);
-          return check_limit_and_attach(cptr, aconf);
-        }
+      ircd_strncpy(fullname, hp->h_name, HOSTLEN);
+      fullname[HOSTLEN] = '\0';
+
+      Debug((DEBUG_DNS, "a_il: %s->%s", cli_sockhost(cptr), fullname));
+
+      if (strchr(aconf->name, '@')) {
+        strcpy(uhost, cli_username(cptr));
+        strcat(uhost, "@");
+      }
+      else
+        *uhost = '\0';
+      strncat(uhost, fullname, sizeof(uhost) - 1 - strlen(uhost));
+      uhost[sizeof(uhost) - 1] = 0;
+      if (0 == match(aconf->name, uhost)) {
+        if (strchr(uhost, '@'))
+          SetFlag(cptr, FLAG_DOID);
+        return check_limit_and_attach(cptr, aconf);
       }
     }
     if (strchr(aconf->host, '@')) {
@@ -452,7 +450,7 @@ enum AuthorizationCheckResult attach_conf(struct Client *cptr, struct ConfItem *
     return ACR_ALREADY_AUTHORIZED;
   if (IsIllegal(aconf))
     return ACR_NO_AUTHORIZATION;
-  if ((aconf->status & (CONF_LOCOP | CONF_OPERATOR | CONF_CLIENT)) &&
+  if ((aconf->status & (CONF_OPERATOR | CONF_CLIENT)) &&
       ConfLinks(aconf) >= ConfMaxLinks(aconf) && ConfMaxLinks(aconf) > 0)
     return ACR_TOO_MANY_IN_CLASS;  /* Use this for printing error message */
   lp = make_link();
@@ -550,7 +548,7 @@ struct ConfItem* find_conf_exact(const char* name, const char* user,
      */
     if (match(tmp->host, userhost))
       continue;
-    if (tmp->status & (CONF_OPERATOR | CONF_LOCOP)) {
+    if (tmp->status & CONF_OPERATOR) {
       if (tmp->clients < MaxLinks(tmp->conn_class))
         return tmp;
       else
@@ -972,11 +970,14 @@ void clear_quarantines(void)
 
 #define MAXCONFLINKS 150
 
+static int conf_error;
+static int conf_already_read;
 extern FILE *yyin;
 void init_lexer(void);
 
 int read_configuration_file(void)
 {
+  conf_error = 0;
   feature_unmark(); /* unmark all features for resetting later */
   /* Now just open an fd. The buffering isn't really needed... */
   init_lexer();
@@ -984,6 +985,7 @@ int read_configuration_file(void)
   fclose(yyin);
   yyin = NULL;
   feature_mark(); /* reset unmarked features */
+  conf_already_read = 1;
   return 1;
 }
 
@@ -994,6 +996,9 @@ yyerror(const char *msg)
                       lineno, msg);
  log_write(LS_CONFIG, L_ERROR, 0, "Config file parse error line %d: %s",
            lineno, msg);
+ if (!conf_already_read)
+   fprintf(stderr, "Config file parse error line %d: %s\n", lineno, msg);
+ conf_error = 1;
 }
 
 /*
@@ -1046,16 +1051,20 @@ int rehash(struct Client *cptr, int sig)
    */
   clearNickJupes();
 
+  clear_quarantines();
+
   if (sig != 2)
-    flush_resolver_cache();
+    restart_resolver();
 
   class_mark_delete();
   mark_listeners_closing();
+  iauth_mark_closing();
 
   read_configuration_file();
 
   log_reopen(); /* reopen log files */
 
+  iauth_close_unused();
   close_listeners();
   class_delete_marked();         /* unless it fails */
 
@@ -1090,8 +1099,8 @@ int rehash(struct Client *cptr, int sig)
         sendto_opmask_butone(0, found_g == -2 ? SNO_GLINE : SNO_OPERKILL,
                              found_g == -2 ? "G-line active for %s%s" :
                              "K-line active for %s%s",
-                             IsUnknown(acptr) ? "Unregistered Client ":"",                     
-                             get_client_name(acptr, HIDE_IP));
+                             IsUnknown(acptr) ? "Unregistered Client ":"",
+                             get_client_name(acptr, SHOW_IP));
         if (exit_client(cptr, acptr, &me, found_g == -2 ? "G-lined" :
             "K-lined") == CPTR_KILLED)
           ret = CPTR_KILLED;
@@ -1122,6 +1131,8 @@ int init_conf(void)
      */
     if (0 == localConf.name || 0 == localConf.numeric)
       return 0;
+    if (conf_error)
+      return 0;
 
     if (0 == localConf.location1)
       DupString(localConf.location1, "");
@@ -1129,7 +1140,7 @@ int init_conf(void)
       DupString(localConf.location2, "");
     if (0 == localConf.contact)
       DupString(localConf.contact, "");
-    
+
     return 1;
   }
   return 0;
@@ -1178,7 +1189,7 @@ int find_kill(struct Client *cptr)
       break;
 
     if (deny->flags & DENY_FLAGS_REALNAME) { /* K: by real name */
-      if (0 == match(deny->hostmask, realname))
+      if (0 == match(deny->hostmask + 2, realname))
        break;
     } else if (deny->flags & DENY_FLAGS_IP) { /* k: by IP */
       Debug((DEBUG_DEBUG, "ip: %08x network: %08x/%i mask: %08x",
@@ -1200,15 +1211,13 @@ int find_kill(struct Client *cptr)
         send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", deny->message);
     }
   }
-  else if ((agline = gline_lookup(cptr, 0)) && GlineIsActive(agline)) {
+  else if ((agline = gline_lookup(cptr, 0))) {
     /*
      * find active glines
      * added a check against the user's IP address to find_gline() -Kev
      */
     send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", GlineReason(agline));
   }
-  else
-    agline = 0;          /* if a gline was found, it was inactive */
 
   if (deny)
     return -1;
@@ -1282,25 +1291,16 @@ int conf_check_server(struct Client *cptr)
 
   if (!c_conf) {
     if (cli_dns_reply(cptr)) {
-      int             i;
-      struct hostent* hp = cli_dns_reply(cptr)->hp;
+      struct DNSReply* hp = cli_dns_reply(cptr);
       const char*     name = hp->h_name;
       /*
        * If we are missing a C or N line from above, search for
        * it under all known hostnames we have for this ip#.
        */
-      for (i = 0; name; name = hp->h_aliases[i++]) {
-        if ((c_conf = find_conf_byhost(lp, name, CONF_SERVER))) {
-          ircd_strncpy(cli_sockhost(cptr), name, HOSTLEN);
-          break;
-        }
-      }
-      if (!c_conf) {
-        for (i = 0; hp->h_addr_list[i]; i++) {
-          if ((c_conf = find_conf_byip(lp, hp->h_addr_list[i], CONF_SERVER)))
-            break;
-        }
-      }
+      if ((c_conf = find_conf_byhost(lp, hp->h_name, CONF_SERVER)))
+        ircd_strncpy(cli_sockhost(cptr), name, HOSTLEN);
+      else
+          c_conf = find_conf_byip(lp, (char*)&((struct sockaddr_in*)&hp->addr)->sin_addr, CONF_SERVER);
     }
     else {
       /*
@@ -1340,7 +1340,8 @@ int conf_check_server(struct Client *cptr)
   if (INADDR_NONE == c_conf->ipnum.s_addr)
     c_conf->ipnum.s_addr = cli_ip(cptr).s_addr;
 
-  Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", cli_name(cptr), cli_sockhost(cptr)));
+  Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]",
+         cli_name(cptr), cli_sockhost(cptr)));
   return 0;
 }