From: Volker Lendecke Date: Fri, 30 Dec 2022 19:49:11 +0000 (+0100) Subject: smbd: Move smb_set_posix_acl() to smb1_trans2.c X-Git-Tag: talloc-2.4.0~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f69b76fa18c8f335919d4859f93bacaabc544ec;p=thirdparty%2Fsamba.git smbd: Move smb_set_posix_acl() to smb1_trans2.c Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c index 54cf9134fb6..f70998e0e13 100644 --- a/source3/smbd/smb1_trans2.c +++ b/source3/smbd/smb1_trans2.c @@ -3686,6 +3686,171 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn, return NT_STATUS_OK; } +/**************************************************************************** + Deal with SMB_SET_POSIX_ACL. +****************************************************************************/ + +static NTSTATUS smb_set_posix_acl(connection_struct *conn, + struct smb_request *req, + const char *pdata, + int total_data_in, + files_struct *fsp, + struct smb_filename *smb_fname) +{ +#if !defined(HAVE_POSIX_ACLS) + return NT_STATUS_INVALID_LEVEL; +#else + uint16_t posix_acl_version; + uint16_t num_file_acls; + uint16_t num_def_acls; + bool valid_file_acls = true; + bool valid_def_acls = true; + NTSTATUS status; + unsigned int size_needed; + unsigned int total_data; + bool close_fsp = false; + + if (total_data_in < 0) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + total_data = total_data_in; + + if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + posix_acl_version = SVAL(pdata,0); + num_file_acls = SVAL(pdata,2); + 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) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + /* Wrap checks. */ + if (num_file_acls + num_def_acls < num_file_acls) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + size_needed = num_file_acls + num_def_acls; + + /* + * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less + * than UINT_MAX, so check by division. + */ + if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE; + if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + size_needed += SMB_POSIX_ACL_HEADER_SIZE; + + if (total_data < size_needed) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + /* + * Ensure we always operate on a file descriptor, not just + * the filename. + */ + if (fsp == NULL || !fsp->fsp_flags.is_fsa) { + uint32_t access_mask = SEC_STD_WRITE_OWNER| + SEC_STD_WRITE_DAC| + SEC_STD_READ_CONTROL| + FILE_READ_ATTRIBUTES| + FILE_WRITE_ATTRIBUTES; + + status = get_posix_fsp(conn, + req, + smb_fname, + access_mask, + &fsp); + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + close_fsp = true; + } + + /* Here we know fsp != NULL */ + SMB_ASSERT(fsp != NULL); + + status = refuse_symlink_fsp(fsp); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + /* If we have a default acl, this *must* be a directory. */ + if (valid_def_acls && !fsp->fsp_flags.is_directory) { + DBG_INFO("Can't set default acls on " + "non-directory %s\n", + fsp_str_dbg(fsp)); + return NT_STATUS_INVALID_HANDLE; + } + + DBG_DEBUG("file %s num_file_acls = %"PRIu16", " + "num_def_acls = %"PRIu16"\n", + fsp_str_dbg(fsp), + num_file_acls, + num_def_acls); + + /* Move pdata to the start of the file ACL entries. */ + pdata += SMB_POSIX_ACL_HEADER_SIZE; + + if (valid_file_acls) { + status = set_unix_posix_acl(conn, + fsp, + num_file_acls, + pdata); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + } + + /* Move pdata to the start of the default ACL entries. */ + pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE); + + if (valid_def_acls) { + status = set_unix_posix_default_acl(conn, + fsp, + num_def_acls, + pdata); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + } + + status = NT_STATUS_OK; + + out: + + if (close_fsp) { + (void)close_file_free(req, &fsp, NORMAL_CLOSE); + } + return status; +#endif +} + static void call_trans2setpathinfo( connection_struct *conn, struct smb_request *req, @@ -3834,6 +3999,10 @@ static void call_trans2setpathinfo( smb_fname->fsp, smb_fname); break; + case SMB_SET_POSIX_ACL: + status = smb_set_posix_acl( + conn, req, *ppdata, total_data, NULL, smb_fname); + break; } if (info_level_handled) { diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c index eff3e7676de..fea88900ed2 100644 --- a/source3/smbd/smb2_trans2.c +++ b/source3/smbd/smb2_trans2.c @@ -5282,169 +5282,6 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, return status; } -/**************************************************************************** - Deal with SMB_SET_POSIX_ACL. -****************************************************************************/ - -#if defined(HAVE_POSIX_ACLS) -static NTSTATUS smb_set_posix_acl(connection_struct *conn, - struct smb_request *req, - const char *pdata, - int total_data_in, - files_struct *fsp, - struct smb_filename *smb_fname) -{ - uint16_t posix_acl_version; - uint16_t num_file_acls; - uint16_t num_def_acls; - bool valid_file_acls = true; - bool valid_def_acls = true; - NTSTATUS status; - unsigned int size_needed; - unsigned int total_data; - bool close_fsp = false; - - if (total_data_in < 0) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - - total_data = total_data_in; - - if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - posix_acl_version = SVAL(pdata,0); - num_file_acls = SVAL(pdata,2); - 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) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - - /* Wrap checks. */ - if (num_file_acls + num_def_acls < num_file_acls) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - - size_needed = num_file_acls + num_def_acls; - - /* - * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less - * than UINT_MAX, so check by division. - */ - if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - - size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE; - if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - size_needed += SMB_POSIX_ACL_HEADER_SIZE; - - if (total_data < size_needed) { - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - - /* - * Ensure we always operate on a file descriptor, not just - * the filename. - */ - if (fsp == NULL || !fsp->fsp_flags.is_fsa) { - uint32_t access_mask = SEC_STD_WRITE_OWNER| - SEC_STD_WRITE_DAC| - SEC_STD_READ_CONTROL| - FILE_READ_ATTRIBUTES| - FILE_WRITE_ATTRIBUTES; - - status = get_posix_fsp(conn, - req, - smb_fname, - access_mask, - &fsp); - - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - close_fsp = true; - } - - /* Here we know fsp != NULL */ - SMB_ASSERT(fsp != NULL); - - status = refuse_symlink_fsp(fsp); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - /* If we have a default acl, this *must* be a directory. */ - if (valid_def_acls && !fsp->fsp_flags.is_directory) { - DBG_INFO("Can't set default acls on " - "non-directory %s\n", - fsp_str_dbg(fsp)); - return NT_STATUS_INVALID_HANDLE; - } - - DBG_DEBUG("file %s num_file_acls = %"PRIu16", " - "num_def_acls = %"PRIu16"\n", - fsp_str_dbg(fsp), - num_file_acls, - num_def_acls); - - /* Move pdata to the start of the file ACL entries. */ - pdata += SMB_POSIX_ACL_HEADER_SIZE; - - if (valid_file_acls) { - status = set_unix_posix_acl(conn, - fsp, - num_file_acls, - pdata); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - } - - /* Move pdata to the start of the default ACL entries. */ - pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE); - - if (valid_def_acls) { - status = set_unix_posix_default_acl(conn, - fsp, - num_def_acls, - pdata); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - } - - status = NT_STATUS_OK; - - out: - - if (close_fsp) { - (void)close_file_free(req, &fsp, NORMAL_CLOSE); - } - return status; -} -#endif - /**************************************************************************** Deal with SMB_SET_FILE_BASIC_INFO. ****************************************************************************/ @@ -5696,63 +5533,6 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn, fail_after_createfile); } -static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn, - struct smb_request *req, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - struct smb_filename *smb_fname, - files_struct *fsp, - char **ppdata, - int total_data, - int *ret_data_size) -{ - char *pdata = *ppdata; - NTSTATUS status = NT_STATUS_OK; - int data_return_size = 0; - - *ret_data_size = 0; - - if (!CAN_WRITE(conn)) { - /* Allow POSIX opens. The open path will deny - * any non-readonly opens. */ - if (info_level != SMB_POSIX_PATH_OPEN) { - return NT_STATUS_DOS(ERRSRV, ERRaccess); - } - } - - DBG_DEBUG("file=%s (%s) info_level=%d totdata=%d\n", - smb_fname_str_dbg(smb_fname), - fsp_fnum_dbg(fsp), - info_level, - total_data); - - switch (info_level) { - -#if defined(HAVE_POSIX_ACLS) - case SMB_SET_POSIX_ACL: - { - status = smb_set_posix_acl(conn, - req, - pdata, - total_data, - fsp, - smb_fname); - break; - } -#endif - - default: - return NT_STATUS_INVALID_LEVEL; - } - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - *ret_data_size = data_return_size; - return NT_STATUS_OK; -} - NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, struct smb_request *req, TALLOC_CTX *mem_ctx, @@ -5766,29 +5546,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; - if (INFO_LEVEL_IS_UNIX(info_level)) { - if (!lp_smb1_unix_extensions()) { - return NT_STATUS_INVALID_LEVEL; - } - if (!req->posix_pathnames) { - return NT_STATUS_INVALID_LEVEL; - } - status = smbd_do_posix_setfilepathinfo(conn, - req, - req, - info_level, - smb_fname, - fsp, - ppdata, - total_data, - &data_return_size); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - *ret_data_size = data_return_size; - return NT_STATUS_OK; - } - *ret_data_size = 0; DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "