1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

s3:smbd: start SMB2 GetInfo support for File*Information levels

TODO: the EA levels are not fully supported.

metze
This commit is contained in:
Stefan Metzmacher 2009-07-10 20:39:08 +02:00
parent 64221bc3fa
commit d7809f65cf

View File

@ -233,7 +233,145 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
if (IS_IPC(conn)) {
tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
return tevent_req_post(req, ev);
}
switch (in_info_type) {
case 0x01:/* SMB2_GETINFO_FILE */
{
uint16_t file_info_level;
char *data = NULL;
unsigned int data_size = 0;
struct smb_filename *smb_fname = NULL;
bool delete_pending = false;
struct timespec write_time_ts;
struct file_id fileid;
struct ea_list *ea_list = NULL;
int lock_data_count = 0;
char *lock_data = NULL;
bool ms_dfs_link = false;
NTSTATUS status;
ZERO_STRUCT(write_time_ts);
switch (in_file_info_class) {
case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
file_info_level = 0xFF00 | in_file_info_class;
break;
case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
file_info_level = 0xFF00 | in_file_info_class;
break;
default:
/* the levels directly map to the passthru levels */
file_info_level = in_file_info_class + 1000;
break;
}
status = create_synthetic_smb_fname_split(state,
fsp->fsp_name,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
if (fsp->fake_file_handle) {
/*
* This is actually for the QUOTA_FAKE_FILE --metze
*/
/* We know this name is ok, it's already passed the checks. */
} else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
if (INFO_LEVEL_IS_UNIX(file_info_level)) {
/* Always do lstat for UNIX calls. */
if (SMB_VFS_LSTAT(conn, smb_fname)) {
DEBUG(3,("call_trans2qfilepathinfo: "
"SMB_VFS_LSTAT of %s failed "
"(%s)\n",
smb_fname_str_dbg(smb_fname),
strerror(errno)));
status = map_nt_error_from_unix(errno);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
} else if (SMB_VFS_STAT(conn, smb_fname)) {
DEBUG(3,("call_trans2qfilepathinfo: "
"SMB_VFS_STAT of %s failed (%s)\n",
smb_fname_str_dbg(smb_fname),
strerror(errno)));
status = map_nt_error_from_unix(errno);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, &delete_pending, &write_time_ts);
} else {
/*
* Original code - this is an open file.
*/
if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
DEBUG(3, ("fstat of fnum %d failed (%s)\n",
fsp->fnum, strerror(errno)));
status = map_nt_error_from_unix(errno);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, &delete_pending, &write_time_ts);
}
status = smbd_do_qfilepathinfo(conn, state,
file_info_level,
fsp,
smb_fname,
delete_pending,
write_time_ts,
ms_dfs_link,
ea_list,
lock_data_count,
lock_data,
STR_UNICODE,
in_output_buffer_length,
&data,
&data_size);
if (!NT_STATUS_IS_OK(status)) {
SAFE_FREE(data);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
if (data_size > 0) {
state->out_output_buffer = data_blob_talloc(state,
data,
data_size);
SAFE_FREE(data);
if (tevent_req_nomem(state->out_output_buffer.data, req)) {
return tevent_req_post(req, ev);
}
}
SAFE_FREE(data);
break;
}
default:
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return tevent_req_post(req, ev);
}
tevent_req_done(req);
return tevent_req_post(req, ev);
}