From 3e212bb9019342693b456b8ba2a56864cae03ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Thu, 22 May 2014 08:46:08 +0200 Subject: [PATCH] Ignored chmod/chown/setfacl when Windows inheritance is applied chmod/chown/setfacl can only define permissions according to Linux rules with references to owner and group. Windows rules are more general and propagated through inheritance, and chmod/chown/setfacl may create unwanted deviations from these rules. Ignoring them prevents text editors from creating such deviations when updating a file and creating a backup one. --- src/lowntfs-3g.c | 30 +++++++++++++++++++++--------- src/ntfs-3g.c | 26 ++++++++++++++++++++------ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 694e376c..3cff727d 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -1432,15 +1432,17 @@ static int ntfs_fuse_chmod(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, int res = 0; ntfs_inode *ni; - /* return unsupported if no user mapping has been defined */ - if (!scx->mapping[MAPUSERS] && !ctx->silent) { + /* Unsupported if inherit or no user mapping has been defined */ + if ((!scx->mapping[MAPUSERS] || ctx->inherit) + && !ctx->silent) { res = -EOPNOTSUPP; } else { ni = ntfs_inode_open(ctx->vol, INODE(ino)); if (!ni) res = -errno; else { - if (scx->mapping[MAPUSERS]) { + /* ignore if Windows inheritance is forced */ + if (scx->mapping[MAPUSERS] && !ctx->inherit) { if (ntfs_set_mode(scx, ni, mode)) res = -errno; else { @@ -1469,7 +1471,8 @@ static int ntfs_fuse_chown(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, ntfs_inode *ni; int res; - if (!scx->mapping[MAPUSERS] + /* Unsupported if inherit or no user mapping has been defined */ + if ((!scx->mapping[MAPUSERS] || ctx->inherit) && !ctx->silent && ((uid != ctx->uid) || (gid != ctx->gid))) res = -EOPNOTSUPP; @@ -1479,7 +1482,9 @@ static int ntfs_fuse_chown(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, if (!ni) res = -errno; else { + /* ignore if Windows inheritance is forced */ if (scx->mapping[MAPUSERS] + && !ctx->inherit && (((int)uid != -1) || ((int)gid != -1))) { if (ntfs_set_owner(scx, ni, uid, gid)) res = -errno; @@ -1508,7 +1513,8 @@ static int ntfs_fuse_chownmod(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, ntfs_inode *ni; int res; - if (!scx->mapping[MAPUSERS] + /* Unsupported if inherit or no user mapping has been defined */ + if ((!scx->mapping[MAPUSERS] || ctx->inherit) && !ctx->silent && ((uid != ctx->uid) || (gid != ctx->gid))) res = -EOPNOTSUPP; @@ -1518,7 +1524,8 @@ static int ntfs_fuse_chownmod(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, if (!ni) res = -errno; else { - if (scx->mapping[MAPUSERS]) { + /* ignore if Windows inheritance is forced */ + if (scx->mapping[MAPUSERS] && !ctx->inherit) { if (ntfs_set_ownmod(scx, ni, uid, gid, mode)) res = -errno; else { @@ -2684,14 +2691,19 @@ static ntfs_inode *ntfs_check_access_xattr(fuse_req_t req, || (attr == XATTR_POSIX_DEF); /* * When accessing Posix ACL, return unsupported if ACL - * were disabled or no user mapping has been defined. + * were disabled or no user mapping has been defined, + * or trying to change a Windows-inherited ACL. * However no error will be returned to getfacl */ - if ((!ntfs_fuse_fill_security_context(req, security) + if (((!ntfs_fuse_fill_security_context(req, security) || (ctx->secure_flags & ((1 << SECURITY_DEFAULT) | (1 << SECURITY_RAW)))) + || (setting && ctx->inherit)) && foracl) { - errno = EOPNOTSUPP; + if (ctx->silent) + errno = 0; + else + errno = EOPNOTSUPP; } else { /* * parent directory must be executable, and diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index faae481a..bef29e1b 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -1510,8 +1510,12 @@ static int ntfs_fuse_chmod(const char *path, if (ntfs_fuse_is_named_data_stream(path)) return -EINVAL; /* n/a for named data streams. */ - /* JPA return unsupported if no user mapping has been defined */ - if (!ntfs_fuse_fill_security_context(&security)) { + /* + * Return unsupported if no user mapping has been defined + * or enforcing Windows-type inheritance + */ + if (ctx->inherit + || !ntfs_fuse_fill_security_context(&security)) { if (ctx->silent) res = 0; else @@ -1550,7 +1554,12 @@ static int ntfs_fuse_chown(const char *path, uid_t uid, gid_t gid) if (ntfs_fuse_is_named_data_stream(path)) return -EINVAL; /* n/a for named data streams. */ - if (!ntfs_fuse_fill_security_context(&security)) { + /* + * Return unsupported if no user mapping has been defined + * or enforcing Windows-type inheritance + */ + if (ctx->inherit + || !ntfs_fuse_fill_security_context(&security)) { if (ctx->silent) return 0; if (uid == ctx->uid && gid == ctx->gid) @@ -2520,14 +2529,19 @@ static ntfs_inode *ntfs_check_access_xattr(struct SECURITY_CONTEXT *security, || (attr == XATTR_POSIX_DEF); /* * When accessing Posix ACL, return unsupported if ACL - * were disabled or no user mapping has been defined. + * were disabled or no user mapping has been defined, + * or trying to change a Windows-inherited ACL. * However no error will be returned to getfacl */ - if ((!ntfs_fuse_fill_security_context(security) + if (((!ntfs_fuse_fill_security_context(security) || (ctx->secure_flags & ((1 << SECURITY_DEFAULT) | (1 << SECURITY_RAW)))) + || (setting && ctx->inherit)) && foracl) { - errno = EOPNOTSUPP; + if (ctx->silent) + errno = 0; + else + errno = EOPNOTSUPP; } else { /* * parent directory must be executable, and