From: Ralph Boehme Date: Thu, 22 Oct 2020 10:26:17 +0000 (+0200) Subject: smbd: split out POSIX info_levels from smbd_do_setfilepathinfo() into own function X-Git-Tag: talloc-2.3.2~137 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=63a4e8835824f0f0696223c0a3b0afb207595078;p=thirdparty%2Fsamba.git smbd: split out POSIX info_levels from smbd_do_setfilepathinfo() into own function smbd_do_setfilepathinfo() can be made fully handle based for all non-POSIX infolevels with pathref fsps, but for a POSIX create we may not have a fsp if the path points at a symlink. Splitting the POSIX from the non-POSIX logic allows for cleaner handling of this in the future with pathref fsps. Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Fri Oct 23 09:19:12 UTC 2020 on sn-devel-184 --- diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 424b9bf5cfb..2e2b9e899a5 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -8954,6 +8954,144 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, return close_file(req, fsp, NORMAL_CLOSE); } +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) { + case SMB_SET_FILE_UNIX_BASIC: + { + status = smb_set_file_unix_basic(conn, req, + pdata, + total_data, + fsp, + smb_fname); + break; + } + + case SMB_SET_FILE_UNIX_INFO2: + { + status = smb_set_file_unix_info2(conn, req, + pdata, + total_data, + fsp, + smb_fname); + break; + } + + case SMB_SET_FILE_UNIX_LINK: + { + if (smb_fname == NULL) { + /* We must have a pathname for this. */ + return NT_STATUS_INVALID_LEVEL; + } + status = smb_set_file_unix_link(conn, req, pdata, + total_data, smb_fname); + break; + } + + case SMB_SET_FILE_UNIX_HLINK: + { + if (smb_fname == NULL) { + /* We must have a pathname for this. */ + return NT_STATUS_INVALID_LEVEL; + } + status = smb_set_file_unix_hlink(conn, req, + pdata, total_data, + smb_fname); + break; + } + +#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 + + case SMB_SET_POSIX_LOCK: + { + if (fsp == NULL) { + return NT_STATUS_INVALID_LEVEL; + } + status = smb_set_posix_lock(conn, req, + pdata, total_data, fsp); + break; + } + + case SMB_POSIX_PATH_OPEN: + { + if (smb_fname == NULL) { + /* We must have a pathname for this. */ + return NT_STATUS_INVALID_LEVEL; + } + + status = smb_posix_open(conn, req, + ppdata, + total_data, + smb_fname, + &data_return_size); + break; + } + + case SMB_POSIX_PATH_UNLINK: + { + if (smb_fname == NULL) { + /* We must have a pathname for this. */ + return NT_STATUS_INVALID_LEVEL; + } + + status = smb_posix_unlink(conn, req, + pdata, + total_data, + smb_fname); + break; + } + + 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, @@ -8967,20 +9105,29 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; - *ret_data_size = 0; - - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - return NT_STATUS_INVALID_LEVEL; - } + if (INFO_LEVEL_IS_UNIX(info_level)) { + if (!lp_unix_extensions()) { + return NT_STATUS_INVALID_LEVEL; + } - 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); + 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 " "totdata=%d\n", smb_fname_str_dbg(smb_fname), fsp_fnum_dbg(fsp), @@ -9109,53 +9256,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_FILE_SHORT_NAME_INFORMATION: return NT_STATUS_NOT_SUPPORTED; - /* - * CIFS UNIX extensions. - */ - - case SMB_SET_FILE_UNIX_BASIC: - { - status = smb_set_file_unix_basic(conn, req, - pdata, - total_data, - fsp, - smb_fname); - break; - } - - case SMB_SET_FILE_UNIX_INFO2: - { - status = smb_set_file_unix_info2(conn, req, - pdata, - total_data, - fsp, - smb_fname); - break; - } - - case SMB_SET_FILE_UNIX_LINK: - { - if (fsp) { - /* We must have a pathname for this. */ - return NT_STATUS_INVALID_LEVEL; - } - status = smb_set_file_unix_link(conn, req, pdata, - total_data, smb_fname); - break; - } - - case SMB_SET_FILE_UNIX_HLINK: - { - if (fsp) { - /* We must have a pathname for this. */ - return NT_STATUS_INVALID_LEVEL; - } - status = smb_set_file_unix_hlink(conn, req, - pdata, total_data, - smb_fname); - break; - } - case SMB_FILE_RENAME_INFORMATION: { status = smb_file_rename_information(conn, req, @@ -9181,58 +9281,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, break; } -#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 - - case SMB_SET_POSIX_LOCK: - { - if (!fsp) { - return NT_STATUS_INVALID_LEVEL; - } - status = smb_set_posix_lock(conn, req, - pdata, total_data, fsp); - break; - } - - case SMB_POSIX_PATH_OPEN: - { - if (fsp) { - /* We must have a pathname for this. */ - return NT_STATUS_INVALID_LEVEL; - } - - status = smb_posix_open(conn, req, - ppdata, - total_data, - smb_fname, - &data_return_size); - break; - } - - case SMB_POSIX_PATH_UNLINK: - { - if (fsp) { - /* We must have a pathname for this. */ - return NT_STATUS_INVALID_LEVEL; - } - - status = smb_posix_unlink(conn, req, - pdata, - total_data, - smb_fname); - break; - } - default: return NT_STATUS_INVALID_LEVEL; }