[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gfarm-discuss:03899] Gfarm + Autofs



Hello,

On the course of trying to make gfarm-fuse automatic using autofs. Since I found no documents/guide related to this topics, so I did some patching to gfarmfs-fuse and make it works with my autofs. Attached with this e-mail is the patch that make gfarmfs-fuse obay uid= and gid= options of fuse. Here's my set-up

/etc/auto.master: /grid /etc/auto.grid --timeout=1200

/etc/auto.grid is the program map. Somehow the program map is not working on compute nodes of ROCKS 4.2 so I have to switch back to file map. Program map is better since fuse only accept numeric value of uid and gid. Below are my program map.

/etc/auto.grid:
uid=$(id -u)
gid=$(id -g)
echo "-fstype=fuse,uid=$uid,gid=$gid,allow_other gfarmfs"

Platform: ROCKS 4.1 (RHEL4) on x86_64
Gfarm: 1.3.1 (no GSI). We're using Gfarm as Cluster file system.
Gfarmfs-fuse: 1.2.1

When user access /grid/user1, their gfarm home will be mapped to /grid/user1/user1. This works quite well. allow_other is a must, since fuse will consider this mount as root, but we need to allow the real owner to access it. But only the real owner can create the file since gfarm security is still apply.

I put seteuid/setegid wrap around every function to make gfarm believe that it run by that user (I put some condition so only root can do this). Will we have any other security issue with this patched? Also, sometimes the gfarmfs is lock up. I don't sure why, but it come back to work again when I do "killall -9 gfarmfs fusermount" :). Don't sure whether this is the result of my seteuid/setegid patch.

Regards,

-- -----------------------------------------------------------------------------------
Somsak Sriprayoonsakul

Thai National Grid Center
Software Industry Promotion Agency
Ministry of ICT, Thailand
somsak_sr@xxxxxxxxxxxxxx
-----------------------------------------------------------------------------------
--- gfarmfs-fuse-1.2.1/gfarmfs.c	2006-02-01 10:52:04.000000000 +0700
+++ gfarmfs-fuse-1.2.1-mod/gfarmfs.c	2006-09-08 15:08:06.000000000 +0700
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <pwd.h>
+#include <grp.h>
 #include <libgen.h>
 #include <stdlib.h>
 #include <time.h>
@@ -65,6 +66,28 @@
 static int enable_gfarm_unbuf = 0;
 static char *arch_name = NULL;
 
+static int enable_priv = 0;
+static uid_t gfarm_run_uid = -1;
+static gid_t gfarm_run_gid = -1;
+static uid_t old_uid = -1;
+static gid_t old_gid = -1;
+
+static void set_priv(void)
+{
+	if(enable_priv) {
+		setegid(gfarm_run_gid);
+		seteuid(gfarm_run_uid);
+	}
+}
+
+static void unset_priv(void)
+{
+	if(enable_priv) {
+		seteuid(old_uid);
+		setegid(old_gid);
+	}
+}
+
 /* This is necessary to free the memory space by free(). */
 static char *
 add_gfarm_prefix(const char *path)
@@ -100,6 +123,8 @@
 static int
 gfarmfs_final(char *e, int val_noerror, const char *name)
 {
+	int retval ;
+
 	if (e == NULL) {
 		return (val_noerror);
 	} else {
@@ -110,7 +135,12 @@
 				fprintf(stderr, "error: %s\n", e);
 			}
 		}
-		return -gfarm_error_to_errno(e);
+		set_priv();
+		
+		retval = -gfarm_error_to_errno(e);
+		unset_priv();
+		
+		return retval;
 	}
 }
 
@@ -122,6 +152,7 @@
 	char *e;
 	int res = 0;
 
+	set_priv();
 	e = gfs_opendir(url, &dir);
 	if (e == NULL) {
 		while ((e = gfs_readdir(dir, &entry)) == NULL &&
@@ -132,6 +163,8 @@
 		}
 		gfs_closedir(dir);
 	}
+	unset_priv();
+	
 	if (res == 0) {
 		return (2);
 	} else {
@@ -164,14 +197,19 @@
 {
 	char *e;
 
+	set_priv();
 	if (arch_name != NULL) {
 		e = gfs_access(url, X_OK);
 		if (e == NULL) {
 			e = gfs_pio_set_view_section(gf, arch_name, NULL, 0);
-			return (e);
+			unset_priv();
+			
+			return e;
 		}
 	}
-	return (NULL);
+	unset_priv();
+	
+	return NULL;
 }
 
 static char *
@@ -181,7 +219,10 @@
 
 	if (arch_name != NULL &&
 	    (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) {
+		set_priv();
 		e = gfs_pio_set_view_section(gf, arch_name, NULL, 0);
+		unset_priv();
+		
 		return (e);
 	} else {
 		return (NULL);
@@ -196,6 +237,7 @@
 	GFS_File gf;
 
 	url = add_gfarm_prefix(path);
+	set_priv();
 	e = gfs_pio_create(url,
 			   GFARM_FILE_WRONLY|GFARM_FILE_TRUNC|
 			   GFARM_FILE_EXCLUSIVE,
@@ -205,6 +247,8 @@
 		e = gfs_pio_close(gf);
 		if (e2 != NULL) e = e2;
 	}
+	unset_priv();
+	
 	free(url);
 	return (e);
 }
@@ -233,6 +277,7 @@
 	if (fc.path != NULL) {
 		char *e;
 
+		set_priv();
 		if (gfarmfs_debug >= 2) {
 			printf("fastcreate flush: %s\n", fc.path);
 		}
@@ -244,6 +289,8 @@
 			}
 		}
 		gfarmfs_fastcreate_free();
+		unset_priv();
+		
 		return (e);
 	} else {
 		return (NULL);  /* do nothing */
@@ -253,7 +300,10 @@
 static char *
 gfarmfs_fastcreate_save(const char *path, mode_t mode)
 {
+	set_priv();
 	gfarmfs_fastcreate_flush();
+	unset_priv();
+	
 
 	fc.path = strdup(path);
 	if (fc.path == NULL) {
@@ -273,6 +323,8 @@
 	char *url;
 
 	url = add_gfarm_prefix(path);
+	set_priv();
+	
 	if (fc.path != NULL && strcmp(fc.path, path) == 0) {
 		if (gfarmfs_debug >= 2) {
 			printf("fastcreate open: %s\n", path);
@@ -293,6 +345,8 @@
 				*gfp, url);
 		}
 	}
+	unset_priv();
+	
 	free(url);
 	return (e);
 }
@@ -308,8 +362,9 @@
 		buf->st_ino = 12345;    /* XXX */
 		buf->st_mode = fc.mode;
 		buf->st_nlink = 1;
-		buf->st_uid = getuid();
-		buf->st_gid = getgid();
+		buf->st_uid = gfarm_run_uid;
+		buf->st_gid = gfarm_run_gid;
+
 		buf->st_size = 0;
 		buf->st_blksize = GFS_BLKSIZE;
 		buf->st_blocks = 0;
@@ -341,8 +396,13 @@
 #endif
 	static struct passwd *p_save = NULL;
 	static char *username_save = NULL;
+	int retval;
 
+	set_priv();
+	
 	if (enable_fastcreate == 1 && gfarmfs_fastcreate_getattr(path, buf)) {
+		setegid(old_uid);
+		seteuid(old_gid);
 		return (0);
 	}
 
@@ -396,8 +456,8 @@
 			username_save = strdup(gs.st_user);
 			p_save = p;
 		} else {
-			buf->st_uid = getuid();
-			buf->st_gid = getgid();
+			buf->st_uid = gfarm_run_uid;
+			buf->st_gid = gfarm_run_gid;
 		}
 
 		buf->st_size = gs.st_size;
@@ -410,7 +470,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -420,7 +483,10 @@
 	struct gfs_dirent *entry;
 	char *e;
 	char *url;
+	int retval;
 
+	set_priv();
+	
 	gfarmfs_fastcreate_check();
 	e = gfarmfs_init();
 	if (e == NULL) {
@@ -443,13 +509,17 @@
 		}
 		e = gfs_closedir(dir);
 	}
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
 gfarmfs_mknod(const char *path, mode_t mode, dev_t rdev)
 {
 	char *e;
+	int retval;
 
 	if (rdev != 0 && ((rdev & S_IFREG) != S_IFREG)) {
 		if (gfarmfs_debug >= 1) {
@@ -458,12 +528,17 @@
 		return (-ENOSYS);  /* XXX */
 	}
 
+	set_priv();
+	
 	if (enable_fastcreate == 1) {
 		e = gfarmfs_fastcreate_save(path, mode);
 	} else {
 		e = gfarmfs_create_empty_file(path, mode);
 	}
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -471,7 +546,10 @@
 {
 	char *e;
 	char *url;
+	int retval;
 
+	set_priv();
+	
 	gfarmfs_fastcreate_check();
 	url = add_gfarm_prefix(path);
 	e = gfarmfs_init();
@@ -480,7 +558,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -488,7 +569,10 @@
 {
 	char *e;
 	char *url;
+	int retval;
 
+	set_priv();
+	
 	gfarmfs_fastcreate_check();
 	if ((e = gfarmfs_init()) != NULL) goto end;
 
@@ -543,7 +627,10 @@
 		free(url);
 	}
 end:
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -551,7 +638,10 @@
 {
 	char *e;
 	char *url;
+	int retval;
 
+	
+	set_priv();
 	gfarmfs_fastcreate_check();
 	url = add_gfarm_prefix(path);
 	e = gfarmfs_init();
@@ -560,7 +650,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -571,13 +664,15 @@
 	char *e;
 	char *url;
 	GFS_File gf;
-	int n = 0;
+	int n = 0, retval;
 
 	gfarmfs_fastcreate_check();
 	if (enable_symlink == 0) {
 		return (-ENOSYS);
 	}
 
+	
+	set_priv();
 	url = add_gfarm_prefix_symlink_suffix(path);
 	e = gfarmfs_init();
 	while (e == NULL) {
@@ -591,7 +686,10 @@
 
 	buf[n] = '\0';
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 #else
 	gfarmfs_fastcreate_check();
 	return (-ENOSYS);
@@ -607,7 +705,10 @@
 	char *url;
 	GFS_File gf;
 	int n, len;
+	int retval;
 
+	
+	set_priv();
 	gfarmfs_fastcreate_check();
 	if (enable_symlink == 0) {
 		return (-ENOSYS);
@@ -633,7 +734,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, to);
+	retval = gfarmfs_final(e, 0, to);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 #else
 	gfarmfs_fastcreate_check();
 	return (-ENOSYS);
@@ -646,7 +750,10 @@
 	char *e;
 	char *from_url;
 	char *to_url;
+	int retval;
 
+	
+	set_priv();
 	gfarmfs_fastcreate_check();
 	e = gfarmfs_init();
 	if (e == NULL) {
@@ -672,7 +779,10 @@
 		free(from_url);
 		free(to_url);
 	}
-	return gfarmfs_final(e, 0, to);
+	retval = gfarmfs_final(e, 0, to);
+	setegid(old_uid);
+	seteuid(old_gid);
+	return retval;
 }
 
 static int
@@ -687,12 +797,15 @@
 	int m, n;
 	char buf[4096];
 	int symlinkmode = 0;
+	int retval;
 
 	gfarmfs_fastcreate_check();
 	if (enable_linkiscopy == 0) {
 		return (-ENOSYS);
 	}
 
+	
+	set_priv();
 	if (gfarmfs_debug >= 2) {
 		printf("hard link is replaced by copy: %s\n", to);
 	}
@@ -767,7 +880,10 @@
 	if (to_opened == 1) {
 		gfs_pio_close(to_gf);
 	}
-	return gfarmfs_final(e, 0, to);
+	retval = gfarmfs_final(e, 0, to);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -775,16 +891,24 @@
 {
 	char *e;
 	char *url;
+	int retval;
 
 	gfarmfs_fastcreate_check();
 	url = add_gfarm_prefix(path);
+	set_priv();
+	
 	e = gfarmfs_init();
 	if (e == NULL) {
 		e = gfs_chmod(url, mode);
 	}
 	free(url);
+	unset_priv();
+	
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -794,7 +918,10 @@
 	char *e;
 	char *url;
 	struct gfs_stat s;
+	int retval;
 
+	set_priv();
+	
 	gfarmfs_fastcreate_check();
 	e = gfarmfs_init();
 	if (e == NULL) {
@@ -811,7 +938,10 @@
 			gfs_stat_free(&s);
 		}
 	}
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -820,9 +950,12 @@
 	char *e;
 	GFS_File gf;
 	char *url;
+	int retval;
 
 	gfarmfs_fastcreate_check();
 	url = add_gfarm_prefix(path);
+	set_priv();
+	
 	e = gfarmfs_init();
 	while (e == NULL) {
 		e = gfs_pio_open(url, GFARM_FILE_WRONLY, &gf);
@@ -837,7 +970,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -845,9 +981,12 @@
 {
 	char *e;
 	char *url;
+	int retval;
 
 	gfarmfs_fastcreate_check();
 	url = add_gfarm_prefix(path);
+	set_priv();
+	
 	e = gfarmfs_init();
 	if (e == NULL) {
 		if (buf == NULL)
@@ -864,7 +1003,10 @@
 	}
 	free(url);
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -872,9 +1014,11 @@
 {
 	char *e;
 	char *url;
-	int flags = 0;
+	int flags = 0, retval;
 	GFS_File gf;
 
+	set_priv();
+	
 	e = gfarmfs_init();
 	while (e == NULL) {
 		if ((fi->flags & O_ACCMODE) == O_RDONLY) {
@@ -914,7 +1058,10 @@
 		break;
 	}
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
@@ -922,26 +1069,34 @@
 {
 	char *e;
 	GFS_File gf;
+	int retval;
 
 	gfarmfs_fastcreate_check();
+	set_priv();
+	
 	e = gfarmfs_init();
 	if (e == NULL) {
 		gf = (GFS_File) fi->fh;
 		e = gfs_pio_close(gf);
 	}
 
-	return gfarmfs_final(e, 0, path);
+	retval = gfarmfs_final(e, 0, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
 gfarmfs_read(const char *path, char *buf, size_t size, off_t offset,
 	     struct fuse_file_info *fi)
 {
-	int n;
+	int n, retval;
 	file_offset_t off;
 	char *e;
 	GFS_File gf;
 
+	set_priv();
+	
 	e = gfarmfs_init();
 	while (e == NULL) {
 		gf = (GFS_File) fi->fh;
@@ -951,18 +1106,23 @@
 		break;
 	}
 
-	return gfarmfs_final(e, n, path);
+	retval = gfarmfs_final(e, n, path);
+	unset_priv();
+	
+	return retval;
 }
 
 static int
 gfarmfs_write(const char *path, const char *buf, size_t size,
 	      off_t offset, struct fuse_file_info *fi)
 {
-	int n;
+	int n, retval;
 	file_offset_t off;
 	char *e;
 	GFS_File gf;
 
+	set_priv();
+	
 	e = gfarmfs_init();
 	while (e == NULL) {
 		gf = (GFS_File) fi->fh;
@@ -972,7 +1132,10 @@
 		break;
 	}
 
-	return gfarmfs_final(e, n, path);
+	retval = gfarmfs_final(e, n, path);
+	unset_priv();
+	
+	return retval;
 }
 
 #if 0
@@ -1093,8 +1256,15 @@
 	int i;
 	int ok_s = 0; /* check -s */
 	char *opt_s_str = "-s";
+	int fuse_opt = 0;
+	char * fuse_args = NULL;
 
 	for(i = 1; i < argc; i++) {
+		if(fuse_opt) {
+			fuse_args = argv[i];
+			fuse_opt = 0;
+			continue;
+		}
 		if (strcmp(argv[i], "-s") == 0) {
 			ok_s = 1;
 		} else if (strcmp(argv[i], "-f") == 0) {
@@ -1104,6 +1274,46 @@
 		} else if (strcmp(argv[i], "-h") == 0) {
 			gfarmfs_usage();
 			exit(0);
+		} else if (strcmp(argv[i], "-o") == 0) {
+			fuse_opt = 1;
+		}
+	}
+	if(fuse_args) {
+		char * tok = NULL;
+		char * cur = fuse_args;
+		char * user, * group;
+		uid_t tmp_uid;
+		gid_t tmp_gid;
+		struct passwd * pwd;
+		struct group * gr;
+
+		tok = strchr(cur, ',');
+		while( (tok != NULL) || ((tok == NULL) && ( (*cur) != '\0'))) {
+			if(tok != NULL) (*tok) = '\0';
+			if(strstr(cur, "uid=") == cur) {
+				tmp_uid = (uid_t)strtoul(&cur[4], &user, 10);
+				if( ((*user) != '\0') && (pwd = getpwnam(&cur[4]))) {
+					/* we got user name instead */
+					tmp_uid = pwd->pw_uid;
+				}
+				gfarm_run_uid = tmp_uid;
+				enable_priv = 1;
+			} else if(strstr(cur, "gid=") == cur) {
+				tmp_gid = (gid_t)strtoul(&cur[4], &group, 10);
+				if( ((*group) != '\0') && (gr = getgrnam(&cur[4]))) {
+					/* we got user name instead */
+					tmp_gid = gr->gr_gid;
+				}
+				gfarm_run_gid = tmp_gid;
+				enable_priv = 1;
+			}
+			if(tok != NULL) {
+				(*tok) = ',';
+				cur = ++tok;
+				tok = strchr(cur, ',');
+			} else {
+				break;
+			}
 		}
 	}
 	if (ok_s == 0) { /* add -s option */
@@ -1176,17 +1386,32 @@
 	int ret;
 	char *e;
 
+	/* initialize privileges */
+	gfarm_run_uid = geteuid();
+	gfarm_run_gid = getegid();
+	old_uid = geteuid();
+	old_gid = getegid();
+
 	if (argc > 0) {
 		program_name = basename(argv[0]);
 	}
+	check_gfarmfs_options(&argc, &argv);
+	/* gfarm uid/gid might be changed by fuse option */
+	check_fuse_options(&argc, &argv);
+	/* Only allow uid change if we run by root */
+	if(geteuid() == 0) {
+		set_priv();
+	} else {
+		gfarm_run_uid = geteuid();
+		gfarm_run_gid = getegid();
+	}
 	/* e = gfarm_initialize(&argc, &argv); */
 	e = gfarm_initialize(NULL, NULL);
+	unset_priv();
 	if (e != NULL) {
 		fprintf(stderr, "%s: %s\n", program_name, e);
 		exit(-1);
 	}
-	check_gfarmfs_options(&argc, &argv);
-	check_fuse_options(&argc, &argv);
 
 	ret = fuse_main(argc, argv, &gfarmfs_oper);
 	gfarmfs_fastcreate_check();