summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/trans2.h6
-rw-r--r--source3/smbd/posix_acls.c56
-rw-r--r--source3/smbd/trans2.c67
3 files changed, 74 insertions, 55 deletions
diff --git a/source3/include/trans2.h b/source3/include/trans2.h
index 55b28ae937..b1fe2d9d83 100644
--- a/source3/include/trans2.h
+++ b/source3/include/trans2.h
@@ -506,6 +506,10 @@ In the same format as the uid/gid fields in the other
UNIX extensions definitions. Use 0xFFFFFFFFFFFFFFFF for
the MASK and OTHER entry types.
+If the Number of ACE entries for either file or default ACE's
+is set to 0xFFFF this means ignore this kind of ACE (and the
+number of entries sent will be zero.
+
*/
/* The query/set info levels for POSIX ACLs. */
@@ -530,4 +534,6 @@ the MASK and OTHER entry types.
#define SMB_POSIX_ACL_HEADER_SIZE 6
#define SMB_POSIX_ACL_ENTRY_SIZE 10
+
+#define SMB_POSIX_IGNORE_ACE_ENTRIES 0xFFFF
#endif
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 9b7c39c00e..7e20313b76 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2638,10 +2638,10 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
size_t sd_size = 0;
SEC_ACL *psa = NULL;
size_t num_acls = 0;
- size_t num_dir_acls = 0;
+ size_t num_def_acls = 0;
size_t num_aces = 0;
SMB_ACL_T posix_acl = NULL;
- SMB_ACL_T dir_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
@@ -2669,8 +2669,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
*/
if(fsp->is_directory) {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
- dir_acl = free_empty_sys_acl(conn, dir_acl);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl = free_empty_sys_acl(conn, def_acl);
}
} else {
@@ -2687,7 +2687,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
posix_acl ? "present" : "absent",
- dir_acl ? "present" : "absent" ));
+ def_acl ? "present" : "absent" ));
pal = load_inherited_info(fsp);
@@ -2725,8 +2725,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
return 0;
}
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ if (fsp->is_directory && def_acl) {
+ dir_ace = canonicalise_acl(fsp, def_acl, &sbuf,
&global_sid_Creator_Owner,
&global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
}
@@ -2790,15 +2790,15 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
}
num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
+ num_def_acls = count_canon_ace_list(dir_ace);
/* Allocate the ace list. */
- if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+ if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_def_acls)* sizeof(SEC_ACE))) == NULL) {
DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
goto done;
}
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+ memset(nt_ace_list, '\0', (num_acls + num_def_acls) * sizeof(SEC_ACE) );
/*
* Create the NT ACE list from the canonical ace lists.
@@ -2824,7 +2824,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
ace = dir_ace;
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ for (i = 0; i < num_def_acls; i++, ace = ace->next) {
SEC_ACCESS acc;
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
@@ -2894,8 +2894,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
if (posix_acl)
SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
- if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl)
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
free_inherited_info(pal);
@@ -3373,16 +3373,16 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
BOOL directory_has_default_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
BOOL has_acl = False;
SMB_ACL_ENTRY_T entry;
- if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
+ if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
has_acl = True;
}
- if (dir_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
return has_acl;
}
@@ -3532,23 +3532,23 @@ static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, uint16 num_
/****************************************************************************
Calls from UNIX extensions - Default POSIX ACL set.
- If num_dir_acls == 0 and not a directory just return. If it is a directory
- and num_dir_acls == 0 then remove the default acl. Else set the default acl
+ If num_def_acls == 0 and not a directory just return. If it is a directory
+ and num_def_acls == 0 then remove the default acl. Else set the default acl
on the directory.
****************************************************************************/
BOOL set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
- uint16 num_dir_acls, const char *pdata)
+ uint16 num_def_acls, const char *pdata)
{
- SMB_ACL_T dir_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
- if (num_dir_acls && !S_ISDIR(psbuf->st_mode)) {
+ if (num_def_acls && !S_ISDIR(psbuf->st_mode)) {
DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
errno = EISDIR;
return False;
}
- if (!num_dir_acls) {
+ if (!num_def_acls) {
/* Remove the default ACL. */
if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fname) == -1) {
DEBUG(5,("set_unix_posix_default_acl: acl_delete_def_file failed on directory %s (%s)\n",
@@ -3558,19 +3558,19 @@ BOOL set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_
return True;
}
- if ((dir_acl = create_posix_acl_from_wire(conn, num_dir_acls, pdata)) == NULL) {
+ if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) {
return False;
}
- if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, dir_acl) == -1) {
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
fname, strerror(errno) ));
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
return False;
}
DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
return True;
}
@@ -3701,7 +3701,7 @@ static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const c
/****************************************************************************
Calls from UNIX extensions - POSIX ACL set.
- If num_dir_acls == 0 then read/modify/write acl after removing all entries
+ If num_def_acls == 0 then read/modify/write acl after removing all entries
except SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER.
****************************************************************************/
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index afe4d352ff..b4140eeafe 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2927,9 +2927,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
case SMB_QUERY_POSIX_ACL:
{
SMB_ACL_T file_acl = NULL;
- SMB_ACL_T dir_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
uint16 num_file_acls = 0;
- uint16 num_dir_acls = 0;
+ uint16 num_def_acls = 0;
if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
@@ -2945,48 +2945,48 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
if (S_ISDIR(sbuf.st_mode)) {
if (fsp && fsp->is_directory) {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
} else {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
}
- dir_acl = free_empty_sys_acl(conn, dir_acl);
+ def_acl = free_empty_sys_acl(conn, def_acl);
}
num_file_acls = count_acl_entries(conn, file_acl);
- num_dir_acls = count_acl_entries(conn, dir_acl);
+ num_def_acls = count_acl_entries(conn, def_acl);
- if ( data_size < (num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
+ if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
data_size,
- (unsigned int)((num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
+ (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
SMB_POSIX_ACL_HEADER_SIZE) ));
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
- if (dir_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
}
SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
SSVAL(pdata,2,num_file_acls);
- SSVAL(pdata,4,num_dir_acls);
+ SSVAL(pdata,4,num_def_acls);
if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
- if (dir_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
}
- if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, dir_acl)) {
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
- if (dir_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
}
@@ -2994,10 +2994,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
- if (dir_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- data_size = (num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
+ data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
break;
}
@@ -3813,34 +3813,47 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
{
uint16 posix_acl_version;
uint16 num_file_acls;
- uint16 num_dir_acls;
+ uint16 num_def_acls;
+ BOOL valid_file_acls = True;
+ BOOL valid_def_acls = True;
if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
}
posix_acl_version = SVAL(pdata,0);
num_file_acls = SVAL(pdata,2);
- num_dir_acls = SVAL(pdata,4);
+ num_def_acls = SVAL(pdata,4);
+
+ if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_file_acls = False;
+ num_file_acls = 0;
+ }
+
+ if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_def_acls = False;
+ num_def_acls = 0;
+ }
if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
}
if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
- (num_file_acls+num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
+ (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
}
- if (!set_unix_posix_default_acl(conn, fname, &sbuf, num_dir_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE +
- (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+ if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (!set_unix_posix_acl(conn, fsp, fname, num_file_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+ if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
+
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);