mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 18:14:24 +08:00
Fixed deletions from a sticky directory (on kernels >= 2.6.25)
This commit is contained in:
parent
7c05f13884
commit
767b4d075c
@ -3747,6 +3747,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
|
||||
int perm;
|
||||
int res;
|
||||
int allow;
|
||||
struct stat stbuf;
|
||||
|
||||
/*
|
||||
* Always allow for root. From the user's point of view,
|
||||
@ -3784,9 +3785,13 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
|
||||
&& ((perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0);
|
||||
break;
|
||||
case S_IWRITE + S_IEXEC + S_ISVTX:
|
||||
if (perm & S_ISVTX)
|
||||
allow = 2;
|
||||
else
|
||||
if (perm & S_ISVTX) {
|
||||
if ((ntfs_get_owner_mode(scx,path,ni,&stbuf) >= 0)
|
||||
&& (stbuf.st_uid == scx->uid))
|
||||
allow = 1;
|
||||
else
|
||||
allow = 2;
|
||||
} else
|
||||
allow = ((perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
|
||||
&& ((perm & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0);
|
||||
break;
|
||||
@ -3821,6 +3826,7 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
|
||||
char *name;
|
||||
ntfs_inode *ni;
|
||||
ntfs_inode *dir_ni;
|
||||
struct stat stbuf;
|
||||
|
||||
allow = 0;
|
||||
dirpath = strdup(path);
|
||||
@ -3835,16 +3841,17 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
|
||||
dir_ni, accesstype);
|
||||
ntfs_inode_close(dir_ni);
|
||||
/*
|
||||
* for a sticky directory, have to retry
|
||||
* and check whether file itself is writeable
|
||||
* for an not-owned sticky directory, have to
|
||||
* check whether file itself is owned
|
||||
*/
|
||||
if ((accesstype == (S_IWRITE + S_IEXEC + S_ISVTX))
|
||||
&& (allow == 2)) {
|
||||
ni = ntfs_pathname_to_inode(scx->vol, NULL,
|
||||
path);
|
||||
allow = FALSE;
|
||||
if (ni) {
|
||||
allow = ntfs_allowed_access(scx,path,
|
||||
ni, S_IWRITE);
|
||||
allow = (ntfs_get_owner_mode(scx,path,ni,&stbuf) >= 0)
|
||||
&& (stbuf.st_uid == scx->uid);
|
||||
ntfs_inode_close(ni);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- ntfsdev/ntfs-3g/src/ntfs-3g.c 2008-04-17 10:12:03.000000000 +0200
|
||||
+++ ntfsacls/ntfs-3g/src/ntfs-3g.c 2008-04-20 12:26:51.000000000 +0200
|
||||
--- ntfsdev/ntfs-3g/src/ntfs-3g.c 2008-06-02 10:13:23.000000000 +0200
|
||||
+++ ntfsacls/ntfs-3g/src/ntfs-3g.c 2008-06-02 11:06:46.000000000 +0200
|
||||
@@ -1069,9 +1069,15 @@
|
||||
securid = ntfs_inherited_id(&security, dir_path,
|
||||
dir_ni, S_ISDIR(type));
|
||||
@ -35,7 +35,7 @@
|
||||
else {
|
||||
/* Adjust read-only (for Windows) */
|
||||
if (perm & S_IWUSR)
|
||||
@@ -1729,6 +1743,38 @@
|
||||
@@ -1750,6 +1764,38 @@
|
||||
ntfschar *lename = NULL;
|
||||
int res, lename_len;
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
if (ctx->streams == NF_STREAMS_INTERFACE_WINDOWS)
|
||||
return ntfs_fuse_getxattr_windows(path, name, value, size);
|
||||
if (ctx->streams != NF_STREAMS_INTERFACE_XATTR)
|
||||
@@ -1779,6 +1825,37 @@
|
||||
@@ -1800,6 +1846,37 @@
|
||||
ntfschar *lename = NULL;
|
||||
int res, lename_len;
|
||||
|
||||
@ -112,7 +112,7 @@
|
||||
if (ctx->streams != NF_STREAMS_INTERFACE_XATTR)
|
||||
return -EOPNOTSUPP;
|
||||
if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) ||
|
||||
@@ -1837,6 +1914,37 @@
|
||||
@@ -1858,6 +1935,37 @@
|
||||
int res = 0, lename_len;
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@
|
||||
if (ctx->streams != NF_STREAMS_INTERFACE_XATTR)
|
||||
return -EOPNOTSUPP;
|
||||
if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) ||
|
||||
--- ntfsdev/ntfs-3g/include/ntfs-3g/security.h 2008-04-17 15:02:46.000000000 +0200
|
||||
--- ntfsdev/ntfs-3g/include/ntfs-3g/security.h 2008-05-30 08:53:07.000000000 +0200
|
||||
+++ ntfsacls/ntfs-3g/include/ntfs-3g/security.h 2008-04-20 11:37:48.000000000 +0200
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "inode.h"
|
||||
@ -285,8 +285,8 @@
|
||||
/*
|
||||
* Security API for direct access to security descriptors
|
||||
* based on Win32 API
|
||||
--- ntfsdev/ntfs-3g/libntfs-3g/security.c 2008-04-21 15:52:57.000000000 +0200
|
||||
+++ ntfsacls/ntfs-3g/libntfs-3g/security.c 2008-04-23 10:15:26.000000000 +0200
|
||||
--- ntfsdev/ntfs-3g/libntfs-3g/security.c 2008-06-02 10:19:12.000000000 +0200
|
||||
+++ ntfsacls/ntfs-3g/libntfs-3g/security.c 2008-06-02 10:26:10.000000000 +0200
|
||||
@@ -526,6 +526,673 @@
|
||||
return (ok);
|
||||
}
|
||||
@ -3493,7 +3493,7 @@
|
||||
} else {
|
||||
errno = EPERM;
|
||||
res = -1; /* neither owner nor root */
|
||||
@@ -3758,7 +6474,11 @@
|
||||
@@ -3759,7 +6475,11 @@
|
||||
if (!scx->usermapping || !scx->uid)
|
||||
allow = 1;
|
||||
else {
|
||||
@ -3506,7 +3506,7 @@
|
||||
if (perm >= 0) {
|
||||
res = EACCES;
|
||||
switch (accesstype) {
|
||||
@@ -3873,6 +6593,10 @@
|
||||
@@ -3880,6 +6600,10 @@
|
||||
mode_t mode;
|
||||
int perm;
|
||||
int res;
|
||||
@ -3517,7 +3517,7 @@
|
||||
|
||||
res = 0;
|
||||
/* get the current owner and mode from cache or security attributes */
|
||||
@@ -3882,10 +6606,23 @@
|
||||
@@ -3889,10 +6613,23 @@
|
||||
fileuid = cached->uid;
|
||||
filegid = cached->gid;
|
||||
mode = cached->mode;
|
||||
@ -3541,7 +3541,7 @@
|
||||
oldattr = getsecurityattr(scx->vol, path, ni);
|
||||
if (oldattr) {
|
||||
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)
|
||||
@@ -3898,6 +6635,21 @@
|
||||
@@ -3905,6 +6642,21 @@
|
||||
usid = (const SID*)
|
||||
&oldattr[le32_to_cpu(phead->owner)];
|
||||
#endif
|
||||
@ -3563,7 +3563,7 @@
|
||||
mode = perm = build_permissions(oldattr,
|
||||
usid, gsid, ni);
|
||||
if (perm >= 0) {
|
||||
@@ -3905,6 +6657,7 @@
|
||||
@@ -3912,6 +6664,7 @@
|
||||
filegid = findgroup(scx,gsid);
|
||||
} else
|
||||
res = -1;
|
||||
@ -3571,7 +3571,7 @@
|
||||
free(oldattr);
|
||||
} else
|
||||
res = -1;
|
||||
@@ -3926,11 +6679,19 @@
|
||||
@@ -3933,11 +6686,19 @@
|
||||
/* unless request originated by root */
|
||||
if (uid && (fileuid != uid))
|
||||
mode &= 01777;
|
||||
|
@ -1321,7 +1321,7 @@ static int ntfs_fuse_rm(const char *org_path)
|
||||
}
|
||||
/* JPA deny unlinking if directory is not writable and executable */
|
||||
if (!ntfs_fuse_fill_security_context(&security)
|
||||
|| ntfs_allowed_access(&security, path, dir_ni,
|
||||
|| ntfs_allowed_dir_access(&security, org_path,
|
||||
S_IEXEC + S_IWRITE + S_ISVTX)) {
|
||||
|
||||
if (ntfs_delete(ctx->vol, org_path, ni, dir_ni,
|
||||
@ -1379,7 +1379,7 @@ static int ntfs_fuse_unlink(const char *org_path)
|
||||
*/
|
||||
if (!ntfs_fuse_fill_security_context(&security)
|
||||
|| ntfs_allowed_dir_access(&security, path,
|
||||
S_IEXEC + S_IWRITE))
|
||||
S_IEXEC + S_IWRITE + S_ISVTX))
|
||||
res = ntfs_fuse_rm_stream(path, stream_name, stream_name_len);
|
||||
else
|
||||
res = -errno;
|
||||
@ -1425,7 +1425,15 @@ err:
|
||||
"to '%s'", new_path, tmp);
|
||||
} else {
|
||||
cleanup:
|
||||
ntfs_fuse_unlink(tmp);
|
||||
/*
|
||||
* Condition for this unlink has already been checked in
|
||||
* "ntfs_fuse_rename_existing_dest()", so it should never
|
||||
* fail (unless concurrent access to directories when fuse
|
||||
* is multithreaded)
|
||||
*/
|
||||
if (ntfs_fuse_unlink(tmp) < 0)
|
||||
ntfs_log_perror("Rename failed. Existing file '%s' still present "
|
||||
"as '%s'", new_path, tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1434,6 +1442,7 @@ static int ntfs_fuse_rename_existing_dest(const char *old_path, const char *new_
|
||||
{
|
||||
int ret, len;
|
||||
char *tmp;
|
||||
struct SECURITY_CONTEXT security;
|
||||
const char *ext = ".ntfs-3g-";
|
||||
|
||||
ntfs_log_trace("Entering\n");
|
||||
@ -1447,9 +1456,21 @@ static int ntfs_fuse_rename_existing_dest(const char *old_path, const char *new_
|
||||
if (ret != len - 1) {
|
||||
ntfs_log_error("snprintf failed: %d != %d\n", ret, len - 1);
|
||||
ret = -EOVERFLOW;
|
||||
} else
|
||||
ret = ntfs_fuse_safe_rename(old_path, new_path, tmp);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Make sure existing dest can be removed.
|
||||
* This is only needed if parent directory is
|
||||
* sticky, because in this situation condition
|
||||
* for unlinking is different from condition for
|
||||
* linking
|
||||
*/
|
||||
if (!ntfs_fuse_fill_security_context(&security)
|
||||
|| ntfs_allowed_dir_access(&security, new_path,
|
||||
S_IEXEC + S_IWRITE + S_ISVTX))
|
||||
ret = ntfs_fuse_safe_rename(old_path, new_path, tmp);
|
||||
else
|
||||
ret = -EACCES;
|
||||
}
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user