home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3244 < prev    next >
Encoding:
Internet Message Format  |  1991-04-27  |  5.0 KB

  1. From: rosen@tristar.samsung.com (MFHorn)
  2. Newsgroups: alt.sources
  3. Subject: detach (THE su enhancer)
  4. Message-ID: <ROSEN.91Apr26165520@tristar.samsung.com>
  5. Date: 26 Apr 91 20:55:20 GMT
  6.  
  7. #ifdef notdef
  8.  
  9. Why mine is better:
  10.  
  11. - You can 'detach' as any user, by uid or username (including uid's that
  12.   don't exist in the password file)
  13. - If specifying a uid (not a username), you pick group id (including gid's
  14.   that don't exist in the group file)
  15. - If specifying a username, it will set all groups before detach'ing
  16. - Compile-time option to disallow detach'ing as uid 0 (allow root is default)
  17.   (cc -DNOROOT)
  18. - Compile-time option to use syslog for all detach'es (no syslog is default)
  19.   (cc -DSYSLOG)
  20. - Default program is /bin/csh
  21. - Putting the text of the article before the source in a "#ifdef notdef"
  22.   is a great idea I just came up with
  23.  
  24. This may not work on some SysV machines (it uses setgroups, getgrent,
  25. etc. and syslog (optional)).  I haven't compiled it in at least two
  26. years...
  27.  
  28. --
  29. Andy Rosen                | rosen@samsung.com       | "I got this guitar
  30. Samsung Software America  | ...!uunet!samsung!rosen |  and I learned how
  31. One Corporate Drive       | (508) 685-7200          |  to make it talk"
  32. Andover, MA 01810         |                         |    -Thunder Road
  33.  
  34. #endif
  35. /*------CUT HERE----------CUT HERE----------CUT HERE----------CUT HERE------*/
  36. /*
  37.  * Copyright (c) 1988, Andrew Rosen.
  38.  * All rights reserved.
  39.  *
  40.  * This software is supplied free of charge.  This software, or any part
  41.  * of it, may  not  be  redistributed or otherwise made available to, or
  42.  * used  by, any  other  person  without the inclusion of this copyright
  43.  * notice.  This software may not be used to make a profit in any way.
  44.  *
  45.  * This  software  is provided with absolutely no warranty, to the extent
  46.  * permitted  by  applicable  state law.  In no event, unless required by
  47.  * applicable law, will the author(s) of this this software be liable for
  48.  * any damages caused by this software.
  49. */
  50.  
  51. /*
  52.  * detach
  53.  *
  54.  * Description:
  55.  *    Execute a command line with an arbitrary user and group id
  56.  *
  57.  * Usage: 
  58.  *    detach -u username [ prog [ options ] ] or
  59.  *    detach uid gid [ prog [ options ] ]
  60.  *
  61.  * History:
  62.  *    03/10/88 - AJR - Creation
  63.  *    03/26/88 - AJR - Do setgroups() before execing
  64.  *                     Added syslog()
  65. */
  66.  
  67. #include <grp.h>
  68. #include <pwd.h>
  69. #include <stdio.h>
  70. #include <syslog.h>
  71. #include <sys/param.h>
  72.  
  73. #define DEF_PROG "/bin/csh"    /* Program to execute if none specified */
  74. #define DEF_OPT  "csh"
  75.  
  76. main(argc, argv)
  77.  
  78. int  argc;
  79. char **argv;
  80.  
  81. {
  82.   struct passwd *pwd;
  83.   struct group *gr;
  84.   int uid, gid;            /* New uid and gid */
  85.   int gidset[NGROUPS];        /* New gidset */
  86.   char *prog, **opts;        /* Program and options to exec */
  87.   char name[20];        /* Name we're going to run as */
  88.   int i;
  89.   int j = 1;
  90.  
  91.   /* Check usage */
  92.   if (argc < 3) {
  93.     printf("Usage: %s -u username [ prog [ options ] ] or\n", argv[0]);
  94.     printf("       %s uid gid  [ prog [ options ] ]\n", argv[0]);
  95.     exit(-1);
  96.   }
  97.  
  98.   if (strcmp(argv[1], "-u") == 0) { /* Specified a username */
  99.     pwd = getpwnam(argv[2]);
  100.     if (pwd == NULL) {
  101.       printf("%s: No such user\n", argv[2]);
  102.       exit(-1);
  103.     }
  104.     uid = pwd->pw_uid;        /* Set uid and gid from password file */
  105.     gid = pwd->pw_gid;
  106.     while (gr = getgrent())    /* Set new user's gidset */
  107.       for (i = 0; gr->gr_mem[i]; i++)
  108.       /* for (i = 0; strcmp(gr->gr_mem[i], NULL) != 0; i++) */
  109.     if ((strcmp(gr->gr_mem[i], argv[2]) == 0) && (gr->gr_gid != gid))
  110.       gidset[j++] = gr->gr_gid;
  111.   }
  112.   else {            /* Specified uid and gid */
  113.     uid = atoi(argv[1]);
  114.     gid = atoi(argv[2]);
  115.     j = 1;            /* Make gidset empty */
  116.   }
  117.  
  118.   /* Don't allow detaching priviledgedly (it's a word now) */
  119. #ifndef NOROOT
  120.   if (uid == 0) {
  121.     fprintf(stderr, "%s: uid 0 not allowed, use su instead\n", argv[0]);
  122.     exit(-1);
  123.   }
  124. #endif
  125.  
  126. #ifdef SYSLOG
  127.   pwd = getpwuid(uid);
  128.   if (pwd != NULL)
  129.     strcpy(name, pwd->pw_name);
  130.   else
  131.     strcpy(name, "unknown user");
  132.  
  133.   pwd = getpwuid(getuid());    /* Who's running the program? */
  134. #endif
  135.  
  136.   /* Initialize the new gidset */
  137.   gidset[0] = gid;
  138.   for (i = j; i < NGROUPS; gidset[i++] = NOGROUP);
  139.   if (setgroups(NGROUPS, gidset)) {
  140.     perror("setgroups");
  141.     exit(-1);
  142.   }
  143.   setugid(uid, gid);
  144.  
  145. #ifdef SYSLOG
  146.   openlog("detach", LOG_CONS, LOG_AUTH);    /* Get syslog ready */
  147. #endif
  148.  
  149.   if (argc > 3) {        /* Program (and maybe options) was specified */
  150.     prog = argv[3];
  151.     opts = &argv[3];
  152.  
  153. #ifdef SYSLOG
  154.     syslog(LOG_NOTICE, "%s [%s] execing %s as %s",
  155.        pwd->pw_name, getlogin(), prog, name);
  156.     closelog();
  157. #endif
  158.  
  159.     execvp(prog, opts, 0);
  160.     perror(prog);
  161.     exit(-1);
  162.   }
  163.  
  164.   /* No program specified, use default */
  165. #ifdef SYSLOG
  166.   syslog(LOG_NOTICE, "%s [%s] execing %s as %s",
  167.      pwd->pw_name, getlogin(), DEF_PROG, name);
  168.   closelog();
  169. #endif
  170.  
  171.   execl(DEF_PROG, DEF_OPT, 0);
  172.   perror(DEF_PROG);
  173.   exit(-1);
  174. }
  175.  
  176.  
  177. /*
  178.  * Set the new user and group ids, both real and effective
  179. */
  180.  
  181. setugid(uid, gid)
  182.  
  183. int uid;
  184. int gid;
  185.  
  186. {
  187.   if (setgid(gid)) {
  188.     perror("setgid");
  189.     exit(-1);
  190.   }
  191.  
  192.   if (setuid(uid)) {
  193.     perror("setuid");
  194.     exit(-1);
  195.   }
  196. }
  197.