diff options
author | John H Terpstra <jht@samba.org> | 2009-07-23 09:33:06 -0500 |
---|---|---|
committer | John H Terpstra <jht@samba.org> | 2009-07-23 09:33:06 -0500 |
commit | 94717ae8e5dfe2ccdb7f3557d5490708b00ae471 (patch) | |
tree | a39f669faf23ad05497963cf5ccf611467d0145b /source3/smbd/smb2_setinfo.c | |
parent | 14952c72a29ec92badb1bcf16d2a15fe100f060d (diff) | |
parent | 7bad4b48c82fed4263c2bfe97a4d00b47913604a (diff) | |
download | samba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.tar.gz samba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.tar.bz2 samba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.zip |
Merge branch 'master' of ssh://jht@git.samba.org/data/git/samba
Diffstat (limited to 'source3/smbd/smb2_setinfo.c')
-rw-r--r-- | source3/smbd/smb2_setinfo.c | 118 |
1 files changed, 117 insertions, 1 deletions
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 110ce6c64a..08c4a7f5bf 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -200,7 +200,123 @@ 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; + 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; + } + + 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, fsp->fsp_name)) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "SMB_VFS_LSTAT of %s failed " + "(%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, fsp->fsp_name) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "fileinfo of %s failed (%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 (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_str_dbg(fsp))); + + 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, &fsp->fsp_name->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, + fsp->fsp_name, + &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); } |