fix
diff --git a/ChangeLog b/ChangeLog
index 34fe25c..ace122c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-13  Miklos Szeredi <miklos@szeredi.hu>
+
+	* Remove 'mount_max' and 'user_allow_other' module options.  These
+	are now checked by fusermount, and can be set in /etc/fuse.conf
+
+	* KERNEL: change check for fsid == 0 to capable(CAP_DAC_OVERRIDE)
+
 2005-01-11  Miklos Szeredi <miklos@szeredi.hu>
 
 	* KERNEL: fix possible inode allocation problem, where
diff --git a/kernel/dir.c b/kernel/dir.c
index e07ea79..6d968ed 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -438,7 +438,7 @@
 		if (!(fc->flags & FUSE_ALLOW_OTHER) &&
 		    current->fsuid != fc->user_id &&
 		    (!(fc->flags & FUSE_ALLOW_ROOT) ||
-		     current->fsuid != 0))
+		     !capable(CAP_DAC_OVERRIDE)))
 			return -EACCES;
 	} else if (time_before_eq(jiffies, fi->i_time))
 		return 0;
@@ -451,7 +451,7 @@
 	struct fuse_conn *fc = get_fuse_conn(inode);
 
 	if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->user_id &&
-	    (!(fc->flags & FUSE_ALLOW_ROOT) || current->fsuid != 0))
+	    (!(fc->flags & FUSE_ALLOW_ROOT) || !capable(CAP_DAC_OVERRIDE)))
 		return -EACCES;
 	else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
 #ifdef KERNEL_2_6_10_PLUS
diff --git a/kernel/inode.c b/kernel/inode.c
index a3a709b..a82a62a 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -16,11 +16,9 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #ifdef KERNEL_2_6
-#include <linux/moduleparam.h>
 #include <linux/parser.h>
 #include <linux/statfs.h>
 #else
-#include <linux/proc_fs.h>
 #include "compat/parser.h"
 #endif
 
@@ -32,23 +30,6 @@
 
 spinlock_t fuse_lock;
 static kmem_cache_t *fuse_inode_cachep;
-static int mount_count;
-
-static int user_allow_other;
-#ifdef KERNEL_2_6
-module_param(user_allow_other, int, 0644);
-#else
-MODULE_PARM(user_allow_other, "i");
-#endif
-MODULE_PARM_DESC(user_allow_other, "Allow non root user to specify the \"allow_other\" or \"allow_root\" mount options");
-
-static int mount_max = 1000;
-#ifdef KERNEL_2_6
-module_param(mount_max, int, 0644);
-#else
-MODULE_PARM(mount_max, "i");
-#endif
-MODULE_PARM_DESC(mount_max, "Maximum number of FUSE mounts allowed, if -1 then unlimited (default: 1000)");
 
 #define FUSE_SUPER_MAGIC 0x65735546
 
@@ -277,7 +258,6 @@
 	struct fuse_conn *fc = get_fuse_conn_super(sb);
 
 	spin_lock(&fuse_lock);
-	mount_count --;
 	fc->sb = NULL;
 	fc->user_id = 0;
 	fc->flags = 0;
@@ -609,17 +589,6 @@
 	.show_options	= fuse_show_options,
 };
 
-static int inc_mount_count(void)
-{
-	int success = 0;
-	spin_lock(&fuse_lock);
-	mount_count ++;
-	if (mount_max == -1 || mount_count <= mount_max)
-		success = 1;
-	spin_unlock(&fuse_lock);
-	return success;
-}
-
 static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct fuse_conn *fc;
@@ -631,11 +600,6 @@
 	if (!parse_fuse_opt((char *) data, &d))
 		return -EINVAL;
 
-	if (!user_allow_other &&
-	    (d.flags & (FUSE_ALLOW_OTHER | FUSE_ALLOW_ROOT)) &&
-	    current->uid != 0)
-		return -EPERM;
-
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = FUSE_SUPER_MAGIC;
@@ -665,10 +629,6 @@
 
 	*get_fuse_conn_super_p(sb) = fc;
 
-	err = -ENFILE;
-	if (!inc_mount_count() && current->uid != 0)
-		goto err;
-
 	err = -ENOMEM;
 	root = get_root_inode(sb, d.rootmode);
 	if (root == NULL)
@@ -684,7 +644,6 @@
 
  err:
 	spin_lock(&fuse_lock);
-	mount_count --;
 	fc->sb = NULL;
 	fuse_release_conn(fc);
 	spin_unlock(&fuse_lock);
diff --git a/util/fusermount.c b/util/fusermount.c
index 259d0f7..9e39dbd 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -40,10 +40,14 @@
 #define FUSE_DEV_OLD "/proc/fs/fuse/dev"
 #define FUSE_DEV_NEW "/dev/fuse"
 #define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
+#define FUSE_CONF "/etc/fuse.conf"
 #define FUSE_MAJOR 10
 #define FUSE_MINOR 229
 
-const char *progname;
+static const char *progname;
+
+static int user_allow_other = 0;
+static int mount_max = 1000;
 
 static const char *get_user_name()
 {
@@ -156,9 +160,9 @@
     if (mtablock >= 0) {
         res = lockf(mtablock, F_LOCK, 0);
         if (res < 0)
-            perror("error getting lock");
+            fprintf(stderr, "%s: error getting lock", progname);
     } else
-        fprintf(stderr, "unable to open fuse lock file, continuing anyway\n");
+        fprintf(stderr, "%s: unable to open fuse lock file\n", progname);
 
     return mtablock;
 }
@@ -215,14 +219,14 @@
 
     fp = setmntent(mtab, "r");
     if (fp == NULL) {
-	fprintf(stderr, "%s failed to open %s: %s\n", progname, mtab,
+	fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
 		strerror(errno));
 	return -1;
     }
     
     newfp = setmntent(mtab_new, "w");
     if (newfp == NULL) {
-	fprintf(stderr, "%s failed to open %s: %s\n", progname, mtab_new,
+	fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab_new,
 		strerror(errno));
 	return -1;
     }
@@ -272,6 +276,24 @@
     return 0;
 }
 
+static int count_fuse_fs()
+{
+    struct mntent *entp;
+    int count = 0;
+    const char *mtab = _PATH_MOUNTED;
+    FILE *fp = setmntent(mtab, "r");
+    if (fp == NULL) {
+        fprintf(stderr, "%s: faild to open %s: %s\n", progname, mtab,
+                strerror(errno));
+        return -1;
+    }
+    while ((entp = getmntent(fp)) != NULL) {
+        if (strcmp(entp->mnt_type, "fuse") == 0)
+            count ++;
+    }
+    endmntent(fp);
+    return count;
+}
 
 static int do_unmount(const char *mnt, int quiet, int lazy, const char *mtab,
                       const char *mtab_new)
@@ -321,6 +343,32 @@
 }
 #endif /* USE_UCLIBC */    
 
+static void read_conf(void)
+{
+    FILE *fp = fopen(FUSE_CONF, "r");
+    if (fp != NULL) {
+        char line[256];
+        int isnewline = 1;
+        while (fgets(line, sizeof(line), fp) != NULL) {
+            if (isnewline) {
+                int tmp;
+                if (strcmp(line, "user_allow_other\n") == 0)
+                    user_allow_other = 1;
+                else if (sscanf(line, "mount_max = %i\n", &tmp) == 1)
+                    mount_max = tmp;
+            }
+            if(line[strlen(line)-1] == '\n')
+                isnewline = 1;
+            else
+                isnewline = 0;
+        }
+        fclose(fp);
+    } else if (errno != ENOENT) {
+        fprintf(stderr, "%s: failed to open %s: %s\n", progname, FUSE_CONF,
+                strerror(errno));
+    }
+}
+
 static int begins_with(const char *s, const char *beg)
 {
     if (strncmp(s, beg, strlen(beg)) == 0)
@@ -424,6 +472,14 @@
     return 0;
 }
 
+static int opt_eq(const char *s, unsigned len, const char *opt)
+{
+    if(strlen(opt) == len && strncmp(s, opt, len) == 0)
+        return 1;
+    else
+        return 0;
+}
+
 static int do_mount(const char *mnt, const char *type, mode_t rootmode,
                     int fd, const char *opts, const char *dev, char **fsnamep,
                     char **mnt_optsp)
@@ -464,9 +520,7 @@
             int on;
             int flag;
             int skip_option = 0;
-            const char *large_read_opt = "large_read";
-            if (len == strlen(large_read_opt) &&
-                strncmp(large_read_opt, s, len) == 0) {
+            if (opt_eq(s, len, "large_read")) {
                 struct utsname utsname;
                 unsigned kmaj, kmin;
                 res = uname(&utsname);
@@ -477,6 +531,13 @@
                     skip_option = 1;
                 }
             }
+            if (getuid() != 0 && !user_allow_other &&
+                (opt_eq(s, len, "allow_other") ||
+                 opt_eq(s, len, "allow_root"))) {
+                fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);
+                free(optbuf);
+                return -1;
+            }
             if (!skip_option) {
                 if (find_mount_flag(s, len, &on, &flag)) {
                     if (on)
@@ -713,7 +774,8 @@
     if (fd >= 0)
         return fd;
     
-    fprintf(stderr, "fuse device not found, try 'modprobe fuse' first\n");
+    fprintf(stderr, "%s: fuse device not found, try 'modprobe fuse' first\n",
+            progname);
     return -1;
 }
 
@@ -729,15 +791,45 @@
     char *mnt_opts;
     const char *real_mnt = mnt;
     int currdir_fd = -1;
+    int mtablock = -1;
 
     fd = open_fuse_device(&dev);
     if (fd == -1)
         return -1;
- 
+
+#ifndef USE_UCLIBC 
+    if (geteuid() == 0) {
+        mtablock = lock_mtab();
+        if (mtablock < 0) {
+            close(fd);
+            return -1;
+        }
+    }
+#endif
+
     if (getuid() != 0) {
         res = drop_privs();
-        if (res == -1)
+        if (res == -1) {
+            close(fd);
+#ifndef USE_UCLIBC
+            unlock_mtab(mtablock);
+#endif
             return -1;
+        }
+    }
+
+    read_conf();
+
+    if (getuid != 0 && mount_max != -1) {
+        int mount_count = count_fuse_fs();
+        if (mount_count >= mount_max) {
+            fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname);
+            close(fd);
+#ifndef USE_UCLIBC
+            unlock_mtab(mtablock);
+#endif
+            return -1;
+        }
     }
 
     res = check_version(dev);
@@ -751,8 +843,13 @@
     if (getuid() != 0)
         restore_privs();
 
-    if (res == -1)
+    if (res == -1) {
+        close(fd);
+#ifndef USE_UCLIBC
+        unlock_mtab(mtablock);
+#endif
         return -1;
+    }
 
     if (currdir_fd != -1) {
         fchdir(currdir_fd);
@@ -761,11 +858,11 @@
     
 #ifndef USE_UCLIBC
     if (geteuid() == 0) {
-        int mtablock = lock_mtab();
         res = add_mount(fsname, mnt, type, mnt_opts);
         unlock_mtab(mtablock);
         if (res == -1) {
             umount2(mnt, 2); /* lazy umount */
+            close(fd);
             return -1;
         }
     }