Example #1
0
static void start_one_job(const char *user, CronLine *line)
{
	const char *shell;
	struct passwd *pas;
	pid_t pid;

	pas = getpwnam(user);
	if (!pas) {
		bb_error_msg("can't get uid for %s", user);
		goto err;
	}

	/* Prepare things before vfork */
	shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL;
	set_env_vars(pas, shell);

	/* Fork as the user in question and run program */
	pid = vfork();
	if (pid == 0) {
		/* CHILD */
		/* initgroups, setgid, setuid, and chdir to home or CRON_DIR */
		change_user(pas);
		log5("child running %s", shell);
		/* crond 3.0pl1-100 puts tasks in separate process groups */
		bb_setpgrp();
		execl(shell, shell, "-c", line->cl_cmd, (char *) NULL);
		bb_error_msg_and_die("can't execute '%s' for user %s", shell, user);
	}
	if (pid < 0) {
		bb_perror_msg("vfork");
 err:
		pid = 0;
	}
	line->cl_pid = pid;
}
void test_signal_task_group() {
  printf("\nTesting group signal_task\n");
  fflush(stdout);
  fflush(stderr);
  pid_t child = fork();
  if (child == -1) {
    printf("FAIL: fork failed\n");
    exit(1);
  } else if (child == 0) {
    setpgrp();
    if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
      exit(1);
    }
    sleep(3600);
    exit(0);
  }
  printf("Child task launched as %d\n", child);
  if (signal_user_task(username, child, SIGKILL) != 0) {
    exit(1);
  }
  int status = 0;
  if (waitpid(child, &status, 0) == -1) {
    printf("FAIL: waitpid failed - %s\n", strerror(errno));
    exit(1);
  }
  if (!WIFSIGNALED(status)) {
    printf("FAIL: child wasn't signalled - %d\n", status);
    exit(1);
  }
  if (WTERMSIG(status) != SIGKILL) {
    printf("FAIL: child was killed with %d instead of %d\n", 
	   WTERMSIG(status), SIGKILL);
    exit(1);
  }
}
void test_signal_container() {
  printf("\nTesting signal_container\n");
  fflush(stdout);
  fflush(stderr);
  pid_t child = fork();
  if (child == -1) {
    printf("FAIL: fork failed\n");
    exit(1);
  } else if (child == 0) {
    if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
      exit(1);
    }
    sleep(3600);
    exit(0);
  } else {
    printf("Child container launched as %" PRId64 "\n", (int64_t)child);
    if (signal_container_as_user(yarn_username, child, SIGQUIT) != 0) {
      exit(1);
    }
    int status = 0;
    if (waitpid(child, &status, 0) == -1) {
      printf("FAIL: waitpid failed - %s\n", strerror(errno));
      exit(1);
    }
    if (!WIFSIGNALED(status)) {
      printf("FAIL: child wasn't signalled - %d\n", status);
      exit(1);
    }
    if (WTERMSIG(status) != SIGQUIT) {
      printf("FAIL: child was killed with %d instead of %d\n", 
	     WTERMSIG(status), SIGQUIT);
      exit(1);
    }
  }
}
Example #4
0
/*
 * Function used to launch a task as the provided user. It does the following :
 * 1) Creates attempt work dir and log dir to be accessible by the child
 * 2) Copies the script file from the TT to the work directory
 * 3) Sets up the environment
 * 4) Does an execlp on the same in order to replace the current image with
 *    task image.
 */
int run_task_as_user(const char *user, const char * good_local_dirs,
                     const char *job_id, const char *task_id,
                     const char *work_dir, const char *script_name) {
  int exit_code = -1;
  char *task_script_path = NULL;
  if (create_attempt_directories(user, good_local_dirs, job_id, task_id) != 0) {
    goto cleanup;
  }
  int task_file_source = open_file_as_task_tracker(script_name);
  if (task_file_source == -1) {
    goto cleanup;
  }
  task_script_path = get_task_launcher_file(work_dir);
  if (task_script_path == NULL) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }
  if (copy_file(task_file_source, script_name,task_script_path,S_IRWXU) != 0) {
    goto cleanup;
  }

  //change the user
  // dlai blocked 12/29/2012 fcloseall();
  // dlai added ditto
  fflush(stdin);
  fflush(stdout);
  fflush(stderr);
  fclose(stdin);
  fclose(stdout);
  fclose(stderr);

  umask(0027);
  if (chdir(work_dir) != 0) {
    fprintf(LOGFILE, "Can't change directory to %s -%s\n", work_dir,
	    strerror(errno));
    goto cleanup;
  }
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    exit_code = SETUID_OPER_FAILED;
    goto cleanup;
  }

  // dlai blocked `1/19/10`1 if (execlp(task_script_path, task_script_path, NULL) != 0) {
  if (execlp(task_script_path, task_script_path, (char*) 0) != 0) {
    fprintf(LOGFILE, "Couldn't execute the task jvm file %s - %s", 
            task_script_path, strerror(errno));
    exit_code = UNABLE_TO_EXECUTE_TASK_SCRIPT;
    goto cleanup;
  }
  exit_code = 0;

 cleanup:
  free(task_script_path);
  return exit_code;
}
int kill_user_task(const char *user, const char *jobid, const char *taskid,
    const char *tt_root) {
  int pid = 0;
  int i = 0;
  char *pid_path = NULL;
  FILE *file_handle = NULL;
#ifdef DEBUG
  fprintf(LOGFILE,"kill_user_task : Job id : %s \n", jobid);
  fprintf(LOGFILE,"kill_user_task : task id : %s \n", taskid);
  fprintf(LOGFILE,"kill_user_task : tt_root : %s \n", tt_root);
  fflush(LOGFILE);
#endif
  if (check_tt_root(tt_root) < 0) {
    fprintf(LOGFILE, "invalid tt root specified");
    cleanup();
    return INVALID_TT_ROOT;
  }
  get_pid_path(jobid, taskid, tt_root, &pid_path);
  if (pid_path == NULL) {
    cleanup();
    return INVALID_PID_PATH;
  }
#ifdef DEBUG
  fprintf(LOGFILE,"kill_user_task : task-pid path :%s \n",pid_path);
  fflush(LOGFILE);
#endif
  file_handle = fopen(pid_path, "r");
  if (file_handle == NULL) {
    fprintf(LOGFILE, "unable to open task-pid file :%s \n", pid_path);
    free(pid_path);
    cleanup();
    return UNABLE_TO_OPEN_PID_FILE_READ_MODE;
  }
  fscanf(file_handle, "%d", &pid);
  fclose(file_handle);
  free(pid_path);
  if (pid == 0) {
    fprintf(LOGFILE, "Unable to read task-pid from path: %s \n", pid_path);
    cleanup();
    return UNABLE_TO_READ_PID;
  }
  if (change_user(user) != 0) {
    cleanup();
    return SETUID_OPER_FAILED;
  }
  if (kill(pid, SIGTERM) < 0) {
    fprintf(LOGFILE, "%s\n", strerror(errno));
    cleanup();
    return UNABLE_TO_KILL_TASK;
  }
  cleanup();
  return 0;
}
Example #6
0
File: test.c Project: zgbkny/ctoolx
/*
 * General server example: accept a client connection and do something.
 * This program just outputs a short HTML page, but can be easily adapted
 * to do other things.
 *
 * This server creates a constant number of processes ("virtual processors"
 * or VPs) and replaces them when they die. Each virtual processor manages
 * its own independent set of state threads (STs), the number of which varies
 * with load against the server. Each state thread listens to exactly one
 * listening socket. The initial process becomes the watchdog, waiting for
 * children (VPs) to die or for a signal requesting termination or restart.
 * Upon receiving a restart signal (SIGHUP), all VPs close and then reopen
 * log files and reload configuration. All currently active connections remain
 * active. It is assumed that new configuration affects only request
 * processing and not the general server parameters such as number of VPs,
 * thread limits, bind addresses, etc. Those are specified as command line
 * arguments, so the server has to be stopped and then started again in order
 * to change them.
 *
 * Each state thread loops processing connections from a single listening
 * socket. Only one ST runs on a VP at a time, and VPs do not share memory,
 * so no mutual exclusion locking is necessary on any data, and the entire
 * server is free to use all the static variables and non-reentrant library
 * functions it wants, greatly simplifying programming and debugging and
 * increasing performance (for example, it is safe to ++ and -- all global
 * counters or call inet_ntoa(3) without any mutexes). The current thread on
 * each VP maintains equilibrium on that VP, starting a new thread or
 * terminating itself if the number of spare threads exceeds the lower or
 * upper limit.
 *
 * All I/O operations on sockets must use the State Thread library's I/O
 * functions because only those functions prevent blocking of the entire VP
 * process and perform state thread scheduling.
 */
int main(int argc, char *argv[])
{
  /* Parse command-line options */
  parse_arguments(argc, argv);

  /* Allocate array of server pids */
  if ((vp_pids = calloc(vp_count, sizeof(pid_t))) == NULL)
    err_sys_quit(errfd, "ERROR: calloc failed");

  /* Start the daemon */
  if (!interactive_mode)
    start_daemon();

  /* Initialize the ST library */
  if (st_init() < 0)
    err_sys_quit(errfd, "ERROR: initialization failed: st_init");

  /* Set thread throttling parameters */
  set_thread_throttling();

  /* Create listening sockets */
  create_listeners();

  /* Change the user */
  if (username)
    change_user();

  /* Open log files */
  open_log_files();

  /* Start server processes (VPs) */
  start_processes();

  /* Turn time caching on */
  st_timecache_set(1);

  /* Install signal handlers */
  install_sighandlers();

  /* Load configuration from config files */
  load_configs();

  /* Start all threads */
  start_threads();

  /* Become a signal processing thread */
  process_signals(NULL);

  /* NOTREACHED */
  return 1;
}
Example #7
0
/**
 * run command as user
 */
int run_command_as_user(const char *user, char* const* args) {
  if (user == NULL) {
    fprintf(LOGFILE, "The user passed is null.\n");
    return INVALID_ARGUMENT_NUMBER;
  }
  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    return -1;
  }
  execvp(args[0], args);
  fprintf(LOGFILE, "Failure to exec command - %s\n",
	  strerror(errno));
  return -1;
} 
Example #8
0
int main(int argc, char **argv){

    // set up the logging stream
    if (!LOGFILE){
        LOGFILE=stdout;
    }
    if (!ERRORFILE){
        ERRORFILE=stderr;
    }

    if (argc < 3) {
        fprintf(ERRORFILE, "Requires at least 3 variables: ./execute-as-user uid command [args]");
        return INVALID_INPUT;
    }

    char *uid = argv[1];

    // gather information about user
    struct passwd *user_info = getpwnam(uid);
    if (user_info == NULL){
        fprintf(LOGFILE, "user does not exist: %s", uid);
        return USER_NOT_FOUND;
    }

    // try to change user
    fprintf(LOGFILE, "Changing user: user: %s, uid: %d, gid: %d\n", uid, user_info->pw_uid, user_info->pw_gid);
    int retval = change_user(user_info->pw_uid, user_info->pw_gid);
    if (retval != 0){
        fprintf(LOGFILE, "Error changing user to %s\n", uid);
        return SETUID_OPER_FAILED;
    }

    // execute the command
    char **user_argv = &argv[2];
    fprintf(LOGFILE, "user command starting from: %s\n", user_argv[0]);
    fflush(LOGFILE);
    retval = execvp(*user_argv, user_argv);
    fprintf(LOGFILE, "system call return value: %d\n", retval);

    // sometimes system(cmd) returns 256, which is interpreted to 0, making a failed job a successful job
    // hence this goofy piece of if statement.
    if (retval != 0){
        return 1;
    }
    else{
        return 0;
    }

}
static int c_init(void)
{
	int r;

	/* TODO: configurable */
	change_user("buxton");

	r = direct_init(MODULE_DIR, confpath ? confpath : CONFPATH);
	if (r == -1) {
		bxt_err("Init: %s", strerror(errno));
		return -1;
	}

	return 0;
}
void engine_init (engine_t *E, const char *const pwd_filename, int index_mode) {
  E->sfd = 0;
  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigusr1_handler;
  sigemptyset (&sa.sa_mask);
  sigaction (SIGUSR1, &sa, NULL);
  sa.sa_handler = sigrtmax_handler;
  sigaction (SIGRTMAX, &sa, NULL);

  if (!index_mode && port < PRIVILEGED_TCP_PORTS) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
    if (E->sfd < 0) {
      kprintf ("cannot open server socket at port %d: %m\n", port);
      exit (1);
    }
  }

  const int gap = 16;
  if (getuid ()) {
    struct rlimit rlim;
    if (getrlimit (RLIMIT_NOFILE, &rlim) < 0) {
      kprintf ("%s: getrlimit (RLIMIT_NOFILE) fail. %m\n", __func__);
      exit (1);
    }
    if (maxconn > rlim.rlim_cur - gap) {
      maxconn = rlim.rlim_cur - gap;
    }
  } else {
    if (raise_file_rlimit (maxconn + gap) < 0) {
      kprintf ("fatal: cannot raise open file limit to %d\n", maxconn + gap);
      exit (1);
    }
  }

  aes_load_pwd_file (pwd_filename);
  
  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  init_dyn_data ();
  if (udp_enabled) {
    init_server_PID (get_my_ipv4 (), port);
  }
}
Example #11
0
int fork_as_user(const char * working_dir, const char * script_file) {
  char *script_file_dest = NULL;
  script_file_dest = get_container_launcher_file(working_dir);
  if (script_file_dest == NULL) {
    return OUT_OF_MEMORY;
  }

  // open launch script
  int script_file_source = open_file_as_wl(script_file);
  if (script_file_source == -1) {
    return -1;
  }

  setsid();

  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    return SETUID_OPER_FAILED;
  }

  if (copy_file(script_file_source, script_file, script_file_dest, S_IRWXU) != 0) {
    return -1;
  }

  fcloseall();
  umask(0027);
  if (chdir(working_dir) != 0) {
    fprintf(LOGFILE, "Can't change directory to %s -%s\n", working_dir,
	    strerror(errno));
    return -1;
  }

  int pid = fork();
  if (pid == 0 && execlp(script_file_dest, script_file_dest, NULL) != 0) {
    fprintf(LOGFILE, "Couldn't execute the container launch file %s - %s",
            script_file_dest, strerror(errno));
    return UNABLE_TO_EXECUTE_CONTAINER_SCRIPT;
  } else {
    fprintf(LOGFILE, "Launched the process from the container launch file %s - with pid %d",
            script_file_dest, pid);
    return 0;
  }

  //Unreachable
  return -1;
}
Example #12
0
int main (int argc, char *argv[]) {
  int i;
  while ((i = getopt (argc, argv, "1H:mtuv")) != -1) {
    switch (i) {
      case 'H':
        http_port = atoi (optarg);
      break;
      case 'm':
        memory_repairing = 1;
      break;
      case 't':
        test_mode = 1;
      break;
      case 'u':
        username = optarg;
      break;
      case 'v':
        verbosity++;
        break;
      case '1':
        exit_on_file_body_error = 0;
        break;
    }
  }
  if (argc < optind + 2) {
    usage ();
    return 1;
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (memory_repairing) {
    if (storage_memory_repair (argv[optind], argv[optind+1]) < 0) {
      unlink (argv[optind+1]);
      return 1;
    }
    return 0;
  }

  storage_binlog_append (argv[optind], argv[optind+1]);
  return 0;
}
Example #13
0
int main (int argc, char *argv[]) {
  int i;

  set_debug_handlers ();
  progname = argv[0];

  if (argc == 1) {
    usage();
    return 2;
  }

  while ((i = getopt (argc, argv, "hu:")) != -1) {
    switch (i) {
    case 'h':
      usage ();
      return 2;
    case 'u':
      username = optarg;
      break;
    }
  }
  if (argc != optind + 2) {
    usage();
    return 2;
  }

  if (change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  init_files (3);

  open_file (0, argv[optind], 0);
  open_file (1, argv[optind + 1], 0);
  fd[2] = 1;

  run();

  flush_w_buff();
  fsync (fd[2]);
//  assert (fsync (fd[2]) >= 0);  // fails when stdout is a pipe

  return 0;
}
Example #14
0
int signal_container_as_user(const char *user, int pid, int sig) {
  if(pid <= 0) {
    return INVALID_CONTAINER_PID;
  }

  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    return SETUID_OPER_FAILED;
  }

  //Don't continue if the process-group is not alive anymore.
  int has_group = 1;
  if (kill(-pid,0) < 0) {
    if (kill(pid, 0) < 0) {
      if (errno == ESRCH) {
        return INVALID_CONTAINER_PID;
      }
      fprintf(LOGFILE, "Error signalling container %d with %d - %s\n",
	      pid, sig, strerror(errno));
      return -1;
    } else {
      has_group = 0;
    }
  }

  if (kill((has_group ? -1 : 1) * pid, sig) < 0) {
    if(errno != ESRCH) {
      fprintf(LOGFILE, 
              "Error signalling process group %d with signal %d - %s\n", 
              -pid, sig, strerror(errno));
      fprintf(stderr, 
              "Error signalling process group %d with signal %d - %s\n", 
              -pid, sig, strerror(errno));
      fflush(LOGFILE);
      return UNABLE_TO_SIGNAL_CONTAINER;
    } else {
      return INVALID_CONTAINER_PID;
    }
  }
  fprintf(LOGFILE, "Killing process %s%d with %d\n",
	  (has_group ? "group " :""), pid, sig);
  return 0;
}
void test_signal_container_group() {
  printf("\nTesting group signal_container\n");
  fflush(stdout);
  fflush(stderr);
  pid_t child = fork();
  if (child == -1) {
    printf("FAIL: fork failed\n");
    exit(1);
  } else if (child == 0) {
    setpgid(0,0);
    if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
      exit(1);
    }
    sleep(3600);
    exit(0);
  }
  printf("Child container launched as %" PRId64 "\n", (int64_t)child);
  // there's a race condition for child calling change_user and us 
  // calling signal_container_as_user, hence sleeping
  sleep(3);
  if (signal_container_as_user(yarn_username, child, SIGKILL) != 0) {
    exit(1);
  }
  int status = 0;
  if (waitpid(child, &status, 0) == -1) {
    printf("FAIL: waitpid failed - %s\n", strerror(errno));
    exit(1);
  }
  if (!WIFSIGNALED(status)) {
    printf("FAIL: child wasn't signalled - %d\n", status);
    exit(1);
  }
  if (WTERMSIG(status) != SIGKILL) {
    printf("FAIL: child was killed with %d instead of %d\n", 
	   WTERMSIG(status), SIGKILL);
    exit(1);
  }
}
Example #16
0
static void edit_file(const struct passwd *pas, const char *file)
{
	const char *ptr;
	int pid = vfork();

	if (pid < 0) /* failure */
		bb_perror_msg_and_die("vfork");
	if (pid) { /* parent */
		wait4pid(pid);
		return;
	}

	/* CHILD - change user and run editor */
	change_user(pas);
	ptr = getenv("VISUAL");
	if (!ptr) {
		ptr = getenv("EDITOR");
		if (!ptr)
			ptr = "vi";
	}

	BB_EXECLP(ptr, ptr, file, NULL);
	bb_perror_msg_and_die("exec %s", ptr);
}
Example #17
0
int launch_container_as_user(const char *user, const char *app_id, 
                   const char *container_id, const char *work_dir,
                   const char *script_name, const char *cred_file,
                   const char* pid_file, char* const* local_dirs,
                   char* const* log_dirs, const char *resources_key,
                   char* const* resources_values) {
  int exit_code = -1;
  char *script_file_dest = NULL;
  char *cred_file_dest = NULL;
  char *exit_code_file = NULL;

  script_file_dest = get_container_launcher_file(work_dir);
  if (script_file_dest == NULL) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }
  cred_file_dest = get_container_credentials_file(work_dir);
  if (NULL == cred_file_dest) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }
  exit_code_file = get_exit_code_file(pid_file);
  if (NULL == exit_code_file) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }

  // open launch script
  int container_file_source = open_file_as_nm(script_name);
  if (container_file_source == -1) {
    goto cleanup;
  }

  // open credentials
  int cred_file_source = open_file_as_nm(cred_file);
  if (cred_file_source == -1) {
    goto cleanup;
  }

  pid_t child_pid = fork();
  if (child_pid != 0) {
    // parent
    exit_code = wait_and_write_exit_code(child_pid, exit_code_file);
    goto cleanup;
  }

  // setsid 
  pid_t pid = setsid();
  if (pid == -1) {
    exit_code = SETSID_OPER_FAILED;
    goto cleanup;
  }

  // write pid to pidfile
  if (pid_file == NULL
      || write_pid_to_file_as_nm(pid_file, pid) != 0) {
    exit_code = WRITE_PIDFILE_FAILED;
    goto cleanup;
  }

  // cgroups-based resource enforcement
  if (resources_key != NULL && ! strcmp(resources_key, "cgroups")) {

    // write pid to cgroups
    char* const* cgroup_ptr;
    for (cgroup_ptr = resources_values; cgroup_ptr != NULL && 
         *cgroup_ptr != NULL; ++cgroup_ptr) {
      if (strcmp(*cgroup_ptr, "none") != 0 &&
            write_pid_to_cgroup_as_root(*cgroup_ptr, pid) != 0) {
        exit_code = WRITE_CGROUP_FAILED;
        goto cleanup;
      }
    }
  }

  // create the user directory on all disks
  int result = initialize_user(user, local_dirs);
  if (result != 0) {
    return result;
  }

  // initializing log dirs
  int log_create_result = create_log_dirs(app_id, log_dirs);
  if (log_create_result != 0) {
    return log_create_result;
  }

  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    exit_code = SETUID_OPER_FAILED;
    goto cleanup;
  }

  // Create container specific directories as user. If there are no resources
  // to localize for this container, app-directories and log-directories are
  // also created automatically as part of this call.
  if (create_container_directories(user, app_id, container_id, local_dirs,
                                   log_dirs, work_dir) != 0) {
    fprintf(LOGFILE, "Could not create container dirs");
    goto cleanup;
  }


  // 700
  if (copy_file(container_file_source, script_name, script_file_dest,S_IRWXU) != 0) {
    goto cleanup;
  }

  // 600
  if (copy_file(cred_file_source, cred_file, cred_file_dest,
        S_IRUSR | S_IWUSR) != 0) {
    goto cleanup;
  }

#if HAVE_FCLOSEALL
  fcloseall();
#else
  // only those fds are opened assuming no bug
  fclose(LOGFILE);
  fclose(ERRORFILE);
  fclose(stdin);
  fclose(stdout);
  fclose(stderr);
#endif
  umask(0027);
  if (chdir(work_dir) != 0) {
    fprintf(LOGFILE, "Can't change directory to %s -%s\n", work_dir,
	    strerror(errno));
    goto cleanup;
  }
  if (execlp(script_file_dest, script_file_dest, NULL) != 0) {
    fprintf(LOGFILE, "Couldn't execute the container launch file %s - %s", 
            script_file_dest, strerror(errno));
    exit_code = UNABLE_TO_EXECUTE_CONTAINER_SCRIPT;
    goto cleanup;
  }
  exit_code = 0;

 cleanup:
  free(exit_code_file);
  free(script_file_dest);
  free(cred_file_dest);
  return exit_code;
}
Example #18
0
/**
 * Function to prepare the job directories for the task JVM.
 */
int initialize_job(const char *user, const char *jobid, 
		   const char* credentials, const char* job_xml,
                   char* const* args) {
  if (jobid == NULL || user == NULL) {
    fprintf(LOGFILE, "Either jobid is null or the user passed is null.\n");
    return INVALID_ARGUMENT_NUMBER;
  }

  // create the user directory
  int result = initialize_user(user);
  if (result != 0) {
    return result;
  }

  // create the log directory for the job
  char *job_log_dir = get_job_log_directory(jobid);
  if (job_log_dir == NULL) {
    return -1;
  }
  result = create_directory_for_user(job_log_dir);
  free(job_log_dir);
  if (result != 0) {
    return -1;
  }

  // open up the credentials file
  int cred_file = open_file_as_task_tracker(credentials);
  if (cred_file == -1) {
    return -1;
  }

  int job_file = open_file_as_task_tracker(job_xml);
  if (job_file == -1) {
    return -1;
  }

  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    return -1;
  }

  // 750
  mode_t permissions = S_IRWXU | S_IRGRP | S_IXGRP;
  char **tt_roots = get_values(TT_SYS_DIR_KEY);

  if (tt_roots == NULL) {
    return INVALID_CONFIG_FILE;
  }

  char **tt_root;
  char *primary_job_dir = NULL;
  for(tt_root=tt_roots; *tt_root != NULL; ++tt_root) {
    char *job_dir = get_job_directory(*tt_root, user, jobid);
    if (job_dir == NULL) {
      // try the next one
    } else if (mkdirs(job_dir, permissions) != 0) {
      free(job_dir);
    } else if (primary_job_dir == NULL) {
      primary_job_dir = job_dir;
    } else {
      free(job_dir);
    }
  }
  free_values(tt_roots);
  if (primary_job_dir == NULL) {
    fprintf(LOGFILE, "Did not create any job directories\n");
    return -1;
  }

  char *cred_file_name = concatenate("%s/%s", "cred file", 2,
				     primary_job_dir, CREDENTIALS_FILENAME);
  if (cred_file_name == NULL) {
    return -1;
  }
  if (copy_file(cred_file, credentials, cred_file_name, S_IRUSR|S_IWUSR) != 0){
    return -1;
  }
  char *job_file_name = concatenate("%s/%s", "job file", 2,
				     primary_job_dir, JOB_FILENAME);
  if (job_file_name == NULL) {
    return -1;
  }
  if (copy_file(job_file, job_xml, job_file_name,
        S_IRUSR|S_IWUSR|S_IRGRP) != 0) {
    return -1;
  }
  fclose(stdin);
  fflush(LOGFILE);
  if (LOGFILE != stdout) {
    fclose(stdout);
  }
  fclose(stderr);
  if (chdir(primary_job_dir)) {
    fprintf(LOGFILE, "Failure to chdir to job dir - %s\n",
      strerror(errno));
    return -1;
  }

  execvp(args[0], args);
  fprintf(LOGFILE, "Failure to exec job initialization process - %s\n",
	  strerror(errno));
  return -1;
}
Example #19
0
int main(int argc, char *argv[]) {
    pa_core *c = NULL;
    pa_strbuf *buf = NULL;
    pa_daemon_conf *conf = NULL;
    pa_mainloop *mainloop = NULL;
    char *s;
    char *configured_address;
    int r = 0, retval = 1, d = 0;
    pa_bool_t valid_pid_file = FALSE;
    pa_bool_t ltdl_init = FALSE;
    int passed_fd = -1;
    const char *e;
#ifdef HAVE_FORK
    int daemon_pipe[2] = { -1, -1 };
    int daemon_pipe2[2] = { -1, -1 };
#endif
#ifdef OS_IS_WIN32
    pa_time_event *win32_timer;
    struct timeval win32_tv;
#endif
    int autospawn_fd = -1;
    pa_bool_t autospawn_locked = FALSE;
#ifdef HAVE_DBUS
    pa_dbusobj_server_lookup *server_lookup = NULL; /* /org/pulseaudio/server_lookup */
    pa_dbus_connection *lookup_service_bus = NULL; /* Always the user bus. */
    pa_dbus_connection *server_bus = NULL; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
    pa_bool_t start_server;
#endif

    pa_log_set_ident("pulseaudio");
    pa_log_set_level(PA_LOG_NOTICE);
    pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);

#if defined(__linux__) && defined(__OPTIMIZE__)
    /*
       Disable lazy relocations to make usage of external libraries
       more deterministic for our RT threads. We abuse __OPTIMIZE__ as
       a check whether we are a debug build or not. This all is
       admittedly a bit snake-oilish.
    */

    if (!getenv("LD_BIND_NOW")) {
        char *rp;
        char *canonical_rp;

        /* We have to execute ourselves, because the libc caches the
         * value of $LD_BIND_NOW on initialization. */

        pa_set_env("LD_BIND_NOW", "1");

        if ((canonical_rp = pa_realpath(PA_BINARY))) {

            if ((rp = pa_readlink("/proc/self/exe"))) {

                if (pa_streq(rp, canonical_rp))
                    pa_assert_se(execv(rp, argv) == 0);
                else
                    pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp);

                pa_xfree(rp);

            } else
                pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");

            pa_xfree(canonical_rp);

        } else
            pa_log_warn("Couldn't canonicalize binary path, cannot self execute.");
    }
#endif

    if ((e = getenv("PULSE_PASSED_FD"))) {
        passed_fd = atoi(e);

        if (passed_fd <= 2)
            passed_fd = -1;
    }

    /* We might be autospawned, in which case have no idea in which
     * context we have been started. Let's cleanup our execution
     * context as good as possible */

    pa_reset_personality();
    pa_drop_root();
    pa_close_all(passed_fd, -1);
    pa_reset_sigs(-1);
    pa_unblock_sigs(-1);
    pa_reset_priority();

    setlocale(LC_ALL, "");
    pa_init_i18n();

    conf = pa_daemon_conf_new();

    if (pa_daemon_conf_load(conf, NULL) < 0)
        goto finish;

    if (pa_daemon_conf_env(conf) < 0)
        goto finish;

    if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
        pa_log(_("Failed to parse command line."));
        goto finish;
    }

    pa_log_set_level(conf->log_level);
    pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
    if (conf->log_meta)
        pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
    if (conf->log_time)
        pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
    pa_log_set_show_backtrace(conf->log_backtrace);

#ifdef HAVE_DBUS
    /* conf->system_instance and conf->local_server_type control almost the
     * same thing; make them agree about what is requested. */
    switch (conf->local_server_type) {
        case PA_SERVER_TYPE_UNSET:
            conf->local_server_type = conf->system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER;
            break;
        case PA_SERVER_TYPE_USER:
        case PA_SERVER_TYPE_NONE:
            conf->system_instance = FALSE;
            break;
        case PA_SERVER_TYPE_SYSTEM:
            conf->system_instance = TRUE;
            break;
        default:
            pa_assert_not_reached();
    }

    start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);

    if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
        pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
        conf->system_instance = FALSE;
    }
#endif

    LTDL_SET_PRELOADED_SYMBOLS();
    pa_ltdl_init();
    ltdl_init = TRUE;

    if (conf->dl_search_path)
        lt_dlsetsearchpath(conf->dl_search_path);

#ifdef OS_IS_WIN32
    {
        WSADATA data;
        WSAStartup(MAKEWORD(2, 0), &data);
    }
#endif

    pa_random_seed();

    switch (conf->cmd) {
        case PA_CMD_DUMP_MODULES:
            pa_dump_modules(conf, argc-d, argv+d);
            retval = 0;
            goto finish;

        case PA_CMD_DUMP_CONF: {

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            s = pa_daemon_conf_dump(conf);
            fputs(s, stdout);
            pa_xfree(s);
            retval = 0;
            goto finish;
        }

        case PA_CMD_DUMP_RESAMPLE_METHODS: {
            int i;

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            for (i = 0; i < PA_RESAMPLER_MAX; i++)
                if (pa_resample_method_supported(i))
                    printf("%s\n", pa_resample_method_to_string(i));

            retval = 0;
            goto finish;
        }

        case PA_CMD_HELP :
            pa_cmdline_help(argv[0]);
            retval = 0;
            goto finish;

        case PA_CMD_VERSION :

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
            retval = 0;
            goto finish;

        case PA_CMD_CHECK: {
            pid_t pid;

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
                pa_log_info(_("Daemon not running"));
            else {
                pa_log_info(_("Daemon running as PID %u"), pid);
                retval = 0;
            }

            goto finish;

        }
        case PA_CMD_KILL:

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
                pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
            else
                retval = 0;

            goto finish;

        case PA_CMD_CLEANUP_SHM:

            if (d < argc) {
                pa_log("Too many arguments.\n");
                goto finish;
            }

            if (pa_shm_cleanup() >= 0)
                retval = 0;

            goto finish;

        default:
            pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
    }

    if (d < argc) {
        pa_log("Too many arguments.\n");
        goto finish;
    }

#ifdef HAVE_GETUID
    if (getuid() == 0 && !conf->system_instance)
        pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
#ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
    else if (getuid() != 0 && conf->system_instance) {
        pa_log(_("Root privileges required."));
        goto finish;
    }
#endif
#endif  /* HAVE_GETUID */

    if (conf->cmd == PA_CMD_START && conf->system_instance) {
        pa_log(_("--start not supported for system instances."));
        goto finish;
    }

    if (conf->cmd == PA_CMD_START && (configured_address = check_configured_address())) {
        /* There is an server address in our config, but where did it come from?
         * By default a standard X11 login will load module-x11-publish which will
         * inject PULSE_SERVER X11 property. If the PA daemon crashes, we will end
         * up hitting this code path. So we have to check to see if our configured_address
         * is the same as the value that would go into this property so that we can
         * recover (i.e. autospawn) from a crash.
         */
        char *ufn;
        pa_bool_t start_anyway = FALSE;

        if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
            char *id;

            if ((id = pa_machine_id())) {
                pa_strlist *server_list;
                char formatted_ufn[256];

                pa_snprintf(formatted_ufn, sizeof(formatted_ufn), "{%s}unix:%s", id, ufn);
                pa_xfree(id);

                if ((server_list = pa_strlist_parse(configured_address))) {
                    char *u = NULL;

                    /* We only need to check the first server */
                    server_list = pa_strlist_pop(server_list, &u);
                    pa_strlist_free(server_list);

                    start_anyway = (u && pa_streq(formatted_ufn, u));
                    pa_xfree(u);
                }
            }
            pa_xfree(ufn);
        }

        if (!start_anyway) {
            pa_log_notice(_("User-configured server at %s, refusing to start/autospawn."), configured_address);
            pa_xfree(configured_address);
            retval = 0;
            goto finish;
        }

        pa_log_notice(_("User-configured server at %s, which appears to be local. Probing deeper."), configured_address);
        pa_xfree(configured_address);
    }

    if (conf->system_instance && !conf->disallow_exit)
        pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));

    if (conf->system_instance && !conf->disallow_module_loading)
        pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));

    if (conf->system_instance && !conf->disable_shm) {
        pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
        conf->disable_shm = TRUE;
    }

    if (conf->system_instance && conf->exit_idle_time >= 0) {
        pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
        conf->exit_idle_time = -1;
    }

    if (conf->cmd == PA_CMD_START) {
        /* If we shall start PA only when it is not running yet, we
         * first take the autospawn lock to make things
         * synchronous. */

        if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
            pa_log("Failed to initialize autospawn lock");
            goto finish;
        }

        if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
            pa_log("Failed to acquire autospawn lock");
            goto finish;
        }

        autospawn_locked = TRUE;
    }

    if (conf->daemonize) {
#ifdef HAVE_FORK
        pid_t child;
#endif

        if (pa_stdio_acquire() < 0) {
            pa_log(_("Failed to acquire stdio."));
            goto finish;
        }

#ifdef HAVE_FORK
        if (pipe(daemon_pipe) < 0) {
            pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
            goto finish;
        }

        if ((child = fork()) < 0) {
            pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
            pa_close_pipe(daemon_pipe);
            goto finish;
        }

        if (child != 0) {
            ssize_t n;
            /* Father */

            pa_assert_se(pa_close(daemon_pipe[1]) == 0);
            daemon_pipe[1] = -1;

            if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {

                if (n < 0)
                    pa_log(_("read() failed: %s"), pa_cstrerror(errno));

                retval = 1;
            }

            if (retval)
                pa_log(_("Daemon startup failed."));
            else
                pa_log_info(_("Daemon startup successful."));

            goto finish;
        }

        if (autospawn_fd >= 0) {
            /* The lock file is unlocked from the parent, so we need
             * to close it in the child */

            pa_autospawn_lock_release();
            pa_autospawn_lock_done(TRUE);

            autospawn_locked = FALSE;
            autospawn_fd = -1;
        }

        pa_assert_se(pa_close(daemon_pipe[0]) == 0);
        daemon_pipe[0] = -1;
#endif

        if (conf->auto_log_target)
            pa_log_set_target(PA_LOG_SYSLOG);

#ifdef HAVE_SETSID
        if (setsid() < 0) {
            pa_log(_("setsid() failed: %s"), pa_cstrerror(errno));
            goto finish;
        }
#endif

#ifdef HAVE_FORK
        /* We now are a session and process group leader. Let's fork
         * again and let the father die, so that we'll become a
         * process that can never acquire a TTY again, in a session and
         * process group without leader */

        if (pipe(daemon_pipe2) < 0) {
            pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
            goto finish;
        }

        if ((child = fork()) < 0) {
            pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
            pa_close_pipe(daemon_pipe2);
            goto finish;
        }

        if (child != 0) {
            ssize_t n;
            /* Father */

            pa_assert_se(pa_close(daemon_pipe2[1]) == 0);
            daemon_pipe2[1] = -1;

            if ((n = pa_loop_read(daemon_pipe2[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {

                if (n < 0)
                    pa_log(_("read() failed: %s"), pa_cstrerror(errno));

                retval = 1;
            }

            /* We now have to take care of signalling the first fork with
             * the return value we've received from this fork... */
            pa_assert(daemon_pipe[1] >= 0);

            pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
            pa_close(daemon_pipe[1]);
            daemon_pipe[1] = -1;

            goto finish;
        }

        pa_assert_se(pa_close(daemon_pipe2[0]) == 0);
        daemon_pipe2[0] = -1;

        /* We no longer need the (first) daemon_pipe as it's handled in our child above */
        pa_close_pipe(daemon_pipe);
#endif

#ifdef SIGTTOU
        signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
        signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
        signal(SIGTSTP, SIG_IGN);
#endif

        pa_nullify_stdfds();
    }

    pa_set_env_and_record("PULSE_INTERNAL", "1");
    pa_assert_se(chdir("/") == 0);
    umask(0022);

#ifdef HAVE_SYS_RESOURCE_H
    set_all_rlimits(conf);
#endif
    pa_rtclock_hrtimer_enable();

    pa_raise_priority(conf->nice_level);

    if (conf->system_instance)
        if (change_user() < 0)
            goto finish;

    pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");

    pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
    pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
    pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);

    s = pa_uname_string();
    pa_log_debug(_("Running on host: %s"), s);
    pa_xfree(s);

    pa_log_debug(_("Found %u CPUs."), pa_ncpus());

    pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);

#ifdef HAVE_VALGRIND_MEMCHECK_H
    pa_log_debug(_("Compiled with Valgrind support: yes"));
#else
    pa_log_debug(_("Compiled with Valgrind support: no"));
#endif

    pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));

    pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));

#ifdef __OPTIMIZE__
    pa_log_debug(_("Optimized build: yes"));
#else
    pa_log_debug(_("Optimized build: no"));
#endif

#ifdef NDEBUG
    pa_log_debug(_("NDEBUG defined, all asserts disabled."));
#elif defined(FASTPATH)
    pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
#else
    pa_log_debug(_("All asserts enabled."));
#endif

    if (!(s = pa_machine_id())) {
        pa_log(_("Failed to get machine ID"));
        goto finish;
    }
    pa_log_info(_("Machine ID is %s."), s);
    pa_xfree(s);

    if ((s = pa_session_id())) {
        pa_log_info(_("Session ID is %s."), s);
        pa_xfree(s);
    }

    if (!(s = pa_get_runtime_dir()))
        goto finish;
    pa_log_info(_("Using runtime directory %s."), s);
    pa_xfree(s);

    if (!(s = pa_get_state_dir()))
        goto finish;
    pa_log_info(_("Using state directory %s."), s);
    pa_xfree(s);

    pa_log_info(_("Using modules directory %s."), conf->dl_search_path);

    pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));

    if (pa_in_system_mode())
        pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
                      "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
                      "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));

    if (conf->use_pid_file) {
        int z;

        if ((z = pa_pid_file_create("pulseaudio")) != 0) {

            if (conf->cmd == PA_CMD_START && z > 0) {
                /* If we are already running and with are run in
                 * --start mode, then let's return this as success. */

                retval = 0;
                goto finish;
            }

            pa_log(_("pa_pid_file_create() failed."));
            goto finish;
        }

        valid_pid_file = TRUE;
    }

    pa_disable_sigpipe();

    if (pa_rtclock_hrtimer())
        pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
    else
        pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));

    if (conf->lock_memory) {
#ifdef HAVE_SYS_MMAN_H
        if (mlockall(MCL_FUTURE) < 0)
            pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
        else
            pa_log_info("Successfully locked process into memory.");
#else
        pa_log_warn("Memory locking requested but not supported on platform.");
#endif
    }

    pa_memtrap_install();

    pa_assert_se(mainloop = pa_mainloop_new());

    if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
        pa_log(_("pa_core_new() failed."));
        goto finish;
    }

    c->default_sample_spec = conf->default_sample_spec;
    c->alternate_sample_rate = conf->alternate_sample_rate;
    c->default_channel_map = conf->default_channel_map;
    c->default_n_fragments = conf->default_n_fragments;
    c->default_fragment_size_msec = conf->default_fragment_size_msec;
    c->deferred_volume_safety_margin_usec = conf->deferred_volume_safety_margin_usec;
    c->deferred_volume_extra_delay_usec = conf->deferred_volume_extra_delay_usec;
    c->exit_idle_time = conf->exit_idle_time;
    c->scache_idle_time = conf->scache_idle_time;
    c->resample_method = conf->resample_method;
    c->realtime_priority = conf->realtime_priority;
    c->realtime_scheduling = !!conf->realtime_scheduling;
    c->disable_remixing = !!conf->disable_remixing;
    c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
    c->deferred_volume = !!conf->deferred_volume;
    c->running_as_daemon = !!conf->daemonize;
    c->disallow_exit = conf->disallow_exit;
    c->flat_volumes = conf->flat_volumes;
#ifdef HAVE_DBUS
    c->server_type = conf->local_server_type;
#endif

    c->cpu_info.cpu_type = PA_CPU_UNDEFINED;
    if (!getenv("PULSE_NO_SIMD")) {
        if (pa_cpu_init_x86(&(c->cpu_info.flags.x86)))
            c->cpu_info.cpu_type = PA_CPU_X86;
        if (pa_cpu_init_arm(&(c->cpu_info.flags.arm)))
            c->cpu_info.cpu_type = PA_CPU_ARM;
	pa_cpu_init_orc(c->cpu_info);
    }

    pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
    pa_signal_new(SIGINT, signal_callback, c);
    pa_signal_new(SIGTERM, signal_callback, c);
#ifdef SIGUSR1
    pa_signal_new(SIGUSR1, signal_callback, c);
#endif
#ifdef SIGUSR2
    pa_signal_new(SIGUSR2, signal_callback, c);
#endif
#ifdef SIGHUP
    pa_signal_new(SIGHUP, signal_callback, c);
#endif

#ifdef OS_IS_WIN32
    win32_timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
#endif

    if (!conf->no_cpu_limit)
        pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);

    buf = pa_strbuf_new();

#ifdef HAVE_DBUS
    pa_assert_se(dbus_threads_init_default());

    if (start_server) {
#endif
        if (conf->load_default_script_file) {
            FILE *f;

            if ((f = pa_daemon_conf_open_default_script_file(conf))) {
                r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
                fclose(f);
            }
        }

        if (r >= 0)
            r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);

        pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
        pa_xfree(s);

        if (r < 0 && conf->fail) {
            pa_log(_("Failed to initialize daemon."));
            goto finish;
        }

        if (!c->modules || pa_idxset_size(c->modules) == 0) {
            pa_log(_("Daemon startup without any loaded modules, refusing to work."));
            goto finish;
        }
#ifdef HAVE_DBUS
    } else {
        /* When we just provide the D-Bus server lookup service, we don't want
         * any modules to be loaded. We haven't loaded any so far, so one might
         * think there's no way to contact the server, but receiving certain
         * signals could still cause modules to load. */
        conf->disallow_module_loading = TRUE;
    }
#endif

    /* We completed the initial module loading, so let's disable it
     * from now on, if requested */
    c->disallow_module_loading = !!conf->disallow_module_loading;

#ifdef HAVE_DBUS
    if (!conf->system_instance) {
        if ((server_lookup = pa_dbusobj_server_lookup_new(c))) {
            if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.PulseAudio1")))
                goto finish;
        }
    }

    if (start_server)
        server_bus = register_dbus_name(c, conf->system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, "org.pulseaudio.Server");
#endif

#ifdef HAVE_FORK
    if (daemon_pipe2[1] >= 0) {
        int ok = 0;
        pa_loop_write(daemon_pipe2[1], &ok, sizeof(ok), NULL);
        pa_close(daemon_pipe2[1]);
        daemon_pipe2[1] = -1;
    }
#endif

    pa_log_info(_("Daemon startup complete."));

    retval = 0;
    if (pa_mainloop_run(mainloop, &retval) < 0)
        goto finish;

    pa_log_info(_("Daemon shutdown initiated."));

finish:
#ifdef HAVE_DBUS
    if (server_bus)
        pa_dbus_connection_unref(server_bus);
    if (lookup_service_bus)
        pa_dbus_connection_unref(lookup_service_bus);
    if (server_lookup)
        pa_dbusobj_server_lookup_free(server_lookup);
#endif

    if (autospawn_fd >= 0) {
        if (autospawn_locked)
            pa_autospawn_lock_release();

        pa_autospawn_lock_done(FALSE);
    }

#ifdef OS_IS_WIN32
    if (mainloop && win32_timer)
        pa_mainloop_get_api(mainloop)->time_free(win32_timer);
#endif

    if (c) {
        /* Ensure all the modules/samples are unloaded when the core is still ref'ed,
         * as unlink callback hooks in modules may need the core to be ref'ed */
        pa_module_unload_all(c);
        pa_scache_free_all(c);

        pa_core_unref(c);
        pa_log_info(_("Daemon terminated."));
    }

    if (!conf->no_cpu_limit)
        pa_cpu_limit_done();

    pa_signal_done();

#ifdef HAVE_FORK
    /* If we have daemon_pipe[1] still open, this means we've failed after
     * the first fork, but before the second. Therefore just write to it. */
    if (daemon_pipe[1] >= 0)
        pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
    else if (daemon_pipe2[1] >= 0)
        pa_loop_write(daemon_pipe2[1], &retval, sizeof(retval), NULL);

    pa_close_pipe(daemon_pipe2);
    pa_close_pipe(daemon_pipe);
#endif

    if (mainloop)
        pa_mainloop_free(mainloop);

    if (conf)
        pa_daemon_conf_free(conf);

    if (valid_pid_file)
        pa_pid_file_remove();

    /* This has no real purpose except making things valgrind-clean */
    pa_unset_env_recorded();

#ifdef OS_IS_WIN32
    WSACleanup();
#endif

    if (ltdl_init)
        pa_ltdl_done();

#ifdef HAVE_DBUS
    dbus_shutdown();
#endif

    return retval;
}
int main (int argc, char *argv[]) {
  int i;
  set_debug_handlers ();

  while ((i = getopt (argc, argv, "vrb:u:a:l:")) != -1) {
    switch (i) {
    case 'v':
      verbosity++;
      break;
    case 'r':
      read_only = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'b':
      backlog = atoi(optarg);
      if (backlog <= 0) backlog = BACKLOG;
      break;
    case 'u':
      username = optarg;
      break;
    case 'a':
      binlogname = optarg;
      break;
    case 'l':
      logname = optarg;
      break;
    }
  }
  if (argc != optind + 1 && argc != optind + 2) {
    usage();
    return 2;
  }

  if (change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    exit(1);
  }

  init_dyn_data ();

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Snapshot = open_recent_snapshot (engine_snapshot_replica);

  if (!Snapshot) {
    fprintf (stderr, "No snapshots found. Nothing to do\n");
    return 0;
  } else {
    int t[5];
    assert (read (Snapshot->fd, t, 20) == 20);
    if (t[0] != RPC_PROXY_INDEX_MAGIC) {
      fprintf (stderr, "Snapshot is not from rpc-proxy\n");
      return 1;
    }
    long long binlog_pos = *(long long *)(t + 1);
    if (verbosity > 0) {
      fprintf (stderr, "log_pos = %lld\n", binlog_pos);
    }
    for (i = 0; i < engine_replica->binlog_num - 1; i++) {
      struct kfs_file_info *FI = engine_replica->binlogs[i];
      int fd = preload_file_info (FI);
      assert (fd >= 0);
      if (FI->log_pos + FI->file_size <= binlog_pos) {
        if (read_only) {
          fprintf (stderr, "Would delete file %s\n", engine_replica->binlogs[i]->filename);
        } else {
          if (verbosity > 0) {
            fprintf (stderr, "Deleting file %s\n", engine_replica->binlogs[i]->filename);
          }
          int r = unlink (engine_replica->binlogs[i]->filename);
          if (r < 0) {
            fprintf (stderr, "Error deleting file %s: %m\n", engine_replica->binlogs[i]->filename);
          }
        }
      }
      if (fd >= 0) {
        close (fd);
      }
    }
    return 0;
  }
}
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "hvu:m:s:t:p")) != -1) {
    switch (i) {
    case 'p':
      fits = positive_counter_fits;
      break;
    case 'v':
      verbosity = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'u':
      username = optarg;
      break;
    case 'm':
      if (sscanf (optarg, "%d,%d", &copy_rem, &copy_mod) != 2 || copy_rem < 0 || copy_rem >= copy_mod) {
	usage();
	return 2;
      }
      break;
    case 's':
      jump_log_pos = atoll (optarg);
      break;
    case 't':
      log_limit_pos = atoll (optarg);
      break;
    }
  }

  if (copy_mod < 0) {
    usage ();
    return 2;
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  if (log_limit_pos >= 0) {
    if (jump_log_pos > log_limit_pos) {
      fprintf (stderr, "fatal: log start position %lld after stop position %lld\n", jump_log_pos, log_limit_pos);
      return 2;
    }
  }

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Binlog = open_binlog (engine_replica, jump_log_pos);
  if (!Binlog) {
    fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, 0LL);
    exit (1);
  }

  binlogname = Binlog->info->filename;

  if (verbosity) {
    fprintf (stderr, "replaying binlog file %s (size %lld)\n", binlogname, Binlog->info->file_size);
  }

  clear_log();

  init_log_data (jump_log_pos, 0, 0);

  if (jump_log_pos > 0) {
    init_stats_data (0);
  }

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
    targ_orig_size = lseek (targ_fd, 0, SEEK_END);
    targ_existed = (targ_orig_size > 0);
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  i = replay_log (0, 1);

  if (i < 0) {
    fprintf (stderr, "fatal: error reading binlog\n");
    exit (1);
  }

  if (log_limit_pos >= 0 && log_readto_pos != log_limit_pos) {
    fprintf (stderr, "fatal: binlog read up to position %lld instead of %lld\n", log_readto_pos, log_limit_pos);
    exit (1);
  }

  flush_out ();

  if (targ_fd != 1) {
    if (fdatasync (targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (verbosity > 0) {
    output_stats ();
  }

  return 0;
}
void server_init (engine_t *E, server_functions_t *F, conn_type_t *listen_connection_type, void *listen_connection_extra) {
  if (F != NULL) {
    if (F->sighup) {
      sf.sighup = F->sighup;
    }
    if (F->sigusr1) {
      sf.sigusr1 = F->sigusr1;
    }
    if (F->save_index) {
      sf.save_index = F->save_index;
    }
    if (F->cron) {
      sf.cron = F->cron;
    }
  }
  
  init_epoll ();
  init_netbuffers ();
  if (udp_enabled) {
    init_msg_buffers (0);
  }
  
  if (daemonize) {
    setsid ();
    reopen_logs ();
  }

  if (!E->sfd) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
  }

  if (E->sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (1);
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (E->sfd, listen_connection_type, listen_connection_extra);
  if (udp_enabled) {
    add_udp_socket (port, 0);
  }
  
  if (binlog_disabled && binlog_fd >= 0) {
    epoll_pre_event = read_new_events;
  }

  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigint_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGTERM); 
  sigaction (SIGINT, &sa, NULL);
  
  sa.sa_handler = sigterm_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGINT);
  sigaction (SIGTERM, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction (SIGPIPE, &sa, NULL);
  sigaction (SIGPOLL, &sa, NULL);
  
  if (daemonize) {
    sa.sa_handler = sighup_handler;
    sigemptyset (&sa.sa_mask);
    sigaction (SIGHUP, &sa, NULL);
  }
}
/**
 * Function to prepare the application directories for the container.
 */
int initialize_app(const char *user, const char *app_id,
                   const char* nmPrivate_credentials_file,
                   char* const* local_dirs, char* const* log_roots,
                   char* const* args) {
  if (app_id == NULL || user == NULL) {
    fprintf(LOGFILE, "Either app_id is null or the user passed is null.\n");
    return INVALID_ARGUMENT_NUMBER;
  }

  // create the user directory on all disks
  int result = initialize_user(user, local_dirs);
  if (result != 0) {
    return result;
  }

  ////////////// create the log directories for the app on all disks
  char* const* log_root;
  char *any_one_app_log_dir = NULL;
  for(log_root=log_roots; *log_root != NULL; ++log_root) {
    char *app_log_dir = get_app_log_directory(*log_root, app_id);
    if (app_log_dir == NULL) {
      // try the next one
    } else if (create_directory_for_user(app_log_dir) != 0) {
      free(app_log_dir);
      return -1;
    } else if (any_one_app_log_dir == NULL) {
      any_one_app_log_dir = app_log_dir;
    } else {
      free(app_log_dir);
    }
  }

  if (any_one_app_log_dir == NULL) {
    fprintf(LOGFILE, "Did not create any app-log directories\n");
    return -1;
  }
  free(any_one_app_log_dir);
  ////////////// End of creating the log directories for the app on all disks

  // open up the credentials file
  int cred_file = open_file_as_nm(nmPrivate_credentials_file);
  if (cred_file == -1) {
    return -1;
  }

  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    return -1;
  }

  // 750
  mode_t permissions = S_IRWXU | S_IRGRP | S_IXGRP;
  char* const* nm_root;
  char *primary_app_dir = NULL;
  for(nm_root=local_dirs; *nm_root != NULL; ++nm_root) {
    char *app_dir = get_app_directory(*nm_root, user, app_id);
    if (app_dir == NULL) {
      // try the next one
    } else if (mkdirs(app_dir, permissions) != 0) {
      free(app_dir);
    } else if (primary_app_dir == NULL) {
      primary_app_dir = app_dir;
    } else {
      free(app_dir);
    }
  }

  if (primary_app_dir == NULL) {
    fprintf(LOGFILE, "Did not create any app directories\n");
    return -1;
  }

  char *nmPrivate_credentials_file_copy = strdup(nmPrivate_credentials_file);
  // TODO: FIXME. The user's copy of creds should go to a path selected by
  // localDirAllocatoir
  char *cred_file_name = concatenate("%s/%s", "cred file", 2,
				   primary_app_dir, basename(nmPrivate_credentials_file_copy));
  if (cred_file_name == NULL) {
	free(nmPrivate_credentials_file_copy);
    return -1;
  }
  if (copy_file(cred_file, nmPrivate_credentials_file,
		  cred_file_name, S_IRUSR|S_IWUSR) != 0){
	free(nmPrivate_credentials_file_copy);
    return -1;
  }

  free(nmPrivate_credentials_file_copy);

  fclose(stdin);
  fflush(LOGFILE);
  if (LOGFILE != stdout) {
    fclose(stdout);
  }
  if (ERRORFILE != stderr) {
    fclose(stderr);
  }
  if (chdir(primary_app_dir) != 0) {
    fprintf(LOGFILE, "Failed to chdir to app dir - %s\n", strerror(errno));
    return -1;
  }
  execvp(args[0], args);
  fprintf(ERRORFILE, "Failure to exec app initialization process - %s\n",
	  strerror(errno));
  return -1;
}
Example #24
0
int main(int argc, char **argv) {
        int opt;
        extern char *optarg;
        extern int optind;
        int loop_status;

        signal(SIGHUP, &handle_signal);
        signal(SIGINT, &handle_signal);

        /* Process command line arguments */
        while ((opt = getopt(argc, argv, "b:df:Fhpqi:l:m:n:o:P:r:st:u:S:")) != -1) {
                switch (opt) {
                        case 'b': use_dumpfile = optarg; break;
                        case 'd': daemon_mode = 1; use_syslog = 1; break;
                        case 'f': format_str = optarg; break;
                        case 'F': force_flush = 1; break;
                        case 'h': display_usage(); break;
                        case 'i': interface = optarg; break;
                        case 'l': rate_threshold = atoi(optarg); break;
                        case 'm': methods_str = optarg; break;
                        case 'n': parse_count = atoi(optarg); break;
                        case 'o': use_outfile = optarg; break;
                        case 'p': set_promisc = 0; break;
                        case 'P': pid_filename = optarg; break;
                        case 'q': quiet_mode = 1; break;
                        case 'r': use_infile = optarg; break;
                        case 's': rate_stats = 1; break;
                        case 't': rate_interval = atoi(optarg); break;
                        case 'u': new_user = optarg; break;
                        case 'S': eth_skip_bits = atoi(optarg); break;
                        default: display_usage();
                }
        }

        display_banner();

        if (daemon_mode && !use_outfile)
                LOG_DIE("Daemon mode requires an output file");

        if (parse_count < 0)
                LOG_DIE("Invalid -n value, must be 0 or greater");

        if (rate_interval < 1)
                LOG_DIE("Invalid -t value, must be 1 or greater");

        if (rate_threshold < 1)
                LOG_DIE("Invalid -l value, must be 1 or greater");

        if (argv[optind] && *(argv[optind])) {
                capfilter = argv[optind];
        } else {
                capfilter = default_capfilter;
        }

        if (!format_str) format_str = default_format;
        if (rate_stats) format_str = rate_format;
        parse_format_string(format_str);

        if (!methods_str) methods_str = default_methods;
        parse_methods_string(methods_str);

        if (force_flush) {
                if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
                        LOG_WARN("Cannot disable buffering on stdout");
        }

        if (!pid_filename) pid_filename = PID_FILENAME;

        pcap_hnd = prepare_capture(interface, set_promisc, use_infile, capfilter);

        open_outfiles();

        if (daemon_mode) runas_daemon();
        if (new_user) change_user(new_user);

        if ((buf = malloc(BUFSIZ + 1)) == NULL)
                LOG_DIE("Cannot allocate memory for packet data buffer");

        if (rate_stats)
                init_rate_stats(rate_interval, use_infile, rate_threshold);

        start_time = time(0);
        loop_status = pcap_loop(pcap_hnd, -1, &parse_http_packet, NULL);
        if (loop_status == -1) {
                LOG_DIE("Problem reading packets from interface: %s", pcap_geterr(pcap_hnd));
        } else if (loop_status == -2) {
                PRINT("Loop halted, shutting down...");
        }

        print_stats();
        cleanup();

        return loop_status == -1 ? EXIT_FAILURE : EXIT_SUCCESS;
}
Example #25
0
int main(int argc, char **argv) {
        int opt;
        extern char *optarg;
        extern int optind;
        int loop_status;

        signal(SIGINT, &handle_signal);

        /* Process command line arguments */
        while ((opt = getopt(argc, argv, "b:df:hpqi:m:n:o:r:u:")) != -1) {
                switch (opt) {
                        case 'b': use_dumpfile = optarg; break;
                        case 'd': daemon_mode = 1;
                                  use_syslog = 1; break;
                        case 'f': format_str = optarg; break;
                        case 'h': display_usage(); break;
                        case 'i': interface = optarg; break;
                        case 'm': methods_str = optarg; break;
                        case 'n': parse_count = atoi(optarg); break;
                        case 'o': use_outfile = optarg; break;
                        case 'p': set_promisc = 0; break;
                        case 'q': quiet_mode = 1; break;
                        case 'r': use_infile = optarg; break;
                        case 'u': new_user = optarg; break;
                        default: display_usage();
                }
        }

        display_banner();

        if (daemon_mode && !use_outfile)
                LOG_DIE("Daemon mode requires an output file");

        if (parse_count < 0)
                LOG_DIE("Invalid -n value, must be 0 or greater");

        if (argv[optind] && *(argv[optind])) {
                capfilter = argv[optind];
        } else {
                capfilter = default_capfilter;
        }

        if (!format_str) format_str = default_format;
        parse_format_string(format_str);

        if (!methods_str) methods_str = default_methods;
        parse_methods_string(methods_str);

        pcap_hnd = prepare_capture(interface, set_promisc, use_infile, capfilter);

        open_outfiles();

        if (daemon_mode) runas_daemon();
        if (new_user) change_user(new_user);

        if ((buf = malloc(BUFSIZ + 1)) == NULL)
                LOG_DIE("Cannot allocate memory for packet data buffer");

        start_time = time(0);
        loop_status = pcap_loop(pcap_hnd, -1, &parse_http_packet, NULL);
        if (loop_status == -1) {
                LOG_DIE("Problem reading packets from interface: %s", pcap_geterr(pcap_hnd));
        } else if (loop_status == -2) {
                PRINT("Loop halted, shutting down...");
        }

        cleanup();

        return loop_status == -1 ? EXIT_FAILURE : EXIT_SUCCESS;
}
int launch_container_as_user(const char *user, const char *app_id, 
                   const char *container_id, const char *work_dir,
                   const char *script_name, const char *cred_file,
                   const char* pid_file, char* const* local_dirs,
                   char* const* log_dirs, const char *resources_key,
                   char* const* resources_values) {
  int exit_code = -1;
  char *script_file_dest = NULL;
  char *cred_file_dest = NULL;
  script_file_dest = get_container_launcher_file(work_dir);
  if (script_file_dest == NULL) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }
  cred_file_dest = get_container_credentials_file(work_dir);
  if (NULL == cred_file_dest) {
    exit_code = OUT_OF_MEMORY;
    goto cleanup;
  }

  // open launch script
  int container_file_source = open_file_as_nm(script_name);
  if (container_file_source == -1) {
    goto cleanup;
  }

  // open credentials
  int cred_file_source = open_file_as_nm(cred_file);
  if (cred_file_source == -1) {
    goto cleanup;
  }

  // setsid 
  pid_t pid = setsid();
  if (pid == -1) {
    exit_code = SETSID_OPER_FAILED;
    goto cleanup;
  }

  // write pid to pidfile
  if (pid_file == NULL
      || write_pid_to_file_as_nm(pid_file, pid) != 0) {
    exit_code = WRITE_PIDFILE_FAILED;
    goto cleanup;
  }

  // cgroups-based resource enforcement
  if (resources_key != NULL && ! strcmp(resources_key, "cgroups")) {

    // write pid to cgroups
    char* const* cgroup_ptr;
    for (cgroup_ptr = resources_values; cgroup_ptr != NULL && 
         *cgroup_ptr != NULL; ++cgroup_ptr) {
      if (strcmp(*cgroup_ptr, "none") != 0 &&
            write_pid_to_cgroup_as_root(*cgroup_ptr, pid) != 0) {
        exit_code = WRITE_CGROUP_FAILED;
        goto cleanup;
      }
    }
  }

  // give up root privs
  if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) {
    exit_code = SETUID_OPER_FAILED;
    goto cleanup;
  }

  if (create_container_directories(user, app_id, container_id, local_dirs,
                                   log_dirs, work_dir) != 0) {
    fprintf(LOGFILE, "Could not create container dirs");
    goto cleanup;
  }

  // 700
  if (copy_file(container_file_source, script_name, script_file_dest,S_IRWXU) != 0) {
    goto cleanup;
  }

  // 600
  if (copy_file(cred_file_source, cred_file, cred_file_dest,
        S_IRUSR | S_IWUSR) != 0) {
    goto cleanup;
  }

  fcloseall();
  umask(0027);
  if (chdir(work_dir) != 0) {
    fprintf(LOGFILE, "Can't change directory to %s -%s\n", work_dir,
	    strerror(errno));
    goto cleanup;
  }
  if (execlp(script_file_dest, script_file_dest, NULL) != 0) {
    fprintf(LOGFILE, "Couldn't execute the container launch file %s - %s", 
            script_file_dest, strerror(errno));
    exit_code = UNABLE_TO_EXECUTE_CONTAINER_SCRIPT;
    goto cleanup;
  }
  exit_code = 0;

 cleanup:
  free(script_file_dest);
  free(cred_file_dest);
  return exit_code;
}
int run_task_as_user(const char * user, const char *jobid, const char *taskid,
    const char *tt_root) {
  char *task_script_path = NULL;
  char *pid_path = NULL;
  char *task_script = NULL;
  FILE *file_handle = NULL;
  int exit_code = 0;
  int i = 0;

#ifdef DEBUG
  fprintf(LOGFILE,"run_task_as_user : Job id : %s \n", jobid);
  fprintf(LOGFILE,"run_task_as_user : task id : %s \n", taskid);
  fprintf(LOGFILE,"run_task_as_user : tt_root : %s \n", tt_root);
  fflush(LOGFILE);
#endif

  if (check_tt_root(tt_root) < 0) {
    fprintf(LOGFILE, "invalid tt root passed %s\n", tt_root);
    cleanup();
    return INVALID_TT_ROOT;
  }

  get_pid_path(jobid, taskid, tt_root, &pid_path);

  if (pid_path == NULL) {
    fprintf(LOGFILE, "Invalid task-pid path provided");
    cleanup();
    return INVALID_PID_PATH;
  }

  errno = 0;
  file_handle = fopen(pid_path, "w");

  if (file_handle == NULL) {
    fprintf(LOGFILE, "Error opening task-pid file %s :%s\n", pid_path,
        strerror(errno));
    exit_code = UNABLE_TO_OPEN_PID_FILE_WRITE_MODE;
    goto cleanup;
  }

  errno = 0;
  if (fprintf(file_handle, "%d\n", getpid()) < 0) {
    fprintf(LOGFILE, "Error writing to task-pid file :%s\n", strerror(errno));
    exit_code = UNABLE_TO_WRITE_TO_PID_FILE;
    goto cleanup;
  }

  fflush(file_handle);
  fclose(file_handle);
  //change the permissions of the file
  errno = 0;
  //setting permission to 777

  if (chmod(pid_path, S_IREAD | S_IEXEC | S_IWRITE | S_IROTH | S_IWOTH
      | S_IXOTH | S_IRGRP | S_IWGRP | S_IXGRP) < 0) {
    fprintf(LOGFILE, "Error changing permission of %s task-pid file : %s",
        pid_path, strerror(errno));
    errno = 0;
    if (remove(pid_path) < 0) {
      fprintf(LOGFILE, "Error deleting %s task-pid file : %s", pid_path,
          strerror(errno));
      exit_code = UNABLE_TO_CHANGE_PERMISSION_AND_DELETE_PID_FILE;
    } else {
      exit_code = UNABLE_TO_CHANGE_PERMISSION_OF_PID_FILE;
    }
    goto cleanup;
  }
#ifdef DEBUG
  fprintf(LOGFILE,"changing file ownership\n");
  fprintf(LOGFILE, "run_task_as_user : uid id %d \n", getuid());
  fprintf(LOGFILE, "run_task_as_user : gid id %d \n", getgid());
#endif
  //change the owner ship of the file to the launching user.
  if(chown(pid_path, getuid(), getgid()) <0 ) {
    fprintf(LOGFILE, "Error changing ownership of %s task-pid file : %s",
        pid_path, strerror(errno));
    if(remove(pid_path) < 0) {
      fprintf(LOGFILE, "Error deleting %s task-pid file : %s", pid_path,
          strerror(errno));
      exit_code = UNABLE_TO_CHANGE_OWNERSHIP_OF_PID_FILE_AND_DELETE_PID_FILE;
    } else {
      exit_code = UNABLE_TO_CHANGE_OWNERSHIP_OF_PID_FILE;
    }
    goto cleanup;
  }


  //free pid_t path which is allocated
  free(pid_path);

  //change the user
  fcloseall();
  fclose(LOGFILE);
  umask(0);
  if (change_user(user) != 0) {
    cleanup();
    return SETUID_OPER_FAILED;
  }

  get_task_file_path(jobid, taskid, tt_root, &task_script_path);

  if (task_script_path == NULL) {
    fprintf(LOGFILE, "Unable to locate task script");
    cleanup();
    return INVALID_TASK_SCRIPT_PATH;
  }
  errno = 0;
  cleanup();
  execlp(task_script_path, task_script_path, NULL);
  if (errno != 0) {
    fprintf(LOGFILE, "Error execing script %s", strerror(errno));
    free(task_script_path);
    exit_code = UNABLE_TO_EXECUTE_TASK_SCRIPT;
  }

  return exit_code;

cleanup:
  if (pid_path != NULL) {
    free(pid_path);
  }
  if (task_script_path != NULL) {
    free(task_script_path);
  }
  if (file_handle != NULL) {
    fclose(file_handle);
  }
  // free configurations
  cleanup();
  return exit_code;
}
Example #28
0
static pid_t
fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail)
{
	struct passwd *pas;
	const char *shell, *prog;
	smallint sv_logmode;
	pid_t pid;

	/* prepare things before vfork */
	pas = getpwnam(user);
	if (!pas) {
		bb_error_msg("can't get uid for %s", user);
		goto err;
	}

	shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL;
	prog = run_sendmail ? SENDMAIL : shell;

	set_env_vars(pas, shell);

	sv_logmode = logmode;
	pid = vfork();
	if (pid == 0) {
		/* CHILD */
		/* initgroups, setgid, setuid, and chdir to home or CRON_DIR */
		change_user(pas);
		log5("child running %s", prog);
		if (mailFd >= 0) {
			xmove_fd(mailFd, run_sendmail ? 0 : 1);
			dup2(1, 2);
		}
		/* crond 3.0pl1-100 puts tasks in separate process groups */
		bb_setpgrp();
		if (!run_sendmail)
			execlp(prog, prog, "-c", line->cl_cmd, (char *) NULL);
		else
			execlp(prog, prog, SENDMAIL_ARGS, (char *) NULL);
		/*
		 * I want this error message on stderr too,
		 * even if other messages go only to syslog:
		 */
		logmode |= LOGMODE_STDIO;
		bb_error_msg_and_die("can't execute '%s' for user %s", prog, user);
	}
	logmode = sv_logmode;

	if (pid < 0) {
		bb_perror_msg("vfork");
 err:
		pid = 0;
	} /* else: PARENT, FORK SUCCESS */

	/*
	 * Close the mail file descriptor.. we can't just leave it open in
	 * a structure, closing it later, because we might run out of descriptors
	 */
	if (mailFd >= 0) {
		close(mailFd);
	}
	return pid;
}
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "hvu:m:f:g:o:")) != -1) {
    switch (i) {
    case 'v':
      verbosity = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'm':
      assert (sscanf(optarg, "%d,%d", &split_rem, &split_mod) == 2);
      assert (split_mod > 0 && split_mod <= 1000 && split_rem >= 0 && split_rem < split_mod);
      break;
    case 'f':
      table_format = get_dump_format(optarg);
      if (!table_format) {
	fprintf (stderr, "fatal: unsupported table dump format: %s\n", optarg);
	return 2;
      }
      break;
    case 'g':
      groups_fname = optarg;
      break;
    case 'o':
      output_format = atol (optarg);
      break;
    case 'u':
      username = optarg;
      break;
    }
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  src_fname = argv[optind];

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  src_fd = open (src_fname, O_RDONLY);
  if (src_fd < 0) {
    fprintf (stderr, "cannot open %s: %m\n", src_fname);
    return 1;
  }

  if (!table_format) {
    table_format = get_dump_format (fname_last (src_fname));
    if (!table_format) {
      fprintf (stderr, "fatal: cannot determine table type from filename %s\n", src_fname);
    }
  }

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  switch (table_format) {
  case TF_AUDIO:
    Args_per_line = au_END;
    start_binlog(SEARCH_SCHEMA_V1, "audio_search");
    while (read_record() > 0) {
      process_audio_row();
    }
    break;
  case TF_VIDEO:
    Args_per_line = vi_END;
    start_binlog(SEARCH_SCHEMA_V1, "video_search");
    while (read_record() > 0) {
      process_video_row();
    }
    break;
  case TF_APPS:
    Args_per_line = ap_END;
    start_binlog(SEARCH_SCHEMA_V1, "apps_search");
    while (read_record() > 0) {
      process_applications_row();
    }
    break;
  case TF_GROUPS:
    Args_per_line = gr_END;
    start_binlog(SEARCH_SCHEMA_V1, "group_search");
    while (read_record() > 0) {
      process_groups_row();
    }
    break;
  case TF_EVENTS:
    Args_per_line = gr_END;
    start_binlog(SEARCH_SCHEMA_V1, "event_search");
    while (read_record() > 0) {
      process_events_row();
    }
    break;
  case TF_BLOG_POSTS:
    Args_per_line = bp_END;
    start_binlog(SEARCH_SCHEMA_V1, "blog_posts_search");
    while (read_record() > 0) {
      process_blog_posts_row();
    }
    break;
  case TF_MEMLITE:
    Args_per_line = ml_END;
    start_binlog(SEARCH_SCHEMA_V1, "member_name_search");
    while (read_record() > 0) {
      process_memlite_row();
    }
    break;
  case TF_MARKET_ITEMS:
    Args_per_line = mi_END;
    start_binlog(SEARCH_SCHEMA_V1, "market_search");
    while (read_record() > 0) {
      process_market_row();
    }
    break;
  case TF_QUESTIONS:
    Args_per_line = qu_END;
    start_binlog(SEARCH_SCHEMA_V1, "question_search");
    while (read_record() > 0) {
      process_questions_row();
    }
    break;
  case TF_TOPICS:
    load_map (1);
    Args_per_line = to_END;
    start_binlog(SEARCH_SCHEMA_V1, "topic_search");
    while (read_record() > 0) {
      process_topics_row();
    }
    break;
  case TF_MINIFEED:
    Args_per_line = mf_END;
    start_binlog(SEARCH_SCHEMA_V1, "status_search");
    while (read_record() > 0) {
      process_minifeed_row();
    }
    break;
  default:
    fprintf (stderr, "unknown table type\n");
    exit(1);
  }

  flush_out();
  if (targ_fd != 1) {
    if (fdatasync(targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (map_size > 0 && map_changes > 0 && groups_fname) {
    map_fd = open (groups_fname, O_WRONLY | O_CREAT | O_TRUNC, 0640);
    if (map_fd < 0) {
      fprintf (stderr, "cannot create map file %s: %m\n", groups_fname);
      exit (1);
    }
    assert (write (map_fd, Map, map_size) == map_size);
    close (map_fd);
    if (verbosity > 0) {
      fprintf (stderr, "%d bytes written to map file %s\n", map_size, groups_fname);
    }
  }

  if (verbosity > 0) {
    output_stats();
  }

  return 0;
}
Example #30
0
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "fhvu:m:s:t:M:F")) != -1) {
    switch (i) {
    case 'F':
      filter_member_fan = 1;
      break;
    case 'v':
      verbosity += 1;
      break;
    case 'f':
      // vkprintf(2, "setting skip_rotate\n");
      skip_rotate = 1;
      break;
    case 'h':
      usage ();
      return 2;
    case 'u':
      username = optarg;
      break;
    case 'm':
      if (sscanf (optarg, "%d,%d", &copy_rem, &copy_mod) != 2 || copy_rem < 0 || copy_rem >= copy_mod) {
	usage();
	return 2;
      }
      break;
    case 's':
      jump_log_pos = atoll (optarg);
      break;
    case 't':
      keep_log_limit_pos = log_limit_pos = atoll (optarg);
      break;
    case 'M':
      if (!strncmp(optarg, "firstint", 9)) {
        split_mode = SPLIT_FIRSTINT;
      } else if (!strncmp(optarg, "liked", 6)) {
        split_mode = SPLIT_LIKED;
      } else {
        usage();
        return 2;
      }
      break;
    default:
      assert (0);
      return 2;
    }
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  if (filter_member_fan) {
    vkprintf (1, "fix member_fans, fan_members mode\n");
    char *p = strrchr (argv[optind], '/');
    p = (p == NULL) ? argv[optind] : (p + 1);
    if (!strncmp (p, "member_fans", 11)) {
      want_write = member_fans_want_write;
    } else if (!strncmp (p, "fan_members", 11)) {
      want_write = fan_members_want_write;
    } else {
      kprintf ("binlogname should starts from member_fans of fan_members when command line switch -F used.\n");
      exit (1);
    }
  }

  if (log_limit_pos >= 0) {
    if (jump_log_pos > log_limit_pos) {
      fprintf (stderr, "fatal: log start position %lld after stop position %lld\n", jump_log_pos, log_limit_pos);
      return 2;
    }
  }

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Binlog = open_binlog (engine_replica, 0);
  if (!Binlog) {
    fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, 0LL);
    exit (1);
  }

  binlogname = Binlog->info->filename;

  if (verbosity) {
    fprintf (stderr, "replaying binlog file %s (size %lld)\n", binlogname, Binlog->info->file_size);
  }

  clear_log();

  init_log_data (0, 0, 0);

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
    targ_orig_size = lseek (targ_fd, 0, SEEK_END);
    targ_existed = (targ_orig_size > 0);
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  if (jump_log_pos > 0) {

    log_limit_pos = 256;
    immediate_exit = 1;

    i = replay_log (0, 1);

    if (!list_id_ints) {
      fprintf (stderr, "fatal: cannot parse first LEV_START entry");
      exit (1);
    }

    log_limit_pos = keep_log_limit_pos;
    immediate_exit = 0;

    clear_log ();

    close_binlog (Binlog, 1);
    Binlog = 0;

    Binlog = open_binlog (engine_replica, jump_log_pos);
    if (!Binlog) {
      fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, jump_log_pos);
      exit (1);
    }

    binlogname = Binlog->info->filename;

    if (verbosity) {
      fprintf (stderr, "replaying binlog file %s (size %lld) from log position %lld\n", binlogname, Binlog->info->file_size, jump_log_pos);
    }

    init_log_data (jump_log_pos, 0, 0);
  }

  i = replay_log (0, 1);

  if (i < 0) {
    fprintf (stderr, "fatal: error reading binlog\n");
    exit (1);
  }

  if (log_limit_pos >= 0 && log_readto_pos != log_limit_pos) {
    fprintf (stderr, "fatal: binlog read up to position %lld instead of %lld\n", log_readto_pos, log_limit_pos);
    exit (1);
  }

  if (!targ_orig_size && !jump_log_pos) {
    vkprintf (1, "Writing CRC32 to the end of target binlog.\n");
    struct lev_crc32 *C = write_alloc (20);
    C->type = LEV_CRC32;
    C->timestamp = last_timestamp;
    C->pos = wr_bytes;
    C->crc32 = ~wr_crc32_complement;
    wr_bytes += 20;
    wr_rec++;
  }

  flush_out ();

  if (targ_fd != 1) {
    if (fdatasync (targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (verbosity > 0) {
    output_stats ();
  }

  return 0;
}