home *** CD-ROM | disk | FTP | other *** search
- From: rosen@tristar.samsung.com (MFHorn)
- Newsgroups: alt.sources
- Subject: detach (THE su enhancer)
- Message-ID: <ROSEN.91Apr26165520@tristar.samsung.com>
- Date: 26 Apr 91 20:55:20 GMT
-
- #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);
- }
- }
-