Beispiel #1
0
int pty_open (int *pid, struct winsize *winsize, char **chargv, char **chenvp)
{
	int pty = -1;
	int i;
	char line[20];
	int c;
	int tty, devtty;

	for (c = 'a'; c <= 'z'; c++)
	{
		for (i = 0; i < 16; i++)
		{
			sprintf (line, "/dev/pty%c%x", c, i);
			pty = open (line, O_RDWR | O_NOCTTY);
			if (pty >= 0)
				break;
		}
		if (pty >= 0)
			break;
	}

	if (pty < 0)
	{
		fprintf (stderr, "Out of pty\n");
		return -1;
	}

	ioctl (pty, TIOCEXCL, NULL);

	if ((*pid = fork ()) != 0)
	{
		/* Father */
		return pty;
	}

	/* Child */

	close (pty);

	setenv ("TERM", "linux", 1);

	line[5] = 't';
	tty = open (line, O_RDWR);
	if (tty < 0)
	{
		fprintf (stderr, "Cannot open slave side\n");
		close (pty);
		return -1;
	}
	(void) chown (line, getuid (), getgid ());
	(void) chmod (line, 0600);

	setsid ();					/* will break terminal affiliation */
	ioctl (tty, TIOCSCTTY, (char *) 0);

	setuid (getuid ());
	setgid (getgid ());

	devtty = open ("/dev/tty", O_RDWR);
	if (devtty < 0)
	{
		perror ("cannot open /dev/tty");
		exit (1);
	}

/*      if (ioctl(devtty, TIOCNOTTY, (char *)0)) {
   perror("cannot do iotctl TIOCNOTTY");
   exit(1);
   }
 */
	ioctl (devtty, TIOCSWINSZ, winsize);
	close (tty);
	dup2 (devtty, 0);
	dup2 (devtty, 1);
	dup2 (devtty, 2);
	execve (chargv[0], chargv, chenvp);
	exit (0);
}
Beispiel #2
0
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
		LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
		LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
		LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
	pid_t pid;
	int flags;
	int numArgs;
	LPSTR* pArgs = NULL;
	char** envp = NULL;
	char* filename = NULL;
	HANDLE thread;
	HANDLE process;
	WINPR_ACCESS_TOKEN* token;
	LPTCH lpszEnvironmentBlock;
	BOOL ret = FALSE;

	pid = 0;
	numArgs = 0;
	lpszEnvironmentBlock = NULL;

	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);

	flags = 0;

	token = (WINPR_ACCESS_TOKEN*) hToken;

	if (lpEnvironment)
	{
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
	}
	else
	{
		lpszEnvironmentBlock = GetEnvironmentStrings();
		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
	}

	filename = FindApplicationPath(pArgs[0]);
	if (NULL == filename)
		goto finish;

	/* fork and exec */

	pid = fork();

	if (pid < 0)
	{
		/* fork failure */
		goto finish;
	}

	if (pid == 0)
	{
		/* child process */
#ifdef __sun
	closefrom(3);
#else
	int maxfd;
#ifdef F_MAXFD // on some BSD derivates
	maxfd = fcntl(0, F_MAXFD);
#else
	maxfd = sysconf(_SC_OPEN_MAX);
#endif
	int fd;
	for(fd=3; fd<maxfd; fd++)
		close(fd);
#endif // __sun

		if (token)
		{
			if (token->GroupId)
			{
				int rc = setgid((gid_t) token->GroupId);
				if (rc < 0)
				{
				}
				else
				{
					initgroups(token->Username, (gid_t) token->GroupId);
				}
			}

			if (token->UserId)
				setuid((uid_t) token->UserId);

			/* TODO: add better cwd handling and error checking */
			if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
				chdir(lpCurrentDirectory);
		}

		if (execve(filename, pArgs, envp) < 0)
		{
			/* execve failed - end the process */
			_exit(1);
		}
	}
	else
	{
		/* parent process */
	}

	process = CreateProcessHandle(pid);

	if (!process)
	{
		goto finish;
	}

	thread = CreateNoneHandle();

	if (!thread)
	{
		ProcessHandleCloseHandle(process);
		goto finish;
	}

	lpProcessInformation->hProcess = process;
	lpProcessInformation->hThread = thread;
	lpProcessInformation->dwProcessId = (DWORD) pid;
	lpProcessInformation->dwThreadId = (DWORD) pid;

	ret = TRUE;

finish:
	if (filename)
	{
		free(filename);
	}

	if (pArgs)
	{
		HeapFree(GetProcessHeap(), 0, pArgs);
	}

	if (lpszEnvironmentBlock)
		FreeEnvironmentStrings(lpszEnvironmentBlock);

	if (envp)
	{
		int i = 0;

		while (envp[i])
		{
			free(envp[i]);
			i++;
		}

		free(envp);
	}

	return ret;
}
Beispiel #3
0
int startup(int argc, char* argv[])
{
  const char* tmp;
  const char* end;
  const char* cwdstr;
  char* ptr;
  unsigned long session_timeout;
  unsigned startup_code;

  if ((tmp = getenv("TCPLOCALIP")) == 0) FAIL("Missing $TCPLOCALIP.");
  if (!parse_localip(tmp)) FAIL("Could not parse $TCPLOCALIP.");
  if ((tmp = getenv("TCPREMOTEIP")) == 0) FAIL("Missing $TCPREMOTEIP.");
  if (!parse_remoteip(tmp)) FAIL("Could not parse $TCPREMOTEIP.");
  if ((tmp = getenv("UID")) == 0) FAIL("Missing $UID.");
  if (!(uid = strtou(tmp, &end)) || *end) FAIL("Invalid $UID.");
  if ((tmp = getenv("GID")) == 0) FAIL("Missing $GID.");
  if (!(gid = strtou(tmp, &end)) || *end) FAIL("Invalid $GID.");
  if ((home = getenv("HOME")) == 0) FAIL("Missing $HOME.");
  if ((tmp = getenv("GIDS")) != 0 && !parse_gids(tmp))
    FAIL("Could not parse or set supplementary group IDs.");

  /* Strip off trailing slashes in $HOME */
  ptr = (char*)home + strlen(home)-1;
  while (ptr > home && *ptr == '/') *ptr-- = 0;

  if ((user = getenv("USER")) == 0) FAIL("Missing $USER.");
  if ((group = getenv("GROUP")) == 0) group = "mygroup";
  if (chdir(home)) FAIL("Could not chdir to $HOME.");
  if (!load_tables()) FAIL("Loading startup tables failed.");
  if (getenv("CHROOT") != 0) {
    cwdstr = "/";
    if (chroot(".")) FAIL("Could not chroot.");
  }
  else if (getenv("SOFTCHROOT") != 0) {
    cwdstr = "/";
  }
  else {
    cwdstr = home;
    if (chdir("/")) FAIL("Could not chdir to '/'.");
  }
  if (!str_copys(&cwd, cwdstr)) FAIL("Could not set CWD string");
  if (setgid(gid)) FAIL("Could not set GID.");
  if (setuid(uid)) FAIL("Could not set UID.");
  if ((user_len = strlen(user)) > MAX_NAME_LEN) {
    user_len = MAX_NAME_LEN;
    ((char*)user)[MAX_NAME_LEN] = 0;
  }
  if ((group_len = strlen(group)) > MAX_NAME_LEN) {
    group_len = MAX_NAME_LEN;
    ((char*)group)[MAX_NAME_LEN] = 0;
  }

  lockhome = (getenv("LOCKHOME") != 0);
  nodotfiles = (getenv("NODOTFILES") != 0);
  list_options = (nodotfiles ? 0 : PATH_MATCH_DOTFILES);

  session_timeout = 0;
  if ((tmp = getenv("SESSION_TIMEOUT")) != 0)
    session_timeout = strtou(tmp, &tmp);
  alarm(session_timeout);
  connect_timeout = timeout;
  if ((tmp = getenv("CONNECT_TIMEOUT")) != 0)
    connect_timeout = strtou(tmp, &tmp);

  if ((tmp = getenv("TWOFTPD_BIND_PORT_FD")) != 0) {
    if ((bind_port_fd = strtou(tmp, &end)) == 0 || *end != 0)
      FAIL("Invalid $TWOFTPD_BIND_PORT_FD");
  }
  else
    bind_port_fd = -1;

  startup_code = (getenv("AUTHENTICATED") != 0) ? 230 : 220;
  if ((tmp = getenv("BANNER")) != 0) show_banner(startup_code, tmp);
  message_file = getenv("MESSAGEFILE");
  show_message_file(startup_code);
  return respond(startup_code, 1, "Ready to transfer files.");
  (void)argc;
  (void)argv;
}
Beispiel #4
0
int
os_server_start_2(const char *user, int close_stdfiles)
{
     int istat;
     gid_t gid, old_egid, old_gid;
     uid_t uid, old_euid, old_uid;

     /*
      *  Close all open files but stdout & stderr
      */
     if (close_stdfiles)
     {
	  if (stderr)
	  {
	       fflush(stderr);
	       fclose(stderr);
	  }
	  else
	  {
	       fsync(2);
	       close(2);
	  }
	  if (stdout)
	  {
	       fflush(stdout);
	       fclose(stdout);
	  }
	  else
	  {
	       fsync(1);
	       close(1);
	  }
	  if (stdin)
	       fclose(stdin);
	  else
	       close(0);
	  os_close_files(3, 20);
     }

     /*
      *  Change our uid & gid
      */
     if (user && *user)
     {
	  if (os_uinfo(&uid, &gid, user))
	       return(-1);

	  /*
	   *  In case things fail....
	   */
	  old_euid = geteuid();
	  old_uid  = getuid();
	  old_egid = getegid();
	  old_gid  = getgid();

	  /*
	   *  On some platforms you first have to elevate the effective UID to
	   *  root before changing real & effective UID to a non-root UID.
	   */
	  seteuid(0);

	  /*
	   *  Now do an irreversible change of our UID and GID
	   */
	  if (setgid(gid))
	  {
	       int save_errno = errno;
	       seteuid(old_euid);
	       errno = save_errno;
	       return(-1);
	  }

	  if (setuid(uid))
	  {
	       int save_errno = errno;
	       seteuid(old_euid);
	       setgid(old_gid);
	       setegid(old_egid);
	       errno = save_errno;
	       return(-1);
	  }
     }
     return(0);
}
Beispiel #5
0
Datei: open10.c Projekt: 1587/ltp
int main(int ac, char *av[])
{
	int ret;
	struct stat buf;
	struct group *group;
	struct passwd *user1;
	char DIR_A[MSGSIZE], DIR_B[MSGSIZE];
	char setgid_A[MSGSIZE], nosetgid_A[MSGSIZE];
	char setgid_B[MSGSIZE], nosetgid_B[MSGSIZE], root_setgid_B[MSGSIZE];
	gid_t group1_gid, group2_gid, mygid;
	uid_t save_myuid, user1_uid;
	pid_t mypid;

	int lc;
	int fail_count = 0;

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		local_flag = PASSED;

		save_myuid = getuid();
		mypid = getpid();
		sprintf(DIR_A, DIR_A_TEMP, mypid);
		sprintf(DIR_B, DIR_B_TEMP, mypid);
		sprintf(setgid_A, "%s/%s", DIR_A, SETGID);
		sprintf(nosetgid_A, "%s/%s", DIR_A, NOSETGID);
		sprintf(setgid_B, "%s/%s", DIR_B, SETGID);
		sprintf(nosetgid_B, "%s/%s", DIR_B, NOSETGID);
		sprintf(root_setgid_B, "%s/%s", DIR_B, ROOT_SETGID);

		/* Get the uid of user1 */
		user1 = getpwnam("nobody");
		if (user1 == NULL)
			tst_brkm(TBROK, cleanup, "nobody not in /etc/passwd");

		user1_uid = user1->pw_uid;

		/*
		 * Get the group IDs of group1 and group2.
		 */
		group = getgrnam("nobody");
		if (group == NULL) {
			group = getgrnam("nogroup");
			if (group == NULL) {
				tst_brkm(TBROK, cleanup,
					 "nobody/nogroup not in /etc/group");
			}
		}
		group1_gid = group->gr_gid;
		group = getgrnam("bin");
		if (group == NULL)
			tst_brkm(TBROK, cleanup, "bin not in /etc/group");

		group2_gid = group->gr_gid;

		/*
		 * Create a directory with group id the same as this process
		 * and with no setgid bit.
		 */
		if (mkdir(DIR_A, MODE_RWX) < 0) {
			tst_resm(TFAIL | TERRNO, "mkdir(%s) failed", DIR_A);
			local_flag = FAILED;
		}

		if (chown(DIR_A, user1_uid, group2_gid) < 0) {
			tst_resm(TFAIL | TERRNO, "chown(%s) failed", DIR_A);
			local_flag = FAILED;
		}

		if (stat(DIR_A, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", DIR_A);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (buf.st_mode & S_ISGID) {
			tst_resm(TFAIL, "%s: Incorrect modes, setgid bit set",
				 DIR_A);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != group2_gid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 DIR_A, buf.st_gid, group2_gid);
			local_flag = FAILED;
		}

		/*
		 * Create a directory with group id different from that of
		 * this process and with the setgid bit set.
		 */
		if (mkdir(DIR_B, MODE_RWX) < 0) {
			tst_resm(TFAIL | TERRNO, "mkdir(%s) failed", DIR_B);
			local_flag = FAILED;
		}

		if (chown(DIR_B, user1_uid, group2_gid) < 0) {
			tst_resm(TFAIL | TERRNO, "chown(%s) failed", DIR_B);
			local_flag = FAILED;
		}

		if (chmod(DIR_B, MODE_SGID) < 0) {
			tst_resm(TFAIL | TERRNO, "chmod(%s) failed", DIR_B);
			local_flag = FAILED;
		}

		if (stat(DIR_B, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", DIR_B);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (!(buf.st_mode & S_ISGID)) {
			tst_resm(TFAIL,
				 "%s: Incorrect modes, setgid bit not set",
				 DIR_B);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != group2_gid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 DIR_B, buf.st_gid, group2_gid);
			local_flag = FAILED;
		}

		if (local_flag == PASSED) {
			tst_resm(TPASS, "Test passed in block0.");
		} else {
			tst_resm(TFAIL, "Test failed in block0.");
			fail_count++;
		}

		local_flag = PASSED;

		/*
		 * Create two files in testdir.A, one with the setgid
		 * bit set in the creation modes and the other without.
		 * Both should inherit the group ID of the process and
		 * maintain the setgid bit as specified in the creation
		 * modes.
		 */
		if (setgid(group1_gid) < 0) {
			tst_resm(TINFO,
				 "Unable to set process group ID to group1");
		}

		if (setreuid(-1, user1_uid) < 0)
			tst_resm(TINFO, "Unable to set process uid to user1");

		mygid = getgid();

		/*
		 * Create the file with setgid not set
		 */
		ret = open(nosetgid_A, O_CREAT | O_EXCL | O_RDWR, MODE_RWX);
		if (ret < 0) {
			tst_resm(TFAIL | TERRNO, "open(%s) failed", nosetgid_A);
			local_flag = FAILED;
		}
		close(ret);

		if (stat(nosetgid_A, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", nosetgid_A);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (buf.st_mode & S_ISGID) {
			tst_resm(TFAIL, "%s: Incorrect modes, setgid bit set",
				 nosetgid_A);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != mygid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 nosetgid_A, buf.st_gid, mygid);
			local_flag = FAILED;
		}

		/*
		 * Create the file with setgid set
		 */
		ret = open(setgid_A, O_CREAT | O_EXCL | O_RDWR, MODE_SGID);
		if (ret < 0) {
			tst_resm(TFAIL | TERRNO, "open(%s) failed", setgid_A);
			local_flag = FAILED;
		}
		close(ret);

		if (stat(setgid_A, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", setgid_A);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (!(buf.st_mode & S_ISGID)) {
			tst_resm(TFAIL,
				 "%s: Incorrect modes, setgid bit not set",
				 setgid_A);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != mygid) {
			tst_resm(TFAIL, "%s: Incorrect group (%d and %d)",
				 setgid_A, buf.st_gid, mygid);
			local_flag = FAILED;
		}

		if (local_flag == PASSED) {
			tst_resm(TPASS, "Test passed in block1.");
		} else {
			tst_resm(TFAIL, "Test failed in block1.");
			fail_count++;
		}

		local_flag = PASSED;

		/*
		 * Create two files in testdir.B, one with the setgid
		 * bit set in the creation modes and the other without.
		 * Both should inherit the group ID of the parent
		 * directory, group2. Either file should have the segid
		 * bit set in the modes.
		 */
		/*
		 * Create the file with setgid not set
		 */
		ret = open(nosetgid_B, O_CREAT | O_EXCL | O_RDWR, MODE_RWX);
		if (ret < 0) {
			tst_resm(TFAIL | TERRNO, "open(%s) failed", nosetgid_B);
			local_flag = FAILED;
		}
		close(ret);

		if (stat(nosetgid_B, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", nosetgid_B);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (buf.st_mode & S_ISGID) {
			tst_resm(TFAIL,
				 "%s: Incorrect modes, setgid bit should be set",
				 nosetgid_B);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != group2_gid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 nosetgid_B, buf.st_gid, group2_gid);
			local_flag = FAILED;
		}

		/*
		 * Create the file with setgid set
		 */
		ret = open(setgid_B, O_CREAT | O_EXCL | O_RDWR, MODE_SGID);
		if (ret < 0) {
			tst_resm(TFAIL | TERRNO, "open(%s) failed", setgid_B);
			local_flag = FAILED;
		}
		close(ret);

		if (stat(setgid_B, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed", setgid_B);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != group2_gid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 setgid_B, buf.st_gid, group2_gid);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (!(buf.st_mode & S_ISGID)) {
			tst_resm(TFAIL,
				 "%s: Incorrect modes, setgid bit not set",
				 setgid_B);
			local_flag = FAILED;
		}

		if (local_flag == PASSED) {
			tst_resm(TPASS, "Test passed in block2.");
		} else {
			tst_resm(TFAIL, "Test failed in block2.");
			fail_count++;
		}

		local_flag = PASSED;

		/*
		 * Create a file in testdir.B, with the setgid bit set
		 * in the creation modes and do so as root. The file
		 * should inherit the group ID of the parent directory,
		 * group2 and should have the setgid bit set.
		 */

		/* Become root again */
		if (setreuid(-1, save_myuid) < 0) {
			tst_resm(TFAIL | TERRNO,
				 "Changing back to root failed");
			local_flag = FAILED;
		}

		/* Create the file with setgid set */
		ret = open(root_setgid_B, O_CREAT | O_EXCL | O_RDWR, MODE_SGID);
		if (ret < 0) {
			tst_resm(TFAIL | TERRNO, "open(%s) failed",
				 root_setgid_B);
			local_flag = FAILED;
		}
		close(ret);

		if (stat(root_setgid_B, &buf) < 0) {
			tst_resm(TFAIL | TERRNO, "stat(%s) failed",
				 root_setgid_B);
			local_flag = FAILED;
		}

		/* Verify modes */
		if (!(buf.st_mode & S_ISGID)) {
			tst_resm(TFAIL,
				 "%s: Incorrect modes, setgid bit not set",
				 root_setgid_B);
			local_flag = FAILED;
		}

		/* Verify group ID */
		if (buf.st_gid != group2_gid) {
			tst_resm(TFAIL, "%s: Incorrect group (got %d and %d)",
				 root_setgid_B, buf.st_gid, group2_gid);
			local_flag = FAILED;
		}

		if (local_flag == PASSED) {
			tst_resm(TPASS, "Test passed in block3.");
		} else {
			tst_resm(TFAIL, "Test failed in block3.");
			fail_count++;
		}

		/*
		 * Clean up any files created by test before call to anyfail.
		 * Remove the directories.
		 */
		if (unlink(setgid_A) < 0)
			tst_resm(TWARN | TERRNO, "unlink(%s) failed", setgid_A);
		if (unlink(nosetgid_A) < 0)
			tst_resm(TWARN | TERRNO, "unlink(%s) failed",
				 nosetgid_A);
		if (rmdir(DIR_A) < 0)
			tst_resm(TWARN | TERRNO, "rmdir(%s) failed", DIR_A);

		if (unlink(setgid_B) < 0)
			tst_resm(TWARN | TERRNO, "unlink(%s) failed", setgid_B);
		if (unlink(root_setgid_B) < 0)
			tst_resm(TWARN | TERRNO, "unlink(%s) failed",
				 root_setgid_B);
		if (unlink(nosetgid_B) < 0)
			tst_resm(TWARN | TERRNO, "unlink(%s) failed",
				 nosetgid_B);
		if (rmdir(DIR_B) < 0)
			tst_resm(TWARN | TERRNO, "rmdir(%s) failed", DIR_B);

		if (fail_count == 0) {
			tst_resm(TPASS, "Test passed.");
		} else {
			tst_resm(TFAIL,
				 "Test failed because of above failures.");
		}

	}

	cleanup();
	tst_exit();
}
static void
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
{
    sigset_t          set;
    uint64_t          cpu_affinity;
    ngx_int_t         n;
    ngx_uint_t        i;
    struct rlimit     rlmt;
    ngx_core_conf_t  *ccf;
    ngx_listening_t  *ls;

    if (ngx_set_environment(cycle, NULL) == NULL) {
        /* fatal */
        exit(2);
    }

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (worker >= 0 && ccf->priority != 0) {
        if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setpriority(%d) failed", ccf->priority);
        }
    }

    if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
        rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
        rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;

        if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setrlimit(RLIMIT_NOFILE, %i) failed",
                          ccf->rlimit_nofile);
        }
    }

    if (ccf->rlimit_core != NGX_CONF_UNSET) {
        rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
        rlmt.rlim_max = (rlim_t) ccf->rlimit_core;

        if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setrlimit(RLIMIT_CORE, %O) failed",
                          ccf->rlimit_core);
        }
    }

#ifdef RLIMIT_SIGPENDING
    if (ccf->rlimit_sigpending != NGX_CONF_UNSET) {
        rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending;
        rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending;

        if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setrlimit(RLIMIT_SIGPENDING, %i) failed",
                          ccf->rlimit_sigpending);
        }
    }
#endif

    if (geteuid() == 0) {
        if (setgid(ccf->group) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "setgid(%d) failed", ccf->group);
            /* fatal */
            exit(2);
        }

        if (initgroups(ccf->username, ccf->group) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "initgroups(%s, %d) failed",
                          ccf->username, ccf->group);
        }

        if (setuid(ccf->user) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "setuid(%d) failed", ccf->user);
            /* fatal */
            exit(2);
        }
    }

    if (worker >= 0) {
        cpu_affinity = ngx_get_cpu_affinity(worker);

        if (cpu_affinity) {
            ngx_setaffinity(cpu_affinity, cycle->log);
        }
    }

#if (NGX_HAVE_PR_SET_DUMPABLE)

    /* allow coredump after setuid() in Linux 2.4.x */

    if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "prctl(PR_SET_DUMPABLE) failed");
    }

#endif

    if (ccf->working_directory.len) {
        if (chdir((char *) ccf->working_directory.data) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "chdir(\"%s\") failed", ccf->working_directory.data);
            /* fatal */
            exit(2);
        }
    }

    sigemptyset(&set);

    if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    srandom((ngx_pid << 16) ^ ngx_time());

    /*
     * disable deleting previous events for the listening sockets because
     * in the worker processes there are no events at all at this point
     */
    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {
        ls[i].previous = NULL;
    }

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_process) {
            if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }

    for (n = 0; n < ngx_last_process; n++) {

        if (ngx_processes[n].pid == -1) {
            continue;
        }

        if (n == ngx_process_slot) {
            continue;
        }

        if (ngx_processes[n].channel[1] == -1) {
            continue;
        }

        if (close(ngx_processes[n].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "close() channel failed");
        }
    }

    if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "close() channel failed");
    }

#if 0
    ngx_last_process = 0;
#endif

    if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
                              ngx_channel_handler)
        == NGX_ERROR)
    {
        /* fatal */
        exit(2);
    }
}
Beispiel #7
0
Datei: daemon.c Projekt: Shmuma/z
int	daemon_start(int allow_root, const char* user)
{
	pid_t   		pid;
	struct passwd		*pwd;
	struct sigaction	phan;

	/* running as root ?*/
	if((0 == allow_root) && (0 == getuid() || 0 == getgid()))
	{
		pwd = getpwnam(user);
		if (NULL == pwd)
		{
			zbx_error("User %s does not exist.",
				user);
			zbx_error("Cannot run as root !");
			exit(FAIL);
		}
		if(setgid(pwd->pw_gid) ==-1)
		{
			zbx_error("Cannot setgid to %s [%s].",
				user,
				strerror(errno));
			exit(FAIL);
		}
#ifdef HAVE_FUNCTION_INITGROUPS
		if(initgroups(user, pwd->pw_gid) == -1) 
		{
			zbx_error("Cannot initgroups to %s [%s].",
				user,
				strerror(errno));
			exit(FAIL);
		}
#endif /* HAVE_FUNCTION_INITGROUPS */
		if(setuid(pwd->pw_uid) == -1)
		{
			zbx_error("Cannot setuid to %s [%s].",
				user,
				strerror(errno));
			exit(FAIL);
		}

#ifdef HAVE_FUNCTION_SETEUID
		if( (setegid(pwd->pw_gid) ==-1) || (seteuid(pwd->pw_uid) == -1) )
		{
			zbx_error("Cannot setegid or seteuid to zabbix [%s].", strerror(errno));
			exit(FAIL);
		}
#endif /* HAVE_FUNCTION_SETEUID */

	}

	if( (pid = zbx_fork()) != 0 )	
	{				
		exit( 0 );		
	}				

	setsid();
	
	signal( SIGHUP, SIG_IGN );

	if( (pid = zbx_fork()) !=0 )	
	{				
		exit( 0 );		
	}				

	/* This is to eliminate warning: ignoring return value of chdir */
	if(-1 == chdir("/"))
	{
		assert(0);
	}
	umask(0002);

	redirect_std(CONFIG_LOG_FILE);

#ifdef HAVE_SYS_RESOURCE_SETPRIORITY

	if(setpriority(PRIO_PROCESS,0,5)!=0)
	{
		zbx_error("Unable to set process priority to 5. Leaving default.");
	}

#endif /* HAVE_SYS_RESOURCE_SETPRIORITY */

/*------------------------------------------------*/

	if( FAIL == create_pid_file(APP_PID_FILE))
	{
		exit(FAIL);
	}

	phan.sa_handler = child_signal_handler;
	sigemptyset(&phan.sa_mask);
	phan.sa_flags = 0;

	sigaction(SIGINT,	&phan, NULL);
	sigaction(SIGQUIT,	&phan, NULL);
	sigaction(SIGTERM,	&phan, NULL);
	sigaction(SIGPIPE,	&phan, NULL);

	zbx_setproctitle("main process");

	return MAIN_ZABBIX_ENTRY();
}
Beispiel #8
0
int
main(int argc, char *argv[])
{
	struct group	*gp;
	struct passwd	*pw;
	char		*endp, *p, *user, *group, *grouplist;
	const char	*shell;
	gid_t		gid, *gidlist;
	uid_t		uid;
	int		ch, gids;
	long		ngroups_max;

	gid = 0;
	uid = 0;
	user = group = grouplist = NULL;
	while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
		switch(ch) {
		case 'u':
			user = optarg;
			if (*user == '\0')
				usage();
			break;
		case 'g':
			group = optarg;
			if (*group == '\0')
				usage();
			break;
		case 'G':
			grouplist = optarg;
			if (*grouplist == '\0')
				usage();
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	if (group != NULL) {
		if (isdigit((unsigned char)*group)) {
			gid = (gid_t)strtoul(group, &endp, 0);
			if (*endp != '\0')
				goto getgroup;
		} else {
 getgroup:
			if ((gp = getgrnam(group)) != NULL)
				gid = gp->gr_gid;
			else
				errx(1, "no such group `%s'", group);
		}
	}

	ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
	if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
		err(1, "malloc");
	for (gids = 0;
	    (p = strsep(&grouplist, ",")) != NULL && gids < ngroups_max; ) {
		if (*p == '\0')
			continue;

		if (isdigit((unsigned char)*p)) {
			gidlist[gids] = (gid_t)strtoul(p, &endp, 0);
			if (*endp != '\0')
				goto getglist;
		} else {
 getglist:
			if ((gp = getgrnam(p)) != NULL)
				gidlist[gids] = gp->gr_gid;
			else
				errx(1, "no such group `%s'", p);
		}
		gids++;
	}
	if (p != NULL && gids == ngroups_max)
		errx(1, "too many supplementary groups provided");

	if (user != NULL) {
		if (isdigit((unsigned char)*user)) {
			uid = (uid_t)strtoul(user, &endp, 0);
			if (*endp != '\0')
				goto getuser;
		} else {
 getuser:
			if ((pw = getpwnam(user)) != NULL)
				uid = pw->pw_uid;
			else
				errx(1, "no such user `%s'", user);
		}
	}

	if (chdir(argv[0]) == -1 || chroot(".") == -1)
		err(1, "%s", argv[0]);

	if (gids && setgroups(gids, gidlist) == -1)
		err(1, "setgroups");
	if (group && setgid(gid) == -1)
		err(1, "setgid");
	if (user && setuid(uid) == -1)
		err(1, "setuid");

	if (argv[1]) {
		execvp(argv[1], &argv[1]);
		err(1, "%s", argv[1]);
	}

	if (!(shell = getenv("SHELL")))
		shell = _PATH_BSHELL;
	execlp(shell, shell, "-i", (char *)NULL);
	err(1, "%s", shell);
	/* NOTREACHED */
}
Beispiel #9
0
static int drop_root(void) {
    struct passwd *pw;
    struct group * gr;
    int r;
    
    
//Edison modify username 20131023
    char dut_user[128];
    memset(dut_user, 0, 128);
    
    strncpy(dut_user, nvram_safe_get("http_username"), 128);

    if (!(pw = getpwnam(dut_user))) {
	avahi_log_error( "Failed to find user '%s'.",dut_user);
        return -1;
    }

    if (!(gr = getgrnam(AVAHI_GROUP))) {
        avahi_log_error( "Failed to find group '"AVAHI_GROUP"'.");
        return -1;
    }

    avahi_log_info("Found user '%s' (UID %lu) and group '"AVAHI_GROUP"' (GID %lu).",dut_user ,(unsigned long) pw->pw_uid, (unsigned long) gr->gr_gid);

    if (initgroups(dut_user, gr->gr_gid) != 0) {
        avahi_log_error("Failed to change group list: %s", strerror(errno));
        return -1;
    }

#if defined(HAVE_SETRESGID)
    r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
#elif defined(HAVE_SETEGID)
    if ((r = setgid(gr->gr_gid)) >= 0)
        r = setegid(gr->gr_gid);
#elif defined(HAVE_SETREGID)
    r = setregid(gr->gr_gid, gr->gr_gid);
#else
#error "No API to drop privileges"
#endif

    if (r < 0) {
        avahi_log_error("Failed to change GID: %s", strerror(errno));
        return -1;
    }

#if defined(HAVE_SETRESUID)
    r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
#elif defined(HAVE_SETEUID)
    if ((r = setuid(pw->pw_uid)) >= 0)
        r = seteuid(pw->pw_uid);
#elif defined(HAVE_SETREUID)
    r = setreuid(pw->pw_uid, pw->pw_uid);
#else
#error "No API to drop privileges"
#endif

    if (r < 0) {
        avahi_log_error("Failed to change UID: %s", strerror(errno));
        return -1;
    }

    set_env("USER", pw->pw_name);
    set_env("LOGNAME", pw->pw_name);
    set_env("HOME", pw->pw_dir);

    avahi_log_info("Successfully dropped root privileges.");

    return 0;
}
Beispiel #10
0
/*{{{  main*/
int main(int argc, char *argv[])
{
  /*{{{  variables*/
  int x, login_y, password_y;
  char loginstr[9], passwordstr[9], ret;
  char ttystr[_POSIX_PATH_MAX];
  char *background = NULL;
  char *fontname = NULL;
  /*}}}  */

  /*{{{  parse arguments*/
  {
    int c;

    while ((c = getopt(argc, argv, "b:f:")) != EOF)
      switch (c) {
      case 'b':
        background = optarg;
        break;
      case 'f':
        fontname = optarg;
        break;
      }
    /*{{{  parse tty*/
    {
      int tty;

      if (optind + 1 > argc) {
        fprintf(stderr, "Usage: %s tty\n", argv[0]);
        exit(1);
      } else {
        strcpy(ttystr, "/dev/");
        strcat(ttystr, argv[optind++]);
      }
      close(0);
      close(1);
      close(2);
      setsid();
      if ((tty = open(ttystr, O_RDWR)) != 0) {
        fprintf(stderr, "%s: Can't open controlling terminal on fd 0.\n", argv[0]);
        exit(1);
      }
      fchmod(tty, 0600);
      fchown(tty, getuid(), getgid());
      open(argv[optind], O_RDWR);
      open(argv[optind], O_RDWR);
    }
    /*}}}  */
  }
  /*}}}  */
  /*{{{  get into grafics mode*/
  signal(SIGTERM, quit);
  signal(SIGHUP, quit);
  set_tty(0);
  if ((screen = bit_open(SCREEN_DEV)) == NULL) {
    reset_tty(0);
    exit(EX_NOPERM);
  }
  bit_grafscreen();
  /*}}}  */
  /*{{{  load font*/
  if (fontname) {
    char fontpath[_POSIX_PATH_MAX];

    if (*fontname == '/' || *fontname == '.')
      strcpy(fontpath, fontname);
    else {
      strcpy(fontpath, ICONDIR);
      strcat(fontpath, "/");
      strcat(fontpath, fontname);
    }

    if ((font = open_font(fontname)) == NULL)
      font = open_font(NULL);
  } else
    font = open_font(NULL);
  /*}}}  */
  /*{{{  draw background*/
  bit_blit(screen, 0, 0, screen->wide, screen->high, BIT_CLR, NULL, 0, 0);
  if (background) {
    BITMAP *bp;
    FILE *fp;
    char backgroundpath[_POSIX_PATH_MAX];

    if (*background == '/' || *background == '.')
      strcpy(backgroundpath, background);
    else {
      strcpy(backgroundpath, ICONDIR);
      strcat(backgroundpath, "/");
      strcat(backgroundpath, background);
    }

    if ((fp = fopen(backgroundpath, "r")) != NULL && (bp = bitmapread(fp)) != NULL) {
      int x, y;

      for (x = 0; x < screen->wide; x += bp->wide)
        bit_blit(
            screen,
            x, 0,
            screen->wide - x < bp->wide ? screen->wide - x : bp->wide,
            bp->high,
            BIT_SRC, bp, 0, 0);

      for (y = 0; y < screen->high; y += bp->high)
        bit_blit(
            screen,
            0, y,
            screen->wide,
            screen->high - y < bp->high ? screen->high - y : bp->high,
            BIT_SRC, screen, 0, 0);
    }
  }
  /*}}}  */
  /*{{{  draw hostname*/
  {
    int bx, bw, by, bh;
    char hostname[_POSIX_PATH_MAX];
    struct hostent *h;

    gethostname(hostname, sizeof(hostname));
    if ((h = gethostbyname(hostname)) != NULL)
      strcpy(hostname, h->h_name);
    bw = font->head.wide * (strlen(hostname) + 2);
    bh = 2 * font->head.high;
    bx = (screen->wide - bw) / 2;
    by = screen->high / 6 - bh / 2;
    cutebox(bx, by, bw, bh);
    printstr(bx + font->head.wide, by + bh - font->head.high / 2, hostname);
  }
  /*}}}  */
  /*{{{  draw login box*/
  {
    int bx, bw, by, bh;

    bx = (screen->wide - font->head.wide * 40) / 2;
    by = (screen->high - font->head.high * 8) / 2;
    bw = font->head.wide * 40;
    bh = font->head.high * 8;
    cutebox(bx, by, bw, bh);
  }
  /*}}}  */
  /*{{{  draw login box contents*/
  x = (screen->wide - font->head.wide * 18) / 2;
  login_y = screen->high / 2 - font->head.wide / 6;
  password_y = screen->high / 2 + font->head.high / 6 + font->head.high;
  printstr(x, password_y, "Password:         "******"Press ESC for terminal login");
  /*}}}  */
  while (1) {
    /*{{{  get login and password or escape*/
    printstr(x, login_y, "Login:            "******"mgr", NULL };
        int i;

        sprintf(env_user, "USER=%s", pw->pw_name);
        sprintf(env_logname, "LOGNAME=%s", pw->pw_name);
        sprintf(env_home, "HOME=%s", pw->pw_dir);
        sprintf(env_shell, "SHELL=%s", pw->pw_shell == NULL || pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell);
        sprintf(env_path, "PATH=%s", PATH);
        sprintf(env_mail, "MAIL=%s/%s", MAILDIR, pw->pw_name);
        if (chdir(pw->pw_dir) != 0)
          chdir("/");
        if (ttyname(0)) {
          chown(ttyname(0), pw->pw_uid, pw->pw_gid);
          chmod(ttyname(0), 0600);
        }
        for (i = 1; i <= _NSIG; i++)
          signal(i, SIG_DFL);
        bit_destroy(screen);
        reset_tty(0);
        initgroups(pw->pw_name, pw->pw_gid);
        setgid(pw->pw_gid);
        setuid(pw->pw_uid);
        sprintf(mgrlogin, "%s/.mgrlogin", pw->pw_dir);
        execve(mgrlogin, login_argv, login_env);
        execve(MGR_BINARY, login_argv, login_env);
        exit(EX_OSFILE);
      }
      /*}}}  */
      else
      /*{{{  incorrect login*/
      {
        printstr((screen->wide - font->head.wide * 16) / 2, login_y + 3 * font->head.high,
            "Login incorrect");
      }
      /*}}}  */
    }
    /*}}}  */
  }
}
Beispiel #11
0
int
main(int argc, char **argv)
{
	int i;
	int rval,ll;
	struct text *kk;

	/* If the user hits start, bail */
	cont_btn_callback(0, CONT_START, (cont_btn_callback_t)arch_exit);

	pvr_init_defaults();
	conio_init(CONIO_TTY_PVR, CONIO_INPUT_LINE);

#if 0
	/* revoke */
	setgid(getgid());
#endif

	init();         /* Initialize everything */
	/* signal(SIGINT,trapdel); */

#if 0
	if (argc > 1)   /* Restore file specified */
	{               /* Restart is label 8305 (Fortran) */
		i = restore(argv[1]);       /* See what we've got */
		switch(i)
		{
		    case 0:     /* The restore worked fine */
			yea=Start();
			k=null;
			unlink(argv[1]);/* Don't re-use the save */
			goto l8;        /* Get where we're going */
		    case 1:             /* Couldn't open it */
			exit(1);        /* So give up */
		    case 2:             /* Oops -- file was altered */
			rspeak(202);    /* You dissolve */
			exit(1);        /* File could be non-adventure */
		}                       /* So don't unlink it. */
	}
#endif

	startup();              /* prepare for a user           */

	for (;;)                        /* main command loop (label 2)  */
	{       if (newloc<9 && newloc!=0 && closng)
		{       rspeak(130);    /* if closing leave only by     */
			newloc=loc;     /*      main office             */
			if (!apanic) clock2=15;
			apanic=TRUE;
		}

		rval=fdwarf();          /* dwarf stuff                  */
		if (rval==99) die(99);

	l2000:  if (loc==0) die(99);    /* label 2000                   */
		kk = &stext[loc];
		if ((abb[loc]%abbnum)==0 || kk->seekadr==0)
			kk = &ltext[loc];
		if (!forced(loc) && dark())
		{       if (wzdark && pct(35))
			{       die(90);
				goto l2000;
			}
			kk = &rtext[16];
		}
		if (toting(bear)) rspeak(141);  /* 2001                 */
		speak(kk);
		k=1;
		if (forced(loc))
			goto l8;
		if (loc==33 && pct(25)&&!closng) rspeak(8);
		if (!dark())
		{       abb[loc]++;
			for (i=atloc[loc]; i!=0; i=linkx[i])     /*2004  */
			{       obj=i;
				if (obj>100) obj -= 100;
				if (obj==steps && toting(nugget)) continue;
				if (prop[obj]<0)
				{       if (closed) continue;
					prop[obj]=0;
					if (obj==rug||obj==chain)
						prop[obj]=1;
					tally--;
					if (tally==tally2 && tally != 0)
						if (limit>35) limit=35;
				}
				ll =  prop[obj];   /* 2006         */
				if (obj==steps && loc==fixed[steps])
					ll = 1;
				pspeak(obj, ll);
			}                                       /* 2008 */
			goto l2012;
	l2009:          k=54;                   /* 2009                 */
	l2010:          spk=k;
	l2011:          rspeak(spk);
		}
	l2012:  verb=0;                         /* 2012                 */
		obj=0;
	l2600:	checkhints();                   /* to 2600-2602         */
		if (closed)
		{       if (prop[oyster]<0 && toting(oyster))
				pspeak(oyster,1);
			for (i=1; i<100; i++)
				if (toting(i)&&prop[i]<0)       /*2604  */
					prop[i] = -1-prop[i];
		}
		wzdark=dark();                  /* 2605                 */
		if (knfloc>0 && knfloc!=loc) knfloc=1;
		getin(&wd1,&wd2);
#if 0
		if (delhit)                     /* user typed a DEL     */
		{       delhit=0;               /* reset counter        */
			strcpy(wd1,"quit");    /* pretend he's quitting*/
			*wd2=0;
		}
#endif
	l2608:  if ((foobar = -foobar)>0) foobar=0;     /* 2608         */
		/* should check here for "magic mode"                   */
		turns++;
		if (demo && turns>=SHORT) done(1);      /* to 13000     */

		if (verb==say && *wd2!=0) verb=0;
		if (verb==say)
			goto l4090;
		if (tally==0 && loc>=15 && loc!=33) clock1--;
		if (clock1==0)
		{       closing();                      /* to 10000     */
			goto l19999;
		}
		if (clock1<0) clock2--;
		if (clock2==0)
		{       caveclose();            /* to 11000             */
			continue;               /* back to 2            */
		}
		if (prop[lamp]==1) limit--;
		if (limit<=30 && here(batter) && prop[batter]==0
			&& here(lamp))
		{       rspeak(188);            /* 12000                */
			prop[batter]=1;
			if (toting(batter)) drop(batter,loc);
			limit=limit+2500;
			lmwarn=FALSE;
			goto l19999;
		}
		if (limit==0)
		{       limit = -1;             /* 12400                */
			prop[lamp]=0;
			rspeak(184);
			goto l19999;
		}
		if (limit<0&&loc<=8)
		{       rspeak(185);            /* 12600                */
			gaveup=TRUE;
			done(2);                /* to 20000             */
		}
		if (limit<=30)
		{       if (lmwarn|| !here(lamp)) goto l19999;  /*12200*/
			lmwarn=TRUE;
			spk=187;
			if (place[batter]==0) spk=183;
			if (prop[batter]==1) spk=189;
			rspeak(spk);
		}
	l19999: k=43;
		if (liqloc(loc)==water) k=70;
		if (!strncmp(wd1,"enter",5) &&
		    (!strncmp(wd2,"strea",5)||!strncmp(wd2,"water",5)))
			goto l2010;
		if (!strncmp(wd1,"enter",5) && *wd2!=0) goto l2800;
		if ((strncmp(wd1,"water",5)&&strncmp(wd1,"oil",3))
		    || (strncmp(wd2,"plant",5)&&strncmp(wd2,"door",4)))
			goto l2610;
		if (at(vocab(wd2,1,0))) strcpy(wd2,"pour");

	l2610:  if (!strncmp(wd1,"west",4))
			if (++iwest==10) rspeak(17);
	l2630:  i=vocab(wd1,-1,0);
		if (i== -1)
		{       spk=60;                 /* 3000         */
			if (pct(20)) spk=61;
			if (pct(20)) spk=13;
			rspeak(spk);
			goto l2600;
		}
		k=i%1000;
		kq=i/1000+1;
		switch(kq)
		{   case 1: goto l8;
		    case 2: goto l5000;
		    case 3: goto l4000;
		    case 4: goto l2010;
		    default:
			bug(22);
		}

	l8:
		switch(march())
		{   case 2: continue;           /* i.e. goto l2         */
		    case 99:
			die(99);
			goto l2000;
		    default: bug(110);
		}

	l2800:  strcpy(wd1,wd2);
		*wd2=0;
		goto l2610;

	l4000:  verb=k;
		spk=actspk[verb];
		if (*wd2!=0 && verb!=say) goto l2800;
		if (verb==say) obj= *wd2;
		if (obj!=0) goto l4090;
		switch(verb)
		{   case 1:                     /* take = 8010          */
			if (atloc[loc]==0||linkx[atloc[loc]]!=0) goto l8000;
			for (i=1; i<=5; i++)
				if (dloc[i]==loc&&dflag>=2) goto l8000;
			obj=atloc[loc];
			goto l9010;
		    case 2: case 3: case 9:     /* 8000 : drop,say,wave */
		    case 10: case 16: case 17:  /* calm,rub,toss        */
		    case 19: case 21: case 28:  /* find,feed,break      */
		    case 29:                    /* wake                 */
		l8000:  printf("%s what?\n",wd1);
			obj=0;
			goto l2600;
		    case 4: case 6:             /* 8040 open,lock       */
			spk=28;
			if (here(clam)) obj=clam;
			if (here(oyster)) obj=oyster;
			if (at(door)) obj=door;
			if (at(grate)) obj=grate;
			if (obj!=0 && here(chain)) goto l8000;
			if (here(chain)) obj=chain;
			if (obj==0) goto l2011;
			goto l9040;
		    case 5: goto l2009;         /* nothing              */
		    case 7: goto l9070;         /* on                   */
		    case 8: goto l9080;         /* off                  */
		    case 11: goto l8000;        /* walk                 */
		    case 12: goto l9120;        /* kill                 */
		    case 13: goto l9130;        /* pour                 */
		    case 14:                    /* eat: 8140            */
			if (!here(food)) goto l8000;
		l8142:  dstroy(food);
			spk=72;
			goto l2011;
		    case 15: goto l9150;        /* drink                */
		    case 18:                    /* quit: 8180           */
			gaveup=yes(22,54,54);
			if (gaveup) done(2);    /* 8185                 */
			goto l2012;
		    case 20:                    /* invent=8200          */
			spk=98;
			for (i=1; i<=100; i++)
			{       if (i!=bear && toting(i))
				{       if (spk==98) rspeak(99);
					blklin=FALSE;
					pspeak(i,-1);
					blklin=TRUE;
					spk=0;
				}
			}
			if (toting(bear)) spk=141;
			goto l2011;
		    case 22: goto l9220;        /* fill                 */
		    case 23: goto l9230;        /* blast                */
		    case 24:                    /* score: 8240          */
			scorng=TRUE;
			printf("If you were to quit now, you would score");
			printf(" %d out of a possible ",score());
			printf("%d.",mxscor);
			scorng=FALSE;
			gaveup=yes(143,54,54);
			if (gaveup) done(2);
			goto l2012;
		    case 25:                    /* foo: 8250            */
			k=vocab(wd1,3,0);
			spk=42;
			if (foobar==1-k) goto l8252;
			if (foobar!=0) spk=151;
			goto l2011;
		l8252:  foobar=k;
			if (k!=4) goto l2009;
			foobar=0;
			if (place[eggs]==plac[eggs]
				||(toting(eggs)&&loc==plac[eggs])) goto l2011;
			if (place[eggs]==0&&place[troll]==0&&prop[troll]==0)
				prop[troll]=1;
			k=2;
			if (here(eggs)) k=1;
			if (loc==plac[eggs]) k=0;
			move(eggs,plac[eggs]);
			pspeak(eggs,k);
			goto l2012;
		    case 26:                    /* brief=8260           */
			spk=156;
			abbnum=10000;
			detail=3;
			goto l2011;
		    case 27:                    /* read=8270            */
			if (here(magzin)) obj=magzin;
			if (here(tablet)) obj=obj*100+tablet;
			if (here(messag)) obj=obj*100+messag;
			if (closed&&toting(oyster)) obj=oyster;
			if (obj>100||obj==0||dark()) goto l8000;
			goto l9270;
		    case 30:                    /* suspend=8300         */
			spk=201;
			if (demo) goto l2011;
			printf("I can suspend your adventure for you so");
			printf(" you can resume later, but\n");
			printf("you will have to wait at least");
			printf(" %d minutes before continuing.",latncy);
			if (!yes(200,54,54)) goto l2012;
			datime(&saved,&savet);
			ciao();                 /* Do we quit? */
			continue;               /* Maybe not */
		    case 31:                    /* hours=8310           */
			printf("Colossal cave is closed 9am-5pm Mon ");
			printf("through Fri except holidays.\n");
			goto l2012;
		    default: bug(23);
		}

	l4090:
		switch(verb)
		{   case 1:                     /* take = 9010          */
	l9010:          switch(trtake())
			{   case 2011: goto l2011;
			    case 9220: goto l9220;
			    case 2009: goto l2009;
			    case 2012: goto l2012;
			    default: bug(102);
			}
	l9020:      case 2:                     /* drop = 9020          */
			switch(trdrop())
			{   case 2011: goto l2011;
			    case 19000: done(3);
			    case 2012: goto l2012;
			    default: bug(105);
			}
		    case 3:
			switch(trsay())
			{   case 2012: goto l2012;
			    case 2630: goto l2630;
			    default: bug(107);
			}
	l9040:      case 4:  case 6:            /* open, close          */
			switch(tropen())
			{   case 2011: goto l2011;
			    case 2010: goto l2010;
			    default: bug(106);
			}
		    case 5: goto l2009;         /* nothing              */
		    case 7:                     /* on   9070            */
	l9070:          if (!here(lamp))  goto l2011;
			spk=184;
			if (limit<0) goto l2011;
			prop[lamp]=1;
			rspeak(39);
			if (wzdark) goto l2000;
			goto l2012;

		    case 8:                     /* off                  */
	l9080:          if (!here(lamp)) goto l2011;
			prop[lamp]=0;
			rspeak(40);
			if (dark()) rspeak(16);
			goto l2012;

		    case 9:                     /* wave                 */
			if ((!toting(obj))&&(obj!=rod||!toting(rod2)))
				spk=29;
			if (obj!=rod||!at(fissur)||!toting(obj)||closng)
				goto l2011;
			prop[fissur]=1-prop[fissur];
			pspeak(fissur,2-prop[fissur]);
			goto l2012;
		    case 10: case 11: case 18:  /* calm, walk, quit     */
		    case 24: case 25: case 26:  /* score, foo, brief    */
		    case 30: case 31:           /* suspend, hours       */
			     goto l2011;
	l9120:      case 12:                    /* kill                 */
			switch(trkill())
			{   case 8000: goto l8000;
			    case 8: goto l8;
			    case 2011: goto l2011;
			    case 2608: goto l2608;
			    case 19000: done(3);
			    default: bug(112);
			}
	l9130:      case 13:                    /* pour                 */
			if (obj==bottle||obj==0) obj=liq();
			if (obj==0) goto l8000;
			if (!toting(obj)) goto l2011;
			spk=78;
			if (obj!=oil&&obj!=water) goto l2011;
			prop[bottle]=1;
			place[obj]=0;
			spk=77;
			if (!(at(plant)||at(door))) goto l2011;
			if (at(door))
			{       prop[door]=0;   /* 9132                 */
				if (obj==oil) prop[door]=1;
				spk=113+prop[door];
				goto l2011;
			}
			spk=112;
			if (obj!=water) goto l2011;
			pspeak(plant,prop[plant]+1);
			prop[plant]=(prop[plant]+2)% 6;
			prop[plant2]=prop[plant]/2;
			k=null;
			goto l8;
		    case 14:                    /* 9140 - eat           */
			if (obj==food) goto l8142;
			if (obj==bird||obj==snake||obj==clam||obj==oyster
			    ||obj==dwarf||obj==dragon||obj==troll
			    ||obj==bear) spk=71;
			goto l2011;
	l9150:      case 15:                    /* 9150 - drink         */
			if (obj==0&&liqloc(loc)!=water&&(liq()!=water
				||!here(bottle))) goto l8000;
			if (obj!=0&&obj!=water) spk=110;
			if (spk==110||liq()!=water||!here(bottle))
				goto l2011;
			prop[bottle]=1;
			place[water]=0;
			spk=74;
			goto l2011;
		    case 16:                    /* 9160: rub            */
			if (obj!=lamp) spk=76;
			goto l2011;
		    case 17:                    /* 9170: throw          */
			switch(trtoss())
			{   case 2011: goto l2011;
			    case 9020: goto l9020;
			    case 9120: goto l9120;
			    case 8: goto l8;
			    case 9210: goto l9210;
			    default: bug(113);
			}
		    case 19: case 20:           /* 9190: find, invent   */
			if (at(obj)||(liq()==obj&&at(bottle))
				||k==liqloc(loc)) spk=94;
			for (i=1; i<=5; i++)
				if (dloc[i]==loc&&dflag>=2&&obj==dwarf)
					spk=94;
			if (closed) spk=138;
			if (toting(obj)) spk=24;
			goto l2011;
	l9210:      case 21:                    /* feed                 */
			switch(trfeed())
			{   case 2011: goto l2011;
			    default: bug(114);
			}
	l9220:      case 22:                    /* fill                 */
			switch(trfill())
			{   case 2011: goto l2011;
			    case 8000: goto l8000;
			    case 9020: goto l9020;
			    default: bug(115);
			}
	l9230:      case 23:                    /* blast                */
			if (prop[rod2]<0||!closed) goto l2011;
			bonus=133;
			if (loc==115) bonus=134;
			if (here(rod2)) bonus=135;
			rspeak(bonus);
			done(2);
	l9270:      case 27:                    /* read                 */
			if (dark()) goto l5190;
			if (obj==magzin) spk=190;
			if (obj==tablet) spk=196;
			if (obj==messag) spk=191;
			if (obj==oyster&&hinted[2]&&toting(oyster)) spk=194;
			if (obj!=oyster||hinted[2]||!toting(oyster)
				||!closed) goto l2011;
			hinted[2]=yes(192,193,54);
			goto l2012;
		    case 28:                    /* break                */
			if (obj==mirror) spk=148;
			if (obj==vase&&prop[vase]==0)
			{       spk=198;
				if (toting(vase)) drop(vase,loc);
				prop[vase]=2;
				fixed[vase]= -1;
				goto l2011;
			}
			if (obj!=mirror||!closed) goto l2011;
			rspeak(197);
			done(3);

		    case 29:                    /* wake                 */
			if (obj!=dwarf||!closed) goto l2011;
			rspeak(199);
			done(3);

		    default: bug(24);
		}

	l5000:
		obj=k;
		if (fixed[k]!=loc && !here(k)) goto l5100;
	l5010:  if (*wd2!=0) goto l2800;
		if (verb!=0) goto l4090;
		printf("What do you want to do with the %s?\n",wd1);
		goto l2600;
	l5100:  if (k!=grate) goto l5110;
		if (loc==1||loc==4||loc==7) k=dprssn;
		if (loc>9&&loc<15) k=entrnc;
		if (k!=grate) goto l8;
	l5110:  if (k!=dwarf) goto l5120;
		for (i=1; i<=5; i++)
			if (dloc[i]==loc&&dflag>=2) goto l5010;
	l5120:  if ((liq()==k&&here(bottle))||k==liqloc(loc)) goto l5010;
		if (obj!=plant||!at(plant2)||prop[plant2]==0) goto l5130;
		obj=plant2;
		goto l5010;
	l5130:  if (obj!=knife||knfloc!=loc) goto l5140;
		knfloc = -1;
		spk=116;
		goto l2011;
	l5140:  if (obj!=rod||!here(rod2)) goto l5190;
		obj=rod2;
		goto l5010;
	l5190:  if ((verb==find||verb==invent)&&*wd2==0) goto l5010;
		printf("I see no %s here\n",wd1);
		goto l2012;
	}
}
Beispiel #12
0
/******************************************************************************
 *                                                                            *
 * Function: daemon_start                                                     *
 *                                                                            *
 * Purpose: init process as daemon                                            *
 *                                                                            *
 * Parameters: allow_root - allow root permission for application             *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: it doesn't allow running under 'root' if allow_root is zero      *
 *                                                                            *
 ******************************************************************************/
int	daemon_start(int allow_root)
{
	pid_t			pid;
	struct passwd		*pwd;
	struct sigaction	phan;
	char			user[7] = "zabbix";

	/* running as root ? */
	if (0 == allow_root && (0 == getuid() || 0 == getgid()))
	{
		pwd = getpwnam(user);
		if (NULL == pwd)
		{
			zbx_error("user %s does not exist", user);
			zbx_error("Cannot run as root!");
			exit(FAIL);
		}

		if (-1 == setgid(pwd->pw_gid))
		{
			zbx_error("cannot setgid to %s: %s", user, zbx_strerror(errno));
			exit(FAIL);
		}

#ifdef HAVE_FUNCTION_INITGROUPS
		if (-1 == initgroups(user, pwd->pw_gid))
		{
			zbx_error("cannot initgroups to %s: %s", user, zbx_strerror(errno));
			exit(FAIL);
		}
#endif

		if (-1 == setuid(pwd->pw_uid))
		{
			zbx_error("cannot setuid to %s: %s", user, zbx_strerror(errno));
			exit(FAIL);
		}

#ifdef HAVE_FUNCTION_SETEUID
		if (-1 == setegid(pwd->pw_gid) || -1 == seteuid(pwd->pw_uid))
		{
			zbx_error("cannot setegid or seteuid to %s: %s", user, zbx_strerror(errno));
			exit(FAIL);
		}
#endif
	}

	if (0 != (pid = zbx_fork()))
		exit(0);

	setsid();

	signal(SIGHUP, SIG_IGN);

	if (0 != (pid = zbx_fork()))
		exit(0);

	/* this is to eliminate warning: ignoring return value of chdir */
	if (-1 == chdir("/"))
		assert(0);

	umask(0002);

	redirect_std(CONFIG_LOG_FILE);

#ifdef HAVE_SYS_RESOURCE_SETPRIORITY
	if (0 != setpriority(PRIO_PROCESS, 0, 5))
		zbx_error("Unable to set process priority to 5. Leaving default.");
#endif

/*------------------------------------------------*/

	if (FAIL == create_pid_file(CONFIG_PID_FILE))
		exit(FAIL);

	parent_pid = (int)getpid();

	phan.sa_sigaction = child_signal_handler;
	sigemptyset(&phan.sa_mask);
	phan.sa_flags = SA_SIGINFO;

	sigaction(SIGINT, &phan, NULL);
	sigaction(SIGQUIT, &phan, NULL);
	sigaction(SIGTERM, &phan, NULL);
	sigaction(SIGPIPE, &phan, NULL);
	sigaction(SIGILL, &phan, NULL);
	sigaction(SIGFPE, &phan, NULL);
	sigaction(SIGSEGV, &phan, NULL);
	sigaction(SIGBUS, &phan, NULL);
	sigaction(SIGALRM, &phan, NULL);
	sigaction(SIGUSR1, &phan, NULL);

	/* Set SIGCHLD now to avoid race conditions when a child process is created before */
	/* sigaction() is called. To avoid problems when scripts exit in zbx_execute() and */
	/* other cases, SIGCHLD is set to SIG_IGN in zbx_child_fork(). */
	phan.sa_sigaction = parent_signal_handler;
	sigaction(SIGCHLD, &phan, NULL);

	zbx_setproctitle("main process");

	return MAIN_ZABBIX_ENTRY();
}
Beispiel #13
0
/* Run an external command returning exit status, and optionally filling
 * provided buffer with STDOUT output up to the size provided.
 *
 * Note: XXX: We are not using the timeout parameter at present. We still need
 *       to implement a reliable timeout mechanism.
*/
static int
_run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
        const size_t so_buf_sz, const int cflag, const int timeout,
        const char *substr_search, int *pid_status,
        const fko_srv_options_t * const opts)
{
    char    so_read_buf[IO_READ_BUF_LEN] = {0};
    pid_t   pid=0;
    FILE   *output;
    int     retval = EXTCMD_SUCCESS_ALL_OUTPUT;
    int     line_ctr = 0, found_str = 0, do_break = 0;

    char   *argv_new[MAX_CMDLINE_ARGS]; /* for validation and/or execvpe() */
    int     argc_new=0;

#if HAVE_EXECVPE
    int     pipe_fd[2];
#endif

#if AFL_FUZZING
    /* Don't allow command execution in AFL fuzzing mode
    */
    return 0;
#endif

    *pid_status = 0;

    /* Even without execvpe() we examine the command for basic validity
     * in term of number of args
    */
    memset(argv_new, 0x0, sizeof(argv_new));

    if(strtoargv(cmd, argv_new, &argc_new) != 1)
    {
        log_msg(LOG_ERR,
                "run_extcmd(): Error converting cmd str to argv via strtoargv()");
        return EXTCMD_ARGV_ERROR;
    }

#if !HAVE_EXECVPE
    /* if we are not using execvpe() then free up argv_new unconditionally
     * since was used only for validation
    */
    free_argv(argv_new, &argc_new);
#endif

#if HAVE_EXECVPE
    if(opts->verbose > 1)
        log_msg(LOG_INFO, "run_extcmd() (with execvpe()): running CMD: %s", cmd);

    if(so_buf != NULL || substr_search != NULL)
    {
        if(pipe(pipe_fd) < 0)
        {
            log_msg(LOG_ERR, "run_extcmd(): pipe() failed: %s", strerror(errno));
            free_argv(argv_new, &argc_new);
            return EXTCMD_PIPE_ERROR;
        }
    }

	//在子进程中创建CMD。
    pid = fork();
    if (pid == 0)
    {
        if(chdir("/") != 0)
            exit(EXTCMD_CHDIR_ERROR);

        if(so_buf != NULL || substr_search != NULL)
        {
            close(pipe_fd[0]);
            dup2(pipe_fd[1], STDOUT_FILENO);
            if(cflag & WANT_STDERR)
                dup2(pipe_fd[1], STDERR_FILENO);
            else
                close(STDERR_FILENO);
        }

        /* Take care of gid/uid settings before running the command.
        */
        if(gid > 0)
            if(setgid(gid) < 0)
                exit(EXTCMD_SETGID_ERROR);

        if(uid > 0)
            if(setuid(uid) < 0)
                exit(EXTCMD_SETUID_ERROR);

        /* don't use env
        */
        execvpe(argv_new[0], argv_new, (char * const *)NULL);
    }
    else if(pid == -1)
    {
        log_msg(LOG_ERR, "run_extcmd(): fork() failed: %s", strerror(errno));
        free_argv(argv_new, &argc_new);
        return EXTCMD_FORK_ERROR;
    }

    /* Only the parent process makes it here
    */
    if(so_buf != NULL || substr_search != NULL)
    {
        close(pipe_fd[1]);
        if ((output = fdopen(pipe_fd[0], "r")) != NULL)
        {
            if(so_buf != NULL)
                memset(so_buf, 0x0, so_buf_sz);

            while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
            {
                line_ctr++;

                copy_or_search(so_read_buf, so_buf, so_buf_sz,
                        substr_search, cflag, &found_str, &do_break);

                if(do_break)
                    break;
            }
            fclose(output);

            /* Make sure we only have complete lines
            */
            if(!(cflag & ALLOW_PARTIAL_LINES))
                truncate_partial_line(so_buf);
        }
        else
        {
            log_msg(LOG_ERR,
                    "run_extcmd(): could not fdopen() pipe output file descriptor.");
            free_argv(argv_new, &argc_new);
            return EXTCMD_OPEN_ERROR;
        }
    }

    free_argv(argv_new, &argc_new);

    waitpid(pid, pid_status, 0);

#else

    if(opts->verbose > 1)
        log_msg(LOG_INFO, "run_extcmd() (without execvpe()): running CMD: %s", cmd);

    if(so_buf == NULL && substr_search == NULL)
    {
        /* Since we do not have to capture output, we will fork here (which we
         * * would have to do anyway if we are running as another user as well).
         * */
        pid = fork();
        if(pid == -1)
        {
            log_msg(LOG_ERR, "run_extcmd: fork failed: %s", strerror(errno));
            return(EXTCMD_FORK_ERROR);
        }
        else if (pid == 0)
        {
            /* We are the child */

            if(chdir("/") != 0)
                exit(EXTCMD_CHDIR_ERROR);

            /* Take care of gid/uid settings before running the command.
            */
            if(gid > 0)
                if(setgid(gid) < 0)
                    exit(EXTCMD_SETGID_ERROR);

            if(uid > 0)
                if(setuid(uid) < 0)
                    exit(EXTCMD_SETUID_ERROR);

            *pid_status = system(cmd);
            exit(*pid_status);
        }
        /* Retval is forced to 0 as we don't care about the exit status of
         * the child (for now)
        */
        retval = EXTCMD_SUCCESS_ALL_OUTPUT;
    }
    else
    {
        /* Looking for output use popen and fill the buffer to its limit.
         */
        output = popen(cmd, "r");
        if(output == NULL)
        {
            log_msg(LOG_ERR, "Got popen error %i: %s", errno, strerror(errno));
            retval = EXTCMD_OPEN_ERROR;
        }
        else
        {
            if(so_buf != NULL)
                memset(so_buf, 0x0, so_buf_sz);

            while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
            {
                line_ctr++;

                copy_or_search(so_read_buf, so_buf, so_buf_sz,
                        substr_search, cflag, &found_str, &do_break);

                if(do_break)
                    break;
            }
            pclose(output);

            /* Make sure we only have complete lines
            */
            if(!(cflag & ALLOW_PARTIAL_LINES))
                truncate_partial_line(so_buf);
        }
    }

#endif

    if(substr_search != NULL)
    {
        /* The semantics of the return value changes in search mode to the line
         * number where the substring match was found, or zero if it wasn't found
        */
        if(found_str)
            retval = line_ctr;
        else
            retval = 0;
    }
    else
    {
        if(WIFEXITED(*pid_status))
        {
            /* Even if the child exited with an error condition, if we make it here
             * then the child exited normally as far as the OS is concerned (i.e. didn't
             * crash or get hit with a signal)
            */
            retval = EXTCMD_SUCCESS_ALL_OUTPUT;
        }
        else
            retval = EXTCMD_EXECUTION_ERROR;
    }

    if(opts->verbose > 1)
        log_msg(LOG_INFO,
            "run_extcmd(): returning %d, pid_status: %d",
            retval, WIFEXITED(*pid_status) ? WEXITSTATUS(*pid_status) : *pid_status);

    return(retval);
}
Beispiel #14
0
int main(int argc, char **argv)
{
	const struct optstruct *opt;
#ifndef	C_WINDOWS
        struct passwd *user = NULL;
#endif
	time_t currtime;
	const char *dbdir, *cfgfile;
	char *pua_cats = NULL, *pt;
	int ret, tcpsock = 0, localsock = 0, i, min_port, max_port;
	unsigned int sigs = 0;
	int lsockets[2], nlsockets = 0;
	unsigned int dboptions = 0;
#ifdef C_LINUX
	struct stat sb;
#endif

#ifdef C_WINDOWS
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
        return 1;
    }
#endif

    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
    	help();
	optfree(opts);
	return 0;
    }

    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	debug_mode = 1;
    }

    /* parse the config file */
    cfgfile = optget(opts, "config-file")->strarg;
    pt = strdup(cfgfile);
    if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
	fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
	free(pt);
	return 1;
    }
    free(pt);

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "DatabaseDirectory")->strarg);
	optfree(opts);
	return 0;
    }

    umask(0);

    /* drop privileges */
#if (!defined(C_OS2)) && (!defined(C_WINDOWS))
    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile);
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }
#endif

    /* initialize logger */
    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logok = optget(opts, "LogClean")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;
    mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg;

    do { /* logger initialized */

    if((opt = optget(opts, "LogFile"))->enabled) {
	char timestr[32];
	logg_file = opt->strarg;
	if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    ret = 1;
	    break;
	}
	time(&currtime);
	if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
	    fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	    ret = 1;
	    break;
	}
    } else
	logg_file = NULL;

    if((ret = cl_init(CL_INIT_DEFAULT))) {
	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ {
	cl_debug();
	logg_verbose = 2;
    }

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	    int fac = LOG_LOCAL6;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    ret = 1;
	    break;
	}

	openlog("clamd", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

#ifdef C_LINUX
    procdev = 0;
    if(stat("/proc", &sb) != -1 && !sb.st_size)
	procdev = sb.st_dev;
#endif

    /* check socket type */

    if(optget(opts, "TCPSocket")->enabled)
	tcpsock = 1;

    if(optget(opts, "LocalSocket")->enabled)
	localsock = 1;

    if(!tcpsock && !localsock) {
	logg("!Please define server type (local and/or TCP).\n");
	ret = 1;
	break;
    }

    logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());

#ifndef C_WINDOWS
    if(user)
	logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
#endif

    if(logg_size)
	logg("#Log file size limited to %d bytes.\n", logg_size);
    else
	logg("#Log file size limit disabled.\n");

    min_port = optget(opts, "StreamMinPort")->numarg;
    max_port = optget(opts, "StreamMaxPort")->numarg;
    if (min_port < 1024 || min_port > max_port || max_port > 65535) {
	logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
	ret = 1;
	break;
    }

    if(!(engine = cl_engine_new())) {
	logg("!Can't initialize antivirus engine\n");
	ret = 1;
	break;
    }

    /* load the database(s) */
    dbdir = optget(opts, "DatabaseDirectory")->strarg;
    logg("#Reading databases from %s\n", dbdir);

    if(optget(opts, "DetectPUA")->enabled) {
	dboptions |= CL_DB_PUA;

	if((opt = optget(opts, "ExcludePUA"))->enabled) {
	    dboptions |= CL_DB_PUA_EXCLUDE;
	    i = 0;
	    logg("#Excluded PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    cl_engine_free(engine);
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if((opt = optget(opts, "IncludePUA"))->enabled) {
	    if(pua_cats) {
		logg("!ExcludePUA and IncludePUA cannot be used at the same time\n");
		free(pua_cats);
		ret = 1;
		break;
	    }
	    dboptions |= CL_DB_PUA_INCLUDE;
	    i = 0;
	    logg("#Included PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if(pua_cats) {
	    if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
		logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
		free(pua_cats);
		ret = 1;
		break;
	    }
	    free(pua_cats);
	}
    } else {
	logg("#Not loading PUA signatures.\n");
    }

    /* set the temporary dir */
    if((opt = optget(opts, "TemporaryDirectory"))->enabled) {
	if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
	    logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
	    ret = 1;
	    break;
	}
    }

    if(optget(opts, "LeaveTemporaryFiles")->enabled)
	cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);

    if(optget(opts, "PhishingSignatures")->enabled)
	dboptions |= CL_DB_PHISHING;
    else
	logg("#Not loading phishing signatures.\n");

    if(optget(opts,"PhishingScanURLs")->enabled)
	dboptions |= CL_DB_PHISHING_URLS;
    else
	logg("#Disabling URL based phishing detection.\n");

    if(optget(opts,"DevACOnly")->enabled) {
	logg("#Only using the A-C matcher.\n");
	cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
    }

    if((opt = optget(opts, "DevACDepth"))->enabled) {
        cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg);
	logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg);
    }

    if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
	logg("!%s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    logg("#Loaded %u signatures.\n", sigs);
    if((ret = cl_engine_compile(engine)) != 0) {
	logg("!Database initialization error: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(tcpsock) {
#ifdef C_WINDOWS
	    WSADATA wsaData;

	if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
	    ret = 1;
	    break;
	}
#endif
	if ((lsockets[nlsockets] = tcpserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    if(localsock) {
	if ((lsockets[nlsockets] = localserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    /* fork into background */
    if(!optget(opts, "Foreground")->enabled) {
#ifdef C_BSD	    
	/* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK);
	}
#endif
	if(daemonize() == -1) {
	    logg("!daemonize() failed\n");
	    ret = 1;
	    break;
	}
#ifdef C_BSD
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK);
	}
#endif
	if(!debug_mode)
	    if(chdir("/") == -1)
		logg("^Can't change current working directory to root\n");

    } else
        foreground = 1;

    ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts);

    } while (0);

    logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");

    for (i = 0; i < nlsockets; i++) {
	closesocket(lsockets[i]);
    }

#ifndef C_OS2
    if(nlsockets && localsock) {
	opt = optget(opts, "LocalSocket");
	if(unlink(opt->strarg) == -1)
	    logg("!Can't unlink the socket file %s\n", opt->strarg);
	else
	    logg("Socket file removed.\n");
    }
#endif

#ifdef C_WINDOWS
    if(tcpsock)
	WSACleanup();

    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	logg_close();
	optfree(opts);
	return 1;
    }
#endif

    logg_close();
    optfree(opts);

    return ret;
}
Beispiel #15
0
static gboolean
start_child(pcmk_child_t * child)
{
    int lpc = 0;
    uid_t uid = 0;
    gid_t gid = 0;
    struct rlimit oflimits;
    gboolean use_valgrind = FALSE;
    gboolean use_callgrind = FALSE;
    const char *devnull = "/dev/null";
    const char *env_valgrind = getenv("PCMK_valgrind_enabled");
    const char *env_callgrind = getenv("PCMK_callgrind_enabled");
    enum cluster_type_e stack = get_cluster_type();

    child->active_before_startup = FALSE;

    if (child->command == NULL) {
        crm_info("Nothing to do for child \"%s\"", child->name);
        return TRUE;
    }

    if (env_callgrind != NULL && crm_is_true(env_callgrind)) {
        use_callgrind = TRUE;
        use_valgrind = TRUE;

    } else if (env_callgrind != NULL && strstr(env_callgrind, child->name)) {
        use_callgrind = TRUE;
        use_valgrind = TRUE;

    } else if (env_valgrind != NULL && crm_is_true(env_valgrind)) {
        use_valgrind = TRUE;

    } else if (env_valgrind != NULL && strstr(env_valgrind, child->name)) {
        use_valgrind = TRUE;
    }

    if (use_valgrind && strlen(VALGRIND_BIN) == 0) {
        crm_warn("Cannot enable valgrind for %s:"
                 " The location of the valgrind binary is unknown", child->name);
        use_valgrind = FALSE;
    }

    if (child->uid) {
        if (crm_user_lookup(child->uid, &uid, &gid) < 0) {
            crm_err("Invalid user (%s) for %s: not found", child->uid, child->name);
            return FALSE;
        }
        crm_info("Using uid=%u and group=%u for process %s", uid, gid, child->name);
    }

    child->pid = fork();
    CRM_ASSERT(child->pid != -1);

    if (child->pid > 0) {
        /* parent */
        mainloop_child_add(child->pid, 0, child->name, child, pcmk_child_exit);

        crm_info("Forked child %d for process %s%s", child->pid, child->name,
                 use_valgrind ? " (valgrind enabled: " VALGRIND_BIN ")" : "");
        update_node_processes(local_nodeid, NULL, get_process_list());
        return TRUE;

    } else {
        /* Start a new session */
        (void)setsid();

        /* Setup the two alternate arg arrarys */
        opts_vgrind[0] = strdup(VALGRIND_BIN);
        if (use_callgrind) {
            opts_vgrind[1] = strdup("--tool=callgrind");
            opts_vgrind[2] = strdup("--callgrind-out-file=" CRM_STATE_DIR "/callgrind.out.%p");
            opts_vgrind[3] = strdup(child->command);
            opts_vgrind[4] = NULL;
        } else {
            opts_vgrind[1] = strdup(child->command);
            opts_vgrind[2] = NULL;
            opts_vgrind[3] = NULL;
            opts_vgrind[4] = NULL;
        }
        opts_default[0] = strdup(child->command);;

        if(gid) {
            if(stack == pcmk_cluster_corosync) {
                /* Drop root privileges completely
                 *
                 * We can do this because we set uidgid.gid.${gid}=1
                 * via CMAP which allows these processes to connect to
                 * corosync
                 */
                if (setgid(gid) < 0) {
                    crm_perror(LOG_ERR, "Could not set group to %d", gid);
                }

                /* Keep the root group (so we can access corosync), but add the haclient group (so we can access ipc) */
            } else if (initgroups(child->uid, gid) < 0) {
                crm_err("Cannot initalize groups for %s: %s (%d)", child->uid, pcmk_strerror(errno), errno);
            }
        }

        if (uid && setuid(uid) < 0) {
            crm_perror(LOG_ERR, "Could not set user to %d (%s)", uid, child->uid);
        }

        /* Close all open file descriptors */
        getrlimit(RLIMIT_NOFILE, &oflimits);
        for (lpc = 0; lpc < oflimits.rlim_cur; lpc++) {
            close(lpc);
        }

        (void)open(devnull, O_RDONLY);  /* Stdin:  fd 0 */
        (void)open(devnull, O_WRONLY);  /* Stdout: fd 1 */
        (void)open(devnull, O_WRONLY);  /* Stderr: fd 2 */

        if (use_valgrind) {
            (void)execvp(VALGRIND_BIN, opts_vgrind);
        } else {
            (void)execvp(child->command, opts_default);
        }
        crm_perror(LOG_ERR, "FATAL: Cannot exec %s", child->command);
        crm_exit(DAEMON_RESPAWN_STOP);
    }
    return TRUE;                /* never reached */
}
int dexopt(const char *apk_path, uid_t uid, int is_public)
{
    struct utimbuf ut;
    struct stat apk_stat, dex_stat;
    char dex_path[PKG_PATH_MAX];
    char dexopt_flags[PROPERTY_VALUE_MAX];
    char *end;
    int res, zip_fd=-1, odex_fd=-1;

        /* Before anything else: is there a .odex file?  If so, we have
         * pre-optimized the apk and there is nothing to do here.
         */
    if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
        return -1;
    }

    /* platform-specific flags affecting optimization and verification */
    property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");

    strcpy(dex_path, apk_path);
    end = strrchr(dex_path, '.');
    if (end != NULL) {
        strcpy(end, ".odex");
        if (stat(dex_path, &dex_stat) == 0) {
            return 0;
        }
    }

    if (create_cache_path(dex_path, apk_path)) {
        return -1;
    }

    memset(&apk_stat, 0, sizeof(apk_stat));
    stat(apk_path, &apk_stat);

    zip_fd = open(apk_path, O_RDONLY, 0);
    if (zip_fd < 0) {
        LOGE("dexopt cannot open '%s' for input\n", apk_path);
        return -1;
    }

    unlink(dex_path);
    odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    if (odex_fd < 0) {
        LOGE("dexopt cannot open '%s' for output\n", dex_path);
        goto fail;
    }
    if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
        LOGE("dexopt cannot chown '%s'\n", dex_path);
        goto fail;
    }
    if (fchmod(odex_fd,
               S_IRUSR|S_IWUSR|S_IRGRP |
               (is_public ? S_IROTH : 0)) < 0) {
        LOGE("dexopt cannot chmod '%s'\n", dex_path);
        goto fail;
    }

    LOGD("DexInv: --- BEGIN '%s' ---\n", apk_path);

    pid_t pid;
    pid = fork();
    if (pid == 0) {
        /* child -- drop privileges before continuing */
        if (setgid(uid) != 0) {
            LOGE("setgid(%d) failed during dexopt\n", uid);
            exit(64);
        }
        if (setuid(uid) != 0) {
            LOGE("setuid(%d) during dexopt\n", uid);
            exit(65);
        }
        if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) {
            LOGE("flock(%s) failed: %s\n", dex_path, strerror(errno));
            exit(66);
        }

        run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags);
        exit(67);   /* only get here on exec failure */
    } else {
        res = wait_dexopt(pid, apk_path);
        if (res != 0) {
            LOGE("dexopt failed on '%s' res = %d\n", dex_path, res);
            goto fail;
        }
    }

    ut.actime = apk_stat.st_atime;
    ut.modtime = apk_stat.st_mtime;
    utime(dex_path, &ut);
    
    close(odex_fd);
    close(zip_fd);
    return 0;

fail:
    if (odex_fd >= 0) {
        close(odex_fd);
        unlink(dex_path);
    }
    if (zip_fd >= 0) {
        close(zip_fd);
    }
    return -1;
}
Beispiel #17
0
static void
run_file(const char *filename, uid_t uid, gid_t gid)
{
/* Run a file by spawning off a process which redirects I/O,
 * spawns a subshell, then waits for it to complete and sends
 * mail to the user.
 */
    pid_t pid;
    int fd_out, fd_in;
    int queue;
    char mailbuf[MAXLOGNAME], fmt[64];
    char *mailname = NULL;
    FILE *stream;
    int send_mail = 0;
    struct stat buf, lbuf;
    off_t size;
    struct passwd *pentry;
    int fflags;
    long nuid;
    long ngid;
#ifdef PAM
    pam_handle_t *pamh = NULL;
    int pam_err;
    struct pam_conv pamc = {
	.conv = openpam_nullconv,
	.appdata_ptr = NULL
    };
#endif

    PRIV_START

    if (chmod(filename, S_IRUSR) != 0)
    {
	perr("cannot change file permissions");
    }

    PRIV_END

    pid = fork();
    if (pid == -1)
	perr("cannot fork");
    
    else if (pid != 0)
	return;

    /* Let's see who we mail to.  Hopefully, we can read it from
     * the command file; if not, send it to the owner, or, failing that,
     * to root.
     */

    pentry = getpwuid(uid);
    if (pentry == NULL)
	perrx("Userid %lu not found - aborting job %s",
		(unsigned long) uid, filename);

#ifdef PAM
    PRIV_START

    pam_err = pam_start(atrun, pentry->pw_name, &pamc, &pamh);
    if (pam_err != PAM_SUCCESS)
	perrx("cannot start PAM: %s", pam_strerror(pamh, pam_err));

    pam_err = pam_acct_mgmt(pamh, PAM_SILENT);
    /* Expired password shouldn't prevent the job from running. */
    if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD)
	perrx("Account %s (userid %lu) unavailable for job %s: %s",
	    pentry->pw_name, (unsigned long)uid,
	    filename, pam_strerror(pamh, pam_err));

    pam_end(pamh, pam_err);

    PRIV_END
#endif /* PAM */

    PRIV_START

    stream=fopen(filename, "r");

    PRIV_END

    if (stream == NULL)
	perr("cannot open input file");

    if ((fd_in = dup(fileno(stream))) <0)
	perr("error duplicating input file descriptor");

    if (fstat(fd_in, &buf) == -1)
	perr("error in fstat of input file descriptor");

    if (lstat(filename, &lbuf) == -1)
	perr("error in fstat of input file");

    if (S_ISLNK(lbuf.st_mode))
	perrx("Symbolic link encountered in job %s - aborting", filename);
 
    if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) ||
        (lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) ||
        (lbuf.st_size!=buf.st_size))
	perrx("Somebody changed files from under us for job %s - aborting",
		filename);
 
    if (buf.st_nlink > 1)
	perrx("Somebody is trying to run a linked script for job %s", filename);
 
    if ((fflags = fcntl(fd_in, F_GETFD)) <0)
	perr("error in fcntl");

    fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);

    snprintf(fmt, sizeof(fmt),
	"#!/bin/sh\n# atrun uid=%%ld gid=%%ld\n# mail %%%ds %%d",
                          MAXLOGNAME - 1);

    if (fscanf(stream, fmt, &nuid, &ngid, mailbuf, &send_mail) != 4)
	perrx("File %s is in wrong format - aborting", filename);

    if (mailbuf[0] == '-')
	perrx("Illegal mail name %s in %s", mailbuf, filename);
 
    mailname = mailbuf;

    if (nuid != uid)
	perrx("Job %s - userid %ld does not match file uid %lu",
		filename, nuid, (unsigned long)uid);

    if (ngid != gid)
	perrx("Job %s - groupid %ld does not match file gid %lu",
		filename, ngid, (unsigned long)gid);

    fclose(stream);

    if (chdir(ATSPOOL_DIR) < 0)
	perr("cannot chdir to %s", ATSPOOL_DIR);
    
    /* Create a file to hold the output of the job we are about to run.
     * Write the mail header.
     */    
    if((fd_out=open(filename,
		O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0)
	perr("cannot create output file");

    write_string(fd_out, "Subject: Output from your job ");
    write_string(fd_out, filename);
    write_string(fd_out, "\n\n");
    fstat(fd_out, &buf);
    size = buf.st_size;

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
 
    pid = fork();
    if (pid < 0)
	perr("error in fork");

    else if (pid == 0)
    {
	char *nul = NULL;
	char **nenvp = &nul;

	/* Set up things for the child; we want standard input from the input file,
	 * and standard output and error sent to our output file.
	 */

	if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0)
	    perr("error in lseek");

	if (dup(fd_in) != STDIN_FILENO)
	    perr("error in I/O redirection");

	if (dup(fd_out) != STDOUT_FILENO)
	    perr("error in I/O redirection");

	if (dup(fd_out) != STDERR_FILENO)
	    perr("error in I/O redirection");

	close(fd_in);
	close(fd_out);
	if (chdir(ATJOB_DIR) < 0)
	    perr("cannot chdir to %s", ATJOB_DIR);

	queue = *filename;

	PRIV_START

        nice(tolower(queue) - 'a');
	
#ifdef LOGIN_CAP
	/*
	 * For simplicity and safety, set all aspects of the user context
	 * except for a selected subset:  Don't set priority, which was
	 * set based on the queue file name according to the tradition.
	 * Don't bother to set environment, including path vars, either
	 * because it will be discarded anyway.  Although the job file
	 * should set umask, preset it here just in case.
	 */
	if (setusercontext(NULL, pentry, uid, LOGIN_SETALL &
		~(LOGIN_SETPRIORITY | LOGIN_SETPATH | LOGIN_SETENV)) != 0)
	    exit(EXIT_FAILURE);	/* setusercontext() logged the error */
#else /* LOGIN_CAP */
	if (initgroups(pentry->pw_name,pentry->pw_gid))
	    perr("cannot init group access list");

	if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0)
	    perr("cannot change group");

	if (setlogin(pentry->pw_name))
	    perr("cannot set login name");

	if (setuid(uid) < 0 || seteuid(uid) < 0)
	    perr("cannot set user id");
#endif /* LOGIN_CAP */

	if (chdir(pentry->pw_dir))
		chdir("/");

	if(execle("/bin/sh","sh",(char *) NULL, nenvp) != 0)
	    perr("exec failed for /bin/sh");

	PRIV_END
    }
Beispiel #18
0
static ngx_int_t
ngx_open_pipe(ngx_cycle_t *cycle, ngx_open_pipe_t *op)
{
    int               fd;
    u_char          **argv;
    ngx_pid_t         pid;
    sigset_t          set;
    ngx_core_conf_t  *ccf;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (pipe(op->pfd) < 0) {
        return NGX_ERROR;
    }

    argv = op->argv->elts;

    if ((pid = fork()) < 0) {
        goto err;
    } else if (pid > 0) {
        op->pid = pid;

        if (op->open_fd->fd != NGX_INVALID_FILE) {
            if (close(op->open_fd->fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              "close \"%s\" failed",
                              op->open_fd->name.data);
            }
        }

        if (op->type == NGX_PIPE_WRITE) {
            op->open_fd->fd = op->pfd[1];
            close(op->pfd[0]);
        } else {
            op->open_fd->fd = op->pfd[0];
            close(op->pfd[1]);
        }
    } else {
        if (op->type == 1) {
            close(op->pfd[1]);
            if (op->pfd[0] != STDIN_FILENO) {
                dup2(op->pfd[0], STDIN_FILENO);
                close(op->pfd[0]);
            }
        } else {
            close(op->pfd[0]);
            if (op->pfd[1] != STDOUT_FILENO) {
                dup2(op->pfd[1], STDOUT_FILENO);
                close(op->pfd[1]);
            }
        }

        if (geteuid() == 0) {
            if (setgid(ccf->group) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              "setgid(%d) failed", ccf->group);
                exit(2);
            }

            if (initgroups(ccf->username, ccf->group) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              "initgroups(%s, %d) failed",
                              ccf->username, ccf->group);
            }

            if (setuid(ccf->user) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              "setuid(%d) failed", ccf->user);
                exit(2);
            }
        }

        /*
         * redirect stderr to /dev/null, because stderr will be connected with
         * fd used by the last pipe when error log is configured using pipe,
         * that will cause it no close
         */

        fd = open("/dev/null", O_WRONLY);
        if (fd == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "open(\"/dev/null\") failed");
            exit(2);
        }

        if (dup2(fd, STDERR_FILENO) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "dup2(STDERR) failed");
            exit(2);
        }

        if (fd > STDERR_FILENO && close(fd) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "close() failed");
            exit(2);
        }

        sigemptyset(&set);

        if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "sigprocmask() failed");
            exit(2);
        }

        execv((const char *) argv[0], (char *const *) op->argv->elts);
        exit(0);
    }

    return NGX_OK;

err:

    close(op->pfd[0]);
    close(op->pfd[1]);

    return NGX_ERROR;
}
Beispiel #19
0
void swWorker_onStart(swServer *serv)
{
    /**
     * Release other worker process
     */
    swWorker *worker;

    if (SwooleWG.id >= serv->worker_num)
    {
        SwooleG.process_type = SW_PROCESS_TASKWORKER;
    }
    else
    {
        SwooleG.process_type = SW_PROCESS_WORKER;
    }

    int is_root = !geteuid();
    struct passwd *passwd = NULL;
    struct group *group = NULL;

    if (is_root)
    {
        //get group info
        if (SwooleG.group)
        {
            group = getgrnam(SwooleG.group);
            if (!group)
            {
                swSysError("get group [%s] info failed.", SwooleG.group);
            }
        }
        //get user info
        if (SwooleG.user)
        {
            passwd = getpwnam(SwooleG.user);
            if (!passwd)
            {
                swSysError("get user [%s] info failed.", SwooleG.user);
            }
        }
        //chroot
        if (SwooleG.chroot)
        {
            if (0 > chroot(SwooleG.chroot))
            {
                swSysError("chroot to [%s] failed.", SwooleG.chroot);
            }
        }
        //set process group
        if (SwooleG.group && group)
        {
            if (setgid(group->gr_gid) < 0)
            {
                swSysError("setgid to [%s] failed.", SwooleG.group);
            }
        }
        //set process user
        if (SwooleG.user && passwd)
        {
            if (setuid(passwd->pw_uid) < 0)
            {
                swSysError("setuid to [%s] failed.", SwooleG.user);
            }
        }
    }

    SwooleWG.worker = swServer_get_worker(serv, SwooleWG.id);

    int i;
    for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++)
    {
        worker = swServer_get_worker(serv, i);
        if (SwooleWG.id == i)
        {
            continue;
        }
        else
        {
            swWorker_free(worker);
        }
        if (swIsWorker())
        {
            swSetNonBlock(worker->pipe_master);
        }
    }

    if (serv->onWorkerStart)
    {
        serv->onWorkerStart(serv, SwooleWG.id);
    }
}
Beispiel #20
0
bool f_posix_setgid(int gid) {
  return setgid(gid);
}
Beispiel #21
0
static void drop_privileges(struct credentials *cred)
{
	if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
	    setgid (cred->gid) || setuid(cred->pass->pw_uid)))
		die("cannot drop privileges");
}
/*
 *  Do chroot, if requested.
 *
 *  Switch UID and GID to what is specified in the config file
 */
static int switch_users(CONF_SECTION *cs)
{
	/*
	 *	Get the current maximum for core files.  Do this
	 *	before anything else so as to ensure it's properly
	 *	initialized.
	 */
	if (fr_set_dumpable_init() < 0) {
		fr_perror("radiusd");
		return 0;
	}

	/*
	 *	Don't do chroot/setuid/setgid if we're in debugging
	 *	as non-root.
	 */
	if (debug_flag && (getuid() != 0)) return 1;

	if (cf_section_parse(cs, NULL, bootstrap_config) < 0) {
		fprintf(stderr, "radiusd: Error: Failed to parse user/group information.\n");
		return 0;
	}


#ifdef HAVE_GRP_H
	/*  Set GID.  */
	if (gid_name) {
		struct group *gr;

		gr = getgrnam(gid_name);
		if (gr == NULL) {
			fprintf(stderr, "%s: Cannot get ID for group %s: %s\n",
				progname, gid_name, fr_syserror(errno));
			return 0;
		}
		server_gid = gr->gr_gid;
	} else {
		server_gid = getgid();
	}
#endif

#ifdef HAVE_PWD_H
	/*  Set UID.  */
	if (uid_name) {
		struct passwd *pw;

		pw = getpwnam(uid_name);
		if (pw == NULL) {
			fprintf(stderr, "%s: Cannot get passwd entry for user %s: %s\n",
				progname, uid_name, fr_syserror(errno));
			return 0;
		}

		if (getuid() == pw->pw_uid) {
			uid_name = NULL;
		} else {

			server_uid = pw->pw_uid;
#ifdef HAVE_INITGROUPS
			if (initgroups(uid_name, server_gid) < 0) {
				fprintf(stderr, "%s: Cannot initialize supplementary group list for user %s: %s\n",
					progname, uid_name, fr_syserror(errno));
				return 0;
			}
#endif
		}
	} else {
		server_uid = getuid();
	}
#endif

	if (chroot_dir) {
		if (chroot(chroot_dir) < 0) {
			fprintf(stderr, "%s: Failed to perform chroot %s: %s",
				progname, chroot_dir, fr_syserror(errno));
			return 0;
		}

		/*
		 *	Note that we leave chdir alone.  It may be
		 *	OUTSIDE of the root.  This allows us to read
		 *	the configuration from "-d ./etc/raddb", with
		 *	the chroot as "./chroot/" for example.  After
		 *	the server has been loaded, it does a "cd
		 *	${logdir}" below, so that core files (if any)
		 *	go to a logging directory.
		 *
		 *	This also allows the configuration of the
		 *	server to be outside of the chroot.  If the
		 *	server is statically linked, then the only
		 *	things needed inside of the chroot are the
		 *	logging directories.
		 */
	}

#ifdef HAVE_GRP_H
	/*  Set GID.  */
	if (gid_name && (setgid(server_gid) < 0)) {
		fprintf(stderr, "%s: Failed setting group to %s: %s",
			progname, gid_name, fr_syserror(errno));
		return 0;
	}
#endif

#ifdef HAVE_SETUID
	/*
	 *	Just before losing root permissions, ensure that the
	 *	log files have the correct owner && group.
	 *
	 *	We have to do this because the log file MAY have been
	 *	specified on the command-line.
	 */
	if (uid_name || gid_name) {
		if ((default_log.dst == L_DST_FILES) &&
		    (default_log.fd < 0)) {
			default_log.fd = open(main_config.log_file,
					      O_WRONLY | O_APPEND | O_CREAT, 0640);
			if (default_log.fd < 0) {
				fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", main_config.log_file, fr_syserror(errno));
				return 0;
			}

			if (chown(main_config.log_file, server_uid, server_gid) < 0) {
				fprintf(stderr, "%s: Cannot change ownership of log file %s: %s\n",
					progname, main_config.log_file, fr_syserror(errno));
				return 0;
			}
		}
	}

	if (uid_name) {
		doing_setuid = true;

		fr_suid_down();
	}
#endif

	/*
	 *	This also clears the dumpable flag if core dumps
	 *	aren't allowed.
	 */
	if (fr_set_dumpable(allow_core_dumps) < 0) {
		ERROR("%s", fr_strerror());
	}

	if (allow_core_dumps) {
		INFO("Core dumps are enabled");
	}

	return 1;
}
Beispiel #23
0
int main(int argc, char **argv) {
	static int verbose = 0, debug = 0, validate = 0;

	static struct option long_options[] = {
		{"help", no_argument, NULL, 'h'},
		{"config", required_argument, NULL, 'c'},
		{"validate", no_argument, NULL, 'C'},
		{"debug", no_argument, NULL, 'd'},
		{"version", no_argument, NULL, 'v'},
		{"verbose", no_argument, NULL, 'V'},
		{"get-socketpath", no_argument, NULL, 'p'},
		{0, 0, 0, 0}
	};

	char *config_path = NULL;

	const char* usage =
		"Usage: sway [options] [command]\n"
		"\n"
		"  -h, --help             Show help message and quit.\n"
		"  -c, --config <config>  Specify a config file.\n"
		"  -C, --validate         Check the validity of the config file, then exit.\n"
		"  -d, --debug            Enables full logging, including debug information.\n"
		"  -v, --version          Show the version number and quit.\n"
		"  -V, --verbose          Enables more verbose logging.\n"
		"      --get-socketpath   Gets the IPC socket path and prints it, then exits.\n"
		"\n";

	int c;
	while (1) {
		int option_index = 0;
		c = getopt_long(argc, argv, "hCdvVpc:", long_options, &option_index);
		if (c == -1) {
			break;
		}
		switch (c) {
		case 'h': // help
			fprintf(stdout, "%s", usage);
			exit(EXIT_SUCCESS);
			break;
		case 'c': // config
			config_path = strdup(optarg);
			break;
		case 'C': // validate
			validate = 1;
			break;
		case 'd': // debug
			debug = 1;
			break;
		case 'v': // version
#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE
			fprintf(stdout, "sway version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH);
#else
			fprintf(stdout, "version not detected\n");
#endif
			exit(EXIT_SUCCESS);
			break;
		case 'V': // verbose
			verbose = 1;
			break;
		case 'p': ; // --get-socketpath
			if (getenv("SWAYSOCK")) {
				fprintf(stdout, "%s\n", getenv("SWAYSOCK"));
				exit(EXIT_SUCCESS);
			} else {
				fprintf(stderr, "sway socket not detected.\n");
				exit(EXIT_FAILURE);
			}
			break;
		default:
			fprintf(stderr, "%s", usage);
			exit(EXIT_FAILURE);
		}
	}

	if (optind < argc) { // Behave as IPC client
		if (getuid() != geteuid() || getgid() != getegid()) {
			if (setgid(getgid()) != 0 || setuid(getuid()) != 0) {
				sway_abort("Unable to drop root");
			}
		}
		char *socket_path = getenv("SWAYSOCK");
		if (!socket_path) {
			sway_abort("Unable to retrieve socket path");
		}
		char *command = join_args(argv + optind, argc - optind);
		run_as_ipc_client(command, socket_path);
		return 0;
	}

	// we need to setup logging before wlc_init in case it fails.
	if (debug) {
		init_log(L_DEBUG);
	} else if (verbose || validate) {
		init_log(L_INFO);
	} else {
		init_log(L_ERROR);
	}
	setenv("WLC_DIM", "0", 0);
	wlc_log_set_handler(wlc_log_handler);
	detect_proprietary();

	/* Changing code earlier than this point requires detailed review */
	/* (That code runs as root on systems without logind, and wlc_init drops to
	 * another user.) */
	if (!wlc_init(&interface, argc, argv)) {
		return 1;
	}
	register_extensions();

	// handle SIGTERM signals
	signal(SIGTERM, sig_handler);

#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE
	sway_log(L_INFO, "Starting sway version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH);
#endif

	init_layout();

	if (validate) {
		bool valid = load_config(config_path);
		return valid ? 0 : 1;
	}

	if (!load_config(config_path)) {
		sway_log(L_ERROR, "Error(s) loading config!");
	}
	if (config_path) {
		free(config_path);
	}

	ipc_init();

	if (!terminate_request) {
		wlc_run();
	}

	ipc_terminate();

	return 0;
}
Beispiel #24
0
static int
__sandbox_task_execute(task_t * ptask)
{
    FUNC_BEGIN("sandbox_task_execute(%p)", ptask);

    assert(ptask);

    /* Run the prisoner program in a separate process group */
    if (setsid() < 0)
    {
        WARNING("failed setting session id");
        return EXIT_FAILURE;
    }

    /* Close fd's not used by the prisoner program */
    int fd;
    for (fd = 0; fd < FILENO_MAX; fd++)
    {
        if ((fd == ptask->ifd) || (fd == ptask->ofd) || (fd == ptask->efd))
        {
            continue;
        }
        close(fd);
    }

    /* Redirect I/O channel */

    if (dup2(ptask->efd, STDERR_FILENO) < 0)
    {
        WARNING("failed redirecting error channel");
        return EXIT_FAILURE;
    }
    DBG("dup2: %d->%d", ptask->efd, STDERR_FILENO);

    if (dup2(ptask->ofd, STDOUT_FILENO) < 0)
    {
        WARNING("failed redirecting output channel(s)");
        return EXIT_FAILURE;
    }
    DBG("dup2: %d->%d", ptask->ofd, STDOUT_FILENO);

    if (dup2(ptask->ifd, STDIN_FILENO) < 0)
    {
        WARNING("failed redirecting input channel(s)");
        return EXIT_FAILURE;
    }
    DBG("dup2: %d->%d", ptask->ifd, STDIN_FILENO);

    /* Apply security restrictions */

    if (strcmp(ptask->jail, "/") != 0)
    {
        if (chdir(ptask->jail) < 0)
        {
            WARNING("failed switching to jail directory");
            return EXIT_FAILURE;
        }
        if (chroot(ptask->jail) < 0)
        {
            WARNING("failed chroot to jail directory");
            return EXIT_FAILURE;
        }
        DBG("jail: \"%s\"", ptask->jail);
    }

    /* Change identity before executing the targeted program */

    if (setgid(ptask->gid) < 0)
    {
        WARNING("changing group identity");
        return EXIT_FAILURE;
    }
    DBG("setgid: %lu", (unsigned long)ptask->gid);

    if (setuid(ptask->uid) < 0)
    {
        WARNING("changing owner identity");
        return EXIT_FAILURE;
    }
    DBG("setuid: %lu", (unsigned long)ptask->uid);

    /* Prepare argument arrray to be passed to execve() */
    char * argv [ARG_MAX] = {NULL};
    int argc = 0;
    while ((argc + 1 < ARG_MAX) && (ptask->comm.args[argc] >= 0))
    {
        argv[argc] = ptask->comm.buff + ptask->comm.args[argc];
        argc++;
    }
    if (strcmp(ptask->jail, "/") != 0)
    {
        argv[0] += strlen(ptask->jail);
    }
    argv[argc] = NULL;

    #ifndef NDEBUG
    argc = 0;
    while (argv[argc] != NULL)
    {
        DBG("argv[%d]: \"%s\"", argc, argv[argc]);
        argc++;
    }
    #endif /* !defined NDEBUG */

    /* Most kinds of resource restrictions are applied through the *setrlimit*
     * system call, with the exceptions of virtual memory limit and the cpu
     * usage limit.
     * Because we might have already changed identity by this time, the hard
     * limits should remain as they were. Thus we must invoke a *getrlimit*
     * ahead of time to load original hard limit value.
     * Also note that, cpu usage limit should be set LAST to reduce overhead. */
    struct rlimit rlimval;

    /* Do NOT produce core dump files at all. */
    if (getrlimit(RLIMIT_CORE, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    rlimval.rlim_cur = 0;
    if (setrlimit(RLIMIT_CORE, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    DBG("RLIMIT_CORE: %ld", rlimval.rlim_cur);

    /* Disk quota */
    if (getrlimit(RLIMIT_FSIZE, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    rlimval.rlim_cur = ptask->quota[S_QUOTA_DISK];
    if (setrlimit(RLIMIT_FSIZE, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    DBG("RLIMIT_FSIZE: %ld", rlimval.rlim_cur);

#ifdef DELETED
    /* Memory quota */
    if (getrlimit(RLIMIT_AS, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    rlimval.rlim_cur = ptask->quota[S_QUOTA_MEMORY];
    if (setrlimit(RLIMIT_AS, &rlimval) < 0)
    {
        return EXIT_FAILURE;
    }
    DBG("RLIMIT_AS: %ld", rlimval.rlim_cur);
#endif /* DELETED */

    /* Time resource limits, these should be set last to reduce overhead. Thus,
     * no debug information is produced on success. */
    struct itimerval timerval;

    /* Wallclock quota */
    timerval.it_interval.tv_sec = 0;
    timerval.it_interval.tv_usec = 0;
    timerval.it_value.tv_sec = ptask->quota[S_QUOTA_WALLCLOCK] / 1000;
    timerval.it_value.tv_usec = (ptask->quota[S_QUOTA_WALLCLOCK] % 1000) * 1000;
    if (setitimer(ITIMER_REAL, &timerval, NULL) < 0)
    {
        WARNING("setting ITIMER_REAL");
        return EXIT_FAILURE;
    }

    /* CPU quota */
    timerval.it_interval.tv_sec = 0;
    timerval.it_interval.tv_usec = 0;
    timerval.it_value.tv_sec = ptask->quota[S_QUOTA_CPU] / 1000;
    timerval.it_value.tv_usec = (ptask->quota[S_QUOTA_CPU] % 1000) * 1000;
    if (setitimer(ITIMER_PROF, &timerval, NULL) < 0)
    {
        WARNING("setting ITIMER_PROF");
        return EXIT_FAILURE;
    }

    /* Enter tracing mode */
    if (!trace_self())
    {
        WARNING("trace_self");
        return EXIT_FAILURE;
    }

    /* Execute the targeted program */
    if (execve(argv[0], argv, NULL) < 0)
    {
        WARNING("execve failed unexpectedly");
        return EXIT_FAILURE;
    }

    /* According to Linux manual, the execve() function will NEVER return on
     * success, thus we should not be able to reach to this line of code! */
    return EXIT_FAILURE;
}
Beispiel #25
0
/*
 * setup() - performs all ONE TIME setup for this test.
 */
void
setup()
{
	char *cwdname = NULL;
	int fd;

	umask(0);

	/* capture signals */
	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	/* Pause if that option was specified */
	TEST_PAUSE;

	ltpuser = getpwnam(nobody_uid);
         if (setgid(ltpuser->pw_uid) == -1) {
                tst_resm(TINFO, "setgid failed to "
                         "to set the gid to %d",
                         ltpuser->pw_uid);
                perror("setgid");
         }
         if (setuid(ltpuser->pw_uid) == -1) {
                tst_resm(TINFO, "setuid failed to "
                         "to set the uid to %d",
                         ltpuser->pw_uid);
                perror("setuid");
         }


	/* make a temporary directory and cd to it */
	tst_tmpdir();

	/*
	 * set up a name that should generate an ENOTDIR error
	 */
	if ((cwdname = getcwd(cwdname, 0)) == NULL) {
		tst_brkm(TBROK, cleanup, "could not get currect directory");
	}

	sprintf(test_name5, "%s/fake.%d", cwdname, getpid());

	if ((fileHandle = creat(test_name5, 0444)) == -1) {
		tst_brkm(TBROK, cleanup, "creat(2) FAILED to create temp file");
	}

	sprintf(test_name3, "%s/fake.%d", test_name5, getpid());

	/* creat() and close a zero length file with executeable permission */
	sprintf(test_name6, "%s/execve03.%d", cwdname, getpid());

	if ((fd = creat(test_name6, 0755)) == -1) {
		tst_brkm(TBROK, cleanup, "creat() failed");
	}
	if (close(fd) == -1) {
		tst_brkm(TBROK, cleanup, "close() failed");
	}

	bad_addr = mmap(0, 1, PROT_NONE,
			MAP_PRIVATE_EXCEPT_UCLINUX|MAP_ANONYMOUS, 0, 0);
	if (bad_addr == MAP_FAILED) {
		tst_brkm(TBROK, cleanup, "mmap failed");
	}
	TC[3].tname = bad_addr;
}
Beispiel #26
0
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
		LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
		LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
		LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
	pid_t pid;
	int flags;
	int numArgs;
	LPSTR* pArgs = NULL;
	char** envp = NULL;
	char* filename = NULL;
	HANDLE thread;
	HANDLE process;
	WINPR_ACCESS_TOKEN* token;
	LPTCH lpszEnvironmentBlock;
	BOOL ret = FALSE;
	sigset_t oldSigMask;
	sigset_t newSigMask;
	BOOL restoreSigMask = FALSE;

	pid = 0;
	numArgs = 0;
	lpszEnvironmentBlock = NULL;

	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);
	if (!pArgs)
		return FALSE;

	flags = 0;

	token = (WINPR_ACCESS_TOKEN*) hToken;

	if (lpEnvironment)
	{
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
	}
	else
	{
		lpszEnvironmentBlock = GetEnvironmentStrings();
		if (!lpszEnvironmentBlock)
			goto finish;
		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
	}
	if (!envp)
		goto finish;

	filename = FindApplicationPath(pArgs[0]);
	if (NULL == filename)
		goto finish;

	/* block all signals so that the child can safely reset the caller's handlers */
	sigfillset(&newSigMask);
	restoreSigMask = !pthread_sigmask(SIG_SETMASK, &newSigMask, &oldSigMask);

	/* fork and exec */

	pid = fork();

	if (pid < 0)
	{
		/* fork failure */
		goto finish;
	}

	if (pid == 0)
	{
		/* child process */
#ifndef __sun
		int maxfd;
#endif
		int fd;
		int sig;
		sigset_t set;
		struct sigaction act;

		/* set default signal handlers */
		memset(&act, 0, sizeof(act));
		act.sa_handler = SIG_DFL;
		act.sa_flags = 0;
		sigemptyset(&act.sa_mask);
		for (sig = 1; sig < NSIG; sig++)
			sigaction(sig, &act, NULL);
		/* unblock all signals */
		sigfillset(&set);
		pthread_sigmask(SIG_UNBLOCK, &set, NULL);

		if (lpStartupInfo)
		{
			int handle_fd;

			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdOutput);
			if (handle_fd != -1)
				dup2(handle_fd, STDOUT_FILENO);

			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdError);
			if (handle_fd != -1)
				dup2(handle_fd, STDERR_FILENO);

			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdInput);
			if (handle_fd != -1)
				dup2(handle_fd, STDIN_FILENO);
		}


#ifdef __sun
		closefrom(3);
#else
#ifdef F_MAXFD // on some BSD derivates
		maxfd = fcntl(0, F_MAXFD);
#else
		maxfd = sysconf(_SC_OPEN_MAX);
#endif
		for(fd=3; fd<maxfd; fd++)
			close(fd);
#endif // __sun

		if (token)
		{
			if (token->GroupId)
			{
				int rc = setgid((gid_t) token->GroupId);
				if (rc < 0)
				{
				}
				else
				{
					initgroups(token->Username, (gid_t) token->GroupId);
				}
			}

			if (token->UserId)
				setuid((uid_t) token->UserId);

		}

		/* TODO: add better cwd handling and error checking */
		if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
			chdir(lpCurrentDirectory);

		if (execve(filename, pArgs, envp) < 0)
		{
			/* execve failed - end the process */
			_exit(1);
		}
	}
	else
	{
		/* parent process */
	}

	process = CreateProcessHandle(pid);

	if (!process)
	{
		goto finish;
	}

	thread = CreateNoneHandle();

	if (!thread)
	{
		ProcessHandleCloseHandle(process);
		goto finish;
	}

	lpProcessInformation->hProcess = process;
	lpProcessInformation->hThread = thread;
	lpProcessInformation->dwProcessId = (DWORD) pid;
	lpProcessInformation->dwThreadId = (DWORD) pid;

	ret = TRUE;

finish:

	/* restore caller's original signal mask */
	if (restoreSigMask)
		pthread_sigmask(SIG_SETMASK, &oldSigMask, NULL);


	free(filename);

	if (pArgs)
	{
		HeapFree(GetProcessHeap(), 0, pArgs);
	}

	if (lpszEnvironmentBlock)
		FreeEnvironmentStrings(lpszEnvironmentBlock);

	if (envp)
	{
		int i = 0;

		while (envp[i])
		{
			free(envp[i]);
			i++;
		}

		free(envp);
	}

	return ret;
}
Beispiel #27
0
int
main(int argc, char **argv)
{
	struct protox *tp = NULL;  /* for printing cblocks & stats */
	int ch;
	int n;

	af = AF_UNSPEC;

	while ((ch = getopt(argc, argv, "Aabc:df:gI:iLlM:mN:nPp:rSsBtuWw:z")) != -1)
		switch(ch) {
		case 'A':
			Aflag = 1;
			break;
		case 'a':
			aflag = 1;
			break;
		case 'b':
			bflag = 1;
			break;
		case 'c':
			kread(0, 0, 0);
			kread(nl[N_NCPUS].n_value, (char *)&n, sizeof(n));
			cpuflag = strtol(optarg, NULL, 0);
			if (cpuflag < 0 || cpuflag >= n)
			    errx(1, "cpu %d does not exist", cpuflag);
			break;
		case 'd':
			dflag = 1;
			break;
		case 'f':
			if (strcmp(optarg, "ipx") == 0)
				af = AF_IPX;
			else if (strcmp(optarg, "inet") == 0)
				af = AF_INET;
#ifdef INET6
			else if (strcmp(optarg, "inet6") == 0)
				af = AF_INET6;
#endif /*INET6*/
#ifdef INET6
			else if (strcmp(optarg, "pfkey") == 0)
				af = PF_KEY;
#endif /*INET6*/
			else if (strcmp(optarg, "unix") == 0)
				af = AF_UNIX;
			else if (strcmp(optarg, "ng") == 0
			    || strcmp(optarg, "netgraph") == 0)
				af = AF_NETGRAPH;
#ifdef ISO
			else if (strcmp(optarg, "iso") == 0)
				af = AF_ISO;
#endif
			else if (strcmp(optarg, "link") == 0)
				af = AF_LINK;
			else if (strcmp(optarg, "mpls") == 0)
				af = AF_MPLS;
			else {
				errx(1, "%s: unknown address family", optarg);
			}
			break;
		case 'g':
			gflag = 1;
			break;
		case 'I': {
			char *cp;

			iflag = 1;
			for (cp = interface = optarg; isalpha(*cp); cp++)
				continue;
			unit = atoi(cp);
			break;
		}
		case 'i':
			iflag = 1;
			break;
		case 'L':
			Lflag = 1;
			break;
		case 'M':
			memf = optarg;
			break;
		case 'm':
			mflag = 1;
			break;
		case 'N':
			nlistf = optarg;
			break;
		case 'n':
			numeric_addr = numeric_port = 1;
			break;
		case 'P':
			Pflag = 1;
			break;
		case 'p':
			if ((tp = name2protox(optarg)) == NULL) {
				errx(1, 
				     "%s: unknown or uninstrumented protocol",
				     optarg);
			}
			pflag = 1;
			break;
		case 'r':
			rflag = 1;
			break;
		case 's':
			++sflag;
			break;
		case 'S':
			numeric_addr = 1;
			break;
		case 'B':
			Bflag = 1;
			break;
		case 't':
			tflag = 1;
			break;
		case 'u':
			af = AF_UNIX;
			break;
		case 'W':
		case 'l':
			Wflag = 1;
			break;
		case 'w':
			interval = atoi(optarg);
			iflag = 1;
			break;
		case 'z':
			zflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argv += optind;
	argc -= optind;

#define	BACKWARD_COMPATIBILITY
#ifdef	BACKWARD_COMPATIBILITY
	if (*argv) {
		if (isdigit(**argv)) {
			interval = atoi(*argv);
			if (interval <= 0)
				usage();
			++argv;
			iflag = 1;
		}
		if (*argv) {
			nlistf = *argv;
			if (*++argv)
				memf = *argv;
		}
	}
#endif

	/*
	 * Discard setgid privileges if not the running kernel so that bad
	 * guys can't print interesting stuff from kernel memory.
	 */
	if (nlistf != NULL || memf != NULL)
		setgid(getgid());

	if (mflag) {
		if (memf != NULL) {
			if (kread(0, 0, 0) == 0)
				mbpr(nl[N_MBSTAT].n_value,
				    nl[N_MBTYPES].n_value,
				    nl[N_NMBCLUSTERS].n_value,
				    nl[N_NMBUFS].n_value,
				    nl[N_NCPUS].n_value);
		} else {
			mbpr(0, 0, 0, 0, 0);
		}
		exit(0);
	}
#if 0
	/*
	 * Keep file descriptors open to avoid overhead
	 * of open/close on each call to get* routines.
	 */
	sethostent(1);
	setnetent(1);
#else
	/*
	 * This does not make sense any more with DNS being default over
	 * the files.  Doing a setXXXXent(1) causes a tcp connection to be
	 * used for the queries, which is slower.
	 */
#endif
	if (iflag && !sflag) {
		kread(0, 0, 0);
		intpr(interval, nl[N_IFNET].n_value, NULL);
		exit(0);
	}
	if (rflag) {
		kread(0, 0, 0);
		if (sflag)
			rt_stats();
		else
			routepr(nl[N_RTREE].n_value);
		exit(0);
	}
	if (gflag) {
		kread(0, 0, 0);
		if (sflag) {
			if (af == AF_INET || af == AF_UNSPEC)
				mrt_stats(nl[N_MRTSTAT].n_value);
#ifdef INET6
			if (af == AF_INET6 || af == AF_UNSPEC)
				mrt6_stats(nl[N_MRT6STAT].n_value);
#endif
		} else {
			if (af == AF_INET || af == AF_UNSPEC)
				mroutepr(nl[N_MFCTABLE].n_value,
					 nl[N_VIFTABLE].n_value);
#ifdef INET6
			if (af == AF_INET6 || af == AF_UNSPEC)
				mroute6pr(nl[N_MF6CTABLE].n_value,
					  nl[N_MIF6TABLE].n_value);
#endif
		}
		exit(0);
	}

	kread(0, 0, 0);
	if (tp) {
		printproto(tp, tp->pr_name);
		exit(0);
	}
	if (af == AF_INET || af == AF_UNSPEC)
		for (tp = protox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#ifdef INET6
	if (af == AF_INET6 || af == AF_UNSPEC)
		for (tp = ip6protox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif /*INET6*/
#ifdef IPSEC
	if (af == PF_KEY || af == AF_UNSPEC)
		for (tp = pfkeyprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif /*IPSEC*/
	if (af == AF_IPX || af == AF_UNSPEC) {
		kread(0, 0, 0);
		for (tp = ipxprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
	}
	if (af == AF_NETGRAPH || af == AF_UNSPEC)
		for (tp = netgraphprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#ifdef ISO
	if (af == AF_ISO || af == AF_UNSPEC)
		for (tp = isoprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif
	if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag)
		unixpr();
	exit(0);
}
Beispiel #28
0
int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {

	int i;
	char *colon = NULL;
	int counter;
	char **uenvs;
	char *uef;
	char **vassal_argv;
	pid_t pid;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe)) {
		uwsgi_error("socketpair()");
		return -1;
	}

	event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);

	if (n_ui->use_config) {
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe_config)) {
			uwsgi_error("socketpair()");
			return -1;
		}
	}

	if (n_ui->zerg) {
		uwsgi.emperor_broodlord_num++;
	}

	// TODO pre-start hook

	// a new uWSGI instance will start 
	pid = fork();
	if (pid < 0) {
		uwsgi_error("fork()")
	}
	else if (pid > 0) {
		n_ui->pid = pid;
		// close the right side of the pipe
		close(n_ui->pipe[1]);
		// close the "on demand" socket
		if (n_ui->on_demand_fd > -1) {
			close(n_ui->on_demand_fd);
			n_ui->on_demand_fd = -1;
		}
		if (n_ui->use_config) {
			close(n_ui->pipe_config[1]);
		}

		if (n_ui->use_config) {
			struct uwsgi_header uh;
			uh.modifier1 = 115;
                	uh.pktsize = n_ui->config_len;
                	uh.modifier2 = 0;
                	if (write(n_ui->pipe_config[0], &uh, 4) != 4) {
                        	uwsgi_error("[uwsgi-emperor] write() header config");
                	}
                	else {
                        	if (write(n_ui->pipe_config[0], n_ui->config, n_ui->config_len) != (long) n_ui->config_len) {
                                	uwsgi_error("[uwsgi-emperor] write() config");
                        	}
                	}

		}
		return 0;
	}
	else {

		if (uwsgi.emperor_tyrant) {
			uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) n_ui->uid, (int) n_ui->gid, n_ui->name);
			if (setgid(n_ui->gid)) {
				uwsgi_error("setgid()");
				exit(1);
			}
			if (setgroups(0, NULL)) {
				uwsgi_error("setgroups()");
				exit(1);
			}

			if (setuid(n_ui->uid)) {
				uwsgi_error("setuid()");
				exit(1);
			}

		}

		unsetenv("UWSGI_RELOADS");
		unsetenv("NOTIFY_SOCKET");

		uef = uwsgi_num2str(n_ui->pipe[1]);
		if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
			uwsgi_error("setenv()");
			exit(1);
		}
		free(uef);

		// add UWSGI_BROODLORD_NUM
		if (n_ui->zerg) {
			uef = uwsgi_num2str(uwsgi.emperor_broodlord_num);
			if (setenv("UWSGI_BROODLORD_NUM", uef, 1)) {
                        	uwsgi_error("setenv()");
                        	exit(1);
                	}
                	free(uef);
		}

		if (n_ui->use_config) {
			uef = uwsgi_num2str(n_ui->pipe_config[1]);
			if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
				uwsgi_error("setenv()");
				exit(1);
			}
			free(uef);
		}

		uenvs = environ;
		while (*uenvs) {
			if (!strncmp(*uenvs, "UWSGI_VASSAL_", 13)) {
				char *ne = uwsgi_concat2("UWSGI_", *uenvs + 13);
				char *oe = uwsgi_concat2n(*uenvs, strchr(*uenvs, '=') - *uenvs, "", 0);
				if (unsetenv(oe)) {
					uwsgi_error("unsetenv()");
					free(oe);
					break;
				}
				free(oe);
#ifdef UWSGI_DEBUG
				uwsgi_log("putenv %s\n", ne);
#endif

				if (putenv(ne)) {
					uwsgi_error("putenv()");
				}
				// do not free ne as putenv will add it to the environ
				uenvs = environ;
				continue;
			}
			uenvs++;
		}

		// close the left side of the pipe
		close(n_ui->pipe[0]);

		if (n_ui->use_config) {
			close(n_ui->pipe_config[0]);
		}

		counter = 4;
		struct uwsgi_string_list *uct = uwsgi.vassals_templates;
		while (uct) {
			counter += 2;
			uct = uct->next;
		}

		vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
		// set args
		vassal_argv[0] = uwsgi.binary_path;

		if (uwsgi.emperor_broodlord) {
			colon = strchr(n_ui->name, ':');
			if (colon) {
				colon[0] = 0;
			}
		}
		// initialize to a default value
		vassal_argv[1] = "--inherit";

		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".xml"))
			vassal_argv[1] = "--xml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".ini"))
			vassal_argv[1] = "--ini";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".yml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".yaml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 3), ".js"))
			vassal_argv[1] = "--json";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".json"))
			vassal_argv[1] = "--json";

		if (colon) {
			colon[0] = ':';
		}


		vassal_argv[2] = n_ui->name;
		if (uwsgi.emperor_magic_exec) {
			if (!access(n_ui->name, R_OK | X_OK)) {
				vassal_argv[2] = uwsgi_concat2("exec://", n_ui->name);
			}

		}

		if (n_ui->use_config) {
			vassal_argv[2] = uwsgi_concat2("emperor://", n_ui->name);
		}

		counter = 3;
		uct = uwsgi.vassals_templates;
		while (uct) {
			vassal_argv[counter] = "--inherit";
			vassal_argv[counter + 1] = uct->value;
			counter += 2;
			uct = uct->next;
		}
		vassal_argv[counter] = NULL;

		// disable stdin OR map it to the "on demand" socket
		if (n_ui->on_demand_fd > -1) {
			if (n_ui->on_demand_fd != 0) {
				if (dup2(n_ui->on_demand_fd, 0) < 0) {
                                        uwsgi_error("dup2()");
                                        exit(1);
                                }
                                close(n_ui->on_demand_fd);
			}
		}
		else {
			int stdin_fd = open("/dev/null", O_RDONLY);
			if (stdin_fd < 0) {
				uwsgi_error_open("/dev/null");
				exit(1);
			}
			if (stdin_fd != 0) {
				if (dup2(stdin_fd, 0) < 0) {
					uwsgi_error("dup2()");
					exit(1);
				}
				close(stdin_fd);
			}
		}

		// close all of the unneded fd
		for (i = 3; i < (int) uwsgi.max_fd; i++) {
			if (n_ui->use_config) {
				if (i == n_ui->pipe_config[1])
					continue;
			}
			if (i != n_ui->pipe[1]) {
				close(i);
			}
		}

		if (uwsgi.vassals_start_hook) {
			uwsgi_log("[emperor] running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
			if (uwsgi.emperor_absolute_dir) {
				if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
					uwsgi_error("setenv()");
				}
			}
			int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
			uwsgi_log("[emperor] %s start-hook returned %d\n", n_ui->name, start_hook_ret);
		}

		// start !!!
		if (execvp(vassal_argv[0], vassal_argv)) {
			uwsgi_error("execvp()");
		}
		uwsgi_log("[emperor] is the uwsgi binary in your system PATH ?\n");
		// never here
		exit(UWSGI_EXILE_CODE);
	}

	return -1;
}
Beispiel #29
0
/*
 *	mail [ -ehpPqrtw ] [-x debuglevel] [ -f file ] [ -F user(s) ]
 *	mail -T file persons
 *	mail [ -tw ] [ -m messagetype ] persons
 *	rmail [ -tw ] persons
 */
int
main(int argc, char **argv)
{
    register int i;
    char *cptr, *p;
    static char pn[] = "main";
    extern char **environ;
    int env_var_idx, next_slot_idx;
    int tmpfd = -1;

    (void)&argc;
    (void)&argv;
    setlocale(LC_CTYPE, "");
    mb_cur_max = MB_CUR_MAX;
    /* fix here for bug #1086130 - security hole	*/
    /* skip over the LD_* env variable		*/
    env_var_idx = 0;
    next_slot_idx = 0;
    while (environ[env_var_idx] != NULL) {
        environ[next_slot_idx] = environ[env_var_idx];
        if (strncmp(environ[env_var_idx], "LD_", 3)) {
            next_slot_idx++;
        }
        env_var_idx++;
    }
    environ[next_slot_idx] = NULL;

    line = smalloc(linesize = LSIZE);
    *line = '\0';

#ifdef SIGCONT
    {
        struct sigaction nsig;
        nsig.sa_handler = SIG_DFL;
        sigemptyset(&nsig.sa_mask);
        nsig.sa_flags = SA_RESTART;
        sigaction(SIGCONT, &nsig, (struct sigaction *)0);
    }
#endif

    /*
     *	Strip off path name of this command for use in messages
     */
    if ((program = strrchr(argv[0], '/')) != NULL) {
        program++;
    } else {
        program = argv[0];
    }

    /* Close all file descriptors except stdin, stdout & stderr */
    for (i = 3; close(i) == 0; i++);

    /*
     *	Get group id for mail, exit if none exists
     */
    if ((grpptr = getgrnam("mail")) == NULL) {
        errmsg(E_GROUP, "");
        exit(1);
    } else {
        mailgrp = grpptr->gr_gid;
    }

    /*
     *	Save the *id for later use.
     */
    my_uid = getuid();
    my_gid = getgid();
    my_euid = geteuid();
    my_egid = getegid();

    /*
     *	What command (rmail or mail)?
     */
    if (strcmp(program, "rmail") == SAME) {
        ismail = FALSE;
    }

    /*
     *	Parse the command line and adjust argc and argv
     *	to compensate for any options
     */
    i = parse(argc, argv);
    argv += (i - 1);
    argc -= (i - 1);

    /* block a potential security hole */
    if (flgT && (my_euid != 0)) {
        setgid(my_gid);
        Tout(pn, "Setgid unset\n");
    }

    if (debug == 0) {
        /* If not set as an invocation option, check for system-wide */
        /* global flag */
        char *xp = xgetenv("DEBUG");
        if (xp != (char *)NULL) {
            debug = atoi(xp);
            if (debug < 0) {
                /* Keep trace file even if successful */
                keepdbgfile = -1;
                debug = -debug;
            }
        }
    }
    if (debug > 0) {
        strcpy(dbgfname, "/tmp/MLDBGXXXXXX");
        if ((tmpfd = mkstemp(dbgfname)) == -1) {
            fprintf(stderr, "%s: can't open debugging file '%s'\n",
                    program, dbgfname);
            exit(13);
        }
        if ((dbgfp = fdopen(tmpfd, "w")) == (FILE *)NULL) {
            fprintf(stderr, "%s: can't open debugging file '%s'\n",
                    program, dbgfname);
            close(tmpfd);
            exit(13);
        }
        setbuf(dbgfp, NULL);
        fprintf(dbgfp, "main(): debugging level == %d\n", debug);
        fprintf(dbgfp, "main(): trace file ='%s': kept %s\n", dbgfname,
                ((keepdbgfile < 0) ?
                 "on success or failure." : "only on failure."));
    }

    if (!ismail && (goerr > 0 || !i)) {
        Dout(pn, 11, "!ismail, goerr=%d, i=%d\n", goerr, i);
        if (goerr > 0) {
            errmsg(E_SYNTAX, "Usage: rmail [-wt] person(s)");
        }
        if (!i) {
            errmsg(E_SYNTAX, "At least one user must be specified");
        }
        Dout(pn, 11, "exiting!\n");
        done(0);
    }

    umsave = umask(7);
    uname(&utsn);
    if ((p = xgetenv("CLUSTER")) != (char *)NULL) {
        /*
         * We are not who we appear...
         */
        thissys = p;
    } else {
        thissys = utsn.nodename;
    }
    Dout(pn, 11, "thissys = '%s', uname = '%s'\n", thissys, utsn.nodename);

    failsafe = xgetenv("FAILSAFE");
    if (failsafe)
        Dout(pn, 11, "failsafe processing enabled to %s\n", failsafe);

    /*
     *	Use environment variables
     */
    home = getenv("HOME");
    if (!home || !*home) {
        home = ".";
    }

    pwd = getpwuid(my_uid);
    if (pwd)
        cpy(&my_name, &my_namesize, pwd->pw_name);
    else
        cpy(&my_name, &my_namesize, "");

    /* If root, use LOGNAME if set */
    if (my_uid == 0) {
        /* If root, use LOGNAME if set */
        if (((cptr = getenv("LOGNAME")) != NULL) &&
                (strlen(cptr) != 0)) {
            cpy(&my_name, &my_namesize, cptr);
        }
    }
    Dout(pn, 11, "my_name = '%s'\n", my_name);

    /*
     *	Catch signals for cleanup
     */
    if (setjmp(sjbuf)) {
        done(0);
    }

    setsig(SIGINT, delete);
    setsig(SIGQUIT, delete);
    setsig(SIGTRAP, delete);
#ifdef	SIGIOT
    setsig(SIGIOT, delete);
#endif
#ifdef	SIGEMT
    setsig(SIGEMT, delete);
#endif
    setsig(SIGBUS, delete);
    setsig(SIGSEGV, delete);
    setsig(SIGPIPE, delete);
    setsig(SIGALRM, delete);

    setsig(SIGHUP, sig_done);
    setsig(SIGTERM, sig_done);

    cksaved(my_name);

    /*
     *	Rmail is always invoked to send mail
     */
    Dout(pn, 11, "ismail=%d, argc=%d\n", ismail, argc);
    if (ismail && (argc == 1)) {
        sending = FALSE;
        printmail();

    } else {
        sending = TRUE;
        sendmail(argc, argv);
    }
    done(0);
    /*NOTREACHED*/
    return 0;
}
Beispiel #30
0
void
closecal(FILE *fp)
{
	uid_t uid;
	struct stat sbuf;
	int nread, pdes[2], status;
	char buf[1024];

	if (!doall)
		return;

	rewind(fp);
	if (fstat(fileno(fp), &sbuf) || !sbuf.st_size)
		goto done;
	if (pipe(pdes) < 0)
		goto done;
	switch (fork()) {
	case -1:			/* error */
		(void)close(pdes[0]);
		(void)close(pdes[1]);
		goto done;
	case 0:
		/* child -- set stdin to pipe output */
		if (pdes[0] != STDIN_FILENO) {
			(void)dup2(pdes[0], STDIN_FILENO);
			(void)close(pdes[0]);
		}
		(void)close(pdes[1]);
		uid = geteuid();
		if (setuid(getuid()) < 0) {
			warnx("setuid failed");
			_exit(1);
		}
		if (setgid(getegid()) < 0) {
			warnx("setgid failed");
			_exit(1);
		}
		if (setuid(uid) < 0) {
			warnx("setuid failed");
			_exit(1);
		}
		execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F",
		    "\"Reminder Service\"", (char *)NULL);
		warn(_PATH_SENDMAIL);
		_exit(1);
	}
	/* parent -- write to pipe input */
	(void)close(pdes[0]);

	write(pdes[1], "From: \"Reminder Service\" <", 26);
	write(pdes[1], pw->pw_name, strlen(pw->pw_name));
	write(pdes[1], ">\nTo: <", 7);
	write(pdes[1], pw->pw_name, strlen(pw->pw_name));
	write(pdes[1], ">\nSubject: ", 11);
	write(pdes[1], dayname, strlen(dayname));
	write(pdes[1], "'s Calendar\nPrecedence: bulk\n\n", 30);

	while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0)
		(void)write(pdes[1], buf, nread);
	(void)close(pdes[1]);
done:	(void)fclose(fp);
	(void)unlink(path);
	while (wait(&status) >= 0);
}