blob: b590c7a689a4ff02b11c427854bab8551a07e038 [file] [log] [blame]
/*
* AgentX Configuration
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "snmpd.h"
#include "agentx/agentx_config.h"
#include "agentx/protocol.h"
netsnmp_feature_require(user_information)
netsnmp_feature_require(string_time_to_secs)
/* ---------------------------------------------------------------------
*
* Common master and sub-agent
*/
void
agentx_parse_agentx_socket(const char *token, char *cptr)
{
DEBUGMSGTL(("agentx/config", "port spec: %s\n", cptr));
netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, cptr);
}
/* ---------------------------------------------------------------------
*
* Master agent
*/
#ifdef USING_AGENTX_MASTER_MODULE
void
agentx_parse_master(const char *token, char *cptr)
{
int i = -1;
if (!strcmp(cptr, "agentx") ||
!strcmp(cptr, "all") ||
!strcmp(cptr, "yes") || !strcmp(cptr, "on")) {
i = 1;
snmp_log(LOG_INFO, "Turning on AgentX master support.\n");
} else if (!strcmp(cptr, "no") || !strcmp(cptr, "off"))
i = 0;
else
i = atoi(cptr);
if (i < 0 || i > 1) {
netsnmp_config_error("master '%s' unrecognised", cptr);
} else
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_MASTER, i);
}
void
agentx_parse_agentx_perms(const char *token, char *cptr)
{
char *socket_perm, *dir_perm, *socket_user, *socket_group;
int uid = -1;
int gid = -1;
int s_perm = -1;
int d_perm = -1;
char *st;
DEBUGMSGTL(("agentx/config", "port permissions: %s\n", cptr));
socket_perm = strtok_r(cptr, " \t", &st);
dir_perm = strtok_r(NULL, " \t", &st);
socket_user = strtok_r(NULL, " \t", &st);
socket_group = strtok_r(NULL, " \t", &st);
if (socket_perm) {
s_perm = strtol(socket_perm, NULL, 8);
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_X_SOCK_PERM, s_perm);
DEBUGMSGTL(("agentx/config", "socket permissions: %o (%d)\n",
s_perm, s_perm));
}
if (dir_perm) {
d_perm = strtol(dir_perm, NULL, 8);
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_X_DIR_PERM, d_perm);
DEBUGMSGTL(("agentx/config", "directory permissions: %o (%d)\n",
d_perm, d_perm));
}
/*
* Try to handle numeric UIDs or user names for the socket owner
*/
if (socket_user) {
uid = netsnmp_str_to_uid(socket_user);
if ( uid != 0 )
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_X_SOCK_USER, uid);
DEBUGMSGTL(("agentx/config", "socket owner: %s (%d)\n",
socket_user, uid));
}
/*
* and similarly for the socket group ownership
*/
if (socket_group) {
gid = netsnmp_str_to_gid(socket_group);
if ( gid != 0 )
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_X_SOCK_GROUP, gid);
DEBUGMSGTL(("agentx/config", "socket group: %s (%d)\n",
socket_group, gid));
}
}
void
agentx_parse_agentx_timeout(const char *token, char *cptr)
{
int x = netsnmp_string_time_to_secs(cptr);
DEBUGMSGTL(("agentx/config/timeout", "%s\n", cptr));
if (x == -1) {
config_perror("Invalid timeout value");
return;
}
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_AGENTX_TIMEOUT, x * ONE_SEC);
}
void
agentx_parse_agentx_retries(const char *token, char *cptr)
{
int x = atoi(cptr);
DEBUGMSGTL(("agentx/config/retries", "%s\n", cptr));
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_AGENTX_RETRIES, x);
}
#endif /* USING_AGENTX_MASTER_MODULE */
/* ---------------------------------------------------------------------
*
* Sub-agent
*/
/* ---------------------------------------------------------------------
*
* Utility support routines
*/
void
agentx_register_config_handler(const char *token,
void (*parser) (const char *, char *),
void (*releaser) (void), const char *help)
{
DEBUGMSGTL(("agentx_register_app_config_handler",
"registering .conf token for \"%s\"\n", token));
register_config_handler(":agentx", token, parser, releaser, help);
}
netsnmp_feature_child_of(agentx_unregister_config_handler, netsnmp_unused)
#ifndef NETSNMP_FEATURE_REMOVE_AGENTX_UNREGISTER_CONFIG_HANDLER
void
agentx_unregister_config_handler(const char *token)
{
unregister_config_handler(":agentx", token);
}
#endif /* NETSNMP_FEATURE_REMOVE_AGENTX_UNREGISTER_CONFIG_HANDLER */
void
agentx_config_init(void)
{
int agent_role = netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_ROLE);
/*
* Common tokens for master/subagent
*/
netsnmp_register_default_domain("agentx", "unix tcp");
netsnmp_register_default_target("agentx", "unix", NETSNMP_AGENTX_SOCKET);
#define val(x) __STRING(x)
netsnmp_register_default_target("agentx", "tcp",
"localhost:" val(AGENTX_PORT));
#undef val
agentx_register_config_handler("agentxsocket",
agentx_parse_agentx_socket, NULL,
"AgentX bind address");
#ifdef USING_AGENTX_MASTER_MODULE
/*
* tokens for master agent
*/
if (MASTER_AGENT == agent_role) {
snmpd_register_config_handler("master",
agentx_parse_master, NULL,
"specify 'agentx' for AgentX support");
agentx_register_config_handler("agentxperms",
agentx_parse_agentx_perms, NULL,
"AgentX socket permissions: socket_perms [directory_perms [username|userid [groupname|groupid]]]");
agentx_register_config_handler("agentxRetries",
agentx_parse_agentx_retries, NULL,
"AgentX Retries");
agentx_register_config_handler("agentxTimeout",
agentx_parse_agentx_timeout, NULL,
"AgentX Timeout (seconds)");
}
#endif /* USING_AGENTX_MASTER_MODULE */
#ifdef USING_AGENTX_SUBAGENT_MODULE
/*
* tokens for master agent
*/
if (SUB_AGENT == agent_role) {
/*
* set up callbacks to initiate master agent pings for this session
*/
netsnmp_ds_register_config(ASN_INTEGER,
netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
NETSNMP_DS_LIB_APPTYPE),
"agentxPingInterval",
NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL);
/* ping and/or reconnect by default every 15 seconds */
netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 15);
}
#endif /* USING_AGENTX_SUBAGENT_MODULE */
}