/*
 * mo_version - oper message handler
 *
 *   parv[0] = sender prefix
 *   parv[1] = servername
 */
int mo_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;

  if (MyConnect(sptr) && parc > 1)
  {
    if (!(acptr = find_match_server(parv[1])))
    {
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
      return 0;
    }
    parv[1] = cli_name(acptr);
  }

  if (hunt_server_cmd(sptr, CMD_VERSION, cptr, feature_int(FEAT_HIS_REMOTE),
                                                           ":%C", 1,
                                                           parc, parv)
                      == HUNTED_ISME)
  {
    send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
	       debug_serveropts());
    send_supported(sptr);
  }

  return 0;
}
Ejemplo n.º 2
0
/*
 * ms_rping - server message handler
 * -- by Run
 *
 *    parv[0] = sender (sptr->name thus)
 * if sender is a person: (traveling towards start server)
 *    parv[1] = pinged server[mask]
 *    parv[2] = start server (current target)
 *    parv[3] = optional remark
 * if sender is a server: (traveling towards pinged server)
 *    parv[1] = pinged server (current target)
 *    parv[2] = original sender (person)
 *    parv[3] = start time in s
 *    parv[4] = start time in us
 *    parv[5] = the optional remark
 */
int ms_rping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* destination = 0;
  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  /*
   * shouldn't happen
   */
  if (!IsPrivileged(sptr))
    return 0;

  if (IsServer(sptr)) {
    if (parc < 6) {
      /*
       * PROTOCOL ERROR
       */
      return need_more_params(sptr, "RPING");
    }
    if ((destination = FindNServer(parv[1]))) {
      /*
       * if it's not for me, pass it on
       */
      if (IsMe(destination))
	sendcmdto_one(&me, CMD_RPONG, sptr, "%s %s %s %s :%s", cli_name(sptr),
		      parv[2], parv[3], parv[4], parv[5]);
      else
	sendcmdto_one(sptr, CMD_RPING, destination, "%C %s %s %s :%s",
		      destination, parv[2], parv[3], parv[4], parv[5]);
    }
  }
  else {
    if (parc < 3) {
      return need_more_params(sptr, "RPING");
    }
    /*
     * Haven't made it to the start server yet, if I'm not the start server
     * pass it on.
     */
    if (hunt_server_cmd(sptr, CMD_RPING, cptr, 1, "%s %C :%s", 2, parc, parv)
	!= HUNTED_ISME)
      return 0;
    /*
     * otherwise ping the destination from here
     */
    if ((destination = find_match_server(parv[1]))) {
      assert(IsServer(destination) || IsMe(destination));
      sendcmdto_one(&me, CMD_RPING, destination, "%C %C %s :%s", destination,
		    sptr, militime(0, 0), parv[3]);
    }
    else
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
  }
  return 0;
}
Ejemplo n.º 3
0
/*
 * mo_rping - oper message handler
 * -- by Run
 *
 *
 * Receive:
 *          RPING blah.*
 *          RPING blah.* :<start time>
 *          RPING blah.* server.* :<start time>
 *
 *    parv[0] = sender (sptr->name thus)
 *    parv[1] = pinged server name or mask (required)
 *    parv[2] = start server name or mask (optional, defaults to me)
 *    parv[3] = client start time (optional) 
 * 
 * Send: NumNick(sptr) RPING blah.* server.net :<start time> (hunt_server)
 *       NumServ(&me) RPING NumServ(blah.bar.net) NumNick(sptr) :<start time> (here)
 */
int mo_rping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* acptr = 0;
  const char*    start_time = "<No client start time>";

  assert(0 != cptr);
  assert(0 != sptr);
  assert(cptr == sptr);
  assert(IsAnOper(sptr));

  if (parc < 2)
    return need_more_params(sptr, "RPING");

  if (parc > 2) {
    if ((acptr = find_match_server(parv[2])) && !IsMe(acptr)) {
      parv[2] = cli_name(acptr);
      if (3 == parc) {
        /*
         * const_cast<char*>(start_time);
         */
        parv[parc++] = (char*) start_time;
      }
      hunt_server_cmd(sptr, CMD_RPING, cptr, 1, "%s %C :%s", 2, parc, parv);
      return 0;
    }
    else
      start_time = parv[2];
  }

  if ((acptr = find_match_server(parv[1]))) {
    assert(IsServer(acptr) || IsMe(acptr));
    sendcmdto_one(&me, CMD_RPING, acptr, "%C %C %s :%s", acptr, sptr,
		  militime(0, 0), start_time);
  }
  else
    send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);

  return 0;
}
Ejemplo n.º 4
0
/*
 * m_oper - generic message handler
 */
int m_oper(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct ConfItem* aconf;
  char*            name;
  char*            password;

  assert(0 != cptr);
  assert(cptr == sptr);

  if ((parc > 3) && feature_bool(FEAT_REMOTE_OPER)) {
    struct Client *srv;

    if (!string_has_wildcards(parv[1]))
      srv = FindServer(parv[1]);
    else
      srv = find_match_server(parv[1]);

    if (!srv)
      return send_reply(sptr, ERR_NOOPERHOST);

    if (IsMe(srv)) {
      parv[1] = parv[2];
      parv[2] = parv[3];
    } else {
      sendcmdto_one(sptr, CMD_OPER, srv, "%C %s %s", srv, parv[2], parv[3]);
      return 0;
    }
  }

  name     = parc > 1 ? parv[1] : 0;
  password = parc > 2 ? parv[2] : 0;

  if (EmptyString(name) || EmptyString(password))
    return need_more_params(sptr, "OPER");

  if (can_oper(cptr, sptr, name, password, &aconf))
    do_oper(cptr, sptr, aconf);

  return 0;
}
Ejemplo n.º 5
0
/*
 * mo_version - oper message handler
 *
 *   parv[0] = sender prefix
 *   parv[1] = servername
 */
int mo_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;

  if (MyConnect(sptr) && parc > 1)
  {
    if (!(acptr = find_match_server(parv[1])))
    {
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
      return 0;
    }
    parv[1] = cli_name(acptr);
  }

  if (hunt_server_cmd(sptr, CMD_VERSION, cptr, feature_int(FEAT_HIS_REMOTE),
                                                           ":%C", 1,
                                                           parc, parv)
                      == HUNTED_ISME)
  {
    send_reply(sptr, RPL_VERSION, version, cvs_version, debugmode, cli_name(&me),
	       debug_serveropts());
#ifdef USE_SSL
#ifdef DEBUGMODE
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Headers: %s", sptr, OPENSSL_VERSION_TEXT);
#endif
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Library: %s", sptr, SSLeay_version(SSLEAY_VERSION));
#endif
#ifdef USE_GEOIP
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :GeoIP %s", sptr, geoip_version());
#endif
#ifdef USE_MMDB
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :MaxMindDB %s", sptr, geoip_libmmdb_version());
#endif
    send_supported(sptr);
  }

  return 0;
}
Ejemplo n.º 6
0
/*
 *  ms_svsnoop
 *
 *  parv[0] = sender prefix
 *  parv[1] = server
 *  parv[2] = +/-
 *
 *  Ported From Ultimate IRCd
 */
int ms_svsnoop(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct ConfItem *aconf;
  struct Client *server = 0;
  char           c;
  char*          cp;

  if (!IsServer(sptr) || parc < 3)
    return 0;

  /* this could be done with hunt_server_cmd but its a bucket of shit */
  if (!string_has_wildcards(parv[1]))
    server = FindServer(parv[1]);
  else
    server = find_match_server(parv[1]);

  if (!server)
    return 0;

  if (server == &me) {
    cp = parv[2];
    c = *cp;
    if (c == '+') {
      for(aconf = GlobalConfList; aconf; aconf = aconf->next) {
        if (aconf->status & CONF_OPERATOR)
          aconf->status |= CONF_ILLEGAL;
      }
      SetServerNoop(&me);
    } else {
      rehash (&me, 2);
      ClearServerNoop(&me);
    }
  }

  sendcmdto_serv_butone(sptr, CMD_SVSNOOP, cptr, "%s %s", parv[1], parv[2]);
  return 0;
}
Ejemplo n.º 7
0
/*
 * mo_gline - oper message handler
 *
 * parv[0] = Sender prefix
 * parv[1] = [[+|-]<G-line mask>]
 *
 * Local (to me) style:
 *
 * parv[2] = [Expiration offset]
 * parv[3] = [Comment]
 *
 * Global (or remote local) style:
 *
 * parv[2] = [target]
 * parv[3] = [Expiration offset]
 * parv[4] = [Comment]
 *
 */
int
mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Client *acptr = 0;
  struct Gline *agline;
  unsigned int flags = 0;
  time_t expire_off;
  char *mask = parv[1], *target = 0, *reason;

  if (parc < 2)
    return gline_list(sptr, 0);

  if (*mask == '!') {
    mask++;

    if (HasPriv(sptr, PRIV_WIDE_GLINE))
      flags |= GLINE_OPERFORCE;
  }

  if (*mask == '+') {
    flags |= GLINE_ACTIVE;
    mask++;

  } else if (*mask == '-')
    mask++;
  else
    return gline_list(sptr, mask);

  if (parc == 4) {
    expire_off = atoi(parv[2]);
    reason = parv[3];
    flags |= GLINE_LOCAL;
  } else if (parc > 4) {
    target = parv[2];
    expire_off = atoi(parv[3]);
    reason = parv[4];
  } else
    return need_more_params(sptr, "GLINE");

  if (target)
  {
    if (!(target[0] == '*' && target[1] == '\0'))
    {
      if (!(acptr = find_match_server(target)))
	return send_reply(sptr, ERR_NOSUCHSERVER, target);

      /* manually propagate, since we don't set it */
      if (!IsMe(acptr))
      {
	if (!feature_bool(FEAT_CONFIG_OPERCMDS))
	  return send_reply(sptr, ERR_DISABLED, "GLINE");

	if (!HasPriv(sptr, PRIV_GLINE))
	  return send_reply(sptr, ERR_NOPRIVILEGES);

	sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s %s %Tu :%s", acptr,
		      flags & GLINE_OPERFORCE ? "!" : "",
		      flags & GLINE_ACTIVE ? '+' : '-', mask, parv[3],
		      TStime(), reason);
	return 0;
      }
      flags |= GLINE_LOCAL;
    }
  }

  if (!(flags & GLINE_LOCAL) && !feature_bool(FEAT_CONFIG_OPERCMDS))
    return send_reply(sptr, ERR_DISABLED, "GLINE");

  if (!HasPriv(sptr, (flags & GLINE_LOCAL ? PRIV_LOCAL_GLINE : PRIV_GLINE)))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  agline = gline_find(mask, GLINE_ANY | GLINE_EXACT);

  if (agline) {
    if (GlineIsLocal(agline) && !(flags & GLINE_LOCAL)) /* global over local */
      gline_free(agline);
    else {
      if (!GlineLastMod(agline)) /* force mods to Uworld-set G-lines local */
	flags |= GLINE_LOCAL;

      if (flags & GLINE_ACTIVE)
	return gline_activate(cptr, sptr, agline,
			      GlineLastMod(agline) ? TStime() : 0, flags);
      else
	return gline_deactivate(cptr, sptr, agline,
				GlineLastMod(agline) ? TStime() : 0, flags);
    }
  }

  return gline_add(cptr, sptr, mask, reason, expire_off, TStime(), flags);
}
Ejemplo n.º 8
0
/*
 * mo_zline - oper message handler
 *
 * parv[0] = Sender prefix
 * parv[1] = [[+|-]<Z-line mask>]
 *
 * For other parameters, see doc/readme.zline.
 */
int
mo_zline(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Client *acptr = 0;
  struct Zline *azline = 0;
  unsigned int flags = 0;
  enum ZlineAction action = ZLINE_MODIFY;
  time_t expire = 0;
  char *mask = parv[1], *target = 0, *reason = 0, *end;

  if (parc < 2)
    return zline_list(sptr, 0);

  if (*mask == '!') {
    mask++;

    if (HasPriv(sptr, PRIV_WIDE_ZLINE))
      flags |= ZLINE_OPERFORCE;
  }

  switch (*mask) { /* handle +, -, <, and > */
  case '+': /* activate the Z-line */
    action = ZLINE_ACTIVATE;
    mask++;
    break;

  case '-': /* deactivate the Z-line */
    action = ZLINE_DEACTIVATE;
    mask++;
    break;

  case '>': /* locally activate the Z-line */
    action = ZLINE_LOCAL_ACTIVATE;
    mask++;
    break;

  case '<': /* locally deactivate the Z-line */
    action = ZLINE_LOCAL_DEACTIVATE;
    mask++;
    break;
  }

  /* OK, let's figure out the parameters... */
  switch (action) {
  case ZLINE_MODIFY: /* no specific action on the Z-line... */
    if (parc == 2) /* user wants a listing of a specific Z-line */
      return zline_list(sptr, mask);
    else if (parc < 4) /* must have target and expire, minimum */
      return need_more_params(sptr, "ZLINE");

    target = parv[2]; /* get the target... */
    if (is_timestamp(parv[3])) {
      expire = strtol(parv[3], &end, 10) + TStime(); /* and the expiration */
      if (*end != '\0')
        return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[3]);
    } else
      expire = ParseInterval(parv[3]) + TStime();

    flags |= ZLINE_EXPIRE; /* remember that we got an expire time */

    if (parc > 4) { /* also got a reason... */
      reason = parv[parc - 1];
      flags |= ZLINE_REASON;
    }

    /* target is not global, interpolate action and require reason */
    if (target[0] != '*' || target[1] != '\0') {
      if (!reason) /* have to have a reason for this */
	return need_more_params(sptr, "ZLINE");

      action = ZLINE_ACTIVATE;
    }
    break;

  case ZLINE_LOCAL_ACTIVATE: /* locally activate a Z-line */
  case ZLINE_LOCAL_DEACTIVATE: /* locally deactivate a Z-line */
    if (parc > 2) { /* if target is available, pick it */
      target = parv[2];
      if (target[0] == '*' && target[1] == '\0')
        return send_reply(sptr, ERR_NOSUCHSERVER, target);
    }
    break;

  case ZLINE_ACTIVATE: /* activating/adding a Z-line */
  case ZLINE_DEACTIVATE: /* deactivating/removing a Z-line */
    if (parc < 3)
      return need_more_params(sptr, "ZLINE");

    if (parc > 3) {
      /* get expiration and target */
      reason = parv[parc - 1];
      if (is_timestamp(parv[parc - 2])) {
        expire = strtol(parv[parc - 2], &end, 10) + TStime();
        if (*end != '\0')
          return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[parc - 2]);
      } else
        expire = ParseInterval(parv[parc - 2]) + TStime();

      flags |= ZLINE_EXPIRE | ZLINE_REASON; /* remember that we got 'em */

      if (parc > 4) /* also have a target! */
	target = parv[2];
    } else {
      target = parv[2]; /* target has to be present, and has to be '*' */

      if (target[0] != '*' || target[1] != '\0')
	return need_more_params(sptr, "ZLINE");
    }
    break;
  }

  /* Is there no mask left? */
  if (mask[0] == '\0')
    return need_more_params(sptr, "ZLINE");

  /* Now let's figure out which is the target server */
  if (!target) /* no target, has to be me... */
    acptr = &me;
  /* if it's not '*', look up the server */
  else if ((target[0] != '*' || target[1] != '\0') &&
	   !(acptr = find_match_server(target)))
    return send_reply(sptr, ERR_NOSUCHSERVER, target);

  /* Z-line deprecation notice */
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Use of Z-line is deprecated. "
 	   " Please use G-line instead.", sptr);

  /* Now, is the Z-line local or global? */
  if (action == ZLINE_LOCAL_ACTIVATE || action == ZLINE_LOCAL_DEACTIVATE ||
      !acptr)
    flags |= ZLINE_GLOBAL;
  else /* it's some form of local Z-line */
    flags |= ZLINE_LOCAL;

  /* If it's a local activate/deactivate and server isn't me, propagate it */
  if ((action == ZLINE_LOCAL_ACTIVATE || action == ZLINE_LOCAL_DEACTIVATE) &&
      !IsMe(acptr)) {
    /* check for permissions... */
    if (!feature_bool(FEAT_CONFIG_OPERCMDS))
      return send_reply(sptr, ERR_DISABLED, "ZLINE");
    else if (!HasPriv(sptr, PRIV_ZLINE))
      return send_reply(sptr, ERR_NOPRIVILEGES);

    Debug((DEBUG_DEBUG, "I am forwarding a local change to a global zline "
	   "to a remote server; target %s, mask %s, operforce %s, action %c",
	   cli_name(acptr), mask, flags & ZLINE_OPERFORCE ? "YES" : "NO",
	   action == ZLINE_LOCAL_ACTIVATE ? '>' : '<'));

    sendcmdto_one(sptr, CMD_ZLINE, acptr, "%C %s%c%s", acptr,
                  flags & ZLINE_OPERFORCE ? "!" : "",
                  action == ZLINE_LOCAL_ACTIVATE ? '>' : '<', mask);

    return 0; /* all done */
  }

  /* Next, try to find the Z-line... */
  if ((flags & ZLINE_GLOBAL) || IsMe(acptr)) /* don't bother if it's not me! */
    azline = zline_find(mask, flags | ZLINE_ANY | ZLINE_EXACT);

  /* We now have all the pieces to tell us what we've got; let's put
   * it all together and convert the rest of the arguments.
   */

  /* Handle the local Z-lines first... */
  if (flags & ZLINE_LOCAL) {
    assert(acptr);

    /* normalize the action, first */
    if (action == ZLINE_LOCAL_ACTIVATE || action == ZLINE_MODIFY)
      action = ZLINE_ACTIVATE;
    else if (action == ZLINE_LOCAL_DEACTIVATE)
      action = ZLINE_DEACTIVATE;

    /* If it's not for us, forward */
    /* UPDATE NOTE: Once all servers are updated to u2.10.12.11, the
     * format string in this sendcmdto_one() may be updated to omit
     * <lastmod> for ZLINE_ACTIVATE and to omit <expire>, <lastmod>,
     * and <reason> for ZLINE_DEACTIVATE.
     */

    if (!IsMe(acptr)) {
      /* check for permissions... */
      if (!feature_bool(FEAT_CONFIG_OPERCMDS))
	return send_reply(sptr, ERR_DISABLED, "ZLINE");
      else if (!HasPriv(sptr, PRIV_ZLINE))
	return send_reply(sptr, ERR_NOPRIVILEGES);

      Debug((DEBUG_DEBUG, "I am forwarding a local Z-line to a remote "
	     "server; target %s, mask %s, operforce %s, action %c, "
	     "expire %Tu, reason %s", target, mask,
	     flags & ZLINE_OPERFORCE ? "YES" : "NO",
	     action == ZLINE_ACTIVATE ? '+' : '-', expire, reason));

      sendcmdto_one(sptr, CMD_ZLINE, acptr, "%C %s%c%s %Tu %Tu :%s",
		    acptr, flags & ZLINE_OPERFORCE ? "!" : "",
		    action == ZLINE_ACTIVATE ? '+' : '-', mask,
		    expire - TStime(), TStime(), reason);

      return 0; /* all done */
    }

    /* check local Z-line permissions... */
    if (!HasPriv(sptr, PRIV_LOCAL_ZLINE))
      return send_reply(sptr, ERR_NOPRIVILEGES);

    /* let's handle activation... */
    if (action == ZLINE_ACTIVATE) {
      if (azline) /* Z-line already exists, so let's ignore it... */
	return 0;

      /* OK, create the local Z-line */
      Debug((DEBUG_DEBUG, "I am creating a local Z-line here; target %s, "
	     "mask %s, operforce %s, action  %s, expire %Tu, reason: %s",
	     target, mask, flags & ZLINE_OPERFORCE ? "YES" : "NO",
	     action == ZLINE_ACTIVATE ? "+" : "-", expire, reason));

      return zline_add(cptr, sptr, mask, reason, expire, 0, 0,
		       flags | ZLINE_ACTIVE);
    } else { /* OK, it's a deactivation/destruction */
      if (!azline) /* Z-line doesn't exist, so let's complain... */
	return send_reply(sptr, ERR_NOSUCHZLINE, mask);

      /* Let's now destroy the Z-line */
      Debug((DEBUG_DEBUG, "I am destroying a local Z-line here; target %s, "
	     "mask %s, operforce %s, action %s", target, mask,
	     flags & ZLINE_OPERFORCE ? "YES" : "NO",
	     action == ZLINE_ACTIVATE ? "+" : "-"));

      return zline_destroy(cptr, sptr, azline);
    }
  }

  /* can't modify a Z-line that doesn't exist...
   * (and if we are creating a new one, we need a reason and expiration)
   */
  if (!azline &&
      (action == ZLINE_MODIFY || action == ZLINE_LOCAL_ACTIVATE ||
       action == ZLINE_LOCAL_DEACTIVATE || !reason || !expire))
    return send_reply(sptr, ERR_NOSUCHZLINE, mask);

  /* check for Z-line permissions... */
  if (action == ZLINE_LOCAL_ACTIVATE || action == ZLINE_LOCAL_DEACTIVATE) {
    /* only need local privileges for locally-limited status changes */
    if (!HasPriv(sptr, PRIV_LOCAL_ZLINE))
      return send_reply(sptr, ERR_NOPRIVILEGES);
  } else { /* global privileges required */
    if (!feature_bool(FEAT_CONFIG_OPERCMDS))
      return send_reply(sptr, ERR_DISABLED, "ZLINE");
    else if (!HasPriv(sptr, PRIV_ZLINE))
      return send_reply(sptr, ERR_NOPRIVILEGES);
  }

  Debug((DEBUG_DEBUG, "I have a global Z-line I am acting upon now; "
	 "target %s, mask %s, operforce %s, action %s, expire %Tu, "
	 "reason: %s; zline %s!  (fields present: %s %s)", target, 
	 mask, flags & ZLINE_OPERFORCE ? "YES" : "NO",
	 action == ZLINE_ACTIVATE ? "+" :
	 (action == ZLINE_DEACTIVATE ? "-" :
	  (action == ZLINE_LOCAL_ACTIVATE ? ">" :
	   (action == ZLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))),
	 expire, reason, azline ? "EXISTS" : "does not exist",
	 flags & ZLINE_EXPIRE ? "expire" : "",
	 flags & ZLINE_REASON ? "reason" : ""));

  if (azline) /* modifying an existing Z-line */
    return zline_modify(cptr, sptr, azline, action, reason, expire,
			TStime(), 0, flags);

  assert(action != ZLINE_LOCAL_ACTIVATE);
  assert(action != ZLINE_LOCAL_DEACTIVATE);
  assert(action != ZLINE_MODIFY);

  /* create a new Z-line */
  return zline_add(cptr, sptr, mask, reason, expire, TStime(), 0,
		   flags | ((action == ZLINE_ACTIVATE) ? ZLINE_ACTIVE : 0));
}
Ejemplo n.º 9
0
int m_challenge(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
#ifdef USE_SSL
  struct ConfItem *aconf;
  RSA *rsa_public_key;
  BIO *file = NULL;
  char *challenge = NULL;
  char *name;
  char *tmpname;
  char             chan[CHANNELLEN-1];
  char*            join[2];
  int nl;
  struct Flags old_mode = cli_flags(sptr);

  if (!MyUser(sptr))
    return 0;

  if (parc < 2)
    return need_more_params(sptr, "CHALLENGE");

  if (parc > 2) { /* This is a remote OPER Request */
    struct Client *srv;
    if (!string_has_wildcards(parv[1]))
      srv = FindServer(parv[1]);
    else
      srv = find_match_server(parv[1]);

    if (!feature_bool(FEAT_REMOTE_OPER))
      return send_reply(sptr, ERR_NOOPERHOST);

    if (!srv)
      return send_reply(sptr, ERR_NOOPERHOST);

    if (IsMe(srv)) {
      parv[1] = parv[2];
    } else {
      sendcmdto_one(sptr, CMD_CHALLENGE, srv, "%C %s", srv, parv[2]);
      return 0;
    }
  }

  /* if theyre an oper, reprint oper motd and ignore */
  if (IsOper(sptr))
  {
    send_reply(sptr, RPL_YOUREOPER);
    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);
  }

  if (*parv[1] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (cli_user(sptr)->response == NULL)
      return 0;

    if (ircd_strcmp(cli_user(sptr)->response, ++parv[1]))
    {
      send_reply(sptr, ERR_PASSWDMISMATCH);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (Password Incorrect)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      tmpname = strdup(cli_user(sptr)->auth_oper);
      failed_challenge_notice(sptr, tmpname, "challenge failed");
      return 0;
    }

    name = strdup(cli_user(sptr)->auth_oper);
     
    aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                            MyUser(sptr) ? cli_sockhost(sptr) :
                            cli_user(sptr)->realhost, CONF_OPS);

    if (!aconf)
      aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

    if (!aconf)
      aconf = find_conf_cidr(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              cli_ip(sptr), CONF_OPS);

    if (!aconf)
    {
      send_reply(sptr, ERR_NOOPERHOST);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      return 0;
    }

    if (CONF_LOCOP == aconf->status) {
      ClearOper(sptr);
      SetLocOp(sptr);
    }
    else {
      /*
       * prevent someone from being both oper and local oper
       */
      ClearLocOp(sptr);
      if (!feature_bool(FEAT_OPERFLAGS) || !(aconf->port & OFLAG_ADMIN)) {
        /* Global Oper */
        SetOper(sptr);
        ClearAdmin(sptr);
      } else {
        /* Admin */
        SetOper(sptr);
        OSetGlobal(sptr);
        SetAdmin(sptr);
      }
      ++UserStats.opers;
    }
    cli_handler(cptr) = OPER_HANDLER;

    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_WHOIS)) {
      OSetWhois(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_IDLE)) {
      OSetIdle(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_XTRAOP)) {
      OSetXtraop(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_HIDECHANS)) {
      OSetHideChans(sptr);
    }

    SetFlag(sptr, FLAG_WALLOP);
    SetFlag(sptr, FLAG_SERVNOTICE);
    SetFlag(sptr, FLAG_DEBUG);

    if (!IsAdmin(sptr))
      cli_oflags(sptr) = aconf->port;

    set_snomask(sptr, SNO_OPERDEFAULT, SNO_ADD);
    client_set_privs(sptr, aconf);
    cli_max_sendq(sptr) = 0; /* Get the sendq from the oper's class */
    send_umode_out(cptr, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
    send_reply(sptr, RPL_YOUREOPER);

    if (IsAdmin(sptr)) {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Administrator",
                    parv[0], cli_user(sptr)->username, cli_sockhost(sptr));

      /* Autojoin admins to admin channel and oper channel (if enabled) */
      if (feature_bool(FEAT_AUTOJOIN_ADMIN)) {
        if (feature_bool(FEAT_AUTOJOIN_ADMIN_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_ADMIN_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_ADMIN_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
      if (feature_bool(FEAT_AUTOJOIN_OPER) && IsOper(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    } else {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Operator (%c)",
                         parv[0], cli_user(sptr)->username, cli_sockhost(sptr),
                         IsOper(sptr) ? 'O' : 'o');

      if (feature_bool(FEAT_AUTOJOIN_OPER) && IsOper(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    }

    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);

    log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#C)", name, sptr);

    ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
    return 0;
  }

  ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
  ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN+1, "%s", "");

  aconf = find_conf_exact(parv[1], cli_user(sptr)->realusername,
                          cli_user(sptr)->realhost, CONF_OPS);

  if (!aconf)
    aconf = find_conf_exact(parv[1], cli_user(sptr)->realusername,
                            ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

  if (!aconf)
    aconf = find_conf_cidr(parv[1], cli_user(sptr)->realusername,
                            cli_ip(sptr), CONF_OPS);

  if (aconf == NULL)
  {
    send_reply(sptr, ERR_NOOPERHOST);
    failed_challenge_notice(sptr, parv[1], "No o:line");
    sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                       parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
    return 0;
  }

  if (!(aconf->port & OFLAG_RSA))
  {
    send_reply(sptr, RPL_NO_CHALL);
    return 0;
  }

  if (!verify_sslclifp(sptr, aconf))
  {
    sendto_allops(&me, SNO_OLDREALOP,
           "Failed OPER attempt by %s (%s@%s) (SSL Fingerprint Missmatch)",
           parv[0], cli_user(sptr)->realusername,
           cli_user(sptr)->realhost);
    send_reply(sptr, ERR_SSLCLIFP);
    return 0;
  }

  if ((file = BIO_new_file(aconf->passwd, "r")) == NULL)
  {
    send_reply(sptr, RPL_NO_KEY);
    return 0;
  }

  rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
  if (rsa_public_key == NULL)
     return send_reply(sptr, RPL_INVALID_KEY);


  if (!generate_challenge(&challenge, rsa_public_key, sptr)) {
      Debug((DEBUG_DEBUG, "generating challenge sum (%s)", challenge));
      send_reply(sptr, RPL_RSACHALLENGE, challenge);
      ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN + 1, "%s", aconf->name);
  }
  nl = BIO_set_close(file, BIO_CLOSE);
  BIO_free(file);

  return 1;
#else
  return 1;
#endif
}
Ejemplo n.º 10
0
static
void do_trace(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
    int i;
    struct Client *acptr;
    struct Client *acptr2;
    const struct ConnectionClass* cl;
    char* tname;
    int doall;
    int *link_s;
    int *link_u;
    int cnt = 0;
    int wilds;
    int dow;

    if (parc < 2 || BadPtr(parv[1]))
    {
        /* just "TRACE" without parameters. Must be from local client */
        parc = 1;
        acptr = &me;
        tname = cli_name(&me);
        i = HUNTED_ISME;
    }
    else if (parc < 3 || BadPtr(parv[2]))
    {
        /* No target specified. Make one before propagating. */
        parc = 2;
        tname = parv[1];
        if ((acptr = find_match_server(parv[1])) ||
                ((acptr = FindClient(parv[1])) && !MyUser(acptr)))
        {
            if (IsUser(acptr))
                parv[2] = cli_name(cli_user(acptr)->server);
            else
                parv[2] = cli_name(acptr);
            parc = 3;
            parv[3] = 0;
            if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, IsServer(acptr),
                                     "%s :%C", 2, parc, parv)) == HUNTED_NOSUCH)
                return;
        }
        else
            i = HUNTED_ISME;
    } else {
        /* Got "TRACE <tname> :<target>" */
        parc = 3;
        if (MyUser(sptr) || Protocol(cptr) < 10)
            acptr = find_match_server(parv[2]);
        else
            acptr = FindNServer(parv[2]);
        if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, 0, "%s :%C", 2, parc,
                                 parv)) == HUNTED_NOSUCH)
            return;
        tname = parv[1];
    }

    if (i == HUNTED_PASS) {
        if (!acptr)
            acptr = next_client(GlobalClientList, tname);
        else
            acptr = cli_from(acptr);
        send_reply(sptr, RPL_TRACELINK,
                   version, debugmode, tname,
                   acptr ? cli_name(cli_from(acptr)) : "<No_match>");
        return;
    }

    doall = (parv[1] && (parc > 1)) ? !match(tname, cli_name(&me)) : 1;
    wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
    dow = wilds || doall;

    /* Don't give (long) remote listings to lusers */
    if (dow && !MyConnect(sptr) && !IsAnOper(sptr)) {
        send_reply(sptr, RPL_TRACEEND);
        return;
    }

    link_s = MyCalloc(2 * maxconnections, sizeof(link_s[0]));
    link_u = link_s + maxconnections;

    if (doall) {
        for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
            if (IsUser(acptr))
                link_u[cli_fd(cli_from(acptr))]++;
            else if (IsServer(acptr))
                link_s[cli_fd(cli_from(acptr))]++;
        }
    }

    /* report all direct connections */

    for (i = 0; i <= HighestFd; i++) {
        const char *conClass;

        if (!(acptr = LocalClientArray[i])) /* Local Connection? */
            continue;
        if (IsInvisible(acptr) && dow && !(MyConnect(sptr) && IsOper(sptr)) &&
                !IsAnOper(acptr) && (acptr != sptr))
            continue;
        if (!doall && wilds && match(tname, cli_name(acptr)))
            continue;
        if (!dow && 0 != ircd_strcmp(tname, cli_name(acptr)))
            continue;

        conClass = get_client_class(acptr);

        switch (cli_status(acptr)) {
        case STAT_CONNECTING:
            send_reply(sptr, RPL_TRACECONNECTING, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_HANDSHAKE:
            send_reply(sptr, RPL_TRACEHANDSHAKE, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_ME:
            break;
        case STAT_UNKNOWN:
        case STAT_UNKNOWN_USER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass,
                       get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        case STAT_UNKNOWN_SERVER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass, "Unknown Server");
            cnt++;
            break;
        case STAT_USER:
            /* Only opers see users if there is a wildcard
               but anyone can see all the opers. */
            if ((IsAnOper(sptr) && (MyUser(sptr) ||
                                    !(dow && IsInvisible(acptr)))) || !dow || IsAnOper(acptr)) {
                if (IsAnOper(acptr))
                    send_reply(sptr, RPL_TRACEOPERATOR, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                else
                    send_reply(sptr, RPL_TRACEUSER, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                cnt++;
            }
            break;
        /*
         * Connection is a server
         *
         * Serv <class> <nS> <nC> <name> <ConnBy> <last> <age>
         *
         * class        Class the server is in
         * nS           Number of servers reached via this link
         * nC           Number of clients reached via this link
         * name         Name of the server linked
         * ConnBy       Who established this link
         * last         Seconds since we got something from this link
         * age          Seconds this link has been alive
         *
         * Additional comments etc......        -Cym-<*****@*****.**>
         */

        case STAT_SERVER:
            if (cli_serv(acptr)->user) {
                if (!cli_serv(acptr)->by[0]
                        || !(acptr2 = findNUser(cli_serv(acptr)->by))
                        || (cli_user(acptr2) != cli_serv(acptr)->user))
                    acptr2 = NULL;
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           acptr2 ? cli_name(acptr2) : "*",
                           cli_serv(acptr)->user->username,
                           cli_serv(acptr)->user->host,
                           CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            } else
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           (*(cli_serv(acptr))->by) ?  cli_serv(acptr)->by : "*", "*",
                           cli_name(&me), CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            cnt++;
            break;
        default:                  /* We actually shouldn't come here, -msa */
            send_reply(sptr, RPL_TRACENEWTYPE, get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        }
    }
    /*
     * Add these lines to summarize the above which can get rather long
     * and messy when done remotely - Avalon
     */
    if (IsAnOper(sptr) && doall) {
        for (cl = get_class_list(); cl; cl = cl->next) {
            if (Links(cl) > 1)
                send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl) - 1);
        }
    }
    send_reply(sptr, RPL_TRACEEND);
    MyFree(link_s);
}
Ejemplo n.º 11
0
/*
 * mo_jupe - oper message handler
 *
 * parv[0] = Send prefix
 * parv[1] = [[+|-]<server name>]
 *
 * Local (to me) style:
 *
 * parv[2] = [Expiration offset]
 * parv[3] = [Comment]
 *
 * Global (or remote local) style:
 *
 * parv[2] = [target]
 * parv[3] = [Expiration offset]
 * parv[4] = [Comment]
 *
 */
int mo_jupe(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
    struct Client *acptr = 0;
    struct Jupe *ajupe;
    unsigned int flags = 0;
    time_t expire_off;
    char *server = parv[1], *target = 0, *reason;

    if (parc < 2)
        return jupe_list(sptr, 0);

    if (*server == '+') {
        flags |= JUPE_ACTIVE;
        server++;
    } else if (*server == '-')
        server++;
    else
        return jupe_list(sptr, server);

    if (!feature_bool(FEAT_CONFIG_OPERCMDS))
        return send_reply(sptr, ERR_DISABLED, "JUPE");

    if (parc == 4) {
        expire_off = atoi(parv[2]);
        reason = parv[3];
        flags |= JUPE_LOCAL;
    } else if (parc > 4) {
        target = parv[2];
        expire_off = atoi(parv[3]);
        reason = parv[4];
    } else
        return need_more_params(sptr, "JUPE");

    if (target) {
        if (!(target[0] == '*' && target[1] == '\0')) {
            if (!(acptr = find_match_server(target)))
                return send_reply(sptr, ERR_NOSUCHSERVER, target);

            if (!IsMe(acptr)) { /* manually propagate, since we don't set it */
                if (!HasPriv(sptr, PRIV_JUPE))
                    return send_reply(sptr, ERR_NOPRIVILEGES);

                sendcmdto_one(sptr, CMD_JUPE, acptr, "%C %c%s %s %Tu :%s", acptr,
                              flags & JUPE_ACTIVE ? '+' : '-', server, parv[3],
                              TStime(), reason);
                return 0;
            } else if (!HasPriv(sptr, PRIV_LOCAL_JUPE))
                return send_reply(sptr, ERR_NOPRIVILEGES);

            flags |= JUPE_LOCAL;
        } else if (!HasPriv(sptr, PRIV_JUPE))
            return send_reply(sptr, ERR_NOPRIVILEGES);
    }

    ajupe = jupe_find(server);

    if (ajupe) {
        if (JupeIsLocal(ajupe) && !(flags & JUPE_LOCAL)) /* global over local */
            jupe_free(ajupe);
        else {
            if (flags & JUPE_ACTIVE)
                return jupe_activate(cptr, sptr, ajupe, TStime(), flags);
            else
                return jupe_deactivate(cptr, sptr, ajupe, TStime(), flags);
        }
    }

    return jupe_add(cptr, sptr, server, reason, expire_off, TStime(), flags);
}
Ejemplo n.º 12
0
/** Handle a CONNECT message from an operator.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the server that should initiate the connection
 * \li \a parv[2] is the port number to connect on (zero for the default)
 * \li \a parv[3] is the server to connect to
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int mo_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  unsigned short   port;
  unsigned short   tmpport;
  const char*      rule;
  struct ConfItem* aconf;
  struct Client*   acptr;
  struct Jupe*     ajupe;

  assert(0 != cptr);
  assert(cptr == sptr);
  assert(IsAnOper(sptr));

  if (parc < 2)
    return need_more_params(sptr, "CONNECT");

  if (parc > 3) {
    /*
     * if parc > 3, we are trying to connect two remote
     * servers to each other
     */
    if (IsLocOp(sptr)) {
      /*
       * Only allow LocOps to make local CONNECTS --SRB
       */
      return send_reply(cptr, ERR_NOPRIVILEGES);
    }
    else {
      struct Client* acptr2;
      struct Client* acptr3;

      if (!(acptr3 = find_match_server(parv[3]))) {
        return send_reply(sptr, ERR_NOSUCHSERVER, parv[3]);
      }

      /*
       * Look for closest matching server 
       * needed for "/connect blah 4400 *"?
       */
      for (acptr2 = acptr3; acptr2 != &me; acptr2 = cli_serv(acptr2)->up) {
        if (!match(parv[3], cli_name(acptr2)))
          acptr3 = acptr2;
      }
      parv[3] = cli_name(acptr3);
      if (hunt_server_cmd(sptr, CMD_CONNECT, cptr, 1, "%s %s :%C", 3, parc,
			  parv) != HUNTED_ISME)
        return 0;
    }
  }
  /*
   * need to find the conf entry first so we can use the server name from
   * the conf entry instead of parv[1] to find out if the server is already
   * present below. --Bleep
   */
  if (0 == (aconf = conf_find_server(parv[1]))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Host %s not listed "
		  "in ircd.conf", sptr, parv[1]);
    return 0;
  }
  /*
   * use aconf->name to look up the server, see above
   */
  if ((acptr = FindServer(aconf->name))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s already "
		  "exists from %s", sptr, parv[1], cli_name(cli_from(acptr)));
    return 0;
  }
  /*
   * Evaluate connection rules...  If no rules found, allow the
   * connect.   Otherwise stop with the first true rule (ie: rules
   * are ored together.  Oper connects are effected only by D
   * lines (CRULEALL) not d lines (CRULEAUTO).
   */
  if ((rule = conf_eval_crule(aconf->name, CRULE_ALL))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Disallowed by rule: %s", sptr, rule);
    return 0;
  }
  /*
   * Check to see if the server is juped; if it is, disallow the connect
   */
  if ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s is juped: %s",
		  sptr, JupeServer(ajupe), JupeReason(ajupe));
    return 0;
  }
  /*
   *  Get port number from user, if given. If not specified,
   *  use the default from configuration structure. If missing
   *  from there, then use the precompiled default.
   */
  port = aconf->address.port;
  if (parc > 2) {
    assert(0 != parv[2]);
    if (0 == (port = atoi(parv[2]))) {
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Invalid port number",
		    sptr);
      return 0;
    }
  }
  if (0 == port && 0 == (port = feature_int(FEAT_SERVER_PORT))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: missing port number",
		  sptr);
    return 0;
  }

  tmpport = aconf->address.port;
  aconf->address.port = port;

  if (connect_server(aconf, sptr)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connecting to %s.", sptr,
		  aconf->name);
  }
  else {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connection to %s failed",
		  sptr, aconf->name);
  }
  aconf->address.port = tmpport;
  return 0;
}