summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-10-31 18:04:53 -0700
committerJeremy Allison <jra@samba.org>2008-10-31 18:04:53 -0700
commit54eaf2de74b4779919ae97b54abceb3878894bf6 (patch)
tree21ab7a23cc7f16d8c5afcae7d37c8305f214a7bb
parent7ca8be13842a488691e33ba3edd0b714e5e3ae6a (diff)
downloadsamba-54eaf2de74b4779919ae97b54abceb3878894bf6.tar.gz
samba-54eaf2de74b4779919ae97b54abceb3878894bf6.tar.bz2
samba-54eaf2de74b4779919ae97b54abceb3878894bf6.zip
Get closer to passing S4 RAW-ACLs.
Jeremy.
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/lib/secdesc.c6
-rw-r--r--source3/lib/util_seaccess.c4
-rw-r--r--source3/modules/vfs_acl_xattr.c91
-rw-r--r--source3/smbd/open.c47
-rw-r--r--source3/smbd/trans2.c9
6 files changed, 130 insertions, 29 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 8b64877d86..fdbad2a22a 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1228,7 +1228,7 @@ struct bitmap {
#define FILE_GENERIC_WRITE (STD_RIGHT_READ_CONTROL_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\
FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE_ACCESS)
-#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|\
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\
FILE_EXECUTE|SYNCHRONIZE_ACCESS)
/* Share specific rights. */
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index 1da2b3ec93..2987306066 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -529,7 +529,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
/* First add the regular ACE entry. */
init_sec_ace(new_ace, ptrustee, ace->type,
- ace->access_mask, SEC_ACE_FLAG_INHERITED_ACE);
+ ace->access_mask, 0);
DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
" inherited as %s:%d/0x%02x/0x%08x\n",
@@ -549,7 +549,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
}
init_sec_ace(new_ace, ptrustee, ace->type,
- ace->access_mask, new_flags | SEC_ACE_FLAG_INHERITED_ACE);
+ ace->access_mask, new_flags);
DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
" inherited as %s:%d/0x%02x/0x%08x\n",
@@ -565,7 +565,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
/* Create child security descriptor to return */
new_dacl = make_sec_acl(ctx,
- ACL_REVISION,
+ NT4_ACL_REVISION,
new_ace_list_ndx,
new_ace_list);
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 17d4b78202..d7fdc9a8b9 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -110,7 +110,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
{
uint32_t denied = 0, granted = 0;
unsigned i;
-
+
if (is_sid_in_token(token, sd->owner_sid)) {
granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
} else if (user_has_privileges(token, &se_restore)) {
@@ -120,7 +120,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
if (sd->dacl == NULL) {
return granted & ~denied;
}
-
+
for (i = 0;i<sd->dacl->num_aces; i++) {
struct security_ace *ace = &sd->dacl->aces[i];
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index ca34e97155..e465e8f380 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -144,7 +144,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
return NT_STATUS_OK;
}
-static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob)
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
{
struct xattr_NTACL xacl;
struct security_descriptor_timestamp sd_ts;
@@ -163,7 +163,7 @@ static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob)
xacl.version = 2;
xacl.info.sd_ts = &sd_ts;
- xacl.info.sd_ts->sd = CONST_DISCARD(SEC_DESC *, psd);
+ xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
@@ -250,7 +250,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
files_struct *fsp,
const char *name,
uint32 security_info,
- SEC_DESC **ppdesc)
+ struct security_descriptor **ppdesc)
{
TALLOC_CTX *ctx = talloc_tos();
DATA_BLOB blob;
@@ -292,8 +292,50 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
}
/*********************************************************************
- * Currently this only works for existing files. Need to work on
- * inheritance for new files.
+ Create a default security descriptor for a file in case no inheritance
+ exists. All permissions to the owner and SYSTEM.
+*********************************************************************/
+
+static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct dom_sid owner_sid, group_sid;
+ size_t sd_size;
+ struct security_ace *pace = NULL;
+ struct security_acl *pacl = NULL;
+
+ uid_to_sid(&owner_sid, psbuf->st_uid);
+ gid_to_sid(&group_sid, psbuf->st_gid);
+
+ pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
+ if (!pace) {
+ return NULL;
+ }
+
+ init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_RIGHTS_FILE_ALL, 0);
+ init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_RIGHTS_FILE_ALL, 0);
+
+ pacl = make_sec_acl(mem_ctx,
+ NT4_ACL_REVISION,
+ 2,
+ pace);
+ if (!pacl) {
+ return NULL;
+ }
+ return make_sec_desc(mem_ctx,
+ SECURITY_DESCRIPTOR_REVISION_1,
+ SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
+ SEC_DESC_DACL_DEFAULTED,
+ &owner_sid,
+ &group_sid,
+ NULL,
+ pacl,
+ &sd_size);
+}
+
+/*********************************************************************
*********************************************************************/
static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
@@ -303,8 +345,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
{
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status;
- SEC_DESC *parent_desc = NULL;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *parent_desc = NULL;
+ struct security_descriptor *psd = NULL;
DATA_BLOB blob;
size_t size;
char *parent_name;
@@ -343,6 +385,25 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ if (psd->dacl == NULL) {
+ SMB_STRUCT_STAT sbuf;
+ int ret;
+
+ TALLOC_FREE(psd);
+ if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ }
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ psd = default_file_sd(ctx, &sbuf);
+ if (!psd) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
status = create_acl_blob(psd, &blob);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -365,7 +426,7 @@ static int open_acl_xattr(vfs_handle_struct *handle,
mode_t mode)
{
uint32_t access_granted = 0;
- SEC_DESC *pdesc = NULL;
+ struct security_descriptor *pdesc = NULL;
bool file_existed = true;
NTSTATUS status = get_nt_acl_xattr_internal(handle,
NULL,
@@ -417,7 +478,7 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m
}
static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
- uint32 security_info, SEC_DESC **ppdesc)
+ uint32 security_info, struct security_descriptor **ppdesc)
{
NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
NULL, security_info, ppdesc);
@@ -434,7 +495,7 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
}
static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
- const char *name, uint32 security_info, SEC_DESC **ppdesc)
+ const char *name, uint32 security_info, struct security_descriptor **ppdesc)
{
NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
name, security_info, ppdesc);
@@ -451,7 +512,7 @@ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
}
static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
- uint32 security_info_sent, const SEC_DESC *psd)
+ uint32 security_info_sent, const struct security_descriptor *psd)
{
NTSTATUS status;
DATA_BLOB blob;
@@ -460,7 +521,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
fsp->fsp_name));
NDR_PRINT_DEBUG(security_descriptor,
- CONST_DISCARD(SEC_DESC *,psd));
+ CONST_DISCARD(struct security_descriptor *,psd));
}
status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
@@ -473,7 +534,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
int ret;
SMB_STRUCT_STAT sbuf;
DOM_SID owner_sid, group_sid;
- SEC_DESC *nc_psd = dup_sec_desc(talloc_tos(), psd);
+ struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
if (!nc_psd) {
return NT_STATUS_OK;
@@ -502,7 +563,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
SE_DESC_DACL_AUTO_INHERIT_REQ))==
(SE_DESC_DACL_AUTO_INHERITED|
SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
- SEC_DESC *new_psd = NULL;
+ struct security_descriptor *new_psd = NULL;
status = append_parent_acl(fsp, psd, &new_psd);
if (!NT_STATUS_IS_OK(status)) {
/* Lower level acl set succeeded,
@@ -516,7 +577,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
fsp->fsp_name));
NDR_PRINT_DEBUG(security_descriptor,
- CONST_DISCARD(SEC_DESC *,psd));
+ CONST_DISCARD(struct security_descriptor *,psd));
}
create_acl_blob(psd, &blob);
store_acl_blob_fsp(fsp, &blob);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 1564525005..5836c43afc 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1370,16 +1370,53 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
}
}
- /* This is a nasty hack - must fix... JRA. */
- if (access_mask == MAXIMUM_ALLOWED_ACCESS) {
- open_access_mask = access_mask = FILE_GENERIC_ALL;
- }
-
/*
* Convert GENERIC bits to specific bits.
*/
se_map_generic(&access_mask, &file_generic_mapping);
+
+ /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
+ if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
+ if (file_existed) {
+ struct security_descriptor *sd;
+ uint32_t access_granted = 0;
+
+ status = SMB_VFS_GET_NT_ACL(conn, fname,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),&sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_file_ntcreate: Could not get acl "
+ "on file %s: %s\n",
+ fname,
+ nt_errstr(status)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ status = se_access_check(sd, conn->server_info->ptok,
+ access_mask, &access_granted);
+
+ TALLOC_FREE(sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_file_ntcreate: Access denied on "
+ "file %s: when calculating maximum access\n",
+ fname));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ access_mask = access_granted;
+ /*
+ * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
+ */
+ access_mask |= FILE_READ_ATTRIBUTES;
+ } else {
+ access_mask = FILE_GENERIC_ALL;
+ }
+ }
+
open_access_mask = access_mask;
if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1da45a8b58..a450a56e72 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -3846,7 +3846,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
files_struct *fsp = NULL;
struct file_id fileid;
struct ea_list *ea_list = NULL;
- uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
char *lock_data = NULL;
bool ms_dfs_link = false;
TALLOC_CTX *ctx = talloc_tos();
@@ -3939,7 +3938,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
pos = fsp->fh->position_information;
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
get_file_infos(fileid, &delete_pending, &write_time_ts);
- access_mask = fsp->access_mask;
}
} else {
@@ -4403,7 +4401,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_FILE_ACCESS_INFORMATION:
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
- SIVAL(pdata,0,access_mask);
+ if (fsp) {
+ SIVAL(pdata,0,fsp->access_mask);
+ } else {
+ /* GENERIC_EXECUTE mapping from Windows */
+ SIVAL(pdata,0,0x12019F);
+ }
data_size = 4;
break;