Se bem entendi, você só precisa su
da raiz para algum outro usuário. Tente copiar um binário su
(ele não precisará ser root setuid), mas não sei se isso funcionará no Solaris. Ou compile um pequeno programa em C que descarta privilégios e executa um comando.
Aqui está um pequeno su "somente para baixo". Minimamente testado. Deve compilar como está no Solaris e no * BSD; você precisa de -D_BDS_SOURCE
e #include <grp.h>
no Linux, e outras plataformas podem precisar comentar a chamada para osetgroups
comum, mas não padrão. Executar como por exemplo sugexec UID GID bash /path/to/script
(você deve passar IDs numéricos de usuário e grupo, para evitar depender de qualquer forma de banco de dados do usuário que não esteja disponível no 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);
}