I'd like to run some unit tests in a barebone chroot jail on Solaris. There's no su or sudo, and a copy of su (with libpam.so.1) just returns exit code 1 without any output, with or without parameters. Is there some easy way to run Bash scripts as a non-root user on such a system? Maybe setuid or a wrapper script?

  • make sure you set the right permissions on su (must be identical to what they are on your main system). setuid scripts is a bad idea (and doesn't work on a lot of systems anyway, not sure about Solaris)
    – Mat
    Apr 19 '11 at 11:05

If I understand correctly, you just need to su from root to some other user. Try copying an su binary (it won't need to be setuid root), but I don't know if that will work on Solaris. Or compile a small C program that drops privileges and executes a command.

Here's a small “down-only” su. Minimally tested. Should compile as is under Solaris and *BSD; you need to -D_BDS_SOURCE and #include <grp.h> under Linux, and other platforms may require commenting out the call to the common but non-standard setgroups. Run as e.g. sugexec UID GID bash /path/to/script (you must pass numerical user and group IDs, to avoid depending on any form of user database that may not be available in the chroot).

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

void die(char *argv0, char *obj, char *msg) {
    if (msg == NULL) msg = strerror(errno);
    fprintf(stderr, "%s: %s: %s\n", argv0, obj, msg);
int main(int argc, char *argv[]) {
    uid_t uid;
    gid_t gid;
    char *endp;
    /* Command line parsing */
    if (argc <= 3) {
        fprintf(stderr, "Usage: %s UID GID COMMAND [ARG...]\n",
                argv[0]==NULL ? "sugexec" : argv[0]);
    uid = strtoul(argv[1], &endp, 0);
    if (*endp) die(argv[0], argv[1], "Bad uid");
    gid = strtoul(argv[2], &endp, 0);
    if (*endp) die(argv[0], argv[2], "Bad gid");
    /* Drop to specified user and group */
    if (setgid(gid)) die(argv[0], "setgid", NULL);
    if (setgroups(0, NULL)) die(argv[0], "setgroups", NULL);
    if (setuid(uid)) die(argv[0], "setuid", NULL);
    /* Execute the command */
    execvp(argv[3], argv + 3);
    die(argv[0], argv[3], NULL);
  • Accepting since there doesn't seem to be any canonical suggestions.
    – l0b0
    May 5 '11 at 7:38

Check out schroot which can chroot into a folder as user. Here the man page for it: http://manpages.ubuntu.com/manpages/hardy/man1/schroot.1.html

  • isn't that a Linux-specific tool?
    – Mat
    Apr 19 '11 at 14:24
  • It seems like the project is developed by Debian but it is present in many Linux distributions. Also a search on google led me to this changelog for schroot back from 2009 which contains code for checking SunOS and Solaris. So I presume it can be compiled on Solaris ... just give it a try. mail-archive.com/debian-release@lists.debian.org/msg30798.html Apr 21 '11 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.