END_TEST START_TEST (auth_endgrent_test) { int res; authtable authtab; char *sym_name = "endgrent"; pr_auth_endgrent(p); fail_unless(endgrent_count == 0, "Expected call count 0, got %u", endgrent_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_endgrent; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); pr_auth_endgrent(p); fail_unless(endgrent_count == 1, "Expected call count 1, got %u", endgrent_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_cache_name2gid_failed_test) { int res; gid_t gid; authtable authtab; char *sym_name = "name2gid"; /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = decline_name2gid; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME); fail_unless(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid); fail_unless(name2gid_count == 1, "Expected call count 1, got %u", name2gid_count); /* Call again; the call counter should NOT increment due to caching. */ gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME); fail_unless(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid); fail_unless(name2gid_count == 1, "Expected call count 1, got %u", name2gid_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_name2gid_test) { int res; gid_t gid; authtable authtab; char *sym_name = "name2gid"; pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_NAME2GID); gid = pr_auth_name2gid(NULL, NULL); fail_unless(gid == (gid_t) -1, "Found GID unexpectedly"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME); fail_unless(gid == (gid_t) -1, "Found GID unexpectedly"); fail_unless(name2gid_count == 0, "Expected call count 0, got %u", name2gid_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_name2gid; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME); fail_unless(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu", (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid); fail_unless(name2gid_count == 1, "Expected call count 1, got %u", name2gid_count); mark_point(); /* Call again; the call counter should NOT increment due to caching. */ gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME); fail_unless(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu", (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid); fail_unless(name2gid_count == 1, "Expected call count 1, got %u", name2gid_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_getgrgid_test) { int res; struct group *gr; authtable authtab; char *sym_name = "getgrgid"; gr = pr_auth_getgrgid(NULL, -1); fail_unless(gr == NULL, "Found grgid unexpectedly"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID); fail_unless(gr == NULL, "Found grgid unexpectedly"); fail_unless(getgrgid_count == 0, "Expected call count 0, got %u", getgrgid_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_getgrgid; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID); fail_unless(gr != NULL, "Failed to find grgid: %s", strerror(errno)); fail_unless(getgrgid_count == 1, "Expected call count 1, got %u", getgrgid_count); mark_point(); gr = pr_auth_getgrgid(p, 5); fail_unless(gr == NULL, "Found grgid for GID 5 unexpectedly"); fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)", errno, strerror(errno)); fail_unless(getgrgid_count == 2, "Expected call count 2, got %u", getgrgid_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_getpwnam_test) { int res; struct passwd *pw; authtable authtab; char *sym_name = "getpwnam"; pw = pr_auth_getpwnam(NULL, NULL); fail_unless(pw == NULL, "Found pwnam unexpectedly"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME); fail_unless(pw == NULL, "Found pwnam unexpectedly"); fail_unless(getpwnam_count == 0, "Expected call count 0, got %u", getpwnam_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_getpwnam; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME); fail_unless(pw != NULL, "Failed to find pwnam: %s", strerror(errno)); fail_unless(getpwnam_count == 1, "Expected call count 1, got %u", getpwnam_count); mark_point(); pw = pr_auth_getpwnam(p, "other"); fail_unless(pw == NULL, "Found pwnam for user 'other' unexpectedly"); fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)", errno, strerror(errno)); fail_unless(getpwnam_count == 2, "Expected call count 2, got %u", getpwnam_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_gid2name_test) { int res; const char *name; authtable authtab; char *sym_name = "gid2name"; pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_GID2NAME); name = pr_auth_gid2name(NULL, -1); fail_unless(name == NULL, "Found name unexpectedly: %s", name); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); mark_point(); name = pr_auth_gid2name(p, PR_TEST_AUTH_GID); fail_unless(name != NULL, "Failed to find name for GID %lu: %s", (unsigned long) PR_TEST_AUTH_GID, strerror(errno)); fail_unless(strcmp(name, PR_TEST_AUTH_GID_STR) == 0, "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name); fail_unless(gid2name_count == 0, "Expected call count 0, got %u", gid2name_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_gid2name; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); name = pr_auth_gid2name(p, PR_TEST_AUTH_GID); fail_unless(name != NULL, "Expected name, got null"); fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0, "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name); fail_unless(gid2name_count == 1, "Expected call count 1, got %u", gid2name_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_getgroups_test) { int res; array_header *gids = NULL; authtable authtab; char *sym_name = "getgroups"; res = pr_auth_getgroups(NULL, NULL, NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, NULL); fail_unless(res < 0, "Found groups for '%s' unexpectedly", PR_TEST_AUTH_NAME); fail_unless(getgroups_count == 0, "Expected call count 0, got %u", getgroups_count); mark_point(); /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = handle_getgroups; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, NULL); fail_unless(res > 0, "Expected group count 1 for '%s', got %d: %s", PR_TEST_AUTH_NAME, res, strerror(errno)); fail_unless(getgroups_count == 1, "Expected call count 1, got %u", getgroups_count); res = pr_auth_getgroups(p, "other", &gids, NULL); fail_unless(res < 0, "Found groups for 'other' unexpectedly"); fail_unless(getgroups_count == 2, "Expected call count 2, got %u", getgroups_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (auth_cache_uid2name_failed_test) { int res; const char *name; authtable authtab; char *sym_name = "uid2name"; /* Load the appropriate AUTH symbol, and call it. */ memset(&authtab, 0, sizeof(authtab)); authtab.name = sym_name; authtab.handler = decline_uid2name; authtab.m = &unit_tests_module; res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name, strerror(errno)); mark_point(); name = pr_auth_uid2name(p, PR_TEST_AUTH_UID); fail_unless(name != NULL, "Expected name, got null"); fail_unless(strcmp(name, PR_TEST_AUTH_UID_STR) == 0, "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name); fail_unless(uid2name_count == 1, "Expected call count 1, got %u", uid2name_count); /* Call again; the call counter should NOT increment due to caching. */ name = pr_auth_uid2name(p, PR_TEST_AUTH_UID); fail_unless(name != NULL, "Expected name, got null"); fail_unless(strcmp(name, PR_TEST_AUTH_UID_STR) == 0, "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name); fail_unless(uid2name_count == 1, "Expected call count 1, got %u", uid2name_count); pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &unit_tests_module); }
END_TEST START_TEST (stash_remove_symbol_test) { int res; conftable conftab; cmdtable cmdtab, hooktab; authtable authtab; res = pr_stash_remove_symbol(0, NULL, NULL); fail_unless(res == -1, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL (got %d)", errno); res = pr_stash_remove_symbol(0, "foo", NULL); fail_unless(res == -1, "Failed to handle bad symbol type"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL (got %d)", errno); res = pr_stash_remove_symbol(PR_SYM_CONF, "foo", NULL); fail_unless(res == 0, "Expected %d, got %d", 0, res); memset(&conftab, 0, sizeof(conftab)); conftab.directive = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_CONF, &conftab); fail_unless(res == 0, "Failed to add CONF symbol: %s", strerror(errno)); res = pr_stash_add_symbol(PR_SYM_CONF, &conftab); fail_unless(res == 0, "Failed to add CONF symbol: %s", strerror(errno)); res = pr_stash_remove_symbol(PR_SYM_CONF, "foo", NULL); fail_unless(res == 2, "Expected %d, got %d", 2, res); memset(&cmdtab, 0, sizeof(cmdtab)); cmdtab.command = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); res = pr_stash_remove_symbol(PR_SYM_CMD, "foo", NULL); fail_unless(res == 2, "Expected %d, got %d", 2, res); memset(&authtab, 0, sizeof(authtab)); authtab.name = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add AUTH symbol: %s", strerror(errno)); res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab); fail_unless(res == 0, "Failed to add AUTH symbol: %s", strerror(errno)); res = pr_stash_remove_symbol(PR_SYM_AUTH, "foo", NULL); fail_unless(res == 2, "Expected %d, got %d", 2, res); memset(&hooktab, 0, sizeof(hooktab)); hooktab.command = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_HOOK, &hooktab); fail_unless(res == 0, "Failed to add HOOK symbol: %s", strerror(errno)); res = pr_stash_add_symbol(PR_SYM_HOOK, &hooktab); fail_unless(res == 0, "Failed to add HOOK symbol: %s", strerror(errno)); res = pr_stash_remove_symbol(PR_SYM_HOOK, "foo", NULL); fail_unless(res == 2, "Expected %d, got %d", 2, res); }
END_TEST START_TEST (stash_remove_cmd_test) { int res; cmdtable cmdtab, cmdtab2; res = pr_stash_remove_cmd(NULL, NULL, 0, NULL, -1); fail_unless(res == -1, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)", errno, strerror(errno)); res = pr_stash_remove_cmd("foo", NULL, 0, NULL, -1); fail_unless(res == 0, "Expected %d, got %d", 0, res); memset(&cmdtab, 0, sizeof(cmdtab)); cmdtab.command = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); memset(&cmdtab2, 0, sizeof(cmdtab2)); cmdtab2.command = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab2); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); res = pr_stash_remove_cmd("foo", NULL, 0, NULL, -1); fail_unless(res == 2, "Expected %d, got %d", 2, res); /* Remove only the PRE_CMD cmd handlers */ mark_point(); memset(&cmdtab, 0, sizeof(cmdtab)); cmdtab.command = pstrdup(p, "foo"); cmdtab.cmd_type = PRE_CMD; res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); memset(&cmdtab2, 0, sizeof(cmdtab2)); cmdtab2.command = pstrdup(p, "foo"); cmdtab2.cmd_type = CMD; res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab2); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); mark_point(); res = pr_stash_remove_cmd("foo", NULL, PRE_CMD, NULL, -1); fail_unless(res == 1, "Expected %d, got %d", 1, res); (void) pr_stash_remove_symbol(PR_SYM_CMD, "foo", NULL); /* Remove only the G_WRITE cmd handlers */ mark_point(); memset(&cmdtab, 0, sizeof(cmdtab)); cmdtab.command = pstrdup(p, "foo"); cmdtab.group = G_WRITE; res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); memset(&cmdtab2, 0, sizeof(cmdtab2)); cmdtab2.command = pstrdup(p, "foo"); res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab2); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); mark_point(); res = pr_stash_remove_cmd("foo", NULL, 0, G_WRITE, -1); fail_unless(res == 1, "Expected %d, got %d", 1, res); (void) pr_stash_remove_symbol(PR_SYM_CMD, "foo", NULL); /* Remove only the CL_SFTP cmd handlers */ mark_point(); memset(&cmdtab, 0, sizeof(cmdtab)); cmdtab.command = pstrdup(p, "foo"); cmdtab.cmd_class = CL_SFTP; res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); memset(&cmdtab2, 0, sizeof(cmdtab2)); cmdtab2.command = pstrdup(p, "foo"); cmdtab2.cmd_class = CL_MISC; res = pr_stash_add_symbol(PR_SYM_CMD, &cmdtab2); fail_unless(res == 0, "Failed to add CMD symbol: %s", strerror(errno)); mark_point(); res = pr_stash_remove_cmd("foo", NULL, 0, NULL, CL_SFTP); fail_unless(res == 1, "Expected %d, got %d", 1, res); (void) pr_stash_remove_symbol(PR_SYM_CMD, "foo", NULL); }
int pr_module_unload(module *m) { char buf[256]; if (m == NULL || m->name == NULL) { errno = EINVAL; return -1; } /* Make sure this module has been loaded. We can't unload a module that * has not been loaded, now can we? */ memset(buf, '\0', sizeof(buf)); snprintf(buf, sizeof(buf), "mod_%s.c", m->name); buf[sizeof(buf)-1] = '\0'; if (pr_module_get(buf) == NULL) { errno = ENOENT; return -1; } /* Generate an event. */ pr_event_generate("core.module-unload", buf); /* Remove the module from the loaded_modules list. */ if (m->prev) { m->prev->next = m->next; } else { /* This module is the start of the loaded_modules list (prev is NULL), * so we need to update that pointer, too. */ loaded_modules = m->next; } if (m->next) m->next->prev = m->prev; m->prev = m->next = NULL; /* Remove the module's config, cmd, and auth tables. */ if (m->conftable) { conftable *conftab; for (conftab = m->conftable; conftab->directive; conftab++) { pr_stash_remove_symbol(PR_SYM_CONF, conftab->directive, conftab->m); } } if (m->cmdtable) { cmdtable *cmdtab; for (cmdtab = m->cmdtable; cmdtab->command; cmdtab++) { if (cmdtab->cmd_type == HOOK) { pr_stash_remove_symbol(PR_SYM_HOOK, cmdtab->command, cmdtab->m); } else { /* All other cmd_types are for CMDs: PRE_CMD, CMD, POST_CMD, etc. */ pr_stash_remove_symbol(PR_SYM_CMD, cmdtab->command, cmdtab->m); } } } if (m->authtable) { authtable *authtab; for (authtab = m->authtable; authtab->name; authtab++) { pr_stash_remove_symbol(PR_SYM_AUTH, authtab->name, authtab->m); } } /* Remove any callbacks that the module may have registered, i.e.: * * ctrls * events * timers * * Ideally we would also automatically unregister other callbacks that * the module may have registered, such as FSIO, NetIO, variables, and * response handlers. However, these APIs do not yet allow for * removal of all callbacks for a given module. */ #ifdef PR_USE_CTRLS pr_ctrls_unregister(m, NULL); #endif /* PR_USE_CTRLS */ pr_event_unregister(m, NULL, NULL); pr_timer_remove(-1, m); return 0; }