When running a login shell with a login_class specified, use
LOGIN_SETENV instead of rolling our own login.conf setenv support since FreeBSD's login.conf has more than just setenv capabilities. This requires us to swap the plugin-provided envp for the global environ before calling setusercontext() and then stash the resulting environ pointer back into the command details, which is kind of a hack.
This commit is contained in:
1
MANIFEST
1
MANIFEST
@@ -179,7 +179,6 @@ plugins/sudoers/linux_audit.c
|
|||||||
plugins/sudoers/linux_audit.h
|
plugins/sudoers/linux_audit.h
|
||||||
plugins/sudoers/logging.c
|
plugins/sudoers/logging.c
|
||||||
plugins/sudoers/logging.h
|
plugins/sudoers/logging.h
|
||||||
plugins/sudoers/login_class.c
|
|
||||||
plugins/sudoers/logwrap.c
|
plugins/sudoers/logwrap.c
|
||||||
plugins/sudoers/match.c
|
plugins/sudoers/match.c
|
||||||
plugins/sudoers/match_addr.c
|
plugins/sudoers/match_addr.c
|
||||||
|
1
configure
vendored
1
configure
vendored
@@ -15445,7 +15445,6 @@ _ACEOF
|
|||||||
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
|
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
SUDOERS_OBJS="${SUDOERS_OBJS} login_class.lo"
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -1990,7 +1990,6 @@ if test ${with_logincap-'no'} != "no"; then
|
|||||||
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
|
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
SUDOERS_OBJS="${SUDOERS_OBJS} login_class.lo"
|
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
if test ${with_project-'no'} != "no"; then
|
if test ${with_project-'no'} != "no"; then
|
||||||
|
2
mkdep.pl
2
mkdep.pl
@@ -52,7 +52,7 @@ sub mkdep {
|
|||||||
$makefile =~ s:\@DEV\@::g;
|
$makefile =~ s:\@DEV\@::g;
|
||||||
$makefile =~ s:\@COMMON_OBJS\@:aix.lo:;
|
$makefile =~ s:\@COMMON_OBJS\@:aix.lo:;
|
||||||
$makefile =~ s:\@SUDO_OBJS\@:preload.o selinux.o sesh.o sudo_noexec.lo:;
|
$makefile =~ s:\@SUDO_OBJS\@:preload.o selinux.o sesh.o sudo_noexec.lo:;
|
||||||
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo plugin_error.lo login_class.lo:;
|
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo plugin_error.lo:;
|
||||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||||
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo glob.lo isblank.lo memrchr.lo mksiglist.lo mktemp.lo nanosleep.lo setenv.lo siglist.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo unsetenv.lo utimes.lo globtest.o fnm_test.o:;
|
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo glob.lo isblank.lo memrchr.lo mksiglist.lo mktemp.lo nanosleep.lo setenv.lo siglist.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo unsetenv.lo utimes.lo globtest.o fnm_test.o:;
|
||||||
|
@@ -579,15 +579,6 @@ logging.lo: $(srcdir)/logging.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
|||||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/logging.c
|
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/logging.c
|
||||||
login_class.lo: $(srcdir)/login_class.c $(top_builddir)/config.h \
|
|
||||||
$(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
|
|
||||||
$(top_builddir)/pathnames.h $(incdir)/missing.h \
|
|
||||||
$(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
|
|
||||||
$(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
|
|
||||||
$(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
|
||||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
|
||||||
$(incdir)/gettext.h
|
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/login_class.c
|
|
||||||
logwrap.lo: $(srcdir)/logwrap.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
logwrap.lo: $(srcdir)/logwrap.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||||
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
||||||
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
|
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
|
||||||
|
@@ -98,6 +98,7 @@ struct environment {
|
|||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
static void sudo_setenv(const char *, const char *, int);
|
||||||
static void sudo_putenv(char *, int, int);
|
static void sudo_putenv(char *, int, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -239,7 +240,7 @@ env_get(void)
|
|||||||
* (not environ) and it always overwrites. The dupcheck param determines
|
* (not environ) and it always overwrites. The dupcheck param determines
|
||||||
* whether we need to verify that the variable is not already set.
|
* whether we need to verify that the variable is not already set.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
sudo_setenv(const char *var, const char *val, int dupcheck)
|
sudo_setenv(const char *var, const char *val, int dupcheck)
|
||||||
{
|
{
|
||||||
char *estring;
|
char *estring;
|
||||||
|
@@ -1,227 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2004, 2011 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <stddef.h>
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_STDLIB_H
|
|
||||||
# include <stdlib.h>
|
|
||||||
# endif
|
|
||||||
#endif /* STDC_HEADERS */
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
# include <string.h>
|
|
||||||
#endif /* HAVE_STRING_H */
|
|
||||||
#ifdef HAVE_STRINGS_H
|
|
||||||
# include <strings.h>
|
|
||||||
#endif /* HAVE_STRING_H */
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif /* HAVE_UNISTD_H */
|
|
||||||
#include <pwd.h>
|
|
||||||
|
|
||||||
#include <login_cap.h>
|
|
||||||
|
|
||||||
#include "sudoers.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether or not a tilde in a string should be expanded.
|
|
||||||
* We only do expansion for things like "~", "~/...", ~me", "~me/...".
|
|
||||||
*/
|
|
||||||
#define tilde_valid(s, u, l) \
|
|
||||||
((s)[1] == '/' || (s)[1] == '\0' || \
|
|
||||||
(strncmp((s)+1, u, l) == 0 && ((s)[l+1] == '/' || (s)[l+1] == '\0')))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make a copy of a string, expanding '~' to the user's homedir, '$' to the
|
|
||||||
* login name and other escape sequences as per cgetstr(3).
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
expandstr(const char *ostr, const struct passwd *pwd)
|
|
||||||
{
|
|
||||||
size_t n, olen, nlen, ulen, dlen;
|
|
||||||
const char *ep, *eo, *op;
|
|
||||||
char *nstr, *np;
|
|
||||||
int ch;
|
|
||||||
|
|
||||||
/* calculate the size of the new string */
|
|
||||||
ulen = strlen(pwd->pw_name);
|
|
||||||
dlen = strlen(pwd->pw_dir);
|
|
||||||
olen = nlen = strlen(ostr);
|
|
||||||
for (op = ostr, ep = ostr + olen; op < ep; op++) {
|
|
||||||
switch (*op) {
|
|
||||||
case '~':
|
|
||||||
if (!tilde_valid(op, pwd->pw_name, ulen))
|
|
||||||
break;
|
|
||||||
if (op[1] != '/' && op[1] != '\0') {
|
|
||||||
op += ulen; /* ~username */
|
|
||||||
nlen = nlen - ulen - 1 + dlen;
|
|
||||||
} else
|
|
||||||
nlen += dlen - 1;
|
|
||||||
break;
|
|
||||||
case '$':
|
|
||||||
nlen += ulen - 1;
|
|
||||||
break;
|
|
||||||
case '^':
|
|
||||||
/* control char */
|
|
||||||
if (*++op != '\0')
|
|
||||||
nlen--;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
if (op[1] == '\0')
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
* Byte in octal notation (\123) or an escaped char (\t)
|
|
||||||
*/
|
|
||||||
eo = op + 4;
|
|
||||||
do {
|
|
||||||
op++;
|
|
||||||
nlen--;
|
|
||||||
} while (op < eo && *op >= '0' && *op <= '7');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
np = nstr = emalloc(++nlen);
|
|
||||||
|
|
||||||
for (op = ostr, ep = ostr + olen; op < ep; op++) {
|
|
||||||
switch ((ch = *op)) {
|
|
||||||
case '~':
|
|
||||||
if (!tilde_valid(op, pwd->pw_name, ulen))
|
|
||||||
break;
|
|
||||||
if (op[1] != '/' && op[1] != '\0')
|
|
||||||
op += ulen; /* ~username */
|
|
||||||
strlcpy(np, pwd->pw_dir, nlen);
|
|
||||||
nlen -= dlen;
|
|
||||||
np += dlen;
|
|
||||||
continue;
|
|
||||||
case '$':
|
|
||||||
strlcpy(np, pwd->pw_name, nlen);
|
|
||||||
nlen -= ulen;
|
|
||||||
np += ulen;
|
|
||||||
continue;
|
|
||||||
case '^':
|
|
||||||
if (op[1] != '\0')
|
|
||||||
ch = *++op & 037;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
if (op[1] == '\0')
|
|
||||||
break;
|
|
||||||
switch(*++op) {
|
|
||||||
case '0': case '1': case '2': case '3':
|
|
||||||
case '4': case '5': case '6': case '7':
|
|
||||||
/* byte in octal up to 3 digits long */
|
|
||||||
ch = 0;
|
|
||||||
n = 3;
|
|
||||||
do {
|
|
||||||
ch = ch * 8 + (*op++ - '0');
|
|
||||||
} while (--n && *op >= '0' && *op <= '7');
|
|
||||||
break;
|
|
||||||
case 'b': case 'B':
|
|
||||||
ch = '\b';
|
|
||||||
break;
|
|
||||||
case 't': case 'T':
|
|
||||||
ch = '\t';
|
|
||||||
break;
|
|
||||||
case 'n': case 'N':
|
|
||||||
ch = '\n';
|
|
||||||
break;
|
|
||||||
case 'f': case 'F':
|
|
||||||
ch = '\f';
|
|
||||||
break;
|
|
||||||
case 'r': case 'R':
|
|
||||||
ch = '\r';
|
|
||||||
break;
|
|
||||||
case 'e': case 'E':
|
|
||||||
ch = '\033';
|
|
||||||
break;
|
|
||||||
case 'c': case 'C':
|
|
||||||
ch = ':';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ch = *op;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*np++ = ch;
|
|
||||||
nlen--;
|
|
||||||
}
|
|
||||||
*np = '\0';
|
|
||||||
return (nstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set an environment variable, substituting for ~ and $
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
login_setenv(char *name, char *ovalue, const struct passwd *pwd)
|
|
||||||
{
|
|
||||||
char *value = NULL;
|
|
||||||
|
|
||||||
if (*ovalue != '\0')
|
|
||||||
value = expandstr(ovalue, pwd);
|
|
||||||
sudo_setenv(name, value ? value : ovalue, 1);
|
|
||||||
efree(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look up "setenv" for this user in login.conf and set the comma-separated
|
|
||||||
* list of environment variables, expanding '~' and '$'.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
sudo_login_setenv(login_cap_t *lc, const struct passwd *pwd)
|
|
||||||
{
|
|
||||||
char *beg, *end, *ep, *list, *value;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (lc == NULL || lc->lc_cap == NULL)
|
|
||||||
return (-1); /* impossible */
|
|
||||||
|
|
||||||
if ((len = cgetustr(lc->lc_cap, "setenv", &list)) <= 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
for (beg = end = list, ep = list + len + 1; end < ep; end++) {
|
|
||||||
switch (*end) {
|
|
||||||
case '\\':
|
|
||||||
if (*(end + 1) == ',')
|
|
||||||
end++; /* skip escaped comma */
|
|
||||||
continue;
|
|
||||||
case ',':
|
|
||||||
case '\0':
|
|
||||||
*end = '\0';
|
|
||||||
if (beg == end) {
|
|
||||||
beg++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((value = strchr(beg, '=')) != NULL)
|
|
||||||
*value++ = '\0';
|
|
||||||
else
|
|
||||||
value = "";
|
|
||||||
login_setenv(beg, value, pwd);
|
|
||||||
beg = end + 1;
|
|
||||||
}
|
|
||||||
efree(list);
|
|
||||||
return (0);
|
|
||||||
}
|
|
@@ -127,9 +127,6 @@ static char *runas_group;
|
|||||||
static struct sudo_nss_list *snl;
|
static struct sudo_nss_list *snl;
|
||||||
static const char *interfaces_string;
|
static const char *interfaces_string;
|
||||||
static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
|
static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
|
||||||
#ifdef HAVE_LOGIN_CAP_H
|
|
||||||
static login_cap_t *lc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* XXX - must be extern for audit bits of sudo_auth.c */
|
/* XXX - must be extern for audit bits of sudo_auth.c */
|
||||||
int NewArgc;
|
int NewArgc;
|
||||||
@@ -595,16 +592,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
|||||||
#if defined(__linux__) || defined(_AIX)
|
#if defined(__linux__) || defined(_AIX)
|
||||||
/* Insert system-wide environment variables. */
|
/* Insert system-wide environment variables. */
|
||||||
read_env_file(_PATH_ENVIRONMENT, true);
|
read_env_file(_PATH_ENVIRONMENT, true);
|
||||||
#elif defined(HAVE_LOGIN_CAP_H)
|
|
||||||
/* Insert login class-specific environment variables. */
|
|
||||||
if (lc != NULL)
|
|
||||||
sudo_login_setenv(lc, runas_pw);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LOGIN_CAP_H
|
|
||||||
login_close(lc);
|
|
||||||
lc = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Insert system-wide environment variables. */
|
/* Insert system-wide environment variables. */
|
||||||
if (def_env_file)
|
if (def_env_file)
|
||||||
@@ -1015,6 +1004,7 @@ static void
|
|||||||
set_loginclass(struct passwd *pw)
|
set_loginclass(struct passwd *pw)
|
||||||
{
|
{
|
||||||
int errflags;
|
int errflags;
|
||||||
|
login_cap_t *lc;
|
||||||
debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
|
debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
|
||||||
|
|
||||||
if (!def_use_loginclass)
|
if (!def_use_loginclass)
|
||||||
@@ -1047,6 +1037,7 @@ set_loginclass(struct passwd *pw)
|
|||||||
log_error(errflags, _("unknown login class: %s"), login_class);
|
log_error(errflags, _("unknown login class: %s"), login_class);
|
||||||
def_use_loginclass = false;
|
def_use_loginclass = false;
|
||||||
}
|
}
|
||||||
|
login_close(lc);
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@@ -197,7 +197,6 @@ struct lbuf;
|
|||||||
struct passwd;
|
struct passwd;
|
||||||
struct stat;
|
struct stat;
|
||||||
struct timeval;
|
struct timeval;
|
||||||
struct login_cap;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function prototypes
|
* Function prototypes
|
||||||
@@ -306,7 +305,6 @@ void init_envtables(void);
|
|||||||
void insert_env_vars(char * const envp[]);
|
void insert_env_vars(char * const envp[]);
|
||||||
void read_env_file(const char *, int);
|
void read_env_file(const char *, int);
|
||||||
void rebuild_env(void);
|
void rebuild_env(void);
|
||||||
void sudo_setenv(const char *var, const char *val, int dupcheck);
|
|
||||||
void validate_env_vars(char * const envp[]);
|
void validate_env_vars(char * const envp[]);
|
||||||
|
|
||||||
/* fmt_string.c */
|
/* fmt_string.c */
|
||||||
@@ -330,9 +328,6 @@ int group_plugin_query(const char *user, const char *group,
|
|||||||
/* setgroups.c */
|
/* setgroups.c */
|
||||||
int sudo_setgroups(int ngids, const GETGROUPS_T *gids);
|
int sudo_setgroups(int ngids, const GETGROUPS_T *gids);
|
||||||
|
|
||||||
/* login_cap.c */
|
|
||||||
int sudo_login_setenv(struct login_cap *lc, const struct passwd *pwd);
|
|
||||||
|
|
||||||
#ifndef _SUDO_MAIN
|
#ifndef _SUDO_MAIN
|
||||||
extern struct sudo_user sudo_user;
|
extern struct sudo_user sudo_user;
|
||||||
extern struct passwd *list_pw;
|
extern struct passwd *list_pw;
|
||||||
|
25
src/sudo.c
25
src/sudo.c
@@ -103,6 +103,7 @@ struct plugin_container_list io_plugins;
|
|||||||
struct user_details user_details;
|
struct user_details user_details;
|
||||||
const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */
|
const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */
|
||||||
int debug_level;
|
int debug_level;
|
||||||
|
static int sudo_mode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local functions
|
* Local functions
|
||||||
@@ -153,10 +154,14 @@ static struct rlimit corelimit;
|
|||||||
static struct rlimit nproclimit;
|
static struct rlimit nproclimit;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LOGIN_CAP_H
|
||||||
|
extern char **environ;
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[], char *envp[])
|
main(int argc, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
int nargc, ok, sudo_mode, exitcode = 0;
|
int nargc, ok, exitcode = 0;
|
||||||
char **nargv, **settings, **env_add;
|
char **nargv, **settings, **env_add;
|
||||||
char **user_info, **command_info, **argv_out, **user_env_out;
|
char **user_info, **command_info, **argv_out, **user_env_out;
|
||||||
struct plugin_container *plugin, *next;
|
struct plugin_container *plugin, *next;
|
||||||
@@ -951,7 +956,8 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
|
|||||||
login_cap_t *lc;
|
login_cap_t *lc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only use setusercontext() to set the nice value and rlimits.
|
* We only use setusercontext() to set the nice value and rlimits
|
||||||
|
* unless this is a login shell (sudo -i).
|
||||||
*/
|
*/
|
||||||
lc = login_getclass((char *)details->login_class);
|
lc = login_getclass((char *)details->login_class);
|
||||||
if (!lc) {
|
if (!lc) {
|
||||||
@@ -959,7 +965,16 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
|
|||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
|
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||||
|
/* Set everything except user, group and login name. */
|
||||||
|
flags = LOGIN_SETALL;
|
||||||
|
CLR(flags, LOGIN_SETGROUP|LOGIN_SETLOGIN|LOGIN_SETUSER);
|
||||||
|
CLR(details->flags, CD_SET_UMASK); /* LOGIN_UMASK instead */
|
||||||
|
/* Swap in the plugin-supplied environment for LOGIN_SETENV */
|
||||||
|
environ = details->envp;
|
||||||
|
} else {
|
||||||
|
flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
|
||||||
|
}
|
||||||
if (setusercontext(lc, pw, pw->pw_uid, flags)) {
|
if (setusercontext(lc, pw, pw->pw_uid, flags)) {
|
||||||
if (pw->pw_uid != ROOT_UID) {
|
if (pw->pw_uid != ROOT_UID) {
|
||||||
warning(_("unable to set user context"));
|
warning(_("unable to set user context"));
|
||||||
@@ -967,6 +982,10 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
|
|||||||
} else
|
} else
|
||||||
warning(_("unable to set user context"));
|
warning(_("unable to set user context"));
|
||||||
}
|
}
|
||||||
|
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||||
|
/* Stash the updated environment pointer in command details */
|
||||||
|
details->envp = environ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LOGIN_CAP_H */
|
#endif /* HAVE_LOGIN_CAP_H */
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user