1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * newgrp [-l | -] [group] 35 * 36 * rules 37 * if no arg, group id in password file is used 38 * else if group id == id in password file 39 * else if login name is in member list 40 * else if password is present and user knows it 41 * else too bad 42 */ 43 #include <stdio.h> 44 #include <sys/types.h> 45 #include <pwd.h> 46 #include <grp.h> 47 #include <crypt.h> 48 #include <string.h> 49 #include <stdlib.h> 50 #include <locale.h> 51 52 #define SHELL "/usr/bin/sh" 53 54 #define PATH "PATH=:/usr/bin:" 55 #define SUPATH "PATH=:/usr/sbin:/usr/bin" 56 #define ELIM 128 57 58 char PW[] = "newgrp: Password: "; 59 char NG[] = "newgrp: Sorry"; 60 char PD[] = "newgrp: Permission denied"; 61 char UG[] = "newgrp: Unknown group"; 62 char NS[] = "newgrp: You have no shell"; 63 64 char *homedir; 65 char *logname; 66 67 char *envinit[ELIM]; 68 extern char **environ; 69 char *path = PATH; 70 char *supath = SUPATH; 71 72 extern void audit_newgrp_login(char *, int); 73 74 main(argc, argv) 75 char *argv[]; 76 { 77 register char *s; 78 register struct passwd *p; 79 char *rname(); 80 gid_t chkgrp(); 81 int eflag = 0; 82 int flag; 83 uid_t uid; 84 char *shell, *dir, *name; 85 size_t len; 86 87 #ifdef DEBUG 88 chroot("."); 89 #endif 90 91 (void) setlocale(LC_ALL, ""); 92 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 93 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 94 #endif 95 (void) textdomain(TEXT_DOMAIN); 96 97 if ((p = getpwuid(getuid())) == NULL) 98 error(NG); 99 endpwent(); 100 101 while ((flag = getopt(argc, argv, "l")) != EOF) { 102 switch (flag) { 103 case 'l': 104 eflag++; 105 break; 106 107 default: 108 usage(); 109 break; 110 } 111 } 112 113 argc -= optind; 114 argv = &argv[optind]; 115 116 if (argc > 0 && *argv[0] == '-') { 117 if (eflag) 118 usage(); 119 eflag++; 120 argv++; 121 --argc; 122 } 123 124 if (argc > 0) 125 p->pw_gid = chkgrp(argv[0], p); 126 127 uid = p->pw_uid; 128 129 len = strlen(p->pw_dir) + 1; 130 if ((dir = (char *)malloc(len)) == NULL) 131 error("newgrp: Memory request failed"); 132 (void) strncpy(dir, p->pw_dir, len); 133 len = strlen(p->pw_name) + 1; 134 if ((name = (char *)malloc(len)) == NULL) 135 error("newgrp: Memory request failed"); 136 (void) strncpy(name, p->pw_name, len); 137 138 if (setgid(p->pw_gid) < 0 || setuid(getuid()) < 0) 139 error(NG); 140 141 if (!*p->pw_shell) { 142 if ((shell = getenv("SHELL")) != NULL) { 143 p->pw_shell = shell; 144 } else { 145 p->pw_shell = SHELL; 146 } 147 } 148 149 if (eflag) { 150 char *simple; 151 152 len = strlen(dir) + 6; 153 if ((homedir = (char *)malloc(len)) == NULL) 154 error("newgrp: Memory request failed"); 155 (void) snprintf(homedir, len, "HOME=%s", dir); 156 len = strlen(name) + 9; 157 if ((logname = (char *)malloc(len)) == NULL) 158 error("newgrp: Memory request failed"); 159 (void) snprintf(logname, len, "LOGNAME=%s", name); 160 161 162 envinit[2] = logname; 163 chdir(dir); 164 envinit[0] = homedir; 165 if (uid == 0) 166 envinit[1] = supath; 167 else 168 envinit[1] = path; 169 envinit[3] = NULL; 170 environ = envinit; 171 172 len = strlen(p->pw_shell) + 2; 173 if ((shell = (char *)malloc(len)) == NULL) 174 error("newgrp: Memory request failed"); 175 (void) snprintf(shell, len, "-%s", p->pw_shell); 176 simple = strrchr(shell, '/'); 177 if (simple) { 178 *(shell+1) = '\0'; 179 shell = strcat(shell, ++simple); 180 } 181 } 182 else 183 shell = p->pw_shell; 184 185 execl(p->pw_shell, shell, NULL); 186 error(NS); 187 } 188 189 warn(s) 190 char *s; 191 { 192 fprintf(stderr, "%s\n", gettext(s)); 193 } 194 195 error(s) 196 char *s; 197 { 198 warn(s); 199 exit(1); 200 } 201 202 gid_t 203 chkgrp(gname, p) 204 char *gname; 205 struct passwd *p; 206 { 207 register char **t; 208 register struct group *g; 209 210 g = getgrnam(gname); 211 endgrent(); 212 if (g == NULL) { 213 warn(UG); 214 return (getgid()); 215 } 216 if (p->pw_gid == g->gr_gid || getuid() == 0) 217 return (g->gr_gid); 218 for (t = g->gr_mem; *t; ++t) { 219 if (strcmp(p->pw_name, *t) == 0) 220 return (g->gr_gid); 221 } 222 if (*g->gr_passwd) { 223 if (!isatty(fileno(stdin))) { 224 error(PD); 225 } 226 if (strcmp(g->gr_passwd, 227 crypt(getpass(PW), g->gr_passwd)) == 0) { 228 audit_newgrp_login(gname, 0); 229 return (g->gr_gid); 230 } 231 audit_newgrp_login(gname, 1); 232 } 233 warn(NG); 234 return (getgid()); 235 } 236 237 /* 238 * return pointer to rightmost component of pathname 239 */ 240 char * 241 rname(pn) 242 char *pn; 243 { 244 register char *q; 245 246 q = pn; 247 while (*pn) 248 if (*pn++ == '/') 249 q = pn; 250 return (q); 251 } 252 253 usage() 254 { 255 fprintf(stderr, gettext( 256 "usage: newgrp [-l | -] [group]\n")); 257 exit(2); 258 } 259