mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
libbsnmp: make binding of client UNIX socket optional and configurable
Before this change snmp_open(3) would always bind(2) client socket to a
random "/tmp/snmpXXXXXXXXXXXXXX" name. However, this binding is not
required for SOCK_STREAM transport. Also, any attempt to specify a
different name would fail, as open_client_local() would blindly rewrite
the name to the default.
Make this binding optional. If application had initialized
snmp_client.local_path, then try to bind to the specified pathname,
otherwise perform the random name binding only if we are in the
SOCK_DGRAM mode.
While here change snmp_client.local_path size to SUNPATHLEN, so that any
legitimate local socket name can be used. This requires library version
bump.
Note that this code has been broken by 81e0e7b9e3 for three years, thus
it is known not to be widely used.
Reviewed by: harti
Differential Revision: https://reviews.freebsd.org/D51070
This commit is contained in:
parent
b9fa99600a
commit
777123969d
7 changed files with 69 additions and 41 deletions
|
|
@ -51,6 +51,9 @@
|
|||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20250725: libbsnmp bumped to version 7
|
||||
OLD_LIBS+=usr/lib/libbsnmp.so.6
|
||||
|
||||
# 20250725: Files which were briefly installed by WITH_MITKRB5 in 15.0.
|
||||
OLD_FILES+=usr/include/kadm5/admin_internal.h
|
||||
OLD_FILES+=usr/include/kadm5/admin_xdr.h
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
.\"
|
||||
.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
|
||||
.\"
|
||||
.Dd March 31, 2020
|
||||
.Dd June 24, 2025
|
||||
.Dt BSNMPCLIENT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -155,7 +155,7 @@ struct snmp_client {
|
|||
snmp_timeout_start_f timeout_start;
|
||||
snmp_timeout_stop_f timeout_stop;
|
||||
|
||||
char local_path[sizeof(SNMP_LOCAL_PATH)];
|
||||
char local_path[SUNPATHLEN];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
|
|
@ -285,8 +285,19 @@ The function will be called with the return value of the corresponding
|
|||
.Fn timeout_start
|
||||
function.
|
||||
.It Va local_path
|
||||
If in local socket mode, the name of the clients socket.
|
||||
Not needed by the application.
|
||||
In local socket mode, optional path name the client socket shall be bound to
|
||||
before connecting to the server.
|
||||
For
|
||||
.Dv SOCK_STREAM
|
||||
local socket the named path is optional, and library will skip
|
||||
.Xr bind 2
|
||||
if path is not provided.
|
||||
For
|
||||
.Dv SOCK_DGRAM
|
||||
local socket the named path is required, thus library will create a random
|
||||
one in
|
||||
.Pa /tmp
|
||||
if path is not provided.
|
||||
.El
|
||||
.Pp
|
||||
In the current implementation there is a global variable
|
||||
|
|
|
|||
|
|
@ -977,7 +977,10 @@ remove_local(void)
|
|||
static int
|
||||
open_client_local(const char *path)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
struct sockaddr_un sa = {
|
||||
.sun_family = AF_LOCAL,
|
||||
.sun_len = sizeof(sa),
|
||||
};
|
||||
char *ptr;
|
||||
int stype;
|
||||
|
||||
|
|
@ -1003,43 +1006,56 @@ open_client_local(const char *path)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
snprintf(snmp_client.local_path, sizeof(snmp_client.local_path),
|
||||
"%s", SNMP_LOCAL_PATH);
|
||||
|
||||
if (mktemp(snmp_client.local_path) == NULL) {
|
||||
seterr(&snmp_client, "%s", strerror(errno));
|
||||
(void)close(snmp_client.fd);
|
||||
snmp_client.fd = -1;
|
||||
return (-1);
|
||||
/*
|
||||
* A datagram socket requires a name to receive replies back. Would
|
||||
* be cool to have an extension to unix(4) sockets similar to ip(4)
|
||||
* IP_RECVDSTADDR/IP_SENDSRCADDR, so that a one-to-many datagram
|
||||
* UNIX socket can send replies to its anonymous peers.
|
||||
*/
|
||||
if (snmp_client.trans == SNMP_TRANS_LOC_DGRAM &&
|
||||
snmp_client.local_path[0] == '\0') {
|
||||
(void)strlcpy(snmp_client.local_path, "/tmp/snmpXXXXXXXXXXXXXX",
|
||||
sizeof(snmp_client.local_path));
|
||||
if (mktemp(snmp_client.local_path) == NULL) {
|
||||
seterr(&snmp_client, "mktemp(3): %s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
sa.sun_family = AF_LOCAL;
|
||||
sa.sun_len = sizeof(sa);
|
||||
strcpy(sa.sun_path, snmp_client.local_path);
|
||||
|
||||
if (bind(snmp_client.fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
|
||||
seterr(&snmp_client, "%s", strerror(errno));
|
||||
(void)close(snmp_client.fd);
|
||||
snmp_client.fd = -1;
|
||||
(void)remove(snmp_client.local_path);
|
||||
return (-1);
|
||||
if (snmp_client.local_path[0] != '\0') {
|
||||
if (strlcpy(sa.sun_path, snmp_client.local_path,
|
||||
sizeof(sa.sun_path)) >=
|
||||
sizeof(sa.sun_path)) {
|
||||
seterr(&snmp_client, "%s",
|
||||
"Local socket pathname too long");
|
||||
goto fail;
|
||||
}
|
||||
if (bind(snmp_client.fd, (struct sockaddr *)&sa, sizeof(sa)) ==
|
||||
-1) {
|
||||
seterr(&snmp_client, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
atexit(remove_local);
|
||||
}
|
||||
atexit(remove_local);
|
||||
|
||||
sa.sun_family = AF_LOCAL;
|
||||
sa.sun_len = offsetof(struct sockaddr_un, sun_path) +
|
||||
strlen(snmp_client.chost);
|
||||
strncpy(sa.sun_path, snmp_client.chost, sizeof(sa.sun_path) - 1);
|
||||
sa.sun_path[sizeof(sa.sun_path) - 1] = '\0';
|
||||
if (strlcpy(sa.sun_path, snmp_client.chost, sizeof(sa.sun_path)) >=
|
||||
sizeof(sa.sun_path)) {
|
||||
seterr(&snmp_client, "%s", "Server socket pathname too long");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(snmp_client.fd, (struct sockaddr *)&sa, sa.sun_len) == -1) {
|
||||
seterr(&snmp_client, "%s", strerror(errno));
|
||||
(void)close(snmp_client.fd);
|
||||
snmp_client.fd = -1;
|
||||
(void)remove(snmp_client.local_path);
|
||||
return (-1);
|
||||
goto fail;
|
||||
}
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
(void)close(snmp_client.fd);
|
||||
snmp_client.fd = -1;
|
||||
if (snmp_client.local_path[0] != '\0')
|
||||
(void)remove(snmp_client.local_path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
@ -42,8 +43,6 @@
|
|||
#define SNMP_STRERROR_LEN 200
|
||||
#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
|
||||
|
||||
#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX"
|
||||
|
||||
/*
|
||||
* transport methods
|
||||
*/
|
||||
|
|
@ -111,7 +110,7 @@ struct snmp_client {
|
|||
snmp_timeout_start_f timeout_start;
|
||||
snmp_timeout_stop_f timeout_stop;
|
||||
|
||||
char local_path[sizeof(SNMP_LOCAL_PATH)];
|
||||
char local_path[SUNPATHLEN];
|
||||
};
|
||||
|
||||
/* the global context */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ CONTRIB= ${SRCTOP}/contrib/bsnmp/lib
|
|||
.PATH: ${CONTRIB}
|
||||
|
||||
LIB= bsnmp
|
||||
SHLIB_MAJOR= 6
|
||||
SHLIB_MAJOR= 7
|
||||
LD_FATAL_WARNINGS= no
|
||||
|
||||
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ OLD_FILES+=usr/include/bsnmp/snmpclient.h
|
|||
OLD_FILES+=usr/include/bsnmp/snmpmod.h
|
||||
OLD_FILES+=usr/lib/libbsnmp.a
|
||||
OLD_FILES+=usr/lib/libbsnmp.so
|
||||
OLD_LIBS+=usr/lib/libbsnmp.so.6
|
||||
OLD_LIBS+=usr/lib/libbsnmp.so.7
|
||||
OLD_FILES+=usr/lib/libbsnmp_p.a
|
||||
OLD_FILES+=usr/lib/libbsnmptools.a
|
||||
OLD_FILES+=usr/lib/libbsnmptools.so
|
||||
|
|
|
|||
|
|
@ -881,12 +881,11 @@ parse_local_path(char *opt_arg)
|
|||
{
|
||||
assert(opt_arg != NULL);
|
||||
|
||||
if (sizeof(opt_arg) > sizeof(SNMP_LOCAL_PATH)) {
|
||||
if (strlcpy(snmp_client.local_path, opt_arg,
|
||||
sizeof(snmp_client.local_path)) >= sizeof(snmp_client.local_path)) {
|
||||
warnx("Filename too long - %s", opt_arg);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strlcpy(snmp_client.local_path, opt_arg, sizeof(SNMP_LOCAL_PATH));
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue