[37794] branches/gsoc08-privileges/base/src/port1.0

pmagrath at macports.org pmagrath at macports.org
Mon Jun 23 11:58:49 PDT 2008


Revision: 37794
          http://trac.macosforge.org/projects/macports/changeset/37794
Author:   pmagrath at macports.org
Date:     2008-06-23 11:58:48 -0700 (Mon, 23 Jun 2008)
Log Message:
-----------
Most actions are now performed using user privileges, up to and including the destroot stage. For install, the original root privileges are recovered and the install takes place as per usual.

Modified Paths:
--------------
    branches/gsoc08-privileges/base/src/port1.0/portclean.tcl
    branches/gsoc08-privileges/base/src/port1.0/portdestroot.tcl
    branches/gsoc08-privileges/base/src/port1.0/portextract.tcl
    branches/gsoc08-privileges/base/src/port1.0/portfetch.tcl
    branches/gsoc08-privileges/base/src/port1.0/portinstall.tcl
    branches/gsoc08-privileges/base/src/port1.0/portutil.tcl

Modified: branches/gsoc08-privileges/base/src/port1.0/portclean.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portclean.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portclean.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -46,9 +46,23 @@
 set_ui_prefix
 
 proc clean_start {args} {
-    global UI_PREFIX
+    global UI_PREFIX macportsuser euid egid
     
     ui_msg "$UI_PREFIX [format [msgcat::mc "Cleaning %s"] [option portname]]"
+    
+	# start gsoc08-privileges
+	if { [getuid] == 0 && [geteuid] == [name_to_uid "$macportsuser"] } { 
+	# if started with sudo but have dropped the privileges
+		ui_debug "Can't guarantee a good clean without elevated privileges."
+		# TODO: modify so that privilege descalation is conditional on needing
+		# to clean a directory in the /opt hierarchy.
+		ui_debug "Going to escalate privileges back to root."
+		seteuid $euid	
+		setegid $egid
+		ui_debug "euid changed to: [geteuid]"
+		ui_debug "egid changed to: [getegid]"
+	}
+	# end gsoc08-privileges
 }
 
 proc clean_main {args} {

Modified: branches/gsoc08-privileges/base/src/port1.0/portdestroot.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portdestroot.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portdestroot.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -87,10 +87,23 @@
 
 proc destroot_start {args} {
     global UI_PREFIX prefix portname destroot portresourcepath os.platform destroot.clean
-    global destroot::oldmask destroot.umask
+    global destroot::oldmask destroot.umask macportsuser euid egid
     
     ui_msg "$UI_PREFIX [format [msgcat::mc "Staging %s into destroot"] ${portname}]"
 
+	# start gsoc08-privileges
+	if { [getuid] == 0 && [geteuid] == [name_to_uid "$macportsuser"] } { 
+	# if started with sudo but have dropped the privileges
+		ui_debug "Can't run destroot under sudo without elevated privileges (due to mtree)."
+		ui_debug "Run destroot without sudo to avoid root privileges."
+		ui_debug "Going to escalate privileges back to root."
+		seteuid $euid	
+		seteuid $egid	
+		ui_debug "euid changed to: [geteuid]"
+		ui_debug "egid changed to: [getegid]"
+	}
+	# end gsoc08-privileges
+
     set oldmask [umask ${destroot.umask}]
     set mtree ${portutil::autoconf::mtree_path}
     
@@ -99,15 +112,18 @@
     }
     
     file mkdir "${destroot}"
+
     if { ${os.platform} == "darwin" } {
         system "cd \"${destroot}\" && ${mtree} -e -U -f ${portresourcepath}/install/macosx.mtree"
     }
     file mkdir "${destroot}/${prefix}"
+
     system "cd \"${destroot}/${prefix}\" && ${mtree} -e -U -f ${portresourcepath}/install/prefix.mtree"
 }
 
 proc destroot_main {args} {
     command_exec destroot
+    ui_debug "destroot_main finished."
     return 0
 }
 

Modified: branches/gsoc08-privileges/base/src/port1.0/portextract.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portextract.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portextract.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -92,19 +92,32 @@
 }
 
 proc extract_main {args} {
-    global UI_PREFIX
+    global UI_PREFIX euid egid worksrcpath macportsuser
     
     if {![exists distfiles] && ![exists extract.only]} {
 	# nothing to do
 	return 0
     }
-    
+
     foreach distfile [option extract.only] {
 	ui_info "$UI_PREFIX [format [msgcat::mc "Extracting %s"] $distfile]"
 	option extract.args "[option distpath]/$distfile"
 	if {[catch {command_exec extract} result]} {
 	    return -code error "$result"
 	}
+	
+	# start gsoc08-privileges
+	if { [getuid] == 0 && [geteuid] == [name_to_uid "$macportsuser"] } {
+	# if started with sudo but have dropped the privileges
+		seteuid $euid	
+		ui_debug "euid changed to: [geteuid]"
+		file attributes "${worksrcpath}" -owner [name_to_uid "$macportsuser"]
+		ui_debug "chowned $worksrcpath to $macportsuser"
+		seteuid [name_to_uid "$macportsuser"]
+		ui_debug "euid changed to: [geteuid]"
+	}
+	# end gsoc08-privileges
+	
     }
     return 0
 }

Modified: branches/gsoc08-privileges/base/src/port1.0/portfetch.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portfetch.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portfetch.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -568,6 +568,7 @@
 				ui_msg "$UI_PREFIX [format [msgcat::mc "Attempting to fetch %s from %s"] $distfile $site]"
 				set file_url [portfetch::assemble_url $site $distfile]
 				set effectiveURL ""
+				
 				if {![catch {eval curl fetch --effective-url effectiveURL $fetch_options {$file_url} ${distpath}/${distfile}.TMP} result] &&
 					![catch {system "mv ${distpath}/${distfile}.TMP ${distpath}/${distfile}"}]} {
 
@@ -625,13 +626,16 @@
 
 # Initialize fetch target and call checkfiles.
 proc fetch_init {args} {
-    global distfiles distname distpath all_dist_files dist_subdir fetch.type fetch_init_done
+    global usealtworkpath distfiles distname distpath all_dist_files dist_subdir fetch.type fetch_init_done
     
     if {[info exists distpath] && [info exists dist_subdir] && ![info exists fetch_init_done]} {
+
 		# start gsoc08-privileges
-    	if {![file writable $distpath]} {
+    	if { $usealtworkpath} {
+    	# I have removed ![file writable $distpath] from the if condition as
+    	# the writable condition seems to get confused by effective uids.
 			set distpath "/Users/[exec whoami]/.macports/[ string range $distpath 1 end ]"
-			ui_warn "Going to use $distpath for fetch."
+			ui_debug "Going to use $distpath for fetch."
     	}
     	# end gsoc08-privileges
 	    set distpath ${distpath}/${dist_subdir}

Modified: branches/gsoc08-privileges/base/src/port1.0/portinstall.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portinstall.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portinstall.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -47,8 +47,21 @@
 set_ui_prefix
 
 proc install_start {args} {
-	global UI_PREFIX portname portversion portrevision variations portvariants
+	global UI_PREFIX portname portversion portrevision variations portvariants macportsuser euid egid
 	ui_msg "$UI_PREFIX [format [msgcat::mc "Installing %s @%s_%s%s"] $portname $portversion $portrevision $portvariants]"
+	
+	# start gsoc08-privileges
+	if { [getuid] == 0 && [geteuid] == [name_to_uid "$macportsuser"] } { 
+	# if started with sudo but have dropped the privileges
+		ui_debug "Can't run install without elevated privileges."
+		ui_debug "Going to escalate privileges back to root."
+		seteuid $euid	
+		setegid $egid
+		ui_debug "euid changed to: [geteuid]"
+		ui_debug "egid changed to: [getegid]"
+	}
+	# end gsoc08-privileges
+	
 }
 
 proc install_element {src_element dst_element} {

Modified: branches/gsoc08-privileges/base/src/port1.0/portutil.tcl
===================================================================
--- branches/gsoc08-privileges/base/src/port1.0/portutil.tcl	2008-06-23 16:07:32 UTC (rev 37793)
+++ branches/gsoc08-privileges/base/src/port1.0/portutil.tcl	2008-06-23 18:58:48 UTC (rev 37794)
@@ -1378,32 +1378,82 @@
 # open_statefile
 # open file to store name of completed targets
 proc open_statefile {args} {
-    global workpath worksymlink place_worksymlink portname portpath ports_ignore_older
+    global macportsuser euid egid usealtworkpath workpath worksymlink place_worksymlink portname portpath ports_ignore_older
     
-    # start gsoc08-privileges
-    if {![file writable $workpath] && [string first "~/.macports" $workpath] == -1} {
+	# start gsoc08-privileges
+	
+	# TODO: move the macportsuser setting to macports.conf
+	set macportsuser "paul"
+
+	# descalate privileges - only ran if macports stated with sudo
+	if { [geteuid] == 0 } {
+		if { [catch {
+				set euid [geteuid]
+				set egid [getegid]
+				ui_debug "changing euid/egid - current euid: $euid - current egid: $egid"
+	
+				#seteuid [name_to_uid [file attributes $workpath -owner]]
+				#setegid [name_to_gid [file attributes $workpath -group]]
+	
+				setegid [name_to_gid "$macportsuser"]
+				seteuid [name_to_uid "$macportsuser"]
+				ui_debug "egid changed to: [getegid]" 
+				ui_debug "euid changed to: [geteuid]"
+				
+				if {![file writable $workpath]} {
+					ui_debug "Privileges successfully descalated. Unable to write to workpath."
+				}
+			}]
+		} {
+			ui_debug "$::errorInfo"
+			ui_error "Failed to descalate privileges."
+		}
+	} else {
+		ui_debug "Privilege desclation not attempted as not running as root."
+	}
     
-    	set userhome "/Users/[exec whoami]"
+    # if unable to write to workpath, implies running without root privileges so use ~/.macports
+    if { ![file writable $workpath] } {
     	
-        set newworkpath "$userhome/.macports/[ string range $workpath 1 end ]"
-		set newworksymlink "$userhome/.macports/[ string range $worksymlink 1 end ]"
-        
-        set sourcepath [string map {"work" ""} $worksymlink] 
-        set newsourcepath "$userhome/.macports/[ string range $sourcepath 1 end ]"
-        
-        if {![file exists ${sourcepath}Portfile] } {
-			file mkdir $newsourcepath
-			ui_debug "$newsourcepath created"
-        	ui_debug "Going to copy: ${sourcepath}Portfile"
-        	file copy ${sourcepath}Portfile $newsourcepath
-        }
-        
-        set workpath $newworkpath
-        set worksymlink $newworksymlink
-        
-        ui_warn "Going to use $newworkpath for statefile."
-    } else {
-    	set notroot no
+    	if { [getuid] !=0 } {
+    		ui_msg "Insufficient privileges to perform action for all users."
+    		ui_msg "Action will be performed for current user only."
+    		ui_msg "Install actions should be executed using sudo."
+    
+    		#set usealtworkpath [gets stdin]
+    		set usealtworkpath yes
+    	} else {
+    		set usealtworkpath yes
+    	}
+    	
+		if {$usealtworkpath} {
+    
+    		# do tilde expansion manually - tcl won't expand tildes automatically for curl, etc.
+			set userhome "/Users/[exec whoami]"
+			
+			# get alternative paths
+			set newworkpath "$userhome/.macports/[ string range $workpath 1 end ]"
+			set newworksymlink "$userhome/.macports/[ string range $worksymlink 1 end ]"
+			
+			set sourcepath [string map {"work" ""} $worksymlink] 
+			set newsourcepath "$userhome/.macports/[ string range $sourcepath 1 end ]"
+	
+			# copy Portfile if not there already
+			# note to self: should this be done always in case existing Portfile is out of date?
+			if {![file exists ${newsourcepath}Portfile] } {
+				file mkdir $newsourcepath
+				ui_debug "$newsourcepath created"
+				ui_debug "Going to copy: ${sourcepath}Portfile"
+				file copy ${sourcepath}Portfile $newsourcepath
+			}
+			
+			set workpath $newworkpath
+			set worksymlink $newworksymlink
+			
+			ui_debug "Going to use $newworkpath for statefile."
+		} else {
+			return -code error "Insufficient privileges."
+		}
     }
     # end gsoc08-privileges
 
@@ -1428,8 +1478,7 @@
 
     # Create a symlink to the workpath for port authors 
     if {[tbool place_worksymlink] && ![file isdirectory $worksymlink]} {
-    	#pmagrath TODO: fix this quick hack.
-		#exec ln -sf $workpath $worksymlink
+		exec ln -sf $workpath $worksymlink
     }
     
     set fd [open $statefile a+]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20080623/61a3b24f/attachment-0001.htm 


More information about the macports-changes mailing list