home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3186 / newgrp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-13  |  3.9 KB  |  181 lines

  1. /* newgrp.c - replacement newgrp since SCO has a stupid umask problem. */
  2.  
  3. /* By Eamonn McManus, Datacode Communications Ltd <em@dce.ie>, January 1991.
  4.    This program is not copyrighted.
  5.  
  6.    Usage: newgrp [-] [group]
  7. */
  8.  
  9. #ifndef __STDC__
  10. #define const /* nothing */
  11. #endif
  12.  
  13. #ifndef lint
  14. static const char rcsid[] =
  15.     "$Id: newgrp.c,v 1.1 91/04/11 13:29:32 em Exp Locker: em $";
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #ifdef __STDC__
  20. #include <stdlib.h>
  21. #endif
  22. #include <string.h>
  23. #include <pwd.h>
  24. #include <grp.h>
  25. #include <errno.h>
  26.  
  27. #ifdef __STDC__    /* <prototypes.h> is worthless, conflicts with <stdlib.h>. */
  28.  
  29. /* Declare everything for gcc -Wall. */
  30. extern int getuid(void), setgid(int gid), setuid(int uid);
  31. extern int execl(const char *path, const char *arg, ...);
  32.  
  33. typedef void *pointer;
  34.  
  35. static void newgrp(const char *grpname, int newgid, int islogin);
  36. static char *groupname(int gid);
  37. static void crash(const char *why, const char *what);
  38. static char *xstrdup(const char *str);
  39. static pointer xmalloc(int size);
  40.  
  41. #else    /* !STDC */
  42.  
  43. extern char *malloc();
  44.  
  45. typedef char *pointer;
  46.  
  47. static void crash();
  48. static char *groupname();
  49. static char *xstrdup();
  50. static pointer xmalloc();
  51.  
  52. #endif    /* !STDC */
  53.  
  54.  
  55. const char *progname = "newgrp";
  56.  
  57.  
  58. int main(argc, argv)
  59. int argc;
  60. char **const argv;
  61. {
  62.     int i;
  63.     int login = 0;
  64.     struct passwd *pwd;
  65.     char *group = NULL;
  66.     if (argc > 0)
  67.     progname = argv[0];
  68.     for (i = 1; i < argc && argv[i][0] == '-'; i++) {
  69.     switch (argv[i][1]) {
  70.     case '\0':
  71.         login = 1; break;
  72.     default:
  73. usage:
  74.         fprintf(stderr, "Usage: %s [-] [group]\n", progname);
  75.         exit(1);
  76.     }
  77.     }
  78.     if (i < argc) {
  79.     group = argv[i];
  80.     if (++i < argc)
  81.         goto usage;
  82.     }
  83.     if ((pwd = getpwuid(getuid())) == NULL)
  84.     crash("*you don't exist", (char *) NULL);
  85.     if (group == NULL)
  86.     newgrp(groupname(pwd->pw_gid), pwd->pw_gid, login);
  87.     else {
  88.     struct group *grp = getgrnam(group);
  89.     if (grp == NULL)
  90.         crash("*no such group", group);
  91.     if (getuid() != 0) {
  92.         char **gnam;
  93.         for (gnam = grp->gr_mem; *gnam; gnam++)
  94.         if (strcmp(*gnam, pwd->pw_name) == 0)
  95.             break;
  96.         if (*gnam == NULL)
  97.         crash("*not a member of group", group);
  98.     }
  99.     newgrp(group, grp->gr_gid, login);
  100.     }
  101.     return 0;    /* Not reached. */
  102. }
  103.  
  104.  
  105. static void newgrp(grpname, newgid, islogin)
  106. const char *grpname;
  107. int newgid, islogin;
  108. {
  109.     char *shell = getenv("SHELL");
  110.     char *argv0;
  111.     if (shell == NULL || *shell == '\0')
  112.     shell = "/bin/sh";
  113.     argv0 = strrchr(shell, '/');
  114.     if (argv0 != NULL)
  115.     argv0++;
  116.     else argv0 = shell;
  117.     if (islogin) {    /* newgrp - */
  118.     char *p = xmalloc(strlen(argv0) + sizeof("-"));
  119.     (void) sprintf(p, "-%s", argv0);
  120.     argv0 = p;
  121.     }
  122.     if (setgid(newgid) < 0)
  123.     crash("setgid", grpname);
  124.     if (setuid(getuid()) < 0)
  125.     crash("setuid", "to real uid");
  126.     execl(shell, argv0, (char *) NULL);
  127.     crash("execl", shell);
  128. }
  129.  
  130.  
  131. static char *groupname(gid)
  132. int gid;
  133. {
  134.     struct group *grp;
  135.     char gidnum[16];
  136.     if ((grp = getgrgid(gid)) != NULL)
  137.     return xstrdup(grp->gr_name);
  138.     (void) sprintf(gidnum, "%d", gid);
  139.     return xstrdup(gidnum);
  140. }
  141.  
  142.  
  143. /* Print message "why: what" to stderr.  The what string is printed with
  144.    perror unless the why string begins with *.  The * is not printed.
  145.    Exits the program.  */
  146. static void crash(why, what)
  147. const char *why, *what;
  148. {
  149.     fprintf(stderr, "%s: ", progname);
  150.     if (*why == '*') {
  151.     fprintf(stderr, "%s", why + 1);
  152.     if (what)
  153.         fprintf(stderr, ": %s", what);
  154.     putc('\n', stderr);
  155.     } else if (what) {
  156.     fprintf(stderr, "%s: ", why);
  157.     perror(what);
  158.     } else perror(why);
  159.     exit(1);
  160. }
  161.  
  162.  
  163. /* Safe malloc, 'cos it crashes if it fails.  (That's safe.) */
  164. static pointer xmalloc(size)
  165. int size;
  166. {
  167.     pointer p;
  168.     if ((p = malloc((size_t) size)) == NULL)
  169.     crash("malloc", (char *) NULL);
  170.     return p;
  171. }
  172.  
  173.  
  174. /* Likewise for strdup.  Since strdup isn't standard we write it by hand. */
  175. static char *xstrdup(str)
  176. const char *str;
  177. {
  178.     char *p = xmalloc(strlen(str) + 1);
  179.     return strcpy(p, str);
  180. }
  181.