6

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?

l0b0
  • 51,350
  • 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

2 Answers2

4

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);
    exit(127);
}
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]);
        exit(127);
    }
    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);
}
0

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

Patkos Csaba
  • 2,530
  • 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. http://www.mail-archive.com/debian-release@lists.debian.org/msg30798.html – Patkos Csaba Apr 21 '11 at 12:32