summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_acl.c')
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index ad7ac5a749..26515cfe1a 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -384,6 +384,9 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
} else {
ret = fchown(fd, new_uid, new_gid);
}
+ if (errno == EPERM && uwrap_enabled()) {
+ ret = 0;
+ }
if (ret == -1) {
return pvfs_map_errno(pvfs, errno);
}
@@ -490,16 +493,16 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
{
uid_t uid = geteuid();
uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
+ struct security_token *token = req->session_info->security_token;
if (pvfs_read_only(pvfs, *access_mask)) {
return NT_STATUS_ACCESS_DENIED;
}
- /* owner and root get extra permissions */
- if (uid == 0) {
- max_bits |= SEC_STD_ALL | SEC_FLAG_SYSTEM_SECURITY;
- } else if (uid == name->st.st_uid) {
+ if (uid == name->st.st_uid) {
max_bits |= SEC_STD_ALL;
+ } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+ max_bits |= SEC_STD_DELETE;
}
if ((name->st.st_mode & S_IWOTH) ||
@@ -516,13 +519,23 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
max_bits |= SEC_STD_ALL;
}
- if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
- *access_mask = max_bits;
- return NT_STATUS_OK;
+ if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
+ *access_mask |= max_bits;
+ *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
}
- if (uid != 0 && (*access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
- return NT_STATUS_ACCESS_DENIED;
+ if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
+ security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
+ max_bits |= SEC_FLAG_SYSTEM_SECURITY;
+ }
+
+ if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
+ security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+ max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
+ }
+ if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
+ security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
+ max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
}
if (*access_mask & ~max_bits) {