Created
September 23, 2009 22:48
-
-
Save fictorial/192360 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This is a simple program to run Node.js as the | |
* specified user and in a chroot. | |
* | |
* BUILD: | |
* gcc -o chrooted-node chrooted-node.c | |
* | |
* USE: | |
* sudo chrooted-node <as-user> <chroot-dir> <file.js> | |
* | |
* Brian Hammond, Fictorial | |
*/ | |
#include <stdio.h> | |
#include <pwd.h> | |
#include <errno.h> | |
#include <unistd.h> | |
#define NODE_BINARY_PATH "/usr/local/bin/node" | |
int main(int argc, char **argv) | |
{ | |
struct passwd *userent; | |
if (geteuid() != 0) | |
{ | |
fprintf(stderr, "must be run as root!\n"); | |
return 1; | |
} | |
if (argc != 4) | |
{ | |
fprintf(stderr, "USAGE: %s <user> <dir> <file.js>\n", argv[0]); | |
return 1; | |
} | |
userent = getpwnam(argv[1]); | |
if (!userent) | |
{ | |
perror("getpwnam"); | |
return 1; | |
} | |
/* | |
* Preload dynamically loaded objects | |
* | |
* Consider operations that require access to full-system resources and | |
* perform them before closing the jail door. These steps are often not | |
* entirely obvious at first and require some trial and error, but | |
* we've found several that qualify. Many systems load nameservice | |
* resolver clients dynamically at runtime, and they are not included | |
* in the shared objects bound to the executables. We have found that | |
* simply calling gethostbyname one time before the jail door is closed | |
* will load all the appropriate libraries required, so that later | |
* nameservice requests are handled properly: | |
* | |
* See http://unixwiz.net/techtips/chroot-practices.html | |
*/ | |
(void) gethostbyname("localhost"); | |
if (chdir(argv[2])) | |
{ | |
perror("chdir"); | |
return 1; | |
} | |
if (chroot(argv[2])) | |
{ | |
perror("chroot"); | |
return 1; | |
} | |
if (setuid(userent->pw_uid)) | |
{ | |
perror("setuid"); | |
return 1; | |
} | |
execl(NODE_BINARY_PATH, "node", argv[3], NULL); | |
perror("execl"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment