* Remove --enable-setuid, --with-nix-user and --with-nix-group.
Rather, setuid support is now always compiled in (at least on platforms that have the setresuid system call, e.g., Linux and FreeBSD), but it must enabled by chowning/chmodding the Nix binaries.
This commit is contained in:
parent
c6a97e3b74
commit
71e867c5f5
10
Makefile.am
10
Makefile.am
|
@ -20,10 +20,11 @@ install-data-local: init-state
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if INIT_STATE
|
if INIT_STATE
|
||||||
if SETUID_HACK
|
|
||||||
INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@
|
# For setuid operation, you can enable the following:
|
||||||
GROUP_WRITABLE = -m 775
|
# INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@
|
||||||
endif
|
# GROUP_WRITABLE = -m 775
|
||||||
|
|
||||||
init-state:
|
init-state:
|
||||||
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix
|
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix
|
||||||
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/db
|
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/db
|
||||||
|
@ -40,6 +41,7 @@ init-state:
|
||||||
$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(prefix)/store
|
$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(prefix)/store
|
||||||
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests
|
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests
|
||||||
# $(bindir)/nix-store --init
|
# $(bindir)/nix-store --init
|
||||||
|
|
||||||
else
|
else
|
||||||
init-state:
|
init-state:
|
||||||
endif
|
endif
|
||||||
|
|
20
configure.ac
20
configure.ac
|
@ -237,32 +237,12 @@ AM_CONDITIONAL(INIT_STATE, test "$init_state" = "yes")
|
||||||
|
|
||||||
|
|
||||||
# Setuid installations.
|
# Setuid installations.
|
||||||
AC_ARG_ENABLE(setuid, AC_HELP_STRING([--enable-setuid],
|
|
||||||
[install Nix setuid]),
|
|
||||||
setuid_hack=$enableval, setuid_hack=no)
|
|
||||||
AM_CONDITIONAL(SETUID_HACK, test "$setuid_hack" = "yes")
|
|
||||||
if test "$setuid_hack" = "yes"; then
|
|
||||||
AC_DEFINE(SETUID_HACK, 1, [whether to install Nix setuid])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_CHECK_FUNC(setresuid, [HAVE_SETRESUID=1], [HAVE_SETRESUID=])
|
AC_CHECK_FUNC(setresuid, [HAVE_SETRESUID=1], [HAVE_SETRESUID=])
|
||||||
AM_CONDITIONAL(HAVE_SETRESUID, test "$HAVE_SETRESUID" = "1")
|
AM_CONDITIONAL(HAVE_SETRESUID, test "$HAVE_SETRESUID" = "1")
|
||||||
if test "$HAVE_SETRESUID" = "1"; then
|
if test "$HAVE_SETRESUID" = "1"; then
|
||||||
AC_DEFINE(HAVE_SETRESUID, 1, [whether we have setresuid()])
|
AC_DEFINE(HAVE_SETRESUID, 1, [whether we have setresuid()])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH(nix-user, AC_HELP_STRING([--with-nix-user=USER],
|
|
||||||
[user for Nix setuid binaries]),
|
|
||||||
NIX_USER=$withval, NIX_USER=nix)
|
|
||||||
AC_SUBST(NIX_USER)
|
|
||||||
AC_DEFINE_UNQUOTED(NIX_USER, ["$NIX_USER"], [Nix user])
|
|
||||||
|
|
||||||
AC_ARG_WITH(nix-group, AC_HELP_STRING([--with-nix-group=USER],
|
|
||||||
[group for Nix setuid binaries]),
|
|
||||||
NIX_GROUP=$withval, NIX_GROUP=nix)
|
|
||||||
AC_SUBST(NIX_GROUP)
|
|
||||||
AC_DEFINE_UNQUOTED(NIX_GROUP, ["$NIX_GROUP"], [Nix group])
|
|
||||||
|
|
||||||
|
|
||||||
# This is needed if ATerm, Berkeley DB or bzip2 are static libraries,
|
# This is needed if ATerm, Berkeley DB or bzip2 are static libraries,
|
||||||
# and the Nix libraries are dynamic.
|
# and the Nix libraries are dynamic.
|
||||||
|
|
|
@ -3,13 +3,4 @@ SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
|
||||||
|
|
||||||
EXTRA_DIST = aterm-helper.pl
|
EXTRA_DIST = aterm-helper.pl
|
||||||
|
|
||||||
SETUID_PROGS = nix-store nix-instantiate nix-env
|
#SETUID_PROGS = nix-store nix-instantiate nix-env
|
||||||
install-exec-hook:
|
|
||||||
if SETUID_HACK
|
|
||||||
if HAVE_SETRESUID
|
|
||||||
cd $(DESTDIR)$(bindir) && chown @NIX_USER@ $(SETUID_PROGS) \
|
|
||||||
&& chgrp @NIX_GROUP@ $(SETUID_PROGS) && chmod ug+s $(SETUID_PROGS)
|
|
||||||
else
|
|
||||||
cd $(DESTDIR)$(bindir) && chown root $(SETUID_PROGS) && chmod u+s $(SETUID_PROGS)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
|
@ -911,7 +911,7 @@ static gid_t savedGid, nixGid;
|
||||||
|
|
||||||
SwitchToOriginalUser::SwitchToOriginalUser()
|
SwitchToOriginalUser::SwitchToOriginalUser()
|
||||||
{
|
{
|
||||||
#if SETUID_HACK && HAVE_SETRESUID
|
#if HAVE_SETRESUID
|
||||||
/* Temporarily switch the effective uid/gid back to the saved
|
/* Temporarily switch the effective uid/gid back to the saved
|
||||||
uid/gid (which is the uid/gid of the user that executed the Nix
|
uid/gid (which is the uid/gid of the user that executed the Nix
|
||||||
program; it's *not* the real uid/gid, since we changed that to
|
program; it's *not* the real uid/gid, since we changed that to
|
||||||
|
@ -928,7 +928,7 @@ SwitchToOriginalUser::SwitchToOriginalUser()
|
||||||
|
|
||||||
SwitchToOriginalUser::~SwitchToOriginalUser()
|
SwitchToOriginalUser::~SwitchToOriginalUser()
|
||||||
{
|
{
|
||||||
#if SETUID_HACK && HAVE_SETRESUID
|
#if HAVE_SETRESUID
|
||||||
/* Switch the effective uid/gid back to the Nix user. */
|
/* Switch the effective uid/gid back to the Nix user. */
|
||||||
if (haveSwitched) {
|
if (haveSwitched) {
|
||||||
if (setuid(nixUid) == -1)
|
if (setuid(nixUid) == -1)
|
||||||
|
@ -942,21 +942,43 @@ SwitchToOriginalUser::~SwitchToOriginalUser()
|
||||||
|
|
||||||
void switchToNixUser()
|
void switchToNixUser()
|
||||||
{
|
{
|
||||||
#if SETUID_HACK
|
fprintf(stderr, "real = %d/%d, effective = %d/%d\n",
|
||||||
|
getuid(), geteuid(), getgid(), getegid());
|
||||||
|
|
||||||
|
/* Note: we require setresuid for now since I don't want to think
|
||||||
|
to deeply about whether this works on systems that don't have
|
||||||
|
setresuid. It's already hard enough. */
|
||||||
|
|
||||||
|
#if HAVE_SETRESUID
|
||||||
|
|
||||||
|
/* Setuid Nix operation works as follows:
|
||||||
|
|
||||||
|
- The Nix binaries are owned by a Nix user and group, e.g.,
|
||||||
|
nix.nix, and must setuid and setgid, e.g.,
|
||||||
|
|
||||||
|
rwsrwsr-x nix.nix
|
||||||
|
|
||||||
|
- Users (say alice.users) are only allowed to run (most) Nix
|
||||||
|
operations if they are in the Nix group. If they aren't,
|
||||||
|
some read-only operations (like nix-env -qa) may still work.
|
||||||
|
|
||||||
|
- We run mostly under the Nix user/group, but we switch back to
|
||||||
|
the calling user/group for some work, like reading Nix
|
||||||
|
expressions.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Don't do anything if this is not a setuid binary. */
|
/* Don't do anything if this is not a setuid binary. */
|
||||||
if (getuid() == geteuid() && getgid() == getegid()) return;
|
if (getuid() == geteuid() && getgid() == getegid()) return;
|
||||||
|
|
||||||
/* Here we set the uid and gid to the Nix user and group,
|
/* Here we set the uid and gid to the Nix user and group,
|
||||||
respectively, IF the current (real) user is a member of the Nix
|
respectively, IF the current (real) user is a member of the Nix
|
||||||
group. Otherwise we just drop all privileges. */
|
group. (The Nix group is the group of the current executable,
|
||||||
|
i.e., the current effective gid.) Otherwise we just drop all
|
||||||
|
privileges. */
|
||||||
|
|
||||||
/* Lookup the Nix gid. */
|
nixGid = geteuid();
|
||||||
struct group * gr = getgrnam(NIX_GROUP);
|
|
||||||
if (!gr) {
|
|
||||||
std::cerr << format("missing group `%1%'\n") % NIX_GROUP;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the supplementary group IDs for the current user. */
|
/* Get the supplementary group IDs for the current user. */
|
||||||
int maxGids = 512, nrGids;
|
int maxGids = 512, nrGids;
|
||||||
|
@ -976,7 +998,7 @@ void switchToNixUser()
|
||||||
/* Check that the current user is a member of the Nix group. */
|
/* Check that the current user is a member of the Nix group. */
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < nrGids; ++i)
|
for (int i = 0; i < nrGids; ++i)
|
||||||
if (gids[i] == gr->gr_gid) {
|
if (gids[i] == nixGid) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -988,31 +1010,29 @@ void switchToNixUser()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the uid/gid of the caller so the we can switch back to
|
||||||
|
that uid/gid for temporary work, like accessing files, in
|
||||||
|
SwitchToOriginaluser. */
|
||||||
savedUid = getuid();
|
savedUid = getuid();
|
||||||
savedGid = getgid();
|
savedGid = getgid();
|
||||||
|
|
||||||
/* Set the real, effective and saved gids to gr->gr_gid. Also
|
/* Set the real and effective gids to nixGid. Also make very sure
|
||||||
make very sure that this succeeded. We switch the gid first
|
that this succeeded. We switch the gid first because we cannot
|
||||||
because we cannot do it after we have dropped root uid. */
|
do it after we have dropped root uid. */
|
||||||
nixGid = gr->gr_gid;
|
|
||||||
if (_setgid(nixGid) != 0 || getgid() != nixGid || getegid() != nixGid) {
|
if (_setgid(nixGid) != 0 || getgid() != nixGid || getegid() != nixGid) {
|
||||||
std::cerr << format("unable to set gid to `%1%'\n") % NIX_GROUP;
|
std::cerr << format("unable to set gid to `%1%'\n") % nixGid;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup the Nix uid. */
|
/* The Nix uid is the effective uid of the owner of the current
|
||||||
struct passwd * pw = getpwnam(NIX_USER);
|
executable, i.e., the current effective uid. */
|
||||||
if (!pw) {
|
nixUid = geteuid();
|
||||||
std::cerr << format("missing user `%1%'\n") % NIX_USER;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This will drop all root privileges, setting the real, effective
|
/* This will drop all root privileges, setting the real, effective
|
||||||
and saved uids to pw->pw_uid. Also make very sure that this
|
and saved uids to pw->pw_uid. Also make very sure that this
|
||||||
succeeded.*/
|
succeeded.*/
|
||||||
nixUid = pw->pw_uid;
|
|
||||||
if (_setuid(nixUid) != 0 || getuid() != nixUid || geteuid() != nixUid) {
|
if (_setuid(nixUid) != 0 || getuid() != nixUid || geteuid() != nixUid) {
|
||||||
std::cerr << format("unable to set uid to `%1%'\n") % NIX_USER;
|
std::cerr << format("unable to set uid to `%1%'\n") % nixUid;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,7 +1042,6 @@ void switchToNixUser()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
haveSwitched = true;
|
haveSwitched = true;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue