mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
smbd: Simplify call_trans2setfilepathinfo()
Move the file/path specific preparations to the respective callers. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
6619b16fec
commit
f72572ff6f
@ -2362,204 +2362,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
|||||||
static void call_trans2setfilepathinfo(connection_struct *conn,
|
static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||||
struct smb_request *req,
|
struct smb_request *req,
|
||||||
unsigned int tran_call,
|
unsigned int tran_call,
|
||||||
|
uint16_t info_level,
|
||||||
|
struct smb_filename *smb_fname,
|
||||||
|
struct files_struct *fsp,
|
||||||
char **pparams, int total_params,
|
char **pparams, int total_params,
|
||||||
char **ppdata, int total_data,
|
char **ppdata, int total_data,
|
||||||
unsigned int max_data_bytes)
|
unsigned int max_data_bytes)
|
||||||
{
|
{
|
||||||
char *params = *pparams;
|
char *params = *pparams;
|
||||||
char *pdata = *ppdata;
|
|
||||||
uint16_t info_level;
|
|
||||||
struct smb_filename *smb_fname = NULL;
|
|
||||||
struct files_struct *dirfsp = NULL;
|
|
||||||
files_struct *fsp = NULL;
|
|
||||||
NTSTATUS status = NT_STATUS_OK;
|
NTSTATUS status = NT_STATUS_OK;
|
||||||
int data_return_size = 0;
|
int data_return_size = 0;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!params) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tran_call == TRANSACT2_SETFILEINFO) {
|
|
||||||
if (total_params < 4) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fsp = file_fsp(req, SVAL(params,0));
|
|
||||||
/* Basic check for non-null fsp. */
|
|
||||||
if (!check_fsp_open(conn, req, fsp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
info_level = SVAL(params,2);
|
|
||||||
|
|
||||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
|
||||||
if (!lp_smb1_unix_extensions()) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!req->posix_pathnames) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
smb_fname = fsp->fsp_name;
|
|
||||||
|
|
||||||
if (fsp_get_pathref_fd(fsp) == -1) {
|
|
||||||
/*
|
|
||||||
* This is actually a SETFILEINFO on a directory
|
|
||||||
* handle (returned from an NT SMB). NT5.0 seems
|
|
||||||
* to do this call. JRA.
|
|
||||||
*/
|
|
||||||
ret = vfs_stat(conn, smb_fname);
|
|
||||||
if (ret != 0) {
|
|
||||||
DBG_NOTICE("vfs_stat of %s failed (%s)\n",
|
|
||||||
smb_fname_str_dbg(smb_fname),
|
|
||||||
strerror(errno));
|
|
||||||
reply_nterror(req,
|
|
||||||
map_nt_error_from_unix(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (fsp->print_file) {
|
|
||||||
/*
|
|
||||||
* Doing a DELETE_ON_CLOSE should cancel a print job.
|
|
||||||
*/
|
|
||||||
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
|
|
||||||
|
|
||||||
fsp->fsp_flags.delete_on_close = true;
|
|
||||||
|
|
||||||
DEBUG(3,("call_trans2setfilepathinfo: "
|
|
||||||
"Cancelling print job (%s)\n",
|
|
||||||
fsp_str_dbg(fsp)));
|
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
|
||||||
send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
|
|
||||||
*ppdata, 0,
|
|
||||||
max_data_bytes);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
reply_nterror(req,
|
|
||||||
NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Original code - this is an open file.
|
|
||||||
*/
|
|
||||||
status = vfs_stat_fsp(fsp);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
DEBUG(3,("call_trans2setfilepathinfo: fstat "
|
|
||||||
"of %s failed (%s)\n", fsp_fnum_dbg(fsp),
|
|
||||||
nt_errstr(status)));
|
|
||||||
reply_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char *fname = NULL;
|
|
||||||
uint32_t ucf_flags = ucf_flags_from_smb_request(req);
|
|
||||||
bool require_existing_object = true;
|
|
||||||
NTTIME twrp = 0;
|
|
||||||
|
|
||||||
/* set path info */
|
|
||||||
if (total_params < 7) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
info_level = SVAL(params,0);
|
|
||||||
|
|
||||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
|
||||||
if (!lp_smb1_unix_extensions()) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!req->posix_pathnames) {
|
|
||||||
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->posix_pathnames) {
|
|
||||||
srvstr_get_path_posix(req,
|
|
||||||
params,
|
|
||||||
req->flags2,
|
|
||||||
&fname,
|
|
||||||
¶ms[6],
|
|
||||||
total_params - 6,
|
|
||||||
STR_TERMINATE,
|
|
||||||
&status);
|
|
||||||
} else {
|
|
||||||
srvstr_get_path(req,
|
|
||||||
params,
|
|
||||||
req->flags2,
|
|
||||||
&fname,
|
|
||||||
¶ms[6],
|
|
||||||
total_params - 6,
|
|
||||||
STR_TERMINATE,
|
|
||||||
&status);
|
|
||||||
}
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
reply_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ucf_flags & UCF_GMT_PATHNAME) {
|
|
||||||
extract_snapshot_token(fname, &twrp);
|
|
||||||
}
|
|
||||||
status = filename_convert_dirfsp(req,
|
|
||||||
conn,
|
|
||||||
fname,
|
|
||||||
ucf_flags,
|
|
||||||
twrp,
|
|
||||||
&dirfsp,
|
|
||||||
&smb_fname);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
|
||||||
reply_botherror(req,
|
|
||||||
NT_STATUS_PATH_NOT_COVERED,
|
|
||||||
ERRSRV, ERRbadpath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reply_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* smb_fname->fsp may be NULL if smb_fname points at a symlink
|
|
||||||
* and we're in POSIX context, so be careful when using fsp
|
|
||||||
* below, it can still be NULL.
|
|
||||||
*/
|
|
||||||
fsp = smb_fname->fsp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are 4 info levels which can
|
|
||||||
* create a new object in the filesystem.
|
|
||||||
* They are:
|
|
||||||
* SMB_SET_FILE_UNIX_LINK -> creates POSIX symlink.
|
|
||||||
* SMB_POSIX_PATH_OPEN -> creates POSIX file or directory.
|
|
||||||
* SMB_SET_FILE_UNIX_BASIC:
|
|
||||||
* SMB_SET_FILE_UNIX_INFO2: can create a POSIX special file.
|
|
||||||
*
|
|
||||||
* These info levels do not require an existing object.
|
|
||||||
*/
|
|
||||||
switch (info_level) {
|
|
||||||
case SMB_SET_FILE_UNIX_LINK:
|
|
||||||
case SMB_POSIX_PATH_OPEN:
|
|
||||||
case SMB_SET_FILE_UNIX_BASIC:
|
|
||||||
case SMB_SET_FILE_UNIX_INFO2:
|
|
||||||
require_existing_object = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!VALID_STAT(smb_fname->st) && require_existing_object) {
|
|
||||||
reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
|
DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
|
||||||
"totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
|
"totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
|
||||||
@ -2635,10 +2447,126 @@ static void call_trans2setpathinfo(
|
|||||||
int total_data,
|
int total_data,
|
||||||
unsigned int max_data_bytes)
|
unsigned int max_data_bytes)
|
||||||
{
|
{
|
||||||
|
uint16_t info_level;
|
||||||
|
struct smb_filename *smb_fname = NULL;
|
||||||
|
struct files_struct *dirfsp = NULL;
|
||||||
|
struct files_struct *fsp = NULL;
|
||||||
|
char *params = *pparams;
|
||||||
|
uint32_t ucf_flags = ucf_flags_from_smb_request(req);
|
||||||
|
bool require_existing_object = true;
|
||||||
|
NTTIME twrp = 0;
|
||||||
|
char *fname = NULL;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (params == NULL) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set path info */
|
||||||
|
if (total_params < 7) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info_level = SVAL(params,0);
|
||||||
|
|
||||||
|
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||||
|
if (!lp_smb1_unix_extensions()) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!req->posix_pathnames) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->posix_pathnames) {
|
||||||
|
srvstr_get_path_posix(req,
|
||||||
|
params,
|
||||||
|
req->flags2,
|
||||||
|
&fname,
|
||||||
|
¶ms[6],
|
||||||
|
total_params - 6,
|
||||||
|
STR_TERMINATE,
|
||||||
|
&status);
|
||||||
|
} else {
|
||||||
|
srvstr_get_path(req,
|
||||||
|
params,
|
||||||
|
req->flags2,
|
||||||
|
&fname,
|
||||||
|
¶ms[6],
|
||||||
|
total_params - 6,
|
||||||
|
STR_TERMINATE,
|
||||||
|
&status);
|
||||||
|
}
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
reply_nterror(req, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ucf_flags & UCF_GMT_PATHNAME) {
|
||||||
|
extract_snapshot_token(fname, &twrp);
|
||||||
|
}
|
||||||
|
status = filename_convert_dirfsp(req,
|
||||||
|
conn,
|
||||||
|
fname,
|
||||||
|
ucf_flags,
|
||||||
|
twrp,
|
||||||
|
&dirfsp,
|
||||||
|
&smb_fname);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||||
|
reply_botherror(req,
|
||||||
|
NT_STATUS_PATH_NOT_COVERED,
|
||||||
|
ERRSRV, ERRbadpath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reply_nterror(req, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* smb_fname->fsp may be NULL if smb_fname points at a symlink
|
||||||
|
* and we're in POSIX context, so be careful when using fsp
|
||||||
|
* below, it can still be NULL.
|
||||||
|
*/
|
||||||
|
fsp = smb_fname->fsp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are 4 info levels which can
|
||||||
|
* create a new object in the filesystem.
|
||||||
|
* They are:
|
||||||
|
* SMB_SET_FILE_UNIX_LINK -> creates POSIX symlink.
|
||||||
|
* SMB_POSIX_PATH_OPEN -> creates POSIX file or directory.
|
||||||
|
* SMB_SET_FILE_UNIX_BASIC:
|
||||||
|
* SMB_SET_FILE_UNIX_INFO2: can create a POSIX special file.
|
||||||
|
*
|
||||||
|
* These info levels do not require an existing object.
|
||||||
|
*/
|
||||||
|
switch (info_level) {
|
||||||
|
case SMB_SET_FILE_UNIX_LINK:
|
||||||
|
case SMB_POSIX_PATH_OPEN:
|
||||||
|
case SMB_SET_FILE_UNIX_BASIC:
|
||||||
|
case SMB_SET_FILE_UNIX_INFO2:
|
||||||
|
require_existing_object = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VALID_STAT(smb_fname->st) && require_existing_object) {
|
||||||
|
reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
call_trans2setfilepathinfo(
|
call_trans2setfilepathinfo(
|
||||||
conn,
|
conn,
|
||||||
req,
|
req,
|
||||||
TRANSACT2_SETPATHINFO,
|
TRANSACT2_SETPATHINFO,
|
||||||
|
info_level,
|
||||||
|
smb_fname,
|
||||||
|
fsp,
|
||||||
pparams,
|
pparams,
|
||||||
total_params,
|
total_params,
|
||||||
ppdata,
|
ppdata,
|
||||||
@ -2655,10 +2583,104 @@ static void call_trans2setfileinfo(
|
|||||||
int total_data,
|
int total_data,
|
||||||
unsigned int max_data_bytes)
|
unsigned int max_data_bytes)
|
||||||
{
|
{
|
||||||
|
char *pdata = *ppdata;
|
||||||
|
uint16_t info_level;
|
||||||
|
struct smb_filename *smb_fname = NULL;
|
||||||
|
struct files_struct *fsp = NULL;
|
||||||
|
char *params = *pparams;
|
||||||
|
NTSTATUS status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (params == NULL) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (total_params < 4) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsp = file_fsp(req, SVAL(params,0));
|
||||||
|
/* Basic check for non-null fsp. */
|
||||||
|
if (!check_fsp_open(conn, req, fsp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info_level = SVAL(params,2);
|
||||||
|
|
||||||
|
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||||
|
if (!lp_smb1_unix_extensions()) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!req->posix_pathnames) {
|
||||||
|
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_fname = fsp->fsp_name;
|
||||||
|
|
||||||
|
if (fsp_get_pathref_fd(fsp) == -1) {
|
||||||
|
/*
|
||||||
|
* This is actually a SETFILEINFO on a directory
|
||||||
|
* handle (returned from an NT SMB). NT5.0 seems
|
||||||
|
* to do this call. JRA.
|
||||||
|
*/
|
||||||
|
ret = vfs_stat(conn, smb_fname);
|
||||||
|
if (ret != 0) {
|
||||||
|
DBG_NOTICE("vfs_stat of %s failed (%s)\n",
|
||||||
|
smb_fname_str_dbg(smb_fname),
|
||||||
|
strerror(errno));
|
||||||
|
reply_nterror(req, map_nt_error_from_unix(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (fsp->print_file) {
|
||||||
|
/*
|
||||||
|
* Doing a DELETE_ON_CLOSE should cancel a print job.
|
||||||
|
*/
|
||||||
|
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) &&
|
||||||
|
CVAL(pdata,0)) {
|
||||||
|
|
||||||
|
fsp->fsp_flags.delete_on_close = true;
|
||||||
|
|
||||||
|
DBG_NOTICE("Cancelling print job (%s)\n",
|
||||||
|
fsp_str_dbg(fsp));
|
||||||
|
|
||||||
|
SSVAL(params,0,0);
|
||||||
|
send_trans2_replies(
|
||||||
|
conn,
|
||||||
|
req,
|
||||||
|
NT_STATUS_OK,
|
||||||
|
params,
|
||||||
|
2,
|
||||||
|
*ppdata, 0,
|
||||||
|
max_data_bytes);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Original code - this is an open file.
|
||||||
|
*/
|
||||||
|
status = vfs_stat_fsp(fsp);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DBG_NOTICE("fstat of %s failed (%s)\n",
|
||||||
|
fsp_fnum_dbg(fsp),
|
||||||
|
nt_errstr(status));
|
||||||
|
reply_nterror(req, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
call_trans2setfilepathinfo(
|
call_trans2setfilepathinfo(
|
||||||
conn,
|
conn,
|
||||||
req,
|
req,
|
||||||
TRANSACT2_SETFILEINFO,
|
TRANSACT2_SETFILEINFO,
|
||||||
|
info_level,
|
||||||
|
smb_fname,
|
||||||
|
fsp,
|
||||||
pparams,
|
pparams,
|
||||||
total_params,
|
total_params,
|
||||||
ppdata,
|
ppdata,
|
||||||
|
Loading…
Reference in New Issue
Block a user