コード例 #1
0
static void tls_policy_lookup(SMTP_SESSION *session, int *site_level,
			              const char *site_name,
			              const char *site_class)
{

    /*
     * Only one lookup with [nexthop]:port, [nexthop] or nexthop:port These
     * are never the domain part of localpart@domain, rather they are
     * explicit nexthops from transport:nexthop, and match only the
     * corresponding policy. Parent domain matching (below) applies only to
     * sub-domains of the recipient domain.
     */
    if (!valid_hostname(site_name, DONT_GRIPE)) {
	tls_policy_lookup_one(session, site_level, site_name, site_class);
	return;
    }

    /*
     * XXX For clarity consider using ``do { .. } while'', instead of using
     * ``while { .. }'' with loop control at the bottom.
     */
    while (1) {
	/* Try the given domain */
	if (tls_policy_lookup_one(session, site_level, site_name, site_class))
	    return;
	/* Re-try with parent domain */
	if ((site_name = strchr(site_name + 1, '.')) == 0)
	    return;
    }
}
コード例 #2
0
ファイル: m_chghost.c プロジェクト: diegoagudo/redebr-ircd
static void
me_chghost(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p = NULL;

	if(parc < 3)
		return;

	if(!IsServer(source_p))
		return;

	if((target_p = find_client(parv[1])) == NULL)
		return;

	if(!IsClient(target_p))
		return;

	if(strlen(parv[2]) > HOSTLEN || !*parv[2] || !valid_hostname(parv[2]))
		return;

	if(!strcmp(target_p->host, parv[2]))
		return;

	if(ConfigChannel.cycle_on_hostchange)
		do_hostchange_quits(target_p);

	strlcpy(target_p->host, parv[2], sizeof(target_p->host));

	if(ConfigChannel.cycle_on_hostchange)
		do_hostchange_joins(target_p);
}
コード例 #3
0
ファイル: get_hostname.c プロジェクト: ajinkya93/netbsd-src
const char *get_hostname(void)
{
    char    namebuf[MAXHOSTNAMELEN + 1];

    /*
     * The gethostname() call is not (or not yet) in ANSI or POSIX, but it is
     * part of the socket interface library. We avoid the more politically-
     * correct uname() routine because that has no portable way of dealing
     * with long (FQDN) hostnames.
     * 
     * DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION. IT BREAKS MAILDIR DELIVERY
     * AND OTHER THINGS WHEN THE MACHINE NAME IS NOT FOUND IN /ETC/HOSTS OR
     * CAUSES PROCESSES TO HANG WHEN THE NETWORK IS DISCONNECTED.
     * 
     * POSTFIX NO LONGER NEEDS A FULLY QUALIFIED HOSTNAME. INSTEAD POSTFIX WILL
     * USE A DEFAULT DOMAIN NAME "LOCALDOMAIN".
     */
    if (my_host_name == 0) {
	/* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
	if (gethostname(namebuf, sizeof(namebuf)) < 0)
	    msg_fatal("gethostname: %m");
	namebuf[MAXHOSTNAMELEN] = 0;
	/* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
	if (valid_hostname(namebuf, DO_GRIPE) == 0)
	    msg_fatal("unable to use my own hostname");
	/* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
	my_host_name = mystrdup(namebuf);
    }
    return (my_host_name);
}
コード例 #4
0
ファイル: genuuid.c プロジェクト: sunny256/suuid
int fill_entry_struct(struct Entry *entry, const struct Rc *rc,
                      const struct Options *opt)
{
	unsigned int i;

	assert(entry);
	assert(rc);
	assert(opt);

	/*
	 * Get information about the environment; hostname, current directory, 
	 * login name and tty.
	 *
	 * Fixme: Add check so this and the session info thing are run only 
	 * once. Only has some effect if creating many UUIDs.
	 */

	entry->host = get_hostname(rc);
	if (!entry->host) {
		myerror("fill_entry_struct(): Cannot get hostname");
		return EXIT_FAILURE;
	}
	if (!valid_hostname(entry->host)) {
		myerror("fill_entry_struct(): Got invalid hostname: \"%s\"",
		        entry->host);
		return EXIT_FAILURE;
	}
	entry->cwd = getpath();
	entry->user = get_username();
	entry->tty = get_tty();

	/*
	 * Store tags and comment in entry.
	 */

	for (i = 0; i < MAX_TAGS && opt->tag[i]; i++)
		if (store_tag(entry, opt->tag[i]) == EXIT_FAILURE)
			return EXIT_FAILURE;

	if (opt->comment) {
		entry->txt = process_comment_option(opt->comment);
		if (!entry->txt)
			return EXIT_FAILURE;
	}

	/*
	 * Store session information from the environment variable.
	 */

	if (get_sess_info(entry) == EXIT_FAILURE) {
		free(entry->txt);
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
コード例 #5
0
int     main(int unused_argc, char **argv)
{
    VSTRING *buffer = vstring_alloc(1);

    msg_vstream_init(argv[0], VSTREAM_ERR);
    msg_verbose = 1;

    while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
	msg_info("testing: \"%s\"", vstring_str(buffer));
	valid_hostname(vstring_str(buffer), DO_GRIPE);
	valid_hostaddr(vstring_str(buffer), DO_GRIPE);
    }
    exit(0);
}
コード例 #6
0
ファイル: m_set.c プロジェクト: Cloudxtreme/elemental-ircd
/* SET OPERHOST */
static void
quote_operhost(struct Client *source_p, const char *arg, int newval)
{
    if(EmptyString(arg)) {
        sendto_one_notice(source_p, ":OPERHOST is currently '%s'", GlobalSetOptions.operhost);
    } else if(!valid_hostname(arg)) {
        sendto_one_notice(source_p, "Invalid hostmask.");
    } else {
        rb_strlcpy(GlobalSetOptions.operhost, arg,
                   sizeof(GlobalSetOptions.operhost));

        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                               "%s has changed OPERHOST to '%s'",
                               get_oper_name(source_p), arg);
    }
}
コード例 #7
0
ファイル: m_nick.c プロジェクト: jmaurice/ircd-hybrid
/* check_clean_host()
 *
 * input        - pointer to client sending us data
 *              - nickname
 *              - hostname to check
 *              - source name
 * output       - none
 * side effects - if hostname is erroneous, return 1
 */
static int
check_clean_host(struct Client *client_p, char *nick,
                 char *host, struct Client *server_p)
{
  if (!valid_hostname(host))
  {
    ++ServerStats.is_kill;
    sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
                         "Bad/Long Hostname: %s Nickname: %s From: %s(via %s)",
                         host, nick, server_p->name, client_p->name);
    sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)",
               me.name, nick, me.name);
    return 1;
  }

  return 0;
}
コード例 #8
0
ファイル: host_port.c プロジェクト: ystk/debian-postfix
const char *host_port(char *buf, char **host, char *def_host,
		              char **port, char *def_service)
{
    char   *cp = buf;

    /*
     * [host]:port, [host]:, [host].
     */
    if (*cp == '[') {
	*host = ++cp;
	if ((cp = split_at(cp, ']')) == 0)
	    return ("missing \"]\"");
	if (*cp && *cp++ != ':')
	    return ("garbage after \"]\"");
	*port = *cp ? cp : def_service;
    }

    /*
     * host:port, host:, host, :port, port.
     */
    else {
	if ((cp = split_at_right(buf, ':')) != 0) {
	    *host = *buf ? buf : def_host;
	    *port = *cp ? cp : def_service;
	} else {
	    *host = def_host ? def_host : (*buf ? buf : 0);
	    *port = def_service ? def_service : (*buf ? buf : 0);
	}
    }
    if (*host == 0)
	return ("missing host information");
    if (*port == 0)
	return ("missing service information");

    /*
     * Final sanity checks. We're still sloppy, allowing bare numerical
     * network addresses instead of requiring proper [ipaddress] forms.
     */
    if (*host != def_host && !valid_hostname(*host, DONT_GRIPE)
	&& !valid_hostaddr(*host, DONT_GRIPE))
	return ("valid hostname or network address required");
    if (*port != def_service && ISDIGIT(**port) && !alldig(*port))
	return ("garbage after numerical service");
    return (0);
}
コード例 #9
0
ファイル: get_hostname.c プロジェクト: TonyChengTW/Rmail
const char *get_hostname(void)
{
    char    namebuf[MAXHOSTNAMELEN + 1];

    /*
     * The gethostname() call is not (or not yet) in ANSI or POSIX, but it is
     * part of the socket interface library. We avoid the more politically-
     * correct uname() routine because that has no portable way of dealing
     * with long (FQDN) hostnames.
     */
    if (my_host_name == 0) {
	if (gethostname(namebuf, sizeof(namebuf)) < 0)
	    msg_fatal("gethostname: %m");
	namebuf[MAXHOSTNAMELEN] = 0;
	if (valid_hostname(namebuf, DO_GRIPE) == 0)
	    msg_fatal("unable to use my own hostname");
	my_host_name = mystrdup(namebuf);
    }
    return (my_host_name);
}
コード例 #10
0
ファイル: m_svshost.c プロジェクト: ircd-hybrid/ircd-hybrid
/*! \brief SVSHOST command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = nickname
 *      - parv[2] = TS
 *      - parv[3] = host name
 */
static int
ms_svshost(struct Client *source_p, int parc, char *parv[])
{
  if (!HasFlag(source_p, FLAGS_SERVICE))
    return 0;

  struct Client *target_p;
  if ((target_p = find_person(source_p, parv[1])) == NULL)
    return 0;

  uintmax_t ts = strtoumax(parv[2], NULL, 10);
  if (ts && (ts != target_p->tsinfo))
    return 0;

  if (valid_hostname(parv[3]) == true)
    user_set_hostmask(target_p, parv[3]);

  sendto_server(source_p, 0, 0, ":%s SVSHOST %s %ju %s",
                source_p->id,
                target_p->id, target_p->tsinfo, parv[3]);
  return 0;
}
コード例 #11
0
static void tls_policy_lookup(SMTP_TLS_POLICY *tls, int *site_level,
			              const char *site_name,
			              const char *site_class)
{

    /*
     * Only one lookup with [nexthop]:port, [nexthop] or nexthop:port These
     * are never the domain part of localpart@domain, rather they are
     * explicit nexthops from transport:nexthop, and match only the
     * corresponding policy. Parent domain matching (below) applies only to
     * sub-domains of the recipient domain.
     * 
     * XXX UNIX-domain connections query with the pathname as destination.
     */
    if (!valid_hostname(site_name, DONT_GRIPE)) {
	tls_policy_lookup_one(tls, site_level, site_name, site_class);
	return;
    }
    do {
	tls_policy_lookup_one(tls, site_level, site_name, site_class);
    } while (*site_level == TLS_LEV_NOTFOUND
	     && (site_name = strchr(site_name + 1, '.')) != 0);
}
コード例 #12
0
int     valid_utf8_hostname(int enable_utf8, const char *name, int gripe)
{
    static const char myname[] = "valid_utf8_hostname";

    /*
     * Trivial cases first.
     */
    if (*name == 0) {
	if (gripe)
	    msg_warn("%s: empty domain name", myname);
	return (0);
    }

    /*
     * Convert non-ASCII domain name to ASCII and validate the result per
     * STD3. midna_domain_to_ascii() applies valid_hostname() to the result.
     * Propagate the gripe parameter for better diagnostics (note that
     * midna_domain_to_ascii() logs a problem only when the result is not
     * cached).
     */
#ifndef NO_EAI
    if (enable_utf8 && !allascii(name)) {
	if (midna_domain_to_ascii(name) == 0) {
	    if (gripe)
		msg_warn("%s: malformed UTF-8 domain name", myname);
	    return (0);
	} else {
	    return (1);
	}
    }
#endif

    /*
     * Validate ASCII name per STD3.
     */
    return (valid_hostname(name, gripe));
}
コード例 #13
0
ファイル: smtpd_peer.c プロジェクト: TonyChengTW/Rmail
void    smtpd_peer_init(SMTPD_STATE *state)
{
    struct sockaddr_in sin;
    SOCKADDR_SIZE len = sizeof(sin);
    struct hostent *hp;
    int     i;

    /*
     * Avoid suprious complaints from Purify on Solaris.
     */
    memset((char *) &sin, 0, len);

    /*
     * Look up the peer address information.
     */
    if (getpeername(vstream_fileno(state->client),
		    (struct sockaddr *) & sin, &len) >= 0) {
	errno = 0;
    }

    /*
     * If peer went away, give up.
     */
    if (errno == ECONNRESET || errno == ECONNABORTED) {
	state->name = mystrdup(CLIENT_NAME_UNKNOWN);
	state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
	state->peer_code = SMTPD_PEER_CODE_PERM;
    }

    /*
     * Look up and "verify" the client hostname.
     */
    else if (errno == 0 && sin.sin_family == AF_INET) {
	state->addr = mystrdup(inet_ntoa(sin.sin_addr));
	hp = gethostbyaddr((char *) &(sin.sin_addr),
			   sizeof(sin.sin_addr), AF_INET);
	if (hp == 0) {
	    state->name = mystrdup(CLIENT_NAME_UNKNOWN);
	    state->peer_code = (h_errno == TRY_AGAIN ?
				SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
	} else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
	    msg_warn("numeric result %s in address->name lookup for %s",
		     hp->h_name, state->addr);
	    state->name = mystrdup(CLIENT_NAME_UNKNOWN);
	    state->peer_code = SMTPD_PEER_CODE_PERM;
	} else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
	    state->name = mystrdup(CLIENT_NAME_UNKNOWN);
	    state->peer_code = SMTPD_PEER_CODE_PERM;
	} else {
	    state->name = mystrdup(hp->h_name);	/* hp->name is clobbered!! */
	    state->peer_code = SMTPD_PEER_CODE_OK;

	    /*
	     * Reject the hostname if it does not list the peer address.
	     */
#define REJECT_PEER_NAME(state, code) { \
	myfree(state->name); \
	state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
	state->peer_code = code; \
    }

	    hp = gethostbyname(state->name);	/* clobbers hp->name!! */
	    if (hp == 0) {
		msg_warn("%s: hostname %s verification failed: %s",
			 state->addr, state->name, HSTRERROR(h_errno));
		REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ?
			      SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM));
	    } else if (hp->h_length != sizeof(sin.sin_addr)) {
		msg_warn("%s: hostname %s verification failed: bad address size %d",
			 state->addr, state->name, hp->h_length);
		REJECT_PEER_NAME(state, SMTPD_PEER_CODE_PERM);
	    } else {
		for (i = 0; /* void */ ; i++) {
		    if (hp->h_addr_list[i] == 0) {
			msg_warn("%s: address not listed for hostname %s",
				 state->addr, state->name);
			REJECT_PEER_NAME(state, SMTPD_PEER_CODE_PERM);
			break;
		    }
		    if (memcmp(hp->h_addr_list[i],
			       (char *) &sin.sin_addr,
			       sizeof(sin.sin_addr)) == 0)
			break;			/* keep peer name */
		}
	    }
	}
    }

    /*
     * If it's not Internet, assume the client is local, and avoid using the
     * naming service because that can hang when the machine is disconnected.
     */
    else {
	state->name = mystrdup("localhost");
	state->addr = mystrdup("127.0.0.1");	/* XXX bogus. */
	state->peer_code = SMTPD_PEER_CODE_OK;
    }

    /*
     * Do the name[addr] formatting for pretty reports.
     */
    state->namaddr =
	concatenate(state->name, "[", state->addr, "]", (char *) 0);
}
コード例 #14
0
ファイル: postqueue.c プロジェクト: Jingeun/tongsu_smtp
int     main(int argc, char **argv)
{
    struct stat st;
    char   *slash;
    int     c;
    int     fd;
    int     mode = PQ_MODE_DEFAULT;
    char   *site_to_flush = 0;
    char   *id_to_flush = 0;
    ARGV   *import_env;
    int     bad_site;

    /*
     * Fingerprint executables and core dumps.
     */
    MAIL_VERSION_STAMP_ALLOCATE;

    /*
     * Be consistent with file permissions.
     */
    umask(022);

    /*
     * To minimize confusion, make sure that the standard file descriptors
     * are open before opening anything else. XXX Work around for 44BSD where
     * fstat can return EBADF on an open file descriptor.
     */
    for (fd = 0; fd < 3; fd++)
	if (fstat(fd, &st) == -1
	    && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
	    msg_fatal_status(EX_UNAVAILABLE, "open /dev/null: %m");

    /*
     * Initialize. Set up logging, read the global configuration file and
     * extract configuration information. Set up signal handlers so that we
     * can clean up incomplete output.
     */
    if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
	argv[0] = slash + 1;
    msg_vstream_init(argv[0], VSTREAM_ERR);
    msg_cleanup(unavailable);
    msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
    set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));

    /*
     * Check the Postfix library version as soon as we enable logging.
     */
    MAIL_VERSION_CHECK;

    /*
     * Parse JCL. This program is set-gid and must sanitize all command-line
     * parameters. The configuration directory argument is validated by the
     * mail configuration read routine. Don't do complex things until we have
     * completed initializations.
     */
    while ((c = GETOPT(argc, argv, "c:fi:ps:v")) > 0) {
	switch (c) {
	case 'c':				/* non-default configuration */
	    if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
		msg_fatal_status(EX_UNAVAILABLE, "out of memory");
	    break;
	case 'f':				/* flush queue */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_QUEUE;
	    break;
	case 'i':				/* flush queue file */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_FILE;
	    id_to_flush = optarg;
	    break;
	case 'p':				/* traditional mailq */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_MAILQ_LIST;
	    break;
	case 's':				/* flush site */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_SITE;
	    site_to_flush = optarg;
	    break;
	case 'v':
	    if (geteuid() == 0)
		msg_verbose++;
	    break;
	default:
	    usage();
	}
    }
    if (argc > optind)
	usage();

    /*
     * Further initialization...
     */
    mail_conf_read();
    /* Re-evaluate mail_task() after reading main.cf. */
    msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
    mail_dict_init();				/* proxy, sql, ldap */
    get_mail_conf_str_table(str_table);

    /*
     * This program is designed to be set-gid, which makes it a potential
     * target for attack. If not running as root, strip the environment so we
     * don't have to trust the C library. If running as root, don't strip the
     * environment so that showq can receive non-default configuration
     * directory info when the mail system is down.
     */
    if (geteuid() != 0) {
	import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
	clean_env(import_env->argv);
	argv_free(import_env);
    }
    if (chdir(var_queue_dir))
	msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir);

    signal(SIGPIPE, SIG_IGN);

    /* End of initializations. */

    /*
     * Further input validation.
     */
    if (site_to_flush != 0) {
	bad_site = 0;
	if (*site_to_flush == '[') {
	    bad_site = !valid_mailhost_literal(site_to_flush, DONT_GRIPE);
	} else {
	    bad_site = !valid_hostname(site_to_flush, DONT_GRIPE);
	}
	if (bad_site)
	    msg_fatal_status(EX_USAGE,
	      "Cannot flush mail queue - invalid destination: \"%.100s%s\"",
		   site_to_flush, strlen(site_to_flush) > 100 ? "..." : "");
    }
    if (id_to_flush != 0) {
	if (!mail_queue_id_ok(id_to_flush))
	    msg_fatal_status(EX_USAGE,
		       "Cannot flush queue ID - invalid name: \"%.100s%s\"",
		       id_to_flush, strlen(id_to_flush) > 100 ? "..." : "");
    }

    /*
     * Start processing.
     */
    switch (mode) {
    default:
	msg_panic("unknown operation mode: %d", mode);
	/* NOTREACHED */
    case PQ_MODE_MAILQ_LIST:
	show_queue();
	exit(0);
	break;
    case PQ_MODE_FLUSH_SITE:
	flush_site(site_to_flush);
	exit(0);
	break;
    case PQ_MODE_FLUSH_FILE:
	flush_file(id_to_flush);
	exit(0);
	break;
    case PQ_MODE_FLUSH_QUEUE:
	flush_queue();
	exit(0);
	break;
    case PQ_MODE_DEFAULT:
	usage();
	/* NOTREACHED */
    }
}
コード例 #15
0
int remote_session( char *acc_method, char *host )
{
  char *program;
  char *user = host;
  char *password = 0;
  char *cp;
  char *hostname;
  char *port;
  char *command = 0;
  enum _login_protocol  login_protocol = rlogin;
  cp = host;
  for ( ; cp[0]; cp++ )
  {
    if ( !( *(short*)(*(int*)(__ctype_b_loc( )) + ( cp[0] * 2 )) & 8 ) && cp[0] != '_' && cp[0] != '-' && cp[0] != ':' && cp[0] != '.' && cp[0] != '@' )
    {
      cp[0] = 0;
      break;
    }
    else
    {
      // cp++;
    }
  }
  hostname = strchr( host, '@' );
  if ( hostname )
  {
    hostname[0] = 0;
    hostname++;
  }
  else
  {
    hostname = host;
    user = 0;
  }
  port = strchr( hostname, ':' );
  if ( port )
  {
    port[0] = 0;
    port++;
  }
  if ( hostname == 0 || hostname[0] == 0 )
  {
    if ( WWW_TraceFlag )
    {
      fprintf( TraceFP( ), "HTTelnet: No host specified!\n" );
    }
    return -204;
  }
  else
  {
    if ( ( valid_hostname( hostname ) & 255 ) == 0 )
    {
      char *prefix = 0;
      char *line = 0;
      if ( WWW_TraceFlag )
      {
        fprintf( TraceFP( ), "HTTelnet: Invalid hostname %s!\n", host );
      }
      HTSprintf0( &prefix, gettext( "remote %s session:" ), acc_method );
      HTSprintf0( &line, gettext( "Invalid hostname %s" ), host );
      HTAlwaysAlert( prefix, line );
      if ( prefix )
      {
        free( prefix );
        prefix = 0;
      }
      if ( line )
      {
        free( line );
        line = 0;
      }
      return -204;
    }
    else
    {
      if ( user )
      {
        password = strchr( user, ':' );
        if ( password )
        {
          password[0] = 0;
          password++;
        }
      }
      if ( HTSecure )
      {
        puts( "\n\nSorry, but the service you have selected is one" );
        puts( "to which you have to log in.  If you were running www" );
        puts( "on your own computer, you would be automatically connected." );
        puts( "For security reasons, this is not allowed when" );
        puts( "you log in to this information service remotely.\n" );
        printf( "You can manually connect to this service using %s\n", acc_method );
        printf( "to host %s", hostname );
        if ( user )
          printf( ", user name %s", user );
        if ( password )
          printf( ", password %s", password );
        if ( port )
          printf( ", port %s", port );
        puts( ".\n" );
        return -204;
      }
      else
      {
        if ( user && login_protocol != rlogin )
          printf( "When you are connected, log in as:  %s\n", user );
        if ( password && login_protocol != rlogin )
          printf( "                  The password is:  %s\n", password );
        fflush( stdout );
        switch ( login_protocol )
        {
        case rlogin:
          program = HTGetProgramPath( 11 );
          if ( program == 0 )
          {
            LYSystem( command );
            return -204;
          }
          HTAddParam( &command, "%s %s%s%s", 1, program );
          HTAddParam( &command, "%s %s%s%s", 2, hostname );
          HTSACat( &command, "" );
          HTAddParam( &command, "%s %s%s%s", 4, user );
          HTEndParam( &command, "%s %s%s%s", 4 );
          break;
        case tn3270:
          program = HTGetProgramPath( 17 );
          if ( program == 0 )
          {
            LYSystem( command );
            return -204;
          }
          HTAddParam( &command, "%s %s %s", 1, program );
          HTAddParam( &command, "%s %s %s", 2, hostname );
          HTAddParam( &command, "%s %s %s", 3, port );
          HTEndParam( &command, "%s %s %s", 3 );
          break;
        case telnet:
          program = HTGetProgramPath( 16 );
          if ( program == 0 )
          {
            LYSystem( command );
            return -204;
          }
          HTAddParam( &command, "%s %s %s", 1, program );
          HTAddParam( &command, "%s %s %s", 2, hostname );
          HTAddParam( &command, "%s %s %s", 3, port );
          HTEndParam( &command, "%s %s %s", 3 );
          break;
        }
      }
    }
  }
}
コード例 #16
0
ファイル: smtp-source.c プロジェクト: KKcorps/postfix
int     main(int argc, char **argv)
{
    SESSION *session;
    char   *host;
    char   *port;
    char   *path;
    int     path_len;
    int     sessions = 1;
    int     ch;
    int     i;
    char   *buf;
    const char *parse_err;
    struct addrinfo *res;
    int     aierr;
    const char *protocols = INET_PROTO_NAME_ALL;
    INET_PROTO_INFO *proto_info;
    char   *message_file = 0;

    /*
     * Fingerprint executables and core dumps.
     */
    MAIL_VERSION_STAMP_ALLOCATE;

    signal(SIGPIPE, SIG_IGN);
    msg_vstream_init(argv[0], VSTREAM_ERR);

    /*
     * Parse JCL.
     */
    while ((ch = GETOPT(argc, argv, "46AcC:df:F:l:Lm:M:Nor:R:s:S:t:T:vw:")) > 0) {
        switch (ch) {
        case '4':
            protocols = INET_PROTO_NAME_IPV4;
            break;
        case '6':
            protocols = INET_PROTO_NAME_IPV6;
            break;
        case 'A':
            allow_reject = 1;
            break;
        case 'c':
            count++;
            break;
        case 'C':
            if ((connect_count = atoi(optarg)) <= 0)
                msg_fatal("bad connection count: %s", optarg);
            break;
        case 'd':
            disconnect = 0;
            break;
        case 'f':
            sender = optarg;
            break;
        case 'F':
            if (message_file == 0 && message_length > 0)
                msg_fatal("-l option cannot be used with -F");
            message_file = optarg;
            break;
        case 'l':
            if (message_file != 0)
                msg_fatal("-l option cannot be used with -F");
            if ((message_length = atoi(optarg)) <= 0)
                msg_fatal("bad message length: %s", optarg);
            break;
        case 'L':
            talk_lmtp = 1;
            break;
        case 'm':
            if ((message_count = atoi(optarg)) <= 0)
                msg_fatal("bad message count: %s", optarg);
            break;
        case 'M':
            if (*optarg == '[') {
                if (!valid_mailhost_literal(optarg, DO_GRIPE))
                    msg_fatal("bad address literal: %s", optarg);
            } else {
                if (!valid_hostname(optarg, DO_GRIPE))
                    msg_fatal("bad hostname: %s", optarg);
            }
            var_myhostname = optarg;
            break;
        case 'N':
            number_rcpts = 1;
            break;
        case 'o':
            send_helo_first = 0;
            send_headers = 0;
            break;
        case 'r':
            if ((recipients = atoi(optarg)) <= 0)
                msg_fatal("bad recipient count: %s", optarg);
            break;
        case 'R':
            if (fixed_delay > 0)
                msg_fatal("do not use -w and -R options at the same time");
            if ((random_delay = atoi(optarg)) <= 0)
                msg_fatal("bad random delay: %s", optarg);
            break;
        case 's':
            if ((sessions = atoi(optarg)) <= 0)
                msg_fatal("bad session count: %s", optarg);
            break;
        case 'S':
            subject = optarg;
            break;
        case 't':
            recipient = optarg;
            break;
        case 'T':
            if ((inet_windowsize = atoi(optarg)) <= 0)
                msg_fatal("bad TCP window size: %s", optarg);
            break;
        case 'v':
            msg_verbose++;
            break;
        case 'w':
            if (random_delay > 0)
                msg_fatal("do not use -w and -R options at the same time");
            if ((fixed_delay = atoi(optarg)) <= 0)
                msg_fatal("bad fixed delay: %s", optarg);
            break;
        default:
            usage(argv[0]);
        }
    }
    if (argc - optind != 1)
        usage(argv[0]);

    if (random_delay > 0)
        srand(getpid());

    /*
     * Initialize the message content, SMTP encoded. smtp_fputs() will append
     * another \r\n but we don't care.
     */
    if (message_file != 0) {
        VSTREAM *fp;
        VSTRING *buf = vstring_alloc(100);
        VSTRING *msg = vstring_alloc(100);

        if ((fp = vstream_fopen(message_file, O_RDONLY, 0)) == 0)
            msg_fatal("open %s: %m", message_file);
        while (vstring_get_nonl(buf, fp) != VSTREAM_EOF) {
            if (*vstring_str(buf) == '.')
                VSTRING_ADDCH(msg, '.');
            vstring_memcat(msg, vstring_str(buf), VSTRING_LEN(buf));
            vstring_memcat(msg, "\r\n", 2);
        }
        if (vstream_ferror(fp))
            msg_fatal("read %s: %m", message_file);
        vstream_fclose(fp);
        vstring_free(buf);
        message_length = VSTRING_LEN(msg);
        message_data = vstring_export(msg);
        send_headers = 0;
    } else if (message_length > 0) {
        message_data = mymalloc(message_length);
        memset(message_data, 'X', message_length);
        for (i = 80; i < message_length; i += 80) {
            message_data[i - 80] = "0123456789"[(i / 80) % 10];
            message_data[i - 2] = '\r';
            message_data[i - 1] = '\n';
        }
    }

    /*
     * Translate endpoint address to internal form.
     */
    proto_info = inet_proto_init("protocols", protocols);
    if (strncmp(argv[optind], "unix:", 5) == 0) {
        path = argv[optind] + 5;
        path_len = strlen(path);
        if (path_len >= (int) sizeof(sun.sun_path))
            msg_fatal("unix-domain name too long: %s", path);
        memset((char *) &sun, 0, sizeof(sun));
        sun.sun_family = AF_UNIX;
#ifdef HAS_SUN_LEN
        sun.sun_len = path_len + 1;
#endif
        memcpy(sun.sun_path, path, path_len);
        sa = (struct sockaddr *) & sun;
        sa_length = sizeof(sun);
    } else {
        if (strncmp(argv[optind], "inet:", 5) == 0)
            argv[optind] += 5;
        buf = mystrdup(argv[optind]);
        if ((parse_err = host_port(buf, &host, (char *) 0, &port, "smtp")) != 0)
            msg_fatal("%s: %s", argv[optind], parse_err);
        if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res)) != 0)
            msg_fatal("%s: %s", argv[optind], MAI_STRERROR(aierr));
        myfree(buf);
        sa = (struct sockaddr *) & ss;
        if (res->ai_addrlen > sizeof(ss))
            msg_fatal("address length %d > buffer length %d",
                      (int) res->ai_addrlen, (int) sizeof(ss));
        memcpy((char *) sa, res->ai_addr, res->ai_addrlen);
        sa_length = res->ai_addrlen;
#ifdef HAS_SA_LEN
        sa->sa_len = sa_length;
#endif
        freeaddrinfo(res);
    }

    /*
     * Make sure the SMTP server cannot run us out of memory by sending
     * never-ending lines of text.
     */
    if (buffer == 0) {
        buffer = vstring_alloc(100);
        vstring_ctl(buffer, VSTRING_CTL_MAXLEN, (ssize_t) var_line_limit, 0);
    }

    /*
     * Make sure we have sender and recipient addresses.
     */
    if (var_myhostname == 0)
        var_myhostname = get_hostname();
    if (sender == 0 || recipient == 0) {
        vstring_sprintf(buffer, "foo@%s", var_myhostname);
        defaddr = mystrdup(vstring_str(buffer));
        if (sender == 0)
            sender = defaddr;
        if (recipient == 0)
            recipient = defaddr;
    }

    /*
     * Start sessions.
     */
    while (sessions-- > 0) {
        session = (SESSION *) mymalloc(sizeof(*session));
        session->stream = 0;
        session->xfer_count = 0;
        session->connect_count = connect_count;
        session->next = 0;
        session_count++;
        startup(session);
    }
    for (;;) {
        event_loop(-1);
        if (session_count <= 0 && message_count <= 0) {
            if (count) {
                VSTREAM_PUTC('\n', VSTREAM_OUT);
                vstream_fflush(VSTREAM_OUT);
            }
            exit(0);
        }
    }
}
コード例 #17
0
ファイル: mail_params.c プロジェクト: ajinkya93/netbsd-src
void    mail_params_init()
{
    static const CONFIG_STR_TABLE first_str_defaults[] = {
	VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0,
	VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 0, 0,
	VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0,
	/* multi_instance_wrapper may have dependencies but not dependents. */
	VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0,
	VAR_MULTI_NAME, DEF_MULTI_NAME, &var_multi_name, 0, 0,
	0,
    };
    static const CONFIG_BOOL_TABLE first_bool_defaults[] = {
	/* read and process the following before opening tables. */
	VAR_DAEMON_OPEN_FATAL, DEF_DAEMON_OPEN_FATAL, &var_daemon_open_fatal,
	0,
    };
    static const CONFIG_STR_FN_TABLE function_str_defaults[] = {
	VAR_MYHOSTNAME, check_myhostname, &var_myhostname, 1, 0,
	VAR_MYDOMAIN, check_mydomainname, &var_mydomain, 1, 0,
	0,
    };
    static const CONFIG_STR_TABLE other_str_defaults[] = {
	VAR_MAIL_NAME, DEF_MAIL_NAME, &var_mail_name, 1, 0,
	VAR_SYSLOG_NAME, DEF_SYSLOG_NAME, &var_syslog_name, 1, 0,
	VAR_MAIL_OWNER, DEF_MAIL_OWNER, &var_mail_owner, 1, 0,
	VAR_SGID_GROUP, DEF_SGID_GROUP, &var_sgid_group, 1, 0,
	VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0,
	VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0,
	VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0,
	VAR_DAEMON_DIR, DEF_DAEMON_DIR, &var_daemon_dir, 1, 0,
	VAR_DATA_DIR, DEF_DATA_DIR, &var_data_dir, 1, 0,
	VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0,
	VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0,
	VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0,
	VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 0, 0,
	VAR_PROXY_INTERFACES, DEF_PROXY_INTERFACES, &var_proxy_interfaces, 0, 0,
	VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0,
	VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0,
	VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 0, 0,
	VAR_MAIL_RELEASE, DEF_MAIL_RELEASE, &var_mail_release, 1, 0,
	VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
	VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
	VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
	VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 0,
	VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
	VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0,
	VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0,
	VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0,
	VAR_MYNETWORKS_STYLE, DEF_MYNETWORKS_STYLE, &var_mynetworks_style, 1, 0,
	VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
	VAR_VERP_DELIMS, DEF_VERP_DELIMS, &var_verp_delims, 2, 2,
	VAR_VERP_FILTER, DEF_VERP_FILTER, &var_verp_filter, 1, 0,
	VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, 0, 0,
	VAR_CONFIG_DIRS, DEF_CONFIG_DIRS, &var_config_dirs, 0, 0,
	VAR_BOUNCE_SERVICE, DEF_BOUNCE_SERVICE, &var_bounce_service, 1, 0,
	VAR_CLEANUP_SERVICE, DEF_CLEANUP_SERVICE, &var_cleanup_service, 1, 0,
	VAR_DEFER_SERVICE, DEF_DEFER_SERVICE, &var_defer_service, 1, 0,
	VAR_PICKUP_SERVICE, DEF_PICKUP_SERVICE, &var_pickup_service, 1, 0,
	VAR_QUEUE_SERVICE, DEF_QUEUE_SERVICE, &var_queue_service, 1, 0,
	VAR_REWRITE_SERVICE, DEF_REWRITE_SERVICE, &var_rewrite_service, 1, 0,
	VAR_SHOWQ_SERVICE, DEF_SHOWQ_SERVICE, &var_showq_service, 1, 0,
	VAR_ERROR_SERVICE, DEF_ERROR_SERVICE, &var_error_service, 1, 0,
	VAR_FLUSH_SERVICE, DEF_FLUSH_SERVICE, &var_flush_service, 1, 0,
	VAR_VERIFY_SERVICE, DEF_VERIFY_SERVICE, &var_verify_service, 1, 0,
	VAR_TRACE_SERVICE, DEF_TRACE_SERVICE, &var_trace_service, 1, 0,
	VAR_PROXYMAP_SERVICE, DEF_PROXYMAP_SERVICE, &var_proxymap_service, 1, 0,
	VAR_PROXYWRITE_SERVICE, DEF_PROXYWRITE_SERVICE, &var_proxywrite_service, 1, 0,
	VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0,
	/* multi_instance_wrapper may have dependencies but not dependents. */
	VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
	0,
    };
    static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
	VAR_MYNETWORKS, mynetworks, &var_mynetworks, 0, 0,
	0,
    };
    static const CONFIG_INT_TABLE other_int_defaults[] = {
	VAR_PROC_LIMIT, DEF_PROC_LIMIT, &var_proc_limit, 1, 0,
	VAR_MAX_USE, DEF_MAX_USE, &var_use_limit, 1, 0,
	VAR_DONT_REMOVE, DEF_DONT_REMOVE, &var_dont_remove, 0, 0,
	VAR_LINE_LIMIT, DEF_LINE_LIMIT, &var_line_limit, 512, 0,
	VAR_HASH_QUEUE_DEPTH, DEF_HASH_QUEUE_DEPTH, &var_hash_queue_depth, 1, 0,
	VAR_FORK_TRIES, DEF_FORK_TRIES, &var_fork_tries, 1, 0,
	VAR_FLOCK_TRIES, DEF_FLOCK_TRIES, &var_flock_tries, 1, 0,
	VAR_DEBUG_PEER_LEVEL, DEF_DEBUG_PEER_LEVEL, &var_debug_peer_level, 1, 0,
	VAR_FAULT_INJ_CODE, DEF_FAULT_INJ_CODE, &var_fault_inj_code, 0, 0,
	VAR_DB_CREATE_BUF, DEF_DB_CREATE_BUF, &var_db_create_buf, 1, 0,
	VAR_DB_READ_BUF, DEF_DB_READ_BUF, &var_db_read_buf, 1, 0,
	VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0,
	VAR_TOKEN_LIMIT, DEF_TOKEN_LIMIT, &var_token_limit, 1, 0,
	VAR_MIME_MAXDEPTH, DEF_MIME_MAXDEPTH, &var_mime_maxdepth, 1, 0,
	VAR_MIME_BOUND_LEN, DEF_MIME_BOUND_LEN, &var_mime_bound_len, 1, 0,
	VAR_DELAY_MAX_RES, DEF_DELAY_MAX_RES, &var_delay_max_res, MIN_DELAY_MAX_RES, MAX_DELAY_MAX_RES,
	VAR_INET_WINDOW, DEF_INET_WINDOW, &var_inet_windowsize, 0, 0,
	0,
    };
    static const CONFIG_LONG_TABLE long_defaults[] = {
	VAR_MESSAGE_LIMIT, DEF_MESSAGE_LIMIT, &var_message_limit, 0, 0,
	VAR_LMDB_MAP_SIZE, DEF_LMDB_MAP_SIZE, &var_lmdb_map_size, 1, 0,
	0,
    };
    static const CONFIG_TIME_TABLE time_defaults[] = {
	VAR_EVENT_DRAIN, DEF_EVENT_DRAIN, &var_event_drain, 1, 0,
	VAR_MAX_IDLE, DEF_MAX_IDLE, &var_idle_limit, 1, 0,
	VAR_IPC_TIMEOUT, DEF_IPC_TIMEOUT, &var_ipc_timeout, 1, 0,
	VAR_IPC_IDLE, DEF_IPC_IDLE, &var_ipc_idle_limit, 1, 0,
	VAR_IPC_TTL, DEF_IPC_TTL, &var_ipc_ttl_limit, 1, 0,
	VAR_TRIGGER_TIMEOUT, DEF_TRIGGER_TIMEOUT, &var_trigger_timeout, 1, 0,
	VAR_FORK_DELAY, DEF_FORK_DELAY, &var_fork_delay, 1, 0,
	VAR_FLOCK_DELAY, DEF_FLOCK_DELAY, &var_flock_delay, 1, 0,
	VAR_FLOCK_STALE, DEF_FLOCK_STALE, &var_flock_stale, 1, 0,
	VAR_DAEMON_TIMEOUT, DEF_DAEMON_TIMEOUT, &var_daemon_timeout, 1, 0,
	VAR_IN_FLOW_DELAY, DEF_IN_FLOW_DELAY, &var_in_flow_delay, 0, 10,
	0,
    };
    static const CONFIG_BOOL_TABLE bool_defaults[] = {
	VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns,
	VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce,
	VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special,
	VAR_STRICT_8BITMIME, DEF_STRICT_8BITMIME, &var_strict_8bitmime,
	VAR_STRICT_7BIT_HDRS, DEF_STRICT_7BIT_HDRS, &var_strict_7bit_hdrs,
	VAR_STRICT_8BIT_BODY, DEF_STRICT_8BIT_BODY, &var_strict_8bit_body,
	VAR_STRICT_ENCODING, DEF_STRICT_ENCODING, &var_strict_encoding,
	VAR_DISABLE_MIME_INPUT, DEF_DISABLE_MIME_INPUT, &var_disable_mime_input,
	VAR_DISABLE_MIME_OCONV, DEF_DISABLE_MIME_OCONV, &var_disable_mime_oconv,
	VAR_VERIFY_NEG_CACHE, DEF_VERIFY_NEG_CACHE, &var_verify_neg_cache,
	VAR_OLDLOG_COMPAT, DEF_OLDLOG_COMPAT, &var_oldlog_compat,
	VAR_HELPFUL_WARNINGS, DEF_HELPFUL_WARNINGS, &var_helpful_warnings,
	VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid,
	VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable,
	VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids,
	0,
    };
    const char *cp;
    INET_PROTO_INFO *proto_info;

    /*
     * Extract syslog_facility early, so that from here on all errors are
     * logged with the proper facility.
     */
    get_mail_conf_str_table(first_str_defaults);

    if (!msg_syslog_facility(var_syslog_facility))
	msg_fatal("file %s/%s: parameter %s: unrecognized value: %s",
		  var_config_dir, MAIN_CONF_FILE,
		  VAR_SYSLOG_FACILITY, var_syslog_facility);

    /*
     * Should daemons terminate after table open error, or should they
     * continue execution with reduced functionality?
     */
    get_mail_conf_bool_table(first_bool_defaults);
    if (var_daemon_open_fatal)
	dict_allow_surrogate = 0;

    /*
     * What protocols should we attempt to support? The result is stored in
     * the global inet_proto_table variable.
     */
    proto_info = inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);

    /*
     * Variables whose defaults are determined at runtime. Some sites use
     * short hostnames in the host table; some sites name their system after
     * the domain.
     */
    get_mail_conf_str_fn_table(function_str_defaults);
    if (!valid_hostname(var_myhostname, DO_GRIPE))
	msg_fatal("file %s/%s: parameter %s: bad parameter value: %s",
		  var_config_dir, MAIN_CONF_FILE,
		  VAR_MYHOSTNAME, var_myhostname);
    if (!valid_hostname(var_mydomain, DO_GRIPE))
	msg_fatal("file %s/%s: parameter %s: bad parameter value: %s",
		  var_config_dir, MAIN_CONF_FILE,
		  VAR_MYDOMAIN, var_mydomain);

    /*
     * Variables that are needed by almost every program.
     * 
     * XXX Reading the myorigin value from file is originally a Debian Linux
     * feature. This code is not enabled by default because of problems: 1)
     * it re-implements its own parameter syntax checks, and 2) it does not
     * implement $name expansions.
     */
    get_mail_conf_str_table(other_str_defaults);
#ifdef MYORIGIN_FROM_FILE
    if (*var_myorigin == '/') {
	char   *origin = read_param_from_file(var_myorigin);

	if (*origin == 0)
	    msg_fatal("%s file %s is empty", VAR_MYORIGIN, var_myorigin);
	myfree(var_myorigin);			/* FIX 20070501 */
	var_myorigin = origin;
    }
#endif
    get_mail_conf_int_table(other_int_defaults);
    get_mail_conf_long_table(long_defaults);
    get_mail_conf_bool_table(bool_defaults);
    get_mail_conf_time_table(time_defaults);
    check_default_privs();
    check_mail_owner();
    check_sgid_group();
    check_overlap();
#ifdef HAS_DB
    dict_db_cache_size = var_db_read_buf;
#endif
#ifdef HAS_LMDB
    dict_lmdb_map_size = var_lmdb_map_size;
#endif
    inet_windowsize = var_inet_windowsize;

    /*
     * Variables whose defaults are determined at runtime, after other
     * variables have been set. This dependency is admittedly a bit tricky.
     * XXX Perhaps we should just register variables, and let the evaluator
     * figure out in what order to evaluate things.
     */
    get_mail_conf_str_fn_table(function_str_defaults_2);

    /*
     * FIX 200412 The IPv6 patch did not call own_inet_addr_list() before
     * entering the chroot jail on Linux IPv6 systems. Linux has the IPv6
     * interface list in /proc, which is not available after chrooting.
     */
    (void) own_inet_addr_list();

    /*
     * The PID variable cannot be set from the configuration file!!
     */
    set_mail_conf_int(VAR_PID, var_pid = getpid());

    /*
     * Neither can the start time variable. It isn't even visible.
     */
    time(&var_starttime);

    /*
     * Export the syslog name so children can inherit and use it before they
     * have initialized.
     */
    if ((cp = safe_getenv(CONF_ENV_LOGTAG)) == 0
	|| strcmp(cp, var_syslog_name) != 0)
	if (setenv(CONF_ENV_LOGTAG, var_syslog_name, 1) < 0)
	    msg_fatal("setenv %s %s: %m", CONF_ENV_LOGTAG, var_syslog_name);

    /*
     * I have seen this happen just too often.
     */
    if (strcasecmp(var_myhostname, var_relayhost) == 0)
	msg_fatal("%s and %s parameter settings must not be identical: %s",
		  VAR_MYHOSTNAME, VAR_RELAYHOST, var_myhostname);

    /*
     * XXX These should be caught by a proper parameter parsing algorithm.
     */
    if (var_myorigin[strcspn(var_myorigin, ", \t\r\n")])
	msg_fatal("%s parameter setting must not contain multiple values: %s",
		  VAR_MYORIGIN, var_myorigin);

    if (var_relayhost[strcspn(var_relayhost, ", \t\r\n")])
	msg_fatal("%s parameter setting must not contain multiple values: %s",
		  VAR_RELAYHOST, var_relayhost);

    /*
     * One more sanity check.
     */
    if ((cp = verp_delims_verify(var_verp_delims)) != 0)
	msg_fatal("file %s/%s: parameters %s and %s: %s",
		  var_config_dir, MAIN_CONF_FILE,
		  VAR_VERP_DELIMS, VAR_VERP_FILTER, cp);
}
コード例 #18
0
ファイル: util.c プロジェクト: 0xffea/illumos-gate
const char *
iffile_to_hostname(const char *path)
{
	FILE		*fp;
	static char	ifline[IFLINE_MAX];

	fp = fopen(path, "r");
	if (fp == NULL)
		return (NULL);

	/*
	 * /etc/hostname.<if> may contain multiple ifconfig commands, but each
	 * such command is on a separate line (see the "while read ifcmds" code
	 * in /etc/init.d/inetinit).  Thus we will read the file a line at a
	 * time, searching for a line of the form
	 *
	 * [ ^I]*inet[ ^I]+hostname[\n]*\0
	 *
	 * extract the host name from it, and check it for validity.
	 */
	while (fgets(ifline, sizeof (ifline), fp) != NULL) {
		char *p;

		if ((p = strstr(ifline, "inet")) != NULL) {
			if ((p != ifline) && !isspace(p[-1])) {
				(void) fclose(fp);
				return (NULL);
			}
			p += 4;	/* skip over "inet" and expect spaces or tabs */
			if ((*p == '\n') || (*p == '\0')) {
				(void) fclose(fp);
				return (NULL);
			}
			if (isspace(*p)) {
				char *nlptr;

				/* no need to read more of the file */
				(void) fclose(fp);

				while (isspace(*p))
					p++;
				if ((nlptr = strrchr(p, '\n')) != NULL)
					*nlptr = '\0';
				if (strlen(p) > MAXHOSTNAMELEN) {
					dhcpmsg(MSG_WARNING,
					    "iffile_to_hostname:"
					    " host name too long");
					return (NULL);
				}
				if (valid_hostname(p)) {
					return (p);
				} else {
					dhcpmsg(MSG_WARNING,
					    "iffile_to_hostname:"
					    " host name not valid");
					return (NULL);
				}
			} else {
				(void) fclose(fp);
				return (NULL);
			}
		}
	}

	(void) fclose(fp);
	return (NULL);
}
コード例 #19
0
ファイル: postscreen_dnsbl.c プロジェクト: DabeDotCom/postfix
static void psc_dnsbl_add_site(const char *site)
{
    const char *myname = "psc_dnsbl_add_site";
    char   *saved_site = mystrdup(site);
    VSTRING *byte_codes = 0;
    PSC_DNSBL_HEAD *head;
    PSC_DNSBL_SITE *new_site;
    char    junk;
    const char *weight_text;
    char   *pattern_text;
    int     weight;
    HTABLE_INFO *ht;
    char   *parse_err;

    /*
     * Parse the required DNSBL domain name, the optional reply filter and
     * the optional reply weight factor.
     */
#define DO_GRIPE	1

    /* Negative weight means whitelist. */
    if ((weight_text = split_at(saved_site, '*')) != 0) {
	if (sscanf(weight_text, "%d%c", &weight, &junk) != 1)
	    msg_fatal("bad DNSBL weight factor \"%s\" in \"%s\"",
		      weight_text, site);
    } else {
	weight = 1;
    }
    /* Reply filter. */
    if ((pattern_text = split_at(saved_site, '=')) != 0) {
	byte_codes = vstring_alloc(100);
	if ((parse_err = ip_match_parse(byte_codes, pattern_text)) != 0)
	    msg_fatal("bad DNSBL filter syntax: %s", parse_err);
    }
    if (valid_hostname(saved_site, DO_GRIPE) == 0)
	msg_fatal("bad DNSBL domain name \"%s\" in \"%s\"",
		  saved_site, site);

    if (msg_verbose > 1)
	msg_info("%s: \"%s\" -> domain=\"%s\" pattern=\"%s\" weight=%d",
		 myname, site, saved_site, pattern_text ? pattern_text :
		 "null", weight);

    /*
     * Look up or create the (filter, weight) list head for this DNSBL domain
     * name.
     */
    if ((head = (PSC_DNSBL_HEAD *)
	 htable_find(dnsbl_site_cache, saved_site)) == 0) {
	head = (PSC_DNSBL_HEAD *) mymalloc(sizeof(*head));
	ht = htable_enter(dnsbl_site_cache, saved_site, (void *) head);
	/* Translate the DNSBL name into a safe name if available. */
	if (psc_dnsbl_reply == 0
	 || (head->safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0)
	    head->safe_dnsbl = ht->key;
	if (psc_dnsbl_reply && psc_dnsbl_reply->error)
	    msg_fatal("%s:%s lookup error", psc_dnsbl_reply->type,
		      psc_dnsbl_reply->name);
	head->first = 0;
    }

    /*
     * Append the new (filter, weight) node to the list for this DNSBL domain
     * name.
     */
    new_site = (PSC_DNSBL_SITE *) mymalloc(sizeof(*new_site));
    new_site->filter = (pattern_text ? mystrdup(pattern_text) : 0);
    new_site->byte_codes = (byte_codes ? ip_match_save(byte_codes) : 0);
    new_site->weight = weight;
    new_site->next = head->first;
    head->first = new_site;

    myfree(saved_site);
    if (byte_codes)
	vstring_free(byte_codes);
}
コード例 #20
0
ファイル: resolve.c プロジェクト: TonyChengTW/Rmail
static void resolve_addr(RES_CONTEXT *rp, char *addr,
			         VSTRING *channel, VSTRING *nexthop,
			         VSTRING *nextrcpt, int *flags)
{
    char   *myname = "resolve_addr";
    VSTRING *addr_buf = vstring_alloc(100);
    TOK822 *tree = 0;
    TOK822 *saved_domain = 0;
    TOK822 *domain = 0;
    char   *destination;
    const char *blame = 0;
    const char *rcpt_domain;
    int     addr_len;
    int     loop_count;
    int     loop_max;
    char   *local;
    char   *oper;
    char   *junk;

    *flags = 0;
    vstring_strcpy(channel, "CHANNEL NOT UPDATED");
    vstring_strcpy(nexthop, "NEXTHOP NOT UPDATED");
    vstring_strcpy(nextrcpt, "NEXTRCPT NOT UPDATED");

    /*
     * The address is in internalized (unquoted) form.
     * 
     * In an ideal world we would parse the externalized address form as given
     * to us by the sender.
     * 
     * However, in the real world we have to look for routing characters like
     * %@! in the address local-part, even when that information is quoted
     * due to the presence of special characters or whitespace. Although
     * technically incorrect, this is needed to stop user@domain@domain relay
     * attempts when forwarding mail to a Sendmail MX host.
     * 
     * This suggests that we parse the address in internalized (unquoted) form.
     * Unfortunately, if we do that, the unparser generates incorrect white
     * space between adjacent non-operator tokens. Example: ``first last''
     * needs white space, but ``stuff[stuff]'' does not. This is is not a
     * problem when unparsing the result from parsing externalized forms,
     * because the parser/unparser were designed for valid externalized forms
     * where ``stuff[stuff]'' does not happen.
     * 
     * As a workaround we start with the quoted form and then dequote the
     * local-part only where needed. This will do the right thing in most
     * (but not all) cases.
     */
    addr_len = strlen(addr);
    quote_822_local(addr_buf, addr);
    tree = tok822_scan_addr(vstring_str(addr_buf));

    /*
     * Let the optimizer replace multiple expansions of this macro by a GOTO
     * to a single instance.
     */
#define FREE_MEMORY_AND_RETURN { \
	if (saved_domain) \
	    tok822_free_tree(saved_domain); \
	if(tree) \
	    tok822_free_tree(tree); \
	if (addr_buf) \
	    vstring_free(addr_buf); \
	return; \
    }

    /*
     * Preliminary resolver: strip off all instances of the local domain.
     * Terminate when no destination domain is left over, or when the
     * destination domain is remote.
     * 
     * XXX To whom it may concern. If you change the resolver loop below, or
     * quote_822_local.c, or tok822_parse.c, be sure to re-run the tests
     * under "make resolve_clnt_test" in the global directory.
     */
#define RESOLVE_LOCAL(domain) \
    resolve_local(STR(tok822_internalize(addr_buf, domain, TOK822_STR_DEFL)))

    dict_errno = 0;

    for (loop_count = 0, loop_max = addr_len + 100; /* void */ ; loop_count++) {

	/*
	 * Grr. resolve_local() table lookups may fail. It may be OK for
	 * local file lookup code to abort upon failure, but with
	 * network-based tables it is preferable to return an error
	 * indication to the requestor.
	 */
	if (dict_errno) {
	    *flags |= RESOLVE_FLAG_FAIL;
	    FREE_MEMORY_AND_RETURN;
	}

	/*
	 * XXX Should never happen, but if this happens with some
	 * pathological address, then that is not sufficient reason to
	 * disrupt the operation of an MTA.
	 */
	if (loop_count > loop_max) {
	    msg_warn("resolve_addr: <%s>: giving up after %d iterations",
		     addr, loop_count);
	    break;
	}

	/*
	 * Strip trailing dot at end of domain, but not dot-dot or at-dot.
	 * This merely makes diagnostics more accurate by leaving bogus
	 * addresses alone.
	 */
	if (tree->tail
	    && tree->tail->type == '.'
	    && tok822_rfind_type(tree->tail, '@') != 0
	    && tree->tail->prev->type != '.'
	    && tree->tail->prev->type != '@')
	    tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));

	/*
	 * Strip trailing @.
	 */
	if (var_resolve_nulldom
	    && tree->tail
	    && tree->tail->type == '@')
	    tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));

	/*
	 * Strip (and save) @domain if local.
	 */
	if ((domain = tok822_rfind_type(tree->tail, '@')) != 0) {
	    if (domain->next && RESOLVE_LOCAL(domain->next) == 0)
		break;
	    tok822_sub_keep_before(tree, domain);
	    if (saved_domain)
		tok822_free_tree(saved_domain);
	    saved_domain = domain;
	    domain = 0;				/* safety for future change */
	}

	/*
	 * After stripping the local domain, if any, replace foo%bar by
	 * foo@bar, site!user by user@site, rewrite to canonical form, and
	 * retry.
	 */
	if (tok822_rfind_type(tree->tail, '@')
	    || (var_swap_bangpath && tok822_rfind_type(tree->tail, '!'))
	    || (var_percent_hack && tok822_rfind_type(tree->tail, '%'))) {
	    rewrite_tree(REWRITE_CANON, tree);
	    continue;
	}

	/*
	 * If the local-part is a quoted string, crack it open when we're
	 * permitted to do so and look for routing operators. This is
	 * technically incorrect, but is needed to stop relaying problems.
	 * 
	 * XXX Do another feeble attempt to keep local-part info quoted.
	 */
	if (var_resolve_dequoted
	    && tree->head && tree->head == tree->tail
	    && tree->head->type == TOK822_QSTRING
	    && ((oper = strrchr(local = STR(tree->head->vstr), '@')) != 0
		|| (var_percent_hack && (oper = strrchr(local, '%')) != 0)
	     || (var_swap_bangpath && (oper = strrchr(local, '!')) != 0))) {
	    if (*oper == '%')
		*oper = '@';
	    tok822_internalize(addr_buf, tree->head, TOK822_STR_DEFL);
	    if (*oper == '@') {
		junk = mystrdup(STR(addr_buf));
		quote_822_local(addr_buf, junk);
		myfree(junk);
	    }
	    tok822_free(tree->head);
	    tree->head = tok822_scan(STR(addr_buf), &tree->tail);
	    rewrite_tree(REWRITE_CANON, tree);
	    continue;
	}

	/*
	 * An empty local-part or an empty quoted string local-part becomes
	 * the local MAILER-DAEMON, for consistency with our own From:
	 * message headers.
	 */
	if (tree->head && tree->head == tree->tail
	    && tree->head->type == TOK822_QSTRING
	    && VSTRING_LEN(tree->head->vstr) == 0) {
	    tok822_free(tree->head);
	    tree->head = 0;
	}
	/* XXX must be localpart only, not user@domain form. */
	if (tree->head == 0)
	    tree->head = tok822_scan(var_empty_addr, &tree->tail);

	/*
	 * We're done. There are no domains left to strip off the address,
	 * and all null local-part information is sanitized.
	 */
	domain = 0;
	break;
    }

    vstring_free(addr_buf);
    addr_buf = 0;

    /*
     * Make sure the resolved envelope recipient has the user@domain form. If
     * no domain was specified in the address, assume the local machine. See
     * above for what happens with an empty address.
     */
    if (domain == 0) {
	if (saved_domain) {
	    tok822_sub_append(tree, saved_domain);
	    saved_domain = 0;
	} else {
	    tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
	    tok822_sub_append(tree, tok822_scan(var_myhostname, (TOK822 **) 0));
	}
    }

    /*
     * Transform the recipient address back to internal form.
     * 
     * XXX This may produce incorrect results if we cracked open a quoted
     * local-part with routing operators; see discussion above at the top of
     * the big loop.
     */
    tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
    rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
    if (*rcpt_domain == '[' ? !valid_hostliteral(rcpt_domain, DONT_GRIPE) :
	(!valid_hostname(rcpt_domain, DONT_GRIPE)
	 || valid_hostaddr(rcpt_domain, DONT_GRIPE)))
	*flags |= RESOLVE_FLAG_ERROR;
    tok822_free_tree(tree);
    tree = 0;

    /*
     * XXX Short-cut invalid address forms.
     */
    if (*flags & RESOLVE_FLAG_ERROR) {
	*flags |= RESOLVE_CLASS_DEFAULT;
	FREE_MEMORY_AND_RETURN;
    }

    /*
     * Recognize routing operators in the local-part, even when we do not
     * recognize ! or % as valid routing operators locally. This is needed to
     * prevent backup MX hosts from relaying third-party destinations through
     * primary MX hosts, otherwise the backup host could end up on black
     * lists. Ignore local swap_bangpath and percent_hack settings because we
     * can't know how the next MX host is set up.
     */
    if (strcmp(STR(nextrcpt) + strcspn(STR(nextrcpt), "@!%") + 1, rcpt_domain))
	*flags |= RESOLVE_FLAG_ROUTED;

    /*
     * With local, virtual, relay, or other non-local destinations, give the
     * highest precedence to transport associated nexthop information.
     * 
     * Otherwise, with relay or other non-local destinations, the relayhost
     * setting overrides the destination domain name.
     * 
     * XXX Nag if the recipient domain is listed in multiple domain lists. The
     * result is implementation defined, and may break when internals change.
     * 
     * For now, we distinguish only a fixed number of address classes.
     * Eventually this may become extensible, so that new classes can be
     * configured with their own domain list, delivery transport, and
     * recipient table.
     */
#define STREQ(x,y) (strcmp((x), (y)) == 0)

    dict_errno = 0;
    if (domain != 0) {

	/*
	 * Virtual alias domain.
	 */
	if (virt_alias_doms
	    && string_list_match(virt_alias_doms, rcpt_domain)) {
	    if (var_helpful_warnings) {
		if (virt_mailbox_doms
		    && string_list_match(virt_mailbox_doms, rcpt_domain))
		    msg_warn("do not list domain %s in BOTH %s and %s",
			     rcpt_domain, VAR_VIRT_ALIAS_DOMS,
			     VAR_VIRT_MAILBOX_DOMS);
		if (relay_domains
		    && domain_list_match(relay_domains, rcpt_domain))
		    msg_warn("do not list domain %s in BOTH %s and %s",
			     rcpt_domain, VAR_VIRT_ALIAS_DOMS,
			     VAR_RELAY_DOMAINS);
#if 0
		if (strcasecmp(rcpt_domain, var_myorigin) == 0)
		    msg_warn("do not list $%s (%s) in %s",
			   VAR_MYORIGIN, var_myorigin, VAR_VIRT_ALIAS_DOMS);
#endif
	    }
	    vstring_strcpy(channel, MAIL_SERVICE_ERROR);
	    vstring_sprintf(nexthop, "User unknown%s",
			    var_show_unk_rcpt_table ?
			    " in virtual alias table" : "");
	    *flags |= RESOLVE_CLASS_ALIAS;
	} else if (dict_errno != 0) {
	    msg_warn("%s lookup failure", VAR_VIRT_ALIAS_DOMS);
	    *flags |= RESOLVE_FLAG_FAIL;
	    FREE_MEMORY_AND_RETURN;
	}

	/*
	 * Virtual mailbox domain.
	 */
	else if (virt_mailbox_doms
		 && string_list_match(virt_mailbox_doms, rcpt_domain)) {
	    if (var_helpful_warnings) {
		if (relay_domains
		    && domain_list_match(relay_domains, rcpt_domain))
		    msg_warn("do not list domain %s in BOTH %s and %s",
			     rcpt_domain, VAR_VIRT_MAILBOX_DOMS,
			     VAR_RELAY_DOMAINS);
	    }
	    vstring_strcpy(channel, RES_PARAM_VALUE(rp->virt_transport));
	    vstring_strcpy(nexthop, rcpt_domain);
	    blame = rp->virt_transport_name;
	    *flags |= RESOLVE_CLASS_VIRTUAL;
	} else if (dict_errno != 0) {
	    msg_warn("%s lookup failure", VAR_VIRT_MAILBOX_DOMS);
	    *flags |= RESOLVE_FLAG_FAIL;
	    FREE_MEMORY_AND_RETURN;
	} else {

	    /*
	     * Off-host relay destination.
	     */
	    if (relay_domains
		&& domain_list_match(relay_domains, rcpt_domain)) {
		vstring_strcpy(channel, RES_PARAM_VALUE(rp->relay_transport));
		blame = rp->relay_transport_name;
		*flags |= RESOLVE_CLASS_RELAY;
	    } else if (dict_errno != 0) {
		msg_warn("%s lookup failure", VAR_RELAY_DOMAINS);
		*flags |= RESOLVE_FLAG_FAIL;
		FREE_MEMORY_AND_RETURN;
	    }

	    /*
	     * Other off-host destination.
	     */
	    else {
		vstring_strcpy(channel, RES_PARAM_VALUE(rp->def_transport));
		blame = rp->def_transport_name;
		*flags |= RESOLVE_CLASS_DEFAULT;
	    }

	    /*
	     * With off-host delivery, relayhost overrides recipient domain.
	     */
	    if (*RES_PARAM_VALUE(rp->relayhost))
		vstring_strcpy(nexthop, RES_PARAM_VALUE(rp->relayhost));
	    else
		vstring_strcpy(nexthop, rcpt_domain);
	}
    }

    /*
     * Local delivery.
     * 
     * XXX Nag if the domain is listed in multiple domain lists. The effect is
     * implementation defined, and may break when internals change.
     */
    else {
	if (var_helpful_warnings) {
	    if (virt_alias_doms
		&& string_list_match(virt_alias_doms, rcpt_domain))
		msg_warn("do not list domain %s in BOTH %s and %s",
			 rcpt_domain, VAR_MYDEST, VAR_VIRT_ALIAS_DOMS);
	    if (virt_mailbox_doms
		&& string_list_match(virt_mailbox_doms, rcpt_domain))
		msg_warn("do not list domain %s in BOTH %s and %s",
			 rcpt_domain, VAR_MYDEST, VAR_VIRT_MAILBOX_DOMS);
	}
	vstring_strcpy(channel, RES_PARAM_VALUE(rp->local_transport));
	vstring_strcpy(nexthop, rcpt_domain);
	blame = rp->local_transport_name;
	*flags |= RESOLVE_CLASS_LOCAL;
    }

    /*
     * An explicit main.cf transport:nexthop setting overrides the nexthop.
     * 
     * XXX We depend on this mechanism to enforce per-recipient concurrencies
     * for local recipients. With "local_transport = local:$myhostname" we
     * force mail for any domain in $mydestination/${proxy,inet}_interfaces
     * to share the same queue.
     */
    if ((destination = split_at(STR(channel), ':')) != 0 && *destination)
	vstring_strcpy(nexthop, destination);

    /*
     * Sanity checks.
     */
    if (*STR(channel) == 0) {
	if (blame == 0)
	    msg_panic("%s: null blame", myname);
	msg_warn("file %s/%s: parameter %s: null transport is not allowed",
		 var_config_dir, MAIN_CONF_FILE, blame);
	*flags |= RESOLVE_FLAG_FAIL;
	FREE_MEMORY_AND_RETURN;
    }
    if (*STR(nexthop) == 0)
	msg_panic("%s: null nexthop", myname);

    /*
     * The transport map can selectively override any transport and/or
     * nexthop host info that is set up above. Unfortunately, the syntax for
     * nexthop information is transport specific. We therefore need sane and
     * intuitive semantics for transport map entries that specify a channel
     * but no nexthop.
     * 
     * With non-error transports, the initial nexthop information is the
     * recipient domain. However, specific main.cf transport definitions may
     * specify a transport-specific destination, such as a host + TCP socket,
     * or the pathname of a UNIX-domain socket. With less precedence than
     * main.cf transport definitions, a main.cf relayhost definition may also
     * override nexthop information for off-host deliveries.
     * 
     * With the error transport, the nexthop information is free text that
     * specifies the reason for non-delivery.
     * 
     * Because nexthop syntax is transport specific we reset the nexthop
     * information to the recipient domain when the transport table specifies
     * a transport without also specifying the nexthop information.
     * 
     * Subtle note: reset nexthop even when the transport table does not change
     * the transport. Otherwise it is hard to get rid of main.cf specified
     * nexthop information.
     * 
     * XXX Don't override the virtual alias class (error:User unknown) result.
     */
    if (rp->transport_info && !(*flags & RESOLVE_CLASS_ALIAS)) {
	if (transport_lookup(rp->transport_info, STR(nextrcpt),
			     rcpt_domain, channel, nexthop) == 0
	    && dict_errno != 0) {
	    msg_warn("%s lookup failure", rp->transport_maps_name);
	    *flags |= RESOLVE_FLAG_FAIL;
	    FREE_MEMORY_AND_RETURN;
	}
    }

    /*
     * Bounce recipients that have moved, regardless of domain address class.
     * We do this last, in anticipation of transport maps that can override
     * the recipient address.
     * 
     * The downside of not doing this in delivery agents is that this table has
     * no effect on local alias expansion results. Such mail will have to
     * make almost an entire iteration through the mail system.
     */
#define IGNORE_ADDR_EXTENSION   ((char **) 0)

    if (relocated_maps != 0) {
	const char *newloc;

	if ((newloc = mail_addr_find(relocated_maps, STR(nextrcpt),
				     IGNORE_ADDR_EXTENSION)) != 0) {
	    vstring_strcpy(channel, MAIL_SERVICE_ERROR);
	    vstring_sprintf(nexthop, "User has moved to %s", newloc);
	} else if (dict_errno != 0) {
	    msg_warn("%s lookup failure", VAR_RELOCATED_MAPS);
	    *flags |= RESOLVE_FLAG_FAIL;
	    FREE_MEMORY_AND_RETURN;
	}
    }

    /*
     * Clean up.
     */
    FREE_MEMORY_AND_RETURN;
}
コード例 #21
0
int     main(int argc, char **argv)
{
    SESSION *session;
    char   *host;
    char   *port;
    char   *path;
    int     path_len;
    int     sessions = 1;
    int     ch;
    ssize_t len;
    int     n;
    int     i;
    char   *buf;
    const char *parse_err;
    struct addrinfo *res;
    int     aierr;
    const char *protocols = INET_PROTO_NAME_ALL;
    INET_PROTO_INFO *proto_info;

    /*
     * Fingerprint executables and core dumps.
     */
    MAIL_VERSION_STAMP_ALLOCATE;

    signal(SIGPIPE, SIG_IGN);
    msg_vstream_init(argv[0], VSTREAM_ERR);

    /*
     * Parse JCL.
     */
    while ((ch = GETOPT(argc, argv, "46cC:f:l:m:M:r:R:s:t:vw:")) > 0) {
	switch (ch) {
	case '4':
	    protocols = INET_PROTO_NAME_IPV4;
	    break;
	case '6':
	    protocols = INET_PROTO_NAME_IPV6;
	    break;
	case 'c':
	    count++;
	    break;
	case 'C':
	    if ((connect_count = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 'f':
	    sender = optarg;
	    break;
	case 'l':
	    if ((message_length = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 'm':
	    if ((message_count = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 'M':
	    if (*optarg == '[') {
		if (!valid_mailhost_literal(optarg, DO_GRIPE))
		    msg_fatal("bad address literal: %s", optarg);
	    } else {
		if (!valid_hostname(optarg, DO_GRIPE))
		    msg_fatal("bad hostname: %s", optarg);
	    }
	    var_myhostname = optarg;
	    break;
	case 'r':
	    if ((recipients = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 'R':
	    if (fixed_delay > 0 || (random_delay = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 's':
	    if ((sessions = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	case 't':
	    recipient = optarg;
	    break;
	case 'v':
	    msg_verbose++;
	    break;
	case 'w':
	    if (random_delay > 0 || (fixed_delay = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	default:
	    usage(argv[0]);
	}
    }
    if (argc - optind != 1)
	usage(argv[0]);

    if (random_delay > 0)
	srand(getpid());

    /*
     * Translate endpoint address to internal form.
     */
    proto_info = inet_proto_init("protocols", protocols);
    if (strncmp(argv[optind], "unix:", 5) == 0) {
	path = argv[optind] + 5;
	path_len = strlen(path);
	if (path_len >= (int) sizeof(sun.sun_path))
	    msg_fatal("unix-domain name too long: %s", path);
	memset((char *) &sun, 0, sizeof(sun));
	sun.sun_family = AF_UNIX;
#ifdef HAS_SUN_LEN
	sun.sun_len = path_len + 1;
#endif
	memcpy(sun.sun_path, path, path_len);
	sa = (struct sockaddr *) & sun;
	sa_length = sizeof(sun);
    } else {
	if (strncmp(argv[optind], "inet:", 5) == 0)
	    argv[optind] += 5;
	buf = mystrdup(argv[optind]);
	if ((parse_err = host_port(buf, &host, (char *) 0, &port, "628")) != 0)
	    msg_fatal("%s: %s", argv[optind], parse_err);
	if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res)) != 0)
	    msg_fatal("%s: %s", argv[optind], MAI_STRERROR(aierr));
	myfree(buf);
	sa = (struct sockaddr *) & ss;
	if (res->ai_addrlen > sizeof(ss))
	    msg_fatal("address length %d > buffer length %d",
		      (int) res->ai_addrlen, (int) sizeof(ss));
	memcpy((char *) sa, res->ai_addr, res->ai_addrlen);
	sa_length = res->ai_addrlen;
#ifdef HAS_SA_LEN
	sa->sa_len = sa_length;
#endif
	freeaddrinfo(res);
    }

    /*
     * Allocate space for temporary buffer.
     */
    buffer = vstring_alloc(100);

    /*
     * Make sure we have sender and recipient addresses.
     */
    if (var_myhostname == 0)
	var_myhostname = get_hostname();
    if (sender == 0 || recipient == 0) {
	vstring_sprintf(buffer, "foo@%s", var_myhostname);
	defaddr = mystrdup(vstring_str(buffer));
	if (sender == 0)
	    sender = defaddr;
	if (recipient == 0)
	    recipient = defaddr;
    }

    /*
     * Prepare some results that may be used multiple times: the message
     * content netstring, the sender netstring, and the recipient netstrings.
     */
    mydate = mail_date(time((time_t *) 0));
    mypid = getpid();

    message_buffer = vstring_alloc(message_length + 200);
    vstring_sprintf(buffer,
		  "From: <%s>\nTo: <%s>\nDate: %s\nMessage-Id: <%d@%s>\n\n",
		    sender, recipient, mydate, mypid, var_myhostname);
    for (n = 1; LEN(buffer) < message_length; n++) {
	for (i = 0; i < n && i < 79; i++)
	    VSTRING_ADDCH(buffer, 'X');
	VSTRING_ADDCH(buffer, '\n');
    }
    STR(buffer)[message_length - 1] = '\n';
    netstring_memcpy(message_buffer, STR(buffer), message_length);

    len = strlen(sender);
    sender_buffer = vstring_alloc(len);
    netstring_memcpy(sender_buffer, sender, len);

    if (recipients == 1) {
	len = strlen(recipient);
	recipient_buffer = vstring_alloc(len);
	netstring_memcpy(recipient_buffer, recipient, len);
    } else {
	recipient_buffer = vstring_alloc(100);
	for (n = 0; n < recipients; n++) {
	    vstring_sprintf(buffer, "%d%s", n, recipient);
	    netstring_memcat(recipient_buffer, STR(buffer), LEN(buffer));
	}
    }

    /*
     * Start sessions.
     */
    while (sessions-- > 0) {
	session = (SESSION *) mymalloc(sizeof(*session));
	session->stream = 0;
	session->xfer_count = 0;
	session->connect_count = connect_count;
	session->next = 0;
	session_count++;
	startup(session);
    }
    for (;;) {
	event_loop(-1);
	if (session_count <= 0 && message_count <= 0) {
	    if (count) {
		VSTREAM_PUTC('\n', VSTREAM_OUT);
		vstream_fflush(VSTREAM_OUT);
	    }
	    exit(0);
	}
    }
}
コード例 #22
0
ファイル: m_svsmode.c プロジェクト: nask0/ircd-hybrid
/*! \brief SVSMODE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = nickname
 *      - parv[2] = TS
 *      - parv[3] = mode
 *      - parv[4] = optional argument (services account, vhost)
 */
static int
ms_svsmode(struct Client *source_p, int parc, char *parv[])
{
  const struct user_modes *tab = NULL;
  struct Client *target_p = NULL;
  int what = MODE_ADD;
  unsigned int setmodes = 0;
  const char *modes = NULL, *extarg = NULL;
  time_t ts = 0;

  if (!HasFlag(source_p, FLAGS_SERVICE))
    return 0;

  ts     = atol(parv[2]);
  modes  = parv[3];
  extarg = (parc > 4) ? parv[4] : NULL;

  if ((target_p = find_person(source_p, parv[1])) == NULL)
    return 0;

  if (ts && (ts != target_p->tsinfo))
    return 0;

  setmodes = target_p->umodes;

  for (const char *m = modes; *m; ++m)
  {
    switch (*m)
    {
      case '+':
        what = MODE_ADD;
        break;
      case '-':
        what = MODE_DEL;
        break;

      case 'd':
        if (!EmptyString(extarg))
          strlcpy(target_p->account, extarg, sizeof(target_p->account));
        break;

      case 'x':
        if (!EmptyString(extarg) && valid_hostname(extarg))
          user_set_hostmask(target_p, extarg, what);
        break;

      case 'o':
        if (what == MODE_DEL && HasUMode(target_p, UMODE_OPER))
        {
          ClearOper(target_p);
          --Count.oper;

          if (MyConnect(target_p))
          {
            dlink_node *node = NULL;

            detach_conf(target_p, CONF_OPER);
            ClrOFlag(target_p);
            DelUMode(target_p, ConfigGeneral.oper_only_umodes);

            if ((node = dlinkFindDelete(&oper_list, target_p)))
              free_dlink_node(node);
          }
        }

        break;

      case 'i':
        if (what == MODE_ADD && !HasUMode(target_p, UMODE_INVISIBLE))
        {
          AddUMode(target_p, UMODE_INVISIBLE);
          ++Count.invisi;
        }

        if (what == MODE_DEL && HasUMode(target_p, UMODE_INVISIBLE))
        {
          DelUMode(target_p, UMODE_INVISIBLE);
          --Count.invisi;
        }

        break;

      case 'S':  /* Only servers may set +S in a burst */
      case 'W':  /* Only servers may set +W in a burst */
        break;

      default:
        if ((tab = umode_map[(unsigned char)*m]))
        {
          if (what == MODE_ADD)
            AddUMode(target_p, tab->flag);
          else
            DelUMode(target_p, tab->flag);
        }

        break;
    }
  }

  if (extarg)
    sendto_server(source_p, 0, 0, ":%s SVSMODE %s %lu %s %s",
                  source_p->id,
                  target_p->id, (unsigned long)target_p->tsinfo, modes, extarg);
  else
    sendto_server(source_p, 0, 0, ":%s SVSMODE %s %lu %s",
                  source_p->id,
                  target_p->id, (unsigned long)target_p->tsinfo, modes);

  if (MyConnect(target_p) && (setmodes != target_p->umodes))
  {
    char modebuf[IRCD_BUFSIZE] = "";

    send_umode(target_p, target_p, setmodes, modebuf);
  }

  return 0;
}
コード例 #23
0
ファイル: m_webirc.c プロジェクト: nask0/ircd-hybrid
/*! \brief WEBIRC command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = password
 *      - parv[2] = fake username (we ignore this)
 *      - parv[3] = fake hostname
 *      - parv[4] = fake ip
 */
static int
mr_webirc(struct Client *source_p, int parc, char *parv[])
{
  struct MaskItem *conf = NULL;
  struct addrinfo hints, *res;

  assert(MyConnect(source_p));

  if (!valid_hostname(parv[3]))
  {
    sendto_one_notice(source_p, &me, ":WEBIRC: Invalid hostname");
    return 0;
  }

  conf = find_address_conf(source_p->host,
                           IsGotId(source_p) ? source_p->username : "******",
                           &source_p->connection->ip,
                           source_p->connection->aftype, parv[1]);
  if (conf == NULL || !IsConfClient(conf))
    return 0;

  if (!IsConfWebIRC(conf))
  {
    sendto_one_notice(source_p, &me, ":Not a WEBIRC auth {} block");
    return 0;
  }

  if (EmptyString(conf->passwd))
  {
    sendto_one_notice(source_p, &me, ":WEBIRC auth {} blocks must have a password");
    return 0;
  }

  if (!match_conf_password(parv[1], conf))
  {
    sendto_one_notice(source_p, &me, ":WEBIRC password incorrect");
    return 0;
  }

  memset(&hints, 0, sizeof(hints));

  hints.ai_family   = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;

  if (getaddrinfo(parv[4], NULL, &hints, &res))
  {
    sendto_one_notice(source_p, &me, ":Invalid WEBIRC IP %s", parv[4]);
    return 0;
  }

  assert(res);

  memcpy(&source_p->connection->ip, res->ai_addr, res->ai_addrlen);
  source_p->connection->ip.ss_len = res->ai_addrlen;
  source_p->connection->ip.ss.ss_family = res->ai_family;
  source_p->connection->aftype = res->ai_family;
  freeaddrinfo(res);

  strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost));
  strlcpy(source_p->host, parv[3], sizeof(source_p->host));

  /* Check dlines now, k-lines will be checked on registration */
  if ((conf = find_dline_conf(&source_p->connection->ip,
                               source_p->connection->aftype)))
  {
    if (!(conf->type == CONF_EXEMPT))
    {
      exit_client(source_p, "D-lined");
      return 0;
    }
  }

  AddUMode(source_p, UMODE_WEBIRC);
  sendto_one_notice(source_p, &me, ":WEBIRC host/IP set to %s %s",
                    parv[3], parv[4]);
  return 0;
}
コード例 #24
0
ファイル: m_change.c プロジェクト: mdharris/ircd
static void
mo_chghost(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  struct Client *target_p = NULL;

  if (MyClient(source_p) && !IsOperAdmin(source_p))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "CHGHOST");
    return;
  }

  if (EmptyString(parv[2]))
  {
    parv[2] = parv[1];
    target_p = source_p;

    if (!IsClient(target_p))
      return;
  }
  else {
    target_p = find_client(parv[1]);

    if (target_p == NULL || !IsClient(target_p))
    {
      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
                 me.name, source_p->name, parv[1]);
      return;
    }
  }

  if (strlen(parv[2]) > HOSTLEN || !*parv[2] || !valid_hostname(parv[2]))
  {
    sendto_one(source_p, ":%s NOTICE %s :Invalid hostname",
               me.name, source_p->name);
    return;
  }

  if (IsUserHostIp(target_p))
    delete_user_host(target_p->username, target_p->host, !MyConnect(target_p));

  strlcpy(target_p->host, parv[2], sizeof(target_p->host));
  SetIPSpoof(target_p);

  add_user_host(target_p->username, target_p->host, !MyConnect(target_p));
  SetUserHost(target_p);

  if (MyClient(source_p))
  {
    sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s ENCAP * CHGHOST %s %s",
                  source_p->name, target_p->name, parv[2]);
    sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s",
               me.name, source_p->name, target_p->name, target_p->username,
               target_p->host);
  }

  if (MyConnect(target_p) && IsClient(source_p))
    sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s",
               me.name, target_p->name, target_p->username, target_p->host);
}