/*
 * 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;
}
Exemplo n.º 2
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"));
}
Exemplo n.º 3
0
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;
}