From 722cd5944f9b70c7f642ec1d510d54bf1592beb5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:23:57 +0200 Subject: s3:smbd: add support for SMB2 SetInfo File*Information metze --- source3/smbd/smb2_setinfo.c | 129 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) (limited to 'source3/smbd/smb2_setinfo.c') diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 110ce6c64a..2974695c9f 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -200,7 +200,134 @@ static struct tevent_req *smbd_smb2_setinfo_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_SETINFO_FILE */ + { + uint16_t file_info_level; + struct smb_filename *smb_fname = NULL; + char *data; + int data_size; + int ret_size = 0; + NTSTATUS status; + + + file_info_level = in_file_info_class + 1000; + if (file_info_level == SMB_FILE_RENAME_INFORMATION) { + file_info_level = 0xFF00 + in_file_info_class; + } + + 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->is_directory || fsp->fh->fd == -1) { + /* + * This is actually a SETFILEINFO 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,("smbd_smb2_setinfo_send: " + "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) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "fileinfo 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 (fsp->print_file) { + /* + * Doing a DELETE_ON_CLOSE should cancel a print job. + */ + if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO) + && in_input_buffer.length >= 1 + && CVAL(in_input_buffer.data,0)) { + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; + + DEBUG(3,("smbd_smb2_setinfo_send: " + "Cancelling print job (%s)\n", + fsp->fsp_name)); + + tevent_req_done(req); + return tevent_req_post(req, ev); + } else { + tevent_req_nterror(req, + NT_STATUS_OBJECT_PATH_INVALID); + return tevent_req_post(req, ev); + } + } else { + /* + * Original code - this is an open file. + */ + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: 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); + } + } + + data = NULL; + data_size = in_input_buffer.length; + if (data_size > 0) { + data = (char *)SMB_MALLOC_ARRAY(char, data_size); + if (tevent_req_nomem(data, req)) { + + } + memcpy(data, in_input_buffer.data, data_size); + } + + status = smbd_do_setfilepathinfo(conn, smbreq, state, + file_info_level, + fsp, + smb_fname, + &data, + data_size, + &ret_size); + SAFE_FREE(data); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + 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); } -- cgit From 5a8d70d465f28ae02f4df7a3c2905e028c2e3142 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 14:50:37 -0700 Subject: s3: Change fsp->fsp_name to be an smb_filename struct! --- source3/smbd/smb2_setinfo.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'source3/smbd/smb2_setinfo.c') diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 2974695c9f..08c4a7f5bf 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -209,7 +209,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, case 0x01:/* SMB2_SETINFO_FILE */ { uint16_t file_info_level; - struct smb_filename *smb_fname = NULL; char *data; int data_size; int ret_size = 0; @@ -221,15 +220,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, file_info_level = 0xFF00 + in_file_info_class; } - 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->is_directory || fsp->fh->fd == -1) { /* * This is actually a SETFILEINFO on a directory @@ -238,21 +228,20 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, */ if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { + if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_setinfo_send: " "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), + "(%s)\n", fsp_str_dbg(fsp), 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) != 0) { + if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: " "fileinfo of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); @@ -270,7 +259,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, DEBUG(3,("smbd_smb2_setinfo_send: " "Cancelling print job (%s)\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); tevent_req_done(req); return tevent_req_post(req, ev); @@ -284,7 +273,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, * Original code - this is an open file. */ - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: fstat " "of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); @@ -307,7 +296,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, status = smbd_do_setfilepathinfo(conn, smbreq, state, file_info_level, fsp, - smb_fname, + fsp->fsp_name, &data, data_size, &ret_size); -- cgit