Index | Thread | Search

From:
Marc Espie <marc.espie.openbsd@gmail.com>
Subject:
Re: roadmap for more privsep in pkgland
To:
ports@openbsd.org
Cc:
bentley@openbsd.org
Date:
Fri, 16 Aug 2024 12:15:05 +0200

Download raw body.

Thread
Here's the basic pkg_add change, very lightly tested for now.
Not that many lines, considering :)

Index: pkg_create.1
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/pkg_create.1,v
diff -u -p -r1.131 pkg_create.1
--- pkg_create.1	5 Jul 2023 01:21:51 -0000	1.131
+++ pkg_create.1	16 Aug 2024 10:13:43 -0000
@@ -434,13 +434,19 @@ If
 does not begin with an @, same as
 .Dl name/
 .Pp
-.It Cm @define-tag Ar tag mode params
+.It Cm @define-tag Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar tag mode params
 Define a tag of name
 .Ar tag .
 Tags define actions to be performed at specific time during
 .Xr pkg_add 1
 and
-.Xr pkg_delete 1 .
+.Xr pkg_delete 1 ,
+after changing identity to owner
+.Ar o
+and/or
+group
+.Ar g
+if specified.
 A given tag may be defined several times with additional properties.
 Currently, the following modes are defined:
 .Bl -tag -width abc -compact
@@ -498,11 +504,15 @@ only rebuilds the local texmf directory 
 so if both tags are seen, only the global command will be run.
 .El
 .Pp
-.It Cm @exec Ar command
+.It Cm @exec Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Execute
 .Ar command
 during
-.Xr pkg_add 1 .
+.Xr pkg_add 1 ,
+after optionally changing identity to user
+.Ar o
+and/or group
+.Ar g .
 Note that
 .Cm @exec
 commands are executed relative to their location in the packing-list,
@@ -562,36 +572,51 @@ in the example case,
 .Pa emacs .
 .El
 .Pp
-.It Cm @exec-always Ar command
+.It Cm @exec-always Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Synonym of
 .Cm @exec .
 .Pp
-.It Cm @exec-add Ar command
+.It Cm @exec-add Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Similar to
 .Cm @exec ,
 except it only gets executed during new installations,
 and not during updates.
 .Pp
-.It Cm @exec-update Ar command
+.It Cm @exec-update Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Similar to
 .Cm @exec ,
 except it only gets executed during updates,
 and not during new installations.
 .Pp
-.It Cm @extra Ar filename
+.It Cm @extra Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Oo always Oc Ar filename
 Declare extra file
 .Ar filename
 to be deleted at deinstall time, if user sets the
 .Fl c
-option.
+option or if the optional parameter
+.Ar always
+is used.
 Those files are extra configuration files that are normally not deleted.
+Allows file ownership to be declared as well.
 .Ar filename
 can be an absolute path.
 If
 .Ar filename
 ends with a slash, it is a directory.
 .Pp
-.It Cm @extraunexec Ar command
+.It Cm @extraglob Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Oo always Oc Ar glob
+Declare extra files matching the shell globbing pattern
+.Ar glob
+to be deleted at deinstall time, if user sets the
+.Fl c
+option or if the optional parameter
+.Ar always
+is used.
+Allows file ownership to be declared as well.
+If
+.Ar glob
+ends with a slash, it is a directory, which will be wiped recursively.
+.It Cm @extraunexec Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Extra
 .Ar command
 to execute when removing extra files.
@@ -862,7 +887,7 @@ Describe the file as a
 .Ox
 static library.
 .Pp
-.It Cm @unexec Ar command
+.It Cm @unexec Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Execute
 .Ar command
 during
@@ -892,17 +917,17 @@ definition must be accessible through th
 is amenable to the same substitutions as
 .Cm @exec .
 .Pp
-.It Cm @unexec-always Ar command
+.It Cm @unexec-always Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Synonym of
 .Cm @unexec .
 .Pp
-.It Cm @unexec-delete Ar command
+.It Cm @unexec-delete Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Similar to
 .Cm @unexec ,
 except it only gets executed during true deletions
 and not while removing an old package during updates.
 .Pp
-.It Cm @unexec-update Ar command
+.It Cm @unexec-update Oo owner Ns = Ns Ar o Oc Oo group Ns = Ns Ar g Oc Ar command
 Similar to
 .Cm @unexec ,
 except it only gets executed while removing an old package during updates,
Index: OpenBSD/Add.pm
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/OpenBSD/Add.pm,v
diff -u -p -r1.196 Add.pm
--- OpenBSD/Add.pm	11 Oct 2023 13:54:43 -0000	1.196
+++ OpenBSD/Add.pm	16 Aug 2024 10:04:50 -0000
@@ -257,8 +257,6 @@ sub tag_user_packages(@p)
 package OpenBSD::PackingElement;
 use OpenBSD::Error;
 
-# used by newuser/newgroup to deal with options.
-my ($uidcache, $gidcache);
 
 # $self->prepare_for_addition($state, $pkgname, $set)
 sub prepare_for_addition($, $, $, $)
@@ -297,19 +295,7 @@ sub copy_info($, $, $)
 sub set_modes($self, $state, $name)
 {
 	if (defined $self->{owner} || defined $self->{group}) {
-		require OpenBSD::IdCache;
-
-		if (!defined $uidcache) {
-			$uidcache = OpenBSD::UidCache->new;
-			$gidcache = OpenBSD::GidCache->new;
-		}
-		my ($uid, $gid) = (-1, -1);
-		if (defined $self->{owner}) {
-			$uid = $uidcache->lookup($self->{owner}, $uid);
-		}
-		if (defined $self->{group}) {
-			$gid = $gidcache->lookup($self->{group}, $gid);
-		}
+		my ($uid, $gid) = $self->find_ids;
 		chown $uid, $gid, $name;
 	}
 	if (defined $self->{mode}) {
@@ -922,6 +908,42 @@ sub find_extractible($self, $state, $wan
 {
 	$state->{current_set}{known_displays}{$self->{d}->key} = 1;
 	$self->SUPER::find_extractible($state, $wanted, $tied);
+}
+
+package OpenBSD::PackingElement::ExtraGlob;
+sub chown($self, $uid, $gid)
+{
+	chown $uid, $gid, glob $self->fullname;
+}
+
+sub install($self, $state)
+{
+	my ($uid, $gid) = $self->find_ids;
+	if ($uid != -1 || $gid != -1) {
+		$self->chown($uid, $gid);
+	}
+}
+
+package OpenBSD::PackingElement::ExtraGlobdir;
+sub chown($self, $uid, $gid)
+{
+	require File::Find;
+	File::Find::find(
+	    sub {
+	    	chown $uid, $gid, $_;
+	    }, glob $self->fullname);
+}
+
+package OpenBSD::PackingElement::Extra;
+# Forwarder
+sub install
+{
+	&OpenBSD::PackingElement::ExtraGlob::install;
+}
+
+sub chown($self, $uid, $gid)
+{
+	chown $uid, $gid, $self->fullname;
 }
 
 1;
Index: OpenBSD/Delete.pm
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/OpenBSD/Delete.pm,v
diff -u -p -r1.169 Delete.pm
--- OpenBSD/Delete.pm	11 Oct 2023 13:54:43 -0000	1.169
+++ OpenBSD/Delete.pm	16 Aug 2024 09:20:13 -0000
@@ -342,6 +342,32 @@ sub should_run($self, $state)
 	return $state->replacing;
 }
 
+package OpenBSD::PackingElement::ExtraGlob;
+sub unlink($self)
+{
+	unlink(glob($self->fullname));
+}
+
+sub delete($self, $state)
+{
+	if ($self->{always} || $state->{extra}) {
+		$self->unlink;
+	} else {
+		my @l = glob($self->fullname);
+		if (@l > 0 && -e $l[0]) {
+			$state->log("You should also remove #1", 
+			    $self->fullname);
+		}
+	}
+}
+
+package OpenBSD::PackingElement::ExtraGlobdir;
+sub unlink($self)
+{
+	require File::Path;
+	File::Path::remove_tree(glob($self->fullname), {safe => 1});
+}
+
 package OpenBSD::PackingElement::DefineTag::Atend;
 sub delete($self, $state)
 {
Index: OpenBSD/PackingElement.pm
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/OpenBSD/PackingElement.pm,v
diff -u -p -r1.291 PackingElement.pm
--- OpenBSD/PackingElement.pm	30 Apr 2024 14:26:50 -0000	1.291
+++ OpenBSD/PackingElement.pm	16 Aug 2024 10:03:24 -0000
@@ -181,6 +181,76 @@ sub finish($class, $state)
 	}
 }
 
+sub new_owned_object($class, $param)
+{
+	my $o = bless {}, $class;
+	my $again;
+	do {
+		$again = 0;
+		if ($param =~ s/^owner\=(\S+)\s+//) {
+			$o->{owner} = $1;
+			$again = 1;
+		}
+		if ($param =~ s/^group\=(\S+)\s+//) {
+			$o->{group} = $1;
+			$again = 1;
+		}
+		if ($param =~ s/^always\s+//) {
+			$o->{always} = 1;
+		}
+	} while ($again);
+	$o->{name} = $param;
+	return $o;
+}
+
+sub stringize_owned_object($self)
+{
+	my @l = ($self->name);
+	if (defined $self->{always}) {
+		unshift(@l, 'always');
+	}
+	if (defined $self->{group}) {
+		unshift(@l, "group=$self->{group}");
+	}
+	if (defined $self->{owner}) {
+		unshift(@l, "owner=$self->{owner}");
+	}
+	return join(' ', @l);
+}
+
+my ($uidcache, $gidcache);
+
+sub find_ids($self)
+{
+	require OpenBSD::IdCache;
+
+	if (!defined $uidcache) {
+		$uidcache = OpenBSD::UidCache->new;
+		$gidcache = OpenBSD::GidCache->new;
+	}
+	my ($uid, $gid) = (-1, -1);
+	if (defined $self->{owner}) {
+		$uid = $uidcache->lookup($self->{owner}, $uid);
+	}
+	if (defined $self->{group}) {
+		$gid = $gidcache->lookup($self->{group}, $gid);
+	}
+	return ($uid, $gid);
+}
+
+sub change_id($self)
+{
+	my ($uid, $gid) = $self->find_ids;
+	if ($gid != -1) {
+		$( = $gid;
+		$) = "$gid $gid";
+	}
+	if ($uid != -1) {
+		$< = $uid;
+		$> = $uid;
+	}
+}
+
 # Basic class hierarchy
 
 # various stuff that's only linked to objects before/after them
@@ -1304,6 +1374,11 @@ use File::Basename;
 use OpenBSD::Error;
 our @ISA=qw(OpenBSD::PackingElement::Action);
 
+sub new($class, $arg)
+{
+	return $class->new_owned_object($arg);
+}
+
 sub command($self)
 {
 	return $self->name;
@@ -1340,7 +1415,15 @@ sub run($self, $state, $v = $self->{expa
 {
 	$state->ldconfig->ensure;
 	$state->say("#1 #2", $self->keyword, $v) if $state->verbose >= 2;
-	$state->log->system(OpenBSD::Paths->sh, '-c', $v) unless $state->{not};
+	$state->log->system(sub { $self->change_id; },
+	    OpenBSD::Paths->sh, '-c', $v) 
+	    	unless $state->{not};
+}
+
+# Forwarder
+sub stringize
+{
+	&OpenBSD::PackingElement::stringize_owned_object;
 }
 
 # so tags are going to get triggered by packages we depend on.
@@ -1407,17 +1490,18 @@ my $subclass = {
 
 sub new($class, $args)
 {
-	my ($tag, $mode, $params) = split(/\s+/, $args, 3);
-	$cache->{$args} //= bless {
-	    name => $tag,
-	    mode => $mode,
-	    params => $params,
-	    }, $class;
+	my $o = $class->new_owned_objet($args);
+	my ($tag, $mode, $params) = split(/\s+/, $o->{name}, 3);
+	$o->{name} = $tag;
+	$o->{mode} = $mode;
+	$o->{params} = $params;
+	$cache->{$args} //= $o;
 }
 
 sub stringize($self)
 {
-	return join(' ', $self->name, $self->{mode}, $self->{params});
+	return join(' ', $self->stringize_owned_object, 
+	    $self->{mode}, $self->{params});
 }
 
 sub add_object($self, $plist)
@@ -1722,6 +1806,17 @@ sub destate($self, $state)
 	$self->compute_fullname($state);
 }
 
+sub new($class, $args)
+{
+	return $class->new_owned_object($args);
+}
+
+# Forwarder
+sub stringize
+{
+	&OpenBSD::PackingElement::stringize_owned_object;
+}
+
 sub dirclass($) { "OpenBSD::PackingElement::Extradir" }
 
 package OpenBSD::PackingElement::Extradir;
@@ -1734,11 +1829,37 @@ sub destate	# forwarder
 }
 
 package OpenBSD::PackingElement::ExtraGlob;
-our @ISA=qw(OpenBSD::PackingElement::FileObject);
+our @ISA=qw(OpenBSD::PackingElement::Object);
+
+sub new($class, $args)
+{
+	return $class->new_owned_object($args);
+}
+
+# Forwarder
+sub destate
+{
+	&OpenBSD::PackingElement::FileObject::destate;
+}
+
+# Forwarder
+sub stringize
+{
+	&OpenBSD::PackingElement::stringize_owned_object;
+}
+
+sub dirclass($)
+{
+	'OpenBSD::PackingElement::ExtraGlobdir'
+}
 
 sub keyword($) { 'extraglob' }
 sub absolute_okay($) { 1 }
+
 __PACKAGE__->register_with_factory;
+
+package OpenBSD::PackingElement::ExtraGlobdir;
+our @ISA=qw(OpenBSD::PackingElement::ExtraGlob);
 
 package OpenBSD::PackingElement::SpecialFile;
 our @ISA=qw(OpenBSD::PackingElement::Unique);