Exemple #1
0
END_TEST

START_TEST(test_atomicio_read_from_small_file)
{
    char wbuf[] = "foobar";
    ssize_t wsize = strlen(wbuf)+1;
    ssize_t numwritten;
    char rbuf[64];
    ssize_t numread;
    errno_t ret;

    fail_if(atio_fd < 0, "No fd to test?\n");

    errno = 0;
    numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
    ret = errno;

    fail_unless(ret == 0, "Error %d while writing\n", ret);
    fail_unless(numwritten == wsize,
                "Wrote %d bytes expected %d\n", numwritten, wsize);

    fsync(atio_fd);
    lseek(atio_fd, 0, SEEK_SET);

    errno = 0;
    numread = sss_atomic_read_s(atio_fd, rbuf, 64);
    ret = errno;

    fail_unless(ret == 0, "Error %d while reading\n", ret);
    fail_unless(numread == numwritten,
                "Read %d bytes expected %d\n", numread, numwritten);
}
Exemple #2
0
static errno_t sss_mc_set_recycled(int fd)
{
    uint32_t w = SSS_MC_HEADER_RECYCLED;
    struct sss_mc_header h;
    off_t offset;
    off_t pos;
    int ret;

    offset = MC_PTR_DIFF(&h.status, &h);

    pos = lseek(fd, offset, SEEK_SET);
    if (pos == -1) {
        /* What do we do now ? */
        return errno;
    }

    errno = 0;
    ret = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status));
    if (ret == -1) {
        return errno;
    }

    if (ret != sizeof(h.status)) {
        /* Write error */
        return EIO;
    }

    return EOK;
}
Exemple #3
0
static int seed_prompt(const char *req)
{
    size_t len = 0;
    size_t i = 0;
    char *prompt = NULL;
    int ret = EOK;

    prompt = talloc_asprintf(NULL, _("Enter %s:"), req);
    if (prompt == NULL) {
        ret = ENOMEM;
        goto done;
    }

    while (prompt[i] != '\0') {
       errno = 0;
       len = sss_atomic_write_s(STDOUT_FILENO, &prompt[i++], 1);
       if (len == -1) {
           ret = errno;
           DEBUG(SSSDBG_CRIT_FAILURE, ("write failed [%d][%s].\n",
                                       ret, strerror(ret)));
           goto done;
       }
    }

done:
    talloc_free(prompt);
    return ret;
}
Exemple #4
0
END_TEST

START_TEST(test_atomicio_read_exact_sized_file)
{
    char wbuf[] = "12345678";
    ssize_t wsize = strlen(wbuf)+1;
    ssize_t numwritten;
    char rbuf[9];
    ssize_t numread;
    errno_t ret;

    fail_if(atio_fd < 0, "No fd to test?\n");

    errno = 0;
    numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
    ret = errno;

    fail_unless(ret == 0, "Error %d while writing\n", ret);
    fail_unless(numwritten == wsize,
                "Wrote %d bytes expected %d\n", numwritten, wsize);

    fsync(atio_fd);
    lseek(atio_fd, 0, SEEK_SET);

    errno = 0;
    numread = sss_atomic_read_s(atio_fd, rbuf, 9);
    ret = errno;

    fail_unless(ret == 0, "Error %d while reading\n", ret);
    fail_unless(numread == numwritten,
                "Read %d bytes expected %d\n", numread, numwritten);

    fail_unless(rbuf[8] == '\0', "String not NULL terminated?");
    fail_unless(strcmp(wbuf, rbuf) == 0, "Read something else than wrote?");

    /* We've reached end-of-file, next read must return 0 */
    errno = 0;
    numread = sss_atomic_read_s(atio_fd, rbuf, 9);
    ret = errno;

    fail_unless(ret == 0, "Error %d while reading\n", ret);
    fail_unless(numread == 0, "More data to read?");
}
Exemple #5
0
END_TEST

START_TEST(test_atomicio_read_from_large_file)
{
    char wbuf[] = "123456781234567812345678";
    ssize_t wsize = strlen(wbuf)+1;
    ssize_t numwritten;
    char rbuf[8];
    ssize_t numread;
    ssize_t total;
    errno_t ret;

    fail_if(atio_fd < 0, "No fd to test?\n");

    errno = 0;
    numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
    ret = errno;

    fail_unless(ret == 0, "Error %d while writing\n", ret);
    fail_unless(numwritten == wsize,
                "Wrote %d bytes expected %d\n", numwritten, wsize);

    fsync(atio_fd);
    lseek(atio_fd, 0, SEEK_SET);

    total = 0;
    do {
        errno = 0;
        numread = sss_atomic_read_s(atio_fd, rbuf, 8);
        ret = errno;

        fail_if(numread == -1, "Read error %d: %s\n", ret, strerror(ret));
        total += numread;
    } while (numread != 0);

    fail_unless(ret == 0, "Error %d while reading\n", ret);
    fail_unless(total == numwritten,
                "Read %d bytes expected %d\n", numread, numwritten);
}
Exemple #6
0
int
main(int argc, const char *argv[])
{
    int opt;
    poptContext pc;
    int debug_fd = -1;
    errno_t ret;
    int sysvol_gpt_version;
    int result;
    TALLOC_CTX *main_ctx = NULL;
    uint8_t *buf = NULL;
    ssize_t len = 0;
    struct input_buffer *ibuf = NULL;
    struct response *resp = NULL;
    size_t written;

    struct poptOption long_options[] = {
        POPT_AUTOHELP
        {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
         _("Debug level"), NULL},
        {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
         _("Add debug timestamps"), NULL},
        {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
         _("Show timestamps with microseconds"), NULL},
        {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
         _("An open file descriptor for the debug logs"), NULL},
        {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
         &debug_to_stderr, 0,
         _("Send the debug output to stderr directly."), NULL },
        POPT_TABLEEND
    };

    /* Set debug level to invalid value so we can decide if -d 0 was used. */
    debug_level = SSSDBG_INVALID;

    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    while((opt = poptGetNextOpt(pc)) != -1) {
        switch(opt) {
        default:
        fprintf(stderr, "\nInvalid option %s: %s\n\n",
                  poptBadOption(pc, 0), poptStrerror(opt));
            poptPrintUsage(pc, stderr, 0);
            _exit(-1);
        }
    }

    poptFreeContext(pc);

    DEBUG_INIT(debug_level);

    debug_prg_name = talloc_asprintf(NULL, "[sssd[gpo_child[%d]]]", getpid());
    if (debug_prg_name == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
        goto fail;
    }

    if (debug_fd != -1) {
        ret = set_debug_file_from_fd(debug_fd);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
        }
    }

    DEBUG(SSSDBG_TRACE_FUNC, "gpo_child started.\n");

    main_ctx = talloc_new(NULL);
    if (main_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
        talloc_free(discard_const(debug_prg_name));
        goto fail;
    }
    talloc_steal(main_ctx, debug_prg_name);

    buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE);
    if (buf == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
        goto fail;
    }

    ibuf = talloc_zero(main_ctx, struct input_buffer);
    if (ibuf == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "context initialized\n");

    errno = 0;
    len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE);
    if (len == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret));
        goto fail;
    }

    close(STDIN_FILENO);

    ret = unpack_buffer(buf, len, ibuf);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret));
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "performing smb operations\n");

    result = perform_smb_operations(ibuf->cached_gpt_version,
                                    ibuf->smb_server,
                                    ibuf->smb_share,
                                    ibuf->smb_path,
                                    ibuf->smb_cse_suffix,
                                    &sysvol_gpt_version);
    if (result != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "perform_smb_operations failed.[%d][%s].\n",
              result, strerror(result));
        goto fail;
    }

    ret = prepare_response(main_ctx, sysvol_gpt_version, result, &resp);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "prepare_response failed. [%d][%s].\n",
                    ret, strerror(ret));
        goto fail;
    }

    errno = 0;

    written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size);
    if (written == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret,
                    strerror(ret));
        goto fail;
    }

    if (written != resp->size) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n",
              resp->size, written);
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "gpo_child completed successfully\n");
    close(STDOUT_FILENO);
    talloc_free(main_ctx);
    return EXIT_SUCCESS;

fail:
    DEBUG(SSSDBG_CRIT_FAILURE, "gpo_child failed!\n");
    close(STDOUT_FILENO);
    talloc_free(main_ctx);
    return EXIT_FAILURE;
}
Exemple #7
0
/*
 * This function stores the input buf to a local file, whose file path
 * is constructed by concatenating:
 *   GPO_CACHE_PATH,
 *   input smb_path,
 *   input smb_cse_suffix
 * Note that the backend will later read the file from the same file path.
 */
static errno_t gpo_cache_store_file(const char *smb_path,
                                    const char *smb_cse_suffix,
                                    uint8_t *buf,
                                    int buflen)
{
    int ret;
    int fd = -1;
    char *tmp_name = NULL;
    ssize_t written;
    mode_t old_umask;
    char *filename = NULL;
    char *smb_path_with_suffix = NULL;
    TALLOC_CTX *tmp_ctx = NULL;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        ret = ENOMEM;
        goto done;
    }

    smb_path_with_suffix =
        talloc_asprintf(tmp_ctx, "%s%s", smb_path, smb_cse_suffix);
    if (smb_path_with_suffix == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
        ret = ENOMEM;
        goto done;
    }

    /* create component directories of smb_path, if needed */
    ret = prepare_gpo_cache(tmp_ctx, GPO_CACHE_PATH, smb_path_with_suffix);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "prepare_gpo_cache failed [%d][%s]\n",
              ret, strerror(ret));
        goto done;
    }

    filename = talloc_asprintf(tmp_ctx, GPO_CACHE_PATH"%s", smb_path_with_suffix);
    if (filename == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
        ret = ENOMEM;
        goto done;
    }

    tmp_name = talloc_asprintf(tmp_ctx, "%sXXXXXX", filename);
    if (tmp_name == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
        ret = ENOMEM;
        goto done;
    }

    old_umask = umask(077);
    fd = mkstemp(tmp_name);
    umask(old_umask);
    if (fd == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "mkstemp failed [%d][%s].\n", ret, strerror(ret));
        goto done;
    }

    errno = 0;
    written = sss_atomic_write_s(fd, buf, buflen);
    if (written == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "write failed [%d][%s].\n", ret, strerror(ret));
        goto done;
    }

    if (written != buflen) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Write error, wrote [%zd] bytes, expected [%d]\n",
               written, buflen);
        ret = EIO;
        goto done;
    }

    ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "fchmod failed [%d][%s].\n", ret, strerror(ret));
        goto done;
    }

    ret = close(fd);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "close failed [%d][%s].\n", ret, strerror(ret));
        goto done;
    }

    ret = rename(tmp_name, filename);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "rename failed [%d][%s].\n", ret, strerror(ret));
        goto done;
    }

 done:

    if (ret != EOK) {
      DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
    }

    talloc_free(tmp_ctx);
    return ret;
}
Exemple #8
0
errno_t write_krb5info_file(const char *realm, const char *server,
                           const char *service)
{
    int ret;
    int fd = -1;
    char *tmp_name = NULL;
    char *krb5info_name = NULL;
    TALLOC_CTX *tmp_ctx = NULL;
    const char *name_tmpl = NULL;
    int server_len;
    ssize_t written;
    mode_t old_umask;

    if (realm == NULL || *realm == '\0' || server == NULL || *server == '\0' ||
        service == NULL || service == '\0') {
        DEBUG(1, ("Missing or empty realm, server or service.\n"));
        return EINVAL;
    }

    if (strcmp(service, SSS_KRB5KDC_FO_SRV) == 0) {
        name_tmpl = KDCINFO_TMPL;
    } else if (strcmp(service, SSS_KRB5KPASSWD_FO_SRV) == 0) {
        name_tmpl = KPASSWDINFO_TMPL;
    } else {
        DEBUG(1, ("Unsupported service [%s]\n.", service));
        return EINVAL;
    }

    server_len = strlen(server);

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(1, ("talloc_new failed.\n"));
        return ENOMEM;
    }

    tmp_name = talloc_asprintf(tmp_ctx, PUBCONF_PATH"/.krb5info_dummy_XXXXXX");
    if (tmp_name == NULL) {
        DEBUG(1, ("talloc_asprintf failed.\n"));
        ret = ENOMEM;
        goto done;
    }

    krb5info_name = talloc_asprintf(tmp_ctx, name_tmpl, realm);
    if (krb5info_name == NULL) {
        DEBUG(1, ("talloc_asprintf failed.\n"));
        ret = ENOMEM;
        goto done;
    }

    old_umask = umask(077);
    fd = mkstemp(tmp_name);
    umask(old_umask);
    if (fd == -1) {
        ret = errno;
        DEBUG(1, ("mkstemp failed [%d][%s].\n", ret, strerror(ret)));
        goto done;
    }

    errno = 0;
    written = sss_atomic_write_s(fd, discard_const(server), server_len);
    if (written == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              ("write failed [%d][%s].\n", ret, strerror(ret)));
        goto done;
    }

    if (written != server_len) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              ("Write error, wrote [%d] bytes, expected [%d]\n",
               written, server_len));
        ret = EIO;
        goto done;
    }

    ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if (ret == -1) {
        ret = errno;
        DEBUG(1, ("fchmod failed [%d][%s].\n", ret, strerror(ret)));
        goto done;
    }

    ret = close(fd);
    if (ret == -1) {
        ret = errno;
        DEBUG(1, ("close failed [%d][%s].\n", ret, strerror(ret)));
        goto done;
    }

    ret = rename(tmp_name, krb5info_name);
    if (ret == -1) {
        ret = errno;
        DEBUG(1, ("rename failed [%d][%s].\n", ret, strerror(ret)));
        goto done;
    }

done:
    talloc_free(tmp_ctx);
    return ret;
}
Exemple #9
0
int main(int argc, const char *argv[])
{
    int ret;
    int kerr;
    int opt;
    int debug_fd = -1;
    poptContext pc;
    TALLOC_CTX *main_ctx = NULL;
    uint8_t *buf = NULL;
    ssize_t len = 0;
    const char *ccname = NULL;
    time_t expire_time = 0;
    struct input_buffer *ibuf = NULL;
    struct response *resp = NULL;
    size_t written;

    struct poptOption long_options[] = {
        POPT_AUTOHELP
        {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
         _("Debug level"), NULL},
        {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
         _("Add debug timestamps"), NULL},
        {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
         _("Show timestamps with microseconds"), NULL},
        {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
         _("An open file descriptor for the debug logs"), NULL},
        POPT_TABLEEND
    };

    /* Set debug level to invalid value so we can decide if -d 0 was used. */
    debug_level = SSSDBG_INVALID;

    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    while((opt = poptGetNextOpt(pc)) != -1) {
        switch(opt) {
        default:
        fprintf(stderr, "\nInvalid option %s: %s\n\n",
                  poptBadOption(pc, 0), poptStrerror(opt));
            poptPrintUsage(pc, stderr, 0);
            _exit(-1);
        }
    }

    poptFreeContext(pc);

    DEBUG_INIT(debug_level);

    debug_prg_name = talloc_asprintf(NULL, "[sssd[ldap_child[%d]]]", getpid());
    if (!debug_prg_name) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf failed.\n"));
        goto fail;
    }

    if (debug_fd != -1) {
        ret = set_debug_file_from_fd(debug_fd);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, ("set_debug_file_from_fd failed.\n"));
        }
    }

    DEBUG(SSSDBG_TRACE_FUNC, ("ldap_child started.\n"));

    main_ctx = talloc_new(NULL);
    if (main_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n"));
        talloc_free(discard_const(debug_prg_name));
        goto fail;
    }
    talloc_steal(main_ctx, debug_prg_name);

    buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE);
    if (buf == NULL) {
        DEBUG(1, ("talloc_size failed.\n"));
        goto fail;
    }

    ibuf = talloc_zero(main_ctx, struct input_buffer);
    if (ibuf == NULL) {
        DEBUG(1, ("talloc_size failed.\n"));
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_INTERNAL, ("context initialized\n"));

    errno = 0;
    len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE);
    if (len == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n", ret, strerror(ret)));
        goto fail;
    }

    close(STDIN_FILENO);

    ret = unpack_buffer(buf, len, ibuf);
    if (ret != EOK) {
        DEBUG(1, ("unpack_buffer failed.[%d][%s].\n", ret, strerror(ret)));
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_INTERNAL, ("getting TGT sync\n"));
    kerr = ldap_child_get_tgt_sync(main_ctx,
                                   ibuf->realm_str, ibuf->princ_str,
                                   ibuf->keytab_name, ibuf->lifetime,
                                   &ccname, &expire_time);
    if (kerr != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("ldap_child_get_tgt_sync failed.\n"));
        /* Do not return, must report failure */
    }

    ret = prepare_response(main_ctx, ccname, expire_time, kerr, &resp);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("prepare_response failed. [%d][%s].\n",
                    ret, strerror(ret)));
        goto fail;
    }

    errno = 0;
    written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size);
    if (written == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE, ("write failed [%d][%s].\n", ret,
                    strerror(ret)));
        goto fail;
    }

    if (written != resp->size) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Expected to write %d bytes, wrote %d\n",
              resp->size, written));
        goto fail;
    }

    DEBUG(SSSDBG_TRACE_FUNC, ("ldap_child completed successfully\n"));
    close(STDOUT_FILENO);
    talloc_free(main_ctx);
    _exit(0);

fail:
    DEBUG(SSSDBG_CRIT_FAILURE, ("ldap_child failed!\n"));
    close(STDOUT_FILENO);
    talloc_free(main_ctx);
    _exit(-1);
}
Exemple #10
0
int pidfile(const char *path, const char *name)
{
    char pid_str[32];
    pid_t pid;
    char *file;
    int fd;
    int ret, err;
    ssize_t len;
    size_t size;
    ssize_t written;
    ssize_t pidlen = sizeof(pid_str) - 1;

    file = talloc_asprintf(NULL, "%s/%s.pid", path, name);
    if (!file) {
        return ENOMEM;
    }

    fd = open(file, O_RDONLY, 0644);
    err = errno;
    if (fd != -1) {
        errno = 0;
        len = sss_atomic_read_s(fd, pid_str, pidlen);
        ret = errno;
        if (len == -1) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "read failed [%d][%s].\n", ret, strerror(ret));
            close(fd);
            talloc_free(file);
            return EINVAL;
        }

        /* Ensure NULL-termination */
        pid_str[len] = '\0';

        /* let's check the pid */
        pid = (pid_t)atoi(pid_str);
        if (pid != 0) {
            errno = 0;
            ret = kill(pid, 0);
            /* succeeded in signaling the process -> another sssd process */
            if (ret == 0) {
                close(fd);
                talloc_free(file);
                return EEXIST;
            }
            if (ret != 0 && errno != ESRCH) {
                err = errno;
                close(fd);
                talloc_free(file);
                return err;
            }
        }

        /* nothing in the file or no process */
        close(fd);
        ret = unlink(file);
        /* non-fatal failure */
        if (ret != EOK) {
            ret = errno;
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Failed to remove file: %s - %d [%s]!\n",
                  file, ret, sss_strerror(ret));
        }
    } else {
        if (err != ENOENT) {
            talloc_free(file);
            return err;
        }
    }

    fd = open(file, O_CREAT | O_WRONLY | O_EXCL, 0644);
    err = errno;
    if (fd == -1) {
        talloc_free(file);
        return err;
    }
    talloc_free(file);

    memset(pid_str, 0, sizeof(pid_str));
    snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid());
    size = strlen(pid_str);

    errno = 0;
    written = sss_atomic_write_s(fd, pid_str, size);
    if (written == -1) {
        err = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "write failed [%d][%s]\n", err, strerror(err));
        close(fd);
        return err;
    }

    if (written != size) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Wrote %zd bytes expected %zu\n", written, size);
        close(fd);
        return EIO;
    }

    close(fd);

    return 0;
}
Exemple #11
0
int main(int argc, const char *argv[])
{
    int opt;
    int debug_fd = -1;
    poptContext pc;
    ssize_t len;
    ssize_t written;
    errno_t ret;
    uint8_t buf[IN_BUF_SIZE];
    const char *action = NULL;
    const char *guitar;
    const char *drums;

    struct poptOption long_options[] = {
        POPT_AUTOHELP
        {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
         _("Debug level"), NULL},
        {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
         _("Add debug timestamps"), NULL},
        {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
         _("Show timestamps with microseconds"), NULL},
        {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
         _("An open file descriptor for the debug logs"), NULL},
        {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \
         _("Send the debug output to stderr directly."), NULL },
        {"guitar", 0, POPT_ARG_STRING, &guitar, 0, _("Who plays guitar"), NULL },
        {"drums", 0, POPT_ARG_STRING, &drums, 0, _("Who plays drums"), NULL },
        POPT_TABLEEND
    };

    /* Set debug level to invalid value so we can decide if -d 0 was used. */
    debug_level = SSSDBG_INVALID;

    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    while((opt = poptGetNextOpt(pc)) != -1) {
        switch(opt) {
        default:
        fprintf(stderr, "\nInvalid option %s: %s\n\n",
                  poptBadOption(pc, 0), poptStrerror(opt));
            poptPrintUsage(pc, stderr, 0);
            poptFreeContext(pc);
            _exit(1);
        }
    }
    poptFreeContext(pc);

    action = getenv("TEST_CHILD_ACTION");
    if (action) {
        if (strcasecmp(action, "check_extra_args") == 0) {
            if (!(strcmp(guitar, "george") == 0 \
                        && strcmp(drums, "ringo") == 0)) {
                DEBUG(SSSDBG_CRIT_FAILURE, "This band sounds weird\n");
                _exit(1);
            }
        } else if (strcasecmp(action, "check_only_extra_args") == 0) {
            if (debug_timestamps == 1) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "debug_timestamp was passed when only extra args "
                      "should have been\n");
                _exit(1);
            }

            if (!(strcmp(guitar, "george") == 0 \
                        && strcmp(drums, "ringo") == 0)) {
                DEBUG(SSSDBG_CRIT_FAILURE, "This band sounds weird\n");
                _exit(1);
            }
        } else if (strcasecmp(action, "check_only_extra_args_neg") == 0) {
            if (debug_timestamps != 1) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "debug_timestamp was not passed as expected\n");
                _exit(1);
            }
        } else if (strcasecmp(action, "echo") == 0) {
            errno = 0;
            len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE);
            if (len == -1) {
                ret = errno;
                DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret));
                _exit(1);
            }
            close(STDIN_FILENO);

            errno = 0;
            written = sss_atomic_write_s(3, buf, len);
            if (written == -1) {
                ret = errno;
                DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret,
                            strerror(ret));
                _exit(1);
            }
            close(STDOUT_FILENO);

            if (written != len) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n",
                      len, written);
                _exit(1);
            }
        }
    }

    DEBUG(SSSDBG_TRACE_FUNC, "test_child completed successfully\n");
    _exit(0);
}
Exemple #12
0
static errno_t sss_write_krb5_snippet_common(const char *file_name,
                                             const char *content)
{
    int ret;
    errno_t err;
    TALLOC_CTX *tmp_ctx = NULL;
    char *tmp_file = NULL;
    int fd = -1;
    mode_t old_mode;
    ssize_t written;
    size_t size;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
        return ENOMEM;
    }

    tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", file_name);
    if (tmp_file == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
        ret = ENOMEM;
        goto done;
    }

    old_mode = umask(SSS_DFL_UMASK);
    fd = mkstemp(tmp_file);
    umask(old_mode);
    if (fd < 0) {
        DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for "
                                 "krb5 config snippet failed.\n", tmp_file);
        ret = EIO;
        talloc_zfree(tmp_ctx);
        goto done;
    }

    size = strlen(content);
    written = sss_atomic_write_s(fd, discard_const(content), size);
    close(fd);
    if (written == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "write failed [%d][%s]\n", ret, sss_strerror(ret));
        goto done;
    }

    if (written != size) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Wrote %zd bytes expected %zu\n", written, size);
        ret = EIO;
        goto done;
    }

    ret = rename(tmp_file, file_name);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "rename failed [%d][%s].\n", ret, sss_strerror(ret));
        goto done;
    }
    tmp_file = NULL;

    ret = chmod(file_name, 0644);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "chmod failed [%d][%s].\n", ret, sss_strerror(ret));
        goto done;
    }

done:
    if (tmp_file != NULL) {
        err = unlink(tmp_file);
        if (err == -1) {
            err = errno;
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Could not remove file [%s]: [%d]: %s\n",
                  tmp_file, err, sss_strerror(err));
        }
    }

    talloc_free(tmp_ctx);
    return ret;
}
Exemple #13
0
/* connect to server using socket */
static int
connect_socket(int family, struct sockaddr *addr, size_t addr_len)
{
    int flags;
    int sock = -1;
    struct pollfd fds[2];
    char buffer[BUFFER_SIZE];
    int i;
    ssize_t res;
    int ret;

    /* set O_NONBLOCK on standard input */
    flags = fcntl(0, F_GETFL);
    if (flags == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    ret = fcntl(0, F_SETFL, flags | O_NONBLOCK);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    /* create socket */
    sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
    if (sock == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("socket() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    /* connect to the server */
    ret = connect(sock, addr, addr_len);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("connect() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    /* set O_NONBLOCK on the socket */
    flags = fcntl(sock, F_GETFL);
    if (flags == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
    if (ret == -1) {
        ret = errno;
        DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
                ret, strerror(ret)));
        goto done;
    }

    fds[0].fd = 0;
    fds[0].events = POLLIN;
    fds[1].fd = sock;
    fds[1].events = POLLIN;

    while (1) {
        ret = poll(fds, 2, -1);
        if (ret == -1) {
            ret = errno;
            if (ret == EINTR || ret == EAGAIN) {
                continue;
            }
            DEBUG(SSSDBG_OP_FAILURE,
                  ("poll() failed (%d): %s\n", ret, strerror(ret)));
            goto done;
        }

        /* read from standard input & write to socket */
        /* read from socket & write to standard output */
        for (i = 0; i < 2; i++) {
            if (fds[i].revents & POLLIN) {
                res = read(fds[i].fd, buffer, BUFFER_SIZE);
                if (res == -1) {
                    ret = errno;
                    if (ret == EAGAIN || ret == EINTR || ret == EWOULDBLOCK) {
                        continue;
                    }
                    DEBUG(SSSDBG_OP_FAILURE,
                          ("read() failed (%d): %s\n", ret, strerror(ret)));
                    goto done;
                } else if (res == 0) {
                    ret = EOK;
                    goto done;
                }

                errno = 0;
                res = sss_atomic_write_s(i == 0 ? sock : 1, buffer, res);
                ret = errno;
                if (res == -1) {
                    DEBUG(SSSDBG_OP_FAILURE,
                          ("sss_atomic_write_s() failed (%d): %s\n",
                           ret, strerror(ret)));
                    goto done;
                } else if (ret == EPIPE) {
                    ret = EOK;
                    goto done;
                }
            }
            if (fds[i].revents & POLLHUP) {
                ret = EOK;
                goto done;
            }
        }
    }

done:
    if (sock >= 0) close(sock);

    return ret;
}
Exemple #14
0
/* This function will store corrupted memcache to disk for later
 * analysis. */
static void  sss_mc_save_corrupted(struct sss_mc_ctx *mc_ctx)
{
    int err;
    int fd = -1;
    ssize_t written = -1;
    char *file = NULL;
    TALLOC_CTX *tmp_ctx;

    if (mc_ctx == NULL) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Cannot store uninitialized cache. Nothing to do.\n");
        return;
    }

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
        return;
    }

    file = talloc_asprintf(tmp_ctx, "%s_%s",
                           mc_ctx->file, "corrupted");
    if (file == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
        goto done;
    }

    /* We will always store only the last problematic cache state */
    fd = creat(file, 0600);
    if (fd == -1) {
        err = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Failed to open file '%s' [%d]: %s\n",
               file, err, strerror(err));
        goto done;
    }

    written = sss_atomic_write_s(fd, mc_ctx->mmap_base, mc_ctx->mmap_size);
    if (written != mc_ctx->mmap_size) {
        if (written == -1) {
            err = errno;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "write() failed [%d]: %s\n", err, strerror(err));
        } else {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "write() returned %zd (expected (%zd))\n",
                   written, mc_ctx->mmap_size);
        }
        goto done;
    }

    sss_log(SSS_LOG_NOTICE,
            "Stored copy of corrupted mmap cache in file '%s\n'", file);
done:
    if (fd != -1) {
        close(fd);
        if (written == -1) {
            err = unlink(file);
            if (err != 0) {
                err = errno;
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Failed to remove file '%s': %s.\n", file,
                       strerror(err));
            }
        }
    }
    talloc_free(tmp_ctx);
}