summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2008-09-26 15:19:56 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2008-09-26 15:19:56 +0000
commitf6aa7e9b26297e3aacacfc47da2dcd9b7a2e9ff6 (patch)
tree8ee0e3d73ae6b1b659de7460ece8408b6860062c
parent78eb4b63025d2ad9bd0479786dd0ca6ea84cfdb0 (diff)
allow to add an additional restricted control socket for trap sending
only (not even show commands). this allows to place a socket for traps in another daemon's chroot. (based on restricted socket support from bgpd)
-rw-r--r--usr.sbin/snmpctl/snmpctl.816
-rw-r--r--usr.sbin/snmpctl/snmpctl.c12
-rw-r--r--usr.sbin/snmpd/control.c62
-rw-r--r--usr.sbin/snmpd/snmpd.818
-rw-r--r--usr.sbin/snmpd/snmpd.c20
-rw-r--r--usr.sbin/snmpd/snmpd.h21
-rw-r--r--usr.sbin/snmpd/snmpe.c10
7 files changed, 107 insertions, 52 deletions
diff --git a/usr.sbin/snmpctl/snmpctl.8 b/usr.sbin/snmpctl/snmpctl.8
index ed46d31fde6..d04e0a7599a 100644
--- a/usr.sbin/snmpctl/snmpctl.8
+++ b/usr.sbin/snmpctl/snmpctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: snmpctl.8,v 1.8 2008/05/17 23:31:52 sobrado Exp $
+.\" $OpenBSD: snmpctl.8,v 1.9 2008/09/26 15:19:55 reyk Exp $
.\"
.\" Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 17 2008 $
+.Dd $Mdocdate: September 26 2008 $
.Dt SNMPCTL 8
.Os
.Sh NAME
@@ -23,6 +23,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl n
+.Op Fl s Ar socket
.Ar command
.Op Ar arg ...
.Sh DESCRIPTION
@@ -36,6 +37,13 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl n
Show numeric OID values instead of their symbolic names.
+.It Fl s Ar socket
+Use
+.Ar socket
+instead of the default
+.Pa /var/run/snmpd.sock
+to communicate with
+.Xr snmpd 8 .
.El
.Pp
The following commands are available:
@@ -97,8 +105,8 @@ An string describing an Object ID, for example
.Sh FILES
.Bl -tag -width "/var/run/snmpd.sockXX" -compact
.It /var/run/snmpd.sock
-Unix-domain socket used for communication with
-.Xr snmpd 8 .
+default UNIX-domain socket used for communication with
+.Xr snmpd 8
.El
.Sh SEE ALSO
.Xr snmpd 8
diff --git a/usr.sbin/snmpctl/snmpctl.c b/usr.sbin/snmpctl/snmpctl.c
index 41a8f3d9efb..89210679866 100644
--- a/usr.sbin/snmpctl/snmpctl.c
+++ b/usr.sbin/snmpctl/snmpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpctl.c,v 1.8 2008/05/17 23:31:52 sobrado Exp $ */
+/* $OpenBSD: snmpctl.c,v 1.9 2008/09/26 15:19:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -95,16 +95,20 @@ main(int argc, char *argv[])
int done = 0;
int n;
int ch;
+ const char *sock = SNMPD_SOCKET;
if ((env = calloc(1, sizeof(struct snmpd *))) == NULL)
err(1, "calloc");
gettimeofday(&env->sc_starttime, NULL);
- while ((ch = getopt(argc, argv, "n")) != -1) {
+ while ((ch = getopt(argc, argv, "ns:")) != -1) {
switch (ch) {
case 'n':
env->sc_flags |= SNMPD_F_NONAMES;
break;
+ case 's':
+ sock = optarg;
+ break;
default:
usage();
/* NOTREACHED */
@@ -140,7 +144,7 @@ main(int argc, char *argv[])
bzero(&sun, sizeof(sun));
sun.sun_family = AF_UNIX;
- strlcpy(sun.sun_path, SNMPD_SOCKET, sizeof(sun.sun_path));
+ strlcpy(sun.sun_path, sock, sizeof(sun.sun_path));
reconnect:
if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
/* Keep retrying if running in monitor mode */
@@ -149,7 +153,7 @@ main(int argc, char *argv[])
usleep(100);
goto reconnect;
}
- err(1, "connect: %s", SNMPD_SOCKET);
+ err(1, "connect: %s", sock);
}
if (res->ibuf != NULL)
diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c
index 646d181d126..bde9dd16ef9 100644
--- a/usr.sbin/snmpd/control.c
+++ b/usr.sbin/snmpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.7 2008/02/07 11:33:26 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.8 2008/09/26 15:19:55 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -43,14 +43,15 @@ struct ctl_connlist ctl_conns;
struct ctl_conn *control_connbyfd(int);
void control_close(int);
-struct imsgbuf *ibuf_parent = NULL;
-
int
-control_init(void)
+control_init(struct control_sock *cs)
{
struct sockaddr_un sun;
int fd;
- mode_t old_umask;
+ mode_t old_umask, mode;
+
+ if (cs->cs_name == NULL)
+ return (0);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
log_warn("control_init: socket");
@@ -58,74 +59,84 @@ control_init(void)
}
sun.sun_family = AF_UNIX;
- if (strlcpy(sun.sun_path, SNMPD_SOCKET,
+ if (strlcpy(sun.sun_path, cs->cs_name,
sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
- log_warn("control_init: %s name too long", SNMPD_SOCKET);
+ log_warn("control_init: %s name too long", cs->cs_name);
close(fd);
return (-1);
}
- if (unlink(SNMPD_SOCKET) == -1)
+ if (unlink(cs->cs_name) == -1)
if (errno != ENOENT) {
- log_warn("control_init: unlink %s", SNMPD_SOCKET);
+ log_warn("control_init: unlink %s", cs->cs_name);
close(fd);
return (-1);
}
- old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
+ if (cs->cs_restricted) {
+ old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+ mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ } else {
+ old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
+ mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
+ }
+
if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
- log_warn("control_init: bind: %s", SNMPD_SOCKET);
+ log_warn("control_init: bind: %s", cs->cs_name);
close(fd);
(void)umask(old_umask);
return (-1);
}
(void)umask(old_umask);
- if (chmod(SNMPD_SOCKET, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+ if (chmod(cs->cs_name, mode) == -1) {
log_warn("control_init: chmod");
close(fd);
- (void)unlink(SNMPD_SOCKET);
+ (void)unlink(cs->cs_name);
return (-1);
}
session_socket_blockmode(fd, BM_NONBLOCK);
- control_state.fd = fd;
+ cs->cs_fd = fd;
return (0);
}
int
-control_listen(struct snmpd *env, struct imsgbuf *parent)
+control_listen(struct control_sock *cs)
{
- ibuf_parent = parent;
+ if (cs->cs_name == NULL)
+ return (0);
- if (listen(control_state.fd, CONTROL_BACKLOG) == -1) {
+ if (listen(cs->cs_fd, CONTROL_BACKLOG) == -1) {
log_warn("control_listen: listen");
return (-1);
}
- event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST,
- control_accept, env);
- event_add(&control_state.ev, NULL);
+ event_set(&cs->cs_ev, cs->cs_fd, EV_READ | EV_PERSIST,
+ control_accept, cs);
+ event_add(&cs->cs_ev, NULL);
return (0);
}
void
-control_cleanup(void)
+control_cleanup(struct control_sock *cs)
{
- (void)unlink(SNMPD_SOCKET);
+ if (cs->cs_name == NULL)
+ return;
+ (void)unlink(cs->cs_name);
}
/* ARGSUSED */
void
control_accept(int listenfd, short event, void *arg)
{
+ struct control_sock *cs = (struct control_sock *)arg;
int connfd;
socklen_t len;
struct sockaddr_un sun;
struct ctl_conn *c;
- struct snmpd *env = arg;
len = sizeof(sun);
if ((connfd = accept(listenfd,
@@ -146,7 +157,7 @@ control_accept(int listenfd, short event, void *arg)
imsg_init(&c->ibuf, connfd, control_dispatch_imsg);
c->ibuf.events = EV_READ;
event_set(&c->ibuf.ev, c->ibuf.fd, c->ibuf.events,
- c->ibuf.handler, env);
+ c->ibuf.handler, cs);
event_add(&c->ibuf.ev, NULL);
TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
@@ -184,6 +195,7 @@ control_close(int fd)
void
control_dispatch_imsg(int fd, short event, void *arg)
{
+ struct control_sock *cs = (struct control_sock *)arg;
struct ctl_conn *c;
struct imsg imsg;
int n;
@@ -220,7 +232,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
if (n == 0)
break;
- if (c->flags & CTL_CONN_LOCKED) {
+ if (cs->cs_restricted || (c->flags & CTL_CONN_LOCKED)) {
switch (imsg.hdr.type) {
case IMSG_SNMP_TRAP:
case IMSG_SNMP_ELEMENT:
diff --git a/usr.sbin/snmpd/snmpd.8 b/usr.sbin/snmpd/snmpd.8
index 94611664dea..3b93e946828 100644
--- a/usr.sbin/snmpd/snmpd.8
+++ b/usr.sbin/snmpd/snmpd.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: snmpd.8,v 1.8 2008/03/30 17:56:27 martin Exp $
+.\" $OpenBSD: snmpd.8,v 1.9 2008/09/26 15:19:55 reyk Exp $
.\"
.\" Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: March 30 2008 $
+.Dd $Mdocdate: September 26 2008 $
.Dt SNMPD 8
.Os
.Sh NAME
@@ -27,6 +27,7 @@
.Fl D Ar macro Ns = Ns Ar value Oc
.Xc
.Op Fl f Ar file
+.Op Fl r Ar path
.Sh DESCRIPTION
.Nm
is a daemon which implements the SNMP protocol.
@@ -55,15 +56,26 @@ Show numeric OID values instead of their symbolic names.
.It Fl n
Configtest mode.
Only check the configuration file for validity.
+.It Fl r Ar path
+Open a second, restricted, control socket that
+.Xr snmpctl 8
+can use.
+Only
+.Em trap
+requests are allowed on this socket.
.It Fl v
Produce more verbose output.
.El
.Sh FILES
-.Bl -tag -width "/etc/snmpd.confXXX" -compact
+.Bl -tag -width "/var/run/snmpd.sockXXX" -compact
.It Pa /etc/snmpd.conf
default
.Nm
configuration file
+.It Pa /var/run/snmpd.sock
+default
+.Nm
+control socket
.El
.Sh SEE ALSO
.Xr snmpd.conf 5 ,
diff --git a/usr.sbin/snmpd/snmpd.c b/usr.sbin/snmpd/snmpd.c
index 4835b92a6f1..fad785ecabf 100644
--- a/usr.sbin/snmpd/snmpd.c
+++ b/usr.sbin/snmpd/snmpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.c,v 1.7 2008/05/12 19:15:02 pyr Exp $ */
+/* $OpenBSD: snmpd.c,v 1.8 2008/09/26 15:19:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -84,8 +84,8 @@ usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-dNnv] [-D macro=value] [-f file]\n",
- __progname);
+ fprintf(stderr, "usage: %s [-dNnv] [-D macro=value] "
+ "[-f file] [-r path]\n", __progname);
exit(1);
}
@@ -102,12 +102,13 @@ main(int argc, char *argv[])
u_int flags = 0;
int noaction = 0;
const char *conffile = CONF_FILE;
+ const char *rcsock = NULL;
smi_init();
log_init(1); /* log to stderr until daemonized */
- while ((c = getopt(argc, argv, "dD:nNf:v")) != -1) {
+ while ((c = getopt(argc, argv, "dD:nNf:r:v")) != -1) {
switch (c) {
case 'd':
debug = 1;
@@ -126,6 +127,9 @@ main(int argc, char *argv[])
case 'f':
conffile = optarg;
break;
+ case 'r':
+ rcsock = optarg;
+ break;
case 'v':
flags |= SNMPD_F_VERBOSE;
break;
@@ -154,6 +158,11 @@ main(int argc, char *argv[])
if (getpwnam(SNMPD_USER) == NULL)
errx(1, "unknown user %s", SNMPD_USER);
+ /* Configure the control sockets */
+ env->sc_csock.cs_name = SNMPD_SOCKET;
+ env->sc_rcsock.cs_name = rcsock;
+ env->sc_rcsock.cs_restricted = 1;
+
log_init(debug);
if (!debug) {
@@ -218,7 +227,8 @@ snmpd_shutdown(struct snmpd *env)
fatal("wait");
} while (pid != -1 || (pid == -1 && errno == EINTR));
- control_cleanup();
+ control_cleanup(&env->sc_csock);
+ control_cleanup(&env->sc_rcsock);
log_info("terminating");
exit(0);
}
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index 16969ebf1dd..36960ba50a3 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.20 2008/07/18 12:30:06 reyk Exp $ */
+/* $OpenBSD: snmpd.h,v 1.21 2008/09/26 15:19:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -118,10 +118,12 @@ enum {
} snmpd_process;
/* initially control.h */
-struct {
- struct event ev;
- int fd;
-} control_state;
+struct control_sock {
+ const char *cs_name;
+ struct event cs_ev;
+ int cs_fd;
+ int cs_restricted;
+};
enum blockmodes {
BM_NORMAL,
@@ -322,6 +324,9 @@ struct snmpd {
struct event sc_ev;
struct timeval sc_starttime;
+ struct control_sock sc_csock;
+ struct control_sock sc_rcsock;
+
char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_trcommunity[SNMPD_MAXCOMMUNITYLEN];
@@ -332,12 +337,12 @@ struct snmpd {
};
/* control.c */
-int control_init(void);
-int control_listen(struct snmpd *, struct imsgbuf *);
+int control_init(struct control_sock *);
+int control_listen(struct control_sock *);
void control_accept(int, short, void *);
void control_dispatch_imsg(int, short, void *);
void control_imsg_forward(struct imsg *);
-void control_cleanup(void);
+void control_cleanup(struct control_sock *);
void session_socket_blockmode(int, enum blockmodes);
diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c
index 37f4b6d9901..62623104f70 100644
--- a/usr.sbin/snmpd/snmpe.c
+++ b/usr.sbin/snmpd/snmpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpe.c,v 1.20 2008/09/03 13:41:49 jsg Exp $ */
+/* $OpenBSD: snmpe.c,v 1.21 2008/09/26 15:19:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -88,8 +88,10 @@ snmpe(struct snmpd *x_env, int pipe_parent2snmpe[2])
env = x_env;
- if (control_init() == -1)
+ if (control_init(&env->sc_csock) == -1)
fatalx("snmpe: control socket setup failed");
+ if (control_init(&env->sc_rcsock) == -1)
+ fatalx("snmpe: restricted control socket setup failed");
if ((env->sc_sock = snmpe_bind(&env->sc_address)) == -1)
fatalx("snmpe: failed to bind SNMP UDP socket");
@@ -147,8 +149,10 @@ snmpe(struct snmpd *x_env, int pipe_parent2snmpe[2])
TAILQ_INIT(&ctl_conns);
- if (control_listen(env, ibuf_parent) == -1)
+ if (control_listen(&env->sc_csock) == -1)
fatalx("snmpe: control socket listen failed");
+ if (control_listen(&env->sc_rcsock) == -1)
+ fatalx("snmpe: restricted control socket listen failed");
event_set(&env->sc_ev, env->sc_sock, EV_READ|EV_PERSIST,
snmpe_recvmsg, env);