Esempio n. 1
0
static int
mmio_write_x(int argc, const char *argv[], const struct cmd_info *info)
{
	int ret;
	unsigned long ldata;
	data_store data;
	struct mmap_info mmap_addr;

	mmap_addr.addr = strtoull(argv[1], NULL, 0);
	ldata = strtoul(argv[2], NULL, 0);

	if (open_mapping(&mmap_addr, O_RDWR, sizeof(data)) < 0) {
		return -1;
	}

	ret = 0;

	#define DO_WRITE(mem_, off_, size_)\
		data.u ##size_ = (typeof(data.u ##size_))ldata;\
		*(typeof(data.u ##size_) *)(mem_+off_) = data.u ##size_

	switch (get_command_size(info)) {
	case SIZE8:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 8);
		break;
	case SIZE16:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 16);
		break;
	case SIZE32:
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 32);
		break;
	case SIZE64:
		if (sizeof(void *) != sizeof(uint64_t)) {
			fprintf(stderr, "warning: 64 bit operations might "
			        "not be atomic on 32 bit builds\n");
		}
		DO_WRITE(mmap_addr.mem, mmap_addr.off, 64);
		break;
	default:
		fprintf(stderr, "invalid mmio_write parameter\n");
		ret = -1;
	}

	close_mapping(&mmap_addr);

	return ret;
}
Esempio n. 2
0
char*
send_command(const char* command, const char* argument)
{
  open_socket();

#define DO_WRITE(buf) \
	if (write(sockfd, buf, strlen(buf)) != strlen(buf)) { \
 		perror("write error to pathname translation server"); \
		abort(); \
	}

  DO_WRITE(command);
  DO_WRITE(" ");
  DO_WRITE(argument);
  DO_WRITE("\n");

  /* xxx read must be much better, we can't assume to receive the whole 
   * answer in one read()
   */
  {
    size_t buflen = 2*PATH_MAX; /* there be buffer overflows */
    char* reply = calloc(1, buflen);
    int read_len = read(sockfd, reply, buflen);

    char* lf = strchr(reply, '\n');

    if (!lf) {
      fprintf(stderr, "received incomplete reply [%s] from pathname "
	      "translation server\n");
      abort();
    }

    *lf = 0;

    return reply;
  }
}
Esempio n. 3
0
static struct KeywordList * 
getKeywords(struct EXTRACT_Process * eproc,
	    const char * filename) {
  struct KeywordList * pos;
  struct KeywordList * next;
  struct KeywordList * head;
  unsigned int count;
  size_t slen;
  int status;

  if (eproc->pid == -1)
    if (0 != do_fork(eproc))
      return NULL;
  if (eproc->pid == -1)
    return NULL;
  fprintf(stderr, "Processing file %s\n", filename);
  head = NULL;
  pos = NULL;
  next = NULL;
  DO_WRITE(eproc->send_pipe, filename, strlen(filename)+1);
  DO_READ(eproc->read_pipe, &count, sizeof(unsigned int));
  while (count-- > 0) {
    next = malloc(sizeof(struct KeywordList));
    DO_READ(eproc->read_pipe, &next->keywordType, sizeof(enum EXTRACTOR_MetaType));
    DO_READ(eproc->read_pipe, &slen, sizeof(size_t));
    if (slen == 0)
    {
      free(next);
      next = NULL;
      continue;
    }
    if (slen > MAX_SLEN) 
      goto ERROR; /* too large! something must have gone wrong! */
    if (pos == NULL) {
      pos = next;
      next = NULL;
      head = pos;
    } else {
      pos->next = next;
      next = NULL;
      pos = pos->next;
    }
    pos->next = NULL;
    pos->keyword = malloc(slen + 1);
    pos->keyword[slen] = '\0';
    DO_READ(eproc->read_pipe, pos->keyword, slen);
  }  
  return head;
 ERROR:
#if DEBUG_IPC
  fprintf(stderr, "READ ERROR!\n");
#endif
  if (next != NULL)
    free(next);
  freeKeywords(head);
  if (eproc->send_pipe != -1)
    close(eproc->send_pipe);
  eproc->send_pipe = -1;
  if (eproc->read_pipe != -1)
    close(eproc->read_pipe);
  eproc->read_pipe = -1;
  if (eproc->pid != -1) {
    kill(eproc->pid, SIGTERM); 
    waitpid(eproc->pid, &status, 0);
  }
  eproc->pid = -1;
  return NULL;  
}
Esempio n. 4
0
/**
 * @return 0 on success, 1 on error.
 */
static int do_fork(struct EXTRACT_Process * proc) {
  int filedes1[2];
  int filedes2[2];
  char buffer[FILENAME_MAX+2];
  size_t pos;
  ssize_t ret;
  size_t slen;
  struct EXTRACTOR_PluginList * list;
  char * filename;
  struct AccuCtx acc_ctx;

#if DEBUG_IPC
  fprintf(stderr, "Forking!\n");
#endif
  if (0 != pipe(filedes1)) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "pipe",
		 strerror(errno));
    return 1;
  }
  if (0 != pipe(filedes2)) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "pipe",
		 strerror(errno));
    close(filedes1[0]);
    close(filedes1[1]);
    return 1;
  } 
  /* log before fork, just to avoid out-of-process problems
     with my_log */
  if (proc->do_default)
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_VERY_VERBOSE,
		 (_("Loading default set of libextractor plugins.\n")));
  if (proc->libs != NULL) 
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_VERY_VERBOSE,
		 _("Loading libextractor plugins: '%s'\n"),
		 proc->libs);  

  proc->pid = fork();
  if (proc->pid == -1) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "fork",
		 strerror(errno));
    close(filedes1[0]);
    close(filedes1[1]);
    close(filedes2[0]);
    close(filedes2[1]);
    return 1;
  }
  if (proc->pid != 0) {
    close(filedes1[1]);
    close(filedes2[0]);
    proc->send_pipe = filedes2[1];
    proc->read_pipe = filedes1[0];
    return 0;
  }
  /* we're now in the forked process! */
  close(filedes1[0]);
  close(filedes2[1]);
  list = NULL;

  if (proc->do_default)
    list = EXTRACTOR_plugin_add_defaults(EXTRACTOR_OPTION_DEFAULT_POLICY);
  if (proc->libs != NULL) 
    list = EXTRACTOR_plugin_add_config(list,
				       proc->libs,
				       EXTRACTOR_OPTION_DEFAULT_POLICY);  
  
  pos = 0;
  buffer[FILENAME_MAX + 1] = '\0';
  ret = read(filedes2[0], &buffer[pos], FILENAME_MAX + 1 - pos);
  while ( (-1 != ret) &&
	  (ret != 0) ) {
    pos += ret;
    slen = strlen(buffer) + 1;
    if (slen <= pos) {
      filename = strdup(buffer);
      memmove(buffer,
	      &buffer[slen],
	      pos - slen);
      pos = pos - slen;
      acc_ctx.count = 0;
      acc_ctx.size = 0;
      acc_ctx.keywords = NULL;
      acc_ctx.types = NULL;
      EXTRACTOR_extract(list,
			filename,
			NULL, 0,
			&accumulator,
			&acc_ctx);
      DO_WRITE(filedes1[1], &acc_ctx.count, sizeof(unsigned int));
      while (0 != acc_ctx.count--) {
	DO_WRITE(filedes1[1], 
		 &acc_ctx.types[acc_ctx.count],
		 sizeof(enum EXTRACTOR_MetaType));
	slen = strlen(acc_ctx.keywords[acc_ctx.count]);
	if (slen > MAX_SLEN)
	  slen = MAX_SLEN; /* cut off -- far too large! */
	DO_WRITE(filedes1[1], &slen, sizeof(size_t));
	DO_WRITE(filedes1[1], acc_ctx.keywords[acc_ctx.count], slen);
	free(acc_ctx.keywords[acc_ctx.count]);
      }
      free (acc_ctx.keywords);
      free (acc_ctx.types);
      acc_ctx.keywords = NULL;
      acc_ctx.types = NULL;
      acc_ctx.size = 0;
    }
    ret = read(filedes2[0], &buffer[pos], FILENAME_MAX + 1 - pos);
  }
  /* exit / cleanup */
 ERROR:
  free (acc_ctx.keywords);
  free (acc_ctx.types);
  EXTRACTOR_plugin_remove_all (list);
  close(filedes2[0]);
  close(filedes1[1]);
  /* never return - we were forked! */
  exit(0);
  return 1; /* eh, dead */
}
Esempio n. 5
0
int
main (int argc, char *argv[], char *environ[])
{
  int n = 1;
  int valid = -1;
  char iobuf[BUFSIZ];
  char sysconfdir[BUFSIZ];
  char c_str[BUFSIZ];
  char c_command[BUFSIZ];
  char *p = NULL;
  char *rand = rand2str (16);
  time_t now = time ((time_t *) NULL);
  struct stat s;
  struct sigaction saterm;
  struct sigaction sawinch;
  struct sigaction sachild;
  struct timeval tv;
  double oldtime, newtime;
  struct stat ttybuf;
  int c;
  char argtest[BUFSIZ];

  user.vshell = NULL;
  user.shell.ptr = NULL;
  user.home.ptr = NULL;
  user.term.ptr = NULL;

  progname = argv[0];

  if ((p = (char *) strrchr (progname, '/')) != NULL)
    progname = p + 1;

  if (*progname == '-')
    loginshell = 1;

  /* Who are you? */
  user.pw = getpwuid ((uid_t) getuid ());

  if (user.pw == NULL)
    {
      fprintf (stderr, "I do not know who you are.  Stopping.\n");
      perror ("getpwuid");
      exit (EXIT_FAILURE);
    }

  strncpy (user.to, user.pw->pw_name, BUFSIZ - 1);

  user.term.ptr = getenv ("TERM");

  if (user.term.ptr == NULL)
    user.term.ptr = "dumb";

  if (strlen (user.term.ptr) < 1)
    user.term.ptr = "dumb";

  snprintf (sysconfdir, BUFSIZ - 1, "%s/sudosh.conf", SYSCONFDIR);
  parse (&sudosh_option, sysconfdir);

  while ((c = getopt (argc, argv, "c:hivV")) != EOF)
    {
      switch (c)
	{
	case 'c':
//              fprintf(stderr,"optarg is [%s]\n",optarg);
	  strncpy (user.from, user.pw->pw_name, BUFSIZ - 1);
	  strncpy (c_str, optarg, BUFSIZ - 1);
	  strncpy (c_command, optarg, BUFSIZ - 1);
	  p = strchr (c_str, ' ');
	  if (p)
	    {
	      p[0] = 0;
//              fprintf(stderr,"args=%s\n",c_args);
	    }

	  if (c_str[0] != 0)
	    {
// Test for methods of escape
	      if (strchr (c_command, ';') != NULL ||
		  strchr (c_command, '&') != NULL ||
		  strchr (c_command, '|') != NULL ||
		  strchr (c_command, '<') != NULL ||
		  strchr (c_command, '>') != NULL ||
		  strchr (c_command, '`') != NULL)
		{
		  fprintf (stderr,
			   "\"%s\" isn't allowed to be executed with process or redirect controls.\n",
			   c_command);
		  exit (EXIT_FAILURE);
		}


//              fprintf(stderr,"Testing c\n");
	      // Make sure that c_str is in argallow

	      sprintf (argtest, "$%.100s$", c_str);
//              fprintf(stderr,"Testing for %s\n",argtest);

	      if (strstr (sudosh_option.argallow, argtest) != NULL || strchr(sudosh_option.argallow, '*')!=NULL)
		{
		  FILE *f;
		  snprintf (script.name, (size_t) BUFSIZ - 1,
			    "%s/%s%c%s%cinteractive%c%i%c%s",
			    sudosh_option.logdir, user.from,
			    sudosh_option.fdl, user.to, sudosh_option.fdl,
			    sudosh_option.fdl, (int) now, sudosh_option.fdl,
			    rand);

		  f = fopen (script.name, "w");

		  if (f == (FILE *) 0)
		    {
		      fprintf (stderr, "%.100s: %.100s (%i)\n", script.name,
			       strerror (errno), errno);
		      exit (EXIT_FAILURE);
		    }

		  fprintf (f, "%.256s\n", c_str);
		  fclose (f);

		  execl ("/bin/sh", "sh", "-c", c_command, (char *) 0);
		  exit (EXIT_SUCCESS);
		  break;
		}
	      else
		{
		  fprintf (stderr, "\"%s\" isn't allowed to be executed.\n",
			   c_str);
		  exit (EXIT_FAILURE);
		  break;
		}
	    }
	  break;
	case 'h':
	case '?':
	  fprintf (stdout,
		   "Usage: sudosh\n"
		   "sudo shell that supports input and output logging to syslog\n"
		   "\n"
		   "-h, --help	display this help and exit\n"
		   "-i, --init	initialize logdir (mkdir and chmod) (ignored for compatibility)\n"
		   "-v, --version	output version information and exit\n"
		   "\n" "Report bugs to <%s>\n", PACKAGE_BUGREPORT);
	  exit (EXIT_SUCCESS);
	  break;
	case 'i':
	  fprintf (stdout,
		   "Ignoring initialize option, this is done automatically\n");
	  exit (EXIT_SUCCESS);
	  break;
	case 'v':
	case 'V':
	  fprintf (stdout, "%s version %s\n", PACKAGE_NAME, VERSION);
	  exit (EXIT_SUCCESS);
	  break;
	default:
	  fputs ("Try `sudosh -h' for more information.\n", stderr);
	  exit (EXIT_FAILURE);
	  break;
	}
    }

  if (ttyname (0) != NULL)
    {
      if (stat (ttyname (0), &ttybuf) == 0)
	{
	  if ((getpwuid (ttybuf.st_uid)->pw_name) == NULL)
	    {
	      fprintf (stderr, "I have no idea who you are.\n");
	      exit (EXIT_FAILURE);
	    }
	  strncpy (user.from, getpwuid (ttybuf.st_uid)->pw_name, BUFSIZ - 1);
	}
      else
	{
	  fprintf (stderr, "Couldn't stat %s\n", ttyname (0));
	  exit (EXIT_FAILURE);
	}
    }
  else
    {
      fprintf (stderr, "%s: couldn't get your controlling terminal.\n",
	       progname);
      exit (EXIT_FAILURE);
    }
  user.pw = getpwuid ((uid_t) getuid ());

  snprintf (user.home.str, BUFSIZ - 1, "HOME=%s", user.pw->pw_dir);
  strncpy (user.to_home.str, user.pw->pw_dir, BUFSIZ - 1);
  snprintf (user.term.str, BUFSIZ - 1, "TERM=%s", user.term.ptr);


#ifdef HAVE_GETUSERSHELL
  if ((user.shell.ptr = getenv ("SHELL")) == NULL)
    user.shell.ptr = user.pw->pw_shell;

  /* check against /etc/shells to make sure it's a real shell */
  setusershell ();
  while ((user.vshell = (char *) getusershell ()) != (char *) 0)
    {
      if (strcmp (user.shell.ptr, user.vshell) == 0)
	valid = 1;
    }
  endusershell ();

  if (valid != 1)
    {
      if (user.shell.ptr == NULL)
	{
	  fprintf (stderr, "Could not determine a valid shell.\n");
	  if (sudosh_option.priority != -1)
	    mysyslog (sudosh_option.priority,
		      "Could not determine a valid shell");
	  exit (EXIT_FAILURE);
	}
      else
	{
	  fprintf (stderr, "%s is not in /etc/shells\n", user.shell.ptr);
	  mysyslog (sudosh_option.priority,
		    "%s,%s: %s is not in /etc/shells", user.from,
		    ttyname (0), user.shell.ptr);
	  exit (EXIT_FAILURE);
	}
    }

  if (stat ((const char *) user.shell.ptr, &s) == -1)
    {
      fprintf (stderr, "Shell %s doesn't exist.\n", user.shell.ptr);
      if (sudosh_option.priority != -1)
	mysyslog (sudosh_option.priority, "%s,%s: shell %s doesn't exist.",
		  user.from, ttyname (0), user.shell.ptr);
      exit (EXIT_FAILURE);
    }
#else
  user.shell.ptr = user.pw->pw_shell;
#endif /* HAVE_GETUSERSHELL */

  if (loginshell)
    user.shell.ptr = sudosh_option.defshell;

  snprintf (script.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cscript%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
  snprintf (timing.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%ctime%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
#ifdef RECORDINPUT
  snprintf (input.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cinput%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
#endif
  snprintf (start_msg, BUFSIZ - 1,
	    "starting session for %s as %s, tty %s, shell %s", user.from,
	    user.to, ttyname (0), user.shell.ptr);

  set_perms_and_open_file(&script);
  set_perms_and_open_file(&timing);
#ifdef RECORDINPUT
  set_perms_and_open_file(&input);
#endif

  if (sudosh_option.priority != -1)
    mysyslog (sudosh_option.priority, start_msg);
  rawmode (0);

  if (findms (&pspair) < 0)
    {
      perror ("open pty failed");
      bye (EXIT_FAILURE);
    }

  switch (fork ())
    {
    case 0:
      close (pspair.mfd);
      prepchild (&pspair);
    case -1:
      perror ("fork failed");
      bye (EXIT_FAILURE);
    default:
      close (pspair.sfd);
    }

  orig_euid = geteuid();

  if (seteuid (getuid ()) != 0)
    {
      perror ("setuid failed");
      bye (EXIT_FAILURE);
    }

  memset (&sawinch, 0, sizeof sawinch);
  sawinch.sa_handler = newwinsize;
  sawinch.sa_flags = SA_RESTART;
  sigaction (SIGWINCH, &sawinch, (struct sigaction *) 0);

  memset (&saterm, 0, sizeof saterm);
  saterm.sa_handler = bye;
  sigaction (SIGTERM, &sawinch, (struct sigaction *) 0);

  memset (&sachild, 0, sizeof sachild);
  sachild.sa_handler = bye;
  sigaction (SIGCHLD, &sachild, (struct sigaction *) 0);

  oldtime = time (NULL);

  while (n > 0)
    {
      fd_set readfds;

      FD_ZERO (&readfds);
      FD_SET (pspair.mfd, &readfds);
      FD_SET (0, &readfds);

      gettimeofday ((struct timeval *) &tv, NULL);
      if (select (pspair.mfd + 1, &readfds, (fd_set *) 0,
		  (fd_set *) 0, (struct timeval *) 0) < 0)
	{

	  if (errno == EINTR)
	    continue;

	  perror ("select");
	  bye (EXIT_FAILURE);
	}

      if (FD_ISSET (pspair.mfd, &readfds))
	{
	  if ((n = read (pspair.mfd, iobuf, sizeof (iobuf))) > 0)
	    {
	      DO_WRITE (1, iobuf, n);
	      script.bytes += DO_WRITE (script.fd, iobuf, n);
	    }
	  newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
	  snprintf (timing.str, BUFSIZ - 1, "%f %i\n", newtime - oldtime, n);
	  timing.bytes += DO_WRITE (timing.fd, &timing.str, strlen (timing.str));
	  oldtime = newtime;

	}

      if (FD_ISSET (0, &readfds))
	{
	  if ((n = read (0, iobuf, BUFSIZ)) > 0)
	    {
	      DO_WRITE (pspair.mfd, iobuf, n);
#ifdef RECORDINPUT
	      switch (*iobuf)
		{
		case '\r':
		  snprintf (input.str, BUFSIZ - 1, "\n");
		  break;
		case 0x003:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-C)");
		  break;
		case 0x004:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-D)\n");
		  break;
		case 0x1a:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-Z)\n");
		  break;
		case 0x1b:
		  snprintf (input.str, BUFSIZ - 1, "(ESC)");
		  break;
		default:
		  DO_WRITE (input.fd, iobuf, 1);
		  written = 1;
		  break;
		}

	      if (written == 0)
		{
		  DO_WRITE (input.fd, &input.str, strlen (input.str));
		}
#endif
	    }
	}
    }

  bye (EXIT_SUCCESS);
  return (0);
}