Commit 2198e48a authored by Russ Allbery's avatar Russ Allbery

Add tests for instance handling

Test allowed and disallowed instances and ensure that they're
queued or ignored as appropriate.
parent 0759b2d4
......@@ -8,7 +8,7 @@
ad_realm = AD.EXAMPLE.COM
ad_admin_server = ad.example.com
ad_ldap_base = ou=Accounts,dc=ad,dc=example,dc=com
ad_instances = exclude
ad_instances = root ipass
queue_dir = queue
syslog = false
......
......@@ -40,7 +40,7 @@ main(void)
char *wanted;
/* Define the plan. */
plan(32);
plan(47);
/* Set up a temporary directory and queue relative to it. */
tmpdir = test_tmpdir();
......@@ -72,7 +72,7 @@ main(void)
bail_krb5(ctx, code, "cannot parse principal test@EXAMPLE.COM");
sync_queue_block("queue", "test", "password");
code = sync_chpass(data, ctx, princ, "foobar");
is_int(0, code, "pwupdate_precommit_password succeeds");
is_int(0, code, "sync_chpass succeeds");
ok(access("queue/.lock", F_OK) == 0, "...lock file now exists");
sync_queue_check_password("queue", "test", "foobar");
sync_queue_unblock("queue", "test", "password");
......@@ -89,11 +89,51 @@ main(void)
sync_queue_check_enable("queue", "test", false);
sync_queue_unblock("queue", "test", "enable");
/* Queue a password change for a root instance. */
krb5_free_principal(ctx, princ);
code = krb5_parse_name(ctx, "test/root@EXAMPLE.COM", &princ);
if (code != 0)
bail_krb5(ctx, code, "cannot parse principal test/root@EXAMPLE.COM");
sync_queue_block("queue", "test/root", "password");
code = sync_chpass(data, ctx, princ, "foobar");
is_int(0, code, "sync_chpass of root instance succeeds");
sync_queue_check_password("queue", "test/root", "foobar");
sync_queue_unblock("queue", "test/root", "password");
/* Queue an account disable for an ipass instance. */
krb5_free_principal(ctx, princ);
code = krb5_parse_name(ctx, "test/ipass@EXAMPLE.COM", &princ);
if (code != 0)
bail_krb5(ctx, code, "cannot parse principal test/ipass@EXAMPLE.COM");
sync_queue_block("queue", "test/ipass", "enable");
code = sync_status(data, ctx, princ, true);
is_int(0, code, "sync_status of root instance succeeds");
sync_queue_check_enable("queue", "test/ipass", true);
sync_queue_unblock("queue", "test/ipass", "enable");
/*
* Try queuing a change for an admin instance, which should do nothing,
* successfully. We'll test there's no queued changes by deleting the
* queue file.
*/
krb5_free_principal(ctx, princ);
code = krb5_parse_name(ctx, "test/admin@EXAMPLE.COM", &princ);
if (code != 0)
bail_krb5(ctx, code, "cannot parse principal test/admin@EXAMPLE.COM");
code = sync_chpass(data, ctx, princ, "foobar");
is_int(0, code, "sync_chpass of admin instance succeeds");
code = sync_status(data, ctx, princ, true);
is_int(0, code, "sync_status enable of admin instance succeeds");
/* Unwind the queue and be sure all the right files exist. */
ok(unlink("queue/.lock") == 0, "Lock file still exists");
ok(rmdir("queue") == 0, "No other files in queue directory");
/* Check failure when there's no queue directory. */
krb5_free_principal(ctx, princ);
code = krb5_parse_name(ctx, "test/root@EXAMPLE.COM", &princ);
if (code != 0)
bail_krb5(ctx, code, "cannot parse principal test/root@EXAMPLE.COM");
basprintf(&wanted, "cannot open lock file queue/.lock: %s",
strerror(ENOENT));
code = sync_chpass(data, ctx, princ, "foobar");
......
......@@ -23,6 +23,23 @@
#include <tests/tap/sync.h>
/*
* Format the user for queue file naming. This just replaces all slashes with
* periods and returns the new user as a newly-allocated string.
*/
static char *
munge_user(const char *user)
{
char *munged_user, *p;
munged_user = bstrdup(user);
for (p = munged_user; *p != '\0'; p++)
if (*p == '/')
*p = '.';
return munged_user;
}
/*
* Block processing by creating a dummy queue file. Takes the queue
* directory, the username (as used for queuing), and the operation to block.
......@@ -32,9 +49,11 @@ void
sync_queue_block(const char *queue, const char *user, const char *op)
{
int fd;
char *file;
char *file, *munged_user;
basprintf(&file, "%s/%s-ad-%s-19700101T000000Z", queue, user, op);
munged_user = munge_user(user);
basprintf(&file, "%s/%s-ad-%s-19700101T000000Z", queue, munged_user, op);
free(munged_user);
fd = open(file, O_CREAT | O_WRONLY, 0666);
if (fd < 0)
sysbail("cannot create blocking queue file %s", file);
......@@ -50,9 +69,11 @@ sync_queue_block(const char *queue, const char *user, const char *op)
void
sync_queue_unblock(const char *queue, const char *user, const char *op)
{
char *file;
char *file, *munged_user;
basprintf(&file, "%s/%s-ad-%s-19700101T000000Z", queue, user, op);
munged_user = munge_user(user);
basprintf(&file, "%s/%s-ad-%s-19700101T000000Z", queue, munged_user, op);
free(munged_user);
if (unlink(file) < 0)
sysbail("cannot delete blocking queue file %s", file);
free(file);
......@@ -68,7 +89,7 @@ static void
queue_check(const char *queue, const char *user, const char *op,
const char *password)
{
char *path, *wanted;
char *path, *wanted, *munged_user;
const char *path_op;
time_t now, timestamp;
struct tm *date;
......@@ -80,16 +101,18 @@ queue_check(const char *queue, const char *user, const char *op,
path = NULL;
now = time(NULL);
path_op = (strcmp("disable", op) == 0) ? "enable" : op;
munged_user = munge_user(user);
for (timestamp = now - 1; timestamp <= now; timestamp++) {
date = gmtime(&timestamp);
basprintf(&path, "%s/%s-ad-%s-%04d%02d%02dT%02d%02d%02dZ-00", queue,
user, path_op, date->tm_year + 1900, date->tm_mon + 1,
munged_user, path_op, date->tm_year + 1900, date->tm_mon + 1,
date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec);
if (access(path, F_OK) == 0)
break;
free(path);
path = NULL;
}
free(munged_user);
/* Check that we found a queued change. */
ok(path != NULL, "%s for %s was queued", op, user);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment