Fix a bunch of "unused variable" warnings.
[ira/wip.git] / source3 / smbd / smb2_close.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/smbd.h"
23 #include "smbd/globals.h"
24 #include "../libcli/smb/smb_common.h"
25
26 static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
27                                 uint16_t in_flags,
28                                 uint64_t in_file_id_volatile,
29                                 DATA_BLOB *outbody);
30
31 NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req)
32 {
33         const uint8_t *inbody;
34         int i = req->current_idx;
35         DATA_BLOB outbody;
36         uint16_t in_flags;
37         uint64_t in_file_id_persistent;
38         uint64_t in_file_id_volatile;
39         NTSTATUS status;
40
41         status = smbd_smb2_request_verify_sizes(req, 0x18);
42         if (!NT_STATUS_IS_OK(status)) {
43                 return smbd_smb2_request_error(req, status);
44         }
45         inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
46
47         outbody = data_blob_talloc(req->out.vector, NULL, 0x3C);
48         if (outbody.data == NULL) {
49                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
50         }
51
52         in_flags                = SVAL(inbody, 0x02);
53         in_file_id_persistent   = BVAL(inbody, 0x08);
54         in_file_id_volatile     = BVAL(inbody, 0x10);
55
56         if (req->compat_chain_fsp) {
57                 /* skip check */
58         } else if (in_file_id_persistent != in_file_id_volatile) {
59                 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
60         }
61
62         status = smbd_smb2_close(req,
63                                 in_flags,
64                                 in_file_id_volatile,
65                                 &outbody);
66         if (!NT_STATUS_IS_OK(status)) {
67                 return smbd_smb2_request_error(req, status);
68         }
69
70         return smbd_smb2_request_done(req, outbody, NULL);
71 }
72
73 static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
74                                 uint16_t in_flags,
75                                 uint64_t in_file_id_volatile,
76                                 DATA_BLOB *outbody)
77 {
78         NTSTATUS status;
79         struct smb_request *smbreq;
80         connection_struct *conn = req->tcon->compat_conn;
81         files_struct *fsp;
82         struct smb_filename *smb_fname = NULL;
83         struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
84         uint64_t allocation_size = 0;
85         uint64_t file_size = 0;
86         uint32_t dos_attrs = 0;
87         uint16_t out_flags = 0;
88         bool posix_open = false;
89
90         ZERO_STRUCT(create_date_ts);
91         ZERO_STRUCT(adate_ts);
92         ZERO_STRUCT(mdate_ts);
93         ZERO_STRUCT(cdate_ts);
94
95         DEBUG(10,("smbd_smb2_close: file_id[0x%016llX]\n",
96                   (unsigned long long)in_file_id_volatile));
97
98         smbreq = smbd_smb2_fake_smb_request(req);
99         if (smbreq == NULL) {
100                 return NT_STATUS_NO_MEMORY;
101         }
102
103         fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
104         if (fsp == NULL) {
105                 return NT_STATUS_FILE_CLOSED;
106         }
107         if (conn != fsp->conn) {
108                 return NT_STATUS_FILE_CLOSED;
109         }
110         if (req->session->vuid != fsp->vuid) {
111                 return NT_STATUS_FILE_CLOSED;
112         }
113
114         posix_open = fsp->posix_open;
115         status = copy_smb_filename(talloc_tos(),
116                                 fsp->fsp_name,
117                                 &smb_fname);
118         if (!NT_STATUS_IS_OK(status)) {
119                 return status;
120         }
121
122         status = close_file(smbreq, fsp, NORMAL_CLOSE);
123         if (!NT_STATUS_IS_OK(status)) {
124                 DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n",
125                          fsp_str_dbg(fsp), nt_errstr(status)));
126                 return status;
127         }
128
129         if (in_flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {
130                 int ret;
131                 if (posix_open) {
132                         ret = SMB_VFS_LSTAT(conn, smb_fname);
133                 } else {
134                         ret = SMB_VFS_STAT(conn, smb_fname);
135                 }
136                 if (ret == 0) {
137                         out_flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
138                         dos_attrs = dos_mode(conn, smb_fname);
139                         mdate_ts = smb_fname->st.st_ex_mtime;
140                         adate_ts = smb_fname->st.st_ex_atime;
141                         create_date_ts = get_create_timespec(conn, NULL, smb_fname);
142                         cdate_ts = get_change_timespec(conn, NULL, smb_fname);
143
144                         if (lp_dos_filetime_resolution(SNUM(conn))) {
145                                 dos_filetime_timespec(&create_date_ts);
146                                 dos_filetime_timespec(&mdate_ts);
147                                 dos_filetime_timespec(&adate_ts);
148                                 dos_filetime_timespec(&cdate_ts);
149                         }
150                         if (!(dos_attrs & FILE_ATTRIBUTE_DIRECTORY)) {
151                                 file_size = get_file_size_stat(&smb_fname->st);
152                         }
153
154                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
155                 }
156         }
157
158         SSVAL(outbody->data, 0x00, 0x3C);       /* struct size */
159         SSVAL(outbody->data, 0x02, out_flags);  /* flags */
160         SIVAL(outbody->data, 0x04, 0);          /* reserved */
161         put_long_date_timespec(conn->ts_res,
162                 (char *)&outbody->data[0x8],create_date_ts); /* creation time */
163         put_long_date_timespec(conn->ts_res,
164                 (char *)&outbody->data[0x10],adate_ts); /* last access time */
165         put_long_date_timespec(conn->ts_res,
166                 (char *)&outbody->data[0x18],mdate_ts); /* last write time */
167         put_long_date_timespec(conn->ts_res,
168                 (char *)&outbody->data[0x20],cdate_ts); /* change time */
169         SBVAL(outbody->data, 0x28, allocation_size);/* allocation size */
170         SBVAL(outbody->data, 0x30, file_size);  /* end of file */
171         SIVAL(outbody->data, 0x38, dos_attrs);  /* file attributes */
172
173         return NT_STATUS_OK;
174 }