Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postfix/src/smtpd/   (Postfix Mailserver Version 3.11©)  Datei vom 18.3.2025 mit Größe 22 kB image not shown  

Quelle  smtpd_peer.c

  Sprache: C
 

/*++
/* NAME
/* smtpd_peer 3
/* SUMMARY
/* look up peer name/address information
/* SYNOPSIS
/* #include "smtpd.h"
/*
/* void smtpd_peer_init(state)
/* SMTPD_STATE *state;
/*
/* void smtpd_peer_reset(state)
/* SMTPD_STATE *state;
/* AUXILIARY METHODS
/* void smtpd_peer_from_default(state)
/* SMTPD_STATE *state;
/* DESCRIPTION
/* The smtpd_peer_init() routine attempts to produce a printable
/* version of the peer name and address of the specified socket.
/* Where information is unavailable, the name and/or address
/* are set to "unknown".
/*
/* Alternatively, the peer address and port may be obtained
/* from a proxy server or from attributes that postscreen(8)
/* passes to smtpd(8) over local IPC.
/*
/* This module uses the local name service via getaddrinfo()
/* and getnameinfo(). It does not query the DNS directly.
/*
/* smtpd_peer_init() updates the following fields:
/* .IP flags.SMTPD_FLAG_HANGUP
/* This flag is raised when the program should hang up
/* without reading client input.
/* .IP name
/* The verified client hostname. This name is represented by
/* the string "unknown" when 1) the address->name lookup failed,
/* 2) the name->address mapping fails, or 3) the name->address
/* mapping does not produce the client IP address.
/* .IP reverse_name
/* The unverified client hostname as found with address->name
/* lookup; it is not verified for consistency with the client
/* IP address result from name->address lookup.
/* .IP addr
/* Printable representation of the client address.
/* .IP addr_family
/* AF_INET or AF_INET6 in case of an open TCP connection.
/* AF_UNSPEC in all other cases, including an open non-socket
/* connection, or a closed connection.
/* .IP namaddr
/* String of the form: "name[addr]:port".
/* .IP rfc_addr
/* String of the form "ipv4addr" or "ipv6:ipv6addr" for use
/* in Received: message headers.
/* .IP dest_addr
/* Server address, used by the Dovecot authentication server,
/* available as Milter {daemon_addr} macro, and as server_address
/* policy delegation attribute.
/* .IP dest_port
/* Server port, available as Milter {daemon_port} macro, and
/* as server_port policy delegation attribute.
/* .IP sockaddr_len
/* .IP dest_sockaddr_len
/* These are initialized to zero, to indicate that the corresponding
/* sockaddr_storage members are not set.
/* .IP name_status
/* The name_status result field specifies how the name
/* information should be interpreted:
/* .RS
/* .IP 2
/* The address->name lookup and name->address lookup produced
/* the client IP address.
/* .IP 4
/* The address->name lookup or name->address lookup failed
/* with a recoverable error.
/* .IP 5
/* The address->name lookup or name->address lookup failed
/* with an unrecoverable error, or the result did not match
/* the client IP address.
/* .RE
/* .IP reverse_name_status
/* The reverse_name_status result field specifies how the
/* reverse_name information should be interpreted:
/* .RS
/* .IP 2
/* The address->name lookup succeeded.
/* .IP 4
/* The address->name lookup failed with a recoverable error.
/* .IP 5
/* The address->name lookup failed with an unrecoverable error.
/* .RE
/* .PP
/* smtpd_peer_reset() releases memory allocated by smtpd_peer_init().
/*
/* smtpd_peer_from_default() looks up connection information
/* when an up-stream proxy indicates that a connection is not
/* proxied.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/


/* System library. */

#include <sys_defs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <htable.h>

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>
#include <stringops.h>
#include <myaddrinfo.h>
#include <sock_addr.h>
#include <inet_proto.h>
#include <split_at.h>
#include <inet_prefix_top.h>

/* Global library. */

#include <mail_proto.h>
#include <valid_mailhost_addr.h>
#include <mail_params.h>
#include <haproxy_srvr.h>

/* Application-specific. */

#include "smtpd.h"

 /*
  * XXX If we make local port information available via logging, then we must
  * also support these attributes with the XFORWARD command.
  * 
  * XXX If support were to be added for Milter applications in down-stream MTAs,
  * then consistency demands that we propagate a lot of Sendmail macro
  * information via the XFORWARD command. Otherwise we could end up with a
  * very confusing situation.
  */


/* smtpd_peer_sockaddr_to_hostaddr - client address/port to printable form */

static int smtpd_peer_sockaddr_to_hostaddr(SMTPD_STATE *state)
{
    const char *myname = "smtpd_peer_sockaddr_to_hostaddr";
    struct sockaddr *sa = (struct sockaddr *) &(state->sockaddr);
    SOCKADDR_SIZE *sa_length = &state->sockaddr_len;

    /*
     * XXX If we're given an IPv6 (or IPv4) connection from, e.g., inetd,
     * while Postfix IPv6 (or IPv4) support is turned off, don't (skip to the
     * final else clause, pretend the origin is localhost[127.0.0.1], and
     * become an open relay).
     */

    if (sa->sa_family == AF_INET
#ifdef AF_INET6
 || sa->sa_family == AF_INET6
#endif
 ) {
 MAI_HOSTADDR_STR client_addr;
 MAI_SERVPORT_STR client_port;
 MAI_HOSTADDR_STR server_addr;
 MAI_SERVPORT_STR server_port;
 int     aierr;

 /*
  * Sanity check: we can't use sockets that we're not configured for.
 */

 if (strchr((char *) inet_proto_info()->sa_family_list, sa->sa_family) == 0)
     msg_fatal("cannot handle socket type %s with \"%s = %s\"",
#ifdef AF_INET6
        sa->sa_family == AF_INET6 ? "AF_INET6" :
#endif
        sa->sa_family == AF_INET ? "AF_INET" :
        "other", VAR_INET_PROTOCOLS, var_inet_protocols);

 /*
  * Sorry, but there are some things that we just cannot do while
  * connected to the network.
 */

 if (geteuid() != var_owner_uid || getuid() != var_owner_uid) {
     msg_error("incorrect SMTP server privileges: uid=%lu euid=%lu",
        (unsigned long) getuid(), (unsigned long) geteuid());
     msg_fatal("the Postfix SMTP server must run with $%s privileges",
        VAR_MAIL_OWNER);
 }

 /*
  * Convert the client address to printable form.
 */

 if ((aierr = sane_sockaddr_to_hostaddr(sa, sa_length, &client_addr,
            &client_port, 0)) != 0)
     msg_fatal("%s: cannot convert client sockaddr type %s length %ld "
        "to string: %s", myname,
#ifdef AF_INET6
        sa->sa_family == AF_INET6 ? "AF_INET6" :
#endif
        sa->sa_family == AF_INET ? "AF_INET" : "other",
        (long) *sa_length, MAI_STRERROR(aierr));
 state->port = mystrdup(client_port.buf);

 /*
  * XXX Require that the infrastructure strips off the IPv6 datalink
  * suffix to avoid false alarms with strict address syntax checks.
 */

#ifdef HAS_IPV6
 if (strchr(client_addr.buf, '%') != 0)
     msg_panic("%s: address %s has datalink suffix",
        myname, client_addr.buf);

 /*
  * Following RFC 2821 section 4.1.3, an IPv6 address literal gets a
  * prefix of 'IPv6:'. We do this consistently for all IPv6 addresses
  * that appear in headers or envelopes. The fact that
  * valid_mailhost_addr() enforces the form helps of course. We use
  * the form without IPV6: prefix when doing access control, or when
  * accessing the connection cache.
 */

 if (sa->sa_family == AF_INET6) {
     state->addr = mystrdup(client_addr.buf);
     state->rfc_addr =
  concatenate(IPV6_COL, client_addr.buf, (char *) 0);
     state->addr_family = sa->sa_family;
 }

 /*
  * An IPv4 address is in dotted quad decimal form.
 */

 else
#endif
 {
     state->addr = mystrdup(client_addr.buf);
     state->rfc_addr = mystrdup(client_addr.buf);
     state->addr_family = sa->sa_family;
 }

 /*
  * Convert the server address/port to printable form.
 */

 if ((aierr = sane_sockaddr_to_hostaddr((struct sockaddr *)
            &state->dest_sockaddr,
            &state->dest_sockaddr_len,
            &server_addr,
            &server_port, 0)) != 0)
     msg_fatal("%s: cannot convert server sockaddr type %s length %ld "
        "to string: %s", myname,
#ifdef AF_INET6
     state->dest_sockaddr.ss_family == AF_INET6 ? "AF_INET6" :
#endif
        state->dest_sockaddr.ss_family == AF_INET ? "AF_INET" :
        "other", (long) state->dest_sockaddr_len,
        MAI_STRERROR(aierr));
 state->dest_addr = mystrdup(server_addr.buf);
 state->dest_port = mystrdup(server_port.buf);

 return (0);
    }

    /*
     * It's not Internet.
     */

    else {
 return (-1);
    }
}

/* smtpd_peer_sockaddr_to_hostname - client hostname lookup */

static void smtpd_peer_sockaddr_to_hostname(SMTPD_STATE *state)
{
    struct sockaddr *sa = (struct sockaddr *) &(state->sockaddr);
    SOCKADDR_SIZE sa_length = state->sockaddr_len;
    MAI_HOSTNAME_STR client_name;
    int     aierr;

    /*
     * Look up and sanity check the client hostname.
     * 
     * It is unsafe to allow numeric hostnames, especially because there exists
     * pressure to turn off the name->addr double check. In that case an
     * attacker could trivally bypass access restrictions.
     * 
     * sockaddr_to_hostname() already rejects malformed or numeric names.
     */

#define TEMP_AI_ERROR(e) \
 ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)

#define REJECT_PEER_NAME(state, code) { \
 myfree(state->name); \
 state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
 state->name_status = code; \
    }

    if (var_smtpd_peername_lookup == 0) {
 state->name = mystrdup(CLIENT_NAME_UNKNOWN);
 state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
 state->name_status = SMTPD_PEER_CODE_PERM;
 state->reverse_name_status = SMTPD_PEER_CODE_PERM;
    } else if ((aierr = sockaddr_to_hostname(sa, sa_length, &client_name,
      (MAI_SERVNAME_STR *) 00)) != 0) {
 state->name = mystrdup(CLIENT_NAME_UNKNOWN);
 state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
 state->name_status = (TEMP_AI_ERROR(aierr) ?
         SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
 state->reverse_name_status = (TEMP_AI_ERROR(aierr) ?
          SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
    } else {
 struct addrinfo *res0;
 struct addrinfo *res;

 state->name = mystrdup(client_name.buf);
 state->reverse_name = mystrdup(client_name.buf);
 state->name_status = SMTPD_PEER_CODE_OK;
 state->reverse_name_status = SMTPD_PEER_CODE_OK;

 /*
  * Reject the hostname if it does not list the peer address. Without
  * further validation or qualification, such information must not be
  * allowed to enter the audit trail, as people would draw false
  * conclusions.
 */

 aierr = hostname_to_sockaddr_pf(state->name, state->addr_family,
     (char *) 00, &res0);
 if (aierr) {
     msg_warn("hostname %s does not resolve to address %s: %s",
       state->name, state->addr, MAI_STRERROR(aierr));
     REJECT_PEER_NAME(state, (TEMP_AI_ERROR(aierr) ?
       SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_FORGED));
 } else {
     for (res = res0; /* void */ ; res = res->ai_next) {
  if (res == 0) {
      msg_warn("hostname %s does not resolve to address %s",
        state->name, state->addr);
      REJECT_PEER_NAME(state, SMTPD_PEER_CODE_FORGED);
      break;
  }
  if (strchr((char *) inet_proto_info()->sa_family_list, res->ai_family) == 0) {
      msg_info("skipping address family %d for host %s",
        res->ai_family, state->name);
      continue;
  }
  if (sock_addr_cmp_addr(res->ai_addr, sa) == 0)
      break;   /* keep peer name */
     }
     freeaddrinfo(res0);
 }
    }
}

/* smtpd_peer_hostaddr_to_sockaddr - convert numeric string to binary */

static void smtpd_peer_hostaddr_to_sockaddr(SMTPD_STATE *state)
{
    const char *myname = "smtpd_peer_hostaddr_to_sockaddr";
    struct addrinfo *res;
    int     aierr;

    /*
     * The client binary address value is provided by non-error peer lookup
     * methods. It is used to compute the anvil aggregation prefix for client
     * IP addresses.
     */

    if ((aierr = hostaddr_to_sockaddr(state->addr, state->port,
          SOCK_STREAM, &res)) != 0)
 msg_fatal("%s: cannot convert client address '%s' port '%s' to binary: %s",
    myname, state->addr, state->port, MAI_STRERROR(aierr));
    if (res->ai_addrlen > sizeof(state->sockaddr))
 msg_panic("%s: address length > struct sockaddr_storage", myname);
    memcpy((void *) &(state->sockaddr), res->ai_addr, res->ai_addrlen);
    state->sockaddr_len = res->ai_addrlen;
    freeaddrinfo(res);

    /*
     * The server binary address is provided by non-error peer lookup
     * methods. It is currently unused, but it is the result of a hermetic
     * conversion, therefore low-risk.
     */

    if ((aierr = hostaddr_to_sockaddr(state->dest_addr, state->dest_port,
          SOCK_STREAM, &res)) != 0)
 msg_fatal("%s: cannot convert server address '%s' port '%s' to binary: %s",
    myname, state->dest_addr, state->dest_port, MAI_STRERROR(aierr));
    if (res->ai_addrlen > sizeof(state->dest_sockaddr))
 msg_panic("%s: address length > struct sockaddr_storage", myname);
    memcpy((void *) &(state->dest_sockaddr), res->ai_addr, res->ai_addrlen);
    state->dest_sockaddr_len = res->ai_addrlen;
    freeaddrinfo(res);
}

/* smtpd_peer_assume_local_client - non-Internet endpoint */

static void smtpd_peer_assume_local_client(SMTPD_STATE *state)
{

    /*
     * 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.
     */

    state->name = mystrdup("localhost");
    state->reverse_name = mystrdup("localhost");
#ifdef AF_INET6
    if (inet_proto_info()->sa_family_list[0] == PF_INET6) {
 state->addr = mystrdup("::1");  /* XXX bogus. */
 state->rfc_addr = mystrdup(IPV6_COL "::1"); /* XXX bogus. */
    } else
#endif
    {
 state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */
 state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
    }
    state->addr_family = AF_UNSPEC;
    state->name_status = SMTPD_PEER_CODE_OK;
    state->reverse_name_status = SMTPD_PEER_CODE_OK;
    state->port = mystrdup("0");  /* XXX bogus. */

    state->dest_addr = mystrdup(state->addr); /* XXX bogus. */
    state->dest_port = mystrdup(state->port); /* XXX bogus. */

    state->sockaddr_len = 0;
    state->dest_sockaddr_len = 0;
}

/* smtpd_peer_assume_unknown_client - peer went away, or peer info unavailable */

static void smtpd_peer_assume_unknown_client(SMTPD_STATE *state)
{
    state->name = mystrdup(CLIENT_NAME_UNKNOWN);
    state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
    state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
    state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
    state->addr_family = AF_UNSPEC;
    state->name_status = SMTPD_PEER_CODE_PERM;
    state->reverse_name_status = SMTPD_PEER_CODE_PERM;
    state->port = mystrdup(CLIENT_PORT_UNKNOWN);

    state->dest_addr = mystrdup(SERVER_ADDR_UNKNOWN);
    state->dest_port = mystrdup(SERVER_PORT_UNKNOWN);

    state->sockaddr_len = 0;
    state->dest_sockaddr_len = 0;
}

/* smtpd_peer_from_pass_attr - initialize from attribute hash */

static int smtpd_peer_from_pass_attr(SMTPD_STATE *state)
{
    HTABLE *attr = (HTABLE *) vstream_context(state->client);
    const char *cp;

#define BAD_PASS_ATTR(...) do { \
 msg_warn(__VA_ARGS__); \
 return (-1); \
    } while (0)

    /*
     * Extract the client endpoint information from the attribute hash.
     */

    if ((cp = htable_find(attr, MAIL_ATTR_ACT_CLIENT_ADDR)) == 0)
 BAD_PASS_ATTR("missing client address from proxy");
    if (strrchr(cp, ':') != 0) {
 if (valid_ipv6_hostaddr(cp, DO_GRIPE) == 0)
     BAD_PASS_ATTR("bad IPv6 client address syntax from proxy: %s", cp);
 state->addr = mystrdup(cp);
 state->rfc_addr = concatenate(IPV6_COL, cp, (char *) 0);
 state->addr_family = AF_INET6;
    } else {
 if (valid_ipv4_hostaddr(cp, DO_GRIPE) == 0)
     BAD_PASS_ATTR("bad IPv4 client address syntax from proxy: %s", cp);
 state->addr = mystrdup(cp);
 state->rfc_addr = mystrdup(cp);
 state->addr_family = AF_INET;
    }
    if ((cp = htable_find(attr, MAIL_ATTR_ACT_CLIENT_PORT)) == 0)
 BAD_PASS_ATTR("missing client port from proxy");
    if (valid_hostport(cp, DO_GRIPE) == 0)
 BAD_PASS_ATTR("bad TCP client port number syntax from proxy: %s", cp);
    state->port = mystrdup(cp);

    /*
     * The Dovecot authentication server needs the server IP address.
     */

    if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_ADDR)) == 0)
 BAD_PASS_ATTR("missing server address from proxy");
    if (valid_hostaddr(cp, DO_GRIPE) == 0)
 BAD_PASS_ATTR("bad IPv6 server address syntax from proxy: %s", cp);
    state->dest_addr = mystrdup(cp);

    if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_PORT)) == 0)
 BAD_PASS_ATTR("missing server port from proxy");
    if (valid_hostport(cp, DO_GRIPE) == 0)
 BAD_PASS_ATTR("bad TCP server port number syntax from proxy: %s", cp);
    state->dest_port = mystrdup(cp);

    /*
     * Convert the client address from string to binary form.
     */

    smtpd_peer_hostaddr_to_sockaddr(state);
    return (0);
}

/* smtpd_peer_from_default - try to initialize peer information from socket */

void    smtpd_peer_from_default(SMTPD_STATE *state)
{

    /*
     * The "no client" routine provides surrogate information so that the
     * application can produce sensible logging when a client disconnects
     * before the server wakes up. The "assume local" routine provides
     * surrogate state for open, presumably, local, IPC channels.
     */

    state->sockaddr_len = sizeof(state->sockaddr);
    state->dest_sockaddr_len = sizeof(state->dest_sockaddr);
    if (getpeername(vstream_fileno(state->client),
      (struct sockaddr *) &state->sockaddr,
      &state->sockaddr_len) <0
 || getsockname(vstream_fileno(state->client),
         (struct sockaddr *) &state->dest_sockaddr,
         &state->dest_sockaddr_len) < 0) {
 if (errno == ENOTSOCK)
     smtpd_peer_assume_local_client(state);
 else
     smtpd_peer_assume_unknown_client(state);
    } else {
 if (smtpd_peer_sockaddr_to_hostaddr(state) < 0)
     smtpd_peer_assume_local_client(state);
    }
}

/* smtpd_peer_fall_back_and_hangup - recover after incomplete peer info */

static void smtpd_peer_fall_back_and_hangup(SMTPD_STATE *state)
{

    /*
     * Clear incomplete endpoint info. Populate the SMTPD_STATE with default
     * endpoint info, so that the caller won't trip over a null pointer. Hang
     * up before accepting input: we don't know what we're talking to and
     * what rights they might have.
     */

    smtpd_peer_reset(state);
    smtpd_peer_assume_unknown_client(state);
    state->flags |= SMTPD_FLAG_HANGUP;
}

/* smtpd_peer_from_proxy - get endpoint info from proxy agent */

static int smtpd_peer_from_proxy(SMTPD_STATE *state)
{
    typedef struct {
 const char *name;
 int     (*endpt_lookup) (SMTPD_STATE *);
    } SMTPD_ENDPT_LOOKUP_INFO;
    static const SMTPD_ENDPT_LOOKUP_INFO smtpd_endpt_lookup_info[] = {
 HAPROXY_PROTO_NAME, smtpd_peer_from_haproxy,

 /*
  * See smtpd_haproxy.c for the a summary of the information that a
  * proxy endpoint lookup function is expected to provide.
 */

 0,
    };
    const SMTPD_ENDPT_LOOKUP_INFO *pp;

    /*
     * When the proxy information is unavailable, we can't maintain an audit
     * trail or enforce access control, therefore we forcibly hang up.
     */

    for (pp = smtpd_endpt_lookup_info; /* see below */ ; pp++) {
 if (pp->name == 0)
     msg_fatal("unsupported %s value: %s",
        VAR_SMTPD_UPROXY_PROTO, var_smtpd_uproxy_proto);
 if (strcmp(var_smtpd_uproxy_proto, pp->name) == 0)
     return (pp->endpt_lookup(state));
    }
}

/* smtpd_peer_init - initialize peer information */

void    smtpd_peer_init(SMTPD_STATE *state)
{

    /*
     * Prepare for partial initialization after error.
     */

    memset((void *) &(state->sockaddr), 0sizeof(state->sockaddr));
    state->sockaddr_len = 0;
    state->name = 0;
    state->reverse_name = 0;
    state->addr = 0;
    state->namaddr = 0;
    state->rfc_addr = 0;
    state->port = 0;
    state->anvil_range = 0;
    state->dest_addr = 0;
    state->dest_port = 0;
    state->dest_sockaddr_len = 0;

    /*
     * Determine the remote SMTP client address and port.
     * 
     * If we can't process the connection hand-off info from postscreen or
     * proxy, fall back to some default endpoint info for logging and force a
     * hangup. We can't determine what rights the peer should have.
     * 
     * XXX In stand-alone mode, don't assume that the peer will be a local
     * process. That could introduce a gaping hole when the SMTP daemon is
     * hooked up to the network via inetd or some other super-server.
     */

    if (vstream_context(state->client) != 0) {
 if (smtpd_peer_from_pass_attr(state) < 0)
     smtpd_peer_fall_back_and_hangup(state);
 if (*var_smtpd_uproxy_proto != 0)
     msg_warn("ignoring non-empty %s setting behind postscreen",
       VAR_SMTPD_UPROXY_PROTO);
    } else if (SMTPD_STAND_ALONE(state) || *var_smtpd_uproxy_proto == 0) {
 smtpd_peer_from_default(state);
    } else {
 if (smtpd_peer_from_proxy(state) < 0)
     smtpd_peer_fall_back_and_hangup(state);
    }

    /*
     * Determine the remote SMTP client hostname. Note: some of the handlers
     * above provide surrogate endpoint information in case of error. In that
     * case, leave the surrogate information alone.
     */

    if (state->name == 0)
 smtpd_peer_sockaddr_to_hostname(state);

    /*
     * Do the name[addr]:port formatting for pretty reports.
     */

    state->namaddr = SMTPD_BUILD_NAMADDRPORT(state->name, state->addr,
          state->port);

    /*
     * Generate the 'address' or 'net/mask' index for anvil event
     * aggregation.
     */


    if (state->addr_family != AF_UNSPEC) {
 state->anvil_range = inet_prefix_top(state->addr_family,
     SOCK_ADDR_ADDRP(&(state->sockaddr)),
          state->addr_family == AF_INET ?
          var_smtpd_cipv4_prefix :
          var_smtpd_cipv6_prefix);
    }
}

/* smtpd_peer_reset - destroy peer information */

void    smtpd_peer_reset(SMTPD_STATE *state)
{
#define MYFREE_AND_ZERO(e) do { myfree(e); (e) = 0; } while (0);

    if (state->name)
 MYFREE_AND_ZERO(state->name);
    if (state->reverse_name)
 MYFREE_AND_ZERO(state->reverse_name);
    if (state->addr)
 MYFREE_AND_ZERO(state->addr);
    if (state->namaddr)
 MYFREE_AND_ZERO(state->namaddr);
    if (state->rfc_addr)
 MYFREE_AND_ZERO(state->rfc_addr);
    if (state->port)
 MYFREE_AND_ZERO(state->port);
    if (state->dest_addr)
 MYFREE_AND_ZERO(state->dest_addr);
    if (state->dest_port)
 MYFREE_AND_ZERO(state->dest_port);
    if (state->anvil_range)
 MYFREE_AND_ZERO(state->anvil_range);
}

Messung V0.5 in Prozent
C=92 H=91 G=91

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.