211 lines
3.7 KiB
C
Executable File
211 lines
3.7 KiB
C
Executable File
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
|
/* All Rights Reserved */
|
|
|
|
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
|
/* The copyright notice above does not evidence any */
|
|
/* actual or intended publication of such source code. */
|
|
|
|
#ident "@(#)newgrp.c 1.12 94/10/12 SMI" /* SVr4.0 1.10 */
|
|
|
|
/*
|
|
* newgrp [-l | -] [group]
|
|
*
|
|
* rules
|
|
* if no arg, group id in password file is used
|
|
* else if group id == id in password file
|
|
* else if login name is in member list
|
|
* else if password is present and user knows it
|
|
* else too bad
|
|
*/
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <crypt.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <locale.h>
|
|
|
|
#define SHELL "/usr/bin/sh"
|
|
|
|
#define PATH "PATH=:/usr/bin:"
|
|
#define SUPATH "PATH=:/usr/sbin:/usr/bin"
|
|
#define ELIM 128
|
|
|
|
char PW[] = "newgrp: Password";
|
|
char NG[] = "newgrp: Sorry";
|
|
char PD[] = "newgrp: Permission denied";
|
|
char UG[] = "newgrp: Unknown group";
|
|
char NS[] = "newgrp: You have no shell";
|
|
|
|
char homedir[64] = "HOME=";
|
|
char logname[20] = "LOGNAME=";
|
|
|
|
char *envinit[ELIM];
|
|
extern char **environ;
|
|
char *path = PATH;
|
|
char *supath = SUPATH;
|
|
|
|
main(argc, argv)
|
|
char *argv[];
|
|
{
|
|
register char *s;
|
|
register struct passwd *p;
|
|
char *rname();
|
|
gid_t chkgrp();
|
|
int eflag = 0;
|
|
int flag;
|
|
uid_t uid;
|
|
char *shell, *dir, *name;
|
|
|
|
#ifdef DEBUG
|
|
chroot(".");
|
|
#endif
|
|
|
|
(void) setlocale(LC_ALL, "");
|
|
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
|
|
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
|
|
#endif
|
|
(void) textdomain(TEXT_DOMAIN);
|
|
|
|
if ((p = getpwuid(getuid())) == NULL)
|
|
error(NG);
|
|
endpwent();
|
|
|
|
while ((flag = getopt(argc, argv, "l")) != EOF) {
|
|
switch (flag) {
|
|
case 'l':
|
|
eflag++;
|
|
break;
|
|
|
|
default:
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
argc -= optind;
|
|
argv = &argv[optind];
|
|
|
|
if (argc > 0 && *argv[0] == '-') {
|
|
if (eflag)
|
|
usage();
|
|
eflag++;
|
|
argv++;
|
|
--argc;
|
|
}
|
|
|
|
if (argc > 0)
|
|
p->pw_gid = chkgrp(argv[0], p);
|
|
|
|
uid = p->pw_uid;
|
|
dir = strcpy((char *)malloc(strlen(p->pw_dir)+1), p->pw_dir);
|
|
name = strcpy((char *)malloc(strlen(p->pw_name)+1), p->pw_name);
|
|
|
|
if (setgid(p->pw_gid) < 0 || setuid(getuid()) < 0)
|
|
error(NG);
|
|
|
|
if (!*p->pw_shell) {
|
|
if ((shell = getenv("SHELL")) != NULL) {
|
|
p->pw_shell = shell;
|
|
} else {
|
|
p->pw_shell = SHELL;
|
|
}
|
|
}
|
|
|
|
if (eflag) {
|
|
char *simple;
|
|
|
|
strcat(homedir, dir);
|
|
strcat(logname, name);
|
|
envinit[2] = logname;
|
|
chdir(dir);
|
|
envinit[0] = homedir;
|
|
if (uid == 0)
|
|
envinit[1] = supath;
|
|
else
|
|
envinit[1] = path;
|
|
envinit[3] = NULL;
|
|
environ = envinit;
|
|
shell = strcpy((char *)malloc(strlen(p->pw_shell) + 2), "-");
|
|
shell = strcat(shell, p->pw_shell);
|
|
simple = strrchr(shell, '/');
|
|
if (simple) {
|
|
*(shell+1) = '\0';
|
|
shell = strcat(shell, ++simple);
|
|
}
|
|
}
|
|
else
|
|
shell = p->pw_shell;
|
|
|
|
execl(p->pw_shell, shell, NULL);
|
|
error(NS);
|
|
}
|
|
|
|
warn(s)
|
|
char *s;
|
|
{
|
|
fprintf(stderr, "%s\n", gettext(s));
|
|
}
|
|
|
|
error(s)
|
|
char *s;
|
|
{
|
|
warn(s);
|
|
exit(1);
|
|
}
|
|
|
|
gid_t
|
|
chkgrp(gname, p)
|
|
char *gname;
|
|
struct passwd *p;
|
|
{
|
|
register char **t;
|
|
register struct group *g;
|
|
|
|
g = getgrnam(gname);
|
|
endgrent();
|
|
if (g == NULL) {
|
|
warn(UG);
|
|
return (getgid());
|
|
}
|
|
if (p->pw_gid == g->gr_gid || getuid() == 0)
|
|
return (g->gr_gid);
|
|
for (t = g->gr_mem; *t; ++t) {
|
|
if (strcmp(p->pw_name, *t) == 0)
|
|
return (g->gr_gid);
|
|
}
|
|
if (*g->gr_passwd) {
|
|
if (!isatty(fileno(stdin))) {
|
|
error(PD);
|
|
}
|
|
if (strcmp(g->gr_passwd, crypt(getpass(PW), g->gr_passwd)) == 0)
|
|
return (g->gr_gid);
|
|
}
|
|
warn(NG);
|
|
return (getgid());
|
|
}
|
|
|
|
/*
|
|
* return pointer to rightmost component of pathname
|
|
*/
|
|
char *
|
|
rname(pn)
|
|
char *pn;
|
|
{
|
|
register char *q;
|
|
|
|
q = pn;
|
|
while (*pn)
|
|
if (*pn++ == '/')
|
|
q = pn;
|
|
return (q);
|
|
}
|
|
|
|
usage()
|
|
{
|
|
fprintf(stderr, gettext(
|
|
"usage: newgrp [-l | -] [group]\n"));
|
|
exit(2);
|
|
}
|