/*
* 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);
}
syntax highlighted by Code2HTML, v. 0.9.1