/* * Copyright (c) 2003, 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * */ #include "sm/generic.h" SM_RCSID("@(#)$Id: runas.c,v 1.3 2005/04/10 23:57:02 ca Exp $") #include "sm/stdio.h" #include "sm/types.h" #include "sm/error.h" #include "sm/pwd.h" #include "sm/string.h" #include "sm/sysexits.h" static void usage(char *prg) { fprintf(stderr, "Usage: %s user command [args]\n", prg); fprintf(stderr, "%s can only be executed by root and must not be set-user-ID\n", prg); exit(EX_USAGE); /* NOTREACHED */ } /* ** RUNAS -- Wrapper to run some program as a specific user. */ int main(int argc, char *argv[], char *envp[]) { uid_t realuid, effuid, newuid; gid_t newgid; char *prg, *cmd, *user; struct passwd *pw; prg = argv[0]; if (argc < 3) usage(prg); realuid = getuid(); if (realuid != 0) usage(prg); effuid = geteuid(); if (effuid != realuid) usage(prg); user = argv[1]; cmd = argv[2]; argv += 2; argc -= 2; pw = getpwnam(user); if (pw == NULL) { fprintf(stderr, "%s: user '%s' not found\n", prg, user); return EX_UNAVAILABLE; } newuid = pw->pw_uid; newgid = pw->pw_gid; if (setgid(newgid) < 0) { fprintf(stderr, "%s: setgid(%ld) failed: %s\n", prg, (long) newgid, strerror(errno)); return errno; } if (setuid(newuid) < 0) { fprintf(stderr, "%s: setuid(%ld) failed: %s\n", prg, (long) newuid, strerror(errno)); return errno; } if (execve(cmd, argv, envp) < 0) { fprintf(stderr, "%s: cannot exec(%s): %s\n", prg, cmd, strerror(errno)); exit(EX_UNAVAILABLE); } /* NOTREACHED */ exit(EX_OSERR); }