mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
Attempt to fix one of the last two bugs with the full Windows ACL support.
When returning an underlying ACL on a directory, normally on a POSIX system it has no inheritable entries, which breaks the Windows ACL when a user does a get/set of a Windows ACL on a POSIX directory with no existing stored Windows ACL from the Windows ACL editor. What happens is any new entry added by the user gets set inheritable, but none of the others entries are (as returned by default). So any new files then only inherit the single new ACE entry (the one marked inheritable by the ACL editor). Fix this by faking up a default 3 element inheritable ACL that represents what a user creating a POSIX file or directory will get by default from the smbd code. Jeremy.
This commit is contained in:
parent
3d85b1ebe5
commit
6dcbb84d48
@ -156,6 +156,85 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Add in 3 inheritable components for a non-inheritable directory ACL.
|
||||
CREATOR_OWNER/CREATOR_GROUP/WORLD.
|
||||
*******************************************************************/
|
||||
|
||||
static void add_directory_inheritable_components(vfs_handle_struct *handle,
|
||||
const char *name,
|
||||
SMB_STRUCT_STAT *psbuf,
|
||||
struct security_descriptor *psd)
|
||||
{
|
||||
struct connection_struct *conn = handle->conn;
|
||||
int num_aces = (psd->dacl ? psd->dacl->num_aces : 0);
|
||||
struct smb_filename smb_fname;
|
||||
enum security_ace_type acl_type;
|
||||
uint32_t access_mask;
|
||||
mode_t dir_mode;
|
||||
mode_t file_mode;
|
||||
mode_t mode;
|
||||
struct security_ace *new_ace_list = TALLOC_ZERO_ARRAY(talloc_tos(),
|
||||
struct security_ace,
|
||||
num_aces + 3);
|
||||
|
||||
if (new_ace_list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fake a quick smb_filename. */
|
||||
ZERO_STRUCT(smb_fname);
|
||||
smb_fname.st = *psbuf;
|
||||
smb_fname.base_name = CONST_DISCARD(char *, name);
|
||||
|
||||
dir_mode = unix_mode(conn,
|
||||
FILE_ATTRIBUTE_DIRECTORY, &smb_fname, NULL);
|
||||
file_mode = unix_mode(conn,
|
||||
FILE_ATTRIBUTE_ARCHIVE, &smb_fname, NULL);
|
||||
|
||||
mode = dir_mode | file_mode;
|
||||
|
||||
DEBUG(10, ("add_directory_inheritable_components: directory %s, "
|
||||
"mode = 0%o\n",
|
||||
name,
|
||||
(unsigned int)mode ));
|
||||
|
||||
if (num_aces) {
|
||||
memcpy(new_ace_list, psd->dacl->aces,
|
||||
num_aces * sizeof(struct security_ace));
|
||||
}
|
||||
access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
|
||||
mode & 0700, false);
|
||||
|
||||
init_sec_ace(&new_ace_list[num_aces],
|
||||
&global_sid_Creator_Owner,
|
||||
acl_type,
|
||||
access_mask,
|
||||
SEC_ACE_FLAG_CONTAINER_INHERIT|
|
||||
SEC_ACE_FLAG_OBJECT_INHERIT|
|
||||
SEC_ACE_FLAG_INHERIT_ONLY);
|
||||
access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
|
||||
(mode << 3) & 0700, false);
|
||||
init_sec_ace(&new_ace_list[num_aces+1],
|
||||
&global_sid_Creator_Group,
|
||||
acl_type,
|
||||
access_mask,
|
||||
SEC_ACE_FLAG_CONTAINER_INHERIT|
|
||||
SEC_ACE_FLAG_OBJECT_INHERIT|
|
||||
SEC_ACE_FLAG_INHERIT_ONLY);
|
||||
access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
|
||||
(mode << 6) & 0700, false);
|
||||
init_sec_ace(&new_ace_list[num_aces+2],
|
||||
&global_sid_World,
|
||||
acl_type,
|
||||
access_mask,
|
||||
SEC_ACE_FLAG_CONTAINER_INHERIT|
|
||||
SEC_ACE_FLAG_OBJECT_INHERIT|
|
||||
SEC_ACE_FLAG_INHERIT_ONLY);
|
||||
psd->dacl->aces = new_ace_list;
|
||||
psd->dacl->num_aces += 3;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Pull a DATA_BLOB from an xattr given a pathname.
|
||||
If the hash doesn't match, or doesn't exist - return the underlying
|
||||
@ -261,6 +340,33 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
|
||||
/* We're returning the blob, throw
|
||||
* away the filesystem SD. */
|
||||
TALLOC_FREE(pdesc_next);
|
||||
} else {
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
SMB_STRUCT_STAT *psbuf = &sbuf;
|
||||
bool is_directory = false;
|
||||
/*
|
||||
* We're returning the underlying ACL from the
|
||||
* filesystem. If it's a directory, and has no
|
||||
* inheritable ACE entries we have to fake them.
|
||||
*/
|
||||
if (fsp) {
|
||||
is_directory = fsp->is_directory;
|
||||
psbuf = &fsp->fsp_name->st;
|
||||
} else {
|
||||
if (vfs_stat_smb_fname(handle->conn,
|
||||
name,
|
||||
&sbuf) == 0) {
|
||||
is_directory = S_ISDIR(sbuf.st_ex_mode);
|
||||
}
|
||||
}
|
||||
if (is_directory &&
|
||||
!sd_has_inheritable_components(psd,
|
||||
true)) {
|
||||
add_directory_inheritable_components(handle,
|
||||
name,
|
||||
psbuf,
|
||||
psd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(security_info & OWNER_SECURITY_INFORMATION)) {
|
||||
|
Loading…
Reference in New Issue
Block a user