1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/*++
/* NAME
/* chrootuid 1
/* SUMMARY
/* run command in restricted environment
/* SYNOPSIS
/* \fBchrootuid\fR \fInewroot newuser command\fR...
/* DESCRIPTION
/* The \fBchrootuid\fR command sets up a restricted environment for
/* executing \fIcommand\fR. Access to the file system is restricted to
/* the \fInewroot\fR subtree; privileges are restricted to those of
/* the \fInewuser\fR account (which must be a known account in the
/* unrestricted environment).
/* The initial working directory is changed to \fInewroot\fR.
/*
/* \fBchrootuid\fR combines chroot(8) and su(1) into one program, so
/* that there is no need to have commands such as /usr/bin/su
/* in the restricted environment.
/*
/* Only the superuser can use the \fBchrootuid\fR command.
/* DIAGNOSTICS
/* The exit status is 1 when \fBchrootuid\fR has a problem, otherwise
/* the exit status is the exit status of \fIcommand\fR.
/* SEE ALSO
/* chroot(8), su(1)
/* DIAGNOSTICS
/* Problems are reported to the syslog daemon.
/* AUTHOR(S)
/* Wietse Venema
/* Eindhoven University of Technology
/* Department of Mathematics and Computer Science
/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
/*
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/* CREATION DATE
/* Tue Oct 13 11:37:29 MET 1992
/* LAST MODIFICATION
/* Wed Jul 25 11:25:08 EDT 2001
/* VERSION/RELEASE
/* 1.3
/*--*/
#ifndef lint
static char sccsid[] = "@(#) chrootuid.c 1.3 2001/07/25 11:25:08";
#endif
/* System libraries. */
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
int main(argc, argv)
int argc;
char **argv;
{
struct passwd *pwd;
/*
* Open a channel to the syslog daemon. Older versions of openlog()
* require only two arguments.
*/
#ifdef LOG_DAEMON
(void) openlog(argv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON);
#else
(void) openlog(argv[0], LOG_PID);
#endif
/*
* Require proper amount of arguments. In all cases of error, exit with
* zero status because we have already reported the problem via syslogd.
* No need to make inetd complain, too.
*/
if (argc < 4) {
syslog(LOG_ERR, "usage: %s path user command", argv[0]);
return (0);
}
/* Must step into the new subtree. */
if (chdir(argv[1])) {
syslog(LOG_ERR, "chdir(%s): %m", argv[1]);
return (0);
}
/* The user must be known in the *unrestricted* universe... */
if ((pwd = getpwnam(argv[2])) == 0) {
syslog(LOG_ERR, "%s: user unknown", argv[2]);
return (0);
}
/* initgroups() accesses the group file in the unrestricted universe... */
if (initgroups(pwd->pw_name, pwd->pw_gid) < 0) {
syslog(LOG_ERR, "initgroups: %m");
return (0);
}
endgrent();
/* Do the chroot() before giving away root privileges. */
if (chroot(argv[1])) {
syslog(LOG_ERR, "chroot(%s): %m", argv[1]);
return (0);
}
/* Switch group id then user id. */
if (setgid(pwd->pw_gid)) {
syslog(LOG_ERR, "setgid(%d): %m", pwd->pw_gid);
return (0);
}
if (setuid(pwd->pw_uid)) {
syslog(LOG_ERR, "setuid(%d): %m", pwd->pw_uid);
return (0);
}
/* In case we still have the /etc/passwd file still open. */
endpwent();
/* Run the command and hope for the best. */
(void) execv(argv[3], argv + 3);
syslog(LOG_ERR, "%s: %m", argv[3]);
return (0);
}
|