* 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 | 	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue