Blame snmplib/snmp_service.c

Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
Packit fcad23
#include <stdlib.h>
Packit fcad23
#include <string.h>
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
#include <net-snmp/library/snmp_transport.h>
Packit fcad23
Packit fcad23
static char**
Packit fcad23
create_word_array_helper(const char* cptr, size_t idx, char* tmp, size_t tmplen)
Packit fcad23
{
Packit fcad23
    char* item;
Packit fcad23
    char** res;
Packit fcad23
    cptr = copy_nword_const(cptr, tmp, tmplen);
Packit fcad23
    item = strdup(tmp);
Packit fcad23
    if (cptr)
Packit fcad23
        res = create_word_array_helper(cptr, idx + 1, tmp, tmplen);
Packit fcad23
    else {
Packit fcad23
        res = (char**)malloc(sizeof(char*) * (idx + 2));
Packit fcad23
        res[idx + 1] = NULL;
Packit fcad23
    }
Packit fcad23
    res[idx] = item;
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
static char**
Packit fcad23
create_word_array(const char* cptr)
Packit fcad23
{
Packit fcad23
    size_t tmplen = strlen(cptr);
Packit fcad23
    char* tmp = (char*)malloc(tmplen + 1);
Packit fcad23
    char** res = create_word_array_helper(cptr, 0, tmp, tmplen + 1);
Packit fcad23
    free(tmp);
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
destroy_word_array(char** arr)
Packit fcad23
{
Packit fcad23
    if (arr) {
Packit fcad23
        char** run = arr;
Packit fcad23
        while(*run) {
Packit fcad23
            free(*run);
Packit fcad23
            ++run;
Packit fcad23
        }
Packit fcad23
        free(arr);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
struct netsnmp_lookup_domain {
Packit fcad23
    char* application;
Packit fcad23
    char** userDomain;
Packit fcad23
    char** domain;
Packit fcad23
    struct netsnmp_lookup_domain* next;
Packit fcad23
};
Packit fcad23
Packit fcad23
static struct netsnmp_lookup_domain* domains = NULL;
Packit fcad23
Packit fcad23
int
Packit fcad23
netsnmp_register_default_domain(const char* application, const char* domain)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
Packit fcad23
    int res = 0;
Packit fcad23
Packit fcad23
    while (run != NULL && strcmp(run->application, application) < 0) {
Packit fcad23
	prev = run;
Packit fcad23
	run = run->next;
Packit fcad23
    }
Packit fcad23
    if (run && strcmp(run->application, application) == 0) {
Packit fcad23
      if (run->domain != NULL) {
Packit fcad23
          destroy_word_array(run->domain);
Packit fcad23
	  run->domain = NULL;
Packit fcad23
	  res = 1;
Packit fcad23
      }
Packit fcad23
    } else {
Packit fcad23
	run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain);
Packit fcad23
	run->application = strdup(application);
Packit fcad23
	run->userDomain = NULL;
Packit fcad23
	if (prev) {
Packit fcad23
	    run->next = prev->next;
Packit fcad23
	    prev->next = run;
Packit fcad23
	} else {
Packit fcad23
	    run->next = domains;
Packit fcad23
	    domains = run;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
    if (domain) {
Packit fcad23
        run->domain = create_word_array(domain);
Packit fcad23
    } else if (run->userDomain == NULL) {
Packit fcad23
	if (prev)
Packit fcad23
	    prev->next = run->next;
Packit fcad23
	else
Packit fcad23
	    domains = run->next;
Packit fcad23
	free(run->application);
Packit fcad23
	free(run);
Packit fcad23
    }
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
void
Packit fcad23
netsnmp_clear_default_domain(void)
Packit fcad23
{
Packit fcad23
    while (domains) {
Packit fcad23
	struct netsnmp_lookup_domain *tmp = domains;
Packit fcad23
	domains = domains->next;
Packit fcad23
	free(tmp->application);
Packit fcad23
        destroy_word_array(tmp->userDomain);
Packit fcad23
        destroy_word_array(tmp->domain);
Packit fcad23
	free(tmp);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
netsnmp_register_user_domain(const char* token, char* cptr)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
Packit fcad23
    size_t len = strlen(cptr) + 1;
Packit fcad23
    char* application = (char*)malloc(len);
Packit fcad23
    char** domain;
Packit fcad23
Packit fcad23
    {
Packit fcad23
        char* cp = copy_nword(cptr, application, len);
Packit fcad23
        if (cp == NULL) {
Packit fcad23
            netsnmp_config_error("No domain(s) in registration of "
Packit fcad23
                                 "defDomain \"%s\"", application);
Packit fcad23
            free(application);
Packit fcad23
            return;
Packit fcad23
        }
Packit fcad23
        domain = create_word_array(cp);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    while (run != NULL && strcmp(run->application, application) < 0) {
Packit fcad23
	prev = run;
Packit fcad23
	run = run->next;
Packit fcad23
    }
Packit fcad23
    if (run && strcmp(run->application, application) == 0) {
Packit fcad23
	if (run->userDomain != NULL) {
Packit fcad23
	    config_perror("Default transport already registered for this "
Packit fcad23
			  "application");
Packit fcad23
            destroy_word_array(domain);
Packit fcad23
            free(application);
Packit fcad23
	    return;
Packit fcad23
	}
Packit fcad23
    } else {
Packit fcad23
	run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain);
Packit fcad23
	run->application = strdup(application);
Packit fcad23
	run->domain = NULL;
Packit fcad23
	if (prev) {
Packit fcad23
	    run->next = prev->next;
Packit fcad23
	    prev->next = run;
Packit fcad23
	} else {
Packit fcad23
	    run->next = domains;
Packit fcad23
	    domains = run;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
    run->userDomain = domain;
Packit fcad23
    free(application);
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
netsnmp_clear_user_domain(void)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
Packit fcad23
Packit fcad23
    while (run) {
Packit fcad23
	if (run->userDomain != NULL) {
Packit fcad23
            destroy_word_array(run->userDomain);
Packit fcad23
	    run->userDomain = NULL;
Packit fcad23
	}
Packit fcad23
	if (run->domain == NULL) {
Packit fcad23
	    struct netsnmp_lookup_domain *tmp = run;
Packit fcad23
	    if (prev)
Packit fcad23
		run = prev->next = run->next;
Packit fcad23
	    else
Packit fcad23
		run = domains = run->next;
Packit fcad23
	    free(tmp->application);
Packit fcad23
	    free(tmp);
Packit fcad23
	} else {
Packit fcad23
	    prev = run;
Packit fcad23
	    run = run->next;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
const char* const *
Packit fcad23
netsnmp_lookup_default_domains(const char* application)
Packit fcad23
{
Packit fcad23
    const char * const * res;
Packit fcad23
Packit fcad23
    if (application == NULL)
Packit fcad23
	res = NULL;
Packit fcad23
    else {
Packit fcad23
        struct netsnmp_lookup_domain *run = domains;
Packit fcad23
Packit fcad23
	while (run && strcmp(run->application, application) < 0)
Packit fcad23
	    run = run->next;
Packit fcad23
	if (run && strcmp(run->application, application) == 0)
Packit fcad23
	    if (run->userDomain)
Packit fcad23
                res = (const char * const *)run->userDomain;
Packit fcad23
	    else
Packit fcad23
                res = (const char * const *)run->domain;
Packit fcad23
	else
Packit fcad23
	    res = NULL;
Packit fcad23
    }
Packit fcad23
    DEBUGMSGTL(("defaults",
Packit fcad23
                "netsnmp_lookup_default_domain(\"%s\") ->",
Packit fcad23
                application ? application : "[NIL]"));
Packit fcad23
    if (res) {
Packit fcad23
        const char * const * r = res;
Packit fcad23
        while(*r) {
Packit fcad23
            DEBUGMSG(("defaults", " \"%s\"", *r));
Packit fcad23
            ++r;
Packit fcad23
        }
Packit fcad23
        DEBUGMSG(("defaults", "\n"));
Packit fcad23
    } else
Packit fcad23
        DEBUGMSG(("defaults", " \"[NIL]\"\n"));
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
const char*
Packit fcad23
netsnmp_lookup_default_domain(const char* application)
Packit fcad23
{
Packit fcad23
    const char * const * res = netsnmp_lookup_default_domains(application);
Packit fcad23
    return (res ? *res : NULL);
Packit fcad23
}
Packit fcad23
Packit fcad23
struct netsnmp_lookup_target {
Packit fcad23
    char* application;
Packit fcad23
    char* domain;
Packit fcad23
    char* userTarget;
Packit fcad23
    char* target;
Packit fcad23
    struct netsnmp_lookup_target* next;
Packit fcad23
};
Packit fcad23
Packit fcad23
static struct netsnmp_lookup_target* targets = NULL;
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * Add an (application, domain, target) triplet to the targets list if target
Packit fcad23
 * != NULL. Remove an entry if target == NULL and the userTarget pointer for
Packit fcad23
 * the entry found is also NULL. Keep at most one target per (application,
Packit fcad23
 * domain) pair.
Packit fcad23
 *
Packit fcad23
 * @return 1 if an entry for (application, domain) was already present in the
Packit fcad23
 *   targets list or 0 if such an entry was not yet present in the targets list.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
netsnmp_register_default_target(const char* application, const char* domain,
Packit fcad23
				const char* target)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
Packit fcad23
    int i = 0, res = 0;
Packit fcad23
    while (run && ((i = strcmp(run->application, application)) < 0 ||
Packit fcad23
		   (i == 0 && strcmp(run->domain, domain) < 0))) {
Packit fcad23
	prev = run;
Packit fcad23
	run = run->next;
Packit fcad23
    }
Packit fcad23
    if (run && i == 0 && strcmp(run->domain, domain) == 0) {
Packit fcad23
      if (run->target != NULL) {
Packit fcad23
	    free(run->target);
Packit fcad23
	    run->target = NULL;
Packit fcad23
	    res = 1;
Packit fcad23
      }
Packit fcad23
    } else {
Packit fcad23
	run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target);
Packit fcad23
	run->application = strdup(application);
Packit fcad23
	run->domain = strdup(domain);
Packit fcad23
	run->userTarget = NULL;
Packit fcad23
	if (prev) {
Packit fcad23
	    run->next = prev->next;
Packit fcad23
	    prev->next = run;
Packit fcad23
	} else {
Packit fcad23
	    run->next = targets;
Packit fcad23
	    targets = run;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
    if (target) {
Packit fcad23
	run->target = strdup(target);
Packit fcad23
    } else if (run->userTarget == NULL) {
Packit fcad23
	if (prev)
Packit fcad23
	    prev->next = run->next;
Packit fcad23
	else
Packit fcad23
	    targets = run->next;
Packit fcad23
	free(run->domain);
Packit fcad23
	free(run->application);
Packit fcad23
	free(run);
Packit fcad23
    }
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * Clear the targets list.
Packit fcad23
 */
Packit fcad23
void
Packit fcad23
netsnmp_clear_default_target(void)
Packit fcad23
{
Packit fcad23
    while (targets) {
Packit fcad23
	struct netsnmp_lookup_target *tmp = targets;
Packit fcad23
	targets = targets->next;
Packit fcad23
	free(tmp->application);
Packit fcad23
	free(tmp->domain);
Packit fcad23
	free(tmp->userTarget);
Packit fcad23
	free(tmp->target);
Packit fcad23
	free(tmp);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
netsnmp_register_user_target(const char* token, char* cptr)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
Packit fcad23
    size_t len = strlen(cptr) + 1;
Packit fcad23
    char* application = (char*)malloc(len);
Packit fcad23
    char* domain = (char*)malloc(len);
Packit fcad23
    char* target = (char*)malloc(len);
Packit fcad23
    int i = 0;
Packit fcad23
Packit fcad23
    {
Packit fcad23
	char* cp = copy_nword(cptr, application, len);
Packit fcad23
        if (cp == NULL) {
Packit fcad23
            netsnmp_config_error("No domain and target in registration of "
Packit fcad23
                                 "defTarget \"%s\"", application);
Packit fcad23
            goto done;
Packit fcad23
        }
Packit fcad23
	cp = copy_nword(cp, domain, len);
Packit fcad23
        if (cp == NULL) {
Packit fcad23
            netsnmp_config_error("No target in registration of "
Packit fcad23
                                 "defTarget \"%s\" \"%s\"",
Packit fcad23
                                 application, domain);
Packit fcad23
            goto done;
Packit fcad23
        }
Packit fcad23
	cp = copy_nword(cp, target, len);
Packit fcad23
	if (cp)
Packit fcad23
	    config_pwarn("Trailing junk found");
Packit fcad23
    }
Packit fcad23
Packit fcad23
    while (run && ((i = strcmp(run->application, application)) < 0 ||
Packit fcad23
		   (i == 0 && strcmp(run->domain, domain) < 0))) {
Packit fcad23
	prev = run;
Packit fcad23
	run = run->next;
Packit fcad23
    }
Packit fcad23
    if (run && i == 0 && strcmp(run->domain, domain) == 0) {
Packit fcad23
	if (run->userTarget != NULL) {
Packit fcad23
	    config_perror("Default target already registered for this "
Packit fcad23
			  "application-domain combination");
Packit fcad23
	    goto done;
Packit fcad23
	}
Packit fcad23
    } else {
Packit fcad23
	run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target);
Packit fcad23
	run->application = strdup(application);
Packit fcad23
	run->domain = strdup(domain);
Packit fcad23
	run->target = NULL;
Packit fcad23
	if (prev) {
Packit fcad23
	    run->next = prev->next;
Packit fcad23
	    prev->next = run;
Packit fcad23
	} else {
Packit fcad23
	    run->next = targets;
Packit fcad23
	    targets = run;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
    run->userTarget = strdup(target);
Packit fcad23
 done:
Packit fcad23
    free(target);
Packit fcad23
    free(domain);
Packit fcad23
    free(application);
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
netsnmp_clear_user_target(void)
Packit fcad23
{
Packit fcad23
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
Packit fcad23
Packit fcad23
    while (run) {
Packit fcad23
	if (run->userTarget != NULL) {
Packit fcad23
	    free(run->userTarget);
Packit fcad23
	    run->userTarget = NULL;
Packit fcad23
	}
Packit fcad23
	if (run->target == NULL) {
Packit fcad23
	    struct netsnmp_lookup_target *tmp = run;
Packit fcad23
	    if (prev)
Packit fcad23
		run = prev->next = run->next;
Packit fcad23
	    else
Packit fcad23
		run = targets = run->next;
Packit fcad23
	    free(tmp->application);
Packit fcad23
	    free(tmp->domain);
Packit fcad23
	    free(tmp);
Packit fcad23
	} else {
Packit fcad23
	    prev = run;
Packit fcad23
	    run = run->next;
Packit fcad23
	}
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
const char*
Packit fcad23
netsnmp_lookup_default_target(const char* application, const char* domain)
Packit fcad23
{
Packit fcad23
    int i = 0;
Packit fcad23
    struct netsnmp_lookup_target *run = targets;
Packit fcad23
    const char *res;
Packit fcad23
Packit fcad23
    if (application == NULL || domain == NULL)
Packit fcad23
	res = NULL;
Packit fcad23
    else {
Packit fcad23
	while (run && ((i = strcmp(run->application, application)) < 0 ||
Packit fcad23
		       (i == 0 && strcmp(run->domain, domain) < 0)))
Packit fcad23
	    run = run->next;
Packit fcad23
	if (run && i == 0 && strcmp(run->domain, domain) == 0)
Packit fcad23
	    if (run->userTarget != NULL)
Packit fcad23
		res = run->userTarget;
Packit fcad23
	    else
Packit fcad23
		res = run->target;
Packit fcad23
	else
Packit fcad23
	    res = NULL;
Packit fcad23
    }
Packit fcad23
    DEBUGMSGTL(("defaults",
Packit fcad23
		"netsnmp_lookup_default_target(\"%s\", \"%s\") -> \"%s\"\n",
Packit fcad23
		application ? application : "[NIL]",
Packit fcad23
		domain ? domain : "[NIL]",
Packit fcad23
		res ? res : "[NIL]"));
Packit fcad23
    return res;
Packit fcad23
}
Packit fcad23
Packit fcad23
void
Packit fcad23
netsnmp_register_service_handlers(void)
Packit fcad23
{
Packit fcad23
    register_config_handler("snmp:", "defDomain",
Packit fcad23
			    netsnmp_register_user_domain,
Packit fcad23
			    netsnmp_clear_user_domain,
Packit fcad23
			    "application domain");
Packit fcad23
    register_config_handler("snmp:", "defTarget",
Packit fcad23
			    netsnmp_register_user_target,
Packit fcad23
			    netsnmp_clear_user_target,
Packit fcad23
			    "application domain target");
Packit fcad23
}