freebsd-ports/sysutils/fusefs-kmod/files/patch-fuse_vnops.c
Martin Matuska b0357819a0 - Update to 0.3.9-pre1
- Add additional patches

PR:		ports/114629
Approved by:	maintainer, garga (mentor, implicit)
Tested by:	freebsd-ports@
2007-08-13 10:48:41 +00:00

106 lines
3.3 KiB
C

--- fuse_module/fuse_vnops.c Sat Jul 14 13:14:27 2007
+++ fuse_module/fuse_vnops.c Sat Jul 14 13:14:27 2007
@@ -42,6 +42,10 @@
#include "fuse_vnode.h"
#include "fuse_io.h"
+#if USE_PRIVILEGE_API
+#include <sys/priv.h>
+#endif
+
/* function prototype for iterators over filehandles (of a vp) */
typedef int fuse_metrics_t(struct vnode *vp, struct thread *td,
struct ucred *cred, struct fuse_filehandle *fufh,
@@ -63,7 +67,9 @@ struct fuse_access_param {
#define FACCESS_CHOWN 0x08 /* do permission check for owner changing */
#define FACCESS_NOCHECKSPY 0x10 /* don't check if daemon is allowed to spy on
user */
-#define FACCESS_XQUERIES FACCESS_STICKY | FACCESS_CHOWN
+#define FACCESS_SETGID 0x12 /* do permission check for setting setgid flag */
+
+#define FACCESS_XQUERIES FACCESS_STICKY | FACCESS_CHOWN | FACCESS_SETGID
#define FVP_ACCESS_NOOP 0x01 /* vnode based control flag for doing access check */
@@ -855,6 +861,7 @@ fuse_access(ap)
/*
* Attribute caching hasn't yet been implemented.
+ * [... Update: it _has been_ implemented.]
* However, within one function we don't wanna query attributes
* several times. Now it's enough pull the attributes once, and throw
* it into the following routine with various modes.
@@ -929,12 +936,16 @@ fuse_access_i(struct vnode *vp, mode_t m
mode == VWRITE) {
if (cred->cr_uid != facp->xuid &&
cred->cr_uid != VTOVA(vp)->va_uid)
- err = suser_cred(cred, SUSER_ALLOWJAIL);
+ err = priv_check_cred(cred,
+ PRIV_VFS_ADMIN,
+ 0);
}
/*
* We return here because this flags is exlusive
* with the others
*/
+ KASSERT(facp->facc_flags == FACCESS_STICKY,
+ ("sticky access check comes in mixed"));
return (err);
}
@@ -947,10 +958,21 @@ fuse_access_i(struct vnode *vp, mode_t m
(cred->cr_gid != facp->xgid &&
facp->xgid != (gid_t)VNOVAL &&
! groupmember(facp->xgid, cred)))
- err = suser_cred(cred, SUSER_ALLOWJAIL);
- return (err);
+ err = priv_check_cred(cred, PRIV_VFS_CHOWN, 0);
+ if (err)
+ return (err);
}
+ if (facp->facc_flags & FACCESS_SETGID) {
+ gid_t sgid = facp->xgid;
+
+ if (sgid == (gid_t)VNOVAL)
+ sgid = VTOVA(vp)->va_gid;
+
+ if (! groupmember(sgid, cred))
+ err = priv_check_cred(cred, PRIV_VFS_SETGID, 0);
+ return (err);
+ }
} else {
#if FUSE_HAS_ACCESS
@@ -1234,7 +1256,13 @@ fuse_lookup(ap)
*/
if (nameiop == RENAME && wantparent && islastcn) {
DEBUG("something to rename...\n");
- if ((err = fuse_access_i(dvp, VWRITE, cred, td, &facp)))
+
+ facp.xuid = fattr->uid;
+ facp.facc_flags |= FACCESS_STICKY;
+ err = fuse_access_i(dvp, VWRITE, cred, td, &facp);
+ facp.facc_flags &= ~FACCESS_XQUERIES;
+
+ if (err)
goto out;
/*
@@ -2948,8 +2976,14 @@ fuse_setattr(ap)
}
if (vap->va_mode != (mode_t)VNOVAL) {
+#if _DEBUG
if (vap->va_mode & S_IFMT)
- DEBUG("fuse_setattr -- weird: format bits in mode field, 0%o\n", vap->va_mode);
+ DEBUG("fuse_setattr -- weird: "
+ "format bits in mode field, 0%o\n",
+ vap->va_mode);
+#endif
+ if (vap->va_mode & S_ISGID)
+ facp.facc_flags |= FACCESS_SETGID;
fsai->FUSEATTR(mode) = vap->va_mode & ALLPERMS;
fsai->valid |= FATTR_MODE;
}