On Thu, 2021-04-29 at 07:30 +0200, Martijn van Duren wrote: > On Thu, 2021-04-29 at 11:22 +1000, Antonino Sidoti wrote: > > Hello, > > > > I was wondering what options are available to monitor OpenBSD SMTPD? Can > > SNMP be utilise? My monitoring system is PRTG and I am using that for most > > of my systems. Can someone share their way of > > monitoring please? I run two OpenSMTP mail servers and would very much like > > to get some insight as to how they are performing day to day. > > > > Thanks > > > > Antonino Sidoti > > I've build the following diff some time ago. But isn't going in as is, > because the other devs want something like the filter interface for this > feature, which is understandable. But that needs to be thought out fully > and then also implemented, which might take some time. I'm currently > focussing on other parts of the snmp stack before I want to venture into > smtp processes again. > > Anyway, the diff adds basic agentx support around the NETWORK-SERVICE- > MIB (RFC2788) and the MTA-MIB (RFC2789). Feel free to use it, test it, > and to report bugs. It will probably help keep things in shape, or maybe > even improve its shape, until we finally have that external process. > Keep in mind that this lacks the proper peer review expected from most > OpenBSD base code. > > Usage: > Let net-snmpd (snmpd(8) currently has no agentx support) create an > agentx socket: > master agentx > smtpd connects via the parent process, which is root, so no need for > custom agentXPerms.
Forgot to mention: start up net-snmpd with "-I-mta_sendmail", because you get some garbage values from net-snmpd trying to interpret some nonexisting sendmail (at least, that's my interpretation of the output, haven't delved in too deep) > Then you just add the following keyword to smtpd.conf > agentx > And you can walk the data: > martijn$ snmp walk 127.0.0.1 mib_2.27 > mib_2.27.1.1.2.1 = STRING: OpenSMTPd > mib_2.27.1.1.3.1 = STRING: > mib_2.27.1.1.4.1 = STRING: 6.9.0 > mib_2.27.1.1.5.1 = Timeticks: (2100) 0:00:21.00 > mib_2.27.1.1.6.1 = INTEGER: 1 > mib_2.27.1.1.7.1 = Timeticks: (0) 0:00:00.00 > mib_2.27.1.1.16.1 = STRING: OpenSMTPD is a FREE implementation of the > server-side SMTP protocol as defined by RFC 5321, with some additional > standard extensions. It allows ordinary machines to > exchange emails with other systems speaking the SMTP protocol. > mib_2.27.1.1.17.1 = STRING: > martijn$ snmp walk 127.0.0.1 mib_2.28 > mib_2.28.1.1.1.1 = Counter32: 0 > mib_2.28.1.1.2.1 = Counter32: 0 > mib_2.28.1.1.3.1 = Counter32: 0 > mib_2.28.1.1.12.1 = Counter32: 0 > > You can set custom (agentx-master-)path and context as well. > > If you have other applications running that uses the NETWORK-SERVICES > MIB and you want predictable indices from the applIndex you can set it > via the applIndex keyword. Keep in mind that your other applications > need to play nice with the indexAllocate system in any case. > > If you're running on !OpenBSD let me know, I have some diffs to make > libagentx work on at least Ubuntu and maybe others. > > martijn@ > > Index: agentx_control.c > =================================================================== > RCS file: agentx_control.c > diff -N agentx_control.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ agentx_control.c 29 Apr 2021 05:22:14 -0000 > @@ -0,0 +1,279 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2020 Martijn van Duren <mart...@openbsd.org> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/queue.h> > +#include <sys/socket.h> > +#include <sys/tree.h> > +#include <sys/uio.h> > + > +#include <agentx.h> > +#include <errno.h> > +#include <event.h> > +#include <imsg.h> > +#include <limits.h> > +#include <stdio.h> > + > +#include "log.h" > +#include "smtpd.h" > + > +static void agentx_control_nofd(struct agentx *, void *, int); > +static void agentx_control_tryconnect(int, short, void *); > +static void agentx_control_read(int, short, void *); > +static void agentx_control_emptystring(struct agentx_varbind *); > +static void agentx_control_applName(struct agentx_varbind *); > +static void agentx_control_applVersion(struct agentx_varbind *); > +static void agentx_control_applUptime(struct agentx_varbind *); > +static void agentx_control_applOperStatus(struct agentx_varbind *); > +static void agentx_control_applLastChange(struct agentx_varbind *); > +static void agentx_control_applDescription(struct agentx_varbind *); > +static void agentx_control_applURL(struct agentx_varbind *); > +static void agentx_control_mtaReceivedMessages(struct agentx_varbind *); > +static void agentx_control_mtaStoredMessages(struct agentx_varbind *); > +static void agentx_control_mtaTransmittedMessages(struct agentx_varbind *); > +static void agentx_control_mtaLoopsDetected(struct agentx_varbind *); > + > +static struct agentx *sa; > +static struct agentx_session *sas; > +static struct agentx_context *sac; > +static struct agentx_region *application, *mta; > +static struct agentx_index *applIndex; > +static struct event connev, rev; > + > +extern struct stat_digest digest; > + > +#define APPLICATION AGENTX_MIB2, 27 > +#define APPLTABLE APPLICATION, 1 > +#define APPLENTRY APPLTABLE, 1 > +#define APPLINDEX APPLENTRY, 1 > +#define APPLNAME APPLENTRY, 2 > +#define APPLDIRECTORYNAME APPLENTRY, 3 > +#define APPLVERSION APPLENTRY, 4 > +#define APPLUPTIME APPLENTRY, 5 > +#define APPLOPERSTATUS APPLENTRY, 6 > +#define APPLLASTCHANGE APPLENTRY, 7 > +#define APPLINBOUNDASSOCIATIONS APPLENTRY, 8 > +#define APPLOUTBOUNDASSOCIATIONS APPLENTRY, 9 > +#define APPLACCUMULATEDINBOUNDASSOCIATIONS APPLENTRY, 10 > +#define APPLACCUMULATEDOUTBOUNDASSOCIATIONS APPLENTRY, 11 > +#define APPLLASTINBOUNDACTIVITY APPLENTRY, 12 > +#define APPLlASTOUTBOUNDACTIVITY APPLENTRY, 13 > +#define APPLREJECTEDINBOUNDASSOCIATIONS APPLENTRY, 14 > +#define APPLFAILEDOUTBOUNDASSOCIATIONS APPLENTRY, 15 > +#define APPLDESCRIPTION APPLENTRY, 16 > +#define APPLURL APPLENTRY, 17 > +#define MTA AGENTX_MIB2, 28 > +#define MTATABLE MTA, 1 > +#define MTAENTRY MTATABLE, 1 > +#define MTARECEIVEDMESSAGES MTAENTRY, 1 > +#define MTASTOREDMESSAGES MTAENTRY, 2 > +#define MTATRANSMITTEDMESSAGES MTAENTRY, 3 > +#define MTARECEIVEDVOLUME MTAENTRY, 4 > +#define MTASTOREDVOLUME MTAENTRY, 5 > +#define MTATRANSMITTEDVOLUME MTAENTRY, 6 > +#define MTARECEIVEDRECIPIENTS MTAENTRY, 7 > +#define MTASTOREDRECIPIENTS MTAENTRY, 8 > +#define MTATRANSMITTEDRECIPIENTS MTAENTRY, 9 > +#define MTASUCCESSFULCONVERTEDMESSAGES MTAENTRY, 10 > +#define MTAFAILEDCONVERTEDMESSAGES MTAENTRY, 11 > +#define MTALOOPSDETECTED MTAENTRY, 12 > + > +void > +agentx_control(void) > +{ > + agentx_log_fatal = fatalx; > + agentx_log_warn = log_warnx; > + agentx_log_info = log_info; > + agentx_log_debug = log_debug; > + > + if ((sa = agentx(agentx_control_nofd, NULL)) == NULL) > + fatal("Can't setup agentx"); > + if ((sas = agentx_session(sa, NULL, 0, "OpenSMTPd", 0)) == NULL) > + fatal("Can't setup agentx session"); > + if ((sac = agentx_context(sas, env->sc_agentx->context)) == NULL) > + fatal("Can't setup agentx context"); > + > + if ((application = agentx_region(sac, > + AGENTX_OID(APPLICATION), 0)) == NULL) > + fatal("agentx_mib application region"); > + if ((mta = agentx_region(sac, > + AGENTX_OID(MTA, 28), 0)) == NULL) > + fatal("agentx_mib application region"); > + switch (env->sc_agentx->applIndexType) { > + case AGENTX_INDEX_TYPE_ANY: > + if ((applIndex = agentx_index_integer_any(application, > + AGENTX_OID(APPLINDEX))) == NULL) > + fatal("agentx_index_integer_new"); > + break; > + case AGENTX_INDEX_TYPE_NEW: > + if ((applIndex = agentx_index_integer_new(application, > + AGENTX_OID(APPLINDEX))) == NULL) > + fatal("agentx_index_integer_new"); > + break; > + case AGENTX_INDEX_TYPE_VALUE: > + if ((applIndex = agentx_index_integer_value(application, > + AGENTX_OID(APPLINDEX), > + env->sc_agentx->applIndex)) == NULL) > + fatal("agentx_index_integer_new"); > + break; > + case AGENTX_INDEX_TYPE_UNDEFINED: > + fatalx("%s: How did I get here?", __func__); > + } > + > + if (agentx_object(application, AGENTX_OID(APPLNAME), &applIndex, 1, > 0, > + agentx_control_applName) == NULL || > + agentx_object(application, AGENTX_OID(APPLDIRECTORYNAME), > + &applIndex, 1, 0, agentx_control_emptystring) == NULL || > + agentx_object(application, AGENTX_OID(APPLVERSION), &applIndex, > 1, > + 0, agentx_control_applVersion) == NULL || > + agentx_object(application, AGENTX_OID(APPLUPTIME), &applIndex, > 1, 0, > + agentx_control_applUptime) == NULL || > + agentx_object(application, AGENTX_OID(APPLOPERSTATUS), > &applIndex, > + 1, 0, agentx_control_applOperStatus) == NULL || > + agentx_object(application, AGENTX_OID(APPLLASTCHANGE), > &applIndex, > + 1, 0, agentx_control_applLastChange) == NULL || > + agentx_object(application, AGENTX_OID(APPLDESCRIPTION), > &applIndex, > + 1, 0, agentx_control_applDescription) == NULL || > + agentx_object(application, AGENTX_OID(APPLURL), &applIndex, 1, 0, > + agentx_control_applURL) == NULL || > + agentx_object(mta, AGENTX_OID(MTARECEIVEDMESSAGES), &applIndex, 1, > + 0, agentx_control_mtaReceivedMessages) == NULL || > + agentx_object(mta, AGENTX_OID(MTASTOREDMESSAGES), &applIndex, 1, > 0, > + agentx_control_mtaStoredMessages) == NULL || > + agentx_object(mta, AGENTX_OID(MTATRANSMITTEDMESSAGES), &applIndex, > + 1, 0, agentx_control_mtaTransmittedMessages) == NULL || > + agentx_object(mta, AGENTX_OID(MTALOOPSDETECTED), &applIndex, 1, 0, > + agentx_control_mtaLoopsDetected) == NULL) > + fatal("agentx_object"); > + > +} > + > +static void > +agentx_control_nofd(struct agentx *unused, void *cookie, int close) > +{ > + event_del(&rev); > + agentx_control_tryconnect(-1, 0, NULL); > +} > + > +static void > +agentx_control_tryconnect(int fd, short event, void *cookie) > +{ > + m_create(p_parent, IMSG_AGENTX_GETFD, 0, 0, -1); > + m_close(p_parent); > +} > + > +static void > +agentx_control_read(int fd, short event, void *cookie) > +{ > + agentx_read(sa); > +} > + > +void > +agentx_control_fdopen(int fd, int serrno) > +{ > + struct timeval timeout = {3, 0}; > + > + if (fd == -1) { > + errno = serrno; > + log_warn("Failed to connect to agentx master"); > + evtimer_set(&connev, agentx_control_tryconnect, NULL); > + evtimer_add(&connev, &timeout); > + return; > + } > + > + agentx_connect(sa, fd); > + > + event_set(&rev, fd, EV_READ|EV_PERSIST, agentx_control_read, NULL); > + event_add(&rev, NULL); > +} > + > +static void > +agentx_control_emptystring(struct agentx_varbind *vb) > +{ > + agentx_varbind_string(vb, ""); > +} > + > +static void > +agentx_control_applName(struct agentx_varbind *vb) > +{ > + agentx_varbind_string(vb, "OpenSMTPd"); > +} > + > +static void > +agentx_control_applVersion(struct agentx_varbind *vb) > +{ > + agentx_varbind_string(vb, SMTPD_VERSION); > +} > + > +static void > +agentx_control_applUptime(struct agentx_varbind *vb) > +{ > + agentx_varbind_timeticks(vb, (uint32_t) ((time(NULL) - > digest.startup) * 100)); > +} > + > +static void > +agentx_control_applOperStatus(struct agentx_varbind *vb) > +{ > + agentx_varbind_integer(vb, env->sc_flags & SMTPD_SMTP_PAUSED ? 2 : 1); > +} > + > +static void > +agentx_control_applLastChange(struct agentx_varbind *vb) > +{ > + /* I can't find this value, so just return a 0-value for now. */ > + agentx_varbind_timeticks(vb, 0); > +} > + > +static void > +agentx_control_applDescription(struct agentx_varbind *vb) > +{ > + agentx_varbind_string(vb, "OpenSMTPD is a FREE implementation of " > + "the server-side SMTP protocol as defined by RFC 5321, with some " > + "additional standard extensions. It allows ordinary machines to " > + "exchange emails with other systems speaking the SMTP protocol."); > +} > + > +static void > +agentx_control_applURL(struct agentx_varbind *vb) > +{ > + agentx_varbind_string(vb, ""); > +} > + > +static void > +agentx_control_mtaReceivedMessages(struct agentx_varbind *vb) > +{ > + agentx_varbind_counter32(vb, (uint32_t) digest.evp_enqueued); > +} > + > +static void > +agentx_control_mtaStoredMessages(struct agentx_varbind *vb) > +{ > + agentx_varbind_counter32(vb, > + (uint32_t) (digest.evp_enqueued - digest.evp_dequeued)); > +} > + > +static void > +agentx_control_mtaTransmittedMessages(struct agentx_varbind *vb) > +{ > + agentx_varbind_counter32(vb, digest.evp_dequeued); > +} > + > +static void > +agentx_control_mtaLoopsDetected(struct agentx_varbind *vb) > +{ > + agentx_varbind_counter32(vb, digest.dlv_loop); > +} > Index: control.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/control.c,v > retrieving revision 1.126 > diff -u -p -r1.126 control.c > --- control.c 31 Dec 2020 08:27:15 -0000 1.126 > +++ control.c 29 Apr 2021 05:22:14 -0000 > @@ -73,7 +73,7 @@ extern const char *backend_stat; > static uint64_t connid = 0; > static struct tree ctl_conns; > static struct tree ctl_count; > -static struct stat_digest digest; > +struct stat_digest digest; > > #define CONTROL_FD_RESERVE 5 > #define CONTROL_MAXCONN_PER_CLIENT 32 > @@ -87,6 +87,7 @@ control_imsg(struct mproc *p, struct ims > const char *key; > const void *data; > size_t sz; > + int serrno; > > if (imsg == NULL) { > if (p->proc != PROC_CLIENT) > @@ -157,6 +158,16 @@ control_imsg(struct mproc *p, struct ims > if (stat_backend) > stat_backend->set(key, &val); > return; > + case IMSG_AGENTX_GETFD: > + serrno = 0; > + if (imsg->fd == -1) { > + m_msg(&m, imsg); > + m_get_int(&m, &serrno); > + m_end(&m); > + } > + > + agentx_control_fdopen(imsg->fd, serrno); > + return; > } > > errx(1, "control_imsg: unexpected %s imsg", > @@ -252,6 +263,9 @@ control(void) > config_peer(PROC_CA); > > control_listen(); > + > + if (env->sc_agentx != NULL) > + agentx_control(); > > if (pledge("stdio unix recvfd sendfd", NULL) == -1) > err(1, "pledge"); > Index: parse.y > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v > retrieving revision 1.287 > diff -u -p -r1.287 parse.y > --- parse.y 9 Apr 2021 16:43:43 -0000 1.287 > +++ parse.y 29 Apr 2021 05:22:14 -0000 > @@ -28,11 +28,13 @@ > #include <sys/socket.h> > #include <sys/stat.h> > #include <sys/ioctl.h> > +#include <sys/un.h> > > #include <net/if.h> > #include <netinet/in.h> > #include <arpa/inet.h> > > +#include <agentx.h> > #include <ctype.h> > #include <err.h> > #include <errno.h> > @@ -177,9 +179,9 @@ typedef struct { > > %} > > -%token ACTION ADMD ALIAS ANY ARROW AUTH AUTH_OPTIONAL > +%token ACTION ADMD AGENTX ALIAS ANY APPLINDEX ARROW AUTH AUTH_OPTIONAL > %token BACKUP BOUNCE BYPASS > -%token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT > +%token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT CONTEXT > %token DATA DATA_LINE DHE DISCONNECT DOMAIN > %token EHLO ENABLE ENCRYPTION ERROR EXPAND_ONLY > %token FCRDNS FILTER FOR FORWARD_ONLY FROM > @@ -192,7 +194,7 @@ typedef struct { > %token MAIL_FROM MAILDIR MASK_SRC MASQUERADE MATCH MAX_MESSAGE_SIZE > MAX_DEFERRED MBOX MDA MTA MX > %token NO_DSN NO_VERIFY NOOP > %token ON > -%token PHASE PKI PORT PROC PROC_EXEC PROTOCOLS PROXY_V2 > +%token PATH PHASE PKI PORT PROC PROC_EXEC PROTOCOLS PROXY_V2 > %token QUEUE QUIT > %token RCPT_TO RDNS RECIPIENT RECEIVEDAUTH REGEX RELAY REJECT REPORT REWRITE > RSET > %token SCHEDULER SENDER SENDERS SMTP SMTP_IN SMTP_OUT SMTPS SOCKET SRC SRS > SUB_ADDR_DELIM > @@ -228,6 +230,7 @@ grammar : /* empty */ > | grammar dispatcher '\n' > | grammar match '\n' > | grammar filter '\n' > + | grammar agentx '\n' > | grammar error '\n' { file->errors++; } > ; > > @@ -1978,6 +1981,82 @@ FILTER STRING CHAIN { > } > ; > > +agentxopt : > +CONTEXT STRING { > + if (conf->sc_agentx->context != NULL) { > + yyerror("redefinition of agentx context"); > + free($2); > + YYERROR; > + } > + conf->sc_agentx->context = $2; > +} > +| PATH STRING { > + if (strlen($2) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { > + yyerror("agentx path too large"); > + free($2); > + YYERROR; > + } > + if ($2[0] != '/') { > + yyerror("agentx path must be absolute"); > + free($2); > + YYERROR; > + } > + if (conf->sc_agentx->path != NULL) { > + yyerror("redefinition of agentx path"); > + free($2); > + YYERROR; > + } > + conf->sc_agentx->path = $2; > +} > +| APPLINDEX STRING { > + if (conf->sc_agentx->applIndexType != AGENTX_INDEX_TYPE_UNDEFINED) { > + yyerror("redefinition of agentx applIndex"); > + YYERROR; > + } > + > + if (strcasecmp($2, "any") == 0) > + conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_ANY; > + else if (strcasecmp($2, "new") == 0) > + conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_NEW; > + else { > + yyerror("invalid applIndex"); > + YYERROR; > + } > +} > +| APPLINDEX NUMBER { > + if (conf->sc_agentx->applIndexType != AGENTX_INDEX_TYPE_UNDEFINED) { > + yyerror("redefinition of agentx applIndex"); > + YYERROR; > + } > + if ($2 > INT32_MAX) { > + yyerror("agentx applIndex too large"); > + YYERROR; > + } > + if ($2 < 1) { > + yyerror("agentx applIndex too small"); > + YYERROR; > + } > + > + conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_VALUE; > + conf->sc_agentx->applIndex = (uint32_t) $2; > +} > +; > + > +agentxopts : /* empty */ > + | agentxopts agentxopt > + ; > + > +agentx: > +AGENTX { > + conf->sc_agentx = xcalloc(1, sizeof(*conf->sc_agentx)); > +} agentxopts { > + if (conf->sc_agentx->path == NULL) > + conf->sc_agentx->path = AGENTX_MASTER_PATH; > + if (conf->sc_agentx->applIndexType == AGENTX_INDEX_TYPE_UNDEFINED) > + conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_ANY; > +} > +; > + > size : NUMBER { > if ($1 < 0) { > yyerror("invalid size: %" PRId64, $1); > @@ -2655,8 +2734,10 @@ lookup(char *s) > static const struct keywords keywords[] = { > { "action", ACTION }, > { "admd", ADMD }, > + { "agentx", AGENTX }, > { "alias", ALIAS }, > { "any", ANY }, > + { "applIndex", APPLINDEX }, > { "auth", AUTH }, > { "auth-optional", AUTH_OPTIONAL }, > { "backup", BACKUP }, > @@ -2670,6 +2751,7 @@ lookup(char *s) > { "commit", COMMIT }, > { "compression", COMPRESSION }, > { "connect", CONNECT }, > + { "context", CONTEXT }, > { "data", DATA }, > { "data-line", DATA_LINE }, > { "dhe", DHE }, > @@ -2713,6 +2795,7 @@ lookup(char *s) > { "no-verify", NO_VERIFY }, > { "noop", NOOP }, > { "on", ON }, > + { "path", PATH }, > { "phase", PHASE }, > { "pki", PKI }, > { "port", PORT }, > Index: smtpd.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v > retrieving revision 1.338 > diff -u -p -r1.338 smtpd.c > --- smtpd.c 21 Apr 2021 07:54:10 -0000 1.338 > +++ smtpd.c 29 Apr 2021 05:22:14 -0000 > @@ -25,6 +25,7 @@ > #include <sys/wait.h> > #include <sys/stat.h> > #include <sys/uio.h> > +#include <sys/un.h> > #include <sys/mman.h> > > #include <bsd_auth.h> > @@ -70,6 +71,7 @@ static void parent_send_config_lka(void) > static void parent_send_config_dispatcher(void); > static void parent_send_config_ca(void); > static void parent_sig_handler(int, short, void *); > +static int parent_open_agentx(void); > static void forkmda(struct mproc *, uint64_t, struct deliver *); > static int parent_forward_open(char *, char *, uid_t, gid_t); > static struct child *child_add(pid_t, int, const char *); > @@ -168,7 +170,7 @@ parent_imsg(struct mproc *p, struct imsg > uint64_t reqid; > size_t sz; > void *i; > - int fd, n, v, ret; > + int fd, n, v, ret, serrno; > > if (imsg == NULL) > fatalx("process %s socket closed", p->name); > @@ -268,6 +270,16 @@ parent_imsg(struct mproc *p, struct imsg > m_add_string(p_lka, procname); > m_close(p_lka); > return; > + case IMSG_AGENTX_GETFD: > + fd = parent_open_agentx(); > + if (fd == -1) > + serrno = errno; > + > + m_create(p_control, IMSG_AGENTX_GETFD, 0, 0, fd); > + if (fd == -1) > + m_add_int(p_control, serrno); > + m_close(p_control); > + return; > } > > errx(1, "parent_imsg: unexpected %s imsg from %s", > @@ -474,6 +486,29 @@ parent_sig_handler(int sig, short event, > } > } > > +static int > +parent_open_agentx(void) > +{ > + int fd; > + struct sockaddr_un sun; > + int serrno; > + > + sun.sun_len = sizeof(sun); > + sun.sun_family = AF_UNIX; > + strlcpy(sun.sun_path, env->sc_agentx->path, sizeof(sun.sun_path)); > + > + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) > + return -1; > + > + if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { > + serrno = errno; > + close(fd); > + errno = serrno; > + return -1; > + } > + return fd; > +} > + > int > main(int argc, char *argv[]) > { > @@ -639,6 +674,7 @@ main(int argc, char *argv[]) > errx(1, "need root privileges"); > > log_init(foreground_log, LOG_MAIL); > + log_setverbose(tracing & TRACE_DEBUG ? 2: 1); > log_trace_verbose(tracing); > load_pki_tree(); > load_pki_keys(); > @@ -2122,6 +2158,8 @@ imsg_to_str(int type) > CASE(IMSG_CA_RSA_PRIVENC); > CASE(IMSG_CA_RSA_PRIVDEC); > CASE(IMSG_CA_ECDSA_SIGN); > + > + CASE(IMSG_AGENTX_GETFD); > default: > (void)snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type); > > Index: smtpd.conf.5 > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v > retrieving revision 1.260 > diff -u -p -r1.260 smtpd.conf.5 > --- smtpd.conf.5 9 Apr 2021 16:43:43 -0000 1.260 > +++ smtpd.conf.5 29 Apr 2021 05:22:14 -0000 > @@ -338,6 +338,33 @@ The Administrative Management Domain thi > The authservid will be forwarded to filters using it to identify or mark > authentication-results headers. > If omitted it defaults to the server name. > +.It Ic agentx Oo Cm applIndex Ar index Oc Oo Cm context Ar context Oc Op Cm > path Ar path > +Export NETWORK-SERVICES-MIB and MTA-MIB metrics via an agentx compatible > +.Pq snmp > +daemon by connecting to > +.Ar path . > +Metrics can be found under the application > +.Pq mib-2.27 > +and mta subtree > +.Pq mib-2.28 . > +If > +.Ar path > +is omitted it will default to > +.Pa /var/agentx/master . > +The index on the applicationTable and mtaTable can be controlled via > +.Cm applIndex . > +For the first available index it can be set to > +.Cm any , > +for a new unused entry it can be set to > +.Cm new , > +and if a fixed position is desired it can be set to a number between 1 and > +2,147,483,647. > +If an index collision occurs because of a fixed position the metrics will > not be > +exported. > +.Cm applIndex > +defaults to any. > +.Ar Context > +is the SNMPv3 context and can usually be omitted. > .It Ic bounce Cm warn-interval Ar delay Op , Ar delay ... > Send warning messages to the envelope sender when temporary delivery > failures cause a message to remain in the queue for longer than > Index: smtpd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v > retrieving revision 1.668 > diff -u -p -r1.668 smtpd.h > --- smtpd.h 21 Apr 2021 07:54:10 -0000 1.668 > +++ smtpd.h 29 Apr 2021 05:22:14 -0000 > @@ -157,7 +157,7 @@ union lookup { > * Bump IMSG_VERSION whenever a change is made to enum imsg_type. > * This will ensure that we can never use a wrong version of smtpctl with > smtpd. > */ > -#define IMSG_VERSION 16 > +#define IMSG_VERSION 17 > > enum imsg_type { > IMSG_NONE, > @@ -327,6 +327,8 @@ enum imsg_type { > IMSG_CA_RSA_PRIVENC, > IMSG_CA_RSA_PRIVDEC, > IMSG_CA_ECDSA_SIGN, > + > + IMSG_AGENTX_GETFD, > }; > > enum smtp_proc_type { > @@ -622,6 +624,8 @@ struct smtpd { > int sc_srs_ttl; > > char *sc_admd; > + > + struct smtp_agentx *sc_agentx; > }; > > #define TRACE_DEBUG 0x0001 > @@ -858,6 +862,20 @@ struct mta_envelope { > char status[LINE_MAX]; > }; > > +enum agentx_index_type { > + AGENTX_INDEX_TYPE_UNDEFINED, > + AGENTX_INDEX_TYPE_ANY, > + AGENTX_INDEX_TYPE_NEW, > + AGENTX_INDEX_TYPE_VALUE, > +}; > + > +struct smtp_agentx { > + const char *path; > + const char *context; > + enum agentx_index_type applIndexType; > + uint32_t applIndex; > +}; > + > struct mta_task { > TAILQ_ENTRY(mta_task) entry; > struct mta_relay *relay; > @@ -1298,6 +1316,9 @@ void config_peer(enum smtp_proc_type); > int control(void); > int control_create_socket(void); > > +/* agentx_control.c */ > +void agentx_control(void); > +void agentx_control_fdopen(int, int); > > /* crypto.c */ > int crypto_setup(const char *, size_t); > Index: smtpd/Makefile > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtpd/Makefile,v > retrieving revision 1.113 > diff -u -p -r1.113 Makefile > --- smtpd/Makefile 21 Apr 2021 07:54:10 -0000 1.113 > +++ smtpd/Makefile 29 Apr 2021 05:22:14 -0000 > @@ -4,7 +4,8 @@ > > PROG= smtpd > > -SRCS= aliases.c > +SRCS= agentx_control.c > +SRCS+= aliases.c > SRCS+= bounce.c > SRCS+= ca.c > SRCS+= compress_backend.c > @@ -79,8 +80,8 @@ SRCS+= stat_ramstat.c > MAN= sendmail.8 smtpd.8 smtpd.conf.5 table.5 > BINDIR= /usr/sbin > > -LDADD+= -levent -lutil -ltls -lssl -lcrypto -lz > -DPADD+= ${LIBEVENT} ${LIBUTIL} ${LIBTLS} ${LIBSSL} > ${LIBCRYPTO} ${LIBZ} > +LDADD+= -levent -lutil -ltls -lssl -lcrypto -lz -lagentx > +DPADD+= ${LIBEVENT} ${LIBUTIL} ${LIBTLS} ${LIBSSL} > ${LIBCRYPTO} ${LIBZ} ${LIBAGENTX} > > CFLAGS+= -fstack-protector-all > CFLAGS+= -I${.CURDIR}/.. > > >