Diff

Differences From Artifact [4990aac269]:

To Artifact [5ba05dc7d6]:


     7      7   #include <stdarg.h>
     8      8   #include <stdlib.h>
     9      9   #include <unistd.h>
    10     10   #include <errno.h>
    11     11   #include <fcntl.h>
    12     12   #include <stdio.h>
    13     13   #include <fuse.h>
           14  +#include <pwd.h>
    14     15   #include <tcl.h>
    15     16   
    16     17   #ifndef APPFS_CACHEDIR
    17     18   #define APPFS_CACHEDIR "/var/cache/appfs"
    18     19   #endif
    19     20   
    20     21   #ifdef DEBUG
................................................................................
    26     27   static pthread_key_t interpKey;
    27     28   
    28     29   struct appfs_thread_data {
    29     30   	sqlite3 *db;
    30     31   	const char *cachedir;
    31     32   	time_t boottime;
    32     33   	const char *platform;
           34  +	struct {
           35  +		int writable;
           36  +	} options;
    33     37   };
    34     38   
    35     39   struct appfs_thread_data globalThread;
    36     40   
    37     41   typedef enum {
    38     42   	APPFS_PATHTYPE_INVALID,
    39     43   	APPFS_PATHTYPE_FILE,
................................................................................
   249    253   
   250    254   	obj->_next = *head_p;
   251    255   	*head_p = obj;
   252    256   
   253    257   	return(0);
   254    258   	
   255    259   }
          260  +
          261  +static uid_t appfs_get_fsuid(void) {
          262  +	struct fuse_context *ctx;
          263  +
          264  +	ctx = fuse_get_context();
          265  +	if (ctx == NULL) {
          266  +		return(1);
          267  +	}
          268  +
          269  +	return(ctx->uid);
          270  +}
          271  +
          272  +static const char *appfs_get_homedir(uid_t fsuid) {
          273  +	struct passwd entry, *result;
          274  +	struct stat stbuf;
          275  +	char buf[1024], *retval;
          276  +	int gpu_ret, stat_ret;
          277  +
          278  +	gpu_ret = getpwuid_r(fsuid, &entry, buf, sizeof(buf), &result);
          279  +	if (gpu_ret != 0) {
          280  +		APPFS_DEBUG("getpwuid_r(%llu, ...) returned in failure", (unsigned long long) fsuid);
          281  +
          282  +		return(NULL);
          283  +	}
          284  +
          285  +	if (result == NULL) {
          286  +		APPFS_DEBUG("getpwuid_r(%llu, ...) returned NULL result", (unsigned long long) fsuid);
          287  +
          288  +		return(NULL);
          289  +	}
          290  +
          291  +	if (result->pw_dir == NULL) {
          292  +		APPFS_DEBUG("getpwuid_r(%llu, ...) returned NULL home directory", (unsigned long long) fsuid);
          293  +
          294  +		return(NULL);
          295  +	}
          296  +
          297  +	stat_ret = stat(result->pw_dir, &stbuf);
          298  +	if (stat_ret != 0) {
          299  +		APPFS_DEBUG("stat(%s) returned in failure", result->pw_dir);
          300  +
          301  +		return(NULL);
          302  +	}
          303  +
          304  +	if (stbuf.st_uid != fsuid) {
          305  +		APPFS_DEBUG("UID mis-match on user %llu's home directory (%s).  It's owned by %llu.",
          306  +		    (unsigned long long) fsuid,
          307  +		    result->pw_dir,
          308  +		    (unsigned long long) stbuf.st_uid
          309  +		);
          310  +
          311  +		return(NULL);
          312  +	}
          313  +
          314  +	retval = sqlite3_mprintf("%s", result->pw_dir);
          315  +
          316  +	return(retval);
          317  +}
          318  +
          319  +static struct appfs_children *appfs_getchildren_fs(struct appfs_children *in_children, const char *fspath) {
          320  +	APPFS_DEBUG("Searching %s", fspath);
          321  +
          322  +	return(in_children);
          323  +}
   256    324   
   257    325   static struct appfs_children *appfs_getchildren(const char *hostname, const char *package_hash, const char *path, int *children_count_p) {
   258    326   	struct appfs_children *head = NULL;
   259         -	char *sql;
          327  +	char *sql, *filebuf, *homedir = NULL;
   260    328   	int sqlite_ret;
          329  +	uid_t fsuid;
   261    330   
   262    331   	if (children_count_p == NULL) {
   263    332   		return(NULL);
   264    333   	}
   265    334   
   266    335   	appfs_update_index(hostname);
   267    336   	appfs_update_manifest(hostname, package_hash);
................................................................................
   280    349   	if (sqlite_ret != SQLITE_OK) {
   281    350   		APPFS_DEBUG("Call to sqlite3_exec failed.");
   282    351   
   283    352   		appfs_free_list_children(head);
   284    353   
   285    354   		return(NULL);
   286    355   	}
          356  +
          357  +	if (globalThread.options.writable) {
          358  +		/* Determine user of process accessing this file */
          359  +		fsuid = appfs_get_fsuid();
          360  +
          361  +		/* Check filesystem paths for updated files */
          362  +		/** Check the global directory (/etc) **/
          363  +		filebuf = sqlite3_mprintf("/etc/appfs/%s/%s", package_hash, path);
          364  +		if (filebuf == NULL) {
          365  +			APPFS_DEBUG("Call to sqlite3_mprintf failed.");
          366  +
          367  +			return(NULL);
          368  +		}
          369  +
          370  +		head = appfs_getchildren_fs(head, filebuf);
          371  +
          372  +		sqlite3_free(filebuf);
          373  +
          374  +		/** Check the user's directory, if we are not root **/
          375  +		if (fsuid != 0) {
          376  +			homedir = (char *) appfs_get_homedir(fsuid);
          377  +		}
          378  +
          379  +		if (homedir != NULL) {
          380  +			filebuf = sqlite3_mprintf("%z/.appfs/%s/%s", homedir, package_hash, path);
          381  +
          382  +			if (filebuf == NULL) {
          383  +				APPFS_DEBUG("Call to sqlite3_mprintf failed.");
          384  +
          385  +				return(NULL);
          386  +			}
          387  +
          388  +			head = appfs_getchildren_fs(head, filebuf);
          389  +
          390  +			sqlite3_free(filebuf);
          391  +		}
          392  +	}
   287    393   
   288    394   	if (head != NULL) {
   289    395   		*children_count_p = head->counter + 1;
          396  +	} else {
          397  +		*children_count_p = 0;
   290    398   	}
   291    399   
   292    400   	return(head);
   293    401   }
   294    402   
   295    403   static int appfs_sqlite3_query_cb(void *_cb_handle, int columns, char **values, char **names) {
   296    404   	struct appfs_sqlite3_query_cb_handle *cb_handle;
................................................................................
   825    933   
   826    934   	memset(stbuf, 0, sizeof(struct stat));
   827    935   
   828    936   	stbuf->st_mtime = pathinfo.time;
   829    937   	stbuf->st_ctime = pathinfo.time;
   830    938   	stbuf->st_atime = pathinfo.time;
   831    939   	stbuf->st_ino   = pathinfo.inode;
          940  +	stbuf->st_mode  = 0;
   832    941   
   833    942   	switch (pathinfo.type) {
   834    943   		case APPFS_PATHTYPE_DIRECTORY:
   835    944   			stbuf->st_mode = S_IFDIR | 0555;
   836    945   			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
   837    946   			break;
   838    947   		case APPFS_PATHTYPE_FILE:
................................................................................
   851    960   			stbuf->st_size = pathinfo.typeinfo.symlink.size;
   852    961   			break;
   853    962   		case APPFS_PATHTYPE_INVALID:
   854    963   			res = -EIO;
   855    964   
   856    965   			break;
   857    966   	}
          967  +
          968  +	if (globalThread.options.writable) {
          969  +		stbuf->st_mode |= 0222;
          970  +	}
   858    971   
   859    972   	return res;
   860    973   }
   861    974   
   862    975   static int appfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
   863    976   	struct appfs_pathinfo pathinfo;
   864    977   	struct appfs_children *children, *child;
................................................................................
   960   1073   	const char *cachedir = APPFS_CACHEDIR;
   961   1074   	char dbfilename[1024];
   962   1075   	int pthread_ret, snprintf_ret, sqlite_ret;
   963   1076   
   964   1077   	globalThread.cachedir = cachedir;
   965   1078   	globalThread.boottime = time(NULL);
   966   1079   	globalThread.platform = "linux-x86_64";
         1080  +	globalThread.options.writable = 1;
   967   1081   
   968   1082   	pthread_ret = pthread_key_create(&interpKey, NULL);
   969   1083   	if (pthread_ret != 0) {
   970   1084   		fprintf(stderr, "Unable to create TSD key for Tcl.  Aborting.\n");
   971   1085   
   972   1086   		return(1);
   973   1087   	}