2 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: newgrp.c,v 1.6 2008/04/28 20:24:14 martin Exp $");
36 #include <sys/param.h>
37 #include <sys/types.h>
50 #include <login_cap.h>
58 (void)fprintf(stderr
, "usage: %s [-l] [group]\n", getprogname());
63 main(int argc
, char *argv
[])
65 extern char **environ
;
68 char *shell
, sbuf
[MAXPATHLEN
+ 2];
72 u_int flags
= LOGIN_SETUSER
;
78 errx(EXIT_FAILURE
, "who are you?");
81 if ((lc
= login_getclass(pwd
->pw_class
)) == NULL
)
82 errx(EXIT_FAILURE
, "%s: unknown login class", pwd
->pw_class
);
85 (void)setprogname(argv
[0]);
87 while ((c
= getopt(argc
, argv
, "-l")) != -1) {
106 pwd
->pw_gid
= newgrp(*argv
, pwd
);
108 if (setgid(pwd
->pw_gid
) < 0)
112 addgroup(lc
, *argv
, pwd
, getuid(), "Password:");
114 addgroup(*argv
, pwd
, getuid(), "Password:");
118 flags
|= LOGIN_SETGROUP
;
120 if (initgroups(pwd
->pw_name
, pwd
->pw_gid
) == -1)
121 err(EXIT_FAILURE
, "initgroups");
122 if (setgid(pwd
->pw_gid
) == -1)
123 err(EXIT_FAILURE
, "setgid");
128 if (setusercontext(lc
, pwd
, uid
, flags
) == -1)
129 err(EXIT_FAILURE
, "setusercontext");
133 if (setuid(pwd
->pw_uid
) == -1)
134 err(EXIT_FAILURE
, "setuid");
137 if (*pwd
->pw_shell
== '\0') {
138 #ifdef TRUST_ENV_SHELL
139 shell
= getenv("SHELL");
141 pwd
->pw_shell
= shell
;
144 pwd
->pw_shell
= __UNCONST(_PATH_BSHELL
);
147 shell
= pwd
->pw_shell
;
155 if (chdir(pwd
->pw_dir
) == -1)
156 warn("%s", pwd
->pw_dir
);
158 term
= getenv("TERM");
160 krbtkfile
= getenv("KRBTKFILE");
163 /* create an empty environment */
164 if ((environ
= malloc(sizeof(char *))) == NULL
)
165 err(EXIT_FAILURE
, NULL
);
168 if (setusercontext(lc
, pwd
, uid
, LOGIN_SETENV
| LOGIN_SETPATH
) == -1)
169 err(EXIT_FAILURE
, "setusercontext");
172 (void)setenv("PATH", _PATH_DEFPATH
, 1);
175 (void)setenv("TERM", term
, 1);
177 if (krbtkfile
!= NULL
)
178 (void)setenv("KRBTKFILE", krbtkfile
, 1);
181 (void)setenv("LOGNAME", pwd
->pw_name
, 1);
182 (void)setenv("USER", pwd
->pw_name
, 1);
183 (void)setenv("HOME", pwd
->pw_dir
, 1);
184 (void)setenv("SHELL", pwd
->pw_shell
, 1);
187 (void)strlcpy(sbuf
+ 1, basename(pwd
->pw_shell
),
192 (void)execl(pwd
->pw_shell
, shell
, NULL
);
193 err(EXIT_FAILURE
, "%s", pwd
->pw_shell
);