Пример #1
0
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;
}
Пример #2
0
/* 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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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);
}
Пример #6
0
/**
 * 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;
}
Пример #7
0
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);
}
Пример #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;
    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);
}