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
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 #3
0
static int seed_id_input(const char *req,
                         uid_t *_id_input)
{
    char buf[BUFSIZE+1];
    size_t len = 0;
    size_t bytes_read = 0;
    char *endptr = NULL;
    int ret = EOK;

    ret = seed_prompt(req);
    if (ret != EOK) {
        return ret;
    }

    errno = 0;
    while ((bytes_read = sss_atomic_read_s(STDIN_FILENO, buf+len, 1)) != 0) {
        if (bytes_read == -1) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n",
                                        ret, strerror(ret)));
            return ret;
        }
        if (buf[len] == '\n' || len == BUFSIZE) {
            buf[len] = '\0';
            break;
        }
        len += bytes_read;
    }

    if (isdigit(*buf)) {
        errno = 0;
        *_id_input = (uid_t)strtoll(buf, &endptr, 10);
        if (errno != 0) {
            ret = errno;
            DEBUG(SSSDBG_OP_FAILURE, ("strtoll failed on [%s]: [%d][%s].\n",
                                      (char *)buf, ret, strerror(ret)));
            return ret;
        }
        if (*endptr != '\0') {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  ("extra characters [%s] after ID [%"SPRIuid"]\n",
                   endptr, *_id_input));
        }
    } else {
        ret = EINVAL;
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to get %s input.\n", req));
    }

    return ret;
}
Exemple #4
0
END_TEST

START_TEST(test_atomicio_read_from_empty_file)
{
    char buf[64];
    int fd;
    ssize_t numread;
    errno_t ret;

    fd = open("/dev/null", O_RDONLY);
    fail_if(fd == -1, "Cannot open /dev/null");

    errno = 0;
    numread = sss_atomic_read_s(fd, buf, 64);
    ret = errno;

    fail_unless(ret == 0, "Error %d while reading\n", ret);
    fail_unless(numread == 0,
                "Read %d bytes expected 0\n", numread);
    close(fd);
}
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
static int seed_str_input(TALLOC_CTX *mem_ctx,
                          const char *req,
                          char **_input)
{
    char buf[BUFSIZE+1];
    size_t len = 0;
    size_t bytes_read = 0;
    int ret = EOK;

    ret = seed_prompt(req);
    if (ret != EOK) {
        return ret;
    }

    errno = 0;
    while ((bytes_read = sss_atomic_read_s(STDIN_FILENO, buf+len, 1)) != 0) {
        if (bytes_read == -1) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n",
                                        ret, strerror(ret)));
            return ret;
        }
        if (buf[len] == '\n' || len == BUFSIZE) {
            buf[len] = '\0';
            break;
        }
        len += bytes_read;
    }

    *_input = talloc_strdup(mem_ctx, buf);
    if (*_input == NULL) {
        ret = ENOMEM;
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to allocate input\n"));
    }

    return ret;
}
Exemple #7
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 #8
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 #9
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 #10
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 #11
0
static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
{
    int ret;
    char path[PATHLEN];
    struct stat stat_buf;
    int fd;
    char buf[BUFSIZE];
    char *p;
    char *e;
    char *endptr;
    uint32_t num=0;
    errno_t error;

    ret = snprintf(path, PATHLEN, "/proc/%d/status", pid);
    if (ret < 0) {
        DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed\n");
        return EINVAL;
    } else if (ret >= PATHLEN) {
        DEBUG(SSSDBG_CRIT_FAILURE, "path too long?!?!\n");
        return EINVAL;
    }

    fd = open(path, O_RDONLY);
    if (fd == -1) {
        error = errno;
        if (error == ENOENT) {
            DEBUG(SSSDBG_TRACE_LIBS,
                  "Proc file [%s] is not available anymore, continuing.\n",
                      path);
            return EOK;
        }
        DEBUG(SSSDBG_CRIT_FAILURE,
              "open failed [%d][%s].\n", error, strerror(error));
        return error;
    }

    ret = fstat(fd, &stat_buf);
    if (ret == -1) {
        error = errno;
        if (error == ENOENT) {
            DEBUG(SSSDBG_TRACE_LIBS,
                  "Proc file [%s] is not available anymore, continuing.\n",
                      path);
            error = EOK;
            goto fail_fd;
        }
        DEBUG(SSSDBG_CRIT_FAILURE,
              "fstat failed [%d][%s].\n", error, strerror(error));
        goto fail_fd;
    }

    if (!S_ISREG(stat_buf.st_mode)) {
        DEBUG(SSSDBG_CRIT_FAILURE, "not a regular file\n");
        error = EINVAL;
        goto fail_fd;
    }

    errno = 0;
    ret = sss_atomic_read_s(fd, buf, BUFSIZE);
    if (ret == -1) {
        error = errno;
        DEBUG(SSSDBG_CRIT_FAILURE,
              "read failed [%d][%s].\n", error, strerror(error));
        goto fail_fd;
    }

    /* Guarantee NULL-termination in case we read the full BUFSIZE somehow */
    buf[BUFSIZE-1] = '\0';

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

    p = strstr(buf, "\nUid:\t");
    if (p != NULL) {
        p += 6;
        e = strchr(p,'\t');
        if (e == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n");
            return EINVAL;
        } else {
            *e = '\0';
        }
        num = (uint32_t) strtoint32(p, &endptr, 10);
        error = errno;
        if (error != 0) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "strtol failed [%s].\n", strerror(error));
            return error;
        }
        if (*endptr != '\0') {
            DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n");
            return EINVAL;
        }

    } else {
        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
        return EINVAL;
    }

    *uid = num;

    return EOK;

fail_fd:
    close(fd);
    return error;
}
Exemple #12
0
static int seed_password_input_file(TALLOC_CTX *mem_ctx,
                                    char *filename,
                                    char **_password)
{
    TALLOC_CTX *tmp_ctx = NULL;
    char *password = NULL;
    int len = 0;
    uint8_t buf[PASS_MAX+1];
    int fd = -1;
    int ret = EOK;
    int valid_i;
    int i;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Could not allocate temp context\n"));
        ret = ENOMEM;
        goto done;
    }

    fd = open(filename, O_RDONLY);
    if (fd == -1) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to open password file "
                                    "[%s] [%d][%s]\n",
                                    filename, errno, strerror(errno)));
        ret = EINVAL;
        goto done;
    }

    errno = 0;
    len = sss_atomic_read_s(fd, buf, PASS_MAX + 1);
    if (len == -1) {
        ret = errno;
        DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to read password from file "
                                     "[%s] [%d][%s]\n",
                                     filename, ret, strerror(ret)));
        close(fd);
        goto done;
    }

    close(fd);

    if (len > PASS_MAX) {
        ERROR("Password file too big.\n");
        ret = EINVAL;
        goto done;
    }

    buf[len] = '\0';

    /* Only the first line is valid (without '\n'). */
    for (valid_i = -1; valid_i + 1 < len; valid_i++) {
        if (buf[valid_i + 1] == '\n') {
            buf[valid_i + 1] = '\0';
            break;
        }
    }

    /* Do not allow empty passwords. */
    if (valid_i < 0) {
        ERROR("Empty passwords are not allowed.\n");
        ret = EINVAL;
        goto done;
    }

    /* valid_i is the last valid index of the password followed by \0.
     * If characters other than \n occur int the rest of the file, it
     * is an error. */
    for (i = valid_i + 2; i < len; i++) {
        if (buf[i] != '\n') {
            ERROR("Multi-line passwords are not allowed.\n");
            ret = EINVAL;
            goto done;
        }
    }

    password = talloc_strdup(tmp_ctx, (char *)buf);
    if (password == NULL) {
        ret = ENOMEM;
        goto done;
    }

    *_password = talloc_steal(mem_ctx, password);

done:
    talloc_free(tmp_ctx);
    return ret;
}