home *** CD-ROM | disk | FTP | other *** search
- /* newgrp.c - replacement newgrp since SCO has a stupid umask problem. */
-
- /* By Eamonn McManus, Datacode Communications Ltd <em@dce.ie>, January 1991.
- This program is not copyrighted.
-
- Usage: newgrp [-] [group]
- */
-
- #ifndef __STDC__
- #define const /* nothing */
- #endif
-
- #ifndef lint
- static const char rcsid[] =
- "$Id: newgrp.c,v 1.1 91/04/11 13:29:32 em Exp Locker: em $";
- #endif
-
- #include <stdio.h>
- #ifdef __STDC__
- #include <stdlib.h>
- #endif
- #include <string.h>
- #include <pwd.h>
- #include <grp.h>
- #include <errno.h>
-
- #ifdef __STDC__ /* <prototypes.h> is worthless, conflicts with <stdlib.h>. */
-
- /* Declare everything for gcc -Wall. */
- extern int getuid(void), setgid(int gid), setuid(int uid);
- extern int execl(const char *path, const char *arg, ...);
-
- typedef void *pointer;
-
- static void newgrp(const char *grpname, int newgid, int islogin);
- static char *groupname(int gid);
- static void crash(const char *why, const char *what);
- static char *xstrdup(const char *str);
- static pointer xmalloc(int size);
-
- #else /* !STDC */
-
- extern char *malloc();
-
- typedef char *pointer;
-
- static void crash();
- static char *groupname();
- static char *xstrdup();
- static pointer xmalloc();
-
- #endif /* !STDC */
-
-
- const char *progname = "newgrp";
-
-
- int main(argc, argv)
- int argc;
- char **const argv;
- {
- int i;
- int login = 0;
- struct passwd *pwd;
- char *group = NULL;
- if (argc > 0)
- progname = argv[0];
- for (i = 1; i < argc && argv[i][0] == '-'; i++) {
- switch (argv[i][1]) {
- case '\0':
- login = 1; break;
- default:
- usage:
- fprintf(stderr, "Usage: %s [-] [group]\n", progname);
- exit(1);
- }
- }
- if (i < argc) {
- group = argv[i];
- if (++i < argc)
- goto usage;
- }
- if ((pwd = getpwuid(getuid())) == NULL)
- crash("*you don't exist", (char *) NULL);
- if (group == NULL)
- newgrp(groupname(pwd->pw_gid), pwd->pw_gid, login);
- else {
- struct group *grp = getgrnam(group);
- if (grp == NULL)
- crash("*no such group", group);
- if (getuid() != 0) {
- char **gnam;
- for (gnam = grp->gr_mem; *gnam; gnam++)
- if (strcmp(*gnam, pwd->pw_name) == 0)
- break;
- if (*gnam == NULL)
- crash("*not a member of group", group);
- }
- newgrp(group, grp->gr_gid, login);
- }
- return 0; /* Not reached. */
- }
-
-
- static void newgrp(grpname, newgid, islogin)
- const char *grpname;
- int newgid, islogin;
- {
- char *shell = getenv("SHELL");
- char *argv0;
- if (shell == NULL || *shell == '\0')
- shell = "/bin/sh";
- argv0 = strrchr(shell, '/');
- if (argv0 != NULL)
- argv0++;
- else argv0 = shell;
- if (islogin) { /* newgrp - */
- char *p = xmalloc(strlen(argv0) + sizeof("-"));
- (void) sprintf(p, "-%s", argv0);
- argv0 = p;
- }
- if (setgid(newgid) < 0)
- crash("setgid", grpname);
- if (setuid(getuid()) < 0)
- crash("setuid", "to real uid");
- execl(shell, argv0, (char *) NULL);
- crash("execl", shell);
- }
-
-
- static char *groupname(gid)
- int gid;
- {
- struct group *grp;
- char gidnum[16];
- if ((grp = getgrgid(gid)) != NULL)
- return xstrdup(grp->gr_name);
- (void) sprintf(gidnum, "%d", gid);
- return xstrdup(gidnum);
- }
-
-
- /* Print message "why: what" to stderr. The what string is printed with
- perror unless the why string begins with *. The * is not printed.
- Exits the program. */
- static void crash(why, what)
- const char *why, *what;
- {
- fprintf(stderr, "%s: ", progname);
- if (*why == '*') {
- fprintf(stderr, "%s", why + 1);
- if (what)
- fprintf(stderr, ": %s", what);
- putc('\n', stderr);
- } else if (what) {
- fprintf(stderr, "%s: ", why);
- perror(what);
- } else perror(why);
- exit(1);
- }
-
-
- /* Safe malloc, 'cos it crashes if it fails. (That's safe.) */
- static pointer xmalloc(size)
- int size;
- {
- pointer p;
- if ((p = malloc((size_t) size)) == NULL)
- crash("malloc", (char *) NULL);
- return p;
- }
-
-
- /* Likewise for strdup. Since strdup isn't standard we write it by hand. */
- static char *xstrdup(str)
- const char *str;
- {
- char *p = xmalloc(strlen(str) + 1);
- return strcpy(p, str);
- }
-