📄 sflprocu.imp
字号:
int SEAE_error = errcode; \
write (pipe_handle [1], &(SEAE_error), sizeof (SEAE_error)); \
exit (EXIT_FAILURE); \
}
/* Sort out privileged issues immediately, to minimise the amount of
* time we have more privilege than the program eventually run will
* have.
*/
/* Force empty strings to be NULL strings, to simplify logic */
if (! procinfo-> username || ! *(procinfo-> username))
new_username = NULL;
else
new_username = procinfo-> username;
if (! procinfo-> groupname || ! *(procinfo-> groupname))
new_groupname = NULL;
else
new_groupname = procinfo-> groupname;
ASSERT (new_username == procinfo-> username || ! *(procinfo-> username));
ASSERT (new_groupname == procinfo-> groupname || ! *(procinfo-> groupname));
if (new_username)
{
struct passwd
*pwdbuf; /* User information from passwd */
pwdbuf = getpwnam (new_username);
if (pwdbuf)
{
new_uid = pwdbuf-> pw_uid;
dosetuid = TRUE;
}
else
SEND_ERROR_AND_EXIT (errno)
}
if (new_groupname)
{
struct group
*grpbuf; /* Group information */
grpbuf = getgrnam (new_groupname);
if (grpbuf)
{
new_gid = grpbuf-> gr_gid;
dosetgid = TRUE;
}
else
SEND_ERROR_AND_EXIT (errno)
}
ASSERT ((new_username && dosetuid) ||
(new_username == NULL && ! dosetuid));
ASSERT ((new_groupname && dosetgid) ||
(new_groupname == NULL && ! dosetgid));
/* HP/UX and BeOS don't provide seteuid() functions */
# if (!defined (__UTYPE_HPUX) && !defined (__UTYPE_BEOS))
/* If we are not to preserve root privileges, and won't otherwise be
* setting the uid, then check to see if we can get root privileges now
* (eg, we have them "saved"). If we do, force a setuid/setgid to
* happen by setting the appropriate flags.
*/
if (!(procinfo-> preserveroot)
&& !(dosetuid && dosetgid))
{
if (seteuid (0) == 0)
{
/* CAREFUL: We're root now; the seteuid worked. */
/* Arrange for setuid/setgid to happen to current real UID/GID. */
dosetuid = TRUE;
new_uid = getuid ();
dosetgid = TRUE;
new_gid = getgid ();
}
}
/* We first set the effective user to be root, to ensure that we can
* carry out the requests. If that fails, we give up immediately.
* This means that the setuid() and setgid() calls will give up all
* other privilege, which is deisred at this point. To make use of
* the saved uid/saved gid ability of some setuid()/setgid() calls,
* use them prior to call create_process(). This is not recommended.
* And chroot() will work only if the euid can be made root (0).
*/
if (procinfo-> rootdir != NULL
|| dosetgid || dosetuid)
{
if (seteuid (0) != 0)
SEND_ERROR_AND_EXIT (errno);
/* CAUTION: We are now root. Careful. */
/* Change root directory, if required */
if (procinfo-> rootdir)
if (chroot (procinfo-> rootdir) != 0)
SEND_ERROR_AND_EXIT (errno);
/* Change uid and gid if required. Since we are root at this point
* these functions should give away all our other gids and our
* original uid.
*/
if (dosetgid)
{
if (setgid (new_gid) != 0)
SEND_ERROR_AND_EXIT (errno);
ASSERT (getgid () == new_gid);
}
if (dosetuid)
{
if (setuid (new_uid) != 0)
SEND_ERROR_AND_EXIT (errno);
ASSERT (getuid () == new_uid);
}
}
/* SANITY CHECK
* -----------------------------------------------------------------
* Unless we are preserving root, or explicitly set our uid to root,
* we should no longer be root, and an attempt to set our euid to root
* should fail. If this turns out not to be the case, we give up
* immediately.
* NOTE: Returning EPERM at this point is probably undesireable, but
* it is not clear what would be better to return.
*/
if (!(procinfo-> preserveroot)
&& !(dosetuid && new_uid == 0))
{
if (getuid () == 0 || geteuid () == 0)
SEND_ERROR_AND_EXIT(EPERM);
if (seteuid (0) == 0) /* Should fail */
SEND_ERROR_AND_EXIT(EPERM);
ASSERT (geteuid () != 0 && getuid () != 0);
}
# endif
/* Now we are not root, unless the user really wanted us to be root. */
# include "sflprocx.imp" /* Get implementation core */
if (procinfo-> error)
SEND_ERROR_AND_EXIT (procinfo-> error);
/* If requested, make this into a daemon process */
if (procinfo-> createdaemon)
{
/* XXX: Maybe we should have a lockfilename as well? */
if (process_server (procinfo-> workdir, NULL, 0, NULL, NULL) == -1)
SEND_ERROR_AND_EXIT (errno);
}
else
/* If requested, change to working directory */
if (procinfo-> workdir)
if (chdir (procinfo-> workdir) == -1)
SEND_ERROR_AND_EXIT (errno);
/* Mark extra file handles to close when we exec() */
if (procinfo-> no_handles < FILEHANDLE_MAX)
{
int fh;
for (fh = procinfo-> no_handles; fh < FILEHANDLE_MAX; fh++)
fcntl (fh, F_SETFD, FD_CLOEXEC); /* Ignore errors */
}
/* Tell the system to close the pipe when we've done the exec() */
fcntl (pipe_handle [0], F_SETFD, FD_CLOEXEC);
fcntl (pipe_handle [1], F_SETFD, FD_CLOEXEC);
/* Execute the program - normally this call does not return, as it
* replaces the current process image by the new one. If we ever do
* return, it is because there was an error.
*/
argv = arglist_to_table (arglist);
if (! argv)
SEND_ERROR_AND_EXIT (ENOMEM);
#if defined (DEBUG)
#if DEBUG > 1
{
char **ptr = argv;
fprintf(stderr, "About to run: (%s) ", full_filename);
while (*ptr != NULL)
fprintf(stderr, "[%s] ", *ptr++);
fprintf(stderr, "\n");
errno = 0;
}
#endif
#endif
execve (full_filename, argv, envv);
/* If we're still here, then exec*() failed for some reason. Tell our
* parent about this.
*/
SEND_ERROR_AND_EXIT (errno);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -