/* * AgentX Configuration */ #include #include #include #include #ifdef HAVE_STDLIB_H #include #endif #if HAVE_STRING_H #include #else #include #endif #include #include #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 */ #ifdef USING_AGENTX_SUBAGENT_MODULE void agentx_parse_agentx_ping_interval(const char *token, char *cptr) { int x = atoi(cptr); DEBUGMSGTL(("agentx/config/ping", "%s\n", cptr)); if (x < 1) { config_perror("Invalid ping interval value"); return; } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, x); } #endif /* USING_AGENTX_SUBAGENT_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"); agentx_register_config_handler("agentxRetries", agentx_parse_agentx_retries, NULL, "AgentX Retries"); /* default to 5 retries */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_RETRIES, 5); agentx_register_config_handler("agentxTimeout", agentx_parse_agentx_timeout, NULL, "AgentX Timeout (seconds)"); /* default to 1 second */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT, 1 * ONE_SEC); #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]]]"); } #endif /* USING_AGENTX_MASTER_MODULE */ #ifdef USING_AGENTX_SUBAGENT_MODULE /* * tokens for subagent */ if (SUB_AGENT == agent_role) { agentx_register_config_handler("agentxPingInterval", agentx_parse_agentx_ping_interval, NULL, "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 */ }