void send_response(Socket_t *sock, uint8_t *data, int length) { uint8_t frame[1024]; length = prepare_response(sock, frame, data, length); XbeeFrame_sendframe(mailbox, frame, length); sock->flags &= ~SF_BUSY; }
/* request not completed, return 1 * serious err, return -1 * send back OK, return 0 */ int do_request(struct request *req) { if (!req) return -1; switch(parse_request(req)) { case 0: break; case -1: return -1; case 1: return 1; } if (prepare_response(req) == -1) return -1; if (send_response(req) == -1) return -1; return 0; }
static u2fh_rc _u2fh_register (u2fh_devs * devs, const char *challenge, const char *origin, char **response, size_t * response_len, u2fh_cmdflags flags) { unsigned char data[V2CHALLEN + HOSIZE]; unsigned char buf[MAXDATASIZE]; char bd[2048]; size_t bdlen = sizeof (bd); size_t len; int rc = U2FH_JSON_ERROR; char chalb64[256]; size_t challen = sizeof (chalb64); int iterations = 0; rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); if (rc != U2FH_OK) { return rc; } rc = prepare_browserdata (chalb64, origin, REGISTER_TYP, bd, &bdlen); if (rc != U2FH_OK) return rc; sha256_buffer (bd, bdlen, data); prepare_origin (challenge, data + V2CHALLEN); /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags flag. */ do { struct u2fdevice *dev; if (iterations++ > 15) { return U2FH_TIMEOUT_ERROR; } for (dev = devs->first; dev != NULL; dev = dev->next) { len = MAXDATASIZE; rc = send_apdu (devs, dev->id, U2F_REGISTER, data, sizeof (data), flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 0, buf, &len); if (rc != U2FH_OK) { return rc; } else if (len != 2) { break; } } if (len != 2) { break; } Sleep (1000); } while ((flags & U2FH_REQUEST_USER_PRESENCE) && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); if (len != 2) { prepare_response (buf, len - 2, bd, response, response_len); return U2FH_OK; } return U2FH_TRANSPORT_ERROR; }
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; }
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); }
/** * u2fh_authenticate: * @devs: a device handle, from u2fh_devs_init() and u2fh_devs_discover(). * @challenge: string with JSON data containing the challenge. * @origin: U2F origin URL. * @response: pointer to output string with JSON data. * @flags: set of ORed #u2fh_cmdflags values. * * Perform the U2F Authenticate operation. * * Returns: On success %U2FH_OK (integer 0) is returned, and on errors * an #u2fh_rc error code. */ u2fh_rc u2fh_authenticate (u2fh_devs * devs, const char *challenge, const char *origin, char **response, u2fh_cmdflags flags) { unsigned char data[CHALLBINLEN + HOSIZE + MAXKHLEN + 1]; unsigned char buf[MAXDATASIZE]; char bd[2048]; size_t bdlen = sizeof (bd); size_t len; int rc; char chalb64[256]; size_t challen = sizeof (chalb64); char khb64[256]; size_t kh64len = sizeof (khb64); base64_decodestate b64; size_t khlen; int skip_devices[devs->num_devices]; int skipped = 0; int iterations = 0; memset (skip_devices, 0, sizeof (skip_devices)); rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); if (rc != U2FH_OK) return rc; rc = prepare_browserdata (chalb64, origin, AUTHENTICATE_TYP, bd, &bdlen); if (rc != U2FH_OK) return rc; sha256_buffer (bd, bdlen, data); prepare_origin (challenge, data + CHALLBINLEN); /* confusion between key_handle and keyHandle */ rc = get_fixed_json_data (challenge, "keyHandle", khb64, &kh64len); if (rc != U2FH_OK) return rc; base64_init_decodestate (&b64); khlen = base64_decode_block (khb64, kh64len, data + HOSIZE + CHALLBINLEN + 1, &b64); data[HOSIZE + CHALLBINLEN] = khlen; /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags flag. */ do { int i; if (iterations++ > 15) { return U2FH_TIMEOUT_ERROR; } for (i = 0; i < devs->num_devices; i++) { unsigned char tmp_buf[MAXDATASIZE]; if (skip_devices[i] != 0) { continue; } if (!devs->devs[i].is_alive) { skipped++; skip_devices[i] = 1; continue; } len = MAXDATASIZE; rc = send_apdu (devs, i, U2F_AUTHENTICATE, data, HOSIZE + CHALLBINLEN + khlen + 1, flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 7, tmp_buf, &len); if (rc != U2FH_OK) { return rc; } else if (len != 2) { memcpy (buf, tmp_buf, len); break; } else if (memcmp (tmp_buf, NOTSATISFIED, 2) != 0) { skipped++; skip_devices[i] = 2; continue; } memcpy (buf, tmp_buf, len); } if (len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0) { Sleep (1000); } } while ((flags & U2FH_REQUEST_USER_PRESENCE) && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); if (len == 2 && memcmp (buf, NOTSATISFIED, 2) != 0) { return U2FH_AUTHENTICATOR_ERROR; } if (len != 2) { prepare_response (buf, len - 2, bd, challenge, response); } return U2FH_OK; }
int main(int argc, char** argv) { int option; int option_index = 0; char *interface = NULL; char *service = NULL; #ifdef CONFIG_DAEMON int killdaemon = 0; pid_t pid; #endif /* CONFIG_DAEMON */ struct sockaddr_storage clientaddr; socklen_t clientsize = sizeof(clientaddr); int client; request_t *request; response_t *response; #ifdef CONFIG_DEBUG char clientstr[INET6_ADDRSTRLEN]; #endif /* CONFIG_DEBUG */ /* getopt_long options */ static struct option long_options[] = { {"version", no_argument, NULL, 0 }, {"help", no_argument, NULL, 0 }, {"interface", required_argument, NULL, 'i'}, {"port", required_argument, NULL, 'p'}, #ifdef CONFIG_DAEMON {"pidfile", required_argument, NULL, 'P'}, {"kill", no_argument, NULL, 'k'}, #endif /* CONFIG_DAEMON */ {NULL, 0, NULL, 0 } }; #ifdef CONFIG_DAEMON /* Open syslog connection */ openlog(PACKAGE_NAME, LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); #endif /* CONFIG_DAEMON */ /* Check for options */ #ifndef CONFIG_DAEMON #define OPTSTRING "i:p:0" #else #define OPTSTRING "i:p:Pk0" #endif /* CONFIG_DAEMON */ while((option = getopt_long(argc, argv, OPTSTRING, long_options, &option_index)) != EOF) { switch(option) { case 'i': if((interface = malloc(strlen(optarg) + 1)) == NULL) { eerror("Failed to allocate interface"); exit(EXIT_FAILURE); } strcpy(interface, optarg); break; case 'p': if((service = malloc(strlen(optarg) + 1)) == NULL) { eerror("Failed to allocate service"); exit(EXIT_FAILURE); } strcpy(service, optarg); break; #ifdef CONFIG_DAEMON case 'P': if((global.pidfile = malloc(strlen(optarg) + 1)) == NULL) { eerror("Failed to allocate pidfile"); exit(EXIT_FAILURE); } strcpy(global.pidfile, optarg); break; case 'k': killdaemon = 1; break; #endif /* CONFIG_DAEMON */ case 0: if(option_index == 0) { fprintf(stdout, "%s\n", PACKAGE_STRING); exit(EXIT_SUCCESS); } case '?': fprintf(stderr, "Usage: " PACKAGE_NAME " [OPTIONS]\n\n" "-i, --interface INTF Use the specified interface (" "default is " DEFAULT_INTERFACE ").\n" "-p, --port PORT Use the specified port (" "default is " DEFAULT_PORT ").\n" #ifdef CONFIG_DAEMON "-P, --pidfile PIDFILE Use the specified pidfile (" "default is " DEFAULT_PIDFILE ").\n" "-k, --kill Kill the running daemon.\n" #endif /* CONFIG_DAEMON */ " --version Display version.\n" " --help Display this help screen.\n\n" PACKAGE_NAME " home page: <" PACKAGE_URL ">\n" "Report " PACKAGE_NAME " bugs to <" PACKAGE_BUGREPORT ">\n"); exit(EXIT_FAILURE); break; } } /* Set default option if needed */ if(interface == NULL) { if((interface = malloc(strlen(DEFAULT_INTERFACE) + 1)) == NULL) { eerror("Failed to allocate interface"); exit(EXIT_FAILURE); } strcpy(interface, DEFAULT_INTERFACE); } if(service == NULL) { if((service = malloc(strlen(DEFAULT_PORT) + 1)) == NULL) { eerror("Failed to allocate service"); exit(EXIT_FAILURE); } strcpy(service, DEFAULT_PORT); } #ifdef CONFIG_DAEMON if(global.pidfile == NULL) { if((global.pidfile = malloc(strlen(DEFAULT_PIDFILE) + 1)) == NULL) { eerror("Failed to allocate pidfile"); exit(EXIT_FAILURE); } strcpy(global.pidfile, DEFAULT_PIDFILE); } /* The --kill option have been used */ if(killdaemon == 1) { if(havepid(global.pidfile) < 0) exit(EXIT_SUCCESS); if((pid = readpid(global.pidfile)) == 0) { critical("Failed to read pid file"); exit(EXIT_FAILURE); } if(kill(pid, 0) < 0) { ewarning("Failed to check process"); if(deletepid(global.pidfile) < 0) { critical("Failed to delete the pid file"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } if(kill(pid, SIGTERM) < 0) { eerror("Failed to send SIGTERM"); info("Waiting one second before SIGKILL"); sleep(1); if(kill(pid, SIGKILL) < 0) { ecritical("Failed to send SIGKILL"); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); } /* Check if a daemon is not already started */ if(havepid(global.pidfile) == 0) { if((pid = readpid(global.pidfile)) == 0) { critical("Failed to read pid file"); exit(EXIT_FAILURE); } if(kill(pid, 0) == 0) { info("The daemon is already started"); exit(EXIT_SUCCESS); } if(deletepid(global.pidfile) < 0) { critical("Failed to delete the pid file"); exit(EXIT_FAILURE); } } /* Become a daemon */ if(daemonize() < 0) { critical("Failed to daemonize"); exit(EXIT_FAILURE); } /* Create the pid file */ if(createpid(global.pidfile) < 0) { critical("Failed to create pid file"); exit(EXIT_FAILURE); } #endif /* CONFIG_DAEMON */ /* Handle SIGTERM */ if(signal(SIGTERM, quit) == SIG_ERR) { ecritical("Failed to handle SIGTERM"); exit(EXIT_FAILURE); } notice("Start %s", PACKAGE_STRING); /* Get listener */ if((global.listener = getintflistener(interface, service, AF_UNSPEC)) < 0) { critical("Failed to get listener"); exit(EXIT_FAILURE); } free(interface); free(service); /* The big loop */ global.running = 1; while(global.running == 1) { if((client = accept(global.listener, (struct sockaddr *)&clientaddr, &clientsize)) < 0) { if(global.running == 0) break; eerror("Failed to accept client"); continue; } #ifdef CONFIG_DEBUG inet_ntop(clientaddr.ss_family, (clientaddr.ss_family == AF_INET) ? (void*)&(((struct sockaddr_in*)&clientaddr)->sin_addr) : (void*)&(((struct sockaddr_in6*)&clientaddr)->sin6_addr), clientstr, sizeof(clientstr)); debug("Got a new connection from: %s", clientstr); #endif /* CONFIG_DEBUG */ if((request = (request_t*)recv_packet(client)) == NULL) { close(client); error("Failed to receive request"); continue; } /* Prepare response */ if((response = (response_t*)prepare_response(SUCCESS, request->data, strlen(request->data))) == NULL) { free(request); close(client); eerror("Failed to prepare response"); continue; } free(request); if(send_packet(client, (packet_t*)response) < 0) { close(client); error("Failed to send response"); continue; } close(client); } exit(EXIT_SUCCESS); }
int main(int argc, const char *argv[]) { int ret; int kerr; int opt; int debug_fd = -1; poptContext pc; TALLOC_CTX *main_ctx; 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 deside 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); CONVERT_AND_SET_DEBUG_LEVEL(debug_level); DEBUG(7, ("ldap_child started.\n")); main_ctx = talloc_new(NULL); if (main_ctx == NULL) { DEBUG(1, ("talloc_new failed.\n")); _exit(-1); } debug_prg_name = talloc_asprintf(main_ctx, "[sssd[ldap_child[%d]]]", getpid()); if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(1, ("set_debug_file_from_fd failed.\n")); } } 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; } while ((ret = read(STDIN_FILENO, buf + len, IN_BUF_SIZE - len)) != 0) { if (ret == -1) { if (errno == EINTR || errno == EAGAIN) { continue; } DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno))); goto fail; } else if (ret > 0) { len += ret; if (len > IN_BUF_SIZE) { DEBUG(1, ("read too much, this should never happen.\n")); goto fail; } continue; } else { DEBUG(1, ("unexpected return code of read [%d].\n", 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; } 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(1, ("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(1, ("prepare_response failed. [%d][%s].\n", ret, strerror(ret))); return ENOMEM; } written = 0; while (written < resp->size) { ret = write(STDOUT_FILENO, resp->buf + written, resp->size - written); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) { continue; } ret = errno; DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret))); return ret; } written += ret; } close(STDOUT_FILENO); talloc_free(main_ctx); _exit(0); fail: close(STDOUT_FILENO); talloc_free(main_ctx); _exit(-1); }