plugins/sudoers/linux_audit.h
plugins/sudoers/logging.c
plugins/sudoers/logging.h
-plugins/sudoers/login_class.c
plugins/sudoers/logwrap.c
plugins/sudoers/match.c
plugins/sudoers/match_addr.c
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
;;
esac
- SUDOERS_OBJS="${SUDOERS_OBJS} login_class.lo"
fi
SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
;;
esac
- SUDOERS_OBJS="${SUDOERS_OBJS} login_class.lo"
])
fi
if test ${with_project-'no'} != "no"; then
$makefile =~ s:\@DEV\@::g;
$makefile =~ s:\@COMMON_OBJS\@:aix.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
$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:;
$(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)/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 \
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
/*
* Prototypes
*/
+static void sudo_setenv(const char *, const char *, int);
static void sudo_putenv(char *, int, int);
/*
* (not environ) and it always overwrites. The dupcheck param determines
* 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)
{
char *estring;
+++ /dev/null
-/*
- * 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);
-}
static struct sudo_nss_list *snl;
static const char *interfaces_string;
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 */
int NewArgc;
#if defined(__linux__) || defined(_AIX)
/* Insert system-wide environment variables. */
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
}
-#ifdef HAVE_LOGIN_CAP_H
- login_close(lc);
- lc = NULL;
-#endif
/* Insert system-wide environment variables. */
if (def_env_file)
set_loginclass(struct passwd *pw)
{
int errflags;
+ login_cap_t *lc;
debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
if (!def_use_loginclass)
log_error(errflags, _("unknown login class: %s"), login_class);
def_use_loginclass = false;
}
+ login_close(lc);
debug_return;
}
#else
struct passwd;
struct stat;
struct timeval;
-struct login_cap;
/*
* Function prototypes
void insert_env_vars(char * const envp[]);
void read_env_file(const char *, int);
void rebuild_env(void);
-void sudo_setenv(const char *var, const char *val, int dupcheck);
void validate_env_vars(char * const envp[]);
/* fmt_string.c */
/* setgroups.c */
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
extern struct sudo_user sudo_user;
extern struct passwd *list_pw;
struct user_details user_details;
const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */
int debug_level;
+static int sudo_mode;
/*
* Local functions
static struct rlimit nproclimit;
#endif
+#ifdef HAVE_LOGIN_CAP_H
+extern char **environ;
+#endif
+
int
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 **user_info, **command_info, **argv_out, **user_env_out;
struct plugin_container *plugin, *next;
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);
if (!lc) {
errno = ENOENT;
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 (pw->pw_uid != ROOT_UID) {
warning(_("unable to set user context"));
} else
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 */
}