rosen@tristar.samsung.com (MFHorn) (04/27/91)
#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@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); } }