Exemplo n.º 1
0
int ensure_path_mounted(const char* path) 
{
    const Volume* volume = get_volume_for_path(path);
	if(volume == NULL) {
		
		ui_print("RECOVERY::ensure_path_mounted: Unable to locate a volume suitable for path %s\n", path);
		return -1;
	}
	
	return mount_volume(volume, NULL);		// Mount the volume if necessary
}
Exemplo n.º 2
0
static int submenu_restoreonevolume(const Volume* volume)
{
	char**			headers = NULL;		// UI menu headers
	const Volume*	sdvolume;			// SDCARD volume
	int 			sdmounted;			// Flag if SDCARD was mounted
	char 			filter[256];		// Directory browse filter string
	char 			imgfile[256];		// Selected image file to restore
	int 			nav;				// Menu navigation code
	int 			result;				// Result from function call
	
	// Allocate a standard header
	headers = alloc_standard_header(SUBHEADER_RESTOREVOLUMES);
	if(headers == NULL) { LOGE("submenu_restoreonevolume: Cannot allocate menu headers"); return NAVIGATE_ERROR; }
	
	// Grab a reference to the SDCARD volume
	sdvolume = get_volume("SDCARD");
	if(sdvolume == NULL) { LOGE("submenu_restoreonevolume: Cannot locate SDCARD volume entry in fstab"); return NAVIGATE_ERROR; }
	
	// The SDCARD volume has to be mounted before we can browse it (obviously)
	result = mount_volume(sdvolume, &sdmounted);
	if(result != 0) { LOGE("submenu_restoreonevolume: Cannot mount SDCARD volume"); return NAVIGATE_ERROR; }
	
	// Generate the directory browse filter string.  Backup files can have a number of different
	// extensions, but if they were created by this recovery they will have the volume name in
	// ALL CAPS as the base file name
	snprintf(filter, 256, "%s*.*", volume->name);
	
	// Invoke the directory browser against the root of the SDCARD ...
	nav = navigate_menu_browse(headers, sdvolume->mount_point, filter, imgfile, 256);
	if(nav == NAVIGATE_SELECT) nav = submenu_restoreonevolume_confirm(volume, imgfile);
	
	// Unmount the SDCARD volume if it was mounted by this function
	if(sdmounted) unmount_volume(sdvolume, NULL);
	
	free_menu_list(headers);			// Release the string array
	return nav;							// Return navigation code
}
Exemplo n.º 3
0
int zuluCryptMountVolume( const char * path,const char * m_point,unsigned long mount_opts,const char * fs_opts,uid_t uid )
{
	int h ;

	string_t opts = StringVoid ;
	string_t fs   = StringVoid ;
	string_t loop = StringVoid ;

	int fd = -1 ;

	m_struct mst ;
	mst.device = path ;
	mst.m_point = m_point ;
	mst.uid = uid ;
	mst.m_flags = mount_opts ;

	/*
	 * zuluCryptGetFileSystemFromDevice() is defined in this source file
	 */
	fs = zuluCryptGetFileSystemFromDevice( path ) ;

	if( fs == StringVoid ){
		/*
		 * failed to read file system,probably because the volume does have any or
		 * a plain volume was opened with a wrong key
		 */
		return zuluExit( 4,fd,opts,fs,loop ) ;
	}

	if( StringStartsWith( fs,"crypto" ) ){
		/*
		 * we cant mount an encrypted volume, exiting
		 */
		return zuluExit( 4,fd,opts,fs,loop ) ;
	}

	/*
	 * zuluCryptMountHasNotAllowedFileSystemOptions() is defined in ./mount_fs_options.c
	 */
	if( zuluCryptMountHasNotAllowedFileSystemOptions( uid,fs_opts,fs ) ){
		return zuluExit( -1,fd,opts,fs,loop ) ;
	}

	mst.fs_flags = fs_opts ;
	mst.fs = StringContent( fs ) ;
	opts = set_mount_options( &mst ) ;

	if( StringPrefixNotEqual( path,"/dev/" ) ){
		/*
		 * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop_device.c
		 */
		if( zuluCryptAttachLoopDeviceToFile( mst.device,O_RDWR,&fd,&loop ) ){
			mst.device = StringContent( loop ) ;
		}else{
			return zuluExit( -1,fd,opts,fs,loop ) ;
		}
	}

	if( zuluCryptFileSystemIsFUSEbased( path ) ){
		/*
		 * These file systems dont see to work with mount() command for some reason.
		 * Them being FUSE based could be a reason.
		 */
		switch( mount_FUSEfs( &mst ) ){
			case 0  : return zuluExit( 0,fd,opts,fs,loop )  ;
			case 16 : return zuluExit( 12,fd,opts,fs,loop ) ;
			default : return zuluExit( 1,fd,opts,fs,loop )  ;
		}
	}else{
		h = mount_volume( &mst ) ;
	}

	return zuluExit( h,fd,opts,fs,loop ) ;
}
Exemplo n.º 4
0
static int process_mount(struct fuse_client * c)
{
	struct afp_server_mount_request * req;
	struct afp_server  * s=NULL;
	struct afp_volume * volume;
	struct afp_connection_request conn_req;
	int ret;
	struct stat lstat;

	if ((c->incoming_size-1) < sizeof(struct afp_server_mount_request)) 
		goto error;

	req=(void *) c->incoming_string+1;

	/* Todo should check the existance and perms of the mount point */

	if ((ret=access(req->mountpoint,X_OK))!=0) {
		log_for_client((void *)c,AFPFSD,LOG_DEBUG,
			"Incorrect permissions on mountpoint %s: %s\n",
			req->mountpoint, strerror(errno));

		goto error;
	}

	if (stat(FUSE_DEVICE,&lstat)) {
		printf("Could not find %s\n",FUSE_DEVICE);
		goto error;
	}

	if (access(FUSE_DEVICE,R_OK | W_OK )!=0) {
		log_for_client((void *)c, AFPFSD,LOG_NOTICE, 
			"Incorrect permissions on %s, mode of device"
			" is %o, uid/gid is %d/%d.  But your effective "
			"uid/gid is %d/%d\n", 
				FUSE_DEVICE,lstat.st_mode, lstat.st_uid, 
				lstat.st_gid, 
				geteuid(),getegid());
		goto error;
	}

	log_for_client((void *)c,AFPFSD,LOG_NOTICE,
		"Mounting %s from %s on %s\n",
		(char *) req->url.servername, 
		(char *) req->url.volumename,req->mountpoint);

	if ((afp_default_connection_request(&conn_req,&req->url))==-1) {
		log_for_client((void *)c,AFPFSD,LOG_ERR,
			"Unknown UAM");
		return -1;
	}

	conn_req.uam_mask=req->uam_mask;

	if ((s=afp_server_full_connect(c,&conn_req))==NULL) {
		signal_main_thread();
		goto error;
	}
	
	if ((volume=mount_volume(c,s,req->url.volumename,
		req->url.volpassword))==NULL) {
		goto error;
	}

	volume->extra_flags|=req->volume_options;

	volume->mapping=req->map;
	afp_detect_mapping(volume);

	snprintf(volume->mountpoint,255,req->mountpoint);

	/* Create the new thread and block until we get an answer back */
	{
		pthread_mutex_t mutex;
		struct timespec ts;
		struct timeval tv;
		int ret;
		struct start_fuse_thread_arg arg;
		memset(&arg,0,sizeof(arg));
		arg.client = c;
		arg.volume = volume;
		arg.wait = 1;
		arg.changeuid=req->changeuid;

		gettimeofday(&tv,NULL);
		ts.tv_sec=tv.tv_sec;
		ts.tv_sec+=5;
		ts.tv_nsec=tv.tv_usec*1000;
		pthread_mutex_init(&mutex,NULL);
		pthread_cond_init(&volume->startup_condition_cond,NULL);

		/* Kickoff a thread to see how quickly it exits.  If
		 * it exits quickly, we have an error and it failed. */

		pthread_create(&volume->thread,NULL,start_fuse_thread,&arg);

		if (arg.wait) ret = pthread_cond_timedwait(
				&volume->startup_condition_cond,&mutex,&ts);

		report_fuse_errors(c);
		
		switch (arg.fuse_result) {
		case 0:
		if (volume->mounted==AFP_VOLUME_UNMOUNTED) {
			/* Try and discover why */
			switch(arg.fuse_errno) {
			case ENOENT:
				log_for_client((void *)c,AFPFSD,LOG_ERR,
					"Permission denied, maybe a problem with the fuse device or mountpoint?\n");
				break;
			default:
				log_for_client((void *)c,AFPFSD,LOG_ERR,
					"Mounting of volume %s of server %s failed.\n", 
						volume->volume_name_printable, 
						volume->server->server_name_printable);
			}
			goto error;
		} else {
			log_for_client((void *)c,AFPFSD,LOG_NOTICE,
				"Mounting of volume %s of server %s succeeded.\n", 
					volume->volume_name_printable, 
					volume->server->server_name_printable);
			return 0;
		}
		break;
		case ETIMEDOUT:
			log_for_client((void *)c,AFPFSD,LOG_NOTICE,
				"Still trying.\n");
			return 0;
			break;
		default:
			volume->mounted=AFP_VOLUME_UNMOUNTED;
			log_for_client((void *)c,AFPFSD,LOG_NOTICE,
				"Unknown error %d, %d.\n", 
				arg.fuse_result,arg.fuse_errno);
			goto error;
		}

	}
	return AFP_SERVER_RESULT_OKAY;
error:
	if ((s) && (!something_is_mounted(s))) {
		afp_server_remove(s);
	}
	signal_main_thread();
	return AFP_SERVER_RESULT_ERROR;
}