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); }
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; }
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; }
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?"); }
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); }
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; }
/* * 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; }
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; }
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); }
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; }
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); }
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; }
/* 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; }
/* 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); }