diff options
author | Kiyoshi Aman <kiyoshi.aman+adelie@gmail.com> | 2019-02-01 22:55:37 +0000 |
---|---|---|
committer | Kiyoshi Aman <kiyoshi.aman+adelie@gmail.com> | 2019-02-03 18:22:05 -0600 |
commit | 5b57d28ffb6e1ef86b50f7d05d977826eae89bfe (patch) | |
tree | 154a22fe556b49e6927197336f8bf91b12eacd5e /usr.bin/newgrp | |
download | userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.gz userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.bz2 userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.xz userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.zip |
initial population
Diffstat (limited to 'usr.bin/newgrp')
-rw-r--r-- | usr.bin/newgrp/grutil.c | 338 | ||||
-rw-r--r-- | usr.bin/newgrp/grutil.h | 40 | ||||
-rw-r--r-- | usr.bin/newgrp/newgrp.1 | 121 | ||||
-rw-r--r-- | usr.bin/newgrp/newgrp.c | 195 |
4 files changed, 694 insertions, 0 deletions
diff --git a/usr.bin/newgrp/grutil.c b/usr.bin/newgrp/grutil.c new file mode 100644 index 0000000..ee81590 --- /dev/null +++ b/usr.bin/newgrp/grutil.c @@ -0,0 +1,338 @@ +/* $NetBSD: grutil.c,v 1.4 2014/06/23 06:57:31 shm Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: grutil.c,v 1.4 2014/06/23 06:57:31 shm Exp $"); + +#include <sys/param.h> +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <util.h> + +#ifdef LOGIN_CAP +#include <login_cap.h> +#endif + +#include "grutil.h" + +typedef enum { + ADDGRP_NOERROR = 0, /* must be zero */ + ADDGRP_EMALLOC = 1, + ADDGRP_EGETGROUPS = 2, + ADDGRP_ESETGROUPS = 3 +} addgrp_ret_t; + +static void +free_groups(void *groups) +{ + int oerrno; + + oerrno = errno; + free(groups); + errno = oerrno; +} + +static addgrp_ret_t +alloc_groups(int *ngroups, gid_t **groups, int *ngroupsmax) +{ + *ngroupsmax = (int)sysconf(_SC_NGROUPS_MAX); + if (*ngroupsmax < 0) + *ngroupsmax = NGROUPS_MAX; + + *groups = malloc(*ngroupsmax * sizeof(**groups)); + if (*groups == NULL) + return ADDGRP_EMALLOC; + + *ngroups = getgroups(*ngroupsmax, *groups); + if (*ngroups == -1) { + free_groups(*groups); + return ADDGRP_ESETGROUPS; + } + return ADDGRP_NOERROR; +} + +static addgrp_ret_t +addgid(gid_t *groups, int ngroups, int ngroupsmax, gid_t gid, int makespace) +{ + int i; + + /* search for gid in supplemental group list */ + for (i = 0; i < ngroups && groups[i] != gid; i++) + continue; + + /* add the gid to the supplemental group list */ + if (i == ngroups) { + if (ngroups < ngroupsmax) + groups[ngroups++] = gid; + else { /* + * setgroups(2) will fail with errno = EINVAL + * if ngroups > nmaxgroups. If makespace is + * set, replace the last group with the new + * one. Otherwise, fail the way setgroups(2) + * would if we passed the larger groups array. + */ + if (makespace) { + /* + * Find a slot that doesn't contain + * the primary group. + */ + struct passwd *pwd; + gid_t pgid; + pwd = getpwuid(getuid()); + if (pwd == NULL) + goto error; + pgid = pwd->pw_gid; + for (i = ngroupsmax - 1; i >= 0; i--) + if (groups[i] != pgid) + break; + if (i < 0) + goto error; + groups[i] = gid; + } + else { + error: + errno = EINVAL; + return ADDGRP_ESETGROUPS; + } + } + if (setgroups(ngroups, groups) < 0) + return ADDGRP_ESETGROUPS; + } + return ADDGRP_NOERROR; +} + +static addgrp_ret_t +addgrp(gid_t newgid, int makespace) +{ + int ngroups, ngroupsmax; + addgrp_ret_t rval; + gid_t *groups; + gid_t oldgid; + + oldgid = getgid(); + if (oldgid == newgid) /* nothing to do */ + return ADDGRP_NOERROR; + + rval = alloc_groups(&ngroups, &groups, &ngroupsmax); + if (rval != ADDGRP_NOERROR) + return rval; + + /* + * BSD based systems normally have the egid in the supplemental + * group list. + */ +#if (defined(BSD) && BSD >= 199306) + /* + * According to POSIX/XPG6: + * On system where the egid is normally in the supplemental group list + * (or whenever the old egid actually is in the supplemental group + * list): + * o If the new egid is in the supplemental group list, + * just change the egid. + * o If the new egid is not in the supplemental group list, + * add the new egid to the list if there is room. + */ + + rval = addgid(groups, ngroups, ngroupsmax, newgid, makespace); +#else + /* + * According to POSIX/XPG6: + * On systems where the egid is not normally in the supplemental group + * list (or whenever the old egid is not in the supplemental group + * list): + * o If the new egid is in the supplemental group list, delete + * it from the list. + * o If the old egid is not in the supplemental group list, + * add the old egid to the list if there is room. + */ + { + int i; + + /* search for new egid in supplemental group list */ + for (i = 0; i < ngroups && groups[i] != newgid; i++) + continue; + + /* remove new egid from supplemental group list */ + if (i != ngroups) + for (--ngroups; i < ngroups; i++) + groups[i] = groups[i + 1]; + + rval = addgid(groups, ngroups, ngroupsmax, oldgid, makespace); + } +#endif + free_groups(groups); + return rval; +} + +/* + * If newgrp fails, it returns (gid_t)-1 and the errno variable is + * set to: + * [EINVAL] Unknown group. + * [EPERM] Bad password. + */ +static gid_t +newgrp(const char *gname, struct passwd *pwd, uid_t ruid, const char *prompt) +{ + struct group *grp; + char **ap; + char *p; + gid_t *groups; + int ngroups, ngroupsmax; + + if (gname == NULL) + return pwd->pw_gid; + + grp = getgrnam(gname); + +#ifdef GRUTIL_ACCEPT_GROUP_NUMBERS + if (grp == NULL) { + gid_t gid; + if (*gname != '-') { + gid = (gid_t)strtol(gname, &p, 10); + if (*p == '\0') + grp = getgrgid(gid); + } + } +#endif + if (grp == NULL) { + errno = EINVAL; + return (gid_t)-1; + } + + if (ruid == 0 || pwd->pw_gid == grp->gr_gid) + return grp->gr_gid; + + if (alloc_groups(&ngroups, &groups, &ngroupsmax) == ADDGRP_NOERROR) { + int i; + for (i = 0; i < ngroups; i++) + if (groups[i] == grp->gr_gid) { + free_groups(groups); + return grp->gr_gid; + } + free_groups(groups); + } + + /* + * Check the group membership list in case the groups[] array + * was maxed out or the user has been added to it since login. + */ + for (ap = grp->gr_mem; *ap != NULL; ap++) + if (strcmp(*ap, pwd->pw_name) == 0) + return grp->gr_gid; + + if (*grp->gr_passwd != '\0') { + p = getpass(prompt); + if (strcmp(grp->gr_passwd, crypt(p, grp->gr_passwd)) == 0) { + (void)memset(p, '\0', _PASSWORD_LEN); + return grp->gr_gid; + } + (void)memset(p, '\0', _PASSWORD_LEN); + } + + errno = EPERM; + return (gid_t)-1; +} + +#ifdef GRUTIL_SETGROUPS_MAKESPACE +# define ADDGRP_MAKESPACE 1 +#else +# define ADDGRP_MAKESPACE 0 +#endif + +#ifdef GRUTIL_ALLOW_GROUP_ERRORS +# define maybe_exit(e) +#else +# define maybe_exit(e) exit(e); +#endif + +void +addgroup( +#ifdef LOGIN_CAP + login_cap_t *lc, +#endif + const char *gname, struct passwd *pwd, uid_t ruid, const char *prompt) +{ + pwd->pw_gid = newgrp(gname, pwd, ruid, prompt); + if (pwd->pw_gid == (gid_t)-1) { + switch (errno) { + case EINVAL: + warnx("Unknown group `%s'", gname); + maybe_exit(EXIT_FAILURE); + break; + case EPERM: /* password failure */ + warnx("Sorry"); + maybe_exit(EXIT_FAILURE); + break; + default: /* XXX - should never happen */ + err(EXIT_FAILURE, "unknown error"); + break; + } + pwd->pw_gid = getgid(); + } + + switch (addgrp(pwd->pw_gid, ADDGRP_MAKESPACE)) { + case ADDGRP_NOERROR: + break; + case ADDGRP_EMALLOC: + err(EXIT_FAILURE, "malloc"); + break; + case ADDGRP_EGETGROUPS: + err(EXIT_FAILURE, "getgroups"); + break; + case ADDGRP_ESETGROUPS: + switch(errno) { + case EINVAL: + warnx("setgroups: ngroups > ngroupsmax"); + maybe_exit(EXIT_FAILURE); + break; + case EPERM: + case EFAULT: + default: + warn("setgroups"); + maybe_exit(EXIT_FAILURE); + break; + } + break; + } + +#ifdef LOGIN_CAP + if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGID) == -1) + err(EXIT_FAILURE, "setting user context"); +#else + if (setgid(pwd->pw_gid) == -1) + err(EXIT_FAILURE, "setgid"); +#endif +} diff --git a/usr.bin/newgrp/grutil.h b/usr.bin/newgrp/grutil.h new file mode 100644 index 0000000..957f798 --- /dev/null +++ b/usr.bin/newgrp/grutil.h @@ -0,0 +1,40 @@ +/* $NetBSD: grutil.h,v 1.2 2008/04/28 20:24:14 martin Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _GRUTIL_H_ +#define _GRUTIL_H_ + +void addgroup( +#ifdef LOGIN_CAP + login_cap_t *, +#endif + const char *, struct passwd *, uid_t, const char *); + +#endif /* _GRUTIL_H_ */ diff --git a/usr.bin/newgrp/newgrp.1 b/usr.bin/newgrp/newgrp.1 new file mode 100644 index 0000000..4bd4785 --- /dev/null +++ b/usr.bin/newgrp/newgrp.1 @@ -0,0 +1,121 @@ +.\" $NetBSD: newgrp.1,v 1.5 2017/07/03 21:34:20 wiz Exp $ +.\" +.\" Copyright (c) 2007, The NetBSD Foundation. +.\" All Rights Reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Brian Ginsbach. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd June 6, 2007 +.Dt NEWGRP 1 +.Os +.Sh NAME +.Nm newgrp +.Nd change to a new primary group +.Sh SYNOPSIS +.Nm +.Op Fl l +.Op Ar group +.Sh DESCRIPTION +The +.Nm +command changes a user to a new primary group +.Pq real and effective group ID +by starting a new shell. +The user remains logged in and the current directory +and file creation mask remain unchanged. +The user is always given a new shell even if +the primary group change fails. +.Pp +The +.Nm +command accepts the following options: +.Bl -tag -width indent +.It Fl l +The environment is changed to what would be expected if the user +actually logged in again. +This simulates a full login. +.El +.Pp +The +.Ar group +is a group name or non-negative numeric group ID from the group database. +The real and effective group IDs are set to +.Ar group +or the group ID associated with the group name. +.Pp +If +.Ar group +is not specified, +.Nm +restores the user's real and effective group IDs to the user's +primary group specified in the password database. +The user's supplementary group IDs are restored to the set specified +for the user in the group database. +.Pp +If the user is not a member of the specified group, and the group +requires a password, the user will be prompted for the group password. +.Sh FILES +.Bl -tag -width /etc/master.passwd -compact +.It Pa /etc/group +The group database +.It Pa /etc/master.passwd +The user database +.It Pa /etc/passwd +A Version 7 format password file +.El +.Sh EXIT STATUS +If a new shell is started the exit status is the exit status of the shell. +Otherwise the exit status will be >0. +.Sh SEE ALSO +.Xr csh 1 , +.Xr groups 1 , +.Xr login 1 , +.Xr sh 1 , +.Xr su 1 , +.Xr umask 2 , +.Xr group 5 , +.Xr passwd 5 , +.Xr environ 7 +.Sh STANDARDS +The +.Nm +command conforms to +.St -p1003.1-2001 . +.Sh HISTORY +A +.Nm +command appeared in +.At v6 . +A +.Nm +command appeared in +.Nx 5.0 . +.Sh BUGS +There is no convenient way to enter a password into +.Pa /etc/group . +The use of group passwords is strongly discouraged +since they are inherently insecure. +It is not possible to stop users from obtaining the encrypted +password from the group database. diff --git a/usr.bin/newgrp/newgrp.c b/usr.bin/newgrp/newgrp.c new file mode 100644 index 0000000..61309c3 --- /dev/null +++ b/usr.bin/newgrp/newgrp.c @@ -0,0 +1,195 @@ +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: newgrp.c,v 1.7 2011/09/16 15:39:27 joerg Exp $"); +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/types.h> + +#include <err.h> +#include <grp.h> +#include <libgen.h> +#include <paths.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef LOGIN_CAP +#include <login_cap.h> +#endif + +#include "grutil.h" + +__dead static void +usage(void) +{ + (void)fprintf(stderr, "usage: %s [-l] [group]\n", getprogname()); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + extern char **environ; + struct passwd *pwd; + int c, lflag; + char *shell, sbuf[MAXPATHLEN + 2]; + uid_t uid; +#ifdef LOGIN_CAP + login_cap_t *lc; + u_int flags = LOGIN_SETUSER; +#endif + + uid = getuid(); + pwd = getpwuid(uid); + if (pwd == NULL) + errx(EXIT_FAILURE, "who are you?"); + +#ifdef LOGIN_CAP + if ((lc = login_getclass(pwd->pw_class)) == NULL) + errx(EXIT_FAILURE, "%s: unknown login class", pwd->pw_class); +#endif + + (void)setprogname(argv[0]); + lflag = 0; + while ((c = getopt(argc, argv, "-l")) != -1) { + switch (c) { + case '-': + case 'l': + if (lflag) + usage(); + lflag = 1; + break; + default: + usage(); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { +#if 0 + pwd->pw_gid = newgrp(*argv, pwd); + addgrp(pwd->pw_gid); + if (setgid(pwd->pw_gid) < 0) + err(1, "setgid"); +#endif +#ifdef LOGIN_CAP + addgroup(lc, *argv, pwd, getuid(), "Password:"); +#else + addgroup(*argv, pwd, getuid(), "Password:"); +#endif + } else { +#ifdef LOGIN_CAP + flags |= LOGIN_SETGROUP; +#else + if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) + err(EXIT_FAILURE, "initgroups"); + if (setgid(pwd->pw_gid) == -1) + err(EXIT_FAILURE, "setgid"); +#endif + } + +#ifdef LOGIN_CAP + if (setusercontext(lc, pwd, uid, flags) == -1) + err(EXIT_FAILURE, "setusercontext"); + if (!lflag) + login_close(lc); +#else + if (setuid(pwd->pw_uid) == -1) + err(EXIT_FAILURE, "setuid"); +#endif + + if (*pwd->pw_shell == '\0') { +#ifdef TRUST_ENV_SHELL + shell = getenv("SHELL"); + if (shell != NULL) + pwd->pw_shell = shell; + else +#endif + pwd->pw_shell = __UNCONST(_PATH_BSHELL); + } + + shell = pwd->pw_shell; + + if (lflag) { + char *term; +#ifdef KERBEROS + char *krbtkfile; +#endif + + if (chdir(pwd->pw_dir) == -1) + warn("%s", pwd->pw_dir); + + term = getenv("TERM"); +#ifdef KERBEROS + krbtkfile = getenv("KRBTKFILE"); +#endif + + /* create an empty environment */ + if ((environ = malloc(sizeof(char *))) == NULL) + err(EXIT_FAILURE, NULL); + environ[0] = NULL; +#ifdef LOGIN_CAP + if (setusercontext(lc, pwd, uid, LOGIN_SETENV | LOGIN_SETPATH) == -1) + err(EXIT_FAILURE, "setusercontext"); + login_close(lc); +#else + (void)setenv("PATH", _PATH_DEFPATH, 1); +#endif + if (term != NULL) + (void)setenv("TERM", term, 1); +#ifdef KERBEROS + if (krbtkfile != NULL) + (void)setenv("KRBTKFILE", krbtkfile, 1); +#endif + + (void)setenv("LOGNAME", pwd->pw_name, 1); + (void)setenv("USER", pwd->pw_name, 1); + (void)setenv("HOME", pwd->pw_dir, 1); + (void)setenv("SHELL", pwd->pw_shell, 1); + + sbuf[0] = '-'; + (void)strlcpy(sbuf + 1, basename(pwd->pw_shell), + sizeof(sbuf) - 1); + shell = sbuf; + } + + (void)execl(pwd->pw_shell, shell, NULL); + err(EXIT_FAILURE, "%s", pwd->pw_shell); + /* NOTREACHED */ +} |