mirror of
https://github.com/samba-team/samba.git
synced 2025-03-01 04:58:35 +03:00
smbd: Move smb_set_posix_acl() to smb1_trans2.c
Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
19c41395e5
commit
4f69b76fa1
@ -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) {
|
||||
|
@ -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 "
|
||||
|
Loading…
x
Reference in New Issue
Block a user