void real_init_master(void) { netsnmp_session sess, *session = NULL; char *agentx_sockets; char *cp1; if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT) return; if (netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)) { agentx_sockets = strdup(netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)); #ifdef NETSNMP_AGENTX_DOM_SOCK_ONLY if (agentx_sockets[0] != '/') { /* unix:/path */ if (agentx_sockets[5] != '/') { snmp_log(LOG_ERR, "Error: %s transport is not supported, disabling agentx/master.\n", agentx_sockets); SNMP_FREE(agentx_sockets); return; } } #endif } else { agentx_sockets = strdup(""); } DEBUGMSGTL(("agentx/master", "initializing...\n")); snmp_sess_init(&sess); sess.version = AGENTX_VERSION_1; sess.flags |= SNMP_FLAGS_STREAM_SOCKET; sess.timeout = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT); sess.retries = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_RETRIES); #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN { int agentx_dir_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_DIR_PERM); if (agentx_dir_perm == 0) agentx_dir_perm = NETSNMP_AGENT_DIRECTORY_MODE; netsnmp_unix_create_path_with_mode(agentx_dir_perm); } #endif cp1 = agentx_sockets; while (cp1) { netsnmp_transport *t; /* * If the AgentX socket string contains multiple descriptors, * then pick this apart and handle them one by one. * */ sess.peername = cp1; cp1 = strchr(sess.peername, ','); if (cp1 != NULL) { *cp1++ = '\0'; } /* * Let 'snmp_open' interpret the descriptor. */ sess.local_port = AGENTX_PORT; /* Indicate server & set default port */ sess.remote_port = 0; sess.callback = handle_master_agentx_packet; errno = 0; t = netsnmp_transport_open_server("agentx", sess.peername); if (t == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session * pointer. */ char buf[1024]; if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { snprintf(buf, sizeof(buf), "Error: Couldn't open a master agentx socket to " "listen on (%s)", sess.peername); snmp_sess_perror(buf, &sess); exit(1); } else { snprintf(buf, sizeof(buf), "Warning: Couldn't open a master agentx socket to " "listen on (%s)", sess.peername); netsnmp_sess_log_error(LOG_WARNING, buf, &sess); } } else { #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN if (t->domain == netsnmp_UnixDomain && t->local != NULL) { /* * Apply any settings to the ownership/permissions of the * AgentX socket */ int agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_PERM); int agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_USER); int agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_GROUP); char name[sizeof(struct sockaddr_un) + 1]; memcpy(name, t->local, t->local_length); name[t->local_length] = '\0'; if (agentx_sock_perm != 0) chmod(name, agentx_sock_perm); if (agentx_sock_user || agentx_sock_group) { /* * If either of user or group haven't been set, * then leave them unchanged. */ if (agentx_sock_user == 0 ) agentx_sock_user = -1; if (agentx_sock_group == 0 ) agentx_sock_group = -1; chown(name, agentx_sock_user, agentx_sock_group); } } #endif session = snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet, NULL); } if (session == NULL) { netsnmp_transport_free(t); } } #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN netsnmp_unix_dont_create_path(); #endif SNMP_FREE(agentx_sockets); DEBUGMSGTL(("agentx/master", "initializing... DONE\n")); }
void real_init_master(void) { netsnmp_session sess, *session; char *agentx_sockets; char *cp1, *cp2; #ifdef SNMP_TRANSPORT_UNIX_DOMAIN int agentx_dir_perm; int agentx_sock_perm; int agentx_sock_user; int agentx_sock_group; #endif if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT) return; if (netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)) { agentx_sockets = strdup(netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)); #ifdef AGENTX_DOM_SOCK_ONLY if (agentx_sockets[0] != '/') { /* unix:/path */ if (agentx_sockets[5] != '/') { snmp_log(LOG_ERR, "Error: %s transport is not supported, disabling agentx/master.\n", agentx_sockets); SNMP_FREE(agentx_sockets); return; } } #endif } else { agentx_sockets = strdup(AGENTX_SOCKET); } DEBUGMSGTL(("agentx/master", "initializing...\n")); snmp_sess_init(&sess); sess.version = AGENTX_VERSION_1; sess.flags |= SNMP_FLAGS_STREAM_SOCKET; sess.timeout = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT); sess.retries = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_RETRIES); cp1 = agentx_sockets; while (1) { /* * If the AgentX socket string contains multiple descriptors, * then pick this apart and handle them one by one. * */ cp2 = strchr(cp1, ','); if (cp2 != NULL) { *cp2 = '\0'; } sess.peername = cp1; if (cp2 != NULL) { cp1 = cp2+1; } if (sess.peername[0] == '/') { #ifdef SNMP_TRANSPORT_UNIX_DOMAIN /* * If this is a Unix pathname, * try and create the directory first. */ agentx_dir_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_DIR_PERM); if (agentx_dir_perm == 0) agentx_dir_perm = AGENT_DIRECTORY_MODE; if (mkdirhier(sess.peername, (mode_t)agentx_dir_perm, 1)) { snmp_log(LOG_ERR, "Failed to create the directory for the agentX socket: %s\n", sess.peername); } #else netsnmp_sess_log_error(LOG_WARNING, "unix domain support not available\n", &sess); #endif } /* * Otherwise, let 'snmp_open' interpret the string. */ sess.local_port = AGENTX_PORT; /* Indicate server & set default port */ sess.remote_port = 0; sess.callback = handle_master_agentx_packet; session = snmp_open_ex(&sess, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet); if (session == NULL && sess.s_errno == EADDRINUSE) { /* * Could be a left-over socket (now deleted) * Try again */ session = snmp_open_ex(&sess, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet); } if (session == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { snmp_sess_perror ("Error: Couldn't open a master agentx socket to listen on", &sess); exit(1); } else { netsnmp_sess_log_error(LOG_WARNING, "Warning: Couldn't open a agentx master socket to listen on", &sess); } } #ifdef SNMP_TRANSPORT_UNIX_DOMAIN /* * Apply any settings to the ownership/permissions of the AgentX socket */ agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_PERM); agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_USER); agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCK_GROUP); if (agentx_sock_perm != 0) chmod(sess.peername, agentx_sock_perm); if (agentx_sock_user || agentx_sock_group) { /* * If either of user or group haven't been set, * then leave them unchanged. */ if (agentx_sock_user == 0 ) agentx_sock_user = -1; if (agentx_sock_group == 0 ) agentx_sock_group = -1; chown(sess.peername, agentx_sock_user, agentx_sock_group); } #endif /* * If we've processed the last (or only) socket, then we're done. */ if (!cp2) break; } SNMP_FREE(agentx_sockets); DEBUGMSGTL(("agentx/master", "initializing... DONE\n")); }
/* * Open a session to the master agent. */ int subagent_open_master_session(void) { netsnmp_transport *t; netsnmp_session sess; DEBUGMSGTL(("agentx/subagent", "opening session...\n")); if (main_session) { snmp_log(LOG_WARNING, "AgentX session to master agent attempted to be re-opened."); return -1; } snmp_sess_init(&sess); sess.version = AGENTX_VERSION_1; sess.retries = SNMP_DEFAULT_RETRIES; sess.timeout = SNMP_DEFAULT_TIMEOUT; sess.flags |= SNMP_FLAGS_STREAM_SOCKET; sess.callback = handle_agentx_packet; sess.authenticator = NULL; t = netsnmp_transport_open_client( "agentx", netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)); if (t == NULL) { /* * Diagnose snmp_open errors with the input * netsnmp_session pointer. */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) { char buf[1024]; const char *socket = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET); snprintf(buf, sizeof(buf), "Warning: " "Failed to connect to the agentx master agent (%s)", socket ? socket : "[NIL]"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { netsnmp_sess_log_error(LOG_WARNING, buf, &sess); } else { snmp_sess_perror(buf, &sess); } } return -1; } main_session = snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet, NULL); if (main_session == NULL) { if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) { char buf[1024]; snprintf(buf, sizeof(buf), "Error: " "Failed to create the agentx master agent session (%s)", netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)); snmp_sess_perror(buf, &sess); } netsnmp_transport_free(t); return -1; } /* * I don't know why 1 is success instead of the usual 0 = noerr, * but that's what the function returns. */ if (1 != agentx_open_session(main_session)) { snmp_close(main_session); main_session = NULL; return -1; } if (add_trap_session(main_session, AGENTX_MSG_NOTIFY, 1, AGENTX_VERSION_1)) { DEBUGMSGTL(("agentx/subagent", " trap session registered OK\n")); } else { DEBUGMSGTL(("agentx/subagent", "trap session registration failed\n")); snmp_close(main_session); main_session = NULL; return -1; } agentx_register_callbacks(main_session); snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_INDEX_START, (void *) main_session); snmp_log(LOG_INFO, "NET-SNMP version %s AgentX subagent connected\n", netsnmp_get_version()); DEBUGMSGTL(("agentx/subagent", "opening session... DONE (%p)\n", main_session)); return 0; }
/* * Open a session to the master agent. */ int subagent_open_master_session(void) { netsnmp_session sess; DEBUGMSGTL(("agentx/subagent", "opening session...\n")); if (main_session) { snmp_log(LOG_WARNING, "AgentX session to master agent attempted to be re-opened."); return -1; } snmp_sess_init(&sess); sess.version = AGENTX_VERSION_1; sess.retries = SNMP_DEFAULT_RETRIES; sess.timeout = SNMP_DEFAULT_TIMEOUT; sess.flags |= SNMP_FLAGS_STREAM_SOCKET; if (netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)) { sess.peername = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET); } else { sess.peername = strdup(AGENTX_SOCKET); } sess.local_port = 0; /* client */ sess.remote_port = AGENTX_PORT; /* default port */ sess.callback = handle_agentx_packet; sess.authenticator = NULL; main_session = snmp_open_ex(&sess, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet); if (main_session == NULL) { /* * Diagnose snmp_open errors with the input * netsnmp_session pointer. */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) { if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { netsnmp_sess_log_error(LOG_WARNING, "Error: Failed to connect to the agentx master agent", &sess); } else { snmp_sess_perror ("Error: Failed to connect to the agentx master agent", &sess); } } return -1; } if (agentx_open_session(main_session) < 0) { snmp_close(main_session); main_session = NULL; return -1; } if (add_trap_session(main_session, AGENTX_MSG_NOTIFY, 1, AGENTX_VERSION_1)) { DEBUGMSGTL(("agentx/subagent", " trap session registered OK\n")); } else { DEBUGMSGTL(("agentx/subagent", "trap session registration failed\n")); snmp_close(main_session); main_session = NULL; return -1; } agentx_register_callbacks(main_session); snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_INDEX_START, (void *) main_session); DEBUGMSGTL(("agentx/subagent", "opening session... DONE (%p)\n", main_session)); return 0; }