* 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
					
				
					 4 changed files with 52 additions and 60 deletions
				
			
		
							
								
								
									
										10
									
								
								Makefile.am
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								Makefile.am
									
										
									
									
									
								
							|  | @ -20,10 +20,11 @@ install-data-local: init-state | |||
| 	fi | ||||
| 
 | ||||
| if INIT_STATE | ||||
| if SETUID_HACK | ||||
| INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@ | ||||
| GROUP_WRITABLE = -m 775 | ||||
| endif | ||||
| 
 | ||||
| # For setuid operation, you can enable the following: | ||||
| # INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@ | ||||
| # GROUP_WRITABLE = -m 775 | ||||
| 
 | ||||
| init-state: | ||||
| 	$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix | ||||
| 	$(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) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests | ||||
| #	$(bindir)/nix-store --init | ||||
| 
 | ||||
| else | ||||
| init-state: | ||||
| endif | ||||
|  |  | |||
							
								
								
									
										20
									
								
								configure.ac
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								configure.ac
									
										
									
									
									
								
							|  | @ -237,33 +237,13 @@ AM_CONDITIONAL(INIT_STATE, test "$init_state" = "yes") | |||
| 
 | ||||
| 
 | ||||
| # 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=]) | ||||
| AM_CONDITIONAL(HAVE_SETRESUID, test "$HAVE_SETRESUID" = "1") | ||||
| if test "$HAVE_SETRESUID" = "1"; then | ||||
|     AC_DEFINE(HAVE_SETRESUID, 1, [whether we have setresuid()]) | ||||
| 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, | ||||
| # and the Nix libraries are dynamic. | ||||
| if test "$(uname)" = "Darwin"; then | ||||
|  |  | |||
|  | @ -3,13 +3,4 @@ SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \ | |||
| 
 | ||||
| EXTRA_DIST = aterm-helper.pl | ||||
| 
 | ||||
| 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 | ||||
| #SETUID_PROGS = nix-store nix-instantiate nix-env | ||||
|  |  | |||
|  | @ -911,7 +911,7 @@ static gid_t savedGid, nixGid; | |||
| 
 | ||||
| SwitchToOriginalUser::SwitchToOriginalUser() | ||||
| { | ||||
| #if SETUID_HACK && HAVE_SETRESUID | ||||
| #if HAVE_SETRESUID | ||||
|     /* Temporarily switch the effective uid/gid back to the saved
 | ||||
|        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 | ||||
|  | @ -928,7 +928,7 @@ SwitchToOriginalUser::SwitchToOriginalUser() | |||
| 
 | ||||
| SwitchToOriginalUser::~SwitchToOriginalUser() | ||||
| { | ||||
| #if SETUID_HACK && HAVE_SETRESUID | ||||
| #if HAVE_SETRESUID | ||||
|     /* Switch the effective uid/gid back to the Nix user. */ | ||||
|     if (haveSwitched) { | ||||
|         if (setuid(nixUid) == -1) | ||||
|  | @ -942,21 +942,43 @@ SwitchToOriginalUser::~SwitchToOriginalUser() | |||
| 
 | ||||
| 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. */ | ||||
|     if (getuid() == geteuid() && getgid() == getegid()) return; | ||||
| 
 | ||||
|     /* 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 | ||||
|        group.  Otherwise we just drop all privileges. */ | ||||
|      | ||||
|     /* Lookup the Nix gid. */ | ||||
|     struct group * gr = getgrnam(NIX_GROUP); | ||||
|     if (!gr) { | ||||
|         std::cerr << format("missing group `%1%'\n") % NIX_GROUP; | ||||
|         exit(1); | ||||
|     } | ||||
|        group.  (The Nix group is the group of the current executable, | ||||
|        i.e., the current effective gid.)  Otherwise we just drop all | ||||
|        privileges. */ | ||||
| 
 | ||||
|     nixGid = geteuid(); | ||||
| 
 | ||||
|     /* Get the supplementary group IDs for the current user. */ | ||||
|     int maxGids = 512, nrGids; | ||||
|  | @ -976,7 +998,7 @@ void switchToNixUser() | |||
|     /* Check that the current user is a member of the Nix group. */ | ||||
|     bool found = false; | ||||
|     for (int i = 0; i < nrGids; ++i) | ||||
|         if (gids[i] == gr->gr_gid) { | ||||
|         if (gids[i] == nixGid) { | ||||
|             found = true; | ||||
|             break; | ||||
|         } | ||||
|  | @ -988,31 +1010,29 @@ void switchToNixUser() | |||
|         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(); | ||||
|     savedGid = getgid(); | ||||
| 
 | ||||
|     /* Set the real, effective and saved gids to gr->gr_gid.  Also
 | ||||
|        make very sure that this succeeded.  We switch the gid first | ||||
|        because we cannot do it after we have dropped root uid. */ | ||||
|     nixGid = gr->gr_gid; | ||||
|     /* Set the real and effective gids to nixGid.  Also make very sure
 | ||||
|        that this succeeded.  We switch the gid first because we cannot | ||||
|        do it after we have dropped root uid. */ | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|     /* Lookup the Nix uid. */ | ||||
|     struct passwd * pw = getpwnam(NIX_USER); | ||||
|     if (!pw) { | ||||
|         std::cerr << format("missing user `%1%'\n") % NIX_USER; | ||||
|         exit(1); | ||||
|     } | ||||
|     /* The Nix uid is the effective uid of the owner of the current
 | ||||
|        executable, i.e., the current effective uid. */ | ||||
|     nixUid = geteuid(); | ||||
| 
 | ||||
|     /* This will drop all root privileges, setting the real, effective
 | ||||
|        and saved uids to pw->pw_uid.  Also make very sure that this | ||||
|        succeeded.*/ | ||||
|     nixUid = pw->pw_uid; | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|  | @ -1022,7 +1042,6 @@ void switchToNixUser() | |||
|     */ | ||||
| 
 | ||||
|     haveSwitched = true; | ||||
|      | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue