cifsd: don't use multiple blank lines
[linux-2.6-microblaze.git] / fs / cifsd / smb2pdu.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
5  */
6
7 #include <linux/inetdevice.h>
8 #include <net/addrconf.h>
9 #include <linux/syscalls.h>
10 #include <linux/namei.h>
11 #include <linux/statfs.h>
12 #include <linux/ethtool.h>
13
14 #include "glob.h"
15 #include "smb2pdu.h"
16 #include "smbfsctl.h"
17 #include "oplock.h"
18 #include "smbacl.h"
19
20 #include "auth.h"
21 #include "asn1.h"
22 #include "buffer_pool.h"
23 #include "connection.h"
24 #include "transport_ipc.h"
25 #include "vfs.h"
26 #include "vfs_cache.h"
27 #include "misc.h"
28
29 #include "server.h"
30 #include "smb_common.h"
31 #include "smbstatus.h"
32 #include "ksmbd_work.h"
33 #include "mgmt/user_config.h"
34 #include "mgmt/share_config.h"
35 #include "mgmt/tree_connect.h"
36 #include "mgmt/user_session.h"
37 #include "mgmt/ksmbd_ida.h"
38 #include "ndr.h"
39
40 static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
41 {
42         if (work->next_smb2_rcv_hdr_off) {
43                 *req = REQUEST_BUF_NEXT(work);
44                 *rsp = RESPONSE_BUF_NEXT(work);
45         } else {
46                 *req = work->request_buf;
47                 *rsp = work->response_buf;
48         }
49 }
50
51 #define WORK_BUFFERS(w, rq, rs) __wbuf((w), (void **)&(rq), (void **)&(rs))
52
53 /**
54  * check_session_id() - check for valid session id in smb header
55  * @conn:       connection instance
56  * @id:         session id from smb header
57  *
58  * Return:      1 if valid session id, otherwise 0
59  */
60 static inline int check_session_id(struct ksmbd_conn *conn, u64 id)
61 {
62         struct ksmbd_session *sess;
63
64         if (id == 0 || id == -1)
65                 return 0;
66
67         sess = ksmbd_session_lookup(conn, id);
68         if (sess)
69                 return 1;
70         ksmbd_err("Invalid user session id: %llu\n", id);
71         return 0;
72 }
73
74 struct channel *lookup_chann_list(struct ksmbd_session *sess)
75 {
76         struct channel *chann;
77         struct list_head *t;
78
79         list_for_each(t, &sess->ksmbd_chann_list) {
80                 chann = list_entry(t, struct channel, chann_list);
81                 if (chann && chann->conn == sess->conn)
82                         return chann;
83         }
84
85         return NULL;
86 }
87
88 /**
89  * smb2_get_ksmbd_tcon() - get tree connection information for a tree id
90  * @work:       smb work
91  *
92  * Return:      matching tree connection on success, otherwise error
93  */
94 int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
95 {
96         struct smb2_hdr *req_hdr = work->request_buf;
97         int tree_id;
98
99         work->tcon = NULL;
100         if (work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE ||
101             work->conn->ops->get_cmd_val(work) ==  SMB2_CANCEL_HE ||
102             work->conn->ops->get_cmd_val(work) ==  SMB2_LOGOFF_HE) {
103                 ksmbd_debug(SMB, "skip to check tree connect request\n");
104                 return 0;
105         }
106
107         if (xa_empty(&work->sess->tree_conns)) {
108                 ksmbd_debug(SMB, "NO tree connected\n");
109                 return -1;
110         }
111
112         tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId);
113         work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id);
114         if (!work->tcon) {
115                 ksmbd_err("Invalid tid %d\n", tree_id);
116                 return -1;
117         }
118
119         return 1;
120 }
121
122 /**
123  * smb2_set_err_rsp() - set error response code on smb response
124  * @work:       smb work containing response buffer
125  */
126 void smb2_set_err_rsp(struct ksmbd_work *work)
127 {
128         struct smb2_err_rsp *err_rsp;
129
130         if (work->next_smb2_rcv_hdr_off)
131                 err_rsp = RESPONSE_BUF_NEXT(work);
132         else
133                 err_rsp = work->response_buf;
134
135         if (err_rsp->hdr.Status != STATUS_STOPPED_ON_SYMLINK) {
136                 err_rsp->StructureSize = SMB2_ERROR_STRUCTURE_SIZE2_LE;
137                 err_rsp->ErrorContextCount = 0;
138                 err_rsp->Reserved = 0;
139                 err_rsp->ByteCount = 0;
140                 err_rsp->ErrorData[0] = 0;
141                 inc_rfc1001_len(work->response_buf, SMB2_ERROR_STRUCTURE_SIZE2);
142         }
143 }
144
145 /**
146  * is_smb2_neg_cmd() - is it smb2 negotiation command
147  * @work:       smb work containing smb header
148  *
149  * Return:      1 if smb2 negotiation command, otherwise 0
150  */
151 int is_smb2_neg_cmd(struct ksmbd_work *work)
152 {
153         struct smb2_hdr *hdr = work->request_buf;
154
155         /* is it SMB2 header ? */
156         if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
157                 return 0;
158
159         /* make sure it is request not response message */
160         if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
161                 return 0;
162
163         if (hdr->Command != SMB2_NEGOTIATE)
164                 return 0;
165
166         return 1;
167 }
168
169 /**
170  * is_smb2_rsp() - is it smb2 response
171  * @work:       smb work containing smb response buffer
172  *
173  * Return:      1 if smb2 response, otherwise 0
174  */
175 int is_smb2_rsp(struct ksmbd_work *work)
176 {
177         struct smb2_hdr *hdr = work->response_buf;
178
179         /* is it SMB2 header ? */
180         if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
181                 return 0;
182
183         /* make sure it is response not request message */
184         if (!(hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR))
185                 return 0;
186
187         return 1;
188 }
189
190 /**
191  * get_smb2_cmd_val() - get smb command code from smb header
192  * @work:       smb work containing smb request buffer
193  *
194  * Return:      smb2 request command value
195  */
196 uint16_t get_smb2_cmd_val(struct ksmbd_work *work)
197 {
198         struct smb2_hdr *rcv_hdr;
199
200         if (work->next_smb2_rcv_hdr_off)
201                 rcv_hdr = REQUEST_BUF_NEXT(work);
202         else
203                 rcv_hdr = work->request_buf;
204         return le16_to_cpu(rcv_hdr->Command);
205 }
206
207 /**
208  * set_smb2_rsp_status() - set error response code on smb2 header
209  * @work:       smb work containing response buffer
210  * @err:        error response code
211  */
212 void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err)
213 {
214         struct smb2_hdr *rsp_hdr;
215
216         if (work->next_smb2_rcv_hdr_off)
217                 rsp_hdr = RESPONSE_BUF_NEXT(work);
218         else
219                 rsp_hdr = work->response_buf;
220         rsp_hdr->Status = err;
221         smb2_set_err_rsp(work);
222 }
223
224 /**
225  * init_smb2_neg_rsp() - initialize smb2 response for negotiate command
226  * @work:       smb work containing smb request buffer
227  *
228  * smb2 negotiate response is sent in reply of smb1 negotiate command for
229  * dialect auto-negotiation.
230  */
231 int init_smb2_neg_rsp(struct ksmbd_work *work)
232 {
233         struct smb2_hdr *rsp_hdr;
234         struct smb2_negotiate_rsp *rsp;
235         struct ksmbd_conn *conn = work->conn;
236
237         if (conn->need_neg == false)
238                 return -EINVAL;
239         if (!(conn->dialect >= SMB20_PROT_ID &&
240               conn->dialect <= SMB311_PROT_ID))
241                 return -EINVAL;
242
243         rsp_hdr = work->response_buf;
244
245         memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
246
247         rsp_hdr->smb2_buf_length =
248                 cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn));
249
250         rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
251         rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
252         rsp_hdr->CreditRequest = cpu_to_le16(2);
253         rsp_hdr->Command = SMB2_NEGOTIATE;
254         rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR);
255         rsp_hdr->NextCommand = 0;
256         rsp_hdr->MessageId = 0;
257         rsp_hdr->Id.SyncId.ProcessId = 0;
258         rsp_hdr->Id.SyncId.TreeId = 0;
259         rsp_hdr->SessionId = 0;
260         memset(rsp_hdr->Signature, 0, 16);
261
262         rsp = work->response_buf;
263
264         WARN_ON(ksmbd_conn_good(work));
265
266         rsp->StructureSize = cpu_to_le16(65);
267         ksmbd_debug(SMB, "conn->dialect 0x%x\n", conn->dialect);
268         rsp->DialectRevision = cpu_to_le16(conn->dialect);
269         /* Not setting conn guid rsp->ServerGUID, as it
270          * not used by client for identifying connection
271          */
272         rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
273         /* Default Max Message Size till SMB2.0, 64K*/
274         rsp->MaxTransactSize = cpu_to_le32(conn->vals->max_trans_size);
275         rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
276         rsp->MaxWriteSize = cpu_to_le32(conn->vals->max_write_size);
277
278         rsp->SystemTime = cpu_to_le64(ksmbd_systime());
279         rsp->ServerStartTime = 0;
280
281         rsp->SecurityBufferOffset = cpu_to_le16(128);
282         rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH);
283         ksmbd_copy_gss_neg_header(((char *)(&rsp->hdr) +
284                 sizeof(rsp->hdr.smb2_buf_length)) +
285                 le16_to_cpu(rsp->SecurityBufferOffset));
286         inc_rfc1001_len(rsp, sizeof(struct smb2_negotiate_rsp) -
287                 sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
288                 AUTH_GSS_LENGTH);
289         rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
290         if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY)
291                 rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
292         conn->use_spnego = true;
293
294         ksmbd_conn_set_need_negotiate(work);
295         return 0;
296 }
297
298 static int smb2_consume_credit_charge(struct ksmbd_work *work,
299                 unsigned short credit_charge)
300 {
301         struct ksmbd_conn *conn = work->conn;
302         unsigned int rsp_credits = 1;
303
304         if (!conn->total_credits)
305                 return 0;
306
307         if (credit_charge > 0)
308                 rsp_credits = credit_charge;
309
310         conn->total_credits -= rsp_credits;
311         return rsp_credits;
312 }
313
314 /**
315  * smb2_set_rsp_credits() - set number of credits in response buffer
316  * @work:       smb work containing smb response buffer
317  */
318 int smb2_set_rsp_credits(struct ksmbd_work *work)
319 {
320         struct smb2_hdr *req_hdr = REQUEST_BUF_NEXT(work);
321         struct smb2_hdr *hdr = RESPONSE_BUF_NEXT(work);
322         struct ksmbd_conn *conn = work->conn;
323         unsigned short credits_requested = le16_to_cpu(req_hdr->CreditRequest);
324         unsigned short credit_charge = 1, credits_granted = 0;
325         unsigned short aux_max, aux_credits, min_credits;
326         int rsp_credit_charge;
327
328         if (hdr->Command == SMB2_CANCEL)
329                 goto out;
330
331         /* get default minimum credits by shifting maximum credits by 4 */
332         min_credits = conn->max_credits >> 4;
333
334         if (conn->total_credits >= conn->max_credits) {
335                 ksmbd_err("Total credits overflow: %d\n", conn->total_credits);
336                 conn->total_credits = min_credits;
337         }
338
339         rsp_credit_charge = smb2_consume_credit_charge(work,
340                 le16_to_cpu(req_hdr->CreditCharge));
341         if (rsp_credit_charge < 0)
342                 return -EINVAL;
343
344         hdr->CreditCharge = cpu_to_le16(rsp_credit_charge);
345
346         if (credits_requested > 0) {
347                 aux_credits = credits_requested - 1;
348                 aux_max = 32;
349                 if (hdr->Command == SMB2_NEGOTIATE)
350                         aux_max = 0;
351                 aux_credits = (aux_credits < aux_max) ? aux_credits : aux_max;
352                 credits_granted = aux_credits + credit_charge;
353
354                 /* if credits granted per client is getting bigger than default
355                  * minimum credits then we should wrap it up within the limits.
356                  */
357                 if ((conn->total_credits + credits_granted) > min_credits)
358                         credits_granted = min_credits - conn->total_credits;
359                 /*
360                  * TODO: Need to adjuct CreditRequest value according to
361                  * current cpu load
362                  */
363         } else if (conn->total_credits == 0) {
364                 credits_granted = 1;
365         }
366
367         conn->total_credits += credits_granted;
368         work->credits_granted += credits_granted;
369
370         if (!req_hdr->NextCommand) {
371                 /* Update CreditRequest in last request */
372                 hdr->CreditRequest = cpu_to_le16(work->credits_granted);
373         }
374 out:
375         ksmbd_debug(SMB,
376                 "credits: requested[%d] granted[%d] total_granted[%d]\n",
377                 credits_requested, credits_granted,
378                 conn->total_credits);
379         return 0;
380 }
381
382 /**
383  * init_chained_smb2_rsp() - initialize smb2 chained response
384  * @work:       smb work containing smb response buffer
385  */
386 static void init_chained_smb2_rsp(struct ksmbd_work *work)
387 {
388         struct smb2_hdr *req = REQUEST_BUF_NEXT(work);
389         struct smb2_hdr *rsp = RESPONSE_BUF_NEXT(work);
390         struct smb2_hdr *rsp_hdr;
391         struct smb2_hdr *rcv_hdr;
392         int next_hdr_offset = 0;
393         int len, new_len;
394
395         /* Len of this response = updated RFC len - offset of previous cmd
396          * in the compound rsp
397          */
398
399         /* Storing the current local FID which may be needed by subsequent
400          * command in the compound request
401          */
402         if (req->Command == SMB2_CREATE && rsp->Status == STATUS_SUCCESS) {
403                 work->compound_fid =
404                         le64_to_cpu(((struct smb2_create_rsp *)rsp)->
405                                 VolatileFileId);
406                 work->compound_pfid =
407                         le64_to_cpu(((struct smb2_create_rsp *)rsp)->
408                                 PersistentFileId);
409                 work->compound_sid = le64_to_cpu(rsp->SessionId);
410         }
411
412         len = get_rfc1002_len(work->response_buf) - work->next_smb2_rsp_hdr_off;
413         next_hdr_offset = le32_to_cpu(req->NextCommand);
414
415         new_len = ALIGN(len, 8);
416         inc_rfc1001_len(work->response_buf, ((sizeof(struct smb2_hdr) - 4)
417                         + new_len - len));
418         rsp->NextCommand = cpu_to_le32(new_len);
419
420         work->next_smb2_rcv_hdr_off += next_hdr_offset;
421         work->next_smb2_rsp_hdr_off += new_len;
422         ksmbd_debug(SMB,
423                 "Compound req new_len = %d rcv off = %d rsp off = %d\n",
424                 new_len, work->next_smb2_rcv_hdr_off,
425                 work->next_smb2_rsp_hdr_off);
426
427         rsp_hdr = RESPONSE_BUF_NEXT(work);
428         rcv_hdr = REQUEST_BUF_NEXT(work);
429
430         if (!(rcv_hdr->Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
431                 ksmbd_debug(SMB, "related flag should be set\n");
432                 work->compound_fid = KSMBD_NO_FID;
433                 work->compound_pfid = KSMBD_NO_FID;
434         }
435         memset((char *)rsp_hdr + 4, 0, sizeof(struct smb2_hdr) + 2);
436         rsp_hdr->ProtocolId = rcv_hdr->ProtocolId;
437         rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
438         rsp_hdr->Command = rcv_hdr->Command;
439
440         /*
441          * Message is response. We don't grant oplock yet.
442          */
443         rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR |
444                                 SMB2_FLAGS_RELATED_OPERATIONS);
445         rsp_hdr->NextCommand = 0;
446         rsp_hdr->MessageId = rcv_hdr->MessageId;
447         rsp_hdr->Id.SyncId.ProcessId = rcv_hdr->Id.SyncId.ProcessId;
448         rsp_hdr->Id.SyncId.TreeId = rcv_hdr->Id.SyncId.TreeId;
449         rsp_hdr->SessionId = rcv_hdr->SessionId;
450         memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
451 }
452
453 /**
454  * is_chained_smb2_message() - check for chained command
455  * @work:       smb work containing smb request buffer
456  *
457  * Return:      true if chained request, otherwise false
458  */
459 bool is_chained_smb2_message(struct ksmbd_work *work)
460 {
461         struct smb2_hdr *hdr = work->request_buf;
462         unsigned int len;
463
464         if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
465                 return false;
466
467         hdr = REQUEST_BUF_NEXT(work);
468         if (le32_to_cpu(hdr->NextCommand) > 0) {
469                 ksmbd_debug(SMB, "got SMB2 chained command\n");
470                 init_chained_smb2_rsp(work);
471                 return true;
472         } else if (work->next_smb2_rcv_hdr_off) {
473                 /*
474                  * This is last request in chained command,
475                  * align response to 8 byte
476                  */
477                 len = ALIGN(get_rfc1002_len(work->response_buf), 8);
478                 len = len - get_rfc1002_len(work->response_buf);
479                 if (len) {
480                         ksmbd_debug(SMB, "padding len %u\n", len);
481                         inc_rfc1001_len(work->response_buf, len);
482                         if (work->aux_payload_sz)
483                                 work->aux_payload_sz += len;
484                 }
485         }
486         return false;
487 }
488
489 /**
490  * init_smb2_rsp_hdr() - initialize smb2 response
491  * @work:       smb work containing smb request buffer
492  *
493  * Return:      0
494  */
495 int init_smb2_rsp_hdr(struct ksmbd_work *work)
496 {
497         struct smb2_hdr *rsp_hdr = work->response_buf;
498         struct smb2_hdr *rcv_hdr = work->request_buf;
499         struct ksmbd_conn *conn = work->conn;
500
501         memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
502         rsp_hdr->smb2_buf_length = cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn));
503         rsp_hdr->ProtocolId = rcv_hdr->ProtocolId;
504         rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
505         rsp_hdr->Command = rcv_hdr->Command;
506
507         /*
508          * Message is response. We don't grant oplock yet.
509          */
510         rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR);
511         rsp_hdr->NextCommand = 0;
512         rsp_hdr->MessageId = rcv_hdr->MessageId;
513         rsp_hdr->Id.SyncId.ProcessId = rcv_hdr->Id.SyncId.ProcessId;
514         rsp_hdr->Id.SyncId.TreeId = rcv_hdr->Id.SyncId.TreeId;
515         rsp_hdr->SessionId = rcv_hdr->SessionId;
516         memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
517
518         work->syncronous = true;
519         if (work->async_id) {
520                 ksmbd_release_id(&conn->async_ida, work->async_id);
521                 work->async_id = 0;
522         }
523
524         return 0;
525 }
526
527 /**
528  * smb2_allocate_rsp_buf() - allocate smb2 response buffer
529  * @work:       smb work containing smb request buffer
530  *
531  * Return:      0 on success, otherwise -ENOMEM
532  */
533 int smb2_allocate_rsp_buf(struct ksmbd_work *work)
534 {
535         struct smb2_hdr *hdr = work->request_buf;
536         size_t small_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
537         size_t large_sz = work->conn->vals->max_trans_size + MAX_SMB2_HDR_SIZE;
538         size_t sz = small_sz;
539         int cmd = le16_to_cpu(hdr->Command);
540
541         if (cmd == SMB2_IOCTL_HE || cmd == SMB2_QUERY_DIRECTORY_HE) {
542                 sz = large_sz;
543                 work->set_trans_buf = true;
544         }
545
546         if (cmd == SMB2_QUERY_INFO_HE) {
547                 struct smb2_query_info_req *req;
548
549                 req = work->request_buf;
550                 if (req->InfoType == SMB2_O_INFO_FILE &&
551                     (req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
552                      req->FileInfoClass == FILE_ALL_INFORMATION)) {
553                         sz = large_sz;
554                         work->set_trans_buf = true;
555                 }
556         }
557
558         /* allocate large response buf for chained commands */
559         if (le32_to_cpu(hdr->NextCommand) > 0)
560                 sz = large_sz;
561
562         if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_TBUF &&
563                         work->set_trans_buf)
564                 work->response_buf = ksmbd_find_buffer(sz);
565         else
566                 work->response_buf = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO);
567
568         if (!work->response_buf)
569                 return -ENOMEM;
570
571         work->response_sz = sz;
572         return 0;
573 }
574
575 /**
576  * smb2_check_user_session() - check for valid session for a user
577  * @work:       smb work containing smb request buffer
578  *
579  * Return:      0 on success, otherwise error
580  */
581 int smb2_check_user_session(struct ksmbd_work *work)
582 {
583         struct smb2_hdr *req_hdr = work->request_buf;
584         struct ksmbd_conn *conn = work->conn;
585         unsigned int cmd = conn->ops->get_cmd_val(work);
586         unsigned long long sess_id;
587
588         work->sess = NULL;
589         /*
590          * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not
591          * require a session id, so no need to validate user session's for
592          * these commands.
593          */
594         if (cmd == SMB2_ECHO_HE || cmd == SMB2_NEGOTIATE_HE ||
595             cmd == SMB2_SESSION_SETUP_HE)
596                 return 0;
597
598         if (!ksmbd_conn_good(work))
599                 return -EINVAL;
600
601         sess_id = le64_to_cpu(req_hdr->SessionId);
602         /* Check for validity of user session */
603         work->sess = ksmbd_session_lookup(conn, sess_id);
604         if (work->sess)
605                 return 1;
606         ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id);
607         return -EINVAL;
608 }
609
610 static void destroy_previous_session(struct ksmbd_user *user, u64 id)
611 {
612         struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
613         struct ksmbd_user *prev_user;
614
615         if (!prev_sess)
616                 return;
617
618         prev_user = prev_sess->user;
619
620         if (!prev_user ||
621             strcmp(user->name, prev_user->name) ||
622             user->passkey_sz != prev_user->passkey_sz ||
623             memcmp(user->passkey, prev_user->passkey, user->passkey_sz)) {
624                 put_session(prev_sess);
625                 return;
626         }
627
628         put_session(prev_sess);
629         ksmbd_session_destroy(prev_sess);
630 }
631
632 /**
633  * smb2_get_name() - get filename string from on the wire smb format
634  * @share:      ksmbd_share_config pointer
635  * @src:        source buffer
636  * @maxlen:     maxlen of source string
637  * @nls_table:  nls_table pointer
638  *
639  * Return:      matching converted filename on success, otherwise error ptr
640  */
641 static char *
642 smb2_get_name(struct ksmbd_share_config *share, const char *src,
643                 const int maxlen, struct nls_table *local_nls)
644 {
645         char *name, *unixname;
646
647         name = smb_strndup_from_utf16(src, maxlen, 1, local_nls);
648         if (IS_ERR(name)) {
649                 ksmbd_err("failed to get name %ld\n", PTR_ERR(name));
650                 return name;
651         }
652
653         /* change it to absolute unix name */
654         ksmbd_conv_path_to_unix(name);
655         ksmbd_strip_last_slash(name);
656
657         unixname = convert_to_unix_name(share, name);
658         kfree(name);
659         if (!unixname) {
660                 ksmbd_err("can not convert absolute name\n");
661                 return ERR_PTR(-ENOMEM);
662         }
663
664         ksmbd_debug(SMB, "absolute name = %s\n", unixname);
665         return unixname;
666 }
667
668 int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
669 {
670         struct smb2_hdr *rsp_hdr;
671         struct ksmbd_conn *conn = work->conn;
672         int id;
673
674         rsp_hdr = work->response_buf;
675         rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND;
676
677         id = ksmbd_acquire_async_msg_id(&conn->async_ida);
678         if (id < 0) {
679                 ksmbd_err("Failed to alloc async message id\n");
680                 return id;
681         }
682         work->syncronous = false;
683         work->async_id = id;
684         rsp_hdr->Id.AsyncId = cpu_to_le64(id);
685
686         ksmbd_debug(SMB,
687                 "Send interim Response to inform async request id : %d\n",
688                 work->async_id);
689
690         work->cancel_fn = fn;
691         work->cancel_argv = arg;
692
693         spin_lock(&conn->request_lock);
694         list_add_tail(&work->async_request_entry, &conn->async_requests);
695         spin_unlock(&conn->request_lock);
696
697         return 0;
698 }
699
700 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
701 {
702         struct smb2_hdr *rsp_hdr;
703
704         rsp_hdr = work->response_buf;
705         smb2_set_err_rsp(work);
706         rsp_hdr->Status = status;
707
708         work->multiRsp = 1;
709         ksmbd_conn_write(work);
710         rsp_hdr->Status = 0;
711         work->multiRsp = 0;
712 }
713
714 static __le32 smb2_get_reparse_tag_special_file(umode_t mode)
715 {
716         if (S_ISDIR(mode) || S_ISREG(mode))
717                 return 0;
718
719         if (S_ISLNK(mode))
720                 return IO_REPARSE_TAG_LX_SYMLINK_LE;
721         else if (S_ISFIFO(mode))
722                 return IO_REPARSE_TAG_LX_FIFO_LE;
723         else if (S_ISSOCK(mode))
724                 return IO_REPARSE_TAG_AF_UNIX_LE;
725         else if (S_ISCHR(mode))
726                 return IO_REPARSE_TAG_LX_CHR_LE;
727         else if (S_ISBLK(mode))
728                 return IO_REPARSE_TAG_LX_BLK_LE;
729
730         return 0;
731 }
732
733 /**
734  * smb2_get_dos_mode() - get file mode in dos format from unix mode
735  * @stat:       kstat containing file mode
736  * @attribute:  attribute flags
737  *
738  * Return:      converted dos mode
739  */
740 static int smb2_get_dos_mode(struct kstat *stat, int attribute)
741 {
742         int attr = 0;
743
744         if (S_ISDIR(stat->mode)) {
745                 attr = ATTR_DIRECTORY |
746                         (attribute & (ATTR_HIDDEN | ATTR_SYSTEM));
747         } else {
748                 attr = (attribute & 0x00005137) | ATTR_ARCHIVE;
749                 attr &= ~(ATTR_DIRECTORY);
750                 if (S_ISREG(stat->mode) && (server_conf.share_fake_fscaps &
751                                 FILE_SUPPORTS_SPARSE_FILES))
752                         attr |= ATTR_SPARSE;
753
754                 if (smb2_get_reparse_tag_special_file(stat->mode))
755                         attr |= ATTR_REPARSE;
756         }
757
758         return attr;
759 }
760
761 static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
762                 __le16 hash_id)
763 {
764         pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
765         pneg_ctxt->DataLength = cpu_to_le16(38);
766         pneg_ctxt->HashAlgorithmCount = cpu_to_le16(1);
767         pneg_ctxt->Reserved = cpu_to_le32(0);
768         pneg_ctxt->SaltLength = cpu_to_le16(SMB311_SALT_SIZE);
769         get_random_bytes(pneg_ctxt->Salt, SMB311_SALT_SIZE);
770         pneg_ctxt->HashAlgorithms = hash_id;
771 }
772
773 static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
774                 __le16 cipher_type)
775 {
776         pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
777         pneg_ctxt->DataLength = cpu_to_le16(4);
778         pneg_ctxt->Reserved = cpu_to_le32(0);
779         pneg_ctxt->CipherCount = cpu_to_le16(1);
780         pneg_ctxt->Ciphers[0] = cipher_type;
781 }
782
783 static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt,
784                 __le16 comp_algo)
785 {
786         pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
787         pneg_ctxt->DataLength =
788                 cpu_to_le16(sizeof(struct smb2_compression_ctx)
789                         - sizeof(struct smb2_neg_context));
790         pneg_ctxt->Reserved = cpu_to_le32(0);
791         pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(1);
792         pneg_ctxt->Reserved1 = cpu_to_le32(0);
793         pneg_ctxt->CompressionAlgorithms[0] = comp_algo;
794 }
795
796 static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
797 {
798         pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
799         pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
800         /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
801         pneg_ctxt->Name[0] = 0x93;
802         pneg_ctxt->Name[1] = 0xAD;
803         pneg_ctxt->Name[2] = 0x25;
804         pneg_ctxt->Name[3] = 0x50;
805         pneg_ctxt->Name[4] = 0x9C;
806         pneg_ctxt->Name[5] = 0xB4;
807         pneg_ctxt->Name[6] = 0x11;
808         pneg_ctxt->Name[7] = 0xE7;
809         pneg_ctxt->Name[8] = 0xB4;
810         pneg_ctxt->Name[9] = 0x23;
811         pneg_ctxt->Name[10] = 0x83;
812         pneg_ctxt->Name[11] = 0xDE;
813         pneg_ctxt->Name[12] = 0x96;
814         pneg_ctxt->Name[13] = 0x8B;
815         pneg_ctxt->Name[14] = 0xCD;
816         pneg_ctxt->Name[15] = 0x7C;
817 }
818
819 static void assemble_neg_contexts(struct ksmbd_conn *conn,
820                 struct smb2_negotiate_rsp *rsp)
821 {
822         /* +4 is to account for the RFC1001 len field */
823         char *pneg_ctxt = (char *)rsp +
824                         le32_to_cpu(rsp->NegotiateContextOffset) + 4;
825         int neg_ctxt_cnt = 1;
826         int ctxt_size;
827
828         ksmbd_debug(SMB,
829                 "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
830         build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt,
831                 conn->preauth_info->Preauth_HashId);
832         rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt);
833         inc_rfc1001_len(rsp, AUTH_GSS_PADDING);
834         ctxt_size = sizeof(struct smb2_preauth_neg_context);
835         /* Round to 8 byte boundary */
836         pneg_ctxt += round_up(sizeof(struct smb2_preauth_neg_context), 8);
837
838         if (conn->cipher_type) {
839                 ctxt_size = round_up(ctxt_size, 8);
840                 ksmbd_debug(SMB,
841                         "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
842                 build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt,
843                         conn->cipher_type);
844                 rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
845                 ctxt_size += sizeof(struct smb2_encryption_neg_context);
846                 /* Round to 8 byte boundary */
847                 pneg_ctxt +=
848                         round_up(sizeof(struct smb2_encryption_neg_context),
849                                  8);
850         }
851
852         if (conn->compress_algorithm) {
853                 ctxt_size = round_up(ctxt_size, 8);
854                 ksmbd_debug(SMB,
855                         "assemble SMB2_COMPRESSION_CAPABILITIES context\n");
856                 /* Temporarily set to SMB3_COMPRESS_NONE */
857                 build_compression_ctxt((struct smb2_compression_ctx *)pneg_ctxt,
858                                         conn->compress_algorithm);
859                 rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
860                 ctxt_size += sizeof(struct smb2_compression_ctx);
861                 /* Round to 8 byte boundary */
862                 pneg_ctxt += round_up(sizeof(struct smb2_compression_ctx), 8);
863         }
864
865         if (conn->posix_ext_supported) {
866                 ctxt_size = round_up(ctxt_size, 8);
867                 ksmbd_debug(SMB,
868                         "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
869                 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
870                 rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
871                 ctxt_size += sizeof(struct smb2_posix_neg_context);
872         }
873
874         inc_rfc1001_len(rsp, ctxt_size);
875 }
876
877 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
878                 struct smb2_preauth_neg_context *pneg_ctxt)
879 {
880         __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
881
882         if (pneg_ctxt->HashAlgorithms ==
883                         SMB2_PREAUTH_INTEGRITY_SHA512) {
884                 conn->preauth_info->Preauth_HashId =
885                         SMB2_PREAUTH_INTEGRITY_SHA512;
886                 err = STATUS_SUCCESS;
887         }
888
889         return err;
890 }
891
892 static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
893                 struct smb2_encryption_neg_context *pneg_ctxt)
894 {
895         int i;
896         int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount);
897
898         conn->cipher_type = 0;
899
900         if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION))
901                 goto out;
902
903         for (i = 0; i < cph_cnt; i++) {
904                 if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM ||
905                     pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM ||
906                     pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM ||
907                     pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) {
908                         ksmbd_debug(SMB, "Cipher ID = 0x%x\n",
909                                 pneg_ctxt->Ciphers[i]);
910                         conn->cipher_type = pneg_ctxt->Ciphers[i];
911                         break;
912                 }
913         }
914
915 out:
916         /*
917          * Return encrypt context size in request.
918          * So need to plus extra number of ciphers size.
919          */
920         return sizeof(struct smb2_encryption_neg_context) +
921                 ((cph_cnt - 1) * 2);
922 }
923
924 static int decode_compress_ctxt(struct ksmbd_conn *conn,
925                 struct smb2_compression_ctx *pneg_ctxt)
926 {
927         int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount);
928
929         conn->compress_algorithm = SMB3_COMPRESS_NONE;
930
931         /*
932          * Return compression context size in request.
933          * So need to plus extra number of CompressionAlgorithms size.
934          */
935         return sizeof(struct smb2_encryption_neg_context) +
936                 ((algo_cnt - 1) * 2);
937 }
938
939 static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
940                 struct smb2_negotiate_req *req)
941 {
942         int i = 0;
943         __le32 status = 0;
944         /* +4 is to account for the RFC1001 len field */
945         char *pneg_ctxt = (char *)req +
946                         le32_to_cpu(req->NegotiateContextOffset) + 4;
947         __le16 *ContextType = (__le16 *)pneg_ctxt;
948         int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
949         int ctxt_size;
950
951         ksmbd_debug(SMB, "negotiate context count = %d\n", neg_ctxt_cnt);
952         status = STATUS_INVALID_PARAMETER;
953         while (i++ < neg_ctxt_cnt) {
954                 if (*ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) {
955                         ksmbd_debug(SMB,
956                                 "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
957                         if (conn->preauth_info->Preauth_HashId)
958                                 break;
959
960                         status = decode_preauth_ctxt(conn,
961                                 (struct smb2_preauth_neg_context *)pneg_ctxt);
962                         pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
963                 } else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) {
964                         ksmbd_debug(SMB,
965                                 "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
966                         if (conn->cipher_type)
967                                 break;
968
969                         ctxt_size = decode_encrypt_ctxt(conn,
970                                 (struct smb2_encryption_neg_context *)pneg_ctxt);
971                         pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
972                 } else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) {
973                         ksmbd_debug(SMB,
974                                 "deassemble SMB2_COMPRESSION_CAPABILITIES context\n");
975                         if (conn->compress_algorithm)
976                                 break;
977
978                         ctxt_size = decode_compress_ctxt(conn,
979                                 (struct smb2_compression_ctx *) pneg_ctxt);
980                         pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
981                 } else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) {
982                         ksmbd_debug(SMB,
983                                 "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
984                         ctxt_size = sizeof(struct smb2_netname_neg_context);
985                         ctxt_size += DIV_ROUND_UP(le16_to_cpu(((struct smb2_netname_neg_context *)
986                                         pneg_ctxt)->DataLength), 8) * 8;
987                         pneg_ctxt += ctxt_size;
988                 } else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) {
989                         ksmbd_debug(SMB,
990                                 "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
991                         conn->posix_ext_supported = true;
992                         pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_posix_neg_context), 8) * 8;
993                 }
994                 ContextType = (__le16 *)pneg_ctxt;
995
996                 if (status != STATUS_SUCCESS)
997                         break;
998         }
999         return status;
1000 }
1001
1002 /**
1003  * smb2_handle_negotiate() - handler for smb2 negotiate command
1004  * @work:       smb work containing smb request buffer
1005  *
1006  * Return:      0
1007  */
1008 int smb2_handle_negotiate(struct ksmbd_work *work)
1009 {
1010         struct ksmbd_conn *conn = work->conn;
1011         struct smb2_negotiate_req *req = work->request_buf;
1012         struct smb2_negotiate_rsp *rsp = work->response_buf;
1013         int rc = 0;
1014         __le32 status;
1015
1016         ksmbd_debug(SMB, "Received negotiate request\n");
1017         conn->need_neg = false;
1018         if (ksmbd_conn_good(work)) {
1019                 ksmbd_err("conn->tcp_status is already in CifsGood State\n");
1020                 work->send_no_response = 1;
1021                 return rc;
1022         }
1023
1024         if (req->DialectCount == 0) {
1025                 ksmbd_err("malformed packet\n");
1026                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1027                 rc = -EINVAL;
1028                 goto err_out;
1029         }
1030
1031         conn->cli_cap = le32_to_cpu(req->Capabilities);
1032         switch (conn->dialect) {
1033         case SMB311_PROT_ID:
1034                 conn->preauth_info =
1035                         kzalloc(sizeof(struct preauth_integrity_info),
1036                         GFP_KERNEL);
1037                 if (!conn->preauth_info) {
1038                         rc = -ENOMEM;
1039                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1040                         goto err_out;
1041                 }
1042
1043                 status = deassemble_neg_contexts(conn, req);
1044                 if (status != STATUS_SUCCESS) {
1045                         ksmbd_err("deassemble_neg_contexts error(0x%x)\n",
1046                                         status);
1047                         rsp->hdr.Status = status;
1048                         rc = -EINVAL;
1049                         goto err_out;
1050                 }
1051
1052                 rc = init_smb3_11_server(conn);
1053                 if (rc < 0) {
1054                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1055                         goto err_out;
1056                 }
1057
1058                 ksmbd_gen_preauth_integrity_hash(conn,
1059                                 work->request_buf,
1060                                 conn->preauth_info->Preauth_HashValue);
1061                 rsp->NegotiateContextOffset =
1062                                 cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
1063                 assemble_neg_contexts(conn, rsp);
1064                 break;
1065         case SMB302_PROT_ID:
1066                 init_smb3_02_server(conn);
1067                 break;
1068         case SMB30_PROT_ID:
1069                 init_smb3_0_server(conn);
1070                 break;
1071         case SMB21_PROT_ID:
1072                 init_smb2_1_server(conn);
1073                 break;
1074         case SMB20_PROT_ID:
1075                 rc = init_smb2_0_server(conn);
1076                 if (rc) {
1077                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
1078                         goto err_out;
1079                 }
1080                 break;
1081         case SMB2X_PROT_ID:
1082         case BAD_PROT_ID:
1083         default:
1084                 ksmbd_debug(SMB, "Server dialect :0x%x not supported\n",
1085                         conn->dialect);
1086                 rsp->hdr.Status = STATUS_NOT_SUPPORTED;
1087                 rc = -EINVAL;
1088                 goto err_out;
1089         }
1090         rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
1091
1092         /* For stats */
1093         conn->connection_type = conn->dialect;
1094
1095         rsp->MaxTransactSize = cpu_to_le32(conn->vals->max_trans_size);
1096         rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
1097         rsp->MaxWriteSize = cpu_to_le32(conn->vals->max_write_size);
1098
1099         if (conn->dialect > SMB20_PROT_ID) {
1100                 memcpy(conn->ClientGUID, req->ClientGUID,
1101                                 SMB2_CLIENT_GUID_SIZE);
1102                 conn->cli_sec_mode = le16_to_cpu(req->SecurityMode);
1103         }
1104
1105         rsp->StructureSize = cpu_to_le16(65);
1106         rsp->DialectRevision = cpu_to_le16(conn->dialect);
1107         /* Not setting conn guid rsp->ServerGUID, as it
1108          * not used by client for identifying server
1109          */
1110         memset(rsp->ServerGUID, 0, SMB2_CLIENT_GUID_SIZE);
1111
1112         rsp->SystemTime = cpu_to_le64(ksmbd_systime());
1113         rsp->ServerStartTime = 0;
1114         ksmbd_debug(SMB, "negotiate context offset %d, count %d\n",
1115                 le32_to_cpu(rsp->NegotiateContextOffset),
1116                 le16_to_cpu(rsp->NegotiateContextCount));
1117
1118         rsp->SecurityBufferOffset = cpu_to_le16(128);
1119         rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH);
1120         ksmbd_copy_gss_neg_header(((char *)(&rsp->hdr) +
1121                 sizeof(rsp->hdr.smb2_buf_length)) +
1122                 le16_to_cpu(rsp->SecurityBufferOffset));
1123         inc_rfc1001_len(rsp, sizeof(struct smb2_negotiate_rsp) -
1124                 sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
1125                 AUTH_GSS_LENGTH);
1126         rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
1127         conn->use_spnego = true;
1128
1129         if ((server_conf.signing == KSMBD_CONFIG_OPT_AUTO ||
1130              server_conf.signing == KSMBD_CONFIG_OPT_DISABLED) &&
1131             req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED_LE)
1132                 conn->sign = true;
1133         else if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) {
1134                 server_conf.enforced_signing = true;
1135                 rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
1136                 conn->sign = true;
1137         }
1138
1139         conn->srv_sec_mode = le16_to_cpu(rsp->SecurityMode);
1140         ksmbd_conn_set_need_negotiate(work);
1141
1142 err_out:
1143         if (rc < 0)
1144                 smb2_set_err_rsp(work);
1145
1146         return rc;
1147 }
1148
1149 static int alloc_preauth_hash(struct ksmbd_session *sess,
1150                 struct ksmbd_conn *conn)
1151 {
1152         if (sess->Preauth_HashValue)
1153                 return 0;
1154
1155         sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue,
1156                         PREAUTH_HASHVALUE_SIZE, GFP_KERNEL);
1157         if (!sess->Preauth_HashValue)
1158                 return -ENOMEM;
1159
1160         return 0;
1161 }
1162
1163 static int generate_preauth_hash(struct ksmbd_work *work)
1164 {
1165         struct ksmbd_conn *conn = work->conn;
1166         struct ksmbd_session *sess = work->sess;
1167
1168         if (conn->dialect != SMB311_PROT_ID)
1169                 return 0;
1170
1171         if (!sess->Preauth_HashValue) {
1172                 if (alloc_preauth_hash(sess, conn))
1173                         return -ENOMEM;
1174         }
1175
1176         ksmbd_gen_preauth_integrity_hash(conn,
1177                                          work->request_buf,
1178                                          sess->Preauth_HashValue);
1179         return 0;
1180 }
1181
1182 static int decode_negotiation_token(struct ksmbd_work *work,
1183                 struct negotiate_message *negblob)
1184 {
1185         struct ksmbd_conn *conn = work->conn;
1186         struct smb2_sess_setup_req *req;
1187         int sz;
1188
1189         if (!conn->use_spnego)
1190                 return -EINVAL;
1191
1192         req = work->request_buf;
1193         sz = le16_to_cpu(req->SecurityBufferLength);
1194
1195         if (ksmbd_decode_negTokenInit((char *)negblob, sz, conn)) {
1196                 if (ksmbd_decode_negTokenTarg((char *)negblob, sz, conn)) {
1197                         conn->auth_mechs |= KSMBD_AUTH_NTLMSSP;
1198                         conn->preferred_auth_mech = KSMBD_AUTH_NTLMSSP;
1199                         conn->use_spnego = false;
1200                 }
1201         }
1202         return 0;
1203 }
1204
1205 static int ntlm_negotiate(struct ksmbd_work *work,
1206                 struct negotiate_message *negblob)
1207 {
1208         struct smb2_sess_setup_req *req = work->request_buf;
1209         struct smb2_sess_setup_rsp *rsp = work->response_buf;
1210         struct challenge_message *chgblob;
1211         unsigned char *spnego_blob = NULL;
1212         u16 spnego_blob_len;
1213         char *neg_blob;
1214         int sz, rc;
1215
1216         ksmbd_debug(SMB, "negotiate phase\n");
1217         sz = le16_to_cpu(req->SecurityBufferLength);
1218         rc = ksmbd_decode_ntlmssp_neg_blob(negblob, sz, work->sess);
1219         if (rc)
1220                 return rc;
1221
1222         sz = le16_to_cpu(rsp->SecurityBufferOffset);
1223         chgblob =
1224                 (struct challenge_message *)((char *)&rsp->hdr.ProtocolId + sz);
1225         memset(chgblob, 0, sizeof(struct challenge_message));
1226
1227         if (!work->conn->use_spnego) {
1228                 sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->sess);
1229                 if (sz < 0)
1230                         return -ENOMEM;
1231
1232                 rsp->SecurityBufferLength = cpu_to_le16(sz);
1233                 return 0;
1234         }
1235
1236         sz = sizeof(struct challenge_message);
1237         sz += (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6;
1238
1239         neg_blob = kzalloc(sz, GFP_KERNEL);
1240         if (!neg_blob)
1241                 return -ENOMEM;
1242
1243         chgblob = (struct challenge_message *)neg_blob;
1244         sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->sess);
1245         if (sz < 0) {
1246                 rc = -ENOMEM;
1247                 goto out;
1248         }
1249
1250         rc = build_spnego_ntlmssp_neg_blob(&spnego_blob,
1251                                           &spnego_blob_len,
1252                                           neg_blob,
1253                                           sz);
1254         if (rc) {
1255                 rc = -ENOMEM;
1256                 goto out;
1257         }
1258
1259         sz = le16_to_cpu(rsp->SecurityBufferOffset);
1260         memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len);
1261         rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
1262
1263 out:
1264         kfree(spnego_blob);
1265         kfree(neg_blob);
1266         return rc;
1267 }
1268
1269 static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
1270                 struct smb2_sess_setup_req *req)
1271 {
1272         int sz;
1273
1274         if (conn->use_spnego && conn->mechToken)
1275                 return (struct authenticate_message *)conn->mechToken;
1276
1277         sz = le16_to_cpu(req->SecurityBufferOffset);
1278         return (struct authenticate_message *)((char *)&req->hdr.ProtocolId
1279                                                + sz);
1280 }
1281
1282 static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
1283                 struct smb2_sess_setup_req *req)
1284 {
1285         struct authenticate_message *authblob;
1286         struct ksmbd_user *user;
1287         char *name;
1288         int sz;
1289
1290         authblob = user_authblob(conn, req);
1291         sz = le32_to_cpu(authblob->UserName.BufferOffset);
1292         name = smb_strndup_from_utf16((const char *)authblob + sz,
1293                                       le16_to_cpu(authblob->UserName.Length),
1294                                       true,
1295                                       conn->local_nls);
1296         if (IS_ERR(name)) {
1297                 ksmbd_err("cannot allocate memory\n");
1298                 return NULL;
1299         }
1300
1301         ksmbd_debug(SMB, "session setup request for user %s\n", name);
1302         user = ksmbd_login_user(name);
1303         kfree(name);
1304         return user;
1305 }
1306
1307 static int ntlm_authenticate(struct ksmbd_work *work)
1308 {
1309         struct smb2_sess_setup_req *req = work->request_buf;
1310         struct smb2_sess_setup_rsp *rsp = work->response_buf;
1311         struct ksmbd_conn *conn = work->conn;
1312         struct ksmbd_session *sess = work->sess;
1313         struct channel *chann = NULL;
1314         struct ksmbd_user *user;
1315         u64 prev_id;
1316         int sz, rc;
1317
1318         ksmbd_debug(SMB, "authenticate phase\n");
1319         if (conn->use_spnego) {
1320                 unsigned char *spnego_blob;
1321                 u16 spnego_blob_len;
1322
1323                 rc = build_spnego_ntlmssp_auth_blob(&spnego_blob,
1324                                                     &spnego_blob_len,
1325                                                     0);
1326                 if (rc)
1327                         return -ENOMEM;
1328
1329                 sz = le16_to_cpu(rsp->SecurityBufferOffset);
1330                 memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len);
1331                 rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
1332                 kfree(spnego_blob);
1333                 inc_rfc1001_len(rsp, spnego_blob_len - 1);
1334         }
1335
1336         user = session_user(conn, req);
1337         if (!user) {
1338                 ksmbd_debug(SMB, "Unknown user name or an error\n");
1339                 rsp->hdr.Status = STATUS_LOGON_FAILURE;
1340                 return -EINVAL;
1341         }
1342
1343         /* Check for previous session */
1344         prev_id = le64_to_cpu(req->PreviousSessionId);
1345         if (prev_id && prev_id != sess->id)
1346                 destroy_previous_session(user, prev_id);
1347
1348         if (sess->state == SMB2_SESSION_VALID) {
1349                 /*
1350                  * Reuse session if anonymous try to connect
1351                  * on reauthetication.
1352                  */
1353                 if (ksmbd_anonymous_user(user)) {
1354                         ksmbd_free_user(user);
1355                         return 0;
1356                 }
1357                 ksmbd_free_user(sess->user);
1358         }
1359
1360         sess->user = user;
1361         if (user_guest(sess->user)) {
1362                 if (conn->sign) {
1363                         ksmbd_debug(SMB, "Guest login not allowed when signing enabled\n");
1364                         rsp->hdr.Status = STATUS_LOGON_FAILURE;
1365                         return -EACCES;
1366                 }
1367
1368                 rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
1369         } else {
1370                 struct authenticate_message *authblob;
1371
1372                 authblob = user_authblob(conn, req);
1373                 sz = le16_to_cpu(req->SecurityBufferLength);
1374                 rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, sess);
1375                 if (rc) {
1376                         set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
1377                         ksmbd_debug(SMB, "authentication failed\n");
1378                         rsp->hdr.Status = STATUS_LOGON_FAILURE;
1379                         return -EINVAL;
1380                 }
1381
1382                 /*
1383                  * If session state is SMB2_SESSION_VALID, We can assume
1384                  * that it is reauthentication. And the user/password
1385                  * has been verified, so return it here.
1386                  */
1387                 if (sess->state == SMB2_SESSION_VALID)
1388                         return 0;
1389
1390                 if ((conn->sign || server_conf.enforced_signing) ||
1391                     (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
1392                         sess->sign = true;
1393
1394                 if (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION &&
1395                     conn->ops->generate_encryptionkey) {
1396                         rc = conn->ops->generate_encryptionkey(sess);
1397                         if (rc) {
1398                                 ksmbd_debug(SMB,
1399                                         "SMB3 encryption key generation failed\n");
1400                                 rsp->hdr.Status = STATUS_LOGON_FAILURE;
1401                                 return rc;
1402                         }
1403                         sess->enc = true;
1404                         rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
1405                         /*
1406                          * signing is disable if encryption is enable
1407                          * on this session
1408                          */
1409                         sess->sign = false;
1410                 }
1411         }
1412
1413         if (conn->dialect >= SMB30_PROT_ID) {
1414                 chann = lookup_chann_list(sess);
1415                 if (!chann) {
1416                         chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
1417                         if (!chann)
1418                                 return -ENOMEM;
1419
1420                         chann->conn = conn;
1421                         INIT_LIST_HEAD(&chann->chann_list);
1422                         list_add(&chann->chann_list, &sess->ksmbd_chann_list);
1423                 }
1424         }
1425
1426         if (conn->ops->generate_signingkey) {
1427                 rc = conn->ops->generate_signingkey(sess);
1428                 if (rc) {
1429                         ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
1430                         rsp->hdr.Status = STATUS_LOGON_FAILURE;
1431                         return rc;
1432                 }
1433         }
1434
1435         if (conn->dialect > SMB20_PROT_ID) {
1436                 if (!ksmbd_conn_lookup_dialect(conn)) {
1437                         ksmbd_err("fail to verify the dialect\n");
1438                         rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
1439                         return -EPERM;
1440                 }
1441         }
1442         return 0;
1443 }
1444
1445 #ifdef CONFIG_SMB_SERVER_KERBEROS5
1446 static int krb5_authenticate(struct ksmbd_work *work)
1447 {
1448         struct smb2_sess_setup_req *req = work->request_buf;
1449         struct smb2_sess_setup_rsp *rsp = work->response_buf;
1450         struct ksmbd_conn *conn = work->conn;
1451         struct ksmbd_session *sess = work->sess;
1452         char *in_blob, *out_blob;
1453         struct channel *chann = NULL;
1454         u64 prev_sess_id;
1455         int in_len, out_len;
1456         int retval;
1457
1458         in_blob = (char *)&req->hdr.ProtocolId +
1459                 le16_to_cpu(req->SecurityBufferOffset);
1460         in_len = le16_to_cpu(req->SecurityBufferLength);
1461         out_blob = (char *)&rsp->hdr.ProtocolId +
1462                 le16_to_cpu(rsp->SecurityBufferOffset);
1463         out_len = work->response_sz -
1464                 offsetof(struct smb2_hdr, smb2_buf_length) -
1465                 le16_to_cpu(rsp->SecurityBufferOffset);
1466
1467         /* Check previous session */
1468         prev_sess_id = le64_to_cpu(req->PreviousSessionId);
1469         if (prev_sess_id && prev_sess_id != sess->id)
1470                 destroy_previous_session(sess->user, prev_sess_id);
1471
1472         if (sess->state == SMB2_SESSION_VALID)
1473                 ksmbd_free_user(sess->user);
1474
1475         retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
1476                         out_blob, &out_len);
1477         if (retval) {
1478                 ksmbd_debug(SMB, "krb5 authentication failed\n");
1479                 rsp->hdr.Status = STATUS_LOGON_FAILURE;
1480                 return retval;
1481         }
1482         rsp->SecurityBufferLength = cpu_to_le16(out_len);
1483         inc_rfc1001_len(rsp, out_len - 1);
1484
1485         if ((conn->sign || server_conf.enforced_signing) ||
1486             (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
1487                 sess->sign = true;
1488
1489         if ((conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) &&
1490             conn->ops->generate_encryptionkey) {
1491                 retval = conn->ops->generate_encryptionkey(sess);
1492                 if (retval) {
1493                         ksmbd_debug(SMB,
1494                                 "SMB3 encryption key generation failed\n");
1495                         rsp->hdr.Status = STATUS_LOGON_FAILURE;
1496                         return retval;
1497                 }
1498                 sess->enc = true;
1499                 rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
1500                 sess->sign = false;
1501         }
1502
1503         if (conn->dialect >= SMB30_PROT_ID) {
1504                 chann = lookup_chann_list(sess);
1505                 if (!chann) {
1506                         chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
1507                         if (!chann)
1508                                 return -ENOMEM;
1509
1510                         chann->conn = conn;
1511                         INIT_LIST_HEAD(&chann->chann_list);
1512                         list_add(&chann->chann_list, &sess->ksmbd_chann_list);
1513                 }
1514         }
1515
1516         if (conn->ops->generate_signingkey) {
1517                 retval = conn->ops->generate_signingkey(sess);
1518                 if (retval) {
1519                         ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
1520                         rsp->hdr.Status = STATUS_LOGON_FAILURE;
1521                         return retval;
1522                 }
1523         }
1524
1525         if (conn->dialect > SMB20_PROT_ID) {
1526                 if (!ksmbd_conn_lookup_dialect(conn)) {
1527                         ksmbd_err("fail to verify the dialect\n");
1528                         rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
1529                         return -EPERM;
1530                 }
1531         }
1532         return 0;
1533 }
1534 #else
1535 static int krb5_authenticate(struct ksmbd_work *work)
1536 {
1537         return -EOPNOTSUPP;
1538 }
1539 #endif
1540
1541 int smb2_sess_setup(struct ksmbd_work *work)
1542 {
1543         struct ksmbd_conn *conn = work->conn;
1544         struct smb2_sess_setup_req *req = work->request_buf;
1545         struct smb2_sess_setup_rsp *rsp = work->response_buf;
1546         struct ksmbd_session *sess;
1547         struct negotiate_message *negblob;
1548         int rc = 0;
1549
1550         ksmbd_debug(SMB, "Received request for session setup\n");
1551
1552         rsp->StructureSize = cpu_to_le16(9);
1553         rsp->SessionFlags = 0;
1554         rsp->SecurityBufferOffset = cpu_to_le16(72);
1555         rsp->SecurityBufferLength = 0;
1556         inc_rfc1001_len(rsp, 9);
1557
1558         if (!req->hdr.SessionId) {
1559                 sess = ksmbd_smb2_session_create();
1560                 if (!sess) {
1561                         rc = -ENOMEM;
1562                         goto out_err;
1563                 }
1564                 rsp->hdr.SessionId = cpu_to_le64(sess->id);
1565                 ksmbd_session_register(conn, sess);
1566         } else {
1567                 sess = ksmbd_session_lookup(conn,
1568                                 le64_to_cpu(req->hdr.SessionId));
1569                 if (!sess) {
1570                         rc = -ENOENT;
1571                         rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
1572                         goto out_err;
1573                 }
1574         }
1575         work->sess = sess;
1576
1577         if (sess->state == SMB2_SESSION_EXPIRED)
1578                 sess->state = SMB2_SESSION_IN_PROGRESS;
1579
1580         negblob = (struct negotiate_message *)((char *)&req->hdr.ProtocolId +
1581                         le16_to_cpu(req->SecurityBufferOffset));
1582
1583         if (decode_negotiation_token(work, negblob) == 0) {
1584                 if (conn->mechToken)
1585                         negblob = (struct negotiate_message *)conn->mechToken;
1586         }
1587
1588         if (server_conf.auth_mechs & conn->auth_mechs) {
1589                 if (conn->preferred_auth_mech &
1590                                 (KSMBD_AUTH_KRB5 | KSMBD_AUTH_MSKRB5)) {
1591                         rc = generate_preauth_hash(work);
1592                         if (rc)
1593                                 goto out_err;
1594
1595                         rc = krb5_authenticate(work);
1596                         if (rc) {
1597                                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1598                                 goto out_err;
1599                         }
1600
1601                         ksmbd_conn_set_good(work);
1602                         sess->state = SMB2_SESSION_VALID;
1603                         kfree(sess->Preauth_HashValue);
1604                         sess->Preauth_HashValue = NULL;
1605                 } else if (conn->preferred_auth_mech == KSMBD_AUTH_NTLMSSP) {
1606                         rc = generate_preauth_hash(work);
1607                         if (rc)
1608                                 goto out_err;
1609
1610                         if (negblob->MessageType == NtLmNegotiate) {
1611                                 rc = ntlm_negotiate(work, negblob);
1612                                 if (rc)
1613                                         goto out_err;
1614                                 rsp->hdr.Status =
1615                                         STATUS_MORE_PROCESSING_REQUIRED;
1616                                 /*
1617                                  * Note: here total size -1 is done as an
1618                                  * adjustment for 0 size blob
1619                                  */
1620                                 inc_rfc1001_len(rsp, le16_to_cpu(rsp->SecurityBufferLength) - 1);
1621
1622                         } else if (negblob->MessageType == NtLmAuthenticate) {
1623                                 rc = ntlm_authenticate(work);
1624                                 if (rc)
1625                                         goto out_err;
1626
1627                                 ksmbd_conn_set_good(work);
1628                                 sess->state = SMB2_SESSION_VALID;
1629                                 kfree(sess->Preauth_HashValue);
1630                                 sess->Preauth_HashValue = NULL;
1631                         }
1632                 } else {
1633                         /* TODO: need one more negotiation */
1634                         ksmbd_err("Not support the preferred authentication\n");
1635                         rc = -EINVAL;
1636                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1637                 }
1638         } else {
1639                 ksmbd_err("Not support authentication\n");
1640                 rc = -EINVAL;
1641                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1642         }
1643
1644 out_err:
1645         if (conn->use_spnego && conn->mechToken) {
1646                 kfree(conn->mechToken);
1647                 conn->mechToken = NULL;
1648         }
1649
1650         if (rc < 0 && sess) {
1651                 ksmbd_session_destroy(sess);
1652                 work->sess = NULL;
1653         }
1654
1655         return rc;
1656 }
1657
1658 /**
1659  * smb2_tree_connect() - handler for smb2 tree connect command
1660  * @work:       smb work containing smb request buffer
1661  *
1662  * Return:      0 on success, otherwise error
1663  */
1664 int smb2_tree_connect(struct ksmbd_work *work)
1665 {
1666         struct ksmbd_conn *conn = work->conn;
1667         struct smb2_tree_connect_req *req = work->request_buf;
1668         struct smb2_tree_connect_rsp *rsp = work->response_buf;
1669         struct ksmbd_session *sess = work->sess;
1670         char *treename = NULL, *name = NULL;
1671         struct ksmbd_tree_conn_status status;
1672         struct ksmbd_share_config *share;
1673         int rc = -EINVAL;
1674
1675         treename = smb_strndup_from_utf16(req->Buffer,
1676                 le16_to_cpu(req->PathLength), true, conn->local_nls);
1677         if (IS_ERR(treename)) {
1678                 ksmbd_err("treename is NULL\n");
1679                 status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
1680                 goto out_err1;
1681         }
1682
1683         name = ksmbd_extract_sharename(treename);
1684         if (IS_ERR(name)) {
1685                 status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
1686                 goto out_err1;
1687         }
1688
1689         ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",
1690                       name, treename);
1691
1692         status = ksmbd_tree_conn_connect(sess, name);
1693         if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
1694                 rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);
1695         else
1696                 goto out_err1;
1697
1698         share = status.tree_conn->share_conf;
1699         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
1700                 ksmbd_debug(SMB, "IPC share path request\n");
1701                 rsp->ShareType = SMB2_SHARE_TYPE_PIPE;
1702                 rsp->MaximalAccess = FILE_READ_DATA_LE | FILE_READ_EA_LE |
1703                         FILE_EXECUTE_LE | FILE_READ_ATTRIBUTES_LE |
1704                         FILE_DELETE_LE | FILE_READ_CONTROL_LE |
1705                         FILE_WRITE_DAC_LE | FILE_WRITE_OWNER_LE |
1706                         FILE_SYNCHRONIZE_LE;
1707         } else {
1708                 rsp->ShareType = SMB2_SHARE_TYPE_DISK;
1709                 rsp->MaximalAccess = FILE_READ_DATA_LE | FILE_READ_EA_LE |
1710                         FILE_EXECUTE_LE | FILE_READ_ATTRIBUTES_LE;
1711                 if (test_tree_conn_flag(status.tree_conn,
1712                                         KSMBD_TREE_CONN_FLAG_WRITABLE)) {
1713                         rsp->MaximalAccess |= FILE_WRITE_DATA_LE |
1714                                 FILE_APPEND_DATA_LE | FILE_WRITE_EA_LE |
1715                                 FILE_DELETE_CHILD_LE | FILE_DELETE_LE |
1716                                 FILE_WRITE_ATTRIBUTES_LE | FILE_DELETE_LE |
1717                                 FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE |
1718                                 FILE_WRITE_OWNER_LE | FILE_SYNCHRONIZE_LE;
1719                 }
1720         }
1721
1722         status.tree_conn->maximal_access = le32_to_cpu(rsp->MaximalAccess);
1723         if (conn->posix_ext_supported)
1724                 status.tree_conn->posix_extensions = true;
1725
1726 out_err1:
1727         rsp->StructureSize = cpu_to_le16(16);
1728         rsp->Capabilities = 0;
1729         rsp->Reserved = 0;
1730         /* default manual caching */
1731         rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING;
1732         inc_rfc1001_len(rsp, 16);
1733
1734         if (!IS_ERR(treename))
1735                 kfree(treename);
1736         if (!IS_ERR(name))
1737                 kfree(name);
1738
1739         switch (status.ret) {
1740         case KSMBD_TREE_CONN_STATUS_OK:
1741                 rsp->hdr.Status = STATUS_SUCCESS;
1742                 rc = 0;
1743                 break;
1744         case KSMBD_TREE_CONN_STATUS_NO_SHARE:
1745                 rsp->hdr.Status = STATUS_BAD_NETWORK_PATH;
1746                 break;
1747         case -ENOMEM:
1748         case KSMBD_TREE_CONN_STATUS_NOMEM:
1749                 rsp->hdr.Status = STATUS_NO_MEMORY;
1750                 break;
1751         case KSMBD_TREE_CONN_STATUS_ERROR:
1752         case KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS:
1753         case KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS:
1754                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
1755                 break;
1756         case -EINVAL:
1757                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1758                 break;
1759         default:
1760                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
1761         }
1762
1763         return rc;
1764 }
1765
1766 /**
1767  * smb2_create_open_flags() - convert smb open flags to unix open flags
1768  * @file_present:       is file already present
1769  * @access:             file access flags
1770  * @disposition:        file disposition flags
1771  *
1772  * Return:      file open flags
1773  */
1774 static int smb2_create_open_flags(bool file_present, __le32 access,
1775                 __le32 disposition)
1776 {
1777         int oflags = O_NONBLOCK | O_LARGEFILE;
1778
1779         if (access & FILE_READ_DESIRED_ACCESS_LE &&
1780             access & FILE_WRITE_DESIRE_ACCESS_LE)
1781                 oflags |= O_RDWR;
1782         else if (access & FILE_WRITE_DESIRE_ACCESS_LE)
1783                 oflags |= O_WRONLY;
1784         else
1785                 oflags |= O_RDONLY;
1786
1787         if (access == FILE_READ_ATTRIBUTES_LE)
1788                 oflags |= O_PATH;
1789
1790         if (file_present) {
1791                 switch (disposition & FILE_CREATE_MASK_LE) {
1792                 case FILE_OPEN_LE:
1793                 case FILE_CREATE_LE:
1794                         break;
1795                 case FILE_SUPERSEDE_LE:
1796                 case FILE_OVERWRITE_LE:
1797                 case FILE_OVERWRITE_IF_LE:
1798                         oflags |= O_TRUNC;
1799                         break;
1800                 default:
1801                         break;
1802                 }
1803         } else {
1804                 switch (disposition & FILE_CREATE_MASK_LE) {
1805                 case FILE_SUPERSEDE_LE:
1806                 case FILE_CREATE_LE:
1807                 case FILE_OPEN_IF_LE:
1808                 case FILE_OVERWRITE_IF_LE:
1809                         oflags |= O_CREAT;
1810                         break;
1811                 case FILE_OPEN_LE:
1812                 case FILE_OVERWRITE_LE:
1813                         oflags &= ~O_CREAT;
1814                         break;
1815                 default:
1816                         break;
1817                 }
1818         }
1819         return oflags;
1820 }
1821
1822 /**
1823  * smb2_tree_disconnect() - handler for smb tree connect request
1824  * @work:       smb work containing request buffer
1825  *
1826  * Return:      0
1827  */
1828 int smb2_tree_disconnect(struct ksmbd_work *work)
1829 {
1830         struct smb2_tree_disconnect_rsp *rsp = work->response_buf;
1831         struct ksmbd_session *sess = work->sess;
1832         struct ksmbd_tree_connect *tcon = work->tcon;
1833
1834         rsp->StructureSize = cpu_to_le16(4);
1835         inc_rfc1001_len(rsp, 4);
1836
1837         ksmbd_debug(SMB, "request\n");
1838
1839         if (!tcon) {
1840                 struct smb2_tree_disconnect_req *req = work->request_buf;
1841
1842                 ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
1843                 rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
1844                 smb2_set_err_rsp(work);
1845                 return 0;
1846         }
1847
1848         ksmbd_close_tree_conn_fds(work);
1849         ksmbd_tree_conn_disconnect(sess, tcon);
1850         return 0;
1851 }
1852
1853 /**
1854  * smb2_session_logoff() - handler for session log off request
1855  * @work:       smb work containing request buffer
1856  *
1857  * Return:      0
1858  */
1859 int smb2_session_logoff(struct ksmbd_work *work)
1860 {
1861         struct ksmbd_conn *conn = work->conn;
1862         struct smb2_logoff_rsp *rsp = work->response_buf;
1863         struct ksmbd_session *sess = work->sess;
1864
1865         rsp->StructureSize = cpu_to_le16(4);
1866         inc_rfc1001_len(rsp, 4);
1867
1868         ksmbd_debug(SMB, "request\n");
1869
1870         /* Got a valid session, set connection state */
1871         WARN_ON(sess->conn != conn);
1872
1873         /* setting CifsExiting here may race with start_tcp_sess */
1874         ksmbd_conn_set_need_reconnect(work);
1875         ksmbd_close_session_fds(work);
1876         ksmbd_conn_wait_idle(conn);
1877
1878         if (ksmbd_tree_conn_session_logoff(sess)) {
1879                 struct smb2_logoff_req *req = work->request_buf;
1880
1881                 ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
1882                 rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
1883                 smb2_set_err_rsp(work);
1884                 return 0;
1885         }
1886
1887         ksmbd_destroy_file_table(&sess->file_table);
1888         sess->state = SMB2_SESSION_EXPIRED;
1889
1890         ksmbd_free_user(sess->user);
1891         sess->user = NULL;
1892
1893         /* let start_tcp_sess free connection info now */
1894         ksmbd_conn_set_need_negotiate(work);
1895         return 0;
1896 }
1897
1898 /**
1899  * create_smb2_pipe() - create IPC pipe
1900  * @work:       smb work containing request buffer
1901  *
1902  * Return:      0 on success, otherwise error
1903  */
1904 static noinline int create_smb2_pipe(struct ksmbd_work *work)
1905 {
1906         struct smb2_create_rsp *rsp = work->response_buf;
1907         struct smb2_create_req *req = work->request_buf;
1908         int id;
1909         int err;
1910         char *name;
1911
1912         name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength),
1913                         1, work->conn->local_nls);
1914         if (IS_ERR(name)) {
1915                 rsp->hdr.Status = STATUS_NO_MEMORY;
1916                 err = PTR_ERR(name);
1917                 goto out;
1918         }
1919
1920         id = ksmbd_session_rpc_open(work->sess, name);
1921         if (id < 0) {
1922                 ksmbd_err("Unable to open RPC pipe: %d\n", id);
1923                 err = id;
1924                 goto out;
1925         }
1926
1927         rsp->hdr.Status = STATUS_SUCCESS;
1928         rsp->StructureSize = cpu_to_le16(89);
1929         rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
1930         rsp->Reserved = 0;
1931         rsp->CreateAction = cpu_to_le32(FILE_OPENED);
1932
1933         rsp->CreationTime = cpu_to_le64(0);
1934         rsp->LastAccessTime = cpu_to_le64(0);
1935         rsp->ChangeTime = cpu_to_le64(0);
1936         rsp->AllocationSize = cpu_to_le64(0);
1937         rsp->EndofFile = cpu_to_le64(0);
1938         rsp->FileAttributes = ATTR_NORMAL_LE;
1939         rsp->Reserved2 = 0;
1940         rsp->VolatileFileId = cpu_to_le64(id);
1941         rsp->PersistentFileId = 0;
1942         rsp->CreateContextsOffset = 0;
1943         rsp->CreateContextsLength = 0;
1944
1945         inc_rfc1001_len(rsp, 88); /* StructureSize - 1*/
1946         kfree(name);
1947         return 0;
1948
1949 out:
1950         switch (err) {
1951         case -EINVAL:
1952                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1953                 break;
1954         case -ENOSPC:
1955         case -ENOMEM:
1956                 rsp->hdr.Status = STATUS_NO_MEMORY;
1957                 break;
1958         }
1959
1960         if (!IS_ERR(name))
1961                 kfree(name);
1962
1963         smb2_set_err_rsp(work);
1964         return err;
1965 }
1966
1967 /**
1968  * smb2_set_ea() - handler for setting extended attributes using set
1969  *              info command
1970  * @eabuf:      set info command buffer
1971  * @path:       dentry path for get ea
1972  *
1973  * Return:      0 on success, otherwise error
1974  */
1975 static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
1976 {
1977         char *attr_name = NULL, *value;
1978         int rc = 0;
1979         int next = 0;
1980
1981         attr_name = kmalloc(XATTR_NAME_MAX + 1, GFP_KERNEL);
1982         if (!attr_name)
1983                 return -ENOMEM;
1984
1985         do {
1986                 if (!eabuf->EaNameLength)
1987                         goto next;
1988
1989                 ksmbd_debug(SMB,
1990                         "name : <%s>, name_len : %u, value_len : %u, next : %u\n",
1991                                 eabuf->name, eabuf->EaNameLength,
1992                                 le16_to_cpu(eabuf->EaValueLength),
1993                                 le32_to_cpu(eabuf->NextEntryOffset));
1994
1995                 if (eabuf->EaNameLength >
1996                                 (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
1997                         rc = -EINVAL;
1998                         break;
1999                 }
2000
2001                 memcpy(attr_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
2002                 memcpy(&attr_name[XATTR_USER_PREFIX_LEN], eabuf->name,
2003                                 eabuf->EaNameLength);
2004                 attr_name[XATTR_USER_PREFIX_LEN + eabuf->EaNameLength] = '\0';
2005                 value = (char *)&eabuf->name + eabuf->EaNameLength + 1;
2006
2007                 if (!eabuf->EaValueLength) {
2008                         rc = ksmbd_vfs_casexattr_len(path->dentry,
2009                                                      attr_name,
2010                                                      XATTR_USER_PREFIX_LEN +
2011                                                      eabuf->EaNameLength);
2012
2013                         /* delete the EA only when it exits */
2014                         if (rc > 0) {
2015                                 rc = ksmbd_vfs_remove_xattr(path->dentry,
2016                                                             attr_name);
2017
2018                                 if (rc < 0) {
2019                                         ksmbd_debug(SMB,
2020                                                 "remove xattr failed(%d)\n",
2021                                                 rc);
2022                                         break;
2023                                 }
2024                         }
2025
2026                         /* if the EA doesn't exist, just do nothing. */
2027                         rc = 0;
2028                 } else {
2029                         rc = ksmbd_vfs_setxattr(path->dentry, attr_name, value,
2030                                         le16_to_cpu(eabuf->EaValueLength), 0);
2031                         if (rc < 0) {
2032                                 ksmbd_debug(SMB,
2033                                         "ksmbd_vfs_setxattr is failed(%d)\n",
2034                                         rc);
2035                                 break;
2036                         }
2037                 }
2038
2039 next:
2040                 next = le32_to_cpu(eabuf->NextEntryOffset);
2041                 eabuf = (struct smb2_ea_info *)((char *)eabuf + next);
2042         } while (next != 0);
2043
2044         kfree(attr_name);
2045         return rc;
2046 }
2047
2048 static inline int check_context_err(void *ctx, char *str)
2049 {
2050         int err;
2051
2052         err = PTR_ERR(ctx);
2053         ksmbd_debug(SMB, "find context %s err %d\n", str, err);
2054
2055         if (err == -EINVAL) {
2056                 ksmbd_err("bad name length\n");
2057                 return err;
2058         }
2059
2060         return 0;
2061 }
2062
2063 static noinline int smb2_set_stream_name_xattr(struct path *path,
2064                 struct ksmbd_file *fp, char *stream_name, int s_type)
2065 {
2066         size_t xattr_stream_size;
2067         char *xattr_stream_name;
2068         int rc;
2069
2070         rc = ksmbd_vfs_xattr_stream_name(stream_name,
2071                                          &xattr_stream_name,
2072                                          &xattr_stream_size,
2073                                          s_type);
2074         if (rc)
2075                 return rc;
2076
2077         fp->stream.name = xattr_stream_name;
2078         fp->stream.size = xattr_stream_size;
2079
2080         /* Check if there is stream prefix in xattr space */
2081         rc = ksmbd_vfs_casexattr_len(path->dentry,
2082                                      xattr_stream_name,
2083                                      xattr_stream_size);
2084         if (rc >= 0)
2085                 return 0;
2086
2087         if (fp->cdoption == FILE_OPEN_LE) {
2088                 ksmbd_debug(SMB, "XATTR stream name lookup failed: %d\n", rc);
2089                 return -EBADF;
2090         }
2091
2092         rc = ksmbd_vfs_setxattr(path->dentry, xattr_stream_name, NULL, 0, 0);
2093         if (rc < 0)
2094                 ksmbd_err("Failed to store XATTR stream name :%d\n", rc);
2095         return 0;
2096 }
2097
2098 static int smb2_remove_smb_xattrs(struct dentry *dentry)
2099 {
2100         char *name, *xattr_list = NULL;
2101         ssize_t xattr_list_len;
2102         int err = 0;
2103
2104         xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
2105         if (xattr_list_len < 0) {
2106                 goto out;
2107         } else if (!xattr_list_len) {
2108                 ksmbd_debug(SMB, "empty xattr in the file\n");
2109                 goto out;
2110         }
2111
2112         for (name = xattr_list; name - xattr_list < xattr_list_len;
2113                         name += strlen(name) + 1) {
2114                 ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
2115
2116                 if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
2117                     strncmp(&name[XATTR_USER_PREFIX_LEN], DOS_ATTRIBUTE_PREFIX,
2118                             DOS_ATTRIBUTE_PREFIX_LEN) &&
2119                     strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN))
2120                         continue;
2121
2122                 err = ksmbd_vfs_remove_xattr(dentry, name);
2123                 if (err)
2124                         ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
2125         }
2126 out:
2127         kvfree(xattr_list);
2128         return err;
2129 }
2130
2131 static int smb2_create_truncate(struct path *path)
2132 {
2133         int rc = vfs_truncate(path, 0);
2134
2135         if (rc) {
2136                 ksmbd_err("vfs_truncate failed, rc %d\n", rc);
2137                 return rc;
2138         }
2139
2140         rc = smb2_remove_smb_xattrs(path->dentry);
2141         if (rc == -EOPNOTSUPP)
2142                 rc = 0;
2143         if (rc)
2144                 ksmbd_debug(SMB,
2145                         "ksmbd_truncate_stream_name_xattr failed, rc %d\n",
2146                                 rc);
2147         return rc;
2148 }
2149
2150 static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path,
2151                 struct ksmbd_file *fp)
2152 {
2153         struct xattr_dos_attrib da = {0};
2154         int rc;
2155
2156         if (!test_share_config_flag(tcon->share_conf,
2157                                     KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
2158                 return;
2159
2160         da.version = 4;
2161         da.attr = le32_to_cpu(fp->f_ci->m_fattr);
2162         da.itime = da.create_time = fp->create_time;
2163         da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
2164                 XATTR_DOSINFO_ITIME;
2165
2166         rc = ksmbd_vfs_set_dos_attrib_xattr(path->dentry, &da);
2167         if (rc)
2168                 ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
2169 }
2170
2171 static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
2172                 struct path *path, struct ksmbd_file *fp)
2173 {
2174         struct xattr_dos_attrib da;
2175         int rc;
2176
2177         fp->f_ci->m_fattr &= ~(ATTR_HIDDEN_LE | ATTR_SYSTEM_LE);
2178
2179         /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
2180         if (!test_share_config_flag(tcon->share_conf,
2181                                     KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
2182                 return;
2183
2184         rc = ksmbd_vfs_get_dos_attrib_xattr(path->dentry, &da);
2185         if (rc > 0) {
2186                 fp->f_ci->m_fattr = cpu_to_le32(da.attr);
2187                 fp->create_time = da.create_time;
2188                 fp->itime = da.itime;
2189         }
2190 }
2191
2192 static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
2193                 int open_flags, umode_t posix_mode, bool is_dir)
2194 {
2195         struct ksmbd_tree_connect *tcon = work->tcon;
2196         struct ksmbd_share_config *share = tcon->share_conf;
2197         umode_t mode;
2198         int rc;
2199
2200         if (!(open_flags & O_CREAT))
2201                 return -EBADF;
2202
2203         ksmbd_debug(SMB, "file does not exist, so creating\n");
2204         if (is_dir == true) {
2205                 ksmbd_debug(SMB, "creating directory\n");
2206
2207                 mode = share_config_directory_mode(share, posix_mode);
2208                 rc = ksmbd_vfs_mkdir(work, name, mode);
2209                 if (rc)
2210                         return rc;
2211         } else {
2212                 ksmbd_debug(SMB, "creating regular file\n");
2213
2214                 mode = share_config_create_mode(share, posix_mode);
2215                 rc = ksmbd_vfs_create(work, name, mode);
2216                 if (rc)
2217                         return rc;
2218         }
2219
2220         rc = ksmbd_vfs_kern_path(name, 0, path, 0);
2221         if (rc) {
2222                 ksmbd_err("cannot get linux path (%s), err = %d\n",
2223                                 name, rc);
2224                 return rc;
2225         }
2226         return 0;
2227 }
2228
2229 static int smb2_create_sd_buffer(struct ksmbd_work *work,
2230                 struct smb2_create_req *req, struct dentry *dentry)
2231 {
2232         struct create_context *context;
2233         int rc = -ENOENT;
2234
2235         if (!req->CreateContextsOffset)
2236                 return rc;
2237
2238         /* Parse SD BUFFER create contexts */
2239         context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER);
2240         if (context && !IS_ERR(context)) {
2241                 struct create_sd_buf_req *sd_buf;
2242
2243                 ksmbd_debug(SMB,
2244                         "Set ACLs using SMB2_CREATE_SD_BUFFER context\n");
2245                 sd_buf = (struct create_sd_buf_req *)context;
2246                 rc = set_info_sec(work->conn, work->tcon, dentry, &sd_buf->ntsd,
2247                         le32_to_cpu(sd_buf->ccontext.DataLength), true);
2248         }
2249
2250         return rc;
2251 }
2252
2253 static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode)
2254 {
2255         fattr->cf_uid = inode->i_uid;
2256         fattr->cf_gid = inode->i_gid;
2257         fattr->cf_mode = inode->i_mode;
2258         fattr->cf_dacls = NULL;
2259
2260         fattr->cf_acls = ksmbd_vfs_get_acl(inode, ACL_TYPE_ACCESS);
2261         if (S_ISDIR(inode->i_mode))
2262                 fattr->cf_dacls = ksmbd_vfs_get_acl(inode, ACL_TYPE_DEFAULT);
2263 }
2264
2265 /**
2266  * smb2_open() - handler for smb file open request
2267  * @work:       smb work containing request buffer
2268  *
2269  * Return:      0 on success, otherwise error
2270  */
2271 int smb2_open(struct ksmbd_work *work)
2272 {
2273         struct ksmbd_conn *conn = work->conn;
2274         struct ksmbd_session *sess = work->sess;
2275         struct ksmbd_tree_connect *tcon = work->tcon;
2276         struct smb2_create_req *req;
2277         struct smb2_create_rsp *rsp, *rsp_org;
2278         struct path path;
2279         struct ksmbd_share_config *share = tcon->share_conf;
2280         struct ksmbd_file *fp = NULL;
2281         struct file *filp = NULL;
2282         struct kstat stat;
2283         struct create_context *context;
2284         struct lease_ctx_info *lc = NULL;
2285         struct create_ea_buf_req *ea_buf = NULL;
2286         struct oplock_info *opinfo;
2287         __le32 *next_ptr = NULL;
2288         int req_op_level = 0, open_flags = 0, file_info = 0;
2289         int rc = 0, len = 0;
2290         int contxt_cnt = 0, query_disk_id = 0;
2291         int maximal_access_ctxt = 0, posix_ctxt = 0;
2292         int s_type = 0;
2293         int next_off = 0;
2294         char *name = NULL;
2295         char *stream_name = NULL;
2296         bool file_present = false, created = false, already_permitted = false;
2297         int share_ret, need_truncate = 0;
2298         u64 time;
2299         umode_t posix_mode = 0;
2300         __le32 daccess, maximal_access = 0;
2301
2302         rsp_org = work->response_buf;
2303         WORK_BUFFERS(work, req, rsp);
2304
2305         if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
2306             (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
2307                 ksmbd_debug(SMB, "invalid flag in chained command\n");
2308                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
2309                 smb2_set_err_rsp(work);
2310                 return -EINVAL;
2311         }
2312
2313         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
2314                 ksmbd_debug(SMB, "IPC pipe create request\n");
2315                 return create_smb2_pipe(work);
2316         }
2317
2318         if (req->NameLength) {
2319                 if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
2320                     *(char *)req->Buffer == '\\') {
2321                         ksmbd_err("not allow directory name included leading slash\n");
2322                         rc = -EINVAL;
2323                         goto err_out1;
2324                 }
2325
2326                 name = smb2_get_name(share,
2327                                      req->Buffer,
2328                                      le16_to_cpu(req->NameLength),
2329                                      work->conn->local_nls);
2330                 if (IS_ERR(name)) {
2331                         rc = PTR_ERR(name);
2332                         if (rc != -ENOMEM)
2333                                 rc = -ENOENT;
2334                         goto err_out1;
2335                 }
2336
2337                 ksmbd_debug(SMB, "converted name = %s\n", name);
2338                 if (strchr(name, ':')) {
2339                         if (!test_share_config_flag(work->tcon->share_conf,
2340                                                     KSMBD_SHARE_FLAG_STREAMS)) {
2341                                 rc = -EBADF;
2342                                 goto err_out1;
2343                         }
2344                         rc = parse_stream_name(name, &stream_name, &s_type);
2345                         if (rc < 0)
2346                                 goto err_out1;
2347                 }
2348
2349                 rc = ksmbd_validate_filename(name);
2350                 if (rc < 0)
2351                         goto err_out1;
2352
2353                 if (ksmbd_share_veto_filename(share, name)) {
2354                         rc = -ENOENT;
2355                         ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n",
2356                                 name);
2357                         goto err_out1;
2358                 }
2359         } else {
2360                 len = strlen(share->path);
2361                 ksmbd_debug(SMB, "share path len %d\n", len);
2362                 name = kmalloc(len + 1, GFP_KERNEL);
2363                 if (!name) {
2364                         rsp->hdr.Status = STATUS_NO_MEMORY;
2365                         rc = -ENOMEM;
2366                         goto err_out1;
2367                 }
2368
2369                 memcpy(name, share->path, len);
2370                 *(name + len) = '\0';
2371         }
2372
2373         req_op_level = req->RequestedOplockLevel;
2374         if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE)
2375                 lc = parse_lease_state(req);
2376
2377         if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) {
2378                 ksmbd_err("Invalid impersonationlevel : 0x%x\n",
2379                         le32_to_cpu(req->ImpersonationLevel));
2380                 rc = -EIO;
2381                 rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL;
2382                 goto err_out1;
2383         }
2384
2385         if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK)) {
2386                 ksmbd_err("Invalid create options : 0x%x\n",
2387                         le32_to_cpu(req->CreateOptions));
2388                 rc = -EINVAL;
2389                 goto err_out1;
2390         } else {
2391
2392                 if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
2393                     req->CreateOptions & FILE_RANDOM_ACCESS_LE)
2394                         req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
2395
2396                 if (req->CreateOptions & (FILE_OPEN_BY_FILE_ID_LE |
2397                         CREATE_TREE_CONNECTION | FILE_RESERVE_OPFILTER_LE)) {
2398                         rc = -EOPNOTSUPP;
2399                         goto err_out1;
2400                 }
2401
2402                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
2403                         if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) {
2404                                 rc = -EINVAL;
2405                                 goto err_out1;
2406                         } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) {
2407                                 req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
2408                         }
2409                 }
2410         }
2411
2412         if (le32_to_cpu(req->CreateDisposition) >
2413                         le32_to_cpu(FILE_OVERWRITE_IF_LE)) {
2414                 ksmbd_err("Invalid create disposition : 0x%x\n",
2415                         le32_to_cpu(req->CreateDisposition));
2416                 rc = -EINVAL;
2417                 goto err_out1;
2418         }
2419
2420         if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) {
2421                 ksmbd_err("Invalid desired access : 0x%x\n",
2422                         le32_to_cpu(req->DesiredAccess));
2423                 rc = -EACCES;
2424                 goto err_out1;
2425         }
2426
2427         if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) {
2428                 ksmbd_err("Invalid file attribute : 0x%x\n",
2429                         le32_to_cpu(req->FileAttributes));
2430                 rc = -EINVAL;
2431                 goto err_out1;
2432         }
2433
2434         if (req->CreateContextsOffset) {
2435                 /* Parse non-durable handle create contexts */
2436                 context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER);
2437                 if (IS_ERR(context)) {
2438                         rc = check_context_err(context, SMB2_CREATE_EA_BUFFER);
2439                         if (rc < 0)
2440                                 goto err_out1;
2441                 } else {
2442                         ea_buf = (struct create_ea_buf_req *)context;
2443                         if (req->CreateOptions & FILE_NO_EA_KNOWLEDGE_LE) {
2444                                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
2445                                 rc = -EACCES;
2446                                 goto err_out1;
2447                         }
2448                 }
2449
2450                 context = smb2_find_context_vals(req,
2451                                 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
2452                 if (IS_ERR(context)) {
2453                         rc = check_context_err(context,
2454                                 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
2455                         if (rc < 0)
2456                                 goto err_out1;
2457                 } else {
2458                         ksmbd_debug(SMB,
2459                                 "get query maximal access context\n");
2460                         maximal_access_ctxt = 1;
2461                 }
2462
2463                 context = smb2_find_context_vals(req,
2464                                 SMB2_CREATE_TIMEWARP_REQUEST);
2465                 if (IS_ERR(context)) {
2466                         rc = check_context_err(context,
2467                                 SMB2_CREATE_TIMEWARP_REQUEST);
2468                         if (rc < 0)
2469                                 goto err_out1;
2470                 } else {
2471                         ksmbd_debug(SMB, "get timewarp context\n");
2472                         rc = -EBADF;
2473                         goto err_out1;
2474                 }
2475
2476                 if (tcon->posix_extensions) {
2477                         context = smb2_find_context_vals(req,
2478                                 SMB2_CREATE_TAG_POSIX);
2479                         if (IS_ERR(context)) {
2480                                 rc = check_context_err(context,
2481                                                 SMB2_CREATE_TAG_POSIX);
2482                                 if (rc < 0)
2483                                         goto err_out1;
2484                         } else {
2485                                 struct create_posix *posix =
2486                                         (struct create_posix *)context;
2487                                 ksmbd_debug(SMB, "get posix context\n");
2488
2489                                 posix_mode = le32_to_cpu(posix->Mode);
2490                                 posix_ctxt = 1;
2491                         }
2492                 }
2493         }
2494
2495         if (ksmbd_override_fsids(work)) {
2496                 rc = -ENOMEM;
2497                 goto err_out1;
2498         }
2499
2500         if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
2501                 /*
2502                  * On delete request, instead of following up, need to
2503                  * look the current entity
2504                  */
2505                 rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2506                 if (!rc) {
2507                         /*
2508                          * If file exists with under flags, return access
2509                          * denied error.
2510                          */
2511                         if (req->CreateDisposition == FILE_OVERWRITE_IF_LE ||
2512                             req->CreateDisposition == FILE_OPEN_IF_LE) {
2513                                 rc = -EACCES;
2514                                 path_put(&path);
2515                                 goto err_out;
2516                         }
2517
2518                         if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2519                                 ksmbd_debug(SMB,
2520                                         "User does not have write permission\n");
2521                                 rc = -EACCES;
2522                                 path_put(&path);
2523                                 goto err_out;
2524                         }
2525                 }
2526         } else {
2527                 if (test_share_config_flag(work->tcon->share_conf,
2528                                            KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) {
2529                         /*
2530                          * Use LOOKUP_FOLLOW to follow the path of
2531                          * symlink in path buildup
2532                          */
2533                         rc = ksmbd_vfs_kern_path(name, LOOKUP_FOLLOW, &path, 1);
2534                         if (rc) { /* Case for broken link ?*/
2535                                 rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2536                         }
2537                 } else {
2538                         rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2539                         if (!rc && d_is_symlink(path.dentry)) {
2540                                 rc = -EACCES;
2541                                 path_put(&path);
2542                                 goto err_out;
2543                         }
2544                 }
2545         }
2546
2547         if (rc) {
2548                 if (rc == -EACCES) {
2549                         ksmbd_debug(SMB,
2550                                 "User does not have right permission\n");
2551                         goto err_out;
2552                 }
2553                 ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n",
2554                                 name, rc);
2555                 rc = 0;
2556         } else {
2557                 file_present = true;
2558                 generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
2559         }
2560         if (stream_name) {
2561                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
2562                         if (s_type == DATA_STREAM) {
2563                                 rc = -EIO;
2564                                 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2565                         }
2566                 } else {
2567                         if (S_ISDIR(stat.mode) && s_type == DATA_STREAM) {
2568                                 rc = -EIO;
2569                                 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
2570                         }
2571                 }
2572
2573                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE &&
2574                     req->FileAttributes & ATTR_NORMAL_LE) {
2575                         rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2576                         rc = -EIO;
2577                 }
2578
2579                 if (rc < 0)
2580                         goto err_out;
2581         }
2582
2583         if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE &&
2584             S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
2585                 ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n",
2586                               name, req->CreateOptions);
2587                 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
2588                 rc = -EIO;
2589                 goto err_out;
2590         }
2591
2592         if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
2593             !(req->CreateDisposition == FILE_CREATE_LE) &&
2594             !S_ISDIR(stat.mode)) {
2595                 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2596                 rc = -EIO;
2597                 goto err_out;
2598         }
2599
2600         if (!stream_name && file_present &&
2601             req->CreateDisposition == FILE_CREATE_LE) {
2602                 rc = -EEXIST;
2603                 goto err_out;
2604         }
2605
2606         daccess = smb_map_generic_desired_access(req->DesiredAccess);
2607
2608         if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
2609                 rc = smb_check_perm_dacl(conn, path.dentry, &daccess,
2610                                 sess->user->uid);
2611                 if (rc)
2612                         goto err_out;
2613         }
2614
2615         if (daccess & FILE_MAXIMAL_ACCESS_LE) {
2616                 if (!file_present) {
2617                         daccess = cpu_to_le32(GENERIC_ALL_FLAGS);
2618                 } else {
2619                         rc = ksmbd_vfs_query_maximal_access(path.dentry,
2620                                                             &daccess);
2621                         if (rc)
2622                                 goto err_out;
2623                         already_permitted = true;
2624                 }
2625                 maximal_access = daccess;
2626         }
2627
2628         open_flags = smb2_create_open_flags(file_present,
2629                 daccess, req->CreateDisposition);
2630
2631         if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2632                 if (open_flags & O_CREAT) {
2633                         ksmbd_debug(SMB,
2634                                 "User does not have write permission\n");
2635                         rc = -EACCES;
2636                         goto err_out;
2637                 }
2638         }
2639
2640         /*create file if not present */
2641         if (!file_present) {
2642                 rc = smb2_creat(work, &path, name, open_flags, posix_mode,
2643                         req->CreateOptions & FILE_DIRECTORY_FILE_LE);
2644                 if (rc)
2645                         goto err_out;
2646
2647                 created = true;
2648                 if (ea_buf) {
2649                         rc = smb2_set_ea(&ea_buf->ea, &path);
2650                         if (rc == -EOPNOTSUPP)
2651                                 rc = 0;
2652                         else if (rc)
2653                                 goto err_out;
2654                 }
2655         } else if (!already_permitted) {
2656                 bool may_delete;
2657
2658                 may_delete = daccess & FILE_DELETE_LE ||
2659                         req->CreateOptions & FILE_DELETE_ON_CLOSE_LE;
2660
2661                 /* FILE_READ_ATTRIBUTE is allowed without inode_permission,
2662                  * because execute(search) permission on a parent directory,
2663                  * is already granted.
2664                  */
2665                 if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
2666                         rc = ksmbd_vfs_inode_permission(path.dentry,
2667                                         open_flags & O_ACCMODE, may_delete);
2668                         if (rc)
2669                                 goto err_out;
2670                 }
2671         }
2672
2673         rc = ksmbd_query_inode_status(d_inode(path.dentry->d_parent));
2674         if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) {
2675                 rc = -EBUSY;
2676                 goto err_out;
2677         }
2678
2679         rc = 0;
2680         filp = dentry_open(&path, open_flags, current_cred());
2681         if (IS_ERR(filp)) {
2682                 rc = PTR_ERR(filp);
2683                 ksmbd_err("dentry open for dir failed, rc %d\n", rc);
2684                 goto err_out;
2685         }
2686
2687         if (file_present) {
2688                 if (!(open_flags & O_TRUNC))
2689                         file_info = FILE_OPENED;
2690                 else
2691                         file_info = FILE_OVERWRITTEN;
2692
2693                 if ((req->CreateDisposition & FILE_CREATE_MASK_LE)
2694                                 == FILE_SUPERSEDE_LE)
2695                         file_info = FILE_SUPERSEDED;
2696         } else if (open_flags & O_CREAT) {
2697                 file_info = FILE_CREATED;
2698         }
2699
2700         ksmbd_vfs_set_fadvise(filp, req->CreateOptions);
2701
2702         /* Obtain Volatile-ID */
2703         fp = ksmbd_open_fd(work, filp);
2704         if (IS_ERR(fp)) {
2705                 fput(filp);
2706                 rc = PTR_ERR(fp);
2707                 fp = NULL;
2708                 goto err_out;
2709         }
2710
2711         /* Get Persistent-ID */
2712         ksmbd_open_durable_fd(fp);
2713         if (!HAS_FILE_ID(fp->persistent_id)) {
2714                 rc = -ENOMEM;
2715                 goto err_out;
2716         }
2717
2718         fp->filename = name;
2719         fp->cdoption = req->CreateDisposition;
2720         fp->daccess = daccess;
2721         fp->saccess = req->ShareAccess;
2722         fp->coption = req->CreateOptions;
2723
2724         /* Set default windows and posix acls if creating new file */
2725         if (created) {
2726                 int posix_acl_rc;
2727                 struct inode *inode = d_inode(path.dentry);
2728
2729                 posix_acl_rc = ksmbd_vfs_inherit_posix_acl(inode, d_inode(path.dentry->d_parent));
2730                 if (posix_acl_rc)
2731                         ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
2732
2733                 if (test_share_config_flag(work->tcon->share_conf,
2734                                            KSMBD_SHARE_FLAG_ACL_XATTR)) {
2735                         rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid,
2736                                         sess->user->gid);
2737                 }
2738
2739                 if (rc) {
2740                         rc = smb2_create_sd_buffer(work, req, path.dentry);
2741                         if (rc) {
2742                                 if (posix_acl_rc)
2743                                         ksmbd_vfs_set_init_posix_acl(inode);
2744
2745                                 if (test_share_config_flag(work->tcon->share_conf,
2746                                                            KSMBD_SHARE_FLAG_ACL_XATTR)) {
2747                                         struct smb_fattr fattr;
2748                                         struct smb_ntsd *pntsd;
2749                                         int pntsd_size, ace_num = 0;
2750
2751                                         ksmbd_acls_fattr(&fattr, inode);
2752                                         if (fattr.cf_acls)
2753                                                 ace_num = fattr.cf_acls->a_count;
2754                                         if (fattr.cf_dacls)
2755                                                 ace_num += fattr.cf_dacls->a_count;
2756
2757                                         pntsd = kmalloc(sizeof(struct smb_ntsd) +
2758                                                         sizeof(struct smb_sid) * 3 +
2759                                                         sizeof(struct smb_acl) +
2760                                                         sizeof(struct smb_ace) * ace_num * 2,
2761                                                         GFP_KERNEL);
2762                                         if (!pntsd)
2763                                                 goto err_out;
2764
2765                                         rc = build_sec_desc(pntsd, NULL,
2766                                                 OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO,
2767                                                 &pntsd_size, &fattr);
2768                                         posix_acl_release(fattr.cf_acls);
2769                                         posix_acl_release(fattr.cf_dacls);
2770
2771                                         rc = ksmbd_vfs_set_sd_xattr(conn,
2772                                                 path.dentry, pntsd, pntsd_size);
2773                                         kfree(pntsd);
2774                                         if (rc)
2775                                                 ksmbd_err("failed to store ntacl in xattr : %d\n",
2776                                                                 rc);
2777                                 }
2778                         }
2779                 }
2780                 rc = 0;
2781         }
2782
2783         if (stream_name) {
2784                 rc = smb2_set_stream_name_xattr(&path,
2785                                                 fp,
2786                                                 stream_name,
2787                                                 s_type);
2788                 if (rc)
2789                         goto err_out;
2790                 file_info = FILE_CREATED;
2791         }
2792
2793         fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
2794                         FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
2795         if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC &&
2796             !fp->attrib_only && !stream_name) {
2797                 smb_break_all_oplock(work, fp);
2798                 need_truncate = 1;
2799         }
2800
2801         /* fp should be searchable through ksmbd_inode.m_fp_list
2802          * after daccess, saccess, attrib_only, and stream are
2803          * initialized.
2804          */
2805         write_lock(&fp->f_ci->m_lock);
2806         list_add(&fp->node, &fp->f_ci->m_fp_list);
2807         write_unlock(&fp->f_ci->m_lock);
2808
2809         rc = ksmbd_vfs_getattr(&path, &stat);
2810         if (rc) {
2811                 generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
2812                 rc = 0;
2813         }
2814
2815         /* Check delete pending among previous fp before oplock break */
2816         if (ksmbd_inode_pending_delete(fp)) {
2817                 rc = -EBUSY;
2818                 goto err_out;
2819         }
2820
2821         share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp);
2822         if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) ||
2823             (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
2824              !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) {
2825                 if (share_ret < 0 && !S_ISDIR(FP_INODE(fp)->i_mode)) {
2826                         rc = share_ret;
2827                         goto err_out;
2828                 }
2829         } else {
2830                 if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) {
2831                         req_op_level = smb2_map_lease_to_oplock(lc->req_state);
2832                         ksmbd_debug(SMB,
2833                                 "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
2834                                         name, req_op_level, lc->req_state);
2835                         rc = find_same_lease_key(sess, fp->f_ci, lc);
2836                         if (rc)
2837                                 goto err_out;
2838                 } else if (open_flags == O_RDONLY &&
2839                            (req_op_level == SMB2_OPLOCK_LEVEL_BATCH ||
2840                             req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
2841                         req_op_level = SMB2_OPLOCK_LEVEL_II;
2842
2843                 rc = smb_grant_oplock(work, req_op_level,
2844                                       fp->persistent_id, fp,
2845                                       le32_to_cpu(req->hdr.Id.SyncId.TreeId),
2846                                       lc, share_ret);
2847                 if (rc < 0)
2848                         goto err_out;
2849         }
2850
2851         if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)
2852                 ksmbd_fd_set_delete_on_close(fp, file_info);
2853
2854         if (need_truncate) {
2855                 rc = smb2_create_truncate(&path);
2856                 if (rc)
2857                         goto err_out;
2858         }
2859
2860         if (req->CreateContextsOffset) {
2861                 struct create_alloc_size_req *az_req;
2862
2863                 az_req = (struct create_alloc_size_req *)
2864                                 smb2_find_context_vals(req,
2865                                 SMB2_CREATE_ALLOCATION_SIZE);
2866                 if (IS_ERR(az_req)) {
2867                         rc = check_context_err(az_req,
2868                                 SMB2_CREATE_ALLOCATION_SIZE);
2869                         if (rc < 0)
2870                                 goto err_out;
2871                 } else {
2872                         loff_t alloc_size = le64_to_cpu(az_req->AllocationSize);
2873                         int err;
2874
2875                         ksmbd_debug(SMB,
2876                                 "request smb2 create allocate size : %llu\n",
2877                                 alloc_size);
2878                         err = ksmbd_vfs_alloc_size(work, fp, alloc_size);
2879                         if (err < 0)
2880                                 ksmbd_debug(SMB,
2881                                         "ksmbd_vfs_alloc_size is failed : %d\n",
2882                                         err);
2883                 }
2884
2885                 context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
2886                 if (IS_ERR(context)) {
2887                         rc = check_context_err(context, SMB2_CREATE_QUERY_ON_DISK_ID);
2888                         if (rc < 0)
2889                                 goto err_out;
2890                 } else {
2891                         ksmbd_debug(SMB, "get query on disk id context\n");
2892                         query_disk_id = 1;
2893                 }
2894         }
2895
2896         if (stat.result_mask & STATX_BTIME)
2897                 fp->create_time = ksmbd_UnixTimeToNT(stat.btime);
2898         else
2899                 fp->create_time = ksmbd_UnixTimeToNT(stat.ctime);
2900         if (req->FileAttributes || fp->f_ci->m_fattr == 0)
2901                 fp->f_ci->m_fattr = cpu_to_le32(smb2_get_dos_mode(&stat,
2902                         le32_to_cpu(req->FileAttributes)));
2903
2904         if (!created)
2905                 smb2_update_xattrs(tcon, &path, fp);
2906         else
2907                 smb2_new_xattrs(tcon, &path, fp);
2908
2909         memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
2910
2911         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
2912
2913         rsp->StructureSize = cpu_to_le16(89);
2914         rcu_read_lock();
2915         opinfo = rcu_dereference(fp->f_opinfo);
2916         rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0;
2917         rcu_read_unlock();
2918         rsp->Reserved = 0;
2919         rsp->CreateAction = cpu_to_le32(file_info);
2920         rsp->CreationTime = cpu_to_le64(fp->create_time);
2921         time = ksmbd_UnixTimeToNT(stat.atime);
2922         rsp->LastAccessTime = cpu_to_le64(time);
2923         time = ksmbd_UnixTimeToNT(stat.mtime);
2924         rsp->LastWriteTime = cpu_to_le64(time);
2925         time = ksmbd_UnixTimeToNT(stat.ctime);
2926         rsp->ChangeTime = cpu_to_le64(time);
2927         rsp->AllocationSize = S_ISDIR(stat.mode) ? 0 :
2928                 cpu_to_le64(stat.blocks << 9);
2929         rsp->EndofFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
2930         rsp->FileAttributes = fp->f_ci->m_fattr;
2931
2932         rsp->Reserved2 = 0;
2933
2934         rsp->PersistentFileId = cpu_to_le64(fp->persistent_id);
2935         rsp->VolatileFileId = cpu_to_le64(fp->volatile_id);
2936
2937         rsp->CreateContextsOffset = 0;
2938         rsp->CreateContextsLength = 0;
2939         inc_rfc1001_len(rsp_org, 88); /* StructureSize - 1*/
2940
2941         /* If lease is request send lease context response */
2942         if (opinfo && opinfo->is_lease) {
2943                 struct create_context *lease_ccontext;
2944
2945                 ksmbd_debug(SMB, "lease granted on(%s) lease state 0x%x\n",
2946                                 name, opinfo->o_lease->state);
2947                 rsp->OplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
2948
2949                 lease_ccontext = (struct create_context *)rsp->Buffer;
2950                 contxt_cnt++;
2951                 create_lease_buf(rsp->Buffer, opinfo->o_lease);
2952                 le32_add_cpu(&rsp->CreateContextsLength,
2953                              conn->vals->create_lease_size);
2954                 inc_rfc1001_len(rsp_org, conn->vals->create_lease_size);
2955                 next_ptr = &lease_ccontext->Next;
2956                 next_off = conn->vals->create_lease_size;
2957         }
2958
2959         if (maximal_access_ctxt) {
2960                 struct create_context *mxac_ccontext;
2961
2962                 if (maximal_access == 0)
2963                         ksmbd_vfs_query_maximal_access(path.dentry,
2964                                                        &maximal_access);
2965                 mxac_ccontext = (struct create_context *)(rsp->Buffer +
2966                                 le32_to_cpu(rsp->CreateContextsLength));
2967                 contxt_cnt++;
2968                 create_mxac_rsp_buf(rsp->Buffer +
2969                                 le32_to_cpu(rsp->CreateContextsLength),
2970                                 le32_to_cpu(maximal_access));
2971                 le32_add_cpu(&rsp->CreateContextsLength,
2972                              conn->vals->create_mxac_size);
2973                 inc_rfc1001_len(rsp_org, conn->vals->create_mxac_size);
2974                 if (next_ptr)
2975                         *next_ptr = cpu_to_le32(next_off);
2976                 next_ptr = &mxac_ccontext->Next;
2977                 next_off = conn->vals->create_mxac_size;
2978         }
2979
2980         if (query_disk_id) {
2981                 struct create_context *disk_id_ccontext;
2982
2983                 disk_id_ccontext = (struct create_context *)(rsp->Buffer +
2984                                 le32_to_cpu(rsp->CreateContextsLength));
2985                 contxt_cnt++;
2986                 create_disk_id_rsp_buf(rsp->Buffer +
2987                                 le32_to_cpu(rsp->CreateContextsLength),
2988                                 stat.ino, tcon->id);
2989                 le32_add_cpu(&rsp->CreateContextsLength,
2990                              conn->vals->create_disk_id_size);
2991                 inc_rfc1001_len(rsp_org, conn->vals->create_disk_id_size);
2992                 if (next_ptr)
2993                         *next_ptr = cpu_to_le32(next_off);
2994                 next_ptr = &disk_id_ccontext->Next;
2995                 next_off = conn->vals->create_disk_id_size;
2996         }
2997
2998         if (posix_ctxt) {
2999                 contxt_cnt++;
3000                 create_posix_rsp_buf(rsp->Buffer +
3001                                 le32_to_cpu(rsp->CreateContextsLength),
3002                                 fp);
3003                 le32_add_cpu(&rsp->CreateContextsLength,
3004                              conn->vals->create_posix_size);
3005                 inc_rfc1001_len(rsp_org, conn->vals->create_posix_size);
3006                 if (next_ptr)
3007                         *next_ptr = cpu_to_le32(next_off);
3008         }
3009
3010         if (contxt_cnt > 0) {
3011                 rsp->CreateContextsOffset =
3012                         cpu_to_le32(offsetof(struct smb2_create_rsp, Buffer)
3013                         - 4);
3014         }
3015
3016 err_out:
3017         if (file_present || created)
3018                 path_put(&path);
3019         ksmbd_revert_fsids(work);
3020 err_out1:
3021         if (rc) {
3022                 if (rc == -EINVAL)
3023                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
3024                 else if (rc == -EOPNOTSUPP)
3025                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
3026                 else if (rc == -EACCES || rc == -ESTALE)
3027                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
3028                 else if (rc == -ENOENT)
3029                         rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
3030                 else if (rc == -EPERM)
3031                         rsp->hdr.Status = STATUS_SHARING_VIOLATION;
3032                 else if (rc == -EBUSY)
3033                         rsp->hdr.Status = STATUS_DELETE_PENDING;
3034                 else if (rc == -EBADF)
3035                         rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
3036                 else if (rc == -ENOEXEC)
3037                         rsp->hdr.Status = STATUS_DUPLICATE_OBJECTID;
3038                 else if (rc == -ENXIO)
3039                         rsp->hdr.Status = STATUS_NO_SUCH_DEVICE;
3040                 else if (rc == -EEXIST)
3041                         rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
3042                 else if (rc == -EMFILE)
3043                         rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
3044                 if (!rsp->hdr.Status)
3045                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
3046
3047                 if (!fp || !fp->filename)
3048                         kfree(name);
3049                 if (fp)
3050                         ksmbd_fd_put(work, fp);
3051                 smb2_set_err_rsp(work);
3052                 ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
3053         }
3054
3055         kfree(lc);
3056
3057         return 0;
3058 }
3059
3060 static int readdir_info_level_struct_sz(int info_level)
3061 {
3062         switch (info_level) {
3063         case FILE_FULL_DIRECTORY_INFORMATION:
3064                 return sizeof(struct file_full_directory_info);
3065         case FILE_BOTH_DIRECTORY_INFORMATION:
3066                 return sizeof(struct file_both_directory_info);
3067         case FILE_DIRECTORY_INFORMATION:
3068                 return sizeof(struct file_directory_info);
3069         case FILE_NAMES_INFORMATION:
3070                 return sizeof(struct file_names_info);
3071         case FILEID_FULL_DIRECTORY_INFORMATION:
3072                 return sizeof(struct file_id_full_dir_info);
3073         case FILEID_BOTH_DIRECTORY_INFORMATION:
3074                 return sizeof(struct file_id_both_directory_info);
3075         case SMB_FIND_FILE_POSIX_INFO:
3076                 return sizeof(struct smb2_posix_info);
3077         default:
3078                 return -EOPNOTSUPP;
3079         }
3080 }
3081
3082 static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
3083 {
3084         switch (info_level) {
3085         case FILE_FULL_DIRECTORY_INFORMATION:
3086         {
3087                 struct file_full_directory_info *ffdinfo;
3088
3089                 ffdinfo = (struct file_full_directory_info *)d_info->rptr;
3090                 d_info->rptr += le32_to_cpu(ffdinfo->NextEntryOffset);
3091                 d_info->name = ffdinfo->FileName;
3092                 d_info->name_len = le32_to_cpu(ffdinfo->FileNameLength);
3093                 return 0;
3094         }
3095         case FILE_BOTH_DIRECTORY_INFORMATION:
3096         {
3097                 struct file_both_directory_info *fbdinfo;
3098
3099                 fbdinfo = (struct file_both_directory_info *)d_info->rptr;
3100                 d_info->rptr += le32_to_cpu(fbdinfo->NextEntryOffset);
3101                 d_info->name = fbdinfo->FileName;
3102                 d_info->name_len = le32_to_cpu(fbdinfo->FileNameLength);
3103                 return 0;
3104         }
3105         case FILE_DIRECTORY_INFORMATION:
3106         {
3107                 struct file_directory_info *fdinfo;
3108
3109                 fdinfo = (struct file_directory_info *)d_info->rptr;
3110                 d_info->rptr += le32_to_cpu(fdinfo->NextEntryOffset);
3111                 d_info->name = fdinfo->FileName;
3112                 d_info->name_len = le32_to_cpu(fdinfo->FileNameLength);
3113                 return 0;
3114         }
3115         case FILE_NAMES_INFORMATION:
3116         {
3117                 struct file_names_info *fninfo;
3118
3119                 fninfo = (struct file_names_info *)d_info->rptr;
3120                 d_info->rptr += le32_to_cpu(fninfo->NextEntryOffset);
3121                 d_info->name = fninfo->FileName;
3122                 d_info->name_len = le32_to_cpu(fninfo->FileNameLength);
3123                 return 0;
3124         }
3125         case FILEID_FULL_DIRECTORY_INFORMATION:
3126         {
3127                 struct file_id_full_dir_info *dinfo;
3128
3129                 dinfo = (struct file_id_full_dir_info *)d_info->rptr;
3130                 d_info->rptr += le32_to_cpu(dinfo->NextEntryOffset);
3131                 d_info->name = dinfo->FileName;
3132                 d_info->name_len = le32_to_cpu(dinfo->FileNameLength);
3133                 return 0;
3134         }
3135         case FILEID_BOTH_DIRECTORY_INFORMATION:
3136         {
3137                 struct file_id_both_directory_info *fibdinfo;
3138
3139                 fibdinfo = (struct file_id_both_directory_info *)d_info->rptr;
3140                 d_info->rptr += le32_to_cpu(fibdinfo->NextEntryOffset);
3141                 d_info->name = fibdinfo->FileName;
3142                 d_info->name_len = le32_to_cpu(fibdinfo->FileNameLength);
3143                 return 0;
3144         }
3145         case SMB_FIND_FILE_POSIX_INFO:
3146         {
3147                 struct smb2_posix_info *posix_info;
3148
3149                 posix_info = (struct smb2_posix_info *)d_info->rptr;
3150                 d_info->rptr += le32_to_cpu(posix_info->NextEntryOffset);
3151                 d_info->name = posix_info->name;
3152                 d_info->name_len = le32_to_cpu(posix_info->name_len);
3153                 return 0;
3154         }
3155         default:
3156                 return -EINVAL;
3157         }
3158 }
3159
3160 /**
3161  * smb2_populate_readdir_entry() - encode directory entry in smb2 response
3162  * buffer
3163  * @conn:       connection instance
3164  * @info_level: smb information level
3165  * @d_info:     structure included variables for query dir
3166  * @ksmbd_kstat:        ksmbd wrapper of dirent stat information
3167  *
3168  * if directory has many entries, find first can't read it fully.
3169  * find next might be called multiple times to read remaining dir entries
3170  *
3171  * Return:      0 on success, otherwise error
3172  */
3173 static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
3174                 struct ksmbd_dir_info *d_info, struct ksmbd_kstat *ksmbd_kstat)
3175 {
3176         int next_entry_offset = 0;
3177         char *conv_name;
3178         int conv_len;
3179         void *kstat;
3180         int struct_sz;
3181
3182         conv_name = ksmbd_convert_dir_info_name(d_info,
3183                                                 conn->local_nls,
3184                                                 &conv_len);
3185         if (!conv_name)
3186                 return -ENOMEM;
3187
3188         /* Somehow the name has only terminating NULL bytes */
3189         if (conv_len < 0) {
3190                 kfree(conv_name);
3191                 return -EINVAL;
3192         }
3193
3194         struct_sz = readdir_info_level_struct_sz(info_level);
3195         next_entry_offset = ALIGN(struct_sz - 1 + conv_len,
3196                                   KSMBD_DIR_INFO_ALIGNMENT);
3197
3198         if (next_entry_offset > d_info->out_buf_len) {
3199                 d_info->out_buf_len = 0;
3200                 return -ENOSPC;
3201         }
3202
3203         kstat = d_info->wptr;
3204         if (info_level != FILE_NAMES_INFORMATION)
3205                 kstat = ksmbd_vfs_init_kstat(&d_info->wptr, ksmbd_kstat);
3206
3207         switch (info_level) {
3208         case FILE_FULL_DIRECTORY_INFORMATION:
3209         {
3210                 struct file_full_directory_info *ffdinfo;
3211
3212                 ffdinfo = (struct file_full_directory_info *)kstat;
3213                 ffdinfo->FileNameLength = cpu_to_le32(conv_len);
3214                 ffdinfo->EaSize =
3215                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3216                 if (ffdinfo->EaSize)
3217                         ffdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3218                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3219                         ffdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3220                 memcpy(ffdinfo->FileName, conv_name, conv_len);
3221                 ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3222                 break;
3223         }
3224         case FILE_BOTH_DIRECTORY_INFORMATION:
3225         {
3226                 struct file_both_directory_info *fbdinfo;
3227
3228                 fbdinfo = (struct file_both_directory_info *)kstat;
3229                 fbdinfo->FileNameLength = cpu_to_le32(conv_len);
3230                 fbdinfo->EaSize =
3231                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3232                 if (fbdinfo->EaSize)
3233                         fbdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3234                 fbdinfo->ShortNameLength = 0;
3235                 fbdinfo->Reserved = 0;
3236                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3237                         fbdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3238                 memcpy(fbdinfo->FileName, conv_name, conv_len);
3239                 fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3240                 break;
3241         }
3242         case FILE_DIRECTORY_INFORMATION:
3243         {
3244                 struct file_directory_info *fdinfo;
3245
3246                 fdinfo = (struct file_directory_info *)kstat;
3247                 fdinfo->FileNameLength = cpu_to_le32(conv_len);
3248                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3249                         fdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3250                 memcpy(fdinfo->FileName, conv_name, conv_len);
3251                 fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3252                 break;
3253         }
3254         case FILE_NAMES_INFORMATION:
3255         {
3256                 struct file_names_info *fninfo;
3257
3258                 fninfo = (struct file_names_info *)kstat;
3259                 fninfo->FileNameLength = cpu_to_le32(conv_len);
3260                 memcpy(fninfo->FileName, conv_name, conv_len);
3261                 fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3262                 break;
3263         }
3264         case FILEID_FULL_DIRECTORY_INFORMATION:
3265         {
3266                 struct file_id_full_dir_info *dinfo;
3267
3268                 dinfo = (struct file_id_full_dir_info *)kstat;
3269                 dinfo->FileNameLength = cpu_to_le32(conv_len);
3270                 dinfo->EaSize =
3271                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3272                 if (dinfo->EaSize)
3273                         dinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3274                 dinfo->Reserved = 0;
3275                 dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
3276                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3277                         dinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3278                 memcpy(dinfo->FileName, conv_name, conv_len);
3279                 dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3280                 break;
3281         }
3282         case FILEID_BOTH_DIRECTORY_INFORMATION:
3283         {
3284                 struct file_id_both_directory_info *fibdinfo;
3285
3286                 fibdinfo = (struct file_id_both_directory_info *)kstat;
3287                 fibdinfo->FileNameLength = cpu_to_le32(conv_len);
3288                 fibdinfo->EaSize =
3289                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3290                 if (fibdinfo->EaSize)
3291                         fibdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3292                 fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
3293                 fibdinfo->ShortNameLength = 0;
3294                 fibdinfo->Reserved = 0;
3295                 fibdinfo->Reserved2 = cpu_to_le16(0);
3296                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3297                         fibdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3298                 memcpy(fibdinfo->FileName, conv_name, conv_len);
3299                 fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3300                 break;
3301         }
3302         case SMB_FIND_FILE_POSIX_INFO:
3303         {
3304                 struct smb2_posix_info *posix_info;
3305                 u64 time;
3306
3307                 posix_info = (struct smb2_posix_info *)kstat;
3308                 posix_info->Ignored = 0;
3309                 posix_info->CreationTime = cpu_to_le64(ksmbd_kstat->create_time);
3310                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
3311                 posix_info->ChangeTime = cpu_to_le64(time);
3312                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->atime);
3313                 posix_info->LastAccessTime = cpu_to_le64(time);
3314                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->mtime);
3315                 posix_info->LastWriteTime = cpu_to_le64(time);
3316                 posix_info->EndOfFile = cpu_to_le64(ksmbd_kstat->kstat->size);
3317                 posix_info->AllocationSize = cpu_to_le64(ksmbd_kstat->kstat->blocks << 9);
3318                 posix_info->DeviceId = cpu_to_le32(ksmbd_kstat->kstat->rdev);
3319                 posix_info->HardLinks = cpu_to_le32(ksmbd_kstat->kstat->nlink);
3320                 posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode);
3321                 posix_info->Inode = cpu_to_le64(ksmbd_kstat->kstat->ino);
3322                 posix_info->DosAttributes =
3323                         S_ISDIR(ksmbd_kstat->kstat->mode) ? ATTR_DIRECTORY_LE : ATTR_ARCHIVE_LE;
3324                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3325                         posix_info->DosAttributes |= ATTR_HIDDEN_LE;
3326                 id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid),
3327                                 SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
3328                 id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid),
3329                                 SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]);
3330                 memcpy(posix_info->name, conv_name, conv_len);
3331                 posix_info->name_len = cpu_to_le32(conv_len);
3332                 posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset);
3333                 break;
3334         }
3335
3336         } /* switch (info_level) */
3337
3338         d_info->last_entry_offset = d_info->data_count;
3339         d_info->data_count += next_entry_offset;
3340         d_info->out_buf_len -= next_entry_offset;
3341         d_info->wptr += next_entry_offset;
3342         kfree(conv_name);
3343
3344         ksmbd_debug(SMB,
3345                 "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
3346                 info_level, d_info->out_buf_len,
3347                 next_entry_offset, d_info->data_count);
3348
3349         return 0;
3350 }
3351
3352 struct smb2_query_dir_private {
3353         struct ksmbd_work       *work;
3354         char                    *search_pattern;
3355         struct ksmbd_file       *dir_fp;
3356
3357         struct ksmbd_dir_info   *d_info;
3358         int                     info_level;
3359 };
3360
3361 static void lock_dir(struct ksmbd_file *dir_fp)
3362 {
3363         struct dentry *dir = dir_fp->filp->f_path.dentry;
3364
3365         inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
3366 }
3367
3368 static void unlock_dir(struct ksmbd_file *dir_fp)
3369 {
3370         struct dentry *dir = dir_fp->filp->f_path.dentry;
3371
3372         inode_unlock(d_inode(dir));
3373 }
3374
3375 static int process_query_dir_entries(struct smb2_query_dir_private *priv)
3376 {
3377         struct kstat            kstat;
3378         struct ksmbd_kstat      ksmbd_kstat;
3379         int                     rc;
3380         int                     i;
3381
3382         for (i = 0; i < priv->d_info->num_entry; i++) {
3383                 struct dentry *dent;
3384
3385                 if (dentry_name(priv->d_info, priv->info_level))
3386                         return -EINVAL;
3387
3388                 lock_dir(priv->dir_fp);
3389                 dent = lookup_one_len(priv->d_info->name,
3390                                       priv->dir_fp->filp->f_path.dentry,
3391                                       priv->d_info->name_len);
3392                 unlock_dir(priv->dir_fp);
3393
3394                 if (IS_ERR(dent)) {
3395                         ksmbd_debug(SMB, "Cannot lookup `%s' [%ld]\n",
3396                                      priv->d_info->name,
3397                                      PTR_ERR(dent));
3398                         continue;
3399                 }
3400                 if (unlikely(d_is_negative(dent))) {
3401                         dput(dent);
3402                         ksmbd_debug(SMB, "Negative dentry `%s'\n",
3403                                     priv->d_info->name);
3404                         continue;
3405                 }
3406
3407                 ksmbd_kstat.kstat = &kstat;
3408                 if (priv->info_level != FILE_NAMES_INFORMATION)
3409                         ksmbd_vfs_fill_dentry_attrs(priv->work,
3410                                                     dent,
3411                                                     &ksmbd_kstat);
3412
3413                 rc = smb2_populate_readdir_entry(priv->work->conn,
3414                                                  priv->info_level,
3415                                                  priv->d_info,
3416                                                  &ksmbd_kstat);
3417                 dput(dent);
3418                 if (rc)
3419                         return rc;
3420         }
3421         return 0;
3422 }
3423
3424 static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
3425                 int info_level)
3426 {
3427         int struct_sz;
3428         int conv_len;
3429         int next_entry_offset;
3430
3431         struct_sz = readdir_info_level_struct_sz(info_level);
3432         if (struct_sz == -EOPNOTSUPP)
3433                 return -EOPNOTSUPP;
3434
3435         conv_len = (d_info->name_len + 1) * 2;
3436         next_entry_offset = ALIGN(struct_sz - 1 + conv_len,
3437                                   KSMBD_DIR_INFO_ALIGNMENT);
3438
3439         if (next_entry_offset > d_info->out_buf_len) {
3440                 d_info->out_buf_len = 0;
3441                 return -ENOSPC;
3442         }
3443
3444         switch (info_level) {
3445         case FILE_FULL_DIRECTORY_INFORMATION:
3446         {
3447                 struct file_full_directory_info *ffdinfo;
3448
3449                 ffdinfo = (struct file_full_directory_info *)d_info->wptr;
3450                 memcpy(ffdinfo->FileName, d_info->name, d_info->name_len);
3451                 ffdinfo->FileName[d_info->name_len] = 0x00;
3452                 ffdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3453                 ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3454                 break;
3455         }
3456         case FILE_BOTH_DIRECTORY_INFORMATION:
3457         {
3458                 struct file_both_directory_info *fbdinfo;
3459
3460                 fbdinfo = (struct file_both_directory_info *)d_info->wptr;
3461                 memcpy(fbdinfo->FileName, d_info->name, d_info->name_len);
3462                 fbdinfo->FileName[d_info->name_len] = 0x00;
3463                 fbdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3464                 fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3465                 break;
3466         }
3467         case FILE_DIRECTORY_INFORMATION:
3468         {
3469                 struct file_directory_info *fdinfo;
3470
3471                 fdinfo = (struct file_directory_info *)d_info->wptr;
3472                 memcpy(fdinfo->FileName, d_info->name, d_info->name_len);
3473                 fdinfo->FileName[d_info->name_len] = 0x00;
3474                 fdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3475                 fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3476                 break;
3477         }
3478         case FILE_NAMES_INFORMATION:
3479         {
3480                 struct file_names_info *fninfo;
3481
3482                 fninfo = (struct file_names_info *)d_info->wptr;
3483                 memcpy(fninfo->FileName, d_info->name, d_info->name_len);
3484                 fninfo->FileName[d_info->name_len] = 0x00;
3485                 fninfo->FileNameLength = cpu_to_le32(d_info->name_len);
3486                 fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3487                 break;
3488         }
3489         case FILEID_FULL_DIRECTORY_INFORMATION:
3490         {
3491                 struct file_id_full_dir_info *dinfo;
3492
3493                 dinfo = (struct file_id_full_dir_info *)d_info->wptr;
3494                 memcpy(dinfo->FileName, d_info->name, d_info->name_len);
3495                 dinfo->FileName[d_info->name_len] = 0x00;
3496                 dinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3497                 dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3498                 break;
3499         }
3500         case FILEID_BOTH_DIRECTORY_INFORMATION:
3501         {
3502                 struct file_id_both_directory_info *fibdinfo;
3503
3504                 fibdinfo = (struct file_id_both_directory_info *)d_info->wptr;
3505                 memcpy(fibdinfo->FileName, d_info->name, d_info->name_len);
3506                 fibdinfo->FileName[d_info->name_len] = 0x00;
3507                 fibdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3508                 fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3509                 break;
3510         }
3511         case SMB_FIND_FILE_POSIX_INFO:
3512         {
3513                 struct smb2_posix_info *posix_info;
3514
3515                 posix_info = (struct smb2_posix_info *)d_info->wptr;
3516                 memcpy(posix_info->name, d_info->name, d_info->name_len);
3517                 posix_info->name[d_info->name_len] = 0x00;
3518                 posix_info->name_len = cpu_to_le32(d_info->name_len);
3519                 posix_info->NextEntryOffset =
3520                         cpu_to_le32(next_entry_offset);
3521                 break;
3522         }
3523         } /* switch (info_level) */
3524
3525         d_info->num_entry++;
3526         d_info->out_buf_len -= next_entry_offset;
3527         d_info->wptr += next_entry_offset;
3528         return 0;
3529 }
3530
3531 static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
3532                 loff_t offset, u64 ino, unsigned int d_type)
3533 {
3534         struct ksmbd_readdir_data       *buf;
3535         struct smb2_query_dir_private   *priv;
3536         struct ksmbd_dir_info           *d_info;
3537         int                             rc;
3538
3539         buf     = container_of(ctx, struct ksmbd_readdir_data, ctx);
3540         priv    = buf->private;
3541         d_info  = priv->d_info;
3542
3543         /* dot and dotdot entries are already reserved */
3544         if (!strcmp(".", name) || !strcmp("..", name))
3545                 return 0;
3546         if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
3547                 return 0;
3548         if (!match_pattern(name, namlen, priv->search_pattern))
3549                 return 0;
3550
3551         d_info->name            = name;
3552         d_info->name_len        = namlen;
3553         rc = reserve_populate_dentry(d_info, priv->info_level);
3554         if (rc)
3555                 return rc;
3556         if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY) {
3557                 d_info->out_buf_len = 0;
3558                 return 0;
3559         }
3560         return 0;
3561 }
3562
3563 static void restart_ctx(struct dir_context *ctx)
3564 {
3565         ctx->pos = 0;
3566 }
3567
3568 static int verify_info_level(int info_level)
3569 {
3570         switch (info_level) {
3571         case FILE_FULL_DIRECTORY_INFORMATION:
3572         case FILE_BOTH_DIRECTORY_INFORMATION:
3573         case FILE_DIRECTORY_INFORMATION:
3574         case FILE_NAMES_INFORMATION:
3575         case FILEID_FULL_DIRECTORY_INFORMATION:
3576         case FILEID_BOTH_DIRECTORY_INFORMATION:
3577         case SMB_FIND_FILE_POSIX_INFO:
3578                 break;
3579         default:
3580                 return -EOPNOTSUPP;
3581         }
3582
3583         return 0;
3584 }
3585
3586 int smb2_query_dir(struct ksmbd_work *work)
3587 {
3588         struct ksmbd_conn *conn = work->conn;
3589         struct smb2_query_directory_req *req;
3590         struct smb2_query_directory_rsp *rsp, *rsp_org;
3591         struct ksmbd_share_config *share = work->tcon->share_conf;
3592         struct ksmbd_file *dir_fp = NULL;
3593         struct ksmbd_dir_info d_info;
3594         int rc = 0;
3595         char *srch_ptr = NULL;
3596         unsigned char srch_flag;
3597         int buffer_sz;
3598         struct smb2_query_dir_private query_dir_private = {NULL, };
3599
3600         rsp_org = work->response_buf;
3601         WORK_BUFFERS(work, req, rsp);
3602
3603         if (ksmbd_override_fsids(work)) {
3604                 rsp->hdr.Status = STATUS_NO_MEMORY;
3605                 smb2_set_err_rsp(work);
3606                 return -ENOMEM;
3607         }
3608
3609         rc = verify_info_level(req->FileInformationClass);
3610         if (rc) {
3611                 rc = -EFAULT;
3612                 goto err_out2;
3613         }
3614
3615         dir_fp = ksmbd_lookup_fd_slow(work,
3616                         le64_to_cpu(req->VolatileFileId),
3617                         le64_to_cpu(req->PersistentFileId));
3618         if (!dir_fp) {
3619                 rc = -EBADF;
3620                 goto err_out2;
3621         }
3622
3623         if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
3624             inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) {
3625                 ksmbd_err("no right to enumerate directory (%s)\n",
3626                         FP_FILENAME(dir_fp));
3627                 rc = -EACCES;
3628                 goto err_out2;
3629         }
3630
3631         if (!S_ISDIR(file_inode(dir_fp->filp)->i_mode)) {
3632                 ksmbd_err("can't do query dir for a file\n");
3633                 rc = -EINVAL;
3634                 goto err_out2;
3635         }
3636
3637         srch_flag = req->Flags;
3638         srch_ptr = smb_strndup_from_utf16(req->Buffer,
3639                         le16_to_cpu(req->FileNameLength), 1,
3640                         conn->local_nls);
3641         if (IS_ERR(srch_ptr)) {
3642                 ksmbd_debug(SMB, "Search Pattern not found\n");
3643                 rc = -EINVAL;
3644                 goto err_out2;
3645         } else {
3646                 ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
3647         }
3648
3649         ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
3650
3651         if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
3652                 ksmbd_debug(SMB, "Restart directory scan\n");
3653                 generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
3654                 restart_ctx(&dir_fp->readdir_data.ctx);
3655         }
3656
3657         memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
3658         d_info.wptr = (char *)rsp->Buffer;
3659         d_info.rptr = (char *)rsp->Buffer;
3660         d_info.out_buf_len = (work->response_sz - (get_rfc1002_len(rsp_org) + 4));
3661         d_info.out_buf_len = min_t(int, d_info.out_buf_len,
3662                 le32_to_cpu(req->OutputBufferLength)) - sizeof(struct smb2_query_directory_rsp);
3663         d_info.flags = srch_flag;
3664
3665         /*
3666          * reserve dot and dotdot entries in head of buffer
3667          * in first response
3668          */
3669         rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass,
3670                 dir_fp, &d_info, srch_ptr, smb2_populate_readdir_entry);
3671         if (rc == -ENOSPC)
3672                 rc = 0;
3673         else if (rc)
3674                 goto err_out;
3675
3676         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES))
3677                 d_info.hide_dot_file = true;
3678
3679         buffer_sz                               = d_info.out_buf_len;
3680         d_info.rptr                             = d_info.wptr;
3681         query_dir_private.work                  = work;
3682         query_dir_private.search_pattern        = srch_ptr;
3683         query_dir_private.dir_fp                = dir_fp;
3684         query_dir_private.d_info                = &d_info;
3685         query_dir_private.info_level            = req->FileInformationClass;
3686         dir_fp->readdir_data.private            = &query_dir_private;
3687         set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
3688
3689         rc = ksmbd_vfs_readdir(dir_fp->filp, &dir_fp->readdir_data);
3690         if (rc == 0)
3691                 restart_ctx(&dir_fp->readdir_data.ctx);
3692         if (rc == -ENOSPC)
3693                 rc = 0;
3694         if (rc)
3695                 goto err_out;
3696
3697         d_info.wptr = d_info.rptr;
3698         d_info.out_buf_len = buffer_sz;
3699         rc = process_query_dir_entries(&query_dir_private);
3700         if (rc)
3701                 goto err_out;
3702
3703         if (!d_info.data_count && d_info.out_buf_len >= 0) {
3704                 if (srch_flag & SMB2_RETURN_SINGLE_ENTRY && !is_asterisk(srch_ptr)) {
3705                         rsp->hdr.Status = STATUS_NO_SUCH_FILE;
3706                 } else {
3707                         dir_fp->dot_dotdot[0] = dir_fp->dot_dotdot[1] = 0;
3708                         rsp->hdr.Status = STATUS_NO_MORE_FILES;
3709                 }
3710                 rsp->StructureSize = cpu_to_le16(9);
3711                 rsp->OutputBufferOffset = cpu_to_le16(0);
3712                 rsp->OutputBufferLength = cpu_to_le32(0);
3713                 rsp->Buffer[0] = 0;
3714                 inc_rfc1001_len(rsp_org, 9);
3715         } else {
3716                 ((struct file_directory_info *)
3717                 ((char *)rsp->Buffer + d_info.last_entry_offset))
3718                 ->NextEntryOffset = 0;
3719
3720                 rsp->StructureSize = cpu_to_le16(9);
3721                 rsp->OutputBufferOffset = cpu_to_le16(72);
3722                 rsp->OutputBufferLength = cpu_to_le32(d_info.data_count);
3723                 inc_rfc1001_len(rsp_org, 8 + d_info.data_count);
3724         }
3725
3726         kfree(srch_ptr);
3727         ksmbd_fd_put(work, dir_fp);
3728         ksmbd_revert_fsids(work);
3729         return 0;
3730
3731 err_out:
3732         ksmbd_err("error while processing smb2 query dir rc = %d\n", rc);
3733         kfree(srch_ptr);
3734
3735 err_out2:
3736         if (rc == -EINVAL)
3737                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
3738         else if (rc == -EACCES)
3739                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
3740         else if (rc == -ENOENT)
3741                 rsp->hdr.Status = STATUS_NO_SUCH_FILE;
3742         else if (rc == -EBADF)
3743                 rsp->hdr.Status = STATUS_FILE_CLOSED;
3744         else if (rc == -ENOMEM)
3745                 rsp->hdr.Status = STATUS_NO_MEMORY;
3746         else if (rc == -EFAULT)
3747                 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
3748         if (!rsp->hdr.Status)
3749                 rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
3750
3751         smb2_set_err_rsp(work);
3752         ksmbd_fd_put(work, dir_fp);
3753         ksmbd_revert_fsids(work);
3754         return 0;
3755 }
3756
3757 /**
3758  * buffer_check_err() - helper function to check buffer errors
3759  * @reqOutputBufferLength:      max buffer length expected in command response
3760  * @rsp:                query info response buffer contains output buffer length
3761  * @infoclass_size:     query info class response buffer size
3762  *
3763  * Return:      0 on success, otherwise error
3764  */
3765 static int buffer_check_err(int reqOutputBufferLength,
3766                 struct smb2_query_info_rsp *rsp, int infoclass_size)
3767 {
3768         if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
3769                 if (reqOutputBufferLength < infoclass_size) {
3770                         ksmbd_err("Invalid Buffer Size Requested\n");
3771                         rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
3772                         rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4);
3773                         return -EINVAL;
3774                 }
3775
3776                 ksmbd_debug(SMB, "Buffer Overflow\n");
3777                 rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
3778                 rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4 +
3779                                 reqOutputBufferLength);
3780                 rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength);
3781         }
3782         return 0;
3783 }
3784
3785 static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
3786 {
3787         struct smb2_file_standard_info *sinfo;
3788
3789         sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
3790
3791         sinfo->AllocationSize = cpu_to_le64(4096);
3792         sinfo->EndOfFile = cpu_to_le64(0);
3793         sinfo->NumberOfLinks = cpu_to_le32(1);
3794         sinfo->DeletePending = 1;
3795         sinfo->Directory = 0;
3796         rsp->OutputBufferLength =
3797                 cpu_to_le32(sizeof(struct smb2_file_standard_info));
3798         inc_rfc1001_len(rsp, sizeof(struct smb2_file_standard_info));
3799 }
3800
3801 static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp,
3802                 u64 num)
3803 {
3804         struct smb2_file_internal_info *file_info;
3805
3806         file_info = (struct smb2_file_internal_info *)rsp->Buffer;
3807
3808         /* any unique number */
3809         file_info->IndexNumber = cpu_to_le64(num | (1ULL << 63));
3810         rsp->OutputBufferLength =
3811                 cpu_to_le32(sizeof(struct smb2_file_internal_info));
3812         inc_rfc1001_len(rsp, sizeof(struct smb2_file_internal_info));
3813 }
3814
3815 static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
3816                 struct smb2_query_info_req *req,
3817                 struct smb2_query_info_rsp *rsp)
3818 {
3819         u64 id;
3820         int rc;
3821
3822         /*
3823          * Windows can sometime send query file info request on
3824          * pipe without opening it, checking error condition here
3825          */
3826         id = le64_to_cpu(req->VolatileFileId);
3827         if (!ksmbd_session_rpc_method(sess, id))
3828                 return -ENOENT;
3829
3830         ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
3831                      req->FileInfoClass, le64_to_cpu(req->VolatileFileId));
3832
3833         switch (req->FileInfoClass) {
3834         case FILE_STANDARD_INFORMATION:
3835                 get_standard_info_pipe(rsp);
3836                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
3837                         rsp, FILE_STANDARD_INFORMATION_SIZE);
3838                 break;
3839         case FILE_INTERNAL_INFORMATION:
3840                 get_internal_info_pipe(rsp, id);
3841                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
3842                         rsp, FILE_INTERNAL_INFORMATION_SIZE);
3843                 break;
3844         default:
3845                 ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
3846                         req->FileInfoClass);
3847                 rc = -EOPNOTSUPP;
3848         }
3849         return rc;
3850 }
3851
3852 /**
3853  * smb2_get_ea() - handler for smb2 get extended attribute command
3854  * @work:       smb work containing query info command buffer
3855  * @fp:         ksmbd_file pointer
3856  * @req:        get extended attribute request
3857  * @rsp:        response buffer pointer
3858  * @rsp_org:    base response buffer pointer in case of chained response
3859  *
3860  * Return:      0 on success, otherwise error
3861  */
3862 static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
3863                 struct smb2_query_info_req *req,
3864                 struct smb2_query_info_rsp *rsp, void *rsp_org)
3865 {
3866         struct smb2_ea_info *eainfo, *prev_eainfo;
3867         char *name, *ptr, *xattr_list = NULL, *buf;
3868         int rc, name_len, value_len, xattr_list_len, idx;
3869         ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0;
3870         struct smb2_ea_info_req *ea_req = NULL;
3871         struct path *path;
3872
3873         if (!(fp->daccess & FILE_READ_EA_LE)) {
3874                 ksmbd_err("Not permitted to read ext attr : 0x%x\n",
3875                           fp->daccess);
3876                 return -EACCES;
3877         }
3878
3879         path = &fp->filp->f_path;
3880         /* single EA entry is requested with given user.* name */
3881         if (req->InputBufferLength) {
3882                 ea_req = (struct smb2_ea_info_req *)req->Buffer;
3883         } else {
3884                 /* need to send all EAs, if no specific EA is requested*/
3885                 if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
3886                         ksmbd_debug(SMB,
3887                                 "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
3888                                 le32_to_cpu(req->Flags));
3889         }
3890
3891         buf_free_len = work->response_sz -
3892                         (get_rfc1002_len(rsp_org) + 4) -
3893                         sizeof(struct smb2_query_info_rsp);
3894
3895         if (le32_to_cpu(req->OutputBufferLength) < buf_free_len)
3896                 buf_free_len = le32_to_cpu(req->OutputBufferLength);
3897
3898         rc = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
3899         if (rc < 0) {
3900                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
3901                 goto out;
3902         } else if (!rc) { /* there is no EA in the file */
3903                 ksmbd_debug(SMB, "no ea data in the file\n");
3904                 goto done;
3905         }
3906         xattr_list_len = rc;
3907
3908         ptr = (char *)rsp->Buffer;
3909         eainfo = (struct smb2_ea_info *)ptr;
3910         prev_eainfo = eainfo;
3911         idx = 0;
3912
3913         while (idx < xattr_list_len) {
3914                 name = xattr_list + idx;
3915                 name_len = strlen(name);
3916
3917                 ksmbd_debug(SMB, "%s, len %d\n", name, name_len);
3918                 idx += name_len + 1;
3919
3920                 /*
3921                  * CIFS does not support EA other than user.* namespace,
3922                  * still keep the framework generic, to list other attrs
3923                  * in future.
3924                  */
3925                 if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3926                         continue;
3927
3928                 if (!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
3929                              STREAM_PREFIX_LEN))
3930                         continue;
3931
3932                 if (req->InputBufferLength &&
3933                     strncmp(&name[XATTR_USER_PREFIX_LEN], ea_req->name,
3934                             ea_req->EaNameLength))
3935                         continue;
3936
3937                 if (!strncmp(&name[XATTR_USER_PREFIX_LEN],
3938                              DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN))
3939                         continue;
3940
3941                 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3942                         name_len -= XATTR_USER_PREFIX_LEN;
3943
3944                 ptr = (char *)(&eainfo->name + name_len + 1);
3945                 buf_free_len -= (offsetof(struct smb2_ea_info, name) +
3946                                 name_len + 1);
3947                 /* bailout if xattr can't fit in buf_free_len */
3948                 value_len = ksmbd_vfs_getxattr(path->dentry, name, &buf);
3949                 if (value_len <= 0) {
3950                         rc = -ENOENT;
3951                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
3952                         goto out;
3953                 }
3954
3955                 buf_free_len -= value_len;
3956                 if (buf_free_len < 0) {
3957                         kfree(buf);
3958                         break;
3959                 }
3960
3961                 memcpy(ptr, buf, value_len);
3962                 kfree(buf);
3963
3964                 ptr += value_len;
3965                 eainfo->Flags = 0;
3966                 eainfo->EaNameLength = name_len;
3967
3968                 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3969                         memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN],
3970                                         name_len);
3971                 else
3972                         memcpy(eainfo->name, name, name_len);
3973
3974                 eainfo->name[name_len] = '\0';
3975                 eainfo->EaValueLength = cpu_to_le16(value_len);
3976                 next_offset = offsetof(struct smb2_ea_info, name) +
3977                         name_len + 1 + value_len;
3978
3979                 /* align next xattr entry at 4 byte bundary */
3980                 alignment_bytes = ((next_offset + 3) & ~3) - next_offset;
3981                 if (alignment_bytes) {
3982                         memset(ptr, '\0', alignment_bytes);
3983                         ptr += alignment_bytes;
3984                         next_offset += alignment_bytes;
3985                         buf_free_len -= alignment_bytes;
3986                 }
3987                 eainfo->NextEntryOffset = cpu_to_le32(next_offset);
3988                 prev_eainfo = eainfo;
3989                 eainfo = (struct smb2_ea_info *)ptr;
3990                 rsp_data_cnt += next_offset;
3991
3992                 if (req->InputBufferLength) {
3993                         ksmbd_debug(SMB, "single entry requested\n");
3994                         break;
3995                 }
3996         }
3997
3998         /* no more ea entries */
3999         prev_eainfo->NextEntryOffset = 0;
4000 done:
4001         rc = 0;
4002         if (rsp_data_cnt == 0)
4003                 rsp->hdr.Status = STATUS_NO_EAS_ON_FILE;
4004         rsp->OutputBufferLength = cpu_to_le32(rsp_data_cnt);
4005         inc_rfc1001_len(rsp_org, rsp_data_cnt);
4006 out:
4007         kvfree(xattr_list);
4008         return rc;
4009 }
4010
4011 static void get_file_access_info(struct smb2_query_info_rsp *rsp,
4012                 struct ksmbd_file *fp, void *rsp_org)
4013 {
4014         struct smb2_file_access_info *file_info;
4015
4016         file_info = (struct smb2_file_access_info *)rsp->Buffer;
4017         file_info->AccessFlags = fp->daccess;
4018         rsp->OutputBufferLength =
4019                 cpu_to_le32(sizeof(struct smb2_file_access_info));
4020         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_access_info));
4021 }
4022
4023 static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
4024                 struct ksmbd_file *fp, void *rsp_org)
4025 {
4026         struct smb2_file_all_info *basic_info;
4027         struct kstat stat;
4028         u64 time;
4029
4030         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4031                 ksmbd_err("no right to read the attributes : 0x%x\n",
4032                            fp->daccess);
4033                 return -EACCES;
4034         }
4035
4036         basic_info = (struct smb2_file_all_info *)rsp->Buffer;
4037         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4038         basic_info->CreationTime = cpu_to_le64(fp->create_time);
4039         time = ksmbd_UnixTimeToNT(stat.atime);
4040         basic_info->LastAccessTime = cpu_to_le64(time);
4041         time = ksmbd_UnixTimeToNT(stat.mtime);
4042         basic_info->LastWriteTime = cpu_to_le64(time);
4043         time = ksmbd_UnixTimeToNT(stat.ctime);
4044         basic_info->ChangeTime = cpu_to_le64(time);
4045         basic_info->Attributes = fp->f_ci->m_fattr;
4046         basic_info->Pad1 = 0;
4047         rsp->OutputBufferLength =
4048                 cpu_to_le32(offsetof(struct smb2_file_all_info, AllocationSize));
4049         inc_rfc1001_len(rsp_org, offsetof(struct smb2_file_all_info,
4050                                           AllocationSize));
4051         return 0;
4052 }
4053
4054 static unsigned long long get_allocation_size(struct inode *inode,
4055                 struct kstat *stat)
4056 {
4057         unsigned long long alloc_size = 0;
4058
4059         if (!S_ISDIR(stat->mode)) {
4060                 if ((inode->i_blocks << 9) <= stat->size)
4061                         alloc_size = stat->size;
4062                 else
4063                         alloc_size = inode->i_blocks << 9;
4064         }
4065
4066         return alloc_size;
4067 }
4068
4069 static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
4070                 struct ksmbd_file *fp, void *rsp_org)
4071 {
4072         struct smb2_file_standard_info *sinfo;
4073         unsigned int delete_pending;
4074         struct inode *inode;
4075         struct kstat stat;
4076
4077         inode = FP_INODE(fp);
4078         generic_fillattr(&init_user_ns, inode, &stat);
4079
4080         sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
4081         delete_pending = ksmbd_inode_pending_delete(fp);
4082
4083         sinfo->AllocationSize = cpu_to_le64(get_allocation_size(inode, &stat));
4084         sinfo->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4085         sinfo->NumberOfLinks = cpu_to_le32(get_nlink(&stat) - delete_pending);
4086         sinfo->DeletePending = delete_pending;
4087         sinfo->Directory = S_ISDIR(stat.mode) ? 1 : 0;
4088         rsp->OutputBufferLength =
4089                 cpu_to_le32(sizeof(struct smb2_file_standard_info));
4090         inc_rfc1001_len(rsp_org,
4091                         sizeof(struct smb2_file_standard_info));
4092 }
4093
4094 static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
4095                 void *rsp_org)
4096 {
4097         struct smb2_file_alignment_info *file_info;
4098
4099         file_info = (struct smb2_file_alignment_info *)rsp->Buffer;
4100         file_info->AlignmentRequirement = 0;
4101         rsp->OutputBufferLength =
4102                 cpu_to_le32(sizeof(struct smb2_file_alignment_info));
4103         inc_rfc1001_len(rsp_org,
4104                         sizeof(struct smb2_file_alignment_info));
4105 }
4106
4107 static int get_file_all_info(struct ksmbd_work *work,
4108                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4109                 void *rsp_org)
4110 {
4111         struct ksmbd_conn *conn = work->conn;
4112         struct smb2_file_all_info *file_info;
4113         unsigned int delete_pending;
4114         struct inode *inode;
4115         struct kstat stat;
4116         int conv_len;
4117         char *filename;
4118         u64 time;
4119
4120         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4121                 ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
4122                                 fp->daccess);
4123                 return -EACCES;
4124         }
4125
4126         filename = convert_to_nt_pathname(fp->filename,
4127                                           work->tcon->share_conf->path);
4128         if (!filename)
4129                 return -ENOMEM;
4130
4131         inode = FP_INODE(fp);
4132         generic_fillattr(&init_user_ns, inode, &stat);
4133
4134         ksmbd_debug(SMB, "filename = %s\n", filename);
4135         delete_pending = ksmbd_inode_pending_delete(fp);
4136         file_info = (struct smb2_file_all_info *)rsp->Buffer;
4137
4138         file_info->CreationTime = cpu_to_le64(fp->create_time);
4139         time = ksmbd_UnixTimeToNT(stat.atime);
4140         file_info->LastAccessTime = cpu_to_le64(time);
4141         time = ksmbd_UnixTimeToNT(stat.mtime);
4142         file_info->LastWriteTime = cpu_to_le64(time);
4143         time = ksmbd_UnixTimeToNT(stat.ctime);
4144         file_info->ChangeTime = cpu_to_le64(time);
4145         file_info->Attributes = fp->f_ci->m_fattr;
4146         file_info->Pad1 = 0;
4147         file_info->AllocationSize =
4148                 cpu_to_le64(get_allocation_size(inode, &stat));
4149         file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4150         file_info->NumberOfLinks =
4151                         cpu_to_le32(get_nlink(&stat) - delete_pending);
4152         file_info->DeletePending = delete_pending;
4153         file_info->Directory = S_ISDIR(stat.mode) ? 1 : 0;
4154         file_info->Pad2 = 0;
4155         file_info->IndexNumber = cpu_to_le64(stat.ino);
4156         file_info->EASize = 0;
4157         file_info->AccessFlags = fp->daccess;
4158         file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
4159         file_info->Mode = fp->coption;
4160         file_info->AlignmentRequirement = 0;
4161         conv_len = smbConvertToUTF16((__le16 *)file_info->FileName,
4162                                              filename,
4163                                              PATH_MAX,
4164                                              conn->local_nls,
4165                                              0);
4166         conv_len *= 2;
4167         file_info->FileNameLength = cpu_to_le32(conv_len);
4168         rsp->OutputBufferLength =
4169                 cpu_to_le32(sizeof(struct smb2_file_all_info) + conv_len - 1);
4170         kfree(filename);
4171         inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength));
4172         return 0;
4173 }
4174
4175 static void get_file_alternate_info(struct ksmbd_work *work,
4176                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4177                 void *rsp_org)
4178 {
4179         struct ksmbd_conn *conn = work->conn;
4180         struct smb2_file_alt_name_info *file_info;
4181         int conv_len;
4182         char *filename;
4183
4184         filename = (char *)FP_FILENAME(fp);
4185         file_info = (struct smb2_file_alt_name_info *)rsp->Buffer;
4186         conv_len = ksmbd_extract_shortname(conn,
4187                                            filename,
4188                                            file_info->FileName);
4189         file_info->FileNameLength = cpu_to_le32(conv_len);
4190         rsp->OutputBufferLength =
4191                 cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len);
4192         inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength));
4193 }
4194
4195 static void get_file_stream_info(struct ksmbd_work *work,
4196                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4197                 void *rsp_org)
4198 {
4199         struct ksmbd_conn *conn = work->conn;
4200         struct smb2_file_stream_info *file_info;
4201         char *stream_name, *xattr_list = NULL, *stream_buf;
4202         struct kstat stat;
4203         struct path *path = &fp->filp->f_path;
4204         ssize_t xattr_list_len;
4205         int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
4206
4207         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4208         file_info = (struct smb2_file_stream_info *)rsp->Buffer;
4209
4210         xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
4211         if (xattr_list_len < 0) {
4212                 goto out;
4213         } else if (!xattr_list_len) {
4214                 ksmbd_debug(SMB, "empty xattr in the file\n");
4215                 goto out;
4216         }
4217
4218         while (idx < xattr_list_len) {
4219                 stream_name = xattr_list + idx;
4220                 streamlen = strlen(stream_name);
4221                 idx += streamlen + 1;
4222
4223                 ksmbd_debug(SMB, "%s, len %d\n", stream_name, streamlen);
4224
4225                 if (strncmp(&stream_name[XATTR_USER_PREFIX_LEN],
4226                             STREAM_PREFIX, STREAM_PREFIX_LEN))
4227                         continue;
4228
4229                 stream_name_len = streamlen - (XATTR_USER_PREFIX_LEN +
4230                                 STREAM_PREFIX_LEN);
4231                 streamlen = stream_name_len;
4232
4233                 /* plus : size */
4234                 streamlen += 1;
4235                 stream_buf = kmalloc(streamlen + 1, GFP_KERNEL);
4236                 if (!stream_buf)
4237                         break;
4238
4239                 streamlen = snprintf(stream_buf, streamlen + 1,
4240                                 ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
4241
4242                 file_info = (struct smb2_file_stream_info *)
4243                         &rsp->Buffer[nbytes];
4244                 streamlen  = smbConvertToUTF16((__le16 *)file_info->StreamName,
4245                                                 stream_buf,
4246                                                 streamlen,
4247                                                 conn->local_nls,
4248                                                 0);
4249                 streamlen *= 2;
4250                 kfree(stream_buf);
4251                 file_info->StreamNameLength = cpu_to_le32(streamlen);
4252                 file_info->StreamSize = cpu_to_le64(stream_name_len);
4253                 file_info->StreamAllocationSize = cpu_to_le64(stream_name_len);
4254
4255                 next = sizeof(struct smb2_file_stream_info) + streamlen;
4256                 nbytes += next;
4257                 file_info->NextEntryOffset = cpu_to_le32(next);
4258         }
4259
4260         if (nbytes) {
4261                 file_info = (struct smb2_file_stream_info *)
4262                         &rsp->Buffer[nbytes];
4263                 streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
4264                         "::$DATA", 7, conn->local_nls, 0);
4265                 streamlen *= 2;
4266                 file_info->StreamNameLength = cpu_to_le32(streamlen);
4267                 file_info->StreamSize = S_ISDIR(stat.mode) ? 0 :
4268                         cpu_to_le64(stat.size);
4269                 file_info->StreamAllocationSize = S_ISDIR(stat.mode) ? 0 :
4270                         cpu_to_le64(stat.size);
4271                 nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
4272         }
4273
4274         /* last entry offset should be 0 */
4275         file_info->NextEntryOffset = 0;
4276 out:
4277         kvfree(xattr_list);
4278
4279         rsp->OutputBufferLength = cpu_to_le32(nbytes);
4280         inc_rfc1001_len(rsp_org, nbytes);
4281 }
4282
4283 static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
4284                 struct ksmbd_file *fp, void *rsp_org)
4285 {
4286         struct smb2_file_internal_info *file_info;
4287         struct kstat stat;
4288
4289         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4290         file_info = (struct smb2_file_internal_info *)rsp->Buffer;
4291         file_info->IndexNumber = cpu_to_le64(stat.ino);
4292         rsp->OutputBufferLength =
4293                 cpu_to_le32(sizeof(struct smb2_file_internal_info));
4294         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info));
4295 }
4296
4297 static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
4298                 struct ksmbd_file *fp, void *rsp_org)
4299 {
4300         struct smb2_file_ntwrk_info *file_info;
4301         struct inode *inode;
4302         struct kstat stat;
4303         u64 time;
4304
4305         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4306                 ksmbd_err("no right to read the attributes : 0x%x\n",
4307                           fp->daccess);
4308                 return -EACCES;
4309         }
4310
4311         file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer;
4312
4313         inode = FP_INODE(fp);
4314         generic_fillattr(&init_user_ns, inode, &stat);
4315
4316         file_info->CreationTime = cpu_to_le64(fp->create_time);
4317         time = ksmbd_UnixTimeToNT(stat.atime);
4318         file_info->LastAccessTime = cpu_to_le64(time);
4319         time = ksmbd_UnixTimeToNT(stat.mtime);
4320         file_info->LastWriteTime = cpu_to_le64(time);
4321         time = ksmbd_UnixTimeToNT(stat.ctime);
4322         file_info->ChangeTime = cpu_to_le64(time);
4323         file_info->Attributes = fp->f_ci->m_fattr;
4324         file_info->AllocationSize =
4325                 cpu_to_le64(get_allocation_size(inode, &stat));
4326         file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4327         file_info->Reserved = cpu_to_le32(0);
4328         rsp->OutputBufferLength =
4329                 cpu_to_le32(sizeof(struct smb2_file_ntwrk_info));
4330         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ntwrk_info));
4331         return 0;
4332 }
4333
4334 static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org)
4335 {
4336         struct smb2_file_ea_info *file_info;
4337
4338         file_info = (struct smb2_file_ea_info *)rsp->Buffer;
4339         file_info->EASize = 0;
4340         rsp->OutputBufferLength =
4341                 cpu_to_le32(sizeof(struct smb2_file_ea_info));
4342         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ea_info));
4343 }
4344
4345 static void get_file_position_info(struct smb2_query_info_rsp *rsp,
4346                 struct ksmbd_file *fp, void *rsp_org)
4347 {
4348         struct smb2_file_pos_info *file_info;
4349
4350         file_info = (struct smb2_file_pos_info *)rsp->Buffer;
4351         file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
4352         rsp->OutputBufferLength =
4353                 cpu_to_le32(sizeof(struct smb2_file_pos_info));
4354         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_pos_info));
4355 }
4356
4357 static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
4358                 struct ksmbd_file *fp, void *rsp_org)
4359 {
4360         struct smb2_file_mode_info *file_info;
4361
4362         file_info = (struct smb2_file_mode_info *)rsp->Buffer;
4363         file_info->Mode = fp->coption & FILE_MODE_INFO_MASK;
4364         rsp->OutputBufferLength =
4365                 cpu_to_le32(sizeof(struct smb2_file_mode_info));
4366         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_mode_info));
4367 }
4368
4369 static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
4370                 struct ksmbd_file *fp, void *rsp_org)
4371 {
4372         struct smb2_file_comp_info *file_info;
4373         struct kstat stat;
4374
4375         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4376
4377         file_info = (struct smb2_file_comp_info *)rsp->Buffer;
4378         file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9);
4379         file_info->CompressionFormat = COMPRESSION_FORMAT_NONE;
4380         file_info->CompressionUnitShift = 0;
4381         file_info->ChunkShift = 0;
4382         file_info->ClusterShift = 0;
4383         memset(&file_info->Reserved[0], 0, 3);
4384
4385         rsp->OutputBufferLength =
4386                 cpu_to_le32(sizeof(struct smb2_file_comp_info));
4387         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_comp_info));
4388 }
4389
4390 static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
4391                 struct ksmbd_file *fp, void *rsp_org)
4392 {
4393         struct smb2_file_attr_tag_info *file_info;
4394
4395         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4396                 ksmbd_err("no right to read the attributes : 0x%x\n",
4397                           fp->daccess);
4398                 return -EACCES;
4399         }
4400
4401         file_info = (struct smb2_file_attr_tag_info *)rsp->Buffer;
4402         file_info->FileAttributes = fp->f_ci->m_fattr;
4403         file_info->ReparseTag = 0;
4404         rsp->OutputBufferLength =
4405                 cpu_to_le32(sizeof(struct smb2_file_attr_tag_info));
4406         inc_rfc1001_len(rsp_org,
4407                 sizeof(struct smb2_file_attr_tag_info));
4408         return 0;
4409 }
4410
4411 static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
4412                 struct ksmbd_file *fp, void *rsp_org)
4413 {
4414         struct smb311_posix_qinfo *file_info;
4415         struct inode *inode = FP_INODE(fp);
4416         u64 time;
4417
4418         file_info = (struct smb311_posix_qinfo *)rsp->Buffer;
4419         file_info->CreationTime = cpu_to_le64(fp->create_time);
4420         time = ksmbd_UnixTimeToNT(inode->i_atime);
4421         file_info->LastAccessTime = cpu_to_le64(time);
4422         time = ksmbd_UnixTimeToNT(inode->i_mtime);
4423         file_info->LastWriteTime = cpu_to_le64(time);
4424         time = ksmbd_UnixTimeToNT(inode->i_ctime);
4425         file_info->ChangeTime = cpu_to_le64(time);
4426         file_info->DosAttributes = fp->f_ci->m_fattr;
4427         file_info->Inode = cpu_to_le64(inode->i_ino);
4428         file_info->EndOfFile = cpu_to_le64(inode->i_size);
4429         file_info->AllocationSize = cpu_to_le64(inode->i_blocks << 9);
4430         file_info->HardLinks = cpu_to_le32(inode->i_nlink);
4431         file_info->Mode = cpu_to_le32(inode->i_mode);
4432         file_info->DeviceId = cpu_to_le32(inode->i_rdev);
4433         rsp->OutputBufferLength =
4434                 cpu_to_le32(sizeof(struct smb311_posix_qinfo));
4435         inc_rfc1001_len(rsp_org, sizeof(struct smb311_posix_qinfo));
4436         return 0;
4437 }
4438
4439 static int smb2_get_info_file(struct ksmbd_work *work,
4440                 struct smb2_query_info_req *req,
4441                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4442 {
4443         struct ksmbd_file *fp;
4444         int fileinfoclass = 0;
4445         int rc = 0;
4446         int file_infoclass_size;
4447         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
4448
4449         if (test_share_config_flag(work->tcon->share_conf,
4450                                    KSMBD_SHARE_FLAG_PIPE)) {
4451                 /* smb2 info file called for pipe */
4452                 return smb2_get_info_file_pipe(work->sess, req, rsp);
4453         }
4454
4455         if (work->next_smb2_rcv_hdr_off) {
4456                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
4457                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
4458                                         work->compound_fid);
4459                         id = work->compound_fid;
4460                         pid = work->compound_pfid;
4461                 }
4462         }
4463
4464         if (!HAS_FILE_ID(id)) {
4465                 id = le64_to_cpu(req->VolatileFileId);
4466                 pid = le64_to_cpu(req->PersistentFileId);
4467         }
4468
4469         fp = ksmbd_lookup_fd_slow(work, id, pid);
4470         if (!fp)
4471                 return -ENOENT;
4472
4473         fileinfoclass = req->FileInfoClass;
4474
4475         switch (fileinfoclass) {
4476         case FILE_ACCESS_INFORMATION:
4477                 get_file_access_info(rsp, fp, rsp_org);
4478                 file_infoclass_size = FILE_ACCESS_INFORMATION_SIZE;
4479                 break;
4480
4481         case FILE_BASIC_INFORMATION:
4482                 rc = get_file_basic_info(rsp, fp, rsp_org);
4483                 file_infoclass_size = FILE_BASIC_INFORMATION_SIZE;
4484                 break;
4485
4486         case FILE_STANDARD_INFORMATION:
4487                 get_file_standard_info(rsp, fp, rsp_org);
4488                 file_infoclass_size = FILE_STANDARD_INFORMATION_SIZE;
4489                 break;
4490
4491         case FILE_ALIGNMENT_INFORMATION:
4492                 get_file_alignment_info(rsp, rsp_org);
4493                 file_infoclass_size = FILE_ALIGNMENT_INFORMATION_SIZE;
4494                 break;
4495
4496         case FILE_ALL_INFORMATION:
4497                 rc = get_file_all_info(work, rsp, fp, rsp_org);
4498                 file_infoclass_size = FILE_ALL_INFORMATION_SIZE;
4499                 break;
4500
4501         case FILE_ALTERNATE_NAME_INFORMATION:
4502                 get_file_alternate_info(work, rsp, fp, rsp_org);
4503                 file_infoclass_size = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
4504                 break;
4505
4506         case FILE_STREAM_INFORMATION:
4507                 get_file_stream_info(work, rsp, fp, rsp_org);
4508                 file_infoclass_size = FILE_STREAM_INFORMATION_SIZE;
4509                 break;
4510
4511         case FILE_INTERNAL_INFORMATION:
4512                 get_file_internal_info(rsp, fp, rsp_org);
4513                 file_infoclass_size = FILE_INTERNAL_INFORMATION_SIZE;
4514                 break;
4515
4516         case FILE_NETWORK_OPEN_INFORMATION:
4517                 rc = get_file_network_open_info(rsp, fp, rsp_org);
4518                 file_infoclass_size = FILE_NETWORK_OPEN_INFORMATION_SIZE;
4519                 break;
4520
4521         case FILE_EA_INFORMATION:
4522                 get_file_ea_info(rsp, rsp_org);
4523                 file_infoclass_size = FILE_EA_INFORMATION_SIZE;
4524                 break;
4525
4526         case FILE_FULL_EA_INFORMATION:
4527                 rc = smb2_get_ea(work, fp, req, rsp, rsp_org);
4528                 file_infoclass_size = FILE_FULL_EA_INFORMATION_SIZE;
4529                 break;
4530
4531         case FILE_POSITION_INFORMATION:
4532                 get_file_position_info(rsp, fp, rsp_org);
4533                 file_infoclass_size = FILE_POSITION_INFORMATION_SIZE;
4534                 break;
4535
4536         case FILE_MODE_INFORMATION:
4537                 get_file_mode_info(rsp, fp, rsp_org);
4538                 file_infoclass_size = FILE_MODE_INFORMATION_SIZE;
4539                 break;
4540
4541         case FILE_COMPRESSION_INFORMATION:
4542                 get_file_compression_info(rsp, fp, rsp_org);
4543                 file_infoclass_size = FILE_COMPRESSION_INFORMATION_SIZE;
4544                 break;
4545
4546         case FILE_ATTRIBUTE_TAG_INFORMATION:
4547                 rc = get_file_attribute_tag_info(rsp, fp, rsp_org);
4548                 file_infoclass_size = FILE_ATTRIBUTE_TAG_INFORMATION_SIZE;
4549                 break;
4550         case SMB_FIND_FILE_POSIX_INFO:
4551                 if (!work->tcon->posix_extensions) {
4552                         ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
4553                         rc = -EOPNOTSUPP;
4554                 } else {
4555                         rc = find_file_posix_info(rsp, fp, rsp_org);
4556                         file_infoclass_size = sizeof(struct smb311_posix_qinfo);
4557                 }
4558                 break;
4559         default:
4560                 ksmbd_debug(SMB, "fileinfoclass %d not supported yet\n",
4561                             fileinfoclass);
4562                 rc = -EOPNOTSUPP;
4563         }
4564         if (!rc)
4565                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4566                                       rsp,
4567                                       file_infoclass_size);
4568         ksmbd_fd_put(work, fp);
4569         return rc;
4570 }
4571
4572 static int smb2_get_info_filesystem(struct ksmbd_work *work,
4573                 struct smb2_query_info_req *req,
4574                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4575 {
4576         struct ksmbd_session *sess = work->sess;
4577         struct ksmbd_conn *conn = sess->conn;
4578         struct ksmbd_share_config *share = work->tcon->share_conf;
4579         int fsinfoclass = 0;
4580         struct kstatfs stfs;
4581         struct path path;
4582         int rc = 0, len;
4583         int fs_infoclass_size = 0;
4584
4585         rc = ksmbd_vfs_kern_path(share->path, LOOKUP_FOLLOW, &path, 0);
4586         if (rc) {
4587                 ksmbd_err("cannot create vfs path\n");
4588                 return -EIO;
4589         }
4590
4591         rc = vfs_statfs(&path, &stfs);
4592         if (rc) {
4593                 ksmbd_err("cannot do stat of path %s\n", share->path);
4594                 path_put(&path);
4595                 return -EIO;
4596         }
4597
4598         fsinfoclass = req->FileInfoClass;
4599
4600         switch (fsinfoclass) {
4601         case FS_DEVICE_INFORMATION:
4602         {
4603                 struct filesystem_device_info *info;
4604
4605                 info = (struct filesystem_device_info *)rsp->Buffer;
4606
4607                 info->DeviceType = cpu_to_le32(stfs.f_type);
4608                 info->DeviceCharacteristics = cpu_to_le32(0x00000020);
4609                 rsp->OutputBufferLength = cpu_to_le32(8);
4610                 inc_rfc1001_len(rsp_org, 8);
4611                 fs_infoclass_size = FS_DEVICE_INFORMATION_SIZE;
4612                 break;
4613         }
4614         case FS_ATTRIBUTE_INFORMATION:
4615         {
4616                 struct filesystem_attribute_info *info;
4617                 size_t sz;
4618
4619                 info = (struct filesystem_attribute_info *)rsp->Buffer;
4620                 info->Attributes = cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS |
4621                                                FILE_PERSISTENT_ACLS |
4622                                                FILE_UNICODE_ON_DISK |
4623                                                FILE_CASE_PRESERVED_NAMES |
4624                                                FILE_CASE_SENSITIVE_SEARCH |
4625                                                FILE_SUPPORTS_BLOCK_REFCOUNTING);
4626
4627                 info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
4628
4629                 info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen);
4630                 len = smbConvertToUTF16((__le16 *)info->FileSystemName,
4631                                         "NTFS", PATH_MAX, conn->local_nls, 0);
4632                 len = len * 2;
4633                 info->FileSystemNameLen = cpu_to_le32(len);
4634                 sz = sizeof(struct filesystem_attribute_info) - 2 + len;
4635                 rsp->OutputBufferLength = cpu_to_le32(sz);
4636                 inc_rfc1001_len(rsp_org, sz);
4637                 fs_infoclass_size = FS_ATTRIBUTE_INFORMATION_SIZE;
4638                 break;
4639         }
4640         case FS_VOLUME_INFORMATION:
4641         {
4642                 struct filesystem_vol_info *info;
4643                 size_t sz;
4644
4645                 info = (struct filesystem_vol_info *)(rsp->Buffer);
4646                 info->VolumeCreationTime = 0;
4647                 /* Taking dummy value of serial number*/
4648                 info->SerialNumber = cpu_to_le32(0xbc3ac512);
4649                 len = smbConvertToUTF16((__le16 *)info->VolumeLabel,
4650                                         share->name, PATH_MAX,
4651                                         conn->local_nls, 0);
4652                 len = len * 2;
4653                 info->VolumeLabelSize = cpu_to_le32(len);
4654                 info->Reserved = 0;
4655                 sz = sizeof(struct filesystem_vol_info) - 2 + len;
4656                 rsp->OutputBufferLength = cpu_to_le32(sz);
4657                 inc_rfc1001_len(rsp_org, sz);
4658                 fs_infoclass_size = FS_VOLUME_INFORMATION_SIZE;
4659                 break;
4660         }
4661         case FS_SIZE_INFORMATION:
4662         {
4663                 struct filesystem_info *info;
4664                 unsigned short logical_sector_size;
4665
4666                 info = (struct filesystem_info *)(rsp->Buffer);
4667                 logical_sector_size =
4668                         ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4669
4670                 info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
4671                 info->FreeAllocationUnits = cpu_to_le64(stfs.f_bfree);
4672                 info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9);
4673                 info->BytesPerSector = cpu_to_le32(logical_sector_size);
4674                 rsp->OutputBufferLength = cpu_to_le32(24);
4675                 inc_rfc1001_len(rsp_org, 24);
4676                 fs_infoclass_size = FS_SIZE_INFORMATION_SIZE;
4677                 break;
4678         }
4679         case FS_FULL_SIZE_INFORMATION:
4680         {
4681                 struct smb2_fs_full_size_info *info;
4682                 unsigned short logical_sector_size;
4683
4684                 info = (struct smb2_fs_full_size_info *)(rsp->Buffer);
4685                 logical_sector_size =
4686                         ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4687
4688                 info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
4689                 info->CallerAvailableAllocationUnits =
4690                                         cpu_to_le64(stfs.f_bavail);
4691                 info->ActualAvailableAllocationUnits =
4692                                         cpu_to_le64(stfs.f_bfree);
4693                 info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9);
4694                 info->BytesPerSector = cpu_to_le32(logical_sector_size);
4695                 rsp->OutputBufferLength = cpu_to_le32(32);
4696                 inc_rfc1001_len(rsp_org, 32);
4697                 fs_infoclass_size = FS_FULL_SIZE_INFORMATION_SIZE;
4698                 break;
4699         }
4700         case FS_OBJECT_ID_INFORMATION:
4701         {
4702                 struct object_id_info *info;
4703
4704                 info = (struct object_id_info *)(rsp->Buffer);
4705
4706                 if (!user_guest(sess->user))
4707                         memcpy(info->objid, user_passkey(sess->user), 16);
4708                 else
4709                         memset(info->objid, 0, 16);
4710
4711                 info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC);
4712                 info->extended_info.version = cpu_to_le32(1);
4713                 info->extended_info.release = cpu_to_le32(1);
4714                 info->extended_info.rel_date = 0;
4715                 memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
4716                 rsp->OutputBufferLength = cpu_to_le32(64);
4717                 inc_rfc1001_len(rsp_org, 64);
4718                 fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE;
4719                 break;
4720         }
4721         case FS_SECTOR_SIZE_INFORMATION:
4722         {
4723                 struct smb3_fs_ss_info *info;
4724                 struct ksmbd_fs_sector_size fs_ss;
4725
4726                 info = (struct smb3_fs_ss_info *)(rsp->Buffer);
4727                 ksmbd_vfs_smb2_sector_size(d_inode(path.dentry), &fs_ss);
4728
4729                 info->LogicalBytesPerSector =
4730                                 cpu_to_le32(fs_ss.logical_sector_size);
4731                 info->PhysicalBytesPerSectorForAtomicity =
4732                                 cpu_to_le32(fs_ss.physical_sector_size);
4733                 info->PhysicalBytesPerSectorForPerf =
4734                                 cpu_to_le32(fs_ss.optimal_io_size);
4735                 info->FSEffPhysicalBytesPerSectorForAtomicity =
4736                                 cpu_to_le32(fs_ss.optimal_io_size);
4737                 info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE |
4738                                     SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
4739                 info->ByteOffsetForSectorAlignment = 0;
4740                 info->ByteOffsetForPartitionAlignment = 0;
4741                 rsp->OutputBufferLength = cpu_to_le32(28);
4742                 inc_rfc1001_len(rsp_org, 28);
4743                 fs_infoclass_size = FS_SECTOR_SIZE_INFORMATION_SIZE;
4744                 break;
4745         }
4746         case FS_CONTROL_INFORMATION:
4747         {
4748                 /*
4749                  * TODO : The current implementation is based on
4750                  * test result with win7(NTFS) server. It's need to
4751                  * modify this to get valid Quota values
4752                  * from Linux kernel
4753                  */
4754                 struct smb2_fs_control_info *info;
4755
4756                 info = (struct smb2_fs_control_info *)(rsp->Buffer);
4757                 info->FreeSpaceStartFiltering = 0;
4758                 info->FreeSpaceThreshold = 0;
4759                 info->FreeSpaceStopFiltering = 0;
4760                 info->DefaultQuotaThreshold = cpu_to_le64(SMB2_NO_FID);
4761                 info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID);
4762                 info->Padding = 0;
4763                 rsp->OutputBufferLength = cpu_to_le32(48);
4764                 inc_rfc1001_len(rsp_org, 48);
4765                 fs_infoclass_size = FS_CONTROL_INFORMATION_SIZE;
4766                 break;
4767         }
4768         case FS_POSIX_INFORMATION:
4769         {
4770                 struct filesystem_posix_info *info;
4771                 unsigned short logical_sector_size;
4772
4773                 if (!work->tcon->posix_extensions) {
4774                         ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
4775                         rc = -EOPNOTSUPP;
4776                 } else {
4777                         info = (struct filesystem_posix_info *)(rsp->Buffer);
4778                         logical_sector_size =
4779                                 ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4780                         info->OptimalTransferSize = cpu_to_le32(logical_sector_size);
4781                         info->BlockSize = cpu_to_le32(stfs.f_bsize);
4782                         info->TotalBlocks = cpu_to_le64(stfs.f_blocks);
4783                         info->BlocksAvail = cpu_to_le64(stfs.f_bfree);
4784                         info->UserBlocksAvail = cpu_to_le64(stfs.f_bavail);
4785                         info->TotalFileNodes = cpu_to_le64(stfs.f_files);
4786                         info->FreeFileNodes = cpu_to_le64(stfs.f_ffree);
4787                         rsp->OutputBufferLength = cpu_to_le32(56);
4788                         inc_rfc1001_len(rsp_org, 56);
4789                         fs_infoclass_size = FS_POSIX_INFORMATION_SIZE;
4790                 }
4791                 break;
4792         }
4793         default:
4794                 path_put(&path);
4795                 return -EOPNOTSUPP;
4796         }
4797         rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4798                               rsp,
4799                               fs_infoclass_size);
4800         path_put(&path);
4801         return rc;
4802 }
4803
4804 static int smb2_get_info_sec(struct ksmbd_work *work,
4805                 struct smb2_query_info_req *req,
4806                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4807 {
4808         struct ksmbd_file *fp;
4809         struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL;
4810         struct smb_fattr fattr = {{0}};
4811         struct inode *inode;
4812         __u32 secdesclen;
4813         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
4814         int addition_info = le32_to_cpu(req->AdditionalInformation);
4815         int rc;
4816
4817         if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO)) {
4818                 ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
4819                         addition_info);
4820
4821                 pntsd->revision = cpu_to_le16(1);
4822                 pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED);
4823                 pntsd->osidoffset = 0;
4824                 pntsd->gsidoffset = 0;
4825                 pntsd->sacloffset = 0;
4826                 pntsd->dacloffset = 0;
4827
4828                 secdesclen = sizeof(struct smb_ntsd);
4829                 rsp->OutputBufferLength = cpu_to_le32(secdesclen);
4830                 inc_rfc1001_len(rsp_org, secdesclen);
4831
4832                 return 0;
4833         }
4834
4835         if (work->next_smb2_rcv_hdr_off) {
4836                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
4837                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
4838                                         work->compound_fid);
4839                         id = work->compound_fid;
4840                         pid = work->compound_pfid;
4841                 }
4842         }
4843
4844         if (!HAS_FILE_ID(id)) {
4845                 id = le64_to_cpu(req->VolatileFileId);
4846                 pid = le64_to_cpu(req->PersistentFileId);
4847         }
4848
4849         fp = ksmbd_lookup_fd_slow(work, id, pid);
4850         if (!fp)
4851                 return -ENOENT;
4852
4853         inode = FP_INODE(fp);
4854         ksmbd_acls_fattr(&fattr, inode);
4855
4856         if (test_share_config_flag(work->tcon->share_conf,
4857                                    KSMBD_SHARE_FLAG_ACL_XATTR))
4858                 ksmbd_vfs_get_sd_xattr(work->conn, fp->filp->f_path.dentry, &ppntsd);
4859
4860         rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr);
4861         posix_acl_release(fattr.cf_acls);
4862         posix_acl_release(fattr.cf_dacls);
4863         kfree(ppntsd);
4864         ksmbd_fd_put(work, fp);
4865         if (rc)
4866                 return rc;
4867
4868         rsp->OutputBufferLength = cpu_to_le32(secdesclen);
4869         inc_rfc1001_len(rsp_org, secdesclen);
4870         return 0;
4871 }
4872
4873 /**
4874  * smb2_query_info() - handler for smb2 query info command
4875  * @work:       smb work containing query info request buffer
4876  *
4877  * Return:      0 on success, otherwise error
4878  */
4879 int smb2_query_info(struct ksmbd_work *work)
4880 {
4881         struct smb2_query_info_req *req;
4882         struct smb2_query_info_rsp *rsp, *rsp_org;
4883         int rc = 0;
4884
4885         rsp_org = work->response_buf;
4886         WORK_BUFFERS(work, req, rsp);
4887
4888         ksmbd_debug(SMB, "GOT query info request\n");
4889
4890         switch (req->InfoType) {
4891         case SMB2_O_INFO_FILE:
4892                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
4893                 rc = smb2_get_info_file(work, req, rsp, (void *)rsp_org);
4894                 break;
4895         case SMB2_O_INFO_FILESYSTEM:
4896                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILESYSTEM\n");
4897                 rc = smb2_get_info_filesystem(work, req, rsp, (void *)rsp_org);
4898                 break;
4899         case SMB2_O_INFO_SECURITY:
4900                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
4901                 rc = smb2_get_info_sec(work, req, rsp, (void *)rsp_org);
4902                 break;
4903         default:
4904                 ksmbd_debug(SMB, "InfoType %d not supported yet\n",
4905                         req->InfoType);
4906                 rc = -EOPNOTSUPP;
4907         }
4908
4909         if (rc < 0) {
4910                 if (rc == -EACCES)
4911                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
4912                 else if (rc == -ENOENT)
4913                         rsp->hdr.Status = STATUS_FILE_CLOSED;
4914                 else if (rc == -EIO)
4915                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
4916                 else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0)
4917                         rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
4918                 smb2_set_err_rsp(work);
4919
4920                 ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
4921                               rc);
4922                 return rc;
4923         }
4924         rsp->StructureSize = cpu_to_le16(9);
4925         rsp->OutputBufferOffset = cpu_to_le16(72);
4926         inc_rfc1001_len(rsp_org, 8);
4927         return 0;
4928 }
4929
4930 /**
4931  * smb2_close_pipe() - handler for closing IPC pipe
4932  * @work:       smb work containing close request buffer
4933  *
4934  * Return:      0
4935  */
4936 static noinline int smb2_close_pipe(struct ksmbd_work *work)
4937 {
4938         u64 id;
4939         struct smb2_close_req *req = work->request_buf;
4940         struct smb2_close_rsp *rsp = work->response_buf;
4941
4942         id = le64_to_cpu(req->VolatileFileId);
4943         ksmbd_session_rpc_close(work->sess, id);
4944
4945         rsp->StructureSize = cpu_to_le16(60);
4946         rsp->Flags = 0;
4947         rsp->Reserved = 0;
4948         rsp->CreationTime = 0;
4949         rsp->LastAccessTime = 0;
4950         rsp->LastWriteTime = 0;
4951         rsp->ChangeTime = 0;
4952         rsp->AllocationSize = 0;
4953         rsp->EndOfFile = 0;
4954         rsp->Attributes = 0;
4955         inc_rfc1001_len(rsp, 60);
4956         return 0;
4957 }
4958
4959 /**
4960  * smb2_close() - handler for smb2 close file command
4961  * @work:       smb work containing close request buffer
4962  *
4963  * Return:      0
4964  */
4965 int smb2_close(struct ksmbd_work *work)
4966 {
4967         unsigned int volatile_id = KSMBD_NO_FID;
4968         u64 sess_id;
4969         struct smb2_close_req *req;
4970         struct smb2_close_rsp *rsp;
4971         struct smb2_close_rsp *rsp_org;
4972         struct ksmbd_conn *conn = work->conn;
4973         struct ksmbd_file *fp;
4974         struct inode *inode;
4975         u64 time;
4976         int err = 0;
4977
4978         rsp_org = work->response_buf;
4979         WORK_BUFFERS(work, req, rsp);
4980
4981         if (test_share_config_flag(work->tcon->share_conf,
4982                                    KSMBD_SHARE_FLAG_PIPE)) {
4983                 ksmbd_debug(SMB, "IPC pipe close request\n");
4984                 return smb2_close_pipe(work);
4985         }
4986
4987         sess_id = le64_to_cpu(req->hdr.SessionId);
4988         if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
4989                 sess_id = work->compound_sid;
4990
4991         work->compound_sid = 0;
4992         if (check_session_id(conn, sess_id)) {
4993                 work->compound_sid = sess_id;
4994         } else {
4995                 rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
4996                 if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
4997                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
4998                 err = -EBADF;
4999                 goto out;
5000         }
5001
5002         if (work->next_smb2_rcv_hdr_off &&
5003             !HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
5004                 if (!HAS_FILE_ID(work->compound_fid)) {
5005                         /* file already closed, return FILE_CLOSED */
5006                         ksmbd_debug(SMB, "file already closed\n");
5007                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5008                         err = -EBADF;
5009                         goto out;
5010                 } else {
5011                         ksmbd_debug(SMB, "Compound request set FID = %u:%u\n",
5012                                         work->compound_fid,
5013                                         work->compound_pfid);
5014                         volatile_id = work->compound_fid;
5015
5016                         /* file closed, stored id is not valid anymore */
5017                         work->compound_fid = KSMBD_NO_FID;
5018                         work->compound_pfid = KSMBD_NO_FID;
5019                 }
5020         } else {
5021                 volatile_id = le64_to_cpu(req->VolatileFileId);
5022         }
5023         ksmbd_debug(SMB, "volatile_id = %u\n", volatile_id);
5024
5025         rsp->StructureSize = cpu_to_le16(60);
5026         rsp->Reserved = 0;
5027
5028         if (req->Flags == SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB) {
5029                 fp = ksmbd_lookup_fd_fast(work, volatile_id);
5030                 if (!fp) {
5031                         err = -ENOENT;
5032                         goto out;
5033                 }
5034
5035                 inode = FP_INODE(fp);
5036                 rsp->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
5037                 rsp->AllocationSize = S_ISDIR(inode->i_mode) ? 0 :
5038                         cpu_to_le64(inode->i_blocks << 9);
5039                 rsp->EndOfFile = cpu_to_le64(inode->i_size);
5040                 rsp->Attributes = fp->f_ci->m_fattr;
5041                 rsp->CreationTime = cpu_to_le64(fp->create_time);
5042                 time = ksmbd_UnixTimeToNT(inode->i_atime);
5043                 rsp->LastAccessTime = cpu_to_le64(time);
5044                 time = ksmbd_UnixTimeToNT(inode->i_mtime);
5045                 rsp->LastWriteTime = cpu_to_le64(time);
5046                 time = ksmbd_UnixTimeToNT(inode->i_ctime);
5047                 rsp->ChangeTime = cpu_to_le64(time);
5048                 ksmbd_fd_put(work, fp);
5049         } else {
5050                 rsp->Flags = 0;
5051                 rsp->AllocationSize = 0;
5052                 rsp->EndOfFile = 0;
5053                 rsp->Attributes = 0;
5054                 rsp->CreationTime = 0;
5055                 rsp->LastAccessTime = 0;
5056                 rsp->LastWriteTime = 0;
5057                 rsp->ChangeTime = 0;
5058         }
5059
5060         err = ksmbd_close_fd(work, volatile_id);
5061 out:
5062         if (err) {
5063                 if (rsp->hdr.Status == 0)
5064                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5065                 smb2_set_err_rsp(work);
5066         } else {
5067                 inc_rfc1001_len(rsp_org, 60);
5068         }
5069
5070         return 0;
5071 }
5072
5073 /**
5074  * smb2_echo() - handler for smb2 echo(ping) command
5075  * @work:       smb work containing echo request buffer
5076  *
5077  * Return:      0
5078  */
5079 int smb2_echo(struct ksmbd_work *work)
5080 {
5081         struct smb2_echo_rsp *rsp = work->response_buf;
5082
5083         rsp->StructureSize = cpu_to_le16(4);
5084         rsp->Reserved = 0;
5085         inc_rfc1001_len(rsp, 4);
5086         return 0;
5087 }
5088
5089 static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
5090                 struct smb2_file_rename_info *file_info,
5091                 struct nls_table *local_nls)
5092 {
5093         struct ksmbd_share_config *share = fp->tcon->share_conf;
5094         char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL;
5095         char *pathname = NULL;
5096         struct path path;
5097         bool file_present = true;
5098         int rc;
5099
5100         ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n");
5101         pathname = kmalloc(PATH_MAX, GFP_KERNEL);
5102         if (!pathname)
5103                 return -ENOMEM;
5104
5105         abs_oldname = d_path(&fp->filp->f_path, pathname, PATH_MAX);
5106         if (IS_ERR(abs_oldname)) {
5107                 rc = -EINVAL;
5108                 goto out;
5109         }
5110         old_name = strrchr(abs_oldname, '/');
5111         if (old_name && old_name[1] != '\0') {
5112                 old_name++;
5113         } else {
5114                 ksmbd_debug(SMB, "can't get last component in path %s\n",
5115                                 abs_oldname);
5116                 rc = -ENOENT;
5117                 goto out;
5118         }
5119
5120         new_name = smb2_get_name(share,
5121                                  file_info->FileName,
5122                                  le32_to_cpu(file_info->FileNameLength),
5123                                  local_nls);
5124         if (IS_ERR(new_name)) {
5125                 rc = PTR_ERR(new_name);
5126                 goto out;
5127         }
5128
5129         if (strchr(new_name, ':')) {
5130                 int s_type;
5131                 char *xattr_stream_name, *stream_name = NULL;
5132                 size_t xattr_stream_size;
5133                 int len;
5134
5135                 rc = parse_stream_name(new_name, &stream_name, &s_type);
5136                 if (rc < 0)
5137                         goto out;
5138
5139                 len = strlen(new_name);
5140                 if (new_name[len - 1] != '/') {
5141                         ksmbd_err("not allow base filename in rename\n");
5142                         rc = -ESHARE;
5143                         goto out;
5144                 }
5145
5146                 rc = ksmbd_vfs_xattr_stream_name(stream_name,
5147                                                  &xattr_stream_name,
5148                                                  &xattr_stream_size,
5149                                                  s_type);
5150                 if (rc)
5151                         goto out;
5152
5153                 rc = ksmbd_vfs_setxattr(fp->filp->f_path.dentry,
5154                                         xattr_stream_name,
5155                                         NULL, 0, 0);
5156                 if (rc < 0) {
5157                         ksmbd_err("failed to store stream name in xattr: %d\n",
5158                                    rc);
5159                         rc = -EINVAL;
5160                         goto out;
5161                 }
5162
5163                 goto out;
5164         }
5165
5166         ksmbd_debug(SMB, "new name %s\n", new_name);
5167         rc = ksmbd_vfs_kern_path(new_name, 0, &path, 1);
5168         if (rc)
5169                 file_present = false;
5170         else
5171                 path_put(&path);
5172
5173         if (ksmbd_share_veto_filename(share, new_name)) {
5174                 rc = -ENOENT;
5175                 ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name);
5176                 goto out;
5177         }
5178
5179         if (file_info->ReplaceIfExists) {
5180                 if (file_present) {
5181                         rc = ksmbd_vfs_remove_file(work, new_name);
5182                         if (rc) {
5183                                 if (rc != -ENOTEMPTY)
5184                                         rc = -EINVAL;
5185                                 ksmbd_debug(SMB, "cannot delete %s, rc %d\n",
5186                                                 new_name, rc);
5187                                 goto out;
5188                         }
5189                 }
5190         } else {
5191                 if (file_present &&
5192                     strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) {
5193                         rc = -EEXIST;
5194                         ksmbd_debug(SMB,
5195                                 "cannot rename already existing file\n");
5196                         goto out;
5197                 }
5198         }
5199
5200         rc = ksmbd_vfs_fp_rename(work, fp, new_name);
5201 out:
5202         kfree(pathname);
5203         if (!IS_ERR(new_name))
5204                 kfree(new_name);
5205         return rc;
5206 }
5207
5208 static int smb2_create_link(struct ksmbd_work *work,
5209                 struct ksmbd_share_config *share,
5210                 struct smb2_file_link_info *file_info, struct file *filp,
5211                 struct nls_table *local_nls)
5212 {
5213         char *link_name = NULL, *target_name = NULL, *pathname = NULL;
5214         struct path path;
5215         bool file_present = true;
5216         int rc;
5217
5218         ksmbd_debug(SMB, "setting FILE_LINK_INFORMATION\n");
5219         pathname = kmalloc(PATH_MAX, GFP_KERNEL);
5220         if (!pathname)
5221                 return -ENOMEM;
5222
5223         link_name = smb2_get_name(share,
5224                                   file_info->FileName,
5225                                   le32_to_cpu(file_info->FileNameLength),
5226                                   local_nls);
5227         if (IS_ERR(link_name) || S_ISDIR(file_inode(filp)->i_mode)) {
5228                 rc = -EINVAL;
5229                 goto out;
5230         }
5231
5232         ksmbd_debug(SMB, "link name is %s\n", link_name);
5233         target_name = d_path(&filp->f_path, pathname, PATH_MAX);
5234         if (IS_ERR(target_name)) {
5235                 rc = -EINVAL;
5236                 goto out;
5237         }
5238
5239         ksmbd_debug(SMB, "target name is %s\n", target_name);
5240         rc = ksmbd_vfs_kern_path(link_name, 0, &path, 0);
5241         if (rc)
5242                 file_present = false;
5243         else
5244                 path_put(&path);
5245
5246         if (file_info->ReplaceIfExists) {
5247                 if (file_present) {
5248                         rc = ksmbd_vfs_remove_file(work, link_name);
5249                         if (rc) {
5250                                 rc = -EINVAL;
5251                                 ksmbd_debug(SMB, "cannot delete %s\n",
5252                                         link_name);
5253                                 goto out;
5254                         }
5255                 }
5256         } else {
5257                 if (file_present) {
5258                         rc = -EEXIST;
5259                         ksmbd_debug(SMB, "link already exists\n");
5260                         goto out;
5261                 }
5262         }
5263
5264         rc = ksmbd_vfs_link(work, target_name, link_name);
5265         if (rc)
5266                 rc = -EINVAL;
5267 out:
5268         if (!IS_ERR(link_name))
5269                 kfree(link_name);
5270         kfree(pathname);
5271         return rc;
5272 }
5273
5274 static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
5275                 struct ksmbd_share_config *share)
5276 {
5277         struct smb2_file_all_info *file_info;
5278         struct iattr attrs;
5279         struct iattr temp_attrs;
5280         struct file *filp;
5281         struct inode *inode;
5282         int rc;
5283
5284         if (!(fp->daccess & FILE_WRITE_ATTRIBUTES_LE))
5285                 return -EACCES;
5286
5287         file_info = (struct smb2_file_all_info *)buf;
5288         attrs.ia_valid = 0;
5289         filp = fp->filp;
5290         inode = file_inode(filp);
5291
5292         if (file_info->CreationTime)
5293                 fp->create_time = le64_to_cpu(file_info->CreationTime);
5294
5295         if (file_info->LastAccessTime) {
5296                 attrs.ia_atime = ksmbd_NTtimeToUnix(file_info->LastAccessTime);
5297                 attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
5298         }
5299
5300         if (file_info->ChangeTime) {
5301                 temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
5302                 attrs.ia_ctime = temp_attrs.ia_ctime;
5303                 attrs.ia_valid |= ATTR_CTIME;
5304         } else {
5305                 temp_attrs.ia_ctime = inode->i_ctime;
5306         }
5307
5308         if (file_info->LastWriteTime) {
5309                 attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
5310                 attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
5311         }
5312
5313         if (file_info->Attributes) {
5314                 if (!S_ISDIR(inode->i_mode) &&
5315                     file_info->Attributes & ATTR_DIRECTORY_LE) {
5316                         ksmbd_err("can't change a file to a directory\n");
5317                         return -EINVAL;
5318                 }
5319
5320                 if (!(S_ISDIR(inode->i_mode) && file_info->Attributes == ATTR_NORMAL_LE))
5321                         fp->f_ci->m_fattr = file_info->Attributes |
5322                                 (fp->f_ci->m_fattr & ATTR_DIRECTORY_LE);
5323         }
5324
5325         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS) &&
5326             (file_info->CreationTime || file_info->Attributes)) {
5327                 struct xattr_dos_attrib da = {0};
5328
5329                 da.version = 4;
5330                 da.itime = fp->itime;
5331                 da.create_time = fp->create_time;
5332                 da.attr = le32_to_cpu(fp->f_ci->m_fattr);
5333                 da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
5334                         XATTR_DOSINFO_ITIME;
5335
5336                 rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da);
5337                 if (rc)
5338                         ksmbd_debug(SMB,
5339                                 "failed to restore file attribute in EA\n");
5340                 rc = 0;
5341         }
5342
5343         /*
5344          * HACK : set ctime here to avoid ctime changed
5345          * when file_info->ChangeTime is zero.
5346          */
5347         attrs.ia_ctime = temp_attrs.ia_ctime;
5348         attrs.ia_valid |= ATTR_CTIME;
5349
5350         if (attrs.ia_valid) {
5351                 struct dentry *dentry = filp->f_path.dentry;
5352                 struct inode *inode = d_inode(dentry);
5353
5354                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
5355                         return -EACCES;
5356
5357                 rc = setattr_prepare(&init_user_ns, dentry, &attrs);
5358                 if (rc)
5359                         return -EINVAL;
5360
5361                 inode_lock(inode);
5362                 setattr_copy(&init_user_ns, inode, &attrs);
5363                 attrs.ia_valid &= ~ATTR_CTIME;
5364                 rc = notify_change(&init_user_ns, dentry, &attrs, NULL);
5365                 inode_unlock(inode);
5366         }
5367         return 0;
5368 }
5369
5370 static int set_file_allocation_info(struct ksmbd_work *work,
5371                 struct ksmbd_file *fp, char *buf)
5372 {
5373         /*
5374          * TODO : It's working fine only when store dos attributes
5375          * is not yes. need to implement a logic which works
5376          * properly with any smb.conf option
5377          */
5378
5379         struct smb2_file_alloc_info *file_alloc_info;
5380         loff_t alloc_blks;
5381         struct inode *inode;
5382         int rc;
5383
5384         if (!(fp->daccess & FILE_WRITE_DATA_LE))
5385                 return -EACCES;
5386
5387         file_alloc_info = (struct smb2_file_alloc_info *)buf;
5388         alloc_blks = (le64_to_cpu(file_alloc_info->AllocationSize) + 511) >> 9;
5389         inode = file_inode(fp->filp);
5390
5391         if (alloc_blks > inode->i_blocks) {
5392                 rc = ksmbd_vfs_alloc_size(work, fp, alloc_blks * 512);
5393                 if (rc && rc != -EOPNOTSUPP) {
5394                         ksmbd_err("ksmbd_vfs_alloc_size is failed : %d\n", rc);
5395                         return rc;
5396                 }
5397         } else if (alloc_blks < inode->i_blocks) {
5398                 loff_t size;
5399
5400                 /*
5401                  * Allocation size could be smaller than original one
5402                  * which means allocated blocks in file should be
5403                  * deallocated. use truncate to cut out it, but inode
5404                  * size is also updated with truncate offset.
5405                  * inode size is retained by backup inode size.
5406                  */
5407                 size = i_size_read(inode);
5408                 rc = ksmbd_vfs_truncate(work, NULL, fp, alloc_blks * 512);
5409                 if (rc) {
5410                         ksmbd_err("truncate failed! filename : %s, err %d\n",
5411                                   fp->filename, rc);
5412                         return rc;
5413                 }
5414                 if (size < alloc_blks * 512)
5415                         i_size_write(inode, size);
5416         }
5417         return 0;
5418 }
5419
5420 static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5421                 char *buf)
5422 {
5423         struct smb2_file_eof_info *file_eof_info;
5424         loff_t newsize;
5425         struct inode *inode;
5426         int rc;
5427
5428         if (!(fp->daccess & FILE_WRITE_DATA_LE))
5429                 return -EACCES;
5430
5431         file_eof_info = (struct smb2_file_eof_info *)buf;
5432         newsize = le64_to_cpu(file_eof_info->EndOfFile);
5433         inode = file_inode(fp->filp);
5434
5435         /*
5436          * If FILE_END_OF_FILE_INFORMATION of set_info_file is called
5437          * on FAT32 shared device, truncate execution time is too long
5438          * and network error could cause from windows client. because
5439          * truncate of some filesystem like FAT32 fill zero data in
5440          * truncated range.
5441          */
5442         if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
5443                 ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
5444                                 fp->filename, newsize);
5445                 rc = ksmbd_vfs_truncate(work, NULL, fp, newsize);
5446                 if (rc) {
5447                         ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
5448                                         fp->filename, rc);
5449                         if (rc != -EAGAIN)
5450                                 rc = -EBADF;
5451                         return rc;
5452                 }
5453         }
5454         return 0;
5455 }
5456
5457 static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5458                 char *buf)
5459 {
5460         struct ksmbd_file *parent_fp;
5461
5462         if (!(fp->daccess & FILE_DELETE_LE)) {
5463                 ksmbd_err("no right to delete : 0x%x\n", fp->daccess);
5464                 return -EACCES;
5465         }
5466
5467         if (ksmbd_stream_fd(fp))
5468                 goto next;
5469
5470         parent_fp = ksmbd_lookup_fd_inode(PARENT_INODE(fp));
5471         if (parent_fp) {
5472                 if (parent_fp->daccess & FILE_DELETE_LE) {
5473                         ksmbd_err("parent dir is opened with delete access\n");
5474                         return -ESHARE;
5475                 }
5476         }
5477 next:
5478         return smb2_rename(work, fp,
5479                            (struct smb2_file_rename_info *)buf,
5480                            work->sess->conn->local_nls);
5481 }
5482
5483 static int set_file_disposition_info(struct ksmbd_file *fp, char *buf)
5484 {
5485         struct smb2_file_disposition_info *file_info;
5486         struct inode *inode;
5487
5488         if (!(fp->daccess & FILE_DELETE_LE)) {
5489                 ksmbd_err("no right to delete : 0x%x\n", fp->daccess);
5490                 return -EACCES;
5491         }
5492
5493         inode = file_inode(fp->filp);
5494         file_info = (struct smb2_file_disposition_info *)buf;
5495         if (file_info->DeletePending) {
5496                 if (S_ISDIR(inode->i_mode) &&
5497                     ksmbd_vfs_empty_dir(fp) == -ENOTEMPTY)
5498                         return -EBUSY;
5499                 ksmbd_set_inode_pending_delete(fp);
5500         } else {
5501                 ksmbd_clear_inode_pending_delete(fp);
5502         }
5503         return 0;
5504 }
5505
5506 static int set_file_position_info(struct ksmbd_file *fp, char *buf)
5507 {
5508         struct smb2_file_pos_info *file_info;
5509         loff_t current_byte_offset;
5510         unsigned short sector_size;
5511         struct inode *inode;
5512
5513         inode = file_inode(fp->filp);
5514         file_info = (struct smb2_file_pos_info *)buf;
5515         current_byte_offset = le64_to_cpu(file_info->CurrentByteOffset);
5516         sector_size = ksmbd_vfs_logical_sector_size(inode);
5517
5518         if (current_byte_offset < 0 ||
5519             (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE &&
5520              current_byte_offset & (sector_size - 1))) {
5521                 ksmbd_err("CurrentByteOffset is not valid : %llu\n",
5522                         current_byte_offset);
5523                 return -EINVAL;
5524         }
5525
5526         fp->filp->f_pos = current_byte_offset;
5527         return 0;
5528 }
5529
5530 static int set_file_mode_info(struct ksmbd_file *fp, char *buf)
5531 {
5532         struct smb2_file_mode_info *file_info;
5533         __le32 mode;
5534
5535         file_info = (struct smb2_file_mode_info *)buf;
5536         mode = file_info->Mode;
5537
5538         if ((mode & ~FILE_MODE_INFO_MASK) ||
5539             (mode & FILE_SYNCHRONOUS_IO_ALERT_LE &&
5540              mode & FILE_SYNCHRONOUS_IO_NONALERT_LE)) {
5541                 ksmbd_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode));
5542                 return -EINVAL;
5543         }
5544
5545         /*
5546          * TODO : need to implement consideration for
5547          * FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT
5548          */
5549         ksmbd_vfs_set_fadvise(fp->filp, mode);
5550         fp->coption = mode;
5551         return 0;
5552 }
5553
5554 /**
5555  * smb2_set_info_file() - handler for smb2 set info command
5556  * @work:       smb work containing set info command buffer
5557  * @fp:         ksmbd_file pointer
5558  * @info_class: smb2 set info class
5559  * @share:      ksmbd_share_config pointer
5560  *
5561  * Return:      0 on success, otherwise error
5562  * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
5563  */
5564 static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
5565                 int info_class, char *buf, struct ksmbd_share_config *share)
5566 {
5567         switch (info_class) {
5568         case FILE_BASIC_INFORMATION:
5569                 return set_file_basic_info(fp, buf, share);
5570
5571         case FILE_ALLOCATION_INFORMATION:
5572                 return set_file_allocation_info(work, fp, buf);
5573
5574         case FILE_END_OF_FILE_INFORMATION:
5575                 return set_end_of_file_info(work, fp, buf);
5576
5577         case FILE_RENAME_INFORMATION:
5578                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5579                         ksmbd_debug(SMB,
5580                                 "User does not have write permission\n");
5581                         return -EACCES;
5582                 }
5583                 return set_rename_info(work, fp, buf);
5584
5585         case FILE_LINK_INFORMATION:
5586                 return smb2_create_link(work, work->tcon->share_conf,
5587                         (struct smb2_file_link_info *)buf, fp->filp,
5588                                 work->sess->conn->local_nls);
5589
5590         case FILE_DISPOSITION_INFORMATION:
5591                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5592                         ksmbd_debug(SMB,
5593                                 "User does not have write permission\n");
5594                         return -EACCES;
5595                 }
5596                 return set_file_disposition_info(fp, buf);
5597
5598         case FILE_FULL_EA_INFORMATION:
5599         {
5600                 if (!(fp->daccess & FILE_WRITE_EA_LE)) {
5601                         ksmbd_err("Not permitted to write ext  attr: 0x%x\n",
5602                                   fp->daccess);
5603                         return -EACCES;
5604                 }
5605
5606                 return smb2_set_ea((struct smb2_ea_info *)buf,
5607                                    &fp->filp->f_path);
5608         }
5609
5610         case FILE_POSITION_INFORMATION:
5611                 return set_file_position_info(fp, buf);
5612
5613         case FILE_MODE_INFORMATION:
5614                 return set_file_mode_info(fp, buf);
5615         }
5616
5617         ksmbd_err("Unimplemented Fileinfoclass :%d\n", info_class);
5618         return -EOPNOTSUPP;
5619 }
5620
5621 static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
5622                 char *buffer, int buf_len)
5623 {
5624         struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer;
5625
5626         fp->saccess |= FILE_SHARE_DELETE_LE;
5627
5628         return set_info_sec(fp->conn, fp->tcon, fp->filp->f_path.dentry, pntsd,
5629                         buf_len, false);
5630 }
5631
5632 /**
5633  * smb2_set_info() - handler for smb2 set info command handler
5634  * @work:       smb work containing set info request buffer
5635  *
5636  * Return:      0 on success, otherwise error
5637  */
5638 int smb2_set_info(struct ksmbd_work *work)
5639 {
5640         struct smb2_set_info_req *req;
5641         struct smb2_set_info_rsp *rsp, *rsp_org;
5642         struct ksmbd_file *fp;
5643         int rc = 0;
5644         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
5645
5646         ksmbd_debug(SMB, "Received set info request\n");
5647
5648         rsp_org = work->response_buf;
5649         if (work->next_smb2_rcv_hdr_off) {
5650                 req = REQUEST_BUF_NEXT(work);
5651                 rsp = RESPONSE_BUF_NEXT(work);
5652                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
5653                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
5654                                         work->compound_fid);
5655                         id = work->compound_fid;
5656                         pid = work->compound_pfid;
5657                 }
5658         } else {
5659                 req = work->request_buf;
5660                 rsp = work->response_buf;
5661         }
5662
5663         if (!HAS_FILE_ID(id)) {
5664                 id = le64_to_cpu(req->VolatileFileId);
5665                 pid = le64_to_cpu(req->PersistentFileId);
5666         }
5667
5668         fp = ksmbd_lookup_fd_slow(work, id, pid);
5669         if (!fp) {
5670                 ksmbd_debug(SMB, "Invalid id for close: %u\n", id);
5671                 rc = -ENOENT;
5672                 goto err_out;
5673         }
5674
5675         switch (req->InfoType) {
5676         case SMB2_O_INFO_FILE:
5677                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
5678                 rc = smb2_set_info_file(work, fp, req->FileInfoClass,
5679                                         req->Buffer, work->tcon->share_conf);
5680                 break;
5681         case SMB2_O_INFO_SECURITY:
5682                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
5683                 rc = smb2_set_info_sec(fp,
5684                         le32_to_cpu(req->AdditionalInformation), req->Buffer,
5685                         le32_to_cpu(req->BufferLength));
5686                 break;
5687         default:
5688                 rc = -EOPNOTSUPP;
5689         }
5690
5691         if (rc < 0)
5692                 goto err_out;
5693
5694         rsp->StructureSize = cpu_to_le16(2);
5695         inc_rfc1001_len(rsp_org, 2);
5696         ksmbd_fd_put(work, fp);
5697         return 0;
5698
5699 err_out:
5700         if (rc == -EACCES || rc == -EPERM)
5701                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
5702         else if (rc == -EINVAL)
5703                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5704         else if (rc == -ESHARE)
5705                 rsp->hdr.Status = STATUS_SHARING_VIOLATION;
5706         else if (rc == -ENOENT)
5707                 rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
5708         else if (rc == -EBUSY || rc == -ENOTEMPTY)
5709                 rsp->hdr.Status = STATUS_DIRECTORY_NOT_EMPTY;
5710         else if (rc == -EAGAIN)
5711                 rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
5712         else if (rc == -EBADF || rc == -ESTALE)
5713                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
5714         else if (rc == -EEXIST)
5715                 rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
5716         else if (rsp->hdr.Status == 0 || rc == -EOPNOTSUPP)
5717                 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
5718         smb2_set_err_rsp(work);
5719         ksmbd_fd_put(work, fp);
5720         ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
5721                         rc);
5722         return rc;
5723 }
5724
5725 /**
5726  * smb2_read_pipe() - handler for smb2 read from IPC pipe
5727  * @work:       smb work containing read IPC pipe command buffer
5728  *
5729  * Return:      0 on success, otherwise error
5730  */
5731 static noinline int smb2_read_pipe(struct ksmbd_work *work)
5732 {
5733         int nbytes = 0, err;
5734         u64 id;
5735         struct ksmbd_rpc_command *rpc_resp;
5736         struct smb2_read_req *req = work->request_buf;
5737         struct smb2_read_rsp *rsp = work->response_buf;
5738
5739         id = le64_to_cpu(req->VolatileFileId);
5740
5741         inc_rfc1001_len(rsp, 16);
5742         rpc_resp = ksmbd_rpc_read(work->sess, id);
5743         if (rpc_resp) {
5744                 if (rpc_resp->flags != KSMBD_RPC_OK) {
5745                         err = -EINVAL;
5746                         goto out;
5747                 }
5748
5749                 work->aux_payload_buf =
5750                         kvmalloc(rpc_resp->payload_sz, GFP_KERNEL | __GFP_ZERO);
5751                 if (!work->aux_payload_buf) {
5752                         err = -ENOMEM;
5753                         goto out;
5754                 }
5755
5756                 memcpy(work->aux_payload_buf, rpc_resp->payload,
5757                         rpc_resp->payload_sz);
5758
5759                 nbytes = rpc_resp->payload_sz;
5760                 work->resp_hdr_sz = get_rfc1002_len(rsp) + 4;
5761                 work->aux_payload_sz = nbytes;
5762                 kvfree(rpc_resp);
5763         }
5764
5765         rsp->StructureSize = cpu_to_le16(17);
5766         rsp->DataOffset = 80;
5767         rsp->Reserved = 0;
5768         rsp->DataLength = cpu_to_le32(nbytes);
5769         rsp->DataRemaining = 0;
5770         rsp->Reserved2 = 0;
5771         inc_rfc1001_len(rsp, nbytes);
5772         return 0;
5773
5774 out:
5775         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
5776         smb2_set_err_rsp(work);
5777         kvfree(rpc_resp);
5778         return err;
5779 }
5780
5781 static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
5782                 struct smb2_read_req *req, void *data_buf, size_t length)
5783 {
5784         struct smb2_buffer_desc_v1 *desc =
5785                 (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
5786         int err;
5787
5788         if (work->conn->dialect == SMB30_PROT_ID &&
5789             req->Channel != SMB2_CHANNEL_RDMA_V1)
5790                 return -EINVAL;
5791
5792         if (req->ReadChannelInfoOffset == 0 ||
5793             le16_to_cpu(req->ReadChannelInfoLength) < sizeof(*desc))
5794                 return -EINVAL;
5795
5796         work->need_invalidate_rkey =
5797                 (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
5798         work->remote_key = le32_to_cpu(desc->token);
5799
5800         err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
5801                         le32_to_cpu(desc->token), le64_to_cpu(desc->offset),
5802                         le32_to_cpu(desc->length));
5803         if (err)
5804                 return err;
5805
5806         return length;
5807 }
5808
5809 /**
5810  * smb2_read() - handler for smb2 read from file
5811  * @work:       smb work containing read command buffer
5812  *
5813  * Return:      0 on success, otherwise error
5814  */
5815 int smb2_read(struct ksmbd_work *work)
5816 {
5817         struct ksmbd_conn *conn = work->conn;
5818         struct smb2_read_req *req;
5819         struct smb2_read_rsp *rsp, *rsp_org;
5820         struct ksmbd_file *fp;
5821         loff_t offset;
5822         size_t length, mincount;
5823         ssize_t nbytes = 0, remain_bytes = 0;
5824         int err = 0;
5825
5826         rsp_org = work->response_buf;
5827         WORK_BUFFERS(work, req, rsp);
5828
5829         if (test_share_config_flag(work->tcon->share_conf,
5830                                    KSMBD_SHARE_FLAG_PIPE)) {
5831                 ksmbd_debug(SMB, "IPC pipe read request\n");
5832                 return smb2_read_pipe(work);
5833         }
5834
5835         fp = ksmbd_lookup_fd_slow(work,
5836                         le64_to_cpu(req->VolatileFileId),
5837                         le64_to_cpu(req->PersistentFileId));
5838         if (!fp) {
5839                 err = -ENOENT;
5840                 goto out;
5841         }
5842
5843         if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
5844                 ksmbd_err("Not permitted to read : 0x%x\n", fp->daccess);
5845                 err = -EACCES;
5846                 goto out;
5847         }
5848
5849         offset = le64_to_cpu(req->Offset);
5850         length = le32_to_cpu(req->Length);
5851         mincount = le32_to_cpu(req->MinimumCount);
5852
5853         if (length > conn->vals->max_read_size) {
5854                 ksmbd_debug(SMB, "limiting read size to max size(%u)\n",
5855                             conn->vals->max_read_size);
5856                 err = -EINVAL;
5857                 goto out;
5858         }
5859
5860         ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp),
5861                 offset, length);
5862
5863         if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) {
5864                 work->aux_payload_buf =
5865                         ksmbd_find_buffer(conn->vals->max_read_size);
5866                 work->set_read_buf = true;
5867         } else {
5868                 work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
5869         }
5870         if (!work->aux_payload_buf) {
5871                 err = -ENOMEM;
5872                 goto out;
5873         }
5874
5875         nbytes = ksmbd_vfs_read(work, fp, length, &offset);
5876         if (nbytes < 0) {
5877                 err = nbytes;
5878                 goto out;
5879         }
5880
5881         if ((nbytes == 0 && length != 0) || nbytes < mincount) {
5882                 if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF)
5883                         ksmbd_release_buffer(work->aux_payload_buf);
5884                 else
5885                         kvfree(work->aux_payload_buf);
5886                 work->aux_payload_buf = NULL;
5887                 rsp->hdr.Status = STATUS_END_OF_FILE;
5888                 smb2_set_err_rsp(work);
5889                 ksmbd_fd_put(work, fp);
5890                 return 0;
5891         }
5892
5893         ksmbd_debug(SMB, "nbytes %zu, offset %lld mincount %zu\n",
5894                                                 nbytes, offset, mincount);
5895
5896         if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
5897             req->Channel == SMB2_CHANNEL_RDMA_V1) {
5898                 /* write data to the client using rdma channel */
5899                 remain_bytes = smb2_read_rdma_channel(work, req,
5900                                                 work->aux_payload_buf, nbytes);
5901                 if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF)
5902                         ksmbd_release_buffer(work->aux_payload_buf);
5903                 else
5904                         kvfree(work->aux_payload_buf);
5905                 work->aux_payload_buf = NULL;
5906
5907                 nbytes = 0;
5908                 if (remain_bytes < 0) {
5909                         err = (int)remain_bytes;
5910                         goto out;
5911                 }
5912         }
5913
5914         rsp->StructureSize = cpu_to_le16(17);
5915         rsp->DataOffset = 80;
5916         rsp->Reserved = 0;
5917         rsp->DataLength = cpu_to_le32(nbytes);
5918         rsp->DataRemaining = cpu_to_le32(remain_bytes);
5919         rsp->Reserved2 = 0;
5920         inc_rfc1001_len(rsp_org, 16);
5921         work->resp_hdr_sz = get_rfc1002_len(rsp_org) + 4;
5922         work->aux_payload_sz = nbytes;
5923         inc_rfc1001_len(rsp_org, nbytes);
5924         ksmbd_fd_put(work, fp);
5925         return 0;
5926
5927 out:
5928         if (err) {
5929                 if (err == -EISDIR)
5930                         rsp->hdr.Status = STATUS_INVALID_DEVICE_REQUEST;
5931                 else if (err == -EAGAIN)
5932                         rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
5933                 else if (err == -ENOENT)
5934                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5935                 else if (err == -EACCES)
5936                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
5937                 else if (err == -ESHARE)
5938                         rsp->hdr.Status = STATUS_SHARING_VIOLATION;
5939                 else if (err == -EINVAL)
5940                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5941                 else
5942                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
5943
5944                 smb2_set_err_rsp(work);
5945         }
5946         ksmbd_fd_put(work, fp);
5947         return err;
5948 }
5949
5950 /**
5951  * smb2_write_pipe() - handler for smb2 write on IPC pipe
5952  * @work:       smb work containing write IPC pipe command buffer
5953  *
5954  * Return:      0 on success, otherwise error
5955  */
5956 static noinline int smb2_write_pipe(struct ksmbd_work *work)
5957 {
5958         struct smb2_write_req *req = work->request_buf;
5959         struct smb2_write_rsp *rsp = work->response_buf;
5960         struct ksmbd_rpc_command *rpc_resp;
5961         u64 id = 0;
5962         int err = 0, ret = 0;
5963         char *data_buf;
5964         size_t length;
5965
5966         length = le32_to_cpu(req->Length);
5967         id = le64_to_cpu(req->VolatileFileId);
5968
5969         if (le16_to_cpu(req->DataOffset) ==
5970             (offsetof(struct smb2_write_req, Buffer) - 4)) {
5971                 data_buf = (char *)&req->Buffer[0];
5972         } else {
5973                 if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
5974                     (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
5975                         ksmbd_err("invalid write data offset %u, smb_len %u\n",
5976                                 le16_to_cpu(req->DataOffset), get_rfc1002_len(req));
5977                         err = -EINVAL;
5978                         goto out;
5979                 }
5980
5981                 data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
5982                                 le16_to_cpu(req->DataOffset));
5983         }
5984
5985         rpc_resp = ksmbd_rpc_write(work->sess, id, data_buf, length);
5986         if (rpc_resp) {
5987                 if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
5988                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
5989                         kvfree(rpc_resp);
5990                         smb2_set_err_rsp(work);
5991                         return -EOPNOTSUPP;
5992                 }
5993                 if (rpc_resp->flags != KSMBD_RPC_OK) {
5994                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
5995                         smb2_set_err_rsp(work);
5996                         kvfree(rpc_resp);
5997                         return ret;
5998                 }
5999                 kvfree(rpc_resp);
6000         }
6001
6002         rsp->StructureSize = cpu_to_le16(17);
6003         rsp->DataOffset = 0;
6004         rsp->Reserved = 0;
6005         rsp->DataLength = cpu_to_le32(length);
6006         rsp->DataRemaining = 0;
6007         rsp->Reserved2 = 0;
6008         inc_rfc1001_len(rsp, 16);
6009         return 0;
6010 out:
6011         if (err) {
6012                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6013                 smb2_set_err_rsp(work);
6014         }
6015
6016         return err;
6017 }
6018
6019 static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
6020                 struct smb2_write_req *req, struct ksmbd_file *fp,
6021                 loff_t offset, size_t length, bool sync)
6022 {
6023         struct smb2_buffer_desc_v1 *desc;
6024         char *data_buf;
6025         int ret;
6026         ssize_t nbytes;
6027
6028         desc = (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
6029
6030         if (work->conn->dialect == SMB30_PROT_ID &&
6031             req->Channel != SMB2_CHANNEL_RDMA_V1)
6032                 return -EINVAL;
6033
6034         if (req->Length != 0 || req->DataOffset != 0)
6035                 return -EINVAL;
6036
6037         if (req->WriteChannelInfoOffset == 0 ||
6038             le16_to_cpu(req->WriteChannelInfoLength) < sizeof(*desc))
6039                 return -EINVAL;
6040
6041         work->need_invalidate_rkey =
6042                 (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
6043         work->remote_key = le32_to_cpu(desc->token);
6044
6045         data_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
6046         if (!data_buf)
6047                 return -ENOMEM;
6048
6049         ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
6050                                 le32_to_cpu(desc->token),
6051                                 le64_to_cpu(desc->offset),
6052                                 le32_to_cpu(desc->length));
6053         if (ret < 0) {
6054                 kvfree(data_buf);
6055                 return ret;
6056         }
6057
6058         ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes);
6059         kvfree(data_buf);
6060         if (ret < 0)
6061                 return ret;
6062
6063         return nbytes;
6064 }
6065
6066 /**
6067  * smb2_write() - handler for smb2 write from file
6068  * @work:       smb work containing write command buffer
6069  *
6070  * Return:      0 on success, otherwise error
6071  */
6072 int smb2_write(struct ksmbd_work *work)
6073 {
6074         struct smb2_write_req *req;
6075         struct smb2_write_rsp *rsp, *rsp_org;
6076         struct ksmbd_file *fp = NULL;
6077         loff_t offset;
6078         size_t length;
6079         ssize_t nbytes;
6080         char *data_buf;
6081         bool writethrough = false;
6082         int err = 0;
6083
6084         rsp_org = work->response_buf;
6085         WORK_BUFFERS(work, req, rsp);
6086
6087         if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
6088                 ksmbd_debug(SMB, "IPC pipe write request\n");
6089                 return smb2_write_pipe(work);
6090         }
6091
6092         if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6093                 ksmbd_debug(SMB, "User does not have write permission\n");
6094                 err = -EACCES;
6095                 goto out;
6096         }
6097
6098         fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId),
6099                 le64_to_cpu(req->PersistentFileId));
6100         if (!fp) {
6101                 err = -ENOENT;
6102                 goto out;
6103         }
6104
6105         if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
6106                 ksmbd_err("Not permitted to write : 0x%x\n", fp->daccess);
6107                 err = -EACCES;
6108                 goto out;
6109         }
6110
6111         offset = le64_to_cpu(req->Offset);
6112         length = le32_to_cpu(req->Length);
6113
6114         if (length > work->conn->vals->max_write_size) {
6115                 ksmbd_debug(SMB, "limiting write size to max size(%u)\n",
6116                             work->conn->vals->max_write_size);
6117                 err = -EINVAL;
6118                 goto out;
6119         }
6120
6121         if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
6122                 writethrough = true;
6123
6124         if (req->Channel != SMB2_CHANNEL_RDMA_V1 &&
6125             req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
6126                 if (le16_to_cpu(req->DataOffset) ==
6127                                 (offsetof(struct smb2_write_req, Buffer) - 4)) {
6128                         data_buf = (char *)&req->Buffer[0];
6129                 } else {
6130                         if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
6131                             (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
6132                                 ksmbd_err("invalid write data offset %u, smb_len %u\n",
6133                                                 le16_to_cpu(req->DataOffset),
6134                                                 get_rfc1002_len(req));
6135                                 err = -EINVAL;
6136                                 goto out;
6137                         }
6138
6139                         data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
6140                                         le16_to_cpu(req->DataOffset));
6141                 }
6142
6143                 ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags));
6144                 if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
6145                         writethrough = true;
6146
6147                 ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n",
6148                         FP_FILENAME(fp), offset, length);
6149                 err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
6150                                       writethrough, &nbytes);
6151                 if (err < 0)
6152                         goto out;
6153         } else {
6154                 /* read data from the client using rdma channel, and
6155                  * write the data.
6156                  */
6157                 nbytes = smb2_write_rdma_channel(work, req, fp, offset,
6158                                         le32_to_cpu(req->RemainingBytes),
6159                                         writethrough);
6160                 if (nbytes < 0) {
6161                         err = (int)nbytes;
6162                         goto out;
6163                 }
6164         }
6165
6166         rsp->StructureSize = cpu_to_le16(17);
6167         rsp->DataOffset = 0;
6168         rsp->Reserved = 0;
6169         rsp->DataLength = cpu_to_le32(nbytes);
6170         rsp->DataRemaining = 0;
6171         rsp->Reserved2 = 0;
6172         inc_rfc1001_len(rsp_org, 16);
6173         ksmbd_fd_put(work, fp);
6174         return 0;
6175
6176 out:
6177         if (err == -EAGAIN)
6178                 rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6179         else if (err == -ENOSPC || err == -EFBIG)
6180                 rsp->hdr.Status = STATUS_DISK_FULL;
6181         else if (err == -ENOENT)
6182                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6183         else if (err == -EACCES)
6184                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
6185         else if (err == -ESHARE)
6186                 rsp->hdr.Status = STATUS_SHARING_VIOLATION;
6187         else if (err == -EINVAL)
6188                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6189         else
6190                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6191
6192         smb2_set_err_rsp(work);
6193         ksmbd_fd_put(work, fp);
6194         return err;
6195 }
6196
6197 /**
6198  * smb2_flush() - handler for smb2 flush file - fsync
6199  * @work:       smb work containing flush command buffer
6200  *
6201  * Return:      0 on success, otherwise error
6202  */
6203 int smb2_flush(struct ksmbd_work *work)
6204 {
6205         struct smb2_flush_req *req;
6206         struct smb2_flush_rsp *rsp, *rsp_org;
6207         int err;
6208
6209         rsp_org = work->response_buf;
6210         WORK_BUFFERS(work, req, rsp);
6211
6212         ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n",
6213                         le64_to_cpu(req->VolatileFileId));
6214
6215         err = ksmbd_vfs_fsync(work,
6216                               le64_to_cpu(req->VolatileFileId),
6217                               le64_to_cpu(req->PersistentFileId));
6218         if (err)
6219                 goto out;
6220
6221         rsp->StructureSize = cpu_to_le16(4);
6222         rsp->Reserved = 0;
6223         inc_rfc1001_len(rsp_org, 4);
6224         return 0;
6225
6226 out:
6227         if (err) {
6228                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6229                 smb2_set_err_rsp(work);
6230         }
6231
6232         return err;
6233 }
6234
6235 /**
6236  * smb2_cancel() - handler for smb2 cancel command
6237  * @work:       smb work containing cancel command buffer
6238  *
6239  * Return:      0 on success, otherwise error
6240  */
6241 int smb2_cancel(struct ksmbd_work *work)
6242 {
6243         struct ksmbd_conn *conn = work->conn;
6244         struct smb2_hdr *hdr = work->request_buf;
6245         struct smb2_hdr *chdr;
6246         struct ksmbd_work *cancel_work = NULL;
6247         struct list_head *tmp;
6248         int canceled = 0;
6249         struct list_head *command_list;
6250
6251         ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
6252                 hdr->MessageId, hdr->Flags);
6253
6254         if (hdr->Flags & SMB2_FLAGS_ASYNC_COMMAND) {
6255                 command_list = &conn->async_requests;
6256
6257                 spin_lock(&conn->request_lock);
6258                 list_for_each(tmp, command_list) {
6259                         cancel_work = list_entry(tmp, struct ksmbd_work,
6260                                         async_request_entry);
6261                         chdr = cancel_work->request_buf;
6262
6263                         if (cancel_work->async_id !=
6264                             le64_to_cpu(hdr->Id.AsyncId))
6265                                 continue;
6266
6267                         ksmbd_debug(SMB,
6268                                 "smb2 with AsyncId %llu cancelled command = 0x%x\n",
6269                                 le64_to_cpu(hdr->Id.AsyncId),
6270                                 le16_to_cpu(chdr->Command));
6271                         canceled = 1;
6272                         break;
6273                 }
6274                 spin_unlock(&conn->request_lock);
6275         } else {
6276                 command_list = &conn->requests;
6277
6278                 spin_lock(&conn->request_lock);
6279                 list_for_each(tmp, command_list) {
6280                         cancel_work = list_entry(tmp, struct ksmbd_work,
6281                                         request_entry);
6282                         chdr = cancel_work->request_buf;
6283
6284                         if (chdr->MessageId != hdr->MessageId ||
6285                             cancel_work == work)
6286                                 continue;
6287
6288                         ksmbd_debug(SMB,
6289                                 "smb2 with mid %llu cancelled command = 0x%x\n",
6290                                 le64_to_cpu(hdr->MessageId),
6291                                 le16_to_cpu(chdr->Command));
6292                         canceled = 1;
6293                         break;
6294                 }
6295                 spin_unlock(&conn->request_lock);
6296         }
6297
6298         if (canceled) {
6299                 cancel_work->state = KSMBD_WORK_CANCELLED;
6300                 if (cancel_work->cancel_fn)
6301                         cancel_work->cancel_fn(cancel_work->cancel_argv);
6302         }
6303
6304         /* For SMB2_CANCEL command itself send no response*/
6305         work->send_no_response = 1;
6306         return 0;
6307 }
6308
6309 struct file_lock *smb_flock_init(struct file *f)
6310 {
6311         struct file_lock *fl;
6312
6313         fl = locks_alloc_lock();
6314         if (!fl)
6315                 goto out;
6316
6317         locks_init_lock(fl);
6318
6319         fl->fl_owner = f;
6320         fl->fl_pid = current->tgid;
6321         fl->fl_file = f;
6322         fl->fl_flags = FL_POSIX;
6323         fl->fl_ops = NULL;
6324         fl->fl_lmops = NULL;
6325
6326 out:
6327         return fl;
6328 }
6329
6330 static int smb2_set_flock_flags(struct file_lock *flock, int flags)
6331 {
6332         int cmd = -EINVAL;
6333
6334         /* Checking for wrong flag combination during lock request*/
6335         switch (flags) {
6336         case SMB2_LOCKFLAG_SHARED:
6337                 ksmbd_debug(SMB, "received shared request\n");
6338                 cmd = F_SETLKW;
6339                 flock->fl_type = F_RDLCK;
6340                 flock->fl_flags |= FL_SLEEP;
6341                 break;
6342         case SMB2_LOCKFLAG_EXCLUSIVE:
6343                 ksmbd_debug(SMB, "received exclusive request\n");
6344                 cmd = F_SETLKW;
6345                 flock->fl_type = F_WRLCK;
6346                 flock->fl_flags |= FL_SLEEP;
6347                 break;
6348         case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
6349                 ksmbd_debug(SMB,
6350                         "received shared & fail immediately request\n");
6351                 cmd = F_SETLK;
6352                 flock->fl_type = F_RDLCK;
6353                 break;
6354         case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
6355                 ksmbd_debug(SMB,
6356                         "received exclusive & fail immediately request\n");
6357                 cmd = F_SETLK;
6358                 flock->fl_type = F_WRLCK;
6359                 break;
6360         case SMB2_LOCKFLAG_UNLOCK:
6361                 ksmbd_debug(SMB, "received unlock request\n");
6362                 flock->fl_type = F_UNLCK;
6363                 cmd = 0;
6364                 break;
6365         }
6366
6367         return cmd;
6368 }
6369
6370 static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock,
6371                 unsigned int cmd, int flags, struct list_head *lock_list)
6372 {
6373         struct ksmbd_lock *lock;
6374
6375         lock = kzalloc(sizeof(struct ksmbd_lock), GFP_KERNEL);
6376         if (!lock)
6377                 return NULL;
6378
6379         lock->cmd = cmd;
6380         lock->fl = flock;
6381         lock->start = flock->fl_start;
6382         lock->end = flock->fl_end;
6383         lock->flags = flags;
6384         if (lock->start == lock->end)
6385                 lock->zero_len = 1;
6386         INIT_LIST_HEAD(&lock->llist);
6387         INIT_LIST_HEAD(&lock->glist);
6388         list_add_tail(&lock->llist, lock_list);
6389
6390         return lock;
6391 }
6392
6393 static void smb2_remove_blocked_lock(void **argv)
6394 {
6395         struct file_lock *flock = (struct file_lock *)argv[0];
6396
6397         ksmbd_vfs_posix_lock_unblock(flock);
6398         wake_up(&flock->fl_wait);
6399 }
6400
6401 static inline bool lock_defer_pending(struct file_lock *fl)
6402 {
6403         /* check pending lock waiters */
6404         return waitqueue_active(&fl->fl_wait);
6405 }
6406
6407 /**
6408  * smb2_lock() - handler for smb2 file lock command
6409  * @work:       smb work containing lock command buffer
6410  *
6411  * Return:      0 on success, otherwise error
6412  */
6413 int smb2_lock(struct ksmbd_work *work)
6414 {
6415         struct smb2_lock_req *req = work->request_buf;
6416         struct smb2_lock_rsp *rsp = work->response_buf;
6417         struct smb2_lock_element *lock_ele;
6418         struct ksmbd_file *fp = NULL;
6419         struct file_lock *flock = NULL;
6420         struct file *filp = NULL;
6421         int lock_count;
6422         int flags = 0;
6423         int cmd = 0;
6424         int err = 0, i;
6425         u64 lock_start, lock_length;
6426         struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp;
6427         int nolock = 0;
6428         LIST_HEAD(lock_list);
6429         LIST_HEAD(rollback_list);
6430         int prior_lock = 0;
6431
6432         ksmbd_debug(SMB, "Received lock request\n");
6433         fp = ksmbd_lookup_fd_slow(work,
6434                 le64_to_cpu(req->VolatileFileId),
6435                 le64_to_cpu(req->PersistentFileId));
6436         if (!fp) {
6437                 ksmbd_debug(SMB, "Invalid file id for lock : %llu\n",
6438                                 le64_to_cpu(req->VolatileFileId));
6439                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6440                 goto out2;
6441         }
6442
6443         filp = fp->filp;
6444         lock_count = le16_to_cpu(req->LockCount);
6445         lock_ele = req->locks;
6446
6447         ksmbd_debug(SMB, "lock count is %d\n", lock_count);
6448         if (!lock_count)  {
6449                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6450                 goto out2;
6451         }
6452
6453         for (i = 0; i < lock_count; i++) {
6454                 flags = le32_to_cpu(lock_ele[i].Flags);
6455
6456                 flock = smb_flock_init(filp);
6457                 if (!flock) {
6458                         rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6459                         goto out;
6460                 }
6461
6462                 cmd = smb2_set_flock_flags(flock, flags);
6463
6464                 lock_start = le64_to_cpu(lock_ele[i].Offset);
6465                 lock_length = le64_to_cpu(lock_ele[i].Length);
6466                 if (lock_start > U64_MAX - lock_length) {
6467                         ksmbd_err("Invalid lock range requested\n");
6468                         rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
6469                         goto out;
6470                 }
6471
6472                 if (lock_start > OFFSET_MAX)
6473                         flock->fl_start = OFFSET_MAX;
6474                 else
6475                         flock->fl_start = lock_start;
6476
6477                 lock_length = le64_to_cpu(lock_ele[i].Length);
6478                 if (lock_length > OFFSET_MAX - flock->fl_start)
6479                         lock_length = OFFSET_MAX - flock->fl_start;
6480
6481                 flock->fl_end = flock->fl_start + lock_length;
6482
6483                 if (flock->fl_end < flock->fl_start) {
6484                         ksmbd_debug(SMB,
6485                                 "the end offset(%llx) is smaller than the start offset(%llx)\n",
6486                                 flock->fl_end, flock->fl_start);
6487                         rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
6488                         goto out;
6489                 }
6490
6491                 /* Check conflict locks in one request */
6492                 list_for_each_entry(cmp_lock, &lock_list, llist) {
6493                         if (cmp_lock->fl->fl_start <= flock->fl_start &&
6494                             cmp_lock->fl->fl_end >= flock->fl_end) {
6495                                 if (cmp_lock->fl->fl_type != F_UNLCK &&
6496                                     flock->fl_type != F_UNLCK) {
6497                                         ksmbd_err("conflict two locks in one request\n");
6498                                         rsp->hdr.Status =
6499                                                 STATUS_INVALID_PARAMETER;
6500                                         goto out;
6501                                 }
6502                         }
6503                 }
6504
6505                 smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list);
6506                 if (!smb_lock) {
6507                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6508                         goto out;
6509                 }
6510         }
6511
6512         list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
6513                 if (smb_lock->cmd < 0) {
6514                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6515                         goto out;
6516                 }
6517
6518                 if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) {
6519                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6520                         goto out;
6521                 }
6522
6523                 if ((prior_lock & (SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_SHARED) &&
6524                      smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) ||
6525                     (prior_lock == SMB2_LOCKFLAG_UNLOCK &&
6526                      !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) {
6527                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6528                         goto out;
6529                 }
6530
6531                 prior_lock = smb_lock->flags;
6532
6533                 if (!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) &&
6534                     !(smb_lock->flags & SMB2_LOCKFLAG_FAIL_IMMEDIATELY))
6535                         goto no_check_gl;
6536
6537                 nolock = 1;
6538                 /* check locks in global list */
6539                 list_for_each_entry(cmp_lock, &global_lock_list, glist) {
6540                         if (file_inode(cmp_lock->fl->fl_file) !=
6541                             file_inode(smb_lock->fl->fl_file))
6542                                 continue;
6543
6544                         if (smb_lock->fl->fl_type == F_UNLCK) {
6545                                 if (cmp_lock->fl->fl_file == smb_lock->fl->fl_file &&
6546                                     cmp_lock->start == smb_lock->start &&
6547                                     cmp_lock->end == smb_lock->end &&
6548                                     !lock_defer_pending(cmp_lock->fl)) {
6549                                         nolock = 0;
6550                                         locks_free_lock(cmp_lock->fl);
6551                                         list_del(&cmp_lock->glist);
6552                                         kfree(cmp_lock);
6553                                         break;
6554                                 }
6555                                 continue;
6556                         }
6557
6558                         if (cmp_lock->fl->fl_file == smb_lock->fl->fl_file) {
6559                                 if (smb_lock->flags & SMB2_LOCKFLAG_SHARED)
6560                                         continue;
6561                         } else {
6562                                 if (cmp_lock->flags & SMB2_LOCKFLAG_SHARED)
6563                                         continue;
6564                         }
6565
6566                         /* check zero byte lock range */
6567                         if (cmp_lock->zero_len && !smb_lock->zero_len &&
6568                             cmp_lock->start > smb_lock->start &&
6569                             cmp_lock->start < smb_lock->end) {
6570                                 ksmbd_err("previous lock conflict with zero byte lock range\n");
6571                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6572                                         goto out;
6573                         }
6574
6575                         if (smb_lock->zero_len && !cmp_lock->zero_len &&
6576                             smb_lock->start > cmp_lock->start &&
6577                             smb_lock->start < cmp_lock->end) {
6578                                 ksmbd_err("current lock conflict with zero byte lock range\n");
6579                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6580                                         goto out;
6581                         }
6582
6583                         if (((cmp_lock->start <= smb_lock->start &&
6584                               cmp_lock->end > smb_lock->start) ||
6585                              (cmp_lock->start < smb_lock->end && cmp_lock->end >= smb_lock->end)) &&
6586                             !cmp_lock->zero_len && !smb_lock->zero_len) {
6587                                 ksmbd_err("Not allow lock operation on exclusive lock range\n");
6588                                 rsp->hdr.Status =
6589                                         STATUS_LOCK_NOT_GRANTED;
6590                                 goto out;
6591                         }
6592                 }
6593
6594                 if (smb_lock->fl->fl_type == F_UNLCK && nolock) {
6595                         ksmbd_err("Try to unlock nolocked range\n");
6596                         rsp->hdr.Status = STATUS_RANGE_NOT_LOCKED;
6597                         goto out;
6598                 }
6599
6600 no_check_gl:
6601                 if (smb_lock->zero_len) {
6602                         err = 0;
6603                         goto skip;
6604                 }
6605
6606                 flock = smb_lock->fl;
6607                 list_del(&smb_lock->llist);
6608 retry:
6609                 err = ksmbd_vfs_lock(filp, smb_lock->cmd, flock);
6610 skip:
6611                 if (flags & SMB2_LOCKFLAG_UNLOCK) {
6612                         if (!err) {
6613                                 ksmbd_debug(SMB, "File unlocked\n");
6614                         } else if (err == -ENOENT) {
6615                                 rsp->hdr.Status = STATUS_NOT_LOCKED;
6616                                 goto out;
6617                         }
6618                         locks_free_lock(flock);
6619                         kfree(smb_lock);
6620                 } else {
6621                         if (err == FILE_LOCK_DEFERRED) {
6622                                 void **argv;
6623
6624                                 ksmbd_debug(SMB,
6625                                         "would have to wait for getting lock\n");
6626                                 list_add_tail(&smb_lock->glist,
6627                                         &global_lock_list);
6628                                 list_add(&smb_lock->llist, &rollback_list);
6629
6630                                 argv = kmalloc(sizeof(void *), GFP_KERNEL);
6631                                 if (!argv) {
6632                                         err = -ENOMEM;
6633                                         goto out;
6634                                 }
6635                                 argv[0] = flock;
6636
6637                                 err = setup_async_work(work,
6638                                         smb2_remove_blocked_lock, argv);
6639                                 if (err) {
6640                                         rsp->hdr.Status =
6641                                            STATUS_INSUFFICIENT_RESOURCES;
6642                                         goto out;
6643                                 }
6644                                 spin_lock(&fp->f_lock);
6645                                 list_add(&work->fp_entry, &fp->blocked_works);
6646                                 spin_unlock(&fp->f_lock);
6647
6648                                 smb2_send_interim_resp(work, STATUS_PENDING);
6649
6650                                 err = ksmbd_vfs_posix_lock_wait(flock);
6651
6652                                 if (!WORK_ACTIVE(work)) {
6653                                         list_del(&smb_lock->llist);
6654                                         list_del(&smb_lock->glist);
6655                                         locks_free_lock(flock);
6656
6657                                         if (WORK_CANCELLED(work)) {
6658                                                 spin_lock(&fp->f_lock);
6659                                                 list_del(&work->fp_entry);
6660                                                 spin_unlock(&fp->f_lock);
6661                                                 rsp->hdr.Status =
6662                                                         STATUS_CANCELLED;
6663                                                 kfree(smb_lock);
6664                                                 smb2_send_interim_resp(work,
6665                                                         STATUS_CANCELLED);
6666                                                 work->send_no_response = 1;
6667                                                 goto out;
6668                                         }
6669                                         init_smb2_rsp_hdr(work);
6670                                         smb2_set_err_rsp(work);
6671                                         rsp->hdr.Status =
6672                                                 STATUS_RANGE_NOT_LOCKED;
6673                                         kfree(smb_lock);
6674                                         goto out2;
6675                                 }
6676
6677                                 list_del(&smb_lock->llist);
6678                                 list_del(&smb_lock->glist);
6679                                 spin_lock(&fp->f_lock);
6680                                 list_del(&work->fp_entry);
6681                                 spin_unlock(&fp->f_lock);
6682                                 goto retry;
6683                         } else if (!err) {
6684                                 list_add_tail(&smb_lock->glist,
6685                                         &global_lock_list);
6686                                 list_add(&smb_lock->llist, &rollback_list);
6687                                 ksmbd_debug(SMB, "successful in taking lock\n");
6688                         } else {
6689                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6690                                 goto out;
6691                         }
6692                 }
6693         }
6694
6695         if (atomic_read(&fp->f_ci->op_count) > 1)
6696                 smb_break_all_oplock(work, fp);
6697
6698         rsp->StructureSize = cpu_to_le16(4);
6699         ksmbd_debug(SMB, "successful in taking lock\n");
6700         rsp->hdr.Status = STATUS_SUCCESS;
6701         rsp->Reserved = 0;
6702         inc_rfc1001_len(rsp, 4);
6703         ksmbd_fd_put(work, fp);
6704         return err;
6705
6706 out:
6707         list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
6708                 locks_free_lock(smb_lock->fl);
6709                 list_del(&smb_lock->llist);
6710                 kfree(smb_lock);
6711         }
6712
6713         list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) {
6714                 struct file_lock *rlock = NULL;
6715
6716                 rlock = smb_flock_init(filp);
6717                 rlock->fl_type = F_UNLCK;
6718                 rlock->fl_start = smb_lock->start;
6719                 rlock->fl_end = smb_lock->end;
6720
6721                 err = ksmbd_vfs_lock(filp, 0, rlock);
6722                 if (err)
6723                         ksmbd_err("rollback unlock fail : %d\n", err);
6724                 list_del(&smb_lock->llist);
6725                 list_del(&smb_lock->glist);
6726                 locks_free_lock(smb_lock->fl);
6727                 locks_free_lock(rlock);
6728                 kfree(smb_lock);
6729         }
6730 out2:
6731         ksmbd_debug(SMB, "failed in taking lock(flags : %x)\n", flags);
6732         smb2_set_err_rsp(work);
6733         ksmbd_fd_put(work, fp);
6734         return 0;
6735 }
6736
6737 static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
6738                 struct smb2_ioctl_rsp *rsp)
6739 {
6740         struct copychunk_ioctl_req *ci_req;
6741         struct copychunk_ioctl_rsp *ci_rsp;
6742         struct ksmbd_file *src_fp = NULL, *dst_fp = NULL;
6743         struct srv_copychunk *chunks;
6744         unsigned int i, chunk_count, chunk_count_written = 0;
6745         unsigned int chunk_size_written = 0;
6746         loff_t total_size_written = 0;
6747         int ret, cnt_code;
6748
6749         cnt_code = le32_to_cpu(req->CntCode);
6750         ci_req = (struct copychunk_ioctl_req *)&req->Buffer[0];
6751         ci_rsp = (struct copychunk_ioctl_rsp *)&rsp->Buffer[0];
6752
6753         rsp->VolatileFileId = req->VolatileFileId;
6754         rsp->PersistentFileId = req->PersistentFileId;
6755         ci_rsp->ChunksWritten =
6756                 cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
6757         ci_rsp->ChunkBytesWritten =
6758                 cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
6759         ci_rsp->TotalBytesWritten =
6760                 cpu_to_le32(ksmbd_server_side_copy_max_total_size());
6761
6762         chunks = (struct srv_copychunk *)&ci_req->Chunks[0];
6763         chunk_count = le32_to_cpu(ci_req->ChunkCount);
6764         total_size_written = 0;
6765
6766         /* verify the SRV_COPYCHUNK_COPY packet */
6767         if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
6768             le32_to_cpu(req->InputCount) <
6769              offsetof(struct copychunk_ioctl_req, Chunks) +
6770              chunk_count * sizeof(struct srv_copychunk)) {
6771                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6772                 return -EINVAL;
6773         }
6774
6775         for (i = 0; i < chunk_count; i++) {
6776                 if (le32_to_cpu(chunks[i].Length) == 0 ||
6777                     le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
6778                         break;
6779                 total_size_written += le32_to_cpu(chunks[i].Length);
6780         }
6781
6782         if (i < chunk_count ||
6783             total_size_written > ksmbd_server_side_copy_max_total_size()) {
6784                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6785                 return -EINVAL;
6786         }
6787
6788         src_fp = ksmbd_lookup_foreign_fd(work,
6789                         le64_to_cpu(ci_req->ResumeKey[0]));
6790         dst_fp = ksmbd_lookup_fd_slow(work,
6791                                  le64_to_cpu(req->VolatileFileId),
6792                                  le64_to_cpu(req->PersistentFileId));
6793         ret = -EINVAL;
6794         if (!src_fp ||
6795             src_fp->persistent_id != le64_to_cpu(ci_req->ResumeKey[1])) {
6796                 rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
6797                 goto out;
6798         }
6799
6800         if (!dst_fp) {
6801                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6802                 goto out;
6803         }
6804
6805         /*
6806          * FILE_READ_DATA should only be included in
6807          * the FSCTL_COPYCHUNK case
6808          */
6809         if (cnt_code == FSCTL_COPYCHUNK && !(dst_fp->daccess &
6810                         (FILE_READ_DATA_LE | FILE_GENERIC_READ_LE))) {
6811                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
6812                 goto out;
6813         }
6814
6815         ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp,
6816                         chunks, chunk_count,
6817                         &chunk_count_written, &chunk_size_written,
6818                         &total_size_written);
6819         if (ret < 0) {
6820                 if (ret == -EACCES)
6821                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
6822                 if (ret == -EAGAIN)
6823                         rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6824                 else if (ret == -EBADF)
6825                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
6826                 else if (ret == -EFBIG || ret == -ENOSPC)
6827                         rsp->hdr.Status = STATUS_DISK_FULL;
6828                 else if (ret == -EINVAL)
6829                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6830                 else if (ret == -EISDIR)
6831                         rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
6832                 else if (ret == -E2BIG)
6833                         rsp->hdr.Status = STATUS_INVALID_VIEW_SIZE;
6834                 else
6835                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
6836         }
6837
6838         ci_rsp->ChunksWritten = cpu_to_le32(chunk_count_written);
6839         ci_rsp->ChunkBytesWritten = cpu_to_le32(chunk_size_written);
6840         ci_rsp->TotalBytesWritten = cpu_to_le32(total_size_written);
6841 out:
6842         ksmbd_fd_put(work, src_fp);
6843         ksmbd_fd_put(work, dst_fp);
6844         return ret;
6845 }
6846
6847 static __be32 idev_ipv4_address(struct in_device *idev)
6848 {
6849         __be32 addr = 0;
6850
6851         struct in_ifaddr *ifa;
6852
6853         rcu_read_lock();
6854         in_dev_for_each_ifa_rcu(ifa, idev) {
6855                 if (ifa->ifa_flags & IFA_F_SECONDARY)
6856                         continue;
6857
6858                 addr = ifa->ifa_address;
6859                 break;
6860         }
6861         rcu_read_unlock();
6862         return addr;
6863 }
6864
6865 static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
6866                 struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp)
6867 {
6868         struct network_interface_info_ioctl_rsp *nii_rsp = NULL;
6869         int nbytes = 0;
6870         struct net_device *netdev;
6871         struct sockaddr_storage_rsp *sockaddr_storage;
6872         unsigned int flags;
6873         unsigned long long speed;
6874
6875         rtnl_lock();
6876         for_each_netdev(&init_net, netdev) {
6877                 if (unlikely(!netdev)) {
6878                         rtnl_unlock();
6879                         return -EINVAL;
6880                 }
6881
6882                 if (netdev->type == ARPHRD_LOOPBACK)
6883                         continue;
6884
6885                 flags = dev_get_flags(netdev);
6886                 if (!(flags & IFF_RUNNING))
6887                         continue;
6888
6889                 nii_rsp = (struct network_interface_info_ioctl_rsp *)
6890                                 &rsp->Buffer[nbytes];
6891                 nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex);
6892
6893                 /* TODO: specify the RDMA capabilities */
6894                 if (netdev->num_tx_queues > 1)
6895                         nii_rsp->Capability = cpu_to_le32(RSS_CAPABLE);
6896                 else
6897                         nii_rsp->Capability = 0;
6898
6899                 nii_rsp->Next = cpu_to_le32(152);
6900                 nii_rsp->Reserved = 0;
6901
6902                 if (netdev->ethtool_ops->get_link_ksettings) {
6903                         struct ethtool_link_ksettings cmd;
6904
6905                         netdev->ethtool_ops->get_link_ksettings(netdev, &cmd);
6906                         speed = cmd.base.speed;
6907                 } else {
6908                         ksmbd_err("%s %s\n", netdev->name,
6909                                 "speed is unknown, defaulting to 1Gb/sec");
6910                         speed = SPEED_1000;
6911                 }
6912
6913                 speed *= 1000000;
6914                 nii_rsp->LinkSpeed = cpu_to_le64(speed);
6915
6916                 sockaddr_storage = (struct sockaddr_storage_rsp *)
6917                                         nii_rsp->SockAddr_Storage;
6918                 memset(sockaddr_storage, 0, 128);
6919
6920                 if (conn->peer_addr.ss_family == PF_INET) {
6921                         struct in_device *idev;
6922
6923                         sockaddr_storage->Family = cpu_to_le16(INTERNETWORK);
6924                         sockaddr_storage->addr4.Port = 0;
6925
6926                         idev = __in_dev_get_rtnl(netdev);
6927                         if (!idev)
6928                                 continue;
6929                         sockaddr_storage->addr4.IPv4address =
6930                                                 idev_ipv4_address(idev);
6931                 } else {
6932                         struct inet6_dev *idev6;
6933                         struct inet6_ifaddr *ifa;
6934                         __u8 *ipv6_addr = sockaddr_storage->addr6.IPv6address;
6935
6936                         sockaddr_storage->Family = cpu_to_le16(INTERNETWORKV6);
6937                         sockaddr_storage->addr6.Port = 0;
6938                         sockaddr_storage->addr6.FlowInfo = 0;
6939
6940                         idev6 = __in6_dev_get(netdev);
6941                         if (!idev6)
6942                                 continue;
6943
6944                         list_for_each_entry(ifa, &idev6->addr_list, if_list) {
6945                                 if (ifa->flags & (IFA_F_TENTATIVE |
6946                                                         IFA_F_DEPRECATED))
6947                                         continue;
6948                                 memcpy(ipv6_addr, ifa->addr.s6_addr, 16);
6949                                 break;
6950                         }
6951                         sockaddr_storage->addr6.ScopeId = 0;
6952                 }
6953
6954                 nbytes += sizeof(struct network_interface_info_ioctl_rsp);
6955         }
6956         rtnl_unlock();
6957
6958         /* zero if this is last one */
6959         if (nii_rsp)
6960                 nii_rsp->Next = 0;
6961
6962         if (!nbytes) {
6963                 rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL;
6964                 return -EINVAL;
6965         }
6966
6967         rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID);
6968         rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID);
6969         return nbytes;
6970 }
6971
6972 static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
6973                 struct validate_negotiate_info_req *neg_req,
6974                 struct validate_negotiate_info_rsp *neg_rsp)
6975 {
6976         int ret = 0;
6977         int dialect;
6978
6979         dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects,
6980                         neg_req->DialectCount);
6981         if (dialect == BAD_PROT_ID || dialect != conn->dialect) {
6982                 ret = -EINVAL;
6983                 goto err_out;
6984         }
6985
6986         if (strncmp(neg_req->Guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE)) {
6987                 ret = -EINVAL;
6988                 goto err_out;
6989         }
6990
6991         if (le16_to_cpu(neg_req->SecurityMode) != conn->cli_sec_mode) {
6992                 ret = -EINVAL;
6993                 goto err_out;
6994         }
6995
6996         if (le32_to_cpu(neg_req->Capabilities) != conn->cli_cap) {
6997                 ret = -EINVAL;
6998                 goto err_out;
6999         }
7000
7001         neg_rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
7002         memset(neg_rsp->Guid, 0, SMB2_CLIENT_GUID_SIZE);
7003         neg_rsp->SecurityMode = cpu_to_le16(conn->srv_sec_mode);
7004         neg_rsp->Dialect = cpu_to_le16(conn->dialect);
7005 err_out:
7006         return ret;
7007 }
7008
7009 static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
7010                 struct file_allocated_range_buffer *qar_req,
7011                 struct file_allocated_range_buffer *qar_rsp,
7012                 int in_count, int *out_count)
7013 {
7014         struct ksmbd_file *fp;
7015         loff_t start, length;
7016         int ret = 0;
7017
7018         *out_count = 0;
7019         if (in_count == 0)
7020                 return -EINVAL;
7021
7022         fp = ksmbd_lookup_fd_fast(work, id);
7023         if (!fp)
7024                 return -ENOENT;
7025
7026         start = le64_to_cpu(qar_req->file_offset);
7027         length = le64_to_cpu(qar_req->length);
7028
7029         ret = ksmbd_vfs_fqar_lseek(fp, start, length,
7030                         qar_rsp, in_count, out_count);
7031         if (ret && ret != -E2BIG)
7032                 *out_count = 0;
7033
7034         ksmbd_fd_put(work, fp);
7035         return ret;
7036 }
7037
7038 static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
7039                 int out_buf_len, struct smb2_ioctl_req *req,
7040                 struct smb2_ioctl_rsp *rsp)
7041 {
7042         struct ksmbd_rpc_command *rpc_resp;
7043         char *data_buf = (char *)&req->Buffer[0];
7044         int nbytes = 0;
7045
7046         rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
7047                         le32_to_cpu(req->InputCount));
7048         if (rpc_resp) {
7049                 if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
7050                         /*
7051                          * set STATUS_SOME_NOT_MAPPED response
7052                          * for unknown domain sid.
7053                          */
7054                         rsp->hdr.Status = STATUS_SOME_NOT_MAPPED;
7055                 } else if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
7056                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7057                         goto out;
7058                 } else if (rpc_resp->flags != KSMBD_RPC_OK) {
7059                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7060                         goto out;
7061                 }
7062
7063                 nbytes = rpc_resp->payload_sz;
7064                 if (rpc_resp->payload_sz > out_buf_len) {
7065                         rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
7066                         nbytes = out_buf_len;
7067                 }
7068
7069                 if (!rpc_resp->payload_sz) {
7070                         rsp->hdr.Status =
7071                                 STATUS_UNEXPECTED_IO_ERROR;
7072                         goto out;
7073                 }
7074
7075                 memcpy((char *)rsp->Buffer, rpc_resp->payload, nbytes);
7076         }
7077 out:
7078         kvfree(rpc_resp);
7079         return nbytes;
7080 }
7081
7082 static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
7083                 struct file_sparse *sparse)
7084 {
7085         struct ksmbd_file *fp;
7086         int ret = 0;
7087         __le32 old_fattr;
7088
7089         fp = ksmbd_lookup_fd_fast(work, id);
7090         if (!fp)
7091                 return -ENOENT;
7092
7093         old_fattr = fp->f_ci->m_fattr;
7094         if (sparse->SetSparse)
7095                 fp->f_ci->m_fattr |= ATTR_SPARSE_FILE_LE;
7096         else
7097                 fp->f_ci->m_fattr &= ~ATTR_SPARSE_FILE_LE;
7098
7099         if (fp->f_ci->m_fattr != old_fattr &&
7100             test_share_config_flag(work->tcon->share_conf,
7101                                    KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
7102                 struct xattr_dos_attrib da;
7103
7104                 ret = ksmbd_vfs_get_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
7105                 if (ret <= 0)
7106                         goto out;
7107
7108                 da.attr = le32_to_cpu(fp->f_ci->m_fattr);
7109                 ret = ksmbd_vfs_set_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
7110                 if (ret)
7111                         fp->f_ci->m_fattr = old_fattr;
7112         }
7113
7114 out:
7115         ksmbd_fd_put(work, fp);
7116         return ret;
7117 }
7118
7119 static int fsctl_request_resume_key(struct ksmbd_work *work,
7120                 struct smb2_ioctl_req *req,
7121                 struct resume_key_ioctl_rsp *key_rsp)
7122 {
7123         struct ksmbd_file *fp;
7124
7125         fp = ksmbd_lookup_fd_slow(work,
7126                         le64_to_cpu(req->VolatileFileId),
7127                         le64_to_cpu(req->PersistentFileId));
7128         if (!fp)
7129                 return -ENOENT;
7130
7131         memset(key_rsp, 0, sizeof(*key_rsp));
7132         key_rsp->ResumeKey[0] = req->VolatileFileId;
7133         key_rsp->ResumeKey[1] = req->PersistentFileId;
7134         ksmbd_fd_put(work, fp);
7135
7136         return 0;
7137 }
7138
7139 /**
7140  * smb2_ioctl() - handler for smb2 ioctl command
7141  * @work:       smb work containing ioctl command buffer
7142  *
7143  * Return:      0 on success, otherwise error
7144  */
7145 int smb2_ioctl(struct ksmbd_work *work)
7146 {
7147         struct smb2_ioctl_req *req;
7148         struct smb2_ioctl_rsp *rsp, *rsp_org;
7149         int cnt_code, nbytes = 0;
7150         int out_buf_len;
7151         u64 id = KSMBD_NO_FID;
7152         struct ksmbd_conn *conn = work->conn;
7153         int ret = 0;
7154
7155         rsp_org = work->response_buf;
7156         if (work->next_smb2_rcv_hdr_off) {
7157                 req = REQUEST_BUF_NEXT(work);
7158                 rsp = RESPONSE_BUF_NEXT(work);
7159                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
7160                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
7161                                         work->compound_fid);
7162                         id = work->compound_fid;
7163                 }
7164         } else {
7165                 req = work->request_buf;
7166                 rsp = work->response_buf;
7167         }
7168
7169         if (!HAS_FILE_ID(id))
7170                 id = le64_to_cpu(req->VolatileFileId);
7171
7172         if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) {
7173                 rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7174                 goto out;
7175         }
7176
7177         cnt_code = le32_to_cpu(req->CntCode);
7178         out_buf_len = le32_to_cpu(req->MaxOutputResponse);
7179         out_buf_len = min(KSMBD_IPC_MAX_PAYLOAD, out_buf_len);
7180
7181         switch (cnt_code) {
7182         case FSCTL_DFS_GET_REFERRALS:
7183         case FSCTL_DFS_GET_REFERRALS_EX:
7184                 /* Not support DFS yet */
7185                 rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED;
7186                 goto out;
7187         case FSCTL_CREATE_OR_GET_OBJECT_ID:
7188         {
7189                 struct file_object_buf_type1_ioctl_rsp *obj_buf;
7190
7191                 nbytes = sizeof(struct file_object_buf_type1_ioctl_rsp);
7192                 obj_buf = (struct file_object_buf_type1_ioctl_rsp *)
7193                         &rsp->Buffer[0];
7194
7195                 /*
7196                  * TODO: This is dummy implementation to pass smbtorture
7197                  * Need to check correct response later
7198                  */
7199                 memset(obj_buf->ObjectId, 0x0, 16);
7200                 memset(obj_buf->BirthVolumeId, 0x0, 16);
7201                 memset(obj_buf->BirthObjectId, 0x0, 16);
7202                 memset(obj_buf->DomainId, 0x0, 16);
7203
7204                 break;
7205         }
7206         case FSCTL_PIPE_TRANSCEIVE:
7207                 nbytes = fsctl_pipe_transceive(work, id, out_buf_len, req, rsp);
7208                 break;
7209         case FSCTL_VALIDATE_NEGOTIATE_INFO:
7210                 if (conn->dialect < SMB30_PROT_ID) {
7211                         ret = -EOPNOTSUPP;
7212                         goto out;
7213                 }
7214
7215                 ret = fsctl_validate_negotiate_info(conn,
7216                         (struct validate_negotiate_info_req *)&req->Buffer[0],
7217                         (struct validate_negotiate_info_rsp *)&rsp->Buffer[0]);
7218                 if (ret < 0)
7219                         goto out;
7220
7221                 nbytes = sizeof(struct validate_negotiate_info_rsp);
7222                 rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID);
7223                 rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID);
7224                 break;
7225         case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
7226                 nbytes = fsctl_query_iface_info_ioctl(conn, req, rsp);
7227                 if (nbytes < 0)
7228                         goto out;
7229                 break;
7230         case FSCTL_REQUEST_RESUME_KEY:
7231                 if (out_buf_len < sizeof(struct resume_key_ioctl_rsp)) {
7232                         ret = -EINVAL;
7233                         goto out;
7234                 }
7235
7236                 ret = fsctl_request_resume_key(work, req,
7237                         (struct resume_key_ioctl_rsp *)&rsp->Buffer[0]);
7238                 if (ret < 0)
7239                         goto out;
7240                 rsp->PersistentFileId = req->PersistentFileId;
7241                 rsp->VolatileFileId = req->VolatileFileId;
7242                 nbytes = sizeof(struct resume_key_ioctl_rsp);
7243                 break;
7244         case FSCTL_COPYCHUNK:
7245         case FSCTL_COPYCHUNK_WRITE:
7246                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7247                         ksmbd_debug(SMB,
7248                                 "User does not have write permission\n");
7249                         ret = -EACCES;
7250                         goto out;
7251                 }
7252
7253                 if (out_buf_len < sizeof(struct copychunk_ioctl_rsp)) {
7254                         ret = -EINVAL;
7255                         goto out;
7256                 }
7257
7258                 nbytes = sizeof(struct copychunk_ioctl_rsp);
7259                 fsctl_copychunk(work, req, rsp);
7260                 break;
7261         case FSCTL_SET_SPARSE:
7262                 ret = fsctl_set_sparse(work, id,
7263                         (struct file_sparse *)&req->Buffer[0]);
7264                 if (ret < 0)
7265                         goto out;
7266                 break;
7267         case FSCTL_SET_ZERO_DATA:
7268         {
7269                 struct file_zero_data_information *zero_data;
7270                 struct ksmbd_file *fp;
7271                 loff_t off, len;
7272
7273                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7274                         ksmbd_debug(SMB,
7275                                 "User does not have write permission\n");
7276                         ret = -EACCES;
7277                         goto out;
7278                 }
7279
7280                 zero_data =
7281                         (struct file_zero_data_information *)&req->Buffer[0];
7282
7283                 fp = ksmbd_lookup_fd_fast(work, id);
7284                 if (!fp) {
7285                         ret = -ENOENT;
7286                         goto out;
7287                 }
7288
7289                 off = le64_to_cpu(zero_data->FileOffset);
7290                 len = le64_to_cpu(zero_data->BeyondFinalZero) - off;
7291
7292                 ret = ksmbd_vfs_zero_data(work, fp, off, len);
7293                 ksmbd_fd_put(work, fp);
7294                 if (ret < 0)
7295                         goto out;
7296                 break;
7297         }
7298         case FSCTL_QUERY_ALLOCATED_RANGES:
7299                 ret = fsctl_query_allocated_ranges(work, id,
7300                         (struct file_allocated_range_buffer *)&req->Buffer[0],
7301                         (struct file_allocated_range_buffer *)&rsp->Buffer[0],
7302                         out_buf_len /
7303                         sizeof(struct file_allocated_range_buffer), &nbytes);
7304                 if (ret == -E2BIG) {
7305                         rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
7306                 } else if (ret < 0) {
7307                         nbytes = 0;
7308                         goto out;
7309                 }
7310
7311                 nbytes *= sizeof(struct file_allocated_range_buffer);
7312                 break;
7313         case FSCTL_GET_REPARSE_POINT:
7314         {
7315                 struct reparse_data_buffer *reparse_ptr;
7316                 struct ksmbd_file *fp;
7317
7318                 reparse_ptr = (struct reparse_data_buffer *)&rsp->Buffer[0];
7319                 fp = ksmbd_lookup_fd_fast(work, id);
7320                 if (!fp) {
7321                         ksmbd_err("not found fp!!\n");
7322                         ret = -ENOENT;
7323                         goto out;
7324                 }
7325
7326                 reparse_ptr->ReparseTag =
7327                         smb2_get_reparse_tag_special_file(FP_INODE(fp)->i_mode);
7328                 reparse_ptr->ReparseDataLength = 0;
7329                 ksmbd_fd_put(work, fp);
7330                 nbytes = sizeof(struct reparse_data_buffer);
7331                 break;
7332         }
7333         case FSCTL_DUPLICATE_EXTENTS_TO_FILE:
7334         {
7335                 struct ksmbd_file *fp_in, *fp_out = NULL;
7336                 struct duplicate_extents_to_file *dup_ext;
7337                 loff_t src_off, dst_off, length, cloned;
7338
7339                 dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0];
7340
7341                 fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
7342                                 dup_ext->PersistentFileHandle);
7343                 if (!fp_in) {
7344                         ksmbd_err("not found file handle in duplicate extent to file\n");
7345                         ret = -ENOENT;
7346                         goto out;
7347                 }
7348
7349                 fp_out = ksmbd_lookup_fd_fast(work, id);
7350                 if (!fp_out) {
7351                         ksmbd_err("not found fp\n");
7352                         ret = -ENOENT;
7353                         goto dup_ext_out;
7354                 }
7355
7356                 src_off = le64_to_cpu(dup_ext->SourceFileOffset);
7357                 dst_off = le64_to_cpu(dup_ext->TargetFileOffset);
7358                 length = le64_to_cpu(dup_ext->ByteCount);
7359                 cloned = vfs_clone_file_range(fp_in->filp, src_off, fp_out->filp,
7360                                 dst_off, length, 0);
7361                 if (cloned == -EXDEV || cloned == -EOPNOTSUPP) {
7362                         ret = -EOPNOTSUPP;
7363                         goto dup_ext_out;
7364                 } else if (cloned != length) {
7365                         cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off,
7366                                         fp_out->filp, dst_off, length);
7367                         if (cloned != length) {
7368                                 if (cloned < 0)
7369                                         ret = cloned;
7370                                 else
7371                                         ret = -EINVAL;
7372                         }
7373                 }
7374
7375 dup_ext_out:
7376                 ksmbd_fd_put(work, fp_in);
7377                 ksmbd_fd_put(work, fp_out);
7378                 if (ret < 0)
7379                         goto out;
7380                 break;
7381         }
7382         default:
7383                 ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
7384                                 cnt_code);
7385                 ret = -EOPNOTSUPP;
7386                 goto out;
7387         }
7388
7389         rsp->CntCode = cpu_to_le32(cnt_code);
7390         rsp->InputCount = cpu_to_le32(0);
7391         rsp->InputOffset = cpu_to_le32(112);
7392         rsp->OutputOffset = cpu_to_le32(112);
7393         rsp->OutputCount = cpu_to_le32(nbytes);
7394         rsp->StructureSize = cpu_to_le16(49);
7395         rsp->Reserved = cpu_to_le16(0);
7396         rsp->Flags = cpu_to_le32(0);
7397         rsp->Reserved2 = cpu_to_le32(0);
7398         inc_rfc1001_len(rsp_org, 48 + nbytes);
7399
7400         return 0;
7401
7402 out:
7403         if (ret == -EACCES)
7404                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
7405         else if (ret == -ENOENT)
7406                 rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
7407         else if (ret == -EOPNOTSUPP)
7408                 rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7409         else if (ret < 0 || rsp->hdr.Status == 0)
7410                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7411         smb2_set_err_rsp(work);
7412         return 0;
7413 }
7414
7415 /**
7416  * smb20_oplock_break_ack() - handler for smb2.0 oplock break command
7417  * @work:       smb work containing oplock break command buffer
7418  *
7419  * Return:      0
7420  */
7421 static void smb20_oplock_break_ack(struct ksmbd_work *work)
7422 {
7423         struct smb2_oplock_break *req = work->request_buf;
7424         struct smb2_oplock_break *rsp = work->response_buf;
7425         struct ksmbd_file *fp;
7426         struct oplock_info *opinfo = NULL;
7427         __le32 err = 0;
7428         int ret = 0;
7429         u64 volatile_id, persistent_id;
7430         char req_oplevel = 0, rsp_oplevel = 0;
7431         unsigned int oplock_change_type;
7432
7433         volatile_id = le64_to_cpu(req->VolatileFid);
7434         persistent_id = le64_to_cpu(req->PersistentFid);
7435         req_oplevel = req->OplockLevel;
7436         ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n",
7437                     volatile_id, persistent_id, req_oplevel);
7438
7439         fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
7440         if (!fp) {
7441                 rsp->hdr.Status = STATUS_FILE_CLOSED;
7442                 smb2_set_err_rsp(work);
7443                 return;
7444         }
7445
7446         opinfo = opinfo_get(fp);
7447         if (!opinfo) {
7448                 ksmbd_err("unexpected null oplock_info\n");
7449                 rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
7450                 smb2_set_err_rsp(work);
7451                 ksmbd_fd_put(work, fp);
7452                 return;
7453         }
7454
7455         if (opinfo->level == SMB2_OPLOCK_LEVEL_NONE) {
7456                 rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
7457                 goto err_out;
7458         }
7459
7460         if (opinfo->op_state == OPLOCK_STATE_NONE) {
7461                 ksmbd_debug(SMB, "unexpected oplock state 0x%x\n", opinfo->op_state);
7462                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7463                 goto err_out;
7464         }
7465
7466         if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7467              opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7468             (req_oplevel != SMB2_OPLOCK_LEVEL_II &&
7469              req_oplevel != SMB2_OPLOCK_LEVEL_NONE)) {
7470                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7471                 oplock_change_type = OPLOCK_WRITE_TO_NONE;
7472         } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
7473                    req_oplevel != SMB2_OPLOCK_LEVEL_NONE) {
7474                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7475                 oplock_change_type = OPLOCK_READ_TO_NONE;
7476         } else if (req_oplevel == SMB2_OPLOCK_LEVEL_II ||
7477                    req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7478                 err = STATUS_INVALID_DEVICE_STATE;
7479                 if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7480                      opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7481                     req_oplevel == SMB2_OPLOCK_LEVEL_II) {
7482                         oplock_change_type = OPLOCK_WRITE_TO_READ;
7483                 } else if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7484                             opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7485                            req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7486                         oplock_change_type = OPLOCK_WRITE_TO_NONE;
7487                 } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
7488                            req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7489                         oplock_change_type = OPLOCK_READ_TO_NONE;
7490                 } else {
7491                         oplock_change_type = 0;
7492                 }
7493         } else {
7494                 oplock_change_type = 0;
7495         }
7496
7497         switch (oplock_change_type) {
7498         case OPLOCK_WRITE_TO_READ:
7499                 ret = opinfo_write_to_read(opinfo);
7500                 rsp_oplevel = SMB2_OPLOCK_LEVEL_II;
7501                 break;
7502         case OPLOCK_WRITE_TO_NONE:
7503                 ret = opinfo_write_to_none(opinfo);
7504                 rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
7505                 break;
7506         case OPLOCK_READ_TO_NONE:
7507                 ret = opinfo_read_to_none(opinfo);
7508                 rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
7509                 break;
7510         default:
7511                 ksmbd_err("unknown oplock change 0x%x -> 0x%x\n",
7512                                 opinfo->level, rsp_oplevel);
7513         }
7514
7515         if (ret < 0) {
7516                 rsp->hdr.Status = err;
7517                 goto err_out;
7518         }
7519
7520         opinfo_put(opinfo);
7521         ksmbd_fd_put(work, fp);
7522         opinfo->op_state = OPLOCK_STATE_NONE;
7523         wake_up_interruptible_all(&opinfo->oplock_q);
7524
7525         rsp->StructureSize = cpu_to_le16(24);
7526         rsp->OplockLevel = rsp_oplevel;
7527         rsp->Reserved = 0;
7528         rsp->Reserved2 = 0;
7529         rsp->VolatileFid = cpu_to_le64(volatile_id);
7530         rsp->PersistentFid = cpu_to_le64(persistent_id);
7531         inc_rfc1001_len(rsp, 24);
7532         return;
7533
7534 err_out:
7535         opinfo->op_state = OPLOCK_STATE_NONE;
7536         wake_up_interruptible_all(&opinfo->oplock_q);
7537
7538         opinfo_put(opinfo);
7539         ksmbd_fd_put(work, fp);
7540         smb2_set_err_rsp(work);
7541 }
7542
7543 static int check_lease_state(struct lease *lease, __le32 req_state)
7544 {
7545         if ((lease->new_state ==
7546              (SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE)) &&
7547             !(req_state & SMB2_LEASE_WRITE_CACHING_LE)) {
7548                 lease->new_state = req_state;
7549                 return 0;
7550         }
7551
7552         if (lease->new_state == req_state)
7553                 return 0;
7554
7555         return 1;
7556 }
7557
7558 /**
7559  * smb21_lease_break_ack() - handler for smb2.1 lease break command
7560  * @work:       smb work containing lease break command buffer
7561  *
7562  * Return:      0
7563  */
7564 static void smb21_lease_break_ack(struct ksmbd_work *work)
7565 {
7566         struct ksmbd_conn *conn = work->conn;
7567         struct smb2_lease_ack *req = work->request_buf;
7568         struct smb2_lease_ack *rsp = work->response_buf;
7569         struct oplock_info *opinfo;
7570         __le32 err = 0;
7571         int ret = 0;
7572         unsigned int lease_change_type;
7573         __le32 lease_state;
7574         struct lease *lease;
7575
7576         ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
7577                         le32_to_cpu(req->LeaseState));
7578         opinfo = lookup_lease_in_table(conn, req->LeaseKey);
7579         if (!opinfo) {
7580                 ksmbd_debug(OPLOCK, "file not opened\n");
7581                 smb2_set_err_rsp(work);
7582                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7583                 return;
7584         }
7585         lease = opinfo->o_lease;
7586
7587         if (opinfo->op_state == OPLOCK_STATE_NONE) {
7588                 ksmbd_err("unexpected lease break state 0x%x\n",
7589                                 opinfo->op_state);
7590                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7591                 goto err_out;
7592         }
7593
7594         if (check_lease_state(lease, req->LeaseState)) {
7595                 rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED;
7596                 ksmbd_debug(OPLOCK,
7597                         "req lease state: 0x%x, expected state: 0x%x\n",
7598                                 req->LeaseState, lease->new_state);
7599                 goto err_out;
7600         }
7601
7602         if (!atomic_read(&opinfo->breaking_cnt)) {
7603                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7604                 goto err_out;
7605         }
7606
7607         /* check for bad lease state */
7608         if (req->LeaseState & (~(SMB2_LEASE_READ_CACHING_LE |
7609                                  SMB2_LEASE_HANDLE_CACHING_LE))) {
7610                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7611                 if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7612                         lease_change_type = OPLOCK_WRITE_TO_NONE;
7613                 else
7614                         lease_change_type = OPLOCK_READ_TO_NONE;
7615                 ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
7616                         le32_to_cpu(lease->state),
7617                         le32_to_cpu(req->LeaseState));
7618         } else if (lease->state == SMB2_LEASE_READ_CACHING_LE &&
7619                    req->LeaseState != SMB2_LEASE_NONE_LE) {
7620                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7621                 lease_change_type = OPLOCK_READ_TO_NONE;
7622                 ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
7623                         le32_to_cpu(lease->state),
7624                         le32_to_cpu(req->LeaseState));
7625         } else {
7626                 /* valid lease state changes */
7627                 err = STATUS_INVALID_DEVICE_STATE;
7628                 if (req->LeaseState == SMB2_LEASE_NONE_LE) {
7629                         if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7630                                 lease_change_type = OPLOCK_WRITE_TO_NONE;
7631                         else
7632                                 lease_change_type = OPLOCK_READ_TO_NONE;
7633                 } else if (req->LeaseState & SMB2_LEASE_READ_CACHING_LE) {
7634                         if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7635                                 lease_change_type = OPLOCK_WRITE_TO_READ;
7636                         else
7637                                 lease_change_type = OPLOCK_READ_HANDLE_TO_READ;
7638                 } else {
7639                         lease_change_type = 0;
7640                 }
7641         }
7642
7643         switch (lease_change_type) {
7644         case OPLOCK_WRITE_TO_READ:
7645                 ret = opinfo_write_to_read(opinfo);
7646                 break;
7647         case OPLOCK_READ_HANDLE_TO_READ:
7648                 ret = opinfo_read_handle_to_read(opinfo);
7649                 break;
7650         case OPLOCK_WRITE_TO_NONE:
7651                 ret = opinfo_write_to_none(opinfo);
7652                 break;
7653         case OPLOCK_READ_TO_NONE:
7654                 ret = opinfo_read_to_none(opinfo);
7655                 break;
7656         default:
7657                 ksmbd_debug(OPLOCK, "unknown lease change 0x%x -> 0x%x\n",
7658                         le32_to_cpu(lease->state),
7659                         le32_to_cpu(req->LeaseState));
7660         }
7661
7662         lease_state = lease->state;
7663         opinfo->op_state = OPLOCK_STATE_NONE;
7664         wake_up_interruptible_all(&opinfo->oplock_q);
7665         atomic_dec(&opinfo->breaking_cnt);
7666         wake_up_interruptible_all(&opinfo->oplock_brk);
7667         opinfo_put(opinfo);
7668
7669         if (ret < 0) {
7670                 rsp->hdr.Status = err;
7671                 goto err_out;
7672         }
7673
7674         rsp->StructureSize = cpu_to_le16(36);
7675         rsp->Reserved = 0;
7676         rsp->Flags = 0;
7677         memcpy(rsp->LeaseKey, req->LeaseKey, 16);
7678         rsp->LeaseState = lease_state;
7679         rsp->LeaseDuration = 0;
7680         inc_rfc1001_len(rsp, 36);
7681         return;
7682
7683 err_out:
7684         opinfo->op_state = OPLOCK_STATE_NONE;
7685         wake_up_interruptible_all(&opinfo->oplock_q);
7686         atomic_dec(&opinfo->breaking_cnt);
7687         wake_up_interruptible_all(&opinfo->oplock_brk);
7688
7689         opinfo_put(opinfo);
7690         smb2_set_err_rsp(work);
7691 }
7692
7693 /**
7694  * smb2_oplock_break() - dispatcher for smb2.0 and 2.1 oplock/lease break
7695  * @work:       smb work containing oplock/lease break command buffer
7696  *
7697  * Return:      0
7698  */
7699 int smb2_oplock_break(struct ksmbd_work *work)
7700 {
7701         struct smb2_oplock_break *req = work->request_buf;
7702         struct smb2_oplock_break *rsp = work->response_buf;
7703
7704         switch (le16_to_cpu(req->StructureSize)) {
7705         case OP_BREAK_STRUCT_SIZE_20:
7706                 smb20_oplock_break_ack(work);
7707                 break;
7708         case OP_BREAK_STRUCT_SIZE_21:
7709                 smb21_lease_break_ack(work);
7710                 break;
7711         default:
7712                 ksmbd_debug(OPLOCK, "invalid break cmd %d\n",
7713                         le16_to_cpu(req->StructureSize));
7714                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7715                 smb2_set_err_rsp(work);
7716         }
7717
7718         return 0;
7719 }
7720
7721 /**
7722  * smb2_notify() - handler for smb2 notify request
7723  * @work:   smb work containing notify command buffer
7724  *
7725  * Return:      0
7726  */
7727 int smb2_notify(struct ksmbd_work *work)
7728 {
7729         struct smb2_notify_req *req;
7730         struct smb2_notify_rsp *rsp;
7731
7732         WORK_BUFFERS(work, req, rsp);
7733
7734         if (work->next_smb2_rcv_hdr_off && req->hdr.NextCommand) {
7735                 rsp->hdr.Status = STATUS_INTERNAL_ERROR;
7736                 smb2_set_err_rsp(work);
7737                 return 0;
7738         }
7739
7740         smb2_set_err_rsp(work);
7741         rsp->hdr.Status = STATUS_NOT_IMPLEMENTED;
7742         return 0;
7743 }
7744
7745 /**
7746  * smb2_is_sign_req() - handler for checking packet signing status
7747  * @work:       smb work containing notify command buffer
7748  * @command:    SMB2 command id
7749  *
7750  * Return:      true if packed is signed, false otherwise
7751  */
7752 bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
7753 {
7754         struct smb2_hdr *rcv_hdr2 = work->request_buf;
7755
7756         if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
7757             command != SMB2_NEGOTIATE_HE &&
7758             command != SMB2_SESSION_SETUP_HE &&
7759             command != SMB2_OPLOCK_BREAK_HE)
7760                 return true;
7761
7762         return false;
7763 }
7764
7765 /**
7766  * smb2_check_sign_req() - handler for req packet sign processing
7767  * @work:   smb work containing notify command buffer
7768  *
7769  * Return:      1 on success, 0 otherwise
7770  */
7771 int smb2_check_sign_req(struct ksmbd_work *work)
7772 {
7773         struct smb2_hdr *hdr, *hdr_org;
7774         char signature_req[SMB2_SIGNATURE_SIZE];
7775         char signature[SMB2_HMACSHA256_SIZE];
7776         struct kvec iov[1];
7777         size_t len;
7778
7779         hdr_org = hdr = work->request_buf;
7780         if (work->next_smb2_rcv_hdr_off)
7781                 hdr = REQUEST_BUF_NEXT(work);
7782
7783         if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
7784                 len = be32_to_cpu(hdr_org->smb2_buf_length);
7785         else if (hdr->NextCommand)
7786                 len = le32_to_cpu(hdr->NextCommand);
7787         else
7788                 len = be32_to_cpu(hdr_org->smb2_buf_length) -
7789                         work->next_smb2_rcv_hdr_off;
7790
7791         memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
7792         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7793
7794         iov[0].iov_base = (char *)&hdr->ProtocolId;
7795         iov[0].iov_len = len;
7796
7797         if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
7798                                 signature))
7799                 return 0;
7800
7801         if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
7802                 ksmbd_err("bad smb2 signature\n");
7803                 return 0;
7804         }
7805
7806         return 1;
7807 }
7808
7809 /**
7810  * smb2_set_sign_rsp() - handler for rsp packet sign processing
7811  * @work:   smb work containing notify command buffer
7812  *
7813  */
7814 void smb2_set_sign_rsp(struct ksmbd_work *work)
7815 {
7816         struct smb2_hdr *hdr, *hdr_org;
7817         struct smb2_hdr *req_hdr;
7818         char signature[SMB2_HMACSHA256_SIZE];
7819         struct kvec iov[2];
7820         size_t len;
7821         int n_vec = 1;
7822
7823         hdr_org = hdr = work->response_buf;
7824         if (work->next_smb2_rsp_hdr_off)
7825                 hdr = RESPONSE_BUF_NEXT(work);
7826
7827         req_hdr = REQUEST_BUF_NEXT(work);
7828
7829         if (!work->next_smb2_rsp_hdr_off) {
7830                 len = get_rfc1002_len(hdr_org);
7831                 if (req_hdr->NextCommand)
7832                         len = ALIGN(len, 8);
7833         } else {
7834                 len = get_rfc1002_len(hdr_org) - work->next_smb2_rsp_hdr_off;
7835                 len = ALIGN(len, 8);
7836         }
7837
7838         if (req_hdr->NextCommand)
7839                 hdr->NextCommand = cpu_to_le32(len);
7840
7841         hdr->Flags |= SMB2_FLAGS_SIGNED;
7842         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7843
7844         iov[0].iov_base = (char *)&hdr->ProtocolId;
7845         iov[0].iov_len = len;
7846
7847         if (work->aux_payload_sz) {
7848                 iov[0].iov_len -= work->aux_payload_sz;
7849
7850                 iov[1].iov_base = work->aux_payload_buf;
7851                 iov[1].iov_len = work->aux_payload_sz;
7852                 n_vec++;
7853         }
7854
7855         if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
7856                                  signature))
7857                 memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
7858 }
7859
7860 /**
7861  * smb3_check_sign_req() - handler for req packet sign processing
7862  * @work:   smb work containing notify command buffer
7863  *
7864  * Return:      1 on success, 0 otherwise
7865  */
7866 int smb3_check_sign_req(struct ksmbd_work *work)
7867 {
7868         struct ksmbd_conn *conn;
7869         char *signing_key;
7870         struct smb2_hdr *hdr, *hdr_org;
7871         struct channel *chann;
7872         char signature_req[SMB2_SIGNATURE_SIZE];
7873         char signature[SMB2_CMACAES_SIZE];
7874         struct kvec iov[1];
7875         size_t len;
7876
7877         hdr_org = hdr = work->request_buf;
7878         if (work->next_smb2_rcv_hdr_off)
7879                 hdr = REQUEST_BUF_NEXT(work);
7880
7881         if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
7882                 len = be32_to_cpu(hdr_org->smb2_buf_length);
7883         else if (hdr->NextCommand)
7884                 len = le32_to_cpu(hdr->NextCommand);
7885         else
7886                 len = be32_to_cpu(hdr_org->smb2_buf_length) -
7887                         work->next_smb2_rcv_hdr_off;
7888
7889         if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
7890                 signing_key = work->sess->smb3signingkey;
7891                 conn = work->sess->conn;
7892         } else {
7893                 chann = lookup_chann_list(work->sess);
7894                 if (!chann)
7895                         return 0;
7896                 signing_key = chann->smb3signingkey;
7897                 conn = chann->conn;
7898         }
7899
7900         if (!signing_key) {
7901                 ksmbd_err("SMB3 signing key is not generated\n");
7902                 return 0;
7903         }
7904
7905         memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
7906         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7907         iov[0].iov_base = (char *)&hdr->ProtocolId;
7908         iov[0].iov_len = len;
7909
7910         if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature))
7911                 return 0;
7912
7913         if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
7914                 ksmbd_err("bad smb2 signature\n");
7915                 return 0;
7916         }
7917
7918         return 1;
7919 }
7920
7921 /**
7922  * smb3_set_sign_rsp() - handler for rsp packet sign processing
7923  * @work:   smb work containing notify command buffer
7924  *
7925  */
7926 void smb3_set_sign_rsp(struct ksmbd_work *work)
7927 {
7928         struct ksmbd_conn *conn;
7929         struct smb2_hdr *req_hdr;
7930         struct smb2_hdr *hdr, *hdr_org;
7931         struct channel *chann;
7932         char signature[SMB2_CMACAES_SIZE];
7933         struct kvec iov[2];
7934         int n_vec = 1;
7935         size_t len;
7936         char *signing_key;
7937
7938         hdr_org = hdr = work->response_buf;
7939         if (work->next_smb2_rsp_hdr_off)
7940                 hdr = RESPONSE_BUF_NEXT(work);
7941
7942         req_hdr = REQUEST_BUF_NEXT(work);
7943
7944         if (!work->next_smb2_rsp_hdr_off) {
7945                 len = get_rfc1002_len(hdr_org);
7946                 if (req_hdr->NextCommand)
7947                         len = ALIGN(len, 8);
7948         } else {
7949                 len = get_rfc1002_len(hdr_org) - work->next_smb2_rsp_hdr_off;
7950                 len = ALIGN(len, 8);
7951         }
7952
7953         if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
7954                 signing_key = work->sess->smb3signingkey;
7955                 conn = work->sess->conn;
7956         } else {
7957                 chann = lookup_chann_list(work->sess);
7958                 if (!chann)
7959                         return;
7960                 signing_key = chann->smb3signingkey;
7961                 conn = chann->conn;
7962         }
7963
7964         if (!signing_key)
7965                 return;
7966
7967         if (req_hdr->NextCommand)
7968                 hdr->NextCommand = cpu_to_le32(len);
7969
7970         hdr->Flags |= SMB2_FLAGS_SIGNED;
7971         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7972         iov[0].iov_base = (char *)&hdr->ProtocolId;
7973         iov[0].iov_len = len;
7974         if (work->aux_payload_sz) {
7975                 iov[0].iov_len -= work->aux_payload_sz;
7976                 iov[1].iov_base = work->aux_payload_buf;
7977                 iov[1].iov_len = work->aux_payload_sz;
7978                 n_vec++;
7979         }
7980
7981         if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature))
7982                 memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
7983 }
7984
7985 /**
7986  * smb3_preauth_hash_rsp() - handler for computing preauth hash on response
7987  * @work:   smb work containing response buffer
7988  *
7989  */
7990 void smb3_preauth_hash_rsp(struct ksmbd_work *work)
7991 {
7992         struct ksmbd_conn *conn = work->conn;
7993         struct ksmbd_session *sess = work->sess;
7994         struct smb2_hdr *req, *rsp;
7995
7996         if (conn->dialect != SMB311_PROT_ID)
7997                 return;
7998
7999         WORK_BUFFERS(work, req, rsp);
8000
8001         if (le16_to_cpu(req->Command) == SMB2_NEGOTIATE_HE)
8002                 ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
8003                         conn->preauth_info->Preauth_HashValue);
8004
8005         if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
8006             sess && sess->state == SMB2_SESSION_IN_PROGRESS) {
8007                 __u8 *hash_value;
8008
8009                 hash_value = sess->Preauth_HashValue;
8010                 ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
8011                                 hash_value);
8012         }
8013 }
8014
8015 static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, char *old_buf,
8016                 __le16 cipher_type)
8017 {
8018         struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf;
8019         unsigned int orig_len = get_rfc1002_len(old_buf);
8020
8021         memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
8022         tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
8023         tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
8024         tr_hdr->Flags = cpu_to_le16(0x01);
8025         if (cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
8026             cipher_type == SMB2_ENCRYPTION_AES256_GCM)
8027                 get_random_bytes(&tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
8028         else
8029                 get_random_bytes(&tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
8030         memcpy(&tr_hdr->SessionId, &hdr->SessionId, 8);
8031         inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - 4);
8032         inc_rfc1001_len(tr_hdr, orig_len);
8033 }
8034
8035 int smb3_encrypt_resp(struct ksmbd_work *work)
8036 {
8037         char *buf = work->response_buf;
8038         struct smb2_transform_hdr *tr_hdr;
8039         struct kvec iov[3];
8040         int rc = -ENOMEM;
8041         int buf_size = 0, rq_nvec = 2 + (work->aux_payload_sz ? 1 : 0);
8042
8043         if (ARRAY_SIZE(iov) < rq_nvec)
8044                 return -ENOMEM;
8045
8046         tr_hdr = kzalloc(sizeof(struct smb2_transform_hdr), GFP_KERNEL);
8047         if (!tr_hdr)
8048                 return rc;
8049
8050         /* fill transform header */
8051         fill_transform_hdr(tr_hdr, buf, work->conn->cipher_type);
8052
8053         iov[0].iov_base = tr_hdr;
8054         iov[0].iov_len = sizeof(struct smb2_transform_hdr);
8055         buf_size += iov[0].iov_len - 4;
8056
8057         iov[1].iov_base = buf + 4;
8058         iov[1].iov_len = get_rfc1002_len(buf);
8059         if (work->aux_payload_sz) {
8060                 iov[1].iov_len = work->resp_hdr_sz - 4;
8061
8062                 iov[2].iov_base = work->aux_payload_buf;
8063                 iov[2].iov_len = work->aux_payload_sz;
8064                 buf_size += iov[2].iov_len;
8065         }
8066         buf_size += iov[1].iov_len;
8067         work->resp_hdr_sz = iov[1].iov_len;
8068
8069         rc = ksmbd_crypt_message(work->conn, iov, rq_nvec, 1);
8070         if (rc)
8071                 return rc;
8072
8073         memmove(buf, iov[1].iov_base, iov[1].iov_len);
8074         tr_hdr->smb2_buf_length = cpu_to_be32(buf_size);
8075         work->tr_buf = tr_hdr;
8076
8077         return rc;
8078 }
8079
8080 int smb3_is_transform_hdr(void *buf)
8081 {
8082         struct smb2_transform_hdr *trhdr = buf;
8083
8084         return trhdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM;
8085 }
8086
8087 int smb3_decrypt_req(struct ksmbd_work *work)
8088 {
8089         struct ksmbd_conn *conn = work->conn;
8090         struct ksmbd_session *sess;
8091         char *buf = work->request_buf;
8092         struct smb2_hdr *hdr;
8093         unsigned int pdu_length = get_rfc1002_len(buf);
8094         struct kvec iov[2];
8095         unsigned int buf_data_size = pdu_length + 4 -
8096                 sizeof(struct smb2_transform_hdr);
8097         struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
8098         unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
8099         int rc = 0;
8100
8101         sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId));
8102         if (!sess) {
8103                 ksmbd_err("invalid session id(%llx) in transform header\n",
8104                         le64_to_cpu(tr_hdr->SessionId));
8105                 return -ECONNABORTED;
8106         }
8107
8108         if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) +
8109                         sizeof(struct smb2_hdr)) {
8110                 ksmbd_err("Transform message is too small (%u)\n",
8111                                 pdu_length);
8112                 return -ECONNABORTED;
8113         }
8114
8115         if (pdu_length + 4 < orig_len + sizeof(struct smb2_transform_hdr)) {
8116                 ksmbd_err("Transform message is broken\n");
8117                 return -ECONNABORTED;
8118         }
8119
8120         iov[0].iov_base = buf;
8121         iov[0].iov_len = sizeof(struct smb2_transform_hdr);
8122         iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr);
8123         iov[1].iov_len = buf_data_size;
8124         rc = ksmbd_crypt_message(conn, iov, 2, 0);
8125         if (rc)
8126                 return rc;
8127
8128         memmove(buf + 4, iov[1].iov_base, buf_data_size);
8129         hdr = (struct smb2_hdr *)buf;
8130         hdr->smb2_buf_length = cpu_to_be32(buf_data_size);
8131
8132         return rc;
8133 }
8134
8135 bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
8136 {
8137         struct ksmbd_conn *conn = work->conn;
8138         struct smb2_hdr *rsp = work->response_buf;
8139
8140         if (conn->dialect < SMB30_PROT_ID)
8141                 return false;
8142
8143         if (work->next_smb2_rcv_hdr_off)
8144                 rsp = RESPONSE_BUF_NEXT(work);
8145
8146         if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
8147             rsp->Status == STATUS_SUCCESS)
8148                 return true;
8149         return false;
8150 }