Check-in [d3bb0824ec]
Overview
Comment:More work towards getting the user multiplexing right
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tcl-ops
Files: files | file ages | folders
SHA1:d3bb0824ec6b5debb2b5c58a4e7c5060f7f73b4e
User & Date: rkeene on 2014-11-10 04:22:15
Other Links: manifest | tags
Context
2014-11-10
04:52
Added initial PKI support check-in: 9279433b2f user: rkeene tags: tcl-ops
04:22
More work towards getting the user multiplexing right check-in: d3bb0824ec user: rkeene tags: tcl-ops
03:34
Updated to cache last home directory looked up and to setfsuid()/setfsgid() before accessing the filesystem so that we may be the right user check-in: 63e41c262c user: rkeene tags: tcl-ops
Changes

Modified appfsd.c from [9cae19dbb7] to [d452ee8ca8].

   429    429   		Tcl_IncrRefCount(last_homedir_obj);
   430    430   	}
   431    431   
   432    432          	Tcl_SetObjResult(interp, homedir_obj);
   433    433   
   434    434           return(TCL_OK);
   435    435   }
          436  +
          437  +static int tcl_appfs_simulate_user_fs_enter(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
          438  +	appfs_simulate_user_fs_enter();
          439  +
          440  +	return(TCL_OK);
          441  +}
          442  +
          443  +static int tcl_appfs_simulate_user_fs_leave(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
          444  +	appfs_simulate_user_fs_leave();
          445  +
          446  +	return(TCL_OK);
          447  +}
   436    448   
   437    449   /*
   438    450    * Generate an inode for a given path.  The inode should be computed in such
   439    451    * a way that it is unlikely to be duplicated and remains the same for a given
   440    452    * file
   441    453    */
   442    454   static long long appfs_get_path_inode(const char *path) {
................................................................................
   467    479   	static __thread Tcl_Obj *attr_key_type = NULL, *attr_key_perms = NULL, *attr_key_size = NULL, *attr_key_time = NULL, *attr_key_source = NULL, *attr_key_childcount = NULL, *attr_key_packaged = NULL;
   468    480   	int tcl_ret;
   469    481   
   470    482   	interp = appfs_TclInterp();
   471    483   	if (interp == NULL) {
   472    484   		return(-EIO);
   473    485   	}
          486  +
          487  +	appfs_simulate_user_fs_enter();
   474    488   
   475    489   	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getattr", path);
          490  +
          491  +	appfs_simulate_user_fs_leave();
          492  +
   476    493   	if (tcl_ret != TCL_OK) {
   477    494   		APPFS_DEBUG("::appfs::getattr(%s) failed.", path);
   478    495   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   479    496   
   480    497   		return(-ENOENT);
   481    498   	}
   482    499   
................................................................................
   555    572   					pathinfo->typeinfo.symlink.size = attr_value_int;
   556    573   					pathinfo->typeinfo.symlink.source[attr_value_int] = '\0';
   557    574   
   558    575   					memcpy(pathinfo->typeinfo.symlink.source, attr_value_str, attr_value_int);
   559    576   				}
   560    577   			}
   561    578   			break;
   562         -		case 'p': /* pipe/fifo */
          579  +		case 'F': /* pipe/fifo */
          580  +			pathinfo->type = APPFS_PATHTYPE_FIFO;
   563    581   			break;
   564    582   		case 'S': /* UNIX domain socket */
          583  +			pathinfo->type = APPFS_PATHTYPE_SOCKET;
   565    584   			break;
   566    585   		default:
   567    586   			return(-EIO);
   568    587   	}
   569    588   
   570    589   	Tcl_DictObjGet(interp, attrs_dict, attr_key_packaged, &attr_value);
   571    590   	if (attr_value != NULL) {
................................................................................
   705    724   			break;
   706    725   		case APPFS_PATHTYPE_SYMLINK:
   707    726   			stbuf->st_mode = S_IFLNK | 0555;
   708    727   			stbuf->st_nlink = 1;
   709    728   			stbuf->st_size = pathinfo.typeinfo.symlink.size;
   710    729   			break;
   711    730   		case APPFS_PATHTYPE_SOCKET:
          731  +			stbuf->st_mode = S_IFSOCK | 0555;
          732  +			stbuf->st_nlink = 1;
          733  +			stbuf->st_size = 0;
          734  +			break;
   712    735   		case APPFS_PATHTYPE_FIFO:
          736  +			stbuf->st_mode = S_IFIFO | 0555;
          737  +			stbuf->st_nlink = 1;
          738  +			stbuf->st_size = 0;
          739  +			break;
   713    740   		case APPFS_PATHTYPE_INVALID:
   714    741   			retval = -ENOENT;
   715    742   
   716    743   			break;
   717    744   	}
   718    745   
   719    746   	if (pathinfo.packaged) {
................................................................................
   734    761   	interp = appfs_TclInterp();
   735    762   	if (interp == NULL) {
   736    763   		return(0);
   737    764   	}
   738    765   
   739    766   	filler(buf, ".", NULL, 0);
   740    767   	filler(buf, "..", NULL, 0);
          768  +
          769  +	appfs_simulate_user_fs_enter();
   741    770   
   742    771   	tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getchildren", path);
          772  +
          773  +	appfs_simulate_user_fs_leave();
          774  +
   743    775   	if (tcl_ret != TCL_OK) {
   744    776   		APPFS_DEBUG("::appfs::getchildren(%s) failed.", path);
   745    777   		APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp));
   746    778   
   747    779   		return(0);
   748    780   	}
   749    781   
................................................................................
  1145   1177   #ifdef USE_TCL_STUBS
  1146   1178   	if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) {
  1147   1179   		return(TCL_ERROR);
  1148   1180   	}
  1149   1181   #endif
  1150   1182   
  1151   1183   	Tcl_CreateObjCommand(interp, "appfsd::get_homedir", tcl_appfs_get_homedir, NULL, NULL);
         1184  +	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_enter", tcl_appfs_simulate_user_fs_enter, NULL, NULL);
         1185  +	Tcl_CreateObjCommand(interp, "appfsd::simulate_user_fs_leave", tcl_appfs_simulate_user_fs_leave, NULL, NULL);
  1152   1186   
  1153   1187   	Tcl_PkgProvide(interp, "appfsd", "1.0");
  1154   1188   
  1155   1189   	return(TCL_OK);
  1156   1190   }
  1157   1191   
  1158   1192   /*

Modified appfsd.tcl from [3ec5e46dc5] to [af80dbf637].

   155    155   		# Create indexes
   156    156   		db eval {CREATE INDEX IF NOT EXISTS sites_index ON sites (hostname);}
   157    157   		db eval {CREATE INDEX IF NOT EXISTS packages_index ON packages (hostname, package, version, os, cpuArch);}
   158    158   		db eval {CREATE INDEX IF NOT EXISTS files_index ON files (package_sha1, file_name, file_directory);}
   159    159   	}
   160    160   
   161    161   	proc download {hostname hash {method sha1}} {
          162  +		::appfsd::simulate_user_fs_leave
          163  +
   162    164   		set url [_construct_url $hostname $hash $method]
   163    165   		set file [_cachefile $url $hash]
          166  +
          167  +		::appfsd::simulate_user_fs_enter
   164    168   
   165    169   		if {![file exists $file]} {
   166    170   			return -code error "Unable to fetch (file does not exist: $file)"
   167    171   		}
   168    172   
   169    173   		return $file
   170    174   	}
................................................................................
   470    474   						set remove [string range $file 0 end-15]
   471    475   						set idx [lsearch -exact $retval $remove]
   472    476   						if {$idx != -1} {
   473    477   							set retval [lreplace $retval $idx $idx]
   474    478   						}
   475    479   					}
   476    480   
   477         -					foreach file [glob -nocomplain -tails -directory $dir -types {d f l} {{.,}*}] {
          481  +					foreach file [glob -nocomplain -tails -directory $dir -types {d f l p s} {{.,}*}] {
   478    482   						if {$file == "." || $file == ".."} {
   479    483   							continue
   480    484   						}
   481    485   
   482    486   						if {$file == ".APPFS.WHITEOUT"} {
   483    487   							continue
   484    488   						}
................................................................................
   580    584   									set retval(perms) ""
   581    585   								}
   582    586   							}
   583    587   							"link" {
   584    588   								set retval(type) "symlink"
   585    589   								set retval(source) [file readlink $localpath]
   586    590   							}
          591  +							"fifo" {
          592  +								# Capitalized so that the first char is unique
          593  +								set retval(type) "Fifo"
          594  +							}
          595  +							"socket" {
          596  +								# Capitalized so that the first char is unique
          597  +								set retval(type) "Socket"
          598  +							}
   587    599   						}
   588    600   					} err
   589    601   				} else {
   590    602   					if {![file exists $whiteoutpath]} {
   591    603   						set retval(is_remotefile) 1
   592    604   
   593    605   						set work [split $pathinfo(file) "/"]
................................................................................
   720    732   
   721    733   		if {![info exists pathattrs(packaged)]} {
   722    734   			return -code error "invalid type"
   723    735   		}
   724    736   
   725    737   		set localpath $pathattrs(localpath)
   726    738   
   727         -		set whiteout 0
   728         -		set isdirectory 0
   729    739   		if {[info exists pathattrs(is_localfile)]} {
   730    740   			if {[file isdirectory $localpath]} {
   731         -				set whiteout 1
          741  +				set children [getchildren $path]
   732    742   
   733         -				set isdirectory 1
   734         -				set children [getchildren $path]
          743  +				if {[llength $children] != 0} {
          744  +					return -code error "Asked to delete non-empty directory"
          745  +				}
   735    746   			}
          747  +
   736    748   			file delete -force -- $localpath
   737    749   		} elseif {[info exists pathattrs(is_remotefile)]} {
   738    750   			if {$pathattrs(type) == "directory"} {
   739         -				set isdirectory 1
   740    751   				set children [getchildren $path]
   741         -			}
   742    752   
   743         -			set whiteout 1
          753  +				if {[llength $children] != 0} {
          754  +					return -code error "Asked to delete non-empty directory"
          755  +				}
          756  +			}
   744    757   		} else {
   745    758   			return -code error "Unknown if file is remote or local !?"
   746    759   		}
   747    760   
   748         -		if {$isdirectory} {
   749         -			if {$children != [list]} {
   750         -				return -code error "Asked to delete non-empty directory"
   751         -			}
   752         -		}
   753         -
   754         -		if {$whiteout} {
   755         -			set whiteoutfile $pathattrs(whiteoutpath)
   756         -			set whiteoutdir [file dirname $whiteoutfile]
   757         -			file mkdir $whiteoutdir
   758         -			close [open $whiteoutfile w]
   759         -		}
          761  +		set whiteoutfile $pathattrs(whiteoutpath)
          762  +		set whiteoutdir [file dirname $whiteoutfile]
          763  +		file mkdir $whiteoutdir
          764  +		close [open $whiteoutfile w]
   760    765   	}
   761    766   }