diff options
Diffstat (limited to 'usr/src/cmd/newgrp/newgrp.c')
| -rw-r--r-- | usr/src/cmd/newgrp/newgrp.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/usr/src/cmd/newgrp/newgrp.c b/usr/src/cmd/newgrp/newgrp.c new file mode 100644 index 0000000000..ee89de2762 --- /dev/null +++ b/usr/src/cmd/newgrp/newgrp.c @@ -0,0 +1,258 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +/* + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * 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; +char *logname; + +char *envinit[ELIM]; +extern char **environ; +char *path = PATH; +char *supath = SUPATH; + +extern void audit_newgrp_login(char *, int); + +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; + size_t len; + +#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; + + len = strlen(p->pw_dir) + 1; + if ((dir = (char *)malloc(len)) == NULL) + error("newgrp: Memory request failed"); + (void) strncpy(dir, p->pw_dir, len); + len = strlen(p->pw_name) + 1; + if ((name = (char *)malloc(len)) == NULL) + error("newgrp: Memory request failed"); + (void) strncpy(name, p->pw_name, len); + + 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; + + len = strlen(dir) + 6; + if ((homedir = (char *)malloc(len)) == NULL) + error("newgrp: Memory request failed"); + (void) snprintf(homedir, len, "HOME=%s", dir); + len = strlen(name) + 9; + if ((logname = (char *)malloc(len)) == NULL) + error("newgrp: Memory request failed"); + (void) snprintf(logname, len, "LOGNAME=%s", name); + + + envinit[2] = logname; + chdir(dir); + envinit[0] = homedir; + if (uid == 0) + envinit[1] = supath; + else + envinit[1] = path; + envinit[3] = NULL; + environ = envinit; + + len = strlen(p->pw_shell) + 2; + if ((shell = (char *)malloc(len)) == NULL) + error("newgrp: Memory request failed"); + (void) snprintf(shell, len, "-%s", 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) { + audit_newgrp_login(gname, 0); + return (g->gr_gid); + } + audit_newgrp_login(gname, 1); + } + 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); +} |
