<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/7a7f01d60dffaf717abb537d3da1227be56478f7">https://github.com/macports/macports-base/commit/7a7f01d60dffaf717abb537d3da1227be56478f7</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new 7a7f01d60 mportsync: run external programs unprivileged
</span>7a7f01d60 is described below
<span style='display:block; white-space:pre;color:#808000;'>commit 7a7f01d60dffaf717abb537d3da1227be56478f7
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Tue Feb 18 13:39:59 2025 +1100
<span style='display:block; white-space:pre;color:#404040;'> mportsync: run external programs unprivileged
</span>---
src/macports1.0/macports.tcl | 78 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 69 insertions(+), 9 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 1e43ba426..7fd97bd8d 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3220,10 +3220,52 @@ proc macports::UpdateVCS {cmd dir} {
</span> return -options $options $result
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+proc macports::run_unprivileged {code {user {}}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[geteuid] == 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$user eq {}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ variable macportsuser
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set uname $macportsuser
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set gname {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $user uname gname
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set uid [name_to_uid $uname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$gname ne {}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set gid [name_to_gid $gname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set gid [uname_to_gid $uname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ setegid $gid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ seteuid $uid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uplevel 1 $code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } finally {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[getuid] == 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ seteuid 0; setegid 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc macports::chown {path user} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[getuid] != 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_debug "Not root; skipping 'chown $path $user'"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lchown $path $user
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[file isdirectory $path]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fs-traverse myfile [list $path] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lchown $myfile $user
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> proc mportsync {{options {}}} {
global macports::sources macports::ui_prefix \
macports::os_platform macports::os_major \
<span style='display:block; white-space:pre;background:#ffe0e0;'>- macports::os_arch macports::autoconf::tar_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::os_arch macports::autoconf::tar_path \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::macportsuser
</span>
if {[dict exists $options no_reindex]} {
upvar [dict get $options needed_portindex_var] any_needed_portindex
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3309,10 +3351,11 @@ proc mportsync {{options {}}} {
</span> set include_option {}
set srcstr $source
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::chown $destdir $macportsuser
</span> # Do rsync fetch
set rsync_commandline "$rsync_path $rsync_options $include_option $exclude_option $srcstr $destdir"
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- system $rsync_commandline
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {system $rsync_commandline}
</span> } on error {} {
ui_error "Synchronization of the local ports tree failed doing rsync"
incr numfailed
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3328,7 +3371,7 @@ proc mportsync {{options {}}} {
</span> set include_option "--include=/${filename} --include=/${filename}.rmd160"
set rsync_commandline "$rsync_path $rsync_options $include_option $exclude_option $srcstr $destdir"
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- system $rsync_commandline
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {system $rsync_commandline}
</span> } on error {} {
ui_error "Synchronization of the local ports tree failed doing rsync"
incr numfailed
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3347,7 +3390,7 @@ proc mportsync {{options {}}} {
</span> set verified 0
foreach pubkey $archivefetch_pubkeys {
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature $tarball
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature $tarball}
</span> set verified 1
ui_debug "successful verification with key $pubkey"
break
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3372,10 +3415,11 @@ proc mportsync {{options {}}} {
</span> }
# extract tarball and move into place
file mkdir ${extractdir}/tmp
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::chown ${extractdir}/tmp $macportsuser
</span> set zflag [expr {[file extension $tarball] eq ".gz" ? "z" : ""}]
set tar_cmd "$tar -C ${extractdir}/tmp -x${zflag}f $tarball"
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- system $tar_cmd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {system $tar_cmd}
</span> } on error {eMessage} {
ui_error "Failed to extract ports tree from tarball: $eMessage"
incr numfailed
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3383,9 +3427,11 @@ proc mportsync {{options {}}} {
</span> }
# save the local PortIndex data
if {[file isfile $indexfile]} {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::chown $indexfile $macportsuser
</span> file copy -force $indexfile ${destdir}/
file rename -force $indexfile ${extractdir}/tmp/ports/
if {[file isfile ${indexfile}.quick]} {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::chown ${indexfile}.quick $macportsuser
</span> file rename -force ${indexfile}.quick ${extractdir}/tmp/ports/
}
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3413,7 +3459,7 @@ proc mportsync {{options {}}} {
</span> set remote_indexdir "${index_source}PortIndex_${os_platform}_${os_major}_${os_arch}/"
set rsync_commandline "$rsync_path $rsync_options $include_option $remote_indexdir $destdir"
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- system $rsync_commandline
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {system $rsync_commandline}
</span>
set ok 1
set needs_portindex false
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3423,7 +3469,10 @@ proc mportsync {{options {}}} {
</span> # verify signature for PortIndex
foreach pubkey $archivefetch_pubkeys {
macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- exec $openssl dgst -ripemd160 -verify $pubkey -signature ${destdir}/PortIndex.rmd160 ${destdir}/PortIndex
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ exec $openssl dgst -ripemd160 -verify $pubkey \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ -signature ${destdir}/PortIndex.rmd160 ${destdir}/PortIndex
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> set ok 1
set needs_portindex false
ui_debug "successful verification with key $pubkey"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3479,6 +3528,7 @@ proc mportsync {{options {}}} {
</span> }
file mkdir $destdir
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::chown $destdir $macportsuser
</span>
global macports::portverbose macports::ui_options
set progressflag {}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3513,7 +3563,11 @@ proc mportsync {{options {}}} {
</span> set striparg "--strip-components=1"
set tar [macports::findBinary tar $tar_path]
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[catch {system -W ${destdir} "$tar $verboseflag $striparg $extflag -xf [macports::shellescape $tarpath]"} error]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ system -W ${destdir} "$tar $verboseflag $striparg $extflag -xf [macports::shellescape $tarpath]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } error]} {
</span> ui_error "Extracting $source failed ($error)"
incr numfailed
continue
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3549,7 +3603,13 @@ proc mportsync {{options {}}} {
</span> if {![dict exists $options no_reindex]} {
global macports::prefix
set indexdir [file dirname [macports::getindex $source]]
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[catch {system "${prefix}/bin/portindex [macports::shellescape $indexdir]"}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set owner [file attributes $indexdir -owner]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set group [file attributes $indexdir -group]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macports::run_unprivileged {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ system "${prefix}/bin/portindex [macports::shellescape $indexdir]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } [list $owner $group]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }]} {
</span> ui_error "updating PortIndex for $source failed"
}
}
</pre><pre style='margin:0'>
</pre>