8672 proc_t changes broke genunix dmods and walker
[unleashed.git] / usr / src / cmd / newgrp / newgrp.c
blob6b16b28bfae66c87f6db4742bcda0b5ceeffabe9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 * newgrp [-l | -] [group]
35 * rules
36 * if no arg, group id in password file is used
37 * else if group id == id in password file
38 * else if login name is in member list
39 * else if password is present and user knows it
40 * else too bad
42 #include <stdio.h>
43 #include <sys/types.h>
44 #include <pwd.h>
45 #include <grp.h>
46 #include <crypt.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <locale.h>
50 #include <syslog.h>
51 #include <unistd.h>
53 #include <bsm/adt_event.h>
55 #define SHELL "/usr/bin/sh"
57 #define PATH "PATH=:/usr/bin:"
58 #define SUPATH "PATH=:/usr/sbin:/usr/bin"
59 #define ELIM 128
61 char PW[] = "newgrp: Password: ";
62 char NG[] = "newgrp: Sorry";
63 char PD[] = "newgrp: Permission denied";
64 char UG[] = "newgrp: Unknown group";
65 char NS[] = "newgrp: You have no shell";
67 char *homedir;
68 char *logname;
70 char *envinit[ELIM];
71 extern char **environ;
72 char *path = PATH;
73 char *supath = SUPATH;
75 void error(char *s) __NORETURN;
76 static void warn(char *s);
77 void usage(void);
79 int
80 main(int argc, char *argv[])
82 struct passwd *p;
83 gid_t chkgrp();
84 int eflag = 0;
85 int flag;
86 uid_t uid;
87 char *shell, *dir, *name;
88 size_t len;
90 #ifdef DEBUG
91 chroot(".");
92 #endif
94 (void) setlocale(LC_ALL, "");
95 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
96 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
97 #endif
98 (void) textdomain(TEXT_DOMAIN);
100 if ((p = getpwuid(getuid())) == NULL)
101 error(NG);
102 endpwent();
104 while ((flag = getopt(argc, argv, "l")) != EOF) {
105 switch (flag) {
106 case 'l':
107 eflag++;
108 break;
110 default:
111 usage();
112 break;
116 argc -= optind;
117 argv = &argv[optind];
119 if (argc > 0 && *argv[0] == '-') {
120 if (eflag)
121 usage();
122 eflag++;
123 argv++;
124 --argc;
127 if (argc > 0)
128 p->pw_gid = chkgrp(argv[0], p);
130 uid = p->pw_uid;
132 len = strlen(p->pw_dir) + 1;
133 if ((dir = (char *)malloc(len)) == NULL)
134 error("newgrp: Memory request failed");
135 (void) strncpy(dir, p->pw_dir, len);
136 len = strlen(p->pw_name) + 1;
137 if ((name = (char *)malloc(len)) == NULL)
138 error("newgrp: Memory request failed");
139 (void) strncpy(name, p->pw_name, len);
141 if (setgid(p->pw_gid) < 0 || setuid(getuid()) < 0)
142 error(NG);
144 if (!*p->pw_shell) {
145 if ((shell = getenv("SHELL")) != NULL) {
146 p->pw_shell = shell;
147 } else {
148 p->pw_shell = SHELL;
152 if (eflag) {
153 char *simple;
155 len = strlen(dir) + 6;
156 if ((homedir = (char *)malloc(len)) == NULL)
157 error("newgrp: Memory request failed");
158 (void) snprintf(homedir, len, "HOME=%s", dir);
159 len = strlen(name) + 9;
160 if ((logname = (char *)malloc(len)) == NULL)
161 error("newgrp: Memory request failed");
162 (void) snprintf(logname, len, "LOGNAME=%s", name);
165 envinit[2] = logname;
166 (void) chdir(dir);
167 envinit[0] = homedir;
168 if (uid == 0)
169 envinit[1] = supath;
170 else
171 envinit[1] = path;
172 envinit[3] = NULL;
173 environ = envinit;
175 len = strlen(p->pw_shell) + 2;
176 if ((shell = (char *)malloc(len)) == NULL)
177 error("newgrp: Memory request failed");
178 (void) snprintf(shell, len, "-%s", p->pw_shell);
179 simple = strrchr(shell, '/');
180 if (simple) {
181 *(shell+1) = '\0';
182 shell = strcat(shell, ++simple);
185 else
186 shell = p->pw_shell;
188 (void) execl(p->pw_shell, shell, NULL);
189 warn(NS);
190 return (1);
193 static void
194 warn(char *s)
196 (void) fprintf(stderr, "%s\n", gettext(s));
199 void
200 error(char *s)
202 warn(s);
203 exit(1);
206 void
207 put_event(char *gname, int sorf)
209 adt_session_data_t *ah;
210 adt_event_data_t *event;
212 if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
213 syslog(LOG_AUTH | LOG_ALERT,
214 "adt_start_session(ADT_newgrp_login): %m");
216 if ((event = adt_alloc_event(ah, ADT_newgrp_login)) == NULL) {
217 syslog(LOG_AUTH | LOG_ALERT,
218 "adt_alloc_event(ADT_newgrp_login): %m");
219 } else {
220 event->adt_newgrp_login.groupname = gname;
223 if (adt_put_event(event, sorf, sorf) != 0) {
224 syslog(LOG_AUTH | LOG_ALERT,
225 "adt_put_event(ADT_newgrp, %d): %m", sorf);
227 adt_free_event(event);
228 (void) adt_end_session(ah);
231 gid_t
232 chkgrp(gname, p)
233 char *gname;
234 struct passwd *p;
236 char **t;
237 struct group *g;
239 g = getgrnam(gname);
240 endgrent();
241 if (g == NULL) {
242 warn(UG);
243 put_event(gname, ADT_FAILURE);
244 return (getgid());
246 if (p->pw_gid == g->gr_gid || getuid() == 0) {
247 put_event(gname, ADT_SUCCESS);
248 return (g->gr_gid);
250 for (t = g->gr_mem; *t; ++t) {
251 if (strcmp(p->pw_name, *t) == 0) {
252 put_event(gname, ADT_SUCCESS);
253 return (g->gr_gid);
256 if (*g->gr_passwd) {
257 if (!isatty(fileno(stdin))) {
258 put_event(gname, ADT_FAILURE);
259 error(PD);
261 if (strcmp(g->gr_passwd,
262 crypt(getpassphrase(PW), g->gr_passwd)) == 0) {
263 put_event(gname, ADT_SUCCESS);
264 return (g->gr_gid);
267 put_event(gname, ADT_FAILURE);
268 warn(NG);
269 return (getgid());
272 void
273 usage(void)
275 (void) fprintf(stderr, gettext(
276 "usage: newgrp [-l | -] [group]\n"));
277 exit(2);