/* * 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; }
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")); }
netsnmp_session * asmp_open(netsnmp_session *in_session) { netsnmp_session *session; netsnmp_transport *transport; if (in_session == NULL) return NULL; netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT, ASMP_PORT); if ((in_session->version == SNMP_VERSION_2c || in_session->version == SNMP_VERSION_1) && (!strncmp(in_session->peername, "asmp:", 5) || !strncmp(in_session->peername, "asmps:", 6) || !strncmp(in_session->peername, "aidp:", 5))) { /* Set TCP flag for non-AIDP connection */ if (strncmp(in_session->peername, "aidp:", 5)) in_session->flags |= SNMP_FLAGS_STREAM_SOCKET; if (in_session->flags & SNMP_FLAGS_STREAM_SOCKET) { transport = netsnmp_tdomain_transport_full("asmp", in_session->peername, in_session->local_port, "tcp", NULL); } else { transport = netsnmp_tdomain_transport_full("aidp", in_session->peername, in_session->local_port, "udp", NULL); } // hook_create_pdu session = snmp_add_full(in_session, transport, NULL, _hook_parse, NULL, _hook_build, NULL, _hook_check, NULL); if (session != NULL && (session->flags & SNMP_FLAGS_STREAM_SOCKET)) { if (asmp_sess_setup(session) != 0) goto free; if (asmp_sess_login(session, ((struct asmp_connection *)transport->data)->proto == ASMP_PROTO_ASMPS ? session->securityName : "", "") != 0) { goto free; } fprintf(stderr, "ASMP initialized\n"); } } else { session = NULL; } return session; free: free(session); return NULL; }