int main(int argc, char *argv[]) {
        sd_id128_t bid;
        char boot_id[SD_ID128_STRING_MAX];
        _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;

        assert_se(sd_id128_get_boot(&bid) >= 0);
        sd_id128_to_string(bid, boot_id);

        x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
        y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
        assert_se(x && y);

        test_tmpdir("abcd.service", x, y);

        z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
        zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);

        assert_se(z && zz);

        test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);

        test_netns();

        return 0;
}
Beispiel #2
0
/*
 * Internal helper function for remctld_start and remctld_start_fakeroot.
 *
 * Takes the Kerberos test configuration (the keytab principal is used as the
 * server principal), the configuration file to use (found via
 * test_file_path), and then any additional arguments to pass to remctld,
 * ending with a NULL.  Returns the PID of the running remctld process.  If
 * anything fails, calls bail.
 *
 * The path to remctld is obtained from the PATH_REMCTLD #define.  If this is
 * not set, remctld_start_internal calls skip_all.
 */
static struct process *
remctld_start_internal(struct kerberos_config *krbconf, const char *config,
                       va_list args, bool fakeroot)
{
    va_list args_copy;
    char *tmpdir, *pidfile, *confpath;
    size_t i, length;
    const char *arg, **argv;
    struct process *process;
    const char *path_remctld = PATH_REMCTLD;

    /* Check prerequisites. */
    if (path_remctld[0] == '\0')
        skip_all("remctld not found");

    /* Determine the location of the PID file and remove any old ones. */
    tmpdir = test_tmpdir();
    basprintf(&pidfile, "%s/remctld.pid", tmpdir);
    if (access(pidfile, F_OK) == 0)
        bail("remctld may already be running: %s exists", pidfile);

    /* Build the argv used to run remctld. */
    confpath = test_file_path(config);
    if (confpath == NULL)
        bail("cannot find remctld config %s", config);
    length = 11;
    va_copy(args_copy, args);
    while ((arg = va_arg(args_copy, const char *)) != NULL)
        length++;
    va_end(args_copy);
    argv = bmalloc(length * sizeof(const char *));
    i = 0;
    argv[i++] = path_remctld;
    argv[i++] = "-mdSF";
    argv[i++] = "-p";
    argv[i++] = "14373";
    argv[i++] = "-s";
    argv[i++] = krbconf->principal;
    argv[i++] = "-P";
    argv[i++] = pidfile;
    argv[i++] = "-f";
    argv[i++] = confpath;
    while ((arg = va_arg(args, const char *)) != NULL)
        argv[i++] = arg;
    argv[i] = NULL;

    /* Start remctld using process_start or process_start_fakeroot. */
    if (fakeroot)
        process = process_start_fakeroot(argv, pidfile);
    else
        process = process_start(argv, pidfile);

    /* Clean up and return. */
    test_file_path_free(confpath);
    free(pidfile);
    test_tmpdir_free(tmpdir);
    free(argv);
    return process;
}
Beispiel #3
0
int
main(void)
{
    struct kerberos_config *config;
    struct remctl *r;
    struct remctl_output *output;
    char *tmpdir, *confpath;
    FILE *conf;
    const char *test[] = { "test", "test", NULL };

    /* Unless we have Kerberos available, we can't really do anything. */
    config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB);

    /* Write out our empty configuration file. */
    tmpdir = test_tmpdir();
    basprintf(&confpath, "%s/conf-empty", tmpdir);
    conf = fopen(confpath, "w");
    if (conf == NULL)
        sysbail("cannot create %s", confpath);
    fclose(conf);

    /* Now we can start remctl with our temporary configuration file. */
    remctld_start(config, "tmp/conf-empty", NULL);

    plan(7);

    /* Test that we get a valid UNKNOWN_COMMAND error. */
    r = remctl_new();
    ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open");
    ok(remctl_command(r, test), "remctl_command");
    output = remctl_output(r);
    ok(output != NULL, "first output token is not null");
    if (output == NULL)
        ok_block(4, 0, "...and has correct content");
    else {
        is_int(REMCTL_OUT_ERROR, output->type, "...and is an error");
        is_int(15, output->length, "...and is right length");
        if (output->data == NULL)
            ok(0, "...and has the right error message");
        else
            ok(memcmp("Unknown command", output->data, 15) == 0,
               "...and has the right error message");
        is_int(ERROR_UNKNOWN_COMMAND, output->error, "...and error number");
    }
    remctl_close(r);
    unlink(confpath);
    free(confpath);
    test_tmpdir_free(tmpdir);
    return 0;
}
Beispiel #4
0
/*
 * Generate a krb5.conf file for testing and set KRB5_CONFIG to point to it.
 * The [appdefaults] section will be stripped out and the default realm will
 * be set to the realm specified, if not NULL.  This will use config/krb5.conf
 * in preference, so users can configure the tests by creating that file if
 * the system file isn't suitable.
 *
 * Depends on data/generate-krb5-conf being present in the test suite.
 */
void
kerberos_generate_conf(const char *realm)
{
    char *path;
    const char *argv[3];

    if (tmpdir_conf != NULL)
        kerberos_cleanup_conf();
    path = test_file_path("data/generate-krb5-conf");
    if (path == NULL)
        bail("cannot find generate-krb5-conf");
    argv[0] = path;
    argv[1] = realm;
    argv[2] = NULL;
    run_setup(argv);
    test_file_path_free(path);
    tmpdir_conf = test_tmpdir();
    basprintf(&krb5_config, "KRB5_CONFIG=%s/krb5.conf", tmpdir_conf);
    putenv(krb5_config);
    if (atexit(kerberos_cleanup_conf) != 0)
        sysdiag("cannot register cleanup function");
}
Beispiel #5
0
int
main(void)
{
    char *path, *tmp;
    FILE *output;
    const char *build;
    struct stat st;
    size_t length;

    output = fopen("c-tmpdir.output", "w");
    if (output == NULL)
        sysbail("cannot create c-tmpdir.output");
    fprintf(output, "Path to temporary directory: %s/tmp\n",
            getenv("C_TAP_BUILD"));
    fclose(output);
    build = getenv("C_TAP_BUILD");
    length = strlen(build) + strlen("/tmp") + 1;
    path = bcalloc_type(length, char);
    sprintf(path, "%s/tmp", build);
    if (access(path, F_OK) == 0)
        bail("%s already exists", path);
    free(path);
    path = test_tmpdir();
    printf("Path to temporary directory: %s\n", path);
    if (stat(path, &st) < 0)
        sysbail("cannot stat %s", path);
    if (!S_ISDIR(st.st_mode))
        sysbail("%s is not a directory", path);
    tmp = bstrdup(path);
    test_tmpdir_free(path);
    if (stat(tmp, &st) == 0)
        bail("temporary directory not removed");
    free(tmp);

    return 0;
}
Beispiel #6
0
int
main(void)
{
    struct script_config config;
    struct kerberos_password *password;
    DIR *tmpdir;
    struct dirent *file;
    char *tmppath, *path;

    /* Load the Kerberos principal and password from a file. */
    password = kerberos_config_password();
    if (password == NULL)
        skip_all("Kerberos tests not configured");
    memset(&config, 0, sizeof(config));
    config.user = password->username;
    config.password = password->password;
    config.extra[0] = password->principal;

    /* Generate a testing krb5.conf file. */
    kerberos_generate_conf(password->realm);

    /* Get the temporary directory and store that as the %1 substitution. */
    tmppath = test_tmpdir();
    config.extra[1] = tmppath;

    plan_lazy();

    /*
     * We need to ensure that the only thing in the test temporary directory
     * is the krb5.conf file that we generated, since we're going to check for
     * cleanup by looking for any out-of-place files.
     */
    tmpdir = opendir(tmppath);
    if (tmpdir == NULL)
        sysbail("cannot open directory %s", tmppath);
    while ((file = readdir(tmpdir)) != NULL) {
        if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
            continue;
        if (strcmp(file->d_name, "krb5.conf") == 0)
            continue;
        basprintf(&path, "%s/%s", tmppath, file->d_name);
        if (unlink(path) < 0)
            sysbail("cannot delete temporary file %s", path);
        free(path);
    }
    closedir(tmpdir);

    /*
     * Authenticate only, call pam_end, and be sure the ticket cache is
     * gone.  The auth-only script sets ccache_dir to the temporary directory,
     * so the module will create a temporary ticket cache there and then
     * should clean it up.
     */
    run_script("data/scripts/cache-cleanup/auth-only", &config);
    path = NULL;
    tmpdir = opendir(tmppath);
    if (tmpdir == NULL)
        sysbail("cannot open directory %s", tmppath);
    while ((file = readdir(tmpdir)) != NULL) {
        if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
            continue;
        if (strcmp(file->d_name, "krb5.conf") == 0)
            continue;
        if (path == NULL)
            basprintf(&path, "%s/%s", tmppath, file->d_name);
    }
    closedir(tmpdir);
    if (path != NULL)
        diag("found stray temporary file %s", path);
    ok(path == NULL, "ticket cache cleaned up");
    if (path != NULL)
        free(path);

    test_tmpdir_free(tmppath);
    kerberos_config_password_free(password);
    return 0;
}
Beispiel #7
0
/*
 * Obtain Kerberos tickets for the principal specified in config/principal
 * using the keytab specified in config/keytab, both of which are presumed to
 * be in tests in either the build or the source tree.  Also sets KRB5_KTNAME
 * and KRB5CCNAME.
 *
 * Returns the contents of config/principal in newly allocated memory or NULL
 * if Kerberos tests are apparently not configured.  If Kerberos tests are
 * configured but something else fails, calls bail.
 */
struct kerberos_config *
kerberos_setup(enum kerberos_needs needs)
{
    char *path;
    char buffer[BUFSIZ];
    FILE *file = NULL;

    /* If we were called before, clean up after the previous run. */
    if (config != NULL)
        kerberos_cleanup();
    config = bcalloc(1, sizeof(struct kerberos_config));

    /*
     * If we have a config/keytab file, set the KRB5CCNAME and KRB5_KTNAME
     * environment variables and obtain initial tickets.
     */
    config->keytab = test_file_path("config/keytab");
    if (config->keytab == NULL) {
        if (needs == TAP_KRB_NEEDS_KEYTAB || needs == TAP_KRB_NEEDS_BOTH)
            skip_all("Kerberos tests not configured");
    } else {
        tmpdir_ticket = test_tmpdir();
        basprintf(&config->cache, "%s/krb5cc_test", tmpdir_ticket);
        basprintf(&krb5ccname, "KRB5CCNAME=%s/krb5cc_test", tmpdir_ticket);
        basprintf(&krb5_ktname, "KRB5_KTNAME=%s", config->keytab);
        putenv(krb5ccname);
        putenv(krb5_ktname);
        kerberos_kinit();
    }

    /*
     * If we have a config/password file, read it and fill out the relevant
     * members of our config struct.
     */
    path = test_file_path("config/password");
    if (path != NULL)
        file = fopen(path, "r");
    if (file == NULL) {
        if (needs == TAP_KRB_NEEDS_PASSWORD || needs == TAP_KRB_NEEDS_BOTH)
            skip_all("Kerberos tests not configured");
    } else {
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read %s", path);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("no newline in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        config->userprinc = bstrdup(buffer);
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read password from %s", path);
        fclose(file);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("password too long in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        config->password = bstrdup(buffer);

        /*
         * Strip the realm from the principal and set realm and username.
         * This is not strictly correct; it doesn't cope with escaped @-signs
         * or enterprise names.
         */
        config->username = bstrdup(config->userprinc);
        config->realm = strchr(config->username, '@');
        if (config->realm == NULL)
            bail("test principal has no realm");
        *config->realm = '\0';
        config->realm++;
    }
    test_file_path_free(path);

    /*
     * If we have PKINIT configuration, read it and fill out the relevant
     * members of our config struct.
     */
    path = test_file_path("config/pkinit-principal");
    if (path != NULL)
        file = fopen(path, "r");
    if (file != NULL) {
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read %s", path);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("no newline in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        fclose(file);
        test_file_path_free(path);
        path = test_file_path("config/pkinit-cert");
        if (path != NULL) {
            config->pkinit_principal = bstrdup(buffer);
            config->pkinit_cert = bstrdup(path);
        }
    }
    test_file_path_free(path);
    if (config->pkinit_cert == NULL && (needs & TAP_KRB_NEEDS_PKINIT) != 0)
        skip_all("PKINIT tests not configured");

    /*
     * Register the cleanup function so that the caller doesn't have to do
     * explicit cleanup.
     */
    test_cleanup_register(kerberos_cleanup_handler);

    /* Return the configuration. */
    return config;
}
Beispiel #8
0
/*
 * Start a process and return its status information.  The status information
 * is also stored in the global processes linked list so that it can be
 * stopped automatically on program exit.
 *
 * The boolean argument says whether to start the process under fakeroot.  If
 * true, PATH_FAKEROOT must be defined, generally by Autoconf.  If it's not
 * found, call skip_all.
 *
 * This is a helper function for process_start and process_start_fakeroot.
 */
static struct process *
process_start_internal(const char *const argv[], const char *pidfile,
                       bool fakeroot)
{
    size_t i;
    int log_fd;
    const char *name;
    struct timeval tv;
    struct process *process;
    const char **fakeroot_argv = NULL;
    const char *path_fakeroot = PATH_FAKEROOT;

    /* Check prerequisites. */
    if (fakeroot && path_fakeroot[0] == '\0')
        skip_all("fakeroot not found");

    /* Create the process struct and log file. */
    process = bcalloc(1, sizeof(struct process));
    process->pidfile = bstrdup(pidfile);
    process->tmpdir = test_tmpdir();
    name = strrchr(argv[0], '/');
    if (name != NULL)
        name++;
    else
        name = argv[0];
    basprintf(&process->logfile, "%s/%s.log.XXXXXX", process->tmpdir, name);
    log_fd = mkstemp(process->logfile);
    if (log_fd < 0)
        sysbail("cannot create log file for %s", argv[0]);

    /* If using fakeroot, rewrite argv accordingly. */
    if (fakeroot) {
        for (i = 0; argv[i] != NULL; i++)
            ;
        fakeroot_argv = bcalloc(2 + i + 1, sizeof(const char *));
        fakeroot_argv[0] = path_fakeroot;
        fakeroot_argv[1] = "--";
        for (i = 0; argv[i] != NULL; i++)
            fakeroot_argv[i + 2] = argv[i];
        fakeroot_argv[i + 2] = NULL;
        argv = fakeroot_argv;
    }

    /*
     * Fork off the child process, redirect its standard output and standard
     * error to the log file, and then exec the program.
     */
    process->pid = fork();
    if (process->pid < 0)
        sysbail("fork failed");
    else if (process->pid == 0) {
        if (dup2(log_fd, STDOUT_FILENO) < 0)
            sysbail("cannot redirect standard output");
        if (dup2(log_fd, STDERR_FILENO) < 0)
            sysbail("cannot redirect standard error");
        close(log_fd);
        if (execv(argv[0], (char *const *) argv) < 0)
            sysbail("exec of %s failed", argv[0]);
    }
    close(log_fd);
    free(fakeroot_argv);

    /*
     * In the parent.  Wait for the child to start by watching for the PID
     * file to appear in 100ms intervals.
     */
    for (i = 0; i < PROCESS_WAIT * 10 && access(pidfile, F_OK) != 0; i++) {
        tv.tv_sec = 0;
        tv.tv_usec = 100000;
        select(0, NULL, NULL, NULL, &tv);
    }

    /*
     * If the PID file still hasn't appeared after ten seconds, attempt to
     * kill the process and then bail.
     */
    if (access(pidfile, F_OK) != 0) {
        kill(process->pid, SIGTERM);
        alarm(5);
        waitpid(process->pid, NULL, 0);
        alarm(0);
        bail("cannot start %s", argv[0]);
    }

    /*
     * Read the PID back from the PID file.  This usually isn't necessary for
     * non-forking daemons, but always doing this makes this function general,
     * and it's required when running under fakeroot.
     */
    if (fakeroot)
        process->pid = read_pidfile(pidfile);
    process->is_child = !fakeroot;

    /* Register the log file as a source of diag messages. */
    diag_file_add(process->logfile);

    /*
     * Add the process to our global list and set our cleanup handler if this
     * is the first process we started.
     */
    if (processes == NULL)
        test_cleanup_register(process_stop_all);
    process->next = processes;
    processes = process;

    /* All done. */
    return process;
}