detach (THE su enhancer)
MFHorn
rosen at tristar.samsung.com
Sat Apr 27 06:55:20 AEST 1991
#ifdef notdef
Why mine is better:
- You can 'detach' as any user, by uid or username (including uid's that
don't exist in the password file)
- If specifying a uid (not a username), you pick group id (including gid's
that don't exist in the group file)
- If specifying a username, it will set all groups before detach'ing
- Compile-time option to disallow detach'ing as uid 0 (allow root is default)
(cc -DNOROOT)
- Compile-time option to use syslog for all detach'es (no syslog is default)
(cc -DSYSLOG)
- Default program is /bin/csh
- Putting the text of the article before the source in a "#ifdef notdef"
is a great idea I just came up with
This may not work on some SysV machines (it uses setgroups, getgrent,
etc. and syslog (optional)). I haven't compiled it in at least two
years...
--
Andy Rosen | rosen at samsung.com | "I got this guitar
Samsung Software America | ...!uunet!samsung!rosen | and I learned how
One Corporate Drive | (508) 685-7200 | to make it talk"
Andover, MA 01810 | | -Thunder Road
#endif
/*------CUT HERE----------CUT HERE----------CUT HERE----------CUT HERE------*/
/*
* Copyright (c) 1988, Andrew Rosen.
* All rights reserved.
*
* This software is supplied free of charge. This software, or any part
* of it, may not be redistributed or otherwise made available to, or
* used by, any other person without the inclusion of this copyright
* notice. This software may not be used to make a profit in any way.
*
* This software is provided with absolutely no warranty, to the extent
* permitted by applicable state law. In no event, unless required by
* applicable law, will the author(s) of this this software be liable for
* any damages caused by this software.
*/
/*
* detach
*
* Description:
* Execute a command line with an arbitrary user and group id
*
* Usage:
* detach -u username [ prog [ options ] ] or
* detach uid gid [ prog [ options ] ]
*
* History:
* 03/10/88 - AJR - Creation
* 03/26/88 - AJR - Do setgroups() before execing
* Added syslog()
*/
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <syslog.h>
#include <sys/param.h>
#define DEF_PROG "/bin/csh" /* Program to execute if none specified */
#define DEF_OPT "csh"
main(argc, argv)
int argc;
char **argv;
{
struct passwd *pwd;
struct group *gr;
int uid, gid; /* New uid and gid */
int gidset[NGROUPS]; /* New gidset */
char *prog, **opts; /* Program and options to exec */
char name[20]; /* Name we're going to run as */
int i;
int j = 1;
/* Check usage */
if (argc < 3) {
printf("Usage: %s -u username [ prog [ options ] ] or\n", argv[0]);
printf(" %s uid gid [ prog [ options ] ]\n", argv[0]);
exit(-1);
}
if (strcmp(argv[1], "-u") == 0) { /* Specified a username */
pwd = getpwnam(argv[2]);
if (pwd == NULL) {
printf("%s: No such user\n", argv[2]);
exit(-1);
}
uid = pwd->pw_uid; /* Set uid and gid from password file */
gid = pwd->pw_gid;
while (gr = getgrent()) /* Set new user's gidset */
for (i = 0; gr->gr_mem[i]; i++)
/* for (i = 0; strcmp(gr->gr_mem[i], NULL) != 0; i++) */
if ((strcmp(gr->gr_mem[i], argv[2]) == 0) && (gr->gr_gid != gid))
gidset[j++] = gr->gr_gid;
}
else { /* Specified uid and gid */
uid = atoi(argv[1]);
gid = atoi(argv[2]);
j = 1; /* Make gidset empty */
}
/* Don't allow detaching priviledgedly (it's a word now) */
#ifndef NOROOT
if (uid == 0) {
fprintf(stderr, "%s: uid 0 not allowed, use su instead\n", argv[0]);
exit(-1);
}
#endif
#ifdef SYSLOG
pwd = getpwuid(uid);
if (pwd != NULL)
strcpy(name, pwd->pw_name);
else
strcpy(name, "unknown user");
pwd = getpwuid(getuid()); /* Who's running the program? */
#endif
/* Initialize the new gidset */
gidset[0] = gid;
for (i = j; i < NGROUPS; gidset[i++] = NOGROUP);
if (setgroups(NGROUPS, gidset)) {
perror("setgroups");
exit(-1);
}
setugid(uid, gid);
#ifdef SYSLOG
openlog("detach", LOG_CONS, LOG_AUTH); /* Get syslog ready */
#endif
if (argc > 3) { /* Program (and maybe options) was specified */
prog = argv[3];
opts = &argv[3];
#ifdef SYSLOG
syslog(LOG_NOTICE, "%s [%s] execing %s as %s",
pwd->pw_name, getlogin(), prog, name);
closelog();
#endif
execvp(prog, opts, 0);
perror(prog);
exit(-1);
}
/* No program specified, use default */
#ifdef SYSLOG
syslog(LOG_NOTICE, "%s [%s] execing %s as %s",
pwd->pw_name, getlogin(), DEF_PROG, name);
closelog();
#endif
execl(DEF_PROG, DEF_OPT, 0);
perror(DEF_PROG);
exit(-1);
}
/*
* Set the new user and group ids, both real and effective
*/
setugid(uid, gid)
int uid;
int gid;
{
if (setgid(gid)) {
perror("setgid");
exit(-1);
}
if (setuid(uid)) {
perror("setuid");
exit(-1);
}
}
More information about the Alt.sources
mailing list