Beispiel #1
0
static bool test_empty(
    Queue * queue)
{
    void *data;
    bool pop_successful;

    TEST(ssize_t, "%zd", Queue_size(queue), ==, 0);
    pop_successful = Queue_trypop(queue, &data);
    TEST_BOOL(pop_successful, false);
    TEST(ssize_t, "%zd", Queue_size(queue), ==, 0);

    return true;
}
Beispiel #2
0
static bool push_range(
    Queue * queue,
    ssize_t initial_size,
    uintptr_t start,
    uintptr_t stop)
{
    uintptr_t data;
    bool push_successful;

    for (data = start; data < stop; ++data)
    {
        push_successful = Queue_push(queue, (void *)data);
        TEST_BOOL(push_successful, true);
        TEST(ssize_t, "%zd", Queue_size(queue), ==,
             initial_size + (ssize_t) (data - start + 1));
    }

    return true;
}
Beispiel #3
0
static bool pop_range(
    Queue * queue,
    ssize_t initial_size,
    uintptr_t start,
    uintptr_t stop)
{
    uintptr_t data1;
    void *data2;
    bool pop_successful;

    for (data1 = start; data1 < stop; ++data1)
    {
        pop_successful = Queue_trypop(queue, &data2);
        TEST_BOOL(pop_successful, true);
        TEST(uintptr_t, "%" PRIuPTR, (uintptr_t) data2, ==, data1);
        TEST(ssize_t, "%zd", Queue_size(queue), ==,
             initial_size - (ssize_t) (data1 - start + 1));
    }

    return true;
}
Beispiel #4
0
int
main(void)
{
    pam_handle_t *pamh;
    struct pam_args *args;
    struct pam_conv conv = { NULL, NULL };
    bool status;
    struct vector *cells;
    char *program;
    struct output *seen;
    const char *argv_bool[2] = { NULL, NULL };
    const char *argv_err[2] = { NULL, NULL };
    const char *argv_empty[] = { NULL };
#ifdef HAVE_KRB5
    const char *argv_all[] = {
        "cells=stanford.edu,ir.stanford.edu", "debug", "expires=1d",
        "ignore_root", "minimum_uid=1000", "program=/bin/true"
    };
    char *krb5conf;
#else
    const char *argv_all[] = {
        "cells=stanford.edu,ir.stanford.edu", "debug", "expires=86400",
        "ignore_root", "minimum_uid=1000", "program=/bin/true"
    };
#endif

    if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
        sysbail("cannot create pam_handle_t");
    args = putil_args_new(pamh, 0);
    if (args == NULL)
        bail("cannot create PAM argument struct");

    plan(161);

    /* First, check just the defaults. */
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting the defaults");
    ok(args->config->cells == NULL, "...cells default");
    is_int(false, args->config->debug, "...debug default");
    is_int(10, args->config->expires, "...expires default");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(0, args->config->minimum_uid, "...minimum_uid default");
    ok(args->config->program == NULL, "...program default");

    /* Now parse an empty set of PAM arguments.  Nothing should change. */
    status = putil_args_parse(args, 0, argv_empty, options, optlen);
    ok(status, "Parse of empty argv");
    ok(args->config->cells == NULL, "...cells still default");
    is_int(false, args->config->debug, "...debug still default");
    is_int(10, args->config->expires, "...expires default");
    is_int(true, args->config->ignore_root, "...ignore_root still default");
    is_int(0, args->config->minimum_uid, "...minimum_uid still default");
    ok(args->config->program == NULL, "...program still default");

    /* Now, check setting everything. */
    status = putil_args_parse(args, 6, argv_all, options, optlen);
    ok(status, "Parse of full argv");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("stanford.edu", args->config->cells->strings[0],
                  "...first is stanford.edu");
        is_string("ir.stanford.edu", args->config->cells->strings[1],
                  "...second is ir.stanford.edu");
    }
    is_int(true, args->config->debug, "...debug is set");
    is_int(86400, args->config->expires, "...expires is set");
    is_int(true, args->config->ignore_root, "...ignore_root is set");
    is_int(1000, args->config->minimum_uid, "...minimum_uid is set");
    is_string("/bin/true", args->config->program, "...program is set");
    config_free(args->config);
    args->config = NULL;

    /* Test deep copying of defaults. */
    cells = vector_new();
    if (cells == NULL)
        sysbail("cannot allocate memory");
    vector_add(cells, "foo.com");
    vector_add(cells, "bar.com");
    options[0].defaults.list = cells;
    program = strdup("/bin/false");
    if (program == NULL)
        sysbail("cannot allocate memory");
    options[5].defaults.string = program;
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting defaults with new defaults");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("foo.com", args->config->cells->strings[0],
                  "...first is foo.com");
        is_string("bar.com", args->config->cells->strings[1],
                  "...second is bar.com");
    }
    is_string("/bin/false", args->config->program,
              "...program is /bin/false");
    status = putil_args_parse(args, 6, argv_all, options, optlen);
    ok(status, "Parse of full argv after defaults");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("stanford.edu", args->config->cells->strings[0],
                  "...first is stanford.edu");
        is_string("ir.stanford.edu", args->config->cells->strings[1],
                  "...second is ir.stanford.edu");
    }
    is_int(true, args->config->debug, "...debug is set");
    is_int(86400, args->config->expires, "...expires is set");
    is_int(true, args->config->ignore_root, "...ignore_root is set");
    is_int(1000, args->config->minimum_uid, "...minimum_uid is set");
    is_string("/bin/true", args->config->program, "...program is set");
    is_string("foo.com", cells->strings[0], "...first cell after parse");
    is_string("bar.com", cells->strings[1], "...second cell after parse");
    is_string("/bin/false", program, "...string after parse");
    config_free(args->config);
    args->config = NULL;
    is_string("foo.com", cells->strings[0], "...first cell after free");
    is_string("bar.com", cells->strings[1], "...second cell after free");
    is_string("/bin/false", program, "...string after free");
    options[0].defaults.list = NULL;
    options[5].defaults.string = NULL;
    vector_free(cells);
    free(program);

    /* Test specifying the default for a vector parameter as a string. */
    options[0].type = TYPE_STRLIST;
    options[0].defaults.string = "foo.com,bar.com";
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting defaults with string default for vector");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("foo.com", args->config->cells->strings[0],
                  "...first is foo.com");
        is_string("bar.com", args->config->cells->strings[1],
                  "...second is bar.com");
    }
    config_free(args->config);
    args->config = NULL;
    options[0].type = TYPE_LIST;
    options[0].defaults.string = NULL;

    /* Should be no errors so far. */
    ok(pam_output() == NULL, "No errors so far");

    /* Test various ways of spelling booleans. */
    args->config = config_new();
    TEST_BOOL("debug", args->config->debug, true);
    TEST_BOOL("debug=false", args->config->debug, false);
    TEST_BOOL("debug=true", args->config->debug, true);
    TEST_BOOL("debug=no", args->config->debug, false);
    TEST_BOOL("debug=yes", args->config->debug, true);
    TEST_BOOL("debug=off", args->config->debug, false);
    TEST_BOOL("debug=on", args->config->debug, true);
    TEST_BOOL("debug=0", args->config->debug, false);
    TEST_BOOL("debug=1", args->config->debug, true);
    TEST_BOOL("debug=False", args->config->debug, false);
    TEST_BOOL("debug=trUe", args->config->debug, true);
    TEST_BOOL("debug=No", args->config->debug, false);
    TEST_BOOL("debug=Yes", args->config->debug, true);
    TEST_BOOL("debug=OFF", args->config->debug, false);
    TEST_BOOL("debug=ON", args->config->debug, true);
    config_free(args->config);
    args->config = NULL;

    /* Test for various parsing errors. */
    args->config = config_new();
    TEST_ERROR("debug=", LOG_ERR,
               "invalid boolean in setting: debug=");
    TEST_ERROR("debug=truth", LOG_ERR,
               "invalid boolean in setting: debug=truth");
    TEST_ERROR("minimum_uid", LOG_ERR,
               "value missing for option minimum_uid");
    TEST_ERROR("minimum_uid=", LOG_ERR,
               "value missing for option minimum_uid=");
    TEST_ERROR("minimum_uid=foo", LOG_ERR,
               "invalid number in setting: minimum_uid=foo");
    TEST_ERROR("minimum_uid=1000foo", LOG_ERR,
               "invalid number in setting: minimum_uid=1000foo");
    TEST_ERROR("program", LOG_ERR, "value missing for option program");
    TEST_ERROR("cells", LOG_ERR, "value missing for option cells");
    config_free(args->config);
    args->config = NULL;

#ifdef HAVE_KRB5

    /* Test for Kerberos krb5.conf option parsing. */
    krb5conf = test_file_path("data/krb5-pam.conf");
    if (krb5conf == NULL)
        bail("cannot find data/krb5-pam.conf");
    if (setenv("KRB5_CONFIG", krb5conf, 1) < 0)
        sysbail("cannot set KRB5_CONFIG");
    krb5_free_context(args->ctx);
    status = krb5_init_context(&args->ctx);
    if (status != 0)
        bail("cannot parse test krb5.conf file");
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting the defaults");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf");
    ok(args->config->cells == NULL, "...cells default");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    ok(args->config->program == NULL, "...program default");
    status = putil_args_krb5(args, "other-test", options, optlen);
    ok(status, "Options from krb5.conf (other-test)");
    is_int(-1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf other-test");

    /* Test with a realm set, which should expose more settings. */
    krb5_free_context(args->ctx);
    status = krb5_init_context(&args->ctx);
    if (status != 0)
        bail("cannot parse test krb5.conf file");
    args->realm = strdup("FOO.COM");
    if (args->realm == NULL)
        sysbail("cannot allocate memory");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf with FOO.COM");
    is_int(2, args->config->cells->count, "...cells count from krb5.conf");
    is_string("foo.com", args->config->cells->strings[0],
              "...first cell from krb5.conf");
    is_string("bar.com", args->config->cells->strings[1],
              "...second cell from krb5.conf");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    is_string("/bin/false", args->config->program,
              "...program from krb5.conf");

    /* Test with a different realm. */
    free(args->realm);
    args->realm = strdup("BAR.COM");
    if (args->realm == NULL)
        sysbail("cannot allocate memory");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf with BAR.COM");
    is_int(2, args->config->cells->count, "...cells count from krb5.conf");
    is_string("bar.com", args->config->cells->strings[0],
              "...first cell from krb5.conf");
    is_string("foo.com", args->config->cells->strings[1],
              "...second cell from krb5.conf");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    is_string("echo /bin/true", args->config->program,
              "...program from krb5.conf");
    config_free(args->config);
    args->config = config_new();
    status = putil_args_krb5(args, "other-test", options, optlen);
    ok(status, "Options from krb5.conf (other-test with realm)");
    ok(args->config->cells == NULL, "...cells is NULL");
    is_string("echo /bin/true", args->config->program,
              "...program from krb5.conf");
    config_free(args->config);
    args->config = NULL;

    /* Test for time parsing errors. */
    args->config = config_new();
    TEST_ERROR("expires=ft87", LOG_ERR,
               "bad time value in setting: expires=ft87");
    config_free(args->config);

    /* Test error reporting from the krb5.conf parser. */
    args->config = config_new();
    status = putil_args_krb5(args, "bad-number", options, optlen);
    ok(status, "Options from krb5.conf (bad-number)");
    seen = pam_output();
    is_string("invalid number in krb5.conf setting for minimum_uid: 1000foo",
              seen->lines[0].line, "...and correct error reported");
    is_int(LOG_ERR, seen->lines[0].priority, "...with correct priority");
    pam_output_free(seen);
    config_free(args->config);
    args->config = NULL;

    /* Test error reporting on times from the krb5.conf parser. */
    args->config = config_new();
    status = putil_args_krb5(args, "bad-time", options, optlen);
    ok(status, "Options from krb5.conf (bad-time)");
    seen = pam_output();
    if (seen == NULL)
        ok_block(2, false, "...no error output");
    else {
        is_string("invalid time in krb5.conf setting for expires: ft87",
                  seen->lines[0].line, "...and correct error reported");
        is_int(LOG_ERR, seen->lines[0].priority, "...with correct priority");
    }
    pam_output_free(seen);
    config_free(args->config);
    args->config = NULL;

    test_file_path_free(krb5conf);

#else /* !HAVE_KRB5 */

    skip_block(37, "Kerberos support not configured");

#endif

    putil_args_free(args);
    pam_end(pamh, 0);
    return 0;
}
void
test_bool (CharT*, Traits*,
           const char *cname,
           const char *tname)
{
    info (cname, tname, "bool");

#define TEST_BOOL(ss, fl, is, ex, ee, es, ne, fw, iv, ev)   \
    TEST (bool, "%b", ss, fl, is, ex, ee, es, ne, fw, iv, ev)

    const int ba    = std::ios::boolalpha;
    const int ba_ws = ba | std::ios::skipws;

    LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
    locale_data.whitespace = "_";
    locale_data.falsename = "NO";
    locale_data.truename  = "YES";

    TEST_BOOL ("",      -1, -1, -1, 0, _ef, 0, 0, false, false);
    TEST_BOOL ("",      -1, -1, -1, 0, _ef, 0, 0, true,  true);
    TEST_BOOL ("0",     -1, -1, -1, 0, _e_, 1, 0, true,  false);
    TEST_BOOL ("1",     -1, -1, -1, 0, _e_, 1, 0, false, true);
    TEST_BOOL ("+0",    -1, -1, -1, 0, _e_, 2, 0, true,  false);
    TEST_BOOL ("-0",    -1, -1, -1, 0, _e_, 2, 0, true,  false);
    TEST_BOOL ("+1",    -1, -1, -1, 0, _e_, 2, 0, false, true);
    TEST_BOOL ("00",    -1, -1, -1, 0, _e_, 2, 0, true,  false);
    TEST_BOOL ("01",    -1, -1, -1, 0, _e_, 2, 0, false, true);
    TEST_BOOL ("_000",  -1, -1, -1, 0, _e_, 4, 0, true,  false);
    TEST_BOOL ("_001",  -1, -1, -1, 0, _e_, 4, 0, false, true);

    TEST_BOOL ("NO",    -1, -1, -1, 0, __f, 0, 0, true,  true);
    TEST_BOOL ("YES",   -1, -1, -1, 0, __f, 0, 0, false, false);
    TEST_BOOL ("_NO",   -1, -1, -1, 0, __f, 1, 0, true,  true);
    TEST_BOOL ("_YES",  -1, -1, -1, 0, __f, 1, 0, false, false);

    TEST_BOOL ("NO",    ba,    -1, -1, 0, ___, 2, 0, false, false);
    TEST_BOOL ("YES",   ba,    -1, -1, 0, ___, 3, 0, true,  true);
    TEST_BOOL ("_NO",   ba_ws, -1, -1, 0, ___, 3, 0, false, false);
    TEST_BOOL ("_YES",  ba_ws, -1, -1, 0, ___, 4, 0, true,  true);
    TEST_BOOL ("_NO_",  ba_ws, -1, -1, 0, ___, 3, 0, false, false);
    TEST_BOOL ("_YES_", ba_ws, -1, -1, 0, ___, 4, 0, true,  true);

    locale_data.falsename = "bool:0";
    locale_data.truename  = "bool:1";

    TEST_BOOL ("bool:0", ba, -1, -1, 0, ___, 6, 0, false, false);
    TEST_BOOL ("bool:1", ba, -1, -1, 0, ___, 6, 0, true,  true);
    TEST_BOOL ("bool:2", ba, -1, -1, 0, __f, 5, 0, true,  true);
}