Files
Arquivotheca.Solaris-2.5/cmd/newgrp/newgrp.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

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);
}