pdp11v/usr/src/cmd/newgrp.c
/* @(#)newgrp.c 1.1 */
/*
* newgrp [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 <pwd.h>
#include <grp.h>
#define SHELL "/bin/sh"
char PW[] = "Password: ";
char NG[] = "Sorry";
char PD[] = "Permission denied";
char UG[] = "Unknown group";
char NS[] = "You have no shell";
struct group *getgrnam();
struct passwd *getpwnam();
char *cuserid();
char *getpass();
char *crypt();
char *malloc();
char *strcpy();
char *strcat();
char *strrchr();
main(argc,argv)
char *argv[];
{
register char *s;
register struct passwd *p;
char *rname();
int eflag = 0;
char *shell;
#ifdef DEBUG
chroot(".");
#endif
if (((s = cuserid(0)) == NULL) || ((p = getpwnam(s)) == NULL))
error(NG);
endpwent();
if(argc > 1 && *argv[1] == '-'){
eflag++;
argv++;
--argc;
}
if (argc > 1)
p->pw_gid = chkgrp(argv[1], p);
if (setgid(p->pw_gid) < 0 || setuid(getuid()) < 0)
error(NG);
if (!*p->pw_shell)
p->pw_shell = SHELL;
if(eflag){
char *simple;
shell = strcpy(malloc(sizeof(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", s);
}
error(s)
char *s;
{
warn(s);
exit(1);
}
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;
}